Skip to content

feat: Fix NotificationCenter Issue for ODPManager #324

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

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
<Compile Include="..\OptimizelySDK\IOptimizely.cs">
<Link>IOptimizely.cs</Link>
</Compile>
<Compile Include="..\OptimizelySDK\Notifications\NotificationCenterRegistry.cs">
<Link>Notifications\NotificationCenterRegistry.cs</Link>
</Compile>
<Compile Include="..\OptimizelySDK\Odp\Constants.cs">
<Link>Odp\Constants.cs</Link>
</Compile>
Expand Down Expand Up @@ -40,9 +43,6 @@
<Compile Include="..\OptimizelySDK\Odp\Entity\OdpEvent.cs">
<Link>Odp\Entity\OdpEvent.cs</Link>
</Compile>
<Compile Include="..\OptimizelySDK\Odp\Entity\OptimizelySdkSettings.cs">
<Link>Odp\Entity\OptimizelySdkSettings.cs</Link>
</Compile>
<Compile Include="..\OptimizelySDK\Odp\Entity\Response.cs">
<Link>Odp\Entity\Response.cs</Link>
</Compile>
Expand Down
68 changes: 42 additions & 26 deletions OptimizelySDK.Tests/OdpTests/OdpEventManagerTests.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2022, Optimizely
* Copyright 2022-2023, Optimizely
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -155,12 +155,14 @@ public void Setup()
[Test]
public void ShouldLogAndDiscardEventsWhenEventManagerNotRunning()
{
var eventManager = new OdpEventManager.Builder().WithOdpConfig(_odpConfig).
var eventManager = new OdpEventManager.Builder().
WithOdpEventApiManager(_mockApiManager.Object).
WithLogger(_mockLogger.Object).
Build(startImmediately: false);
WithAutoStart(false).
Build();
eventManager.UpdateSettings(_odpConfig);

// since we've not called start() then...
// since we've not called Start() then...
eventManager.SendEvent(_testEvents[0]);

// ...we should get a notice after trying to send an event
Expand All @@ -173,11 +175,13 @@ public void ShouldLogAndDiscardEventsWhenEventManagerNotRunning()
public void ShouldLogAndDiscardEventsWhenEventManagerConfigNotReady()
{
var mockOdpConfig = new Mock<OdpConfig>(API_KEY, API_HOST, _emptySegmentsToCheck);
mockOdpConfig.Setup(o => o.IsReady()).Returns(false);
var eventManager = new OdpEventManager.Builder().WithOdpConfig(mockOdpConfig.Object).
mockOdpConfig.Setup(o => o.IsReady()).Returns(false); // stay not ready
var eventManager = new OdpEventManager.Builder().
WithOdpEventApiManager(_mockApiManager.Object).
WithLogger(_mockLogger.Object).
Build(startImmediately: false); // doing it manually in Act next
WithAutoStart(false). // start manually in Act
Build();
eventManager.UpdateSettings(mockOdpConfig.Object);

eventManager.Start(); // Log when Start() called
eventManager.SendEvent(_testEvents[0]); // Log when enqueue attempted
Expand All @@ -191,30 +195,33 @@ public void ShouldLogAndDiscardEventsWhenEventManagerConfigNotReady()
public void ShouldLogWhenOdpNotIntegratedAndIdentifyUserCalled()
{
var mockOdpConfig = new Mock<OdpConfig>(API_KEY, API_HOST, _emptySegmentsToCheck);
mockOdpConfig.Setup(o => o.IsReady()).Returns(false);
var eventManager = new OdpEventManager.Builder().WithOdpConfig(mockOdpConfig.Object).
mockOdpConfig.Setup(o => o.IsReady()).Returns(false); // never ready
var eventManager = new OdpEventManager.Builder().
WithOdpEventApiManager(_mockApiManager.Object).
WithLogger(_mockLogger.Object).
Build();
Build(); // assumed AutoStart true; Logs 1x here
eventManager.UpdateSettings(mockOdpConfig.Object); // auto-start after update; Logs 1x here

eventManager.IdentifyUser(FS_USER_ID);
eventManager.IdentifyUser(FS_USER_ID); // Logs 1x here too

_mockLogger.Verify(
l => l.Log(LogLevel.WARN, Constants.ODP_NOT_INTEGRATED_MESSAGE),
Times.Exactly(2)); // during Start() and SendEvent()
Times.Exactly(3)); // during Start() and SendEvent()
}

[Test]
public void ShouldLogWhenOdpNotIntegratedAndStartCalled()
{
var mockOdpConfig = new Mock<OdpConfig>(API_KEY, API_HOST, _emptySegmentsToCheck);
mockOdpConfig.Setup(o => o.IsReady()).Returns(false);
var eventManager = new OdpEventManager.Builder().WithOdpConfig(mockOdpConfig.Object).
mockOdpConfig.Setup(o => o.IsReady()).Returns(false); // since never ready
var eventManager = new OdpEventManager.Builder().
WithOdpEventApiManager(_mockApiManager.Object).
WithLogger(_mockLogger.Object).
Build(startImmediately: false); // doing it manually in Act next
WithAutoStart(false). // doing it manually in Act next
Build();
eventManager.UpdateSettings(mockOdpConfig.Object);

eventManager.Start();
eventManager.Start(); // Log 1x here too

_mockLogger.Verify(l => l.Log(LogLevel.WARN, Constants.ODP_NOT_INTEGRATED_MESSAGE),
Times.Once);
Expand Down Expand Up @@ -250,10 +257,11 @@ public void ShouldDiscardEventsWithInvalidData()
"key-3", new DateTime()
},
});
var eventManager = new OdpEventManager.Builder().WithOdpConfig(_odpConfig).
var eventManager = new OdpEventManager.Builder().
WithOdpEventApiManager(_mockApiManager.Object).
WithLogger(_mockLogger.Object).
Build();
eventManager.UpdateSettings(_odpConfig);

