-- =====================================================================
--  TeeCup — isolasjonstest (oppførsel, ikke bare skjema)
-- =====================================================================
--  Beviser at RLS faktisk hindrer én organisasjon i å se en annens data,
--  sett fra runtime-rollen teecup_app (som IKKE er superuser/BYPASSRLS).
--
--  Kjør som admin/superbruker mot en scratch- eller test-database der
--  001_initial_schema.sql og 002_roles_and_grants.sql allerede er kjørt:
--    psql -d teecup_scratch -f test_isolation.sql
--
--  Alt kjøres i én transaksjon som RULLES TILBAKE til slutt — ingen testdata
--  blir liggende igjen. Skriptet stopper med feil hvis isolasjonen svikter.
-- =====================================================================

\set ON_ERROR_STOP on

BEGIN;

-- --- Seed to organisasjoner + én turnering hver (som privilegert rolle) ---
-- (Superbruker omgår RLS, så innsettingen går uhindret her — det er meningen.)
INSERT INTO organization (id, name) VALUES
    ('aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa', 'Org A'),
    ('bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb', 'Org B');

INSERT INTO tournament (organization_id, name) VALUES
    ('aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa', 'A-Cup'),
    ('bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb', 'B-Cup');

-- --- Bytt til runtime-rollen: nå SKAL RLS gjelde ---------------------
SET ROLE teecup_app;
SELECT set_config('app.current_org', 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa', false);

-- Test 1: Ser bare Org A sine turneringer (1, ikke 2).
DO $$
DECLARE n int;
BEGIN
    SELECT count(*) INTO n FROM tournament;
    IF n <> 1 THEN
        RAISE EXCEPTION 'ISOLASJON FEILET (lesing): ser % turneringer, forventet 1', n;
    END IF;
    RAISE NOTICE 'OK  Test 1: ser kun egen organisasjons turneringer (%).', n;
END $$;

-- Test 2: Ser bare sin egen organisasjonsrad.
DO $$
DECLARE n int;
BEGIN
    SELECT count(*) INTO n FROM organization;
    IF n <> 1 THEN
        RAISE EXCEPTION 'ISOLASJON FEILET (organization): ser % rader, forventet 1', n;
    END IF;
    RAISE NOTICE 'OK  Test 2: ser kun egen organisasjonsrad (%).', n;
END $$;

-- Test 3: Kan IKKE sette inn data merket med en annen organisasjon.
--         WITH CHECK skal blokkere det (SQLSTATE 42501).
DO $$
BEGIN
    BEGIN
        INSERT INTO tournament (organization_id, name)
            VALUES ('bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb', 'kryss-org-forsøk');
        -- Kommer vi hit, ble det tillatt -> isolasjonen er brutt.
        RAISE EXCEPTION 'ISOLASJON FEILET (skriving): fikk sette inn data for annen org';
    EXCEPTION
        WHEN insufficient_privilege THEN
            RAISE NOTICE 'OK  Test 3: WITH CHECK blokkerte kryss-org innsetting.';
    END;
END $$;

-- Test 4: Kontrollprøve — bytter kontekst til Org B og ser Bs turnering isteden.
SELECT set_config('app.current_org', 'bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb', false);
DO $$
DECLARE nm text;
BEGIN
    SELECT name INTO nm FROM tournament;
    IF nm <> 'B-Cup' THEN
        RAISE EXCEPTION 'ISOLASJON FEILET (kontekstbytte): forventet B-Cup, fikk %', nm;
    END IF;
    RAISE NOTICE 'OK  Test 4: kontekstbytte gir riktig organisasjons data (%).', nm;
END $$;

RESET ROLE;
RESET app.current_org;

ROLLBACK;   -- ingen testdata blir liggende igjen

\echo '============================================'
\echo ' Alle isolasjonstester bestått (se OK-linjer)'
\echo '============================================'
