diff --git a/subsonic-api/src/integrationTest/kotlin/org/moire/ultrasonic/api/subsonic/SubsonicApiGetAvatarTest.kt b/subsonic-api/src/integrationTest/kotlin/org/moire/ultrasonic/api/subsonic/SubsonicApiGetAvatarTest.kt new file mode 100644 index 00000000..deeab4a3 --- /dev/null +++ b/subsonic-api/src/integrationTest/kotlin/org/moire/ultrasonic/api/subsonic/SubsonicApiGetAvatarTest.kt @@ -0,0 +1,65 @@ +package org.moire.ultrasonic.api.subsonic + +import okhttp3.mockwebserver.MockResponse +import org.amshove.kluent.`should be` +import org.amshove.kluent.`should equal to` +import org.amshove.kluent.`should equal` +import org.amshove.kluent.`should not be` +import org.junit.Test + +/** + * Integration test for [SubsonicAPIClient.getAvatar] call. + */ +class SubsonicApiGetAvatarTest : SubsonicAPIClientTest() { + @Test + fun `Should handle api error response`() { + mockWebServerRule.enqueueResponse("generic_error_response.json") + + val response = client.getAvatar("some") + + with(response) { + stream `should be` null + responseHttpCode `should equal to` 200 + apiError `should equal` SubsonicError.GENERIC + } + } + + @Test + fun `Should handle server error`() { + val httpErrorCode = 500 + mockWebServerRule.mockWebServer.enqueue(MockResponse().setResponseCode(httpErrorCode)) + + val response = client.getAvatar("some") + + with(response) { + stream `should equal` null + responseHttpCode `should equal to` httpErrorCode + apiError `should be` null + } + } + + @Test + fun `Should return successful call stream`() { + mockWebServerRule.mockWebServer.enqueue(MockResponse() + .setBody(mockWebServerRule.loadJsonResponse("ping_ok.json"))) + + val response = client.stream("some") + + with(response) { + responseHttpCode `should equal to` 200 + apiError `should be` null + stream `should not be` null + val expectedContent = mockWebServerRule.loadJsonResponse("ping_ok.json") + stream!!.bufferedReader().readText() `should equal to` expectedContent + } + } + + @Test + fun `Should pass username as param`() { + val username = "Guardian" + + mockWebServerRule.assertRequestParam(expectedParam = "username=$username") { + client.api.getAvatar(username).execute() + } + } +} diff --git a/subsonic-api/src/main/kotlin/org/moire/ultrasonic/api/subsonic/SubsonicAPIClient.kt b/subsonic-api/src/main/kotlin/org/moire/ultrasonic/api/subsonic/SubsonicAPIClient.kt index 9a4bc92e..988a165b 100644 --- a/subsonic-api/src/main/kotlin/org/moire/ultrasonic/api/subsonic/SubsonicAPIClient.kt +++ b/subsonic-api/src/main/kotlin/org/moire/ultrasonic/api/subsonic/SubsonicAPIClient.kt @@ -101,6 +101,17 @@ class SubsonicAPIClient(baseUrl: String, api.stream(id, maxBitrate, offset = offset).execute() } + /** + * Convenient method to get user avatar using [username]. + * + * It detects the response `Content-Type` and tries to parse subsonic error if there is one. + * + * Prefer this method over [SubsonicAPIDefinition.getAvatar] as this handles error cases. + */ + fun getAvatar(username: String): StreamResponse = handleStreamResponse { + api.getAvatar(username).execute() + } + private inline fun handleStreamResponse(apiCall: () -> Response): StreamResponse { val response = apiCall() return if (response.isSuccessful) { 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 784562fc..7e086af9 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 @@ -245,4 +245,7 @@ interface SubsonicAPIDefinition { @GET("getVideos.view") fun getVideos(): Call + + @GET("getAvatar.view") + fun getAvatar(@Query("username") username: String): Call }