Skip to content
This repository was archived by the owner on Jun 21, 2023. It is now read-only.

Commit 04ad62f

Browse files
committed
Add testing to react-sdk
1 parent e9bb245 commit 04ad62f

File tree

11 files changed

+4014
-161
lines changed

11 files changed

+4014
-161
lines changed
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
module.exports = {
2+
"roots": [
3+
"./src"
4+
],
5+
"transform": {
6+
"^.+\\.tsx?$": "ts-jest"
7+
},
8+
"testRegex": "(/__tests__/.*|(\\.|/)(test|spec))\\.tsx?$",
9+
"moduleFileExtensions": [
10+
"ts",
11+
"tsx",
12+
"js",
13+
"jsx",
14+
"json",
15+
"node"
16+
],
17+
}

packages/js-web-sdk/packages/react-sdk/package.json

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@
1919
"scripts": {
2020
"tsc": "rm -rf lib/ && tsc",
2121
"build": "rm -rf dist/ && node ./scripts/build.js",
22-
"test": "echo \"Error: run tests from root\" && exit 1"
23-
},
22+
"test": "jest"
23+
},
2424
"dependencies": {
2525
"prop-types": "^15.6.2",
2626
"react-broadcast": "^0.7.1"
@@ -30,15 +30,24 @@
3030
},
3131
"devDependencies": {
3232
"@optimizely/js-web-sdk": "^0.1.0",
33+
"@types/enzyme": "^3.1.15",
34+
"@types/enzyme-adapter-react-16": "^1.0.3",
35+
"@types/jest": "^23.3.12",
3336
"@types/prop-types": "^15.5.6",
3437
"@types/react": "^16.7.18",
3538
"@types/react-broadcast": "^0.6.1",
39+
"enzyme": "^3.8.0",
40+
"enzyme-adapter-react-16": "^1.7.1",
41+
"jest": "^23.6.0",
42+
"react": "^16.7.0",
43+
"react-dom": "^16.7.0",
3644
"rollup": "^1.1.0",
3745
"rollup-plugin-commonjs": "^9.2.0",
3846
"rollup-plugin-node-resolve": "^4.0.0",
3947
"rollup-plugin-replace": "^2.1.0",
4048
"rollup-plugin-typescript2": "^0.18.1",
4149
"rollup-plugin-uglify": "^6.0.1",
50+
"ts-jest": "^23.10.5",
4251
"tslib": "^1.9.3",
4352
"utility-types": "^2.1.0"
4453
}

packages/js-web-sdk/packages/react-sdk/rollup.config.js

