source: Klonkt/test/site-permissions.test.js@ 7e9d0ea

main
Last change on this file since 7e9d0ea was 7e9d0ea, checked in by Robin <roboburr@…>, 4 weeks ago

De laatste tenancy-resten, en een testbestand dat alleen zijn naam kwijt was (shaer-x7c0)

Het meeste van de bead was al gedaan door 72ec6a4 (Hub-modus en guardian-lite
eruit), dezelfde dag nog. Wat er lag:

  • database.js beschreef nog een tenancy-modus met hub, en zette bij elke boot een app_settings-rij 'tenancy' die niemand meer leest. Beide weg. Bestaande rijen blijven staan; die opruimen is een aparte beslissing.
  • ensurePrimarySite.js noemde solo/hub/circle op twee plekken.

En het belangrijkste, precies wat de bead verkeerd had: hub-permissions.test.js
test GEEN verwijderde modus. Het dekt canAdminSite (inclusief de site_members-tak
die ooit stil kapot was), canEditPost en getPrimarySite -- allemaal springlevend,
en CLAUDE.md wijst dit bestand aan als de vangrail daarvoor. Weggooien had die
dekking gesloopt. Alleen de naam verwees nog naar de hub, dus die is aangepast,
met een kop die uitlegt waarom het bestand blijft.

  • Property mode set to 100644
File size: 4.7 KB
Line 
1// Unit-tests voor de site-permissielaag — juist `canAdminSite` was lang stil kapot
2// (las een nooit-gevulde user.siteRoles), dus dit dekt 'm nu af. Draait op de
3// ingebouwde node:test (geen extra deps). In-memory SQLite → raakt geen echte data.
4//
5// Heette hub-permissions.test.js: de hub-modus is weg (72ec6a4), maar wat hier
6// getest wordt niet. canAdminSite, canEditPost en getPrimarySite zijn springlevend
7// en dit bestand is hun enige dekking — alleen de naam verwees nog naar de modus.
8//
9// Run: npm test (= node --test)
10
11import { test } from 'node:test';
12import assert from 'node:assert/strict';
13
14// Isoleer van de echte DB: ':memory:' MOET gezet zijn vóór de eerste import van
15// config/database.js (die maakt de singleton-connectie op basis van deze env).
16process.env.DATABASE_PATH = ':memory:';
17
18const dbMod = await import('../src/config/database.js');
19const db = dbMod.default;
20const PermissionsService = (await import('../src/services/PermissionsService.js')).default;
21const { getPrimarySite } = await import('../src/middleware/site.js');
22
23dbMod.initializeDatabase();
24
25// ── Seed ────────────────────────────────────────────────────────────────
26function addUser(id, role) {
27 db.prepare('INSERT INTO users (id, username, email, password_hash, role) VALUES (?,?,?,?,?)')
28 .run(id, id, id + '@test', 'x', role);
29}
30function addSite(id, slug, ownerId, isPrimary = 0) {
31 db.prepare('INSERT INTO sites (id, slug, title, owner_id, is_primary) VALUES (?,?,?,?,?)')
32 .run(id, slug, slug, ownerId, isPrimary);
33}
34addUser('u-god', 'god');
35addUser('u-owner', 'member');
36addUser('u-collab', 'member');
37addUser('u-stranger', 'member');
38addSite('s1', 'site-een', 'u-owner', 1);
39
40const god = { id: 'u-god', role: 'god' };
41const owner = { id: 'u-owner', role: 'member' };
42const collab = { id: 'u-collab', role: 'member' };
43const stranger = { id: 'u-stranger', role: 'member' };
44const site = () => db.prepare('SELECT * FROM sites WHERE id = ?').get('s1');
45
46// ── canAdminSite ─────────────────────────────────────────────────────────
47test('canAdminSite: god mag altijd', () => {
48 assert.equal(PermissionsService.canAdminSite(god, site()), true);
49});
50test('canAdminSite: owner mag', () => {
51 assert.equal(PermissionsService.canAdminSite(owner, site()), true);
52});
53test('canAdminSite: vreemde zonder membership mag niet', () => {
54 assert.equal(PermissionsService.canAdminSite(stranger, site()), false);
55});
56test('canAdminSite: collaborator zonder membership mag niet', () => {
57 assert.equal(PermissionsService.canAdminSite(collab, site()), false);
58});
59test('canAdminSite: collaborator MET site_members-admin mag (de gefixte dode code)', () => {
60 db.prepare("INSERT OR REPLACE INTO site_members (site_id, user_id, role) VALUES ('s1','u-collab','admin')").run();
61 assert.equal(PermissionsService.canAdminSite(collab, site()), true);
62});
63test('canAdminSite: site_members met rol "member" (geen admin) mag niet', () => {
64 db.prepare("INSERT OR REPLACE INTO site_members (site_id, user_id, role) VALUES ('s1','u-stranger','member')").run();
65 assert.equal(PermissionsService.canAdminSite(stranger, site()), false);
66});
67test('canAdminSite: null user of null site → false (geen crash)', () => {
68 assert.equal(PermissionsService.canAdminSite(null, site()), false);
69 assert.equal(PermissionsService.canAdminSite(owner, null), false);
70});
71
72// ── Delegatie: canEditPost via canAdminSite ──────────────────────────────
73test('canEditPost: collaborator-admin kan een post van een ander bewerken (via canAdminSite)', () => {
74 const post = { author_id: 'iemand-anders' };
75 assert.equal(PermissionsService.canEditPost(collab, post, site()), true);
76});
77test('canEditPost: vreemde kan een post van een ander NIET bewerken', () => {
78 const post = { author_id: 'iemand-anders' };
79 assert.equal(PermissionsService.canEditPost(stranger, post, site()), false);
80});
81
82// ── getPrimarySite (#3) ──────────────────────────────────────────────────
83test('getPrimarySite: geeft de is_primary-site', () => {
84 assert.equal(getPrimarySite().id, 's1');
85});
86test('getPrimarySite: valt terug op de oudste als geen is_primary gemarkeerd is', () => {
87 db.prepare('UPDATE sites SET is_primary = 0').run();
88 assert.equal(getPrimarySite().id, 's1'); // s1 is de oudste/enige
89 db.prepare("UPDATE sites SET is_primary = 1 WHERE id = 's1'").run(); // herstel
90});
Note: See TracBrowser for help on using the repository browser.