@newrelic/browser-agent 1.241.0 → 1.243.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/CHANGELOG.md +1465 -0
- package/dist/cjs/cdn/polyfills/lite.js +13 -1
- package/dist/cjs/cdn/polyfills/pro.js +17 -1
- package/dist/cjs/cdn/polyfills/spa.js +18 -1
- package/dist/cjs/common/config/state/init.js +32 -5
- package/dist/cjs/common/constants/env.cdn.js +1 -1
- package/dist/cjs/common/constants/env.npm.js +1 -1
- package/dist/cjs/common/dom/query-selector.js +16 -0
- package/dist/cjs/common/session/session-entity.js +20 -2
- package/dist/cjs/common/wrap/wrap-function.js +1 -1
- package/dist/cjs/features/ajax/aggregate/index.js +1 -1
- package/dist/cjs/features/session_replay/aggregate/index.js +84 -50
- package/dist/cjs/features/utils/feature-base.js +1 -2
- package/dist/cjs/features/utils/instrument-base.js +1 -0
- package/dist/cjs/loaders/api/api.js +2 -2
- package/dist/cjs/loaders/api/apiAsync.js +0 -37
- package/dist/cjs/loaders/configure/configure.js +1 -1
- package/dist/cjs/loaders/configure/public-path.js +6 -3
- package/dist/esm/cdn/polyfills/lite.js +8 -1
- package/dist/esm/cdn/polyfills/pro.js +13 -2
- package/dist/esm/cdn/polyfills/spa.js +13 -1
- package/dist/esm/common/config/state/init.js +32 -5
- package/dist/esm/common/constants/env.cdn.js +1 -1
- package/dist/esm/common/constants/env.npm.js +1 -1
- package/dist/esm/common/dom/query-selector.js +9 -0
- package/dist/esm/common/session/session-entity.js +18 -1
- package/dist/esm/common/wrap/wrap-function.js +1 -1
- package/dist/esm/features/ajax/aggregate/index.js +1 -1
- package/dist/esm/features/session_replay/aggregate/index.js +83 -50
- package/dist/esm/features/utils/feature-base.js +1 -2
- package/dist/esm/features/utils/instrument-base.js +1 -0
- package/dist/esm/loaders/api/api.js +2 -2
- package/dist/esm/loaders/api/apiAsync.js +1 -36
- package/dist/esm/loaders/configure/configure.js +1 -1
- package/dist/esm/loaders/configure/public-path.js +6 -3
- package/dist/types/common/config/state/init.d.ts.map +1 -1
- package/dist/types/common/dom/query-selector.d.ts +2 -0
- package/dist/types/common/dom/query-selector.d.ts.map +1 -0
- package/dist/types/common/session/session-entity.d.ts +5 -0
- package/dist/types/common/session/session-entity.d.ts.map +1 -1
- package/dist/types/features/session_replay/aggregate/index.d.ts +11 -14
- package/dist/types/features/session_replay/aggregate/index.d.ts.map +1 -1
- package/dist/types/features/utils/feature-base.d.ts.map +1 -1
- package/dist/types/features/utils/instrument-base.d.ts.map +1 -1
- package/dist/types/loaders/api/api.d.ts.map +1 -1
- package/dist/types/loaders/api/apiAsync.d.ts.map +1 -1
- package/dist/types/loaders/configure/public-path.d.ts +1 -1
- package/dist/types/loaders/configure/public-path.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/cdn/polyfills/lite.js +14 -1
- package/src/cdn/polyfills/pro.js +23 -2
- package/src/cdn/polyfills/spa.js +24 -1
- package/src/common/config/state/init.js +33 -4
- package/src/common/dom/query-selector.js +9 -0
- package/src/common/session/session-entity.js +20 -1
- package/src/common/wrap/wrap-function.js +1 -1
- package/src/features/ajax/aggregate/index.js +2 -2
- package/src/features/session_replay/aggregate/index.js +82 -34
- package/src/features/utils/feature-base.js +1 -2
- package/src/features/utils/instrument-base.js +1 -0
- package/src/loaders/api/api.js +1 -2
- package/src/loaders/api/apiAsync.js +1 -39
- package/src/loaders/configure/configure.js +1 -1
- package/src/loaders/configure/public-path.js +6 -3
- package/src/common/aggregate/aggregator.test.js +0 -107
- package/src/common/config/state/configurable.test.js +0 -73
- package/src/common/config/state/info.test.js +0 -31
- package/src/common/config/state/init.test.js +0 -28
- package/src/common/config/state/loader-config.test.js +0 -21
- package/src/common/config/state/runtime.test.js +0 -21
- package/src/common/constants/env.cdn.test.js +0 -7
- package/src/common/constants/env.npm.test.js +0 -7
- package/src/common/constants/env.test.js +0 -7
- package/src/common/constants/runtime.test.js +0 -176
- package/src/common/deny-list/deny-list.test.js +0 -104
- package/src/common/drain/drain.test.js +0 -74
- package/src/common/event-emitter/contextual-ee.component-test.js +0 -293
- package/src/common/event-emitter/handle.test.js +0 -56
- package/src/common/event-emitter/register-handler.test.js +0 -61
- package/src/common/harvest/harvest-scheduler.test.js +0 -492
- package/src/common/harvest/harvest.test.js +0 -813
- package/src/common/ids/id.test.js +0 -92
- package/src/common/ids/unique-id.test.js +0 -58
- package/src/common/session/session-entity.component-test.js +0 -346
- package/src/common/storage/local-storage.test.js +0 -17
- package/src/common/timer/interaction-timer.component-test.js +0 -212
- package/src/common/timer/timer.test.js +0 -99
- package/src/common/timing/nav-timing.test.js +0 -161
- package/src/common/url/canonicalize-url.test.js +0 -45
- package/src/common/url/clean-url.test.js +0 -25
- package/src/common/url/encode.test.js +0 -81
- package/src/common/url/location.test.js +0 -15
- package/src/common/url/parse-url.test.js +0 -110
- package/src/common/url/protocol.test.js +0 -17
- package/src/common/util/console.test.js +0 -34
- package/src/common/util/data-size.test.js +0 -56
- package/src/common/util/feature-flags.test.js +0 -94
- package/src/common/util/get-or-set.test.js +0 -58
- package/src/common/util/invoke.test.js +0 -65
- package/src/common/util/map-own.test.js +0 -52
- package/src/common/util/obfuscate.component-test.js +0 -173
- package/src/common/util/stringify.test.js +0 -49
- package/src/common/util/submit-data.test.js +0 -183
- package/src/common/util/traverse.test.js +0 -50
- package/src/common/vitals/cumulative-layout-shift.test.js +0 -71
- package/src/common/vitals/first-contentful-paint.test.js +0 -124
- package/src/common/vitals/first-input-delay.test.js +0 -88
- package/src/common/vitals/first-paint.test.js +0 -127
- package/src/common/vitals/interaction-to-next-paint.test.js +0 -74
- package/src/common/vitals/largest-contentful-paint.test.js +0 -94
- package/src/common/vitals/long-task.test.js +0 -122
- package/src/common/vitals/time-to-first-byte.test.js +0 -147
- package/src/common/vitals/vital-metric.test.js +0 -171
- package/src/common/wrap/wrap-promise.component-test.js +0 -110
- package/src/features/ajax/instrument/distributed-tracing.test.js +0 -375
- package/src/features/jserrors/aggregate/canonical-function-name.test.js +0 -13
- package/src/features/jserrors/aggregate/compute-stack-trace.test.js +0 -414
- package/src/features/jserrors/aggregate/format-stack-trace.test.js +0 -39
- package/src/features/jserrors/aggregate/string-hash-code.test.js +0 -12
- package/src/features/metrics/aggregate/framework-detection.test.js +0 -332
- package/src/features/page_view_timing/aggregate/index.component-test.js +0 -86
- package/src/features/session_replay/aggregate/index.component-test.js +0 -317
- package/src/features/spa/aggregate/interaction-node.test.js +0 -17
- package/src/features/utils/agent-session.test.js +0 -194
- package/src/features/utils/aggregate-base.test.js +0 -123
- package/src/features/utils/feature-base.test.js +0 -45
- package/src/features/utils/handler-cache.test.js +0 -72
- package/src/features/utils/instrument-base.test.js +0 -216
- package/src/features/utils/lazy-feature-loader.test.js +0 -37
- package/src/loaders/api/api.component-test.js +0 -45
- package/src/loaders/api/api.test.js +0 -85
- package/src/loaders/api/apiAsync.test.js +0 -17
|
@@ -1,813 +0,0 @@
|
|
|
1
|
-
import { faker } from '@faker-js/faker'
|
|
2
|
-
|
|
3
|
-
import * as encodeModule from '../url/encode'
|
|
4
|
-
import * as submitDataModule from '../util/submit-data'
|
|
5
|
-
import * as configModule from '../config/config'
|
|
6
|
-
import { warn } from '../util/console'
|
|
7
|
-
import { applyFnToProps } from '../util/traverse'
|
|
8
|
-
|
|
9
|
-
import { Harvest } from './harvest'
|
|
10
|
-
|
|
11
|
-
jest.enableAutomock()
|
|
12
|
-
jest.unmock('./harvest')
|
|
13
|
-
|
|
14
|
-
let harvestInstance
|
|
15
|
-
|
|
16
|
-
beforeEach(() => {
|
|
17
|
-
harvestInstance = new Harvest()
|
|
18
|
-
})
|
|
19
|
-
|
|
20
|
-
afterEach(() => {
|
|
21
|
-
jest.clearAllMocks()
|
|
22
|
-
})
|
|
23
|
-
|
|
24
|
-
describe('sendX', () => {
|
|
25
|
-
beforeEach(() => {
|
|
26
|
-
jest.mocked(submitDataModule.getSubmitMethod).mockReturnValue(jest.fn())
|
|
27
|
-
jest.spyOn(harvestInstance, '_send').mockImplementation(jest.fn())
|
|
28
|
-
jest.spyOn(harvestInstance, 'obfuscateAndSend').mockImplementation(jest.fn())
|
|
29
|
-
jest.spyOn(harvestInstance, 'createPayload').mockReturnValue({})
|
|
30
|
-
})
|
|
31
|
-
|
|
32
|
-
test('should pass spec settings on to _send method', async () => {
|
|
33
|
-
const endpoint = faker.datatype.uuid()
|
|
34
|
-
const spec = {
|
|
35
|
-
endpoint,
|
|
36
|
-
[faker.datatype.uuid()]: faker.lorem.sentence()
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
harvestInstance.sendX(spec)
|
|
40
|
-
|
|
41
|
-
expect(harvestInstance._send).toHaveBeenCalledWith(expect.objectContaining(spec))
|
|
42
|
-
})
|
|
43
|
-
|
|
44
|
-
test('should create payload with retry true', async () => {
|
|
45
|
-
const endpoint = faker.datatype.uuid()
|
|
46
|
-
const spec = {
|
|
47
|
-
endpoint,
|
|
48
|
-
opts: {
|
|
49
|
-
unload: false
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
jest.mocked(submitDataModule.getSubmitMethod).mockReturnValue(submitDataModule.xhr)
|
|
53
|
-
|
|
54
|
-
harvestInstance.sendX(spec)
|
|
55
|
-
|
|
56
|
-
expect(harvestInstance.createPayload).toHaveBeenCalledWith(spec.endpoint, { retry: true, isFinalHarvest: false })
|
|
57
|
-
})
|
|
58
|
-
|
|
59
|
-
test('should not use obfuscateAndSend', async () => {
|
|
60
|
-
jest.mocked(harvestInstance.obfuscator.shouldObfuscate).mockReturnValue(false)
|
|
61
|
-
|
|
62
|
-
const endpoint = faker.datatype.uuid()
|
|
63
|
-
harvestInstance.sendX({ endpoint })
|
|
64
|
-
|
|
65
|
-
expect(harvestInstance._send).toHaveBeenCalledWith({
|
|
66
|
-
endpoint,
|
|
67
|
-
payload: {},
|
|
68
|
-
submitMethod: expect.any(Function)
|
|
69
|
-
})
|
|
70
|
-
expect(harvestInstance.obfuscateAndSend).not.toHaveBeenCalled()
|
|
71
|
-
})
|
|
72
|
-
|
|
73
|
-
test('should use obfuscateAndSend', async () => {
|
|
74
|
-
jest.mocked(harvestInstance.obfuscator.shouldObfuscate).mockReturnValue(true)
|
|
75
|
-
|
|
76
|
-
const endpoint = faker.datatype.uuid()
|
|
77
|
-
harvestInstance.sendX({ endpoint })
|
|
78
|
-
|
|
79
|
-
expect(harvestInstance.obfuscateAndSend).toHaveBeenCalledWith({
|
|
80
|
-
endpoint,
|
|
81
|
-
payload: {},
|
|
82
|
-
submitMethod: expect.any(Function)
|
|
83
|
-
})
|
|
84
|
-
expect(harvestInstance._send).not.toHaveBeenCalled()
|
|
85
|
-
})
|
|
86
|
-
|
|
87
|
-
test.each([undefined, {}])('should still call _send when spec is %s', async (spec) => {
|
|
88
|
-
harvestInstance.sendX(spec)
|
|
89
|
-
|
|
90
|
-
expect(harvestInstance._send).toHaveBeenCalledWith({
|
|
91
|
-
payload: {},
|
|
92
|
-
submitMethod: expect.any(Function)
|
|
93
|
-
})
|
|
94
|
-
})
|
|
95
|
-
})
|
|
96
|
-
|
|
97
|
-
describe('send', () => {
|
|
98
|
-
beforeEach(() => {
|
|
99
|
-
jest.spyOn(harvestInstance, '_send').mockImplementation(jest.fn())
|
|
100
|
-
jest.spyOn(harvestInstance, 'obfuscateAndSend').mockImplementation(jest.fn())
|
|
101
|
-
})
|
|
102
|
-
|
|
103
|
-
test('should pass spec settings on to _send method', async () => {
|
|
104
|
-
const endpoint = faker.datatype.uuid()
|
|
105
|
-
const spec = {
|
|
106
|
-
endpoint,
|
|
107
|
-
[faker.datatype.uuid()]: faker.lorem.sentence()
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
harvestInstance.send(spec)
|
|
111
|
-
|
|
112
|
-
expect(harvestInstance._send).toHaveBeenCalledWith(spec)
|
|
113
|
-
})
|
|
114
|
-
|
|
115
|
-
test('should not use obfuscateAndSend', async () => {
|
|
116
|
-
jest.mocked(harvestInstance.obfuscator.shouldObfuscate).mockReturnValue(false)
|
|
117
|
-
|
|
118
|
-
const endpoint = faker.datatype.uuid()
|
|
119
|
-
harvestInstance.send({ endpoint })
|
|
120
|
-
|
|
121
|
-
expect(harvestInstance._send).toHaveBeenCalledWith({
|
|
122
|
-
endpoint
|
|
123
|
-
})
|
|
124
|
-
expect(harvestInstance.obfuscateAndSend).not.toHaveBeenCalled()
|
|
125
|
-
})
|
|
126
|
-
|
|
127
|
-
test('should use obfuscateAndSend', async () => {
|
|
128
|
-
jest.mocked(harvestInstance.obfuscator.shouldObfuscate).mockReturnValue(true)
|
|
129
|
-
|
|
130
|
-
const endpoint = faker.datatype.uuid()
|
|
131
|
-
harvestInstance.send({ endpoint })
|
|
132
|
-
|
|
133
|
-
expect(harvestInstance.obfuscateAndSend).toHaveBeenCalledWith({
|
|
134
|
-
endpoint
|
|
135
|
-
})
|
|
136
|
-
expect(harvestInstance._send).not.toHaveBeenCalled()
|
|
137
|
-
})
|
|
138
|
-
|
|
139
|
-
test.each([undefined, {}])('should still call _send when spec is %s', async (spec) => {
|
|
140
|
-
harvestInstance.send(spec)
|
|
141
|
-
|
|
142
|
-
expect(harvestInstance._send).toHaveBeenCalledWith(spec || {})
|
|
143
|
-
})
|
|
144
|
-
})
|
|
145
|
-
|
|
146
|
-
describe('_send', () => {
|
|
147
|
-
let errorBeacon
|
|
148
|
-
let submitMethod
|
|
149
|
-
let spec
|
|
150
|
-
let licenseKey
|
|
151
|
-
|
|
152
|
-
beforeEach(() => {
|
|
153
|
-
errorBeacon = faker.internet.domainName()
|
|
154
|
-
licenseKey = faker.datatype.uuid()
|
|
155
|
-
jest.mocked(configModule.getInfo).mockReturnValue({
|
|
156
|
-
errorBeacon,
|
|
157
|
-
licenseKey
|
|
158
|
-
})
|
|
159
|
-
jest.mocked(configModule.getRuntime).mockReturnValue({
|
|
160
|
-
maxBytes: Infinity
|
|
161
|
-
})
|
|
162
|
-
jest.mocked(configModule.getConfiguration).mockReturnValue({
|
|
163
|
-
ssl: undefined,
|
|
164
|
-
proxy: {}
|
|
165
|
-
})
|
|
166
|
-
|
|
167
|
-
spec = {
|
|
168
|
-
endpoint: faker.datatype.uuid(),
|
|
169
|
-
payload: {
|
|
170
|
-
body: {
|
|
171
|
-
[faker.datatype.uuid()]: faker.lorem.sentence()
|
|
172
|
-
},
|
|
173
|
-
qs: {
|
|
174
|
-
[faker.datatype.uuid()]: faker.lorem.sentence()
|
|
175
|
-
}
|
|
176
|
-
},
|
|
177
|
-
opts: {}
|
|
178
|
-
}
|
|
179
|
-
submitMethod = jest.fn().mockReturnValue(true)
|
|
180
|
-
jest.mocked(submitDataModule.getSubmitMethod).mockReturnValue(submitMethod)
|
|
181
|
-
})
|
|
182
|
-
|
|
183
|
-
test('should return false when info.errorBeacon is not defined', () => {
|
|
184
|
-
jest.mocked(configModule.getInfo).mockReturnValue({})
|
|
185
|
-
|
|
186
|
-
const result = harvestInstance._send(spec)
|
|
187
|
-
|
|
188
|
-
expect(result).toEqual(false)
|
|
189
|
-
expect(submitMethod).not.toHaveBeenCalled()
|
|
190
|
-
})
|
|
191
|
-
|
|
192
|
-
test('should return false when body is empty and sendEmptyBody is false', () => {
|
|
193
|
-
jest.spyOn(harvestInstance, 'cleanPayload').mockReturnValue({ body: {}, qs: {} })
|
|
194
|
-
spec.opts.sendEmptyBody = false
|
|
195
|
-
spec.cbFinished = jest.fn()
|
|
196
|
-
|
|
197
|
-
const result = harvestInstance._send(spec)
|
|
198
|
-
|
|
199
|
-
expect(result).toEqual(false)
|
|
200
|
-
expect(submitMethod).not.toHaveBeenCalled()
|
|
201
|
-
expect(spec.cbFinished).toHaveBeenCalledWith({ sent: false })
|
|
202
|
-
})
|
|
203
|
-
|
|
204
|
-
test('should construct the rum url', () => {
|
|
205
|
-
spec.endpoint = 'rum'
|
|
206
|
-
|
|
207
|
-
const result = harvestInstance._send(spec)
|
|
208
|
-
|
|
209
|
-
expect(result).toEqual(true)
|
|
210
|
-
expect(submitMethod).toHaveBeenCalledWith({
|
|
211
|
-
body: JSON.stringify(spec.payload.body),
|
|
212
|
-
headers: [{ key: 'content-type', value: 'text/plain' }],
|
|
213
|
-
sync: undefined,
|
|
214
|
-
url: expect.stringContaining(`https://${errorBeacon}/1/${licenseKey}?`)
|
|
215
|
-
})
|
|
216
|
-
})
|
|
217
|
-
|
|
218
|
-
test('should construct the non-rum url', () => {
|
|
219
|
-
const result = harvestInstance._send(spec)
|
|
220
|
-
|
|
221
|
-
expect(result).toEqual(true)
|
|
222
|
-
expect(submitMethod).toHaveBeenCalledWith({
|
|
223
|
-
body: JSON.stringify(spec.payload.body),
|
|
224
|
-
headers: [{ key: 'content-type', value: 'text/plain' }],
|
|
225
|
-
sync: undefined,
|
|
226
|
-
url: expect.stringContaining(`https://${errorBeacon}/${spec.endpoint}/1/${licenseKey}?`)
|
|
227
|
-
})
|
|
228
|
-
})
|
|
229
|
-
|
|
230
|
-
test('able to use and send to proxy when defined', () => {
|
|
231
|
-
jest.mocked(configModule.getConfiguration).mockReturnValue({ proxy: { beacon: 'some_other_string' } })
|
|
232
|
-
const result = harvestInstance._send(spec)
|
|
233
|
-
|
|
234
|
-
expect(result).toEqual(true)
|
|
235
|
-
expect(submitMethod).toHaveBeenCalledWith({
|
|
236
|
-
body: JSON.stringify(spec.payload.body),
|
|
237
|
-
headers: [{ key: 'content-type', value: 'text/plain' }],
|
|
238
|
-
sync: undefined,
|
|
239
|
-
url: expect.stringContaining(`https://some_other_string/${spec.endpoint}/1/${licenseKey}?`)
|
|
240
|
-
})
|
|
241
|
-
})
|
|
242
|
-
|
|
243
|
-
test('should use the custom defined url', () => {
|
|
244
|
-
spec.customUrl = faker.internet.url()
|
|
245
|
-
|
|
246
|
-
const result = harvestInstance._send(spec)
|
|
247
|
-
|
|
248
|
-
expect(result).toEqual(true)
|
|
249
|
-
expect(submitMethod).toHaveBeenCalledWith({
|
|
250
|
-
body: JSON.stringify(spec.payload.body),
|
|
251
|
-
headers: [{ key: 'content-type', value: 'text/plain' }],
|
|
252
|
-
sync: undefined,
|
|
253
|
-
url: expect.stringContaining(`${spec.customUrl}?`)
|
|
254
|
-
})
|
|
255
|
-
})
|
|
256
|
-
|
|
257
|
-
test('should not include the license key or base params in a raw url', () => {
|
|
258
|
-
spec.raw = true
|
|
259
|
-
|
|
260
|
-
const result = harvestInstance._send(spec)
|
|
261
|
-
const queryString = Object.entries(spec.payload.qs)
|
|
262
|
-
.map(([key, value]) => `${key}=${encodeURIComponent(value)}`)
|
|
263
|
-
.join('&')
|
|
264
|
-
|
|
265
|
-
expect(result).toEqual(true)
|
|
266
|
-
expect(submitMethod).toHaveBeenCalledWith({
|
|
267
|
-
body: JSON.stringify(spec.payload.body),
|
|
268
|
-
headers: [{ key: 'content-type', value: 'text/plain' }],
|
|
269
|
-
sync: undefined,
|
|
270
|
-
url: `https://${errorBeacon}/${spec.endpoint}?${queryString}`
|
|
271
|
-
})
|
|
272
|
-
})
|
|
273
|
-
|
|
274
|
-
test('should remove leading ampersand from encoded payload params', () => {
|
|
275
|
-
const queryString = Object.entries(spec.payload.qs)
|
|
276
|
-
.map(([key, value]) => `${key}=${encodeURIComponent(value)}`)
|
|
277
|
-
.join('&')
|
|
278
|
-
|
|
279
|
-
jest.mocked(encodeModule.obj).mockReturnValue(`&${queryString}`)
|
|
280
|
-
spec.raw = true
|
|
281
|
-
|
|
282
|
-
const result = harvestInstance._send(spec)
|
|
283
|
-
|
|
284
|
-
expect(result).toEqual(true)
|
|
285
|
-
expect(submitMethod).toHaveBeenCalledWith({
|
|
286
|
-
body: JSON.stringify(spec.payload.body),
|
|
287
|
-
headers: [{ key: 'content-type', value: 'text/plain' }],
|
|
288
|
-
sync: undefined,
|
|
289
|
-
url: `https://${errorBeacon}/${spec.endpoint}?${queryString}`
|
|
290
|
-
})
|
|
291
|
-
})
|
|
292
|
-
|
|
293
|
-
test('should not alter body when gzip qs is present', () => {
|
|
294
|
-
spec.payload.qs.attributes += '&content_encoding=gzip'
|
|
295
|
-
|
|
296
|
-
const result = harvestInstance._send(spec)
|
|
297
|
-
|
|
298
|
-
expect(result).toEqual(true)
|
|
299
|
-
expect(submitMethod).toHaveBeenCalledWith({
|
|
300
|
-
body: spec.payload.body,
|
|
301
|
-
headers: [{ key: 'content-type', value: 'text/plain' }],
|
|
302
|
-
sync: undefined,
|
|
303
|
-
url: expect.stringContaining(`https://${errorBeacon}/${spec.endpoint}/1/${licenseKey}?`)
|
|
304
|
-
})
|
|
305
|
-
})
|
|
306
|
-
|
|
307
|
-
test('should warn (once) if payload is large', () => {
|
|
308
|
-
spec.payload.body = 'x'.repeat(1024 * 1024) // ~1mb string
|
|
309
|
-
|
|
310
|
-
const result = harvestInstance._send(spec)
|
|
311
|
-
|
|
312
|
-
expect(result).toEqual(true)
|
|
313
|
-
expect(warn).toHaveBeenCalledWith(expect.stringContaining('The Browser Agent is attempting to send a very large payload'))
|
|
314
|
-
expect(warn).toHaveBeenCalledTimes(1)
|
|
315
|
-
|
|
316
|
-
const result2 = harvestInstance._send(spec)
|
|
317
|
-
expect(result2).toEqual(true)
|
|
318
|
-
expect(warn).toHaveBeenCalledTimes(1)
|
|
319
|
-
})
|
|
320
|
-
|
|
321
|
-
test('should set body to events when endpoint is events', () => {
|
|
322
|
-
spec.endpoint = 'events'
|
|
323
|
-
spec.payload.body.e = faker.lorem.sentence()
|
|
324
|
-
|
|
325
|
-
const result = harvestInstance._send(spec)
|
|
326
|
-
|
|
327
|
-
expect(result).toEqual(true)
|
|
328
|
-
expect(submitMethod).toHaveBeenCalledWith({
|
|
329
|
-
body: spec.payload.body.e,
|
|
330
|
-
headers: [{ key: 'content-type', value: 'text/plain' }],
|
|
331
|
-
sync: undefined,
|
|
332
|
-
url: expect.stringContaining(`https://${errorBeacon}/${spec.endpoint}/1/${licenseKey}?`)
|
|
333
|
-
})
|
|
334
|
-
})
|
|
335
|
-
|
|
336
|
-
test.each([
|
|
337
|
-
null,
|
|
338
|
-
undefined,
|
|
339
|
-
{},
|
|
340
|
-
[]
|
|
341
|
-
])('should set body to empty string when %s', (inputBody) => {
|
|
342
|
-
spec.opts.sendEmptyBody = true
|
|
343
|
-
spec.payload.body = inputBody
|
|
344
|
-
|
|
345
|
-
const result = harvestInstance._send(spec)
|
|
346
|
-
|
|
347
|
-
expect(result).toEqual(true)
|
|
348
|
-
expect(submitMethod).toHaveBeenCalledWith({
|
|
349
|
-
body: '',
|
|
350
|
-
headers: [{ key: 'content-type', value: 'text/plain' }],
|
|
351
|
-
sync: undefined,
|
|
352
|
-
url: expect.stringContaining(`https://${errorBeacon}/${spec.endpoint}/1/${licenseKey}?`)
|
|
353
|
-
})
|
|
354
|
-
})
|
|
355
|
-
|
|
356
|
-
test('should add a callback to XHR and call cbCallback when not a final harvest', () => {
|
|
357
|
-
jest.mocked(submitDataModule.getSubmitMethod).mockReturnValue(submitDataModule.xhr)
|
|
358
|
-
spec.cbFinished = jest.fn()
|
|
359
|
-
|
|
360
|
-
const result = harvestInstance._send(spec)
|
|
361
|
-
const xhrAddEventListener = jest.mocked(submitDataModule.xhr).mock.results[0].value.addEventListener
|
|
362
|
-
const xhrLoadHandler = jest.mocked(xhrAddEventListener).mock.calls[0][1]
|
|
363
|
-
|
|
364
|
-
const xhrState = {
|
|
365
|
-
status: faker.datatype.uuid()
|
|
366
|
-
}
|
|
367
|
-
xhrLoadHandler.call(xhrState)
|
|
368
|
-
|
|
369
|
-
expect(xhrAddEventListener).toHaveBeenCalledWith('load', expect.any(Function), expect.any(Object))
|
|
370
|
-
expect(result).toEqual(jest.mocked(submitDataModule.xhr).mock.results[0].value)
|
|
371
|
-
expect(submitMethod).not.toHaveBeenCalled()
|
|
372
|
-
expect(spec.cbFinished).toHaveBeenCalledWith({ ...xhrState, sent: true })
|
|
373
|
-
})
|
|
374
|
-
|
|
375
|
-
test('should set cbFinished state retry to true with delay when xhr has 429 status', () => {
|
|
376
|
-
jest.mocked(submitDataModule.getSubmitMethod).mockReturnValue(submitDataModule.xhr)
|
|
377
|
-
spec.cbFinished = jest.fn()
|
|
378
|
-
harvestInstance.tooManyRequestsDelay = faker.datatype.number({ min: 100, max: 1000 })
|
|
379
|
-
|
|
380
|
-
const result = harvestInstance._send(spec)
|
|
381
|
-
const xhrAddEventListener = jest.mocked(submitDataModule.xhr).mock.results[0].value.addEventListener
|
|
382
|
-
const xhrLoadHandler = jest.mocked(xhrAddEventListener).mock.calls[0][1]
|
|
383
|
-
|
|
384
|
-
const xhrState = {
|
|
385
|
-
status: 429
|
|
386
|
-
}
|
|
387
|
-
xhrLoadHandler.call(xhrState)
|
|
388
|
-
|
|
389
|
-
expect(xhrAddEventListener).toHaveBeenCalledWith('load', expect.any(Function), expect.any(Object))
|
|
390
|
-
expect(result).toEqual(jest.mocked(submitDataModule.xhr).mock.results[0].value)
|
|
391
|
-
expect(submitMethod).not.toHaveBeenCalled()
|
|
392
|
-
expect(spec.cbFinished).toHaveBeenCalledWith({
|
|
393
|
-
...xhrState,
|
|
394
|
-
sent: true,
|
|
395
|
-
retry: true,
|
|
396
|
-
delay: harvestInstance.tooManyRequestsDelay
|
|
397
|
-
})
|
|
398
|
-
})
|
|
399
|
-
|
|
400
|
-
test.each([
|
|
401
|
-
408, 500, 503
|
|
402
|
-
])('should set cbFinished state retry to true without delay when xhr has %s status', (statusCode) => {
|
|
403
|
-
jest.mocked(submitDataModule.getSubmitMethod).mockReturnValue(submitDataModule.xhr)
|
|
404
|
-
spec.cbFinished = jest.fn()
|
|
405
|
-
|
|
406
|
-
const result = harvestInstance._send(spec)
|
|
407
|
-
const xhrAddEventListener = jest.mocked(submitDataModule.xhr).mock.results[0].value.addEventListener
|
|
408
|
-
const xhrLoadHandler = jest.mocked(xhrAddEventListener).mock.calls[0][1]
|
|
409
|
-
|
|
410
|
-
const xhrState = {
|
|
411
|
-
status: statusCode
|
|
412
|
-
}
|
|
413
|
-
xhrLoadHandler.call(xhrState)
|
|
414
|
-
|
|
415
|
-
expect(xhrAddEventListener).toHaveBeenCalledWith('load', expect.any(Function), expect.any(Object))
|
|
416
|
-
expect(result).toEqual(jest.mocked(submitDataModule.xhr).mock.results[0].value)
|
|
417
|
-
expect(submitMethod).not.toHaveBeenCalled()
|
|
418
|
-
expect(spec.cbFinished).toHaveBeenCalledWith({
|
|
419
|
-
...xhrState,
|
|
420
|
-
sent: true,
|
|
421
|
-
retry: true
|
|
422
|
-
})
|
|
423
|
-
})
|
|
424
|
-
|
|
425
|
-
test('should include response in call to cbFinished when needResponse is true', () => {
|
|
426
|
-
jest.mocked(submitDataModule.getSubmitMethod).mockReturnValue(submitDataModule.xhr)
|
|
427
|
-
spec.cbFinished = jest.fn()
|
|
428
|
-
spec.opts.needResponse = true
|
|
429
|
-
|
|
430
|
-
const result = harvestInstance._send(spec)
|
|
431
|
-
const xhrAddEventListener = jest.mocked(submitDataModule.xhr).mock.results[0].value.addEventListener
|
|
432
|
-
const xhrLoadHandler = jest.mocked(xhrAddEventListener).mock.calls[0][1]
|
|
433
|
-
|
|
434
|
-
const xhrState = {
|
|
435
|
-
status: faker.datatype.uuid(),
|
|
436
|
-
responseText: faker.lorem.sentence()
|
|
437
|
-
}
|
|
438
|
-
xhrLoadHandler.call(xhrState)
|
|
439
|
-
|
|
440
|
-
expect(xhrAddEventListener).toHaveBeenCalledWith('load', expect.any(Function), expect.any(Object))
|
|
441
|
-
expect(result).toEqual(jest.mocked(submitDataModule.xhr).mock.results[0].value)
|
|
442
|
-
expect(submitMethod).not.toHaveBeenCalled()
|
|
443
|
-
expect(spec.cbFinished).toHaveBeenCalledWith({
|
|
444
|
-
...xhrState,
|
|
445
|
-
sent: true
|
|
446
|
-
})
|
|
447
|
-
})
|
|
448
|
-
|
|
449
|
-
test('should not include response in call to cbFinished when needResponse is false', () => {
|
|
450
|
-
jest.mocked(submitDataModule.getSubmitMethod).mockReturnValue(submitDataModule.xhr)
|
|
451
|
-
spec.cbFinished = jest.fn()
|
|
452
|
-
spec.opts.needResponse = false
|
|
453
|
-
|
|
454
|
-
const result = harvestInstance._send(spec)
|
|
455
|
-
const xhrAddEventListener = jest.mocked(submitDataModule.xhr).mock.results[0].value.addEventListener
|
|
456
|
-
const xhrLoadHandler = jest.mocked(xhrAddEventListener).mock.calls[0][1]
|
|
457
|
-
|
|
458
|
-
const xhrState = {
|
|
459
|
-
status: faker.datatype.uuid(),
|
|
460
|
-
responseText: faker.lorem.sentence()
|
|
461
|
-
}
|
|
462
|
-
xhrLoadHandler.call(xhrState)
|
|
463
|
-
|
|
464
|
-
expect(xhrAddEventListener).toHaveBeenCalledWith('load', expect.any(Function), expect.any(Object))
|
|
465
|
-
expect(result).toEqual(jest.mocked(submitDataModule.xhr).mock.results[0].value)
|
|
466
|
-
expect(submitMethod).not.toHaveBeenCalled()
|
|
467
|
-
expect(spec.cbFinished).toHaveBeenCalledWith({
|
|
468
|
-
...xhrState,
|
|
469
|
-
responseText: undefined,
|
|
470
|
-
sent: true
|
|
471
|
-
})
|
|
472
|
-
})
|
|
473
|
-
})
|
|
474
|
-
|
|
475
|
-
describe('obfuscateAndSend', () => {
|
|
476
|
-
beforeEach(() => {
|
|
477
|
-
jest.spyOn(harvestInstance, '_send').mockImplementation(jest.fn())
|
|
478
|
-
})
|
|
479
|
-
|
|
480
|
-
test('should apply obfuscation to payload', () => {
|
|
481
|
-
const payload = {
|
|
482
|
-
body: {
|
|
483
|
-
foo: faker.lorem.sentence()
|
|
484
|
-
},
|
|
485
|
-
qs: {
|
|
486
|
-
foo: faker.lorem.sentence()
|
|
487
|
-
}
|
|
488
|
-
}
|
|
489
|
-
|
|
490
|
-
harvestInstance.obfuscateAndSend({ payload })
|
|
491
|
-
|
|
492
|
-
expect(applyFnToProps).toHaveBeenCalledWith(payload, expect.any(Function), 'string', ['e'])
|
|
493
|
-
expect(harvestInstance.obfuscator.obfuscateString).toHaveBeenCalledWith(payload)
|
|
494
|
-
})
|
|
495
|
-
|
|
496
|
-
test('should still call _send when spec is undefined', () => {
|
|
497
|
-
harvestInstance.obfuscateAndSend()
|
|
498
|
-
|
|
499
|
-
expect(harvestInstance._send).toHaveBeenCalled()
|
|
500
|
-
})
|
|
501
|
-
|
|
502
|
-
test.each([
|
|
503
|
-
null,
|
|
504
|
-
undefined
|
|
505
|
-
])('should still call _send when payload is %s', (payload) => {
|
|
506
|
-
harvestInstance.obfuscateAndSend({ payload })
|
|
507
|
-
|
|
508
|
-
expect(harvestInstance._send).toHaveBeenCalled()
|
|
509
|
-
})
|
|
510
|
-
})
|
|
511
|
-
|
|
512
|
-
describe('baseQueryString', () => {
|
|
513
|
-
beforeEach(() => {
|
|
514
|
-
jest.mocked(configModule.getInfo).mockReturnValue({})
|
|
515
|
-
jest.mocked(configModule.getRuntime).mockReturnValue({})
|
|
516
|
-
})
|
|
517
|
-
|
|
518
|
-
test('should construct a string of base query parameters', () => {
|
|
519
|
-
const applicationID = faker.datatype.uuid()
|
|
520
|
-
const sa = faker.datatype.uuid()
|
|
521
|
-
jest.mocked(configModule.getInfo).mockReturnValue({
|
|
522
|
-
applicationID,
|
|
523
|
-
sa
|
|
524
|
-
})
|
|
525
|
-
const customTransaction = faker.datatype.uuid()
|
|
526
|
-
const ptid = faker.datatype.uuid()
|
|
527
|
-
jest.mocked(configModule.getRuntime).mockReturnValue({
|
|
528
|
-
customTransaction,
|
|
529
|
-
ptid
|
|
530
|
-
})
|
|
531
|
-
|
|
532
|
-
const results = harvestInstance.baseQueryString()
|
|
533
|
-
|
|
534
|
-
expect(results).toContain(`a=${applicationID}`)
|
|
535
|
-
expect(encodeModule.param).toHaveBeenCalledWith('sa', sa)
|
|
536
|
-
expect(results).toContain(`&sa=${sa}`)
|
|
537
|
-
expect(encodeModule.param).toHaveBeenCalledWith('v', expect.stringMatching(/\d{1,3}\.\d{1,3}\.\d{1,3}/))
|
|
538
|
-
expect(results).toMatch(/&v=\d{1,3}\.\d{1,3}\.\d{1,3}/)
|
|
539
|
-
expect(encodeModule.param).toHaveBeenCalledWith('t', 'Unnamed Transaction')
|
|
540
|
-
expect(results).toContain('&t=Unnamed%20Transaction')
|
|
541
|
-
expect(encodeModule.param).toHaveBeenCalledWith('ct', customTransaction)
|
|
542
|
-
expect(results).toContain(`&ct=${customTransaction}`)
|
|
543
|
-
expect(results).toMatch(/&rst=\d{1,9}/)
|
|
544
|
-
expect(results).toContain('&ck=0')
|
|
545
|
-
expect(results).toContain('&s=0')
|
|
546
|
-
expect(encodeModule.param).toHaveBeenCalledWith('ref', location)
|
|
547
|
-
expect(results).toContain(`&ref=${encodeURIComponent(location)}`)
|
|
548
|
-
expect(encodeModule.param).toHaveBeenCalledWith('ptid', ptid)
|
|
549
|
-
expect(results).toContain(`&ptid=${ptid}`)
|
|
550
|
-
})
|
|
551
|
-
|
|
552
|
-
test('should set t param to info.tNamePlain', () => {
|
|
553
|
-
const tNamePlain = faker.datatype.uuid()
|
|
554
|
-
jest.mocked(configModule.getInfo).mockReturnValue({
|
|
555
|
-
tNamePlain
|
|
556
|
-
})
|
|
557
|
-
|
|
558
|
-
const results = harvestInstance.baseQueryString()
|
|
559
|
-
|
|
560
|
-
expect(encodeModule.param).toHaveBeenCalledWith('t', tNamePlain)
|
|
561
|
-
expect(results).toContain(`&t=${tNamePlain}`)
|
|
562
|
-
})
|
|
563
|
-
|
|
564
|
-
test('should set to param to info.transactionName and exclude t param', () => {
|
|
565
|
-
const transactionName = faker.datatype.uuid()
|
|
566
|
-
jest.mocked(configModule.getInfo).mockReturnValue({
|
|
567
|
-
transactionName
|
|
568
|
-
})
|
|
569
|
-
|
|
570
|
-
const results = harvestInstance.baseQueryString()
|
|
571
|
-
|
|
572
|
-
expect(encodeModule.param).not.toHaveBeenCalledWith('t', expect.any(String))
|
|
573
|
-
expect(results).not.toContain('&t=')
|
|
574
|
-
expect(encodeModule.param).toHaveBeenCalledWith('to', transactionName)
|
|
575
|
-
expect(results).toContain(`&to=${transactionName}`)
|
|
576
|
-
})
|
|
577
|
-
|
|
578
|
-
test('should default sa to empty string', () => {
|
|
579
|
-
const results = harvestInstance.baseQueryString()
|
|
580
|
-
|
|
581
|
-
expect(encodeModule.param).toHaveBeenCalledWith('sa', '')
|
|
582
|
-
expect(results).toContain('&sa=')
|
|
583
|
-
})
|
|
584
|
-
|
|
585
|
-
test('should default s to 0', () => {
|
|
586
|
-
const results = harvestInstance.baseQueryString()
|
|
587
|
-
|
|
588
|
-
expect(results).toContain('&s=0')
|
|
589
|
-
})
|
|
590
|
-
|
|
591
|
-
test('should obfuscate ref', () => {
|
|
592
|
-
const obfuscatedLocation = faker.datatype.uuid()
|
|
593
|
-
jest.mocked(harvestInstance.obfuscator.shouldObfuscate).mockReturnValue(true)
|
|
594
|
-
jest.mocked(harvestInstance.obfuscator.obfuscateString).mockReturnValue(obfuscatedLocation)
|
|
595
|
-
|
|
596
|
-
const results = harvestInstance.baseQueryString()
|
|
597
|
-
|
|
598
|
-
expect(harvestInstance.obfuscator.obfuscateString).toHaveBeenCalledWith(location)
|
|
599
|
-
expect(results).toContain(`&ref=${obfuscatedLocation}`)
|
|
600
|
-
})
|
|
601
|
-
|
|
602
|
-
test('should default ptid to empty string', () => {
|
|
603
|
-
const results = harvestInstance.baseQueryString()
|
|
604
|
-
|
|
605
|
-
expect(encodeModule.param).toHaveBeenCalledWith('ptid', '')
|
|
606
|
-
expect(results).toContain('&ptid=')
|
|
607
|
-
})
|
|
608
|
-
})
|
|
609
|
-
|
|
610
|
-
describe('createPayload', () => {
|
|
611
|
-
test('should return empty body and qs values when no listeners exist', () => {
|
|
612
|
-
const feature = faker.datatype.uuid()
|
|
613
|
-
const results = harvestInstance.createPayload(feature)
|
|
614
|
-
|
|
615
|
-
expect(results).toEqual({
|
|
616
|
-
body: {},
|
|
617
|
-
qs: {}
|
|
618
|
-
})
|
|
619
|
-
})
|
|
620
|
-
|
|
621
|
-
test('should pass options to callback', () => {
|
|
622
|
-
const feature = faker.datatype.uuid()
|
|
623
|
-
const options = {
|
|
624
|
-
[faker.datatype.uuid()]: faker.lorem.sentence()
|
|
625
|
-
}
|
|
626
|
-
const harvestCallback = jest.fn()
|
|
627
|
-
|
|
628
|
-
harvestInstance.on(feature, harvestCallback)
|
|
629
|
-
const results = harvestInstance.createPayload(feature, options)
|
|
630
|
-
|
|
631
|
-
expect(results).toEqual({
|
|
632
|
-
body: {},
|
|
633
|
-
qs: {}
|
|
634
|
-
})
|
|
635
|
-
})
|
|
636
|
-
|
|
637
|
-
test('should aggregate the body properties of the payload', () => {
|
|
638
|
-
const feature = faker.datatype.uuid()
|
|
639
|
-
const payloadA = {
|
|
640
|
-
body: {
|
|
641
|
-
[faker.datatype.uuid()]: {
|
|
642
|
-
[faker.datatype.uuid()]: faker.lorem.sentence()
|
|
643
|
-
}
|
|
644
|
-
}
|
|
645
|
-
}
|
|
646
|
-
const payloadB = {
|
|
647
|
-
body: {
|
|
648
|
-
[faker.datatype.uuid()]: {
|
|
649
|
-
[faker.datatype.uuid()]: faker.lorem.sentence()
|
|
650
|
-
}
|
|
651
|
-
}
|
|
652
|
-
}
|
|
653
|
-
const harvestCallbackA = jest.fn().mockReturnValue(payloadA)
|
|
654
|
-
const harvestCallbackB = jest.fn().mockReturnValue(payloadB)
|
|
655
|
-
|
|
656
|
-
harvestInstance.on(feature, harvestCallbackA)
|
|
657
|
-
harvestInstance.on(feature, harvestCallbackB)
|
|
658
|
-
const results = harvestInstance.createPayload(feature)
|
|
659
|
-
|
|
660
|
-
expect(results).toEqual({
|
|
661
|
-
body: {
|
|
662
|
-
...payloadA.body,
|
|
663
|
-
...payloadB.body
|
|
664
|
-
},
|
|
665
|
-
qs: {}
|
|
666
|
-
})
|
|
667
|
-
})
|
|
668
|
-
|
|
669
|
-
test('should aggregate the qs properties of the payload', () => {
|
|
670
|
-
const feature = faker.datatype.uuid()
|
|
671
|
-
const payloadA = {
|
|
672
|
-
qs: {
|
|
673
|
-
[faker.datatype.uuid()]: {
|
|
674
|
-
[faker.datatype.uuid()]: faker.lorem.sentence()
|
|
675
|
-
}
|
|
676
|
-
}
|
|
677
|
-
}
|
|
678
|
-
const payloadB = {
|
|
679
|
-
qs: {
|
|
680
|
-
[faker.datatype.uuid()]: {
|
|
681
|
-
[faker.datatype.uuid()]: faker.lorem.sentence()
|
|
682
|
-
}
|
|
683
|
-
}
|
|
684
|
-
}
|
|
685
|
-
const harvestCallbackA = jest.fn().mockReturnValue(payloadA)
|
|
686
|
-
const harvestCallbackB = jest.fn().mockReturnValue(payloadB)
|
|
687
|
-
|
|
688
|
-
harvestInstance.on(feature, harvestCallbackA)
|
|
689
|
-
harvestInstance.on(feature, harvestCallbackB)
|
|
690
|
-
const results = harvestInstance.createPayload(feature)
|
|
691
|
-
|
|
692
|
-
expect(results).toEqual({
|
|
693
|
-
body: {},
|
|
694
|
-
qs: {
|
|
695
|
-
...payloadA.qs,
|
|
696
|
-
...payloadB.qs
|
|
697
|
-
}
|
|
698
|
-
})
|
|
699
|
-
})
|
|
700
|
-
|
|
701
|
-
test('should not deep merge the body and qs properties', () => {
|
|
702
|
-
const feature = faker.datatype.uuid()
|
|
703
|
-
const bodyProp = faker.datatype.uuid()
|
|
704
|
-
const qsProp = faker.datatype.uuid()
|
|
705
|
-
const payloadA = {
|
|
706
|
-
body: {
|
|
707
|
-
[bodyProp]: {
|
|
708
|
-
[faker.datatype.uuid()]: faker.lorem.sentence()
|
|
709
|
-
}
|
|
710
|
-
},
|
|
711
|
-
qs: {
|
|
712
|
-
[qsProp]: {
|
|
713
|
-
[faker.datatype.uuid()]: faker.lorem.sentence()
|
|
714
|
-
}
|
|
715
|
-
}
|
|
716
|
-
}
|
|
717
|
-
const payloadB = {
|
|
718
|
-
body: {
|
|
719
|
-
[bodyProp]: {
|
|
720
|
-
[faker.datatype.uuid()]: faker.lorem.sentence()
|
|
721
|
-
}
|
|
722
|
-
},
|
|
723
|
-
qs: {
|
|
724
|
-
[qsProp]: {
|
|
725
|
-
[faker.datatype.uuid()]: faker.lorem.sentence()
|
|
726
|
-
}
|
|
727
|
-
}
|
|
728
|
-
}
|
|
729
|
-
const harvestCallbackA = jest.fn().mockReturnValue(payloadA)
|
|
730
|
-
const harvestCallbackB = jest.fn().mockReturnValue(payloadB)
|
|
731
|
-
|
|
732
|
-
harvestInstance.on(feature, harvestCallbackA)
|
|
733
|
-
harvestInstance.on(feature, harvestCallbackB)
|
|
734
|
-
const results = harvestInstance.createPayload(feature)
|
|
735
|
-
|
|
736
|
-
expect(results).toEqual({
|
|
737
|
-
body: payloadB.body,
|
|
738
|
-
qs: payloadB.qs
|
|
739
|
-
})
|
|
740
|
-
})
|
|
741
|
-
})
|
|
742
|
-
|
|
743
|
-
describe('cleanPayload', () => {
|
|
744
|
-
test('should remove undefined properties from body and qs', () => {
|
|
745
|
-
const payload = {
|
|
746
|
-
body: {
|
|
747
|
-
foo: undefined,
|
|
748
|
-
[faker.datatype.uuid()]: faker.lorem.sentence()
|
|
749
|
-
},
|
|
750
|
-
qs: {
|
|
751
|
-
foo: undefined,
|
|
752
|
-
[faker.datatype.uuid()]: faker.lorem.sentence()
|
|
753
|
-
}
|
|
754
|
-
}
|
|
755
|
-
|
|
756
|
-
const results = harvestInstance.cleanPayload(payload)
|
|
757
|
-
|
|
758
|
-
expect(Object.keys(results.body)).not.toContain('foo')
|
|
759
|
-
expect(Object.keys(results.qs)).not.toContain('foo')
|
|
760
|
-
})
|
|
761
|
-
|
|
762
|
-
test('should remove null properties from body and qs', () => {
|
|
763
|
-
const payload = {
|
|
764
|
-
body: {
|
|
765
|
-
foo: null,
|
|
766
|
-
[faker.datatype.uuid()]: faker.lorem.sentence()
|
|
767
|
-
},
|
|
768
|
-
qs: {
|
|
769
|
-
foo: null,
|
|
770
|
-
[faker.datatype.uuid()]: faker.lorem.sentence()
|
|
771
|
-
}
|
|
772
|
-
}
|
|
773
|
-
|
|
774
|
-
const results = harvestInstance.cleanPayload(payload)
|
|
775
|
-
|
|
776
|
-
expect(Object.keys(results.body)).not.toContain('foo')
|
|
777
|
-
expect(Object.keys(results.qs)).not.toContain('foo')
|
|
778
|
-
})
|
|
779
|
-
|
|
780
|
-
test('should remove empty string properties from body and qs', () => {
|
|
781
|
-
const payload = {
|
|
782
|
-
body: {
|
|
783
|
-
foo: '',
|
|
784
|
-
[faker.datatype.uuid()]: faker.lorem.sentence()
|
|
785
|
-
},
|
|
786
|
-
qs: {
|
|
787
|
-
foo: '',
|
|
788
|
-
[faker.datatype.uuid()]: faker.lorem.sentence()
|
|
789
|
-
}
|
|
790
|
-
}
|
|
791
|
-
|
|
792
|
-
const results = harvestInstance.cleanPayload(payload)
|
|
793
|
-
|
|
794
|
-
expect(Object.keys(results.body)).not.toContain('foo')
|
|
795
|
-
expect(Object.keys(results.qs)).not.toContain('foo')
|
|
796
|
-
})
|
|
797
|
-
|
|
798
|
-
test.each([
|
|
799
|
-
{ [faker.datatype.uuid()]: { [faker.datatype.uuid()]: faker.datatype.number({ min: 100, max: 1000 }) } },
|
|
800
|
-
{ [faker.datatype.uuid()]: faker.datatype.number({ min: 100, max: 1000 }) },
|
|
801
|
-
{ [faker.datatype.uuid()]: new Uint8Array(faker.datatype.number({ min: 100, max: 1000 })) }
|
|
802
|
-
])('should retain %s properties in body and qs', (input) => {
|
|
803
|
-
const payload = {
|
|
804
|
-
body: input,
|
|
805
|
-
qs: input
|
|
806
|
-
}
|
|
807
|
-
|
|
808
|
-
const results = harvestInstance.cleanPayload(payload)
|
|
809
|
-
|
|
810
|
-
expect(results.body).toEqual(input)
|
|
811
|
-
expect(results.qs).toEqual(input)
|
|
812
|
-
})
|
|
813
|
-
})
|