diff --git a/subsonic-api/src/integrationTest/kotlin/org/moire/ultrasonic/api/subsonic/SubsonicApiGetAlbumListRequestTest.kt b/subsonic-api/src/integrationTest/kotlin/org/moire/ultrasonic/api/subsonic/SubsonicApiGetAlbumListRequestTest.kt new file mode 100644 index 00000000..258b3489 --- /dev/null +++ b/subsonic-api/src/integrationTest/kotlin/org/moire/ultrasonic/api/subsonic/SubsonicApiGetAlbumListRequestTest.kt @@ -0,0 +1,109 @@ +package org.moire.ultrasonic.api.subsonic + +import org.amshove.kluent.`should equal to` +import org.amshove.kluent.`should equal` +import org.junit.Test +import org.moire.ultrasonic.api.subsonic.models.AlbumListType +import org.moire.ultrasonic.api.subsonic.models.AlbumListType.BY_GENRE +import org.moire.ultrasonic.api.subsonic.models.MusicDirectoryChild + +/** + * Integration tests for [SubsonicAPIDefinition] for getAlbumList call. + */ +class SubsonicApiGetAlbumListRequestTest : SubsonicAPIClientTest() { + @Test + fun `Should handle error response`() { + val response = checkErrorCallParsed(mockWebServerRule) { + client.api.getAlbumList(BY_GENRE).execute() + } + + response.albumList `should equal` emptyList() + } + + @Test + fun `Should handle ok response`() { + mockWebServerRule.enqueueResponse("get_album_list_ok.json") + + val response = client.api.getAlbumList(BY_GENRE).execute() + + assertResponseSuccessful(response) + with(response.body().albumList) { + size `should equal to` 2 + this[1] `should equal` MusicDirectoryChild(id = 9997, parent = 9996, isDir = true, + title = "Endless Forms Most Beautiful", album = "Endless Forms Most Beautiful", + artist = "Nightwish", year = 2015, genre = "Symphonic Metal", + coverArt = "9997", playCount = 11, + created = parseDate("2017-09-02T16:22:49.000Z")) + } + } + + @Test + fun `Should pass type in request params`() { + val listType = AlbumListType.HIGHEST + + mockWebServerRule.assertRequestParam(responseResourceName = "get_album_list_ok.json", + expectedParam = "type=${listType.typeName}") { + client.api.getAlbumList(type = listType).execute() + } + } + + @Test + fun `Should pass size in request params`() { + val size = 45 + + mockWebServerRule.assertRequestParam(responseResourceName = "get_album_list_ok.json", + expectedParam = "size=$size") { + client.api.getAlbumList(type = BY_GENRE, size = size).execute() + } + } + + @Test + fun `Should pass offset in request params`() { + val offset = 3 + + mockWebServerRule.assertRequestParam(responseResourceName = "get_album_list_ok.json", + expectedParam = "offset=$offset") { + client.api.getAlbumList(type = BY_GENRE, offset = offset).execute() + } + } + + @Test + fun `Should pass from year in request params`() { + val fromYear = 2001 + + mockWebServerRule.assertRequestParam(responseResourceName = "get_album_list_ok.json", + expectedParam = "fromYear=$fromYear") { + client.api.getAlbumList(type = BY_GENRE, fromYear = fromYear).execute() + } + } + + @Test + fun `Should pass to year in request params`() { + val toYear = 2017 + + mockWebServerRule.assertRequestParam(responseResourceName = "get_album_list_ok.json", + expectedParam = "toYear=$toYear") { + client.api.getAlbumList(type = BY_GENRE, toYear = toYear).execute() + } + } + + @Test + fun `Should pass genre in request params`() { + val genre = "Rock" + + mockWebServerRule.assertRequestParam(responseResourceName = "get_album_list_ok.json", + expectedParam = "genre=$genre") { + client.api.getAlbumList(type = BY_GENRE, genre = genre).execute() + } + } + + @Test + fun `Should pass music folder id in request params`() { + val folderId = 545L + + mockWebServerRule.assertRequestParam(responseResourceName = "get_album_list_ok.json", + expectedParam = "musicFolderId=$folderId") { + client.api.getAlbumList(type = BY_GENRE, musicFolderId = folderId).execute() + } + } +} diff --git a/subsonic-api/src/integrationTest/resources/get_album_list_ok.json b/subsonic-api/src/integrationTest/resources/get_album_list_ok.json new file mode 100644 index 00000000..9de7d2e1 --- /dev/null +++ b/subsonic-api/src/integrationTest/resources/get_album_list_ok.json @@ -0,0 +1,33 @@ +{ + "subsonic-response" : { + "status" : "ok", + "version" : "1.15.0", + "albumList" : { + "album" : [ { + "id" : "10020", + "parent" : "490", + "isDir" : true, + "title" : "Fury", + "album" : "Fury", + "artist" : "Sick Puppies", + "year" : 2016, + "genre" : "Alternative Rock", + "coverArt" : "10020", + "playCount" : 13, + "created" : "2017-09-02T17:34:51.000Z" + }, { + "id" : "9997", + "parent" : "9996", + "isDir" : true, + "title" : "Endless Forms Most Beautiful", + "album" : "Endless Forms Most Beautiful", + "artist" : "Nightwish", + "year" : 2015, + "genre" : "Symphonic Metal", + "coverArt" : "9997", + "playCount" : 11, + "created" : "2017-09-02T16:22:49.000Z" + } ] + } + } +} \ No newline at end of file diff --git a/subsonic-api/src/main/kotlin/org/moire/ultrasonic/api/subsonic/SubsonicAPIDefinition.kt b/subsonic-api/src/main/kotlin/org/moire/ultrasonic/api/subsonic/SubsonicAPIDefinition.kt index ad396526..4bc2b692 100644 --- a/subsonic-api/src/main/kotlin/org/moire/ultrasonic/api/subsonic/SubsonicAPIDefinition.kt +++ b/subsonic-api/src/main/kotlin/org/moire/ultrasonic/api/subsonic/SubsonicAPIDefinition.kt @@ -1,5 +1,7 @@ package org.moire.ultrasonic.api.subsonic +import org.moire.ultrasonic.api.subsonic.models.AlbumListType +import org.moire.ultrasonic.api.subsonic.response.GetAlbumListResponse import org.moire.ultrasonic.api.subsonic.response.GetAlbumResponse import org.moire.ultrasonic.api.subsonic.response.GetArtistResponse import org.moire.ultrasonic.api.subsonic.response.GetArtistsResponse @@ -123,4 +125,13 @@ interface SubsonicAPIDefinition { fun scrobble(@Query("id") id: String, @Query("time") time: Long? = null, @Query("submission") submission: Boolean? = null): Call + + @GET("getAlbumList.view") + fun getAlbumList(@Query("type") type: AlbumListType, + @Query("size") size: Int? = null, + @Query("offset") offset: Int? = null, + @Query("fromYear") fromYear: Int? = null, + @Query("toYear") toYear: Int? = null, + @Query("genre") genre: String? = null, + @Query("musicFolderId") musicFolderId: Long? = null): Call } diff --git a/subsonic-api/src/main/kotlin/org/moire/ultrasonic/api/subsonic/models/AlbumListType.kt b/subsonic-api/src/main/kotlin/org/moire/ultrasonic/api/subsonic/models/AlbumListType.kt new file mode 100644 index 00000000..bd29f3e8 --- /dev/null +++ b/subsonic-api/src/main/kotlin/org/moire/ultrasonic/api/subsonic/models/AlbumListType.kt @@ -0,0 +1,24 @@ +package org.moire.ultrasonic.api.subsonic.models + +/** + * Type of album list used in [org.moire.ultrasonic.api.subsonic.SubsonicAPIDefinition.getAlbumList] + * calls. + * + * @author Yahor Berdnikau + */ +enum class AlbumListType(val typeName: String) { + RANDOM("random"), + NEWEST("newest"), + HIGHEST("highest"), + FREQUENT("frequent"), + RECENT("recent"), + SORTED_BY_NAME("alphabeticalByName"), + SORTED_BY_ARTIST("alphabeticalByArtist"), + STARRED("starred"), + BY_YEAR("byYear"), + BY_GENRE("byGenre"); + + override fun toString(): String { + return super.toString().toLowerCase() + } +} diff --git a/subsonic-api/src/main/kotlin/org/moire/ultrasonic/api/subsonic/response/GetAlbumListResponse.kt b/subsonic-api/src/main/kotlin/org/moire/ultrasonic/api/subsonic/response/GetAlbumListResponse.kt new file mode 100644 index 00000000..44e1cccf --- /dev/null +++ b/subsonic-api/src/main/kotlin/org/moire/ultrasonic/api/subsonic/response/GetAlbumListResponse.kt @@ -0,0 +1,19 @@ +package org.moire.ultrasonic.api.subsonic.response + +import com.fasterxml.jackson.annotation.JsonProperty +import org.moire.ultrasonic.api.subsonic.SubsonicAPIVersions +import org.moire.ultrasonic.api.subsonic.SubsonicError +import org.moire.ultrasonic.api.subsonic.models.MusicDirectoryChild + +class GetAlbumListResponse(status: Status, + version: SubsonicAPIVersions, + error: SubsonicError?) + : SubsonicResponse(status, version, error) { + @JsonProperty("albumList") private val albumWrapper = AlbumWrapper() + + val albumList: List + get() = albumWrapper.albumList +} + +private class AlbumWrapper( + @JsonProperty("album") val albumList: List = emptyList())