d3ro-voice/server/supabase/tests/payple-checkout-active-subscription.integration.sql

146 lines
5.2 KiB
PL/PgSQL

\set ON_ERROR_STOP on
-- Regression: a second Payple checkout (stale tab, direct API call) must not
-- charge an active Payple subscriber again and restart the paid period.
-- Covers reserve_payment_provider_operation from
-- 20260928200000_payple_checkout_active_subscription_guard.sql.
BEGIN;
CREATE OR REPLACE FUNCTION pg_temp.assert_true(condition boolean, message text)
RETURNS void
LANGUAGE plpgsql
AS $$
BEGIN
IF condition IS NOT TRUE THEN
RAISE EXCEPTION 'assertion_failed: %', message;
END IF;
END;
$$;
INSERT INTO auth.users (
id, aud, role, email, encrypted_password, email_confirmed_at,
raw_app_meta_data, raw_user_meta_data, created_at, updated_at
) VALUES (
'20000000-0000-4000-8000-000000000020', 'authenticated', 'authenticated',
'payple-active-guard@example.invalid', crypt('fixture-password', gen_salt('bf')), now(),
'{"provider":"email","providers":["email"]}'::jsonb, '{}'::jsonb, now(), now()
);
DO $$
DECLARE
c_user constant uuid := '20000000-0000-4000-8000-000000000020';
v_first jsonb;
v_apply jsonb;
v_second jsonb;
v_upgrade jsonb;
v_cancel jsonb;
v_lapsed jsonb;
v_period_end timestamptz;
v_before public.subscriptions%ROWTYPE;
v_after public.subscriptions%ROWTYPE;
v_operations integer;
BEGIN
-- First tab: a free user subscribes to Pro through Payple.
v_first := public.reserve_payment_provider_operation(
c_user, 'payple', 'checkout', 'pro',
'payple-checkout:active-guard-first', 'D3RO-20260928030000-guard01',
'payer-active-guard'
);
PERFORM pg_temp.assert_true((v_first->>'created')::boolean, 'free user can reserve checkout');
v_period_end := now() + interval '1 month';
v_apply := public.apply_payment_provider_event(
p_user_id => c_user,
p_provider => 'payple',
p_event_id => 'payple-payment:active-guard-first',
p_event_created_at => now() - interval '1 minute',
p_event_type => 'payment.completed',
p_payload_digest => repeat('a', 64),
p_provider_resource_id => 'payer-active-guard',
p_tier => 'pro',
p_status => 'active',
p_entitled => true,
p_current_period_start => now() - interval '1 minute',
p_current_period_end => v_period_end,
p_cancel_at => NULL,
p_auto_renewing => true,
p_provider_customer_id => 'payer-active-guard',
p_provider_order_id => 'D3RO-20260928030000-guard01',
p_operation_id => (v_first->>'operation_id')::uuid
);
PERFORM pg_temp.assert_true((v_apply->>'applied')::boolean, 'first checkout applied');
SELECT * INTO v_before FROM public.subscriptions WHERE user_id = c_user;
-- Second (stale) tab: fresh idempotency key, same provider, same tier.
v_second := public.reserve_payment_provider_operation(
c_user, 'payple', 'checkout', 'pro',
'payple-checkout:active-guard-second', 'D3RO-20260928030500-guard02',
'payer-active-guard'
);
PERFORM pg_temp.assert_true(
NOT coalesce((v_second->>'created')::boolean, false),
'active Payple subscriber must not reserve a second checkout'
);
PERFORM pg_temp.assert_true(
v_second->>'reason' = 'subscription_already_active',
'second checkout is rejected as subscription_already_active, got '
|| coalesce(v_second->>'reason', '<null>')
);
-- An unprorated full-price "upgrade" through checkout is rejected too.
v_upgrade := public.reserve_payment_provider_operation(
c_user, 'payple', 'checkout', 'pro_plus',
'payple-checkout:active-guard-upgrade', 'D3RO-20260928031000-guard03',
'payer-active-guard'
);
PERFORM pg_temp.assert_true(
v_upgrade->>'reason' = 'subscription_already_active',
'checkout cannot be used as an unprorated upgrade'
);
SELECT count(*) INTO v_operations
FROM public.payment_provider_operations
WHERE user_id = c_user AND operation_type = 'checkout';
PERFORM pg_temp.assert_true(v_operations = 1, 'rejected checkouts create no operation');
SELECT * INTO v_after FROM public.subscriptions WHERE user_id = c_user;
PERFORM pg_temp.assert_true(
v_after.current_period_start = v_before.current_period_start
AND v_after.current_period_end = v_before.current_period_end
AND v_after.current_period_end = v_period_end
AND v_after.tier = 'pro',
'paid period is preserved after the rejected checkout'
);
-- Cancellation of the live entitlement is still possible.
v_cancel := public.reserve_payment_provider_operation(
c_user, 'payple', 'cancellation', NULL,
'payple-manage:active-guard-cancel', NULL,
'payer-active-guard'
);
PERFORM pg_temp.assert_true((v_cancel->>'created')::boolean, 'active subscriber can still cancel');
PERFORM public.mark_payment_provider_operation(
(v_cancel->>'operation_id')::uuid, 'failed', NULL, 'fixture_released'
);
-- Once the paid period has lapsed, a new checkout is allowed again.
UPDATE public.subscriptions
SET current_period_end = now() - interval '1 second'
WHERE user_id = c_user;
v_lapsed := public.reserve_payment_provider_operation(
c_user, 'payple', 'checkout', 'pro',
'payple-checkout:active-guard-lapsed', 'D3RO-20260928031500-guard04',
'payer-active-guard'
);
PERFORM pg_temp.assert_true(
(v_lapsed->>'created')::boolean,
'checkout is allowed after the paid Payple period ended'
);
END;
$$;
ROLLBACK;
SELECT 'payple_checkout_active_subscription_ok' AS result;