diff --git a/library/src/main/java/io/constructor/core/Constants.kt b/library/src/main/java/io/constructor/core/Constants.kt index 3ce0e588..77b4ea54 100755 --- a/library/src/main/java/io/constructor/core/Constants.kt +++ b/library/src/main/java/io/constructor/core/Constants.kt @@ -35,6 +35,10 @@ class Constants { const val FILTER_GROUP_ID = "filters[group_id]" const val FILTER_FACET = "filters[%s]" const val RESULT_ID = "result_id" + const val FILTER_NAME = "filter_name" + const val FILTER_VALUE = "filter_value" + const val RESULT_POSITION_ON_PAGE = "result_position_on_page" + const val RESULT_COUNT = "result_count" } 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 47289e0a..c2199f42 100755 --- a/library/src/main/java/io/constructor/core/ConstructorIo.kt +++ b/library/src/main/java/io/constructor/core/ConstructorIo.kt @@ -2,6 +2,7 @@ package io.constructor.core import android.annotation.SuppressLint import android.content.Context +import io.constructor.BuildConfig import io.constructor.data.ConstructorData import io.constructor.data.DataManager import io.constructor.data.local.PreferencesHelper @@ -10,6 +11,8 @@ import io.constructor.data.model.autocomplete.AutocompleteResponse import io.constructor.data.model.common.ResultGroup import io.constructor.data.model.search.SearchResponse import io.constructor.data.model.browse.BrowseResponse +import io.constructor.data.model.browse.BrowseResultClickRequestBody +import io.constructor.data.model.browse.BrowseResultLoadRequestBody import io.constructor.injection.component.AppComponent import io.constructor.injection.component.DaggerAppComponent import io.constructor.injection.module.AppModule @@ -354,9 +357,27 @@ object ConstructorIo { } internal fun trackBrowseResultsLoadedInternal(filterName: String, filterValue: String, resultCount: Int): Completable { preferenceHelper.getSessionId(sessionIncrementHandler) - return dataManager.trackBrowseResultsLoaded(filterName, filterValue, resultCount, arrayOf( - Constants.QueryConstants.ACTION to Constants.QueryValues.EVENT_BROWSE_RESULTS - )) + val browseResultLoadRequestBody = BrowseResultLoadRequestBody( + filterName, + filterValue, + resultCount, + BuildConfig.CLIENT_VERSION, + preferenceHelper.id, + preferenceHelper.getSessionId(), + preferenceHelper.apiKey, + configMemoryHolder.userId, + configMemoryHolder.segments, + true, + preferenceHelper.defaultItemSection, + System.currentTimeMillis().toString() + ) + + return dataManager.trackBrowseResultsLoaded( + browseResultLoadRequestBody, + arrayOf( + Constants.QueryConstants.ACTION to Constants.QueryValues.EVENT_BROWSE_RESULTS + ) + ) } /** @@ -377,10 +398,29 @@ object ConstructorIo { preferenceHelper.getSessionId(sessionIncrementHandler) val encodedParams: ArrayList> = arrayListOf() resultID?.let { encodedParams.add(Constants.QueryConstants.RESULT_ID.urlEncode() to it.urlEncode()) } - val sName = sectionName ?: preferenceHelper.defaultItemSection - return dataManager.trackBrowseResultClick(filterName, filterValue, customerId, resultPositionOnPage, arrayOf( - Constants.QueryConstants.AUTOCOMPLETE_SECTION to sName - ), encodedParams.toTypedArray()) + val section = sectionName ?: preferenceHelper.defaultItemSection + val browseResultClickRequestBody = BrowseResultClickRequestBody( + filterName, + filterValue, + customerId, + resultPositionOnPage, + BuildConfig.CLIENT_VERSION, + preferenceHelper.id, + preferenceHelper.getSessionId(), + preferenceHelper.apiKey, + configMemoryHolder.userId, + configMemoryHolder.segments, + true, + section, + System.currentTimeMillis().toString() + ) + + return dataManager.trackBrowseResultClick( + browseResultClickRequestBody, + arrayOf( + Constants.QueryConstants.AUTOCOMPLETE_SECTION to section + ), encodedParams.toTypedArray() + ) } diff --git a/library/src/main/java/io/constructor/data/DataManager.kt b/library/src/main/java/io/constructor/data/DataManager.kt index d43e9210..9b4c3fd9 100755 --- a/library/src/main/java/io/constructor/data/DataManager.kt +++ b/library/src/main/java/io/constructor/data/DataManager.kt @@ -4,6 +4,8 @@ import com.squareup.moshi.Moshi import io.constructor.data.model.autocomplete.AutocompleteResponse import io.constructor.data.model.search.SearchResponse import io.constructor.data.model.browse.BrowseResponse +import io.constructor.data.model.browse.BrowseResultClickRequestBody +import io.constructor.data.model.browse.BrowseResultLoadRequestBody import io.constructor.data.remote.ApiPaths import io.constructor.data.remote.ConstructorApi import io.reactivex.Completable @@ -115,12 +117,12 @@ constructor(private val constructorApi: ConstructorApi, private val moshi: Moshi }.toObservable() } - fun trackBrowseResultClick(filterName: String, filterValue: String, customerId: String, resultPositionOnPage: Int, params: Array> = arrayOf(), encodedParams: Array> = arrayOf()): Completable { - return constructorApi.trackBrowseResultClick(filterName, filterValue, customerId, resultPositionOnPage, params.toMap(), encodedParams.toMap()) + fun trackBrowseResultsLoaded(browseResultLoadRequestBody: BrowseResultLoadRequestBody, params: Array>): Completable { + return constructorApi.trackBrowseResultsLoaded(browseResultLoadRequestBody, params.toMap()) } - fun trackBrowseResultsLoaded(filterName: String, filterValue: String, resultCount: Int, params: Array>): Completable { - return constructorApi.trackBrowseResultsLoaded(filterName, filterValue, resultCount, params.toMap()) + fun trackBrowseResultClick(browseResultClickRequestBody: BrowseResultClickRequestBody, params: Array> = arrayOf(), encodedParams: Array> = arrayOf()): Completable { + return constructorApi.trackBrowseResultClick(browseResultClickRequestBody, params.toMap(), encodedParams.toMap()) } } \ No newline at end of file diff --git a/library/src/main/java/io/constructor/data/model/browse/BrowseResultClickRequestBody.kt b/library/src/main/java/io/constructor/data/model/browse/BrowseResultClickRequestBody.kt new file mode 100644 index 00000000..9e3347c8 --- /dev/null +++ b/library/src/main/java/io/constructor/data/model/browse/BrowseResultClickRequestBody.kt @@ -0,0 +1,21 @@ +package io.constructor.data.model.browse + +import com.squareup.moshi.Json +import io.constructor.data.model.common.*; +import java.io.Serializable + +data class BrowseResultClickRequestBody( + @Json(name = "filter_name") val filterName: String, + @Json(name = "filter_value") val filterValue: String, + @Json(name = "item_id") val item_id: String, + @Json(name = "result_position_on_page") val resultPositionOnPage: Int, + @Json(name = "c") val c: String, + @Json(name = "i") val i: String, + @Json(name = "s") val s: Int, + @Json(name = "key") val key: String, + @Json(name = "ui") val ui: String?, + @Json(name = "us") val us: List, + @Json(name= "beacon") val beacon: Boolean?, + @Json(name= "autocomplete_section") val autocomplete_section: String?, + @Json(name= "_dt") val _dt: String? +) : Serializable \ No newline at end of file diff --git a/library/src/main/java/io/constructor/data/model/browse/BrowseResultLoadRequestBody.kt b/library/src/main/java/io/constructor/data/model/browse/BrowseResultLoadRequestBody.kt new file mode 100644 index 00000000..af95dcd0 --- /dev/null +++ b/library/src/main/java/io/constructor/data/model/browse/BrowseResultLoadRequestBody.kt @@ -0,0 +1,20 @@ +package io.constructor.data.model.browse + +import com.squareup.moshi.Json +import io.constructor.data.model.common.*; +import java.io.Serializable + +data class BrowseResultLoadRequestBody( + @Json(name = "filter_name") val filterName: String, + @Json(name = "filter_value") val filterValue: String, + @Json(name = "result_count") val resultCount: Int, + @Json(name = "c") val c: String, + @Json(name = "i") val i: String, + @Json(name = "s") val s: Int, + @Json(name = "key") val key: String, + @Json(name = "ui") val ui: String?, + @Json(name = "us") val us: List, + @Json(name= "beacon") val beacon: Boolean?, + @Json(name= "autocomplete_section") val autocomplete_section: String?, + @Json(name= "_dt") val _dt: String? +) : Serializable \ 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 ba8b2e1a..f218df48 100755 --- a/library/src/main/java/io/constructor/data/remote/ConstructorApi.kt +++ b/library/src/main/java/io/constructor/data/remote/ConstructorApi.kt @@ -2,6 +2,8 @@ package io.constructor.data.remote import io.constructor.core.Constants import io.constructor.data.model.autocomplete.AutocompleteResponse +import io.constructor.data.model.browse.BrowseResultClickRequestBody +import io.constructor.data.model.browse.BrowseResultLoadRequestBody import io.reactivex.Completable import io.reactivex.Single import okhttp3.ResponseBody @@ -61,18 +63,13 @@ interface ConstructorApi { @GET fun getBrowseResults(@Url browseUrl: String): Single> - @GET(ApiPaths.URL_BROWSE_RESULT_CLICK_EVENT) - fun trackBrowseResultClick(@Query("filter_name") filterName: String, - @Query("filter_value") filterValue: String, - @Query("customer_id") customerId: String, - @Query("result_position_on_page") resultPositionOnPage: Int, - @QueryMap params: Map, + @POST(ApiPaths.URL_BROWSE_RESULT_CLICK_EVENT) + fun trackBrowseResultClick(@Body browseResultClickRequestBody: BrowseResultClickRequestBody, + @QueryMap params: Map, @QueryMap(encoded = true) encodedData: Map): Completable - @GET(ApiPaths.URL_BROWSE_RESULT_LOAD_EVENT) - fun trackBrowseResultsLoaded(@Query("filter_name") filterName: String, - @Query("filter_value") filterValue: String, - @Query("num_results") resultCount: Int, + @POST(ApiPaths.URL_BROWSE_RESULT_LOAD_EVENT) + fun trackBrowseResultsLoaded(@Body browseRequestBody: BrowseResultLoadRequestBody, @QueryMap params: Map): Completable } \ No newline at end of file diff --git a/library/src/test/java/io/constructor/core/ConstructorIoTrackingTest.kt b/library/src/test/java/io/constructor/core/ConstructorIoTrackingTest.kt index 7621df04..794178d9 100755 --- a/library/src/test/java/io/constructor/core/ConstructorIoTrackingTest.kt +++ b/library/src/test/java/io/constructor/core/ConstructorIoTrackingTest.kt @@ -15,6 +15,8 @@ import org.junit.Rule import org.junit.Test import java.net.SocketTimeoutException import java.util.concurrent.TimeUnit +import kotlin.test.assertEquals +import kotlin.test.assertTrue class ConstructorIoTest { @@ -365,8 +367,11 @@ class ConstructorIoTest { val observer = ConstructorIo.trackBrowseResultsLoadedInternal("group_id", "Movies", 10).test() observer.assertComplete() val request = mockServer.takeRequest() - val path = "/v2/behavioral_action/browse_result_load?filter_name=group_id&filter_value=Movies&num_results=10&action=browse-results&key=copper-key&i=wacko-the-guid&ui=player-three&s=67&c=cioand-2.3.1&_dt="; + val path = "/v2/behavioral_action/browse_result_load?action=browse-results&key=copper-key&i=wacko-the-guid&ui=player-three&s=67&c=cioand-2.3.1&_dt=" + print(request.body.readUtf8()) assert(request.path.startsWith(path)) + assertTrue(request.bodySize > 220) + assertEquals("POST", request.method) } @Test @@ -376,8 +381,10 @@ class ConstructorIoTest { val observer = ConstructorIo.trackBrowseResultsLoadedInternal("group_id", "Movies", 10).test() observer.assertError { true } val request = mockServer.takeRequest() - val path = "/v2/behavioral_action/browse_result_load?filter_name=group_id&filter_value=Movies&num_results=10&action=browse-results&key=copper-key&i=wacko-the-guid&ui=player-three&s=67&c=cioand-2.3.1&_dt="; + val path = "/v2/behavioral_action/browse_result_load?action=browse-results&key=copper-key&i=wacko-the-guid&ui=player-three&s=67&c=cioand-2.3.1&_dt=" assert(request.path.startsWith(path)) + assertTrue(request.bodySize > 220) + assertEquals("POST", request.method) } @Test @@ -387,9 +394,8 @@ class ConstructorIoTest { mockServer.enqueue(mockResponse) val observer = ConstructorIo.trackBrowseResultsLoadedInternal("group_id", "Movies", 10).test() observer.assertError(SocketTimeoutException::class.java) - val request = mockServer.takeRequest() - val path = "/v2/behavioral_action/browse_result_load?filter_name=group_id&filter_value=Movies&num_results=10&action=browse-results&key=copper-key&i=wacko-the-guid&ui=player-three&s=67&c=cioand-2.3.1&_dt="; - assert(request.path.startsWith(path)) + val request = mockServer.takeRequest(10, TimeUnit.SECONDS) + assertEquals(null, request) } @Test @@ -399,8 +405,11 @@ class ConstructorIoTest { val observer = ConstructorIo.trackBrowseResultClickInternal("group_id", "Movies","TIT-REP-1997", 4).test() observer.assertComplete() val request = mockServer.takeRequest() - val path = "/v2/behavioral_action/browse_result_click?filter_name=group_id&filter_value=Movies&customer_id=TIT-REP-1997&result_position_on_page=4&autocomplete_section=Products&key=copper-key&i=wacko-the-guid&ui=player-three&s=67&c=cioand-2.3.1&_dt="; + val path = "/v2/behavioral_action/browse_result_click?autocomplete_section=Products&key=copper-key&i=wacko-the-guid&ui=player-three&s=67&c=cioand-2.3.1&_dt="; + print(request.body.readUtf8()) assert(request.path.startsWith(path)) + assertTrue(request.bodySize > 250) + assertEquals("POST", request.method) } @Test @@ -410,8 +419,10 @@ class ConstructorIoTest { val observer = ConstructorIo.trackBrowseResultClickInternal("group_id", "Movies","TIT-REP-1997", 4, "Products", "3467632").test() observer.assertComplete() val request = mockServer.takeRequest() - val path = "/v2/behavioral_action/browse_result_click?filter_name=group_id&filter_value=Movies&customer_id=TIT-REP-1997&result_position_on_page=4&autocomplete_section=Products&result_id=3467632&key=copper-key&i=wacko-the-guid&ui=player-three&s=67&c=cioand-2.3.1&_dt="; + val path = "/v2/behavioral_action/browse_result_click?autocomplete_section=Products&result_id=3467632&key=copper-key&i=wacko-the-guid&ui=player-three&s=67&c=cioand-2.3.1&_dt="; assert(request.path.startsWith(path)) + assertTrue(request.bodySize > 250) + assertEquals("POST", request.method) } @Test @@ -421,8 +432,10 @@ class ConstructorIoTest { val observer = ConstructorIo.trackBrowseResultClickInternal("group_id", "Movies","TIT-REP-1997", 4).test() observer.assertError { true } val request = mockServer.takeRequest() - val path = "/v2/behavioral_action/browse_result_click?filter_name=group_id&filter_value=Movies&customer_id=TIT-REP-1997&result_position_on_page=4&autocomplete_section=Products&key=copper-key&i=wacko-the-guid&ui=player-three&s=67&c=cioand-2.3.1&_dt="; + val path = "/v2/behavioral_action/browse_result_click?autocomplete_section=Products&key=copper-key&i=wacko-the-guid&ui=player-three&s=67&c=cioand-2.3.1&_dt="; assert(request.path.startsWith(path)) + assertTrue(request.bodySize > 250) + assertEquals("POST", request.method) } @Test @@ -432,9 +445,8 @@ class ConstructorIoTest { mockServer.enqueue(mockResponse) val observer = ConstructorIo.trackBrowseResultClickInternal("group_id", "Movies","TIT-REP-1997", 4).test() observer.assertError(SocketTimeoutException::class.java) - val request = mockServer.takeRequest() - val path = "/v2/behavioral_action/browse_result_click?filter_name=group_id&filter_value=Movies&customer_id=TIT-REP-1997&result_position_on_page=4&autocomplete_section=Products&key=copper-key&i=wacko-the-guid&ui=player-three&s=67&c=cioand-2.3.1&_dt="; - assert(request.path.startsWith(path)) + val request = mockServer.takeRequest(10, TimeUnit.SECONDS) + assertEquals(null, request) } }