d3ro-voice/apps/mobile-rn/__tests__/stt-quota.local.integration.mjs
2026-08-29 18:33:45 +09:00

121 lines
5.1 KiB
JavaScript

import assert from 'node:assert/strict';
import { randomUUID } from 'node:crypto';
import { createClient } from '@supabase/supabase-js';
const url = process.env.SUPABASE_URL;
const serviceKey = process.env.SUPABASE_SERVICE_ROLE_KEY;
const publishableKey = process.env.SUPABASE_ANON_KEY ?? process.env.SUPABASE_PUBLISHABLE_KEY;
assert(url && serviceKey && publishableKey, 'SUPABASE_URL, service role key and public key are required');
const service = createClient(url, serviceKey, {
auth: { persistSession: false, autoRefreshToken: false },
});
const email = `stt-quota-${randomUUID()}@example.invalid`;
const password = `Fixture-${randomUUID()}!`;
let userId = null;
let assertions = 0;
function ok(condition, message) {
assert(condition, message);
assertions += 1;
}
async function reserve(id) {
const { data, error } = await service.rpc('reserve_stt_quota', {
p_user_id: userId,
p_reservation_id: id,
});
assert.equal(error, null, error?.message);
return data;
}
async function finalize(id, succeeded) {
const { data, error } = await service.rpc('finalize_stt_quota', {
p_reservation_id: id,
p_succeeded: succeeded,
});
assert.equal(error, null, error?.message);
return data;
}
try {
const created = await service.auth.admin.createUser({ email, password, email_confirm: true });
assert.equal(created.error, null, created.error?.message);
userId = created.data.user.id;
const subscription = await service.from('subscriptions')
.update({ tier: 'free', status: 'active', overage_credits: 0 })
.eq('user_id', userId);
assert.equal(subscription.error, null, subscription.error?.message);
const usage = await service.from('daily_usage').insert({
user_id: userId,
date: new Date().toISOString().slice(0, 10),
feature: 'stt_transcribe',
count: 249,
});
assert.equal(usage.error, null, usage.error?.message);
const competingIds = Array.from({ length: 20 }, () => randomUUID());
const competing = await Promise.all(competingIds.map(reserve));
const winners = competing.filter((item) => item.allowed === true);
ok(winners.length === 1, 'twenty concurrent requests reserve exactly one remaining base unit');
ok(competing.filter((item) => item.status === 'denied').length === 19, 'all excess work is denied before provider use');
await finalize(winners[0].reservation_id, false);
const replayId = randomUUID();
const replay = await Promise.all(Array.from({ length: 10 }, () => reserve(replayId)));
ok(replay.every((item) => item.allowed && item.reservation_id === replayId), 'same request replay is idempotent');
const usageAfterReplay = await service.from('daily_usage')
.select('count')
.eq('user_id', userId)
.eq('feature', 'stt_transcribe')
.single();
assert.equal(usageAfterReplay.error, null, usageAfterReplay.error?.message);
ok(usageAfterReplay.data.count === 250, 'idempotent replay consumes one unit only');
await finalize(replayId, true);
const creditsUpdate = await service.from('subscriptions')
.update({ overage_credits: 3 })
.eq('user_id', userId);
assert.equal(creditsUpdate.error, null, creditsUpdate.error?.message);
const overage = await Promise.all(Array.from({ length: 10 }, () => reserve(randomUUID())));
const overageWinners = overage.filter((item) => item.allowed === true);
ok(overageWinners.length === 3, 'concurrent requests cannot overspend three overage credits');
ok(overageWinners.every((item) => item.consumed_from === 'overage'), 'base exhaustion uses only overage');
await finalize(overageWinners[0].reservation_id, true);
await Promise.all(overageWinners.slice(1).map((item) => finalize(item.reservation_id, false)));
const finalSubscription = await service.from('subscriptions')
.select('overage_credits')
.eq('user_id', userId)
.single();
const finalUsage = await service.from('daily_usage')
.select('count')
.eq('user_id', userId)
.eq('feature', 'stt_transcribe')
.single();
assert.equal(finalSubscription.error, null, finalSubscription.error?.message);
assert.equal(finalUsage.error, null, finalUsage.error?.message);
ok(finalSubscription.data.overage_credits === 2, 'two failed providers refund exactly two overage credits');
ok(finalUsage.data.count === 251, 'only the successful overage provider remains charged');
const userClient = createClient(url, publishableKey, {
auth: { persistSession: false, autoRefreshToken: false },
});
const signedIn = await userClient.auth.signInWithPassword({ email, password });
assert.equal(signedIn.error, null, signedIn.error?.message);
const forbiddenLedger = await userClient.from('stt_quota_reservations').select('id').limit(1);
ok(forbiddenLedger.error !== null, 'authenticated users cannot read the reservation ledger');
const forbiddenReserve = await userClient.rpc('reserve_stt_quota', {
p_user_id: userId,
p_reservation_id: randomUUID(),
});
ok(forbiddenReserve.error !== null, 'authenticated users cannot invoke reservation RPCs');
console.log(`stt quota integration GREEN: ${assertions} assertions`);
} finally {
if (userId) {
const removed = await service.auth.admin.deleteUser(userId);
assert.equal(removed.error, null, removed.error?.message);
}
}