bv-ui-core 0.1.1
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/.eslintrc +40 -0
- package/.travis.yml +5 -0
- package/CONTRIBUTING.md +98 -0
- package/LICENSE.md +13 -0
- package/OWNERS +2 -0
- package/README.md +63 -0
- package/catalog-info.yaml +30 -0
- package/karma.conf.js +130 -0
- package/lib/README.md +61 -0
- package/lib/api/.babelrc +3 -0
- package/lib/api/.eslintrc +9 -0
- package/lib/api/README.md +134 -0
- package/lib/api/index.js +15 -0
- package/lib/api/statistics.js +148 -0
- package/lib/application/README.md +96 -0
- package/lib/application/index.js +171 -0
- package/lib/body/README.md +13 -0
- package/lib/body/index.js +19 -0
- package/lib/bvFetch/README.md +101 -0
- package/lib/bvFetch/index.js +383 -0
- package/lib/checkHighContrast/README.md +26 -0
- package/lib/checkHighContrast/index.js +36 -0
- package/lib/cookie/README.md +29 -0
- package/lib/cookie/index.js +111 -0
- package/lib/cookieConsent/README.md +41 -0
- package/lib/cookieConsent/index.js +227 -0
- package/lib/cssLoadChecker/README.md +19 -0
- package/lib/cssLoadChecker/index.js +72 -0
- package/lib/date.now/README.md +11 -0
- package/lib/date.now/index.js +40 -0
- package/lib/domainPolice/README.md +66 -0
- package/lib/domainPolice/index.js +95 -0
- package/lib/evented/README.md +42 -0
- package/lib/evented/index.js +135 -0
- package/lib/getOriginalConstructor/README.md +16 -0
- package/lib/getOriginalConstructor/index.js +52 -0
- package/lib/global/README.md +10 -0
- package/lib/global/index.js +48 -0
- package/lib/ie/README.md +13 -0
- package/lib/ie/index.js +25 -0
- package/lib/loader/README.md +73 -0
- package/lib/loader/index.js +358 -0
- package/lib/logger/README.md +82 -0
- package/lib/logger/index.js +180 -0
- package/lib/messageFormat/README.md +10 -0
- package/lib/messageFormat/index.js +42 -0
- package/lib/namespacer/README.md +57 -0
- package/lib/namespacer/index.js +98 -0
- package/lib/performance/README.md +35 -0
- package/lib/performance/entries.js +5 -0
- package/lib/performance/getEntries.js +42 -0
- package/lib/performance/getEntriesByName.js +61 -0
- package/lib/performance/getEntriesByType.js +55 -0
- package/lib/performance/index.js +11 -0
- package/lib/performance/mark.js +97 -0
- package/lib/performance/measure.js +106 -0
- package/lib/performance/now.js +63 -0
- package/lib/pixelsDisplayed/README.md +19 -0
- package/lib/pixelsDisplayed/index.js +113 -0
- package/lib/polyfills/README.md +39 -0
- package/lib/polyfills/fetch/Headers.js +3 -0
- package/lib/polyfills/fetch/Request.js +3 -0
- package/lib/polyfills/fetch/Response.js +3 -0
- package/lib/polyfills/fetch/fetch.js +3 -0
- package/lib/polyfills/fetch/index.js +57 -0
- package/lib/polyfills/promise.js +265 -0
- package/lib/queryShadowDom/README.md +50 -0
- package/lib/queryShadowDom/index.js +93 -0
- package/lib/region/README.md +64 -0
- package/lib/region/europe/index.js +94 -0
- package/lib/region/europe/territories.js +40 -0
- package/lib/region/index.js +123 -0
- package/lib/staticAssetLoader/README.md +116 -0
- package/lib/staticAssetLoader/index.js +248 -0
- package/lib/waitForBody/README.md +21 -0
- package/lib/waitForBody/index.js +36 -0
- package/mkdocs.yaml +5 -0
- package/package.json +55 -0
- package/test/.eslintrc +5 -0
- package/test/fixtures/lib.loader.document-is-wrong-in-ie8.js +5 -0
- package/test/fixtures/lib.loader.loadscript-attribute.js +3 -0
- package/test/fixtures/lib.loader.loadscript.js +3 -0
- package/test/fixtures/lib.loader.loadstylesheet.css +3 -0
- package/test/unit/api/.eslintrc +6 -0
- package/test/unit/api/index.spec.js +37 -0
- package/test/unit/api/response.json +67 -0
- package/test/unit/api/statistics.spec.js +218 -0
- package/test/unit/application/index.spec.js +313 -0
- package/test/unit/body/index.spec.js +15 -0
- package/test/unit/bvFetch/index.spec.js +246 -0
- package/test/unit/checkHighContrast/index.spec.js +16 -0
- package/test/unit/cookie/index.spec.js +191 -0
- package/test/unit/cookieConsent/index.spec.js +119 -0
- package/test/unit/cssLoadChecker/index.spec.js +75 -0
- package/test/unit/date.now/index.spec.js +21 -0
- package/test/unit/domainPolice/index.spec.js +141 -0
- package/test/unit/evented/index.spec.js +59 -0
- package/test/unit/getOriginalConstructor/index.spec.js +60 -0
- package/test/unit/global/index.spec.js +84 -0
- package/test/unit/ie/index.spec.js +14 -0
- package/test/unit/loader/index.spec.js +644 -0
- package/test/unit/logger/index.spec.js +141 -0
- package/test/unit/messageFormat/index.spec.js +31 -0
- package/test/unit/mochaInit.js +8 -0
- package/test/unit/namespacer/index.spec.js +100 -0
- package/test/unit/performance/getEntries.spec.js +30 -0
- package/test/unit/performance/getEntriesByName.spec.js +88 -0
- package/test/unit/performance/getEntriesByType.spec.js +48 -0
- package/test/unit/performance/index.spec.js +35 -0
- package/test/unit/performance/mark.spec.js +40 -0
- package/test/unit/performance/measure.spec.js +50 -0
- package/test/unit/performance/now.spec.js +21 -0
- package/test/unit/pixelsDisplayed/index.spec.js +271 -0
- package/test/unit/polyfills/fetch/Headers.js +12 -0
- package/test/unit/polyfills/fetch/Request.js +12 -0
- package/test/unit/polyfills/fetch/Response.js +12 -0
- package/test/unit/polyfills/fetch/fetch.js +12 -0
- package/test/unit/polyfills/fetch/index.js +61 -0
- package/test/unit/polyfills/promise.spec.js +48 -0
- package/test/unit/region/europe/index.spec.js +70 -0
- package/test/unit/region/index.spec.js +113 -0
- package/test/unit/staticAssetLoader/index.spec.js +215 -0
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileOverview
|
|
3
|
+
* Unit tests for the application module.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// Imports.
|
|
7
|
+
var Application = require('../../../lib/application');
|
|
8
|
+
var global = require('../../../lib/global');
|
|
9
|
+
|
|
10
|
+
describe('lib/application', function () {
|
|
11
|
+
|
|
12
|
+
var config;
|
|
13
|
+
var application;
|
|
14
|
+
var sandbox;
|
|
15
|
+
|
|
16
|
+
beforeEach(function () {
|
|
17
|
+
config = { foo: 'bar' };
|
|
18
|
+
application = new Application(config);
|
|
19
|
+
sandbox = sinon.sandbox.create();
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
afterEach(function () {
|
|
23
|
+
sandbox.restore();
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
describe('ready method', function () {
|
|
27
|
+
|
|
28
|
+
it('queues calls to ready', function () {
|
|
29
|
+
var fn = sandbox.spy();
|
|
30
|
+
|
|
31
|
+
expect(application._readyQueue.length).to.equal(0);
|
|
32
|
+
application.ready(fn);
|
|
33
|
+
expect(application._readyQueue.length).to.equal(1);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it('original ready method always gets replaced', function () {
|
|
37
|
+
application.originalReady = application.ready;
|
|
38
|
+
application.processReady();
|
|
39
|
+
|
|
40
|
+
expect(application.originalRender).to.not.equal(application.ready);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it('automatically processes callbacks after processReady is called', function () {
|
|
44
|
+
var fn = sandbox.spy();
|
|
45
|
+
|
|
46
|
+
application.ready(fn);
|
|
47
|
+
sinon.assert.notCalled(fn);
|
|
48
|
+
|
|
49
|
+
application.processReady();
|
|
50
|
+
sinon.assert.calledOnce(fn);
|
|
51
|
+
|
|
52
|
+
application.ready(fn);
|
|
53
|
+
sinon.assert.calledTwice(fn);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it('returns a Promise', function () {
|
|
57
|
+
if (typeof global.Promise === 'function') {
|
|
58
|
+
var returnVal = application.ready();
|
|
59
|
+
expect(returnVal).to.not.be.a('number');
|
|
60
|
+
expect(returnVal.then).to.be.a('function');
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
// Auto-pass in this environment
|
|
64
|
+
expect(true).to.equal(true);
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
it('automatically processes Promise chain callbacks after processReady is called', function () {
|
|
69
|
+
if (typeof global.Promise === 'function') {
|
|
70
|
+
var fn = sandbox.spy();
|
|
71
|
+
|
|
72
|
+
application.ready().then(fn);
|
|
73
|
+
sinon.assert.notCalled(fn);
|
|
74
|
+
|
|
75
|
+
application.processReady();
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Apparently, Promises get processed asynchronously, even when
|
|
79
|
+
* they're not asynchronous processes, e.g., the following code
|
|
80
|
+
* fails its assertions:
|
|
81
|
+
*
|
|
82
|
+
* var fn = sandbox.spy();
|
|
83
|
+
* var promise = Promise.resolve();
|
|
84
|
+
* promise.then(fn);
|
|
85
|
+
* sinon.assert.calledOnce(fn);
|
|
86
|
+
*
|
|
87
|
+
* Because of this, we have to wrap our below assertions in a
|
|
88
|
+
* double layer of setTimeout(0) statements, to defer to the
|
|
89
|
+
* next event loop before we check the status of our spies.
|
|
90
|
+
*/
|
|
91
|
+
setTimeout(function () {
|
|
92
|
+
sinon.assert.calledOnce(fn);
|
|
93
|
+
|
|
94
|
+
application.ready().then(fn);
|
|
95
|
+
|
|
96
|
+
setTimeout(function () {
|
|
97
|
+
sinon.assert.calledTwice(fn);
|
|
98
|
+
}, 0);
|
|
99
|
+
}, 0);
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
// Auto-pass in this environment
|
|
103
|
+
expect(true).to.equal(true);
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
describe('processReady method', function () {
|
|
110
|
+
|
|
111
|
+
it('processes the queue sync', function () {
|
|
112
|
+
var fn = sandbox.spy();
|
|
113
|
+
|
|
114
|
+
application.ready(fn);
|
|
115
|
+
application.processReady();
|
|
116
|
+
|
|
117
|
+
sinon.assert.calledOnce(fn);
|
|
118
|
+
|
|
119
|
+
application.ready(fn);
|
|
120
|
+
|
|
121
|
+
sinon.assert.calledTwice(fn);
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
it('injects its callbacks with its own instance when invoked with no error', function () {
|
|
125
|
+
if (typeof global.Promise === 'function') {
|
|
126
|
+
// Auto-pass in this environment
|
|
127
|
+
expect(true).to.equal(true);
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
var fn = sandbox.spy();
|
|
131
|
+
|
|
132
|
+
application.ready(fn);
|
|
133
|
+
application.processReady();
|
|
134
|
+
|
|
135
|
+
sinon.assert.calledWith(fn, [null, application]);
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
it('injects its callbacks with an error when invoked with an error', function () {
|
|
140
|
+
if (typeof global.Promise === 'function') {
|
|
141
|
+
// Auto-pass in this environment
|
|
142
|
+
expect(true).to.equal(true);
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
var error = new Error('Test Error');
|
|
146
|
+
var fn = sandbox.spy();
|
|
147
|
+
|
|
148
|
+
application.ready(fn);
|
|
149
|
+
application.processReady(error);
|
|
150
|
+
|
|
151
|
+
sinon.assert.calledWith(fn, [error, application]);
|
|
152
|
+
}
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
it('resolves its promise with its own instance when invoked with no error', function (done) {
|
|
156
|
+
if (typeof global.Promise === 'function') {
|
|
157
|
+
application.ready()
|
|
158
|
+
.then(function (app) {
|
|
159
|
+
expect(application).to.equal(app);
|
|
160
|
+
})
|
|
161
|
+
.catch(function (err) {
|
|
162
|
+
expect(false).to.equal(true);
|
|
163
|
+
})
|
|
164
|
+
.then(function () {
|
|
165
|
+
done();
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
application.processReady();
|
|
169
|
+
}
|
|
170
|
+
else {
|
|
171
|
+
// Auto-pass in this environment
|
|
172
|
+
expect(true).to.equal(true);
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
it('rejects its promise with an error when invoked with an error', function (done) {
|
|
177
|
+
if (typeof global.Promise === 'function') {
|
|
178
|
+
var error = new Error('Test Error');
|
|
179
|
+
|
|
180
|
+
application.ready()
|
|
181
|
+
.then(function (app) {
|
|
182
|
+
expect(false).to.equal(true);
|
|
183
|
+
})
|
|
184
|
+
.catch(function (err) {
|
|
185
|
+
expect(error).to.equal(err);
|
|
186
|
+
})
|
|
187
|
+
.then(function () {
|
|
188
|
+
done();
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
application.processReady(error);
|
|
192
|
+
}
|
|
193
|
+
else {
|
|
194
|
+
// Auto-pass in this environment
|
|
195
|
+
expect(true).to.equal(true);
|
|
196
|
+
}
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
describe('render method', function () {
|
|
202
|
+
|
|
203
|
+
it('queues calls to render', function () {
|
|
204
|
+
expect(application._renderQueue.length).to.equal(0);
|
|
205
|
+
application.render(config);
|
|
206
|
+
expect(application._renderQueue.length).to.equal(1);
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
it('original render method always gets replaced', function () {
|
|
210
|
+
var fn = sandbox.spy();
|
|
211
|
+
|
|
212
|
+
application.originalRender = application.render;
|
|
213
|
+
application.processQueue(fn);
|
|
214
|
+
|
|
215
|
+
// Even calling application's original definition of render
|
|
216
|
+
// should call the new function.
|
|
217
|
+
application.originalRender();
|
|
218
|
+
application.originalRender();
|
|
219
|
+
application.originalRender();
|
|
220
|
+
|
|
221
|
+
sinon.assert.calledThrice(fn);
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
describe('processQueue method', function () {
|
|
227
|
+
|
|
228
|
+
it('processes the queue async', function (done) {
|
|
229
|
+
var fn = sandbox.spy();
|
|
230
|
+
|
|
231
|
+
application.render(config);
|
|
232
|
+
application.render(config);
|
|
233
|
+
application.processQueue(fn);
|
|
234
|
+
|
|
235
|
+
sinon.assert.notCalled(fn);
|
|
236
|
+
|
|
237
|
+
setTimeout(function () {
|
|
238
|
+
sinon.assert.calledTwice(fn);
|
|
239
|
+
done();
|
|
240
|
+
}, 100);
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
it('redefines the render method', function (done) {
|
|
244
|
+
var fn = function () {};
|
|
245
|
+
|
|
246
|
+
application.processQueue(fn);
|
|
247
|
+
|
|
248
|
+
setTimeout(function () {
|
|
249
|
+
expect(application.render).to.equal(fn);
|
|
250
|
+
done();
|
|
251
|
+
}, 100);
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
it('throws if handler is not provided', function () {
|
|
255
|
+
expect(function () {
|
|
256
|
+
application.processQueue();
|
|
257
|
+
}).to.throw(Error);
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
describe('configure method', function () {
|
|
263
|
+
|
|
264
|
+
it('queues calls to configure', function () {
|
|
265
|
+
expect(application._configQueue.length).to.equal(0);
|
|
266
|
+
application.configure(config);
|
|
267
|
+
expect(application._configQueue.length).to.equal(1);
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
it('original configure method always gets replaced', function () {
|
|
271
|
+
var fn = sandbox.spy();
|
|
272
|
+
|
|
273
|
+
application.originalConfigure = application.configure;
|
|
274
|
+
application.processConfig(fn);
|
|
275
|
+
|
|
276
|
+
// Even calling application's original definition of configure
|
|
277
|
+
// should call the new function.
|
|
278
|
+
application.originalConfigure();
|
|
279
|
+
application.originalConfigure();
|
|
280
|
+
application.originalConfigure();
|
|
281
|
+
|
|
282
|
+
sinon.assert.calledThrice(fn);
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
});
|
|
286
|
+
|
|
287
|
+
describe('processConfig method', function () {
|
|
288
|
+
|
|
289
|
+
it('processes the queue', function () {
|
|
290
|
+
var fn = sandbox.spy();
|
|
291
|
+
|
|
292
|
+
application.configure(config);
|
|
293
|
+
application.configure(config);
|
|
294
|
+
application.processConfig(fn);
|
|
295
|
+
|
|
296
|
+
sinon.assert.calledTwice(fn);
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
it('redefines the configure method', function () {
|
|
300
|
+
var fn = function () {};
|
|
301
|
+
|
|
302
|
+
application.processConfig(fn);
|
|
303
|
+
expect(application.configure).to.equal(fn);
|
|
304
|
+
});
|
|
305
|
+
|
|
306
|
+
it('throws if handler is not provided', function () {
|
|
307
|
+
expect(function () {
|
|
308
|
+
application.processConfig();
|
|
309
|
+
}).to.throw(Error);
|
|
310
|
+
});
|
|
311
|
+
|
|
312
|
+
});
|
|
313
|
+
});
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileOverview
|
|
3
|
+
* Unit tests for the body module.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// Imports.
|
|
7
|
+
var body = require('../../../lib/body');
|
|
8
|
+
|
|
9
|
+
describe('lib/body', function () {
|
|
10
|
+
|
|
11
|
+
it('Should return the body', function () {
|
|
12
|
+
expect(body().tagName).to.equal('BODY');
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
});
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
//Imports
|
|
2
|
+
|
|
3
|
+
var BvFetch = require('../../../lib/bvFetch');
|
|
4
|
+
|
|
5
|
+
describe('BvFetch', function () {
|
|
6
|
+
let bvFetchInstance;
|
|
7
|
+
let cacheStub;
|
|
8
|
+
let cacheStorage;
|
|
9
|
+
|
|
10
|
+
beforeEach(function () {
|
|
11
|
+
bvFetchInstance = new BvFetch({
|
|
12
|
+
shouldCache: null,
|
|
13
|
+
cacheName: 'testCache'
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
// Define cacheStorage as a Map
|
|
17
|
+
cacheStorage = new Map();
|
|
18
|
+
|
|
19
|
+
// Stubbing caches.open
|
|
20
|
+
cacheStub = sinon.stub(caches, 'open').resolves({
|
|
21
|
+
match: key => {
|
|
22
|
+
const cachedResponse = cacheStorage.get(key);
|
|
23
|
+
return Promise.resolve(cachedResponse);
|
|
24
|
+
},
|
|
25
|
+
put: (key, response) => {
|
|
26
|
+
cacheStorage.set(key, response);
|
|
27
|
+
return Promise.resolve();
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
afterEach(function () {
|
|
34
|
+
bvFetchInstance = null;
|
|
35
|
+
// Restore the original method after each test
|
|
36
|
+
caches.open.restore();
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it('should generate correct cache key', function () {
|
|
40
|
+
const url = 'https://jsonplaceholder.typicode.com/todos';
|
|
41
|
+
const options = {
|
|
42
|
+
method: 'GET',
|
|
43
|
+
headers: {
|
|
44
|
+
'X-Header-1': 'Value 1',
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
const expectedKey = new Request(url, options)
|
|
48
|
+
const generatedKey = bvFetchInstance.generateCacheKey(url, options);
|
|
49
|
+
expect(generatedKey.url).to.equal(expectedKey.url);
|
|
50
|
+
expect(generatedKey.headers).to.deep.equal(expectedKey.headers);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
it('should fetch from cache when the response is cached', function (done) {
|
|
55
|
+
const url = 'https://jsonplaceholder.typicode.com/todos';
|
|
56
|
+
const options = {
|
|
57
|
+
method: 'GET',
|
|
58
|
+
headers: {
|
|
59
|
+
'X-Header-1': 'Value 1',
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
// Mocking cache response
|
|
64
|
+
const mockResponse = new Response('Mock Data', {
|
|
65
|
+
status: 200,
|
|
66
|
+
statusText: 'OK',
|
|
67
|
+
headers: {
|
|
68
|
+
'Cache-Control': 'max-age=3600',
|
|
69
|
+
'X-Bazaarvoice-Cached-Time': Date.now()
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
const cacheKey = bvFetchInstance.generateCacheKey(url, options);
|
|
74
|
+
|
|
75
|
+
// Overriding the stub for this specific test case
|
|
76
|
+
caches.open.resolves({
|
|
77
|
+
match: (key) => {
|
|
78
|
+
expect(key.url).to.equal(cacheKey.url);
|
|
79
|
+
expect(key.headers).to.deep.equal(cacheKey.headers);
|
|
80
|
+
return Promise.resolve(mockResponse)
|
|
81
|
+
},
|
|
82
|
+
put: (key, response) => {
|
|
83
|
+
cacheStorage.set(key, response);
|
|
84
|
+
return Promise.resolve();
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
// Simulate that the response is cached
|
|
89
|
+
bvFetchInstance.cachedRequests.add(cacheKey);
|
|
90
|
+
|
|
91
|
+
// Call the function under test
|
|
92
|
+
bvFetchInstance.bvFetchFunc(url, options)
|
|
93
|
+
.then(response => {
|
|
94
|
+
// Check if response is fetched from cache
|
|
95
|
+
expect(response).to.not.be.null;
|
|
96
|
+
|
|
97
|
+
// Check if response is cached
|
|
98
|
+
const cachedResponse = cacheStorage.get(cacheKey);
|
|
99
|
+
expect(cachedResponse).to.not.be.null;
|
|
100
|
+
|
|
101
|
+
// Check if caches.open was called
|
|
102
|
+
expect(cacheStub.called).to.be.true;
|
|
103
|
+
|
|
104
|
+
done();
|
|
105
|
+
})
|
|
106
|
+
.catch(error => {
|
|
107
|
+
done(error); // Call done with error if any
|
|
108
|
+
})
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
it('should fetch from network when response is not cached', function (done) {
|
|
113
|
+
const url = 'https://jsonplaceholder.typicode.com/todos';
|
|
114
|
+
const options = {};
|
|
115
|
+
|
|
116
|
+
const matchSpy = sinon.spy((key) => {
|
|
117
|
+
expect(key).to.equal(cacheKey);
|
|
118
|
+
Promise.resolve(null)
|
|
119
|
+
});
|
|
120
|
+
caches.open.resolves({
|
|
121
|
+
match: matchSpy,
|
|
122
|
+
put: (key, response) => {
|
|
123
|
+
cacheStorage.set(key, response);
|
|
124
|
+
return Promise.resolve();
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
bvFetchInstance.bvFetchFunc(url, options)
|
|
130
|
+
.then(response => {
|
|
131
|
+
// Check if response is fetched from network
|
|
132
|
+
expect(response).to.not.be.null;
|
|
133
|
+
console.log(response.body)
|
|
134
|
+
|
|
135
|
+
// Check if caches.match was called
|
|
136
|
+
expect(matchSpy.called).to.be.false;
|
|
137
|
+
|
|
138
|
+
done();
|
|
139
|
+
})
|
|
140
|
+
.catch(done);
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
it('should not cache response when there is an error', function (done) {
|
|
144
|
+
const url = 'https://jsonplaceholder.typicode.com/todos';
|
|
145
|
+
const options = {};
|
|
146
|
+
|
|
147
|
+
// Define shouldCache directly in bvFetchInstance
|
|
148
|
+
bvFetchInstance.shouldCache = (res) => {
|
|
149
|
+
return false
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
bvFetchInstance.bvFetchFunc(url, options)
|
|
153
|
+
.then(response => {
|
|
154
|
+
// Check if response is fetched from network
|
|
155
|
+
setTimeout(() => {
|
|
156
|
+
expect(response).to.not.be.null;
|
|
157
|
+
console.log(response.body)
|
|
158
|
+
|
|
159
|
+
// Check if caches.match was called
|
|
160
|
+
expect(cacheStub.calledOnce).to.be.false;
|
|
161
|
+
|
|
162
|
+
// Check if response is not cached
|
|
163
|
+
const cachedResponse = cacheStorage.get(url);
|
|
164
|
+
expect(cachedResponse).to.be.undefined;
|
|
165
|
+
}, 500)
|
|
166
|
+
done();
|
|
167
|
+
})
|
|
168
|
+
.catch(done);
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
it('should handle a 204 response without a JSON parse error', function (done) {
|
|
172
|
+
const cacheKey = bvFetchInstance.generateCacheKey('https://example.com/empty', {});
|
|
173
|
+
const shouldCache = sinon.spy();
|
|
174
|
+
const response = new Response(null, {
|
|
175
|
+
status: 204,
|
|
176
|
+
headers: {
|
|
177
|
+
'Cache-Control': 'max-age=3600'
|
|
178
|
+
}
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
bvFetchInstance.shouldCache = shouldCache;
|
|
182
|
+
expect(() => bvFetchInstance.cacheData(response, cacheKey)).to.not.throw();
|
|
183
|
+
|
|
184
|
+
setTimeout(() => {
|
|
185
|
+
expect(shouldCache.called).to.be.false;
|
|
186
|
+
expect(cacheStorage.get(cacheKey)).to.be.undefined;
|
|
187
|
+
done();
|
|
188
|
+
}, 0);
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
it('should delete cache when size is greater than 10 MB', function (done) {
|
|
192
|
+
// Mock cache entries exceeding 10 MB
|
|
193
|
+
const mockCacheEntries = [
|
|
194
|
+
{ key: 'key1', size: 6000000 }, // 6 MB
|
|
195
|
+
{ key: 'key2', size: 6000000 } // 6 MB
|
|
196
|
+
// Add more entries as needed to exceed 10 MB
|
|
197
|
+
];
|
|
198
|
+
|
|
199
|
+
// Stub cache operations
|
|
200
|
+
const deleteSpy = sinon.spy(
|
|
201
|
+
(key) => {
|
|
202
|
+
const index = mockCacheEntries.findIndex(entry => entry.key === key);
|
|
203
|
+
if (index !== -1) {
|
|
204
|
+
mockCacheEntries.splice(index, 1); // Delete entry from mock cache entries
|
|
205
|
+
}
|
|
206
|
+
return Promise.resolve(true);
|
|
207
|
+
}
|
|
208
|
+
)
|
|
209
|
+
caches.open.resolves({
|
|
210
|
+
keys: () => Promise.resolve(mockCacheEntries.map(entry => entry.key)),
|
|
211
|
+
match: (key) => {
|
|
212
|
+
const entry = mockCacheEntries.find(entry => entry.key === key);
|
|
213
|
+
if (entry) {
|
|
214
|
+
return Promise.resolve({
|
|
215
|
+
headers: new Headers({
|
|
216
|
+
'X-Bazaarvoice-Response-Size': entry.size.toString(),
|
|
217
|
+
'X-Bazaarvoice-Cached-Time': Date.now(),
|
|
218
|
+
'Cache-Control': 'max-age=3600'
|
|
219
|
+
})
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
else {
|
|
223
|
+
return Promise.resolve(null);
|
|
224
|
+
}
|
|
225
|
+
},
|
|
226
|
+
delete: deleteSpy
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
// Create a new instance of BvFetch
|
|
230
|
+
const bvFetchInstance = new BvFetch({ shouldCache: true });
|
|
231
|
+
|
|
232
|
+
// Call manageCache function
|
|
233
|
+
bvFetchInstance.manageCache()
|
|
234
|
+
setTimeout(() => {
|
|
235
|
+
// Ensure cache deletion occurred until the total size is under 10 MB
|
|
236
|
+
const totalSizeAfterDeletion = mockCacheEntries.reduce((acc, entry) => acc + entry.size, 0);
|
|
237
|
+
expect(totalSizeAfterDeletion).to.be.at.most(10 * 1024 * 1024); // Total size should be under 10 MB
|
|
238
|
+
// Ensure cache.delete was called for each deleted entry
|
|
239
|
+
expect(deleteSpy.called).to.be.true;
|
|
240
|
+
expect(deleteSpy.callCount).to.equal(mockCacheEntries.length);
|
|
241
|
+
done();
|
|
242
|
+
}, 500);
|
|
243
|
+
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
});
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileOverview
|
|
3
|
+
* Unit tests for the checkHighContrast utility.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// Imports.
|
|
7
|
+
var global = require('../../../lib/global');
|
|
8
|
+
var checkHighContrast = require('../../../lib/checkHighContrast');
|
|
9
|
+
|
|
10
|
+
describe('lib/checkHighContrast', function () {
|
|
11
|
+
|
|
12
|
+
it('normally returns false', function () {
|
|
13
|
+
expect(checkHighContrast(global.document.body)).to.equal(false);
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
});
|