Skip to content

Commit b780494

Browse files
committed
make PagingObject inherit from List<T>, not List<T?>
Signed-off-by: Adam Ratzman <[email protected]>
1 parent 6181884 commit b780494

File tree

4 files changed

+102
-12
lines changed

4 files changed

+102
-12
lines changed

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

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -199,23 +199,24 @@ public class ClientPlayerApi(api: GenericSpotifyApi) : SpotifyEndpoint(api) {
199199
/**
200200
* Start or resume playback.
201201
*
202-
* **Note:** You can only use one of the following: [offsetNum] or [offsetPlayableUri]
202+
* **Note:** You can only use one of the following: [offsetNum], [offsetPlayableUri], or [collectionUri]
203203
*
204204
* **Specify nothing to play to simply resume playback**
205205
*
206206
* **Requires** the [SpotifyScope.USER_MODIFY_PLAYBACK_STATE] scope
207207
*
208208
* **[Api Reference](https://developer.spotify.com/documentation/web-api/reference/player/start-a-users-playback/)**
209209
*
210+
* @param collectionUri Start playing an album, artist, or playlist
210211
* @param playableUrisToPlay [PlayableUri] (Track or Local track URIs) uris to play. these are converted into URIs. Max 100
211212
* @param offsetNum Indicates from where in the context playback should start. Only available when [playableUrisToPlay] is used.
212-
* @param offsetPlayableUri Does the same as [offsetNum] but with a track/local track uri instead of place number
213+
* @param offsetPlayableUri Start playing at a track/local track uri instead of place number ([offsetNum])
213214
* @param deviceId The device to play on
214215
*
215216
* @throws BadRequestException if more than one type of play type is specified or the offset is illegal.
216217
*/
217218
public suspend fun startPlayback(
218-
collection: CollectionUri? = null,
219+
collectionUri: CollectionUri? = null,
219220
offsetNum: Int? = null,
220221
offsetPlayableUri: PlayableUri? = null,
221222
deviceId: String? = null,
@@ -224,7 +225,7 @@ public class ClientPlayerApi(api: GenericSpotifyApi) : SpotifyEndpoint(api) {
224225
val url = endpointBuilder("/me/player/play").with("device_id", deviceId).toString()
225226
val body = jsonMap()
226227
when {
227-
collection != null -> body += buildJsonObject { put("context_uri", collection.uri) }
228+
collectionUri != null -> body += buildJsonObject { put("context_uri", collectionUri.uri) }
228229
playableUrisToPlay.isNotEmpty() -> body += buildJsonObject {
229230
put(
230231
"uris", JsonArray(

src/commonMain/kotlin/com.adamratzman.spotify/models/PagingObjects.kt

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,6 @@ public class NullablePagingObject<T : Any>(
6565
override val previous: String? = null,
6666
override val total: Int = 0
6767
) : AbstractPagingObject<T, NullablePagingObject<T>>() {
68-
override fun get(index: Int): T? = items[index]
69-
7068
public fun toPagingObject(): PagingObject<T> {
7169
val pagingObject = PagingObject(
7270
href, items.filterNotNull(), limit, next, offset, previous, total
@@ -75,6 +73,12 @@ public class NullablePagingObject<T : Any>(
7573

7674
return pagingObject
7775
}
76+
77+
override fun get(index: Int): T? = items[index]
78+
override fun iterator(): Iterator<T?> = items.iterator()
79+
override fun listIterator(): ListIterator<T?> = items.listIterator()
80+
override fun listIterator(index: Int): ListIterator<T?> = items.listIterator(index)
81+
override fun subList(fromIndex: Int, toIndex: Int): List<T?> = items.subList(fromIndex, toIndex)
7882
}
7983

8084
/**
@@ -93,6 +97,11 @@ public data class PagingObject<T : Any>(
9397
override val total: Int = 0
9498
) : AbstractPagingObject<T, PagingObject<T>>() {
9599
override fun get(index: Int): T = items[index]
100+
101+
override fun iterator(): Iterator<T> = items.iterator()
102+
override fun listIterator(): ListIterator<T> = items.listIterator()
103+
override fun listIterator(index: Int): ListIterator<T> = items.listIterator(index)
104+
override fun subList(fromIndex: Int, toIndex: Int): List<T> = items.subList(fromIndex, toIndex)
96105
}
97106

98107
/**
@@ -257,8 +266,6 @@ public data class CursorBasedPagingObject<T : Any>(
257266
override val offset: Int = 0,
258267
override val previous: String? = null
259268
) : PagingObjectBase<T, CursorBasedPagingObject<T>>() {
260-
override fun get(index: Int): T = items[index]
261-
262269
/**
263270
* Synchronously retrieve the next [total] paging objects associated with this [CursorBasedPagingObject], including this [CursorBasedPagingObject].
264271
*
@@ -324,6 +331,12 @@ public data class CursorBasedPagingObject<T : Any>(
324331

325332
return pagingObjects.distinctBy { it.href }
326333
}
334+
335+
override fun get(index: Int): T = items[index]
336+
override fun iterator(): Iterator<T> = items.iterator()
337+
override fun listIterator(): ListIterator<T> = items.listIterator()
338+
override fun listIterator(index: Int): ListIterator<T> = items.listIterator(index)
339+
override fun subList(fromIndex: Int, toIndex: Int): List<T> = items.subList(fromIndex, toIndex)
327340
}
328341

329342
/**
@@ -491,11 +504,7 @@ public abstract class PagingObjectBase<T : Any, Z : PagingObjectBase<T, Z>> : Li
491504
override fun containsAll(elements: Collection<T?>): Boolean = items.containsAll(elements)
492505
override fun indexOf(element: T?): Int = items.indexOf(element)
493506
override fun isEmpty(): Boolean = items.isEmpty()
494-
override fun iterator(): Iterator<T?> = items.iterator()
495507
override fun lastIndexOf(element: T?): Int = items.lastIndexOf(element)
496-
override fun listIterator(): ListIterator<T?> = items.listIterator()
497-
override fun listIterator(index: Int): ListIterator<T?> = items.listIterator(index)
498-
override fun subList(fromIndex: Int, toIndex: Int): List<T?> = items.subList(fromIndex, toIndex)
499508
}
500509

501510
internal fun Any.instantiateLateinitsIfPagingObjects(api: GenericSpotifyApi) = when (this) {
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package com.adamratzman.spotify.priv
2+
3+
import com.adamratzman.spotify.SpotifyClientApi
4+
import com.adamratzman.spotify.buildSpotifyApi
5+
import com.adamratzman.spotify.models.SpotifyTrackUri
6+
import com.adamratzman.spotify.models.Track
7+
import com.adamratzman.spotify.runBlockingTest
8+
import kotlin.test.Test
9+
import kotlin.test.assertTrue
10+
11+
class ClientPlayerApiTest {
12+
lateinit var api: SpotifyClientApi
13+
14+
init {
15+
runBlockingTest {
16+
(buildSpotifyApi() as? SpotifyClientApi)?.let { api = it }
17+
}
18+
}
19+
20+
fun testPrereq() = ::api.isInitialized
21+
22+
@Test
23+
fun testGetDevices() {
24+
runBlockingTest {
25+
if (!testPrereq()) return@runBlockingTest
26+
27+
assertTrue(api.player.getDevices().isNotEmpty())
28+
}
29+
}
30+
31+
@Test
32+
fun testGetCurrentContext() {
33+
runBlockingTest {
34+
if (!testPrereq()) return@runBlockingTest
35+
val device = api.player.getDevices().first()
36+
api.player.startPlayback(
37+
playableUrisToPlay = listOf(SpotifyTrackUri("spotify:track:6WcinC5nKan2DMFUfjVerX")),
38+
deviceId = device.id
39+
)
40+
val getCurrentContext = suspend { api.player.getCurrentContext() }
41+
var context = getCurrentContext()
42+
assertTrue(context != null && context.isPlaying && context.track?.id == "6WcinC5nKan2DMFUfjVerX")
43+
api.player.pause()
44+
context = getCurrentContext()!!
45+
46+
assertTrue(!context.isPlaying && context.track?.id != null)
47+
48+
val playlist = api.playlists.getPlaylist("37i9dQZF1DXcBWIGoYBM5M")!!
49+
api.player.startPlayback(
50+
collectionUri = playlist.uri
51+
)
52+
context = getCurrentContext()
53+
assertTrue(context != null && context.isPlaying && context.track?.id == playlist.tracks.items.first().track!!.id)
54+
api.player.pause()
55+
56+
57+
}
58+
}
59+
60+
@Test
61+
fun testGetRecentlyPlayed() {
62+
runBlockingTest {
63+
if (!testPrereq()) return@runBlockingTest
64+
val device = api.player.getDevices().first()
65+
api.player.getRecentlyPlayed()
66+
}
67+
}
68+
69+
70+
}

src/commonTest/kotlin/com.adamratzman/spotify/utilities/UtilityTests.kt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import com.adamratzman.spotify.runBlockingTest
1212
import com.adamratzman.spotify.spotifyAppApi
1313
import com.adamratzman.spotify.spotifyClientApi
1414
import kotlin.test.Test
15+
import kotlin.test.assertEquals
1516
import kotlin.test.assertTrue
1617

1718
class UtilityTests {
@@ -26,6 +27,15 @@ class UtilityTests {
2627
fun testPrereq() = ::api.isInitialized
2728

2829
@Test
30+
fun testPagingObjectTakeItemsSize() {
31+
runBlockingTest {
32+
if (!testPrereq()) return@runBlockingTest
33+
34+
assertEquals(60, api.browse.getNewReleases(limit = 12).take(60).size)
35+
}
36+
}
37+
38+
@Test
2939
fun testInvalidApiBuilderParameters() {
3040
runBlockingTest {
3141
if (!testPrereq()) return@runBlockingTest

0 commit comments

Comments
 (0)