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
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -330,9 +330,11 @@ var variationsMap: VariationsMap = VariationsMap(
dtype = "array",
"""{"and":[{"field":"data.brand","value":"Best Brand"}]}""",
)
var preFilterExpression = """{ "and": [ { "name": "Color", "value": "green" } ] }"""


// Using RxJava
ConstructorIo.getRecommendationResults(podId, selectedFacets?.map { it.key to it.value }, numResults, variationsMap = variationsMap)
ConstructorIo.getRecommendationResults(podId, selectedFacets?.map { it.key to it.value }, numResults, variationsMap = variationsMap, preFilterExpression = preFilterExpression)
.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
.subscribe {
it.onValue {
Expand Down
14 changes: 9 additions & 5 deletions library/src/main/java/io/constructor/core/ConstructorIo.kt
Original file line number Diff line number Diff line change
Expand Up @@ -1887,9 +1887,10 @@ object ConstructorIo {
* @param itemId: The item id to retrieve recommendations (strategy specific)
* @param term: The term to use to refine results (strategy specific)
* @param variationsMap specify which attributes within variations should be returned
* @param preFilterExpression faceting expression to scope results
*/
fun getRecommendationResults(podId: String, facets: List<Pair<String, List<String>>>? = null, numResults: Int? = null, sectionName: String? = null, itemId: String? = null, term: String? = null, variationsMap: VariationsMap? = null): Observable<ConstructorData<RecommendationsResponse>> {
val encodedParams: ArrayList<Pair<String, String>> = getEncodedParams(numResults = numResults, sectionName = sectionName, itemId = itemId, term = term, facets = facets, variationsMap = variationsMap)
fun getRecommendationResults(podId: String, facets: List<Pair<String, List<String>>>? = null, numResults: Int? = null, sectionName: String? = null, itemId: String? = null, term: String? = null, variationsMap: VariationsMap? = null, preFilterExpression: String? = null): Observable<ConstructorData<RecommendationsResponse>> {
val encodedParams: ArrayList<Pair<String, String>> = getEncodedParams(numResults = numResults, sectionName = sectionName, itemId = itemId, term = term, facets = facets, variationsMap = variationsMap, preFilterExpression = preFilterExpression)

return dataManager.getRecommendationResults(podId, encodedParams = encodedParams.toTypedArray())
}
Expand Down Expand Up @@ -1917,9 +1918,10 @@ object ConstructorIo {
* @param itemId: The item id to retrieve recommendations (strategy specific)
* @param term: The term to use to refine results (strategy specific)
* @param variationsMap specify which attributes within variations should be returned
* @param preFilterExpression faceting expression to scope results
*/
suspend fun getRecommendationResultsCRT(podId: String, facets: List<Pair<String, List<String>>>? = null, numResults: Int? = null, sectionName: String? = null, itemId: String? = null, term: String? = null, variationsMap: VariationsMap? = null): RecommendationsResponse {
val encodedParams: ArrayList<Pair<String, String>> = getEncodedParams(numResults = numResults, sectionName = sectionName, itemId = itemId, term = term, facets = facets, variationsMap = variationsMap)
suspend fun getRecommendationResultsCRT(podId: String, facets: List<Pair<String, List<String>>>? = null, numResults: Int? = null, sectionName: String? = null, itemId: String? = null, term: String? = null, variationsMap: VariationsMap? = null, preFilterExpression: String? = null): RecommendationsResponse {
val encodedParams: ArrayList<Pair<String, String>> = getEncodedParams(numResults = numResults, sectionName = sectionName, itemId = itemId, term = term, facets = facets, variationsMap = variationsMap, preFilterExpression = preFilterExpression)

return dataManager.getRecommendationResultsCRT(podId, encodedParams = encodedParams.toTypedArray())
}
Expand Down Expand Up @@ -1950,9 +1952,11 @@ object ConstructorIo {
* @param term the term to use to refine results (strategy specific)
* @param numResults the number of results to return
* @param section the section the results will come from, i.e. "Products"
* @param variationsMap specify which attributes within variations should be returned
* @param preFilterExpression faceting expression to scope results
*/
fun getRecommendationResults(request: RecommendationsRequest): Observable<ConstructorData<RecommendationsResponse>> {
val encodedParams: ArrayList<Pair<String, String>> = getEncodedParams(facets = request.filters?.toList(), itemIds = request.itemIds, term = request.term, numResults = request.numResults, sectionName = request.section, variationsMap = request.variationsMap )
val encodedParams: ArrayList<Pair<String, String>> = getEncodedParams(facets = request.filters?.toList(), itemIds = request.itemIds, term = request.term, numResults = request.numResults, sectionName = request.section, variationsMap = request.variationsMap, preFilterExpression = request.preFilterExpression)

return dataManager.getRecommendationResults(request.podId, encodedParams = encodedParams.toTypedArray())
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ class RecommendationsRequest (
val numResults: Int? = null,
val section: String? = null,
val variationsMap: VariationsMap? = null,
val preFilterExpression: String? = null,
) {
private constructor(builder: Builder) : this(
builder.podId,
Expand All @@ -22,6 +23,7 @@ class RecommendationsRequest (
builder.numResults,
builder.section,
builder.variationsMap,
builder.preFilterExpression,
)

companion object {
Expand All @@ -37,13 +39,15 @@ class RecommendationsRequest (
var term: String? = null
var section: String? = null
var variationsMap: VariationsMap? = null
var preFilterExpression: String? = null

fun setFilters(facets: Map<String, List<String>>): Builder = apply { this.filters = facets }
fun setItemIds(itemIds: List<String>): Builder = apply { this.itemIds = itemIds }
fun setTerm(term: String): Builder = apply { this.term = term }
fun setNumResults(numResults: Int): Builder = apply { this.numResults = numResults }
fun setSection(section: String): Builder = apply { this.section = section }
fun setVariationsMap(variationsMap: VariationsMap): Builder = apply { this.variationsMap = variationsMap }
fun setPreFilterExpression(preFilterExpression: String): Builder = apply { this.preFilterExpression = preFilterExpression }
fun build(): RecommendationsRequest = RecommendationsRequest(this)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1123,6 +1123,19 @@ class ConstructorIoIntegrationTest {
Thread.sleep(timeBetweenTests)
}

@Test
fun getRecommendationResultsCRTWithPreFilterExpressionAgainstRealResponse() {
runBlocking {
val preFilterExpression = """{"and":[{"name":"Color","value":"green"}]}"""
val recommendationResults = constructorIo.getRecommendationResultsCRT("home_page_1", preFilterExpression = preFilterExpression)
assertTrue(recommendationResults.resultId !== null)
assertTrue(recommendationResults.response!!.results!!.isNotEmpty())
assertTrue(recommendationResults.response!!.resultCount!! > 0)
assertNotNull(recommendationResults.request!!["pre_filter_expression"])
}
Thread.sleep(timeBetweenTests)
}

@Test
fun trackRecommendationResultClickAgainstRealResponse() {
val observer = constructorIo.trackRecommendationResultClickInternal(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -195,13 +195,52 @@ class ConstructorIoRecommendationsTest {
assertThat(request.requestUrl!!.encodedPath).isEqualTo("/recommendations/v1/pods/titanic")
with(request.requestUrl!!) {
val queryParams = mapOf(
"variations_map" to """{"dtype":"array","values":{"Price":{"aggregation":"min","field":"data.facets.price"},"Country":{"aggregation":"all","field":"data.facets.country"}},"group_by":[{"name":"Country","field":"data.facets.Country"}]}""",
"key" to "golden-key",
"i" to "guido-the-guid",
"ui" to "player-one",
"s" to "79",
"c" to "cioand-2.30.0",
"_dt" to "1"
"variations_map" to """{"dtype":"array","values":{"Price":{"aggregation":"min","field":"data.facets.price"},"Country":{"aggregation":"all","field":"data.facets.country"}},"group_by":[{"name":"Country","field":"data.facets.Country"}]}""",
"key" to "golden-key",
"i" to "guido-the-guid",
"ui" to "player-one",
"s" to "79",
"c" to "cioand-2.30.0",
"_dt" to "1"
)
assertThat(queryParameterNames).containsExactlyInAnyOrderElementsOf(queryParams.keys)

queryParams.forEach { (key, value) ->
if (key == "_dt") {
assertThat(queryParameter(key)).containsOnlyDigits()
} else {
assertThat(queryParameter(key)).isEqualTo(value)
}
}
}
}

@Test
fun getRecommendationResultsWithPreFilterExpressionUsingBuilder() {
val mockResponse = MockResponse().setResponseCode(200).setBody(TestDataLoader.loadAsString("recommendation_response.json"))
mockServer.enqueue(mockResponse)
val preFilterExpression = """{"and":[{"name":"Country","value":"US"}]}"""
val recommendationsRequest = RecommendationsRequest.Builder("titanic")
.setPreFilterExpression(preFilterExpression)
.build()
val observer = constructorIo.getRecommendationResults(recommendationsRequest).test()
observer.assertComplete().assertValue {
var recommendationResponse = it.get()
recommendationResponse?.response?.results?.isNotEmpty()!!
}
observer.assertNoErrors()

val request = mockServer.takeRequest()
assertThat(request.requestUrl!!.encodedPath).isEqualTo("/recommendations/v1/pods/titanic")
with(request.requestUrl!!) {
val queryParams = mapOf(
"pre_filter_expression" to preFilterExpression,
"key" to "golden-key",
"i" to "guido-the-guid",
"ui" to "player-one",
"s" to "79",
"c" to "cioand-2.30.0",
"_dt" to "1"
)
assertThat(queryParameterNames).containsExactlyInAnyOrderElementsOf(queryParams.keys)

Expand Down