From 4f3f06fc7a464dbfcee4cbf603f82591c92e893b Mon Sep 17 00:00:00 2001 From: Yasir Ali Date: Wed, 14 Oct 2020 12:50:16 +0500 Subject: [PATCH] suggested changes made. --- Sources/Optimizely/OptimizelyClient.swift | 2 +- Sources/Utils/Constants.swift | 1 + .../BatchEventBuilderTests_Events.swift | 119 ++++++++++++++++-- .../DecisionListenerTests.swift | 62 +-------- 4 files changed, 114 insertions(+), 70 deletions(-) diff --git a/Sources/Optimizely/OptimizelyClient.swift b/Sources/Optimizely/OptimizelyClient.swift index 7e1facea4..81b7d1f7c 100644 --- a/Sources/Optimizely/OptimizelyClient.swift +++ b/Sources/Optimizely/OptimizelyClient.swift @@ -260,7 +260,7 @@ open class OptimizelyClient: NSObject { userId: userId, attributes: attributes, flagKey: "", - ruleType: "experiment") + ruleType: Constants.DecisionSource.experiment.rawValue) return variation.key } diff --git a/Sources/Utils/Constants.swift b/Sources/Utils/Constants.swift index d43ad4918..bedb676a6 100644 --- a/Sources/Utils/Constants.swift +++ b/Sources/Utils/Constants.swift @@ -45,6 +45,7 @@ struct Constants { } enum DecisionSource: String { + case experiment = "experiment" case featureTest = "feature-test" case rollout = "rollout" } diff --git a/Tests/OptimizelyTests-Common/BatchEventBuilderTests_Events.swift b/Tests/OptimizelyTests-Common/BatchEventBuilderTests_Events.swift index c80e111f7..197436911 100644 --- a/Tests/OptimizelyTests-Common/BatchEventBuilderTests_Events.swift +++ b/Tests/OptimizelyTests-Common/BatchEventBuilderTests_Events.swift @@ -20,14 +20,15 @@ class BatchEventBuilderTests_Events: XCTestCase { let experimentKey = "ab_running_exp_audience_combo_exact_foo_or_true__and__42_or_4_2" let userId = "test_user_1" + let featureKey = "feature_1" var optimizely: OptimizelyClient! var eventDispatcher: FakeEventDispatcher! var project: Project! + let datafile = OTUtils.loadJSONDatafile("api_datafile")! override func setUp() { eventDispatcher = FakeEventDispatcher() - optimizely = OTUtils.createOptimizely(datafileName: "audience_targeting", clearUserProfileService: true, eventDispatcher: eventDispatcher)! @@ -50,7 +51,7 @@ class BatchEventBuilderTests_Events: XCTestCase { userId: userId, attributes: attributes) - let event = getFirstEventJSON()! + let event = getFirstEventJSON(dispatcher: eventDispatcher)! XCTAssertEqual((event["revision"] as! String), project.revision) XCTAssertEqual((event["account_id"] as! String), project.accountId) @@ -77,7 +78,7 @@ class BatchEventBuilderTests_Events: XCTestCase { XCTAssertEqual(decision["experiment_id"] as! String, expExperimentId) let metaData = decision["metadata"] as! Dictionary - XCTAssertEqual(metaData["rule_type"] as! String, "experiment") + XCTAssertEqual(metaData["rule_type"] as! String, Constants.DecisionSource.experiment.rawValue) XCTAssertEqual(metaData["rule_key"] as! String, "ab_running_exp_audience_combo_exact_foo_or_true__and__42_or_4_2") XCTAssertEqual(metaData["flag_key"] as! String, "") XCTAssertEqual(metaData["variation_key"] as! String, "all_traffic_variation") @@ -188,7 +189,7 @@ class BatchEventBuilderTests_Events: XCTestCase { attributes: attributes, eventTags: eventTags) - let event = getFirstEventJSON()! + let event = getFirstEventJSON(dispatcher: eventDispatcher)! XCTAssertEqual(event["revision"] as! String, project.revision) XCTAssertEqual(event["account_id"] as! String, project.accountId) @@ -249,17 +250,119 @@ class BatchEventBuilderTests_Events: XCTestCase { } +// MARK: - API Tests + +extension BatchEventBuilderTests_Events { + + func testImpressionEventWithUserNotInExperimentAndRollout() { + let eventDispatcher2 = FakeEventDispatcher() + let fakeOptimizelyManager = FakeManager(sdkKey: "12345", + eventDispatcher: eventDispatcher2) + try! fakeOptimizelyManager.start(datafile: datafile) + + let exp = expectation(description: "Wait for event to dispatch") + fakeOptimizelyManager.config!.project!.sendFlagDecisions = true + fakeOptimizelyManager.setDecisionServiceData(experiment: nil, variation: nil, source: "") + _ = fakeOptimizelyManager.isFeatureEnabled(featureKey: featureKey, userId: userId) + + let result = XCTWaiter.wait(for: [exp], timeout: 0.1) + if result == XCTWaiter.Result.timedOut { + let event = getFirstEventJSON(dispatcher: eventDispatcher2)! + let visitor = (event["visitors"] as! Array>)[0] + let snapshot = (visitor["snapshots"] as! Array>)[0] + let decision = (snapshot["decisions"] as! Array>)[0] + + let metaData = decision["metadata"] as! Dictionary + XCTAssertEqual(metaData["rule_type"] as! String, Constants.DecisionSource.rollout.rawValue) + XCTAssertEqual(metaData["rule_key"] as! String, "") + XCTAssertEqual(metaData["flag_key"] as! String, "feature_1") + XCTAssertEqual(metaData["variation_key"] as! String, "") + } else { + XCTFail("No event found") + } + fakeOptimizelyManager.config!.project!.sendFlagDecisions = nil + } + + func testImpressionEventWithWithUserInRollout() { + let eventDispatcher2 = FakeEventDispatcher() + let fakeOptimizelyManager = FakeManager(sdkKey: "12345", + eventDispatcher: eventDispatcher2) + try! fakeOptimizelyManager.start(datafile: datafile) + + let exp = expectation(description: "Wait for event to dispatch") + fakeOptimizelyManager.config!.project!.sendFlagDecisions = true + + let experiment: Experiment = fakeOptimizelyManager.config!.allExperiments.first! + var variation: Variation = (experiment.variations.first)! + variation.featureEnabled = true + fakeOptimizelyManager.setDecisionServiceData(experiment: experiment, variation: variation, source: Constants.DecisionSource.rollout.rawValue) + _ = fakeOptimizelyManager.isFeatureEnabled(featureKey: featureKey, userId: userId) + + let result = XCTWaiter.wait(for: [exp], timeout: 0.1) + if result == XCTWaiter.Result.timedOut { + let event = getFirstEventJSON(dispatcher: eventDispatcher2)! + let visitor = (event["visitors"] as! Array>)[0] + let snapshot = (visitor["snapshots"] as! Array>)[0] + let decision = (snapshot["decisions"] as! Array>)[0] + + let metaData = decision["metadata"] as! Dictionary + XCTAssertEqual(metaData["rule_type"] as! String, Constants.DecisionSource.rollout.rawValue) + XCTAssertEqual(metaData["rule_key"] as! String, "exp_with_audience") + XCTAssertEqual(metaData["flag_key"] as! String, "feature_1") + XCTAssertEqual(metaData["variation_key"] as! String, "a") + } else { + XCTFail("No event found") + } + variation.featureEnabled = false + fakeOptimizelyManager.config!.project!.sendFlagDecisions = nil + } + + func testImpressionEventWithUserInExperiment() { + let eventDispatcher2 = FakeEventDispatcher() + let fakeOptimizelyManager = FakeManager(sdkKey: "12345", + eventDispatcher: eventDispatcher2) + try! fakeOptimizelyManager.start(datafile: datafile) + + let exp = expectation(description: "Wait for event to dispatch") + fakeOptimizelyManager.config!.project!.sendFlagDecisions = true + + let experiment: Experiment = (fakeOptimizelyManager.config?.allExperiments.first!)! + var variation: Variation = (experiment.variations.first)! + variation.featureEnabled = true + fakeOptimizelyManager.setDecisionServiceData(experiment: experiment, variation: variation, source: Constants.DecisionSource.featureTest.rawValue) + _ = fakeOptimizelyManager.isFeatureEnabled(featureKey: featureKey, userId: userId) + + let result = XCTWaiter.wait(for: [exp], timeout: 0.1) + if result == XCTWaiter.Result.timedOut { + let event = getFirstEventJSON(dispatcher: eventDispatcher2)! + let visitor = (event["visitors"] as! Array>)[0] + let snapshot = (visitor["snapshots"] as! Array>)[0] + let decision = (snapshot["decisions"] as! Array>)[0] + + let metaData = decision["metadata"] as! Dictionary + XCTAssertEqual(metaData["rule_type"] as! String, Constants.DecisionSource.featureTest.rawValue) + XCTAssertEqual(metaData["rule_key"] as! String, "exp_with_audience") + XCTAssertEqual(metaData["flag_key"] as! String, "feature_1") + XCTAssertEqual(metaData["variation_key"] as! String, "a") + } else { + XCTFail("No event found") + } + variation.featureEnabled = false + fakeOptimizelyManager.config!.project!.sendFlagDecisions = nil + } +} + // MARK: - Utils extension BatchEventBuilderTests_Events { - func getFirstEvent() -> EventForDispatch? { + func getFirstEvent(dispatcher: FakeEventDispatcher) -> EventForDispatch? { optimizely.eventLock.sync{} - return eventDispatcher.events.first + return dispatcher.events.first } - func getFirstEventJSON() -> [String: Any]? { - guard let event = getFirstEvent() else { return nil } + func getFirstEventJSON(dispatcher: FakeEventDispatcher) -> [String: Any]? { + guard let event = getFirstEvent(dispatcher: dispatcher) else { return nil } let json = try! JSONSerialization.jsonObject(with: event.body, options: .allowFragments) as! [String: Any] return json diff --git a/Tests/OptimizelyTests-Common/DecisionListenerTests.swift b/Tests/OptimizelyTests-Common/DecisionListenerTests.swift index fe0b494dd..31826d7b8 100644 --- a/Tests/OptimizelyTests-Common/DecisionListenerTests.swift +++ b/Tests/OptimizelyTests-Common/DecisionListenerTests.swift @@ -765,9 +765,6 @@ class DecisionListenerTests: XCTestCase { func testDecisionListenerWithUserNotInExperimentAndRollout() { let exp = expectation(description: "x") - eventDispatcher.events.removeAll() - self.optimizely.config!.project!.sendFlagDecisions = true - self.optimizely.setDecisionServiceData(experiment: nil, variation: nil, source: "") notificationCenter.clearAllNotificationListeners() _ = notificationCenter.addDecisionNotificationListener { (_, _, _, decisionInfo) in @@ -780,26 +777,11 @@ class DecisionListenerTests: XCTestCase { _ = self.optimizely.isFeatureEnabled(featureKey: kFeatureKey, userId: kUserId) wait(for: [exp], timeout: 1) - - let event = getFirstEventJSON()! - let visitor = (event["visitors"] as! Array>)[0] - let snapshot = (visitor["snapshots"] as! Array>)[0] - let decision = (snapshot["decisions"] as! Array>)[0] - - let metaData = decision["metadata"] as! Dictionary - XCTAssertEqual(metaData["rule_type"] as! String, Constants.DecisionSource.rollout.rawValue) - XCTAssertEqual(metaData["rule_key"] as! String, "") - XCTAssertEqual(metaData["flag_key"] as! String, "feature_1") - XCTAssertEqual(metaData["variation_key"] as! String, "") - - self.optimizely.config!.project!.sendFlagDecisions = nil } func testDecisionListenerWithUserInRollout() { var exp = expectation(description: "x") - eventDispatcher.events.removeAll() - self.optimizely.config!.project!.sendFlagDecisions = true - + let experiment: Experiment = self.optimizely.config!.allExperiments.first! var variation: Variation = (experiment.variations.first)! variation.featureEnabled = true @@ -814,17 +796,6 @@ class DecisionListenerTests: XCTestCase { } _ = self.optimizely.isFeatureEnabled(featureKey: kFeatureKey, userId: kUserId) wait(for: [exp], timeout: 1) - - let event = getFirstEventJSON()! - let visitor = (event["visitors"] as! Array>)[0] - let snapshot = (visitor["snapshots"] as! Array>)[0] - let decision = (snapshot["decisions"] as! Array>)[0] - - let metaData = decision["metadata"] as! Dictionary - XCTAssertEqual(metaData["rule_type"] as! String, Constants.DecisionSource.rollout.rawValue) - XCTAssertEqual(metaData["rule_key"] as! String, "exp_with_audience") - XCTAssertEqual(metaData["flag_key"] as! String, "feature_1") - XCTAssertEqual(metaData["variation_key"] as! String, "a") exp = expectation(description: "x") @@ -840,12 +811,10 @@ class DecisionListenerTests: XCTestCase { } _ = self.optimizely.isFeatureEnabled(featureKey: kFeatureKey, userId: kUserId) wait(for: [exp], timeout: 1) - self.optimizely.config!.project!.sendFlagDecisions = nil } func testDecisionListenerWithUserInExperiment() { var exp = expectation(description: "x") - eventDispatcher.events.removeAll() let experiment: Experiment = (self.optimizely.config?.allExperiments.first!)! var variation: Variation = (experiment.variations.first)! @@ -864,17 +833,6 @@ class DecisionListenerTests: XCTestCase { _ = self.optimizely.isFeatureEnabled(featureKey: kFeatureKey, userId: kUserId) wait(for: [exp], timeout: 1) - let event = getFirstEventJSON()! - let visitor = (event["visitors"] as! Array>)[0] - let snapshot = (visitor["snapshots"] as! Array>)[0] - let decision = (snapshot["decisions"] as! Array>)[0] - - let metaData = decision["metadata"] as! Dictionary - XCTAssertEqual(metaData["rule_type"] as! String, Constants.DecisionSource.featureTest.rawValue) - XCTAssertEqual(metaData["rule_key"] as! String, "exp_with_audience") - XCTAssertEqual(metaData["flag_key"] as! String, "feature_1") - XCTAssertEqual(metaData["variation_key"] as! String, "a") - exp = expectation(description: "x") variation.featureEnabled = false @@ -950,21 +908,3 @@ fileprivate extension HandlerRegistryService { self.binders.property?.removeAll() } } - -// MARK: - Utils - -extension DecisionListenerTests { - - func getFirstEvent() -> EventForDispatch? { - optimizely.eventLock.sync{} - return eventDispatcher.events.first - } - - func getFirstEventJSON() -> [String: Any]? { - guard let event = getFirstEvent() else { return nil } - - let json = try! JSONSerialization.jsonObject(with: event.body, options: .allowFragments) as! [String: Any] - return json - } - -}