From 94fa791431bbe62e43e6d349ead435de5d65ccae Mon Sep 17 00:00:00 2001 From: qbasso Date: Tue, 5 Feb 2019 20:53:45 +0100 Subject: [PATCH 1/5] ch3226 match tracking calls singatures to iOS calls --- .../java/io/constructor/core/Constants.kt | 1 + .../java/io/constructor/core/ConstructorIo.kt | 41 ++++++++-------- .../java/io/constructor/data/DataManager.kt | 16 +++---- .../constructor/data/remote/ConstructorApi.kt | 8 ++-- .../io/constructor/service/OnSearchService.kt | 8 ++-- .../io/constructor/service/OnSelectService.kt | 8 ++-- .../io/constructor/core/ConstructorIoTest.kt | 28 +++++------ .../io/constructor/data/DataManagerTest.kt | 48 +++++++++---------- .../io/constructor/sample/MainActivity.kt | 4 +- 9 files changed, 82 insertions(+), 80 deletions(-) diff --git a/library/src/main/java/io/constructor/core/Constants.kt b/library/src/main/java/io/constructor/core/Constants.kt index 6acba189..a0e9167b 100755 --- a/library/src/main/java/io/constructor/core/Constants.kt +++ b/library/src/main/java/io/constructor/core/Constants.kt @@ -26,6 +26,7 @@ class Constants { const val GROUP_ID = "group[group_id]" const val GROUP_DISPLAY_NAME = "group[display_name]" const val USER_ID = "ui" + const val TERM_UNKNOWN = "TERM_UNKNOWN" } object QueryValues { diff --git a/library/src/main/java/io/constructor/core/ConstructorIo.kt b/library/src/main/java/io/constructor/core/ConstructorIo.kt index 34e7bdce..cc33af98 100755 --- a/library/src/main/java/io/constructor/core/ConstructorIo.kt +++ b/library/src/main/java/io/constructor/core/ConstructorIo.kt @@ -6,8 +6,8 @@ import io.constructor.data.ConstructorData import io.constructor.data.DataManager 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.SuggestionViewModel import io.constructor.injection.component.AppComponent import io.constructor.injection.component.DaggerAppComponent import io.constructor.injection.module.AppModule @@ -101,19 +101,19 @@ object ConstructorIo { return dataManager.getAutocompleteResults(query, params.toTypedArray()) } - fun trackSelect(query: String, suggestion: SuggestionViewModel, errorCallback: ConstructorError = null) { + fun trackAutocompleteSelect(searchTerm: String, originalQuery: String, sectionName: String, group: Group? = null, errorCallback: ConstructorError = null) { val sessionId = preferenceHelper.getSessionId(sessionIncrementEventHandler) val encodedParams: ArrayList> = arrayListOf() - suggestion.group?.groupId?.let { encodedParams.add(Constants.QueryConstants.GROUP_ID.urlEncode() to it) } - suggestion.group?.displayName?.let { encodedParams.add(Constants.QueryConstants.GROUP_DISPLAY_NAME.urlEncode() to it.urlEncode()) } - disposable.add(dataManager.trackSelect(suggestion.term, + group?.groupId?.let { encodedParams.add(Constants.QueryConstants.GROUP_ID.urlEncode() to it) } + group?.displayName?.let { encodedParams.add(Constants.QueryConstants.GROUP_DISPLAY_NAME.urlEncode() to it.urlEncode()) } + disposable.add(dataManager.trackAutocompleteSelect(searchTerm, arrayOf(Constants.QueryConstants.SESSION to sessionId.toString(), - Constants.QueryConstants.AUTOCOMPLETE_SECTION to suggestion.section!!, - Constants.QueryConstants.ORIGINAL_QUERY to query, + Constants.QueryConstants.AUTOCOMPLETE_SECTION to sectionName, + Constants.QueryConstants.ORIGINAL_QUERY to originalQuery, Constants.QueryConstants.EVENT to Constants.QueryValues.EVENT_CLICK), encodedParams.toTypedArray()) .subscribe({ - context.broadcastIntent(Constants.EVENT_QUERY_SENT, Constants.EXTRA_TERM to query) + context.broadcastIntent(Constants.EVENT_QUERY_SENT, Constants.EXTRA_TERM to searchTerm) }, { t -> t.printStackTrace() errorCallback?.invoke(t) @@ -121,17 +121,17 @@ object ConstructorIo { })) } - fun trackSearch(query: String, suggestion: SuggestionViewModel, errorCallback: ConstructorError = null) { + fun trackSearchSubmit(searchTerm: String, originalQuery: String, group: Group?, errorCallback: ConstructorError = null) { val sessionId = preferenceHelper.getSessionId(sessionIncrementEventHandler) val encodedParams: ArrayList> = arrayListOf() - suggestion.group?.groupId?.let { encodedParams.add(Constants.QueryConstants.GROUP_ID.urlEncode() to it) } - suggestion.group?.displayName?.let { encodedParams.add(Constants.QueryConstants.GROUP_DISPLAY_NAME.urlEncode() to it.urlEncode()) } - disposable.add(dataManager.trackSearch(suggestion.term, + group?.groupId?.let { encodedParams.add(Constants.QueryConstants.GROUP_ID.urlEncode() to it) } + group?.displayName?.let { encodedParams.add(Constants.QueryConstants.GROUP_DISPLAY_NAME.urlEncode() to it.urlEncode()) } + disposable.add(dataManager.trackSearchSubmit(searchTerm, arrayOf(Constants.QueryConstants.SESSION to sessionId.toString(), - Constants.QueryConstants.ORIGINAL_QUERY to query, + Constants.QueryConstants.ORIGINAL_QUERY to originalQuery, Constants.QueryConstants.EVENT to Constants.QueryValues.EVENT_SEARCH), encodedParams.toTypedArray()) .subscribe({ - context.broadcastIntent(Constants.EVENT_QUERY_SENT, Constants.EXTRA_TERM to query) + context.broadcastIntent(Constants.EVENT_QUERY_SENT, Constants.EXTRA_TERM to searchTerm) }, { it.printStackTrace() errorCallback?.invoke(it) @@ -139,11 +139,11 @@ object ConstructorIo { })) } - fun trackConversion(itemId: String, term: String = "TERM_UNKNOWN", revenue: String? = null, errorCallback: ConstructorError = null) { + fun trackConversion(itemName: String, customerId: String, revenue: Double?, searchTerm: String = Constants.QueryConstants.TERM_UNKNOWN, sectionName: String? = null, errorCallback: ConstructorError = null) { val sessionId = preferenceHelper.getSessionId(sessionIncrementEventHandler) - disposable.add(dataManager.trackConversion(term, itemId, revenue, + disposable.add(dataManager.trackConversion(searchTerm, itemName, customerId, "%.2f".format(revenue), arrayOf(Constants.QueryConstants.SESSION to sessionId.toString(), - Constants.QueryConstants.AUTOCOMPLETE_SECTION to preferenceHelper.defaultItemSection)).subscribeOn(Schedulers.io()) + Constants.QueryConstants.AUTOCOMPLETE_SECTION to (sectionName ?: preferenceHelper.defaultItemSection))).subscribeOn(Schedulers.io()) .subscribe({}, { t -> t.printStackTrace() errorCallback?.invoke(t) @@ -151,11 +151,12 @@ object ConstructorIo { })) } - fun trackSearchResultClickThrough(term: String, itemId: String, position: String? = null, errorCallback: ConstructorError = null) { + fun trackSearchResultClick(itemName: String, customerId: String, searchTerm: String = Constants.QueryConstants.TERM_UNKNOWN, sectionName: String? = null, errorCallback: ConstructorError = null) { val sessionId = preferenceHelper.getSessionId(sessionIncrementEventHandler) - disposable.add(dataManager.trackSearchResultClickThrough(term, itemId, position, + val sName = sectionName ?: preferenceHelper.defaultItemSection + disposable.add(dataManager.trackSearchResultClick(itemName, customerId, searchTerm, arrayOf(Constants.QueryConstants.SESSION to sessionId.toString(), - Constants.QueryConstants.AUTOCOMPLETE_SECTION to preferenceHelper.defaultItemSection)).subscribeOn(Schedulers.io()) + Constants.QueryConstants.AUTOCOMPLETE_SECTION to sName)).subscribeOn(Schedulers.io()) .subscribe({}, { t -> t.printStackTrace() errorCallback?.invoke(t) diff --git a/library/src/main/java/io/constructor/data/DataManager.kt b/library/src/main/java/io/constructor/data/DataManager.kt index ffb575a1..544a58d3 100755 --- a/library/src/main/java/io/constructor/data/DataManager.kt +++ b/library/src/main/java/io/constructor/data/DataManager.kt @@ -25,24 +25,24 @@ constructor(private val constructorApi: ConstructorApi) { } }.toObservable() - fun trackSelect(term: String, params: Array> = arrayOf(), encodedParams: Array> = arrayOf()): Completable { - return constructorApi.trackSelect(term, params.toMap(), encodedParams.toMap()) + fun trackAutocompleteSelect(term: String, params: Array> = arrayOf(), encodedParams: Array> = arrayOf()): Completable { + return constructorApi.trackAutocompleteSelect(term, params.toMap(), encodedParams.toMap()) } - fun trackSearch(term: String, params: Array> = arrayOf(), encodedParams: Array> = arrayOf()): Completable { - return constructorApi.trackSearch(term, params.toMap(), encodedParams.toMap()) + fun trackSearchSubmit(term: String, params: Array> = arrayOf(), encodedParams: Array> = arrayOf()): Completable { + return constructorApi.trackSearchSubmit(term, params.toMap(), encodedParams.toMap()) } fun trackSessionStart(params: Array>): Completable { return constructorApi.trackSessionStart(params.toMap()) } - fun trackConversion(term: String, itemId: String, revenue: String? = null, params: Array> = arrayOf()): Completable { - return constructorApi.trackConversion(term, itemId, revenue, params.toMap()) + fun trackConversion(term: String, itemName: String, customerId: String, revenue: String? = null, params: Array> = arrayOf()): Completable { + return constructorApi.trackConversion(term, itemName, customerId, revenue, params.toMap()) } - fun trackSearchResultClickThrough(term: String, itemId: String, position: String? = null, params: Array> = arrayOf()): Completable { - return constructorApi.trackSearchResultClickThrough(term, itemId, position, params.toMap()) + fun trackSearchResultClick(itemName: String, customerId: String, term: String, params: Array> = arrayOf()): Completable { + return constructorApi.trackSearchResultTerm(term, itemName, customerId, params.toMap()) } fun trackSearchResultLoaded(term: String, resultCount: Int, params: Array>): Completable { 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 348e9ffc..34f3f517 100755 --- a/library/src/main/java/io/constructor/data/remote/ConstructorApi.kt +++ b/library/src/main/java/io/constructor/data/remote/ConstructorApi.kt @@ -15,19 +15,19 @@ interface ConstructorApi { fun getSuggestions(@Path("value") value: String, @QueryMap data: Map): Single> @GET(ApiPaths.URL_SELECT_EVENT) - fun trackSelect(@Path("term") term: String, @QueryMap data: Map, @QueryMap(encoded = true) encodedData: Map): Completable + fun trackAutocompleteSelect(@Path("term") term: String, @QueryMap data: Map, @QueryMap(encoded = true) encodedData: Map): Completable @GET(ApiPaths.URL_SEARCH_EVENT) - fun trackSearch(@Path("term") term: String, @QueryMap data: Map, @QueryMap(encoded = true) encodedData: Map): Completable + fun trackSearchSubmit(@Path("term") term: String, @QueryMap data: Map, @QueryMap(encoded = true) encodedData: Map): Completable @GET(ApiPaths.URL_SESSION_START_EVENT) fun trackSessionStart(@QueryMap params: Map): Completable @GET(ApiPaths.URL_CONVERT_EVENT) - fun trackConversion(@Path("term") term: String, @Query("item_id") itemId: String, @Query("revenue") revenue: String?, @QueryMap params: Map): Completable + fun trackConversion(@Path("term") term: String, @Query("name") itemName: String, @Query("customer_id") customerId: String, @Query("revenue") revenue: String?, @QueryMap params: Map): Completable @GET(ApiPaths.URL_CLICK_THROUGH_EVENT) - fun trackSearchResultClickThrough(@Path("term") term: String, @Query("item_id") itemId: String, @Query("position") position: String?, @QueryMap params: Map): Completable + fun trackSearchResultTerm(@Path("term") term: String, @Query("name") itemName: String, @Query("customer_id") customerId: String, @QueryMap params: Map): Completable @GET(ApiPaths.URL_BEHAVIOR) fun trackSearchResultLoaded(@Query("term") term: String, @Query("num_results") resultCount: Int, @QueryMap params: Map): Completable diff --git a/library/src/main/java/io/constructor/service/OnSearchService.kt b/library/src/main/java/io/constructor/service/OnSearchService.kt index 362657b7..23d6613e 100755 --- a/library/src/main/java/io/constructor/service/OnSearchService.kt +++ b/library/src/main/java/io/constructor/service/OnSearchService.kt @@ -18,11 +18,11 @@ class OnSearchService : IntentService("OnSearchService") { } } - override fun onHandleIntent(intent: Intent?) { - val query: String? = intent?.getStringExtra(Constants.EXTRA_QUERY) - val suggestion: SuggestionViewModel = intent?.getSerializableExtra(Constants.EXTRA_SUGGESTION) as SuggestionViewModel + override fun onHandleIntent(intent: Intent) { + val query: String = intent.getStringExtra(Constants.EXTRA_QUERY) + val suggestion: SuggestionViewModel = intent.getSerializableExtra(Constants.EXTRA_SUGGESTION) as SuggestionViewModel if (!suggestion.term.isBlank()) { - ConstructorIo.trackSearch(query!!, suggestion) + ConstructorIo.trackSearchSubmit(suggestion.term, query, suggestion.group) } } } \ No newline at end of file diff --git a/library/src/main/java/io/constructor/service/OnSelectService.kt b/library/src/main/java/io/constructor/service/OnSelectService.kt index 52715ec8..ab97e34e 100755 --- a/library/src/main/java/io/constructor/service/OnSelectService.kt +++ b/library/src/main/java/io/constructor/service/OnSelectService.kt @@ -22,11 +22,11 @@ class OnSelectService : IntentService("OnSelectService") { } - override fun onHandleIntent(intent: Intent?) { - val query: String? = intent?.getStringExtra(Constants.EXTRA_QUERY) - val suggestion: SuggestionViewModel = intent?.getSerializableExtra(Constants.EXTRA_SUGGESTION) as SuggestionViewModel + override fun onHandleIntent(intent: Intent) { + val query: String = intent.getStringExtra(Constants.EXTRA_QUERY) + val suggestion: SuggestionViewModel = intent.getSerializableExtra(Constants.EXTRA_SUGGESTION) as SuggestionViewModel if (!suggestion.term.isBlank()) { - ConstructorIo.trackSelect(query!!, suggestion) + ConstructorIo.trackAutocompleteSelect(suggestion.term, query, suggestion.section!!, suggestion.group) } } } \ 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 cc7dcedf..9ddcdd35 100755 --- a/library/src/test/java/io/constructor/core/ConstructorIoTest.kt +++ b/library/src/test/java/io/constructor/core/ConstructorIoTest.kt @@ -157,8 +157,8 @@ class ConstructorIoTest { fun trackSelectSuccess() { staticMockk("io.constructor.util.ExtensionsKt").use { every { ctx.broadcastIntent(any(), any()) } returns Unit - every { data.trackSelect(any(), any(), any()) } returns Completable.complete() - constructorIo.trackSelect("doggy dog", dummySuggestion) + every { data.trackAutocompleteSelect(any(), any(), any()) } returns Completable.complete() + constructorIo.trackAutocompleteSelect("doggy dog", "dog", "section1", dummySuggestion.group) verify(exactly = 1) { ctx.broadcastIntent(any(), any()) } } } @@ -167,8 +167,8 @@ class ConstructorIoTest { fun trackSelectError() { staticMockk("io.constructor.util.ExtensionsKt").use { every { ctx.broadcastIntent(any(), any()) } returns Unit - every { data.trackSelect(any(), any(), any()) } returns Completable.error(Exception()) - constructorIo.trackSelect("doggy dog", dummySuggestion) + every { data.trackAutocompleteSelect(any(), any(), any()) } returns Completable.error(Exception()) + constructorIo.trackAutocompleteSelect("doggy dog", "dog", "section1", dummySuggestion.group) verify(exactly = 0) { ctx.broadcastIntent(any(), any()) } } } @@ -177,8 +177,8 @@ class ConstructorIoTest { fun trackSearchSuccess() { staticMockk("io.constructor.util.ExtensionsKt").use { every { ctx.broadcastIntent(any(), any()) } returns Unit - every { data.trackSearch(any(), any(), any()) } returns Completable.complete() - constructorIo.trackSearch("doggy dog", dummySuggestion) + every { data.trackSearchSubmit(any(), any(), any()) } returns Completable.complete() + constructorIo.trackSearchSubmit("doggy dog", "dog", dummySuggestion.group) verify(exactly = 1) { ctx.broadcastIntent(any(), any()) } } } @@ -228,8 +228,8 @@ class ConstructorIoTest { fun trackSearchError() { staticMockk("io.constructor.util.ExtensionsKt").use { every { ctx.broadcastIntent(any(), any()) } returns Unit - every { data.trackSearch(any(), any(), any()) } returns Completable.error(Exception()) - constructorIo.trackSearch("doggy dog", dummySuggestion) + every { data.trackSearchSubmit(any(), any(), any()) } returns Completable.error(Exception()) + constructorIo.trackSearchSubmit("doggy dog", "dog", dummySuggestion.group) verify(exactly = 0) { ctx.broadcastIntent(any(), any()) } } } @@ -237,17 +237,17 @@ class ConstructorIoTest { @Test fun trackConversion() { every { pref.defaultItemSection } returns "Products" - every { data.trackConversion(any(), any(), any(), any()) } returns Completable.complete() - constructorIo.trackConversion(itemId = "1") - verify(exactly = 1) { data.trackConversion(any(), any(), any(), any()) } + every { data.trackConversion(any(), any(), any(), any(), any()) } returns Completable.complete() + constructorIo.trackConversion("corn", "id1", 11.99) + verify(exactly = 1) { data.trackConversion("TERM_UNKNOWN", any(), any(), any(), any()) } } @Test fun trackSearchResultClickThrough() { every { pref.defaultItemSection } returns "Products" - every { data.trackSearchResultClickThrough(any(), any(), any(), any()) } returns Completable.complete() - constructorIo.trackSearchResultClickThrough("1", "1") - verify(exactly = 1) { data.trackSearchResultClickThrough(any(), any(), any(), any()) } + every { data.trackSearchResultClick(any(), any(), any(), any()) } returns Completable.complete() + constructorIo.trackSearchResultClick("1", "1") + verify(exactly = 1) { data.trackSearchResultClick(any(), any(), any(), any()) } } @Test diff --git a/library/src/test/java/io/constructor/data/DataManagerTest.kt b/library/src/test/java/io/constructor/data/DataManagerTest.kt index e787ca27..d5c46571 100755 --- a/library/src/test/java/io/constructor/data/DataManagerTest.kt +++ b/library/src/test/java/io/constructor/data/DataManagerTest.kt @@ -73,36 +73,36 @@ class DataManagerTest { @Test fun trackSelect() { - every { constructorApi.trackSelect(any(), any(),any()) } returns Completable.complete() - dataManager.trackSelect("titanic") - verify(exactly = 1) { constructorApi.trackSelect(any(), any(), any())} + every { constructorApi.trackAutocompleteSelect(any(), any(),any()) } returns Completable.complete() + dataManager.trackAutocompleteSelect("titanic") + verify(exactly = 1) { constructorApi.trackAutocompleteSelect(any(), any(), any())} } @Test fun trackSelectError() { - every { constructorApi.trackSelect(any(), any(),any()) } returns Completable.error(Exception()) - val observer = dataManager.trackSelect("titanic").test() + every { constructorApi.trackAutocompleteSelect(any(), any(),any()) } returns Completable.error(Exception()) + val observer = dataManager.trackAutocompleteSelect("titanic").test() observer.assertError { true } - verify(exactly = 1) { constructorApi.trackSelect(any(), any(), any())} + verify(exactly = 1) { constructorApi.trackAutocompleteSelect(any(), any(), any())} } @Test fun trackSearch() { - every { constructorApi.trackSearch(any(), any(), any()) } returns Completable.complete() - dataManager.trackSearch("titanic") - verify(exactly = 1) { constructorApi.trackSearch(any(), any(), any())} + every { constructorApi.trackSearchSubmit(any(), any(), any()) } returns Completable.complete() + dataManager.trackSearchSubmit("titanic") + verify(exactly = 1) { constructorApi.trackSearchSubmit(any(), any(), any())} } @Test fun trackSearchError() { - every { constructorApi.trackSearch(any(), any(), any()) } returns Completable.error(Exception()) - val observer = dataManager.trackSearch("titanic").test() + every { constructorApi.trackSearchSubmit(any(), any(), any()) } returns Completable.error(Exception()) + val observer = dataManager.trackSearchSubmit("titanic").test() observer.assertError { true } - verify(exactly = 1) { constructorApi.trackSearch(any(), any(), any())} + verify(exactly = 1) { constructorApi.trackSearchSubmit(any(), any(), any())} } @Test @@ -124,34 +124,34 @@ class DataManagerTest { @Test fun trackConversion() { - every { constructorApi.trackConversion(any(), any(), any(), any()) } returns Completable.complete() - dataManager.trackConversion("testTerm", "1") - verify(exactly = 1) { constructorApi.trackConversion(any(), any(), any(), any())} + every { constructorApi.trackConversion(any(), any(), any(), any(), any()) } returns Completable.complete() + dataManager.trackConversion("testTerm", "item1", "id1", "11.99") + verify(exactly = 1) { constructorApi.trackConversion(any(), any(), any(), any(), any())} } @Test fun trackConversionError() { - every { constructorApi.trackConversion(any(), any(), any(), any()) } returns Completable.error(Exception()) - val observer = dataManager.trackConversion("testTerm", "1").test() + every { constructorApi.trackConversion(any(), any(), any(), any(), any()) } returns Completable.error(Exception()) + val observer = dataManager.trackConversion("testTerm", "item1", "id1").test() observer.assertError { true } - verify(exactly = 1) { constructorApi.trackConversion(any(), any(), any(), any())} + verify(exactly = 1) { constructorApi.trackConversion(any(), any(), any(), any(), any())} } @Test fun trackSearchResultClickThrough() { - every { constructorApi.trackSearchResultClickThrough(any(), any(), any(), any()) } returns Completable.complete() - dataManager.trackSearchResultClickThrough("term", "1") - verify(exactly = 1) { constructorApi.trackSearchResultClickThrough(any(), any(), any(), any())} + every { constructorApi.trackSearchResultTerm(any(), any(), any(), any()) } returns Completable.complete() + dataManager.trackSearchResultClick("term", "id1", "term1") + verify(exactly = 1) { constructorApi.trackSearchResultTerm(any(), any(), any(), any())} } @Test fun trackSearchResultClickThroughError() { - every { constructorApi.trackSearchResultClickThrough(any(), any(), any(), any()) } returns Completable.error(Exception()) - val observer = dataManager.trackSearchResultClickThrough("term", "1").test() + every { constructorApi.trackSearchResultTerm(any(), any(), any(), any()) } returns Completable.error(Exception()) + val observer = dataManager.trackSearchResultClick("term", "1", "term1").test() observer.assertError { true } - verify(exactly = 1) { constructorApi.trackSearchResultClickThrough(any(), any(), any(), any())} + verify(exactly = 1) { constructorApi.trackSearchResultTerm(any(), any(), any(), any())} } @Test diff --git a/sample/src/main/java/io/constructor/sample/MainActivity.kt b/sample/src/main/java/io/constructor/sample/MainActivity.kt index 6186b2d4..ead8b358 100755 --- a/sample/src/main/java/io/constructor/sample/MainActivity.kt +++ b/sample/src/main/java/io/constructor/sample/MainActivity.kt @@ -14,8 +14,8 @@ class MainActivity : AppCompatActivity() { setContentView(R.layout.activity_main) button.setOnClickListener { startActivity(Intent(this, SampleActivity::class.java)) } button2.setOnClickListener { startActivity(Intent(this, SampleActivityCustom::class.java)) } - button3.setOnClickListener { ConstructorIo.trackConversion("testId", revenue = "$11.99") } - button4.setOnClickListener { ConstructorIo.trackSearchResultClickThrough("testTerm", "testId", "1") } + button3.setOnClickListener { ConstructorIo.trackConversion("testId", "id", 11.99) } + button4.setOnClickListener { ConstructorIo.trackSearchResultClick("testTerm", "testId", "1") } button5.setOnClickListener { ConstructorIo.trackSearchResultLoaded("testTerm", Random().nextInt(99) + 1) } } } From 5181cc879b10489ddff86491f7e869a8cd640aa5 Mon Sep 17 00:00:00 2001 From: Zubin Tiku Date: Tue, 5 Feb 2019 23:21:20 -0800 Subject: [PATCH 2/5] Fixed naming conventions --- README.md | 38 +++++++++++++++---- build.gradle | 2 +- .../java/io/constructor/core/ConstructorIo.kt | 6 +-- .../java/io/constructor/data/DataManager.kt | 4 +- .../io/constructor/data/remote/ApiPaths.kt | 4 +- .../constructor/data/remote/ConstructorApi.kt | 6 +-- .../ui/suggestion/SuggestionsPresenter.kt | 2 +- .../io/constructor/core/ConstructorIoTest.kt | 16 ++++---- .../io/constructor/data/DataManagerTest.kt | 28 +++++++------- .../io/constructor/sample/MainActivity.kt | 2 +- sample/src/main/res/layout/activity_main.xml | 4 +- 11 files changed, 68 insertions(+), 44 deletions(-) diff --git a/README.md b/README.md index c2c0ded4..b95b6f18 100755 --- a/README.md +++ b/README.md @@ -136,18 +136,42 @@ The Android Client sends behavioral events to [Constructor.io](http://constructo Three types of these events exist: 1. **General Events** are sent as needed when an instance of the Client is created or initialized -1. **Autocomplete Events** measure user interaction with autocomplete results and the `CIOAutocompleteViewController` sends them automatically. +1. **Autocomplete Events** measure user interaction with autocomplete results and extending from `BaseSuggestionFragment` sends them automatically. 1. **Search Events** measure user interaction with search results and the consuming app has to explicitly instrument them itself +### Autocomplete Events + +If you decide to extend from the `BaseSuggestionFragment`, these events are sent automatically. + ```kotlin import io.constructor.core.ConstructorIo -// Track search results loaded (term, resultCount) -ConstructorIo.trackSearchResultLoaded("a search term", 123) +// Track when the user focuses into the search bar +ConstructorIo.trackInputFocus("") -// Track search result click (term, itemId, position) -ConstructorIo.trackSearchResultClickThrough("a search term", "an item id", "1") +// Track when the user selects an autocomplete suggestion +ConstructorIo.trackAutocompleteSelect("toothpicks", "tooth", "Search Suggestions") -// Track conversion (item id, term, revenue) -constructorIO.trackConversion("an item id", "a search term", "45.00") +// Track when the user submits a search (either by selecting a suggestion or not selecting a suggestion) +ConstructorIo.trackSearchSubmit("toothpicks", "tooth") ``` + +### Search Events + +These events should be sent manually by the consuming app. + +```kotlin +import io.constructor.core.ConstructorIo + +// Track when search results are loaded into view +ConstructorIo.trackSearchResultsLoaded("tooth", 789) + +// Track when a search result is clicked +ConstructorIo.trackSearchResultClick("Fashionable Toothpicks", "1234567-AB", "tooth") + +// Track when a search result converts +ConstructorIo.trackConversion("Fashionable Toothpicks", "1234567-AB", 12.99, "tooth") + +// Track when products are purchased +ConstructorIo.trackPurchase(customerIDs: ["123-AB", "456-CD"]) +``` \ No newline at end of file diff --git a/build.gradle b/build.gradle index a222e170..3536be0b 100755 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,5 @@ buildscript { - ext.kotlin_version = '1.2.41' + ext.kotlin_version = '1.2.31' repositories { google() jcenter() diff --git a/library/src/main/java/io/constructor/core/ConstructorIo.kt b/library/src/main/java/io/constructor/core/ConstructorIo.kt index cc33af98..d0b87aa6 100755 --- a/library/src/main/java/io/constructor/core/ConstructorIo.kt +++ b/library/src/main/java/io/constructor/core/ConstructorIo.kt @@ -160,13 +160,13 @@ object ConstructorIo { .subscribe({}, { t -> t.printStackTrace() errorCallback?.invoke(t) - e("Conversion click through event error: ${t.message}") + e("Search result click event error: ${t.message}") })) } - fun trackSearchResultLoaded(term: String, resultCount: Int, errorCallback: ConstructorError = null) { + fun trackSearchResultsLoaded(term: String, resultCount: Int, errorCallback: ConstructorError = null) { val sessionId = preferenceHelper.getSessionId(sessionIncrementEventHandler) - disposable.add(dataManager.trackSearchResultLoaded(term, resultCount, + disposable.add(dataManager.trackSearchResultsLoaded(term, resultCount, arrayOf(Constants.QueryConstants.SESSION to sessionId.toString(), Constants.QueryConstants.ACTION to Constants.QueryValues.EVENT_SEARCH_RESULTS)).subscribeOn(Schedulers.io()) .subscribe({}, { t -> diff --git a/library/src/main/java/io/constructor/data/DataManager.kt b/library/src/main/java/io/constructor/data/DataManager.kt index 544a58d3..d4582b01 100755 --- a/library/src/main/java/io/constructor/data/DataManager.kt +++ b/library/src/main/java/io/constructor/data/DataManager.kt @@ -45,8 +45,8 @@ constructor(private val constructorApi: ConstructorApi) { return constructorApi.trackSearchResultTerm(term, itemName, customerId, params.toMap()) } - fun trackSearchResultLoaded(term: String, resultCount: Int, params: Array>): Completable { - return constructorApi.trackSearchResultLoaded(term, resultCount, params.toMap()) + fun trackSearchResultsLoaded(term: String, resultCount: Int, params: Array>): Completable { + return constructorApi.trackSearchResultsLoaded(term, resultCount, params.toMap()) } fun trackInputFocus(term: String?, params: Array>): Completable { 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 f4cf1baa..d92d34f5 100755 --- a/library/src/main/java/io/constructor/data/remote/ApiPaths.kt +++ b/library/src/main/java/io/constructor/data/remote/ApiPaths.kt @@ -5,8 +5,8 @@ object ApiPaths { const val URL_SELECT_EVENT = "autocomplete/{term}/select" const val URL_SEARCH_EVENT = "autocomplete/{term}/search" const val URL_SESSION_START_EVENT = "behavior" - const val URL_CONVERT_EVENT = "autocomplete/{term}/conversion" - const val URL_CLICK_THROUGH_EVENT = "autocomplete/{term}/click_through" + const val URL_CONVERSION_EVENT = "autocomplete/{term}/conversion" + const val URL_SEARCH_CLICK_EVENT = "autocomplete/{term}/click_through" const val URL_BEHAVIOR = "behavior" const val URL_PURCHASE = "autocomplete/TERM_UNKNOWN/purchase" 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 34f3f517..e8d57c23 100755 --- a/library/src/main/java/io/constructor/data/remote/ConstructorApi.kt +++ b/library/src/main/java/io/constructor/data/remote/ConstructorApi.kt @@ -23,14 +23,14 @@ interface ConstructorApi { @GET(ApiPaths.URL_SESSION_START_EVENT) fun trackSessionStart(@QueryMap params: Map): Completable - @GET(ApiPaths.URL_CONVERT_EVENT) + @GET(ApiPaths.URL_CONVERSION_EVENT) fun trackConversion(@Path("term") term: String, @Query("name") itemName: String, @Query("customer_id") customerId: String, @Query("revenue") revenue: String?, @QueryMap params: Map): Completable - @GET(ApiPaths.URL_CLICK_THROUGH_EVENT) + @GET(ApiPaths.URL_SEARCH_CLICK_EVENT) fun trackSearchResultTerm(@Path("term") term: String, @Query("name") itemName: String, @Query("customer_id") customerId: String, @QueryMap params: Map): Completable @GET(ApiPaths.URL_BEHAVIOR) - fun trackSearchResultLoaded(@Query("term") term: String, @Query("num_results") resultCount: Int, @QueryMap params: Map): Completable + fun trackSearchResultsLoaded(@Query("term") term: String, @Query("num_results") resultCount: Int, @QueryMap params: Map): Completable @GET(ApiPaths.URL_BEHAVIOR) fun trackInputFocus(@Query("term") term: String?, @QueryMap params: Map): Completable diff --git a/library/src/main/java/io/constructor/ui/suggestion/SuggestionsPresenter.kt b/library/src/main/java/io/constructor/ui/suggestion/SuggestionsPresenter.kt index 05c7ed0d..0bdfecd5 100755 --- a/library/src/main/java/io/constructor/ui/suggestion/SuggestionsPresenter.kt +++ b/library/src/main/java/io/constructor/ui/suggestion/SuggestionsPresenter.kt @@ -48,7 +48,7 @@ constructor(private val preferencesHelper: PreferencesHelper) : BasePresenter?>>()).subscribe { data -> data.onValue { - ConstructorIo.trackSearchResultLoaded(text, it!!.size) + ConstructorIo.trackSearchResultsLoaded(text, it!!.size) mvpView.showSuggestions(it, preferencesHelper.groupsShownForFirstTerm) } data.onError { diff --git a/library/src/test/java/io/constructor/core/ConstructorIoTest.kt b/library/src/test/java/io/constructor/core/ConstructorIoTest.kt index 9ddcdd35..f88c845d 100755 --- a/library/src/test/java/io/constructor/core/ConstructorIoTest.kt +++ b/library/src/test/java/io/constructor/core/ConstructorIoTest.kt @@ -91,7 +91,7 @@ class ConstructorIoTest { } @Test - fun verifySessionStartUrl() { + fun verifySessionStartEventUrl() { val expected = "https://ac.cnstrc.com/behavior?c=${BuildConfig.CLIENT_VERSION}&s=1&action=session_start&key=testKey&_dt=1520000000000" val urlBuilder = HttpUrl.Builder().scheme("https") .host("ac.cnstrc.com") @@ -106,7 +106,7 @@ class ConstructorIoTest { } @Test - fun verifySearchClickThroughEvent() { + fun verifySearchResultClickEventUrl() { val expected = "https://ac.cnstrc.com/autocomplete/term/click_through?c=${BuildConfig.CLIENT_VERSION}&s=1&autocomplete_section=Products&key=testKey&_dt=1520000000000" val urlBuilder = HttpUrl.Builder().scheme("https") .host("ac.cnstrc.com") @@ -123,7 +123,7 @@ class ConstructorIoTest { } @Test - fun verifySearchLoadedEventUrl() { + fun verifySearchResultsLoadedEventUrl() { val expected = "https://ac.cnstrc.com/behavior?c=${BuildConfig.CLIENT_VERSION}&s=1&action=search-results&key=testKey&_dt=1520000000000" val urlBuilder = HttpUrl.Builder().scheme("https") .host("ac.cnstrc.com") @@ -154,7 +154,7 @@ class ConstructorIoTest { } @Test - fun trackSelectSuccess() { + fun trackAutocompleteSelectSuccess() { staticMockk("io.constructor.util.ExtensionsKt").use { every { ctx.broadcastIntent(any(), any()) } returns Unit every { data.trackAutocompleteSelect(any(), any(), any()) } returns Completable.complete() @@ -164,7 +164,7 @@ class ConstructorIoTest { } @Test - fun trackSelectError() { + fun trackAutocompleteSelectError() { staticMockk("io.constructor.util.ExtensionsKt").use { every { ctx.broadcastIntent(any(), any()) } returns Unit every { data.trackAutocompleteSelect(any(), any(), any()) } returns Completable.error(Exception()) @@ -174,7 +174,7 @@ class ConstructorIoTest { } @Test - fun trackSearchSuccess() { + fun trackSearchSubmitSuccess() { staticMockk("io.constructor.util.ExtensionsKt").use { every { ctx.broadcastIntent(any(), any()) } returns Unit every { data.trackSearchSubmit(any(), any(), any()) } returns Completable.complete() @@ -225,7 +225,7 @@ class ConstructorIoTest { } @Test - fun trackSearchError() { + fun trackSearchSubmitError() { staticMockk("io.constructor.util.ExtensionsKt").use { every { ctx.broadcastIntent(any(), any()) } returns Unit every { data.trackSearchSubmit(any(), any(), any()) } returns Completable.error(Exception()) @@ -243,7 +243,7 @@ class ConstructorIoTest { } @Test - fun trackSearchResultClickThrough() { + fun trackSearchResultClick() { every { pref.defaultItemSection } returns "Products" every { data.trackSearchResultClick(any(), any(), any(), any()) } returns Completable.complete() constructorIo.trackSearchResultClick("1", "1") diff --git a/library/src/test/java/io/constructor/data/DataManagerTest.kt b/library/src/test/java/io/constructor/data/DataManagerTest.kt index d5c46571..2ebfad37 100755 --- a/library/src/test/java/io/constructor/data/DataManagerTest.kt +++ b/library/src/test/java/io/constructor/data/DataManagerTest.kt @@ -72,14 +72,14 @@ class DataManagerTest { } @Test - fun trackSelect() { + fun trackAutocompleteSelect() { every { constructorApi.trackAutocompleteSelect(any(), any(),any()) } returns Completable.complete() dataManager.trackAutocompleteSelect("titanic") verify(exactly = 1) { constructorApi.trackAutocompleteSelect(any(), any(), any())} } @Test - fun trackSelectError() { + fun trackAutocompleteSelectError() { every { constructorApi.trackAutocompleteSelect(any(), any(),any()) } returns Completable.error(Exception()) val observer = dataManager.trackAutocompleteSelect("titanic").test() observer.assertError { @@ -89,14 +89,14 @@ class DataManagerTest { } @Test - fun trackSearch() { + fun trackSearchSubmit() { every { constructorApi.trackSearchSubmit(any(), any(), any()) } returns Completable.complete() dataManager.trackSearchSubmit("titanic") verify(exactly = 1) { constructorApi.trackSearchSubmit(any(), any(), any())} } @Test - fun trackSearchError() { + fun trackSearchSubmitError() { every { constructorApi.trackSearchSubmit(any(), any(), any()) } returns Completable.error(Exception()) val observer = dataManager.trackSearchSubmit("titanic").test() observer.assertError { @@ -140,14 +140,14 @@ class DataManagerTest { } @Test - fun trackSearchResultClickThrough() { + fun trackSearchResultClick() { every { constructorApi.trackSearchResultTerm(any(), any(), any(), any()) } returns Completable.complete() dataManager.trackSearchResultClick("term", "id1", "term1") verify(exactly = 1) { constructorApi.trackSearchResultTerm(any(), any(), any(), any())} } @Test - fun trackSearchResultClickThroughError() { + fun trackSearchResultClickError() { every { constructorApi.trackSearchResultTerm(any(), any(), any(), any()) } returns Completable.error(Exception()) val observer = dataManager.trackSearchResultClick("term", "1", "term1").test() observer.assertError { true } @@ -155,18 +155,18 @@ class DataManagerTest { } @Test - fun trackSearchResultLoaded() { - every { constructorApi.trackSearchResultLoaded(any(), any(), any()) } returns Completable.complete() - dataManager.trackSearchResultLoaded("term", 10, arrayOf()) - verify(exactly = 1) { constructorApi.trackSearchResultLoaded(any(), any(), any())} + fun trackSearchResultsLoaded() { + every { constructorApi.trackSearchResultsLoaded(any(), any(), any()) } returns Completable.complete() + dataManager.trackSearchResultsLoaded("term", 10, arrayOf()) + verify(exactly = 1) { constructorApi.trackSearchResultsLoaded(any(), any(), any())} } @Test - fun trackSearchResultLoadedError() { - every { constructorApi.trackSearchResultLoaded(any(), any(), any()) } returns Completable.error(Exception()) - val observer = dataManager.trackSearchResultLoaded("term", 10, arrayOf()).test() + fun trackSearchResultsLoadedError() { + every { constructorApi.trackSearchResultsLoaded(any(), any(), any()) } returns Completable.error(Exception()) + val observer = dataManager.trackSearchResultsLoaded("term", 10, arrayOf()).test() observer.assertError { true } - verify(exactly = 1) { constructorApi.trackSearchResultLoaded(any(), any(), any())} + verify(exactly = 1) { constructorApi.trackSearchResultsLoaded(any(), any(), any())} } @Test diff --git a/sample/src/main/java/io/constructor/sample/MainActivity.kt b/sample/src/main/java/io/constructor/sample/MainActivity.kt index ead8b358..61a7a5a5 100755 --- a/sample/src/main/java/io/constructor/sample/MainActivity.kt +++ b/sample/src/main/java/io/constructor/sample/MainActivity.kt @@ -16,6 +16,6 @@ class MainActivity : AppCompatActivity() { button2.setOnClickListener { startActivity(Intent(this, SampleActivityCustom::class.java)) } button3.setOnClickListener { ConstructorIo.trackConversion("testId", "id", 11.99) } button4.setOnClickListener { ConstructorIo.trackSearchResultClick("testTerm", "testId", "1") } - button5.setOnClickListener { ConstructorIo.trackSearchResultLoaded("testTerm", Random().nextInt(99) + 1) } + button5.setOnClickListener { ConstructorIo.trackSearchResultsLoaded("testTerm", Random().nextInt(99) + 1) } } } diff --git a/sample/src/main/res/layout/activity_main.xml b/sample/src/main/res/layout/activity_main.xml index 312e6efa..ea623bb5 100755 --- a/sample/src/main/res/layout/activity_main.xml +++ b/sample/src/main/res/layout/activity_main.xml @@ -41,7 +41,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="16dp" - android:text="Trigger SearchThrough" + android:text="Trigger Search Result Click" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/button3" /> @@ -51,7 +51,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="16dp" - android:text="Trigger SearchResult Loaded" + android:text="Trigger Search Result Loaded" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/button4" /> From a60f143a741697ad6667bf896237733ec9affea0 Mon Sep 17 00:00:00 2001 From: Zubin Tiku Date: Tue, 5 Feb 2019 23:24:18 -0800 Subject: [PATCH 3/5] Updated README.md --- README.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index b95b6f18..f5386118 100755 --- a/README.md +++ b/README.md @@ -146,13 +146,13 @@ If you decide to extend from the `BaseSuggestionFragment`, these events are sent ```kotlin import io.constructor.core.ConstructorIo -// Track when the user focuses into the search bar +// Track when the user focuses into the search bar (searchTerm) ConstructorIo.trackInputFocus("") -// Track when the user selects an autocomplete suggestion +// Track when the user selects an autocomplete suggestion (searchTerm, originalQuery, sectionName) ConstructorIo.trackAutocompleteSelect("toothpicks", "tooth", "Search Suggestions") -// Track when the user submits a search (either by selecting a suggestion or not selecting a suggestion) +// Track when the user submits a search (searchTerm, originalQuery) ConstructorIo.trackSearchSubmit("toothpicks", "tooth") ``` @@ -163,15 +163,15 @@ These events should be sent manually by the consuming app. ```kotlin import io.constructor.core.ConstructorIo -// Track when search results are loaded into view +// Track when search results are loaded into view (searchTerm, resultCount) ConstructorIo.trackSearchResultsLoaded("tooth", 789) -// Track when a search result is clicked +// Track when a search result is clicked (itemName, customerId, searchTerm) ConstructorIo.trackSearchResultClick("Fashionable Toothpicks", "1234567-AB", "tooth") -// Track when a search result converts +// Track when a search result converts (itemName, customerId, revenue, searchTerm) ConstructorIo.trackConversion("Fashionable Toothpicks", "1234567-AB", 12.99, "tooth") -// Track when products are purchased +// Track when products are purchased (customerIds) ConstructorIo.trackPurchase(customerIDs: ["123-AB", "456-CD"]) ``` \ No newline at end of file From 64e26b38b263bcdce7e786c376206e276cfae404 Mon Sep 17 00:00:00 2001 From: Zubin Tiku Date: Tue, 5 Feb 2019 23:25:08 -0800 Subject: [PATCH 4/5] Reverted build.gradle --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 3536be0b..a222e170 100755 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,5 @@ buildscript { - ext.kotlin_version = '1.2.31' + ext.kotlin_version = '1.2.41' repositories { google() jcenter() From 86dbd3e60353b96a785d444f87a8f228104510ac Mon Sep 17 00:00:00 2001 From: Zubin Tiku Date: Tue, 5 Feb 2019 23:31:48 -0800 Subject: [PATCH 5/5] Updated naming --- .../src/main/java/io/constructor/data/remote/ApiPaths.kt | 6 +++--- .../main/java/io/constructor/data/remote/ConstructorApi.kt | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) 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 d92d34f5..2264b226 100755 --- a/library/src/main/java/io/constructor/data/remote/ApiPaths.kt +++ b/library/src/main/java/io/constructor/data/remote/ApiPaths.kt @@ -2,11 +2,11 @@ package io.constructor.data.remote object ApiPaths { const val URL_GET_SUGGESTIONS = "autocomplete/{value}" - const val URL_SELECT_EVENT = "autocomplete/{term}/select" - const val URL_SEARCH_EVENT = "autocomplete/{term}/search" + const val URL_AUTOCOMPLETE_SELECT_EVENT = "autocomplete/{term}/select" + const val URL_SEARCH_SUBMIT_EVENT = "autocomplete/{term}/search" const val URL_SESSION_START_EVENT = "behavior" const val URL_CONVERSION_EVENT = "autocomplete/{term}/conversion" - const val URL_SEARCH_CLICK_EVENT = "autocomplete/{term}/click_through" + const val URL_SEARCH_RESULT_CLICK_EVENT = "autocomplete/{term}/click_through" const val URL_BEHAVIOR = "behavior" const val URL_PURCHASE = "autocomplete/TERM_UNKNOWN/purchase" 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 e8d57c23..0a04d8ca 100755 --- a/library/src/main/java/io/constructor/data/remote/ConstructorApi.kt +++ b/library/src/main/java/io/constructor/data/remote/ConstructorApi.kt @@ -14,10 +14,10 @@ interface ConstructorApi { @GET(ApiPaths.URL_GET_SUGGESTIONS) fun getSuggestions(@Path("value") value: String, @QueryMap data: Map): Single> - @GET(ApiPaths.URL_SELECT_EVENT) + @GET(ApiPaths.URL_AUTOCOMPLETE_SELECT_EVENT) fun trackAutocompleteSelect(@Path("term") term: String, @QueryMap data: Map, @QueryMap(encoded = true) encodedData: Map): Completable - @GET(ApiPaths.URL_SEARCH_EVENT) + @GET(ApiPaths.URL_SEARCH_SUBMIT_EVENT) fun trackSearchSubmit(@Path("term") term: String, @QueryMap data: Map, @QueryMap(encoded = true) encodedData: Map): Completable @GET(ApiPaths.URL_SESSION_START_EVENT) @@ -26,7 +26,7 @@ interface ConstructorApi { @GET(ApiPaths.URL_CONVERSION_EVENT) fun trackConversion(@Path("term") term: String, @Query("name") itemName: String, @Query("customer_id") customerId: String, @Query("revenue") revenue: String?, @QueryMap params: Map): Completable - @GET(ApiPaths.URL_SEARCH_CLICK_EVENT) + @GET(ApiPaths.URL_SEARCH_RESULT_CLICK_EVENT) fun trackSearchResultTerm(@Path("term") term: String, @Query("name") itemName: String, @Query("customer_id") customerId: String, @QueryMap params: Map): Completable @GET(ApiPaths.URL_BEHAVIOR)