Skip to content

Commit 3c2091b

Browse files
committed
add builder, some following tests
1 parent 923ac68 commit 3c2091b

File tree

14 files changed

+160
-21
lines changed

14 files changed

+160
-21
lines changed

.idea/libraries/Gradle__org_jetbrains_kotlin_kotlin_stdlib_common_1_3_0.xml

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/libraries/Gradle__org_spekframework_spek2_spek_runtime_common_2_0_0_alpha_1.xml

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/main/kotlin/com/adamratzman/spotify/endpoints/client/ClientFollowingAPI.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ class ClientFollowingAPI(api: SpotifyAPI) : FollowingAPI(api) {
7777
})
7878
}
7979

80-
fun getFollowedUsers(): SpotifyRestAction<SpotifyPublicUser> = throw NotImplementedError("Though Spotify will implement this in the future, it is not currently supported.")
80+
fun getFollowedUsers(): SpotifyRestAction<List<SpotifyPublicUser>> = throw NotImplementedError("Though Spotify will implement this in the future, it is not currently supported.")
8181

8282
/**
8383
* Add the current user as a follower of another user

src/main/kotlin/com/adamratzman/spotify/endpoints/client/PlayerAPI.kt renamed to src/main/kotlin/com/adamratzman/spotify/endpoints/client/ClientPlayerAPI.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import java.util.function.Supplier
1010
* These endpoints allow for viewing and controlling user playback. Please view [the official documentation](https://developer.spotify.com/web-api/working-with-connect/)
1111
* for more information on how this works. This is in beta and is available for **premium users only**. Endpoints are **not** guaranteed to work
1212
*/
13-
class PlayerAPI(api: SpotifyAPI) : SpotifyEndpoint(api) {
13+
class ClientPlayerAPI(api: SpotifyAPI) : SpotifyEndpoint(api) {
1414
fun getDevices(): SpotifyRestAction<List<Device>> {
1515
return toAction(Supplier {
1616
get(EndpointBuilder("/me/player/devices").toString()).toInnerObject<Device>("devices", api)

src/main/kotlin/com/adamratzman/spotify/main/SpotifyAPI.kt

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -70,12 +70,12 @@ class SpotifyApiBuilderJava(val clientId: String, val clientSecret: String) {
7070
* @property redirectUri nullable redirect uri (use if you're doing client authentication
7171
*/
7272
class SpotifyCredentialsBuilder {
73-
var clientId: String = ""
74-
var clientSecret: String = ""
73+
var clientId: String?=null
74+
var clientSecret: String?=null
7575
var redirectUri: String? = null
7676

7777
fun build() =
78-
if (clientId.isEmpty() || clientSecret.isEmpty()) throw IllegalArgumentException("clientId or clientSecret is empty")
78+
if (clientId?.isNotEmpty() == false || clientSecret?.isNotEmpty() == false) throw IllegalArgumentException("clientId or clientSecret is empty")
7979
else SpotifyCredentials(clientId, clientSecret, redirectUri)
8080
}
8181

@@ -121,8 +121,6 @@ class SpotifyApiBuilder {
121121
}
122122
}
123123

124-
// TODO look into whether Client should be renamed to User
125-
126124
fun buildClient(automaticRefresh: Boolean = false): SpotifyClientAPI =
127125
buildClient(clientAuthentication.authorizationCode, clientAuthentication.tokenString,
128126
clientAuthentication.token, automaticRefresh)
@@ -218,15 +216,14 @@ class SpotifyClientAPI internal constructor(clientId: String, clientSecret: Stri
218216
override val tracks: TracksAPI = TracksAPI(this)
219217
override val following: ClientFollowingAPI = ClientFollowingAPI(this)
220218
val personalization: ClientPersonalizationAPI = ClientPersonalizationAPI(this)
221-
val clientProfile: ClientUserAPI = ClientUserAPI(this)
222219
val library: ClientLibraryAPI = ClientLibraryAPI(this)
223-
val player: PlayerAPI = PlayerAPI(this)
220+
val player: ClientPlayerAPI = ClientPlayerAPI(this)
224221

225222
val userId: String
226223

227224
init {
228225
init(automaticRefresh)
229-
userId = clientProfile.getUserProfile().complete().id
226+
userId = users.getUserProfile().complete().id
230227
}
231228

232229
private fun init(automaticRefresh: Boolean) {

src/main/kotlin/com/adamratzman/spotify/utils/Endpoints.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ abstract class SpotifyEndpoint(val api: SpotifyAPI) {
5353
fun <T> toAction(supplier: Supplier<T>) = SpotifyRestAction(api, supplier)
5454
}
5555

56-
internal class EndpointBuilder(val path: String) {
56+
internal class EndpointBuilder(private val path: String) {
5757
private val builder = StringBuilder(base + path)
5858

5959
fun with(key: String, value: Any?): EndpointBuilder {

src/main/kotlin/com/adamratzman/spotify/utils/Helpers.kt

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
@file:Suppress("UNCHECKED_CAST")
2+
13
package com.adamratzman.spotify.utils
24

35
import com.adamratzman.spotify.main.SpotifyAPI
@@ -17,11 +19,29 @@ data class CursorBasedPagingObject<out T>(val href: String, val items: List<T>,
1719
next?.let { endpoint.get(it).toCursorBasedPagingObject<T>(endpoint = endpoint) }
1820
}
1921
})
22+
23+
inline fun <reified T> getAll(): SpotifyRestAction<List<CursorBasedPagingObject<T>>> {
24+
return endpoint.toAction(Supplier {
25+
this as CursorBasedPagingObject<T>
26+
val pagingObjects = mutableListOf<CursorBasedPagingObject<T>>(this)
27+
var next = getNext<T>().complete()
28+
while (next != null) {
29+
pagingObjects.add(next)
30+
next = getNext<T>().complete()
31+
}
32+
pagingObjects.toList()
33+
})
34+
}
35+
36+
inline fun <reified T> getAllItems(): SpotifyRestAction<List<T>> {
37+
return endpoint.toAction(Supplier {
38+
getAll<T>().complete().map { it.items }.flatten()
39+
})
40+
}
2041
}
2142

2243
data class Cursor(val after: String)
2344

24-
@Suppress("UNCHECKED_CAST")
2545
data class PagingObject<out T>(val href: String, val items: List<T>, val limit: Int, val next: String? = null, val offset: Int = 0,
2646
val previous: String? = null, val total: Int, var endpoint: SpotifyEndpoint) {
2747
inline fun <reified T> getNext(): SpotifyRestAction<PagingObject<T>?> = endpoint.toAction(
@@ -61,6 +81,12 @@ data class PagingObject<out T>(val href: String, val items: List<T>, val limit:
6181
pagingObjects.map { it.items }.flatten()
6282
})
6383
}
84+
85+
inline fun <reified T> getAllItems(): SpotifyRestAction<List<T>> {
86+
return endpoint.toAction(Supplier {
87+
getAll<T>().complete().asSequence().map { it as PagingObject<T> }.map { it.items }.toList().flatten()
88+
})
89+
}
6490
}
6591

6692
data class LinkedResult<out T>(val href: String, val items: List<T>) {

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ val api = when {
1919
redirectUri = System.getProperty("spotifyRedirectUri")
2020
}
2121
clientAuthentication {
22-
authorizationCode = System.getProperty("spotifyAuthCode")
22+
tokenString = System.getProperty("spotifyTokenString")
2323
}
2424
}.buildClient()
2525
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package com.adamratzman.spotify.private
2+
3+
import com.adamratzman.spotify.api
4+
import com.adamratzman.spotify.main.SpotifyClientAPI
5+
import com.adamratzman.spotify.utils.Artist
6+
import com.adamratzman.spotify.utils.BadRequestException
7+
import org.junit.jupiter.api.Assertions.*
8+
import org.junit.jupiter.api.assertThrows
9+
import org.spekframework.spek2.Spek
10+
import org.spekframework.spek2.style.specification.describe
11+
12+
class ClientFollowingAPITest : Spek({
13+
describe("Client following tests") {
14+
if (api !is SpotifyClientAPI) return@describe
15+
it("following/unfollowing artists") {
16+
val testArtistId = "7eCmccnRwPmRnWPw61x6jM"
17+
18+
if (api.following.isFollowingArtist(testArtistId).complete()) {
19+
api.following.unfollowArtist(testArtistId).complete()
20+
}
21+
22+
assert(!api.following.isFollowingArtist(testArtistId).complete())
23+
24+
val beforeFollowing = api.following.getFollowedArtists().complete().getAllItems<Artist>().complete()
25+
26+
assertNull(beforeFollowing.find { it.id == testArtistId })
27+
28+
api.following.followArtist(testArtistId).complete()
29+
30+
assert(api.following.isFollowingArtist(testArtistId).complete())
31+
32+
assertEquals(1, api.following.getFollowedArtists().complete().getAllItems<Artist>().complete().size - beforeFollowing.size)
33+
34+
api.following.unfollowArtist(testArtistId).complete()
35+
36+
assert(beforeFollowing.size == api.following.getFollowedArtists().complete().getAllItems<Artist>().complete().size)
37+
38+
assert(!api.following.isFollowingArtist(testArtistId).complete())
39+
40+
assertThrows<BadRequestException> { api.following.isFollowingArtist("no u").complete() }
41+
assertThrows<BadRequestException> { api.following.followArtist("no u").complete() }
42+
assertThrows<BadRequestException> { api.following.followArtists(testArtistId,"no u").complete() }
43+
assertThrows<BadRequestException> { api.following.unfollowArtist("no u").complete() }
44+
}
45+
}
46+
})
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package com.adamratzman.spotify.private
2+
3+
import org.spekframework.spek2.Spek
4+
5+
class ClientLibraryAPITest: Spek({
6+
7+
})

0 commit comments

Comments
 (0)