openvibers/openvibe.work Commits
SEO-13: no JobPosting on the jobs listing; a job's page carries one (#114)
Changes
@@@ -139,6 +139,7 @@ const first = async (t, path) => (await t.get(path)).json();await check('the listing page carries a valid JobPosting whose url is the original, not this page', async () => {const job = (await first(t, '/api/v1/jobs?q=DevOps')).jobs[0];const html = (await t.get(`/jobs/${job.id}`)).text;++ assert.strictEqual((html.match(/application\/ld\+json/g) || []).length, 1, 'one JSON-LD script per page');const blocks = ldBlocks(html);const posting = blocks.find((b) => b['@type'] === 'JobPosting');assert.ok(posting, `no JobPosting node: ${JSON.stringify(blocks.map((b) => b['@type']))}`);@@@ -151,6 +152,8 @@ const first = async (t, path) => (await t.get(path)).json();assert.strictEqual(posting.identifier.name, 'remoteok');assert.ok(posting.description.length <= 320);assert.ok(posting['@context'] === 'https://schema.org');++ // The search page lists many listings but is not one job, so it carries no JobPosting.++ assert.ok(!ldBlocks((await t.get('/jobs')).text).some((b) => b['@type'] === 'JobPosting'), 'the listing page has no JobPosting');// Every JSON-LD block on the page parses (the escaping must survive a hostile title).assert.ok(blocks.length >= 1);});
@@ -139,6 +139,7 @@ const first = async (t, path) => (await t.get(path)).json();
@@ -139,6 +139,7 @@ const first = async (t, path) => (await t.get(path)).json();
await check('the listing page carries a valid JobPosting whose url is the original, not this page', async () => {
await check('the listing page carries a valid JobPosting whose url is the original, not this page', async () => {
const job = (await first(t, '/api/v1/jobs?q=DevOps')).jobs[0];
const job = (await first(t, '/api/v1/jobs?q=DevOps')).jobs[0];
const html = (await t.get(`/jobs/${job.id}`)).text;
const html = (await t.get(`/jobs/${job.id}`)).text;
+ assert.strictEqual((html.match(/application\/ld\+json/g) || []).length, 1, 'one JSON-LD script per page');
const blocks = ldBlocks(html);
const blocks = ldBlocks(html);
const posting = blocks.find((b) => b['@type'] === 'JobPosting');
const posting = blocks.find((b) => b['@type'] === 'JobPosting');
assert.ok(posting, `no JobPosting node: ${JSON.stringify(blocks.map((b) => b['@type']))}`);
assert.ok(posting, `no JobPosting node: ${JSON.stringify(blocks.map((b) => b['@type']))}`);
@@ -151,6 +152,8 @@ const first = async (t, path) => (await t.get(path)).json();
@@ -151,6 +152,8 @@ const first = async (t, path) => (await t.get(path)).json();
assert.strictEqual(posting.identifier.name, 'remoteok');
assert.strictEqual(posting.identifier.name, 'remoteok');
assert.ok(posting.description.length <= 320);
assert.ok(posting.description.length <= 320);
assert.ok(posting['@context'] === 'https://schema.org');
assert.ok(posting['@context'] === 'https://schema.org');
+ // The search page lists many listings but is not one job, so it carries no JobPosting.
+ assert.ok(!ldBlocks((await t.get('/jobs')).text).some((b) => b['@type'] === 'JobPosting'), 'the listing page has no JobPosting');
// Every JSON-LD block on the page parses (the escaping must survive a hostile title).
// Every JSON-LD block on the page parses (the escaping must survive a hostile title).
assert.ok(blocks.length >= 1);
assert.ok(blocks.length >= 1);
});
});