worldwide todo list: public todo list of 68 real, sourced problems (planet to street) at /projects/worldwide-todo. worldtodo schema (categories, tasks, change_requests), idempotent seed on deploy, public add/edit/delete requests with Turnstile + salted daily-rotating IP-hash rate limit, owner-only review queue (approve, edit & approve, reject) with live updates over /ws/worldtodo(-owner), JSON API, detail pages with OSM map and history; listed in projects, header, /start and sitemap
Some checks failed
Deploy production / deploy (push) Failing after 9s
Some checks failed
Deploy production / deploy (push) Failing after 9s
This commit is contained in:
83
src/lib/worldtodo/shared.test.ts
Normal file
83
src/lib/worldtodo/shared.test.ts
Normal file
@@ -0,0 +1,83 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import {
|
||||
WORLDTODO_REQUEST_KINDS,
|
||||
WORLDTODO_REQUEST_STATUSES,
|
||||
WORLDTODO_SCALES,
|
||||
WORLDTODO_STATUSES,
|
||||
changedFields,
|
||||
matchesFilters,
|
||||
type PublicTask,
|
||||
type TaskFields
|
||||
} from './shared';
|
||||
import {
|
||||
worldtodoRequestKind,
|
||||
worldtodoRequestStatus,
|
||||
worldtodoScale,
|
||||
worldtodoStatus
|
||||
} from '#lib/server/db/schema/worldtodo.js';
|
||||
import seed from '../../../data/worldtodo-seed.json';
|
||||
|
||||
const base: TaskFields = {
|
||||
title: 'Repair the bridge',
|
||||
description: 'The bridge is broken and needs fixing.',
|
||||
scale: 'city',
|
||||
category: 'infrastructure',
|
||||
location_name: 'Gouda',
|
||||
country_code: 'NL',
|
||||
lat: 52,
|
||||
lon: 4.7,
|
||||
status: 'open',
|
||||
source_urls: ['https://example.org/a']
|
||||
};
|
||||
|
||||
describe('worldtodo shared', () => {
|
||||
it('keeps the schema enums in sync with the shared constants', () => {
|
||||
expect(worldtodoScale.enumValues).toEqual([...WORLDTODO_SCALES]);
|
||||
expect(worldtodoStatus.enumValues).toEqual([...WORLDTODO_STATUSES]);
|
||||
expect(worldtodoRequestKind.enumValues).toEqual([...WORLDTODO_REQUEST_KINDS]);
|
||||
expect(worldtodoRequestStatus.enumValues).toEqual([...WORLDTODO_REQUEST_STATUSES]);
|
||||
});
|
||||
|
||||
it('returns only the changed fields', () => {
|
||||
expect(changedFields(base, { ...base })).toEqual({});
|
||||
expect(changedFields(base, { ...base, status: 'done', lat: 52 })).toEqual({ status: 'done' });
|
||||
expect(
|
||||
changedFields(base, { ...base, source_urls: ['https://example.org/a', 'https://b.org'] })
|
||||
).toEqual({ source_urls: ['https://example.org/a', 'https://b.org'] });
|
||||
expect(changedFields(base, { country_code: null })).toEqual({ country_code: null });
|
||||
});
|
||||
|
||||
it('matches list filters like the server', () => {
|
||||
const t = {
|
||||
slug: 'x',
|
||||
title: 'Repair the bridge',
|
||||
description: 'd',
|
||||
locationName: 'Gouda',
|
||||
scale: 'city',
|
||||
category: 'infrastructure',
|
||||
status: 'done'
|
||||
} as PublicTask;
|
||||
const f = { scale: '', category: '', status: 'todo', q: '' };
|
||||
expect(matchesFilters(t, f)).toBe(false);
|
||||
expect(matchesFilters(t, { ...f, status: 'all' })).toBe(true);
|
||||
expect(matchesFilters(t, { ...f, status: 'done', q: 'gouda bridge' })).toBe(true);
|
||||
expect(matchesFilters(t, { ...f, status: 'all', scale: 'planet' })).toBe(false);
|
||||
});
|
||||
|
||||
it('ships the full, sourced seed (68 tasks with the expected spread)', () => {
|
||||
const tasks = seed.tasks;
|
||||
expect(tasks).toHaveLength(68);
|
||||
expect(new Set(tasks.map((t) => t.slug)).size).toBe(68);
|
||||
const by = (k: 'scale' | 'status') =>
|
||||
tasks.reduce<Record<string, number>>((a, t) => ((a[t[k]] = (a[t[k]] ?? 0) + 1), a), {});
|
||||
expect(by('scale')).toEqual({ planet: 13, region: 12, country: 12, city: 12, street: 19 });
|
||||
expect(by('status')).toEqual({ open: 58, in_progress: 10 });
|
||||
for (const t of tasks) {
|
||||
expect(t.source_urls.length).toBeGreaterThan(0);
|
||||
expect(seed.categories).toContain(t.category);
|
||||
expect(['request', 'requests', 'queue', 'api']).not.toContain(t.slug);
|
||||
expect(t.title.length).toBeGreaterThanOrEqual(5);
|
||||
expect(t.title.length).toBeLessThanOrEqual(140);
|
||||
}
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user