test: add vitest test infrastructure and configuration
- Add vitest.config.ts with coverage thresholds - Add test/setup.ts with testing-library setup - Add test/helpers.ts with test utilities
This commit is contained in:
157
admin-web/test/helpers.ts
Normal file
157
admin-web/test/helpers.ts
Normal file
@@ -0,0 +1,157 @@
|
||||
import { createClient } from '@supabase/supabase-js'
|
||||
|
||||
const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL
|
||||
const supabaseKey = process.env.SUPABASE_SERVICE_ROLE_KEY || process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY
|
||||
|
||||
// Create test client with service role for admin access (only if credentials exist)
|
||||
export const testSupabase = supabaseUrl && supabaseKey
|
||||
? createClient(
|
||||
supabaseUrl,
|
||||
supabaseKey,
|
||||
{
|
||||
auth: {
|
||||
autoRefreshToken: false,
|
||||
persistSession: false,
|
||||
},
|
||||
}
|
||||
)
|
||||
: null
|
||||
|
||||
// Test data generators
|
||||
export function generateTestTrainer(overrides = {}) {
|
||||
return {
|
||||
name: `Test Trainer ${Date.now()}`,
|
||||
specialty: 'Test Specialty',
|
||||
color: '#FF6B35',
|
||||
...overrides,
|
||||
}
|
||||
}
|
||||
|
||||
export function generateTestWorkout(overrides = {}) {
|
||||
return {
|
||||
title: `Test Workout ${Date.now()}`,
|
||||
category: 'full-body' as const,
|
||||
level: 'Beginner' as const,
|
||||
duration: 4,
|
||||
calories: 45,
|
||||
rounds: 8,
|
||||
prep_time: 10,
|
||||
work_time: 20,
|
||||
rest_time: 10,
|
||||
equipment: [],
|
||||
music_vibe: 'electronic' as const,
|
||||
exercises: [{ name: 'Test Exercise', duration: 20 }],
|
||||
is_featured: false,
|
||||
...overrides,
|
||||
}
|
||||
}
|
||||
|
||||
// Database cleanup helpers
|
||||
export async function cleanupTestData() {
|
||||
if (!testSupabase) {
|
||||
console.warn('⚠️ No test database configured, skipping cleanup')
|
||||
return
|
||||
}
|
||||
|
||||
// Delete test workouts (with timestamps to avoid deleting real data)
|
||||
const { error: workoutsError } = await testSupabase
|
||||
.from('workouts')
|
||||
.delete()
|
||||
.ilike('title', 'Test Workout%')
|
||||
|
||||
if (workoutsError) {
|
||||
console.error('Failed to cleanup test workouts:', workoutsError)
|
||||
}
|
||||
|
||||
// Delete test trainers
|
||||
const { error: trainersError } = await testSupabase
|
||||
.from('trainers')
|
||||
.delete()
|
||||
.ilike('name', 'Test Trainer%')
|
||||
|
||||
if (trainersError) {
|
||||
console.error('Failed to cleanup test trainers:', trainersError)
|
||||
}
|
||||
|
||||
// Delete test collections
|
||||
const { error: collectionsError } = await testSupabase
|
||||
.from('collections')
|
||||
.delete()
|
||||
.ilike('title', 'Test Collection%')
|
||||
|
||||
if (collectionsError) {
|
||||
console.error('Failed to cleanup test collections:', collectionsError)
|
||||
}
|
||||
}
|
||||
|
||||
// Setup test trainer
|
||||
export async function createTestTrainer(overrides = {}) {
|
||||
if (!testSupabase) {
|
||||
throw new Error('Test database not configured')
|
||||
}
|
||||
|
||||
const trainer = generateTestTrainer(overrides)
|
||||
const { data, error } = await testSupabase
|
||||
.from('trainers')
|
||||
.insert(trainer)
|
||||
.select()
|
||||
.single()
|
||||
|
||||
if (error) {
|
||||
throw new Error(`Failed to create test trainer: ${error.message}`)
|
||||
}
|
||||
|
||||
return data
|
||||
}
|
||||
|
||||
// Setup test workout
|
||||
export async function createTestWorkout(trainerId: string, overrides = {}) {
|
||||
if (!testSupabase) {
|
||||
throw new Error('Test database not configured')
|
||||
}
|
||||
|
||||
const workout = generateTestWorkout(overrides)
|
||||
const { data, error } = await testSupabase
|
||||
.from('workouts')
|
||||
.insert({ ...workout, trainer_id: trainerId })
|
||||
.select()
|
||||
.single()
|
||||
|
||||
if (error) {
|
||||
throw new Error(`Failed to create test workout: ${error.message}`)
|
||||
}
|
||||
|
||||
return data
|
||||
}
|
||||
|
||||
// Delete specific workout
|
||||
export async function deleteWorkout(id: string) {
|
||||
if (!testSupabase) {
|
||||
throw new Error('Test database not configured')
|
||||
}
|
||||
|
||||
const { error } = await testSupabase
|
||||
.from('workouts')
|
||||
.delete()
|
||||
.eq('id', id)
|
||||
|
||||
if (error) {
|
||||
throw new Error(`Failed to delete workout: ${error.message}`)
|
||||
}
|
||||
}
|
||||
|
||||
// Delete specific trainer
|
||||
export async function deleteTrainer(id: string) {
|
||||
if (!testSupabase) {
|
||||
throw new Error('Test database not configured')
|
||||
}
|
||||
|
||||
const { error } = await testSupabase
|
||||
.from('trainers')
|
||||
.delete()
|
||||
.eq('id', id)
|
||||
|
||||
if (error) {
|
||||
throw new Error(`Failed to delete trainer: ${error.message}`)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user