Files
collective-lists/supabase/tests/002_item_frequency_trigger.sql
Oier Bravo Urtasun d6cea5146f feat(fase-5.10.0): drop shopping_items.unit column
The unit field had no edit path under the redesign (only name + qty
remain in the row; the double-tap overlay is name-only). Users can encode
the unit inside the name when it matters — e.g. "Milk 1L", "Eggs 1 doz".

Changes
  supabase/migrations/011_drop_shopping_items_unit.sql — DROP COLUMN
  supabase/seed.sql — unit values folded into names where relevant
  supabase/tests/002_item_frequency_trigger.sql — remove unit from INSERT
  packages/types — remove unit from ShoppingItem Row/Insert/Update
  apps/web/src/lib/stores/lists.ts — addItem/updateItem signatures
  apps/web/src/routes/(app)/lists/[id]/+page.svelte — purge newUnit /
    editUnit state + inputs + display
  apps/web/src/routes/(app)/lists/[id]/session/+page.svelte — simplify
    quantity-only render
  apps/web/messages/{en,es}.json — remove list_unit_label

Verification
  just test-db  → 34 pgTAP green
  just test-integration → 140 + 2 skipped
  just test-unit → 11 green
  just test-e2e → 39 + 2 skipped

The generated search tsvector on shopping_items.search already indexes
only `name`, so full-text search coverage is unchanged.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 19:00:08 +02:00

83 lines
2.9 KiB
PL/PgSQL

-- pgTAP: fn_record_item_frequency trigger — D/E-series
-- Verifies the SECURITY DEFINER trigger populates item_frequency correctly.
-- Run with: psql -U postgres -d postgres -f supabase/tests/002_item_frequency_trigger.sql
CREATE EXTENSION IF NOT EXISTS pgtap;
-- Note: tests E-02/E-03/E-04 (RLS rejection of direct writes) are covered by
-- the Vitest integration suite (packages/test-utils/tests/rls-frequency.test.ts)
-- which connects as an authenticated role. The postgres superuser bypasses RLS
-- entirely, so pgTAP cannot assert those policies here.
BEGIN;
SELECT plan(3);
-- Setup: temporary list for item insertion
INSERT INTO public.shopping_lists (id, collective_id, name, status, created_by)
VALUES (
'cccccccc-cccc-cccc-cccc-cccccccccccc',
'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa',
'Trigger test list',
'active',
'11111111-1111-1111-1111-111111111111'
) ON CONFLICT (id) DO NOTHING;
-- D-13: Inserting an item creates a new frequency row (normalized name)
INSERT INTO public.shopping_items (list_id, name, quantity, sort_order, created_by)
VALUES ('cccccccc-cccc-cccc-cccc-cccccccccccc', ' Butter ', 1, 50, '11111111-1111-1111-1111-111111111111');
SELECT ok(
EXISTS (
SELECT 1 FROM public.item_frequency
WHERE collective_id = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa'
AND name = 'butter'
),
'D-13: trigger normalises name (lower+trim) and inserts into item_frequency'
);
-- D-14: Inserting the same item again increments use_count
DO $$
DECLARE v_count_before integer;
BEGIN
SELECT use_count INTO v_count_before
FROM public.item_frequency
WHERE collective_id = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa'
AND name = 'butter';
INSERT INTO public.shopping_items (list_id, name, sort_order, created_by)
VALUES ('cccccccc-cccc-cccc-cccc-cccccccccccc', 'Butter', 51, '11111111-1111-1111-1111-111111111111');
END $$;
SELECT ok(
(SELECT use_count FROM public.item_frequency
WHERE collective_id = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa'
AND name = 'butter') >= 2,
'D-14: use_count increments on repeated INSERT'
);
-- D-15: Trigger does not fire on UPDATE (only on INSERT)
-- (PostgreSQL does not allow LIMIT on UPDATE — use a ctid subquery instead.)
DO $$
BEGIN
UPDATE public.shopping_items
SET name = 'Butter'
WHERE ctid = (
SELECT ctid FROM public.shopping_items
WHERE list_id = 'cccccccc-cccc-cccc-cccc-cccccccccccc'
AND name = 'Butter'
LIMIT 1
);
END $$;
-- We can't easily compare before/after in a single statement in pgTAP without
-- a custom helper. Instead just verify the count is still reasonable (> 0).
SELECT ok(
(SELECT use_count FROM public.item_frequency
WHERE collective_id = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa'
AND name = 'butter') > 0,
'D-15: item_frequency still intact after item UPDATE'
);
SELECT * FROM finish();
ROLLBACK;