-- pgTAP: public.sync_conflicts table + RLS (migration 016)
-- Run with: psql -U postgres -d postgres -f supabase/tests/010_sync_conflicts.sql
--
-- Fase 9.3 — append-only audit log of offline-sync last-write-wins
-- conflicts. The tests cover:
--  * structure (table exists, RLS enabled, expected columns)
--  * RLS reads scoped to auth.uid()
--  * RLS inserts only allowed when row.user_id = auth.uid()
--  * UPDATE and DELETE blocked across the board (no policy = denied)

CREATE EXTENSION IF NOT EXISTS pgtap;

BEGIN;
SELECT plan(12);

-- ── Structure ───────────────────────────────────────────────────────────
SELECT has_table(
    'public', 'sync_conflicts',
    'public.sync_conflicts exists'
);

SELECT ok(
    (SELECT relrowsecurity FROM pg_class WHERE oid = 'public.sync_conflicts'::regclass),
    'sync_conflicts has RLS enabled'
);

SELECT col_not_null(
    'public', 'sync_conflicts', 'user_id',
    'sync_conflicts.user_id is NOT NULL'
);

SELECT col_is_null(
    'public', 'sync_conflicts', 'collective_id',
    'sync_conflicts.collective_id is nullable (some conflicts have no collective scope)'
);

-- ── Seed two distinct conflicts (one for Ana, one for Borja) as admin ──
-- IDs map to seed.sql.
DO $$
BEGIN
    INSERT INTO public.sync_conflicts (user_id, collective_id, entity_type, entity_id, local_version, remote_version, resolution)
    VALUES
        ('11111111-1111-1111-1111-111111111111', NULL, 'shopping_item', gen_random_uuid(), '{"name":"ana-local"}'::jsonb, '{"name":"ana-remote"}'::jsonb, 'remote_won'),
        ('22222222-2222-2222-2222-222222222222', NULL, 'shopping_item', gen_random_uuid(), '{"name":"borja-local"}'::jsonb, '{"name":"borja-remote"}'::jsonb, 'remote_won');
END $$;

-- ── RLS: Ana sees only her own row ──────────────────────────────────────
SET LOCAL ROLE authenticated;
SET LOCAL request.jwt.claims TO '{"sub":"11111111-1111-1111-1111-111111111111","role":"authenticated"}';

SELECT is(
    (SELECT count(*)::int FROM public.sync_conflicts),
    1,
    'Ana can read only the one row she owns'
);

SELECT is(
    (SELECT user_id FROM public.sync_conflicts LIMIT 1),
    '11111111-1111-1111-1111-111111111111'::uuid,
    'Visible row belongs to Ana'
);

-- ── RLS: Ana can INSERT her own row ─────────────────────────────────────
INSERT INTO public.sync_conflicts (user_id, entity_type, entity_id, local_version, remote_version, resolution)
VALUES ('11111111-1111-1111-1111-111111111111', 'shopping_item', gen_random_uuid(), '{"a":1}'::jsonb, '{"a":2}'::jsonb, 'remote_won');
SELECT is(
    (SELECT count(*)::int FROM public.sync_conflicts),
    2,
    'Ana can insert a row attributed to herself'
);

-- ── RLS: Ana cannot INSERT a row owned by Borja ─────────────────────────
SELECT throws_ok(
    $$INSERT INTO public.sync_conflicts (user_id, entity_type, entity_id, local_version, remote_version, resolution)
      VALUES ('22222222-2222-2222-2222-222222222222', 'shopping_item', gen_random_uuid(), '{}'::jsonb, '{}'::jsonb, 'remote_won')$$,
    '42501',
    NULL,
    'Ana cannot insert a row attributed to Borja'
);

-- ── RLS: UPDATE is denied (no policy) ───────────────────────────────────
-- An UPDATE with no matching policy returns 0 rows updated (silently),
-- not a privilege error. Assert nothing was modified.
WITH bumped AS (
    UPDATE public.sync_conflicts SET resolution = 'local_won' WHERE user_id = '11111111-1111-1111-1111-111111111111' RETURNING 1
)
SELECT is(
    (SELECT count(*)::int FROM bumped),
    0,
    'UPDATE on sync_conflicts is denied (no policy)'
);

-- ── RLS: DELETE is denied (no policy) ───────────────────────────────────
WITH gone AS (
    DELETE FROM public.sync_conflicts WHERE user_id = '11111111-1111-1111-1111-111111111111' RETURNING 1
)
SELECT is(
    (SELECT count(*)::int FROM gone),
    0,
    'DELETE on sync_conflicts is denied (no policy)'
);

-- ── RLS: Borja cannot see Ana's rows ────────────────────────────────────
SET LOCAL request.jwt.claims TO '{"sub":"22222222-2222-2222-2222-222222222222","role":"authenticated"}';
SELECT is(
    (SELECT count(*)::int FROM public.sync_conflicts WHERE user_id = '11111111-1111-1111-1111-111111111111'),
    0,
    'Borja cannot see Ana''s sync_conflicts rows'
);

-- ── RLS: select_own — Borja sees their own seeded row only ──────────────
SELECT is(
    (SELECT count(*)::int FROM public.sync_conflicts),
    1,
    'Borja sees only the row attributed to them'
);

SELECT * FROM finish();
ROLLBACK;
