@quintype/seo 1.41.5-description-fallback.1 → 1.41.5-description-fallback.2

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.
@@ -1,44 +1,48 @@
1
1
  const { TextTags, SEO } = require("..");
2
2
  const { getSeoMetadata, assertContains, assertDoesNotContains } = require("./utils");
3
3
 
4
- const assert = require('assert');
4
+ const assert = require("assert");
5
5
  const url = require("url");
6
6
 
7
- describe('TextTags', function () {
8
- describe('Home And Section Page', function () {
7
+ describe("TextTags", function () {
8
+ describe("Home And Section Page", function () {
9
9
  it("gets the homepage config", function () {
10
10
  const seoConfig = {
11
11
  generators: [TextTags],
12
- }
13
- const config = { "seo-metadata": [{ "owner-type": "home", "owner-id": null, "data": { 'page-title': "Foobar" }, authors: [{ 'name': "foo" }] }] };
14
- const string = getSeoMetadata(seoConfig, config, 'home-page', {}, { url: url.parse("/") });
15
- assertContains('<title>Foobar</title>', string);
12
+ };
13
+ const config = {
14
+ "seo-metadata": [
15
+ { "owner-type": "home", "owner-id": null, data: { "page-title": "Foobar" }, authors: [{ name: "foo" }] },
16
+ ],
17
+ };
18
+ const string = getSeoMetadata(seoConfig, config, "home-page", {}, { url: url.parse("/") });
19
+ assertContains("<title>Foobar</title>", string);
16
20
  });
17
21
 
18
22
  it("does not crash if the metadata is missing", function () {
19
23
  const seoConfig = {
20
24
  generators: [TextTags],
21
- }
25
+ };
22
26
  const config = { "seo-metadata": [] };
23
- const string = getSeoMetadata(seoConfig, config, 'home-page', {}, { url: url.parse("/") })
24
- assert.equal('', string);
27
+ const string = getSeoMetadata(seoConfig, config, "home-page", {}, { url: url.parse("/") });
28
+ assert.equal("", string);
25
29
  });
26
30
 
27
- it('generates tags for custom static pages', function () {
31
+ it("generates tags for custom static pages", function () {
28
32
  const seoConfig = {
29
33
  generators: [TextTags],
30
34
  customTags: {
31
- 'services-page': {
35
+ "services-page": {
32
36
  title: "services-page-title",
33
37
  "page-title": "services-page-title",
34
38
  description: "services-page-desc",
35
- keywords: ['services-page1', 'services-page2']
36
- }
37
- }
39
+ keywords: ["services-page1", "services-page2"],
40
+ },
41
+ },
38
42
  };
39
- const config = { "seo-metadata": [{ "owner-type": "home", "data": { 'page-title': "Foobar" } }] };
40
- const string = getSeoMetadata(seoConfig, config, 'services-page', {}, { url: url.parse("/") })
41
- assertContains('<title>services-page-title</title>', string);
43
+ const config = { "seo-metadata": [{ "owner-type": "home", data: { "page-title": "Foobar" } }] };
44
+ const string = getSeoMetadata(seoConfig, config, "services-page", {}, { url: url.parse("/") });
45
+ assertContains("<title>services-page-title</title>", string);
42
46
  assertContains('<meta name="description" content="services-page-desc"/>', string);
43
47
  assertContains('<meta name="title" content="services-page-title"/>', string);
44
48
  assertContains('<meta name="keywords" content="services-page1,services-page2"/>', string);
@@ -49,14 +53,20 @@ describe('TextTags', function () {
49
53
  generators: [TextTags],
50
54
  };
51
55
  const data = {
52
- 'page-title': "Quintype Demo Homepage",
56
+ "page-title": "Quintype Demo Homepage",
53
57
  title: "Quintype Demo Homepage Meta",
54
58
  description: "This is a demo page for Quintype",
55
- keywords: "quintype, demo"
59
+ keywords: "quintype, demo",
56
60
  };
57
- const config = { "seo-metadata": [{ "owner-type": 'section', 'owner-id': 42, data }] };
58
- const string = getSeoMetadata(seoConfig, config, 'section-page', { data: { section: { id: 42 } } }, { url: url.parse("/") });
59
- assertContains('<title>Quintype Demo Homepage</title>', string);
61
+ const config = { "seo-metadata": [{ "owner-type": "section", "owner-id": 42, data }] };
62
+ const string = getSeoMetadata(
63
+ seoConfig,
64
+ config,
65
+ "section-page",
66
+ { data: { section: { id: 42 } } },
67
+ { url: url.parse("/") }
68
+ );
69
+ assertContains("<title>Quintype Demo Homepage</title>", string);
60
70
  assertContains('<meta name="description" content="This is a demo page for Quintype"/>', string);
61
71
  assertContains('<meta name="title" content="Quintype Demo Homepage Meta"/>', string);
62
72
  assertContains('<meta name="keywords" content="quintype, demo"/>', string);
@@ -67,18 +77,24 @@ describe('TextTags', function () {
67
77
  generators: [TextTags],
68
78
  };
69
79
  const data = {
70
- 'page-title': "Quintype Demo Homepage",
80
+ "page-title": "Quintype Demo Homepage",
71
81
  title: "Quintype Demo Homepage Meta",
72
- keywords: "quintype, demo"
82
+ keywords: "quintype, demo",
73
83
  };
74
84
  const config = {
75
85
  "seo-metadata": [
76
- { "owner-type": 'section', 'owner-id': 42, data },
77
- { "owner-type": 'home', 'owner-id': 42, data: { 'description': 'home description' } }
78
- ]
86
+ { "owner-type": "section", "owner-id": 42, data },
87
+ { "owner-type": "home", "owner-id": 42, data: { description: "home description" } },
88
+ ],
79
89
  };
80
- const string = getSeoMetadata(seoConfig, config, 'section-page', { data: { section: { id: 42 } } }, { url: url.parse("/") });
81
- assertContains('<title>Quintype Demo Homepage</title>', string);
90
+ const string = getSeoMetadata(
91
+ seoConfig,
92
+ config,
93
+ "section-page",
94
+ { data: { section: { id: 42 } } },
95
+ { url: url.parse("/") }
96
+ );
97
+ assertContains("<title>Quintype Demo Homepage</title>", string);
82
98
  assertContains('<meta name="description" content="home description"/>', string);
83
99
  assertContains('<meta name="title" content="Quintype Demo Homepage Meta"/>', string);
84
100
  assertContains('<meta name="keywords" content="quintype, demo"/>', string);
@@ -89,24 +105,28 @@ describe('TextTags', function () {
89
105
  generators: [TextTags],
90
106
  };
91
107
  const data = {
92
- 'page-title': "Quintype Demo Homepage",
93
- 'description': "Section Description",
94
- 'keywords': "quintype, demo"
108
+ "page-title": "Quintype Demo Homepage",
109
+ description: "Section Description",
110
+ keywords: "quintype, demo",
95
111
  };
96
112
  const config = {
97
- "sections": [
113
+ sections: [
98
114
  {
99
- "id": 42,
100
- "name": "Current Affairs",
115
+ id: 42,
116
+ name: "Current Affairs",
101
117
  "section-url": "http://foo.com/",
102
- }
118
+ },
103
119
  ],
104
- "seo-metadata": [
105
- { "owner-type": 'section', 'owner-id': 42, data },
106
- ]
120
+ "seo-metadata": [{ "owner-type": "section", "owner-id": 42, data }],
107
121
  };
108
- const string = getSeoMetadata(seoConfig, config, 'section-page', { data: { section: { id: 42 } } }, { url: url.parse("/") });
109
- assertContains('<title>Quintype Demo Homepage</title>', string);
122
+ const string = getSeoMetadata(
123
+ seoConfig,
124
+ config,
125
+ "section-page",
126
+ { data: { section: { id: 42 } } },
127
+ { url: url.parse("/") }
128
+ );
129
+ assertContains("<title>Quintype Demo Homepage</title>", string);
110
130
  assertContains('<meta name="description" content="Section Description"/>', string);
111
131
  assertContains('<meta name="title" content="Current Affairs"/>', string);
112
132
  assertContains('<meta name="keywords" content="quintype, demo"/>', string);
@@ -118,23 +138,27 @@ describe('TextTags', function () {
118
138
  generators: [TextTags],
119
139
  };
120
140
  const data = {
121
- 'title': "Quintype Demo",
122
- 'description': "Section Description",
123
- 'keywords': "quintype, demo"
141
+ title: "Quintype Demo",
142
+ description: "Section Description",
143
+ keywords: "quintype, demo",
124
144
  };
125
145
  const config = {
126
- "sections": [
146
+ sections: [
127
147
  {
128
- "id": 42,
129
- "name": "Current Affairs",
130
- }
148
+ id: 42,
149
+ name: "Current Affairs",
150
+ },
131
151
  ],
132
- "seo-metadata": [
133
- { "owner-type": 'section', 'owner-id': 42, data },
134
- ]
152
+ "seo-metadata": [{ "owner-type": "section", "owner-id": 42, data }],
135
153
  };
136
- const string = getSeoMetadata(seoConfig, config, 'section-page', { data: { section: { id: 42 } } }, { url: url.parse("/") });
137
- assertContains('<title>Current Affairs</title>', string);
154
+ const string = getSeoMetadata(
155
+ seoConfig,
156
+ config,
157
+ "section-page",
158
+ { data: { section: { id: 42 } } },
159
+ { url: url.parse("/") }
160
+ );
161
+ assertContains("<title>Current Affairs</title>", string);
138
162
  assertContains('<meta name="description" content="Section Description"/>', string);
139
163
  assertContains('<meta name="title" content="Quintype Demo"/>', string);
140
164
  assertContains('<meta name="keywords" content="quintype, demo"/>', string);
@@ -143,29 +167,38 @@ describe('TextTags', function () {
143
167
  it("defaults to the homepage config if section is not found", function () {
144
168
  const seoConfig = {
145
169
  generators: [TextTags],
146
- }
147
- const config = { "seo-metadata": [{ "owner-type": 'home', "owner-id": null, data: { 'page-title': "Foobar" } }] };
148
- const string = getSeoMetadata(seoConfig, config, 'section-page', { data: { section: { id: 42 } } }, { url: url.parse("/") })
149
- assertContains('<title>Foobar</title>', string);
170
+ };
171
+ const config = { "seo-metadata": [{ "owner-type": "home", "owner-id": null, data: { "page-title": "Foobar" } }] };
172
+ const string = getSeoMetadata(
173
+ seoConfig,
174
+ config,
175
+ "section-page",
176
+ { data: { section: { id: 42 } } },
177
+ { url: url.parse("/") }
178
+ );
179
+ assertContains("<title>Foobar</title>", string);
150
180
  });
151
181
 
152
182
  it("uses a given title if that is passed instead", function () {
153
183
  const seoConfig = {
154
184
  generators: [TextTags],
155
- }
156
- const config = { "seo-metadata": [{ "owner-type": 'home', "owner-id": null, "data": { 'page-title': "Foobar" } }] };
157
- const string = getSeoMetadata(seoConfig, config, 'home-page', { title: "The Title" }, { url: url.parse("/") })
158
- assertContains('<title>The Title</title>', string);
185
+ };
186
+ const config = { "seo-metadata": [{ "owner-type": "home", "owner-id": null, data: { "page-title": "Foobar" } }] };
187
+ const string = getSeoMetadata(seoConfig, config, "home-page", { title: "The Title" }, { url: url.parse("/") });
188
+ assertContains("<title>The Title</title>", string);
159
189
  });
160
190
 
161
191
  it("Also generates all other fields", function () {
162
192
  const seoConfig = {
163
193
  generators: [TextTags],
164
194
  enableOgTags: true,
165
- enableTwitterCards: true
195
+ enableTwitterCards: true,
166
196
  };
167
- const config = { "sketches-host": "http://foo.com", "seo-metadata": [{ "owner-type": 'home', "owner-id": null, "data": { 'title': "Foobar" } }] };
168
- const string = getSeoMetadata(seoConfig, config, 'home-page', {}, { url: url.parse("/") })
197
+ const config = {
198
+ "sketches-host": "http://foo.com",
199
+ "seo-metadata": [{ "owner-type": "home", "owner-id": null, data: { title: "Foobar" } }],
200
+ };
201
+ const string = getSeoMetadata(seoConfig, config, "home-page", {}, { url: url.parse("/") });
169
202
  assertContains('<meta name="title" content="Foobar"/>', string);
170
203
  assertContains('<meta name="twitter:title" content="Foobar"/>', string);
171
204
  assertContains('<meta property="og:title" content="Foobar"/>', string);
@@ -176,11 +209,26 @@ describe('TextTags', function () {
176
209
  const seoConfig = {
177
210
  generators: [TextTags],
178
211
  enableOgTags: true,
179
- enableTwitterCards: true
212
+ enableTwitterCards: true,
180
213
  };
181
- const config = { "sketches-host": "http://foo.com", "seo-metadata": [{ "owner-type": "home", "data": { 'title': "Foobar" } }] };
182
- const string = getSeoMetadata(seoConfig, config, 'story-page', { data: { story: { slug: 'story-slug', headline: 'story-headline' } } }, { url: url.parse("/") })
183
- const ampPageString = getSeoMetadata(seoConfig, config, 'story-page-amp', { data: { story: { slug: 'story-slug', headline: 'story-headline' } } }, { url: url.parse("/") })
214
+ const config = {
215
+ "sketches-host": "http://foo.com",
216
+ "seo-metadata": [{ "owner-type": "home", data: { title: "Foobar" } }],
217
+ };
218
+ const string = getSeoMetadata(
219
+ seoConfig,
220
+ config,
221
+ "story-page",
222
+ { data: { story: { slug: "story-slug", headline: "story-headline" } } },
223
+ { url: url.parse("/") }
224
+ );
225
+ const ampPageString = getSeoMetadata(
226
+ seoConfig,
227
+ config,
228
+ "story-page-amp",
229
+ { data: { story: { slug: "story-slug", headline: "story-headline" } } },
230
+ { url: url.parse("/") }
231
+ );
184
232
  assertContains('<meta name="title" content="story-headline"/>', string);
185
233
  assertContains('<meta name="twitter:title" content="story-headline"/>', string);
186
234
  assertContains('<meta property="og:title" content="story-headline"/>', string);
@@ -197,17 +245,23 @@ describe('TextTags', function () {
197
245
  generators: [TextTags],
198
246
  };
199
247
  const config = {
200
- 'sketches-host': "http://foo.com",
201
- "sections": [],
202
- "seo-metadata": []
248
+ "sketches-host": "http://foo.com",
249
+ sections: [],
250
+ "seo-metadata": [],
203
251
  };
204
252
  const collection = { name: "Collection Title", summary: "Collection Description" };
205
- const string = getSeoMetadata(seoConfig, config, 'section-page', { data: { collection } }, { url: url.parse("/") });
206
- assertContains('<title>Collection Title</title>', string);
253
+ const string = getSeoMetadata(
254
+ seoConfig,
255
+ config,
256
+ "section-page",
257
+ { data: { collection } },
258
+ { url: url.parse("/") }
259
+ );
260
+ assertContains("<title>Collection Title</title>", string);
207
261
  assertContains('<meta name="description" content="Collection Description"/>', string);
208
262
  assertContains('<meta name="title" content="Collection Title"/>', string);
209
- assertDoesNotContains('canonical', string);
210
- assertDoesNotContains('og:url', string);
263
+ assertDoesNotContains("canonical", string);
264
+ assertDoesNotContains("og:url", string);
211
265
  });
212
266
 
213
267
  it("picks up the home page description if the collection is missing the description", function () {
@@ -215,13 +269,19 @@ describe('TextTags', function () {
215
269
  generators: [TextTags],
216
270
  };
217
271
  const config = {
218
- 'sketches-host': "http://foo.com",
219
- "sections": [],
220
- "seo-metadata": [{ "owner-type": 'home', "owner-id": null, data: { 'description': 'Home Description' } }]
272
+ "sketches-host": "http://foo.com",
273
+ sections: [],
274
+ "seo-metadata": [{ "owner-type": "home", "owner-id": null, data: { description: "Home Description" } }],
221
275
  };
222
276
  const collection = { name: "Collection Title" };
223
- const string = getSeoMetadata(seoConfig, config, 'section-page', { data: { collection } }, { url: url.parse("/") });
224
- assertContains('<title>Collection Title</title>', string);
277
+ const string = getSeoMetadata(
278
+ seoConfig,
279
+ config,
280
+ "section-page",
281
+ { data: { collection } },
282
+ { url: url.parse("/") }
283
+ );
284
+ assertContains("<title>Collection Title</title>", string);
225
285
  assertContains('<meta name="description" content="Home Description"/>', string);
226
286
  assertContains('<meta name="title" content="Collection Title"/>', string);
227
287
  });
@@ -231,63 +291,204 @@ describe('TextTags', function () {
231
291
  generators: [TextTags],
232
292
  };
233
293
  const config = {
234
- 'sketches-host': "http://foo.com",
235
- "sections": [],
236
- "seo-metadata": []
294
+ "sketches-host": "http://foo.com",
295
+ sections: [],
296
+ "seo-metadata": [],
237
297
  };
238
298
  const collection = { name: "Collection Title" };
239
- const string = getSeoMetadata(seoConfig, config, 'section-page', { data: { collection } }, { url: url.parse("/") });
240
- assertContains('<title>Collection Title</title>', string);
241
- assertDoesNotContains('description', string);
299
+ const string = getSeoMetadata(
300
+ seoConfig,
301
+ config,
302
+ "section-page",
303
+ { data: { collection } },
304
+ { url: url.parse("/") }
305
+ );
306
+ assertContains("<title>Collection Title</title>", string);
307
+ assertDoesNotContains("description", string);
242
308
  });
243
- })
244
-
245
-
246
-
247
-
248
-
309
+ });
249
310
  });
250
311
 
251
-
252
-
253
-
254
-
255
-
256
-
257
-
258
-
259
-
260
-
261
-
262
-
263
-
264
-
265
-
266
-
267
-
268
-
269
-
270
-
271
- describe('Story Page', function () {
312
+ describe("Story Page", function () {
272
313
  it("Generates SEO tags for a story page", function () {
273
314
  const seoConfig = {
274
315
  generators: [TextTags],
275
- }
276
- const story = { headline: "Foobar", summary: "Some Foobar", tags: [{ name: "Footag" }], slug: "politics/awesome", authors: [{ 'name': "foo" }] }
277
- const string = getSeoMetadata(seoConfig, { "sketches-host": "http://foo.com" }, 'story-page', { data: { story: story } }, { url: url.parse("/my-page") })
278
- assertContains('<title>Foobar</title>', string);
316
+ };
317
+ const story = {
318
+ headline: "Foobar",
319
+ summary: "Some Foobar",
320
+ tags: [{ name: "Footag" }],
321
+ slug: "politics/awesome",
322
+ authors: [{ name: "foo" }],
323
+ };
324
+ const string = getSeoMetadata(
325
+ seoConfig,
326
+ { "sketches-host": "http://foo.com" },
327
+ "story-page",
328
+ { data: { story: story } },
329
+ { url: url.parse("/my-page") }
330
+ );
331
+ assertContains("<title>Foobar</title>", string);
279
332
  assertContains('<meta name="title" content="Foobar"/>', string);
280
333
  assertContains('<meta name="description" content="Some Foobar"/>', string);
281
334
  assertContains('<meta name="keywords" content="Footag"/>', string);
282
335
  assertContains('<link rel="canonical" href="http://foo.com/politics/awesome"/>', string);
283
336
  });
284
337
 
338
+ it("Generates SEO tag like description for a story page with extra fallback", function () {
339
+ const seoConfig = {
340
+ generators: [TextTags],
341
+ enableMetaDescriptionFallback: true,
342
+ };
343
+ const story = {
344
+ headline: "Foobar",
345
+ subheadline: "Some Subheadline",
346
+ summary: "Summary Foobar",
347
+ seo: { "meta-description": "Meta Description" },
348
+ cards: [
349
+ {
350
+ "story-elements": [
351
+ {
352
+ subtype: null,
353
+ type: "text",
354
+ text: "<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam malesuada pellentesque turpis, congue auctor nulla lacinia sed. Quisque laoreet suscipit massa in tincidunt. Maecenas malesuada justo ac porta laoreet. Integer id ex facilisis, bibendum sem eget, porta sem. Proin ac mattis diam, gravida pellentesque lectus. Donec vulputate vehicula quam at rhoncus. Proin eget vulputate leo, non vulputate turpis. In eget orci placerat, scelerisque dui vitae, vulputate neque. Nullam non pretium turpis, at commodo justo.</p>",
355
+ },
356
+ ],
357
+ },
358
+ ],
359
+ };
360
+
361
+ const stringWithMetaDescription = getSeoMetadata(
362
+ seoConfig,
363
+ { "sketches-host": "http://foo.com" },
364
+ "story-page",
365
+ { data: { story: story } },
366
+ { url: url.parse("/my-page") }
367
+ );
368
+ assertContains('<meta name="description" content="Meta Description"/>', stringWithMetaDescription);
369
+
370
+ const stringWithSummaryFallback = getSeoMetadata(
371
+ seoConfig,
372
+ { "sketches-host": "http://foo.com" },
373
+ "story-page",
374
+ { data: { story: { ...story, seo: null } } },
375
+ { url: url.parse("/my-page") }
376
+ );
377
+ assertContains('<meta name="description" content="Summary Foobar"/>', stringWithSummaryFallback);
378
+
379
+ const stringWithSubheadlineFallback = getSeoMetadata(
380
+ seoConfig,
381
+ { "sketches-host": "http://foo.com" },
382
+ "story-page",
383
+ { data: { story: { ...story, seo: null, summary: null } } },
384
+ { url: url.parse("/my-page") }
385
+ );
386
+ assertContains('<meta name="description" content="Some Subheadline"/>', stringWithSubheadlineFallback);
387
+
388
+ const stringWithStoryContentFallback = getSeoMetadata(
389
+ seoConfig,
390
+ { "sketches-host": "http://foo.com" },
391
+ "story-page",
392
+ { data: { story: { ...story, seo: null, summary: null, subheadline: null } } },
393
+ { url: url.parse("/my-page") }
394
+ );
395
+ assertContains(
396
+ '<meta name="description" content="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam malesuada pellentesque turpis, congue auctor nulla lacinia sed. Quisque laoreet suscipit massa in"/>',
397
+ stringWithStoryContentFallback
398
+ );
399
+ });
400
+
401
+ it("Generates SEO tags like og:description and twitter:description for a story page with extra fallback", function () {
402
+ const seoConfig = {
403
+ generators: [TextTags],
404
+ enableMetaDescriptionFallback: true,
405
+ enableOgTags: true,
406
+ enableTwitterCards: true,
407
+ };
408
+ const story = {
409
+ headline: "Foobar",
410
+ subheadline: "Some Subheadline",
411
+ summary: "Summary Foobar",
412
+ seo: { "meta-description": "Meta Description" },
413
+ cards: [
414
+ {
415
+ "story-elements": [
416
+ {
417
+ subtype: null,
418
+ type: "text",
419
+ text: "<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam malesuada pellentesque turpis, congue auctor nulla lacinia sed. Quisque laoreet suscipit massa in tincidunt. Maecenas malesuada justo ac porta laoreet. Integer id ex facilisis, bibendum sem eget, porta sem. Proin ac mattis diam, gravida pellentesque lectus. Donec vulputate vehicula quam at rhoncus. Proin eget vulputate leo, non vulputate turpis. In eget orci placerat, scelerisque dui vitae, vulputate neque. Nullam non pretium turpis, at commodo justo.</p>",
420
+ },
421
+ ],
422
+ },
423
+ ],
424
+ };
425
+
426
+ const stringWithSummary = getSeoMetadata(
427
+ seoConfig,
428
+ { "sketches-host": "http://foo.com" },
429
+ "story-page",
430
+ { data: { story: story } },
431
+ { url: url.parse("/my-page") }
432
+ );
433
+ assertContains('<meta property="og:description" content="Summary Foobar"/>', stringWithSummary);
434
+ assertContains('<meta name="twitter:description" content="Summary Foobar"/>', stringWithSummary);
435
+
436
+ const stringWithStoryContentFallback = getSeoMetadata(
437
+ seoConfig,
438
+ { "sketches-host": "http://foo.com" },
439
+ "story-page",
440
+ { data: { story: { ...story, summary: null } } },
441
+ { url: url.parse("/my-page") }
442
+ );
443
+ assertContains(
444
+ '<meta property="og:description" content="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam malesuada pellentesque turpis, congue auctor nulla lacinia sed. Quisque laoreet suscipit massa in"/>',
445
+ stringWithStoryContentFallback
446
+ );
447
+ assertContains(
448
+ '<meta name="twitter:description" content="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam malesuada pellentesque turpis, congue auctor nulla lacinia sed. Quisque laoreet suscipit massa in"/>',
449
+ stringWithStoryContentFallback
450
+ );
451
+
452
+ const stringWithSubheadlineFallback = getSeoMetadata(
453
+ seoConfig,
454
+ { "sketches-host": "http://foo.com" },
455
+ "story-page",
456
+ { data: { story: { ...story, summary: null, cards: [] } } },
457
+ { url: url.parse("/my-page") }
458
+ );
459
+ assertContains('<meta property="og:description" content="Some Subheadline', stringWithSubheadlineFallback);
460
+ assertContains('<meta name="twitter:description" content="Some Subheadline', stringWithSubheadlineFallback);
461
+
462
+ const stringWithMetaDescriptionFallback = getSeoMetadata(
463
+ seoConfig,
464
+ { "sketches-host": "http://foo.com" },
465
+ "story-page",
466
+ { data: { story: { ...story, summary: null, cards: [], subheadline: null } } },
467
+ { url: url.parse("/my-page") }
468
+ );
469
+ assertContains('<meta property="og:description" content="Meta Description', stringWithMetaDescriptionFallback);
470
+ assertContains('<meta name="twitter:description" content="Meta Description', stringWithMetaDescriptionFallback);
471
+ });
472
+
285
473
  it("takes the story url over the story slug if present", function () {
286
474
  const seoConfig = {
287
475
  generators: [TextTags],
288
- }
289
- const story = { headline: "Foobar", summary: "Some Foobar", tags: [{ name: "Footag" }], slug: "politics/awesome", authors: [{ 'name': "foo" }], url: "http://domain.com/politics/awesome" }
290
- const string = getSeoMetadata(seoConfig, { "sketches-host": "http://foo.com" }, 'story-page', { data: { story: story } }, { url: url.parse("/my-page") })
476
+ };
477
+ const story = {
478
+ headline: "Foobar",
479
+ summary: "Some Foobar",
480
+ tags: [{ name: "Footag" }],
481
+ slug: "politics/awesome",
482
+ authors: [{ name: "foo" }],
483
+ url: "http://domain.com/politics/awesome",
484
+ };
485
+ const string = getSeoMetadata(
486
+ seoConfig,
487
+ { "sketches-host": "http://foo.com" },
488
+ "story-page",
489
+ { data: { story: story } },
490
+ { url: url.parse("/my-page") }
491
+ );
291
492
  assertContains('<link rel="canonical" href="http://domain.com/politics/awesome"/>', string);
292
493
  });
293
494
 
@@ -295,21 +496,31 @@ describe('TextTags', function () {
295
496
  const seoConfig = {
296
497
  generators: [TextTags],
297
498
  };
298
- const story = { headline: "Foobar", summary: "Some Foobar", tags: [{ name: "Footag" }], slug: "politics/awesome", authors: [{ 'name': "foo" }] }
299
- const string = getSeoMetadata(seoConfig, { "sketches-host": "http://foo.com" }, 'visual-story', { story: story }, { url: url.parse("/my-page") })
300
- assertContains('<title>Foobar</title>', string);
499
+ const story = {
500
+ headline: "Foobar",
501
+ summary: "Some Foobar",
502
+ tags: [{ name: "Footag" }],
503
+ slug: "politics/awesome",
504
+ authors: [{ name: "foo" }],
505
+ };
506
+ const string = getSeoMetadata(
507
+ seoConfig,
508
+ { "sketches-host": "http://foo.com" },
509
+ "visual-story",
510
+ { story: story },
511
+ { url: url.parse("/my-page") }
512
+ );
513
+ assertContains("<title>Foobar</title>", string);
301
514
  assertContains('<meta name="title" content="Foobar"/>', string);
302
515
  assertContains('<meta name="description" content="Some Foobar"/>', string);
303
516
  assertContains('<meta name="keywords" content="Footag"/>', string);
304
517
  assertContains('<link rel="canonical" href="http://foo.com/politics/awesome"/>', string);
305
518
  });
306
519
 
307
-
308
-
309
520
  it("Generates SEO tags for a card in story page", function () {
310
521
  const seoConfig = {
311
522
  generators: [TextTags],
312
- enableOgTags: true
523
+ enableOgTags: true,
313
524
  };
314
525
 
315
526
  const story = {
@@ -318,59 +529,67 @@ describe('TextTags', function () {
318
529
  tags: [{ name: "Footag" }],
319
530
  slug: "politics/awesome",
320
531
  "hero-image-s3-key": "my/image.png",
321
- "cards": [
532
+ cards: [
322
533
  {
323
- "id": "sample-card-id",
324
- "metadata": {
534
+ id: "sample-card-id",
535
+ metadata: {
325
536
  "social-share": {
326
- "title": "share-card-title",
327
- "message": "share-card-description",
328
- "image": {
329
- "key": "my/card/image.jpg",
330
- "metadata": {
331
- "width": 1300,
332
- "height": 1065,
333
- "mime-type": "image/jpeg"
334
- }
335
- }
336
- }
337
- }
338
- }
537
+ title: "share-card-title",
538
+ message: "share-card-description",
539
+ image: {
540
+ key: "my/card/image.jpg",
541
+ metadata: {
542
+ width: 1300,
543
+ height: 1065,
544
+ "mime-type": "image/jpeg",
545
+ },
546
+ },
547
+ },
548
+ },
549
+ },
339
550
  ],
340
- "authors": [
551
+ authors: [
341
552
  {
342
553
  id: 712440,
343
- name: 'Foo',
344
- slug: 'foo',
345
- 'avatar-url': null,
346
- 'avatar-s3-key': null,
347
- 'twitter-handle': null,
554
+ name: "Foo",
555
+ slug: "foo",
556
+ "avatar-url": null,
557
+ "avatar-s3-key": null,
558
+ "twitter-handle": null,
348
559
  bio: null,
349
- 'contributor-role': null
350
- }
351
- ]
560
+ "contributor-role": null,
561
+ },
562
+ ],
352
563
  };
353
564
 
354
565
  const opts = {
355
566
  url: {
356
567
  query: {
357
- cardId: 'sample-card-id'
358
- }
359
- }
568
+ cardId: "sample-card-id",
569
+ },
570
+ },
360
571
  };
361
572
 
362
- const string = getSeoMetadata(seoConfig, { "sketches-host": "http://foo.com" }, 'story-page', { data: { story: story } }, opts);
363
- assertContains('<title>Foobar</title>', string);
573
+ const string = getSeoMetadata(
574
+ seoConfig,
575
+ { "sketches-host": "http://foo.com" },
576
+ "story-page",
577
+ { data: { story: story } },
578
+ opts
579
+ );
580
+ assertContains("<title>Foobar</title>", string);
364
581
  assertContains('<meta name="title" content="share-card-title"/>', string);
365
582
  assertContains('<meta name="description" content="share-card-description"/>', string);
366
583
  assertContains('<meta name="keywords" content="Footag"/>', string);
367
584
  assertContains('<link rel="canonical" href="http://foo.com/politics/awesome"/>', string);
368
- assertContains('<meta property="og:url" content="http://foo.com/politics/awesome?cardId=sample-card-id"/>', string);
585
+ assertContains(
586
+ '<meta property="og:url" content="http://foo.com/politics/awesome?cardId=sample-card-id"/>',
587
+ string
588
+ );
369
589
  assertContains('<meta property="og:title" content="share-card-title"/>', string);
370
590
  assertContains('<meta property="og:description" content="share-card-description"/>', string);
371
591
  });
372
592
 
373
-
374
593
  it("gets story data as fallback if the card metadata is falsy", function () {
375
594
  const seoConfig = {
376
595
  generators: [TextTags],
@@ -382,56 +601,61 @@ describe('TextTags', function () {
382
601
  tags: [{ name: "Footag" }],
383
602
  slug: "politics/awesome",
384
603
  "hero-image-s3-key": "my/image.png",
385
- "cards": [
604
+ cards: [
386
605
  {
387
- "id": "sample-card-id",
388
- "metadata": {
606
+ id: "sample-card-id",
607
+ metadata: {
389
608
  "social-share": {
390
- "title": undefined,
391
- "message": "",
392
- "image": {
393
- "key": "my/card/image.jpg",
394
- "metadata": {
395
- "width": 1300,
396
- "height": 1065,
397
- "mime-type": "image/jpeg"
398
- }
399
- }
400
- }
401
- }
402
- }
609
+ title: undefined,
610
+ message: "",
611
+ image: {
612
+ key: "my/card/image.jpg",
613
+ metadata: {
614
+ width: 1300,
615
+ height: 1065,
616
+ "mime-type": "image/jpeg",
617
+ },
618
+ },
619
+ },
620
+ },
621
+ },
403
622
  ],
404
- "authors": [
623
+ authors: [
405
624
  {
406
625
  id: 712440,
407
- name: 'Foo',
408
- slug: 'foo',
409
- 'avatar-url': null,
410
- 'avatar-s3-key': null,
411
- 'twitter-handle': null,
626
+ name: "Foo",
627
+ slug: "foo",
628
+ "avatar-url": null,
629
+ "avatar-s3-key": null,
630
+ "twitter-handle": null,
412
631
  bio: null,
413
- 'contributor-role': null
414
- }
415
- ]
632
+ "contributor-role": null,
633
+ },
634
+ ],
416
635
  };
417
636
 
418
637
  const opts = {
419
638
  url: {
420
639
  query: {
421
- cardId: 'sample-card-id'
422
- }
423
- }
640
+ cardId: "sample-card-id",
641
+ },
642
+ },
424
643
  };
425
644
 
426
- const string = getSeoMetadata(seoConfig, { "sketches-host": "http://foo.com" }, 'story-page', { data: { story: story } }, opts);
427
- assertContains('<title>Foobar</title>', string);
645
+ const string = getSeoMetadata(
646
+ seoConfig,
647
+ { "sketches-host": "http://foo.com" },
648
+ "story-page",
649
+ { data: { story: story } },
650
+ opts
651
+ );
652
+ assertContains("<title>Foobar</title>", string);
428
653
  assertContains('<meta name="title" content="Foobar"/>', string);
429
654
  assertContains('<meta name="description" content="Some Foobar"/>', string);
430
655
  assertContains('<meta name="keywords" content="Footag"/>', string);
431
656
  assertContains('<link rel="canonical" href="http://foo.com/politics/awesome"/>', string);
432
657
  });
433
658
 
434
-
435
659
  it("gets story data as fallback if card id is improper", function () {
436
660
  const seoConfig = {
437
661
  generators: [TextTags],
@@ -442,72 +666,93 @@ describe('TextTags', function () {
442
666
  summary: "Some Foobar",
443
667
  tags: [{ name: "Footag" }],
444
668
  slug: "politics/awesome",
445
- authors: [{
446
- id: 712440,
447
- name: 'FooBar',
448
- slug: 'foobar',
449
- 'avatar-url': null,
450
- 'avatar-s3-key': null,
451
- 'twitter-handle': null,
452
- bio: null,
453
- 'contributor-role': null
454
- }],
669
+ authors: [
670
+ {
671
+ id: 712440,
672
+ name: "FooBar",
673
+ slug: "foobar",
674
+ "avatar-url": null,
675
+ "avatar-s3-key": null,
676
+ "twitter-handle": null,
677
+ bio: null,
678
+ "contributor-role": null,
679
+ },
680
+ ],
455
681
  "hero-image-s3-key": "my/image.png",
456
- "cards": [
682
+ cards: [
457
683
  {
458
- "id": "sample-card-id",
459
- "metadata": {
684
+ id: "sample-card-id",
685
+ metadata: {
460
686
  "social-share": {
461
- "title": "share-card-title",
462
- "message": "share-card-description",
463
- "image": {
464
- "key": "my/card/image.jpg",
465
- "metadata": {
466
- "width": 1300,
467
- "height": 1065,
468
- "mime-type": "image/jpeg"
469
- }
470
- }
471
- }
472
- }
473
- }
474
- ]
687
+ title: "share-card-title",
688
+ message: "share-card-description",
689
+ image: {
690
+ key: "my/card/image.jpg",
691
+ metadata: {
692
+ width: 1300,
693
+ height: 1065,
694
+ "mime-type": "image/jpeg",
695
+ },
696
+ },
697
+ },
698
+ },
699
+ },
700
+ ],
475
701
  };
476
702
 
477
703
  const opts = {
478
704
  url: {
479
705
  query: {
480
- cardId: 'sample-card-id-bad'
481
- }
482
- }
706
+ cardId: "sample-card-id-bad",
707
+ },
708
+ },
483
709
  };
484
710
 
485
- const string = getSeoMetadata(seoConfig, { "sketches-host": "http://foo.com" }, 'story-page', { data: { story: story } }, opts);
486
- assertContains('<title>Foobar</title>', string);
711
+ const string = getSeoMetadata(
712
+ seoConfig,
713
+ { "sketches-host": "http://foo.com" },
714
+ "story-page",
715
+ { data: { story: story } },
716
+ opts
717
+ );
718
+ assertContains("<title>Foobar</title>", string);
487
719
  assertContains('<meta name="title" content="Foobar"/>', string);
488
720
  assertContains('<meta name="description" content="Some Foobar"/>', string);
489
721
  assertContains('<meta name="keywords" content="Footag"/>', string);
490
722
  assertContains('<link rel="canonical" href="http://foo.com/politics/awesome"/>', string);
491
723
  });
492
724
 
493
-
494
-
495
-
496
725
  it("Overrides the canonical url", function () {
497
726
  const seoConfig = {
498
727
  generators: [TextTags],
499
- }
500
- const story = { 'canonical-url': "http://foobar.com/mystory", authors: [{ 'name': "foo" }] }
501
- const string = getSeoMetadata(seoConfig, { "sketches-host": "http://foo.com" }, 'story-page', { data: { story: story } }, { url: url.parse("/my-page") })
728
+ };
729
+ const story = { "canonical-url": "http://foobar.com/mystory", authors: [{ name: "foo" }] };
730
+ const string = getSeoMetadata(
731
+ seoConfig,
732
+ { "sketches-host": "http://foo.com" },
733
+ "story-page",
734
+ { data: { story: story } },
735
+ { url: url.parse("/my-page") }
736
+ );
502
737
  assertContains('<link rel="canonical" href="http://foobar.com/mystory"/>', string);
503
738
  });
504
739
 
505
740
  it("Overrides the canonical meta title and description", function () {
506
741
  const seoConfig = {
507
742
  generators: [TextTags],
508
- }
509
- const story = { seo: { "meta-title": "Foobar", "meta-description": "Some Foobar", "meta-keywords": ["Footag"] }, tags: [], authors: [{ 'name': "foo" }] }
510
- const string = getSeoMetadata(seoConfig, { "sketches-host": "http://foo.com" }, 'story-page', { data: { story: story } }, { url: url.parse("/my-page") })
743
+ };
744
+ const story = {
745
+ seo: { "meta-title": "Foobar", "meta-description": "Some Foobar", "meta-keywords": ["Footag"] },
746
+ tags: [],
747
+ authors: [{ name: "foo" }],
748
+ };
749
+ const string = getSeoMetadata(
750
+ seoConfig,
751
+ { "sketches-host": "http://foo.com" },
752
+ "story-page",
753
+ { data: { story: story } },
754
+ { url: url.parse("/my-page") }
755
+ );
511
756
  assertContains('<meta name="title" content="Foobar"/>', string);
512
757
  assertContains('<meta name="description" content="Some Foobar"/>', string);
513
758
  assertContains('<meta name="keywords" content="Footag"/>', string);
@@ -516,23 +761,46 @@ describe('TextTags', function () {
516
761
  it("Can generate news tags", function () {
517
762
  const seoConfig = {
518
763
  generators: [TextTags],
519
- enableNews: true
520
- }
521
- const story = { slug: "politics/awesome", seo: { "meta-google-news-standout": true }, tags: [{ name: "Footag" }], authors: [{ 'name': "foo" }] }
522
- const string = getSeoMetadata(seoConfig, { "sketches-host": "http://foo.com" }, 'story-page', { data: { story: story } }, { url: url.parse("/my-page") })
764
+ enableNews: true,
765
+ };
766
+ const story = {
767
+ slug: "politics/awesome",
768
+ seo: { "meta-google-news-standout": true },
769
+ tags: [{ name: "Footag" }],
770
+ authors: [{ name: "foo" }],
771
+ };
772
+ const string = getSeoMetadata(
773
+ seoConfig,
774
+ { "sketches-host": "http://foo.com" },
775
+ "story-page",
776
+ { data: { story: story } },
777
+ { url: url.parse("/my-page") }
778
+ );
523
779
  assertContains('<meta name="news_keywords" content="Footag"/>', string);
524
780
  assertContains('<link rel="standout" href="http://foo.com/politics/awesome"/>', string);
525
781
  });
526
782
  });
527
783
 
528
- describe('Amp story Page', function () {
784
+ describe("Amp story Page", function () {
529
785
  it("Generates SEO tags for a amp story page", function () {
530
786
  const seoConfig = {
531
787
  generators: [TextTags],
532
- }
533
- const story = { headline: "Foobar", summary: "Some Foobar", tags: [{ name: "Footag" }], slug: "politics/awesome", authors: [{ 'name': "foo" }] }
534
- const string = getSeoMetadata(seoConfig, { "sketches-host": "http://foo.com" }, 'story-page-amp', { data: { story: story } }, { url: url.parse("/my-page") })
535
- assertContains('<title>Foobar</title>', string);
788
+ };
789
+ const story = {
790
+ headline: "Foobar",
791
+ summary: "Some Foobar",
792
+ tags: [{ name: "Footag" }],
793
+ slug: "politics/awesome",
794
+ authors: [{ name: "foo" }],
795
+ };
796
+ const string = getSeoMetadata(
797
+ seoConfig,
798
+ { "sketches-host": "http://foo.com" },
799
+ "story-page-amp",
800
+ { data: { story: story } },
801
+ { url: url.parse("/my-page") }
802
+ );
803
+ assertContains("<title>Foobar</title>", string);
536
804
  assertContains('<meta name="title" content="Foobar"/>', string);
537
805
  assertContains('<meta name="description" content="Some Foobar"/>', string);
538
806
  assertContains('<meta name="keywords" content="Footag"/>', string);
@@ -542,16 +810,29 @@ describe('TextTags', function () {
542
810
  it("takes the story url over the story slug if present", function () {
543
811
  const seoConfig = {
544
812
  generators: [TextTags],
545
- }
546
- const story = { headline: "Foobar", summary: "Some Foobar", tags: [{ name: "Footag" }], slug: "politics/awesome", authors: [{ 'name': "foo" }], url: "http://domain.com/politics/awesome" }
547
- const string = getSeoMetadata(seoConfig, { "sketches-host": "http://foo.com" }, 'story-page-amp', { data: { story: story } }, { url: url.parse("/my-page") })
813
+ };
814
+ const story = {
815
+ headline: "Foobar",
816
+ summary: "Some Foobar",
817
+ tags: [{ name: "Footag" }],
818
+ slug: "politics/awesome",
819
+ authors: [{ name: "foo" }],
820
+ url: "http://domain.com/politics/awesome",
821
+ };
822
+ const string = getSeoMetadata(
823
+ seoConfig,
824
+ { "sketches-host": "http://foo.com" },
825
+ "story-page-amp",
826
+ { data: { story: story } },
827
+ { url: url.parse("/my-page") }
828
+ );
548
829
  assertContains('<link rel="canonical" href="http://domain.com/politics/awesome"/>', string);
549
830
  });
550
831
 
551
832
  it("Generates SEO tags for a card in amp story page", function () {
552
833
  const seoConfig = {
553
834
  generators: [TextTags],
554
- enableOgTags: true
835
+ enableOgTags: true,
555
836
  };
556
837
 
557
838
  const story = {
@@ -560,59 +841,67 @@ describe('TextTags', function () {
560
841
  tags: [{ name: "Footag" }],
561
842
  slug: "politics/awesome",
562
843
  "hero-image-s3-key": "my/image.png",
563
- "cards": [
844
+ cards: [
564
845
  {
565
- "id": "sample-card-id",
566
- "metadata": {
846
+ id: "sample-card-id",
847
+ metadata: {
567
848
  "social-share": {
568
- "title": "share-card-title",
569
- "message": "share-card-description",
570
- "image": {
571
- "key": "my/card/image.jpg",
572
- "metadata": {
573
- "width": 1300,
574
- "height": 1065,
575
- "mime-type": "image/jpeg"
576
- }
577
- }
578
- }
579
- }
580
- }
849
+ title: "share-card-title",
850
+ message: "share-card-description",
851
+ image: {
852
+ key: "my/card/image.jpg",
853
+ metadata: {
854
+ width: 1300,
855
+ height: 1065,
856
+ "mime-type": "image/jpeg",
857
+ },
858
+ },
859
+ },
860
+ },
861
+ },
581
862
  ],
582
- "authors": [
863
+ authors: [
583
864
  {
584
865
  id: 712440,
585
- name: 'Foo',
586
- slug: 'foo',
587
- 'avatar-url': null,
588
- 'avatar-s3-key': null,
589
- 'twitter-handle': null,
866
+ name: "Foo",
867
+ slug: "foo",
868
+ "avatar-url": null,
869
+ "avatar-s3-key": null,
870
+ "twitter-handle": null,
590
871
  bio: null,
591
- 'contributor-role': null
592
- }
593
- ]
872
+ "contributor-role": null,
873
+ },
874
+ ],
594
875
  };
595
876
 
596
877
  const opts = {
597
878
  url: {
598
879
  query: {
599
- cardId: 'sample-card-id'
600
- }
601
- }
880
+ cardId: "sample-card-id",
881
+ },
882
+ },
602
883
  };
603
884
 
604
- const string = getSeoMetadata(seoConfig, { "sketches-host": "http://foo.com" }, 'story-page-amp', { data: { story: story } }, opts);
605
- assertContains('<title>Foobar</title>', string);
885
+ const string = getSeoMetadata(
886
+ seoConfig,
887
+ { "sketches-host": "http://foo.com" },
888
+ "story-page-amp",
889
+ { data: { story: story } },
890
+ opts
891
+ );
892
+ assertContains("<title>Foobar</title>", string);
606
893
  assertContains('<meta name="title" content="share-card-title"/>', string);
607
894
  assertContains('<meta name="description" content="share-card-description"/>', string);
608
895
  assertContains('<meta name="keywords" content="Footag"/>', string);
609
896
  assertContains('<link rel="canonical" href="http://foo.com/politics/awesome"/>', string);
610
- assertContains('<meta property="og:url" content="http://foo.com/politics/awesome?cardId=sample-card-id"/>', string);
897
+ assertContains(
898
+ '<meta property="og:url" content="http://foo.com/politics/awesome?cardId=sample-card-id"/>',
899
+ string
900
+ );
611
901
  assertContains('<meta property="og:title" content="share-card-title"/>', string);
612
902
  assertContains('<meta property="og:description" content="share-card-description"/>', string);
613
903
  });
614
904
 
615
-
616
905
  it("gets story data as fallback if the card metadata is falsy", function () {
617
906
  const seoConfig = {
618
907
  generators: [TextTags],
@@ -624,56 +913,61 @@ describe('TextTags', function () {
624
913
  tags: [{ name: "Footag" }],
625
914
  slug: "politics/awesome",
626
915
  "hero-image-s3-key": "my/image.png",
627
- "cards": [
916
+ cards: [
628
917
  {
629
- "id": "sample-card-id",
630
- "metadata": {
918
+ id: "sample-card-id",
919
+ metadata: {
631
920
  "social-share": {
632
- "title": undefined,
633
- "message": "",
634
- "image": {
635
- "key": "my/card/image.jpg",
636
- "metadata": {
637
- "width": 1300,
638
- "height": 1065,
639
- "mime-type": "image/jpeg"
640
- }
641
- }
642
- }
643
- }
644
- }
921
+ title: undefined,
922
+ message: "",
923
+ image: {
924
+ key: "my/card/image.jpg",
925
+ metadata: {
926
+ width: 1300,
927
+ height: 1065,
928
+ "mime-type": "image/jpeg",
929
+ },
930
+ },
931
+ },
932
+ },
933
+ },
645
934
  ],
646
- "authors": [
935
+ authors: [
647
936
  {
648
937
  id: 712440,
649
- name: 'Foo',
650
- slug: 'foo',
651
- 'avatar-url': null,
652
- 'avatar-s3-key': null,
653
- 'twitter-handle': null,
938
+ name: "Foo",
939
+ slug: "foo",
940
+ "avatar-url": null,
941
+ "avatar-s3-key": null,
942
+ "twitter-handle": null,
654
943
  bio: null,
655
- 'contributor-role': null
656
- }
657
- ]
944
+ "contributor-role": null,
945
+ },
946
+ ],
658
947
  };
659
948
 
660
949
  const opts = {
661
950
  url: {
662
951
  query: {
663
- cardId: 'sample-card-id'
664
- }
665
- }
952
+ cardId: "sample-card-id",
953
+ },
954
+ },
666
955
  };
667
956
 
668
- const string = getSeoMetadata(seoConfig, { "sketches-host": "http://foo.com" }, 'story-page-amp', { data: { story: story } }, opts);
669
- assertContains('<title>Foobar</title>', string);
957
+ const string = getSeoMetadata(
958
+ seoConfig,
959
+ { "sketches-host": "http://foo.com" },
960
+ "story-page-amp",
961
+ { data: { story: story } },
962
+ opts
963
+ );
964
+ assertContains("<title>Foobar</title>", string);
670
965
  assertContains('<meta name="title" content="Foobar"/>', string);
671
966
  assertContains('<meta name="description" content="Some Foobar"/>', string);
672
967
  assertContains('<meta name="keywords" content="Footag"/>', string);
673
968
  assertContains('<link rel="canonical" href="http://foo.com/politics/awesome"/>', string);
674
969
  });
675
970
 
676
-
677
971
  it("gets story data as fallback if card id is improper", function () {
678
972
  const seoConfig = {
679
973
  generators: [TextTags],
@@ -684,72 +978,93 @@ describe('TextTags', function () {
684
978
  summary: "Some Foobar",
685
979
  tags: [{ name: "Footag" }],
686
980
  slug: "politics/awesome",
687
- authors: [{
688
- id: 712440,
689
- name: 'FooBar',
690
- slug: 'foobar',
691
- 'avatar-url': null,
692
- 'avatar-s3-key': null,
693
- 'twitter-handle': null,
694
- bio: null,
695
- 'contributor-role': null
696
- }],
981
+ authors: [
982
+ {
983
+ id: 712440,
984
+ name: "FooBar",
985
+ slug: "foobar",
986
+ "avatar-url": null,
987
+ "avatar-s3-key": null,
988
+ "twitter-handle": null,
989
+ bio: null,
990
+ "contributor-role": null,
991
+ },
992
+ ],
697
993
  "hero-image-s3-key": "my/image.png",
698
- "cards": [
994
+ cards: [
699
995
  {
700
- "id": "sample-card-id",
701
- "metadata": {
996
+ id: "sample-card-id",
997
+ metadata: {
702
998
  "social-share": {
703
- "title": "share-card-title",
704
- "message": "share-card-description",
705
- "image": {
706
- "key": "my/card/image.jpg",
707
- "metadata": {
708
- "width": 1300,
709
- "height": 1065,
710
- "mime-type": "image/jpeg"
711
- }
712
- }
713
- }
714
- }
715
- }
716
- ]
999
+ title: "share-card-title",
1000
+ message: "share-card-description",
1001
+ image: {
1002
+ key: "my/card/image.jpg",
1003
+ metadata: {
1004
+ width: 1300,
1005
+ height: 1065,
1006
+ "mime-type": "image/jpeg",
1007
+ },
1008
+ },
1009
+ },
1010
+ },
1011
+ },
1012
+ ],
717
1013
  };
718
1014
 
719
1015
  const opts = {
720
1016
  url: {
721
1017
  query: {
722
- cardId: 'sample-card-id-bad'
723
- }
724
- }
1018
+ cardId: "sample-card-id-bad",
1019
+ },
1020
+ },
725
1021
  };
726
1022
 
727
- const string = getSeoMetadata(seoConfig, { "sketches-host": "http://foo.com" }, 'story-page-amp', { data: { story: story } }, opts);
728
- assertContains('<title>Foobar</title>', string);
1023
+ const string = getSeoMetadata(
1024
+ seoConfig,
1025
+ { "sketches-host": "http://foo.com" },
1026
+ "story-page-amp",
1027
+ { data: { story: story } },
1028
+ opts
1029
+ );
1030
+ assertContains("<title>Foobar</title>", string);
729
1031
  assertContains('<meta name="title" content="Foobar"/>', string);
730
1032
  assertContains('<meta name="description" content="Some Foobar"/>', string);
731
1033
  assertContains('<meta name="keywords" content="Footag"/>', string);
732
1034
  assertContains('<link rel="canonical" href="http://foo.com/politics/awesome"/>', string);
733
1035
  });
734
1036
 
735
-
736
-
737
-
738
1037
  it("Overrides the canonical url", function () {
739
1038
  const seoConfig = {
740
1039
  generators: [TextTags],
741
- }
742
- const story = { 'canonical-url': "http://foobar.com/mystory", authors: [{ 'name': "foo" }] }
743
- const string = getSeoMetadata(seoConfig, { "sketches-host": "http://foo.com" }, 'story-page-amp', { data: { story: story } }, { url: url.parse("/my-page") })
1040
+ };
1041
+ const story = { "canonical-url": "http://foobar.com/mystory", authors: [{ name: "foo" }] };
1042
+ const string = getSeoMetadata(
1043
+ seoConfig,
1044
+ { "sketches-host": "http://foo.com" },
1045
+ "story-page-amp",
1046
+ { data: { story: story } },
1047
+ { url: url.parse("/my-page") }
1048
+ );
744
1049
  assertContains('<link rel="canonical" href="http://foobar.com/mystory"/>', string);
745
1050
  });
746
1051
 
747
1052
  it("Overrides the canonical meta title and description", function () {
748
1053
  const seoConfig = {
749
1054
  generators: [TextTags],
750
- }
751
- const story = { seo: { "meta-title": "Foobar", "meta-description": "Some Foobar", "meta-keywords": ["Footag"] }, tags: [], authors: [{ 'name': "foo" }] }
752
- const string = getSeoMetadata(seoConfig, { "sketches-host": "http://foo.com" }, 'story-page-amp', { data: { story: story } }, { url: url.parse("/my-page") })
1055
+ };
1056
+ const story = {
1057
+ seo: { "meta-title": "Foobar", "meta-description": "Some Foobar", "meta-keywords": ["Footag"] },
1058
+ tags: [],
1059
+ authors: [{ name: "foo" }],
1060
+ };
1061
+ const string = getSeoMetadata(
1062
+ seoConfig,
1063
+ { "sketches-host": "http://foo.com" },
1064
+ "story-page-amp",
1065
+ { data: { story: story } },
1066
+ { url: url.parse("/my-page") }
1067
+ );
753
1068
  assertContains('<meta name="title" content="Foobar"/>', string);
754
1069
  assertContains('<meta name="description" content="Some Foobar"/>', string);
755
1070
  assertContains('<meta name="keywords" content="Footag"/>', string);
@@ -758,10 +1073,21 @@ describe('TextTags', function () {
758
1073
  it("Can generate news tags", function () {
759
1074
  const seoConfig = {
760
1075
  generators: [TextTags],
761
- enableNews: true
762
- }
763
- const story = { slug: "politics/awesome", seo: { "meta-google-news-standout": true }, tags: [{ name: "Footag" }], authors: [{ 'name': "foo" }] }
764
- const string = getSeoMetadata(seoConfig, { "sketches-host": "http://foo.com" }, 'story-page-amp', { data: { story: story } }, { url: url.parse("/my-page") })
1076
+ enableNews: true,
1077
+ };
1078
+ const story = {
1079
+ slug: "politics/awesome",
1080
+ seo: { "meta-google-news-standout": true },
1081
+ tags: [{ name: "Footag" }],
1082
+ authors: [{ name: "foo" }],
1083
+ };
1084
+ const string = getSeoMetadata(
1085
+ seoConfig,
1086
+ { "sketches-host": "http://foo.com" },
1087
+ "story-page-amp",
1088
+ { data: { story: story } },
1089
+ { url: url.parse("/my-page") }
1090
+ );
765
1091
  assertContains('<meta name="news_keywords" content="Footag"/>', string);
766
1092
  assertContains('<link rel="standout" href="http://foo.com/politics/awesome"/>', string);
767
1093
  });
@@ -770,38 +1096,63 @@ describe('TextTags', function () {
770
1096
  describe("Getting the title", function () {
771
1097
  it("can also get the title only", function () {
772
1098
  const seo = new SEO({ generators: [] });
773
- const config = { "seo-metadata": [{ "owner-type": 'home', "owner-id": null, "data": { 'page-title': "Foobar" } }] };
774
- assert.equal("Foobar", seo.getTitle(config, 'home-page', {}, {}));
1099
+ const config = { "seo-metadata": [{ "owner-type": "home", "owner-id": null, data: { "page-title": "Foobar" } }] };
1100
+ assert.equal("Foobar", seo.getTitle(config, "home-page", {}, {}));
775
1101
  });
776
1102
 
777
1103
  it("can also get the title if passed in from data", function () {
778
1104
  const seo = new SEO({ generators: [] });
779
- const config = { "seo-metadata": [{ "owner-type": 'home', "owner-id": null, "data": { 'page-title': "Foobar" } }] };
780
- assert.equal("My Title", seo.getTitle(config, 'home-page', { title: "My Title" }, {}));
781
- assert.equal("My Title", seo.getTitle(config, 'home-page', { data: { title: "My Title" } }, {}));
1105
+ const config = { "seo-metadata": [{ "owner-type": "home", "owner-id": null, data: { "page-title": "Foobar" } }] };
1106
+ assert.equal("My Title", seo.getTitle(config, "home-page", { title: "My Title" }, {}));
1107
+ assert.equal("My Title", seo.getTitle(config, "home-page", { data: { title: "My Title" } }, {}));
782
1108
  });
783
1109
  it("can also get the customSeo title if it is passed in from data", function () {
784
1110
  const seo = new SEO({ generators: [] });
785
- const config = { "seo-metadata": [{ "owner-type": 'home', "owner-id": null, "data": { 'page-title': "Foobar" } }] };
786
- assert.equal("My Customseo Title", seo.getTitle(config, 'home-page', { data: { customSeo: { title: "My Customseo Title" } } }, {}));
1111
+ const config = { "seo-metadata": [{ "owner-type": "home", "owner-id": null, data: { "page-title": "Foobar" } }] };
1112
+ assert.equal(
1113
+ "My Customseo Title",
1114
+ seo.getTitle(config, "home-page", { data: { customSeo: { title: "My Customseo Title" } } }, {})
1115
+ );
787
1116
  });
788
1117
 
789
1118
  it("fallback to default seo title if the customSeo title is not passed from data", function () {
790
1119
  const seo = new SEO({ generators: [] });
791
- const config = { "seo-metadata": [{ "owner-type": 'home', "owner-id": null, "data": { 'page-title': "Foobar" } }] };
792
- assert.equal("My Title", seo.getTitle(config, 'home-page', { data: { customSeo: { title: "" }, title: "My Title" } }, {}));
1120
+ const config = { "seo-metadata": [{ "owner-type": "home", "owner-id": null, data: { "page-title": "Foobar" } }] };
1121
+ assert.equal(
1122
+ "My Title",
1123
+ seo.getTitle(config, "home-page", { data: { customSeo: { title: "" }, title: "My Title" } }, {})
1124
+ );
793
1125
  });
794
1126
  });
795
1127
 
796
- describe('Tag Page', function () {
1128
+ describe("Tag Page", function () {
797
1129
  it("Generates SEO tags for a tag page", function () {
798
1130
  const seoConfig = {
799
1131
  generators: [TextTags],
800
1132
  };
801
1133
  const tag = { id: 123, name: "Footag", "meta-description": "Some Foobar", slug: "Foobar" };
802
- const config = { "sketches-host": "http://foo.com", "seo-metadata": [{ "owner-type": "home", "data": { 'page-title': "Foobar", 'description': "Some Foobar", 'keywords': "keywords", 'canonicalUrl': "http://foo.com" } }] };
803
- const string = getSeoMetadata(seoConfig, config, 'tag-page', { data: { tag: tag } }, { url: url.parse("/topic/my-tag") });
804
- assertContains('<title>Footag</title>', string);
1134
+ const config = {
1135
+ "sketches-host": "http://foo.com",
1136
+ "seo-metadata": [
1137
+ {
1138
+ "owner-type": "home",
1139
+ data: {
1140
+ "page-title": "Foobar",
1141
+ description: "Some Foobar",
1142
+ keywords: "keywords",
1143
+ canonicalUrl: "http://foo.com",
1144
+ },
1145
+ },
1146
+ ],
1147
+ };
1148
+ const string = getSeoMetadata(
1149
+ seoConfig,
1150
+ config,
1151
+ "tag-page",
1152
+ { data: { tag: tag } },
1153
+ { url: url.parse("/topic/my-tag") }
1154
+ );
1155
+ assertContains("<title>Footag</title>", string);
805
1156
  assertContains('<meta name="description" content="Some Foobar"/>', string);
806
1157
  assertContains('<meta name="keywords" content="Footag"/>', string);
807
1158
  assertContains('<link rel="canonical" href="http://foo.com/topic/my-tag"/>', string);
@@ -809,48 +1160,86 @@ describe('TextTags', function () {
809
1160
  it("Gets home data as fallback if the tag metadata is falsy", function () {
810
1161
  const seoConfig = {
811
1162
  generators: [TextTags],
812
- }
813
- const tag = {}
814
- const config = { "sketches-host": "http://foo.com", "seo-metadata": [{ "owner-type": 'home', "owner-id": null, "data": { 'page-title': "Foobar", 'description': "Some Foobar", 'keywords': "keywords", 'canonicalUrl': "http://foo.com" } }] };
815
- const string = getSeoMetadata(seoConfig, config, 'tag-page', {}, { url: '' });
816
- assertContains('<title>Foobar</title>', string);
1163
+ };
1164
+ const tag = {};
1165
+ const config = {
1166
+ "sketches-host": "http://foo.com",
1167
+ "seo-metadata": [
1168
+ {
1169
+ "owner-type": "home",
1170
+ "owner-id": null,
1171
+ data: {
1172
+ "page-title": "Foobar",
1173
+ description: "Some Foobar",
1174
+ keywords: "keywords",
1175
+ canonicalUrl: "http://foo.com",
1176
+ },
1177
+ },
1178
+ ],
1179
+ };
1180
+ const string = getSeoMetadata(seoConfig, config, "tag-page", {}, { url: "" });
1181
+ assertContains("<title>Foobar</title>", string);
817
1182
  assertContains('<meta name="description" content="Some Foobar"/>', string);
818
1183
  assertContains('<meta name="keywords" content="keywords"/>', string);
819
1184
  assertContains('<link rel="canonical" href="http://foo.com"/>', string);
820
1185
  });
821
1186
  });
822
1187
 
823
- describe('Collection Page', function () {
1188
+ describe("Collection Page", function () {
824
1189
  it("Generate SEO tags for collection page", function () {
825
1190
  const seoConfig = {
826
1191
  generators: [TextTags],
827
1192
  };
828
1193
  const config = {
829
- 'sketches-host': "http://foo.com",
830
- "sections": [],
831
- "seo-metadata": []
1194
+ "sketches-host": "http://foo.com",
1195
+ sections: [],
1196
+ "seo-metadata": [],
832
1197
  };
833
1198
  const collection = { name: "Collection Title", summary: "Collection Description" };
834
- const string = getSeoMetadata(seoConfig, config, 'collection-page', { data: { collection } }, { url: url.parse("/") });
835
- assertContains('<title>Collection Title</title>', string);
1199
+ const string = getSeoMetadata(
1200
+ seoConfig,
1201
+ config,
1202
+ "collection-page",
1203
+ { data: { collection } },
1204
+ { url: url.parse("/") }
1205
+ );
1206
+ assertContains("<title>Collection Title</title>", string);
836
1207
  assertContains('<meta name="description" content="Collection Description"/>', string);
837
1208
  assertContains('<meta name="title" content="Collection Title"/>', string);
838
- assertDoesNotContains('canonical', string);
839
- assertDoesNotContains('og:url', string);
1209
+ assertDoesNotContains("canonical", string);
1210
+ assertDoesNotContains("og:url", string);
840
1211
  });
841
1212
  it("Gets home data as fallback if the collection data is falsy", function () {
842
1213
  const seoConfig = {
843
1214
  generators: [TextTags],
844
1215
  };
845
- const config = { "sketches-host": "http://foo.com", "seo-metadata": [{ "owner-type": 'home', "owner-id": null, "data": { 'page-title': "Foobar", 'description': "Some Foobar", 'keywords': "keywords", 'canonicalUrl': "http://foo.com" } }] };
1216
+ const config = {
1217
+ "sketches-host": "http://foo.com",
1218
+ "seo-metadata": [
1219
+ {
1220
+ "owner-type": "home",
1221
+ "owner-id": null,
1222
+ data: {
1223
+ "page-title": "Foobar",
1224
+ description: "Some Foobar",
1225
+ keywords: "keywords",
1226
+ canonicalUrl: "http://foo.com",
1227
+ },
1228
+ },
1229
+ ],
1230
+ };
846
1231
  const collection = {};
847
- const string = getSeoMetadata(seoConfig, config, 'collection-page', { data: { collection } }, { url: url.parse("/") });
848
- assertContains('<title>Foobar</title>', string);
1232
+ const string = getSeoMetadata(
1233
+ seoConfig,
1234
+ config,
1235
+ "collection-page",
1236
+ { data: { collection } },
1237
+ { url: url.parse("/") }
1238
+ );
1239
+ assertContains("<title>Foobar</title>", string);
849
1240
  assertContains('<meta name="description" content="Some Foobar"/>', string);
850
1241
  assertContains('<meta name="keywords" content="keywords"/>', string);
851
1242
  assertContains('<link rel="canonical" href="http://foo.com"/>', string);
852
1243
  });
853
-
854
- })
855
-
1244
+ });
856
1245
  });