diff --git a/subsonic-api/src/integrationTest/kotlin/org/moire/ultrasonic/api/subsonic/SubsonicAPITest.kt b/subsonic-api/src/integrationTest/kotlin/org/moire/ultrasonic/api/subsonic/SubsonicAPITest.kt index 264eaffe..ac110997 100644 --- a/subsonic-api/src/integrationTest/kotlin/org/moire/ultrasonic/api/subsonic/SubsonicAPITest.kt +++ b/subsonic-api/src/integrationTest/kotlin/org/moire/ultrasonic/api/subsonic/SubsonicAPITest.kt @@ -9,6 +9,7 @@ import org.junit.Before import org.junit.Rule import org.junit.Test import org.moire.ultrasonic.api.subsonic.models.License +import org.moire.ultrasonic.api.subsonic.models.MusicFolder import org.moire.ultrasonic.api.subsonic.response.SubsonicResponse import org.moire.ultrasonic.api.subsonic.rules.MockWebServerRule import retrofit2.Response @@ -47,8 +48,7 @@ class SubsonicAPITest { assertResponseSuccessful(response) with(response.body()) { - status `should be` SubsonicResponse.Status.OK - version `should be` SubsonicAPIVersions.V1_13_0 + assertBaseResponseOk() } } @@ -65,8 +65,7 @@ class SubsonicAPITest { assertResponseSuccessful(response) with(response.body()) { - status `should be` SubsonicResponse.Status.OK - version `should be` SubsonicAPIVersions.V1_13_0 + assertBaseResponseOk() license `should equal` License(true, parseDate("2016-11-23T20:17:15.206Z")) } } @@ -78,6 +77,26 @@ class SubsonicAPITest { response.license `should be` null } + @Test + fun `Should parse get music folders ok response`() { + enqueueResponse("get_music_directories_ok.json") + + val response = api.getApi().getMusicFolders().execute() + + assertResponseSuccessful(response) + with(response.body()) { + assertBaseResponseOk() + musicFolders `should equal` listOf(MusicFolder(0, "Music"), MusicFolder(2, "Test")) + } + } + + @Test + fun `Should parse get music folders error response`() { + val response = checkErrorCallParsed { api.getApi().getMusicFolders().execute() } + + response.musicFolders `should be` null + } + private fun enqueueResponse(resourceName: String) { mockWebServerRule.mockWebServer.enqueue(MockResponse() .setBody(loadJsonResponse(resourceName))) @@ -113,4 +132,10 @@ class SubsonicAPITest { } return response.body() } + + private fun SubsonicResponse.assertBaseResponseOk() { + status `should be` SubsonicResponse.Status.OK + version `should be` SubsonicAPIVersions.V1_13_0 + error `should be` null + } } \ No newline at end of file diff --git a/subsonic-api/src/integrationTest/resources/get_music_directories_ok.json b/subsonic-api/src/integrationTest/resources/get_music_directories_ok.json index b4f1d547..f3a92efc 100644 --- a/subsonic-api/src/integrationTest/resources/get_music_directories_ok.json +++ b/subsonic-api/src/integrationTest/resources/get_music_directories_ok.json @@ -6,6 +6,9 @@ "musicFolder" : [ { "id" : 0, "name" : "Music" + }, { + "id" : 2, + "name" : "Test" } ] } } 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 3bde6bd1..15559da6 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,6 +1,7 @@ package org.moire.ultrasonic.api.subsonic import org.moire.ultrasonic.api.subsonic.response.LicenseResponse +import org.moire.ultrasonic.api.subsonic.response.MusicFoldersResponse import org.moire.ultrasonic.api.subsonic.response.SubsonicResponse import retrofit2.Call import retrofit2.http.GET @@ -14,4 +15,7 @@ interface SubsonicAPIDefinition { @GET("getLicense.view") fun getLicense(): Call + + @GET("getMusicFolders.view") + fun getMusicFolders(): Call } \ No newline at end of file diff --git a/subsonic-api/src/main/kotlin/org/moire/ultrasonic/api/subsonic/models/MusicFolder.kt b/subsonic-api/src/main/kotlin/org/moire/ultrasonic/api/subsonic/models/MusicFolder.kt new file mode 100644 index 00000000..13484b2c --- /dev/null +++ b/subsonic-api/src/main/kotlin/org/moire/ultrasonic/api/subsonic/models/MusicFolder.kt @@ -0,0 +1,3 @@ +package org.moire.ultrasonic.api.subsonic.models + +data class MusicFolder(val id: Long, val name: String) \ No newline at end of file diff --git a/subsonic-api/src/main/kotlin/org/moire/ultrasonic/api/subsonic/response/MusicFoldersResponse.kt b/subsonic-api/src/main/kotlin/org/moire/ultrasonic/api/subsonic/response/MusicFoldersResponse.kt new file mode 100644 index 00000000..de133a27 --- /dev/null +++ b/subsonic-api/src/main/kotlin/org/moire/ultrasonic/api/subsonic/response/MusicFoldersResponse.kt @@ -0,0 +1,33 @@ +package org.moire.ultrasonic.api.subsonic.response + +import com.fasterxml.jackson.core.JsonParser +import com.fasterxml.jackson.core.JsonToken +import com.fasterxml.jackson.databind.DeserializationContext +import com.fasterxml.jackson.databind.JsonDeserializer +import com.fasterxml.jackson.databind.JsonMappingException +import com.fasterxml.jackson.databind.annotation.JsonDeserialize +import org.moire.ultrasonic.api.subsonic.SubsonicAPIVersions +import org.moire.ultrasonic.api.subsonic.SubsonicError +import org.moire.ultrasonic.api.subsonic.models.MusicFolder + +class MusicFoldersResponse(status: Status, + version: SubsonicAPIVersions, + error: SubsonicError?, + @JsonDeserialize(using = MusicFoldersDeserializer::class) + val musicFolders: List?): + SubsonicResponse(status, version, error) { + companion object { + class MusicFoldersDeserializer(): JsonDeserializer>() { + override fun deserialize(p: JsonParser?, ctxt: DeserializationContext?): List { + p!!.nextToken() + if (p.currentName == "musicFolder" && p.nextToken() == JsonToken.START_ARRAY) { + val mfJavaType = ctxt!!.typeFactory + .constructCollectionType(List::class.java, MusicFolder::class.java) + return ctxt.readValue(p, mfJavaType) + } + + throw JsonMappingException(p, "Failed to parse music folders list") + } + } + } +} \ No newline at end of file