Skip to content

Commit b7f0b0a

Browse files
author
Vinicius de Lacerda
committed
Fix tests
1 parent ea62f11 commit b7f0b0a

File tree

4 files changed

+52
-47
lines changed

4 files changed

+52
-47
lines changed

Diff for: .changeset/unlucky-phones-clap.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'opticks': minor
3+
---
4+
5+
Adds support to MVT tests and simplify the code in the Optimizely integration to abstract the difference between rollouts and MVT/AB

Diff for: packages/lib/src/integrations/__mocks__/@optimizely/optimizely-sdk.ts

+10-12
Original file line numberDiff line numberDiff line change
@@ -9,27 +9,25 @@ export const createInstanceMock = jest.fn(() => ({
99
notificationCenter: {
1010
addNotificationListener: addNotificationListenerMock
1111
},
12-
activate: activateMock,
1312
createUserContext: optimizelyUserContextMock
1413
}))
1514

16-
export const decideMock = jest.fn((toggleKey) => ({
17-
enabled: toggleKey === 'foo'
18-
}))
15+
export const decideMock = jest.fn((toggleKey) => {
16+
switch (toggleKey) {
17+
case 'foo':
18+
return {variationKey: 'b'}
19+
case 'bax':
20+
return {variationKey: 'c'}
21+
default:
22+
return {variationKey: undefined}
23+
}
24+
})
1925
export const optimizelyUserContextMock = jest.fn(() => ({
2026
decide: decideMock
2127
}))
2228

2329
export const isFeatureEnabledMock = jest.fn((toggleId) => toggleId === 'foo')
2430

25-
export const activateMock = jest.fn((toggleId, userId) => {
26-
const shouldReturnB =
27-
(toggleId === 'foo' && userId === 'fooBSide') ||
28-
(toggleId === 'bar' && userId === 'barBSide')
29-
30-
return shouldReturnB && 'b'
31-
})
32-
3331
const originalModule = jest.requireActual('@optimizely/optimizely-sdk')
3432

3533
const mock = {

Diff for: packages/lib/src/integrations/optimizely.test.ts

+9-28
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,6 @@ import Optimizely, {
2121
// @ts-expect-error
2222
isFeatureEnabledMock,
2323
// @ts-expect-error
24-
activateMock,
25-
// @ts-expect-error
2624
decideMock,
2725
// @ts-expect-error
2826
optimizelyUserContextMock
@@ -44,16 +42,12 @@ const testAudienceSegmentationCacheBusting = (toggleFn, fn) => {
4442

4543
toggleFn('foo', 'a', 'b', 'c') // call 1
4644
expect(fn).toHaveBeenCalledTimes(1)
47-
expect(fn).toHaveBeenCalledWith('foo', 'fooBSide', {
48-
foo: 'baz'
49-
})
45+
expect(fn).toHaveBeenCalledWith('foo')
5046
toggleFn('foo', 'a', 'b', 'c') // cached
5147
toggleFn('bar', 'a', 'b', 'c') // call 2
5248
toggleFn('bar', 'a', 'b', 'c') // cached
5349
expect(fn).toHaveBeenCalledTimes(2)
54-
expect(fn).toHaveBeenCalledWith('bar', 'fooBSide', {
55-
foo: 'baz'
56-
})
50+
expect(fn).toHaveBeenCalledWith('bar')
5751
})
5852
}
5953

@@ -82,7 +76,7 @@ describe('Optimizely Integration', () => {
8276
expect(addNotificationListenerMock).toHaveBeenCalledWith(
8377
NOTIFICATION_TYPES.DECISION,
8478
// 'DECISION:type, userId, attributes, decisionInfo',
85-
activateHandler
79+
expect.any(Function)
8680
)
8781
})
8882
})
@@ -141,14 +135,9 @@ describe('Optimizely Integration', () => {
141135

142136
it('Forwards toggle reading and audienceSegmentationAttributes to Optimizely', () => {
143137
toggle('foo', 'a', 'b', 'c')
144-
expect(activateMock).toHaveBeenCalledWith('foo', 'fooBSide', {})
145138
toggle('foo')
146-
expect(decideMock).toHaveBeenCalledWith(
147-
'foo'
148-
)
149-
expect(optimizelyUserContextMock).toHaveBeenCalledWith(
150-
'fooBSide', {}
151-
)
139+
expect(decideMock).toHaveBeenCalledWith('foo')
140+
expect(optimizelyUserContextMock).toHaveBeenCalledWith('fooBSide', {})
152141
})
153142
})
154143

