-
Notifications
You must be signed in to change notification settings - Fork 183
/
analytics.spec.ts
126 lines (96 loc) · 3.37 KB
/
analytics.spec.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
import mockConsole, { RestoreConsole } from 'jest-mock-console'
import { Analytics } from '../analytics'
import Bridge from '../bridge'
jest.mock('../bridge')
const nextTick = () => new Promise(resolve => setImmediate(resolve))
const getBridgeStub = <K extends keyof typeof Bridge>(
name: K
): jest.Mock<(typeof Bridge)[K]> => (Bridge as any)[name]
let analytics: Analytics.Client = null!
let restoreConsole: RestoreConsole = null!
const ctx = {
library: {
name: 'analytics-react-native',
version: require('../../package.json').version
}
}
beforeEach(async () => {
restoreConsole = mockConsole()
analytics = new Analytics.Client()
Object.keys(Bridge).forEach(key => getBridgeStub(key as any).mockClear())
await analytics.setup('write key')
})
afterEach(() => {
restoreConsole()
})
it('is ready', () => expect(analytics.ready).toBe(true))
it('catches bridge errors', async () => {
const error = new Error('test-error')
const onError = jest.fn()
getBridgeStub('track').mockImplementationOnce(
() => Promise.reject(error) as any
)
analytics.catch(onError)
analytics.track('test')
expect(onError).not.toHaveBeenCalled()
await new Promise(resolve => setImmediate(resolve))
expect(onError).toHaveBeenCalledWith(error)
})
it('waits for .setup()', async () => {
const client = new Analytics.Client()
client.track('test 1')
client.track('test 2')
expect(Bridge.track).not.toHaveBeenCalled()
await client.setup('key')
expect(Bridge.track).toHaveBeenNthCalledWith(1, 'test 1', {}, {}, ctx)
expect(Bridge.track).toHaveBeenNthCalledWith(2, 'test 2', {}, {}, ctx)
})
it('does .track()', () =>
testCall('track')('Added to cart', { productId: 'azertyuiop' }, {}, ctx))
it('does .screen()', () =>
testCall('screen')('Shopping cart', { from: 'Product page' }, {}, ctx))
it('does .identify()', () =>
testCall('identify')('sloth', { eats: 'leaves' }, {}, ctx))
it('does .group()', () => testCall('group')('bots', { humans: false }, {}, ctx))
it('does .alias()', () => testCall('alias')('new alias', {}, ctx))
it('does .reset()', testCall('reset'))
it('does .flush()', testCall('flush'))
it('does .enable()', testCall('enable'))
it('does .disable()', testCall('disable'))
it('does .getAnonymousId()', testCall('getAnonymousId'))
it('logs uncaught bridge errors', async () => {
const error = {
message: 'test-error'
}
getBridgeStub('track').mockImplementationOnce(
() => Promise.reject(error) as any
)
expect(analytics.track('test')).rejects.toBe(error)
expect(console.error).not.toHaveBeenCalled()
await nextTick()
expect(console.error).toHaveBeenCalledWith('Uncaught Analytics error', error)
})
function testCall<K extends keyof typeof Bridge>(name: K) {
return (async (...args: any[]) => {
analytics.constructor.prototype[name].call(analytics, ...args)
await nextTick()
expect(Bridge[name]).toHaveBeenNthCalledWith(1, ...args)
}) as (typeof Bridge)[K]
}
it('enables setting integrations from the middleware', async () => {
const integrations = {
'Google Analytics': false,
Mixpanel: { foo: 'bar' }
}
analytics.middleware(async ({ next, context, data }) =>
// @ts-ignore ts is expecting newId for some reasons
next(context, { ...data, integrations })
)
const trackSpy = jest.fn()
getBridgeStub('track').mockImplementationOnce(trackSpy)
analytics.track('test')
await nextTick()
expect(trackSpy).toBeCalledWith('test', {}, integrations, {
library: ctx.library
})
})