From c6fdd2684031761c1b7082e6b7b556450314bbf3 Mon Sep 17 00:00:00 2001 From: qbasso Date: Thu, 7 Mar 2019 21:23:47 +0100 Subject: [PATCH 1/6] added search funcionality --- build.gradle | 2 +- library/build.gradle | 6 +- .../java/io/constructor/core/Constants.kt | 8 ++- .../java/io/constructor/core/ConstructorIo.kt | 22 ++++++- .../java/io/constructor/data/DataManager.kt | 30 +++++++++- .../data/model/search/FacetOption.kt | 3 + .../constructor/data/model/search/Result.kt | 5 ++ .../data/model/search/ResultData.kt | 12 ++++ .../data/model/search/ResultFacet.kt | 3 + .../data/model/search/SearchData.kt | 6 ++ .../data/model/search/SearchFacet.kt | 11 ++++ .../data/model/search/SearchGroup.kt | 9 +++ .../data/model/search/SearchResponse.kt | 5 ++ .../io/constructor/data/remote/ApiPaths.kt | 3 +- .../constructor/data/remote/ConstructorApi.kt | 10 ++-- .../io/constructor/core/ConstructorIoTest.kt | 6 +- .../constructor/data/DataManagerHttpTest.kt | 57 ++++++++++++++++++- .../io/constructor/data/DataManagerTest.kt | 37 +++++++++++- .../io/constructor/util/TestDataLoader.kt | 13 +++++ .../src/test/resources/search_response.json | 1 + .../search_response_unexpected_data.json | 1 + sample/build.gradle | 3 + .../io/constructor/sample/MainActivity.kt | 5 ++ sample/src/main/res/layout/activity_main.xml | 10 ++++ 24 files changed, 250 insertions(+), 18 deletions(-) create mode 100644 library/src/main/java/io/constructor/data/model/search/FacetOption.kt create mode 100644 library/src/main/java/io/constructor/data/model/search/Result.kt create mode 100644 library/src/main/java/io/constructor/data/model/search/ResultData.kt create mode 100644 library/src/main/java/io/constructor/data/model/search/ResultFacet.kt create mode 100644 library/src/main/java/io/constructor/data/model/search/SearchData.kt create mode 100644 library/src/main/java/io/constructor/data/model/search/SearchFacet.kt create mode 100644 library/src/main/java/io/constructor/data/model/search/SearchGroup.kt create mode 100644 library/src/main/java/io/constructor/data/model/search/SearchResponse.kt create mode 100755 library/src/test/resources/search_response.json create mode 100755 library/src/test/resources/search_response_unexpected_data.json diff --git a/build.gradle b/build.gradle index 57530186..c030adcc 100755 --- a/build.gradle +++ b/build.gradle @@ -8,7 +8,7 @@ buildscript { dependencies { classpath 'com.android.tools.build:gradle:3.3.1' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" - classpath 'org.jacoco:org.jacoco.core:0.8.3' + classpath 'org.jacoco:org.jacoco.core:0.8.1' classpath 'com.github.dcendents:android-maven-gradle-plugin:2.0' } } diff --git a/library/build.gradle b/library/build.gradle index 428af783..11a376fa 100755 --- a/library/build.gradle +++ b/library/build.gradle @@ -8,7 +8,7 @@ apply plugin: 'jacoco' group='com.github.Constructor-io' jacoco { - toolVersion = '0.8.3' + toolVersion = '0.8.1' } tasks.withType(Test) { @@ -158,8 +158,8 @@ apply from: 'dependencies.gradle' dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version" - implementation 'io.reactivex.rxjava2:rxandroid:2.0.1' - implementation 'io.reactivex.rxjava2:rxjava:2.1.8' + implementation 'io.reactivex.rxjava2:rxandroid:2.0.2' + implementation 'io.reactivex.rxjava2:rxjava:2.1.13' implementation 'io.reactivex.rxjava2:rxkotlin:2.2.0' testImplementation 'io.mockk:mockk:1.9.kotlin12' testImplementation 'org.robolectric:robolectric:3.6.1' diff --git a/library/src/main/java/io/constructor/core/Constants.kt b/library/src/main/java/io/constructor/core/Constants.kt index a0e9167b..3d292a5c 100755 --- a/library/src/main/java/io/constructor/core/Constants.kt +++ b/library/src/main/java/io/constructor/core/Constants.kt @@ -27,15 +27,19 @@ class Constants { const val GROUP_DISPLAY_NAME = "group[display_name]" const val USER_ID = "ui" const val TERM_UNKNOWN = "TERM_UNKNOWN" + const val PAGE = "page" + const val PER_PAGE = "num_results_per_page" + const val FILTER_GROUP_ID = "filters[group_id]" + const val FILTER_FACET = "filters[%s]" } object QueryValues { const val EVENT_CLICK = "click" - const val EVENT_SEARCH = "search" + const val EVENT_SEARCH = "getSearchResults" const val EVENT_SESSION_START = "session_start" const val SEARCH_SUGGESTIONS = "Search Suggestions" const val PRODUCTS = "Products" - const val EVENT_SEARCH_RESULTS = "search-results" + const val EVENT_SEARCH_RESULTS = "getSearchResults-results" const val EVENT_INPUT_FOCUS = "focus" } } \ No newline at end of file diff --git a/library/src/main/java/io/constructor/core/ConstructorIo.kt b/library/src/main/java/io/constructor/core/ConstructorIo.kt index df83ba94..f746d829 100755 --- a/library/src/main/java/io/constructor/core/ConstructorIo.kt +++ b/library/src/main/java/io/constructor/core/ConstructorIo.kt @@ -8,6 +8,7 @@ import io.constructor.data.local.PreferencesHelper import io.constructor.data.memory.ConfigMemoryHolder import io.constructor.data.model.Group import io.constructor.data.model.Suggestion +import io.constructor.data.model.search.SearchResponse import io.constructor.injection.component.AppComponent import io.constructor.injection.component.DaggerAppComponent import io.constructor.injection.module.AppModule @@ -105,6 +106,25 @@ object ConstructorIo { return dataManager.getAutocompleteResults(query, params.toTypedArray()) } + fun getSearchResults(text: String, vararg facets: Pair>, page: Int? = null, perPage: Int? = null, groupId: Int? = null): Observable> { + val sessionId = preferenceHelper.getSessionId(sessionIncrementEventHandler) + val encodedParams: ArrayList> = arrayListOf() + groupId?.let { encodedParams.add(Constants.QueryConstants.FILTER_GROUP_ID.urlEncode() to it.toString()) } + page?.let { + encodedParams.add(Constants.QueryConstants.PAGE.urlEncode() to page.toString().urlEncode()) + } + perPage?.let { + encodedParams.add(Constants.QueryConstants.PER_PAGE.urlEncode() to perPage.toString().urlEncode()) + } + encodedParams.add(Constants.QueryConstants.SESSION.urlEncode() to sessionId.toString().urlEncode()) + facets.forEach { facet -> + facet.second.forEach { + encodedParams.add(Constants.QueryConstants.FILTER_FACET.format(facet.first).urlEncode() to it.urlEncode()) + } + } + return dataManager.getSearchResults(text, encodedParams = encodedParams.toTypedArray()) + } + fun trackAutocompleteSelect(searchTerm: String, originalQuery: String, sectionName: String, group: Group? = null, errorCallback: ConstructorError = null) { val sessionId = preferenceHelper.getSessionId(sessionIncrementEventHandler) val encodedParams: ArrayList> = arrayListOf() @@ -139,7 +159,7 @@ object ConstructorIo { }, { it.printStackTrace() errorCallback?.invoke(it) - e("trigger search error: ${it.message}") + e("trigger getSearchResults error: ${it.message}") })) } diff --git a/library/src/main/java/io/constructor/data/DataManager.kt b/library/src/main/java/io/constructor/data/DataManager.kt index 80c44395..d2346ba1 100755 --- a/library/src/main/java/io/constructor/data/DataManager.kt +++ b/library/src/main/java/io/constructor/data/DataManager.kt @@ -1,6 +1,10 @@ package io.constructor.data +import com.squareup.moshi.Moshi +import io.constructor.BuildConfig import io.constructor.data.model.Suggestion +import io.constructor.data.model.search.SearchResponse +import io.constructor.data.remote.ApiPaths import io.constructor.data.remote.ConstructorApi import io.reactivex.Completable import io.reactivex.Observable @@ -9,7 +13,7 @@ import javax.inject.Singleton @Singleton class DataManager @Inject -constructor(private val constructorApi: ConstructorApi) { +constructor(private val constructorApi: ConstructorApi, private val moshi: Moshi) { fun getAutocompleteResults(text: String, params: Array> = arrayOf()): Observable?>> = constructorApi.getSuggestions(text, params.toMap()).map { if (!it.isError) { @@ -25,6 +29,30 @@ constructor(private val constructorApi: ConstructorApi) { } }.toObservable() + fun getSearchResults(text: String, encodedParams: Array> = arrayOf()): Observable> { + var dynamicUrl = BuildConfig.BASE_API_URL + "/${ApiPaths.URL_SEARCH.format(text)}" + encodedParams.forEachIndexed { index, pair -> + dynamicUrl += "${if (index != 0) "&" else "?" }${pair.first}=${pair.second}" + } + return constructorApi.search(dynamicUrl).map { result -> + if (!result.isError) { + result.response()?.let { + if (it.isSuccessful){ + val adapter = moshi.adapter(SearchResponse::class.java) + val response = it.body()?.string() + val result = response?.let { adapter.fromJson(it) } + result?.rawData = response + ConstructorData.of(result!!) + } else { + ConstructorData.networkError(it.errorBody()?.string()) + } + } ?: ConstructorData.error(result.error()) + } else { + ConstructorData.error(result.error()) + } + }.toObservable() + } + fun trackAutocompleteSelect(term: String, params: Array> = arrayOf(), encodedParams: Array> = arrayOf()): Completable { return constructorApi.trackAutocompleteSelect(term, params.toMap(), encodedParams.toMap()) } diff --git a/library/src/main/java/io/constructor/data/model/search/FacetOption.kt b/library/src/main/java/io/constructor/data/model/search/FacetOption.kt new file mode 100644 index 00000000..3900e7c5 --- /dev/null +++ b/library/src/main/java/io/constructor/data/model/search/FacetOption.kt @@ -0,0 +1,3 @@ +package io.constructor.data.model.search + +data class FacetOption(val count: Int, val value: String?) \ No newline at end of file diff --git a/library/src/main/java/io/constructor/data/model/search/Result.kt b/library/src/main/java/io/constructor/data/model/search/Result.kt new file mode 100644 index 00000000..364f7f26 --- /dev/null +++ b/library/src/main/java/io/constructor/data/model/search/Result.kt @@ -0,0 +1,5 @@ +package io.constructor.data.model.search + +import com.squareup.moshi.Json + +data class Result(@Json(name = "data") val result: ResultData, @Json(name = "matched_terms") val matchedTerms: List?, val value: String) diff --git a/library/src/main/java/io/constructor/data/model/search/ResultData.kt b/library/src/main/java/io/constructor/data/model/search/ResultData.kt new file mode 100644 index 00000000..5595199e --- /dev/null +++ b/library/src/main/java/io/constructor/data/model/search/ResultData.kt @@ -0,0 +1,12 @@ +package io.constructor.data.model.search + +import com.squareup.moshi.Json +import io.constructor.data.model.Group + +data class ResultData(val description: String?, + val id: String, + @Json(name = "image_url") val imageUrl: String?, + val url: String?, + val facets: List?, + val groups: List?, + var metadata: Map?) \ No newline at end of file diff --git a/library/src/main/java/io/constructor/data/model/search/ResultFacet.kt b/library/src/main/java/io/constructor/data/model/search/ResultFacet.kt new file mode 100644 index 00000000..d92e7986 --- /dev/null +++ b/library/src/main/java/io/constructor/data/model/search/ResultFacet.kt @@ -0,0 +1,3 @@ +package io.constructor.data.model.search + +data class ResultFacet(val name: String, val values: List?) diff --git a/library/src/main/java/io/constructor/data/model/search/SearchData.kt b/library/src/main/java/io/constructor/data/model/search/SearchData.kt new file mode 100644 index 00000000..f40a9a98 --- /dev/null +++ b/library/src/main/java/io/constructor/data/model/search/SearchData.kt @@ -0,0 +1,6 @@ +package io.constructor.data.model.search + +import com.squareup.moshi.Json + + +data class SearchData(val facets: List?, val groups: List?, val results: List?, @Json(name = "total_num_results") val resultCount: Int) diff --git a/library/src/main/java/io/constructor/data/model/search/SearchFacet.kt b/library/src/main/java/io/constructor/data/model/search/SearchFacet.kt new file mode 100644 index 00000000..fa861f52 --- /dev/null +++ b/library/src/main/java/io/constructor/data/model/search/SearchFacet.kt @@ -0,0 +1,11 @@ +package io.constructor.data.model.search + +import com.squareup.moshi.Json + +data class SearchFacet(val name: String, + @Json(name = "display_name") val displayName: String?, + val status: Map?, + val type: String?, + val min: Int?, + val max: Int?, + val options: List?) diff --git a/library/src/main/java/io/constructor/data/model/search/SearchGroup.kt b/library/src/main/java/io/constructor/data/model/search/SearchGroup.kt new file mode 100644 index 00000000..8dbe9fa2 --- /dev/null +++ b/library/src/main/java/io/constructor/data/model/search/SearchGroup.kt @@ -0,0 +1,9 @@ +package io.constructor.data.model.search + +import com.squareup.moshi.Json + +data class SearchGroup(@Json(name = "children") val children: List?, + @Json(name = "parents") val parents: List?, + val count: Int, + @Json(name = "display_name") val displayName: String, + @Json(name = "group_id") val groupId: Long) \ No newline at end of file diff --git a/library/src/main/java/io/constructor/data/model/search/SearchResponse.kt b/library/src/main/java/io/constructor/data/model/search/SearchResponse.kt new file mode 100644 index 00000000..96d4ae86 --- /dev/null +++ b/library/src/main/java/io/constructor/data/model/search/SearchResponse.kt @@ -0,0 +1,5 @@ +package io.constructor.data.model.search + +import com.squareup.moshi.Json + +data class SearchResponse(@Json(name = "response") val searchData: SearchData, @Json(name = "result_id") val resultId: String, var rawData: String?) \ No newline at end of file diff --git a/library/src/main/java/io/constructor/data/remote/ApiPaths.kt b/library/src/main/java/io/constructor/data/remote/ApiPaths.kt index 2264b226..d0c8345c 100755 --- a/library/src/main/java/io/constructor/data/remote/ApiPaths.kt +++ b/library/src/main/java/io/constructor/data/remote/ApiPaths.kt @@ -3,11 +3,12 @@ package io.constructor.data.remote object ApiPaths { const val URL_GET_SUGGESTIONS = "autocomplete/{value}" const val URL_AUTOCOMPLETE_SELECT_EVENT = "autocomplete/{term}/select" - const val URL_SEARCH_SUBMIT_EVENT = "autocomplete/{term}/search" + const val URL_SEARCH_SUBMIT_EVENT = "autocomplete/{term}/getSearchResults" const val URL_SESSION_START_EVENT = "behavior" const val URL_CONVERSION_EVENT = "autocomplete/{term}/conversion" const val URL_SEARCH_RESULT_CLICK_EVENT = "autocomplete/{term}/click_through" const val URL_BEHAVIOR = "behavior" const val URL_PURCHASE = "autocomplete/TERM_UNKNOWN/purchase" + const val URL_SEARCH = "search/%s" } \ No newline at end of file diff --git a/library/src/main/java/io/constructor/data/remote/ConstructorApi.kt b/library/src/main/java/io/constructor/data/remote/ConstructorApi.kt index 128c4381..a581b695 100755 --- a/library/src/main/java/io/constructor/data/remote/ConstructorApi.kt +++ b/library/src/main/java/io/constructor/data/remote/ConstructorApi.kt @@ -4,11 +4,9 @@ import io.constructor.core.Constants import io.constructor.data.model.AutocompleteResult import io.reactivex.Completable import io.reactivex.Single +import okhttp3.ResponseBody import retrofit2.adapter.rxjava2.Result -import retrofit2.http.GET -import retrofit2.http.Path -import retrofit2.http.Query -import retrofit2.http.QueryMap +import retrofit2.http.* interface ConstructorApi { @@ -40,4 +38,8 @@ interface ConstructorApi { fun trackPurchase(@Query(Constants.QueryConstants.CUSTOMER_ID) customerIds: List, @Query("revenue") revenue: String?, @QueryMap params: Map): Completable + + @GET + fun search(@Url searchUrl: String): Single> + } \ No newline at end of file diff --git a/library/src/test/java/io/constructor/core/ConstructorIoTest.kt b/library/src/test/java/io/constructor/core/ConstructorIoTest.kt index 66277685..4eadbc05 100755 --- a/library/src/test/java/io/constructor/core/ConstructorIoTest.kt +++ b/library/src/test/java/io/constructor/core/ConstructorIoTest.kt @@ -125,7 +125,7 @@ class ConstructorIoTest { @Test fun verifySearchResultsLoadedEventUrl() { - val expected = "https://ac.cnstrc.com/behavior?c=${BuildConfig.CLIENT_VERSION}&s=1&action=search-results&key=testKey&_dt=1520000000000" + val expected = "https://ac.cnstrc.com/behavior?c=${BuildConfig.CLIENT_VERSION}&s=1&action=getSearchResults-results&key=testKey&_dt=1520000000000" val urlBuilder = HttpUrl.Builder().scheme("https") .host("ac.cnstrc.com") .addPathSegment("behavior") @@ -186,14 +186,14 @@ class ConstructorIoTest { @Test fun verifySearchUrl() { - val expected = "https://ac.cnstrc.com/autocomplete/hot%20dogs/search?s=1&i=1&_dt=1520000000000&original_query=dog&group%5Bgroup_id%5D=Meat%20%26%20Seafood&group%5Bdisplay_name%5D=Meat%20%26%20Seafood&tr=search&c=cioand-${BuildConfig.VERSION_NAME}&key=testKey" + val expected = "https://ac.cnstrc.com/autocomplete/hot%20dogs/getSearchResults?s=1&i=1&_dt=1520000000000&original_query=dog&group%5Bgroup_id%5D=Meat%20%26%20Seafood&group%5Bdisplay_name%5D=Meat%20%26%20Seafood&tr=getSearchResults&c=cioand-${BuildConfig.VERSION_NAME}&key=testKey" val originalQuery = "dog" val term = "hot dogs" val urlBuilder = HttpUrl.Builder().scheme("https") .host("ac.cnstrc.com") .addPathSegment("autocomplete") .addPathSegment(term) - .addPathSegment("search") + .addPathSegment("getSearchResults") .addQueryParameter(Constants.QueryConstants.SESSION, "1") .addQueryParameter(Constants.QueryConstants.IDENTITY, "1") .addQueryParameter(Constants.QueryConstants.TIMESTAMP, sampleMillis) diff --git a/library/src/test/java/io/constructor/data/DataManagerHttpTest.kt b/library/src/test/java/io/constructor/data/DataManagerHttpTest.kt index 1c2ad871..21940811 100755 --- a/library/src/test/java/io/constructor/data/DataManagerHttpTest.kt +++ b/library/src/test/java/io/constructor/data/DataManagerHttpTest.kt @@ -27,6 +27,7 @@ import retrofit2.converter.moshi.MoshiConverterFactory import java.net.SocketTimeoutException import java.util.concurrent.TimeUnit + class DataManagerHttpTest { @Rule @@ -68,7 +69,7 @@ class DataManagerHttpTest { .build() constructorApi = retrofit.create(ConstructorApi::class.java) - dataManager = DataManager(constructorApi) + dataManager = DataManager(constructorApi, moshi) } @Test @@ -436,4 +437,58 @@ class DataManagerHttpTest { assert(request.path.contains("${Constants.QueryConstants.CUSTOMER_ID}=2")) } +// @Test +// fun getSearchResult() { +// val mockResponse = MockResponse().setResponseCode(200).setBody(TestDataLoader.loadAsString("search_response.json")) +// mockServer.enqueue(mockResponse) +// val observer = dataManager.getSearchResults("corn").test() +// observer.assertComplete().assertValue { +// it.get()!!.searchData.results!!.size == 5 +// } +// } +// +// @Test +// fun getSearchResultsBadServerResponse() { +// val mockResponse = MockResponse().setResponseCode(500).setBody("Internal server error") +// mockServer.enqueue(mockResponse) +// val observer = dataManager.getSearchResults("corn").test() +// observer.assertComplete().assertValue { +// it.networkError +// } +// } +// +// @Test +// fun getSearchResultsTimeoutException() { +// val mockResponse = MockResponse().setResponseCode(200).setBody(TestDataLoader.loadAsString("search_response.json")) +// mockResponse.throttleBody(128, 5, TimeUnit.SECONDS) +// mockServer.enqueue(mockResponse) +// val observer = dataManager.getSearchResults("corn").test() +// observer.assertComplete().assertValue { +// it.isError +// } +// } +// +// @Test +// fun getSearchUnexpectedDataResponse() { +// val mockResponse = MockResponse().setResponseCode(200).setBody(TestDataLoader.loadAsString("search_response_unexpected_data.json")) +// mockServer.enqueue(mockResponse) +// val observer = dataManager.getSearchResults("corn").test() +// observer.assertComplete().assertValue { +// it.get()!!.searchData.resultCount == 23 +// } +// } +// +// @Test +// fun getSearchResultsEmptyResponse() { +// val path = "/" + ApiPaths.URL_SEARCH.format("corn") +// val mockResponse = MockResponse().setResponseCode(200).setBody(TestDataLoader.loadAsString("empty_response.json")) +// mockServer.enqueue(mockResponse) +// val observer = dataManager.getSearchResults("corn").test() +// observer.assertComplete().assertValue { +// it.isEmpty +// } +// val request = mockServer.takeRequest() +// assert(request.path.startsWith(path)) +// } + } \ No newline at end of file diff --git a/library/src/test/java/io/constructor/data/DataManagerTest.kt b/library/src/test/java/io/constructor/data/DataManagerTest.kt index b834292b..32982da3 100755 --- a/library/src/test/java/io/constructor/data/DataManagerTest.kt +++ b/library/src/test/java/io/constructor/data/DataManagerTest.kt @@ -1,5 +1,7 @@ package io.constructor.data +import com.squareup.moshi.KotlinJsonAdapterFactory +import com.squareup.moshi.Moshi import io.constructor.data.model.AutocompleteResult import io.constructor.data.remote.ConstructorApi import io.constructor.util.RxSchedulersOverrideRule @@ -23,7 +25,12 @@ class DataManagerTest { private var constructorApi = mockk() - private var dataManager = DataManager(constructorApi) + private var moshi = Moshi + .Builder() + .add(KotlinJsonAdapterFactory()) + .build() + + private var dataManager = DataManager(constructorApi, moshi) @Test fun getSuggestions() { @@ -191,4 +198,32 @@ class DataManagerTest { verify(exactly = 1) { constructorApi.trackPurchase(any(), any(), any()) } } + @Test + fun search() { + val rb = ResponseBody.create(MediaType.get("application/json"), TestDataLoader.loadAsString("search_response.json")) + every { constructorApi.search(any()) } returns Single.just(Result.response(Response.success(rb))) + val observer = dataManager.getSearchResults("corn").test() + observer.assertComplete().assertValue { + it.get()!!.searchData.resultCount == 23 + } + } + + @Test + fun searchBadServerResponse() { + every { constructorApi.search("https://ac.cnstrc.com/getSearchResults/corn") } returns Single.just(Result.response(Response.error(500, ResponseBody.create(MediaType.parse("text/plain"), "Error")))) + val observer = dataManager.getSearchResults("corn").test() + observer.assertComplete().assertValue { + it.networkError + } + } + + @Test + fun searchException() { + every { constructorApi.search("https://ac.cnstrc.com/getSearchResults/corn") } returns Single.just(Result.error(Exception())) + val observer = dataManager.getSearchResults("corn").test() + observer.assertComplete().assertValue { + it.isError + } + } + } \ No newline at end of file diff --git a/library/src/test/java/io/constructor/util/TestDataLoader.kt b/library/src/test/java/io/constructor/util/TestDataLoader.kt index 140a0693..08e442da 100755 --- a/library/src/test/java/io/constructor/util/TestDataLoader.kt +++ b/library/src/test/java/io/constructor/util/TestDataLoader.kt @@ -3,6 +3,7 @@ package io.constructor.util import com.squareup.moshi.KotlinJsonAdapterFactory import com.squareup.moshi.Moshi import io.constructor.data.model.AutocompleteResult +import io.constructor.data.model.search.SearchResponse import okio.Buffer import java.io.File import java.io.FileInputStream @@ -31,6 +32,18 @@ object TestDataLoader { return result } + private fun convertToSearchResult(stringResponse: String): SearchResponse? { + val moshi = Moshi.Builder().add(KotlinJsonAdapterFactory()).build() + val jsonAdapter = moshi.adapter(SearchResponse::class.java) + var result: SearchResponse? = null + try { + result = jsonAdapter.fromJson(stringResponse) + } catch (e: IOException) { + e.printStackTrace() + } + return result + } + fun loadAsString(fileName: String): String { var result = "" try { diff --git a/library/src/test/resources/search_response.json b/library/src/test/resources/search_response.json new file mode 100755 index 00000000..cdad3efe --- /dev/null +++ b/library/src/test/resources/search_response.json @@ -0,0 +1 @@ +{"request": {"ef-11": "22", "ef-ab": "cd", "fmt_options": {"groups_max_depth": 1, "groups_start": "current"}, "num_results_per_page": 20, "page": 1, "section": "Products", "sort_by": "relevance", "sort_order": "descending", "term": "corn"}, "response": {"facets": [], "groups": [{"children": [], "count": 9, "display_name": "Horror", "group_id": "27", "parents": []}, {"children": [], "count": 7, "display_name": "Thriller", "group_id": "53", "parents": []}, {"children": [], "count": 4, "display_name": "Drama", "group_id": "18", "parents": []}, {"children": [], "count": 3, "display_name": "Documentary", "group_id": "99", "parents": []}, {"children": [], "count": 1, "display_name": "Mystery", "group_id": "9648", "parents": []}, {"children": [], "count": 1, "display_name": "Fantasy", "group_id": "14", "parents": []}, {"children": [], "count": 1, "display_name": "Animation", "group_id": "16", "parents": []}, {"children": [], "count": 6, "display_name": "Comedy", "group_id": "35", "parents": []}, {"children": [], "count": 3, "display_name": "Crime", "group_id": "80", "parents": []}, {"children": [], "count": 3, "display_name": "Action", "group_id": "28", "parents": []}, {"children": [], "count": 2, "display_name": "Romance", "group_id": "10749", "parents": []}, {"children": [], "count": 1, "display_name": "Science Fiction", "group_id": "878", "parents": []}], "results": [{"data": {"groups": [{"display_name": "Horror", "group_id": "27", "path": null, "path_list": []}], "id": "children of the corn iv: the gathering", "image_url": "https://image.tmdb.org/t/p/w185_and_h278_bestv2/tRjeV9AZgCXGTqyvlp7Ui55Yb3l.jpg", "url": "https://www.top250.tv/movies/25750"}, "matched_terms": ["corn"], "value": "Children of the Corn IV: The Gathering"}, {"data": {"groups": [{"display_name": "Drama", "group_id": "18", "path": null, "path_list": []}, {"display_name": "Fantasy", "group_id": "14", "path": null, "path_list": []}, {"display_name": "Horror", "group_id": "27", "path": null, "path_list": []}, {"display_name": "Thriller", "group_id": "53", "path": null, "path_list": []}], "id": "children of the corn", "image_url": "https://image.tmdb.org/t/p/w185_and_h278_bestv2/zH77CDSRPeYfZZJyyKSt84j62m8.jpg", "url": "https://www.top250.tv/movies/10823"}, "matched_terms": ["corn"], "value": "Children of the Corn"}, {"data": {"groups": [{"display_name": "Horror", "group_id": "27", "path": null, "path_list": []}], "id": "children of the corn ii: the final sacrifice", "image_url": "https://image.tmdb.org/t/p/w185_and_h278_bestv2/lqFb8Mnx9tFPUevnfbz9o2adLFw.jpg", "url": "https://www.top250.tv/movies/25748"}, "matched_terms": ["corn"], "value": "Children of the Corn II: The Final Sacrifice"}, {"data": {"groups": [{"display_name": "Thriller", "group_id": "53", "path": null, "path_list": []}, {"display_name": "Horror", "group_id": "27", "path": null, "path_list": []}], "id": "children of the corn iii: urban harvest", "image_url": "https://image.tmdb.org/t/p/w185_and_h278_bestv2/Ajp5lVNAW0Kfi3uUlCCpIri28B8.jpg", "url": "https://www.top250.tv/movies/25749"}, "matched_terms": ["corn"], "value": "Children of the Corn III: Urban Harvest"}, {"data": {"groups": [{"display_name": "Drama", "group_id": "18", "path": null, "path_list": []}], "id": "the corn is green", "image_url": "https://image.tmdb.org/t/p/w185_and_h278_bestv2/zBN62KUP4WGys96vmJUFRKc43B9.jpg", "url": "https://www.top250.tv/movies/43492"}, "matched_terms": ["corn"], "value": "The Corn Is Green"}, {"data": {"groups": [{"display_name": "Documentary", "group_id": "99", "path": null, "path_list": []}], "id": "king corn", "image_url": "https://image.tmdb.org/t/p/w185_and_h278_bestv2/pvqjdmu5IdzUPQgqwylpPrUSKSd.jpg", "url": "https://www.top250.tv/movies/15281"}, "matched_terms": ["corn"], "value": "King Corn"}, {"data": {"groups": [{"display_name": "Drama", "group_id": "18", "path": null, "path_list": []}], "id": "corn island", "image_url": "https://image.tmdb.org/t/p/w185_and_h278_bestv2/zM4ZZ7IpKQA266ynNWOvn3LfKE.jpg", "url": "https://www.top250.tv/movies/282376"}, "matched_terms": ["corn"], "value": "Corn Island"}, {"data": {"groups": [{"display_name": "Horror", "group_id": "27", "path": null, "path_list": []}, {"display_name": "Mystery", "group_id": "9648", "path": null, "path_list": []}], "id": "children of the corn 666: isaac's return", "image_url": "https://image.tmdb.org/t/p/w185_and_h278_bestv2/cAoLi0dxRZwA20LUzTTGN3Xn39Y.jpg", "url": "https://www.top250.tv/movies/25752"}, "matched_terms": ["corn"], "value": "Children of the Corn 666: Isaac's Return"}, {"data": {"groups": [{"display_name": "Horror", "group_id": "27", "path": null, "path_list": []}, {"display_name": "Thriller", "group_id": "53", "path": null, "path_list": []}], "id": "children of the corn v: fields of terror", "image_url": "https://image.tmdb.org/t/p/w185_and_h278_bestv2/w3ZOi0jbHNEQ26MEt1X3XCJzBYe.jpg", "url": "https://www.top250.tv/movies/25751"}, "matched_terms": ["corn"], "value": "Children of the Corn V: Fields of Terror"}, {"data": {"groups": [{"display_name": "Horror", "group_id": "27", "path": null, "path_list": []}, {"display_name": "Thriller", "group_id": "53", "path": null, "path_list": []}], "id": "children of the corn: genesis", "image_url": "https://image.tmdb.org/t/p/w185_and_h278_bestv2/94Cc2YJMsCtezYRcmL1PyBNhE1y.jpg", "url": "https://www.top250.tv/movies/70575"}, "matched_terms": ["corn"], "value": "Children of the Corn: Genesis"}, {"data": {"groups": [{"display_name": "Horror", "group_id": "27", "path": null, "path_list": []}], "id": "children of the corn: revelation", "image_url": "https://image.tmdb.org/t/p/w185_and_h278_bestv2/sL3ZaPFwgkfn9KuIsh861zsPX0Y.jpg", "url": "https://www.top250.tv/movies/25753"}, "matched_terms": ["corn"], "value": "Children of the Corn: Revelation"}, {"data": {"groups": [{"display_name": "Animation", "group_id": "16", "path": null, "path_list": []}], "id": "corn on the cop", "image_url": "https://image.tmdb.org/t/p/w185_and_h278_bestv2/1ifAyPrAJW4WDVqmvBmZo3hDhrD.jpg", "url": "https://www.top250.tv/movies/234377"}, "matched_terms": ["corn"], "value": "Corn on the Cop"}, {"data": {"groups": [{"display_name": "Action", "group_id": "28", "path": null, "path_list": []}, {"display_name": "Thriller", "group_id": "53", "path": null, "path_list": []}, {"display_name": "Crime", "group_id": "80", "path": null, "path_list": []}], "id": "con air", "image_url": "https://image.tmdb.org/t/p/w185_and_h278_bestv2/yhaOQ7xXw0PLHLvg1w0M9zlPdg6.jpg", "url": "https://www.top250.tv/movies/1701"}, "matched_terms": ["con"], "value": "Con Air"}, {"data": {"groups": [{"display_name": "Horror", "group_id": "27", "path": null, "path_list": []}, {"display_name": "Science Fiction", "group_id": "878", "path": null, "path_list": []}, {"display_name": "Thriller", "group_id": "53", "path": null, "path_list": []}, {"display_name": "Action", "group_id": "28", "path": null, "path_list": []}], "id": "def-con 4", "image_url": "https://image.tmdb.org/t/p/w185_and_h278_bestv2/wmCLwtkwzrrphDhR1smtFLZrQxG.jpg", "url": "https://www.top250.tv/movies/42033"}, "matched_terms": ["con"], "value": "Def-Con 4"}, {"data": {"groups": [{"display_name": "Romance", "group_id": "10749", "path": null, "path_list": []}, {"display_name": "Comedy", "group_id": "35", "path": null, "path_list": []}, {"display_name": "Crime", "group_id": "80", "path": null, "path_list": []}, {"display_name": "Drama", "group_id": "18", "path": null, "path_list": []}], "id": "the con", "image_url": "https://image.tmdb.org/t/p/w185_and_h278_bestv2/fDcPgFzVioueAcp13nLw8TGiVOC.jpg", "url": "https://www.top250.tv/movies/131729"}, "matched_terms": ["con"], "value": "The Con"}, {"data": {"groups": [{"display_name": "Documentary", "group_id": "99", "path": null, "path_list": []}], "id": "comic-con episode iv: a fan's hope", "image_url": "https://image.tmdb.org/t/p/w185_and_h278_bestv2/axltQJKHxolLfbGwuTKZZlLbBsZ.jpg", "url": "https://www.top250.tv/movies/91356"}, "matched_terms": ["con"], "value": "Comic-Con Episode IV: A Fan's Hope"}, {"data": {"groups": [{"display_name": "Comedy", "group_id": "35", "path": null, "path_list": []}, {"display_name": "Documentary", "group_id": "99", "path": null, "path_list": []}], "id": "chronic-con, episode 420: a new dope", "image_url": "https://image.tmdb.org/t/p/w185_and_h278_bestv2/16pPnt4ce0i3zU7QOoHDD4JN9Oe.jpg", "url": "https://www.top250.tv/movies/347528"}, "matched_terms": ["con"], "value": "Chronic-Con, Episode 420: A New Dope"}, {"data": {"groups": [{"display_name": "Comedy", "group_id": "35", "path": null, "path_list": []}], "id": "vaya con dios", "image_url": "https://image.tmdb.org/t/p/w185_and_h278_bestv2/pIV1xgavkLYL33agVmRxpwq9CE4.jpg", "url": "https://www.top250.tv/movies/6318"}, "matched_terms": ["con"], "value": "Vaya con Dios"}, {"data": {"groups": [{"display_name": "Thriller", "group_id": "53", "path": null, "path_list": []}, {"display_name": "Action", "group_id": "28", "path": null, "path_list": []}, {"display_name": "Crime", "group_id": "80", "path": null, "path_list": []}], "id": "the con artists", "image_url": "https://image.tmdb.org/t/p/w185_and_h278_bestv2/rn2xTdw2pyRTcjcwHy5yEfxkfyQ.jpg", "url": "https://www.top250.tv/movies/300433"}, "matched_terms": ["con"], "value": "The Con Artists"}, {"data": {"groups": [{"display_name": "Comedy", "group_id": "35", "path": null, "path_list": []}], "id": "tempo instabile con probabili schiarite", "image_url": "https://image.tmdb.org/t/p/w185_and_h278_bestv2/iaOhlyHXqAIhsoGXqD9S4I066zo.jpg", "url": "https://www.top250.tv/movies/333888"}, "matched_terms": ["con"], "value": "Tempo instabile con probabili schiarite"}], "sort_options": [], "total_num_results": 23}, "result_id": "5b19c365-1c85-4c2d-b627-0509d60ce2d5"} \ No newline at end of file diff --git a/library/src/test/resources/search_response_unexpected_data.json b/library/src/test/resources/search_response_unexpected_data.json new file mode 100755 index 00000000..ee40a7f9 --- /dev/null +++ b/library/src/test/resources/search_response_unexpected_data.json @@ -0,0 +1 @@ +{"request": {"ef-11": "22", "ef-ab": "cd", "fmt_options": {"groups_max_depth": 1, "groups_start": "current"}, "num_results_per_page": 20, "page": 1, "section": "Products", "sort_by": "relevance", "sort_order": "descending", "term": "corn"}, "response": {"facets": [], "groups": [{"children": [], "count": 9, "display_name": "Horror", "group_id": "27", "parents": []}, {"children": [], "count": 7, "display_name": "Thriller", "unknown_name": "New name", "group_id": "53", "parents": []}, {"children": [], "count": 4, "display_name": "Drama", "group_id": "18", "parents": []}, {"children": [], "count": 3, "display_name": "Documentary", "group_id": "99", "parents": []}, {"children": [], "count": 1, "display_name": "Mystery", "group_id": "9648", "parents": []}, {"children": [], "count": 1, "display_name": "Fantasy", "group_id": "14", "parents": []}, {"children": [], "count": 1, "display_name": "Animation", "group_id": "16", "parents": []}, {"children": [], "count": 6, "display_name": "Comedy", "group_id": "35", "parents": []}, {"children": [], "count": 3, "display_name": "Crime", "group_id": "80", "parents": []}, {"children": [], "count": 3, "display_name": "Action", "group_id": "28", "parents": []}, {"children": [], "count": 2, "display_name": "Romance", "group_id": "10749", "parents": []}, {"children": [], "count": 1, "display_name": "Science Fiction", "group_id": "878", "parents": []}], "results": [{"data": {"groups": [{"display_name": "Horror", "group_id": "27", "path": null, "path_list": []}], "id": "children of the corn iv: the gathering", "image_url": "https://image.tmdb.org/t/p/w185_and_h278_bestv2/tRjeV9AZgCXGTqyvlp7Ui55Yb3l.jpg", "url": "https://www.top250.tv/movies/25750"}, "matched_terms": ["corn"], "value": "Children of the Corn IV: The Gathering"}, {"data": {"groups": [{"display_name": "Drama", "group_id": "18", "path": null, "path_list": []}, {"display_name": "Fantasy", "group_id": "14", "path": null, "path_list": []}, {"display_name": "Horror", "group_id": "27", "path": null, "path_list": []}, {"display_name": "Thriller", "group_id": "53", "path": null, "path_list": []}], "id": "children of the corn", "image_url": "https://image.tmdb.org/t/p/w185_and_h278_bestv2/zH77CDSRPeYfZZJyyKSt84j62m8.jpg", "url": "https://www.top250.tv/movies/10823"}, "matched_terms": ["corn"], "value": "Children of the Corn"}, {"data": {"groups": [{"display_name": "Horror", "group_id": "27", "path": null, "path_list": []}], "id": "children of the corn ii: the final sacrifice", "image_url": "https://image.tmdb.org/t/p/w185_and_h278_bestv2/lqFb8Mnx9tFPUevnfbz9o2adLFw.jpg", "url": "https://www.top250.tv/movies/25748"}, "matched_terms": ["corn"], "value": "Children of the Corn II: The Final Sacrifice"}, {"data": {"groups": [{"display_name": "Thriller", "group_id": "53", "path": null, "path_list": []}, {"display_name": "Horror", "group_id": "27", "path": null, "path_list": []}], "id": "children of the corn iii: urban harvest", "image_url": "https://image.tmdb.org/t/p/w185_and_h278_bestv2/Ajp5lVNAW0Kfi3uUlCCpIri28B8.jpg", "url": "https://www.top250.tv/movies/25749"}, "matched_terms": ["corn"], "value": "Children of the Corn III: Urban Harvest"}, {"data": {"groups": [{"display_name": "Drama", "group_id": "18", "path": null, "path_list": []}], "id": "the corn is green", "image_url": "https://image.tmdb.org/t/p/w185_and_h278_bestv2/zBN62KUP4WGys96vmJUFRKc43B9.jpg", "url": "https://www.top250.tv/movies/43492"}, "matched_terms": ["corn"], "value": "The Corn Is Green"}, {"data": {"groups": [{"display_name": "Documentary", "group_id": "99", "path": null, "path_list": []}], "id": "king corn", "image_url": "https://image.tmdb.org/t/p/w185_and_h278_bestv2/pvqjdmu5IdzUPQgqwylpPrUSKSd.jpg", "url": "https://www.top250.tv/movies/15281"}, "matched_terms": ["corn"], "value": "King Corn"}, {"data": {"groups": [{"display_name": "Drama", "group_id": "18", "path": null, "path_list": []}], "id": "corn island", "image_url": "https://image.tmdb.org/t/p/w185_and_h278_bestv2/zM4ZZ7IpKQA266ynNWOvn3LfKE.jpg", "url": "https://www.top250.tv/movies/282376"}, "matched_terms": ["corn"], "value": "Corn Island"}, {"data": {"groups": [{"display_name": "Horror", "group_id": "27", "path": null, "path_list": []}, {"display_name": "Mystery", "group_id": "9648", "path": null, "path_list": []}], "id": "children of the corn 666: isaac's return", "image_url": "https://image.tmdb.org/t/p/w185_and_h278_bestv2/cAoLi0dxRZwA20LUzTTGN3Xn39Y.jpg", "url": "https://www.top250.tv/movies/25752"}, "matched_terms": ["corn"], "value": "Children of the Corn 666: Isaac's Return"}, {"data": {"groups": [{"display_name": "Horror", "group_id": "27", "path": null, "path_list": []}, {"display_name": "Thriller", "group_id": "53", "path": null, "path_list": []}], "id": "children of the corn v: fields of terror", "image_url": "https://image.tmdb.org/t/p/w185_and_h278_bestv2/w3ZOi0jbHNEQ26MEt1X3XCJzBYe.jpg", "url": "https://www.top250.tv/movies/25751"}, "matched_terms": ["corn"], "value": "Children of the Corn V: Fields of Terror"}, {"data": {"groups": [{"display_name": "Horror", "group_id": "27", "path": null, "path_list": []}, {"display_name": "Thriller", "group_id": "53", "path": null, "path_list": []}], "id": "children of the corn: genesis", "image_url": "https://image.tmdb.org/t/p/w185_and_h278_bestv2/94Cc2YJMsCtezYRcmL1PyBNhE1y.jpg", "url": "https://www.top250.tv/movies/70575"}, "matched_terms": ["corn"], "value": "Children of the Corn: Genesis"}, {"data": {"groups": [{"display_name": "Horror", "group_id": "27", "path": null, "path_list": []}], "id": "children of the corn: revelation", "image_url": "https://image.tmdb.org/t/p/w185_and_h278_bestv2/sL3ZaPFwgkfn9KuIsh861zsPX0Y.jpg", "url": "https://www.top250.tv/movies/25753"}, "matched_terms": ["corn"], "value": "Children of the Corn: Revelation"}, {"data": {"groups": [{"display_name": "Animation", "group_id": "16", "path": null, "path_list": []}], "id": "corn on the cop", "image_url": "https://image.tmdb.org/t/p/w185_and_h278_bestv2/1ifAyPrAJW4WDVqmvBmZo3hDhrD.jpg", "url": "https://www.top250.tv/movies/234377"}, "matched_terms": ["corn"], "value": "Corn on the Cop"}, {"data": {"groups": [{"display_name": "Action", "group_id": "28", "path": null, "path_list": []}, {"display_name": "Thriller", "group_id": "53", "path": null, "path_list": []}, {"display_name": "Crime", "group_id": "80", "path": null, "path_list": []}], "id": "con air", "image_url": "https://image.tmdb.org/t/p/w185_and_h278_bestv2/yhaOQ7xXw0PLHLvg1w0M9zlPdg6.jpg", "url": "https://www.top250.tv/movies/1701"}, "matched_terms": ["con"], "value": "Con Air"}, {"data": {"groups": [{"display_name": "Horror", "group_id": "27", "path": null, "path_list": []}, {"display_name": "Science Fiction", "group_id": "878", "path": null, "path_list": []}, {"display_name": "Thriller", "group_id": "53", "path": null, "path_list": []}, {"display_name": "Action", "group_id": "28", "path": null, "path_list": []}], "id": "def-con 4", "image_url": "https://image.tmdb.org/t/p/w185_and_h278_bestv2/wmCLwtkwzrrphDhR1smtFLZrQxG.jpg", "url": "https://www.top250.tv/movies/42033"}, "matched_terms": ["con"], "value": "Def-Con 4"}, {"data": {"groups": [{"display_name": "Romance", "group_id": "10749", "path": null, "path_list": []}, {"display_name": "Comedy", "group_id": "35", "path": null, "path_list": []}, {"display_name": "Crime", "group_id": "80", "path": null, "path_list": []}, {"display_name": "Drama", "group_id": "18", "path": null, "path_list": []}], "id": "the con", "image_url": "https://image.tmdb.org/t/p/w185_and_h278_bestv2/fDcPgFzVioueAcp13nLw8TGiVOC.jpg", "url": "https://www.top250.tv/movies/131729"}, "matched_terms": ["con"], "value": "The Con"}, {"data": {"groups": [{"display_name": "Documentary", "group_id": "99", "path": null, "path_list": []}], "id": "comic-con episode iv: a fan's hope", "image_url": "https://image.tmdb.org/t/p/w185_and_h278_bestv2/axltQJKHxolLfbGwuTKZZlLbBsZ.jpg", "url": "https://www.top250.tv/movies/91356"}, "matched_terms": ["con"], "value": "Comic-Con Episode IV: A Fan's Hope"}, {"data": {"groups": [{"display_name": "Comedy", "group_id": "35", "path": null, "path_list": []}, {"display_name": "Documentary", "group_id": "99", "path": null, "path_list": []}], "id": "chronic-con, episode 420: a new dope", "image_url": "https://image.tmdb.org/t/p/w185_and_h278_bestv2/16pPnt4ce0i3zU7QOoHDD4JN9Oe.jpg", "url": "https://www.top250.tv/movies/347528"}, "matched_terms": ["con"], "value": "Chronic-Con, Episode 420: A New Dope"}, {"data": {"groups": [{"display_name": "Comedy", "group_id": "35", "path": null, "path_list": []}], "id": "vaya con dios", "image_url": "https://image.tmdb.org/t/p/w185_and_h278_bestv2/pIV1xgavkLYL33agVmRxpwq9CE4.jpg", "url": "https://www.top250.tv/movies/6318"}, "matched_terms": ["con"], "value": "Vaya con Dios"}, {"data": {"groups": [{"display_name": "Thriller", "group_id": "53", "path": null, "path_list": []}, {"display_name": "Action", "group_id": "28", "path": null, "path_list": []}, {"display_name": "Crime", "group_id": "80", "path": null, "path_list": []}], "id": "the con artists", "image_url": "https://image.tmdb.org/t/p/w185_and_h278_bestv2/rn2xTdw2pyRTcjcwHy5yEfxkfyQ.jpg", "url": "https://www.top250.tv/movies/300433"}, "matched_terms": ["con"], "value": "The Con Artists"}, {"data": {"groups": [{"display_name": "Comedy", "group_id": "35", "path": null, "path_list": []}], "id": "tempo instabile con probabili schiarite", "image_url": "https://image.tmdb.org/t/p/w185_and_h278_bestv2/iaOhlyHXqAIhsoGXqD9S4I066zo.jpg", "url": "https://www.top250.tv/movies/333888"}, "matched_terms": ["con"], "value": "Tempo instabile con probabili schiarite"}], "sort_options": [], "total_num_results": 23}, "result_id": "5b19c365-1c85-4c2d-b627-0509d60ce2d5"} \ No newline at end of file diff --git a/sample/build.gradle b/sample/build.gradle index 35ddde42..c99a9db0 100755 --- a/sample/build.gradle +++ b/sample/build.gradle @@ -38,6 +38,9 @@ dependencies { implementation 'com.android.support:appcompat-v7:28.0.0' implementation 'com.android.support:recyclerview-v7:28.0.0' implementation "com.android.support:cardview-v7:28.0.0" + implementation 'io.reactivex.rxjava2:rxandroid:2.0.2' + implementation 'io.reactivex.rxjava2:rxjava:2.1.13' + implementation 'io.reactivex.rxjava2:rxkotlin:2.2.0' implementation 'com.android.support.constraint:constraint-layout:1.1.3' testImplementation 'junit:junit:4.12' } diff --git a/sample/src/main/java/io/constructor/sample/MainActivity.kt b/sample/src/main/java/io/constructor/sample/MainActivity.kt index 0a963b54..de7a872a 100755 --- a/sample/src/main/java/io/constructor/sample/MainActivity.kt +++ b/sample/src/main/java/io/constructor/sample/MainActivity.kt @@ -4,6 +4,7 @@ import android.content.Intent import android.os.Bundle import android.support.v7.app.AppCompatActivity import io.constructor.core.ConstructorIo +import io.reactivex.schedulers.Schedulers import kotlinx.android.synthetic.main.activity_main.* import java.util.* @@ -18,5 +19,9 @@ class MainActivity : AppCompatActivity() { button3.setOnClickListener { ConstructorIo.trackConversion("testId", "id", 11.0) } button4.setOnClickListener { ConstructorIo.trackSearchResultClick("testTerm", "testId", "1") } button5.setOnClickListener { ConstructorIo.trackSearchResultsLoaded("testTerm", Random().nextInt(99) + 1) } + button6.setOnClickListener { ConstructorIo.getSearchResults("corn").subscribeOn(Schedulers.io()).subscribe { + + } } + } } diff --git a/sample/src/main/res/layout/activity_main.xml b/sample/src/main/res/layout/activity_main.xml index ea623bb5..03103d6d 100755 --- a/sample/src/main/res/layout/activity_main.xml +++ b/sample/src/main/res/layout/activity_main.xml @@ -55,4 +55,14 @@ app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/button4" /> + +