@microsoft/applicationinsights-channel-js 2.7.2-nightly.2111-08 → 2.7.2-nightly.2111-09
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/Tests/Unit/src/Sample.tests.ts +154 -0
- package/Tests/Unit/src/Sender.tests.ts +1578 -0
- package/Tests/Unit/src/aichannel.tests.ts +7 -0
- package/Tests/UnitTests.html +53 -0
- package/Tests/tsconfig.json +17 -0
- package/api-extractor.json +361 -0
- package/applicationinsights-channel-js.build.error.log +20 -0
- package/applicationinsights-channel-js.build.log +265 -0
- package/browser/applicationinsights-channel-js.integrity.json +9 -9
- package/browser/applicationinsights-channel-js.js +2 -2
- package/browser/applicationinsights-channel-js.js.map +1 -1
- package/browser/applicationinsights-channel-js.min.js +2 -2
- package/browser/applicationinsights-channel-js.min.js.map +1 -1
- package/dist/applicationinsights-channel-js.api.json +1 -1
- package/dist/applicationinsights-channel-js.d.ts +1 -1
- package/dist/applicationinsights-channel-js.js +2 -2
- package/dist/applicationinsights-channel-js.js.map +1 -1
- package/dist/applicationinsights-channel-js.min.js +2 -2
- package/dist/applicationinsights-channel-js.min.js.map +1 -1
- package/dist/applicationinsights-channel-js.rollup.d.ts +1 -1
- package/dist-esm/EnvelopeCreator.js +2 -2
- package/dist-esm/EnvelopeCreator.js.map +1 -1
- package/dist-esm/Interfaces.js +1 -1
- package/dist-esm/Offline.js +1 -1
- package/dist-esm/SendBuffer.js +1 -1
- package/dist-esm/Sender.js +1 -1
- package/dist-esm/Serializer.js +1 -1
- package/dist-esm/TelemetryProcessors/Sample.js +1 -1
- package/dist-esm/TelemetryProcessors/SamplingScoreGenerators/HashCodeScoreGenerator.js +1 -1
- package/dist-esm/TelemetryProcessors/SamplingScoreGenerators/SamplingScoreGenerator.js +1 -1
- package/dist-esm/applicationinsights-channel-js.js +1 -1
- package/microsoft-applicationinsights-channel-js-2.7.2-nightly.2111-09.tgz +0 -0
- package/package.json +3 -3
- package/rollup.config.js +139 -0
- package/src/EnvelopeCreator.ts +1 -1
- package/temp/applicationinsights-channel-js.api.md +62 -0
- package/tslint.json +8 -0
- package/types/tsdoc-metadata.json +1 -1
|
@@ -0,0 +1,1578 @@
|
|
|
1
|
+
import { AITestClass } from "@microsoft/ai-test-framework";
|
|
2
|
+
import { Sender } from "../../../src/Sender";
|
|
3
|
+
import { Offline } from '../../../src/Offline';
|
|
4
|
+
import { EnvelopeCreator } from '../../../src/EnvelopeCreator';
|
|
5
|
+
import { Exception, CtxTagKeys, Util } from "@microsoft/applicationinsights-common";
|
|
6
|
+
import { ITelemetryItem, AppInsightsCore, ITelemetryPlugin, DiagnosticLogger, NotificationManager, SendRequestReason, _InternalMessageId, LoggingSeverity, getGlobalInst, getGlobal } from "@microsoft/applicationinsights-core-js";
|
|
7
|
+
|
|
8
|
+
export class SenderTests extends AITestClass {
|
|
9
|
+
private _sender: Sender;
|
|
10
|
+
private _instrumentationKey = 'iKey';
|
|
11
|
+
|
|
12
|
+
public testInitialize() {
|
|
13
|
+
this._sender = new Sender();
|
|
14
|
+
this._sender.initialize({ instrumentationKey: this._instrumentationKey }, new AppInsightsCore(), []);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
public testCleanup() {
|
|
18
|
+
this._sender = null;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
public registerTests() {
|
|
22
|
+
|
|
23
|
+
this.testCase({
|
|
24
|
+
name: "Channel Config: Channel can properly take args from root config",
|
|
25
|
+
test: () => {
|
|
26
|
+
this._sender.initialize(
|
|
27
|
+
{
|
|
28
|
+
instrumentationKey: 'abc',
|
|
29
|
+
maxBatchInterval: 123,
|
|
30
|
+
endpointUrl: 'https://example.com',
|
|
31
|
+
maxBatchSizeInBytes: 654,
|
|
32
|
+
extensionConfig: {
|
|
33
|
+
[this._sender.identifier]: {
|
|
34
|
+
maxBatchSizeInBytes: 456
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
}, new AppInsightsCore(), []
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
QUnit.assert.equal(123, this._sender._senderConfig.maxBatchInterval(), 'Channel config can be set from root config (maxBatchInterval)');
|
|
42
|
+
QUnit.assert.equal('https://example.com', this._sender._senderConfig.endpointUrl(), 'Channel config can be set from root config (endpointUrl)');
|
|
43
|
+
QUnit.assert.notEqual(654, this._sender._senderConfig.maxBatchSizeInBytes(), 'Channel config does not equal root config option if extensionConfig field is also set');
|
|
44
|
+
QUnit.assert.equal(456, this._sender._senderConfig.maxBatchSizeInBytes(), 'Channel config prioritizes extensionConfig over root config');
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
this.testCase({
|
|
49
|
+
name: "processTelemetry can be called with optional fields undefined",
|
|
50
|
+
useFakeTimers: true,
|
|
51
|
+
test: () => {
|
|
52
|
+
this._sender.initialize({
|
|
53
|
+
instrumentationKey: 'abc'
|
|
54
|
+
}, new AppInsightsCore(), []);
|
|
55
|
+
|
|
56
|
+
const loggerSpy = this.sandbox.stub(this._sender, "triggerSend");
|
|
57
|
+
const telemetryItem: ITelemetryItem = {
|
|
58
|
+
name: 'fake item',
|
|
59
|
+
iKey: 'iKey',
|
|
60
|
+
baseType: 'some type',
|
|
61
|
+
baseData: {}
|
|
62
|
+
};
|
|
63
|
+
try {
|
|
64
|
+
this._sender.processTelemetry(telemetryItem, null);
|
|
65
|
+
} catch(e) {
|
|
66
|
+
QUnit.assert.ok(false, "Exception - " + e);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
QUnit.assert.equal(false, loggerSpy.calledOnce, "The send has not yet been triggered");
|
|
70
|
+
this.clock.tick(15000);
|
|
71
|
+
QUnit.assert.equal(true, loggerSpy.calledOnce, "The send has been triggered");
|
|
72
|
+
}
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
this.testCase({
|
|
76
|
+
name: "processTelemetry process ItelemetryItem with iKey",
|
|
77
|
+
useFakeTimers: true,
|
|
78
|
+
test: () => {
|
|
79
|
+
this._sender.initialize({
|
|
80
|
+
instrumentationKey: 'abc'
|
|
81
|
+
}, new AppInsightsCore(), []);
|
|
82
|
+
|
|
83
|
+
const loggerSpy = this.sandbox.stub(this._sender, "triggerSend");
|
|
84
|
+
const expectedIkey = 'testIkey';
|
|
85
|
+
const telemetryItem: ITelemetryItem = {
|
|
86
|
+
name: 'fake item',
|
|
87
|
+
iKey: expectedIkey,
|
|
88
|
+
baseType: 'some type',
|
|
89
|
+
baseData: {}
|
|
90
|
+
};
|
|
91
|
+
try {
|
|
92
|
+
this._sender.processTelemetry(telemetryItem, null);
|
|
93
|
+
let buffer = this._sender._buffer.getItems();
|
|
94
|
+
let payload = JSON.parse(buffer[buffer.length-1]);
|
|
95
|
+
var actualIkey = payload.iKey;
|
|
96
|
+
} catch(e) {
|
|
97
|
+
QUnit.assert.ok(false, "Exception - " + e);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
QUnit.assert.equal(false, loggerSpy.calledOnce, "The send has not yet been triggered");
|
|
101
|
+
QUnit.assert.equal(expectedIkey, actualIkey, "processTelemetry replaced ItelemetryItem Ikey");
|
|
102
|
+
this.clock.tick(15000);
|
|
103
|
+
QUnit.assert.equal(true, loggerSpy.calledOnce, "The send has been triggered");
|
|
104
|
+
}
|
|
105
|
+
})
|
|
106
|
+
|
|
107
|
+
this.testCase({
|
|
108
|
+
name: "telemetry is not send when legacy telemetry initializer returns false",
|
|
109
|
+
test: () => {
|
|
110
|
+
const cr = new AppInsightsCore();
|
|
111
|
+
cr.logger = new DiagnosticLogger({instrumentationKey: "ikey"});
|
|
112
|
+
this._sender.initialize({
|
|
113
|
+
instrumentationKey: 'abc'
|
|
114
|
+
}, cr, []);
|
|
115
|
+
|
|
116
|
+
const nextPlugin = <ITelemetryPlugin> {
|
|
117
|
+
identifier: "foo",
|
|
118
|
+
processTelemetry: (it) => {},
|
|
119
|
+
priority: 200,
|
|
120
|
+
setNextPlugin: (it) => {}
|
|
121
|
+
};
|
|
122
|
+
this._sender.setNextPlugin(nextPlugin);
|
|
123
|
+
|
|
124
|
+
const processTelemetrySpy = this.sandbox.stub(nextPlugin, "processTelemetry");
|
|
125
|
+
const telemetryItem: ITelemetryItem = {
|
|
126
|
+
name: 'fake item',
|
|
127
|
+
iKey: 'iKey',
|
|
128
|
+
baseType: 'some type',
|
|
129
|
+
baseData: {},
|
|
130
|
+
tags: [
|
|
131
|
+
]
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
telemetryItem.tags["ProcessLegacy"] = [e => true, e => false, f=> true];
|
|
135
|
+
try {
|
|
136
|
+
this._sender.processTelemetry(telemetryItem, null);
|
|
137
|
+
} catch(e) {
|
|
138
|
+
QUnit.assert.ok(false);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
QUnit.assert.ok(!processTelemetrySpy.calledOnce);
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
this.testCase({
|
|
146
|
+
name: 'BeaconAPI is not used when isBeaconApiDisabled flag is true',
|
|
147
|
+
test: () => {
|
|
148
|
+
let sendBeaconCalled = false;
|
|
149
|
+
this.hookSendBeacon((url: string) => {
|
|
150
|
+
sendBeaconCalled = true;
|
|
151
|
+
return true;
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
const sender = new Sender();
|
|
155
|
+
const cr = new AppInsightsCore();
|
|
156
|
+
|
|
157
|
+
sender.initialize({
|
|
158
|
+
instrumentationKey: 'abc',
|
|
159
|
+
isBeaconApiDisabled: true
|
|
160
|
+
}, cr, []);
|
|
161
|
+
|
|
162
|
+
const telemetryItem: ITelemetryItem = {
|
|
163
|
+
name: 'fake item',
|
|
164
|
+
iKey: 'iKey',
|
|
165
|
+
baseType: 'some type',
|
|
166
|
+
baseData: {}
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
QUnit.assert.ok(Util.IsBeaconApiSupported(), "Beacon API is supported");
|
|
170
|
+
QUnit.assert.equal(false, sendBeaconCalled, "Beacon API was not called before");
|
|
171
|
+
QUnit.assert.equal(0, this._getXhrRequests().length, "xhr sender was not called before");
|
|
172
|
+
|
|
173
|
+
try {
|
|
174
|
+
sender.processTelemetry(telemetryItem, null);
|
|
175
|
+
sender.flush();
|
|
176
|
+
} catch(e) {
|
|
177
|
+
QUnit.assert.ok(false);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
QUnit.assert.equal(false, sendBeaconCalled, "Beacon API is disabled, Beacon API is not called");
|
|
181
|
+
QUnit.assert.equal(1, this._getXhrRequests().length, "xhr sender is called when Beacon API is disabled");
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
this.testCase({
|
|
186
|
+
name: 'beaconSender is called when isBeaconApiDisabled flag is false',
|
|
187
|
+
useFakeTimers: true,
|
|
188
|
+
test: () => {
|
|
189
|
+
let sendBeaconCalled = false;
|
|
190
|
+
this.hookSendBeacon((url: string) => {
|
|
191
|
+
sendBeaconCalled = true;
|
|
192
|
+
return true;
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
const cr = new AppInsightsCore();
|
|
196
|
+
const sender = new Sender();
|
|
197
|
+
|
|
198
|
+
sender.initialize({
|
|
199
|
+
instrumentationKey: 'abc',
|
|
200
|
+
isBeaconApiDisabled: false
|
|
201
|
+
}, cr, []);
|
|
202
|
+
|
|
203
|
+
const telemetryItem: ITelemetryItem = {
|
|
204
|
+
name: 'fake item',
|
|
205
|
+
iKey: 'iKey',
|
|
206
|
+
baseType: 'some type',
|
|
207
|
+
baseData: {}
|
|
208
|
+
};
|
|
209
|
+
|
|
210
|
+
QUnit.assert.ok(Util.IsBeaconApiSupported(), "Beacon API is supported");
|
|
211
|
+
QUnit.assert.equal(false, sendBeaconCalled, "Beacon API was not called before");
|
|
212
|
+
QUnit.assert.equal(0, this._getXhrRequests().length, "xhr sender was not called before");
|
|
213
|
+
|
|
214
|
+
try {
|
|
215
|
+
sender.processTelemetry(telemetryItem, null);
|
|
216
|
+
sender.flush();
|
|
217
|
+
} catch(e) {
|
|
218
|
+
QUnit.assert.ok(false);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
this.clock.tick(15000);
|
|
222
|
+
|
|
223
|
+
QUnit.assert.equal(0, this._getXhrRequests().length, "xhr sender is not called when Beacon API is enabled");
|
|
224
|
+
QUnit.assert.equal(true, sendBeaconCalled, "Beacon API is enabled, Beacon API is called");
|
|
225
|
+
}
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
this.testCase({
|
|
229
|
+
name: 'BeaconAPI is not used when isBeaconApiDisabled flag is false but payload size is over 64k, fall off to xhr sender',
|
|
230
|
+
useFakeTimers: true,
|
|
231
|
+
test: () => {
|
|
232
|
+
let sendBeaconCalled = false;
|
|
233
|
+
this.hookSendBeacon((url: string) => {
|
|
234
|
+
sendBeaconCalled = true;
|
|
235
|
+
return false;
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
const sender = new Sender();
|
|
239
|
+
const cr = new AppInsightsCore();
|
|
240
|
+
cr["logger"] = new DiagnosticLogger();
|
|
241
|
+
const MAX_PROPERTIES_SIZE = 8000;
|
|
242
|
+
const payload = new Array(MAX_PROPERTIES_SIZE).join('a');
|
|
243
|
+
|
|
244
|
+
sender.initialize({
|
|
245
|
+
instrumentationKey: 'abc',
|
|
246
|
+
isBeaconApiDisabled: false
|
|
247
|
+
}, cr, []);
|
|
248
|
+
|
|
249
|
+
const telemetryItems: ITelemetryItem[] = [];
|
|
250
|
+
for (let i = 0; i < 8; i ++) {
|
|
251
|
+
const telemetryItem: ITelemetryItem = {
|
|
252
|
+
name: 'fake item',
|
|
253
|
+
iKey: 'iKey',
|
|
254
|
+
baseType: 'some type',
|
|
255
|
+
baseData: {},
|
|
256
|
+
data: {
|
|
257
|
+
properties: {
|
|
258
|
+
payload
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
};
|
|
262
|
+
telemetryItems[i] = telemetryItem;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
QUnit.assert.ok(Util.IsBeaconApiSupported(), "Beacon API is supported");
|
|
266
|
+
QUnit.assert.equal(false, sendBeaconCalled, "Beacon API was not called before");
|
|
267
|
+
QUnit.assert.equal(0, this._getXhrRequests().length, "xhr sender was not called before");
|
|
268
|
+
|
|
269
|
+
try {
|
|
270
|
+
for (let i = 0; i < 8; i++) {
|
|
271
|
+
sender.processTelemetry(telemetryItems[i], null);
|
|
272
|
+
}
|
|
273
|
+
sender.flush();
|
|
274
|
+
} catch(e) {
|
|
275
|
+
QUnit.assert.ok(false);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
this.clock.tick(15000);
|
|
279
|
+
|
|
280
|
+
QUnit.assert.equal(true, sendBeaconCalled, "Beacon API is enabled but payload is over size, Beacon API is called");
|
|
281
|
+
QUnit.assert.ok(this._getXhrRequests().length > 0, "xhr sender is called when payload is over size");
|
|
282
|
+
}
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
this.testCase({
|
|
286
|
+
name: 'FetchAPI is used when isBeaconApiDisabled flag is true and disableXhr flag is true , use fetch sender.',
|
|
287
|
+
test: () => {
|
|
288
|
+
let window = getGlobalInst("window");
|
|
289
|
+
let fakeXMLHttpRequest = (window as any).XMLHttpRequest;
|
|
290
|
+
let fetchstub = this.sandbox.stub((window as any), "fetch");
|
|
291
|
+
|
|
292
|
+
let sendBeaconCalled = false;
|
|
293
|
+
this.hookSendBeacon((url: string) => {
|
|
294
|
+
sendBeaconCalled = true;
|
|
295
|
+
return false;
|
|
296
|
+
});
|
|
297
|
+
|
|
298
|
+
const sender = new Sender();
|
|
299
|
+
const cr = new AppInsightsCore();
|
|
300
|
+
|
|
301
|
+
sender.initialize({
|
|
302
|
+
instrumentationKey: 'abc',
|
|
303
|
+
isBeaconApiDisabled: true,
|
|
304
|
+
disableXhr: true
|
|
305
|
+
}, cr, []);
|
|
306
|
+
|
|
307
|
+
const telemetryItem: ITelemetryItem = {
|
|
308
|
+
name: 'fake item',
|
|
309
|
+
iKey: 'iKey',
|
|
310
|
+
baseType: 'some type',
|
|
311
|
+
baseData: {}
|
|
312
|
+
};
|
|
313
|
+
|
|
314
|
+
QUnit.assert.ok(Util.IsBeaconApiSupported(), "Beacon API is supported");
|
|
315
|
+
QUnit.assert.equal(false, sendBeaconCalled, "Beacon API was not called before");
|
|
316
|
+
QUnit.assert.equal(0, this._getXhrRequests().length, "xhr sender was not called before");
|
|
317
|
+
|
|
318
|
+
try {
|
|
319
|
+
sender.processTelemetry(telemetryItem, null);
|
|
320
|
+
sender.flush();
|
|
321
|
+
} catch(e) {
|
|
322
|
+
QUnit.assert.ok(false);
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
QUnit.assert.equal(false, sendBeaconCalled, "Beacon API is disabled, Beacon API is not called");
|
|
326
|
+
QUnit.assert.equal(0, this._getXhrRequests().length, "xhr sender is not called");
|
|
327
|
+
QUnit.assert.ok(fetchstub.called, "fetch sender is called");
|
|
328
|
+
// store it back
|
|
329
|
+
(window as any).XMLHttpRequest = fakeXMLHttpRequest;
|
|
330
|
+
}
|
|
331
|
+
});
|
|
332
|
+
|
|
333
|
+
this.testCase({
|
|
334
|
+
name: 'FetchAPI is used when isBeaconApiDisabled flag is true and XMLHttpRequest is not supported, use fetch sender.',
|
|
335
|
+
test: () => {
|
|
336
|
+
let window = getGlobalInst("window");
|
|
337
|
+
let fakeXMLHttpRequest = (window as any).XMLHttpRequest;
|
|
338
|
+
(window as any).XMLHttpRequest = undefined;
|
|
339
|
+
let fetchstub = this.sandbox.stub((window as any), "fetch");
|
|
340
|
+
|
|
341
|
+
let sendBeaconCalled = false;
|
|
342
|
+
this.hookSendBeacon((url: string) => {
|
|
343
|
+
sendBeaconCalled = true;
|
|
344
|
+
return false;
|
|
345
|
+
});
|
|
346
|
+
|
|
347
|
+
const sender = new Sender();
|
|
348
|
+
const cr = new AppInsightsCore();
|
|
349
|
+
|
|
350
|
+
sender.initialize({
|
|
351
|
+
instrumentationKey: 'abc',
|
|
352
|
+
isBeaconApiDisabled: true
|
|
353
|
+
}, cr, []);
|
|
354
|
+
|
|
355
|
+
const telemetryItem: ITelemetryItem = {
|
|
356
|
+
name: 'fake item',
|
|
357
|
+
iKey: 'iKey',
|
|
358
|
+
baseType: 'some type',
|
|
359
|
+
baseData: {}
|
|
360
|
+
};
|
|
361
|
+
|
|
362
|
+
QUnit.assert.ok(Util.IsBeaconApiSupported(), "Beacon API is supported");
|
|
363
|
+
QUnit.assert.equal(false, sendBeaconCalled, "Beacon API was not called before");
|
|
364
|
+
QUnit.assert.equal(0, this._getXhrRequests().length, "xhr sender was not called before");
|
|
365
|
+
|
|
366
|
+
try {
|
|
367
|
+
sender.processTelemetry(telemetryItem, null);
|
|
368
|
+
sender.flush();
|
|
369
|
+
} catch(e) {
|
|
370
|
+
QUnit.assert.ok(false);
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
QUnit.assert.equal(false, sendBeaconCalled, "Beacon API is disabled, Beacon API is not called");
|
|
374
|
+
QUnit.assert.equal(0, this._getXhrRequests().length, "xhr sender is not called");
|
|
375
|
+
QUnit.assert.ok(fetchstub.called, "fetch sender is called");
|
|
376
|
+
// store it back
|
|
377
|
+
(window as any).XMLHttpRequest = fakeXMLHttpRequest;
|
|
378
|
+
}
|
|
379
|
+
});
|
|
380
|
+
|
|
381
|
+
this.testCase({
|
|
382
|
+
name: 'Users are not allowed to add customHeaders when endpointUrl is Breeze.',
|
|
383
|
+
test: () => {
|
|
384
|
+
let sendBeaconCalled = false;
|
|
385
|
+
this.hookSendBeacon((url: string) => {
|
|
386
|
+
sendBeaconCalled = true;
|
|
387
|
+
return true;
|
|
388
|
+
});
|
|
389
|
+
|
|
390
|
+
const sender = new Sender();
|
|
391
|
+
const cr = new AppInsightsCore();
|
|
392
|
+
|
|
393
|
+
sender.initialize({
|
|
394
|
+
instrumentationKey: 'abc',
|
|
395
|
+
isBeaconApiDisabled: true,
|
|
396
|
+
customHeaders: [
|
|
397
|
+
{
|
|
398
|
+
header: 'testHeader',
|
|
399
|
+
value: 'testValue'
|
|
400
|
+
}
|
|
401
|
+
]
|
|
402
|
+
}, cr, []);
|
|
403
|
+
|
|
404
|
+
const telemetryItem: ITelemetryItem = {
|
|
405
|
+
name: 'fake item',
|
|
406
|
+
iKey: 'iKey',
|
|
407
|
+
baseType: 'some type',
|
|
408
|
+
baseData: {}
|
|
409
|
+
};
|
|
410
|
+
|
|
411
|
+
try {
|
|
412
|
+
sender.processTelemetry(telemetryItem, null);
|
|
413
|
+
sender.flush();
|
|
414
|
+
} catch(e) {
|
|
415
|
+
QUnit.assert.ok(false);
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
QUnit.assert.equal(1, this._getXhrRequests().length, "xhr sender is called");
|
|
419
|
+
QUnit.assert.notOk(this._getXhrRequests()[0].requestHeaders.hasOwnProperty('testHeader'));
|
|
420
|
+
}
|
|
421
|
+
});
|
|
422
|
+
|
|
423
|
+
this.testCase({
|
|
424
|
+
name: 'Users are allowed to add customHeaders when endpointUrl is not Breeze.',
|
|
425
|
+
test: () => {
|
|
426
|
+
let sendBeaconCalled = false;
|
|
427
|
+
this.hookSendBeacon((url: string) => {
|
|
428
|
+
sendBeaconCalled = true;
|
|
429
|
+
return true;
|
|
430
|
+
});
|
|
431
|
+
|
|
432
|
+
const sender = new Sender();
|
|
433
|
+
const cr = new AppInsightsCore();
|
|
434
|
+
|
|
435
|
+
sender.initialize({
|
|
436
|
+
instrumentationKey: 'abc',
|
|
437
|
+
isBeaconApiDisabled: true,
|
|
438
|
+
endpointUrl: 'https://example.com',
|
|
439
|
+
customHeaders: [
|
|
440
|
+
{
|
|
441
|
+
header: 'testHeader',
|
|
442
|
+
value: 'testValue'
|
|
443
|
+
}
|
|
444
|
+
]
|
|
445
|
+
}, cr, []);
|
|
446
|
+
|
|
447
|
+
const telemetryItem: ITelemetryItem = {
|
|
448
|
+
name: 'fake item',
|
|
449
|
+
iKey: 'iKey',
|
|
450
|
+
baseType: 'some type',
|
|
451
|
+
baseData: {}
|
|
452
|
+
};
|
|
453
|
+
|
|
454
|
+
try {
|
|
455
|
+
sender.processTelemetry(telemetryItem, null);
|
|
456
|
+
sender.flush();
|
|
457
|
+
} catch(e) {
|
|
458
|
+
QUnit.assert.ok(false);
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
QUnit.assert.equal(1, this._getXhrRequests().length, "xhr sender is called");
|
|
462
|
+
QUnit.assert.ok(this._getXhrRequests()[0].requestHeaders.hasOwnProperty('testHeader'));
|
|
463
|
+
QUnit.assert.equal(this._getXhrRequests()[0].requestHeaders.testHeader, 'testValue');
|
|
464
|
+
}
|
|
465
|
+
});
|
|
466
|
+
|
|
467
|
+
this.testCase({
|
|
468
|
+
name: 'Users are allowed to add customHeaders via addHeader method.',
|
|
469
|
+
test: () => {
|
|
470
|
+
let sendBeaconCalled = false;
|
|
471
|
+
this.hookSendBeacon((url: string) => {
|
|
472
|
+
sendBeaconCalled = true;
|
|
473
|
+
return true;
|
|
474
|
+
});
|
|
475
|
+
|
|
476
|
+
const sender = new Sender();
|
|
477
|
+
const cr = new AppInsightsCore();
|
|
478
|
+
|
|
479
|
+
sender.addHeader('testHeader', 'testValue');
|
|
480
|
+
|
|
481
|
+
sender.initialize({
|
|
482
|
+
instrumentationKey: 'abc',
|
|
483
|
+
isBeaconApiDisabled: true
|
|
484
|
+
}, cr, []);
|
|
485
|
+
|
|
486
|
+
const telemetryItem: ITelemetryItem = {
|
|
487
|
+
name: 'fake item',
|
|
488
|
+
iKey: 'iKey',
|
|
489
|
+
baseType: 'some type',
|
|
490
|
+
baseData: {}
|
|
491
|
+
};
|
|
492
|
+
|
|
493
|
+
try {
|
|
494
|
+
sender.processTelemetry(telemetryItem, null);
|
|
495
|
+
sender.flush();
|
|
496
|
+
} catch(e) {
|
|
497
|
+
QUnit.assert.ok(false);
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
QUnit.assert.equal(1, this._getXhrRequests().length, "xhr sender is called");
|
|
501
|
+
QUnit.assert.ok(this._getXhrRequests()[0].requestHeaders.hasOwnProperty('testHeader'));
|
|
502
|
+
QUnit.assert.equal(this._getXhrRequests()[0].requestHeaders.testHeader, 'testValue');
|
|
503
|
+
}
|
|
504
|
+
});
|
|
505
|
+
|
|
506
|
+
this.testCase({
|
|
507
|
+
name: "AppInsightsTests: AppInsights Envelope created for Custom Event",
|
|
508
|
+
test: () => {
|
|
509
|
+
const inputEnvelope: ITelemetryItem = {
|
|
510
|
+
name: "test",
|
|
511
|
+
time: new Date("2018-06-12").toISOString(),
|
|
512
|
+
iKey: "iKey",
|
|
513
|
+
ext: {
|
|
514
|
+
app: {
|
|
515
|
+
sesId: "d041d2e5fa834b4f9eee41ac163bf402"
|
|
516
|
+
},
|
|
517
|
+
device: {
|
|
518
|
+
deviceClass: "Browser",
|
|
519
|
+
localId: "browser"
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
},
|
|
523
|
+
tags: [{"ai.internal.sdkVersion": "javascript:2.5.1"}],
|
|
524
|
+
data: {
|
|
525
|
+
"property1": "val1",
|
|
526
|
+
"measurement1": 50.0,
|
|
527
|
+
"measurement2": 1.3,
|
|
528
|
+
"property2": "val2"
|
|
529
|
+
},
|
|
530
|
+
baseData: {
|
|
531
|
+
"name": "Event Name"
|
|
532
|
+
}
|
|
533
|
+
};
|
|
534
|
+
const appInsightsEnvelope = Sender.constructEnvelope(inputEnvelope, this._instrumentationKey, null);
|
|
535
|
+
|
|
536
|
+
const baseData = appInsightsEnvelope.data.baseData;
|
|
537
|
+
|
|
538
|
+
// Assert measurements
|
|
539
|
+
const resultMeasurements = baseData.measurements;
|
|
540
|
+
QUnit.assert.ok(resultMeasurements);
|
|
541
|
+
QUnit.assert.ok(resultMeasurements["measurement1"]);
|
|
542
|
+
QUnit.assert.equal(50.0, resultMeasurements["measurement1"]);
|
|
543
|
+
QUnit.assert.ok(resultMeasurements["measurement2"]);
|
|
544
|
+
QUnit.assert.equal(1.3, resultMeasurements["measurement2"]);
|
|
545
|
+
|
|
546
|
+
// Assert custom properties
|
|
547
|
+
QUnit.assert.ok(baseData.properties);
|
|
548
|
+
QUnit.assert.equal("val1", baseData.properties["property1"]);
|
|
549
|
+
QUnit.assert.equal("val2", baseData.properties["property2"]);
|
|
550
|
+
|
|
551
|
+
// Assert Event name
|
|
552
|
+
QUnit.assert.ok(baseData.name);
|
|
553
|
+
QUnit.assert.equal("Event Name", baseData.name);
|
|
554
|
+
|
|
555
|
+
// Assert ver
|
|
556
|
+
QUnit.assert.ok(baseData.ver);
|
|
557
|
+
QUnit.assert.equal(2, baseData.ver);
|
|
558
|
+
|
|
559
|
+
// Assert baseType added by default
|
|
560
|
+
QUnit.assert.ok(appInsightsEnvelope.data.baseType);
|
|
561
|
+
QUnit.assert.equal("EventData", appInsightsEnvelope.data.baseType);
|
|
562
|
+
|
|
563
|
+
// Assert tags
|
|
564
|
+
QUnit.assert.ok(appInsightsEnvelope.tags);
|
|
565
|
+
QUnit.assert.equal("d041d2e5fa834b4f9eee41ac163bf402", appInsightsEnvelope.tags["ai.session.id"]);
|
|
566
|
+
QUnit.assert.equal("browser", appInsightsEnvelope.tags["ai.device.id"]);
|
|
567
|
+
QUnit.assert.equal("Browser", appInsightsEnvelope.tags["ai.device.type"]);
|
|
568
|
+
QUnit.assert.equal("javascript:2.5.1", appInsightsEnvelope.tags["ai.internal.sdkVersion"]);
|
|
569
|
+
|
|
570
|
+
// Assert name
|
|
571
|
+
QUnit.assert.ok(appInsightsEnvelope.name);
|
|
572
|
+
QUnit.assert.equal("Microsoft.ApplicationInsights.iKey.Event", appInsightsEnvelope.name);
|
|
573
|
+
|
|
574
|
+
// Assert iKey
|
|
575
|
+
QUnit.assert.ok(appInsightsEnvelope.iKey);
|
|
576
|
+
QUnit.assert.equal("iKey", appInsightsEnvelope.iKey);
|
|
577
|
+
|
|
578
|
+
// Assert timestamp
|
|
579
|
+
QUnit.assert.ok(appInsightsEnvelope.time);
|
|
580
|
+
}
|
|
581
|
+
});
|
|
582
|
+
|
|
583
|
+
this.testCase({
|
|
584
|
+
name: "AppInsightsTests: AppInsights Envelope use default config iKey when iKey of ItelemetryItem is empty",
|
|
585
|
+
test: () => {
|
|
586
|
+
const inputEnvelope: ITelemetryItem = {
|
|
587
|
+
name: "test",
|
|
588
|
+
iKey: "",
|
|
589
|
+
ext: {},
|
|
590
|
+
data: { "property1": "val1"},
|
|
591
|
+
baseData: {
|
|
592
|
+
"name": "Event Name"
|
|
593
|
+
}
|
|
594
|
+
};
|
|
595
|
+
const appInsightsEnvelope = Sender.constructEnvelope(inputEnvelope, this._instrumentationKey, null);
|
|
596
|
+
|
|
597
|
+
const baseData = appInsightsEnvelope.data.baseData;
|
|
598
|
+
|
|
599
|
+
// Assert Event name
|
|
600
|
+
QUnit.assert.ok(baseData.name);
|
|
601
|
+
QUnit.assert.equal("Event Name", baseData.name);
|
|
602
|
+
|
|
603
|
+
// Assert name
|
|
604
|
+
QUnit.assert.ok(appInsightsEnvelope.name);
|
|
605
|
+
QUnit.assert.equal("Microsoft.ApplicationInsights.iKey.Event", appInsightsEnvelope.name);
|
|
606
|
+
|
|
607
|
+
// Assert iKey
|
|
608
|
+
QUnit.assert.ok(appInsightsEnvelope.iKey);
|
|
609
|
+
QUnit.assert.equal( this._instrumentationKey, appInsightsEnvelope.iKey, "default config iKey is not set");
|
|
610
|
+
}
|
|
611
|
+
});
|
|
612
|
+
|
|
613
|
+
this.testCase({
|
|
614
|
+
name: "AppInsightsTests: AppInsights Envelope unknown type returns custom Event data type",
|
|
615
|
+
test: () => {
|
|
616
|
+
const inputEnvelope: ITelemetryItem = {
|
|
617
|
+
name: "test",
|
|
618
|
+
time: new Date("2018-06-12").toISOString(),
|
|
619
|
+
iKey: "iKey",
|
|
620
|
+
ext: {
|
|
621
|
+
"ai.session.id": "d041d2e5fa834b4f9eee41ac163bf402",
|
|
622
|
+
"ai.device.id": "browser",
|
|
623
|
+
"ai.device.type": "Browser",
|
|
624
|
+
},
|
|
625
|
+
tags: [{}],
|
|
626
|
+
data: {
|
|
627
|
+
"property1": "val1",
|
|
628
|
+
"measurement1": 50.0,
|
|
629
|
+
"measurement2": 1.3,
|
|
630
|
+
"property2": "val2"
|
|
631
|
+
},
|
|
632
|
+
baseType: "PageUnloadData",
|
|
633
|
+
baseData: {
|
|
634
|
+
id: "EADE2F09-DEBA-4B60-A222-E1D80BB8AA7F",
|
|
635
|
+
vpHeight: 1002,
|
|
636
|
+
vScrollOffset: 292
|
|
637
|
+
}
|
|
638
|
+
};
|
|
639
|
+
const appInsightsEnvelope = Sender.constructEnvelope(inputEnvelope, this._instrumentationKey, null);
|
|
640
|
+
const baseData = appInsightsEnvelope.data.baseData;
|
|
641
|
+
|
|
642
|
+
// Assert measurements
|
|
643
|
+
const resultMeasurements = baseData.measurements;
|
|
644
|
+
QUnit.assert.ok(resultMeasurements);
|
|
645
|
+
QUnit.assert.ok(resultMeasurements["measurement1"]);
|
|
646
|
+
QUnit.assert.equal(50.0, resultMeasurements["measurement1"]);
|
|
647
|
+
QUnit.assert.ok(resultMeasurements["measurement2"]);
|
|
648
|
+
QUnit.assert.equal(1.3, resultMeasurements["measurement2"]);
|
|
649
|
+
QUnit.assert.ok(resultMeasurements["vpHeight"]);
|
|
650
|
+
QUnit.assert.equal(1002, resultMeasurements["vpHeight"]);
|
|
651
|
+
QUnit.assert.ok(resultMeasurements["vScrollOffset"]);
|
|
652
|
+
QUnit.assert.equal(292, resultMeasurements["vScrollOffset"]);
|
|
653
|
+
|
|
654
|
+
// Assert custom properties
|
|
655
|
+
QUnit.assert.ok(baseData.properties);
|
|
656
|
+
QUnit.assert.equal("val1", baseData.properties["property1"]);
|
|
657
|
+
QUnit.assert.equal("val2", baseData.properties["property2"]);
|
|
658
|
+
QUnit.assert.equal("EADE2F09-DEBA-4B60-A222-E1D80BB8AA7F", baseData.properties["id"]);
|
|
659
|
+
|
|
660
|
+
// Assert Event name
|
|
661
|
+
QUnit.assert.ok(baseData.name);
|
|
662
|
+
QUnit.assert.equal("PageUnloadData", baseData.properties['baseTypeSource']);
|
|
663
|
+
|
|
664
|
+
// Assert ver
|
|
665
|
+
QUnit.assert.ok(baseData.ver);
|
|
666
|
+
QUnit.assert.equal(2, baseData.ver);
|
|
667
|
+
|
|
668
|
+
QUnit.assert.equal("javascript:2.7.2-nightly.2111-09", appInsightsEnvelope.tags["ai.internal.sdkVersion"]);
|
|
669
|
+
}
|
|
670
|
+
})
|
|
671
|
+
|
|
672
|
+
this.testCase({
|
|
673
|
+
name: "AppInsightsTests: AppInsights Envelope create for Dependency Data",
|
|
674
|
+
test: () => {
|
|
675
|
+
// setup
|
|
676
|
+
const inputEnvelope: ITelemetryItem = {
|
|
677
|
+
name: "test",
|
|
678
|
+
time: new Date("2018-06-12").toISOString(),
|
|
679
|
+
iKey: "iKey",
|
|
680
|
+
ext: {
|
|
681
|
+
"user" : {
|
|
682
|
+
"localId": "TestId",
|
|
683
|
+
"authId": "AuthenticatedId",
|
|
684
|
+
"id": "TestId"
|
|
685
|
+
}
|
|
686
|
+
},
|
|
687
|
+
tags: [{"ai.user.accountId": "TestAccountId"},
|
|
688
|
+
{"ai.location.ip": "10.22.8.2"}],
|
|
689
|
+
baseType: "RemoteDependencyData",
|
|
690
|
+
baseData: {
|
|
691
|
+
id: 'some id',
|
|
692
|
+
name: "Some name given",
|
|
693
|
+
success: true,
|
|
694
|
+
responseCode: 200,
|
|
695
|
+
duration: 123,
|
|
696
|
+
type: 'Fetch',
|
|
697
|
+
data: 'some data',
|
|
698
|
+
target: 'https://example.com/test/name?q=bar',
|
|
699
|
+
correlationContext: "cid-v1:foo"
|
|
700
|
+
},
|
|
701
|
+
data: {
|
|
702
|
+
property1: "val1",
|
|
703
|
+
property2: "val2",
|
|
704
|
+
measurement1: 50.0,
|
|
705
|
+
measurement2: 1.3
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
// act
|
|
711
|
+
const appInsightsEnvelope = Sender.constructEnvelope(inputEnvelope, this._instrumentationKey, null);
|
|
712
|
+
const { baseData } = appInsightsEnvelope.data;
|
|
713
|
+
|
|
714
|
+
// assert
|
|
715
|
+
const resultDuration = baseData.duration;
|
|
716
|
+
QUnit.assert.equal("00:00:00.123", resultDuration);
|
|
717
|
+
|
|
718
|
+
// Assert measurements
|
|
719
|
+
const resultMeasurements = baseData.measurements;
|
|
720
|
+
QUnit.assert.ok(resultMeasurements);
|
|
721
|
+
QUnit.assert.ok(resultMeasurements["measurement1"]);
|
|
722
|
+
QUnit.assert.equal(50.0, resultMeasurements["measurement1"]);
|
|
723
|
+
QUnit.assert.ok(resultMeasurements["measurement2"]);
|
|
724
|
+
QUnit.assert.equal(1.3, resultMeasurements["measurement2"]);
|
|
725
|
+
QUnit.assert.ok(!resultMeasurements.duration, "duration is not supposed to be treated as measurement");
|
|
726
|
+
|
|
727
|
+
// Assert custom properties
|
|
728
|
+
QUnit.assert.ok(baseData.properties);
|
|
729
|
+
QUnit.assert.equal("val1", baseData.properties["property1"]);
|
|
730
|
+
QUnit.assert.equal("val2", baseData.properties["property2"]);
|
|
731
|
+
|
|
732
|
+
// Assert baseData
|
|
733
|
+
QUnit.assert.ok(baseData.name);
|
|
734
|
+
QUnit.assert.equal("Some name given", baseData.data);
|
|
735
|
+
QUnit.assert.equal("some id", baseData.id);
|
|
736
|
+
QUnit.assert.equal(true, baseData.success);
|
|
737
|
+
QUnit.assert.equal(200, baseData.resultCode);
|
|
738
|
+
QUnit.assert.equal("Some name given", baseData.name);
|
|
739
|
+
QUnit.assert.equal("example.com | cid-v1:foo", baseData.target);
|
|
740
|
+
|
|
741
|
+
// Assert ver
|
|
742
|
+
QUnit.assert.ok(baseData.ver);
|
|
743
|
+
QUnit.assert.equal(2, baseData.ver);
|
|
744
|
+
|
|
745
|
+
// Assert baseType
|
|
746
|
+
QUnit.assert.ok(appInsightsEnvelope.data.baseType);
|
|
747
|
+
QUnit.assert.equal("RemoteDependencyData", appInsightsEnvelope.data.baseType);
|
|
748
|
+
|
|
749
|
+
// Assert tags
|
|
750
|
+
QUnit.assert.ok(appInsightsEnvelope.tags);
|
|
751
|
+
QUnit.assert.equal("TestAccountId", appInsightsEnvelope.tags["ai.user.accountId"]);
|
|
752
|
+
QUnit.assert.equal("10.22.8.2", appInsightsEnvelope.tags["ai.location.ip"]);
|
|
753
|
+
|
|
754
|
+
QUnit.assert.equal("AuthenticatedId", appInsightsEnvelope.tags["ai.user.authUserId"]);
|
|
755
|
+
QUnit.assert.equal("TestId", appInsightsEnvelope.tags["ai.user.id"]);
|
|
756
|
+
|
|
757
|
+
// Assert name
|
|
758
|
+
QUnit.assert.ok(appInsightsEnvelope.name);
|
|
759
|
+
QUnit.assert.equal("Microsoft.ApplicationInsights.iKey.RemoteDependency", appInsightsEnvelope.name);
|
|
760
|
+
|
|
761
|
+
// Assert iKey
|
|
762
|
+
QUnit.assert.ok(appInsightsEnvelope.iKey);
|
|
763
|
+
QUnit.assert.equal("iKey", appInsightsEnvelope.iKey);
|
|
764
|
+
|
|
765
|
+
// Assert timestamp
|
|
766
|
+
QUnit.assert.ok(appInsightsEnvelope.time);
|
|
767
|
+
}
|
|
768
|
+
});
|
|
769
|
+
|
|
770
|
+
this.testCase({
|
|
771
|
+
name: "AppInsightsTests: When name is not provided, it is obtained from hostname",
|
|
772
|
+
test: () => {
|
|
773
|
+
// setup
|
|
774
|
+
const inputEnvelope: ITelemetryItem = {
|
|
775
|
+
name: "test",
|
|
776
|
+
time: new Date("2018-06-12").toISOString(),
|
|
777
|
+
iKey: "iKey",
|
|
778
|
+
ext: {
|
|
779
|
+
"user" : {
|
|
780
|
+
"localId": "TestId",
|
|
781
|
+
"authId": "AuthenticatedId",
|
|
782
|
+
"id": "TestId"
|
|
783
|
+
}
|
|
784
|
+
},
|
|
785
|
+
tags: [{"ai.user.accountId": "TestAccountId"},
|
|
786
|
+
{"ai.location.ip": "10.22.8.2"}, {"ai.internal.sdkVersion": "1234"}],
|
|
787
|
+
baseType: "RemoteDependencyData",
|
|
788
|
+
baseData: {
|
|
789
|
+
id: 'some id',
|
|
790
|
+
success: true,
|
|
791
|
+
responseCode: 200,
|
|
792
|
+
duration: 123,
|
|
793
|
+
type: 'Fetch',
|
|
794
|
+
data: 'some data',
|
|
795
|
+
target: 'https://example.com/test/name'
|
|
796
|
+
},
|
|
797
|
+
data: {
|
|
798
|
+
property1: "val1",
|
|
799
|
+
property2: "val2",
|
|
800
|
+
measurement1: 50.0,
|
|
801
|
+
measurement2: 1.3
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
}
|
|
805
|
+
|
|
806
|
+
// act
|
|
807
|
+
const appInsightsEnvelope = Sender.constructEnvelope(inputEnvelope, this._instrumentationKey, null);
|
|
808
|
+
const { baseData } = appInsightsEnvelope.data;
|
|
809
|
+
|
|
810
|
+
// Assert baseData
|
|
811
|
+
QUnit.assert.ok(baseData.name);
|
|
812
|
+
QUnit.assert.equal("GET /test/name", baseData.name); // retrieved from target
|
|
813
|
+
QUnit.assert.equal("/test/name", baseData.data);
|
|
814
|
+
|
|
815
|
+
// Assert sdkVersion
|
|
816
|
+
QUnit.assert.equal("1234", appInsightsEnvelope.tags["ai.internal.sdkVersion"])
|
|
817
|
+
}
|
|
818
|
+
});
|
|
819
|
+
|
|
820
|
+
this.testCase({
|
|
821
|
+
name: "AppInsightsTests: AppInsights Envelope created for Page View",
|
|
822
|
+
test: () => {
|
|
823
|
+
// setup
|
|
824
|
+
const inputEnvelope: ITelemetryItem = {
|
|
825
|
+
name: "test",
|
|
826
|
+
time: new Date("2018-06-12").toISOString(),
|
|
827
|
+
iKey: "iKey",
|
|
828
|
+
ext: {
|
|
829
|
+
"user": {
|
|
830
|
+
"localId": "TestId",
|
|
831
|
+
"authId": "AuthenticatedId",
|
|
832
|
+
"id": "TestId"
|
|
833
|
+
},
|
|
834
|
+
"trace": {
|
|
835
|
+
"traceID": "1528B5FF-6455-4657-BE77-E6664CAC72DC",
|
|
836
|
+
"parentID": "1528B5FF-6455-4657-BE77-E6664CACEEEE"
|
|
837
|
+
}
|
|
838
|
+
},
|
|
839
|
+
tags: [{"ai.user.accountId": "TestAccountId"}],
|
|
840
|
+
baseType: "PageviewData",
|
|
841
|
+
baseData: {
|
|
842
|
+
"name": "Page View Name",
|
|
843
|
+
"uri": "https://fakeUri.com",
|
|
844
|
+
properties: {
|
|
845
|
+
"property1": "val1",
|
|
846
|
+
"property2": "val2",
|
|
847
|
+
"duration": 300000
|
|
848
|
+
},
|
|
849
|
+
measurements: {
|
|
850
|
+
"measurement1": 50.0,
|
|
851
|
+
"measurement2": 1.3,
|
|
852
|
+
}
|
|
853
|
+
},
|
|
854
|
+
data: {
|
|
855
|
+
"property3": "val3",
|
|
856
|
+
"measurement3": 1000
|
|
857
|
+
}
|
|
858
|
+
};
|
|
859
|
+
|
|
860
|
+
// Act
|
|
861
|
+
const appInsightsEnvelope = Sender.constructEnvelope(inputEnvelope, this._instrumentationKey, null);
|
|
862
|
+
const baseData = appInsightsEnvelope.data.baseData;
|
|
863
|
+
|
|
864
|
+
// Assert duration
|
|
865
|
+
const resultDuration = baseData.duration;
|
|
866
|
+
QUnit.assert.equal("00:05:00.000", resultDuration);
|
|
867
|
+
|
|
868
|
+
// Assert measurements
|
|
869
|
+
const resultMeasurements = baseData.measurements;
|
|
870
|
+
const props = baseData.properties;
|
|
871
|
+
QUnit.assert.ok(resultMeasurements);
|
|
872
|
+
QUnit.assert.ok(resultMeasurements["measurement1"]);
|
|
873
|
+
QUnit.assert.equal(50.0, resultMeasurements["measurement1"]);
|
|
874
|
+
QUnit.assert.ok(resultMeasurements["measurement2"]);
|
|
875
|
+
QUnit.assert.equal(1.3, resultMeasurements["measurement2"]);
|
|
876
|
+
QUnit.assert.ok(!resultMeasurements.duration, "duration is not supposed to be treated as property in envelope");
|
|
877
|
+
|
|
878
|
+
// Assert custom properties
|
|
879
|
+
QUnit.assert.ok(baseData.properties);
|
|
880
|
+
QUnit.assert.equal("val1", baseData.properties["property1"]);
|
|
881
|
+
QUnit.assert.equal("val2", baseData.properties["property2"]);
|
|
882
|
+
|
|
883
|
+
// Assert deprecated data custom properties/measurements
|
|
884
|
+
QUnit.assert.equal("val3", baseData.properties["property3"])
|
|
885
|
+
QUnit.assert.equal(1000, baseData.measurements["measurement3"]);
|
|
886
|
+
|
|
887
|
+
// Assert Page View name
|
|
888
|
+
QUnit.assert.ok(baseData.name);
|
|
889
|
+
QUnit.assert.equal("Page View Name", baseData.name);
|
|
890
|
+
|
|
891
|
+
|
|
892
|
+
// Assert ver
|
|
893
|
+
QUnit.assert.ok(baseData.ver);
|
|
894
|
+
QUnit.assert.equal(2, baseData.ver);
|
|
895
|
+
|
|
896
|
+
// Assert baseType
|
|
897
|
+
QUnit.assert.ok(appInsightsEnvelope.data.baseType);
|
|
898
|
+
QUnit.assert.equal("PageviewData", appInsightsEnvelope.data.baseType);
|
|
899
|
+
|
|
900
|
+
// Assert tags
|
|
901
|
+
QUnit.assert.ok(appInsightsEnvelope.tags);
|
|
902
|
+
QUnit.assert.equal("TestAccountId", appInsightsEnvelope.tags["ai.user.accountId"]);
|
|
903
|
+
QUnit.assert.equal("AuthenticatedId", appInsightsEnvelope.tags["ai.user.authUserId"]);
|
|
904
|
+
QUnit.assert.equal("TestId", appInsightsEnvelope.tags["ai.user.id"]);
|
|
905
|
+
|
|
906
|
+
// Assert sdkVersion
|
|
907
|
+
QUnit.assert.ok(EnvelopeCreator.Version)
|
|
908
|
+
QUnit.assert.ok(EnvelopeCreator.Version.length > 0)
|
|
909
|
+
QUnit.assert.equal(`javascript:${EnvelopeCreator.Version}`, appInsightsEnvelope.tags["ai.internal.sdkVersion"])
|
|
910
|
+
|
|
911
|
+
// QUnit.assert.equal("d041d2e5fa834b4f9eee41ac163bf402", appInsightsEnvelope.tags["ai.session.id"]);
|
|
912
|
+
// QUnit.assert.equal("browser", appInsightsEnvelope.tags["ai.device.id"]);
|
|
913
|
+
// QUnit.assert.equal("Browser", appInsightsEnvelope.tags["ai.device.type"]);
|
|
914
|
+
// QUnit.assert.equal("javascript:1.0.18", appInsightsEnvelope.tags["ai.internal.sdkVersion"]);
|
|
915
|
+
|
|
916
|
+
// Assert name
|
|
917
|
+
QUnit.assert.ok(appInsightsEnvelope.name);
|
|
918
|
+
QUnit.assert.equal("Microsoft.ApplicationInsights.iKey.Pageview", appInsightsEnvelope.name);
|
|
919
|
+
|
|
920
|
+
// Assert iKey
|
|
921
|
+
QUnit.assert.ok(appInsightsEnvelope.iKey);
|
|
922
|
+
QUnit.assert.equal("iKey", appInsightsEnvelope.iKey);
|
|
923
|
+
|
|
924
|
+
// Assert timestamp
|
|
925
|
+
QUnit.assert.ok(appInsightsEnvelope.time);
|
|
926
|
+
|
|
927
|
+
|
|
928
|
+
QUnit.assert.equal("1528B5FF-6455-4657-BE77-E6664CAC72DC", appInsightsEnvelope.tags["ai.operation.id"]);
|
|
929
|
+
QUnit.assert.equal("1528B5FF-6455-4657-BE77-E6664CACEEEE", appInsightsEnvelope.tags["ai.operation.parentId"])
|
|
930
|
+
}
|
|
931
|
+
});
|
|
932
|
+
|
|
933
|
+
this.testCase({
|
|
934
|
+
name: "AppInsightsTests: AppInsights Envelope created for Page View with duration in customProperties Part C",
|
|
935
|
+
test: () => {
|
|
936
|
+
// setup
|
|
937
|
+
const inputEnvelope: ITelemetryItem = {
|
|
938
|
+
name: "test",
|
|
939
|
+
time: new Date("2018-06-12").toISOString(),
|
|
940
|
+
iKey: "iKey",
|
|
941
|
+
ext: {
|
|
942
|
+
"user": {
|
|
943
|
+
"localId": "TestId",
|
|
944
|
+
"authId": "AuthenticatedId",
|
|
945
|
+
"id": "TestId"
|
|
946
|
+
},
|
|
947
|
+
"trace": {
|
|
948
|
+
"traceID": "1528B5FF-6455-4657-BE77-E6664CAC72DC",
|
|
949
|
+
"parentID": "1528B5FF-6455-4657-BE77-E6664CACEEEE"
|
|
950
|
+
}
|
|
951
|
+
},
|
|
952
|
+
tags: [{"ai.user.accountId": "TestAccountId"}],
|
|
953
|
+
baseType: "PageviewData",
|
|
954
|
+
baseData: {
|
|
955
|
+
"name": "Page View Name",
|
|
956
|
+
"uri": "https://fakeUri.com",
|
|
957
|
+
properties: {
|
|
958
|
+
"property1": "val1",
|
|
959
|
+
"property2": "val2",
|
|
960
|
+
},
|
|
961
|
+
measurements: {
|
|
962
|
+
"measurement1": 50.0,
|
|
963
|
+
"measurement2": 1.3,
|
|
964
|
+
}
|
|
965
|
+
},
|
|
966
|
+
data: {
|
|
967
|
+
"duration": 300000
|
|
968
|
+
}
|
|
969
|
+
};
|
|
970
|
+
|
|
971
|
+
// Act
|
|
972
|
+
const appInsightsEnvelope = Sender.constructEnvelope(inputEnvelope, this._instrumentationKey, null);
|
|
973
|
+
const baseData = appInsightsEnvelope.data.baseData;
|
|
974
|
+
|
|
975
|
+
// Assert duration
|
|
976
|
+
const resultDuration = baseData.duration;
|
|
977
|
+
QUnit.assert.equal("00:05:00.000", resultDuration);
|
|
978
|
+
}
|
|
979
|
+
});
|
|
980
|
+
|
|
981
|
+
this.testCase({
|
|
982
|
+
name: 'Envelope: custom properties are put into envelope for Exception data type',
|
|
983
|
+
test: () => {
|
|
984
|
+
const bd = new Exception(
|
|
985
|
+
null,
|
|
986
|
+
new Error(),
|
|
987
|
+
{"property1": "val1", "property2": "val2" },
|
|
988
|
+
{"measurement1": 50.0, "measurement2": 1.3 }
|
|
989
|
+
);
|
|
990
|
+
const inputEnvelope: ITelemetryItem = {
|
|
991
|
+
name: "test",
|
|
992
|
+
time: new Date("2018-06-12").toISOString(),
|
|
993
|
+
iKey: "iKey",
|
|
994
|
+
baseType: Exception.dataType,
|
|
995
|
+
baseData: bd,
|
|
996
|
+
data: {
|
|
997
|
+
"property3": "val3",
|
|
998
|
+
"measurement3": 3.0
|
|
999
|
+
},
|
|
1000
|
+
ext: {
|
|
1001
|
+
"user": {
|
|
1002
|
+
"localId": "TestId",
|
|
1003
|
+
"authId": "AuthenticatedId",
|
|
1004
|
+
"id": "TestId"
|
|
1005
|
+
}
|
|
1006
|
+
},
|
|
1007
|
+
tags: [{"user.accountId": "TestAccountId"}],
|
|
1008
|
+
};
|
|
1009
|
+
|
|
1010
|
+
// Act
|
|
1011
|
+
const appInsightsEnvelope = Sender.constructEnvelope(inputEnvelope, this._instrumentationKey, null);
|
|
1012
|
+
const baseData = appInsightsEnvelope.data.baseData;
|
|
1013
|
+
|
|
1014
|
+
QUnit.assert.equal("val3", baseData.properties["property3"], "ExceptionData: customProperties (item.data) are added to the properties of the envelope and not included in the item.data")
|
|
1015
|
+
QUnit.assert.equal("val1", baseData.properties["property1"], "ExceptionData: properties (item.baseData.properties) are added to telemetry envelope");
|
|
1016
|
+
QUnit.assert.equal(50.0, baseData.measurements["measurement1"], "ExceptionData: measurements (item.baseData.measurements) are added to telemetry envelope");
|
|
1017
|
+
|
|
1018
|
+
}
|
|
1019
|
+
});
|
|
1020
|
+
|
|
1021
|
+
this.testCase({
|
|
1022
|
+
name: 'Offline watcher is listening to events',
|
|
1023
|
+
test: () => {
|
|
1024
|
+
QUnit.assert.ok(Offline.isListening, 'Offline is listening');
|
|
1025
|
+
QUnit.assert.equal(true, Offline.isOnline(), 'Offline reports online status');
|
|
1026
|
+
QUnit.assert.equal(false, Offline.isOffline(), 'Offline reports offline status');
|
|
1027
|
+
}
|
|
1028
|
+
});
|
|
1029
|
+
|
|
1030
|
+
this.testCase({
|
|
1031
|
+
name: 'Offline watcher responds to offline events (window.addEventListener)',
|
|
1032
|
+
useFakeTimers: true,
|
|
1033
|
+
test: () => {
|
|
1034
|
+
// Setup
|
|
1035
|
+
const offlineEvent = new Event('offline');
|
|
1036
|
+
const onlineEvent = new Event('online');
|
|
1037
|
+
|
|
1038
|
+
// Verify precondition
|
|
1039
|
+
QUnit.assert.ok(Offline.isListening);
|
|
1040
|
+
QUnit.assert.ok(Offline.isOnline());
|
|
1041
|
+
|
|
1042
|
+
// Act - Go offline
|
|
1043
|
+
window.dispatchEvent(offlineEvent);
|
|
1044
|
+
this.clock.tick(1);
|
|
1045
|
+
|
|
1046
|
+
// Verify offline
|
|
1047
|
+
QUnit.assert.ok(Offline.isOffline());
|
|
1048
|
+
|
|
1049
|
+
// Act - Go online
|
|
1050
|
+
window.dispatchEvent(onlineEvent);
|
|
1051
|
+
this.clock.tick(1);
|
|
1052
|
+
|
|
1053
|
+
// Verify online
|
|
1054
|
+
QUnit.assert.ok(Offline.isOnline());
|
|
1055
|
+
}
|
|
1056
|
+
});
|
|
1057
|
+
|
|
1058
|
+
this.testCase({
|
|
1059
|
+
name: "AppInsightsTests: AppInsights Envelope created for Page View with new web extension",
|
|
1060
|
+
test: () => {
|
|
1061
|
+
// setup
|
|
1062
|
+
const inputEnvelope: ITelemetryItem = {
|
|
1063
|
+
name: "test",
|
|
1064
|
+
iKey: "iKey",
|
|
1065
|
+
ext: {
|
|
1066
|
+
"web": {
|
|
1067
|
+
"domain": "www.bing.com",
|
|
1068
|
+
"userConsent": true,
|
|
1069
|
+
"screenRes": "1024x768",
|
|
1070
|
+
"browser": "internet explorer",
|
|
1071
|
+
"browserVer": "48.0",
|
|
1072
|
+
"isManual": true,
|
|
1073
|
+
"browserLang": "EN"
|
|
1074
|
+
}
|
|
1075
|
+
},
|
|
1076
|
+
baseType: "PageviewData",
|
|
1077
|
+
baseData: {
|
|
1078
|
+
"name": "Page View Name",
|
|
1079
|
+
"uri": "https://fakeUri.com",
|
|
1080
|
+
"startTime": new Date(123),
|
|
1081
|
+
properties: {
|
|
1082
|
+
"property1": "val1",
|
|
1083
|
+
"property2": "val2"
|
|
1084
|
+
},
|
|
1085
|
+
measurements: {
|
|
1086
|
+
"measurement1": 50.0,
|
|
1087
|
+
}
|
|
1088
|
+
}
|
|
1089
|
+
};
|
|
1090
|
+
|
|
1091
|
+
// Act
|
|
1092
|
+
const appInsightsEnvelope = Sender.constructEnvelope(inputEnvelope, this._instrumentationKey, null);
|
|
1093
|
+
const baseData = appInsightsEnvelope.data.baseData;
|
|
1094
|
+
|
|
1095
|
+
// Assert envelope
|
|
1096
|
+
QUnit.assert.deepEqual(appInsightsEnvelope.time, new Date(123).toISOString());
|
|
1097
|
+
|
|
1098
|
+
// Assert measurements
|
|
1099
|
+
const resultMeasurements = baseData.measurements;
|
|
1100
|
+
QUnit.assert.ok(resultMeasurements);
|
|
1101
|
+
QUnit.assert.ok(resultMeasurements["measurement1"]);
|
|
1102
|
+
QUnit.assert.equal(50.0, resultMeasurements["measurement1"]);
|
|
1103
|
+
|
|
1104
|
+
// Assert custom properties
|
|
1105
|
+
QUnit.assert.ok(baseData.properties);
|
|
1106
|
+
QUnit.assert.equal("val1", baseData.properties["property1"]);
|
|
1107
|
+
QUnit.assert.equal("val2", baseData.properties["property2"]);
|
|
1108
|
+
QUnit.assert.equal("true", baseData.properties["isManual"]);
|
|
1109
|
+
QUnit.assert.equal("1024x768", baseData.properties["screenRes"]);
|
|
1110
|
+
QUnit.assert.equal("true", baseData.properties["userConsent"]);
|
|
1111
|
+
QUnit.assert.equal("www.bing.com", baseData.properties["domain"]);
|
|
1112
|
+
|
|
1113
|
+
QUnit.assert.equal("internet explorer", appInsightsEnvelope.tags[CtxTagKeys.deviceBrowser]);
|
|
1114
|
+
QUnit.assert.equal("48.0", appInsightsEnvelope.tags[CtxTagKeys.deviceBrowserVersion]);
|
|
1115
|
+
QUnit.assert.equal("EN", appInsightsEnvelope.tags[CtxTagKeys.deviceLanguage]);
|
|
1116
|
+
|
|
1117
|
+
// Assert Page View name
|
|
1118
|
+
QUnit.assert.ok(baseData.name);
|
|
1119
|
+
QUnit.assert.equal("Page View Name", baseData.name);
|
|
1120
|
+
|
|
1121
|
+
// Assert ver
|
|
1122
|
+
QUnit.assert.ok(baseData.ver);
|
|
1123
|
+
QUnit.assert.equal(2, baseData.ver);
|
|
1124
|
+
|
|
1125
|
+
// Assert baseType
|
|
1126
|
+
QUnit.assert.ok(appInsightsEnvelope.data.baseType);
|
|
1127
|
+
QUnit.assert.equal("PageviewData", appInsightsEnvelope.data.baseType);
|
|
1128
|
+
|
|
1129
|
+
// Assert name
|
|
1130
|
+
QUnit.assert.ok(appInsightsEnvelope.name);
|
|
1131
|
+
QUnit.assert.equal("Microsoft.ApplicationInsights.iKey.Pageview", appInsightsEnvelope.name);
|
|
1132
|
+
}
|
|
1133
|
+
});
|
|
1134
|
+
|
|
1135
|
+
this.testCase({
|
|
1136
|
+
name: "Channel Config: Notification is sent when requests are being sent when requests exceed max batch size",
|
|
1137
|
+
useFakeTimers: true,
|
|
1138
|
+
test: () => {
|
|
1139
|
+
let sendNotifications = [];
|
|
1140
|
+
let notificationManager = new NotificationManager();
|
|
1141
|
+
notificationManager.addNotificationListener({
|
|
1142
|
+
eventsSendRequest: (sendReason: number, isAsync?: boolean) => {
|
|
1143
|
+
sendNotifications.push({
|
|
1144
|
+
sendReason,
|
|
1145
|
+
isAsync
|
|
1146
|
+
});
|
|
1147
|
+
}
|
|
1148
|
+
});
|
|
1149
|
+
|
|
1150
|
+
let core = new AppInsightsCore();
|
|
1151
|
+
this.sandbox.stub(core, "getNotifyMgr").returns(notificationManager);
|
|
1152
|
+
|
|
1153
|
+
this._sender.initialize(
|
|
1154
|
+
{
|
|
1155
|
+
instrumentationKey: 'abc',
|
|
1156
|
+
maxBatchInterval: 123,
|
|
1157
|
+
endpointUrl: 'https://example.com',
|
|
1158
|
+
maxBatchSizeInBytes: 100,
|
|
1159
|
+
extensionConfig: {
|
|
1160
|
+
[this._sender.identifier]: {
|
|
1161
|
+
maxBatchSizeInBytes: 100
|
|
1162
|
+
}
|
|
1163
|
+
}
|
|
1164
|
+
|
|
1165
|
+
}, core, []
|
|
1166
|
+
);
|
|
1167
|
+
|
|
1168
|
+
const loggerSpy = this.sandbox.spy(this._sender, "triggerSend");
|
|
1169
|
+
const telemetryItem: ITelemetryItem = {
|
|
1170
|
+
name: 'fake item',
|
|
1171
|
+
iKey: 'iKey',
|
|
1172
|
+
baseType: 'some type',
|
|
1173
|
+
baseData: {}
|
|
1174
|
+
};
|
|
1175
|
+
try {
|
|
1176
|
+
this._sender.processTelemetry(telemetryItem, null);
|
|
1177
|
+
} catch(e) {
|
|
1178
|
+
QUnit.assert.ok(false);
|
|
1179
|
+
}
|
|
1180
|
+
|
|
1181
|
+
QUnit.assert.equal(true, loggerSpy.calledOnce);
|
|
1182
|
+
this.clock.tick(1);
|
|
1183
|
+
QUnit.assert.ok(sendNotifications.length === 1);
|
|
1184
|
+
QUnit.assert.ok(sendNotifications[0].sendReason === SendRequestReason.MaxBatchSize);
|
|
1185
|
+
}
|
|
1186
|
+
});
|
|
1187
|
+
|
|
1188
|
+
this.testCase({
|
|
1189
|
+
name: "Channel Config: Notification is sent when requests are being sent with manual flush",
|
|
1190
|
+
useFakeTimers: true,
|
|
1191
|
+
test: () => {
|
|
1192
|
+
let sendNotifications = [];
|
|
1193
|
+
let notificationManager = new NotificationManager();
|
|
1194
|
+
notificationManager.addNotificationListener({
|
|
1195
|
+
eventsSendRequest: (sendReason: number, isAsync?: boolean) => {
|
|
1196
|
+
sendNotifications.push({
|
|
1197
|
+
sendReason,
|
|
1198
|
+
isAsync
|
|
1199
|
+
});
|
|
1200
|
+
}
|
|
1201
|
+
});
|
|
1202
|
+
|
|
1203
|
+
let core = new AppInsightsCore();
|
|
1204
|
+
this.sandbox.stub(core, "getNotifyMgr").returns(notificationManager);
|
|
1205
|
+
|
|
1206
|
+
this._sender.initialize(
|
|
1207
|
+
{
|
|
1208
|
+
instrumentationKey: 'abc',
|
|
1209
|
+
maxBatchInterval: 123,
|
|
1210
|
+
endpointUrl: 'https://example.com',
|
|
1211
|
+
extensionConfig: {
|
|
1212
|
+
}
|
|
1213
|
+
|
|
1214
|
+
}, core, []
|
|
1215
|
+
);
|
|
1216
|
+
|
|
1217
|
+
const loggerSpy = this.sandbox.spy(this._sender, "triggerSend");
|
|
1218
|
+
const telemetryItem: ITelemetryItem = {
|
|
1219
|
+
name: 'fake item',
|
|
1220
|
+
iKey: 'iKey',
|
|
1221
|
+
baseType: 'some type',
|
|
1222
|
+
baseData: {}
|
|
1223
|
+
};
|
|
1224
|
+
try {
|
|
1225
|
+
this._sender.processTelemetry(telemetryItem, null);
|
|
1226
|
+
} catch(e) {
|
|
1227
|
+
QUnit.assert.ok(false);
|
|
1228
|
+
}
|
|
1229
|
+
|
|
1230
|
+
QUnit.assert.equal(false, loggerSpy.calledOnce);
|
|
1231
|
+
QUnit.assert.equal(0, sendNotifications.length);
|
|
1232
|
+
|
|
1233
|
+
this._sender.flush();
|
|
1234
|
+
QUnit.assert.equal(true, loggerSpy.calledOnce);
|
|
1235
|
+
QUnit.assert.equal(0, sendNotifications.length);
|
|
1236
|
+
|
|
1237
|
+
this.clock.tick(1);
|
|
1238
|
+
|
|
1239
|
+
QUnit.assert.equal(1, sendNotifications.length);
|
|
1240
|
+
QUnit.assert.equal(SendRequestReason.ManualFlush, sendNotifications[0].sendReason);
|
|
1241
|
+
}
|
|
1242
|
+
});
|
|
1243
|
+
|
|
1244
|
+
this.testCase({
|
|
1245
|
+
name: "IKey Validation Test",
|
|
1246
|
+
test: () => {
|
|
1247
|
+
let appInsightsCore = new AppInsightsCore();
|
|
1248
|
+
appInsightsCore.logger = new DiagnosticLogger();
|
|
1249
|
+
let messageId: _InternalMessageId = _InternalMessageId.InvalidInstrumentationKey;
|
|
1250
|
+
let logInternalSpy = this.sandbox.spy(appInsightsCore.logger, 'logInternalMessage');
|
|
1251
|
+
this._sender.initialize(
|
|
1252
|
+
{
|
|
1253
|
+
instrumentationKey: '1aa11111-bbbb-1ccc-8ddd-eeeeffff3333',
|
|
1254
|
+
maxBatchInterval: 123,
|
|
1255
|
+
endpointUrl: 'https://example.com',
|
|
1256
|
+
maxBatchSizeInBytes: 654,
|
|
1257
|
+
extensionConfig: {
|
|
1258
|
+
[this._sender.identifier]: {
|
|
1259
|
+
maxBatchSizeInBytes: 456
|
|
1260
|
+
}
|
|
1261
|
+
}
|
|
1262
|
+
|
|
1263
|
+
}, appInsightsCore, []
|
|
1264
|
+
);
|
|
1265
|
+
|
|
1266
|
+
QUnit.assert.equal(false,logInternalSpy.calledOnce, 'valid Ikey test-1');
|
|
1267
|
+
QUnit.assert.equal(0, appInsightsCore.logger.queue.length, "POST: No messageId logged");
|
|
1268
|
+
|
|
1269
|
+
appInsightsCore = new AppInsightsCore();
|
|
1270
|
+
appInsightsCore.logger = new DiagnosticLogger();
|
|
1271
|
+
messageId = _InternalMessageId.InvalidInstrumentationKey;
|
|
1272
|
+
logInternalSpy = this.sandbox.spy(appInsightsCore.logger, 'logInternalMessage');
|
|
1273
|
+
this._sender.initialize(
|
|
1274
|
+
{
|
|
1275
|
+
instrumentationKey: '1aa11111bbbb1ccc8dddeeeeffff3333',
|
|
1276
|
+
maxBatchInterval: 123,
|
|
1277
|
+
endpointUrl: 'https://example.com',
|
|
1278
|
+
maxBatchSizeInBytes: 654,
|
|
1279
|
+
extensionConfig: {
|
|
1280
|
+
[this._sender.identifier]: {
|
|
1281
|
+
maxBatchSizeInBytes: 456
|
|
1282
|
+
}
|
|
1283
|
+
}
|
|
1284
|
+
|
|
1285
|
+
}, appInsightsCore, []
|
|
1286
|
+
);
|
|
1287
|
+
|
|
1288
|
+
QUnit.assert.ok(logInternalSpy.calledOnce, 'iKey Validation check -throwInternal called');
|
|
1289
|
+
QUnit.assert.equal(messageId, logInternalSpy.args[0][1].messageId, "Correct message logged");
|
|
1290
|
+
QUnit.assert.ok(logInternalSpy.args[0][1].message.indexOf('Invalid Instrumentation key') !== -1, "Correct message logged");
|
|
1291
|
+
QUnit.assert.equal(1, appInsightsCore.logger.queue.length, "POST: Correct messageId logged");
|
|
1292
|
+
QUnit.assert.ok(appInsightsCore.logger.queue[0].message.indexOf('Invalid Instrumentation key') !== -1, "Correct message logged");
|
|
1293
|
+
QUnit.assert.equal(messageId, appInsightsCore.logger.queue[0].messageId, "Correct message logged");
|
|
1294
|
+
|
|
1295
|
+
appInsightsCore = new AppInsightsCore();
|
|
1296
|
+
appInsightsCore.logger = new DiagnosticLogger();
|
|
1297
|
+
messageId = _InternalMessageId.InvalidInstrumentationKey;
|
|
1298
|
+
logInternalSpy = this.sandbox.spy(appInsightsCore.logger, 'logInternalMessage');
|
|
1299
|
+
this._sender.initialize(
|
|
1300
|
+
{
|
|
1301
|
+
instrumentationKey: 'abc',
|
|
1302
|
+
maxBatchInterval: 123,
|
|
1303
|
+
endpointUrl: 'https://example.com',
|
|
1304
|
+
maxBatchSizeInBytes: 654,
|
|
1305
|
+
extensionConfig: {
|
|
1306
|
+
[this._sender.identifier]: {
|
|
1307
|
+
maxBatchSizeInBytes: 456
|
|
1308
|
+
}
|
|
1309
|
+
}
|
|
1310
|
+
|
|
1311
|
+
}, appInsightsCore, []
|
|
1312
|
+
);
|
|
1313
|
+
|
|
1314
|
+
QUnit.assert.ok(logInternalSpy.calledOnce, 'iKey Validation check -throwInternal called');
|
|
1315
|
+
QUnit.assert.equal(messageId, logInternalSpy.args[0][1].messageId, "Correct message logged");
|
|
1316
|
+
QUnit.assert.ok(logInternalSpy.args[0][1].message.indexOf('Invalid Instrumentation key') !== -1, "Correct message logged");
|
|
1317
|
+
QUnit.assert.equal(1, appInsightsCore.logger.queue.length, "POST: Correct messageId logged");
|
|
1318
|
+
QUnit.assert.ok(appInsightsCore.logger.queue[0].message.indexOf('Invalid Instrumentation key') !== -1, "Correct message logged");
|
|
1319
|
+
QUnit.assert.equal(messageId, appInsightsCore.logger.queue[0].messageId, "Correct message logged");
|
|
1320
|
+
|
|
1321
|
+
appInsightsCore = new AppInsightsCore();
|
|
1322
|
+
appInsightsCore.logger = new DiagnosticLogger();
|
|
1323
|
+
messageId = _InternalMessageId.InvalidInstrumentationKey;
|
|
1324
|
+
logInternalSpy = this.sandbox.spy(appInsightsCore.logger, 'logInternalMessage');
|
|
1325
|
+
this._sender.initialize(
|
|
1326
|
+
{
|
|
1327
|
+
instrumentationKey: '',
|
|
1328
|
+
maxBatchInterval: 123,
|
|
1329
|
+
endpointUrl: 'https://example.com',
|
|
1330
|
+
maxBatchSizeInBytes: 654,
|
|
1331
|
+
extensionConfig: {
|
|
1332
|
+
[this._sender.identifier]: {
|
|
1333
|
+
maxBatchSizeInBytes: 456
|
|
1334
|
+
}
|
|
1335
|
+
}
|
|
1336
|
+
|
|
1337
|
+
}, appInsightsCore, []
|
|
1338
|
+
);
|
|
1339
|
+
|
|
1340
|
+
QUnit.assert.ok(logInternalSpy.calledOnce, 'iKey Validation check -throwInternal called');
|
|
1341
|
+
QUnit.assert.equal(messageId, logInternalSpy.args[0][1].messageId, "Correct message logged");
|
|
1342
|
+
QUnit.assert.ok(logInternalSpy.args[0][1].message.indexOf('Invalid Instrumentation key') !== -1, "Correct message logged");
|
|
1343
|
+
QUnit.assert.equal(1, appInsightsCore.logger.queue.length, "POST: Correct messageId logged");
|
|
1344
|
+
QUnit.assert.ok(appInsightsCore.logger.queue[0].message.indexOf('Invalid Instrumentation key') !== -1, "Correct message logged");
|
|
1345
|
+
QUnit.assert.equal(messageId, appInsightsCore.logger.queue[0].messageId, "Correct message logged");
|
|
1346
|
+
|
|
1347
|
+
appInsightsCore = new AppInsightsCore();
|
|
1348
|
+
appInsightsCore.logger = new DiagnosticLogger();
|
|
1349
|
+
messageId = _InternalMessageId.InvalidInstrumentationKey;
|
|
1350
|
+
logInternalSpy = this.sandbox.spy(appInsightsCore.logger, 'logInternalMessage');
|
|
1351
|
+
this._sender.initialize(
|
|
1352
|
+
{
|
|
1353
|
+
instrumentationKey: 'abc',
|
|
1354
|
+
maxBatchInterval: 123,
|
|
1355
|
+
endpointUrl: 'https://example.com',
|
|
1356
|
+
maxBatchSizeInBytes: 654,
|
|
1357
|
+
extensionConfig: {
|
|
1358
|
+
[this._sender.identifier]: {
|
|
1359
|
+
maxBatchSizeInBytes: 456
|
|
1360
|
+
}
|
|
1361
|
+
},
|
|
1362
|
+
disableInstrumentationKeyValidation: true
|
|
1363
|
+
|
|
1364
|
+
}, appInsightsCore, []
|
|
1365
|
+
);
|
|
1366
|
+
|
|
1367
|
+
QUnit.assert.equal(false,logInternalSpy.calledOnce, 'disableIKeyValidation flag set to yes');
|
|
1368
|
+
QUnit.assert.equal(0, appInsightsCore.logger.queue.length, "POST: No messageId logged");
|
|
1369
|
+
}
|
|
1370
|
+
|
|
1371
|
+
|
|
1372
|
+
});
|
|
1373
|
+
|
|
1374
|
+
this.testCase({
|
|
1375
|
+
name: "Channel Config: convert custom dimension undefined values to customer defined value with config convertUndefined",
|
|
1376
|
+
test: () => {
|
|
1377
|
+
const inputEnvelope: ITelemetryItem = {
|
|
1378
|
+
name: "test",
|
|
1379
|
+
iKey: "iKey",
|
|
1380
|
+
data: {
|
|
1381
|
+
"property1": undefined,
|
|
1382
|
+
"property2": "value2"
|
|
1383
|
+
},
|
|
1384
|
+
baseData: {
|
|
1385
|
+
"name": "Event Name"
|
|
1386
|
+
}
|
|
1387
|
+
};
|
|
1388
|
+
const appInsightsEnvelope = Sender.constructEnvelope(inputEnvelope, this._instrumentationKey, null, "test");
|
|
1389
|
+
|
|
1390
|
+
const baseData = appInsightsEnvelope.data.baseData;
|
|
1391
|
+
|
|
1392
|
+
// Assert custom properties
|
|
1393
|
+
QUnit.assert.ok(baseData.properties);
|
|
1394
|
+
QUnit.assert.equal("test", baseData.properties["property1"]);
|
|
1395
|
+
QUnit.assert.equal("value2", baseData.properties["property2"]);
|
|
1396
|
+
}
|
|
1397
|
+
});
|
|
1398
|
+
|
|
1399
|
+
this.testCase({
|
|
1400
|
+
name: "Channel Config: Validate pausing and resuming sending with manual flush",
|
|
1401
|
+
useFakeTimers: true,
|
|
1402
|
+
test: () => {
|
|
1403
|
+
let sendNotifications = [];
|
|
1404
|
+
let notificationManager = new NotificationManager();
|
|
1405
|
+
notificationManager.addNotificationListener({
|
|
1406
|
+
eventsSendRequest: (sendReason: number, isAsync?: boolean) => {
|
|
1407
|
+
sendNotifications.push({
|
|
1408
|
+
sendReason,
|
|
1409
|
+
isAsync
|
|
1410
|
+
});
|
|
1411
|
+
}
|
|
1412
|
+
});
|
|
1413
|
+
|
|
1414
|
+
let core = new AppInsightsCore();
|
|
1415
|
+
this.sandbox.stub(core, "getNotifyMgr").returns(notificationManager);
|
|
1416
|
+
|
|
1417
|
+
this._sender.initialize(
|
|
1418
|
+
{
|
|
1419
|
+
instrumentationKey: 'abc',
|
|
1420
|
+
maxBatchInterval: 123,
|
|
1421
|
+
endpointUrl: 'https://example.com',
|
|
1422
|
+
extensionConfig: {
|
|
1423
|
+
}
|
|
1424
|
+
|
|
1425
|
+
}, core, []
|
|
1426
|
+
);
|
|
1427
|
+
|
|
1428
|
+
const loggerSpy = this.sandbox.spy(this._sender, "triggerSend");
|
|
1429
|
+
const telemetryItem: ITelemetryItem = {
|
|
1430
|
+
name: 'fake item',
|
|
1431
|
+
iKey: 'iKey',
|
|
1432
|
+
baseType: 'some type',
|
|
1433
|
+
baseData: {}
|
|
1434
|
+
};
|
|
1435
|
+
try {
|
|
1436
|
+
this._sender.processTelemetry(telemetryItem, null);
|
|
1437
|
+
} catch(e) {
|
|
1438
|
+
QUnit.assert.ok(false);
|
|
1439
|
+
}
|
|
1440
|
+
|
|
1441
|
+
QUnit.assert.equal(false, loggerSpy.calledOnce);
|
|
1442
|
+
QUnit.assert.equal(0, sendNotifications.length);
|
|
1443
|
+
|
|
1444
|
+
this._sender.pause();
|
|
1445
|
+
this._sender.flush();
|
|
1446
|
+
QUnit.assert.equal(false, loggerSpy.calledOnce);
|
|
1447
|
+
QUnit.assert.equal(0, sendNotifications.length);
|
|
1448
|
+
|
|
1449
|
+
this.clock.tick(1);
|
|
1450
|
+
|
|
1451
|
+
QUnit.assert.equal(0, sendNotifications.length);
|
|
1452
|
+
|
|
1453
|
+
this._sender.resume();
|
|
1454
|
+
this._sender.flush();
|
|
1455
|
+
QUnit.assert.equal(true, loggerSpy.calledOnce);
|
|
1456
|
+
QUnit.assert.equal(0, sendNotifications.length);
|
|
1457
|
+
|
|
1458
|
+
this.clock.tick(1);
|
|
1459
|
+
|
|
1460
|
+
QUnit.assert.equal(1, sendNotifications.length);
|
|
1461
|
+
QUnit.assert.equal(SendRequestReason.ManualFlush, sendNotifications[0].sendReason);
|
|
1462
|
+
}
|
|
1463
|
+
});
|
|
1464
|
+
|
|
1465
|
+
this.testCase({
|
|
1466
|
+
name: "Channel Config: Validate pausing and resuming sending when exceeding the batch size limits",
|
|
1467
|
+
useFakeTimers: true,
|
|
1468
|
+
test: () => {
|
|
1469
|
+
let sendNotifications = [];
|
|
1470
|
+
let notificationManager = new NotificationManager();
|
|
1471
|
+
notificationManager.addNotificationListener({
|
|
1472
|
+
eventsSendRequest: (sendReason: number, isAsync?: boolean) => {
|
|
1473
|
+
sendNotifications.push({
|
|
1474
|
+
sendReason,
|
|
1475
|
+
isAsync
|
|
1476
|
+
});
|
|
1477
|
+
}
|
|
1478
|
+
});
|
|
1479
|
+
|
|
1480
|
+
let core = new AppInsightsCore();
|
|
1481
|
+
this.sandbox.stub(core, "getNotifyMgr").returns(notificationManager);
|
|
1482
|
+
|
|
1483
|
+
this._sender.initialize(
|
|
1484
|
+
{
|
|
1485
|
+
instrumentationKey: 'abc',
|
|
1486
|
+
maxBatchInterval: 123,
|
|
1487
|
+
maxBatchSizeInBytes: 4096,
|
|
1488
|
+
endpointUrl: 'https://example.com',
|
|
1489
|
+
extensionConfig: {
|
|
1490
|
+
}
|
|
1491
|
+
|
|
1492
|
+
}, core, []
|
|
1493
|
+
);
|
|
1494
|
+
|
|
1495
|
+
const triggerSendSpy = this.sandbox.spy(this._sender, "triggerSend");
|
|
1496
|
+
const telemetryItem: ITelemetryItem = {
|
|
1497
|
+
name: 'fake item',
|
|
1498
|
+
iKey: 'iKey',
|
|
1499
|
+
baseType: 'some type',
|
|
1500
|
+
baseData: {}
|
|
1501
|
+
};
|
|
1502
|
+
|
|
1503
|
+
this._sender.pause();
|
|
1504
|
+
|
|
1505
|
+
// Keep sending events until the max payload size is reached
|
|
1506
|
+
while (!triggerSendSpy.calledOnce) {
|
|
1507
|
+
try {
|
|
1508
|
+
this._sender.processTelemetry(telemetryItem, null);
|
|
1509
|
+
} catch(e) {
|
|
1510
|
+
QUnit.assert.ok(false);
|
|
1511
|
+
}
|
|
1512
|
+
}
|
|
1513
|
+
|
|
1514
|
+
QUnit.assert.equal(true, triggerSendSpy.calledOnce);
|
|
1515
|
+
QUnit.assert.equal(0, sendNotifications.length);
|
|
1516
|
+
|
|
1517
|
+
this.clock.tick(1);
|
|
1518
|
+
|
|
1519
|
+
QUnit.assert.equal(0, sendNotifications.length);
|
|
1520
|
+
|
|
1521
|
+
QUnit.assert.equal(false, triggerSendSpy.calledTwice);
|
|
1522
|
+
this._sender.resume();
|
|
1523
|
+
|
|
1524
|
+
QUnit.assert.equal(true, triggerSendSpy.calledTwice);
|
|
1525
|
+
QUnit.assert.equal(0, sendNotifications.length);
|
|
1526
|
+
|
|
1527
|
+
this.clock.tick(1);
|
|
1528
|
+
|
|
1529
|
+
QUnit.assert.equal(1, sendNotifications.length);
|
|
1530
|
+
QUnit.assert.equal(SendRequestReason.MaxBatchSize, sendNotifications[0].sendReason);
|
|
1531
|
+
}
|
|
1532
|
+
});
|
|
1533
|
+
|
|
1534
|
+
this.testCase({
|
|
1535
|
+
name: 'Envelope: operation.name is correctly truncated if required',
|
|
1536
|
+
test: () => {
|
|
1537
|
+
const excessiveName = new Array(1234).join("a"); // exceeds max of 1024
|
|
1538
|
+
|
|
1539
|
+
const bd = new Exception(
|
|
1540
|
+
null,
|
|
1541
|
+
new Error(),
|
|
1542
|
+
{"property1": "val1", "property2": "val2" },
|
|
1543
|
+
{"measurement1": 50.0, "measurement2": 1.3 }
|
|
1544
|
+
);
|
|
1545
|
+
const inputEnvelope: ITelemetryItem = {
|
|
1546
|
+
name: "test",
|
|
1547
|
+
time: new Date("2018-06-12").toISOString(),
|
|
1548
|
+
iKey: "iKey",
|
|
1549
|
+
baseType: Exception.dataType,
|
|
1550
|
+
baseData: bd,
|
|
1551
|
+
data: {
|
|
1552
|
+
"property3": "val3",
|
|
1553
|
+
"measurement3": 3.0
|
|
1554
|
+
},
|
|
1555
|
+
ext: {
|
|
1556
|
+
"trace": {
|
|
1557
|
+
"traceID": "1528B5FF-6455-4657-BE77-E6664CAC72DC",
|
|
1558
|
+
"parentID": "1528B5FF-6455-4657-BE77-E6664CACEEEE",
|
|
1559
|
+
"name": excessiveName
|
|
1560
|
+
}
|
|
1561
|
+
},
|
|
1562
|
+
tags: [
|
|
1563
|
+
{"user.accountId": "TestAccountId"},
|
|
1564
|
+
],
|
|
1565
|
+
};
|
|
1566
|
+
|
|
1567
|
+
// Act
|
|
1568
|
+
const appInsightsEnvelope = Sender.constructEnvelope(inputEnvelope, this._instrumentationKey, null);
|
|
1569
|
+
const baseData = appInsightsEnvelope.data.baseData;
|
|
1570
|
+
|
|
1571
|
+
QUnit.assert.equal("val3", baseData.properties["property3"], "ExceptionData: customProperties (item.data) are added to the properties of the envelope and not included in the item.data")
|
|
1572
|
+
QUnit.assert.equal("val1", baseData.properties["property1"], "ExceptionData: properties (item.baseData.properties) are added to telemetry envelope");
|
|
1573
|
+
QUnit.assert.equal(50.0, baseData.measurements["measurement1"], "ExceptionData: measurements (item.baseData.measurements) are added to telemetry envelope");
|
|
1574
|
+
QUnit.assert.equal(1024, appInsightsEnvelope.tags["ai.operation.name"].length, "The ai.operation.name should have been truncated to the maximum");
|
|
1575
|
+
}
|
|
1576
|
+
});
|
|
1577
|
+
}
|
|
1578
|
+
}
|