Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 27 additions & 7 deletions library/src/main/java/io/constructor/core/ConstructorIo.kt
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import io.constructor.data.model.quiz.*
import io.constructor.data.model.recommendations.RecommendationResultClickRequestBody
import io.constructor.data.model.recommendations.RecommendationResultViewRequestBody
import io.constructor.data.model.recommendations.RecommendationsResponse
import io.constructor.data.model.search.SearchResponse
import io.constructor.data.model.search.*
import io.constructor.data.model.tracking.GenericResultClickRequestBody
import io.constructor.data.model.tracking.ItemDetailLoadRequestBody
import io.constructor.injection.component.AppComponent
Expand Down Expand Up @@ -1451,18 +1451,38 @@ object ConstructorIo {
* @param term the term that results are displayed for, i.e. "Pumpkin"
* @param resultCount the number of results for that term
* @param customerIds the customerIds of shown items
* @param analyticsTags Additional analytics tags to pass
*/
fun trackSearchResultsLoaded(term: String, resultCount: Int, customerIds: Array<String>? = null) {
var completable = trackSearchResultsLoadedInternal(term, resultCount, customerIds)
fun trackSearchResultsLoaded(term: String, resultCount: Int, customerIds: Array<String>? = null, analyticsTags: Map<String, String>? = null) {
var completable = trackSearchResultsLoadedInternal(term, resultCount, customerIds, analyticsTags)
disposable.add(completable.subscribeOn(Schedulers.io()).subscribe({}, {
t -> e("Search Results Loaded error: ${t.message}")
}))
}
internal fun trackSearchResultsLoadedInternal(term: String, resultCount: Int, customerIds: Array<String>? = null): Completable {
internal fun trackSearchResultsLoadedInternal(term: String, resultCount: Int, customerIds: Array<String>? = null, analyticsTags: Map<String, String>? = null): Completable {
preferenceHelper.getSessionId(sessionIncrementHandler)
return dataManager.trackSearchResultsLoaded(term, resultCount, customerIds, arrayOf(
Constants.QueryConstants.ACTION to Constants.QueryValues.EVENT_SEARCH_RESULTS
))
val items = customerIds?.map{ item -> TrackingItem(item, null)}
val searchResultLoadRequestBody = SearchResultLoadRequestBody(
term,
items,
resultCount,
"Not Available",
BuildConfig.CLIENT_VERSION,
preferenceHelper.id,
preferenceHelper.getSessionId(),
preferenceHelper.apiKey,
configMemoryHolder.userId,
configMemoryHolder.segments,
mergeAnalyticsTags(configMemoryHolder.defaultAnalyticsTags, analyticsTags),
true,
preferenceHelper.defaultItemSection,
System.currentTimeMillis()
)

return dataManager.trackSearchResultsLoaded(
searchResultLoadRequestBody,
arrayOf()
)
}

/**
Expand Down
6 changes: 3 additions & 3 deletions library/src/main/java/io/constructor/data/DataManager.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import io.constructor.data.model.quiz.*
import io.constructor.data.model.recommendations.RecommendationResultClickRequestBody
import io.constructor.data.model.recommendations.RecommendationResultViewRequestBody
import io.constructor.data.model.recommendations.RecommendationsResponse
import io.constructor.data.model.search.SearchResponse
import io.constructor.data.model.search.*
import io.constructor.data.model.tracking.GenericResultClickRequestBody
import io.constructor.data.remote.ApiPaths
import io.constructor.data.remote.ConstructorApi
Expand Down Expand Up @@ -108,8 +108,8 @@ constructor(private val constructorApi: ConstructorApi, @ConstructorSdk private
return constructorApi.trackSearchResultClick(term, itemName, customerId, variationId, params.toMap(), encodedParams.toMap())
}

fun trackSearchResultsLoaded(term: String, resultCount: Int, customerIds: Array<String>? = null, params: Array<Pair<String, String>>): Completable {
return constructorApi.trackSearchResultsLoaded(term, resultCount, customerIds?.take(60)?.joinToString(","), params.toMap())
fun trackSearchResultsLoaded(searchResultLoadRequestBody: SearchResultLoadRequestBody, params: Array<Pair<String, String>>): Completable {
return constructorApi.trackSearchResultsLoaded(searchResultLoadRequestBody, params.toMap())
}

fun trackInputFocus(term: String?, params: Array<Pair<String, String>>): Completable {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package io.constructor.data.model.search;

import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import io.constructor.data.model.common.*;
import java.io.Serializable

/**
* @suppress
*/
@JsonClass(generateAdapter = true)
data class SearchResultLoadRequestBody(
@Json(name = "search_term") val searchTerm: String,
@Json(name = "items") val items: List<TrackingItem>?,
@Json(name = "result_count") val resultCount: Int,
@Json(name = "url") val url: String,
@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<String?>,
@Json(name = "analytics_tags") val analyticsTags: Map<String, String>?,
@Json(name= "beacon") val beacon: Boolean?,
@Json(name= "section") val section: String?,
@Json(name= "_dt") val _dt: Long?
) : Serializable
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ object ApiPaths {
const val URL_SESSION_START_EVENT = "behavior"
const val URL_CONVERSION_EVENT = "v2/behavioral_action/conversion"
const val URL_SEARCH_RESULT_CLICK_EVENT = "autocomplete/{term}/click_through"
const val URL_SEARCH_RESULT_LOAD_EVENT = "v2/behavioral_action/search_result_load"
const val URL_BEHAVIOR = "behavior"
const val URL_PURCHASE = "v2/behavioral_action/purchase"
const val URL_SEARCH = "search/%s"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import io.constructor.data.model.quiz.*
import io.constructor.data.model.recommendations.RecommendationResultClickRequestBody
import io.constructor.data.model.recommendations.RecommendationResultViewRequestBody
import io.constructor.data.model.recommendations.RecommendationsResponse
import io.constructor.data.model.search.SearchResponse
import io.constructor.data.model.search.*
import io.constructor.data.model.tracking.GenericResultClickRequestBody
import io.reactivex.Completable
import io.reactivex.Single
Expand Down Expand Up @@ -53,10 +53,8 @@ interface ConstructorApi {
@QueryMap params: Map<String, String>,
@QueryMap(encoded = true) encodedData: Map<String, String>): Completable

@GET(ApiPaths.URL_BEHAVIOR)
fun trackSearchResultsLoaded(@Query("term") term: String,
@Query("num_results") resultCount: Int,
@Query("customer_ids") customerIds: String?,
@POST(ApiPaths.URL_SEARCH_RESULT_LOAD_EVENT)
fun trackSearchResultsLoaded(@Body searchRequestBody: SearchResultLoadRequestBody,
@QueryMap params: Map<String, String>): Completable

@GET(ApiPaths.URL_BEHAVIOR)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -973,6 +973,13 @@ class ConstructorIoIntegrationTest {
Thread.sleep(timeBetweenTests)
}

@Test
fun trackSearchResultsLoadedAgainstRealResponse() {
val observer = constructorIo.trackSearchResultsLoadedInternal("titanic", 10, arrayOf("123", "234")).test()
observer.assertComplete()
Thread.sleep(timeBetweenTests)
}

@Test
fun trackConversionAgainstRealResponse() {
val observer = constructorIo.trackConversionInternal(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -361,18 +361,46 @@ class ConstructorIoTrackingTest {
val observer = ConstructorIo.trackSearchResultsLoadedInternal("titanic", 10).test()
observer.assertComplete()
val request = mockServer.takeRequest()
val path = "/behavior?term=titanic&num_results=10&action=search-results&key=copper-key&i=wacko-the-guid&ui=player-three&s=67&c=cioand-2.34.1&_dt="
val requestBody = getRequestBody(request)
val path = "/v2/behavioral_action/search_result_load?key=copper-key&i=wacko-the-guid&ui=player-three&s=67&c=cioand-2.34.1&_dt="
assertEquals("titanic", requestBody["search_term"])
assertEquals("10", requestBody["result_count"])
assertEquals(null, requestBody["items"])
assertEquals("POST", request.method)
assert(request.path!!.startsWith(path))
}

@Test
fun trackSearchResultLoadedWithCustomerIDs() {
val mockResponse = MockResponse().setResponseCode(204)
mockServer.enqueue(mockResponse)
val observer = ConstructorIo.trackSearchResultsLoadedInternal("titanic", 10, arrayOf("TIT-REP-1997", "QE2-REP-1969")).test()
val items = arrayOf("123", "234");
val observer = ConstructorIo.trackSearchResultsLoadedInternal("titanic", 10, items).test()
observer.assertComplete()
val request = mockServer.takeRequest()
val path = "/behavior?term=titanic&num_results=10&customer_ids=TIT-REP-1997%2CQE2-REP-1969&action=search-results&key=copper-key&i=wacko-the-guid&ui=player-three&s=67&c=cioand-2.34.1&_dt="
val requestBody = getRequestBody(request)
val path = "/v2/behavioral_action/search_result_load?key=copper-key&i=wacko-the-guid&ui=player-three&s=67&c=cioand-2.34.1&_dt="
assertEquals("titanic", requestBody["search_term"])
assertEquals("10", requestBody["result_count"])
assertEquals("[{item_id:123},{item_id:234}]", requestBody["items"])
assertEquals("POST", request.method)
assert(request.path!!.startsWith(path))
}

@Test
fun trackSearchResultLoadedWithAnalyticsTags() {
val mockResponse = MockResponse().setResponseCode(204)
mockServer.enqueue(mockResponse)
val observer = ConstructorIo.trackSearchResultsLoadedInternal("titanic", 10, analyticsTags = mapOf("test" to "test1", "appVersion" to "150")).test()
observer.assertComplete()
val request = mockServer.takeRequest()
val requestBody = getRequestBody(request)
val path = "/v2/behavioral_action/search_result_load?key=copper-key&i=wacko-the-guid&ui=player-three&s=67&c=cioand-2.34.1&_dt="
assertEquals("titanic", requestBody["search_term"])
assertEquals("10", requestBody["result_count"])
assertEquals(null, requestBody["items"])
assertEquals("{appVersion:150,appPlatform:Android,test:test1}", requestBody["analytics_tags"])
assertEquals("POST", request.method)
assert(request.path!!.startsWith(path))
}

Expand All @@ -383,7 +411,7 @@ class ConstructorIoTrackingTest {
val observer = ConstructorIo.trackSearchResultsLoadedInternal("titanic", 10).test()
observer.assertError { true }
val request = mockServer.takeRequest()
val path = "/behavior?term=titanic&num_results=10&action=search-results&key=copper-key&i=wacko-the-guid&ui=player-three&s=67&c=cioand-2.34.1&_dt="
val path = "/v2/behavioral_action/search_result_load?key=copper-key&i=wacko-the-guid&ui=player-three&s=67&c=cioand-2.34.1&_dt="
assert(request.path!!.startsWith(path))
}

Expand All @@ -394,9 +422,8 @@ class ConstructorIoTrackingTest {
mockServer.enqueue(mockResponse)
val observer = ConstructorIo.trackSearchResultsLoadedInternal("titanic", 10).test()
observer.assertError(SocketTimeoutException::class.java)
val request = mockServer.takeRequest()
val path = "/behavior?term=titanic&num_results=10&action=search-results&key=copper-key&i=wacko-the-guid&ui=player-three&s=67&c=cioand-2.34.1&_dt="
assert(request.path!!.startsWith(path))
val request = mockServer.takeRequest(10, TimeUnit.SECONDS)
assertEquals(null, request)
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ class ConstructorioSegmentsTest {
val observer = ConstructorIo.trackSearchResultsLoadedInternal("titanic", 10).test()
observer.assertComplete()
val request = mockServer.takeRequest()
val path = "/behavior?term=titanic&num_results=10&action=search-results&key=aluminium-key&i=koopa-the-guid&ui=player-two&s=14&us=mobile&us=COUNTRY_US&c=cioand-2.34.1&_dt="
val path = "/v2/behavioral_action/search_result_load?key=aluminium-key&i=koopa-the-guid&ui=player-two&s=14&us=mobile&us=COUNTRY_US&c=cioand-2.34.1&_dt="
assert(request.path!!.startsWith(path))
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ class ConstructorioTestCellTest {
val observer = ConstructorIo.trackSearchResultsLoadedInternal("titanic", 10).test()
observer.assertComplete()
val request = mockServer.takeRequest()
val path = "/behavior?term=titanic&num_results=10&action=search-results&key=aluminium-key&i=koopa-the-guid&ui=player-two&s=14&ef-cellone=vanilla&ef-celltwo=whipped-cream&c=cioand-2.34.1&_dt=";
val path = "/v2/behavioral_action/search_result_load?key=aluminium-key&i=koopa-the-guid&ui=player-two&s=14&ef-cellone=vanilla&ef-celltwo=whipped-cream&c=cioand-2.34.1&_dt=";
assert(request.path!!.startsWith(path))
}

Expand Down