Skip to content

Commit 64c1843

Browse files
authored
Merge pull request #325 from adamint/dev/adamint/fix-progress-bar-and-maven-central-issues
Fix progress bar and maven central issues
2 parents 830589f + 1360e9b commit 64c1843

File tree

20 files changed

+88
-110
lines changed

20 files changed

+88
-110
lines changed

.github/workflows/ci-client.yml

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
name: CI Client Test Workflow
2+
on:
3+
workflow_dispatch:
4+
inputs:
5+
spotify_test_client_token:
6+
description: 'Spotify client redirect token (for client tests before release)'
7+
required: true
8+
spotify_test_redirect_uri:
9+
description: 'Spotify redirect uri'
10+
required: true
11+
env:
12+
SPOTIFY_CLIENT_ID: ${{ secrets.SPOTIFY_CLIENT_ID }}
13+
SPOTIFY_CLIENT_SECRET: ${{ secrets.SPOTIFY_CLIENT_SECRET }}
14+
SPOTIFY_TOKEN_STRING: ${{ github.event.inputs.spotify_test_client_token }}
15+
SPOTIFY_REDIRECT_URI: ${{ github.event.inputs.spotify_test_redirect_uri }}
16+
jobs:
17+
verify_client_android_jvm_linux_js:
18+
runs-on: ubuntu-latest
19+
environment: release
20+
steps:
21+
- name: Check out repo
22+
uses: actions/checkout@v2
23+
- name: Install java 11
24+
uses: actions/setup-java@v2
25+
with:
26+
distribution: 'adopt'
27+
java-version: '11'
28+
- name: Install curl
29+
run: sudo apt-get install -y curl libcurl4-openssl-dev
30+
- name: Verify Android
31+
run: ./gradlew testDebugUnitTest
32+
- name: Verify JVM/JS
33+
run: ./gradlew jvmTest
34+
- name: Archive test results
35+
uses: actions/upload-artifact@v2
36+
with:
37+
name: code-coverage-report
38+
path: build/reports
39+
if: always()

.github/workflows/ci.yml

+3-41
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,10 @@
1-
# This workflow will build a Java project with Gradle
2-
# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-gradle
3-
41
name: CI Test Workflow
52

