Skip to content

Commit 5e7f8ae

Browse files
authored
[sc-118386] - Adds proper support to MVT experiments (#83)
* Adds proper support to MVT experiments and simplifies the usage of Optimizely's SDK after update to >v4.5 * Fix tests
1 parent fc32e5b commit 5e7f8ae

File tree

5 files changed

+121
-120
lines changed

5 files changed

+121
-120
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', () => {

0 commit comments

Comments
 (0)