amphora-html 6.0.1-dev.0 → 7.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -0
- package/index.js +2 -0
- package/lib/clone-deep.js +181 -0
- package/lib/files.js +66 -0
- package/lib/media.js +83 -79
- package/lib/render.js +44 -19
- package/lib/setup.js +55 -28
- package/lib/styleguide.js +40 -15
- package/lib/utils.js +127 -0
- package/package.json +21 -44
- package/.circleci/config.yml +0 -44
- package/.eslintrc +0 -75
- package/.github/workflows/push.yml +0 -26
- package/.istanbul.yml +0 -51
- package/__mocks__/fileMock.js +0 -3
- package/docs/README.md +0 -31
- package/docs/integration.md +0 -93
- package/docs/intro.md +0 -21
- package/docs/style.md +0 -47
- package/lib/log.test.js +0 -42
- package/lib/media.test.js +0 -908
- package/lib/render.test.js +0 -295
- package/lib/setup.test.js +0 -153
- package/lib/styleguide.test.js +0 -268
- package/test/setupFile.js +0 -3
- package/website/README.md +0 -114
- package/website/core/Footer.js +0 -55
- package/website/package.json +0 -16
- package/website/pages/en/index.js +0 -103
- package/website/pages/en/versions.js +0 -92
- package/website/sidebars.json +0 -13
- package/website/siteConfig.js +0 -66
- package/website/static/css/custom.css +0 -16
- package/website/static/img/logo.svg +0 -13
- package/website/versioned_docs/version-4.0.0/integration.md +0 -94
- package/website/versioned_docs/version-4.0.0/intro.md +0 -22
- package/website/versioned_docs/version-4.0.0/style.md +0 -48
- package/website/versioned_sidebars/version-4.0.0-sidebars.json +0 -13
- package/website/versions.json +0 -3
package/lib/media.test.js
DELETED
|
@@ -1,908 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
/* eslint max-nested-callbacks:[2,5] */
|
|
3
|
-
|
|
4
|
-
const _ = require('lodash'),
|
|
5
|
-
filename = __filename.split('/').pop().split('.').shift(),
|
|
6
|
-
lib = require('./' + filename),
|
|
7
|
-
setup = require('./setup'),
|
|
8
|
-
styleguideUtil = require('./styleguide'),
|
|
9
|
-
files = require('nymag-fs');
|
|
10
|
-
|
|
11
|
-
jest.mock('nymag-fs', () => ({
|
|
12
|
-
fileExists: () => false,
|
|
13
|
-
readFilePromise: () => Promise.resolve(''),
|
|
14
|
-
tryRequire: () => ({})
|
|
15
|
-
}));
|
|
16
|
-
|
|
17
|
-
describe(_.startCase(filename), () => {
|
|
18
|
-
let basicHtml = '<html><head></head><body></body></html>',
|
|
19
|
-
basicSection = '<section><header></header><footer></footer></section>',
|
|
20
|
-
styleString = '.test { color: red; }',
|
|
21
|
-
linkString = '/css/article.css',
|
|
22
|
-
tagString = '/js/a.js',
|
|
23
|
-
scriptString = 'console.log("Tests!");',
|
|
24
|
-
componentStyleHtml = '<html><head><style>' + styleString + '</style></head><body></body></html>',
|
|
25
|
-
componentScriptHtml = `<html><head></head><body><script type="text/javascript">
|
|
26
|
-
// <![CDATA[
|
|
27
|
-
${scriptString}
|
|
28
|
-
// ]]
|
|
29
|
-
</script></body></html>`,
|
|
30
|
-
componentStyleSection = '<section><style>' + styleString + '</style><header></header><footer></footer></section>',
|
|
31
|
-
componentLinkedSection = `<section><link rel="stylesheet" type="text/css" href="${linkString}"><header></header><footer></footer></section>`,
|
|
32
|
-
componentScriptSection = `<section><header></header><footer></footer><script type="text/javascript">
|
|
33
|
-
// <![CDATA[
|
|
34
|
-
${scriptString}
|
|
35
|
-
// ]]
|
|
36
|
-
</script></section>`,
|
|
37
|
-
componentTaggedSection = `<section><header></header><footer></footer><script type="text/javascript" src="${tagString}"></script></section>`,
|
|
38
|
-
componentTaggedSectionWithBust = `<section><header></header><footer></footer><script type="text/javascript" src="${tagString}?version=a"></script></section>`;
|
|
39
|
-
|
|
40
|
-
const state = {
|
|
41
|
-
locals: {
|
|
42
|
-
edit: true,
|
|
43
|
-
site: {
|
|
44
|
-
slug: 'foo',
|
|
45
|
-
assetDir: '/foo'
|
|
46
|
-
}
|
|
47
|
-
},
|
|
48
|
-
_components: []
|
|
49
|
-
},
|
|
50
|
-
emptyMediaMap = {
|
|
51
|
-
scripts: [],
|
|
52
|
-
styles: []
|
|
53
|
-
},
|
|
54
|
-
cssMediaMap = {
|
|
55
|
-
scripts: [],
|
|
56
|
-
styles: ['/css/article.css']
|
|
57
|
-
},
|
|
58
|
-
scriptMediaMap = {
|
|
59
|
-
scripts: ['/js/a.js'],
|
|
60
|
-
styles: []
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
afterEach(() => {
|
|
64
|
-
lib.editStylesTags = false;
|
|
65
|
-
lib.editScriptsTags = false;
|
|
66
|
-
setup.resolveMedia = undefined;
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
describe('configure', () => {
|
|
70
|
-
const fn = lib['configure'];
|
|
71
|
-
|
|
72
|
-
test(
|
|
73
|
-
'sets both edit styles and scripts to true if a boolean is passed in',
|
|
74
|
-
() => {
|
|
75
|
-
fn(true);
|
|
76
|
-
|
|
77
|
-
expect(lib.editStylesTags).toBe(true);
|
|
78
|
-
expect(lib.editScriptsTags).toBe(true);
|
|
79
|
-
}
|
|
80
|
-
);
|
|
81
|
-
|
|
82
|
-
test(
|
|
83
|
-
'sets both edit styles and scripts to false if a boolean is passed in',
|
|
84
|
-
() => {
|
|
85
|
-
fn(false);
|
|
86
|
-
|
|
87
|
-
expect(lib.editStylesTags).toBe(false);
|
|
88
|
-
expect(lib.editScriptsTags).toBe(false);
|
|
89
|
-
}
|
|
90
|
-
);
|
|
91
|
-
|
|
92
|
-
test('uses object properties to set the values', () => {
|
|
93
|
-
fn({ styles: true, scripts: false });
|
|
94
|
-
|
|
95
|
-
expect(lib.editStylesTags).toBe(true);
|
|
96
|
-
expect(lib.editScriptsTags).toBe(false);
|
|
97
|
-
});
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
describe('getMediaMap', () => {
|
|
101
|
-
const fn = lib['getMediaMap'];
|
|
102
|
-
|
|
103
|
-
test('accepts state with empty components', () => {
|
|
104
|
-
expect(fn(state)).toEqual({manifestAssets: [], scripts: [], styles: []});
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
test('accepts list, empty slug (non-existent components)', () => {
|
|
108
|
-
expect(
|
|
109
|
-
fn(
|
|
110
|
-
_.merge(
|
|
111
|
-
{
|
|
112
|
-
_components: ['a', 'b', 'c']
|
|
113
|
-
},
|
|
114
|
-
_.omit(state, ['locals.site.slug'])
|
|
115
|
-
)
|
|
116
|
-
)
|
|
117
|
-
).toEqual({manifestAssets: [], scripts: [], styles: []});
|
|
118
|
-
});
|
|
119
|
-
|
|
120
|
-
test('accepts list and slug (non-existent components)', () => {
|
|
121
|
-
expect(
|
|
122
|
-
fn(
|
|
123
|
-
_.merge(
|
|
124
|
-
{
|
|
125
|
-
_components: ['a', 'b', 'c']
|
|
126
|
-
},
|
|
127
|
-
state
|
|
128
|
-
)
|
|
129
|
-
)
|
|
130
|
-
).toEqual({manifestAssets: [], scripts: [], styles: []});
|
|
131
|
-
});
|
|
132
|
-
|
|
133
|
-
test(
|
|
134
|
-
'retrieves media map based on getScriptFiles and getStyleFiles',
|
|
135
|
-
() => {
|
|
136
|
-
const expectedScriptFiles = [
|
|
137
|
-
'/e/a',
|
|
138
|
-
'/e/b',
|
|
139
|
-
'/e/c',
|
|
140
|
-
'/e/cc'
|
|
141
|
-
];
|
|
142
|
-
|
|
143
|
-
jest.spyOn(lib, 'getScriptFiles').mockReturnValue(expectedScriptFiles);
|
|
144
|
-
|
|
145
|
-
expect(
|
|
146
|
-
fn(
|
|
147
|
-
_.merge(
|
|
148
|
-
state,
|
|
149
|
-
{
|
|
150
|
-
_components: ['a', 'b', 'c']
|
|
151
|
-
}
|
|
152
|
-
)
|
|
153
|
-
)
|
|
154
|
-
).toEqual({manifestAssets: [], scripts: expectedScriptFiles, styles: []});
|
|
155
|
-
}
|
|
156
|
-
);
|
|
157
|
-
});
|
|
158
|
-
|
|
159
|
-
describe('getStyleFiles', () => {
|
|
160
|
-
const fn = lib['getStyleFiles'];
|
|
161
|
-
|
|
162
|
-
test(
|
|
163
|
-
'utilizes the default MEDIA_DIRECTORY when site has not assetDir defined',
|
|
164
|
-
() => {
|
|
165
|
-
jest.spyOn(files, 'fileExists').mockImplementation(path => {
|
|
166
|
-
if (path === `${process.cwd()}/public/css/a.css`) return true;
|
|
167
|
-
if (path === `${process.cwd()}/public/css/a.${state.locals.site.slug}.css`) return true;
|
|
168
|
-
return false;
|
|
169
|
-
});
|
|
170
|
-
|
|
171
|
-
expect(fn({
|
|
172
|
-
locals: {
|
|
173
|
-
edit: true,
|
|
174
|
-
site: {
|
|
175
|
-
slug: 'foo'
|
|
176
|
-
}
|
|
177
|
-
},
|
|
178
|
-
_components: [
|
|
179
|
-
'a',
|
|
180
|
-
'b'
|
|
181
|
-
]
|
|
182
|
-
})).toEqual([
|
|
183
|
-
'/css/a.css',
|
|
184
|
-
`/css/a.${state.locals.site.slug}.css`
|
|
185
|
-
]);
|
|
186
|
-
}
|
|
187
|
-
);
|
|
188
|
-
|
|
189
|
-
test('utilizes the assetHost when provided', () => {
|
|
190
|
-
jest.spyOn(files, 'fileExists').mockImplementation(path => {
|
|
191
|
-
if (path === `${state.locals.site.assetDir}/css/a.css`) return true;
|
|
192
|
-
if (path === `${state.locals.site.assetDir}/css/a.${state.locals.site.slug}.css`) return true;
|
|
193
|
-
return false;
|
|
194
|
-
});
|
|
195
|
-
|
|
196
|
-
expect(fn({
|
|
197
|
-
locals: {
|
|
198
|
-
edit: true,
|
|
199
|
-
site: {
|
|
200
|
-
slug: 'foo',
|
|
201
|
-
assetDir: '/foo',
|
|
202
|
-
assetHost: 'https://cache.foo.com'
|
|
203
|
-
}
|
|
204
|
-
},
|
|
205
|
-
_components: [
|
|
206
|
-
'a',
|
|
207
|
-
'b'
|
|
208
|
-
]
|
|
209
|
-
})).toEqual([
|
|
210
|
-
'https://cache.foo.com/css/a.css',
|
|
211
|
-
`https://cache.foo.com/css/a.${state.locals.site.slug}.css`
|
|
212
|
-
]);
|
|
213
|
-
});
|
|
214
|
-
|
|
215
|
-
test(
|
|
216
|
-
'returns no styles when there is a style guide but no _usedVariations object',
|
|
217
|
-
() => {
|
|
218
|
-
const localState = {
|
|
219
|
-
locals: {
|
|
220
|
-
edit: false,
|
|
221
|
-
site: {
|
|
222
|
-
slug: 'foo',
|
|
223
|
-
assetDir: '/foo',
|
|
224
|
-
styleguide: 'bar'
|
|
225
|
-
}
|
|
226
|
-
},
|
|
227
|
-
_components: []
|
|
228
|
-
};
|
|
229
|
-
|
|
230
|
-
expect(fn(localState)).toEqual([]);
|
|
231
|
-
}
|
|
232
|
-
);
|
|
233
|
-
|
|
234
|
-
describe('with no site styleguide (legacy)', () => {
|
|
235
|
-
test('handles an empty component list', () => {
|
|
236
|
-
expect(fn({
|
|
237
|
-
locals: state.locals,
|
|
238
|
-
_components: []
|
|
239
|
-
})).toEqual([]);
|
|
240
|
-
});
|
|
241
|
-
|
|
242
|
-
test('handles non-existent components', () => {
|
|
243
|
-
expect(fn({
|
|
244
|
-
locals: state.locals,
|
|
245
|
-
_components: [
|
|
246
|
-
'a',
|
|
247
|
-
'b'
|
|
248
|
-
]
|
|
249
|
-
})).toEqual([]);
|
|
250
|
-
});
|
|
251
|
-
|
|
252
|
-
test('handles existent and non-existent components', () => {
|
|
253
|
-
jest.spyOn(files, 'fileExists').mockImplementation(path => {
|
|
254
|
-
if (path === `${state.locals.site.assetDir}/css/a.css`) return true;
|
|
255
|
-
if (path === `${state.locals.site.assetDir}/css/a.${state.locals.site.slug}.css`) return true;
|
|
256
|
-
return false;
|
|
257
|
-
});
|
|
258
|
-
|
|
259
|
-
expect(fn({
|
|
260
|
-
locals: state.locals,
|
|
261
|
-
_components: [
|
|
262
|
-
'a',
|
|
263
|
-
'b'
|
|
264
|
-
]
|
|
265
|
-
})).toEqual([
|
|
266
|
-
'/css/a.css',
|
|
267
|
-
`/css/a.${state.locals.site.slug}.css`
|
|
268
|
-
]);
|
|
269
|
-
});
|
|
270
|
-
});
|
|
271
|
-
|
|
272
|
-
describe('with site styleguide (modern)', () => {
|
|
273
|
-
test('handles an empty component list', () => {
|
|
274
|
-
const localState = {
|
|
275
|
-
locals: {
|
|
276
|
-
edit: false,
|
|
277
|
-
site: {
|
|
278
|
-
slug: 'foo',
|
|
279
|
-
assetDir: '/foo',
|
|
280
|
-
styleguide: 'bar'
|
|
281
|
-
}
|
|
282
|
-
},
|
|
283
|
-
_components: [],
|
|
284
|
-
_usedVariations: []
|
|
285
|
-
};
|
|
286
|
-
|
|
287
|
-
expect(fn(localState)).toEqual([]);
|
|
288
|
-
});
|
|
289
|
-
|
|
290
|
-
test('handles an empty _usedVariations', () => {
|
|
291
|
-
const localState = {
|
|
292
|
-
locals: {
|
|
293
|
-
edit: false,
|
|
294
|
-
site: {
|
|
295
|
-
slug: 'foo',
|
|
296
|
-
assetDir: '/foo',
|
|
297
|
-
styleguide: 'bar'
|
|
298
|
-
}
|
|
299
|
-
},
|
|
300
|
-
_components: [
|
|
301
|
-
'a',
|
|
302
|
-
'b'
|
|
303
|
-
],
|
|
304
|
-
_usedVariations: []
|
|
305
|
-
};
|
|
306
|
-
|
|
307
|
-
expect(fn(localState)).toEqual([]);
|
|
308
|
-
});
|
|
309
|
-
|
|
310
|
-
test('it handles non-existent component', () => {
|
|
311
|
-
const localState = {
|
|
312
|
-
locals: {
|
|
313
|
-
edit: false,
|
|
314
|
-
site: {
|
|
315
|
-
slug: 'foo',
|
|
316
|
-
assetDir: '/foo',
|
|
317
|
-
styleguide: 'bar'
|
|
318
|
-
}
|
|
319
|
-
},
|
|
320
|
-
_components: [
|
|
321
|
-
'a',
|
|
322
|
-
'b'
|
|
323
|
-
],
|
|
324
|
-
_usedVariations: [
|
|
325
|
-
'a_baz',
|
|
326
|
-
'b'
|
|
327
|
-
]
|
|
328
|
-
};
|
|
329
|
-
|
|
330
|
-
expect(fn(localState)).toEqual([]);
|
|
331
|
-
});
|
|
332
|
-
|
|
333
|
-
test(
|
|
334
|
-
'defaults to the _default styleguide if the site styleguide file cannot be found',
|
|
335
|
-
() => {
|
|
336
|
-
const localState = {
|
|
337
|
-
locals: {
|
|
338
|
-
edit: false,
|
|
339
|
-
site: {
|
|
340
|
-
slug: 'foo',
|
|
341
|
-
assetDir: '/foo',
|
|
342
|
-
styleguide: 'bar'
|
|
343
|
-
}
|
|
344
|
-
},
|
|
345
|
-
_components: [
|
|
346
|
-
'a',
|
|
347
|
-
'b'
|
|
348
|
-
],
|
|
349
|
-
_usedVariations: [
|
|
350
|
-
'a_baz',
|
|
351
|
-
'b'
|
|
352
|
-
]
|
|
353
|
-
};
|
|
354
|
-
|
|
355
|
-
jest.spyOn(files, 'fileExists').mockImplementation(path => {
|
|
356
|
-
if (path === `${localState.locals.site.assetDir}/css/a_baz._default.css`) return true;
|
|
357
|
-
return false;
|
|
358
|
-
});
|
|
359
|
-
|
|
360
|
-
expect(fn(localState)).toEqual([
|
|
361
|
-
'/css/a_baz._default.css'
|
|
362
|
-
]);
|
|
363
|
-
}
|
|
364
|
-
);
|
|
365
|
-
|
|
366
|
-
test('prefers the site styleguide file when it can be found', () => {
|
|
367
|
-
const localState = {
|
|
368
|
-
locals: {
|
|
369
|
-
edit: false,
|
|
370
|
-
site: {
|
|
371
|
-
slug: 'foo',
|
|
372
|
-
assetDir: '/foo',
|
|
373
|
-
styleguide: 'bar'
|
|
374
|
-
}
|
|
375
|
-
},
|
|
376
|
-
_components: [
|
|
377
|
-
'a',
|
|
378
|
-
'b'
|
|
379
|
-
],
|
|
380
|
-
_usedVariations: [
|
|
381
|
-
'a_baz',
|
|
382
|
-
'b'
|
|
383
|
-
]
|
|
384
|
-
};
|
|
385
|
-
|
|
386
|
-
jest.spyOn(files, 'fileExists').mockImplementation(path => {
|
|
387
|
-
if (path === `${localState.locals.site.assetDir}/css/a_baz.${localState.locals.site.styleguide}.css`) return true;
|
|
388
|
-
return false;
|
|
389
|
-
});
|
|
390
|
-
|
|
391
|
-
expect(fn(localState)).toEqual([
|
|
392
|
-
`/css/a_baz.${localState.locals.site.styleguide}.css`
|
|
393
|
-
]);
|
|
394
|
-
});
|
|
395
|
-
|
|
396
|
-
test('includes all variations in edit mode', () => {
|
|
397
|
-
const styleguide = 'bar',
|
|
398
|
-
assetDir = '/foo',
|
|
399
|
-
localState = {
|
|
400
|
-
locals: {
|
|
401
|
-
edit: true,
|
|
402
|
-
site: {
|
|
403
|
-
slug: 'foo',
|
|
404
|
-
assetDir,
|
|
405
|
-
styleguide
|
|
406
|
-
}
|
|
407
|
-
},
|
|
408
|
-
_components: ['a', 'b', 'c'],
|
|
409
|
-
_usedVariations: []
|
|
410
|
-
};
|
|
411
|
-
|
|
412
|
-
jest.spyOn(styleguideUtil, 'getVariations').mockImplementation(styleguide => {
|
|
413
|
-
if (styleguide === 'bar') return {a: ['a_x', 'a_y']};
|
|
414
|
-
return {};
|
|
415
|
-
}),
|
|
416
|
-
jest.spyOn(files, 'fileExists').mockImplementation(path => {
|
|
417
|
-
if (path === `${assetDir}/css/a_x.${styleguide}.css`) return true;
|
|
418
|
-
if (path === `${assetDir}/css/a_y._default.css`) return true;
|
|
419
|
-
if (path === `${assetDir}/css/b.${styleguide}.css`) return true;
|
|
420
|
-
if (path === `${assetDir}/css/c._default.css`) return true;
|
|
421
|
-
return false;
|
|
422
|
-
});
|
|
423
|
-
|
|
424
|
-
expect(fn(localState)).toEqual([
|
|
425
|
-
`/css/a_x.${styleguide}.css`,
|
|
426
|
-
'/css/a_y._default.css',
|
|
427
|
-
`/css/b.${styleguide}.css`,
|
|
428
|
-
'/css/c._default.css'
|
|
429
|
-
]);
|
|
430
|
-
});
|
|
431
|
-
|
|
432
|
-
test('includes layout styles', () => {
|
|
433
|
-
const styleguide = 'bar',
|
|
434
|
-
assetDir = '/foo',
|
|
435
|
-
localState = {
|
|
436
|
-
locals: {
|
|
437
|
-
edit: true,
|
|
438
|
-
site: {
|
|
439
|
-
slug: 'foo',
|
|
440
|
-
assetDir,
|
|
441
|
-
styleguide
|
|
442
|
-
}
|
|
443
|
-
},
|
|
444
|
-
_components: ['a', 'b', 'c'],
|
|
445
|
-
_usedVariations: [],
|
|
446
|
-
_layoutData: {
|
|
447
|
-
name: 'layout'
|
|
448
|
-
}
|
|
449
|
-
};
|
|
450
|
-
|
|
451
|
-
jest.spyOn(styleguideUtil, 'getVariations').mockImplementation(styleguide => {
|
|
452
|
-
if (styleguide === 'bar') return {a: ['a_x', 'a_y']};
|
|
453
|
-
return {};
|
|
454
|
-
}),
|
|
455
|
-
jest.spyOn(files, 'fileExists').mockImplementation(path => {
|
|
456
|
-
if (path === `${assetDir}/css/a_x.${styleguide}.css`) return true;
|
|
457
|
-
if (path === `${assetDir}/css/a_y._default.css`) return true;
|
|
458
|
-
if (path === `${assetDir}/css/b.${styleguide}.css`) return true;
|
|
459
|
-
if (path === `${assetDir}/css/c._default.css`) return true;
|
|
460
|
-
if (path === `${assetDir}/css/layout.${styleguide}.css`) return true;
|
|
461
|
-
return false;
|
|
462
|
-
});
|
|
463
|
-
|
|
464
|
-
expect(fn(localState)).toEqual([
|
|
465
|
-
`/css/a_x.${styleguide}.css`,
|
|
466
|
-
'/css/a_y._default.css',
|
|
467
|
-
`/css/b.${styleguide}.css`,
|
|
468
|
-
'/css/c._default.css',
|
|
469
|
-
`/css/layout.${styleguide}.css`
|
|
470
|
-
]);
|
|
471
|
-
});
|
|
472
|
-
});
|
|
473
|
-
});
|
|
474
|
-
|
|
475
|
-
describe('getScriptFiles', () => {
|
|
476
|
-
const fn = lib['getScriptFiles'];
|
|
477
|
-
|
|
478
|
-
test('handles an empty component list', () => {
|
|
479
|
-
const localState = {
|
|
480
|
-
locals: {
|
|
481
|
-
site: {
|
|
482
|
-
slug: 'foo',
|
|
483
|
-
assetDir: '/foo'
|
|
484
|
-
}
|
|
485
|
-
},
|
|
486
|
-
_components: []
|
|
487
|
-
};
|
|
488
|
-
|
|
489
|
-
expect(fn(localState)).toEqual([]);
|
|
490
|
-
});
|
|
491
|
-
|
|
492
|
-
test('handles non-existent components', () => {
|
|
493
|
-
const localState = {
|
|
494
|
-
locals: {
|
|
495
|
-
site: {
|
|
496
|
-
slug: 'foo',
|
|
497
|
-
assetDir: '/foo'
|
|
498
|
-
}
|
|
499
|
-
},
|
|
500
|
-
_components: [
|
|
501
|
-
'a'
|
|
502
|
-
]
|
|
503
|
-
};
|
|
504
|
-
|
|
505
|
-
expect(fn(localState)).toEqual([]);
|
|
506
|
-
});
|
|
507
|
-
|
|
508
|
-
test(
|
|
509
|
-
'handles a mixture non-existent components and existent components',
|
|
510
|
-
() => {
|
|
511
|
-
const localState = {
|
|
512
|
-
locals: {
|
|
513
|
-
site: {
|
|
514
|
-
slug: 'foo',
|
|
515
|
-
assetDir: '/foo'
|
|
516
|
-
}
|
|
517
|
-
},
|
|
518
|
-
_components: [
|
|
519
|
-
'a',
|
|
520
|
-
'b'
|
|
521
|
-
]
|
|
522
|
-
};
|
|
523
|
-
|
|
524
|
-
jest.spyOn(files, 'fileExists').mockImplementation(path => {
|
|
525
|
-
if (path === `${localState.locals.site.assetDir}/js/a.js`) return true;
|
|
526
|
-
if (path === `${localState.locals.site.assetDir}/js/a.${localState.locals.site.slug}.js`) return true;
|
|
527
|
-
if (path === `${localState.locals.site.assetDir}/js/a.client.js`) return true;
|
|
528
|
-
return false;
|
|
529
|
-
});
|
|
530
|
-
|
|
531
|
-
expect(fn(localState)).toEqual([
|
|
532
|
-
'/js/a.js',
|
|
533
|
-
`/js/a.${localState.locals.site.slug}.js`,
|
|
534
|
-
'/js/a.client.js'
|
|
535
|
-
]);
|
|
536
|
-
}
|
|
537
|
-
);
|
|
538
|
-
|
|
539
|
-
test(
|
|
540
|
-
'uses the MEDIA_DIRECTORY if one is not defined on the site',
|
|
541
|
-
() => {
|
|
542
|
-
const localState = {
|
|
543
|
-
locals: {
|
|
544
|
-
site: {
|
|
545
|
-
slug: 'foo'
|
|
546
|
-
}
|
|
547
|
-
},
|
|
548
|
-
_components: [
|
|
549
|
-
'a',
|
|
550
|
-
'b'
|
|
551
|
-
]
|
|
552
|
-
};
|
|
553
|
-
|
|
554
|
-
jest.spyOn(files, 'fileExists').mockImplementation(path => {
|
|
555
|
-
if (path === `${process.cwd()}/public/js/a.js`) return true;
|
|
556
|
-
if (path === `${process.cwd()}/public/js/a.${localState.locals.site.slug}.js`) return true;
|
|
557
|
-
if (path === `${process.cwd()}/public/js/a.client.js`) return true;
|
|
558
|
-
return false;
|
|
559
|
-
});
|
|
560
|
-
|
|
561
|
-
expect(fn(localState)).toEqual([
|
|
562
|
-
'/js/a.js',
|
|
563
|
-
`/js/a.${localState.locals.site.slug}.js`,
|
|
564
|
-
'/js/a.client.js'
|
|
565
|
-
]);
|
|
566
|
-
}
|
|
567
|
-
);
|
|
568
|
-
|
|
569
|
-
test('uses the assetHost value if one is passed in', () => {
|
|
570
|
-
const localState = {
|
|
571
|
-
locals: {
|
|
572
|
-
site: {
|
|
573
|
-
slug: 'foo',
|
|
574
|
-
assetDir: '/foo',
|
|
575
|
-
assetHost: 'https://cache.foo.com'
|
|
576
|
-
}
|
|
577
|
-
},
|
|
578
|
-
_components: [
|
|
579
|
-
'a',
|
|
580
|
-
'b'
|
|
581
|
-
]
|
|
582
|
-
};
|
|
583
|
-
|
|
584
|
-
jest.spyOn(files, 'fileExists').mockImplementation(path => {
|
|
585
|
-
if (path === `${localState.locals.site.assetDir}/js/a.js`) return true;
|
|
586
|
-
if (path === `${localState.locals.site.assetDir}/js/a.${localState.locals.site.slug}.js`) return true;
|
|
587
|
-
if (path === `${localState.locals.site.assetDir}/js/a.client.js`) return true;
|
|
588
|
-
return false;
|
|
589
|
-
});
|
|
590
|
-
|
|
591
|
-
expect(fn(localState)).toEqual([
|
|
592
|
-
`${localState.locals.site.assetHost}/js/a.js`,
|
|
593
|
-
`${localState.locals.site.assetHost}/js/a.${localState.locals.site.slug}.js`,
|
|
594
|
-
`${localState.locals.site.assetHost}/js/a.client.js`
|
|
595
|
-
]);
|
|
596
|
-
});
|
|
597
|
-
|
|
598
|
-
test(
|
|
599
|
-
'makes 3 file exists calls for every component in the component list',
|
|
600
|
-
() => {
|
|
601
|
-
const localState = {
|
|
602
|
-
locals: {
|
|
603
|
-
site: {
|
|
604
|
-
slug: 'foo',
|
|
605
|
-
assetDir: '/foo'
|
|
606
|
-
}
|
|
607
|
-
},
|
|
608
|
-
_components: [
|
|
609
|
-
'a',
|
|
610
|
-
'b'
|
|
611
|
-
]
|
|
612
|
-
};
|
|
613
|
-
|
|
614
|
-
jest.spyOn(files, 'fileExists').mockImplementation(() => false);
|
|
615
|
-
fn(localState);
|
|
616
|
-
expect(files.fileExists.mock.calls.map(function (argv) { return argv[0]; })).toEqual([
|
|
617
|
-
`${localState.locals.site.assetDir}/js/a.js`,
|
|
618
|
-
`${localState.locals.site.assetDir}/js/a.${localState.locals.site.slug}.js`,
|
|
619
|
-
`${localState.locals.site.assetDir}/js/a.client.js`,
|
|
620
|
-
`${localState.locals.site.assetDir}/js/b.js`,
|
|
621
|
-
`${localState.locals.site.assetDir}/js/b.${localState.locals.site.slug}.js`,
|
|
622
|
-
`${localState.locals.site.assetDir}/js/b.client.js`
|
|
623
|
-
]);
|
|
624
|
-
}
|
|
625
|
-
);
|
|
626
|
-
});
|
|
627
|
-
|
|
628
|
-
describe('getManifestAssets', () => {
|
|
629
|
-
const fn = lib['getManifestAssets'];
|
|
630
|
-
|
|
631
|
-
describe('constructs the correct asset URL', () => {
|
|
632
|
-
test('when assetHost is configured', () => {
|
|
633
|
-
const assetHost = 'https://assets.nymag.com';
|
|
634
|
-
const localState = {
|
|
635
|
-
locals: {
|
|
636
|
-
site: {
|
|
637
|
-
assetHost
|
|
638
|
-
}
|
|
639
|
-
},
|
|
640
|
-
_components: [
|
|
641
|
-
'a',
|
|
642
|
-
'b'
|
|
643
|
-
]
|
|
644
|
-
};
|
|
645
|
-
const manifest = {
|
|
646
|
-
entrypoints: {
|
|
647
|
-
a: {
|
|
648
|
-
assets: {
|
|
649
|
-
js: ['/a.js']
|
|
650
|
-
}
|
|
651
|
-
},
|
|
652
|
-
b: {
|
|
653
|
-
assets: {
|
|
654
|
-
js: ['b.js']
|
|
655
|
-
}
|
|
656
|
-
}
|
|
657
|
-
}
|
|
658
|
-
};
|
|
659
|
-
|
|
660
|
-
jest.spyOn(files, 'tryRequire').mockImplementation(() => manifest);
|
|
661
|
-
|
|
662
|
-
expect(fn(localState)).toEqual([
|
|
663
|
-
`${ assetHost }/a.js`,
|
|
664
|
-
`${ assetHost }/b.js`
|
|
665
|
-
]);
|
|
666
|
-
});
|
|
667
|
-
|
|
668
|
-
test('when assetHost is not configured', () => {
|
|
669
|
-
const localState = {
|
|
670
|
-
locals: {
|
|
671
|
-
site: {
|
|
672
|
-
}
|
|
673
|
-
},
|
|
674
|
-
_components: [
|
|
675
|
-
'a',
|
|
676
|
-
'b'
|
|
677
|
-
]
|
|
678
|
-
};
|
|
679
|
-
const manifest = {
|
|
680
|
-
entrypoints: {
|
|
681
|
-
a: {
|
|
682
|
-
assets: {
|
|
683
|
-
js: ['/a.js']
|
|
684
|
-
}
|
|
685
|
-
},
|
|
686
|
-
b: {
|
|
687
|
-
assets: {
|
|
688
|
-
js: ['b.js']
|
|
689
|
-
}
|
|
690
|
-
}
|
|
691
|
-
}
|
|
692
|
-
};
|
|
693
|
-
|
|
694
|
-
jest.spyOn(files, 'tryRequire').mockImplementation(() => manifest);
|
|
695
|
-
|
|
696
|
-
expect(fn(localState)).toEqual([
|
|
697
|
-
'/a.js',
|
|
698
|
-
'/b.js'
|
|
699
|
-
]);
|
|
700
|
-
});
|
|
701
|
-
|
|
702
|
-
test('without prepending assetPath', () => {
|
|
703
|
-
const localState = {
|
|
704
|
-
locals: {
|
|
705
|
-
site: {
|
|
706
|
-
assetPath: '/strategist'
|
|
707
|
-
}
|
|
708
|
-
},
|
|
709
|
-
_components: [
|
|
710
|
-
'a',
|
|
711
|
-
'b'
|
|
712
|
-
]
|
|
713
|
-
};
|
|
714
|
-
const manifest = {
|
|
715
|
-
entrypoints: {
|
|
716
|
-
a: {
|
|
717
|
-
assets: {
|
|
718
|
-
js: ['/a.js']
|
|
719
|
-
}
|
|
720
|
-
},
|
|
721
|
-
b: {
|
|
722
|
-
assets: {
|
|
723
|
-
js: ['b.js']
|
|
724
|
-
}
|
|
725
|
-
}
|
|
726
|
-
}
|
|
727
|
-
};
|
|
728
|
-
|
|
729
|
-
jest.spyOn(files, 'tryRequire').mockImplementation(() => manifest);
|
|
730
|
-
|
|
731
|
-
expect(fn(localState)).toEqual([
|
|
732
|
-
'/a.js',
|
|
733
|
-
'/b.js'
|
|
734
|
-
]);
|
|
735
|
-
});
|
|
736
|
-
});
|
|
737
|
-
});
|
|
738
|
-
|
|
739
|
-
describe('injectScriptsAndStyles', () => {
|
|
740
|
-
const fn = lib['injectScriptsAndStyles'];
|
|
741
|
-
|
|
742
|
-
test('calls resolveMedia if it\'s defined', () => {
|
|
743
|
-
setup.resolveMedia = jest.fn().mockReturnValue(emptyMediaMap);
|
|
744
|
-
return fn(state)(basicHtml).then(function () {
|
|
745
|
-
expect(setup.resolveMedia.mock.calls.length).toBe(1);
|
|
746
|
-
});
|
|
747
|
-
});
|
|
748
|
-
|
|
749
|
-
test('uses default media map if resolve media returns false', () => {
|
|
750
|
-
setup.resolveMedia = jest.fn().mockReturnValue(false);
|
|
751
|
-
// jest.spyOn(setup, 'resolveMedia').mockReturnValue(false);
|
|
752
|
-
|
|
753
|
-
return fn(state)(basicHtml)
|
|
754
|
-
.then(function () {
|
|
755
|
-
expect(setup.resolveMedia.mock.calls.length).toBe(1);
|
|
756
|
-
});
|
|
757
|
-
});
|
|
758
|
-
|
|
759
|
-
test('throws when missing html', () => {
|
|
760
|
-
expect.assertions(1);
|
|
761
|
-
expect(() => {
|
|
762
|
-
fn(state)();
|
|
763
|
-
}).toThrowError('Missing html parameter');
|
|
764
|
-
});
|
|
765
|
-
|
|
766
|
-
test('adds nothing to bottom of head when no styles', () => {
|
|
767
|
-
return fn(state)(basicHtml).then((html) => {
|
|
768
|
-
expect(html).toEqual(basicHtml);
|
|
769
|
-
});
|
|
770
|
-
});
|
|
771
|
-
|
|
772
|
-
test('if in view mode, just inlines immediately', () => {
|
|
773
|
-
return fn({ locals: { edit: false, site: {} }, _components: [] })(basicHtml).then((html) => {
|
|
774
|
-
expect(html).toEqual(basicHtml);
|
|
775
|
-
});
|
|
776
|
-
});
|
|
777
|
-
|
|
778
|
-
test('adds nothing to top of root when no components', () => {
|
|
779
|
-
return fn(state)(basicSection)
|
|
780
|
-
.then(function (html) {
|
|
781
|
-
expect(html).toEqual(basicSection);
|
|
782
|
-
});
|
|
783
|
-
});
|
|
784
|
-
|
|
785
|
-
test('adds nothing to bottom of root when no components', () => {
|
|
786
|
-
return fn(state)(basicHtml)
|
|
787
|
-
.then(function (html) {
|
|
788
|
-
expect(html).toEqual(basicHtml);
|
|
789
|
-
});
|
|
790
|
-
});
|
|
791
|
-
|
|
792
|
-
describe('with styles', () => {
|
|
793
|
-
function resolveBody(html) {
|
|
794
|
-
expect(html).toEqual(componentStyleHtml);
|
|
795
|
-
}
|
|
796
|
-
|
|
797
|
-
function resolveSection(html) {
|
|
798
|
-
expect(html).toEqual(componentStyleSection);
|
|
799
|
-
}
|
|
800
|
-
|
|
801
|
-
function resolveLinkedSection(html) {
|
|
802
|
-
expect(html).toEqual(componentLinkedSection);
|
|
803
|
-
}
|
|
804
|
-
|
|
805
|
-
// Body HTML
|
|
806
|
-
test('adds to bottom of head', () => {
|
|
807
|
-
jest.spyOn(lib, 'getMediaMap').mockReturnValue(_.cloneDeep(cssMediaMap));
|
|
808
|
-
jest.spyOn(files, 'readFilePromise').mockResolvedValueOnce(styleString);
|
|
809
|
-
|
|
810
|
-
return fn(state)(basicHtml)
|
|
811
|
-
.then(resolveBody);
|
|
812
|
-
});
|
|
813
|
-
|
|
814
|
-
// Error
|
|
815
|
-
test('throws an error if there is an error reading the file', () => {
|
|
816
|
-
expect.assertions(1);
|
|
817
|
-
|
|
818
|
-
jest.spyOn(lib, 'getMediaMap').mockReturnValue(_.cloneDeep(cssMediaMap));
|
|
819
|
-
jest.spyOn(files, 'readFilePromise').mockRejectedValueOnce('darn');
|
|
820
|
-
|
|
821
|
-
return expect(fn(state)(basicHtml)).rejects.toMatch('darn');
|
|
822
|
-
});
|
|
823
|
-
|
|
824
|
-
// Section HTML
|
|
825
|
-
test('adds to top of root', () => {
|
|
826
|
-
files.readFilePromise.cache = new _.memoize.Cache();
|
|
827
|
-
|
|
828
|
-
jest.spyOn(lib, 'getMediaMap').mockReturnValue(_.cloneDeep(cssMediaMap));
|
|
829
|
-
jest.spyOn(files, 'readFilePromise').mockResolvedValueOnce(styleString);
|
|
830
|
-
|
|
831
|
-
return fn(state)(basicSection)
|
|
832
|
-
.then(resolveSection);
|
|
833
|
-
});
|
|
834
|
-
|
|
835
|
-
/* don't think this is testing anything... */
|
|
836
|
-
test.skip('it checks for inlining vs script tags if edit mode', () => {
|
|
837
|
-
jest.spyOn(lib, 'getMediaMap').mockReturnValue(_.cloneDeep(cssMediaMap));
|
|
838
|
-
jest.spyOn(files, 'readFilePromise').mockResolvedValueOnce(styleString);
|
|
839
|
-
// sandbox.stub(lib, 'getMediaMap').returns(_.cloneDeep(cssMediaMap));
|
|
840
|
-
// files.readFilePromise.onCall(0).returns(Promise.resolve(styleString));
|
|
841
|
-
|
|
842
|
-
return fn(state)(basicSection)
|
|
843
|
-
.then(resolveSection);
|
|
844
|
-
});
|
|
845
|
-
|
|
846
|
-
test('inlines styles in edit mode if the options', () => {
|
|
847
|
-
jest.spyOn(lib, 'getMediaMap').mockReturnValue(_.cloneDeep(cssMediaMap));
|
|
848
|
-
lib.configure({ styles: true, scripts: false });
|
|
849
|
-
|
|
850
|
-
return fn(state)(basicSection)
|
|
851
|
-
.then(resolveLinkedSection);
|
|
852
|
-
});
|
|
853
|
-
});
|
|
854
|
-
|
|
855
|
-
describe('with scripts', () => {
|
|
856
|
-
function resolveBody(html) {
|
|
857
|
-
expect(html).toEqual(componentScriptHtml);
|
|
858
|
-
}
|
|
859
|
-
|
|
860
|
-
function resolveSection(html) {
|
|
861
|
-
expect(html).toEqual(componentScriptSection);
|
|
862
|
-
}
|
|
863
|
-
|
|
864
|
-
function resolveTaggedSection(html) {
|
|
865
|
-
expect(html).toEqual(componentTaggedSection);
|
|
866
|
-
}
|
|
867
|
-
|
|
868
|
-
function resolveTaggedSectionWithBust(html) {
|
|
869
|
-
expect(html).toEqual(componentTaggedSectionWithBust);
|
|
870
|
-
}
|
|
871
|
-
|
|
872
|
-
test('adds to bottom of body', () => {
|
|
873
|
-
jest.spyOn(lib, 'getMediaMap').mockReturnValue(_.cloneDeep(scriptMediaMap));
|
|
874
|
-
jest.spyOn(files, 'readFilePromise').mockResolvedValueOnce(scriptString);
|
|
875
|
-
|
|
876
|
-
return fn(state)(basicHtml)
|
|
877
|
-
.then(resolveBody);
|
|
878
|
-
});
|
|
879
|
-
|
|
880
|
-
test('adds to bottom of root', () => {
|
|
881
|
-
jest.spyOn(lib, 'getMediaMap').mockReturnValue(_.cloneDeep(scriptMediaMap));
|
|
882
|
-
jest.spyOn(files, 'readFilePromise').mockResolvedValueOnce(scriptString);
|
|
883
|
-
|
|
884
|
-
return fn(state)(basicSection)
|
|
885
|
-
.then(resolveSection);
|
|
886
|
-
});
|
|
887
|
-
|
|
888
|
-
test('inlines scripts in edit mode if the options', () => {
|
|
889
|
-
jest.spyOn(lib, 'getMediaMap').mockReturnValue(_.cloneDeep(scriptMediaMap));
|
|
890
|
-
lib.configure({ styles: false, scripts: true });
|
|
891
|
-
|
|
892
|
-
return fn(state)(basicSection)
|
|
893
|
-
.then(resolveTaggedSection);
|
|
894
|
-
});
|
|
895
|
-
|
|
896
|
-
test(
|
|
897
|
-
'inlines scripts in edit mode if the options with the cache busting',
|
|
898
|
-
() => {
|
|
899
|
-
jest.spyOn(lib, 'getMediaMap').mockReturnValue(_.cloneDeep(scriptMediaMap));
|
|
900
|
-
lib.configure({ styles: false, scripts: true }, 'a');
|
|
901
|
-
|
|
902
|
-
return fn(state)(basicSection)
|
|
903
|
-
.then(resolveTaggedSectionWithBust);
|
|
904
|
-
}
|
|
905
|
-
);
|
|
906
|
-
});
|
|
907
|
-
});
|
|
908
|
-
});
|