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

This commit is contained in:
2026-10-26 01:25:59 +00:00
parent 0ee981a96b
commit 5e812271e1
58 changed files with 47689 additions and 9 deletions

View 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);
}
});
});