89 lines
3.1 KiB
PowerShell
89 lines
3.1 KiB
PowerShell
param(
|
|
[string]$DatabaseContainer = 'supabase_db_d3ro-voice'
|
|
)
|
|
|
|
$ErrorActionPreference = 'Stop'
|
|
$userId = '20000000-0000-4000-8000-000000000099'
|
|
$runId = [guid]::NewGuid().ToString('N')
|
|
$firstTransactionId = "race-transaction-first-$runId"
|
|
$secondTransactionId = "race-transaction-second-$runId"
|
|
|
|
function Invoke-D3roSql {
|
|
param([Parameter(Mandatory)][string]$Sql)
|
|
$output = $Sql | docker exec -i $DatabaseContainer psql -v ON_ERROR_STOP=1 -U postgres -d postgres -t -A
|
|
if ($LASTEXITCODE -ne 0) { throw 'D3RO PostgreSQL command failed' }
|
|
return ($output -join "`n").Trim()
|
|
}
|
|
|
|
$setup = @"
|
|
DELETE FROM auth.users WHERE id = '$userId';
|
|
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 (
|
|
'$userId', 'authenticated', 'authenticated',
|
|
'reward-race@example.invalid', crypt('fixture-password', gen_salt('bf')), now(),
|
|
'{"provider":"email","providers":["email"]}'::jsonb, '{}'::jsonb, now(), now()
|
|
);
|
|
UPDATE public.subscriptions
|
|
SET tier = 'free', status = 'active', overage_credits = 0
|
|
WHERE user_id = '$userId';
|
|
"@
|
|
|
|
try {
|
|
[void](Invoke-D3roSql -Sql $setup)
|
|
|
|
$firstSql = @"
|
|
BEGIN;
|
|
SELECT public.grant_verified_ad_reward(
|
|
'$userId', 'admob:race', 'rewarded_video_quota', '5224354917',
|
|
'$firstTransactionId', 50
|
|
);
|
|
SELECT pg_sleep(2);
|
|
COMMIT;
|
|
"@
|
|
$secondSql = @"
|
|
SELECT public.grant_verified_ad_reward(
|
|
'$userId', 'admob:race', 'rewarded_video_quota', '5224354917',
|
|
'$secondTransactionId', 50
|
|
);
|
|
"@
|
|
|
|
$first = Start-Job -ScriptBlock {
|
|
param($Container, $Sql)
|
|
$Sql | docker exec -i $Container psql -v ON_ERROR_STOP=1 -U postgres -d postgres -t -A
|
|
if ($LASTEXITCODE -ne 0) { throw 'first reward connection failed' }
|
|
} -ArgumentList $DatabaseContainer, $firstSql
|
|
Start-Sleep -Milliseconds 200
|
|
$second = Start-Job -ScriptBlock {
|
|
param($Container, $Sql)
|
|
$Sql | docker exec -i $Container psql -v ON_ERROR_STOP=1 -U postgres -d postgres -t -A
|
|
if ($LASTEXITCODE -ne 0) { throw 'second reward connection failed' }
|
|
} -ArgumentList $DatabaseContainer, $secondSql
|
|
|
|
$firstOutput = (Receive-Job -Job $first -Wait -AutoRemoveJob | Out-String)
|
|
$secondOutput = (Receive-Job -Job $second -Wait -AutoRemoveJob | Out-String)
|
|
if ($firstOutput -notmatch '"granted": true') {
|
|
throw "first callback was not granted: $firstOutput"
|
|
}
|
|
if ($secondOutput -notmatch '"reason": "cooldown"') {
|
|
throw "second callback was not serialized into cooldown: $secondOutput"
|
|
}
|
|
|
|
$verification = Invoke-D3roSql -Sql @"
|
|
SELECT
|
|
(SELECT count(*) FROM public.ad_reward_claims WHERE user_id = '$userId')::text
|
|
|| ':' ||
|
|
(SELECT overage_credits FROM public.subscriptions WHERE user_id = '$userId')::text;
|
|
"@
|
|
if ($verification -ne '1:50') {
|
|
throw "reward race changed more than one claim/balance: $verification"
|
|
}
|
|
Write-Output 'mobile_reward_race_ok claims=1 credits=50 second=cooldown'
|
|
} finally {
|
|
[void](Invoke-D3roSql -Sql @"
|
|
DELETE FROM public.ad_reward_receipts
|
|
WHERE transaction_id IN ('$firstTransactionId', '$secondTransactionId');
|
|
DELETE FROM auth.users WHERE id = '$userId';
|
|
"@)
|
|
}
|