-- pgTAP: auto-promote oldest member when sole admin leaves — B-13 (RN-10) -- Run with: psql -U postgres -d postgres -f supabase/tests/003_promote_on_admin_leave.sql -- -- The trigger fires on DELETE FROM public.users (user account deletion). -- We use a synthetic test user so we don't disturb seed data. The collective -- is created by Borja (created_by), so deleting the test admin user doesn't -- hit the ON DELETE RESTRICT on collectives.created_by. CREATE EXTENSION IF NOT EXISTS pgtap; BEGIN; SELECT plan(3); -- ── Setup ───────────────────────────────────────────────────────────────────── -- Use UUIDs outside the seed range (e9...) to avoid collisions. INSERT INTO public.users (id, email, display_name, language, avatar_type) VALUES ('e9999999-9999-9999-9999-999999999999', 'promote-test@local', 'Promote Admin', 'es', 'initials') ON CONFLICT (id) DO NOTHING; -- Collective owned (created_by) by Borja so the admin-user delete won't be -- blocked by ON DELETE RESTRICT on collectives.created_by. INSERT INTO public.collectives (id, name, emoji, created_by) VALUES ('dddddddd-dddd-dddd-dddd-dddddddddddd', 'Promote test collective', '🔄', '22222222-2222-2222-2222-222222222222') ON CONFLICT (id) DO NOTHING; -- Two members: synthetic admin (to be deleted) and Ana as the oldest member. INSERT INTO public.collective_members (collective_id, user_id, role, joined_at) VALUES ('dddddddd-dddd-dddd-dddd-dddddddddddd', 'e9999999-9999-9999-9999-999999999999', 'admin', now() - INTERVAL '10 days'), ('dddddddd-dddd-dddd-dddd-dddddddddddd', '11111111-1111-1111-1111-111111111111', 'member', now() - INTERVAL '5 days') ON CONFLICT (collective_id, user_id) DO NOTHING; -- B-13a: Initial state — one admin SELECT is( (SELECT COUNT(*)::integer FROM public.collective_members WHERE collective_id = 'dddddddd-dddd-dddd-dddd-dddddddddddd' AND role = 'admin'), 1, 'B-13a: initially one admin in the test collective' ); -- ── Fire the trigger: delete the sole admin user ────────────────────────────── -- Trigger `promote_on_admin_leave` fires BEFORE DELETE on public.users and -- promotes the oldest remaining member (Ana) before the delete cascade removes -- the admin's collective_members row. DELETE FROM public.users WHERE id = 'e9999999-9999-9999-9999-999999999999'; -- B-13b: Ana (oldest remaining) must now be admin SELECT results_eq( $$ SELECT role::text FROM public.collective_members WHERE collective_id = 'dddddddd-dddd-dddd-dddd-dddddddddddd' AND user_id = '11111111-1111-1111-1111-111111111111' $$, $$ VALUES ('admin') $$, 'B-13b: oldest member auto-promoted to admin when sole admin leaves' ); -- B-13c: Exactly one admin after promotion SELECT is( (SELECT COUNT(*)::integer FROM public.collective_members WHERE collective_id = 'dddddddd-dddd-dddd-dddd-dddddddddddd' AND role = 'admin'), 1, 'B-13c: exactly one admin after promotion' ); SELECT * FROM finish(); ROLLBACK;