63
on:
74
push:
8-
branches: [ main, dev ]
5+
branches: [ main, dev, dev/** ]
96
pull_request:
10-
branches: [ main, dev ]
11-
repository_dispatch:
12-
types: [ok-to-test-command]
7+
branches: [ main, dev, dev/** ]
138

149
jobs:
1510
test_android_jvm_linux_trusted:
@@ -38,37 +33,4 @@ jobs:
3833
if: always()
3934
with:
4035
name: code-coverage-report
41-
path: build/reports
42-
test_android_jvm_linux_untrusted:
43-
runs-on: ubuntu-latest
44-
if:
45-
github.event_name == 'repository_dispatch' &&
46-
github.event.client_payload.slash_command.sha != '' &&
47-
contains(github.event.client_payload.pull_request.head.sha, github.event.client_payload.slash_command.sha) &&
48-
github.event.pull_request.head.repo.full_name != github.repository
49-
environment: testing
50-
env:
51-
SPOTIFY_CLIENT_ID: ${{ secrets.SPOTIFY_CLIENT_ID }}
52-
SPOTIFY_CLIENT_SECRET: ${{ secrets.SPOTIFY_CLIENT_SECRET }}
53-
steps:
54-
- name: Fork based /ok-to-test checkout
55-
uses: actions/checkout@v2
56-
with:
57-
ref: 'refs/pull/${{ github.event.client_payload.pull_request.number }}/merge'
58-
- name: Install java 11
59-
uses: actions/setup-java@v2
60-
with:
61-
distribution: 'adopt'
62-
java-version: '11'
63-
- name: Install curl
64-
run: sudo apt-get install -y curl libcurl4-openssl-dev
65-
- name: Test android
66-
run: ./gradlew testDebugUnitTest
67-
- name: Test jvm
68-
run: ./gradlew jvmTest
69-
- name: Archive test results
70-
uses: actions/upload-artifact@v2
71-
if: always()
72-
with:
73-
name: code-coverage-report
74-
path: build/reports
36+
path: build/reports

.github/workflows/ok-to-test.yml

-33
This file was deleted.

build.gradle.kts

+6-5
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ plugins {
1414
kotlin("plugin.serialization")
1515
id("com.diffplug.spotless") version "6.11.0"
1616
id("com.moowork.node") version "1.3.1"
17-
id("org.jetbrains.dokka") version "1.7.20"
17+
id("org.jetbrains.dokka") version "1.8.20"
1818
}
1919

2020
repositories {
@@ -69,7 +69,7 @@ android {
6969
this.unitTests.isReturnDefaultValues = true
7070
}
7171
sourceSets["main"].setRoot("src/androidMain")
72-
sourceSets["test"].setRoot("src/androidTest")
72+
sourceSets["test"].setRoot("src/androidUnitTest")
7373
}
7474

7575
// invoked in kotlin closure, needs to be registered before
@@ -83,7 +83,7 @@ val dokkaJar: TaskProvider<Jar> by tasks.registering(Jar::class) {
8383
kotlin {
8484
explicitApiWarning()
8585

86-
android {
86+
androidTarget {
8787
compilations.all { kotlinOptions.jvmTarget = "1.8" }
8888

8989
mavenPublication { setupPom(artifactId) }
@@ -116,7 +116,7 @@ kotlin {
116116
testTask {
117117
useKarma {
118118
useChromeHeadless()
119-
webpackConfig.cssSupport.enabled = true
119+
webpackConfig.cssSupport { isEnabled = true }
120120
}
121121
}
122122
}
@@ -173,6 +173,7 @@ kotlin {
173173
implementation("com.soywiz.korlibs.krypto:krypto:$korlibsVersion")
174174
implementation("com.soywiz.korlibs.korim:korim:$korlibsVersion")
175175
implementation("org.jetbrains.kotlinx:kotlinx-datetime:$kotlinxDatetimeVersion")
176+
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:$kotlinxCoroutinesVersion")
176177
}
177178
}
178179

@@ -253,7 +254,7 @@ kotlin {
253254
}
254255
}
255256

256-
val androidTest by getting {
257+
val androidUnitTest by getting {
257258
dependsOn(commonJvmLikeTest)
258259
}
259260

gradle.properties

+3-3
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,14 @@ android.enableJetifier=true
99
android.disableAutomaticComponentCreation=false
1010

1111
# language dependencies
12-
kotlinVersion=1.7.21
12+
kotlinVersion=1.9.0
1313

1414
# library dependencies
1515
kotlinxDatetimeVersion=0.4.0
16-
kotlinxSerializationVersion=1.4.1
16+
kotlinxSerializationVersion=1.5.1
1717
ktorVersion=2.1.3
1818
korlibsVersion=3.4.0
19-
kotlinxCoroutinesVersion=1.6.4
19+
kotlinxCoroutinesVersion=1.7.2
2020

2121
androidBuildToolsVersion=7.2.0
2222
androidSpotifyAuthVersion=1.2.5

settings.gradle.kts

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,4 @@ pluginManagement {
3434
}
3535
}
3636

37-
rootProject.name = "spotify-web-api-kotlin"
37+
rootProject.name = "spotify-api-kotlin"

src/androidMain/res/layout/spotify_pkce_auth_layout.xml

+2
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
android:layout_width="80dp"
1717
android:layout_height="80dp"
1818
android:layout_gravity="center"
19+
android:indeterminate="true"
20+
android:indeterminateTint="#5588FF"
1921
wheel:matProg_barColor="#5588FF"
2022
wheel:matProg_progressIndeterminate="true" />
2123

src/commonMain/kotlin/com.adamratzman.spotify/endpoints/client/ClientPlayerApi.kt

+1-2
Original file line numberDiff line numberDiff line change
@@ -165,8 +165,7 @@ public class ClientPlayerApi(api: GenericSpotifyApi) : SpotifyEndpoint(api) {
165165
.with("market", market?.name)
166166
.toString()
167167
)
168-
.toObject(CurrentlyPlayingObject.serializer(), api, json)
169-
}
168+
}?.toObject(CurrentlyPlayingObject.serializer(), api, json)
170169
if (obj?.timestamp == null) null else obj
171170
} catch (pe: SpotifyException.ParseException) {
172171
pe.printStackTrace()

src/commonMain/kotlin/com.adamratzman.spotify/endpoints/pub/ArtistApi.kt

+2-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import com.adamratzman.spotify.models.serialization.toObject
1717
import com.adamratzman.spotify.utils.Market
1818
import com.adamratzman.spotify.utils.catch
1919
import com.adamratzman.spotify.utils.encodeUrl
20+
import com.adamratzman.spotify.utils.getSpotifyId
2021
import kotlinx.serialization.builtins.ListSerializer
2122

2223
/**
@@ -123,7 +124,7 @@ public class ArtistApi(api: GenericSpotifyApi) : SpotifyEndpoint(api) {
123124
public suspend fun getArtistTopTracks(artist: String, market: Market = Market.US): List<Track> = get(
124125
endpointBuilder("/artists/${ArtistUri(artist).id.encodeUrl()}/top-tracks").with(
125126
"country",
126-
market.name
127+
market.getSpotifyId()
127128
).toString()
128129
).toInnerArray(ListSerializer(Track.serializer()), "tracks", json)
129130

src/commonMain/kotlin/com.adamratzman.spotify/endpoints/pub/EpisodeApi.kt

+3-2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import com.adamratzman.spotify.models.serialization.toObject
1313
import com.adamratzman.spotify.utils.Market
1414
import com.adamratzman.spotify.utils.catch
1515
import com.adamratzman.spotify.utils.encodeUrl
16+
import com.adamratzman.spotify.utils.getSpotifyId
1617

1718
/**
1819
* Endpoints for retrieving information about one or more episodes from the Spotify catalog.
@@ -38,7 +39,7 @@ public open class EpisodeApi(api: GenericSpotifyApi) : SpotifyEndpoint(api) {
3839
public suspend fun getEpisode(id: String, market: Market): Episode? {
3940
return catch {
4041
get(
41-
endpointBuilder("/episodes/${EpisodeUri(id).id.encodeUrl()}").with("market", market.name).toString()
42+
endpointBuilder("/episodes/${EpisodeUri(id).id.encodeUrl()}").with("market", market.getSpotifyId()).toString()
4243
).toObject(Episode.serializer(), api, json)
4344
}
4445
}
@@ -67,7 +68,7 @@ public open class EpisodeApi(api: GenericSpotifyApi) : SpotifyEndpoint(api) {
6768
return bulkStatelessRequest(50, ids.toList()) { chunk ->
6869
get(
6970
endpointBuilder("/episodes").with("ids", chunk.joinToString(",") { EpisodeUri(it).id.encodeUrl() })
70-
.with("market", market.name).toString()
71+
.with("market", market.getSpotifyId()).toString()
7172
).toObject(EpisodeList.serializer(), api, json).episodes
7273
}.flatten()
7374
}

src/commonMain/kotlin/com.adamratzman.spotify/endpoints/pub/ShowApi.kt

+4-3
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import com.adamratzman.spotify.models.serialization.toObject
1717
import com.adamratzman.spotify.utils.Market
1818
import com.adamratzman.spotify.utils.catch
1919
import com.adamratzman.spotify.utils.encodeUrl
20+
import com.adamratzman.spotify.utils.getSpotifyId
2021

2122
/**
2223
* Endpoints for retrieving information about one or more shows and their episodes from the Spotify catalog.
@@ -42,7 +43,7 @@ public open class ShowApi(api: GenericSpotifyApi) : SpotifyEndpoint(api) {
4243
public suspend fun getShow(id: String, market: Market): Show? {
4344
return catch {
4445
get(
45-
endpointBuilder("/shows/${ShowUri(id).id.encodeUrl()}").with("market", market.name).toString()
46+
endpointBuilder("/shows/${ShowUri(id).id.encodeUrl()}").with("market", market.getSpotifyId()).toString()
4647
).toObject(Show.serializer(), api, json)
4748
}
4849
}
@@ -70,7 +71,7 @@ public open class ShowApi(api: GenericSpotifyApi) : SpotifyEndpoint(api) {
7071
return bulkStatelessRequest(50, ids.toList()) { chunk ->
7172
get(
7273
endpointBuilder("/shows").with("ids", chunk.joinToString(",") { ShowUri(it).id.encodeUrl() })
73-
.with("market", market.name).toString()
74+
.with("market", market.getSpotifyId()).toString()
7475
).toObject(ShowList.serializer(), api, json).shows
7576
}.flatten()
7677
}
@@ -99,6 +100,6 @@ public open class ShowApi(api: GenericSpotifyApi) : SpotifyEndpoint(api) {
99100
market: Market
100101
): PagingObject<SimpleEpisode> = get(
101102
endpointBuilder("/shows/${ShowUri(id).id.encodeUrl()}/episodes").with("limit", limit)
102-
.with("offset", offset).with("market", market.name).toString()
103+
.with("offset", offset).with("market", market.getSpotifyId()).toString()
103104
).toNonNullablePagingObject(SimpleEpisode.serializer(), null, api, json)
104105
}

src/commonMain/kotlin/com.adamratzman.spotify/endpoints/pub/UserApi.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public open class UserApi(api: GenericSpotifyApi) : SpotifyEndpoint(api) {
2424
*
2525
* @return All publicly-available information about the user
2626
*/
27-
public suspend fun getProfile(user: String): SpotifyPublicUser? = catch {
27+
public suspend fun getProfile(user: String): SpotifyPublicUser? = catch(/* some incorrect user ids will return 500 */ catchInternalServerError = true) {
2828
get(endpointBuilder("/users/${UserUri(user).id.encodeUrl()}").toString())
2929
.toObject(SpotifyPublicUser.serializer(), api, json)
3030
}

src/commonMain/kotlin/com.adamratzman.spotify/utils/Market.kt

+4
Original file line numberDiff line numberDiff line change
@@ -1829,3 +1829,7 @@ public enum class Market(
18291829
NOT_USED
18301830
}
18311831
}
1832+
1833+
internal fun Market.getSpotifyId(): String {
1834+
return if (this == Market.FROM_TOKEN) this.marketName else this.name
1835+
}

src/commonMain/kotlin/com.adamratzman.spotify/utils/Utils.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ internal expect fun formatDate(date: Long): String
1717

1818
internal fun jsonMap(vararg pairs: Pair<String, JsonElement>) = pairs.toMap().toMutableMap()
1919

20-
internal suspend inline fun <T> catch(crossinline function: suspend () -> T): T? {
20+
internal suspend inline fun <T> catch(catchInternalServerError: Boolean = false, crossinline function: suspend () -> T): T? {
2121
return try {
2222
function()
2323
} catch (e: SpotifyException.BadRequestException) {

src/commonTest/kotlin/com.adamratzman/spotify/AbstractTest.kt

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ abstract class AbstractTest<T : GenericSpotifyApi> {
1616

1717
val api = buildSpotifyApi(testClassQualifiedName, testName)
1818
if (api != null && api is Z) {
19+
api.spotifyApiOptions.retryOnInternalServerErrorTimes = 10
1920
api.spotifyApiOptions.httpResponseSubscriber = { request, response ->
2021
getResponseCacher()?.cacheResponse(
2122
testClassQualifiedName,

src/commonTest/kotlin/com.adamratzman/spotify/Common.kt

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import kotlinx.coroutines.test.runTest
1111
import kotlinx.coroutines.withContext
1212
import kotlinx.serialization.Serializable
1313
import kotlin.test.assertTrue
14+
import kotlin.time.Duration.Companion.seconds
1415

1516
expect fun areLivePkceTestsEnabled(): Boolean
1617
expect fun arePlayerTestsEnabled(): Boolean
@@ -41,8 +42,7 @@ suspend inline fun <reified T : Throwable> assertFailsWithSuspend(crossinline bl
4142
}
4243
}
4344

44-
@OptIn(ExperimentalCoroutinesApi::class)
45-
fun <T> runTestOnDefaultDispatcher(block: suspend CoroutineScope.() -> T): TestResult = runTest {
45+
fun <T> runTestOnDefaultDispatcher(block: suspend CoroutineScope.() -> T): TestResult = runTest(timeout = 60.seconds) {
4646
withContext(Dispatchers.Default) {
4747
block()
4848
}

src/commonTest/kotlin/com.adamratzman/spotify/priv/ClientEpisodeApiTest.kt

+2-4
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,8 @@ class ClientEpisodeApiTest : AbstractTest<SpotifyClientApi>() {
3030
buildApi<SpotifyClientApi>(::testGetEpisodes.name)
3131
if (!isApiInitialized()) return@runTestOnDefaultDispatcher
3232

33-
assertFailsWith<BadRequestException> { api.episodes.getEpisodes("hi", "dad") }
34-
assertFailsWith<BadRequestException> {
35-
api.episodes.getEpisodes("1cfOhXP4GQCd5ZFHoSF8gg", "j").map { it?.name }
36-
}
33+
assertEquals(listOf(null, null), api.episodes.getEpisodes("hi", "dad"))
34+
assertEquals(null, api.episodes.getEpisodes("1cfOhXP4GQCd5ZFHoSF8gg", "j")[1])
3735
assertEquals(
3836
listOf("The Great Inflation (Classic)"),
3937
api.episodes.getEpisodes("3lMZTE81Pbrp0U12WZe27l").map { it?.name }

src/commonTest/kotlin/com.adamratzman/spotify/priv/ClientShowApiTest.kt

+3-1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ class ClientShowApiTest : AbstractTest<SpotifyClientApi>() {
2323

2424
assertNull(api.shows.getShow("invalid-show"))
2525
assertEquals("Freakonomics Radio", api.shows.getShow("spotify:show:6z4NLXyHPga1UmSJsPK7G1")?.name)
26+
assertEquals("Freakonomics Radio", api.shows.getShow("spotify:show:6z4NLXyHPga1UmSJsPK7G1", Market.FROM_TOKEN)?.name)
2627
}
2728

2829
@Test
@@ -37,7 +38,8 @@ class ClientShowApiTest : AbstractTest<SpotifyClientApi>() {
3738
assertEquals(listOf("Freakonomics Radio"), api.shows.getShows("6z4NLXyHPga1UmSJsPK7G1").map { it?.name })
3839
}
3940

40-
@Test
41+
//@Test
42+
//todo re-enable. Flaky test disabled due to infrequent spotify 500s
4143
fun testGetShowEpisodes(): TestResult = runTestOnDefaultDispatcher {
4244
buildApi<SpotifyClientApi>(::testGetShowEpisodes.name)
4345
if (!isApiInitialized()) return@runTestOnDefaultDispatcher

0 commit comments

Comments
 (0)