/** * Test Utilities for EuchreCamp * * Provides helper functions for creating and cleaning up test data */ import { prisma } from '@/lib/prisma'; import type { User, Player, Event, Match } from '@prisma/client'; // Track created test records for cleanup const createdRecords = { users: [] as string[], players: [] as number[], events: [] as number[], matches: [] as number[], }; /** * Create a test user with optional player association */ export async function createTestUser(options: { email?: string; name?: string; role?: string; playerId?: number | null; } = {}) { const timestamp = Date.now(); const email = options.email || `test-user-${timestamp}@example.com`; const name = options.name || `Test User ${timestamp}`; const role = options.role || 'player'; const user = await prisma.user.create({ data: { email, name, role, playerId: options.playerId, }, }); createdRecords.users.push(user.id); return user; } /** * Create a test player */ export async function createTestPlayer(options: { name?: string; currentElo?: number; } = {}) { const timestamp = Date.now(); const name = options.name || `Test Player ${timestamp}`; const player = await prisma.player.create({ data: { name, normalizedName: name.toLowerCase(), currentElo: options.currentElo || 1000, }, }); createdRecords.players.push(player.id); return player; } /** * Create a test event (tournament) */ export async function createTestEvent(options: { name?: string; ownerId?: string; } = {}) { const timestamp = Date.now(); const name = options.name || `Test Event ${timestamp}`; const event = await prisma.event.create({ data: { name, eventType: 'tournament', format: 'round_robin', status: 'planned', ownerId: options.ownerId, }, }); createdRecords.events.push(event.id); return event; } /** * Create a test match */ export async function createTestMatch(options: { eventId?: number; team1P1Id: number; team1P2Id: number; team2P1Id: number; team2P2Id: number; team1Score?: number; team2Score?: number; }) { const timestamp = Date.now(); const match = await prisma.match.create({ data: { eventId: options.eventId, player1P1Id: options.team1P1Id, player1P2Id: options.team1P2Id, player2P1Id: options.team2P1Id, player2P2Id: options.team2P2Id, team1Score: options.team1Score ?? 10, team2Score: options.team2Score ?? 5, status: 'completed', }, }); createdRecords.matches.push(match.id); return match; } /** * Clean up all created test records */ export async function cleanupTestRecords() { console.log('๐Ÿงน Cleaning up test records...'); try { // Delete matches first (they reference players) if (createdRecords.matches.length > 0) { await prisma.match.deleteMany({ where: { id: { in: createdRecords.matches } }, }); console.log(` Deleted ${createdRecords.matches.length} matches`); } // Delete events if (createdRecords.events.length > 0) { await prisma.event.deleteMany({ where: { id: { in: createdRecords.events } }, }); console.log(` Deleted ${createdRecords.events.length} events`); } // Delete users first (to break player associations) if (createdRecords.users.length > 0) { await prisma.user.deleteMany({ where: { id: { in: createdRecords.users } }, }); console.log(` Deleted ${createdRecords.users.length} users`); } // Delete players if (createdRecords.players.length > 0) { await prisma.player.deleteMany({ where: { id: { in: createdRecords.players } }, }); console.log(` Deleted ${createdRecords.players.length} players`); } // Reset tracking createdRecords.users = []; createdRecords.players = []; createdRecords.events = []; createdRecords.matches = []; console.log('โœ… Test records cleaned up successfully'); } catch (error) { console.error('โŒ Error cleaning up test records:', error); // Still reset tracking to avoid trying to delete again createdRecords.users = []; createdRecords.players = []; createdRecords.events = []; createdRecords.matches = []; } } /** * Get count of created records (for assertions) */ export function getCreatedRecordCounts() { return { users: createdRecords.users.length, players: createdRecords.players.length, events: createdRecords.events.length, matches: createdRecords.matches.length, }; } /** * Clean up test users by email pattern */ export async function cleanupTestUsersByEmailPattern(pattern: string = 'test-') { try { const result = await prisma.user.deleteMany({ where: { email: { contains: pattern, }, }, }); console.log(` Deleted ${result.count} test users matching pattern "${pattern}"`); return result.count; } catch (error) { console.error('โŒ Error cleaning up test users:', error); return 0; } } /** * Clean up test players by name pattern */ export async function cleanupTestPlayersByNamePattern(pattern: string = 'Test ') { try { const result = await prisma.player.deleteMany({ where: { name: { contains: pattern, }, }, }); console.log(` Deleted ${result.count} test players matching pattern "${pattern}"`); return result.count; } catch (error) { console.error('โŒ Error cleaning up test players:', error); return 0; } } /** * Clean up all test data (aggressive cleanup) */ export async function cleanupAllTestData() { console.log('๐Ÿงน Aggressive cleanup of all test data...'); try { // Delete test users first const userResult = await prisma.user.deleteMany({ where: { email: { contains: 'test-', }, }, }); console.log(` Deleted ${userResult.count} test users`); // Delete test players const playerResult = await prisma.player.deleteMany({ where: { name: { contains: 'Test ', }, }, }); console.log(` Deleted ${playerResult.count} test players`); // Delete test events const eventResult = await prisma.event.deleteMany({ where: { name: { contains: 'Test ', }, }, }); console.log(` Deleted ${eventResult.count} test events`); console.log('โœ… All test data cleaned up'); } catch (error) { console.error('โŒ Error during aggressive cleanup:', error); } } // Export cleanup function for global setup/teardown export const testCleanup = cleanupTestRecords;