From 9fe701aa9850221ac325b4e238b8d9271bd8af39 Mon Sep 17 00:00:00 2001 From: Enes Kutay SEZEN Date: Mon, 12 Jan 2026 11:52:46 +0300 Subject: [PATCH 1/4] Initial implementation --- .../client/modules/RecommendationsTests.cs | 17 +++++++++++++++ .../RecommendationsRequestTest.cs | 21 +++++++++++++++++++ .../Recommendations/RecommendationsRequest.cs | 11 ++++++++++ 3 files changed, 49 insertions(+) diff --git a/src/Constructorio_NET.Tests/client/modules/RecommendationsTests.cs b/src/Constructorio_NET.Tests/client/modules/RecommendationsTests.cs index 99a7c9d..c28d84a 100644 --- a/src/Constructorio_NET.Tests/client/modules/RecommendationsTests.cs +++ b/src/Constructorio_NET.Tests/client/modules/RecommendationsTests.cs @@ -321,5 +321,22 @@ public async Task GetRecommendationsResultsShouldReturnAResultProvidedUserInfo() Assert.GreaterOrEqual(res.Response.Results.Count, 0, "Results exist"); Assert.NotNull(res.ResultId, "Result id exists"); } + + [Test] + public async Task GetRecommendationsResultsWithPreFilterExpression() + { + ValuePreFilterExpression filterByBrand = new ValuePreFilterExpression("Brand", "XYZ"); + RecommendationsRequest req = new RecommendationsRequest("filtered_items") + { + UserInfo = this.UserInfo, + PreFilterExpression = filterByBrand, + }; + ConstructorIO constructorio = new ConstructorIO(this.Config); + RecommendationsResponse res = await constructorio.Recommendations.GetRecommendationsResults(req); + + Assert.GreaterOrEqual(res.Response.Results.Count, 0, "Results exist"); + Assert.NotNull(res.ResultId, "Result id exists"); + Assert.IsNotNull(res.Request["pre_filter_expression"], "PreFilterExpression was passed as parameter"); + } } } diff --git a/src/Constructorio_NET.Tests/models/Recommendations/RecommendationsRequestTest.cs b/src/Constructorio_NET.Tests/models/Recommendations/RecommendationsRequestTest.cs index 7f3f3a8..af55362 100644 --- a/src/Constructorio_NET.Tests/models/Recommendations/RecommendationsRequestTest.cs +++ b/src/Constructorio_NET.Tests/models/Recommendations/RecommendationsRequestTest.cs @@ -91,5 +91,26 @@ public void RecommendationsRequestWithInvalidPod() { Assert.Throws(() => new RecommendationsRequest(null)); } + + [Test] + public void GetRequestParametersWithPreFilterExpression() + { + ValuePreFilterExpression filterByGroupId = new ValuePreFilterExpression("group_id", "BrandXY"); + ValuePreFilterExpression filterByColor = new ValuePreFilterExpression("Color", "red"); + AndPreFilterExpression preFilterExpression = new AndPreFilterExpression( + new List { filterByGroupId, filterByColor } + ); + + RecommendationsRequest req = new RecommendationsRequest(this.Pod) + { + UserInfo = this.UserInfo, + PreFilterExpression = preFilterExpression + }; + + Hashtable requestParameters = req.GetRequestParameters(); + Assert.IsNotNull(requestParameters[Constants.PRE_FILTER_EXPRESSION]); + Assert.IsTrue(requestParameters[Constants.PRE_FILTER_EXPRESSION].ToString().Contains("group_id")); + Assert.IsTrue(requestParameters[Constants.PRE_FILTER_EXPRESSION].ToString().Contains("BrandXY")); + } } } diff --git a/src/constructor.io/models/Recommendations/RecommendationsRequest.cs b/src/constructor.io/models/Recommendations/RecommendationsRequest.cs index 4871356..27df884 100644 --- a/src/constructor.io/models/Recommendations/RecommendationsRequest.cs +++ b/src/constructor.io/models/Recommendations/RecommendationsRequest.cs @@ -75,6 +75,11 @@ public RecommendationsRequest(string podId) /// public VariationsMap VariationsMap { get; set; } + /// + /// Gets or sets the filtering expression used to scope results. + /// + public PreFilterExpression PreFilterExpression { get; set; } + /// /// Get request parameters. /// @@ -147,6 +152,12 @@ public Hashtable GetRequestParameters() parameters.Add(Constants.VARIATIONS_MAP, serializedJson); } + if (this.PreFilterExpression != null) + { + string preFilterJson = this.PreFilterExpression.GetExpression(); + parameters.Add(Constants.PRE_FILTER_EXPRESSION, preFilterJson); + } + return parameters; } From 622132ba4ab0023bd6b7e342e7808aaa78bceb02 Mon Sep 17 00:00:00 2001 From: Enes Kutay SEZEN Date: Mon, 12 Jan 2026 11:54:46 +0300 Subject: [PATCH 2/4] More tests and consistency --- .../client/modules/RecommendationsTests.cs | 31 +++++++++++++++++++ .../Recommendations/RecommendationsRequest.cs | 2 +- 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/src/Constructorio_NET.Tests/client/modules/RecommendationsTests.cs b/src/Constructorio_NET.Tests/client/modules/RecommendationsTests.cs index c28d84a..09b30e3 100644 --- a/src/Constructorio_NET.Tests/client/modules/RecommendationsTests.cs +++ b/src/Constructorio_NET.Tests/client/modules/RecommendationsTests.cs @@ -338,5 +338,36 @@ public async Task GetRecommendationsResultsWithPreFilterExpression() Assert.NotNull(res.ResultId, "Result id exists"); Assert.IsNotNull(res.Request["pre_filter_expression"], "PreFilterExpression was passed as parameter"); } + + [Test] + public async Task GetRecommendationsResultsWithPreFilterExpressionJson() + { + JObject preFilterExpressionJObject = JObject.Parse( + @"{ + 'name': 'Brand', + 'value': 'XYZ' + }" + ); + JsonPrefilterExpression preFilterExpression = new JsonPrefilterExpression( + preFilterExpressionJObject + ); + RecommendationsRequest req = new RecommendationsRequest("filtered_items") + { + UserInfo = this.UserInfo, + PreFilterExpression = preFilterExpression, + }; + + ConstructorIO constructorio = new ConstructorIO(this.Config); + RecommendationsResponse res = await constructorio.Recommendations.GetRecommendationsResults(req); + res.Request.TryGetValue("pre_filter_expression", out object reqPreFilterExpression); + + Assert.AreEqual( + reqPreFilterExpression, + JObject.Parse(preFilterExpression.GetExpression()), + "Pre Filter Expression is sent in request" + ); + Assert.GreaterOrEqual(res.Response.Results.Count, 0, "Results exist"); + Assert.NotNull(res.ResultId, "Result id exists"); + } } } diff --git a/src/constructor.io/models/Recommendations/RecommendationsRequest.cs b/src/constructor.io/models/Recommendations/RecommendationsRequest.cs index 27df884..71eef29 100644 --- a/src/constructor.io/models/Recommendations/RecommendationsRequest.cs +++ b/src/constructor.io/models/Recommendations/RecommendationsRequest.cs @@ -76,7 +76,7 @@ public RecommendationsRequest(string podId) public VariationsMap VariationsMap { get; set; } /// - /// Gets or sets the filtering expression used to scope results. + /// Gets or sets the filtering expression used to scope recommendation results. /// public PreFilterExpression PreFilterExpression { get; set; } From bae9f52c6ddabbd83c5bdb98f56f8b9579ce9990 Mon Sep 17 00:00:00 2001 From: Enes Kutay SEZEN Date: Mon, 12 Jan 2026 13:37:43 +0300 Subject: [PATCH 3/4] Update src/Constructorio_NET.Tests/client/modules/RecommendationsTests.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../client/modules/RecommendationsTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Constructorio_NET.Tests/client/modules/RecommendationsTests.cs b/src/Constructorio_NET.Tests/client/modules/RecommendationsTests.cs index 09b30e3..4aac687 100644 --- a/src/Constructorio_NET.Tests/client/modules/RecommendationsTests.cs +++ b/src/Constructorio_NET.Tests/client/modules/RecommendationsTests.cs @@ -348,7 +348,7 @@ public async Task GetRecommendationsResultsWithPreFilterExpressionJson() 'value': 'XYZ' }" ); - JsonPrefilterExpression preFilterExpression = new JsonPrefilterExpression( + JsonPreFilterExpression preFilterExpression = new JsonPreFilterExpression( preFilterExpressionJObject ); RecommendationsRequest req = new RecommendationsRequest("filtered_items") From 4eebe377f364c63c0d0c110b9d4f32a293ec8701 Mon Sep 17 00:00:00 2001 From: Enes Kutay SEZEN Date: Tue, 20 Jan 2026 17:56:22 +0300 Subject: [PATCH 4/4] Update src/Constructorio_NET.Tests/client/modules/RecommendationsTests.cs Co-authored-by: Ahmad Mudaafi' --- .../client/modules/RecommendationsTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Constructorio_NET.Tests/client/modules/RecommendationsTests.cs b/src/Constructorio_NET.Tests/client/modules/RecommendationsTests.cs index 4aac687..09b30e3 100644 --- a/src/Constructorio_NET.Tests/client/modules/RecommendationsTests.cs +++ b/src/Constructorio_NET.Tests/client/modules/RecommendationsTests.cs @@ -348,7 +348,7 @@ public async Task GetRecommendationsResultsWithPreFilterExpressionJson() 'value': 'XYZ' }" ); - JsonPreFilterExpression preFilterExpression = new JsonPreFilterExpression( + JsonPrefilterExpression preFilterExpression = new JsonPrefilterExpression( preFilterExpressionJObject ); RecommendationsRequest req = new RecommendationsRequest("filtered_items")