151 lines
4.9 KiB
MySQL
151 lines
4.9 KiB
MySQL
|
|
BEGIN;
|
||
|
|
SELECT plan(6);
|
||
|
|
|
||
|
|
DO $$
|
||
|
|
DECLARE
|
||
|
|
owner_id uuid := gen_random_uuid();
|
||
|
|
member_id uuid := gen_random_uuid();
|
||
|
|
tablo_id text;
|
||
|
|
parent_task_id text;
|
||
|
|
BEGIN
|
||
|
|
-- Insert auth users
|
||
|
|
INSERT INTO auth.users (id, instance_id, aud, role, email, encrypted_password, email_confirmed_at, created_at, updated_at)
|
||
|
|
VALUES
|
||
|
|
(owner_id, '00000000-0000-0000-0000-000000000000', 'authenticated', 'authenticated', 'etape_owner_' || owner_id::text || '@test.com', 'encrypted', now(), now(), now()),
|
||
|
|
(member_id, '00000000-0000-0000-0000-000000000000', 'authenticated', 'authenticated', 'etape_member_' || member_id::text || '@test.com', 'encrypted', now(), now(), now())
|
||
|
|
ON CONFLICT DO NOTHING;
|
||
|
|
|
||
|
|
-- Insert public profiles
|
||
|
|
INSERT INTO public.profiles (id, email, first_name, last_name, short_user_id)
|
||
|
|
VALUES
|
||
|
|
(owner_id, 'etape_owner_' || owner_id::text || '@test.com', 'Etape', 'Owner', substring(owner_id::text from 1 for 8)),
|
||
|
|
(member_id, 'etape_member_' || member_id::text || '@test.com', 'Etape', 'Member', substring(member_id::text from 1 for 8))
|
||
|
|
ON CONFLICT DO NOTHING;
|
||
|
|
|
||
|
|
-- Create tablo as owner
|
||
|
|
PERFORM set_config('request.jwt.claims', json_build_object('sub', owner_id::text)::text, true);
|
||
|
|
INSERT INTO public.tablos (owner_id, name, status, position)
|
||
|
|
VALUES (owner_id, 'Parent Tasks Test Tablo', 'todo', 0)
|
||
|
|
RETURNING id INTO tablo_id;
|
||
|
|
|
||
|
|
-- Grant access to member
|
||
|
|
INSERT INTO public.tablo_access (tablo_id, user_id, granted_by, is_active, is_admin)
|
||
|
|
VALUES (tablo_id, member_id, owner_id, true, false);
|
||
|
|
|
||
|
|
-- Create an Etape as owner
|
||
|
|
INSERT INTO public.tasks (tablo_id, title, description, status, position, is_parent)
|
||
|
|
VALUES (tablo_id, 'Initial Étape', 'Owner created etape', 'todo', 0, true)
|
||
|
|
RETURNING id INTO parent_task_id;
|
||
|
|
|
||
|
|
-- Persist identifiers for tests
|
||
|
|
PERFORM set_config('test.owner_id', owner_id::text, true);
|
||
|
|
PERFORM set_config('test.member_id', member_id::text, true);
|
||
|
|
PERFORM set_config('test.tablo_id', tablo_id, true);
|
||
|
|
PERFORM set_config('test.parent_task_id', parent_task_id, true);
|
||
|
|
END $$;
|
||
|
|
|
||
|
|
SELECT is(
|
||
|
|
(SELECT is_parent FROM public.tasks WHERE id = current_setting('test.parent_task_id')),
|
||
|
|
true,
|
||
|
|
'Owner-created task is flagged as an Etape'
|
||
|
|
);
|
||
|
|
|
||
|
|
SELECT is(
|
||
|
|
(SELECT parent_task_id FROM public.tasks WHERE id = current_setting('test.parent_task_id')),
|
||
|
|
NULL,
|
||
|
|
'Etape cannot reference another parent task'
|
||
|
|
);
|
||
|
|
|
||
|
|
DO $$
|
||
|
|
BEGIN
|
||
|
|
PERFORM set_config('request.jwt.claims', json_build_object('sub', current_setting('test.owner_id'))::text, true);
|
||
|
|
UPDATE public.tasks
|
||
|
|
SET title = 'Renamed Étape'
|
||
|
|
WHERE id = current_setting('test.parent_task_id');
|
||
|
|
END $$;
|
||
|
|
|
||
|
|
SELECT is(
|
||
|
|
(SELECT title FROM public.tasks WHERE id = current_setting('test.parent_task_id')),
|
||
|
|
'Renamed Étape',
|
||
|
|
'Tablo owner can update an Etape'
|
||
|
|
);
|
||
|
|
|
||
|
|
DO $$
|
||
|
|
DECLARE
|
||
|
|
failed boolean := false;
|
||
|
|
BEGIN
|
||
|
|
PERFORM set_config('request.jwt.claims', json_build_object('sub', current_setting('test.member_id'))::text, true);
|
||
|
|
BEGIN
|
||
|
|
INSERT INTO public.tasks (tablo_id, title, status, position, is_parent)
|
||
|
|
VALUES (current_setting('test.tablo_id'), 'Member Étape Attempt', 'todo', 1, true);
|
||
|
|
EXCEPTION
|
||
|
|
WHEN insufficient_privilege THEN
|
||
|
|
failed := true;
|
||
|
|
WHEN others THEN
|
||
|
|
RAISE;
|
||
|
|
END;
|
||
|
|
PERFORM set_config('test.member_etape_insert_blocked', failed::text, true);
|
||
|
|
END $$;
|
||
|
|
|
||
|
|
SELECT is(
|
||
|
|
current_setting('test.member_etape_insert_blocked', true)::boolean,
|
||
|
|
true,
|
||
|
|
'Non-owner cannot create an Etape'
|
||
|
|
);
|
||
|
|
|
||
|
|
DO $$
|
||
|
|
DECLARE
|
||
|
|
failed boolean := false;
|
||
|
|
BEGIN
|
||
|
|
PERFORM set_config('request.jwt.claims', json_build_object('sub', current_setting('test.member_id'))::text, true);
|
||
|
|
BEGIN
|
||
|
|
UPDATE public.tasks
|
||
|
|
SET title = 'Member Update Attempt'
|
||
|
|
WHERE id = current_setting('test.parent_task_id');
|
||
|
|
EXCEPTION
|
||
|
|
WHEN insufficient_privilege THEN
|
||
|
|
failed := true;
|
||
|
|
WHEN others THEN
|
||
|
|
RAISE;
|
||
|
|
END;
|
||
|
|
PERFORM set_config('test.member_etape_update_blocked', failed::text, true);
|
||
|
|
END $$;
|
||
|
|
|
||
|
|
SELECT is(
|
||
|
|
current_setting('test.member_etape_update_blocked', true)::boolean,
|
||
|
|
true,
|
||
|
|
'Non-owner cannot update an Etape'
|
||
|
|
);
|
||
|
|
|
||
|
|
DO $$
|
||
|
|
DECLARE
|
||
|
|
child_task_id text;
|
||
|
|
BEGIN
|
||
|
|
PERFORM set_config('request.jwt.claims', json_build_object('sub', current_setting('test.member_id'))::text, true);
|
||
|
|
INSERT INTO public.tasks (tablo_id, title, status, position, is_parent, parent_task_id)
|
||
|
|
VALUES (
|
||
|
|
current_setting('test.tablo_id'),
|
||
|
|
'Child Task',
|
||
|
|
'todo',
|
||
|
|
2,
|
||
|
|
false,
|
||
|
|
current_setting('test.parent_task_id')
|
||
|
|
)
|
||
|
|
RETURNING id INTO child_task_id;
|
||
|
|
|
||
|
|
PERFORM set_config('test.child_task_id', child_task_id, true);
|
||
|
|
END $$;
|
||
|
|
|
||
|
|
SELECT ok(
|
||
|
|
(
|
||
|
|
SELECT EXISTS (
|
||
|
|
SELECT 1 FROM public.tasks WHERE id = current_setting('test.child_task_id')
|
||
|
|
)
|
||
|
|
),
|
||
|
|
'Members can still create regular tasks assigned to an Etape'
|
||
|
|
);
|
||
|
|
|
||
|
|
SELECT * FROM finish();
|
||
|
|
ROLLBACK;
|
||
|
|
|