mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-20 06:51:12 -05:00
207 lines
5.3 KiB
TypeScript
207 lines
5.3 KiB
TypeScript
/**
|
||
* Database Fixtures for Playwright Tests
|
||
*
|
||
* Provides direct database access for test setup and teardown using service role.
|
||
* IMPORTANT: Only use for test data management, never in production code!
|
||
*/
|
||
|
||
import { createClient } from '@supabase/supabase-js';
|
||
import type { Database } from '@/integrations/supabase/types';
|
||
|
||
const supabaseUrl = 'https://ydvtmnrszybqnbcqbdcy.supabase.co';
|
||
const supabaseAnonKey = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InlkdnRtbnJzenlicW5iY3FiZGN5Iiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTgzMjYzNTYsImV4cCI6MjA3MzkwMjM1Nn0.DM3oyapd_omP5ZzIlrT0H9qBsiQBxBRgw2tYuqgXKX4';
|
||
|
||
// For test setup/teardown only - requires service role key
|
||
const supabaseServiceRoleKey = process.env.SUPABASE_SERVICE_ROLE_KEY;
|
||
|
||
// Regular client for authenticated operations
|
||
export const supabase = createClient<Database>(supabaseUrl, supabaseAnonKey);
|
||
|
||
// Service role client for test setup/teardown (bypasses RLS)
|
||
export const supabaseAdmin = supabaseServiceRoleKey
|
||
? createClient<Database>(supabaseUrl, supabaseServiceRoleKey)
|
||
: null;
|
||
|
||
/**
|
||
* Create a test user with specific role
|
||
*/
|
||
export async function setupTestUser(
|
||
email: string,
|
||
password: string,
|
||
role: 'user' | 'moderator' | 'admin' | 'superuser' = 'user'
|
||
): Promise<{ userId: string; email: string }> {
|
||
if (!supabaseAdmin) {
|
||
throw new Error('Service role key not configured');
|
||
}
|
||
|
||
// Check if user already exists
|
||
const { data: existingUsers } = await supabaseAdmin.auth.admin.listUsers();
|
||
const existingUser = existingUsers?.users.find(u => u.email === email);
|
||
|
||
let userId: string;
|
||
|
||
if (existingUser) {
|
||
// User exists - use their ID
|
||
userId = existingUser.id;
|
||
console.log(`ℹ️ Using existing test user: ${email}`);
|
||
} else {
|
||
// User doesn't exist - create new one
|
||
const { data: authData, error: authError } = await supabaseAdmin.auth.admin.createUser({
|
||
email,
|
||
password,
|
||
email_confirm: true,
|
||
});
|
||
|
||
if (authError) throw authError;
|
||
if (!authData.user) throw new Error('User creation failed');
|
||
|
||
userId = authData.user.id;
|
||
console.log(`✓ Created new test user: ${email}`);
|
||
}
|
||
|
||
// Create or update profile (ensures correct role and is_test_data flag)
|
||
const { error: profileError } = await supabaseAdmin
|
||
.from('profiles')
|
||
.upsert({
|
||
id: userId,
|
||
username: email.split('@')[0],
|
||
email,
|
||
role,
|
||
is_test_data: true,
|
||
});
|
||
|
||
if (profileError) throw profileError;
|
||
|
||
return { userId, email };
|
||
}
|
||
|
||
/**
|
||
* Clean up all test data
|
||
*/
|
||
export async function cleanupTestData(): Promise<void> {
|
||
if (!supabaseAdmin) {
|
||
throw new Error('Service role key not configured');
|
||
}
|
||
|
||
// Delete in dependency order (child tables first)
|
||
const tables = [
|
||
'ride_photos',
|
||
'park_photos',
|
||
'submission_items',
|
||
'content_submissions',
|
||
'ride_versions',
|
||
'park_versions',
|
||
'company_versions',
|
||
'ride_model_versions',
|
||
'rides',
|
||
'ride_models',
|
||
'parks',
|
||
'companies',
|
||
];
|
||
|
||
for (const table of tables) {
|
||
await supabaseAdmin
|
||
.from(table as any)
|
||
.delete()
|
||
.eq('is_test_data', true);
|
||
}
|
||
|
||
// Delete test profiles
|
||
const { data: profiles } = await supabaseAdmin
|
||
.from('profiles')
|
||
.select('id')
|
||
.eq('is_test_data', true);
|
||
|
||
if (profiles) {
|
||
for (const profile of profiles) {
|
||
await supabaseAdmin.auth.admin.deleteUser(profile.id);
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Query database directly for assertions
|
||
*/
|
||
export async function queryDatabase<T = any>(
|
||
table: string,
|
||
query: (qb: any) => any
|
||
): Promise<T[]> {
|
||
if (!supabaseAdmin) {
|
||
throw new Error('Service role key not configured');
|
||
}
|
||
|
||
const { data, error } = await query(supabaseAdmin.from(table));
|
||
|
||
if (error) throw error;
|
||
return data || [];
|
||
}
|
||
|
||
/**
|
||
* Wait for a version to be created
|
||
*/
|
||
export async function waitForVersion(
|
||
entityId: string,
|
||
versionNumber: number,
|
||
table: string,
|
||
maxWaitMs: number = 5000
|
||
): Promise<boolean> {
|
||
if (!supabaseAdmin) {
|
||
throw new Error('Service role key not configured');
|
||
}
|
||
|
||
const startTime = Date.now();
|
||
|
||
while (Date.now() - startTime < maxWaitMs) {
|
||
const { data } = await supabaseAdmin
|
||
.from(table as any)
|
||
.select('version_number')
|
||
.eq('entity_id', entityId)
|
||
.eq('version_number', versionNumber)
|
||
.single();
|
||
|
||
if (data) return true;
|
||
|
||
await new Promise(resolve => setTimeout(resolve, 500));
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
/**
|
||
* Approve a submission directly (for test setup)
|
||
*/
|
||
export async function approveSubmissionDirect(submissionId: string): Promise<void> {
|
||
if (!supabaseAdmin) {
|
||
throw new Error('Service role key not configured');
|
||
}
|
||
|
||
const { error } = await supabaseAdmin.rpc('approve_submission', {
|
||
submission_id: submissionId,
|
||
});
|
||
|
||
if (error) throw error;
|
||
}
|
||
|
||
/**
|
||
* Get test data statistics
|
||
*/
|
||
export async function getTestDataStats(): Promise<Record<string, number>> {
|
||
if (!supabaseAdmin) {
|
||
throw new Error('Service role key not configured');
|
||
}
|
||
|
||
const tables = ['parks', 'rides', 'companies', 'ride_models', 'content_submissions'];
|
||
const stats: Record<string, number> = {};
|
||
|
||
for (const table of tables) {
|
||
const { count } = await supabaseAdmin
|
||
.from(table as any)
|
||
.select('*', { count: 'exact', head: true })
|
||
.eq('is_test_data', true);
|
||
|
||
stats[table] = count || 0;
|
||
}
|
||
|
||
return stats;
|
||
}
|