-
Notifications
You must be signed in to change notification settings - Fork 20
[FSSDK-10265] fix: UPS Lookup
& Save
during batched Decide
#374
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 14 commits
963fc07
d0f59b6
14dface
66708d8
aa0d018
dd072b9
f9f3f3f
b43e10f
0dd1b74
2b17438
c9047a0
dfe1367
57c1ccd
9ca271c
c97f36e
5b7e5ae
c6889e8
2f46b18
54a2dc2
9f2f471
73658f6
80e73d4
236728b
d6258f1
9c6e9bb
49f9584
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
/* | ||
* Copyright 2020-2021, 2022-2023 Optimizely and contributors | ||
* Copyright 2020-2024 Optimizely and contributors | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
|
@@ -16,7 +16,6 @@ | |
|
||
using System; | ||
using System.Collections.Generic; | ||
using System.Threading; | ||
using Castle.Core.Internal; | ||
using Moq; | ||
using NUnit.Framework; | ||
|
@@ -62,6 +61,22 @@ public void SetUp() | |
LoggerMock.Object, ErrorHandlerMock.Object); | ||
} | ||
|
||
private Mock<UserProfileService> makeUserProfileServiceMock() | ||
{ | ||
var projectConfig = DatafileProjectConfig.Create(TestData.Datafile, LoggerMock.Object, | ||
ErrorHandlerMock.Object); | ||
var experiment = projectConfig.Experiments[8]; | ||
var variation = experiment.Variations[0]; | ||
var decision = new Decision(variation.Id); | ||
var userProfile = new UserProfile(UserID, new Dictionary<string, Decision> | ||
{ | ||
{ experiment.Id, decision }, | ||
}); | ||
var userProfileServiceMock = new Mock<UserProfileService>(); | ||
userProfileServiceMock.Setup(up => up.Lookup(UserID)).Returns(userProfile.ToMap()); | ||
return userProfileServiceMock; | ||
} | ||
|
||
[Test] | ||
public void OptimizelyUserContextWithAttributes() | ||
{ | ||
|
@@ -193,7 +208,7 @@ public void SetAttributeToOverrideAttribute() | |
Assert.AreEqual(user.GetAttributes()["k1"], true); | ||
} | ||
|
||
#region decide | ||
#region Decide | ||
|
||
[Test] | ||
public void TestDecide() | ||
|
@@ -409,9 +424,55 @@ public void DecideWhenConfigIsNull() | |
Assert.IsTrue(TestData.CompareObjects(decision, decisionExpected)); | ||
} | ||
|
||
#endregion decide | ||
[Test] | ||
public void DecideWithUspShouldOnlyLookupSaveOnce() | ||
{ | ||
var flagKeyFromTestDataJson = "double_single_variable_feature"; | ||
var userProfileServiceMock = makeUserProfileServiceMock(); | ||
var optimizely = new Optimizely(TestData.Datafile, EventDispatcherMock.Object, | ||
LoggerMock.Object, ErrorHandlerMock.Object, userProfileServiceMock.Object); | ||
var user = optimizely.CreateUserContext(UserID); | ||
|
||
_ = user.Decide(flagKeyFromTestDataJson); | ||
|
||
LoggerMock.Verify( | ||
l => l.Log(LogLevel.INFO, | ||
"We were unable to get a user profile map from the UserProfileService."), | ||
Times.Never); | ||
LoggerMock.Verify( | ||
l => l.Log(LogLevel.ERROR, "The UserProfileService returned an invalid map."), | ||
Times.Never); | ||
userProfileServiceMock.Verify(l => l.Lookup(UserID), Times.Once); | ||
userProfileServiceMock.Verify(l => l.Save(It.IsAny<Dictionary<string, object>>()), | ||
Times.Once); | ||
} | ||
|
||
#endregion Decide | ||
|
||
#region DecideForKeys | ||
|
||
[Test] | ||
public void DecideForKeysWithUspShouldOnlyLookupSaveOnceWithMultipleFlags() | ||
{ | ||
var flagKeys = new[] { "double_single_variable_feature", "boolean_feature" }; | ||
var userProfileServiceMock = makeUserProfileServiceMock(); | ||
var optimizely = new Optimizely(TestData.Datafile, EventDispatcherMock.Object, | ||
LoggerMock.Object, ErrorHandlerMock.Object, userProfileServiceMock.Object); | ||
var userContext = optimizely.CreateUserContext(UserID); | ||
|
||
_ = userContext.DecideForKeys(flagKeys); | ||
|
||
#region decideAll | ||
LoggerMock.Verify( | ||
l => l.Log(LogLevel.INFO, | ||
"We were unable to get a user profile map from the UserProfileService."), | ||
Times.Never); | ||
LoggerMock.Verify( | ||
l => l.Log(LogLevel.ERROR, "The UserProfileService returned an invalid map."), | ||
Times.Never); | ||
userProfileServiceMock.Verify(l => l.Lookup(UserID), Times.Once); | ||
userProfileServiceMock.Verify(l => l.Save(It.IsAny<Dictionary<string, object>>()), | ||
Times.Once); | ||
} | ||
|
||
[Test] | ||
public void DecideForKeysWithOneFlag() | ||
|
@@ -443,6 +504,32 @@ public void DecideForKeysWithOneFlag() | |
Assert.IsTrue(TestData.CompareObjects(decision, expDecision)); | ||
} | ||
|
||
#endregion DecideForKeys | ||
|
||
#region DecideAll | ||
|
||
[Test] | ||
public void DecideAllWithUspShouldOnlyLookupSaveOnce() | ||
{ | ||
var userProfileServiceMock = makeUserProfileServiceMock(); | ||
var optimizely = new Optimizely(TestData.Datafile, EventDispatcherMock.Object, | ||
LoggerMock.Object, ErrorHandlerMock.Object, userProfileServiceMock.Object); | ||
var user = optimizely.CreateUserContext(UserID); | ||
|
||
_ = user.DecideAll(); | ||
|
||
LoggerMock.Verify( | ||
l => l.Log(LogLevel.INFO, | ||
"We were unable to get a user profile map from the UserProfileService."), | ||
Times.Never); | ||
LoggerMock.Verify( | ||
l => l.Log(LogLevel.ERROR, "The UserProfileService returned an invalid map."), | ||
Times.Never); | ||
userProfileServiceMock.Verify(l => l.Lookup(UserID), Times.Once); | ||
userProfileServiceMock.Verify(l => l.Save(It.IsAny<Dictionary<string, object>>()), | ||
Times.Once); | ||
} | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These tests look good. Wondering if we have tests covering the contents of the final UPS save call, combining all decisions in the session. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we also have the similar coverage (lookup once - save once, the ups save contents) with legacy APIs (activate, getVariation) for regression? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added coverage of the final UPS I'm researching the |
||
[Test] | ||
public void DecideAllTwoFlag() | ||
{ | ||
|
Uh oh!
There was an error while loading. Please reload this page.