@@ -8,10 +8,14 @@ import {
8
8
VariationType ,
9
9
IBanditEvent ,
10
10
IBanditLogger ,
11
+ IConfigurationWire ,
12
+ ContextAttributes ,
13
+ Attributes ,
14
+ decodePrecomputedFlag ,
15
+ BanditParameters ,
16
+ BanditVariation ,
11
17
} from '@eppo/js-client-sdk-common' ;
12
- import { BanditParameters , BanditVariation } from '@eppo/js-client-sdk-common/dist/interfaces' ;
13
- import { ContextAttributes } from '@eppo/js-client-sdk-common/dist/types' ;
14
- import { Attributes } from '@eppo/js-client-sdk-common/src/types' ;
18
+ import * as base64 from 'js-base64' ;
15
19
import * as td from 'testdouble' ;
16
20
17
21
import apiServer , { TEST_BANDIT_API_KEY , TEST_SERVER_PORT } from '../test/mockApiServer' ;
@@ -258,6 +262,49 @@ describe('EppoClient E2E test', () => {
258
262
} ) ;
259
263
} ) ;
260
264
265
+ describe ( 'get precomputed assignments' , ( ) => {
266
+ it ( 'obfuscates assignments' , async ( ) => {
267
+ const client = await init ( {
268
+ apiKey,
269
+ baseUrl : `http://127.0.0.1:${ TEST_SERVER_PORT } ` ,
270
+ assignmentLogger : mockLogger ,
271
+ } ) ;
272
+ const subjectAttributes = { id : 'zach' } ;
273
+ const expectedAssignment = client . getStringAssignment (
274
+ 'new-user-onboarding' ,
275
+ 'subject' ,
276
+ subjectAttributes ,
277
+ 'default-value' ,
278
+ ) ;
279
+ expect ( expectedAssignment ) . toBe ( 'purple' ) ;
280
+ const salt = base64 . fromUint8Array ( new Uint8Array ( [ 7 , 53 , 17 , 78 ] ) ) ;
281
+ const encodedPrecomputedWire = client . getPrecomputedConfiguration (
282
+ 'subject' ,
283
+ subjectAttributes ,
284
+ { } ,
285
+ salt ,
286
+ ) ;
287
+ const { precomputed } = JSON . parse ( encodedPrecomputedWire ) as IConfigurationWire ;
288
+ if ( ! precomputed ) {
289
+ fail ( 'Precomputed data not in Configuration response' ) ;
290
+ }
291
+ const precomputedResponse = JSON . parse ( precomputed . response ) ;
292
+ expect ( precomputedResponse ) . toBeTruthy ( ) ;
293
+ expect ( precomputedResponse . salt ) . toEqual ( 'BzURTg==' ) ;
294
+ const precomputedFlags = precomputedResponse ?. flags ?? { } ;
295
+ expect ( Object . keys ( precomputedFlags ) ) . toContain ( 'f0da9e751eb86ad80968df152390fa4f' ) ; // 'new-user-onboarding', md5 hashed
296
+ const decodedFirstFlag = decodePrecomputedFlag (
297
+ precomputedFlags [ 'f0da9e751eb86ad80968df152390fa4f' ] ,
298
+ ) ;
299
+ expect ( decodedFirstFlag . flagKey ) . toEqual ( 'f0da9e751eb86ad80968df152390fa4f' ) ;
300
+ expect ( decodedFirstFlag . variationType ) . toEqual ( VariationType . STRING ) ;
301
+ expect ( decodedFirstFlag . variationKey ) . toEqual ( 'purple' ) ;
302
+ expect ( decodedFirstFlag . variationValue ) . toEqual ( 'purple' ) ;
303
+ expect ( decodedFirstFlag . doLog ) . toEqual ( false ) ;
304
+ expect ( decodedFirstFlag . extraLogging ) . toEqual ( { } ) ;
305
+ } ) ;
306
+ } ) ;
307
+
261
308
describe ( 'Shared Bandit Test Cases' , ( ) => {
262
309
beforeAll ( async ( ) => {
263
310
const dummyBanditLogger : IBanditLogger = {
@@ -367,6 +414,7 @@ describe('EppoClient E2E test', () => {
367
414
client . useExpiringInMemoryBanditAssignmentCache ( 2 ) ;
368
415
369
416
// Let's say someone is rage refreshing - we want to log assignment only once
417
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
370
418
for ( const _ of Array ( 3 ) . keys ( ) ) {
371
419
client . getBanditAction ( flagKey , bobKey , bobAttributes , bobActions , 'default' ) ;
372
420
}
0 commit comments