Skip to content

Commit 6f57b12

Browse files
lokeshdudmegha-iterableEvan Greer
authored
Fix AUT issue where multiple users are created and merge (#899)
Co-authored-by: Megha <[email protected]> Co-authored-by: Evan Greer <[email protected]>
1 parent c138ef9 commit 6f57b12

File tree

3 files changed

+50
-4
lines changed

3 files changed

+50
-4
lines changed

swift-sdk/Internal/AnonymousUserManager.swift

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ public class AnonymousUserManager: AnonymousUserManagerProtocol {
2828
private let notificationStateProvider: NotificationStateProviderProtocol
2929
private var config: IterableConfig
3030
private(set) var lastCriteriaFetch: Double = 0
31+
private var isCriteriaMatched = false
3132

3233
/// Tracks an anonymous event and store it locally
3334
public func trackAnonEvent(name: String, dataFields: [AnyHashable: Any]?) {
@@ -182,6 +183,7 @@ public class AnonymousUserManager: AnonymousUserManagerProtocol {
182183
dataFields: self.localStorage.anonymousUserUpdate,
183184
requestJson: anonSessions
184185
).onError { error in
186+
self.isCriteriaMatched = false
185187
if error.httpStatusCode == 409 {
186188
self.getAnonCriteria() // refetch the criteria
187189
}
@@ -229,7 +231,8 @@ public class AnonymousUserManager: AnonymousUserManagerProtocol {
229231
processAndStoreEvent(type: type, data: data)
230232
}
231233

232-
if let criteriaId = evaluateCriteriaAndReturnID() {
234+
if let criteriaId = evaluateCriteriaAndReturnID(), !isCriteriaMatched {
235+
isCriteriaMatched = true
233236
createAnonymousUser(criteriaId)
234237
}
235238
}

tests/unit-tests/IterableApiCriteriaFetchTests.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ class IterableApiCriteriaFetchTests: XCTestCase {
4949

5050
let config = IterableConfig()
5151
config.enableAnonActivation = true
52-
config.enableOnForegroundCriteriaFetching = true
52+
config.enableForegroundCriteriaFetch = true
5353

5454
IterableAPI.initializeForTesting(apiKey: IterableApiCriteriaFetchTests.apiKey,
5555
config: config,
@@ -85,7 +85,7 @@ class IterableApiCriteriaFetchTests: XCTestCase {
8585

8686
let config = IterableConfig()
8787
config.enableAnonActivation = true
88-
config.enableOnForegroundCriteriaFetching = false
88+
config.enableForegroundCriteriaFetch = false
8989

9090
internalApi = InternalIterableAPI.initializeForTesting(
9191
config: config,
@@ -124,7 +124,7 @@ class IterableApiCriteriaFetchTests: XCTestCase {
124124

125125
let config = IterableConfig()
126126
config.enableAnonActivation = true
127-
config.enableOnForegroundCriteriaFetching = true
127+
config.enableForegroundCriteriaFetch = true
128128

129129
IterableAPI.initializeForTesting(apiKey: IterableApiCriteriaFetchTests.apiKey,
130130
config: config,

tests/unit-tests/UserMergeScenariosTests.swift

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -974,6 +974,49 @@ class UserMergeScenariosTests: XCTestCase, AuthProvider {
974974

975975
waitForExpectations(timeout: 5, handler: nil)
976976
}
977+
978+
func testCriteriaMetTwice() {
979+
let config = IterableConfig()
980+
config.enableAnonActivation = true
981+
982+
let mockSession = MockNetworkSession()
983+
984+
IterableAPI.initializeForTesting(apiKey: UserMergeScenariosTests.apiKey,
985+
config: config,
986+
networkSession: mockSession,
987+
localStorage: localStorage)
988+
989+
IterableAPI.logoutUser()
990+
guard let jsonData = mockData.data(using: .utf8) else { return }
991+
localStorage.criteriaData = jsonData
992+
993+
IterableAPI.track(event: "testEvent")
994+
IterableAPI.track(event: "testEvent")
995+
996+
waitForDuration(seconds: 3)
997+
998+
if let anonUser = localStorage.userIdAnnon {
999+
XCTAssertFalse(anonUser.isEmpty, "Expected anon user nil")
1000+
} else {
1001+
XCTFail("Expected anon user nil but found")
1002+
}
1003+
1004+
// Verify that anon session request was made exactly once
1005+
let anonSessionRequest = mockSession.getRequest(withEndPoint: Const.Path.trackAnonSession)
1006+
XCTAssertNotNil(anonSessionRequest, "Anonymous session request should not be nil")
1007+
1008+
// Count total requests with anon session endpoint
1009+
let anonSessionRequests = mockSession.requests.filter { request in
1010+
request.url?.absoluteString.contains(Const.Path.trackAnonSession) == true
1011+
}
1012+
XCTAssertEqual(anonSessionRequests.count, 1, "Anonymous session should be called exactly once")
1013+
1014+
// Verify track events were made
1015+
let trackRequests = mockSession.requests.filter { request in
1016+
request.url?.absoluteString.contains(Const.Path.trackEvent) == true
1017+
}
1018+
XCTAssertEqual(trackRequests.count, 2, "Track event should be called twice")
1019+
}
9771020
}
9781021

9791022

0 commit comments

Comments
 (0)