mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-09-25 05:16:19 -07:00
168 lines
6.6 KiB
TypeScript
168 lines
6.6 KiB
TypeScript
import { expect, test } from 'bun:test';
|
|
import { fileURLToPath } from 'node:url';
|
|
import type { TransformContext } from 'vitepress';
|
|
import docsConfig from './.vitepress/config';
|
|
|
|
const docsSiteDir = fileURLToPath(new URL('.', import.meta.url));
|
|
|
|
function makeTransformContext(page: string): TransformContext {
|
|
return {
|
|
page,
|
|
siteConfig: {} as TransformContext['siteConfig'],
|
|
siteData: {} as TransformContext['siteData'],
|
|
pageData: {} as TransformContext['pageData'],
|
|
title: 'SubMiner',
|
|
description: 'SubMiner docs',
|
|
head: [],
|
|
content: '',
|
|
assets: [],
|
|
};
|
|
}
|
|
|
|
test('docs pages emit stable self-referential canonical URLs', async () => {
|
|
const rootHead = await docsConfig.transformHead?.(makeTransformContext('index.md'));
|
|
const usageHead = await docsConfig.transformHead?.(makeTransformContext('usage.md'));
|
|
|
|
expect(rootHead).toContainEqual([
|
|
'link',
|
|
{ rel: 'canonical', href: 'https://docs.subminer.moe/' },
|
|
]);
|
|
expect(usageHead).toContainEqual([
|
|
'link',
|
|
{ rel: 'canonical', href: 'https://docs.subminer.moe/usage' },
|
|
]);
|
|
expect(JSON.stringify(rootHead).toLowerCase()).not.toContain('noindex');
|
|
});
|
|
|
|
test('main docs canonical uses /main/ and emits noindex', async () => {
|
|
const previousChannel = process.env.SUBMINER_DOCS_CHANNEL;
|
|
const previousBase = process.env.SUBMINER_DOCS_BASE;
|
|
process.env.SUBMINER_DOCS_CHANNEL = 'main';
|
|
process.env.SUBMINER_DOCS_BASE = '/main/';
|
|
const { default: mainDocsConfig } = await import('./.vitepress/config?main-docs');
|
|
|
|
const head = await mainDocsConfig.transformHead?.(makeTransformContext('usage.md'));
|
|
const rootHead = await mainDocsConfig.transformHead?.(makeTransformContext('index.md'));
|
|
|
|
expect(head).toContainEqual([
|
|
'link',
|
|
{ rel: 'canonical', href: 'https://docs.subminer.moe/main/usage' },
|
|
]);
|
|
expect(rootHead).toContainEqual([
|
|
'link',
|
|
{ rel: 'canonical', href: 'https://docs.subminer.moe/main/' },
|
|
]);
|
|
expect(head).toContainEqual(['meta', { name: 'robots', content: 'noindex,follow' }]);
|
|
expect(mainDocsConfig.sitemap).toBeUndefined();
|
|
|
|
process.env.SUBMINER_DOCS_CHANNEL = previousChannel;
|
|
process.env.SUBMINER_DOCS_BASE = previousBase;
|
|
});
|
|
|
|
test.each([
|
|
['v0.14.0', '/v/0.14.0/', 'https://docs.subminer.moe/v/0.14.0/usage'],
|
|
['v0.12.0', '/v/0.12.0/', 'https://docs.subminer.moe/v/0.12.0/usage'],
|
|
])(
|
|
'%s archive keeps a self-referential canonical and stays out of the index',
|
|
async (version, base, expectedCanonical) => {
|
|
const previousChannel = process.env.SUBMINER_DOCS_CHANNEL;
|
|
const previousBase = process.env.SUBMINER_DOCS_BASE;
|
|
const previousVersion = process.env.SUBMINER_DOCS_VERSION;
|
|
process.env.SUBMINER_DOCS_CHANNEL = 'stable-archive';
|
|
process.env.SUBMINER_DOCS_BASE = base;
|
|
process.env.SUBMINER_DOCS_VERSION = version;
|
|
try {
|
|
const { default: archiveConfig } = await import(`./.vitepress/config?archive-${version}`);
|
|
|
|
const head = await archiveConfig.transformHead?.(makeTransformContext('usage.md'));
|
|
|
|
expect(head).toContainEqual(['link', { rel: 'canonical', href: expectedCanonical }]);
|
|
expect(head).toContainEqual(['meta', { name: 'robots', content: 'noindex,follow' }]);
|
|
// A sitemap here would advertise the archive tree we just excluded.
|
|
expect(archiveConfig.sitemap).toBeUndefined();
|
|
} finally {
|
|
process.env.SUBMINER_DOCS_CHANNEL = previousChannel;
|
|
process.env.SUBMINER_DOCS_BASE = previousBase;
|
|
process.env.SUBMINER_DOCS_VERSION = previousVersion;
|
|
}
|
|
},
|
|
);
|
|
|
|
test('archive nav keeps page links in-version and version links release-independent', async () => {
|
|
const previousCwd = process.cwd();
|
|
const previousChannel = process.env.SUBMINER_DOCS_CHANNEL;
|
|
const previousBase = process.env.SUBMINER_DOCS_BASE;
|
|
const previousVersion = process.env.SUBMINER_DOCS_VERSION;
|
|
process.chdir(docsSiteDir);
|
|
process.env.SUBMINER_DOCS_CHANNEL = 'stable-archive';
|
|
process.env.SUBMINER_DOCS_BASE = '/v/0.12.0/';
|
|
process.env.SUBMINER_DOCS_VERSION = 'v0.12.0';
|
|
try {
|
|
const { default: archiveConfig } = await import('./.vitepress/config?stable-archive-links');
|
|
|
|
const nav = archiveConfig.themeConfig?.nav as Array<{
|
|
text: string;
|
|
link?: string;
|
|
items?: Array<{ text: string; link: string }>;
|
|
}>;
|
|
const sidebar = archiveConfig.themeConfig?.sidebar as Array<{
|
|
text: string;
|
|
items?: Array<{ text: string; link: string }>;
|
|
}>;
|
|
const configurationSidebar = sidebar
|
|
.find((item) => item.text === 'Reference')
|
|
?.items?.find((item) => item.text === 'Configuration');
|
|
|
|
expect(nav.find((item) => item.text === 'Configuration')?.link).toBe('/configuration');
|
|
expect(configurationSidebar?.link).toBe('/configuration');
|
|
// Frozen archives must not embed the release list, or every new tag would
|
|
// invalidate them. They point at the root-only /versions page instead.
|
|
expect(nav.find((item) => item.text === 'v0.12.0')?.items).toEqual([
|
|
{ text: 'Latest stable', link: 'https://docs.subminer.moe/', target: '_self', noIcon: true },
|
|
{ text: 'main', link: 'https://docs.subminer.moe/main/', target: '_self', noIcon: true },
|
|
{
|
|
text: 'All versions',
|
|
link: 'https://docs.subminer.moe/versions',
|
|
target: '_self',
|
|
noIcon: true,
|
|
},
|
|
]);
|
|
expect(archiveConfig.themeConfig?.logo).toEqual({
|
|
light: '/assets/SubMiner.png',
|
|
dark: '/assets/SubMiner.png',
|
|
});
|
|
} finally {
|
|
process.chdir(previousCwd);
|
|
process.env.SUBMINER_DOCS_CHANNEL = previousChannel;
|
|
process.env.SUBMINER_DOCS_BASE = previousBase;
|
|
process.env.SUBMINER_DOCS_VERSION = previousVersion;
|
|
}
|
|
});
|
|
|
|
test('docs sitemap excludes duplicate README page from indexable URLs', async () => {
|
|
const items = [{ url: '' }, { url: 'README' }, { url: 'usage' }];
|
|
|
|
const transformedItems = await docsConfig.sitemap?.transformItems?.(items);
|
|
|
|
expect(transformedItems?.map((item) => item.url)).toEqual(['', 'usage']);
|
|
});
|
|
|
|
test('docs sitemap dates every URL from the tracked checkout', async () => {
|
|
const previousRepoDir = process.env.SUBMINER_DOCS_REPO_DIR;
|
|
// Production builds render from an untracked snapshot, so the date has to come from
|
|
// the real checkout rather than VitePress's own srcDir git lookup.
|
|
process.env.SUBMINER_DOCS_REPO_DIR = docsSiteDir;
|
|
try {
|
|
const { default: sitemapConfig } = await import('./.vitepress/config?sitemap-lastmod');
|
|
|
|
const items = await sitemapConfig.sitemap?.transformItems?.([{ url: '' }, { url: 'usage' }]);
|
|
|
|
expect(items).toHaveLength(2);
|
|
for (const item of items ?? []) {
|
|
expect(item.lastmod).toMatch(/^\d{4}-\d{2}-\d{2}T/);
|
|
}
|
|
} finally {
|
|
process.env.SUBMINER_DOCS_REPO_DIR = previousRepoDir;
|
|
}
|
|
});
|