From b70a7b9cd1f2cc434ca960da5503d110168be5e3 Mon Sep 17 00:00:00 2001 From: esrakartalOpt Date: Wed, 20 Aug 2025 12:58:13 -0500 Subject: [PATCH 01/14] [FSSDK-11454] Swift - Add SDK Multi-Region Support for Data Hosting --- .../DispatchEvents/BatchEvent.swift | 2 + .../DispatchEvents/EventForDispatch.swift | 15 +- Sources/Data Model/Project.swift | 16 +- Sources/Data Model/ProjectConfig.swift | 7 + .../ArrayEventForDispatch+Extension.swift | 19 +- .../Events/BatchEventBuilder.swift | 18 +- .../BatchEventBuilderTests_Region.swift | 348 ++++++++++++++++++ 7 files changed, 412 insertions(+), 13 deletions(-) create mode 100644 Tests/OptimizelyTests-Common/BatchEventBuilderTests_Region.swift diff --git a/Sources/Data Model/DispatchEvents/BatchEvent.swift b/Sources/Data Model/DispatchEvents/BatchEvent.swift index 345c7b85b..5c7a26f9a 100644 --- a/Sources/Data Model/DispatchEvents/BatchEvent.swift +++ b/Sources/Data Model/DispatchEvents/BatchEvent.swift @@ -25,6 +25,7 @@ struct BatchEvent: Codable, Equatable { let clientName: String let anonymizeIP: Bool let enrichDecisions: Bool + let region: String enum CodingKeys: String, CodingKey { case revision @@ -35,6 +36,7 @@ struct BatchEvent: Codable, Equatable { case clientName = "client_name" case anonymizeIP = "anonymize_ip" case enrichDecisions = "enrich_decisions" + case region } func getEventAttribute(key: String) -> EventAttribute? { diff --git a/Sources/Data Model/DispatchEvents/EventForDispatch.swift b/Sources/Data Model/DispatchEvents/EventForDispatch.swift index 88cf5d83c..1677a04ca 100644 --- a/Sources/Data Model/DispatchEvents/EventForDispatch.swift +++ b/Sources/Data Model/DispatchEvents/EventForDispatch.swift @@ -18,12 +18,23 @@ import Foundation @objcMembers public class EventForDispatch: NSObject, Codable { public static var eventEndpoint = "https://logx.optimizely.com/v1/events" + public static var euEventEndpoint = "https://eu.logx.optimizely.com/v1/events" + + public static func getEndpoint(for region: Region) -> String { + switch region { + case .EU: + return euEventEndpoint + case .US: + return eventEndpoint + } + } public let url: URL public let body: Data - public init(url: URL? = nil, body: Data) { - self.url = url ?? URL(string: EventForDispatch.eventEndpoint)! + public init(url: URL? = nil, body: Data, region: Region = .US) { + let endpoint = url?.absoluteString ?? EventForDispatch.getEndpoint(for: region) + self.url = URL(string: endpoint)! self.body = body } diff --git a/Sources/Data Model/Project.swift b/Sources/Data Model/Project.swift index 3a518c25d..95d58248d 100644 --- a/Sources/Data Model/Project.swift +++ b/Sources/Data Model/Project.swift @@ -16,6 +16,12 @@ import Foundation +/// Optimizely region identifiers +public enum Region: String, Codable, Equatable { + case US + case EU +} + protocol ProjectProtocol { func evaluateAudience(audienceId: String, user: OptimizelyUserContext) throws -> Bool } @@ -48,6 +54,8 @@ struct Project: Codable, Equatable { var environmentKey: String? // Holdouts var holdouts: [Holdout] + // Region + var region: Region? let logger = OPTLoggerFactory.getLogger() // Required since logger is not decodable @@ -57,7 +65,7 @@ struct Project: Codable, Equatable { // V3 case anonymizeIP // V4 - case rollouts, integrations, typedAudiences, featureFlags, botFiltering, sendFlagDecisions, sdkKey, environmentKey, holdouts + case rollouts, integrations, typedAudiences, featureFlags, botFiltering, sendFlagDecisions, sdkKey, environmentKey, holdouts, region } init(from decoder: Decoder) throws { @@ -88,6 +96,8 @@ struct Project: Codable, Equatable { environmentKey = try container.decodeIfPresent(String.self, forKey: .environmentKey) // Holdouts - defaults to empty array if key is not present holdouts = try container.decodeIfPresent([Holdout].self, forKey: .holdouts) ?? [] + // Region - defaults to US if not present + region = try container.decodeIfPresent(Region.self, forKey: .region) } // Required since logger is not equatable @@ -97,7 +107,9 @@ struct Project: Codable, Equatable { lhs.accountId == rhs.accountId && lhs.events == rhs.events && lhs.revision == rhs.revision && lhs.anonymizeIP == rhs.anonymizeIP && lhs.rollouts == rhs.rollouts && lhs.integrations == rhs.integrations && lhs.typedAudiences == rhs.typedAudiences && - lhs.featureFlags == rhs.featureFlags && lhs.botFiltering == rhs.botFiltering && lhs.sendFlagDecisions == rhs.sendFlagDecisions && lhs.sdkKey == rhs.sdkKey && lhs.environmentKey == rhs.environmentKey + lhs.featureFlags == rhs.featureFlags && lhs.botFiltering == rhs.botFiltering && + lhs.sendFlagDecisions == rhs.sendFlagDecisions && lhs.sdkKey == rhs.sdkKey && + lhs.environmentKey == rhs.environmentKey && lhs.region == rhs.region } } diff --git a/Sources/Data Model/ProjectConfig.swift b/Sources/Data Model/ProjectConfig.swift index a2cd3bf28..be2c71d67 100644 --- a/Sources/Data Model/ProjectConfig.swift +++ b/Sources/Data Model/ProjectConfig.swift @@ -215,6 +215,13 @@ extension ProjectConfig { extension ProjectConfig { + /** + * Get the region value. Defaults to US if not specified in the project. + */ + public var region: Region { + return project.region ?? .US + } + /** * Get sendFlagDecisions value. */ diff --git a/Sources/Extensions/ArrayEventForDispatch+Extension.swift b/Sources/Extensions/ArrayEventForDispatch+Extension.swift index 5d8e5d28f..01da321a9 100644 --- a/Sources/Extensions/ArrayEventForDispatch+Extension.swift +++ b/Sources/Extensions/ArrayEventForDispatch+Extension.swift @@ -45,6 +45,7 @@ extension Array where Element == EventForDispatch { var url: URL? var projectId: String? var revision: String? + var region: String? let checkUrl = { (event: EventForDispatch) -> Bool in if url == nil { @@ -69,10 +70,18 @@ extension Array where Element == EventForDispatch { } return revision == batchEvent.revision } + + let checkRegion = { (batchEvent: BatchEvent) -> Bool in + if region == nil { + region = batchEvent.region + return region != nil + } + return region == batchEvent.region + } for event in self { if let batchEvent = try? JSONDecoder().decode(BatchEvent.self, from: event.body) { - if !checkUrl(event) || !checkProjectId(batchEvent) || !checkRevision(batchEvent) { + if !checkUrl(event) || !checkProjectId(batchEvent) || !checkRevision(batchEvent) || !checkRegion(batchEvent) { break } @@ -101,12 +110,14 @@ extension Array where Element == EventForDispatch { projectID: base.projectID, clientName: base.clientName, anonymizeIP: base.anonymizeIP, - enrichDecisions: true) + enrichDecisions: true, + region: base.region) guard let data = try? JSONEncoder().encode(batchEvent) else { return nil } - - return EventForDispatch(url: url, body: data) + + let regionValue = base.region == Region.EU.rawValue ? Region.EU : Region.US + return EventForDispatch(url: url, body: data, region: regionValue) } } diff --git a/Sources/Implementation/Events/BatchEventBuilder.swift b/Sources/Implementation/Events/BatchEventBuilder.swift index 4027b0321..cd044af8a 100644 --- a/Sources/Implementation/Events/BatchEventBuilder.swift +++ b/Sources/Implementation/Events/BatchEventBuilder.swift @@ -47,7 +47,8 @@ class BatchEventBuilder { userId: userId, attributes: attributes, decisions: [decision], - dispatchEvents: [dispatchEvent]) + dispatchEvents: [dispatchEvent], + region: config.region) } // MARK: - Converison Event @@ -77,7 +78,8 @@ class BatchEventBuilder { userId: userId, attributes: attributes, decisions: nil, - dispatchEvents: [dispatchEvent]) + dispatchEvents: [dispatchEvent], + region: config.region) } // MARK: - Create Event @@ -86,7 +88,9 @@ class BatchEventBuilder { userId: String, attributes: OptimizelyAttributes?, decisions: [Decision]?, - dispatchEvents: [DispatchEvent]) -> Data? { + dispatchEvents: [DispatchEvent], + region: Region? = nil) -> Data? { + let eventRegion = region ?? config.region let snapShot = Snapshot(decisions: decisions, events: dispatchEvents) let eventAttributes = getEventAttributes(config: config, attributes: attributes) @@ -100,9 +104,13 @@ class BatchEventBuilder { projectID: config.project.projectId, clientName: Utils.swiftSdkClientName, anonymizeIP: config.project.anonymizeIP, - enrichDecisions: true) + enrichDecisions: true, + region: eventRegion.rawValue) + + let data = try? JSONEncoder().encode(batchEvent) + let eventForDispatch = EventForDispatch(url: nil, body: data ?? Data(), region: eventRegion) - return try? JSONEncoder().encode(batchEvent) + return eventForDispatch.body } // MARK: - Event Tags diff --git a/Tests/OptimizelyTests-Common/BatchEventBuilderTests_Region.swift b/Tests/OptimizelyTests-Common/BatchEventBuilderTests_Region.swift new file mode 100644 index 000000000..b57ff9ad3 --- /dev/null +++ b/Tests/OptimizelyTests-Common/BatchEventBuilderTests_Region.swift @@ -0,0 +1,348 @@ +// +// Copyright 2023-2025, Optimizely, Inc. and contributors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import XCTest + +class BatchEventBuilderTests_Region: 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: MockEventDispatcher! + var project: Project! + let datafile = OTUtils.loadJSONDatafile("api_datafile")! + + override func setUp() { + eventDispatcher = MockEventDispatcher() + optimizely = OTUtils.createOptimizely(datafileName: "audience_targeting", + clearUserProfileService: true, + eventDispatcher: eventDispatcher)! + project = optimizely.config!.project! + } + + override func tearDown() { + Utils.sdkVersion = OPTIMIZELYSDKVERSION + Utils.swiftSdkClientName = "swift-sdk" + optimizely?.close() + optimizely = nil + optimizely?.eventDispatcher = nil + super.tearDown() + } + + // MARK: - Test Impression Event with Region + + func testCreateImpressionEventWithUSRegion() { + // Set the region to US + optimizely.config?.project.region = .US + + let attributes: [String: Any] = [ + "s_foo": "foo", + "b_true": true, + "i_42": 42, + "d_4_2": 4.2 + ] + + _ = try! optimizely.activate(experimentKey: experimentKey, + userId: userId, + attributes: attributes) + + let event = getFirstEventJSON(dispatcher: eventDispatcher)! + + // Check if the region is correctly set to US in the event + XCTAssertEqual(event["region"] as! String, "US") + + // Check if the event was sent to the correct endpoint + let eventForDispatch = getFirstEvent(dispatcher: eventDispatcher)! + XCTAssertEqual(eventForDispatch.url.absoluteString, EventForDispatch.getEndpoint(for: .US)) + } + + func testCreateImpressionEventWithEURegion() { + // Set the region to EU + optimizely.config?.project.region = .EU + + let attributes: [String: Any] = [ + "s_foo": "foo", + "b_true": true, + "i_42": 42, + "d_4_2": 4.2 + ] + + _ = try! optimizely.activate(experimentKey: experimentKey, + userId: userId, + attributes: attributes) + + let event = getFirstEventJSON(dispatcher: eventDispatcher)! + + // Check if the region is correctly set to EU in the event + XCTAssertEqual(event["region"] as! String, "EU") + + // Check if the event was sent to the correct endpoint + let eventForDispatch = getFirstEvent(dispatcher: eventDispatcher)! + XCTAssertEqual(eventForDispatch.url.absoluteString, EventForDispatch.getEndpoint(for: .EU)) + } + + // MARK: - Test Conversion Event with Region + + func testCreateConversionEventWithUSRegion() { + // Set the region to US + optimizely.config?.project.region = .US + + let eventKey = "event_single_targeted_exp" + let attributes: [String: Any] = ["s_foo": "bar"] + let eventTags: [String: Any] = ["browser": "chrome"] + + try! optimizely.track(eventKey: eventKey, + userId: userId, + attributes: attributes, + eventTags: eventTags) + + let event = getFirstEventJSON(dispatcher: eventDispatcher)! + + // Check if the region is correctly set to US in the event + XCTAssertEqual(event["region"] as! String, "US") + + // Check if the event was sent to the correct endpoint + let eventForDispatch = getFirstEvent(dispatcher: eventDispatcher)! + XCTAssertEqual(eventForDispatch.url.absoluteString, EventForDispatch.getEndpoint(for: .US)) + } + + func testCreateConversionEventWithEURegion() { + // Set the region to EU + optimizely.config?.project.region = .EU + + let eventKey = "event_single_targeted_exp" + let attributes: [String: Any] = ["s_foo": "bar"] + let eventTags: [String: Any] = ["browser": "chrome"] + + try! optimizely.track(eventKey: eventKey, + userId: userId, + attributes: attributes, + eventTags: eventTags) + + let event = getFirstEventJSON(dispatcher: eventDispatcher)! + + // Check if the region is correctly set to EU in the event + XCTAssertEqual(event["region"] as! String, "EU") + + // Check if the event was sent to the correct endpoint + let eventForDispatch = getFirstEvent(dispatcher: eventDispatcher)! + XCTAssertEqual(eventForDispatch.url.absoluteString, EventForDispatch.getEndpoint(for: .EU)) + } + + // MARK: - Test Direct Event Creation with Region + + func testDirectImpressionEventCreationWithUSRegion() { + // Set the region to US + optimizely.config?.project.region = .US + + let experiment = optimizely.config?.getExperiment(id: "10390977714") + let variation = experiment?.variations.first + + let event = BatchEventBuilder.createImpressionEvent(config: optimizely.config!, + experiment: experiment, + variation: variation, + userId: userId, + attributes: nil, + flagKey: experiment!.key, + ruleType: Constants.DecisionSource.experiment.rawValue, + enabled: true, + cmabUUID: nil) + + XCTAssertNotNil(event) + + let eventJson = getEventJSON(data: event!)! + + // Check if the region is correctly set to US in the event + XCTAssertEqual(eventJson["region"] as! String, "US") + } + + func testDirectImpressionEventCreationWithEURegion() { + // Set the region to EU + optimizely.config?.project.region = .EU + + let experiment = optimizely.config?.getExperiment(id: "10390977714") + let variation = experiment?.variations.first + + let event = BatchEventBuilder.createImpressionEvent(config: optimizely.config!, + experiment: experiment, + variation: variation, + userId: userId, + attributes: nil, + flagKey: experiment!.key, + ruleType: Constants.DecisionSource.experiment.rawValue, + enabled: true, + cmabUUID: nil) + + XCTAssertNotNil(event) + + let eventJson = getEventJSON(data: event!)! + + // Check if the region is correctly set to EU in the event + XCTAssertEqual(eventJson["region"] as! String, "EU") + } + + func testDirectConversionEventCreationWithUSRegion() { + // Set the region to US + optimizely.config?.project.region = .US + + let eventKey = "event_single_targeted_exp" + let eventTags: [String: Any] = ["browser": "chrome"] + + let event = BatchEventBuilder.createConversionEvent(config: optimizely.config!, + eventKey: eventKey, + userId: userId, + attributes: nil, + eventTags: eventTags) + + XCTAssertNotNil(event) + + let eventJson = getEventJSON(data: event!)! + + // Check if the region is correctly set to US in the event + XCTAssertEqual(eventJson["region"] as! String, "US") + } + + func testDirectConversionEventCreationWithEURegion() { + // Set the region to EU + optimizely.config?.project.region = .EU + + let eventKey = "event_single_targeted_exp" + let eventTags: [String: Any] = ["browser": "chrome"] + + let event = BatchEventBuilder.createConversionEvent(config: optimizely.config!, + eventKey: eventKey, + userId: userId, + attributes: nil, + eventTags: eventTags) + + XCTAssertNotNil(event) + + let eventJson = getEventJSON(data: event!)! + + // Check if the region is correctly set to EU in the event + XCTAssertEqual(eventJson["region"] as! String, "EU") + } + + // MARK: - Test Event Batching with Region + + func testEventBatchingWithSameRegion() { + // Set the region to US + optimizely.config?.project.region = .US + + // Create two events with the same region + let experiment = optimizely.config?.getExperiment(id: "10390977714") + let variation = experiment?.variations.first + + // Create first event + let event1 = BatchEventBuilder.createImpressionEvent(config: optimizely.config!, + experiment: experiment, + variation: variation, + userId: userId, + attributes: nil, + flagKey: experiment!.key, + ruleType: Constants.DecisionSource.experiment.rawValue, + enabled: true, + cmabUUID: nil) + + // Create second event + let event2 = BatchEventBuilder.createImpressionEvent(config: optimizely.config!, + experiment: experiment, + variation: variation, + userId: userId + "2", + attributes: nil, + flagKey: experiment!.key, + ruleType: Constants.DecisionSource.experiment.rawValue, + enabled: true, + cmabUUID: nil) + + // Create EventForDispatch objects + let eventForDispatch1 = EventForDispatch(url: nil, body: event1!, region: .US) + let eventForDispatch2 = EventForDispatch(url: nil, body: event2!, region: .US) + + // Test batching + let batchResult = [eventForDispatch1, eventForDispatch2].batch() + + // Events should be batched together since they have the same region + XCTAssertEqual(batchResult.numEvents, 2) + XCTAssertNotNil(batchResult.eventForDispatch) + } + + func testEventBatchingWithDifferentRegions() { + // Create two events with different regions + let experiment = optimizely.config?.getExperiment(id: "10390977714") + let variation = experiment?.variations.first + + // Set region to US for first event + optimizely.config?.project.region = .US + + // Create first event (US) + let event1 = BatchEventBuilder.createImpressionEvent(config: optimizely.config!, + experiment: experiment, + variation: variation, + userId: userId, + attributes: nil, + flagKey: experiment!.key, + ruleType: Constants.DecisionSource.experiment.rawValue, + enabled: true, + cmabUUID: nil) + + // Set region to EU for second event + optimizely.config?.project.region = .EU + + // Create second event (EU) + let event2 = BatchEventBuilder.createImpressionEvent(config: optimizely.config!, + experiment: experiment, + variation: variation, + userId: userId + "2", + attributes: nil, + flagKey: experiment!.key, + ruleType: Constants.DecisionSource.experiment.rawValue, + enabled: true, + cmabUUID: nil) + + // Create EventForDispatch objects + let eventForDispatch1 = EventForDispatch(url: nil, body: event1!, region: .US) + let eventForDispatch2 = EventForDispatch(url: nil, body: event2!, region: .EU) + + // Test batching + let batchResult = [eventForDispatch1, eventForDispatch2].batch() + + // Only the first event should be batched as they have different regions + XCTAssertEqual(batchResult.numEvents, 1) + XCTAssertNotNil(batchResult.eventForDispatch) + } + + // MARK: - Utils + + func getFirstEvent(dispatcher: MockEventDispatcher) -> EventForDispatch? { + optimizely.eventLock.sync{} + return dispatcher.events.first + } + + func getFirstEventJSON(dispatcher: MockEventDispatcher) -> [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 + } + + func getEventJSON(data: Data) -> [String: Any]? { + let json = try! JSONSerialization.jsonObject(with: data, options: .allowFragments) as! [String: Any] + return json + } +} From 77f45750fecb4ff219831a418772f5c487a4efb9 Mon Sep 17 00:00:00 2001 From: esrakartalOpt Date: Wed, 20 Aug 2025 13:28:30 -0500 Subject: [PATCH 02/14] Fix test errors --- .../Optimizely+Decide/OptimizelyUserContext+ObjC.swift | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Sources/Optimizely+Decide/OptimizelyUserContext+ObjC.swift b/Sources/Optimizely+Decide/OptimizelyUserContext+ObjC.swift index fa2a79b58..321f090f0 100644 --- a/Sources/Optimizely+Decide/OptimizelyUserContext+ObjC.swift +++ b/Sources/Optimizely+Decide/OptimizelyUserContext+ObjC.swift @@ -32,7 +32,7 @@ import Foundation return userContext.optimizely } - public init(optimizely: OptimizelyClient, userId: String, attributes: [String: Any]? = nil) { + public init(optimizely: OptimizelyClient, userId: String, attributes: [String: Any]? = nil, region: String = "US") { userContext = OptimizelyUserContext(optimizely: optimizely, userId: userId, attributes: attributes) } @@ -97,6 +97,13 @@ extension OptimizelyClient { return ObjcOptimizelyUserContext(user: user) } + @available(swift, obsoleted: 1.0) + @objc(createUserContextWithUserId:attributes:region:) + public func objcCreateUserContext(userId: String, attributes: [String: Any]? = nil, region: String) -> ObjcOptimizelyUserContext { + let user = createUserContext(userId: userId, attributes: attributes) + return ObjcOptimizelyUserContext(user: user) + } + @available(swift, obsoleted: 1.0) @objc public convenience init(sdkKey: String, logger: OPTLogger?, From 835afee73c7d4b078a7b3eba190f760b65f8b2a6 Mon Sep 17 00:00:00 2001 From: esrakartalOpt Date: Wed, 20 Aug 2025 13:34:57 -0500 Subject: [PATCH 03/14] Fix errors --- Sources/Optimizely+Decide/OptimizelyUserContext+ObjC.swift | 2 +- Sources/Optimizely+Decide/OptimizelyUserContext.swift | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Sources/Optimizely+Decide/OptimizelyUserContext+ObjC.swift b/Sources/Optimizely+Decide/OptimizelyUserContext+ObjC.swift index 321f090f0..24c39f659 100644 --- a/Sources/Optimizely+Decide/OptimizelyUserContext+ObjC.swift +++ b/Sources/Optimizely+Decide/OptimizelyUserContext+ObjC.swift @@ -100,7 +100,7 @@ extension OptimizelyClient { @available(swift, obsoleted: 1.0) @objc(createUserContextWithUserId:attributes:region:) public func objcCreateUserContext(userId: String, attributes: [String: Any]? = nil, region: String) -> ObjcOptimizelyUserContext { - let user = createUserContext(userId: userId, attributes: attributes) + let user = OptimizelyUserContext(optimizely: self, userId: userId, attributes: attributes, region: region) return ObjcOptimizelyUserContext(user: user) } diff --git a/Sources/Optimizely+Decide/OptimizelyUserContext.swift b/Sources/Optimizely+Decide/OptimizelyUserContext.swift index 70959baf7..d04414af1 100644 --- a/Sources/Optimizely+Decide/OptimizelyUserContext.swift +++ b/Sources/Optimizely+Decide/OptimizelyUserContext.swift @@ -70,9 +70,11 @@ public class OptimizelyUserContext { /// - optimizely: An instance of OptimizelyClient to be used for decisions. /// - userId: The user ID to be used for bucketing. /// - attributes: A map of attribute names to current user attribute values. + /// - region: The region for the user context (optional). Defaults to the region from the project config. public convenience init(optimizely: OptimizelyClient, userId: String, - attributes: [String: Any?]? = nil) { + attributes: [String: Any?]? = nil, + region: String? = nil) { self.init(optimizely: optimizely, userId: userId, attributes: attributes ?? [:], identify: true) } From 4b359d51c68ea028de6c4e7f85c83e32c0eeb0e7 Mon Sep 17 00:00:00 2001 From: esrakartalOpt Date: Thu, 21 Aug 2025 12:11:43 -0500 Subject: [PATCH 04/14] Fix missing arg error --- .../Optimizely+Decide/OptimizelyUserContext+ObjC.swift | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Sources/Optimizely+Decide/OptimizelyUserContext+ObjC.swift b/Sources/Optimizely+Decide/OptimizelyUserContext+ObjC.swift index 24c39f659..ee5782ad0 100644 --- a/Sources/Optimizely+Decide/OptimizelyUserContext+ObjC.swift +++ b/Sources/Optimizely+Decide/OptimizelyUserContext+ObjC.swift @@ -36,7 +36,7 @@ import Foundation userContext = OptimizelyUserContext(optimizely: optimizely, userId: userId, attributes: attributes) } - public init(user: OptimizelyUserContext) { + public init(user: OptimizelyUserContext, region: String = "US") { self.userContext = user } @@ -83,7 +83,7 @@ import Foundation ruleKey = decision.ruleKey flagKey = decision.flagKey - userContext = ObjcOptimizelyUserContext(user: decision.userContext) + userContext = ObjcOptimizelyUserContext(user: decision.userContext, region: "US") reasons = decision.reasons } } @@ -94,14 +94,14 @@ extension OptimizelyClient { @objc(createUserContextWithUserId:attributes:) public func objcCreateUserContext(userId: String, attributes: [String: Any]? = nil) -> ObjcOptimizelyUserContext { let user = createUserContext(userId: userId, attributes: attributes) - return ObjcOptimizelyUserContext(user: user) + return ObjcOptimizelyUserContext(user: user, region: "US") } @available(swift, obsoleted: 1.0) @objc(createUserContextWithUserId:attributes:region:) public func objcCreateUserContext(userId: String, attributes: [String: Any]? = nil, region: String) -> ObjcOptimizelyUserContext { let user = OptimizelyUserContext(optimizely: self, userId: userId, attributes: attributes, region: region) - return ObjcOptimizelyUserContext(user: user) + return ObjcOptimizelyUserContext(user: user, region: region) } @available(swift, obsoleted: 1.0) From 4562f38bf51f8e6501ad104429a4032e80f383b8 Mon Sep 17 00:00:00 2001 From: esrakartalOpt Date: Thu, 21 Aug 2025 12:33:54 -0500 Subject: [PATCH 05/14] Implement copilot reviews --- Sources/Implementation/Events/BatchEventBuilder.swift | 2 +- Sources/Optimizely+Decide/OptimizelyUserContext+ObjC.swift | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Sources/Implementation/Events/BatchEventBuilder.swift b/Sources/Implementation/Events/BatchEventBuilder.swift index cd044af8a..6e11e856f 100644 --- a/Sources/Implementation/Events/BatchEventBuilder.swift +++ b/Sources/Implementation/Events/BatchEventBuilder.swift @@ -110,7 +110,7 @@ class BatchEventBuilder { let data = try? JSONEncoder().encode(batchEvent) let eventForDispatch = EventForDispatch(url: nil, body: data ?? Data(), region: eventRegion) - return eventForDispatch.body + return eventForDispatch } // MARK: - Event Tags diff --git a/Sources/Optimizely+Decide/OptimizelyUserContext+ObjC.swift b/Sources/Optimizely+Decide/OptimizelyUserContext+ObjC.swift index ee5782ad0..ed8a32453 100644 --- a/Sources/Optimizely+Decide/OptimizelyUserContext+ObjC.swift +++ b/Sources/Optimizely+Decide/OptimizelyUserContext+ObjC.swift @@ -33,9 +33,9 @@ import Foundation } public init(optimizely: OptimizelyClient, userId: String, attributes: [String: Any]? = nil, region: String = "US") { - userContext = OptimizelyUserContext(optimizely: optimizely, userId: userId, attributes: attributes) + userContext = OptimizelyUserContext(optimizely: optimizely, userId: userId, attributes: attributes ,region: region) } - + public init(user: OptimizelyUserContext, region: String = "US") { self.userContext = user } From a905455b1201e0eb3963b96bcd49a6a5b1cdb02b Mon Sep 17 00:00:00 2001 From: esrakartalOpt Date: Thu, 21 Aug 2025 12:40:41 -0500 Subject: [PATCH 06/14] Fix errors --- Sources/Implementation/Events/BatchEventBuilder.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/Implementation/Events/BatchEventBuilder.swift b/Sources/Implementation/Events/BatchEventBuilder.swift index 6e11e856f..cd044af8a 100644 --- a/Sources/Implementation/Events/BatchEventBuilder.swift +++ b/Sources/Implementation/Events/BatchEventBuilder.swift @@ -110,7 +110,7 @@ class BatchEventBuilder { let data = try? JSONEncoder().encode(batchEvent) let eventForDispatch = EventForDispatch(url: nil, body: data ?? Data(), region: eventRegion) - return eventForDispatch + return eventForDispatch.body } // MARK: - Event Tags From 572ba7f796174ba7379b7f32fd1e6f7510d8436e Mon Sep 17 00:00:00 2001 From: esrakartalOpt Date: Thu, 21 Aug 2025 12:56:44 -0500 Subject: [PATCH 07/14] Fix region error --- .../OptimizelyTests-Batch-iOS/EventDispatcherTests_Batch.swift | 3 ++- Tests/TestUtils/OTUtils.swift | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Tests/OptimizelyTests-Batch-iOS/EventDispatcherTests_Batch.swift b/Tests/OptimizelyTests-Batch-iOS/EventDispatcherTests_Batch.swift index 946cea17c..c5d0da8c8 100644 --- a/Tests/OptimizelyTests-Batch-iOS/EventDispatcherTests_Batch.swift +++ b/Tests/OptimizelyTests-Batch-iOS/EventDispatcherTests_Batch.swift @@ -950,7 +950,8 @@ extension EventDispatcherTests_Batch { projectID: testProjectId, clientName: kClientName, anonymizeIP: kAnonymizeIP, - enrichDecisions: kEnrichDecision) + enrichDecisions: kEnrichDecision, + region: "US") } func dispatchMultipleEvents(_ events: [(url: String, event: BatchEvent)]) { diff --git a/Tests/TestUtils/OTUtils.swift b/Tests/TestUtils/OTUtils.swift index 426338390..549a71284 100644 --- a/Tests/TestUtils/OTUtils.swift +++ b/Tests/TestUtils/OTUtils.swift @@ -232,7 +232,8 @@ class OTUtils { projectID: testProjectId, clientName: "test", anonymizeIP: true, - enrichDecisions: true) + enrichDecisions: true, + region: "US") } static func clearAllEventQueues() { From f657413e88060c2e70164a59bcefad0df6f8fef7 Mon Sep 17 00:00:00 2001 From: muzahidul-opti Date: Fri, 22 Aug 2025 19:20:10 +0600 Subject: [PATCH 08/14] feat(EventForDispatch): add Objective-C initializer --- Sources/Optimizely/OptimizelyClient+ObjC.swift | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Sources/Optimizely/OptimizelyClient+ObjC.swift b/Sources/Optimizely/OptimizelyClient+ObjC.swift index 54161ad5b..fc7abd69f 100644 --- a/Sources/Optimizely/OptimizelyClient+ObjC.swift +++ b/Sources/Optimizely/OptimizelyClient+ObjC.swift @@ -546,3 +546,10 @@ extension OptimizelyClient { } } + +// MARK: - EventForDispatch Objective-C initializer +extension EventForDispatch { + @objc public convenience init(url: URL? = nil, body: Data) { + self.init(url: url, body: body, region: .US) + } +} From 187eadc382f3865a5256f2a04db2ebd0f74a0ce6 Mon Sep 17 00:00:00 2001 From: esrakartalOpt Date: Mon, 25 Aug 2025 09:49:53 -0500 Subject: [PATCH 09/14] Add test cases for invalid region --- .../BatchEventBuilderTests_Region.swift | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/Tests/OptimizelyTests-Common/BatchEventBuilderTests_Region.swift b/Tests/OptimizelyTests-Common/BatchEventBuilderTests_Region.swift index b57ff9ad3..502ea2c68 100644 --- a/Tests/OptimizelyTests-Common/BatchEventBuilderTests_Region.swift +++ b/Tests/OptimizelyTests-Common/BatchEventBuilderTests_Region.swift @@ -95,6 +95,31 @@ class BatchEventBuilderTests_Region: XCTestCase { let eventForDispatch = getFirstEvent(dispatcher: eventDispatcher)! XCTAssertEqual(eventForDispatch.url.absoluteString, EventForDispatch.getEndpoint(for: .EU)) } + + func testCreateImpressionEventWithInvalidRegion() { + // Set the region to invalid ZZ + optimizely.config?.project.region = .ZZ + + let attributes: [String: Any] = [ + "s_foo": "foo", + "b_true": true, + "i_42": 42, + "d_4_2": 4.2 + ] + + _ = try! optimizely.activate(experimentKey: experimentKey, + userId: userId, + attributes: attributes) + + let event = getFirstEventJSON(dispatcher: eventDispatcher)! + + // Check if the region is correctly set to default US in the event + XCTAssertEqual(event["region"] as! String, "US") + + // Check if the event was sent to the correct endpoint + let eventForDispatch = getFirstEvent(dispatcher: eventDispatcher)! + XCTAssertEqual(eventForDispatch.url.absoluteString, EventForDispatch.getEndpoint(for: .US)) + } // MARK: - Test Conversion Event with Region @@ -143,6 +168,29 @@ class BatchEventBuilderTests_Region: XCTestCase { let eventForDispatch = getFirstEvent(dispatcher: eventDispatcher)! XCTAssertEqual(eventForDispatch.url.absoluteString, EventForDispatch.getEndpoint(for: .EU)) } + + func testCreateConversionEventWithInvalidRegion() { + // Set the region to invalid ZZ + optimizely.config?.project.region = .ZZ + + let eventKey = "event_single_targeted_exp" + let attributes: [String: Any] = ["s_foo": "bar"] + let eventTags: [String: Any] = ["browser": "chrome"] + + try! optimizely.track(eventKey: eventKey, + userId: userId, + attributes: attributes, + eventTags: eventTags) + + let event = getFirstEventJSON(dispatcher: eventDispatcher)! + + // Check if the region is correctly set to default US in the event + XCTAssertEqual(event["region"] as! String, "US") + + // Check if the event was sent to the correct endpoint + let eventForDispatch = getFirstEvent(dispatcher: eventDispatcher)! + XCTAssertEqual(eventForDispatch.url.absoluteString, EventForDispatch.getEndpoint(for: .US)) + } // MARK: - Test Direct Event Creation with Region From f68d396b818f64a27e95af6a66de61d97e9717bd Mon Sep 17 00:00:00 2001 From: esrakartalOpt Date: Wed, 27 Aug 2025 14:03:55 -0500 Subject: [PATCH 10/14] Implemented comments --- Sources/Data Model/DispatchEvents/EventForDispatch.swift | 2 +- Sources/Extensions/ArrayEventForDispatch+Extension.swift | 3 +-- Sources/Implementation/Events/BatchEventBuilder.swift | 5 ++--- Sources/Optimizely+Decide/OptimizelyUserContext.swift | 3 +-- 4 files changed, 5 insertions(+), 8 deletions(-) diff --git a/Sources/Data Model/DispatchEvents/EventForDispatch.swift b/Sources/Data Model/DispatchEvents/EventForDispatch.swift index 1677a04ca..10f77bb70 100644 --- a/Sources/Data Model/DispatchEvents/EventForDispatch.swift +++ b/Sources/Data Model/DispatchEvents/EventForDispatch.swift @@ -33,7 +33,7 @@ import Foundation public let body: Data public init(url: URL? = nil, body: Data, region: Region = .US) { - let endpoint = url?.absoluteString ?? EventForDispatch.getEndpoint(for: region) + let endpoint = region == .US ? Self.eventEndpoint : Self.euEventEndpoint self.url = URL(string: endpoint)! self.body = body } diff --git a/Sources/Extensions/ArrayEventForDispatch+Extension.swift b/Sources/Extensions/ArrayEventForDispatch+Extension.swift index 01da321a9..17855f22e 100644 --- a/Sources/Extensions/ArrayEventForDispatch+Extension.swift +++ b/Sources/Extensions/ArrayEventForDispatch+Extension.swift @@ -117,7 +117,6 @@ extension Array where Element == EventForDispatch { return nil } - let regionValue = base.region == Region.EU.rawValue ? Region.EU : Region.US - return EventForDispatch(url: url, body: data, region: regionValue) + return EventForDispatch(url: url, body: data, region: Region(rawValue: base.region) ?? .US) } } diff --git a/Sources/Implementation/Events/BatchEventBuilder.swift b/Sources/Implementation/Events/BatchEventBuilder.swift index cd044af8a..7cf796310 100644 --- a/Sources/Implementation/Events/BatchEventBuilder.swift +++ b/Sources/Implementation/Events/BatchEventBuilder.swift @@ -88,9 +88,8 @@ class BatchEventBuilder { userId: String, attributes: OptimizelyAttributes?, decisions: [Decision]?, - dispatchEvents: [DispatchEvent], - region: Region? = nil) -> Data? { - let eventRegion = region ?? config.region + dispatchEvents: [DispatchEvent]) -> Data? { + let eventRegion = config.region let snapShot = Snapshot(decisions: decisions, events: dispatchEvents) let eventAttributes = getEventAttributes(config: config, attributes: attributes) diff --git a/Sources/Optimizely+Decide/OptimizelyUserContext.swift b/Sources/Optimizely+Decide/OptimizelyUserContext.swift index d04414af1..736102d62 100644 --- a/Sources/Optimizely+Decide/OptimizelyUserContext.swift +++ b/Sources/Optimizely+Decide/OptimizelyUserContext.swift @@ -73,8 +73,7 @@ public class OptimizelyUserContext { /// - region: The region for the user context (optional). Defaults to the region from the project config. public convenience init(optimizely: OptimizelyClient, userId: String, - attributes: [String: Any?]? = nil, - region: String? = nil) { + attributes: [String: Any?]? = nil) { self.init(optimizely: optimizely, userId: userId, attributes: attributes ?? [:], identify: true) } From 6e3c1b433da7ff9272702e55ef1d26d03e018f78 Mon Sep 17 00:00:00 2001 From: esrakartalOpt Date: Wed, 27 Aug 2025 15:32:56 -0500 Subject: [PATCH 11/14] Remove unused region arg --- Sources/Implementation/Events/BatchEventBuilder.swift | 6 ++---- Sources/Optimizely+Decide/OptimizelyUserContext+ObjC.swift | 4 ++-- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/Sources/Implementation/Events/BatchEventBuilder.swift b/Sources/Implementation/Events/BatchEventBuilder.swift index 7cf796310..57db1dcb7 100644 --- a/Sources/Implementation/Events/BatchEventBuilder.swift +++ b/Sources/Implementation/Events/BatchEventBuilder.swift @@ -47,8 +47,7 @@ class BatchEventBuilder { userId: userId, attributes: attributes, decisions: [decision], - dispatchEvents: [dispatchEvent], - region: config.region) + dispatchEvents: [dispatchEvent]) } // MARK: - Converison Event @@ -78,8 +77,7 @@ class BatchEventBuilder { userId: userId, attributes: attributes, decisions: nil, - dispatchEvents: [dispatchEvent], - region: config.region) + dispatchEvents: [dispatchEvent]) } // MARK: - Create Event diff --git a/Sources/Optimizely+Decide/OptimizelyUserContext+ObjC.swift b/Sources/Optimizely+Decide/OptimizelyUserContext+ObjC.swift index ed8a32453..a3275d88e 100644 --- a/Sources/Optimizely+Decide/OptimizelyUserContext+ObjC.swift +++ b/Sources/Optimizely+Decide/OptimizelyUserContext+ObjC.swift @@ -33,7 +33,7 @@ import Foundation } public init(optimizely: OptimizelyClient, userId: String, attributes: [String: Any]? = nil, region: String = "US") { - userContext = OptimizelyUserContext(optimizely: optimizely, userId: userId, attributes: attributes ,region: region) + userContext = OptimizelyUserContext(optimizely: optimizely, userId: userId, attributes: attributes) } public init(user: OptimizelyUserContext, region: String = "US") { @@ -100,7 +100,7 @@ extension OptimizelyClient { @available(swift, obsoleted: 1.0) @objc(createUserContextWithUserId:attributes:region:) public func objcCreateUserContext(userId: String, attributes: [String: Any]? = nil, region: String) -> ObjcOptimizelyUserContext { - let user = OptimizelyUserContext(optimizely: self, userId: userId, attributes: attributes, region: region) + let user = OptimizelyUserContext(optimizely: self, userId: userId, attributes: attributes) return ObjcOptimizelyUserContext(user: user, region: region) } From da9e6e8eb89be61493e0b4fc7fe1ac799812f97e Mon Sep 17 00:00:00 2001 From: esrakartalOpt Date: Fri, 29 Aug 2025 10:40:15 -0500 Subject: [PATCH 12/14] Implement suggested cleanup and change --- .../DispatchEvents/EventForDispatch.swift | 2 +- .../OptimizelyUserContext+ObjC.swift | 14 +++++++------- .../Optimizely+Decide/OptimizelyUserContext.swift | 1 - 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/Sources/Data Model/DispatchEvents/EventForDispatch.swift b/Sources/Data Model/DispatchEvents/EventForDispatch.swift index 10f77bb70..4ce659fbd 100644 --- a/Sources/Data Model/DispatchEvents/EventForDispatch.swift +++ b/Sources/Data Model/DispatchEvents/EventForDispatch.swift @@ -33,7 +33,7 @@ import Foundation public let body: Data public init(url: URL? = nil, body: Data, region: Region = .US) { - let endpoint = region == .US ? Self.eventEndpoint : Self.euEventEndpoint + let endpoint = url?.absoluteString ?? (region == .US ? Self.eventEndpoint : Self.euEventEndpoint) self.url = URL(string: endpoint)! self.body = body } diff --git a/Sources/Optimizely+Decide/OptimizelyUserContext+ObjC.swift b/Sources/Optimizely+Decide/OptimizelyUserContext+ObjC.swift index a3275d88e..e56b23341 100644 --- a/Sources/Optimizely+Decide/OptimizelyUserContext+ObjC.swift +++ b/Sources/Optimizely+Decide/OptimizelyUserContext+ObjC.swift @@ -32,11 +32,11 @@ import Foundation return userContext.optimizely } - public init(optimizely: OptimizelyClient, userId: String, attributes: [String: Any]? = nil, region: String = "US") { + public init(optimizely: OptimizelyClient, userId: String, attributes: [String: Any]? = nil) { userContext = OptimizelyUserContext(optimizely: optimizely, userId: userId, attributes: attributes) } - public init(user: OptimizelyUserContext, region: String = "US") { + public init(user: OptimizelyUserContext) { self.userContext = user } @@ -83,7 +83,7 @@ import Foundation ruleKey = decision.ruleKey flagKey = decision.flagKey - userContext = ObjcOptimizelyUserContext(user: decision.userContext, region: "US") + userContext = ObjcOptimizelyUserContext(user: decision.userContext) reasons = decision.reasons } } @@ -94,14 +94,14 @@ extension OptimizelyClient { @objc(createUserContextWithUserId:attributes:) public func objcCreateUserContext(userId: String, attributes: [String: Any]? = nil) -> ObjcOptimizelyUserContext { let user = createUserContext(userId: userId, attributes: attributes) - return ObjcOptimizelyUserContext(user: user, region: "US") + return ObjcOptimizelyUserContext(user: user) } @available(swift, obsoleted: 1.0) - @objc(createUserContextWithUserId:attributes:region:) - public func objcCreateUserContext(userId: String, attributes: [String: Any]? = nil, region: String) -> ObjcOptimizelyUserContext { + @objc(createUserContextWithUserId:attributes:) + public func objcCreateUserContext(userId: String, attributes: [String: Any]? = nil) -> ObjcOptimizelyUserContext { let user = OptimizelyUserContext(optimizely: self, userId: userId, attributes: attributes) - return ObjcOptimizelyUserContext(user: user, region: region) + return ObjcOptimizelyUserContext(user: user) } @available(swift, obsoleted: 1.0) diff --git a/Sources/Optimizely+Decide/OptimizelyUserContext.swift b/Sources/Optimizely+Decide/OptimizelyUserContext.swift index 736102d62..70959baf7 100644 --- a/Sources/Optimizely+Decide/OptimizelyUserContext.swift +++ b/Sources/Optimizely+Decide/OptimizelyUserContext.swift @@ -70,7 +70,6 @@ public class OptimizelyUserContext { /// - optimizely: An instance of OptimizelyClient to be used for decisions. /// - userId: The user ID to be used for bucketing. /// - attributes: A map of attribute names to current user attribute values. - /// - region: The region for the user context (optional). Defaults to the region from the project config. public convenience init(optimizely: OptimizelyClient, userId: String, attributes: [String: Any?]? = nil) { From f63cea482b9cf99b8d9a2e6ca7e0de18906e081d Mon Sep 17 00:00:00 2001 From: esrakartalOpt Date: Fri, 29 Aug 2025 10:57:47 -0500 Subject: [PATCH 13/14] Remove duplicate method --- Sources/Optimizely+Decide/OptimizelyUserContext+ObjC.swift | 7 ------- 1 file changed, 7 deletions(-) diff --git a/Sources/Optimizely+Decide/OptimizelyUserContext+ObjC.swift b/Sources/Optimizely+Decide/OptimizelyUserContext+ObjC.swift index e56b23341..83a90a68c 100644 --- a/Sources/Optimizely+Decide/OptimizelyUserContext+ObjC.swift +++ b/Sources/Optimizely+Decide/OptimizelyUserContext+ObjC.swift @@ -97,13 +97,6 @@ extension OptimizelyClient { return ObjcOptimizelyUserContext(user: user) } - @available(swift, obsoleted: 1.0) - @objc(createUserContextWithUserId:attributes:) - public func objcCreateUserContext(userId: String, attributes: [String: Any]? = nil) -> ObjcOptimizelyUserContext { - let user = OptimizelyUserContext(optimizely: self, userId: userId, attributes: attributes) - return ObjcOptimizelyUserContext(user: user) - } - @available(swift, obsoleted: 1.0) @objc public convenience init(sdkKey: String, logger: OPTLogger?, From a788cfe83803a7d223c57f802029b609fefd391d Mon Sep 17 00:00:00 2001 From: esrakartalOpt Date: Fri, 29 Aug 2025 12:12:44 -0500 Subject: [PATCH 14/14] Remove unnecessary getEndpoint method --- .../Data Model/DispatchEvents/EventForDispatch.swift | 9 --------- .../BatchEventBuilderTests_Region.swift | 12 ++++++------ 2 files changed, 6 insertions(+), 15 deletions(-) diff --git a/Sources/Data Model/DispatchEvents/EventForDispatch.swift b/Sources/Data Model/DispatchEvents/EventForDispatch.swift index 4ce659fbd..966e1f331 100644 --- a/Sources/Data Model/DispatchEvents/EventForDispatch.swift +++ b/Sources/Data Model/DispatchEvents/EventForDispatch.swift @@ -20,15 +20,6 @@ import Foundation public static var eventEndpoint = "https://logx.optimizely.com/v1/events" public static var euEventEndpoint = "https://eu.logx.optimizely.com/v1/events" - public static func getEndpoint(for region: Region) -> String { - switch region { - case .EU: - return euEventEndpoint - case .US: - return eventEndpoint - } - } - public let url: URL public let body: Data diff --git a/Tests/OptimizelyTests-Common/BatchEventBuilderTests_Region.swift b/Tests/OptimizelyTests-Common/BatchEventBuilderTests_Region.swift index 502ea2c68..1d00f65e1 100644 --- a/Tests/OptimizelyTests-Common/BatchEventBuilderTests_Region.swift +++ b/Tests/OptimizelyTests-Common/BatchEventBuilderTests_Region.swift @@ -68,7 +68,7 @@ class BatchEventBuilderTests_Region: XCTestCase { // Check if the event was sent to the correct endpoint let eventForDispatch = getFirstEvent(dispatcher: eventDispatcher)! - XCTAssertEqual(eventForDispatch.url.absoluteString, EventForDispatch.getEndpoint(for: .US)) + XCTAssertEqual(eventForDispatch.url.absoluteString, EventForDispatch.eventEndpoint) } func testCreateImpressionEventWithEURegion() { @@ -93,7 +93,7 @@ class BatchEventBuilderTests_Region: XCTestCase { // Check if the event was sent to the correct endpoint let eventForDispatch = getFirstEvent(dispatcher: eventDispatcher)! - XCTAssertEqual(eventForDispatch.url.absoluteString, EventForDispatch.getEndpoint(for: .EU)) + XCTAssertEqual(eventForDispatch.url.absoluteString, EventForDispatch.euEventEndpoint) } func testCreateImpressionEventWithInvalidRegion() { @@ -118,7 +118,7 @@ class BatchEventBuilderTests_Region: XCTestCase { // Check if the event was sent to the correct endpoint let eventForDispatch = getFirstEvent(dispatcher: eventDispatcher)! - XCTAssertEqual(eventForDispatch.url.absoluteString, EventForDispatch.getEndpoint(for: .US)) + XCTAssertEqual(eventForDispatch.url.absoluteString, EventForDispatch.eventEndpoint) } // MARK: - Test Conversion Event with Region @@ -143,7 +143,7 @@ class BatchEventBuilderTests_Region: XCTestCase { // Check if the event was sent to the correct endpoint let eventForDispatch = getFirstEvent(dispatcher: eventDispatcher)! - XCTAssertEqual(eventForDispatch.url.absoluteString, EventForDispatch.getEndpoint(for: .US)) + XCTAssertEqual(eventForDispatch.url.absoluteString, EventForDispatch.eventEndpoint) } func testCreateConversionEventWithEURegion() { @@ -166,7 +166,7 @@ class BatchEventBuilderTests_Region: XCTestCase { // Check if the event was sent to the correct endpoint let eventForDispatch = getFirstEvent(dispatcher: eventDispatcher)! - XCTAssertEqual(eventForDispatch.url.absoluteString, EventForDispatch.getEndpoint(for: .EU)) + XCTAssertEqual(eventForDispatch.url.absoluteString, EventForDispatch.euEventEndpoint) } func testCreateConversionEventWithInvalidRegion() { @@ -189,7 +189,7 @@ class BatchEventBuilderTests_Region: XCTestCase { // Check if the event was sent to the correct endpoint let eventForDispatch = getFirstEvent(dispatcher: eventDispatcher)! - XCTAssertEqual(eventForDispatch.url.absoluteString, EventForDispatch.getEndpoint(for: .US)) + XCTAssertEqual(eventForDispatch.url.absoluteString, EventForDispatch.eventEndpoint) } // MARK: - Test Direct Event Creation with Region