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 @@
+
+
+
+
+
+
+
+
+
+## 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)
+ }
+}