openvibers/openvibe.fun Commits
JSON-LD page names match the titles on the HTML pages too (#57)
Changes
@@@ -92,7 +92,7 @@ function createPageRoutes(ctx) {index: true, cache: result ? PUBLIC_CACHE : null, agentLayer: true,title: 'The local guide',description: 'What\'s fun near me? Places from OpenStreetMap and local events from Ticketmaster when a key is configured, with a map, times and links.',-- jsonLd: [seo.jsonLd.webPage({ name: 'The OpenVibe.Fun local guide', url: `${base()}/guide`, description: 'Places from OpenStreetMap, local events when Ticketmaster is configured.', siteUrl: base() })],++ jsonLd: [seo.jsonLd.webPage({ name: 'The local guide', url: `${base()}/guide`, description: 'Places from OpenStreetMap, local events when Ticketmaster is configured.', siteUrl: base() })],body: raw(views.guide({ values, result, error: problem })),}, status);});@@@ -104,7 +104,7 @@ function createPageRoutes(ctx) {index: true, cache: PUBLIC_CACHE, agentLayer: true,title: 'IRL quests on Live',description: 'Viewers suggest, chat votes, the streamer accepts and a moderator or the chat verifies. Safe, accessible challenges for the real world.',-- jsonLd: [seo.jsonLd.webPage({ name: 'IRL quests on OpenVibe.Live', url: `${base()}/quests`, description: 'Safe IRL challenges for streamers and their chat.', siteUrl: base() })],++ jsonLd: [seo.jsonLd.webPage({ name: 'IRL quests on Live', url: `${base()}/quests`, description: 'Safe IRL challenges for streamers and their chat.', siteUrl: base() })],body: raw(views.quests({ quests: out.quests, ideas: ideas.IDEAS })),});});@@@ -255,7 +255,7 @@ function createPageRoutes(ctx) {index: true, cache: PUBLIC_CACHE, agentLayer: true,title: 'Group plans',description: 'Two or three options, one link, one vote each. The group picks the plan and the winner can go to Today.',-- jsonLd: [seo.jsonLd.webPage({ name: 'Group plans on OpenVibe.Fun', url: `${base()}/plans`, description: 'Decide a plan together and send the winner to Today.', siteUrl: base() })],++ jsonLd: [seo.jsonLd.webPage({ name: 'Group plans', url: `${base()}/plans`, description: 'Decide a plan together and send the winner to Today.', siteUrl: base() })],body: raw(views.plans({ plans: out.plans, now: s.now(), base: base() })),});});@@@ -26,6 +26,16 @@ function jsonLd(html) {const p = await t.get('/api/v1/plans', { as: kim, json: { title: 'Friday with the group', summary: 'Two choices.', city: 'Portland', starts_at: future, timezone: 'UTC', visibility: 'public', options: [{ title: 'Mural walk', accessible: true }, { title: 'Bowling' }] } });const plan = p.json();++ await check('each page\'s WebPage name is on the page, in its <title> (the release check\'s JSON-LD rule)', async () => {++ for (const path of ['/guide', '/quests', '/plans', '/developers']) {++ const html = (await t.get(path)).text;++ const title = (/<title>([^<]*)<\/title>/.exec(html) || [])[1] || '';++ const pages = jsonLd(html).flatMap((x) => [].concat(x['@graph'] || x)).filter((x) => /WebPage/.test(String(x['@type'])));++ assert.ok(pages.length, `${path} has a WebPage`);++ for (const w of pages) assert.ok(title.includes(w.name), `${path}: "${w.name}" is in "${title}"`);++ }++ });++await check('home: semantic, the featured quests and plans, the guide teaser, public cache with Vary: Cookie', async () => {const r = await t.get('/');assert.strictEqual(r.status, 200);
@@ -92,7 +92,7 @@ function createPageRoutes(ctx) {
@@ -92,7 +92,7 @@ function createPageRoutes(ctx) {
index: true, cache: result ? PUBLIC_CACHE : null, agentLayer: true,
index: true, cache: result ? PUBLIC_CACHE : null, agentLayer: true,
title: 'The local guide',
title: 'The local guide',
description: 'What\'s fun near me? Places from OpenStreetMap and local events from Ticketmaster when a key is configured, with a map, times and links.',
description: 'What\'s fun near me? Places from OpenStreetMap and local events from Ticketmaster when a key is configured, with a map, times and links.',
- jsonLd: [seo.jsonLd.webPage({ name: 'The OpenVibe.Fun local guide', url: `${base()}/guide`, description: 'Places from OpenStreetMap, local events when Ticketmaster is configured.', siteUrl: base() })],
+ jsonLd: [seo.jsonLd.webPage({ name: 'The local guide', url: `${base()}/guide`, description: 'Places from OpenStreetMap, local events when Ticketmaster is configured.', siteUrl: base() })],
body: raw(views.guide({ values, result, error: problem })),
body: raw(views.guide({ values, result, error: problem })),
}, status);
}, status);
});
});
@@ -104,7 +104,7 @@ function createPageRoutes(ctx) {
@@ -104,7 +104,7 @@ function createPageRoutes(ctx) {
index: true, cache: PUBLIC_CACHE, agentLayer: true,
index: true, cache: PUBLIC_CACHE, agentLayer: true,
title: 'IRL quests on Live',
title: 'IRL quests on Live',
description: 'Viewers suggest, chat votes, the streamer accepts and a moderator or the chat verifies. Safe, accessible challenges for the real world.',
description: 'Viewers suggest, chat votes, the streamer accepts and a moderator or the chat verifies. Safe, accessible challenges for the real world.',
- jsonLd: [seo.jsonLd.webPage({ name: 'IRL quests on OpenVibe.Live', url: `${base()}/quests`, description: 'Safe IRL challenges for streamers and their chat.', siteUrl: base() })],
+ jsonLd: [seo.jsonLd.webPage({ name: 'IRL quests on Live', url: `${base()}/quests`, description: 'Safe IRL challenges for streamers and their chat.', siteUrl: base() })],
body: raw(views.quests({ quests: out.quests, ideas: ideas.IDEAS })),
body: raw(views.quests({ quests: out.quests, ideas: ideas.IDEAS })),
});
});
});
});
@@ -255,7 +255,7 @@ function createPageRoutes(ctx) {
@@ -255,7 +255,7 @@ function createPageRoutes(ctx) {
index: true, cache: PUBLIC_CACHE, agentLayer: true,
index: true, cache: PUBLIC_CACHE, agentLayer: true,
title: 'Group plans',
title: 'Group plans',
description: 'Two or three options, one link, one vote each. The group picks the plan and the winner can go to Today.',
description: 'Two or three options, one link, one vote each. The group picks the plan and the winner can go to Today.',
- jsonLd: [seo.jsonLd.webPage({ name: 'Group plans on OpenVibe.Fun', url: `${base()}/plans`, description: 'Decide a plan together and send the winner to Today.', siteUrl: base() })],
+ jsonLd: [seo.jsonLd.webPage({ name: 'Group plans', url: `${base()}/plans`, description: 'Decide a plan together and send the winner to Today.', siteUrl: base() })],
body: raw(views.plans({ plans: out.plans, now: s.now(), base: base() })),
body: raw(views.plans({ plans: out.plans, now: s.now(), base: base() })),
});
});
});
});
@@ -26,6 +26,16 @@ function jsonLd(html) {
@@ -26,6 +26,16 @@ function jsonLd(html) {
const p = await t.get('/api/v1/plans', { as: kim, json: { title: 'Friday with the group', summary: 'Two choices.', city: 'Portland', starts_at: future, timezone: 'UTC', visibility: 'public', options: [{ title: 'Mural walk', accessible: true }, { title: 'Bowling' }] } });
const p = await t.get('/api/v1/plans', { as: kim, json: { title: 'Friday with the group', summary: 'Two choices.', city: 'Portland', starts_at: future, timezone: 'UTC', visibility: 'public', options: [{ title: 'Mural walk', accessible: true }, { title: 'Bowling' }] } });
const plan = p.json();
const plan = p.json();
+ await check('each page\'s WebPage name is on the page, in its <title> (the release check\'s JSON-LD rule)', async () => {
+ for (const path of ['/guide', '/quests', '/plans', '/developers']) {
+ const html = (await t.get(path)).text;
+ const title = (/<title>([^<]*)<\/title>/.exec(html) || [])[1] || '';
+ const pages = jsonLd(html).flatMap((x) => [].concat(x['@graph'] || x)).filter((x) => /WebPage/.test(String(x['@type'])));
+ assert.ok(pages.length, `${path} has a WebPage`);
+ for (const w of pages) assert.ok(title.includes(w.name), `${path}: "${w.name}" is in "${title}"`);
+ }
+ });
+
await check('home: semantic, the featured quests and plans, the guide teaser, public cache with Vary: Cookie', async () => {
await check('home: semantic, the featured quests and plans, the guide teaser, public cache with Vary: Cookie', async () => {
const r = await t.get('/');
const r = await t.get('/');
assert.strictEqual(r.status, 200);
assert.strictEqual(r.status, 200);