zone1-data-integrity.test.ts43 lines · main
| 1 | import { readFileSync } from 'node:fs'; |
| 2 | import { fileURLToPath } from 'node:url'; |
| 3 | |
| 4 | import { describe, expect, test } from 'bun:test'; |
| 5 | |
| 6 | /** |
| 7 | * Zone-1 data-integrity regression guards. |
| 8 | * |
| 9 | * The two fixes below live inside raw `sql` templates that only execute |
| 10 | * against a live Postgres control plane (the full behaviour is covered by |
| 11 | * account-deletion.integration.test.ts, which gates on a real DB). These |
| 12 | * lightweight source guards lock in the exact predicates so a future edit |
| 13 | * can't silently reintroduce the original bugs without a DB to hand. |
| 14 | */ |
| 15 | |
| 16 | function readSrc(rel: string): string { |
| 17 | return readFileSync(fileURLToPath(new URL(rel, import.meta.url)), 'utf8'); |
| 18 | } |
| 19 | |
| 20 | describe('hardDeleteExpiredAccounts GC predicate', () => { |
| 21 | const src = readSrc('./account-deletion.ts'); |
| 22 | |
| 23 | test('selects orgs to purge via org_members owner role (mirrors isSoleOwner)', () => { |
| 24 | // The org purge must qualify orgs by OWNERSHIP, not organizations.created_by |
| 25 | // alone — created_by is nulled by the 0042/0044 FK SET NULL sweep, so a |
| 26 | // created_by-only predicate leaves zombie soft-deleted orgs that block the |
| 27 | // user DELETE forever (the original account-deletion incident). |
| 28 | expect(src).toContain('FROM org_members m'); |
| 29 | expect(src).toContain("m.role = 'owner'"); |
| 30 | expect(src).toContain('m.user_id IN ('); |
| 31 | }); |
| 32 | }); |
| 33 | |
| 34 | describe('admin abuse-report rollup', () => { |
| 35 | const src = readSrc('./admin.ts'); |
| 36 | |
| 37 | test("counts open + triaged reports, never the non-existent 'investigating' status", () => { |
| 38 | // abuseStatus enum is ['open','triaged','resolved'] — 'investigating' is not |
| 39 | // a member, so the old predicate silently under-counted the operator queue. |
| 40 | expect(src).toContain("status IN ('open', 'triaged')"); |
| 41 | expect(src).not.toContain('investigating'); |
| 42 | }); |
| 43 | }); |