1- import { ISplit } from '../../../../dtos/types' ;
1+ import { IRBSegment , ISplit } from '../../../../dtos/types' ;
22import { readinessManagerFactory } from '../../../../readiness/readinessManager' ;
33import { splitApiFactory } from '../../../../services/splitApi' ;
44import { SegmentsCacheInMemory } from '../../../../storages/inMemory/SegmentsCacheInMemory' ;
55import { SplitsCacheInMemory } from '../../../../storages/inMemory/SplitsCacheInMemory' ;
66import { splitChangesFetcherFactory } from '../../fetchers/splitChangesFetcher' ;
7- import { splitChangesUpdaterFactory , parseSegments , computeSplitsMutation } from '../splitChangesUpdater' ;
7+ import { splitChangesUpdaterFactory , parseSegments , computeMutation } from '../splitChangesUpdater' ;
88import splitChangesMock1 from '../../../../__tests__/mocks/splitchanges.since.-1.json' ;
99import fetchMock from '../../../../__tests__/testUtils/fetchMock' ;
1010import { fullSettings , settingsSplitApi } from '../../../../utils/settingsValidation/__tests__/settings.mocks' ;
1111import { EventEmitter } from '../../../../utils/MinEvents' ;
1212import { loggerMock } from '../../../../logger/__tests__/sdkLogger.mock' ;
1313import { telemetryTrackerFactory } from '../../../../trackers/telemetryTracker' ;
1414import { splitNotifications } from '../../../streaming/__tests__/dataMocks' ;
15+ import { RBSegmentsCacheInMemory } from '../../../../storages/inMemory/RBSegmentsCacheInMemory' ;
1516
1617const ARCHIVED_FF = 'ARCHIVED' ;
1718
@@ -94,58 +95,60 @@ test('splitChangesUpdater / segments parser', () => {
9495test ( 'splitChangesUpdater / compute splits mutation' , ( ) => {
9596 const splitFiltersValidation = { queryString : null , groupedFilters : { bySet : [ ] , byName : [ ] , byPrefix : [ ] } , validFilters : [ ] } ;
9697
97- let splitsMutation = computeSplitsMutation ( [ activeSplitWithSegments , archivedSplit ] as ISplit [ ] , splitFiltersValidation ) ;
98+ let segments = new Set < string > ( ) ;
99+ let splitsMutation = computeMutation ( [ activeSplitWithSegments , archivedSplit ] as ISplit [ ] , segments , splitFiltersValidation ) ;
98100
99101 expect ( splitsMutation . added ) . toEqual ( [ activeSplitWithSegments ] ) ;
100102 expect ( splitsMutation . removed ) . toEqual ( [ archivedSplit ] ) ;
101- expect ( splitsMutation . segments ) . toEqual ( [ 'A' , 'B' ] ) ;
103+ expect ( Array . from ( segments ) ) . toEqual ( [ 'A' , 'B' ] ) ;
102104
103105 // SDK initialization without sets
104106 // should process all the notifications
105- splitsMutation = computeSplitsMutation ( [ testFFSetsAB , test2FFSetsX ] as ISplit [ ] , splitFiltersValidation ) ;
107+ segments = new Set < string > ( ) ;
108+ splitsMutation = computeMutation ( [ testFFSetsAB , test2FFSetsX ] as ISplit [ ] , segments , splitFiltersValidation ) ;
106109
107110 expect ( splitsMutation . added ) . toEqual ( [ testFFSetsAB , test2FFSetsX ] ) ;
108111 expect ( splitsMutation . removed ) . toEqual ( [ ] ) ;
109- expect ( splitsMutation . segments ) . toEqual ( [ ] ) ;
112+ expect ( Array . from ( segments ) ) . toEqual ( [ ] ) ;
110113} ) ;
111114
112115test ( 'splitChangesUpdater / compute splits mutation with filters' , ( ) => {
113116 // SDK initialization with sets: [set_a, set_b]
114117 let splitFiltersValidation = { queryString : '&sets=set_a,set_b' , groupedFilters : { bySet : [ 'set_a' , 'set_b' ] , byName : [ 'name_1' ] , byPrefix : [ ] } , validFilters : [ ] } ;
115118
116119 // fetching new feature flag in sets A & B
117- let splitsMutation = computeSplitsMutation ( [ testFFSetsAB ] , splitFiltersValidation ) ;
120+ let splitsMutation = computeMutation ( [ testFFSetsAB ] , new Set ( ) , splitFiltersValidation ) ;
118121
119122 // should add it to mutations
120123 expect ( splitsMutation . added ) . toEqual ( [ testFFSetsAB ] ) ;
121124 expect ( splitsMutation . removed ) . toEqual ( [ ] ) ;
122125
123126 // fetching existing test feature flag removed from set B
124- splitsMutation = computeSplitsMutation ( [ testFFRemoveSetB ] , splitFiltersValidation ) ;
127+ splitsMutation = computeMutation ( [ testFFRemoveSetB ] , new Set ( ) , splitFiltersValidation ) ;
125128
126129 expect ( splitsMutation . added ) . toEqual ( [ testFFRemoveSetB ] ) ;
127130 expect ( splitsMutation . removed ) . toEqual ( [ ] ) ;
128131
129132 // fetching existing test feature flag removed from set B
130- splitsMutation = computeSplitsMutation ( [ testFFRemoveSetA ] , splitFiltersValidation ) ;
133+ splitsMutation = computeMutation ( [ testFFRemoveSetA ] , new Set ( ) , splitFiltersValidation ) ;
131134
132135 expect ( splitsMutation . added ) . toEqual ( [ ] ) ;
133136 expect ( splitsMutation . removed ) . toEqual ( [ testFFRemoveSetA ] ) ;
134137
135138 // fetching existing test feature flag removed from set B
136- splitsMutation = computeSplitsMutation ( [ testFFEmptySet ] , splitFiltersValidation ) ;
139+ splitsMutation = computeMutation ( [ testFFEmptySet ] , new Set ( ) , splitFiltersValidation ) ;
137140
138141 expect ( splitsMutation . added ) . toEqual ( [ ] ) ;
139142 expect ( splitsMutation . removed ) . toEqual ( [ testFFEmptySet ] ) ;
140143
141144 // SDK initialization with names: ['test2']
142145 splitFiltersValidation = { queryString : '&names=test2' , groupedFilters : { bySet : [ ] , byName : [ 'test2' ] , byPrefix : [ ] } , validFilters : [ ] } ;
143- splitsMutation = computeSplitsMutation ( [ testFFSetsAB ] , splitFiltersValidation ) ;
146+ splitsMutation = computeMutation ( [ testFFSetsAB ] , new Set ( ) , splitFiltersValidation ) ;
144147
145148 expect ( splitsMutation . added ) . toEqual ( [ ] ) ;
146149 expect ( splitsMutation . removed ) . toEqual ( [ testFFSetsAB ] ) ;
147150
148- splitsMutation = computeSplitsMutation ( [ test2FFSetsX , testFFEmptySet ] , splitFiltersValidation ) ;
151+ splitsMutation = computeMutation ( [ test2FFSetsX , testFFEmptySet ] , new Set ( ) , splitFiltersValidation ) ;
149152
150153 expect ( splitsMutation . added ) . toEqual ( [ test2FFSetsX ] ) ;
151154 expect ( splitsMutation . removed ) . toEqual ( [ testFFEmptySet ] ) ;
@@ -161,10 +164,13 @@ describe('splitChangesUpdater', () => {
161164 const splits = new SplitsCacheInMemory ( ) ;
162165 const updateSplits = jest . spyOn ( splits , 'update' ) ;
163166
167+ const rbSegments = new RBSegmentsCacheInMemory ( ) ;
168+ const updateRbSegments = jest . spyOn ( rbSegments , 'update' ) ;
169+
164170 const segments = new SegmentsCacheInMemory ( ) ;
165171 const registerSegments = jest . spyOn ( segments , 'registerSegments' ) ;
166172
167- const storage = { splits, segments } ;
173+ const storage = { splits, rbSegments , segments } ;
168174
169175 const readinessManager = readinessManagerFactory ( EventEmitter , fullSettings ) ;
170176 const splitsEmitSpy = jest . spyOn ( readinessManager . splits , 'emit' ) ;
@@ -179,22 +185,29 @@ describe('splitChangesUpdater', () => {
179185
180186 test ( 'test without payload' , async ( ) => {
181187 const result = await splitChangesUpdater ( ) ;
188+
189+ expect ( fetchSplitChanges ) . toBeCalledTimes ( 1 ) ;
190+ expect ( fetchSplitChanges ) . lastCalledWith ( - 1 , undefined , undefined , - 1 ) ;
182191 expect ( updateSplits ) . toBeCalledTimes ( 1 ) ;
183- expect ( updateSplits ) . lastCalledWith ( splitChangesMock1 . splits , [ ] , splitChangesMock1 . till ) ;
192+ expect ( updateSplits ) . lastCalledWith ( splitChangesMock1 . ff . d , [ ] , splitChangesMock1 . ff . t ) ;
193+ expect ( updateRbSegments ) . toBeCalledTimes ( 0 ) ; // no rbSegments to update
184194 expect ( registerSegments ) . toBeCalledTimes ( 1 ) ;
185195 expect ( splitsEmitSpy ) . toBeCalledWith ( 'state::splits-arrived' ) ;
186196 expect ( result ) . toBe ( true ) ;
187197 } ) ;
188198
189- test ( 'test with payload' , async ( ) => {
199+ test ( 'test with ff payload' , async ( ) => {
190200 let index = 0 ;
191201 for ( const notification of splitNotifications ) {
192202 const payload = notification . decoded as Pick < ISplit , 'name' | 'changeNumber' | 'killed' | 'defaultTreatment' | 'trafficTypeName' | 'conditions' | 'status' | 'seed' | 'trafficAllocation' | 'trafficAllocationSeed' | 'configurations' > ;
193203 const changeNumber = payload . changeNumber ;
194204
195205 await expect ( splitChangesUpdater ( undefined , undefined , { payload, changeNumber : changeNumber } ) ) . resolves . toBe ( true ) ;
196- // fetch not being called
206+
207+ // fetch and RBSegments.update not being called
197208 expect ( fetchSplitChanges ) . toBeCalledTimes ( 0 ) ;
209+ expect ( updateRbSegments ) . toBeCalledTimes ( 0 ) ;
210+
198211 expect ( updateSplits ) . toBeCalledTimes ( index + 1 ) ;
199212 // Change number being updated
200213 expect ( updateSplits . mock . calls [ index ] [ 2 ] ) . toEqual ( changeNumber ) ;
@@ -209,6 +222,23 @@ describe('splitChangesUpdater', () => {
209222 }
210223 } ) ;
211224
225+ test ( 'test with rbsegment payload' , async ( ) => {
226+ const payload = { name : 'rbsegment' , status : 'ACTIVE' , changeNumber : 1684329854385 , conditions : [ ] } as unknown as IRBSegment ;
227+ const changeNumber = payload . changeNumber ;
228+
229+ await expect ( splitChangesUpdater ( undefined , undefined , { payload, changeNumber : changeNumber } ) ) . resolves . toBe ( true ) ;
230+
231+ // fetch and Splits.update not being called
232+ expect ( fetchSplitChanges ) . toBeCalledTimes ( 0 ) ;
233+ expect ( updateSplits ) . toBeCalledTimes ( 0 ) ;
234+
235+ expect ( updateRbSegments ) . toBeCalledTimes ( 1 ) ;
236+ expect ( updateRbSegments ) . toBeCalledWith ( [ payload ] , [ ] , changeNumber ) ;
237+
238+ expect ( registerSegments ) . toBeCalledTimes ( 1 ) ;
239+ expect ( registerSegments ) . toBeCalledWith ( [ ] ) ;
240+ } ) ;
241+
212242 test ( 'flag sets splits-arrived emission' , async ( ) => {
213243 const payload = splitNotifications [ 3 ] . decoded as Pick < ISplit , 'name' | 'changeNumber' | 'killed' | 'defaultTreatment' | 'trafficTypeName' | 'conditions' | 'status' | 'seed' | 'trafficAllocation' | 'trafficAllocationSeed' | 'configurations' > ;
214244 const setMocks = [
0 commit comments