Lines changed: 0 additions & 84 deletions
This file was deleted.
Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
import * as React from 'react'
2+
import * as Enzyme from 'enzyme'
3+
import * as Adapter from 'enzyme-adapter-react-16'
4+
Enzyme.configure({ adapter: new Adapter() })
5+
6+
import { Experiment, OptimizelyExperiment } from './Experiment'
7+
8+
import { mount } from 'enzyme'
9+
import { OptimizelyProvider } from './Provider'
10+
import { OptimizelySDKWrapper } from '@optimizely/js-web-sdk'
11+
import { OptimizelyVariation } from './Variation';
12+
13+
async function sleep(timeout = 0): Promise<{}> {
14+
return new Promise(resolve => {
15+
setTimeout(() => {
16+
resolve()
17+
}, timeout)
18+
})
19+
}
20+
21+
describe('<OptimizelyExperiment>', () => {
22+
it('throws an error when not rendered in the context of an OptimizelyProvider', () => {
23+
expect(() => {
24+
// @ts-ignore
25+
mount(
26+
<OptimizelyExperiment experiment="experiment1">
27+
{variation => variation}
28+
</OptimizelyExperiment>,
29+
)
30+
}).toThrow()
31+
})
32+
33+
it('should wait until onReady() is resolved then render result of activate', async () => {
34+
let resolver: any
35+
const variationKey = 'variationResult'
36+
const onReadyPromise = new Promise((resolve, reject) => {
37+
resolver = {
38+
reject,
39+
resolve,
40+
}
41+
})
42+
43+
const optimizelyMock = ({
44+
onReady: jest.fn().mockImplementation(config => onReadyPromise),
45+
activate: jest.fn().mockImplementation(experimentKey => variationKey),
46+
} as unknown) as OptimizelySDKWrapper
47+
48+
const component = mount(
49+
<OptimizelyProvider optimizely={optimizelyMock} timeout={100}>
50+
<OptimizelyExperiment experiment="experiment1">
51+
{variation => variation}
52+
</OptimizelyExperiment>
53+
</OptimizelyProvider>,
54+
)
55+
56+
expect(optimizelyMock.onReady).toHaveBeenCalledWith({ timeout: 100 })
57+
// while it's waiting for onReady()
58+
expect(component.text()).toBe(null)
59+
resolver.resolve()
60+
61+
await sleep()
62+
63+
expect(optimizelyMock.activate).toHaveBeenCalledWith('experiment1')
64+
expect(component.text()).toBe(variationKey)
65+
})
66+
67+
it('should render using <OptimizelyVariation> when the variationKey matches', async () => {
68+
let resolver: any
69+
const variationKey = 'variationResult'
70+
const onReadyPromise = new Promise((resolve, reject) => {
71+
resolver = {
72+
reject,
73+
resolve,
74+
}
75+
})
76+
77+
const optimizelyMock = ({
78+
onReady: jest.fn().mockImplementation(config => onReadyPromise),
79+
activate: jest.fn().mockImplementation(experimentKey => variationKey),
80+
} as unknown) as OptimizelySDKWrapper
81+
82+
const component = mount(
83+
<OptimizelyProvider optimizely={optimizelyMock}>
84+
<OptimizelyExperiment experiment="experiment1">
85+
<OptimizelyVariation variation="otherVariation">
86+
other variation
87+
</OptimizelyVariation>
88+
<OptimizelyVariation variation="variationResult">
89+
correct variation
90+
</OptimizelyVariation>
91+
<OptimizelyVariation default>
92+
default variation
93+
</OptimizelyVariation>
94+
</OptimizelyExperiment>
95+
</OptimizelyProvider>,
96+
)
97+
98+
// while it's waiting for onReady()
99+
expect(component.text()).toBe(null)
100+
resolver.resolve()
101+
102+
await sleep()
103+
104+
expect(component.text()).toBe('correct variation')
105+
})
106+
107+
it('should render using <OptimizelyVariation default>', async () => {
108+
let resolver: any
109+
const variationKey = 'variationResult'
110+
const onReadyPromise = new Promise((resolve, reject) => {
111+
resolver = {
112+
reject,
113+
resolve,
114+
}
115+
})
116+
117+
const optimizelyMock = ({
118+
onReady: jest.fn().mockImplementation(config => onReadyPromise),
119+
activate: jest.fn().mockImplementation(experimentKey => variationKey),
120+
} as unknown) as OptimizelySDKWrapper
121+
122+
const component = mount(
123+
<OptimizelyProvider optimizely={optimizelyMock}>
124+
<OptimizelyExperiment experiment="experiment1">
125+
<OptimizelyVariation variation="otherVariation">
126+
other variation
127+
</OptimizelyVariation>
128+
<OptimizelyVariation default>
129+
default variation
130+
</OptimizelyVariation>
131+
</OptimizelyExperiment>
132+
</OptimizelyProvider>,
133+
)
134+
135+
// while it's waiting for onReady()
136+
expect(component.text()).toBe(null)
137+
resolver.resolve()
138+
139+
await sleep()
140+
141+
expect(component.text()).toBe('default variation')
142+
})
143+
144+
it('should render null when no default or matching variation is provided', async () => {
145+
let resolver: any
146+
const variationKey = 'variationResult'
147+
const onReadyPromise = new Promise((resolve, reject) => {
148+
resolver = {
149+
reject,
150+
resolve,
151+
}
152+
})
153+
154+
const optimizelyMock = ({
155+
onReady: jest.fn().mockImplementation(config => onReadyPromise),
156+
activate: jest.fn().mockImplementation(experimentKey => variationKey),
157+
} as unknown) as OptimizelySDKWrapper
158+
159+
const component = mount(
160+
<OptimizelyProvider optimizely={optimizelyMock}>
161+
<OptimizelyExperiment experiment="experiment1">
162+
<OptimizelyVariation variation="otherVariation">
163+
other variation
164+
</OptimizelyVariation>
165+
<OptimizelyVariation variation="otherVariation2">
166+
other variation 2
167+
</OptimizelyVariation>
168+
</OptimizelyExperiment>
169+
</OptimizelyProvider>,
170+
)
171+
172+
// while it's waiting for onReady()
173+
expect(component.text()).toBe(null)
174+
resolver.resolve()
175+
176+
await sleep()
177+
178+
expect(component.text()).toBe(null)
179+
})
180+
})

packages/js-web-sdk/packages/react-sdk/src/Experiment.tsx

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ export class Experiment extends React.Component<ExperimentProps, ExperimentState
3030

3131
componentDidMount() {
3232
const { experiment, optimizely, optimizelyReadyTimeout } = this.props
33-
if (optimizely === null) {
33+
if (!optimizely) {
3434
throw new Error('optimizely prop must be supplied')
3535
}
3636

@@ -65,18 +65,14 @@ export class Experiment extends React.Component<ExperimentProps, ExperimentState
6565
this.props.children,
6666
(child: React.ReactElement<VariationProps>) => {
6767
if (match || !React.isValidElement(child)) {
68-
console.log('found', match, !React.isValidElement(child))
6968
return
7069
}
7170

72-
console.log('child props', child.props)
7371
if (child.props.variation) {
74-
console.log('child variation', child.props.variation)
7572
if (variation === child.props.variation) {
7673
match = child
7774
}
7875
} else if (child.props.default) {
79-
console.log('child default', child.props.default)
8076
match = child
8177
}
8278
},

0 commit comments

Comments
 (0)