mirror of
https://github.com/nexu-io/open-design.git
synced 2026-06-01 03:14:35 +07:00
154 lines
4.6 KiB
TypeScript
154 lines
4.6 KiB
TypeScript
import { describe, expect, it } from 'vitest';
|
|
|
|
import {
|
|
canOverwriteHtmlArtifactEntry,
|
|
resolveHtmlArtifactFileName,
|
|
rewriteHtmlLinksToCurrentProjectFiles,
|
|
} from '../../src/artifacts/html-links';
|
|
|
|
describe('resolveHtmlArtifactFileName', () => {
|
|
it('keeps index.html as the stable entry point when the saved artifact already owns it', () => {
|
|
expect(
|
|
resolveHtmlArtifactFileName({
|
|
baseName: 'index',
|
|
ext: '.html',
|
|
existingFileNames: new Set(['index.html']),
|
|
savedArtifactName: 'index.html',
|
|
}),
|
|
).toBe('index.html');
|
|
});
|
|
|
|
it('uses a suffix for index.html when the existing file is unrelated', () => {
|
|
expect(
|
|
resolveHtmlArtifactFileName({
|
|
baseName: 'index',
|
|
ext: '.html',
|
|
existingFileNames: new Set(['index.html']),
|
|
}),
|
|
).toBe('index-2.html');
|
|
});
|
|
|
|
it('keeps index.html when overwrite ownership is proven by the caller', () => {
|
|
expect(
|
|
resolveHtmlArtifactFileName({
|
|
baseName: 'index',
|
|
ext: '.html',
|
|
existingFileNames: new Set(['index.html']),
|
|
canOverwriteExistingEntry: true,
|
|
}),
|
|
).toBe('index.html');
|
|
});
|
|
|
|
it('keeps numbered collision names for non-entry html artifacts', () => {
|
|
expect(
|
|
resolveHtmlArtifactFileName({
|
|
baseName: 'about',
|
|
ext: '.html',
|
|
existingFileNames: new Set(['about.html', 'about-2.html']),
|
|
}),
|
|
).toBe('about-3.html');
|
|
});
|
|
});
|
|
|
|
describe('canOverwriteHtmlArtifactEntry', () => {
|
|
it('allows index.html overwrite when the existing manifest identifier matches', () => {
|
|
expect(
|
|
canOverwriteHtmlArtifactEntry({
|
|
baseName: 'index',
|
|
ext: '.html',
|
|
projectFiles: [
|
|
htmlFile('index.html', 10, { artifactIdentifier: 'index' }),
|
|
],
|
|
artifactIdentifier: 'index',
|
|
}),
|
|
).toBe(true);
|
|
});
|
|
|
|
it('rejects index.html overwrite when the existing manifest identifier is empty', () => {
|
|
expect(
|
|
canOverwriteHtmlArtifactEntry({
|
|
baseName: 'index',
|
|
ext: '.html',
|
|
projectFiles: [
|
|
htmlFile('index.html', 10, { artifactIdentifier: '' }),
|
|
],
|
|
artifactIdentifier: '',
|
|
}),
|
|
).toBe(false);
|
|
});
|
|
});
|
|
|
|
describe('rewriteHtmlLinksToCurrentProjectFiles', () => {
|
|
it('rewrites relative html links to the newest matching project file', () => {
|
|
const html =
|
|
'<!doctype html><html><body>' +
|
|
'<a href="about.html">About</a>' +
|
|
'<a href="contact.html?tab=team#lead">Contact</a>' +
|
|
'<a href="#local">Local</a>' +
|
|
'<a href="https://example.com/about.html">External</a>' +
|
|
'</body></html>';
|
|
|
|
const out = rewriteHtmlLinksToCurrentProjectFiles(html, [
|
|
htmlFile('about.html', 10, { artifactIdentifier: 'about' }),
|
|
htmlFile('about-2.html', 30, { artifactIdentifier: 'about' }),
|
|
htmlFile('contact.html', 20, { artifactIdentifier: 'contact' }),
|
|
htmlFile('contact-2.html', 40, { artifactIdentifier: 'contact' }),
|
|
]);
|
|
|
|
expect(out).toContain('href="about-2.html"');
|
|
expect(out).toContain('href="contact-2.html?tab=team#lead"');
|
|
expect(out).toContain('href="#local"');
|
|
expect(out).toContain('href="https://example.com/about.html"');
|
|
});
|
|
|
|
it('rewrites home links when the artifact entry had to move off index.html', () => {
|
|
const html =
|
|
'<!doctype html><html><body>' +
|
|
'<a href="index.html">Home</a>' +
|
|
'<a href="./index.html#top">Top</a>' +
|
|
'</body></html>';
|
|
|
|
const out = rewriteHtmlLinksToCurrentProjectFiles(html, [
|
|
htmlFile('index.html', 10, { artifactIdentifier: 'index' }),
|
|
htmlFile('index-2.html', 40, { artifactIdentifier: 'index' }),
|
|
]);
|
|
|
|
expect(out).toContain('href="index-2.html"');
|
|
expect(out).toContain('href="./index-2.html#top"');
|
|
});
|
|
|
|
it('does not rewrite to an unrelated newer numbered html file', () => {
|
|
const html =
|
|
'<!doctype html><html><body>' +
|
|
'<a href="about.html">About</a>' +
|
|
'</body></html>';
|
|
|
|
const out = rewriteHtmlLinksToCurrentProjectFiles(html, [
|
|
htmlFile('about.html', 10, { artifactIdentifier: 'about' }),
|
|
htmlFile('about-2.html', 40, { artifactIdentifier: 'other-about' }),
|
|
]);
|
|
|
|
expect(out).toContain('href="about.html"');
|
|
expect(out).not.toContain('href="about-2.html"');
|
|
});
|
|
});
|
|
|
|
function htmlFile(
|
|
name: string,
|
|
mtime: number,
|
|
options: { artifactIdentifier?: string } = {},
|
|
) {
|
|
return {
|
|
name,
|
|
kind: 'html',
|
|
mime: 'text/html',
|
|
size: 1,
|
|
mtime,
|
|
artifactManifest: options.artifactIdentifier !== undefined
|
|
? {
|
|
entry: name,
|
|
metadata: { identifier: options.artifactIdentifier },
|
|
}
|
|
: undefined,
|
|
};
|
|
}
|