From a816b9494f8be8d95d623544e1781a67a01b6009 Mon Sep 17 00:00:00 2001 From: Bill Al Date: Tue, 12 Aug 2025 14:32:40 -0700 Subject: [PATCH 1/3] updated api class and integrations tests --- .../Classes/ImpressionsSdkApiClient.cs | 53 ++++++++++++++++-- .../PollingClientTests.cs | 2 - .../BaseAsyncClientTests.cs | 11 +++- .../BaseIntegrationTests.cs | 54 ++++++++++++++----- .../Resources/InMemoryHelper.cs | 1 + .../Resources/KeyImpressionBackend.cs | 1 + 6 files changed, 99 insertions(+), 23 deletions(-) diff --git a/src/Splitio/Services/Impressions/Classes/ImpressionsSdkApiClient.cs b/src/Splitio/Services/Impressions/Classes/ImpressionsSdkApiClient.cs index c095330c..6de0f076 100644 --- a/src/Splitio/Services/Impressions/Classes/ImpressionsSdkApiClient.cs +++ b/src/Splitio/Services/Impressions/Classes/ImpressionsSdkApiClient.cs @@ -10,6 +10,8 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Linq.Expressions; +using System.Runtime.ExceptionServices; using System.Threading.Tasks; namespace Splitio.Services.Impressions.Classes @@ -77,12 +79,53 @@ public async Task SendBulkImpressionsCountAsync(List impr // Public for tests public static string ConvertToJson(List impressions) { - var impressionsPerFeature = - impressions - .GroupBy(item => item.Feature) - .Select(group => new { f = group.Key, i = group.Select(x => new { k = x.KeyName, t = x.Treatment, m = x.Time, c = x.ChangeNumber, r = x.Label, b = x.BucketingKey }) }); + List> impressionsPerFeature = new List>(); + List> currentFeatureImps = new List>(); + String currentFeature = ""; + Dictionary impRecord = new Dictionary(); + Boolean first = true; + foreach (KeyImpression impression in impressions.OrderBy(i => i.Feature)) + { + if (first) + { + currentFeature = impression.Feature; + first = false; + } + + if (impression.Feature != currentFeature) + { + impressionsPerFeature.Add(new Dictionary + { + { "f", currentFeature }, + { "i", currentFeatureImps } + }); + currentFeature = ""; + currentFeatureImps = new List>(); + } + impRecord = new Dictionary + { + { "k", impression.KeyName }, + { "t", impression.Treatment }, + { "m", impression.Time }, + { "c", impression.ChangeNumber }, + { "r", impression.Label }, + { "b", impression.BucketingKey } + }; + if (impression.Properties != null) + { + impRecord.Add("properties", impression.Properties); + } + currentFeatureImps.Add(impRecord); + currentFeature = impression.Feature; + } + impressionsPerFeature.Add(new Dictionary + { + { "f", currentFeature }, + { "i", currentFeatureImps } + }); + - return JsonConvert.SerializeObject(impressionsPerFeature); + return JsonConvert.SerializeObject(impressionsPerFeature); } public static string ConvertToJson(List impressionsCount) diff --git a/tests/Splitio.Integration-tests/PollingClientTests.cs b/tests/Splitio.Integration-tests/PollingClientTests.cs index beaafcc8..d3635a3d 100644 --- a/tests/Splitio.Integration-tests/PollingClientTests.cs +++ b/tests/Splitio.Integration-tests/PollingClientTests.cs @@ -347,8 +347,6 @@ public void GetTreatments_ValidateDedupeImpressions_Debug() Assert.AreEqual(0, impressionCounts.Count); } - // TODO: None mode is not supported yet. - [Ignore] [TestMethod] public void GetTreatments_WithImpressionsInNoneMode() { diff --git a/tests/Splitio.Tests.Common/BaseAsyncClientTests.cs b/tests/Splitio.Tests.Common/BaseAsyncClientTests.cs index 3c8e3f67..89be55ef 100644 --- a/tests/Splitio.Tests.Common/BaseAsyncClientTests.cs +++ b/tests/Splitio.Tests.Common/BaseAsyncClientTests.cs @@ -172,9 +172,14 @@ public async Task GetTreatment_BetweenSemverMatcher() var client = splitFactory.Client(); client.BlockUntilReady(10000); + EvaluationOptions evaluationOption = new EvaluationOptions( + new Dictionary { + { "prop1", "val1" } + } + ); // Act. - var result1 = await client.GetTreatmentAsync("mauro_test", "semver_between", new Dictionary { { "version", "2.0.0" } }); + var result1 = await client.GetTreatmentAsync("mauro_test", "semver_between", new Dictionary { { "version", "2.0.0" } }, evaluationOptions: evaluationOption); var result2 = await client.GetTreatmentAsync("mauro_test2", "semver_between", new Dictionary { { "version", "3.0.0" } }); client.Destroy(); @@ -182,7 +187,9 @@ public async Task GetTreatment_BetweenSemverMatcher() Assert.AreEqual("on", result1); Assert.AreEqual("off", result2); - var impressionExpected1 = Helper.GetImpressionExpected("semver_between", "mauro_test"); + var impExp = Helper.GetImpressionExpected("semver_between", "mauro_test"); + KeyImpression impressionExpected1 = new KeyImpression(impExp.KeyName, impExp.Feature, impExp.Treatment, impExp.Time, impExp.ChangeNumber, impExp.Label, impExp.BucketingKey, impExp.ImpressionsDisabled, impExp.PreviousTime, impExp.Optimized); + impressionExpected1.Properties = "{\"prop1\":\"val1\"}"; var impressionExpected2 = Helper.GetImpressionExpected("semver_between", "mauro_test2"); //Validate impressions sent to the be. diff --git a/tests/Splitio.Tests.Common/BaseIntegrationTests.cs b/tests/Splitio.Tests.Common/BaseIntegrationTests.cs index 5ffd6192..571499bf 100644 --- a/tests/Splitio.Tests.Common/BaseIntegrationTests.cs +++ b/tests/Splitio.Tests.Common/BaseIntegrationTests.cs @@ -1,10 +1,12 @@ -using Microsoft.VisualStudio.TestTools.UnitTesting; +using HandlebarsDotNet.Features; +using Microsoft.VisualStudio.TestTools.UnitTesting; using Splitio.Domain; using Splitio.Services.Client.Classes; using Splitio.Services.Impressions.Interfaces; using Splitio.Tests.Common.Resources; using System.Collections.Generic; using System.Linq; +using System.Reflection.Emit; namespace Splitio.Tests.Common { @@ -361,7 +363,9 @@ public void GetTreatment_WithtBUR_WithMultipleCalls_ReturnsTreatments() Assert.AreEqual("on", result3); Assert.AreEqual("off", result4); - var impressionExpected1 = GetImpressionExpected("FACUNDO_TEST", "nico_test"); + var impExp = GetImpressionExpected("FACUNDO_TEST", "nico_test"); + KeyImpression impressionExpected1 = new KeyImpression(impExp.KeyName, impExp.Feature, impExp.Treatment, impExp.Time, impExp.ChangeNumber, impExp.Label, impExp.BucketingKey, impExp.ImpressionsDisabled, impExp.PreviousTime, impExp.Optimized); + impressionExpected1.Properties = "{\"prop1\":\"val1\"}"; var impressionExpected2 = GetImpressionExpected("FACUNDO_TEST", "mauro_test"); var impressionExpected3 = GetImpressionExpected("Test_Save_1", "1"); var impressionExpected4 = GetImpressionExpected("Test_Save_1", "24"); @@ -516,7 +520,9 @@ public void GetTreatmentWithConfig_WithtBUR_WithMultipleCalls_ReturnsTreatments( Assert.AreEqual("{\"version\":\"v2\"}", result3.Config); Assert.AreEqual("{\"version\":\"v1\"}", result4.Config); - var impExpected1 = GetImpressionExpected("FACUNDO_TEST", "nico_test"); + var impExp = GetImpressionExpected("FACUNDO_TEST", "nico_test"); + KeyImpression impExpected1 = new KeyImpression(impExp.KeyName, impExp.Feature, impExp.Treatment, impExp.Time, impExp.ChangeNumber, impExp.Label, impExp.BucketingKey, impExp.ImpressionsDisabled, impExp.PreviousTime, impExp.Optimized); + impExpected1.Properties = "{\"prop1\":\"val1\"}"; var impExpected2 = GetImpressionExpected("FACUNDO_TEST", "mauro_test"); var impExpected3 = GetImpressionExpected("MAURO_TEST", "mauro"); var impExpected4 = GetImpressionExpected("MAURO_TEST", "test"); @@ -635,9 +641,15 @@ public void GetTreatments_WithtBUR_ReturnsTreatments() Assert.AreEqual("off", result["MAURO_TEST"]); Assert.AreEqual("off", result["Test_Save_1"]); - var impExpected1 = GetImpressionExpected("FACUNDO_TEST", "nico_test"); - var impExpected2 = GetImpressionExpected("MAURO_TEST", "nico_test"); - var impExpected3 = GetImpressionExpected("Test_Save_1", "nico_test"); + var impExp = GetImpressionExpected("FACUNDO_TEST", "nico_test"); + KeyImpression impExpected1 = new KeyImpression(impExp.KeyName, impExp.Feature, impExp.Treatment, impExp.Time, impExp.ChangeNumber, impExp.Label, impExp.BucketingKey, impExp.ImpressionsDisabled, impExp.PreviousTime, impExp.Optimized); + impExpected1.Properties = "{\"prop1\":\"val1\"}"; + impExp = GetImpressionExpected("MAURO_TEST", "nico_test"); + KeyImpression impExpected2 = new KeyImpression(impExp.KeyName, impExp.Feature, impExp.Treatment, impExp.Time, impExp.ChangeNumber, impExp.Label, impExp.BucketingKey, impExp.ImpressionsDisabled, impExp.PreviousTime, impExp.Optimized); + impExpected2.Properties = "{\"prop1\":\"val1\"}"; + impExp = GetImpressionExpected("Test_Save_1", "nico_test"); + KeyImpression impExpected3 = new KeyImpression(impExp.KeyName, impExp.Feature, impExp.Treatment, impExp.Time, impExp.ChangeNumber, impExp.Label, impExp.BucketingKey, impExp.ImpressionsDisabled, impExp.PreviousTime, impExp.Optimized); + impExpected3.Properties = "{\"prop1\":\"val1\"}"; //Validate impressions sent to the be. AssertSentImpressions(3, impExpected1, impExpected2, impExpected3); @@ -761,9 +773,15 @@ public void GetTreatmentsWithConfig_WithtBUR_ReturnsTreatments() Assert.AreEqual("{\"version\":\"v1\"}", result["MAURO_TEST"].Config); Assert.IsNull(result["Test_Save_1"].Config); - var impExpected1 = GetImpressionExpected("FACUNDO_TEST", "nico_test"); - var impExpected2 = GetImpressionExpected("MAURO_TEST", "nico_test"); - var impExpected3 = GetImpressionExpected("Test_Save_1", "nico_test"); + var impExp = GetImpressionExpected("FACUNDO_TEST", "nico_test"); + KeyImpression impExpected1 = new KeyImpression(impExp.KeyName, impExp.Feature, impExp.Treatment, impExp.Time, impExp.ChangeNumber, impExp.Label, impExp.BucketingKey, impExp.ImpressionsDisabled, impExp.PreviousTime, impExp.Optimized); + impExpected1.Properties = "{\"prop1\":\"val1\"}"; + impExp = GetImpressionExpected("MAURO_TEST", "nico_test"); + KeyImpression impExpected2 = new KeyImpression(impExp.KeyName, impExp.Feature, impExp.Treatment, impExp.Time, impExp.ChangeNumber, impExp.Label, impExp.BucketingKey, impExp.ImpressionsDisabled, impExp.PreviousTime, impExp.Optimized); + impExpected2.Properties = "{\"prop1\":\"val1\"}"; + impExp = GetImpressionExpected("Test_Save_1", "nico_test"); + KeyImpression impExpected3 = new KeyImpression(impExp.KeyName, impExp.Feature, impExp.Treatment, impExp.Time, impExp.ChangeNumber, impExp.Label, impExp.BucketingKey, impExp.ImpressionsDisabled, impExp.PreviousTime, impExp.Optimized); + impExpected3.Properties = "{\"prop1\":\"val1\"}"; //Validate impressions sent to the be. AssertSentImpressions(3, impExpected1, impExpected2, impExpected3); @@ -902,8 +920,10 @@ public void GetTreatmentsWithConfigByFlagSets_WithoutFlagSetsInConfig() Assert.AreEqual("{\"color\":\"green\"}", treatment.Value.Config); //Validate impressions sent to the be. - var impressionExpected = new KeyImpression("nico_test", "FACUNDO_TEST", "on", 0, 1506703262916, "whitelisted", null, false, null, false); - + var impExp = new KeyImpression("nico_test", "FACUNDO_TEST", "on", 0, 1506703262916, "whitelisted", null, false, null, false); + KeyImpression impressionExpected = new KeyImpression(impExp.KeyName, impExp.Feature, impExp.Treatment, impExp.Time, impExp.ChangeNumber, impExp.Label, impExp.BucketingKey, impExp.ImpressionsDisabled, impExp.PreviousTime, impExp.Optimized); + impressionExpected.Properties = "{\"prop1\":\"val1\"}"; + AssertSentImpressions(1, impressionExpected); AssertImpressionListener(1, impressionListener); Helper.AssertImpression(impressionListener.Get("FACUNDO_TEST", "nico_test"), impressionExpected); @@ -964,7 +984,9 @@ public void GetTreatmentsByFlagSets_WithoutFlagSetsInConfig() Assert.AreEqual("FACUNDO_TEST", treatment.Key); Assert.AreEqual("on", treatment.Value); - var impExpected1 = GetImpressionExpected("FACUNDO_TEST", "nico_test"); + var impExp = GetImpressionExpected("FACUNDO_TEST", "nico_test"); + KeyImpression impExpected1 = new KeyImpression(impExp.KeyName, impExp.Feature, impExp.Treatment, impExp.Time, impExp.ChangeNumber, impExp.Label, impExp.BucketingKey, impExp.ImpressionsDisabled, impExp.PreviousTime, impExp.Optimized); + impExpected1.Properties = "{\"prop1\":\"val1\"}"; //Validate impressions sent to the be. AssertSentImpressions(1, impExpected1); @@ -1028,7 +1050,9 @@ public void GetTreatmentsWithConfigByFlagSet_WithoutFlagSetsInConfig() Assert.AreEqual("on", treatment.Value.Treatment); Assert.AreEqual("{\"color\":\"green\"}", treatment.Value.Config); - var impExpected1 = GetImpressionExpected("FACUNDO_TEST", "nico_test"); + var impExp = GetImpressionExpected("FACUNDO_TEST", "nico_test"); + KeyImpression impExpected1 = new KeyImpression(impExp.KeyName, impExp.Feature, impExp.Treatment, impExp.Time, impExp.ChangeNumber, impExp.Label, impExp.BucketingKey, impExp.ImpressionsDisabled, impExp.PreviousTime, impExp.Optimized); + impExpected1.Properties = "{\"prop1\":\"val1\"}"; //Validate impressions sent to the be. AssertSentImpressions(1, impExpected1); @@ -1091,7 +1115,9 @@ public void GetTreatmentsByFlagSet_WithoutFlagSetsInConfig() Assert.AreEqual("FACUNDO_TEST", treatment.Key); Assert.AreEqual("on", treatment.Value); - var impExpected1 = GetImpressionExpected("FACUNDO_TEST", "nico_test"); + var impExp = GetImpressionExpected("FACUNDO_TEST", "nico_test"); + KeyImpression impExpected1 = new KeyImpression(impExp.KeyName, impExp.Feature, impExp.Treatment, impExp.Time, impExp.ChangeNumber, impExp.Label, impExp.BucketingKey, impExp.ImpressionsDisabled, impExp.PreviousTime, impExp.Optimized); + impExpected1.Properties = "{\"prop1\":\"val1\"}"; //Validate impressions sent to the be. AssertSentImpressions(1, impExpected1); diff --git a/tests/Splitio.Tests.Common/Resources/InMemoryHelper.cs b/tests/Splitio.Tests.Common/Resources/InMemoryHelper.cs index 67f1d98f..9419df76 100644 --- a/tests/Splitio.Tests.Common/Resources/InMemoryHelper.cs +++ b/tests/Splitio.Tests.Common/Resources/InMemoryHelper.cs @@ -107,6 +107,7 @@ public static void AssertSentImpressions(int sentImpressionsCount, HttpClientMoc .Where(si => expectedImp.KeyName == si.K) .Where(si => expectedImp.Label == si.R) .Where(si => expectedImp.Treatment == si.T) + .Where(si => expectedImp.Properties == si.PROPERTIES) .Any()); } } diff --git a/tests/Splitio.Tests.Common/Resources/KeyImpressionBackend.cs b/tests/Splitio.Tests.Common/Resources/KeyImpressionBackend.cs index c0eae1d1..a21c44b4 100644 --- a/tests/Splitio.Tests.Common/Resources/KeyImpressionBackend.cs +++ b/tests/Splitio.Tests.Common/Resources/KeyImpressionBackend.cs @@ -14,6 +14,7 @@ public class ImpressionData public string B { get; set; } public string T { get; set; } public string R { get; set; } + public string PROPERTIES { get; set; } public long? C { get; set; } public long? M { get; set; } } From f4760ee9ab0d23f6e07ab3209c737803415a8d00 Mon Sep 17 00:00:00 2001 From: Bill Al Date: Tue, 12 Aug 2025 14:36:58 -0700 Subject: [PATCH 2/3] polish --- .../Services/Impressions/Classes/ImpressionsSdkApiClient.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/Splitio/Services/Impressions/Classes/ImpressionsSdkApiClient.cs b/src/Splitio/Services/Impressions/Classes/ImpressionsSdkApiClient.cs index 6de0f076..7734c15d 100644 --- a/src/Splitio/Services/Impressions/Classes/ImpressionsSdkApiClient.cs +++ b/src/Splitio/Services/Impressions/Classes/ImpressionsSdkApiClient.cs @@ -10,8 +10,6 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Linq.Expressions; -using System.Runtime.ExceptionServices; using System.Threading.Tasks; namespace Splitio.Services.Impressions.Classes @@ -124,8 +122,7 @@ public static string ConvertToJson(List impressions) { "i", currentFeatureImps } }); - - return JsonConvert.SerializeObject(impressionsPerFeature); + return JsonConvert.SerializeObject(impressionsPerFeature); } public static string ConvertToJson(List impressionsCount) From 18a7af60f5e9d08bff7527ea1de65c99d12bc7a1 Mon Sep 17 00:00:00 2001 From: Bill Al Date: Tue, 12 Aug 2025 16:21:12 -0700 Subject: [PATCH 3/3] poilsh --- .../Services/Impressions/Classes/ImpressionsSdkApiClient.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Splitio/Services/Impressions/Classes/ImpressionsSdkApiClient.cs b/src/Splitio/Services/Impressions/Classes/ImpressionsSdkApiClient.cs index 7734c15d..95f8b8e0 100644 --- a/src/Splitio/Services/Impressions/Classes/ImpressionsSdkApiClient.cs +++ b/src/Splitio/Services/Impressions/Classes/ImpressionsSdkApiClient.cs @@ -97,7 +97,6 @@ public static string ConvertToJson(List impressions) { "f", currentFeature }, { "i", currentFeatureImps } }); - currentFeature = ""; currentFeatureImps = new List>(); } impRecord = new Dictionary