import { describe, it, expect, beforeAll, vi } from 'vitest'; import { pool } from '../../lib/db/pool.js'; import { resetDb } from '../helpers/db.js'; import { migrateUp } from '../../lib/db/migrate.js'; import { ensureSpace } from '../../migrate/spaces.js'; import { importBookstack } from '../../migrate/sources/bookstack.js'; let spaceId; beforeAll(async () => { await resetDb(); await migrateUp(); spaceId = await ensureSpace('wiki', 'Wiki'); }); describe('bookstack importer', () => { it('imports pages with markdown body, idempotently', async () => { const list = { data: [{ id: 1, name: 'Page One' }, { id: 2, name: 'Page Two' }] }; const detail = (id) => ({ id, name: id === 1 ? 'Page One' : 'Page Two', markdown: `# P${id}\nbody`, html: `

body

` }); const fetchImpl = vi.fn(async (u) => { if (u.endsWith('/api/pages')) return { ok: true, json: async () => list }; const id = Number(u.split('/').pop()); return { ok: true, json: async () => detail(id) }; }); const r1 = await importBookstack({ apiUrl: 'http://bs', tokenId: 'i', tokenSecret: 's', spaceId, fetchImpl }); expect(r1.created).toBe(2); const { rows } = await pool.query(`SELECT title FROM pages WHERE space_id=$1 ORDER BY title`, [spaceId]); expect(rows.map(r => r.title)).toEqual(['Page One', 'Page Two']); const r2 = await importBookstack({ apiUrl: 'http://bs', tokenId: 'i', tokenSecret: 's', spaceId, fetchImpl }); expect(r2.created).toBe(0); }); });