## Summary - Closes the public-page gaps from #124: each route gets its own title, description, canonical, heading, links, and JSON-LD, and unknown URLs have a real 404 document. - Adds HeyCatch and the Google tag (`G-V12DLRLPWR`) only on the production site and the iOS and Android apps. Tianji still loads on beta. - Needs the server-infra change that stops serving the app shell for missing paths. ## Test plan - [ ] Build production and confirm `/` and `/pricing/` HTML include a unique title, description, canonical, one h1, social tags, related links, and Organization JSON-LD. - [ ] Confirm a nonsense path is served as `404.html` once the nginx change is deployed. - [ ] Confirm beta and local web do not load HeyCatch or gtag, and that a production or native build does. - [ ] Open the live site after deploy and click around, then mark HeyCatch installed in its dashboard. Reviewed-on: #125
88 lines
2.9 KiB
JavaScript
88 lines
2.9 KiB
JavaScript
const { test } = require('node:test');
|
|
const assert = require('node:assert/strict');
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
const {
|
|
newestChangelogDate,
|
|
termsUpdated,
|
|
renderSitemap,
|
|
gitLastmod,
|
|
indexNowBody,
|
|
INDEXNOW_KEY,
|
|
} = require('./sitemap');
|
|
const { pingIndexNow } = require('./pingIndexNow');
|
|
|
|
const repoRoot = path.resolve(__dirname, '../..');
|
|
|
|
test('changelog lastmod is the newest entry date', () => {
|
|
const source = `
|
|
{ date: '2026-08-01', title: 'Documents' },
|
|
{ date: '2026-08-04', title: 'Account deletion' },
|
|
`;
|
|
assert.equal(newestChangelogDate(source), '2026-08-04');
|
|
});
|
|
|
|
test('terms lastmod is the Last Updated line, not today', () => {
|
|
assert.equal(
|
|
termsUpdated('Last Updated: July 27, 2026'),
|
|
'2026-07-27',
|
|
);
|
|
});
|
|
|
|
test('live page sources supply lastmod', () => {
|
|
const changelog = fs.readFileSync(
|
|
path.join(repoRoot, 'llm-fe/src/llm-fe/pages/Changelog/changelogEntries.ts'),
|
|
'utf8',
|
|
);
|
|
const terms = fs.readFileSync(
|
|
path.join(repoRoot, 'llm-fe/src/llm-fe/components/legal/TermsOfServiceDocument.tsx'),
|
|
'utf8',
|
|
);
|
|
assert.equal(newestChangelogDate(changelog), '2026-08-04');
|
|
assert.equal(termsUpdated(terms), '2026-07-27');
|
|
|
|
for (const file of [
|
|
'llm-fe/src/llm-fe/pages/Landing/LandingPage.tsx',
|
|
'llm-fe/src/llm-fe/pages/Pricing/PricingPage.tsx',
|
|
'llm-fe/src/llm-fe/pages/Privacy/PrivacyPage.tsx',
|
|
'llm-fe/src/llm-fe/pages/AccountDeletion/AccountDeletionPage.tsx',
|
|
]) {
|
|
try {
|
|
assert.match(gitLastmod(file), /^\d{4}-\d{2}-\d{2}$/);
|
|
} catch (error) {
|
|
if (!String(error.message).includes('no git commit date')) throw error;
|
|
}
|
|
}
|
|
|
|
const xml = renderSitemap([
|
|
{ loc: 'https://hesychia.ai/changelog/', lastmod: newestChangelogDate(changelog) },
|
|
{ loc: 'https://hesychia.ai/terms_of_service/', lastmod: termsUpdated(terms) },
|
|
]);
|
|
assert.match(xml, /<loc>https:\/\/hesychia\.ai\/changelog\/<\/loc>\n\s*<lastmod>2026-08-04<\/lastmod>/);
|
|
assert.match(xml, /<lastmod>2026-07-27<\/lastmod>/);
|
|
assert.equal(xml.includes('<html'), false);
|
|
});
|
|
|
|
test('IndexNow POST body lists the published URLs and the hosted key', async () => {
|
|
const urls = ['https://hesychia.ai/', 'https://hesychia.ai/pricing/'];
|
|
assert.deepEqual(indexNowBody(INDEXNOW_KEY, urls), {
|
|
host: 'hesychia.ai',
|
|
key: INDEXNOW_KEY,
|
|
keyLocation: `https://hesychia.ai/${INDEXNOW_KEY}.txt`,
|
|
urlList: urls,
|
|
});
|
|
|
|
let posted;
|
|
const result = await pingIndexNow(async (url, init) => {
|
|
posted = { url, init };
|
|
return { status: 202, text: async () => '' };
|
|
}, urls);
|
|
assert.equal(posted.url, 'https://api.indexnow.org/indexnow');
|
|
assert.equal(posted.init.method, 'POST');
|
|
assert.equal(posted.init.headers['Content-Type'], 'application/json');
|
|
const body = JSON.parse(posted.init.body);
|
|
assert.equal(body.keyLocation, `https://hesychia.ai/${INDEXNOW_KEY}.txt`);
|
|
assert.deepEqual(body.urlList, urls);
|
|
assert.equal(result.status, 202);
|
|
});
|