fix(watchlist): preserve custom body sections through sync rewrite

renderNote wiped any ## heading not owned by the renderer (Synopsis,
Cast, Links, My Notes) on every sync, destroying user content like
## Collection graph-link sections. extractCustomSections now pulls
non-owned sections out of the existing body before rewrite, and
renderNote re-emits them verbatim, in original order, between Links
and My Notes.
This commit is contained in:
afiqzudinhadi 2026-07-30 14:59:24 +08:00
parent 2c663568ca
commit fb3f52e4b0
6 changed files with 130 additions and 4 deletions

View file

@ -37,3 +37,28 @@ describe('renderNote golden', () => {
expect(renderNote(r, '')).not.toContain('**Rating:**');
});
});
describe('renderNote custom sections', () => {
test('no custom sections → output unchanged (golden)', () => {
const expected = readFileSync(join(import.meta.dir, 'fixtures', 'canonical-series.md'), 'utf-8');
expect(renderNote(LOKI, '', [])).toBe(expected);
});
test('single custom section placed after Links, before My Notes', () => {
const out = renderNote(LOKI, '', [{ heading: 'Collection', content: 'Part of [[Movies]]' }]);
const linksIdx = out.indexOf('## Links');
const collectionIdx = out.indexOf('## Collection');
const myNotesIdx = out.indexOf('## My Notes');
expect(linksIdx).toBeGreaterThan(-1);
expect(collectionIdx).toBeGreaterThan(linksIdx);
expect(myNotesIdx).toBeGreaterThan(collectionIdx);
expect(out).toContain('## Collection\nPart of [[Movies]]\n');
});
test('multiple custom sections keep relative order', () => {
const out = renderNote(LOKI, '', [
{ heading: 'Collection', content: 'Part of [[Movies]]' },
{ heading: 'Rewatch Log', content: '- 2024-01-01' },
]);
expect(out.indexOf('## Collection')).toBeLessThan(out.indexOf('## Rewatch Log'));
expect(out.indexOf('## Rewatch Log')).toBeLessThan(out.indexOf('## My Notes'));
});
});