diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..86b5d0a --- /dev/null +++ b/.gitignore @@ -0,0 +1,40 @@ +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +.idea/discord.xml +.idea/encodings.xml +*.iws +*.iml +*.ipr + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store \ No newline at end of file diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/kotlinc.xml b/.idea/kotlinc.xml new file mode 100644 index 0000000..8d81632 --- /dev/null +++ b/.idea/kotlinc.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..82dbec8 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,14 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..cb50b35 --- /dev/null +++ b/README.md @@ -0,0 +1,125 @@ + +

+ + OMDb API Icon + +

+ +

OMDbAPI.com Client for Kotlin

+ +## Installation + +To begin, import the library using jitpack.io. + +You can include jitpack in your `pom.xml` by adding the following jitpack repository: + +```xml + + jitpack.io + https://www.jitpack.io + +``` + +Then add this `omdb-kotlin` dependency to your `pom.xml` project! + +```xml + + com.github.official-wizard + omdb-kotlin + 1.0.0 + +``` + +## Usage + +### Basic Usage + +```kotlin +val credentials = Credentials("") +val api: OmdbInterface = OmdbClient(credentials).api + +// access the api interface in `api` +``` + +#### Search + +
+Search Title (or imdb ID) +
+ +> A call to this function will retrieve a single result for the provided title or Imdb ID + +**Available Parameters** + +> NOTE: Although `Title` and `ImdbId` are optional, at least 1 of them is required! + +| Name | Type | Description | Example | OPTIONAL | +|:--------------|:----------|:-------------------------------------------------------------------|:----------------|----------| +| title | String | The name of the film you'd like to search for. | Demons | yes | +| imdbId | String | The imdb ID for the film you'd like to search for. | tt0089013 | yes | +| type | QueryType | The type of film you'd like to search for (Movie, Series, Episode) | QueryType.movie | yes | +| yearOfRelease | String | The year the film was released | 1985 | yes | +| plot | Plot | Short or full plot. | Plot.short | yes | + +**Example** +```kotlin +val credentials = Credentials("") +val api: OmdbInterface = OmdbClient(credentials).api + +val response: NetworkResponse = api.searchTitle( + title = "Demons" +) + +if (response is NetworkResponse.Success) { + // handle the data + val searchResult: Search.Response = response.body + +} else if (response is NetworkResponse.Error) { + // if the server returns an error it be found here + val errorResponse: Error.Response? = response.body + + // if the api (locally) had an internal error, it'll be found here + val internalError: Throwable? = response.error +} +``` + +
+ +
+Search List +
+ +> A call to this function will retrieve a list of results for the provided title + +**Available Parameters** + +| Name | Type | Description | Example | OPTIONAL | +|:--------------|:----------|:-------------------------------------------------------------------|:----------------|----------| +| title | String | The name of the film you'd like to search for. | Demons | no | +| type | QueryType | The type of film you'd like to search for (Movie, Series, Episode) | QueryType.movie | yes | +| yearOfRelease | String | The year the film was released | 1985 | yes | +| page | Int | The page number to search through. | Plot.short | yes | + +**Example** +```kotlin +val credentials = Credentials("") +val api: OmdbInterface = OmdbClient(credentials).api + +val response: NetworkResponse = api.searchList( + title = "Demons" +) + +if (response is NetworkResponse.Success) { + // handle the data + val searchResult: SearchList.Response = response.body + +} else if (response is NetworkResponse.Error) { + // if the server returns an error it be found here + val errorResponse: Error.Response? = response.body + + // if the api (locally) had an internal error, it'll be found here + val internalError: Throwable? = response.error +} +``` + +
diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..a6a658f --- /dev/null +++ b/pom.xml @@ -0,0 +1,137 @@ + + + 4.0.0 + + com.omdbapi + omdb-kotlin + 1.0.0 + + + + + org.junit + junit-bom + 5.10.2 + pom + import + + + + + + UTF-8 + official + 1.8 + + + + + jitpack.io + https://jitpack.io + + + + mavenCentral + https://repo1.maven.org/maven2/ + + + + + src/main/kotlin + src/test/kotlin + + + org.jetbrains.kotlin + kotlin-maven-plugin + 1.9.22 + + + compile + compile + + compile + + + + test-compile + test-compile + + test-compile + + + + + + maven-surefire-plugin + 2.22.2 + + + maven-failsafe-plugin + 2.22.2 + + + org.codehaus.mojo + exec-maven-plugin + 1.6.0 + + MainKt + + + + + + + + org.jetbrains.kotlin + kotlin-test-junit5 + 1.9.22 + test + + + + org.junit.jupiter + junit-jupiter-engine + test + + + + org.jetbrains.kotlin + kotlin-stdlib + 1.9.22 + + + + + com.squareup.okhttp3 + logging-interceptor + 4.12.0 + + + + com.github.haroldadmin + NetworkResponseAdapter + 5.0.0 + + + + com.squareup.retrofit2 + retrofit + 2.9.0 + + + + com.squareup.retrofit2 + converter-gson + 2.11.0 + + + + co.infinum + retromock + 1.1.1 + + + + \ No newline at end of file diff --git a/src/main/kotlin/com/omdbapi/api/OMDbClient.kt b/src/main/kotlin/com/omdbapi/api/OMDbClient.kt new file mode 100644 index 0000000..cfd8e58 --- /dev/null +++ b/src/main/kotlin/com/omdbapi/api/OMDbClient.kt @@ -0,0 +1,11 @@ +package com.omdbapi.api + +import com.omdbapi.api.core.Credentials +import com.omdbapi.api.core.CoreClient + +class OMDbClient(credentials: Credentials, debugging: Boolean = false) + : CoreClient(credentials, "https://www.omdbapi.com/", debugging) { + + // the API interface for the client + val api: OMDbInterface = omdbClient.create(OMDbInterface::class.java) +} diff --git a/src/main/kotlin/com/omdbapi/api/OMDbInterface.kt b/src/main/kotlin/com/omdbapi/api/OMDbInterface.kt new file mode 100644 index 0000000..110cec3 --- /dev/null +++ b/src/main/kotlin/com/omdbapi/api/OMDbInterface.kt @@ -0,0 +1,45 @@ +package com.omdbapi.api + +import co.infinum.retromock.meta.Mock +import co.infinum.retromock.meta.MockResponse +import com.haroldadmin.cnradapter.NetworkResponse +import com.omdbapi.api.data.Plot +import com.omdbapi.api.data.QueryType +import com.omdbapi.api.data.pojo.Error +import com.omdbapi.api.data.pojo.Search +import com.omdbapi.api.data.pojo.SearchList +import retrofit2.http.GET +import retrofit2.http.Query + +interface OMDbInterface { + + /** + * This [searchList] function will search OMDB for a list of movies by the provided [title] and query options + */ + @Mock @MockResponse(body = "/v1/search/SearchList.json") + @GET("/") + suspend fun searchList( + @Query("s") title: String, + @Query("type") type: QueryType? = null, + @Query("y") yearOfRelease: Int? = null, + @Query("page") page: Int = 1, + @Query("callback") callback: String? = null, + @Query("v") apiVersion: Int = 1 + ): NetworkResponse + + /** + * This [searchTitle] function will search OMDB for the specified [title] or [imdbId] + * although both parameters are marked as nullable/optional, at least one of the option is required! + */ + @Mock @MockResponse(body = "/v1/search/SearchTitle.json") + @GET("/") + suspend fun searchTitle( + @Query("t") title: String? = null, + @Query("i") imdbId: String? = null, + @Query("type") type: QueryType? = null, + @Query("y") yearOfRelease: Int? = null, + @Query("plot") plot: Plot? = null, + @Query("callback") callback: String? = null, + @Query("v") apiVersion: Int = 1 + ): NetworkResponse +} \ No newline at end of file diff --git a/src/main/kotlin/com/omdbapi/api/core/AuthenticatorInterceptor.kt b/src/main/kotlin/com/omdbapi/api/core/AuthenticatorInterceptor.kt new file mode 100644 index 0000000..157f50d --- /dev/null +++ b/src/main/kotlin/com/omdbapi/api/core/AuthenticatorInterceptor.kt @@ -0,0 +1,48 @@ +package com.omdbapi.api.core + +import com.omdbapi.api.core.Credentials +import okhttp3.HttpUrl +import okhttp3.HttpUrl.Companion.toHttpUrlOrNull +import okhttp3.Interceptor +import okhttp3.Request +import okhttp3.Response + +/** + * This [Interceptor] takes care of the authentication process between requests + */ +class AuthenticatorInterceptor(private val credentials: Credentials): Interceptor { + + override fun intercept(chain: Interceptor.Chain): Response { + val request = chain.request() + + return chain.proceed(createAuthenticatedRequest( + request = request, + authenticatedUrl = createAuthenticatedUrl(request) + )) + } + + /** + * Creates a new [Request] from the original [request] using the [authenticatedUrl] provided + */ + private fun createAuthenticatedRequest(request: Request, authenticatedUrl: HttpUrl): Request { + val authenticatedRequest = request.newBuilder() + .url(authenticatedUrl) + .build() + + return authenticatedRequest + } + + /** + * Creates a new [HttpUrl] with [credentials] appended to the query + * + * OMDbApi.com uses query parameters for the authentication process + */ + private fun createAuthenticatedUrl(request: Request): HttpUrl { + val parsed = request.url.toString().toHttpUrlOrNull() + ?: throw IllegalArgumentException("Invalid URL: ${request.url}") + + return parsed.newBuilder() + .addQueryParameter("apikey", credentials.apiKey) + .build() + } +} diff --git a/src/main/kotlin/com/omdbapi/api/core/CoreClient.kt b/src/main/kotlin/com/omdbapi/api/core/CoreClient.kt new file mode 100644 index 0000000..222c7c2 --- /dev/null +++ b/src/main/kotlin/com/omdbapi/api/core/CoreClient.kt @@ -0,0 +1,37 @@ +package com.omdbapi.api.core + +import com.google.gson.GsonBuilder +import com.haroldadmin.cnradapter.NetworkResponseAdapterFactory +import com.omdbapi.api.core.Credentials +import com.omdbapi.api.core.ResponseTypeInterceptor +import okhttp3.OkHttpClient +import okhttp3.logging.HttpLoggingInterceptor +import retrofit2.Retrofit +import retrofit2.converter.gson.GsonConverterFactory + +open class CoreClient(credentials: Credentials, baseUrl: String, debugging: Boolean = false) { + + // custom [OkHttpClient] client to add an authentication interceptor + var httpClient: OkHttpClient = OkHttpClient.Builder().apply { + + // append query parameter to add the API Key to our requests + addInterceptor(AuthenticatorInterceptor(credentials)) + + // append query parameter to make responses come back as JSON + addInterceptor(ResponseTypeInterceptor()) + + if (debugging) { + addInterceptor(HttpLoggingInterceptor().apply { + setLevel(HttpLoggingInterceptor.Level.BODY) + }) + } + }.build() + + // custom [Retrofit] client to add custom [OkHttpClient] and add Gson (JSON) support + val omdbClient: Retrofit = Retrofit.Builder() + .addConverterFactory(GsonConverterFactory.create(GsonBuilder().create())) + .addCallAdapterFactory(NetworkResponseAdapterFactory()) + .baseUrl(baseUrl) + .client(httpClient) + .build() +} diff --git a/src/main/kotlin/com/omdbapi/api/core/Credentials.kt b/src/main/kotlin/com/omdbapi/api/core/Credentials.kt new file mode 100644 index 0000000..cf5ef61 --- /dev/null +++ b/src/main/kotlin/com/omdbapi/api/core/Credentials.kt @@ -0,0 +1,5 @@ +package com.omdbapi.api.core + +data class Credentials( + val apiKey: String +) \ No newline at end of file diff --git a/src/main/kotlin/com/omdbapi/api/core/ResponseTypeInterceptor.kt b/src/main/kotlin/com/omdbapi/api/core/ResponseTypeInterceptor.kt new file mode 100644 index 0000000..86e9990 --- /dev/null +++ b/src/main/kotlin/com/omdbapi/api/core/ResponseTypeInterceptor.kt @@ -0,0 +1,36 @@ +package com.omdbapi.api.core + +import okhttp3.HttpUrl +import okhttp3.HttpUrl.Companion.toHttpUrlOrNull +import okhttp3.Interceptor +import okhttp3.Request +import okhttp3.Response + +class ResponseTypeInterceptor: Interceptor { + + override fun intercept(chain: Interceptor.Chain): Response { + val request = chain.request() + + return chain.proceed(createJsonTypeRequest( + request = request, + authenticatedUrl = createJsonRequestUrl(request) + )) + } + + private fun createJsonTypeRequest(request: Request, authenticatedUrl: HttpUrl): Request { + val authenticatedRequest = request.newBuilder() + .url(authenticatedUrl) + .build() + + return authenticatedRequest + } + + private fun createJsonRequestUrl(request: Request): HttpUrl { + val parsed = request.url.toString().toHttpUrlOrNull() + ?: throw IllegalArgumentException("Invalid URL: ${request.url}") + + return parsed.newBuilder() + .addQueryParameter("r", "json") + .build() + } +} diff --git a/src/main/kotlin/com/omdbapi/api/data/Plot.kt b/src/main/kotlin/com/omdbapi/api/data/Plot.kt new file mode 100644 index 0000000..bbe29b5 --- /dev/null +++ b/src/main/kotlin/com/omdbapi/api/data/Plot.kt @@ -0,0 +1,5 @@ +package com.omdbapi.api.data + +enum class Plot { + short, full +} \ No newline at end of file diff --git a/src/main/kotlin/com/omdbapi/api/data/QueryType.kt b/src/main/kotlin/com/omdbapi/api/data/QueryType.kt new file mode 100644 index 0000000..1c2a6a9 --- /dev/null +++ b/src/main/kotlin/com/omdbapi/api/data/QueryType.kt @@ -0,0 +1,5 @@ +package com.omdbapi.api.data + +enum class QueryType { + movie, series, episode +} \ No newline at end of file diff --git a/src/main/kotlin/com/omdbapi/api/data/pojo/Error.kt b/src/main/kotlin/com/omdbapi/api/data/pojo/Error.kt new file mode 100644 index 0000000..03d9015 --- /dev/null +++ b/src/main/kotlin/com/omdbapi/api/data/pojo/Error.kt @@ -0,0 +1,15 @@ +package com.omdbapi.api.data.pojo + +import com.google.gson.annotations.SerializedName + +class Error { + + data class Response( + + @SerializedName("Response") + val response: String, + + @SerializedName("Error") + val error: String + ) +} \ No newline at end of file diff --git a/src/main/kotlin/com/omdbapi/api/data/pojo/Search.kt b/src/main/kotlin/com/omdbapi/api/data/pojo/Search.kt new file mode 100644 index 0000000..1805126 --- /dev/null +++ b/src/main/kotlin/com/omdbapi/api/data/pojo/Search.kt @@ -0,0 +1,94 @@ +package com.omdbapi.api.data.pojo + +import com.google.gson.annotations.SerializedName + +class Search { + + data class Response( + + @SerializedName("Title") + val title: String, + + @SerializedName("Year") + val year: String, + + @SerializedName("Rated") + val rated: String, + + @SerializedName("Released") + val released: String, + + @SerializedName("Runtime") + val runtime: String, + + @SerializedName("Genre") + val genre: String, + + @SerializedName("Director") + val director: String, + + @SerializedName("Writer") + val writer: String, + + @SerializedName("Actors") + val actors: String, + + @SerializedName("Plot") + val plot: String, + + @SerializedName("Language") + val language: String, + + @SerializedName("Country") + val country: String, + + @SerializedName("Awards") + val awards: String, + + @SerializedName("Poster") + val poster: String, + + @SerializedName("Ratings") + val ratings: List, + + @SerializedName("Metascore") + val metascore: String, + + @SerializedName("imdbRating") + val imdbRating: String, + + @SerializedName("imdbVotes") + val imdbVotes: String, + + @SerializedName("imdbID") + val imdbId: String, + + @SerializedName("Type") + val type: String, + + @SerializedName("DVD") + val dvd: String, + + @SerializedName("BoxOffice") + val boxOffice: String, + + @SerializedName("Production") + val production: String, + + @SerializedName("Website") + val website: String, + + @SerializedName("Response") + val response: String + ) { + + data class Rating( + + @SerializedName("Source") + val source: String, + + @SerializedName("Value") + val value: String + ) + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/omdbapi/api/data/pojo/SearchList.kt b/src/main/kotlin/com/omdbapi/api/data/pojo/SearchList.kt new file mode 100644 index 0000000..1e73160 --- /dev/null +++ b/src/main/kotlin/com/omdbapi/api/data/pojo/SearchList.kt @@ -0,0 +1,12 @@ +package com.omdbapi.api.data.pojo + +import com.google.gson.annotations.SerializedName + +class SearchList { + + data class Response( + + @SerializedName("Search") + val search: List + ) +} \ No newline at end of file diff --git a/src/main/resources/mock/v1/search/SearchList.json b/src/main/resources/mock/v1/search/SearchList.json new file mode 100644 index 0000000..abf7cad --- /dev/null +++ b/src/main/resources/mock/v1/search/SearchList.json @@ -0,0 +1,76 @@ +{ + "Search": [ + { + "Title": "Angels & Demons", + "Year": "2009", + "imdbID": "tt0808151", + "Type": "movie", + "Poster": "https://m.media-amazon.com/images/M/MV5BMjEzNzM2MjgxMF5BMl5BanBnXkFtZTcwNTQ1MTM0Mg@@._V1_SX300.jpg" + }, + { + "Title": "Da Vinci's Demons", + "Year": "2013–2015", + "imdbID": "tt2094262", + "Type": "series", + "Poster": "https://m.media-amazon.com/images/M/MV5BYzA5YjY2ZmUtODliNS00ZjhlLTkwZjItODNmYzQ3MDc0YThlXkEyXkFqcGdeQXVyOTQxNzM2MjY@._V1_SX300.jpg" + }, + { + "Title": "Demons", + "Year": "1985", + "imdbID": "tt0089013", + "Type": "movie", + "Poster": "https://m.media-amazon.com/images/M/MV5BMWE0NTAxOTMtOThkNC00MzZlLTgyODYtYjQ0YmJlYWE3NjEwXkEyXkFqcGdeQXVyMzIwNDY4NDI@._V1_SX300.jpg" + }, + { + "Title": "Night of the Demons", + "Year": "1988", + "imdbID": "tt0093624", + "Type": "movie", + "Poster": "https://m.media-amazon.com/images/M/MV5BZjU2Y2VmMGYtN2Y3OC00OGMwLWFlYTMtOTRlMTE5NDgwODU4XkEyXkFqcGdeQXVyMTQxNzMzNDI@._V1_SX300.jpg" + }, + { + "Title": "Journey to the West: Conquering the Demons", + "Year": "2013", + "imdbID": "tt2017561", + "Type": "movie", + "Poster": "https://m.media-amazon.com/images/M/MV5BMTQzMzUxNzk0NV5BMl5BanBnXkFtZTgwMTEwOTE4MDE@._V1_SX300.jpg" + }, + { + "Title": "Demons 2", + "Year": "1986", + "imdbID": "tt0090930", + "Type": "movie", + "Poster": "https://m.media-amazon.com/images/M/MV5BZjExNjA2NTktZWViYS00NTQyLWExM2UtZjZkNjhhZWM1ZGRlXkEyXkFqcGdeQXVyNzc5MjA3OA@@._V1_SX300.jpg" + }, + { + "Title": "Constantine: City of Demons - The Movie", + "Year": "2018", + "imdbID": "tt9177882", + "Type": "movie", + "Poster": "https://m.media-amazon.com/images/M/MV5BZjM3M2EzYzAtYzcxYi00MWU2LWFhNmItNGJiZjMyZTUyNTQyXkEyXkFqcGdeQXVyMTU0OTM5ODc1._V1_SX300.jpg" + }, + { + "Title": "Night of the Demons", + "Year": "2009", + "imdbID": "tt1268809", + "Type": "movie", + "Poster": "https://m.media-amazon.com/images/M/MV5BMjI2NDMxMzU2OF5BMl5BanBnXkFtZTcwNzcwODM3Mw@@._V1_SX300.jpg" + }, + { + "Title": "Constantine: City of Demons", + "Year": "2018–2019", + "imdbID": "tt6404896", + "Type": "series", + "Poster": "https://m.media-amazon.com/images/M/MV5BZTU4NjA0YmEtNmZlZi00MTVhLTk0OGMtYzQ5Zjk5NTUxNzQwXkEyXkFqcGdeQXVyODc5Mjc4Nzg@._V1_SX300.jpg" + }, + { + "Title": "Night of the Demons 2", + "Year": "1994", + "imdbID": "tt0110667", + "Type": "movie", + "Poster": "https://m.media-amazon.com/images/M/MV5BY2QxY2JhZjQtNDcwYy00Mjk1LTkzMmItZjEzZmE0OGJkNmRkXkEyXkFqcGdeQXVyMTQxNzMzNDI@._V1_SX300.jpg" + } + ], + "totalResults": "447", + "Response": "True" +} \ No newline at end of file diff --git a/src/main/resources/mock/v1/search/SearchTitle.json b/src/main/resources/mock/v1/search/SearchTitle.json new file mode 100644 index 0000000..af1fdee --- /dev/null +++ b/src/main/resources/mock/v1/search/SearchTitle.json @@ -0,0 +1,40 @@ +{ + "Title": "Demons", + "Year": "1985", + "Rated": "Not Rated", + "Released": "30 May 1986", + "Runtime": "88 min", + "Genre": "Horror", + "Director": "Lamberto Bava", + "Writer": "Dardano Sacchetti, Dario Argento, Lamberto Bava", + "Actors": "Urbano Barberini, Natasha Hovey, Karl Zinny", + "Plot": "A group of random people are invited to a screening of a mysterious movie, only to find themselves trapped in the theater with ravenous demons.", + "Language": "Italian", + "Country": "Italy", + "Awards": "2 nominations", + "Poster": "https://m.media-amazon.com/images/M/MV5BMWE0NTAxOTMtOThkNC00MzZlLTgyODYtYjQ0YmJlYWE3NjEwXkEyXkFqcGdeQXVyMzIwNDY4NDI@._V1_SX300.jpg", + "Ratings": [ + { + "Source": "Internet Movie Database", + "Value": "6.6/10" + }, + { + "Source": "Rotten Tomatoes", + "Value": "69%" + }, + { + "Source": "Metacritic", + "Value": "53/100" + } + ], + "Metascore": "53", + "imdbRating": "6.6", + "imdbVotes": "26,800", + "imdbID": "tt0089013", + "Type": "movie", + "DVD": "N/A", + "BoxOffice": "N/A", + "Production": "N/A", + "Website": "N/A", + "Response": "True" +} \ No newline at end of file diff --git a/src/test/kotlin/com/omdbapi/api/OMDbInterfaceTest.kt b/src/test/kotlin/com/omdbapi/api/OMDbInterfaceTest.kt new file mode 100644 index 0000000..d3c1a59 --- /dev/null +++ b/src/test/kotlin/com/omdbapi/api/OMDbInterfaceTest.kt @@ -0,0 +1,53 @@ +package com.omdbapi.api + +import co.infinum.retromock.Retromock +import com.haroldadmin.cnradapter.NetworkResponse +import com.omdbapi.api.core.Credentials +import kotlinx.coroutines.runBlocking +import org.junit.jupiter.api.Test +import com.omdbapi.api.test.ResourceBodyFactory +import kotlin.test.assertNotNull + +class OMDbInterfaceTest { + + @Test + fun `check search list response parser`() { + runBlocking { + val api = createMockedApi() + + val searchList = api.searchList( + title = "Demons" + ) + + assert(searchList is NetworkResponse.Success) + assertNotNull((searchList as NetworkResponse.Success).body) + } + } + + @Test + fun `check search response parser`() { + runBlocking { + val api = createMockedApi() + + val searchTitle = api.searchTitle( + title = "Demons" + ) + + assert(searchTitle is NetworkResponse.Success) + assertNotNull((searchTitle as NetworkResponse.Success).body) + } + } + + private fun createMockedApi(): OMDbInterface { + + val client = OMDbClient(Credentials("")) + val retro = client.omdbClient + + val mockRetrofit: Retromock = Retromock.Builder() + .defaultBodyFactory(ResourceBodyFactory()) + .retrofit(retro) + .build() + + return mockRetrofit.create(OMDbInterface::class.java) + } +} \ No newline at end of file diff --git a/src/test/kotlin/com/omdbapi/api/test/ResourceBodyFactory.kt b/src/test/kotlin/com/omdbapi/api/test/ResourceBodyFactory.kt new file mode 100644 index 0000000..d15f0b9 --- /dev/null +++ b/src/test/kotlin/com/omdbapi/api/test/ResourceBodyFactory.kt @@ -0,0 +1,11 @@ +package com.omdbapi.api.test + +import co.infinum.retromock.BodyFactory +import java.io.FileInputStream +import java.io.InputStream + +internal class ResourceBodyFactory : BodyFactory { + override fun create(input: String): InputStream { + return FileInputStream(ResourceBodyFactory::class.java.classLoader.getResource("mock/$input").file) + } +}