@segment/analytics-browser-actions-braze 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +40 -0
- package/src/__tests__/__snapshots__/initialization.test.ts.snap +24 -0
- package/src/__tests__/__snapshots__/integration.test.ts.snap +96 -0
- package/src/__tests__/__snapshots__/trackPurchase.test.ts.snap +97 -0
- package/src/__tests__/debounce.test.ts +133 -0
- package/src/__tests__/initialization.test.ts +139 -0
- package/src/__tests__/integration.test.ts +156 -0
- package/src/__tests__/trackEvent.test.ts +65 -0
- package/src/__tests__/trackPurchase.test.ts +65 -0
- package/src/__tests__/updateUserProfile.test.ts +145 -0
- package/src/braze-types.ts +9 -0
- package/src/debounce/generated-types.ts +3 -0
- package/src/debounce/index.ts +67 -0
- package/src/generated-types.ts +104 -0
- package/src/index.ts +358 -0
- package/src/trackEvent/generated-types.ts +14 -0
- package/src/trackEvent/index.ts +40 -0
- package/src/trackPurchase/generated-types.ts +31 -0
- package/src/trackPurchase/index.ts +83 -0
- package/src/updateUserProfile/generated-types.ts +70 -0
- package/src/updateUserProfile/index.ts +227 -0
- package/tsconfig.json +9 -0
package/package.json
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@segment/analytics-browser-actions-braze",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"license": "MIT",
|
|
5
|
+
"exports": {
|
|
6
|
+
".": {
|
|
7
|
+
"require": "./dist/cjs/index.js",
|
|
8
|
+
"import": "./dist/esm/index.js"
|
|
9
|
+
},
|
|
10
|
+
"./debounce": {
|
|
11
|
+
"require": "./dist/cjs/debounce/index.js",
|
|
12
|
+
"import": "./dist/esm/debounce/index.js"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"scripts": {
|
|
16
|
+
"build": "yarn build:esm && yarn build:cjs",
|
|
17
|
+
"build:cjs": "tsc --module commonjs --outDir ./dist/cjs",
|
|
18
|
+
"build:esm": "tsc --outDir ./dist/esm"
|
|
19
|
+
},
|
|
20
|
+
"typesVersions": {
|
|
21
|
+
"*": {
|
|
22
|
+
"*": [
|
|
23
|
+
"dist/esm/index.d.ts"
|
|
24
|
+
],
|
|
25
|
+
"debounce": [
|
|
26
|
+
"dist/esm/debounce/index.d.ts"
|
|
27
|
+
]
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
"typings": "./dist/esm",
|
|
31
|
+
"dependencies": {
|
|
32
|
+
"@braze/web-sdk": "npm:@braze/web-sdk@^4.1.0",
|
|
33
|
+
"@braze/web-sdk-v3": "npm:@braze/web-sdk@^3.5.1",
|
|
34
|
+
"@segment/actions-core": "^3.71.0",
|
|
35
|
+
"@segment/browser-destination-runtime": "^1.0.0"
|
|
36
|
+
},
|
|
37
|
+
"peerDependencies": {
|
|
38
|
+
"@segment/analytics-next": "*"
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
+
|
|
3
|
+
exports[`initialization can load braze:
|
|
4
|
+
NodeList [
|
|
5
|
+
<script
|
|
6
|
+
src="https://js.appboycdn.com/web-sdk/3.5/appboy.no-amd.min.js"
|
|
7
|
+
type="text/javascript"
|
|
8
|
+
/>,
|
|
9
|
+
<script>
|
|
10
|
+
// the emptiness
|
|
11
|
+
</script>,
|
|
12
|
+
]
|
|
13
|
+
1`] = `
|
|
14
|
+
NodeList [
|
|
15
|
+
<script
|
|
16
|
+
src="https://js.appboycdn.com/web-sdk/3.5/appboy.no-amd.min.js"
|
|
17
|
+
status="loaded"
|
|
18
|
+
type="text/javascript"
|
|
19
|
+
/>,
|
|
20
|
+
<script>
|
|
21
|
+
// the emptiness
|
|
22
|
+
</script>,
|
|
23
|
+
]
|
|
24
|
+
`;
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
+
|
|
3
|
+
exports[`loads different versions from CDN 3.0:
|
|
4
|
+
NodeList [
|
|
5
|
+
<script
|
|
6
|
+
src="https://js.appboycdn.com/web-sdk/3.0/appboy.no-amd.min.js"
|
|
7
|
+
type="text/javascript"
|
|
8
|
+
/>,
|
|
9
|
+
<script>
|
|
10
|
+
// the emptiness
|
|
11
|
+
</script>,
|
|
12
|
+
]
|
|
13
|
+
1`] = `
|
|
14
|
+
NodeList [
|
|
15
|
+
<script
|
|
16
|
+
src="https://js.appboycdn.com/web-sdk/3.0/appboy.no-amd.min.js"
|
|
17
|
+
status="loaded"
|
|
18
|
+
type="text/javascript"
|
|
19
|
+
/>,
|
|
20
|
+
<script>
|
|
21
|
+
// the emptiness
|
|
22
|
+
</script>,
|
|
23
|
+
]
|
|
24
|
+
`;
|
|
25
|
+
|
|
26
|
+
exports[`loads different versions from CDN 3.1:
|
|
27
|
+
NodeList [
|
|
28
|
+
<script
|
|
29
|
+
src="https://js.appboycdn.com/web-sdk/3.1/appboy.no-amd.min.js"
|
|
30
|
+
status="loaded"
|
|
31
|
+
type="text/javascript"
|
|
32
|
+
/>,
|
|
33
|
+
<script>
|
|
34
|
+
// the emptiness
|
|
35
|
+
</script>,
|
|
36
|
+
]
|
|
37
|
+
1`] = `
|
|
38
|
+
NodeList [
|
|
39
|
+
<script
|
|
40
|
+
src="https://js.appboycdn.com/web-sdk/3.1/appboy.no-amd.min.js"
|
|
41
|
+
status="loaded"
|
|
42
|
+
type="text/javascript"
|
|
43
|
+
/>,
|
|
44
|
+
<script>
|
|
45
|
+
// the emptiness
|
|
46
|
+
</script>,
|
|
47
|
+
]
|
|
48
|
+
`;
|
|
49
|
+
|
|
50
|
+
exports[`loads different versions from CDN 3.5:
|
|
51
|
+
NodeList [
|
|
52
|
+
<script
|
|
53
|
+
src="https://js.appboycdn.com/web-sdk/3.5/appboy.no-amd.min.js"
|
|
54
|
+
status="loaded"
|
|
55
|
+
type="text/javascript"
|
|
56
|
+
/>,
|
|
57
|
+
<script>
|
|
58
|
+
// the emptiness
|
|
59
|
+
</script>,
|
|
60
|
+
]
|
|
61
|
+
1`] = `
|
|
62
|
+
NodeList [
|
|
63
|
+
<script
|
|
64
|
+
src="https://js.appboycdn.com/web-sdk/3.5/appboy.no-amd.min.js"
|
|
65
|
+
status="loaded"
|
|
66
|
+
type="text/javascript"
|
|
67
|
+
/>,
|
|
68
|
+
<script>
|
|
69
|
+
// the emptiness
|
|
70
|
+
</script>,
|
|
71
|
+
]
|
|
72
|
+
`;
|
|
73
|
+
|
|
74
|
+
exports[`loads different versions from CDN undefined version:
|
|
75
|
+
NodeList [
|
|
76
|
+
<script
|
|
77
|
+
src="https://js.appboycdn.com/web-sdk/4.6/braze.no-module.min.js"
|
|
78
|
+
status="loaded"
|
|
79
|
+
type="text/javascript"
|
|
80
|
+
/>,
|
|
81
|
+
<script>
|
|
82
|
+
// the emptiness
|
|
83
|
+
</script>,
|
|
84
|
+
]
|
|
85
|
+
1`] = `
|
|
86
|
+
NodeList [
|
|
87
|
+
<script
|
|
88
|
+
src="https://js.appboycdn.com/web-sdk/4.6/braze.no-module.min.js"
|
|
89
|
+
status="loaded"
|
|
90
|
+
type="text/javascript"
|
|
91
|
+
/>,
|
|
92
|
+
<script>
|
|
93
|
+
// the emptiness
|
|
94
|
+
</script>,
|
|
95
|
+
]
|
|
96
|
+
`;
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
+
|
|
3
|
+
exports[`reports products when present (v3.5) 1`] = `
|
|
4
|
+
Array [
|
|
5
|
+
"p_123",
|
|
6
|
+
399,
|
|
7
|
+
"BGP",
|
|
8
|
+
2,
|
|
9
|
+
Object {
|
|
10
|
+
"banana": "yellow",
|
|
11
|
+
"products": Array [
|
|
12
|
+
Object {
|
|
13
|
+
"currency": "BGP",
|
|
14
|
+
"price": 399,
|
|
15
|
+
"product_id": "p_123",
|
|
16
|
+
"quantity": 2,
|
|
17
|
+
},
|
|
18
|
+
Object {
|
|
19
|
+
"price": 0,
|
|
20
|
+
"product_id": "p_456",
|
|
21
|
+
},
|
|
22
|
+
],
|
|
23
|
+
},
|
|
24
|
+
]
|
|
25
|
+
`;
|
|
26
|
+
|
|
27
|
+
exports[`reports products when present (v3.5) 2`] = `
|
|
28
|
+
Array [
|
|
29
|
+
"p_456",
|
|
30
|
+
0,
|
|
31
|
+
"USD",
|
|
32
|
+
1,
|
|
33
|
+
Object {
|
|
34
|
+
"banana": "yellow",
|
|
35
|
+
"products": Array [
|
|
36
|
+
Object {
|
|
37
|
+
"currency": "BGP",
|
|
38
|
+
"price": 399,
|
|
39
|
+
"product_id": "p_123",
|
|
40
|
+
"quantity": 2,
|
|
41
|
+
},
|
|
42
|
+
Object {
|
|
43
|
+
"price": 0,
|
|
44
|
+
"product_id": "p_456",
|
|
45
|
+
},
|
|
46
|
+
],
|
|
47
|
+
},
|
|
48
|
+
]
|
|
49
|
+
`;
|
|
50
|
+
|
|
51
|
+
exports[`reports products when present (v4.1) 1`] = `
|
|
52
|
+
Array [
|
|
53
|
+
"p_123",
|
|
54
|
+
399,
|
|
55
|
+
"BGP",
|
|
56
|
+
2,
|
|
57
|
+
Object {
|
|
58
|
+
"banana": "yellow",
|
|
59
|
+
"products": Array [
|
|
60
|
+
Object {
|
|
61
|
+
"currency": "BGP",
|
|
62
|
+
"price": 399,
|
|
63
|
+
"product_id": "p_123",
|
|
64
|
+
"quantity": 2,
|
|
65
|
+
},
|
|
66
|
+
Object {
|
|
67
|
+
"price": 0,
|
|
68
|
+
"product_id": "p_456",
|
|
69
|
+
},
|
|
70
|
+
],
|
|
71
|
+
},
|
|
72
|
+
]
|
|
73
|
+
`;
|
|
74
|
+
|
|
75
|
+
exports[`reports products when present (v4.1) 2`] = `
|
|
76
|
+
Array [
|
|
77
|
+
"p_456",
|
|
78
|
+
0,
|
|
79
|
+
"USD",
|
|
80
|
+
1,
|
|
81
|
+
Object {
|
|
82
|
+
"banana": "yellow",
|
|
83
|
+
"products": Array [
|
|
84
|
+
Object {
|
|
85
|
+
"currency": "BGP",
|
|
86
|
+
"price": 399,
|
|
87
|
+
"product_id": "p_123",
|
|
88
|
+
"quantity": 2,
|
|
89
|
+
},
|
|
90
|
+
Object {
|
|
91
|
+
"price": 0,
|
|
92
|
+
"product_id": "p_456",
|
|
93
|
+
},
|
|
94
|
+
],
|
|
95
|
+
},
|
|
96
|
+
]
|
|
97
|
+
`;
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { Analytics, Context } from '@segment/analytics-next'
|
|
2
|
+
import brazeDestination from '../index'
|
|
3
|
+
|
|
4
|
+
let ajs: Analytics
|
|
5
|
+
|
|
6
|
+
describe('debounce', () => {
|
|
7
|
+
beforeEach(async () => {
|
|
8
|
+
ajs = new Analytics({
|
|
9
|
+
writeKey: 'w_123'
|
|
10
|
+
})
|
|
11
|
+
})
|
|
12
|
+
|
|
13
|
+
test('changes the integration object', async () => {
|
|
14
|
+
const [debounce] = await brazeDestination({
|
|
15
|
+
api_key: 'b_123',
|
|
16
|
+
endpoint: 'endpoint',
|
|
17
|
+
doNotLoadFontAwesome: true,
|
|
18
|
+
sdkVersion: '3.5',
|
|
19
|
+
subscriptions: [
|
|
20
|
+
{
|
|
21
|
+
partnerAction: 'debounce',
|
|
22
|
+
name: 'Debounce',
|
|
23
|
+
enabled: true,
|
|
24
|
+
subscribe: 'type = "identify"',
|
|
25
|
+
mapping: {}
|
|
26
|
+
}
|
|
27
|
+
]
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
await debounce.load(Context.system(), ajs)
|
|
31
|
+
const ctx = await debounce.identify?.(
|
|
32
|
+
new Context({
|
|
33
|
+
type: 'identify',
|
|
34
|
+
userId: 'hasbulla',
|
|
35
|
+
anonymousId: 'the goat',
|
|
36
|
+
traits: {}
|
|
37
|
+
})
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
expect(ctx.event.integrations['Braze Web Mode (Actions)']).toBe(true)
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
test('does not send the event to braze if IDs are the same', async () => {
|
|
44
|
+
const [debounce] = await brazeDestination({
|
|
45
|
+
api_key: 'b_123',
|
|
46
|
+
endpoint: 'endpoint',
|
|
47
|
+
doNotLoadFontAwesome: true,
|
|
48
|
+
sdkVersion: '3.5',
|
|
49
|
+
subscriptions: [
|
|
50
|
+
{
|
|
51
|
+
partnerAction: 'debounce',
|
|
52
|
+
name: 'Debounce',
|
|
53
|
+
enabled: true,
|
|
54
|
+
subscribe: 'type = "identify"',
|
|
55
|
+
mapping: {}
|
|
56
|
+
}
|
|
57
|
+
]
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
await ajs.register(debounce)
|
|
61
|
+
|
|
62
|
+
const ctx = await ajs.identify('hasbulla', {
|
|
63
|
+
goat: true
|
|
64
|
+
})
|
|
65
|
+
expect(ctx.event.integrations['Braze Web Mode (Actions)']).toBe(true)
|
|
66
|
+
|
|
67
|
+
const secondCtx = await ajs.identify('hasbulla', {
|
|
68
|
+
goat: true
|
|
69
|
+
})
|
|
70
|
+
expect(secondCtx.event.integrations['Braze Web Mode (Actions)']).toBe(false)
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
test('ignores blank anonymous ids', async () => {
|
|
74
|
+
const [debounce] = await brazeDestination({
|
|
75
|
+
api_key: 'b_123',
|
|
76
|
+
endpoint: 'endpoint',
|
|
77
|
+
doNotLoadFontAwesome: true,
|
|
78
|
+
sdkVersion: '4.1',
|
|
79
|
+
subscriptions: [
|
|
80
|
+
{
|
|
81
|
+
partnerAction: 'debounce',
|
|
82
|
+
name: 'Debounce',
|
|
83
|
+
enabled: true,
|
|
84
|
+
subscribe: 'type = "identify"',
|
|
85
|
+
mapping: {}
|
|
86
|
+
}
|
|
87
|
+
]
|
|
88
|
+
})
|
|
89
|
+
|
|
90
|
+
await ajs.register(debounce)
|
|
91
|
+
|
|
92
|
+
const ctx = await ajs.identify()
|
|
93
|
+
expect(ctx.event.integrations['Braze Web Mode (Actions)']).toBe(true)
|
|
94
|
+
|
|
95
|
+
const secondCtx = await ajs.identify()
|
|
96
|
+
expect(secondCtx.event.integrations['Braze Web Mode (Actions)']).toBe(false)
|
|
97
|
+
})
|
|
98
|
+
|
|
99
|
+
test('send events on trait changes', async () => {
|
|
100
|
+
const [debounce] = await brazeDestination({
|
|
101
|
+
api_key: 'b_123',
|
|
102
|
+
endpoint: 'endpoint',
|
|
103
|
+
doNotLoadFontAwesome: true,
|
|
104
|
+
sdkVersion: '4.1',
|
|
105
|
+
subscriptions: [
|
|
106
|
+
{
|
|
107
|
+
partnerAction: 'debounce',
|
|
108
|
+
name: 'Debounce',
|
|
109
|
+
enabled: true,
|
|
110
|
+
subscribe: 'type = "identify"',
|
|
111
|
+
mapping: {}
|
|
112
|
+
}
|
|
113
|
+
]
|
|
114
|
+
})
|
|
115
|
+
|
|
116
|
+
await ajs.register(debounce)
|
|
117
|
+
|
|
118
|
+
const ctx = await ajs.identify('hasbulla', {
|
|
119
|
+
goat: true
|
|
120
|
+
})
|
|
121
|
+
expect(ctx.event.integrations['Braze Web Mode (Actions)']).toBe(true)
|
|
122
|
+
|
|
123
|
+
const sameCtx = await ajs.identify('hasbulla', {
|
|
124
|
+
goat: true
|
|
125
|
+
})
|
|
126
|
+
expect(sameCtx.event.integrations['Braze Web Mode (Actions)']).toBe(false)
|
|
127
|
+
|
|
128
|
+
const changedTraits = await ajs.identify('hasbulla', {
|
|
129
|
+
weight: 'feather'
|
|
130
|
+
})
|
|
131
|
+
expect(changedTraits.event.integrations['Braze Web Mode (Actions)']).toBe(true)
|
|
132
|
+
})
|
|
133
|
+
})
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { Analytics, Context } from '@segment/analytics-next'
|
|
2
|
+
import { Subscription } from '@segment/browser-destination-runtime'
|
|
3
|
+
import brazeDestination, { destination } from '../index'
|
|
4
|
+
|
|
5
|
+
describe('initialization', () => {
|
|
6
|
+
const settings = {
|
|
7
|
+
safariWebsitePushId: 'safari',
|
|
8
|
+
allowCrawlerActivity: true,
|
|
9
|
+
doNotLoadFontAwesome: true,
|
|
10
|
+
enableLogging: false,
|
|
11
|
+
localization: 'pt',
|
|
12
|
+
minimumIntervalBetweenTriggerActionsInSeconds: 60,
|
|
13
|
+
openInAppMessagesInNewTab: true,
|
|
14
|
+
sessionTimeoutInSeconds: 60,
|
|
15
|
+
requireExplicitInAppMessageDismissal: true,
|
|
16
|
+
allowUserSuppliedJavascript: true,
|
|
17
|
+
contentSecurityNonce: 'bar',
|
|
18
|
+
endpoint: 'endpoint',
|
|
19
|
+
sdkVersion: '3.5'
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
beforeEach(async () => {
|
|
23
|
+
jest.restoreAllMocks()
|
|
24
|
+
jest.resetAllMocks()
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
test('can load braze', async () => {
|
|
28
|
+
const [event] = await brazeDestination({
|
|
29
|
+
api_key: 'b_123',
|
|
30
|
+
subscriptions: [
|
|
31
|
+
{
|
|
32
|
+
partnerAction: 'trackPurchase',
|
|
33
|
+
name: 'Log Custom Event',
|
|
34
|
+
enabled: true,
|
|
35
|
+
subscribe: 'type = "track"',
|
|
36
|
+
mapping: {
|
|
37
|
+
eventName: {
|
|
38
|
+
'@path': '$.event'
|
|
39
|
+
},
|
|
40
|
+
eventProperties: {
|
|
41
|
+
'@path': '$.properties'
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
],
|
|
46
|
+
...settings
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
jest.spyOn(destination.actions.trackPurchase, 'perform')
|
|
50
|
+
jest.spyOn(destination, 'initialize')
|
|
51
|
+
|
|
52
|
+
await event.load(Context.system(), {} as Analytics)
|
|
53
|
+
expect(destination.initialize).toHaveBeenCalled()
|
|
54
|
+
|
|
55
|
+
const ctx = await event.track?.(
|
|
56
|
+
new Context({
|
|
57
|
+
type: 'track',
|
|
58
|
+
properties: {
|
|
59
|
+
banana: '📞'
|
|
60
|
+
}
|
|
61
|
+
})
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
expect(destination.actions.trackPurchase.perform).toHaveBeenCalled()
|
|
65
|
+
expect(ctx).not.toBeUndefined()
|
|
66
|
+
|
|
67
|
+
const scripts = window.document.querySelectorAll('script')
|
|
68
|
+
|
|
69
|
+
expect(scripts).toMatchSnapshot(`
|
|
70
|
+
NodeList [
|
|
71
|
+
<script
|
|
72
|
+
src="https://js.appboycdn.com/web-sdk/3.5/appboy.no-amd.min.js"
|
|
73
|
+
type="text/javascript"
|
|
74
|
+
/>,
|
|
75
|
+
<script>
|
|
76
|
+
// the emptiness
|
|
77
|
+
</script>,
|
|
78
|
+
]
|
|
79
|
+
`)
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
test('can defer braze initialization when deferUntilIdentified is on', async () => {
|
|
83
|
+
const [updateUserProfile, trackEvent] = await brazeDestination({
|
|
84
|
+
api_key: 'b_123',
|
|
85
|
+
deferUntilIdentified: true,
|
|
86
|
+
subscriptions: destination.presets?.map((sub) => ({ ...sub, enabled: true })) as Subscription[],
|
|
87
|
+
...settings
|
|
88
|
+
})
|
|
89
|
+
|
|
90
|
+
jest.spyOn(destination.actions.trackEvent, 'perform')
|
|
91
|
+
const initializeSpy = jest.spyOn(destination, 'initialize')
|
|
92
|
+
|
|
93
|
+
const analytics = new Analytics({ writeKey: '123' })
|
|
94
|
+
|
|
95
|
+
await analytics.register(updateUserProfile, trackEvent)
|
|
96
|
+
|
|
97
|
+
// Spy on the braze APIs now that braze has been loaded.
|
|
98
|
+
const { instance: braze } = await initializeSpy.mock.results[0].value
|
|
99
|
+
const openSessionSpy = jest.spyOn(braze, 'openSession')
|
|
100
|
+
const logCustomEventSpy = jest.spyOn(braze, 'logCustomEvent')
|
|
101
|
+
|
|
102
|
+
await analytics.track?.({
|
|
103
|
+
type: 'track',
|
|
104
|
+
event: 'UFC',
|
|
105
|
+
properties: {
|
|
106
|
+
goat: 'hasbulla'
|
|
107
|
+
}
|
|
108
|
+
})
|
|
109
|
+
|
|
110
|
+
expect(destination.actions.trackEvent.perform).toHaveBeenCalledWith(
|
|
111
|
+
expect.objectContaining({
|
|
112
|
+
instance: expect.objectContaining({
|
|
113
|
+
logCustomEvent: expect.any(Function)
|
|
114
|
+
})
|
|
115
|
+
}),
|
|
116
|
+
|
|
117
|
+
expect.objectContaining({
|
|
118
|
+
payload: { eventName: 'UFC', eventProperties: { goat: 'hasbulla' } }
|
|
119
|
+
})
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
expect(analytics.user().id()).toBe(null)
|
|
123
|
+
expect(openSessionSpy).not.toHaveBeenCalled()
|
|
124
|
+
expect(logCustomEventSpy).not.toHaveBeenCalled()
|
|
125
|
+
|
|
126
|
+
await analytics.identify('27413')
|
|
127
|
+
|
|
128
|
+
await analytics.track?.({
|
|
129
|
+
type: 'track',
|
|
130
|
+
event: 'FIFA',
|
|
131
|
+
properties: {
|
|
132
|
+
goat: 'deno'
|
|
133
|
+
}
|
|
134
|
+
})
|
|
135
|
+
|
|
136
|
+
expect(openSessionSpy).toHaveBeenCalled()
|
|
137
|
+
expect(logCustomEventSpy).toHaveBeenCalledWith('FIFA', { goat: 'deno' })
|
|
138
|
+
})
|
|
139
|
+
})
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import { Analytics, Context } from '@segment/analytics-next'
|
|
2
|
+
import braze, { destination } from '..'
|
|
3
|
+
import type { Subscription } from '@segment/browser-destination-runtime/types'
|
|
4
|
+
|
|
5
|
+
const example: Subscription[] = [
|
|
6
|
+
{
|
|
7
|
+
partnerAction: 'trackEvent',
|
|
8
|
+
name: 'Log Custom Event',
|
|
9
|
+
enabled: true,
|
|
10
|
+
subscribe: 'type = "track"',
|
|
11
|
+
mapping: {
|
|
12
|
+
name: {
|
|
13
|
+
'@path': '$.name'
|
|
14
|
+
},
|
|
15
|
+
properties: {
|
|
16
|
+
'@path': '$.properties'
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
]
|
|
21
|
+
|
|
22
|
+
test('can load braze', async () => {
|
|
23
|
+
const [trackEvent] = await braze({
|
|
24
|
+
api_key: 'api_key',
|
|
25
|
+
endpoint: 'sdk.iad-01.braze.com',
|
|
26
|
+
subscriptions: example,
|
|
27
|
+
doNotLoadFontAwesome: true,
|
|
28
|
+
sdkVersion: '3.5'
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
jest.spyOn(destination.actions.trackEvent, 'perform')
|
|
32
|
+
jest.spyOn(destination, 'initialize')
|
|
33
|
+
|
|
34
|
+
await trackEvent.load(Context.system(), {} as Analytics)
|
|
35
|
+
expect(destination.initialize).toHaveBeenCalled()
|
|
36
|
+
|
|
37
|
+
const ctx = await trackEvent.track?.(
|
|
38
|
+
new Context({
|
|
39
|
+
type: 'track',
|
|
40
|
+
properties: {
|
|
41
|
+
banana: '📞'
|
|
42
|
+
}
|
|
43
|
+
})
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
expect(destination.actions.trackEvent.perform).toHaveBeenCalled()
|
|
47
|
+
expect(ctx).not.toBeUndefined()
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
describe('loads different versions from CDN', () => {
|
|
51
|
+
test('3.0', async () => {
|
|
52
|
+
const [trackEvent] = await braze({
|
|
53
|
+
api_key: 'api_key',
|
|
54
|
+
endpoint: 'sdk.iad-01.braze.com',
|
|
55
|
+
sdkVersion: '3.0',
|
|
56
|
+
doNotLoadFontAwesome: true,
|
|
57
|
+
subscriptions: example
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
await trackEvent.load(Context.system(), {} as Analytics)
|
|
61
|
+
|
|
62
|
+
const scripts = window.document.querySelectorAll('script')
|
|
63
|
+
expect(scripts).toMatchSnapshot(`
|
|
64
|
+
NodeList [
|
|
65
|
+
<script
|
|
66
|
+
src="https://js.appboycdn.com/web-sdk/3.0/appboy.no-amd.min.js"
|
|
67
|
+
type="text/javascript"
|
|
68
|
+
/>,
|
|
69
|
+
<script>
|
|
70
|
+
// the emptiness
|
|
71
|
+
</script>,
|
|
72
|
+
]
|
|
73
|
+
`)
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
test('3.1', async () => {
|
|
77
|
+
const [trackEvent] = await braze({
|
|
78
|
+
api_key: 'api_key',
|
|
79
|
+
endpoint: 'sdk.iad-01.braze.com',
|
|
80
|
+
sdkVersion: '3.1',
|
|
81
|
+
doNotLoadFontAwesome: true,
|
|
82
|
+
subscriptions: example
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
await trackEvent.load(Context.system(), {} as Analytics)
|
|
86
|
+
|
|
87
|
+
const scripts = window.document.querySelectorAll('script')
|
|
88
|
+
// loads the service worker
|
|
89
|
+
expect(scripts).toMatchSnapshot(`
|
|
90
|
+
NodeList [
|
|
91
|
+
<script
|
|
92
|
+
src="https://js.appboycdn.com/web-sdk/3.1/appboy.no-amd.min.js"
|
|
93
|
+
status="loaded"
|
|
94
|
+
type="text/javascript"
|
|
95
|
+
/>,
|
|
96
|
+
<script>
|
|
97
|
+
// the emptiness
|
|
98
|
+
</script>,
|
|
99
|
+
]
|
|
100
|
+
`)
|
|
101
|
+
})
|
|
102
|
+
|
|
103
|
+
test('3.5', async () => {
|
|
104
|
+
const [trackEvent] = await braze({
|
|
105
|
+
api_key: 'api_key',
|
|
106
|
+
endpoint: 'sdk.iad-01.braze.com',
|
|
107
|
+
sdkVersion: '3.5',
|
|
108
|
+
doNotLoadFontAwesome: true,
|
|
109
|
+
subscriptions: example
|
|
110
|
+
})
|
|
111
|
+
|
|
112
|
+
await trackEvent.load(Context.system(), {} as Analytics)
|
|
113
|
+
|
|
114
|
+
const scripts = window.document.querySelectorAll('script')
|
|
115
|
+
// loads the service worker
|
|
116
|
+
expect(scripts).toMatchSnapshot(`
|
|
117
|
+
NodeList [
|
|
118
|
+
<script
|
|
119
|
+
src="https://js.appboycdn.com/web-sdk/3.5/appboy.no-amd.min.js"
|
|
120
|
+
status="loaded"
|
|
121
|
+
type="text/javascript"
|
|
122
|
+
/>,
|
|
123
|
+
<script>
|
|
124
|
+
// the emptiness
|
|
125
|
+
</script>,
|
|
126
|
+
]
|
|
127
|
+
`)
|
|
128
|
+
})
|
|
129
|
+
|
|
130
|
+
test('undefined version', async () => {
|
|
131
|
+
//@ts-expect-error sdkVersion is expected but undefined
|
|
132
|
+
const [trackEvent] = await braze({
|
|
133
|
+
api_key: 'api_key',
|
|
134
|
+
endpoint: 'sdk.iad-01.braze.com',
|
|
135
|
+
doNotLoadFontAwesome: true,
|
|
136
|
+
subscriptions: example
|
|
137
|
+
})
|
|
138
|
+
|
|
139
|
+
await trackEvent.load(Context.system(), {} as Analytics)
|
|
140
|
+
|
|
141
|
+
const scripts = window.document.querySelectorAll('script')
|
|
142
|
+
// loads the service worker
|
|
143
|
+
expect(scripts).toMatchSnapshot(`
|
|
144
|
+
NodeList [
|
|
145
|
+
<script
|
|
146
|
+
src="https://js.appboycdn.com/web-sdk/4.6/braze.no-module.min.js"
|
|
147
|
+
status="loaded"
|
|
148
|
+
type="text/javascript"
|
|
149
|
+
/>,
|
|
150
|
+
<script>
|
|
151
|
+
// the emptiness
|
|
152
|
+
</script>,
|
|
153
|
+
]
|
|
154
|
+
`)
|
|
155
|
+
})
|
|
156
|
+
})
|