diff --git a/subsonic-api/src/integrationTest/kotlin/org/moire/ultrasonic/api/subsonic/SubsonicApiSearchThreeTest.kt b/subsonic-api/src/integrationTest/kotlin/org/moire/ultrasonic/api/subsonic/SubsonicApiSearchThreeTest.kt new file mode 100644 index 00000000..40ef8b30 --- /dev/null +++ b/subsonic-api/src/integrationTest/kotlin/org/moire/ultrasonic/api/subsonic/SubsonicApiSearchThreeTest.kt @@ -0,0 +1,112 @@ +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.Album +import org.moire.ultrasonic.api.subsonic.models.Artist +import org.moire.ultrasonic.api.subsonic.models.MusicDirectoryChild + +/** + * Integration test for [SubsonicAPIClient] for search3 call. + */ +class SubsonicApiSearchThreeTest : SubsonicAPIClientTest() { + @Test + fun `Should parse error response`() { + checkErrorCallParsed(mockWebServerRule, { + client.api.search3("some-query").execute() + }) + } + + @Test + fun `Should parse ok response`() { + mockWebServerRule.enqueueResponse("search3_ok.json") + + val response = client.api.search3("some-query").execute() + + assertResponseSuccessful(response) + with(response.body().searchResult) { + artistList.size `should equal to` 1 + artistList[0] `should equal` Artist(id = 505, name = "The Prodigy", coverArt = "ar-505", + albumCount = 5) + albumList.size `should equal to` 1 + albumList[0] `should equal` Album(id = 855, name = "Always Outnumbered, Never Outgunned", + artist = "The Prodigy", artistId = 505, coverArt = "al-855", songCount = 12, + duration = 3313, created = parseDate("2016-10-23T20:57:27.000Z"), + year = 2004, genre = "Electronic") + songList.size `should equal to` 1 + songList[0] `should equal` MusicDirectoryChild(id = 5831, parent = 5766, isDir = false, + title = "You'll Be Under My Wheels", album = "Need for Speed Most Wanted", + artist = "The Prodigy", track = 17, year = 2005, genre = "Rap", + coverArt = "5766", size = 5607024, contentType = "audio/mpeg", + suffix = "mp3", duration = 233, bitRate = 192, + path = "Compilations/Need for Speed Most Wanted/17 You'll Be Under My Wheels.mp3", + isVideo = false, playCount = 0, discNumber = 1, + created = parseDate("2016-10-23T20:09:02.000Z"), albumId = 568, + artistId = 505, type = "music") + } + } + + @Test + fun `Should pass query as request param`() { + val query = "some-wip-query" + + mockWebServerRule.assertRequestParam(responseResourceName = "search3_ok.json", apiRequest = { + client.api.search3(query = query).execute() + }, expectedParam = "query=$query") + } + + @Test + fun `Should pass artist count as request param`() { + val artistCount = 67 + + mockWebServerRule.assertRequestParam(responseResourceName = "search3_ok.json", apiRequest = { + client.api.search3("some", artistCount = artistCount).execute() + }, expectedParam = "artistCount=$artistCount") + } + + @Test + fun `Should pass artist offset as request param`() { + val artistOffset = 34 + + mockWebServerRule.assertRequestParam(responseResourceName = "search3_ok.json", apiRequest = { + client.api.search3("some", artistOffset = artistOffset).execute() + }, expectedParam = "artistOffset=$artistOffset") + } + + @Test + fun `Should pass album count as request param`() { + val albumCount = 21 + + mockWebServerRule.assertRequestParam(responseResourceName = "search3_ok.json", apiRequest = { + client.api.search3("some", albumCount = albumCount).execute() + }, expectedParam = "albumCount=$albumCount") + } + + @Test + fun `Should pass album offset as request param`() { + val albumOffset = 43 + + mockWebServerRule.assertRequestParam(responseResourceName = "search3_ok.json", apiRequest = { + client.api.search3("some", albumOffset = albumOffset).execute() + }, expectedParam = "albumOffset=$albumOffset") + } + + @Test + fun `Should pass song count as request param`() { + val songCount = 15 + + mockWebServerRule.assertRequestParam(responseResourceName = "search3_ok.json", apiRequest = { + client.api.search3("some", songCount = songCount).execute() + }, expectedParam = "songCount=$songCount") + } + + @Test + fun `Should pass music folder id as request param`() { + val musicFolderId = 43L + + mockWebServerRule.assertRequestParam(responseResourceName = "search3_ok.json", apiRequest = { + client.api.search3("some", musicFolderId = musicFolderId).execute() + }, expectedParam = "musicFolderId=$musicFolderId") + } +} diff --git a/subsonic-api/src/integrationTest/resources/search3_ok.json b/subsonic-api/src/integrationTest/resources/search3_ok.json new file mode 100644 index 00000000..a9cd9858 --- /dev/null +++ b/subsonic-api/src/integrationTest/resources/search3_ok.json @@ -0,0 +1,51 @@ +{ + "subsonic-response" : { + "status" : "ok", + "version" : "1.15.0", + "searchResult3" : { + "artist" : [ { + "id" : "505", + "name" : "The Prodigy", + "coverArt" : "ar-505", + "albumCount" : 5 + } ], + "album" : [ { + "id" : "855", + "name" : "Always Outnumbered, Never Outgunned", + "artist" : "The Prodigy", + "artistId" : "505", + "coverArt" : "al-855", + "songCount" : 12, + "duration" : 3313, + "created" : "2016-10-23T20:57:27.000Z", + "year" : 2004, + "genre" : "Electronic" + } ], + "song" : [ { + "id" : "5831", + "parent" : "5766", + "isDir" : false, + "title" : "You'll Be Under My Wheels", + "album" : "Need for Speed Most Wanted", + "artist" : "The Prodigy", + "track" : 17, + "year" : 2005, + "genre" : "Rap", + "coverArt" : "5766", + "size" : 5607024, + "contentType" : "audio/mpeg", + "suffix" : "mp3", + "duration" : 233, + "bitRate" : 192, + "path" : "Compilations/Need for Speed Most Wanted/17 You'll Be Under My Wheels.mp3", + "isVideo" : false, + "playCount" : 0, + "discNumber" : 1, + "created" : "2016-10-23T20:09:02.000Z", + "albumId" : "568", + "artistId" : "505", + "type" : "music" + } ] + } + } +} \ 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 7c3d3ad3..e16dbb01 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 @@ -9,6 +9,7 @@ import org.moire.ultrasonic.api.subsonic.response.LicenseResponse import org.moire.ultrasonic.api.subsonic.response.MusicFoldersResponse import org.moire.ultrasonic.api.subsonic.response.SearchTwoResponse import org.moire.ultrasonic.api.subsonic.response.SearchResponse +import org.moire.ultrasonic.api.subsonic.response.SearchThreeResponse import org.moire.ultrasonic.api.subsonic.response.SubsonicResponse import retrofit2.Call import retrofit2.http.GET @@ -73,4 +74,13 @@ interface SubsonicAPIDefinition { @Query("albumOffset") albumOffset: Int? = null, @Query("songCount") songCount: Int? = null, @Query("musicFolderId") musicFolderId: Long? = null): Call + + @GET("search3.view") + fun search3(@Query("query") query: String, + @Query("artistCount") artistCount: Int? = null, + @Query("artistOffset") artistOffset: Int? = null, + @Query("albumCount") albumCount: Int? = null, + @Query("albumOffset") albumOffset: Int? = null, + @Query("songCount") songCount: Int? = null, + @Query("musicFolderId") musicFolderId: Long? = null): Call } diff --git a/subsonic-api/src/main/kotlin/org/moire/ultrasonic/api/subsonic/models/SearchThreeResult.kt b/subsonic-api/src/main/kotlin/org/moire/ultrasonic/api/subsonic/models/SearchThreeResult.kt new file mode 100644 index 00000000..c6c3a626 --- /dev/null +++ b/subsonic-api/src/main/kotlin/org/moire/ultrasonic/api/subsonic/models/SearchThreeResult.kt @@ -0,0 +1,9 @@ +package org.moire.ultrasonic.api.subsonic.models + +import com.fasterxml.jackson.annotation.JsonProperty + +data class SearchThreeResult( + @JsonProperty("artist") val artistList: List = emptyList(), + @JsonProperty("album") val albumList: List = emptyList(), + @JsonProperty("song") val songList: List = emptyList() +) diff --git a/subsonic-api/src/main/kotlin/org/moire/ultrasonic/api/subsonic/response/SearchThreeResponse.kt b/subsonic-api/src/main/kotlin/org/moire/ultrasonic/api/subsonic/response/SearchThreeResponse.kt new file mode 100644 index 00000000..32cd4ae0 --- /dev/null +++ b/subsonic-api/src/main/kotlin/org/moire/ultrasonic/api/subsonic/response/SearchThreeResponse.kt @@ -0,0 +1,13 @@ +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.SearchThreeResult + +class SearchThreeResponse( + status: Status, + version: SubsonicAPIVersions, + error: SubsonicError?, + @JsonProperty("searchResult3") val searchResult: SearchThreeResult = SearchThreeResult()) + : SubsonicResponse(status, version, error)