Skip to content

Commit 384bfa8

Browse files
Add test cases for bucketToEntity
1 parent f0c1d5b commit 384bfa8

File tree

2 files changed

+195
-0
lines changed

2 files changed

+195
-0
lines changed

OptimizelySwiftSDK.xcodeproj/project.pbxproj

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2018,6 +2018,8 @@
20182018
984159102E13013E0042C01E /* OptimizelyUserContextTests_Decide_Async.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9841590E2E13013E0042C01E /* OptimizelyUserContextTests_Decide_Async.swift */; };
20192019
984159122E141B640042C01E /* OptimizelyUserContextTests_Decide_CMAB.swift in Sources */ = {isa = PBXBuildFile; fileRef = 984159112E141B640042C01E /* OptimizelyUserContextTests_Decide_CMAB.swift */; };
20202020
984159132E141B640042C01E /* OptimizelyUserContextTests_Decide_CMAB.swift in Sources */ = {isa = PBXBuildFile; fileRef = 984159112E141B640042C01E /* OptimizelyUserContextTests_Decide_CMAB.swift */; };
2021+
984159372E16A7C50042C01E /* BucketTests_BucketToEntity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 984159362E16A7C50042C01E /* BucketTests_BucketToEntity.swift */; };
2022+
984159382E16A7C50042C01E /* BucketTests_BucketToEntity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 984159362E16A7C50042C01E /* BucketTests_BucketToEntity.swift */; };
20212023
984E2FDC2B27199B001F477A /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 987F11D92AF3F56F0083D3F9 /* PrivacyInfo.xcprivacy */; };
20222024
984E2FDD2B27199C001F477A /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 987F11D92AF3F56F0083D3F9 /* PrivacyInfo.xcprivacy */; };
20232025
984E2FDE2B27199D001F477A /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 987F11D92AF3F56F0083D3F9 /* PrivacyInfo.xcprivacy */; };
@@ -2575,6 +2577,7 @@
25752577
982C071E2D8C82AE0068B1FF /* HoldoutTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HoldoutTests.swift; sourceTree = "<group>"; };
25762578
9841590E2E13013E0042C01E /* OptimizelyUserContextTests_Decide_Async.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OptimizelyUserContextTests_Decide_Async.swift; sourceTree = "<group>"; };
25772579
984159112E141B640042C01E /* OptimizelyUserContextTests_Decide_CMAB.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OptimizelyUserContextTests_Decide_CMAB.swift; sourceTree = "<group>"; };
2580+
984159362E16A7C50042C01E /* BucketTests_BucketToEntity.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BucketTests_BucketToEntity.swift; sourceTree = "<group>"; };
25782581
984FE5102CC8AA88004F6F41 /* UserProfileTracker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserProfileTracker.swift; sourceTree = "<group>"; };
25792582
987F11D92AF3F56F0083D3F9 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = PrivacyInfo.xcprivacy; sourceTree = "<group>"; };
25802583
989428B22DBFA431008BA1C8 /* MockBucketer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockBucketer.swift; sourceTree = "<group>"; };
@@ -3099,6 +3102,7 @@
30993102
6E75198F22C5211100B2B157 /* BucketTests_BucketVariation.swift */,
31003103
6E75198C22C5211100B2B157 /* BucketTests_ExpToVariation.swift */,
31013104
6E75198322C5211100B2B157 /* BucketTests_GroupToExp.swift */,
3105+
984159362E16A7C50042C01E /* BucketTests_BucketToEntity.swift */,
31023106
98AC98452DB7B762001405DD /* BucketTests_HoldoutToVariation.swift */,
31033107
6E75198422C5211100B2B157 /* BucketTests_Others.swift */,
31043108
6E75199622C5211100B2B157 /* DatafileHandlerTests.swift */,
@@ -5021,6 +5025,7 @@
50215025
6E9B116A22C5487100C22D81 /* BucketTests_Base.swift in Sources */,
50225026
6E9B115F22C5487100C22D81 /* MurmurTests.swift in Sources */,
50235027
6E9B116022C5487100C22D81 /* DecisionServiceTests_Experiments.swift in Sources */,
5028+
984159382E16A7C50042C01E /* BucketTests_BucketToEntity.swift in Sources */,
50245029
6E9B116322C5487100C22D81 /* BucketTests_GroupToExp.swift in Sources */,
50255030
6E7516AF22C520D400B2B157 /* DefaultLogger.swift in Sources */,
50265031
6EF8DE2524BD1BB2008B9488 /* OptimizelyDecideOption.swift in Sources */,
@@ -5315,6 +5320,7 @@
53155320
6E9B115022C5486E00C22D81 /* BucketTests_Base.swift in Sources */,
53165321
6E9B114522C5486E00C22D81 /* MurmurTests.swift in Sources */,
53175322
6E9B114622C5486E00C22D81 /* DecisionServiceTests_Experiments.swift in Sources */,
5323+
984159372E16A7C50042C01E /* BucketTests_BucketToEntity.swift in Sources */,
53185324
6E9B114922C5486E00C22D81 /* BucketTests_GroupToExp.swift in Sources */,
53195325
6E75182B22C520D400B2B157 /* BatchEvent.swift in Sources */,
53205326
6EF8DE1E24BD1BB2008B9488 /* OptimizelyDecideOption.swift in Sources */,
Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
//
2+
// Copyright 2022, Optimizely, Inc. and contributors
3+
//
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
//
8+
// http://www.apache.org/licenses/LICENSE-2.0
9+
//
10+
// Unless required by applicable law or agreed to in writing, software
11+
// distributed under the License is distributed on an "AS IS" BASIS,
12+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
// See the License for the specific language governing permissions and
14+
// limitations under the License.
15+
//
16+
17+
import XCTest
18+
19+
class BucketTests_BucketToEntity: XCTestCase {
20+
var optimizely: OptimizelyClient!
21+
var config: ProjectConfig!
22+
var bucketer: DefaultBucketer!
23+
24+
var kUserId = "12345"
25+
var kGroupId = "333333"
26+
var kExperimentId = "444444"
27+
28+
var kExperimentKey = "countryExperiment"
29+
30+
var kVariationKeyA = "a"
31+
var kVariationKeyB = "b"
32+
var kVariationKeyC = "c"
33+
var kVariationKeyD = "d"
34+
35+
var kVariationIdA = "a11"
36+
var kVariationIdB = "b11"
37+
var kVariationIdC = "c11"
38+
var kVariationIdD = "d11"
39+
40+
var kAudienceIdCountry = "10"
41+
var kAudienceIdAge = "20"
42+
var kAudienceIdInvalid = "9999999"
43+
44+
var kAttributesCountryMatch: [String: Any] = ["country": "us"]
45+
var kAttributesCountryNotMatch: [String: Any] = ["country": "ca"]
46+
var kAttributesAgeMatch: [String: Any] = ["age": 30]
47+
var kAttributesAgeNotMatch: [String: Any] = ["age": 10]
48+
var kAttributesEmpty: [String: Any] = [:]
49+
50+
var experiment: Experiment!
51+
52+
// MARK: - Sample datafile data
53+
54+
var sampleExperimentData: [String: Any] { return
55+
[
56+
"status": "Running",
57+
"id": kExperimentId,
58+
"key": kExperimentKey,
59+
"layerId": "10420273888",
60+
"trafficAllocation": [
61+
["entityId": kVariationIdA, "endOfRange": 2500],
62+
["entityId": kVariationIdB, "endOfRange": 5000],
63+
["entityId": kVariationIdC, "endOfRange": 7500],
64+
["entityId": kVariationIdD, "endOfRange": 10000]
65+
],
66+
"audienceIds": [kAudienceIdCountry],
67+
"variations": [
68+
[
69+
"variables": [],
70+
"id": kVariationIdA,
71+
"key": kVariationKeyA
72+
],
73+
[
74+
"variables": [],
75+
"id": kVariationIdB,
76+
"key": kVariationKeyB
77+
],
78+
[
79+
"variables": [],
80+
"id": kVariationIdC,
81+
"key": kVariationKeyC
82+
],
83+
[
84+
"variables": [],
85+
"id": kVariationIdD,
86+
"key": kVariationKeyD
87+
]
88+
],
89+
"forcedVariations": [:]
90+
]
91+
}
92+
93+
var sampleGroupData: [String: Any] { return
94+
["id": kGroupId,
95+
"policy": "random",
96+
"trafficAllocation": [
97+
["entityId": kExperimentId, "endOfRange": 10000]
98+
],
99+
"experiments": [sampleExperimentData]
100+
]
101+
}
102+
103+
// MARK: - Setup
104+
105+
override func setUp() {
106+
super.setUp()
107+
108+
self.optimizely = OTUtils.createOptimizely(datafileName: "empty_datafile",
109+
clearUserProfileService: true)
110+
self.config = self.optimizely.config
111+
self.bucketer = ((optimizely.decisionService as! DefaultDecisionService).bucketer as! DefaultBucketer)
112+
}
113+
114+
func testBucketToEntityWithEmptyGroup() {
115+
experiment = try! OTUtils.model(from: sampleExperimentData)
116+
self.config.project.experiments = [experiment]
117+
118+
self.config.project.groups = []
119+
120+
let fullAllocation = TrafficAllocation(entityId: "entity_123", endOfRange: 10000)
121+
let bucketedEntityId = bucketer.bucketToEntityId(config: config, experiment: experiment, bucketingId: "id_123", trafficAllocation: [fullAllocation]).result
122+
XCTAssertEqual(bucketedEntityId, "entity_123")
123+
124+
let zeroAllocation = TrafficAllocation(entityId: "entity_123", endOfRange: 0)
125+
let nilEntityId = bucketer.bucketToEntityId(config: config, experiment: experiment, bucketingId: "id_123", trafficAllocation: [zeroAllocation]).result
126+
XCTAssertEqual(nilEntityId, nil)
127+
}
128+
129+
func testBucketToEntityWithGroupMatched() {
130+
experiment = try! OTUtils.model(from: sampleExperimentData)
131+
self.config.project.experiments = [experiment]
132+
133+
let group: Group = try! OTUtils.model(from: sampleGroupData)
134+
self.config.project.groups = [group]
135+
136+
let tests = [["userId": "ppid1", "entityId": "entity1", "expect": "entity1"],
137+
["userId": "ppid2", "entityId": "entity2", "expect": "entity2"],
138+
["userId": "ppid3", "entityId": "entity3", "expect": "entity3"],
139+
["userId": "a very very very very very very very very very very very very very very very long ppd string", "entityId": "entity4", "expect": "entity4"]]
140+
141+
var entityId: String!
142+
143+
for (idx, test) in tests.enumerated() {
144+
entityId = bucketer.bucketToEntityId(config: config, experiment: experiment, bucketingId: test["userId"]!, trafficAllocation: [TrafficAllocation(entityId: test["entityId"]!, endOfRange: 10000)]).result
145+
XCTAssertEqual(test["expect"], entityId, "test[\(idx)] failed")
146+
}
147+
}
148+
149+
func testBucketToEntityWithGroupNotMatched() {
150+
experiment = try! OTUtils.model(from: sampleExperimentData)
151+
self.config.project.experiments = [experiment]
152+
153+
var group: Group = try! OTUtils.model(from: sampleGroupData)
154+
group.trafficAllocation[0].endOfRange = 0
155+
self.config.project.groups = [group]
156+
157+
let tests = [["userId": "ppid1", "entityId": "entity1", "expect": "entity1"],
158+
["userId": "ppid2", "entityId": "entity2", "expect": "entity2"],
159+
["userId": "ppid3", "entityId": "entity3", "expect": "entity3"],
160+
["userId": "a very very very very very very very very very very very very very very very long ppd string", "entityId": "entity4", "expect": "entity4"]]
161+
162+
for (_, test) in tests.enumerated() {
163+
let response: DecisionResponse<String> = bucketer.bucketToEntityId(config: config, experiment: experiment, bucketingId: test["userId"]!, trafficAllocation: [TrafficAllocation(entityId: test["entityId"]!, endOfRange: 10000)])
164+
XCTAssertEqual(response.result, nil)
165+
}
166+
}
167+
168+
func testBucketToEntityWithNoRandoomGroup() {
169+
experiment = try! OTUtils.model(from: sampleExperimentData)
170+
self.config.project.experiments = [experiment]
171+
172+
var group: Group = try! OTUtils.model(from: sampleGroupData)
173+
group.policy = .overlapping
174+
self.config.project.groups = [group]
175+
176+
let tests = [["userId": "ppid1", "entityId": "entity1", "expect": "entity1"],
177+
["userId": "ppid2", "entityId": "entity2", "expect": "entity2"],
178+
["userId": "ppid3", "entityId": "entity3", "expect": "entity3"],
179+
["userId": "a very very very very very very very very very very very very very very very long ppd string", "entityId": "entity4", "expect": "entity4"]]
180+
181+
var entityId: String!
182+
183+
for (idx, test) in tests.enumerated() {
184+
entityId = bucketer.bucketToEntityId(config: config, experiment: experiment, bucketingId: test["userId"]!, trafficAllocation: [TrafficAllocation(entityId: test["entityId"]!, endOfRange: 10000)]).result
185+
XCTAssertEqual(test["expect"], entityId, "test[\(idx)] failed")
186+
}
187+
}
188+
189+
}

0 commit comments

Comments
 (0)