Skip to content

Commit b5658b1

Browse files
test: cover new cases
1 parent b315d5d commit b5658b1

File tree

1 file changed

+158
-5
lines changed

1 file changed

+158
-5
lines changed

OptimizelySDK.Tests/OptimizelyUserContextTest.cs

Lines changed: 158 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2020-2021, 2022-2023 Optimizely and contributors
2+
* Copyright 2020-2021, 2022-2024 Optimizely and contributors
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,7 +16,7 @@
1616

1717
using System;
1818
using System.Collections.Generic;
19-
using System.Threading;
19+
using System.Linq;
2020
using Castle.Core.Internal;
2121
using Moq;
2222
using NUnit.Framework;
@@ -61,6 +61,22 @@ public void SetUp()
6161
Optimizely = new Optimizely(TestData.Datafile, EventDispatcherMock.Object,
6262
LoggerMock.Object, ErrorHandlerMock.Object);
6363
}
64+
65+
private Mock<UserProfileService> MakeUserProfileServiceMock()
66+
{
67+
var projectConfig = DatafileProjectConfig.Create(TestData.Datafile, LoggerMock.Object,
68+
ErrorHandlerMock.Object);
69+
var experiment = projectConfig.Experiments[8];
70+
var variation = experiment.Variations[0];
71+
var decision = new Decision(variation.Id);
72+
var userProfile = new UserProfile(UserID, new Dictionary<string, Decision>
73+
{
74+
{ experiment.Id, decision },
75+
});
76+
var userProfileServiceMock = new Mock<UserProfileService>();
77+
userProfileServiceMock.Setup(up => up.Lookup(UserID)).Returns(userProfile.ToMap());
78+
return userProfileServiceMock;
79+
}
6480

6581
[Test]
6682
public void OptimizelyUserContextWithAttributes()
@@ -193,7 +209,7 @@ public void SetAttributeToOverrideAttribute()
193209
Assert.AreEqual(user.GetAttributes()["k1"], true);
194210
}
195211

196-
#region decide
212+
#region Decide
197213

198214
[Test]
199215
public void TestDecide()
@@ -409,10 +425,111 @@ public void DecideWhenConfigIsNull()
409425
Assert.IsTrue(TestData.CompareObjects(decision, decisionExpected));
410426
}
411427

412-
#endregion decide
428+
[Test]
429+
public void SeparateDecideShouldHaveSameNumberOfUpsSaveOnlyOneLookup()
430+
{
431+
var experimentFlagKey = "double_single_variable_feature";
432+
var rolloutFlagKey = "boolean_single_variable_feature";
433+
var userProfileServiceMock = MakeUserProfileServiceMock();
434+
var saveArgsCollector = new List<Dictionary<string, object>>();
435+
userProfileServiceMock.Setup(up => up.Save(Capture.In(saveArgsCollector)));
436+
var optimizely = new Optimizely(TestData.Datafile, EventDispatcherMock.Object,
437+
LoggerMock.Object, ErrorHandlerMock.Object, userProfileServiceMock.Object);
438+
var user = optimizely.CreateUserContext(UserID);
439+
var expectedUserProfileExperiment = new UserProfile(UserID, new Dictionary<string, Decision>
440+
{
441+
{ "224", new Decision("280") },
442+
{ "122238", new Decision("122240") },
443+
});
444+
var expectedUserProfileRollout = new UserProfile(UserID, new Dictionary<string, Decision>
445+
{
446+
{ "999", new Decision("99") },
447+
{ "99999", new Decision("999") },
448+
});
449+
450+
user.Decide(experimentFlagKey);
451+
user.Decide(rolloutFlagKey);
452+
453+
LoggerMock.Verify(
454+
l => l.Log(LogLevel.INFO,
455+
"We were unable to get a user profile map from the UserProfileService."),
456+
Times.Never);
457+
LoggerMock.Verify(
458+
l => l.Log(LogLevel.ERROR, "The UserProfileService returned an invalid map."),
459+
Times.Never);
460+
userProfileServiceMock.Verify(l => l.Lookup(UserID), Times.Once);
461+
userProfileServiceMock.Verify(l => l.Save(It.IsAny<Dictionary<string, object>>()),
462+
Times.Exactly(2));
463+
Assert.AreEqual(saveArgsCollector[0], expectedUserProfileExperiment.ToMap());
464+
Assert.AreEqual(saveArgsCollector[1], expectedUserProfileRollout.ToMap());
465+
}
466+
467+
[Test]
468+
public void DecideWithUpsShouldOnlyLookupSaveOnce()
469+
{
470+
var flagKeyFromTestDataJson = "double_single_variable_feature";
471+
var userProfileServiceMock = MakeUserProfileServiceMock();
472+
var saveArgsCollector = new List<Dictionary<string, object>>();
473+
userProfileServiceMock.Setup(up => up.Save(Capture.In(saveArgsCollector)));
474+
var optimizely = new Optimizely(TestData.Datafile, EventDispatcherMock.Object,
475+
LoggerMock.Object, ErrorHandlerMock.Object, userProfileServiceMock.Object);
476+
var user = optimizely.CreateUserContext(UserID);
477+
var expectedUserProfile = new UserProfile(UserID, new Dictionary<string, Decision>
478+
{
479+
{ "224", new Decision("280") },
480+
{ "122238", new Decision("122240") },
481+
});
482+
483+
user.Decide(flagKeyFromTestDataJson);
484+
485+
LoggerMock.Verify(
486+
l => l.Log(LogLevel.INFO,
487+
"We were unable to get a user profile map from the UserProfileService."),
488+
Times.Never);
489+
LoggerMock.Verify(
490+
l => l.Log(LogLevel.ERROR, "The UserProfileService returned an invalid map."),
491+
Times.Never);
492+
userProfileServiceMock.Verify(l => l.Lookup(UserID), Times.Once);
493+
userProfileServiceMock.Verify(l => l.Save(It.IsAny<Dictionary<string, object>>()),
494+
Times.Once);
495+
Assert.AreEqual(saveArgsCollector.First(), expectedUserProfile.ToMap());
496+
}
497+
498+
#endregion Decide
499+
500+
#region DecideForKeys
413501

