212 lines
6.8 KiB
PL/PgSQL
212 lines
6.8 KiB
PL/PgSQL
begin;
|
|
|
|
create extension "basejump-supabase_test_helpers" version '0.0.6';
|
|
|
|
select no_plan();
|
|
|
|
-- =====================================================
|
|
-- Member Management Function Tests
|
|
-- Tests PG functions for correctness, auth, atomicity
|
|
-- =====================================================
|
|
|
|
-- Setup: create test users and account
|
|
select tests.create_supabase_user('owner', 'owner@test.com');
|
|
select tests.create_supabase_user('member_user', 'member@test.com');
|
|
select tests.create_supabase_user('outsider', 'outsider@test.com');
|
|
|
|
select makerkit.set_identifier('owner', 'owner@test.com');
|
|
select makerkit.set_identifier('member_user', 'member@test.com');
|
|
select makerkit.set_identifier('outsider', 'outsider@test.com');
|
|
|
|
-- Create a team account owned by 'owner'
|
|
set local role service_role;
|
|
select public.create_team_account('Test Verein', tests.get_supabase_uid('owner'));
|
|
|
|
-- Get account ID
|
|
select makerkit.authenticate_as('owner');
|
|
\set test_account_id '(select id from public.accounts where slug = ''test-verein'' limit 1)'
|
|
|
|
-- Grant members.write permission to owner
|
|
set local role postgres;
|
|
insert into public.role_permissions (role, permission)
|
|
values ('owner', 'members.write')
|
|
on conflict do nothing;
|
|
|
|
-- -------------------------------------------------------
|
|
-- Test: get_next_member_number
|
|
-- -------------------------------------------------------
|
|
select makerkit.authenticate_as('owner');
|
|
|
|
select is(
|
|
public.get_next_member_number(:test_account_id),
|
|
'0001',
|
|
'First member number should be 0001'
|
|
);
|
|
|
|
-- Insert a member to test incrementing
|
|
set local role service_role;
|
|
insert into public.members (account_id, first_name, last_name, member_number, status, entry_date, created_by, updated_by)
|
|
values (:test_account_id, 'Max', 'Mustermann', '0001', 'active', current_date,
|
|
tests.get_supabase_uid('owner'), tests.get_supabase_uid('owner'));
|
|
|
|
select makerkit.authenticate_as('owner');
|
|
|
|
select is(
|
|
public.get_next_member_number(:test_account_id),
|
|
'0002',
|
|
'Second member number should be 0002'
|
|
);
|
|
|
|
-- -------------------------------------------------------
|
|
-- Test: get_member_quick_stats
|
|
-- -------------------------------------------------------
|
|
select isnt_empty(
|
|
$$ select * from public.get_member_quick_stats((select id from public.accounts where slug = 'test-verein' limit 1)) $$,
|
|
'Quick stats returns data for account with members'
|
|
);
|
|
|
|
-- -------------------------------------------------------
|
|
-- Test: check_duplicate_member
|
|
-- -------------------------------------------------------
|
|
select isnt_empty(
|
|
$$ select * from public.check_duplicate_member(
|
|
(select id from public.accounts where slug = 'test-verein' limit 1),
|
|
'Max', 'Mustermann', null
|
|
) $$,
|
|
'Duplicate check finds existing member by name'
|
|
);
|
|
|
|
select is_empty(
|
|
$$ select * from public.check_duplicate_member(
|
|
(select id from public.accounts where slug = 'test-verein' limit 1),
|
|
'Nonexistent', 'Person', null
|
|
) $$,
|
|
'Duplicate check returns empty for non-matching name'
|
|
);
|
|
|
|
-- -------------------------------------------------------
|
|
-- Test: approve_application
|
|
-- -------------------------------------------------------
|
|
|
|
-- Create a test application
|
|
set local role service_role;
|
|
insert into public.membership_applications (
|
|
account_id, first_name, last_name, email, status
|
|
) values (
|
|
:test_account_id, 'Anna', 'Bewerberin', 'anna@test.com', 'submitted'
|
|
);
|
|
|
|
select makerkit.authenticate_as('owner');
|
|
|
|
-- Approve it
|
|
select lives_ok(
|
|
$$ select public.approve_application(
|
|
(select id from public.membership_applications where email = 'anna@test.com'),
|
|
tests.get_supabase_uid('owner')
|
|
) $$,
|
|
'Owner can approve application'
|
|
);
|
|
|
|
-- Verify member was created
|
|
select isnt_empty(
|
|
$$ select * from public.members where first_name = 'Anna' and last_name = 'Bewerberin' $$,
|
|
'Approved application creates a member'
|
|
);
|
|
|
|
-- Verify application status changed
|
|
select is(
|
|
(select status from public.membership_applications where email = 'anna@test.com'),
|
|
'approved'::public.application_status,
|
|
'Application status is approved'
|
|
);
|
|
|
|
-- -------------------------------------------------------
|
|
-- Test: reject_application
|
|
-- -------------------------------------------------------
|
|
set local role service_role;
|
|
insert into public.membership_applications (
|
|
account_id, first_name, last_name, email, status
|
|
) values (
|
|
:test_account_id, 'Bob', 'Abgelehnt', 'bob@test.com', 'submitted'
|
|
);
|
|
|
|
select makerkit.authenticate_as('owner');
|
|
|
|
select lives_ok(
|
|
$$ select public.reject_application(
|
|
(select id from public.membership_applications where email = 'bob@test.com'),
|
|
tests.get_supabase_uid('owner'),
|
|
'Nicht qualifiziert'
|
|
) $$,
|
|
'Owner can reject application'
|
|
);
|
|
|
|
select is(
|
|
(select status from public.membership_applications where email = 'bob@test.com'),
|
|
'rejected'::public.application_status,
|
|
'Application status is rejected'
|
|
);
|
|
|
|
-- -------------------------------------------------------
|
|
-- Test: approve_application — already approved should fail
|
|
-- -------------------------------------------------------
|
|
-- Verify the re-approval throws with status message
|
|
prepare approve_again as select public.approve_application(
|
|
(select id from public.membership_applications where email = 'anna@test.com'),
|
|
tests.get_supabase_uid('owner')
|
|
);
|
|
select throws_ok(
|
|
'approve_again',
|
|
'P0001',
|
|
'Application is not in a reviewable state (current: approved)',
|
|
'Cannot approve already-approved application'
|
|
);
|
|
|
|
-- -------------------------------------------------------
|
|
-- Test: get_member_timeline
|
|
-- -------------------------------------------------------
|
|
-- The member creation via approve_application should have generated an audit entry
|
|
select isnt_empty(
|
|
$$ select * from public.get_member_timeline(
|
|
(select id from public.members where first_name = 'Anna' limit 1),
|
|
1, 50, null
|
|
) $$,
|
|
'Member timeline has entries after creation'
|
|
);
|
|
|
|
-- -------------------------------------------------------
|
|
-- Test: log_member_audit_event
|
|
-- -------------------------------------------------------
|
|
select makerkit.authenticate_as('owner');
|
|
|
|
select lives_ok(
|
|
$$ select public.log_member_audit_event(
|
|
(select id from public.members where first_name = 'Max' limit 1),
|
|
(select id from public.accounts where slug = 'test-verein' limit 1),
|
|
'note_added',
|
|
'{"note": "Test note"}'::jsonb,
|
|
'{}'::jsonb
|
|
) $$,
|
|
'Owner can log audit event for member'
|
|
);
|
|
|
|
-- -------------------------------------------------------
|
|
-- Test: outsider cannot access functions
|
|
-- -------------------------------------------------------
|
|
select makerkit.authenticate_as('outsider');
|
|
|
|
-- Outsider should get an error when calling get_next_member_number
|
|
prepare outsider_member_number as select public.get_next_member_number(
|
|
(select id from public.accounts where slug = 'test-verein' limit 1)
|
|
);
|
|
select throws_ok(
|
|
'outsider_member_number',
|
|
'P0001',
|
|
null,
|
|
'Outsider cannot call get_next_member_number'
|
|
);
|
|
|
|
select * from finish();
|
|
|
|
rollback;
|