Files
platform/src/servers/api/todos/todo-tree.test.ts
T
pastilhasandClaude Fable 5 420cd07507 /todos: a kanban board over the todo/ tree, owner-only
The filesystem is the database: GET reads the tree through the same module the
index generator now imports, PATCH splices frontmatter (status, priority, due,
order) and never touches a body byte, and every write regenerates TODO.md.
Columns open/doing/blocked/done, native drag between them, selection and theme
filter in the URL. Registry entry 'todos' (kind admin, 22 entries, docs:check
green), isSuperAdmin double-gate on the router.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-25 00:18:14 +00:00

63 lines
1.8 KiB
TypeScript

import { describe, expect, test } from 'bun:test';
import { bodyOf, frontmatter, patchFrontmatter } from './todo-tree';
const FILE = `---
id: fleet/an-item
title: "An item, with: punctuation"
theme: fleet
status: open
created: 2026-08-21
order: 2
---
**The body.** Hand-written prose with --- inside it.
- a list
`;
describe('frontmatter', () => {
test('reads plain and JSON-quoted values', () => {
const fm = frontmatter(FILE);
expect(fm.id).toBe('fleet/an-item');
expect(fm.title).toBe('An item, with: punctuation');
expect(fm.order).toBe('2');
});
test('accepts prettier-style single quotes', () => {
expect(frontmatter(`---\ntitle: 'A quoted title'\n---\n`).title).toBe('A quoted title');
});
test('no frontmatter → empty', () => {
expect(frontmatter('just prose')).toEqual({});
});
});
describe('bodyOf', () => {
test('returns everything after the fence, trimmed of leading blank lines', () => {
expect(bodyOf(FILE).startsWith('**The body.**')).toBe(true);
});
});
describe('patchFrontmatter', () => {
test('replaces an existing key in place', () => {
const out = patchFrontmatter(FILE, { status: 'done' });
expect(frontmatter(out).status).toBe('done');
expect(out.match(/^status:/gm)).toHaveLength(1);
});
test('appends a key that was absent', () => {
const out = patchFrontmatter(FILE, { priority: 'urgent' });
expect(frontmatter(out).priority).toBe('urgent');
});
test('never touches the body — byte for byte', () => {
const out = patchFrontmatter(FILE, { status: 'doing', order: '9' });
expect(bodyOf(out)).toBe(bodyOf(FILE));
});
test('a --- inside the body is not mistaken for the fence', () => {
const out = patchFrontmatter(FILE, { status: 'done' });
expect(out).toContain('with --- inside it');
});
});