eventManager.SendEvent(eventWithAnArray);
eventManager.SendEvent(eventWithADate);
Expand All @@ -271,16 +279,17 @@ public void ShouldAddAdditionalInformationToEachEvent()
_mockApiManager.Setup(api => api.SendEvents(It.IsAny<string>(), It.IsAny<string>(),
Capture.In(eventsCollector))).
Callback(() => cde.Signal());
var eventManager = new OdpEventManager.Builder().WithOdpConfig(_odpConfig).
var eventManager = new OdpEventManager.Builder().
WithOdpEventApiManager(_mockApiManager.Object).
WithLogger(_mockLogger.Object).
WithEventQueue(new BlockingCollection<object>(10)). // max capacity of 10
WithBatchSize(10).
WithFlushInterval(TimeSpan.FromMilliseconds(100)).
Build();
eventManager.UpdateSettings(_odpConfig);

eventManager.SendEvent(_testEvents[0]);
cde.Wait();
cde.Wait(MAX_COUNT_DOWN_EVENT_WAIT_MS);

var eventsSentToApi = eventsCollector.FirstOrDefault();
var actualEvent = eventsSentToApi?.FirstOrDefault();
Expand All @@ -304,13 +313,14 @@ public void ShouldAddAdditionalInformationToEachEvent()
[Test]
public void ShouldAttemptToFlushAnEmptyQueueAtFlushInterval()
{
var eventManager = new OdpEventManager.Builder().WithOdpConfig(_odpConfig).
var eventManager = new OdpEventManager.Builder().
WithOdpEventApiManager(_mockApiManager.Object).
WithLogger(_mockLogger.Object).
WithEventQueue(new BlockingCollection<object>(10)).
WithBatchSize(10).
WithFlushInterval(TimeSpan.FromMilliseconds(100)).
Build();
eventManager.UpdateSettings(_odpConfig);

// do not add events to the queue, but allow for
// at least 3 flush intervals executions
Expand All @@ -328,13 +338,14 @@ public void ShouldDispatchEventsInCorrectNumberOfBatches()
a.SendEvents(It.IsAny<string>(), It.IsAny<string>(),
It.IsAny<List<OdpEvent>>())).
Returns(false);
var eventManager = new OdpEventManager.Builder().WithOdpConfig(_odpConfig).
var eventManager = new OdpEventManager.Builder().
WithOdpEventApiManager(_mockApiManager.Object).
WithLogger(_mockLogger.Object).
WithEventQueue(new BlockingCollection<object>(10)).
WithBatchSize(10).
WithFlushInterval(TimeSpan.FromMilliseconds(500)).
Build();
eventManager.UpdateSettings(_odpConfig);

