@@ -13,18 +13,26 @@ const STORED_SPLITS: Record<string, ISplit> = {
13
13
} ;
14
14
15
15
const STORED_SEGMENTS : Record < string , Set < string > > = {
16
- 'segment_test ' :
new Set ( [ '[email protected] ' ] ) ,
16
+ 'excluded_standard_segment ' :
new Set ( [ '[email protected] ' ] ) ,
17
17
'regular_segment' :
new Set ( [ '[email protected] ' ] )
18
18
} ;
19
19
20
+ const STORED_LARGE_SEGMENTS : Record < string , Set < string > > = {
21
+ 'excluded_large_segment' :
new Set ( [ '[email protected] ' ] )
22
+ } ;
23
+
20
24
const STORED_RBSEGMENTS : Record < string , IRBSegment > = {
21
25
'mauro_rule_based_segment' : {
22
26
changeNumber : 5 ,
23
27
name : 'mauro_rule_based_segment' ,
24
28
status : 'ACTIVE' ,
25
29
excluded : {
26
30
27
- segments : [ 'segment_test' ]
31
+ segments : [
32
+ { type : 'standard' , name : 'excluded_standard_segment' } ,
33
+ { type : 'large' , name : 'excluded_large_segment' } ,
34
+ { type : 'rule-based' , name : 'excluded_rule_based_segment' }
35
+ ]
28
36
} ,
29
37
conditions : [
30
38
{
@@ -87,8 +95,8 @@ const STORED_RBSEGMENTS: Record<string, IRBSegment> = {
87
95
changeNumber : 123 ,
88
96
status : 'ACTIVE' ,
89
97
excluded : {
90
- keys : [ ] ,
91
- segments : [ ]
98
+ keys : null ,
99
+ segments : null ,
92
100
} ,
93
101
conditions : [ {
94
102
matcherGroup : {
@@ -135,6 +143,37 @@ const STORED_RBSEGMENTS: Record<string, IRBSegment> = {
135
143
}
136
144
} ]
137
145
} ,
146
+ 'excluded_rule_based_segment' : {
147
+ name : 'excluded_rule_based_segment' ,
148
+ changeNumber : 123 ,
149
+ status : 'ACTIVE' ,
150
+ conditions : [
151
+ {
152
+ matcherGroup : {
153
+ combiner : 'AND' ,
154
+ matchers : [
155
+ {
156
+ keySelector : null ,
157
+ matcherType : 'WHITELIST' ,
158
+ negate : false ,
159
+ userDefinedSegmentMatcherData : null ,
160
+ whitelistMatcherData : {
161
+
162
+ } ,
163
+ unaryNumericMatcherData : null ,
164
+ betweenMatcherData : null
165
+ }
166
+ ]
167
+ }
168
+ }
169
+ ] ,
170
+ } ,
171
+ 'rule_based_segment_without_conditions' : {
172
+ name : 'rule_based_segment_without_conditions' ,
173
+ changeNumber : 123 ,
174
+ status : 'ACTIVE' ,
175
+ conditions : [ ]
176
+ }
138
177
} ;
139
178
140
179
const mockStorageSync = {
@@ -149,6 +188,11 @@ const mockStorageSync = {
149
188
return STORED_SEGMENTS [ segmentName ] ? STORED_SEGMENTS [ segmentName ] . has ( matchingKey ) : false ;
150
189
}
151
190
} ,
191
+ largeSegments : {
192
+ isInSegment ( segmentName : string , matchingKey : string ) {
193
+ return STORED_LARGE_SEGMENTS [ segmentName ] ? STORED_LARGE_SEGMENTS [ segmentName ] . has ( matchingKey ) : false ;
194
+ }
195
+ } ,
152
196
rbSegments : {
153
197
get ( rbsegmentName : string ) {
154
198
return STORED_RBSEGMENTS [ rbsegmentName ] ;
@@ -168,6 +212,11 @@ const mockStorageAsync = {
168
212
return Promise . resolve ( STORED_SEGMENTS [ segmentName ] ? STORED_SEGMENTS [ segmentName ] . has ( matchingKey ) : false ) ;
169
213
}
170
214
} ,
215
+ largeSegments : {
216
+ isInSegment ( segmentName : string , matchingKey : string ) {
217
+ return Promise . resolve ( STORED_LARGE_SEGMENTS [ segmentName ] ? STORED_LARGE_SEGMENTS [ segmentName ] . has ( matchingKey ) : false ) ;
218
+ }
219
+ } ,
171
220
rbSegments : {
172
221
get ( rbsegmentName : string ) {
173
222
return Promise . resolve ( STORED_RBSEGMENTS [ rbsegmentName ] ) ;
@@ -190,18 +239,28 @@ describe.each([
190
239
value : 'depend_on_mauro_rule_based_segment'
191
240
} as IMatcherDto , mockStorage ) ! ;
192
241
193
- [ matcher , dependentMatcher ] . forEach ( async matcher => {
242
+ [ matcher , dependentMatcher ] . forEach ( async ( matcher ) => {
194
243
195
244
// should return false if the provided key is excluded (even if some condition is met)
196
245
let match = matcher ( { key :
'[email protected] ' , attributes :
{ location :
'mdp' } } , evaluateFeature ) ;
197
246
expect ( thenable ( match ) ) . toBe ( isAsync ) ;
198
247
expect ( await match ) . toBe ( false ) ;
199
248
200
- // should return false if the provided key is in some excluded segment (even if some condition is met)
249
+ // should return false if the provided key is in some excluded standard segment (even if some condition is met)
201
250
match = matcher ( { key :
'[email protected] ' , attributes :
{ location :
'tandil' } } , evaluateFeature ) ;
202
251
expect ( thenable ( match ) ) . toBe ( isAsync ) ;
203
252
expect ( await match ) . toBe ( false ) ;
204
253
254
+ // should return false if the provided key is in some excluded large segment (even if some condition is met)
255
+ match = matcher ( { key :
'[email protected] ' , attributes :
{ location :
'tandil' } } , evaluateFeature ) ;
256
+ expect ( thenable ( match ) ) . toBe ( isAsync ) ;
257
+ expect ( await match ) . toBe ( false ) ;
258
+
259
+ // should return false if the provided key is in some excluded rule-based segment (even if some condition is met)
260
+ match = matcher ( { key :
'[email protected] ' , attributes :
{ location :
'tandil' } } , evaluateFeature ) ;
261
+ expect ( thenable ( match ) ) . toBe ( isAsync ) ;
262
+ expect ( await match ) . toBe ( false ) ;
263
+
205
264
// should return false if doesn't match any condition
206
265
match = matcher ( { key :
'[email protected] ' } , evaluateFeature ) ;
207
266
expect ( thenable ( match ) ) . toBe ( isAsync ) ;
@@ -238,6 +297,14 @@ describe.each([
238
297
239
298
// should support feature flag dependency matcher
240
299
expect ( await matcherTrueAlwaysOn ( { key : 'a-key' } , evaluateFeature ) ) . toBe ( true ) ; // Parent split returns one of the expected treatments, so the matcher returns true
300
+
301
+ const matcherTrueRuleBasedSegmentWithoutConditions = matcherFactory ( loggerMock , {
302
+ type : matcherTypes . IN_RULE_BASED_SEGMENT ,
303
+ value : 'rule_based_segment_without_conditions'
304
+ } as IMatcherDto , mockStorageSync ) ! ;
305
+
306
+ // should support rule-based segment without conditions
307
+ expect ( await matcherTrueRuleBasedSegmentWithoutConditions ( { key : 'a-key' } , evaluateFeature ) ) . toBe ( false ) ;
241
308
} ) ;
242
309
243
310
} ) ;
0 commit comments