@@ -166,15 +155,6 @@ describe('Optimizely Integration', () => {
166155

167156
it('Forwards toggle reading and audienceSegmentationAttributes to Optimizely', () => {
168157
toggle('foo', 'a', 'b', 'c')
169-
expect(activateMock).toHaveBeenCalledWith('foo', 'fooBSide', {
170-
thisWillNotBeOverwritten: 'foo',
171-
deviceType: 'mobile',
172-
isLoggedIn: false
173-
})
174-
})
175-
176-
it('Forwards toggle reading and audienceSegmentationAttributes to Optimizely', () => {
177-
toggle('foo')
178158
expect(optimizelyUserContextMock).toHaveBeenCalledWith('fooBSide', {
179159
thisWillNotBeOverwritten: 'foo',
180160
deviceType: 'mobile',
@@ -192,7 +172,8 @@ describe('Optimizely Integration', () => {
192172

193173
it('Forwards correct audience segmentation attributes', () => {
194174
toggle('foo', 'a', 'b', 'c')
195-
expect(activateMock).toHaveBeenCalledWith('foo', 'fooBSide', {
175+
176+
expect(optimizelyUserContextMock).toHaveBeenCalledWith('fooBSide', {
196177
valueAfterReset: true
197178
})
198179

@@ -208,7 +189,7 @@ describe('Optimizely Integration', () => {
208189
})
209190
})
210191

211-
testAudienceSegmentationCacheBusting(toggle, activateMock)
192+
testAudienceSegmentationCacheBusting(toggle, decideMock)
212193

213194
it("Returns Optimizely's value when no arguments supplied", () => {
214195
// maps to a, b, c
@@ -252,7 +233,7 @@ describe('Optimizely Integration', () => {
252233
})
253234

254235
it('makes sure Toggles return defaults if forced values are of wrong type', () => {
255-
expect(toggle('baz', 'a', 'b', 'c')).toEqual('a')
236+
expect(toggle('boz', 'a', 'b', 'c')).toEqual('a')
256237
})
257238

258239
describe('Clearing forced toggles', () => {

Diff for: packages/lib/src/integrations/optimizely.ts

+28-7
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ type AudienceSegmentationAttributesType = {
1616
[key in AudienceSegmentationAttributeKeyType]?: AudienceSegmentationAttributeValueType
1717
}
1818

19-
type ExperimentToggleValueType = boolean | string
19+
type ExperimentToggleValueType = string | boolean
2020
type ToggleValueType = ExperimentToggleValueType
2121

2222
export type OptimizelyDatafileType = object
@@ -53,7 +53,9 @@ export const registerLibrary = (lib) => {
5353
optimizely = lib
5454
}
5555

56-
const clearExperimentCache = () => (experimentCache = {})
56+
const clearExperimentCache = () => {
57+
experimentCache = {}
58+
}
5759

5860
/**
5961
* Adds / removes Toggles to force from the forcedToggles list
@@ -66,6 +68,15 @@ export const forceToggles = (toggleKeyValues: {
6668
Object.keys(toggleKeyValues).forEach((toggleId) => {
6769
const value = toggleKeyValues[toggleId]
6870

71+
/**
72+
* Keeping the old behaviour of using boolean values for toggles to represent `a` and `b` versions
73+
*/
74+
const isBoolean = typeof value === 'boolean'
75+
if (isBoolean) {
76+
forcedToggles[toggleId] = value ? 'b' : 'a'
77+
return
78+
}
79+
6980
if (value === null) {
7081
delete forcedToggles[toggleId]
7182
} else {
@@ -85,7 +96,7 @@ const invalidateCaches = () => {
8596
* @param id
8697
*/
8798
export const setUserId = (id: UserIdType) => {
88-
invalidateCaches()
99+
if (userId !== id) invalidateCaches()
89100
userId = id
90101
}
91102

@@ -98,11 +109,20 @@ export const setUserId = (id: UserIdType) => {
98109
export const setAudienceSegmentationAttributes = (
99110
attributes: AudienceSegmentationAttributesType = {}
100111
) => {
101-
invalidateCaches()
102-
audienceSegmentationAttributes = {
112+
const newSegmentationAttributes = {
103113
...audienceSegmentationAttributes,
104114
...attributes
105115
}
116+
117+
const shouldInvalidateCache =
118+
JSON.stringify(newSegmentationAttributes) !==
119+
JSON.stringify(audienceSegmentationAttributes || {})
120+
121+
if (shouldInvalidateCache) {
122+
invalidateCaches()
123+
}
124+
125+
audienceSegmentationAttributes = newSegmentationAttributes
106126
}
107127

108128
/**
@@ -132,7 +152,7 @@ export enum ExperimentType {
132152
* It would be best if Opticks abstracts this difference from the client in future versions.
133153
*/
134154
interface ActivateNotificationPayload extends ListenerPayload {
135-
type: ExperimentType.mvt
155+
type: ExperimentType
136156
decisionInfo: {
137157
experimentKey: ToggleIdType
138158
variationKey: VariantType
@@ -316,7 +336,8 @@ const getToggle = (toggleId: ToggleIdType): ExperimentToggleValueType => {
316336

317337
// Assuming the variation keys follow a, b, c, etc. convention
318338
// TODO: Enforce ^ ?
319-
return (experimentCache[toggleId] = decision || DEFAULT)
339+
experimentCache[toggleId] = decision || DEFAULT
340+
return decision || DEFAULT
320341
}
321342

322343
/**

0 commit comments

Comments
 (0)