Three test files covering the Phase 1 invariants: - derivePulseStatus: draft/closed are sticky; open auto-closes by date. - vote UNIQUE(pulse_id, user_id): castVote (OR IGNORE) keeps the first vote silently, a raw second INSERT raises a constraint error, and uniqueness is per-pulse (same user on a different pulse is fine). - homeRouteForRole: cab/fenja → /pulse, pilot → null (render existing home). tests/setup.ts opens BIFROST_DB_PATH=':memory:' and applies all migrations before tests run, so the in-memory DB has the live schema. Each vitest fork gets its own globalThis → its own fresh in-memory DB. The homeRouteForRole helper extraction makes the / role-redirect testable without booting Astro. Step 6 will use it from /index.astro. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
34 lines
1.5 KiB
TypeScript
34 lines
1.5 KiB
TypeScript
import { describe, it, expect } from 'vitest';
|
|
import { derivePulseStatus } from '../src/lib/db.js';
|
|
|
|
const ago = (mins: number) => new Date(Date.now() - mins * 60_000).toISOString();
|
|
const ahead = (mins: number) => new Date(Date.now() + mins * 60_000).toISOString();
|
|
|
|
describe('derivePulseStatus', () => {
|
|
it('a draft stays a draft regardless of dates', () => {
|
|
expect(derivePulseStatus('draft', ago(60))).toBe('draft');
|
|
expect(derivePulseStatus('draft', ahead(60))).toBe('draft');
|
|
});
|
|
|
|
it('a closed pulse stays closed', () => {
|
|
expect(derivePulseStatus('closed', ahead(60))).toBe('closed');
|
|
expect(derivePulseStatus('closed', ago(60))).toBe('closed');
|
|
});
|
|
|
|
it('an open pulse stays open while now < closes_at', () => {
|
|
expect(derivePulseStatus('open', ahead(1))).toBe('open');
|
|
expect(derivePulseStatus('open', ahead(60 * 24))).toBe('open');
|
|
});
|
|
|
|
it('an open pulse becomes closed once now ≥ closes_at', () => {
|
|
expect(derivePulseStatus('open', ago(1))).toBe('closed');
|
|
expect(derivePulseStatus('open', ago(60 * 24))).toBe('closed');
|
|
});
|
|
|
|
it('respects an injected anchor time (deterministic)', () => {
|
|
const closes = '2026-05-11T12:00:00Z';
|
|
expect(derivePulseStatus('open', closes, new Date('2026-05-11T11:59:59Z'))).toBe('open');
|
|
expect(derivePulseStatus('open', closes, new Date('2026-05-11T12:00:00Z'))).toBe('closed');
|
|
expect(derivePulseStatus('open', closes, new Date('2026-05-11T12:00:01Z'))).toBe('closed');
|
|
});
|
|
});
|