Fix M-4: punctuation-only page name yields empty slug ('.html')

slugify('!!!') stripped down to '' since punctuation-only names have no
a-z0-9 characters left; buildSavePayload then wrote filename = '' +
'.html'. slugify now falls back to 'page' when the computed slug is
empty, so uniqueSlug's existing dedupe (page, page-2, ...) applies same
as any other collision. Landing page slug stays forced to 'index'.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-12 17:33:33 -07:00
parent 25507cb57a
commit e12fb89ada
2 changed files with 38 additions and 1 deletions
+32
View File
@@ -121,6 +121,38 @@ describe('PageProvider slug dedupe', () => {
unmount();
});
test('M-4: a punctuation-only page name ("!!!") falls back to slug "page", never empty string', () => {
let ctx: ReturnType<typeof usePages> | null = null;
const Consumer: React.FC = () => {
ctx = usePages();
return null;
};
render(
<PageProvider>
<Consumer />
</PageProvider>,
);
act(() => {
ctx!.addPage('!!!', '');
});
const added = ctx!.pages.find((p) => p.name === '!!!')!;
expect(added.slug).toBe('page');
expect(added.slug).not.toBe('');
// A second punctuation-only-named page dedupes to 'page-2', not ''.
act(() => {
ctx!.addPage('???', '');
});
const second = ctx!.pages.find((p) => p.name === '???')!;
expect(second.slug).toBe('page-2');
expect(second.slug).not.toBe('');
unmount();
});
test('landing page slug always stays "index" even if renamed to collide', () => {
let ctx: ReturnType<typeof usePages> | null = null;
const Consumer: React.FC = () => {