for (int i = 0; i < 25; i++)
{
Expand Down Expand Up @@ -362,12 +373,13 @@ public void ShouldDispatchEventsWithCorrectPayload()
Capture.In(eventCollector))).
Callback(() => cde.Signal()).
Returns(false);
var eventManager = new OdpEventManager.Builder().WithOdpConfig(_odpConfig).
var eventManager = new OdpEventManager.Builder().
WithOdpEventApiManager(_mockApiManager.Object).
WithLogger(_mockLogger.Object).
WithBatchSize(10).
WithFlushInterval(TimeSpan.FromSeconds(1)).
Build();
eventManager.UpdateSettings(_odpConfig);

_testEvents.ForEach(e => eventManager.SendEvent(e));
cde.Wait(MAX_COUNT_DOWN_EVENT_WAIT_MS);
Expand Down Expand Up @@ -395,13 +407,14 @@ public void ShouldRetryFailedEvents()
It.IsAny<List<OdpEvent>>())).
Callback(() => cde.Signal()).
Returns(true);
var eventManager = new OdpEventManager.Builder().WithOdpConfig(_odpConfig).
var eventManager = new OdpEventManager.Builder().
WithOdpEventApiManager(_mockApiManager.Object).
WithLogger(_mockLogger.Object).
WithEventQueue(new BlockingCollection<object>(10)).
WithBatchSize(2).
WithFlushInterval(TimeSpan.FromMilliseconds(100)).
Build();
eventManager.UpdateSettings(_odpConfig);

for (int i = 0; i < 4; i++)
{
Expand All @@ -419,13 +432,14 @@ public void ShouldRetryFailedEvents()
[Test]
public void ShouldFlushAllScheduledEventsBeforeStopping()
{
var eventManager = new OdpEventManager.Builder().WithOdpConfig(_odpConfig).
var eventManager = new OdpEventManager.Builder().
WithOdpEventApiManager(_mockApiManager.Object).
WithLogger(_mockLogger.Object).
WithEventQueue(new BlockingCollection<object>(100)).
WithBatchSize(2). // small batch size
WithFlushInterval(TimeSpan.FromSeconds(2)). // long flush interval
Build();
eventManager.UpdateSettings(_odpConfig);

for (int i = 0; i < 25; i++)
{
Expand Down Expand Up @@ -453,12 +467,13 @@ public void ShouldPrepareCorrectPayloadForIdentifyUser()
_mockApiManager.Setup(api => api.SendEvents(It.IsAny<string>(), It.IsAny<string>(),
Capture.In(eventsCollector))).
Callback(() => cde.Signal());
var eventManager = new OdpEventManager.Builder().WithOdpConfig(_odpConfig).
var eventManager = new OdpEventManager.Builder().
WithOdpEventApiManager(_mockApiManager.Object).
WithLogger(_mockLogger.Object).
WithEventQueue(new BlockingCollection<object>(1)).
WithBatchSize(1).
Build();
eventManager.UpdateSettings(_odpConfig);

eventManager.IdentifyUser(USER_ID);
cde.Wait(MAX_COUNT_DOWN_EVENT_WAIT_MS);
Expand Down Expand Up @@ -488,10 +503,11 @@ public void ShouldApplyUpdatedOdpConfigurationWhenAvailable()
"1-item-cart",
};
var differentOdpConfig = new OdpConfig(apiKey, apiHost, segmentsToCheck);
var eventManager = new OdpEventManager.Builder().WithOdpConfig(_odpConfig).
var eventManager = new OdpEventManager.Builder().
WithOdpEventApiManager(_mockApiManager.Object).
WithLogger(_mockLogger.Object).
Build();
eventManager.UpdateSettings(_odpConfig);

eventManager.UpdateSettings(differentOdpConfig);

Expand Down
Loading