Skip to content

Commit 606537e

Browse files
authored
[CH 10275] Add Support for Variations and Sorting in Search/Browse Responses (#41)
* Add FilteSortOption model, update SearchResponse/Result models, update tests and test resource * Update to handle moving metadata out of variations * Add search response test resource, update browse response and tests * Update and fix tests
1 parent c6a61e4 commit 606537e

File tree

10 files changed

+8724
-4
lines changed

10 files changed

+8724
-4
lines changed

constructorio-client/src/main/java/io/constructor/client/ConstructorIO.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -867,11 +867,17 @@ protected static void moveMetadataOutOfResultData(JSONArray results) {
867867
JSONObject result = results.getJSONObject(i);
868868
JSONObject resultData = result.getJSONObject("data");
869869
JSONObject metadata = new JSONObject();
870+
871+
// Recursive call to move unspecified properties in result variations to it's metadata object
872+
if (!result.isNull("variations")) {
873+
JSONArray variations = result.getJSONArray("variations");
874+
moveMetadataOutOfResultData(variations);
875+
}
870876

871877
// Move unspecified properties in result data object to metadata object
872878
for (Object propertyKey : resultData.keySet()) {
873879
String propertyName = (String)propertyKey;
874-
if (!propertyName.matches("(description|id|url|image_url|groups|facets)")) {
880+
if (!propertyName.matches("(description|id|url|image_url|groups|facets|variation_id)")) {
875881
metadata.put(propertyName, resultData.get(propertyName));
876882
}
877883
}

constructorio-client/src/main/java/io/constructor/client/models/BrowseResponseInner.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ public class BrowseResponseInner {
2121
@SerializedName("total_num_results")
2222
private Integer totalNumberOfResults;
2323

24+
@SerializedName("sort_options")
25+
private List<FilterSortOption> sortOptions;
26+
2427
/**
2528
* @return the facets
2629
*/
@@ -48,4 +51,11 @@ public List<Result> getResults() {
4851
public Integer getTotalNumberOfResults() {
4952
return totalNumberOfResults;
5053
}
54+
55+
/**
56+
* @return the sort options
57+
*/
58+
public List<FilterSortOption> getSortOptions() {
59+
return sortOptions;
60+
}
5161
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package io.constructor.client.models;
2+
3+
import com.google.gson.annotations.SerializedName;
4+
5+
/**
6+
* Constructor.io Sort Option ... uses Gson/Reflection to load data in
7+
*/
8+
public class FilterSortOption {
9+
10+
@SerializedName("display_name")
11+
private String displayName;
12+
13+
@SerializedName("sort_by")
14+
private String sortBy;
15+
16+
@SerializedName("sort_order")
17+
private String sortOrder;
18+
19+
@SerializedName("status")
20+
private String status;
21+
22+
/**
23+
* @return the display name
24+
*/
25+
public String getDisplayName() {
26+
return displayName;
27+
}
28+
29+
/**
30+
* @return the sort by
31+
*/
32+
public String getSortBy() {
33+
return sortBy;
34+
}
35+
36+
/**
37+
* @return the sort order
38+
*/
39+
public String getSortOrder() {
40+
return sortOrder;
41+
}
42+
43+
/**
44+
* @return the status
45+
*/
46+
public String getStatus() {
47+
return status;
48+
}
49+
50+
}

constructorio-client/src/main/java/io/constructor/client/models/Result.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ public class Result {
1818
@SerializedName("matched_terms")
1919
private List<String> matchedTerms;
2020

21+
@SerializedName("variations")
22+
private List<Result> variations;
23+
2124
/**
2225
* @return the value
2326
*/
@@ -38,4 +41,11 @@ public ResultData getData() {
3841
public List<String> getMatchedTerms() {
3942
return matchedTerms;
4043
}
44+
45+
/**
46+
* @return the variations
47+
*/
48+
public List<Result> getVariations() {
49+
return variations;
50+
}
4151
}

constructorio-client/src/main/java/io/constructor/client/models/ResultData.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ public class ResultData {
2828
@SerializedName("facets")
2929
private List<ResultFacet> facets;
3030

31+
@SerializedName("variation_id")
32+
private String variationId;
33+
3134
@SerializedName("metadata")
3235
private Map<String, Object> metadata;
3336

@@ -73,6 +76,13 @@ public List<ResultFacet> getFacets() {
7376
return facets;
7477
}
7578

79+
/**
80+
* @return the variation id
81+
*/
82+
public String getVariationId() {
83+
return variationId;
84+
}
85+
7686
/**
7787
* @return the metadata
7888
*/

constructorio-client/src/main/java/io/constructor/client/models/SearchResponseInner.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
public class SearchResponseInner {
1111

1212
@SerializedName("facets")
13-
List<FilterFacet> facets;
13+
private List<FilterFacet> facets;
1414

1515
@SerializedName("groups")
1616
private List<FilterGroup> groups;
@@ -21,6 +21,9 @@ public class SearchResponseInner {
2121
@SerializedName("total_num_results")
2222
private Integer totalNumberOfResults;
2323

24+
@SerializedName("sort_options")
25+
private List<FilterSortOption> sortOptions;
26+
2427
/**
2528
* @return the facets
2629
*/
@@ -48,4 +51,11 @@ public List<Result> getResults() {
4851
public Integer getTotalNumberOfResults() {
4952
return totalNumberOfResults;
5053
}
54+
55+
/**
56+
* @return the sort options
57+
*/
58+
public List<FilterSortOption> getSortOptions() {
59+
return sortOptions;
60+
}
5161
}

constructorio-client/src/test/java/io/constructor/client/ConstructorIOBrowseTest.java

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,41 @@ public void createBrowseResponseShouldReturnAResult() throws Exception {
3333
assertTrue("browse result id exists", response.getResultId() != null);
3434
}
3535

36+
@Test
37+
public void createBrowseResponseShouldReturnAResultWithVariations() throws Exception {
38+
String string = Utils.getTestResource("response.browse.color.blue.json");
39+
BrowseResponse response = ConstructorIO.createBrowseResponse(string);
40+
assertEquals("browse facets exists", response.getResponse().getFacets().size(), 7);
41+
assertEquals("browse groups exists", response.getResponse().getGroups().size(), 1);
42+
assertEquals("browse results exists", response.getResponse().getResults().size(), 5);
43+
assertEquals("browse result [id] exists", response.getResponse().getResults().get(0).getData().getId(), "aspesi-coat-I502997385098-blue");
44+
assertEquals("browse result [variation id] exists", response.getResponse().getResults().get(0).getData().getVariationId(), "M0E20000000ECTT");
45+
assertEquals("browse result [variations] exists", response.getResponse().getResults().get(0).getVariations().size(), 8);
46+
assertEquals("browse result variation [facets] exists", response.getResponse().getResults().get(0).getVariations().get(0).getData().getFacets().size(), 8);
47+
assertEquals("browse result variation [value] exists", response.getResponse().getResults().get(0).getVariations().get(0).getValue(), "Coat Aspesi blue");
48+
assertEquals("browse result variation [variation id] exists", response.getResponse().getResults().get(0).getVariations().get(0).getData().getVariationId(), "M0E20000000ECTT");
49+
assertEquals("browse result variation [image url] exists", response.getResponse().getResults().get(0).getVariations().get(0).getData().getImageUrl(), "https://s3-eu-west-1.amazonaws.com/commercetools-maximilian/products/081200_1_large.jpg");
50+
assertEquals("browse result variation [url] exists", response.getResponse().getResults().get(0).getVariations().get(0).getData().getUrl(), "https://demo.commercetools.com/en/aspesi-coat-I502997385098-blue.html");
51+
assertTrue("browse result variation [metadata] exists", response.getResponse().getResults().get(0).getVariations().get(0).getData().getMetadata() != null);
52+
assertEquals("browse result variation metadata [product type] exists", response.getResponse().getResults().get(0).getVariations().get(0).getData().getMetadata().get("productType"), "Outerwear");
53+
assertEquals("browse result variation metadata [price] exists", response.getResponse().getResults().get(0).getVariations().get(0).getData().getMetadata().get("price"), "536.25");
54+
assertEquals("total number of results", (int)response.getResponse().getTotalNumberOfResults(), 562);
55+
assertTrue("browse result id exists", response.getResultId() != null);
56+
}
57+
58+
@Test
59+
public void createBrowseResponseShouldReturnAResultWithSortOptions() throws Exception {
60+
String string = Utils.getTestResource("response.browse.color.blue.json");
61+
BrowseResponse response = ConstructorIO.createBrowseResponse(string);
62+
assertEquals("browse result [sort options] exists", response.getResponse().getSortOptions().size(), 4);
63+
assertEquals("browse result sort option [display name] exists", response.getResponse().getSortOptions().get(0).getDisplayName(), "Relevance");
64+
assertEquals("browse result sort option [sort by] exists", response.getResponse().getSortOptions().get(0).getSortBy(), "relevance");
65+
assertEquals("browse result sort option [sort order] exists", response.getResponse().getSortOptions().get(0).getSortOrder(), "descending");
66+
assertEquals("browse result sort option [status] exists", response.getResponse().getSortOptions().get(0).getStatus(), "selected");
67+
assertEquals("total number of results", (int) response.getResponse().getTotalNumberOfResults(), 562);
68+
assertTrue("browse result id exists", response.getResultId() != null);
69+
}
70+
3671
@Test
3772
public void BrowseShouldReturnAResult() throws Exception {
3873
ConstructorIO constructor = new ConstructorIO("", "key_dKjn8oS8czBw7Ebv", true, null);
@@ -92,6 +127,37 @@ public void BrowseShouldReturnAResultWithBrandFacets() throws Exception {
92127
assertTrue("browse result id exists", response.getResultId() != null);
93128
}
94129

130+
@Test
131+
public void BrowseShouldReturnAResultWithVariations() throws Exception {
132+
ConstructorIO constructor = new ConstructorIO("", "key_dKjn8oS8czBw7Ebv", true, null);
133+
UserInfo userInfo = new UserInfo(3, "c62a-2a09-faie");
134+
BrowseRequest request = new BrowseRequest("Color", "Blue");
135+
BrowseResponse response = constructor.browse(request, userInfo);
136+
assertEquals("browse results exist", response.getResponse().getResults().size(), 30);
137+
assertEquals("browse result [variations] exists", response.getResponse().getResults().get(0).getVariations().size(), 25);
138+
assertEquals("browse result variation [facets] exists", response.getResponse().getResults().get(0).getVariations().get(0).getData().getFacets().size(), 8);
139+
assertEquals("browse result variation [value] exists", response.getResponse().getResults().get(0).getVariations().get(0).getValue(), "Sneakers ”H222” Hogan light blue");
140+
assertEquals("browse result variation [variation id] exists", response.getResponse().getResults().get(0).getVariations().get(0).getData().getVariationId(), "M0E20000000DVZF");
141+
assertEquals("browse result variation [url] exists", response.getResponse().getResults().get(0).getVariations().get(0).getData().getUrl(), "https://demo.commercetools.com/en/hogan-sneakers-38714173-lightblue.html");
142+
assertEquals("browse results count as expected", (int) response.getResponse().getTotalNumberOfResults(), 562);
143+
assertTrue("browse result id exists", response.getResultId() != null);
144+
}
145+
146+
@Test
147+
public void BrowseShouldReturnAResultWithSortOptions() throws Exception {
148+
ConstructorIO constructor = new ConstructorIO("", "key_dKjn8oS8czBw7Ebv", true, null);
149+
UserInfo userInfo = new UserInfo(3, "c62a-2a09-faie");
150+
BrowseRequest request = new BrowseRequest("Color", "Blue");
151+
BrowseResponse response = constructor.browse(request, userInfo);
152+
assertEquals("browse result [sort options] exists", response.getResponse().getSortOptions().size(), 1);
153+
assertEquals("browse result sort option [display name] exists", response.getResponse().getSortOptions().get(0).getDisplayName(), "Relevance");
154+
assertEquals("browse result sort option [sort by] exists", response.getResponse().getSortOptions().get(0).getSortBy(), "relevance");
155+
assertEquals("browse result sort option [sort order] exists", response.getResponse().getSortOptions().get(0).getSortOrder(), "descending");
156+
assertEquals("browse result sort option [status] exists", response.getResponse().getSortOptions().get(0).getStatus(), "selected");
157+
assertEquals("browse results count as expected", (int) response.getResponse().getTotalNumberOfResults(), 562);
158+
assertTrue("browse result id exists", response.getResultId() != null);
159+
}
160+
95161
@Test
96162
public void BrowseShouldReturnAResultWithNullUserInfo() throws Exception {
97163
ConstructorIO constructor = new ConstructorIO("", "key_dKjn8oS8czBw7Ebv", true, null);

constructorio-client/src/test/java/io/constructor/client/ConstructorIOSearchTest.java

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,41 @@ public void createSearchResponseShouldReturnAResult() throws Exception {
3333
assertTrue("search result id exists", response.getResultId() != null);
3434
}
3535

36+
@Test
37+
public void createSearchResponseShouldReturnAResultWithVariations() throws Exception {
38+
String string = Utils.getTestResource("response.search.shirt.json");
39+
SearchResponse response = ConstructorIO.createSearchResponse(string);
40+
assertEquals("search facets exists", response.getResponse().getFacets().size(), 7);
41+
assertEquals("search groups exists", response.getResponse().getGroups().size(), 1);
42+
assertEquals("search results exists", response.getResponse().getResults().size(), 20);
43+
assertEquals("search result [id] exists", response.getResponse().getResults().get(0).getData().getId(), "bully-leather-jacket-251-grey");
44+
assertEquals("search result [variation id] exists", response.getResponse().getResults().get(0).getData().getVariationId(), "M0E20000000FBLO");
45+
assertEquals("search result [variations] exists", response.getResponse().getResults().get(0).getVariations().size(), 13);
46+
assertEquals("search result variation [facets] exists", response.getResponse().getResults().get(0).getVariations().get(0).getData().getFacets().size(), 8);
47+
assertEquals("search result variation [value] exists", response.getResponse().getResults().get(0).getVariations().get(0).getValue(), "Bully – Leather Jacket");
48+
assertEquals("search result variation [variation id] exists", response.getResponse().getResults().get(0).getVariations().get(0).getData().getVariationId(), "M0E20000000FBLO");
49+
assertEquals("search result variation [image url] exists", response.getResponse().getResults().get(0).getVariations().get(0).getData().getImageUrl(), "https://demo.commercetools.com/en/bully-leather-jacket-251-grey.html");
50+
assertEquals("search result variation [url] exists", response.getResponse().getResults().get(0).getVariations().get(0).getData().getUrl(), "https://demo.commercetools.com/en/bully-leather-jacket-251-grey.html");
51+
assertTrue("search result variation [metadata] exists", response.getResponse().getResults().get(0).getVariations().get(0).getData().getMetadata() != null);
52+
assertEquals("search result variation metadata [product type] exists", response.getResponse().getResults().get(0).getVariations().get(0).getData().getMetadata().get("productType"), "Apparel");
53+
assertEquals("search result variation metadata [price] exists", response.getResponse().getResults().get(0).getVariations().get(0).getData().getMetadata().get("price"), "411.25");
54+
assertEquals("total number of results", (int)response.getResponse().getTotalNumberOfResults(), 261);
55+
assertTrue("search result id exists", response.getResultId() != null);
56+
}
57+
58+
@Test
59+
public void createSearchResponseShouldReturnAResultWithSortOptions() throws Exception {
60+
String string = Utils.getTestResource("response.search.shirt.json");
61+
SearchResponse response = ConstructorIO.createSearchResponse(string);
62+
assertEquals("search result [sort options] exists", response.getResponse().getSortOptions().size(), 1);
63+
assertEquals("search result sort option [display name] exists", response.getResponse().getSortOptions().get(0).getDisplayName(), "Relevance");
64+
assertEquals("search result sort option [sort by] exists", response.getResponse().getSortOptions().get(0).getSortBy(), "relevance");
65+
assertEquals("search result sort option [sort order] exists", response.getResponse().getSortOptions().get(0).getSortOrder(), "descending");
66+
assertEquals("search result sort option [status] exists", response.getResponse().getSortOptions().get(0).getStatus(), "selected");
67+
assertEquals("total number of results", (int)response.getResponse().getTotalNumberOfResults(), 261);
68+
assertTrue("search result id exists", response.getResultId() != null);
69+
}
70+
3671
@Test
3772
public void SearchShouldReturnAResult() throws Exception {
3873
ConstructorIO constructor = new ConstructorIO("", "key_K2hlXt5aVSwoI1Uw", true, null);
@@ -104,6 +139,37 @@ public void SearchShouldReturnAResultWithBrandFacets() throws Exception {
104139
assertTrue("search result id exists", response.getResultId() != null);
105140
}
106141

142+
@Test
143+
public void SearchShouldReturnAResultWithVariations() throws Exception {
144+
ConstructorIO constructor = new ConstructorIO("", "key_dKjn8oS8czBw7Ebv", true, null);
145+
UserInfo userInfo = new UserInfo(3, "c62a-2a09-faie");
146+
SearchRequest request = new SearchRequest("jacket");
147+
SearchResponse response = constructor.search(request, userInfo);
148+
assertEquals("search results exist", response.getResponse().getResults().size(), 30);
149+
assertEquals("search result [variations] exists", response.getResponse().getResults().get(0).getVariations().size(), 13);
150+
assertEquals("search result variation [facets] exists", response.getResponse().getResults().get(0).getVariations().get(0).getData().getFacets().size(), 8);
151+
assertEquals("search result variation [value] exists", response.getResponse().getResults().get(0).getVariations().get(0).getValue(), "Bully – Leather Jacket");
152+
assertEquals("search result variation [variation id] exists", response.getResponse().getResults().get(0).getVariations().get(0).getData().getVariationId(), "M0E20000000FBLO");
153+
assertEquals("search result variation [url] exists", response.getResponse().getResults().get(0).getVariations().get(0).getData().getUrl(), "https://demo.commercetools.com/en/bully-leather-jacket-251-grey.html");
154+
assertEquals("search results count as expected", (int) response.getResponse().getTotalNumberOfResults(), 261);
155+
assertTrue("search result id exists", response.getResultId() != null);
156+
}
157+
158+
@Test
159+
public void SearchShouldReturnAResultWithSortOptions() throws Exception {
160+
ConstructorIO constructor = new ConstructorIO("", "key_dKjn8oS8czBw7Ebv", true, null);
161+
UserInfo userInfo = new UserInfo(3, "c62a-2a09-faie");
162+
SearchRequest request = new SearchRequest("jacket");
163+
SearchResponse response = constructor.search(request, userInfo);
164+
assertEquals("search result [sort options] exists", response.getResponse().getSortOptions().size(), 1);
165+
assertEquals("search result sort option [display name] exists", response.getResponse().getSortOptions().get(0).getDisplayName(), "Relevance");
166+
assertEquals("search result sort option [sort by] exists", response.getResponse().getSortOptions().get(0).getSortBy(), "relevance");
167+
assertEquals("search result sort option [sort order] exists", response.getResponse().getSortOptions().get(0).getSortOrder(), "descending");
168+
assertEquals("search result sort option [status] exists", response.getResponse().getSortOptions().get(0).getStatus(), "selected");
169+
assertEquals("search results count as expected", (int) response.getResponse().getTotalNumberOfResults(), 261);
170+
assertTrue("search result id exists", response.getResultId() != null);
171+
}
172+
107173
@Test
108174
public void SearchShouldReturnAResultWithNullUserInfo() throws Exception {
109175
ConstructorIO constructor = new ConstructorIO("", "key_K2hlXt5aVSwoI1Uw", true, null);

0 commit comments

Comments
 (0)