64 lines
2.3 KiB
TypeScript
64 lines
2.3 KiB
TypeScript
|
|
import { describe, test, expect, beforeAll, afterAll } from 'bun:test';
|
||
|
|
import type { Server } from 'bun';
|
||
|
|
import { fetchDonetickChores } from './donetick';
|
||
|
|
|
||
|
|
const today = new Date().toISOString().slice(0, 10);
|
||
|
|
const tomorrow = new Date(Date.now() + 86_400_000).toISOString().slice(0, 10);
|
||
|
|
const yesterday = new Date(Date.now() - 86_400_000).toISOString().slice(0, 10);
|
||
|
|
|
||
|
|
const CHORES = [
|
||
|
|
{ id: 1, name: 'Make the bed', assignedTo: 1, nextDueDate: `${tomorrow}T00:00:00Z`, isActive: true },
|
||
|
|
{ id: 2, name: 'Water the plants', assignedTo: 1, nextDueDate: `${today}T00:00:00Z`, isActive: true },
|
||
|
|
{ id: 3, name: 'Walk the dog', assignedTo: 2, nextDueDate: `${today}T00:00:00Z`, isActive: true },
|
||
|
|
{ id: 4, name: 'Inactive chore', assignedTo: 1, nextDueDate: `${today}T00:00:00Z`, isActive: false },
|
||
|
|
{ id: 5, name: 'Shared chore', assignedTo: 2, nextDueDate: `${yesterday}T00:00:00Z`, isActive: true, assignees: [{ userId: 1 }, { userId: 2 }] },
|
||
|
|
];
|
||
|
|
|
||
|
|
let server: Server;
|
||
|
|
let baseUrl: string;
|
||
|
|
|
||
|
|
beforeAll(() => {
|
||
|
|
server = Bun.serve({
|
||
|
|
port: 0,
|
||
|
|
hostname: '127.0.0.1',
|
||
|
|
routes: {
|
||
|
|
'/eapi/v1/chore': (req) => {
|
||
|
|
if (req.headers.get('secretkey') !== 'test-token')
|
||
|
|
return new Response('Unauthorized', { status: 401 });
|
||
|
|
return Response.json(CHORES);
|
||
|
|
},
|
||
|
|
},
|
||
|
|
});
|
||
|
|
baseUrl = `http://127.0.0.1:${server.port}`;
|
||
|
|
});
|
||
|
|
|
||
|
|
afterAll(() => {
|
||
|
|
server.stop();
|
||
|
|
});
|
||
|
|
|
||
|
|
describe('donetick source', () => {
|
||
|
|
test('fetches chores for the configured user', async () => {
|
||
|
|
const chores = await fetchDonetickChores({
|
||
|
|
url: baseUrl,
|
||
|
|
token: 'test-token',
|
||
|
|
user_id: 1,
|
||
|
|
});
|
||
|
|
|
||
|
|
// Should include: Water the plants (due today), Shared chore (overdue, in assignees)
|
||
|
|
// Should exclude: Make the bed (done, nextDueDate=tomorrow), Walk the dog (different user), Inactive chore
|
||
|
|
expect(chores).toHaveLength(2);
|
||
|
|
expect(chores.map((c) => c.text)).toContain('Water the plants');
|
||
|
|
expect(chores.map((c) => c.text)).toContain('Shared chore');
|
||
|
|
expect(chores.map((c) => c.text)).not.toContain('Make the bed');
|
||
|
|
expect(chores.map((c) => c.text)).not.toContain('Walk the dog');
|
||
|
|
expect(chores.map((c) => c.text)).not.toContain('Inactive chore');
|
||
|
|
|
||
|
|
});
|
||
|
|
|
||
|
|
test('throws on auth failure', async () => {
|
||
|
|
await expect(
|
||
|
|
fetchDonetickChores({ url: baseUrl, token: 'wrong', user_id: 1 })
|
||
|
|
).rejects.toThrow('401');
|
||
|
|
});
|
||
|
|
});
|