414-
#region decideAll
502+
[Test]
503+
public void DecideForKeysWithUpsShouldOnlyLookupSaveOnceWithMultipleFlags()
504+
{
505+
var flagKeys = new[] { "double_single_variable_feature", "boolean_feature" };
506+
var userProfileServiceMock = MakeUserProfileServiceMock();
507+
var saveArgsCollector = new List<Dictionary<string, object>>();
508+
userProfileServiceMock.Setup(up => up.Save(Capture.In(saveArgsCollector)));
509+
var optimizely = new Optimizely(TestData.Datafile, EventDispatcherMock.Object,
510+
LoggerMock.Object, ErrorHandlerMock.Object, userProfileServiceMock.Object);
511+
var userContext = optimizely.CreateUserContext(UserID);
512+
var expectedUserProfile = new UserProfile(UserID, new Dictionary<string, Decision>
513+
{
514+
{ "224", new Decision("280") },
515+
{ "122238", new Decision("122240") },
516+
});
415517

518+
userContext.DecideForKeys(flagKeys);
519+
520+
LoggerMock.Verify(
521+
l => l.Log(LogLevel.INFO,
522+
"We were unable to get a user profile map from the UserProfileService."),
523+
Times.Never);
524+
LoggerMock.Verify(
525+
l => l.Log(LogLevel.ERROR, "The UserProfileService returned an invalid map."),
526+
Times.Never);
527+
userProfileServiceMock.Verify(l => l.Lookup(UserID), Times.Once);
528+
userProfileServiceMock.Verify(l => l.Save(It.IsAny<Dictionary<string, object>>()),
529+
Times.Once);
530+
Assert.AreEqual(saveArgsCollector.First(), expectedUserProfile.ToMap());
531+
}
532+
416533
[Test]
417534
public void DecideForKeysWithOneFlag()
418535
{
@@ -442,6 +559,42 @@ public void DecideForKeysWithOneFlag()
442559
new string[0]);
443560
Assert.IsTrue(TestData.CompareObjects(decision, expDecision));
444561
}
562+
563+
#endregion DecideForKeys
564+
565+
#region DecideAll
566+
567+
[Test]
568+
public void DecideAllWithUpsShouldOnlyLookupSaveOnce()
569+
{
570+
var userProfileServiceMock = MakeUserProfileServiceMock();
571+
var saveArgsCollector = new List<Dictionary<string, object>>();
572+
userProfileServiceMock.Setup(up => up.Save(Capture.In(saveArgsCollector)));
573+
var optimizely = new Optimizely(TestData.Datafile, EventDispatcherMock.Object,
574+
LoggerMock.Object, ErrorHandlerMock.Object, userProfileServiceMock.Object);
575+
var user = optimizely.CreateUserContext(UserID);
576+
var expectedUserProfile = new UserProfile(UserID, new Dictionary<string, Decision>
577+
{
578+
{ "224", new Decision("280") },
579+
{ "122238", new Decision("122240") },
580+
{ "122241", new Decision("122242") },
581+
{ "122235", new Decision("122236") },
582+
{ "188880", new Decision("188881") },
583+
});
584+
585+
user.DecideAll();
586+
587+
LoggerMock.Verify(
588+
l => l.Log(LogLevel.INFO,
589+
"We were unable to get a user profile map from the UserProfileService."),
590+
Times.Never);
591+
LoggerMock.Verify(
592+
l => l.Log(LogLevel.ERROR, "The UserProfileService returned an invalid map."),
593+
Times.Never);
594+
userProfileServiceMock.Verify(l => l.Lookup(UserID), Times.Once);
595+
userProfileServiceMock.Verify(l => l.Save(It.IsAny<Dictionary<string,object>>()), Times.Once);
596+
Assert.AreEqual(saveArgsCollector.First(), expectedUserProfile.ToMap());
597+
}
445598

446599
[Test]
447600
public void DecideAllTwoFlag()

0 commit comments

Comments
 (0)