feat: Implement tournament schedule tab and fix E2E tests #27
+92
-29
@@ -29,6 +29,46 @@ if (DB_URL.includes('_dev') || DB_URL.includes('_dev_')) {
|
|||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Single source of truth for test object patterns
|
||||||
|
const TEST_PATTERNS = {
|
||||||
|
players: [
|
||||||
|
'%Test%',
|
||||||
|
'%Setup%',
|
||||||
|
'%Home Test%',
|
||||||
|
'%Home Match Player%',
|
||||||
|
'%Admin User%',
|
||||||
|
'%NinePart%',
|
||||||
|
'%Nine Part%',
|
||||||
|
'%Test Player%',
|
||||||
|
'%TestUser%',
|
||||||
|
'%Cucumber%',
|
||||||
|
'%Config Admin%',
|
||||||
|
],
|
||||||
|
events: [
|
||||||
|
'%Test%',
|
||||||
|
'%Setup%',
|
||||||
|
'%Recent%',
|
||||||
|
'%Test Tournament%',
|
||||||
|
'%Cucumber%',
|
||||||
|
],
|
||||||
|
users: [
|
||||||
|
'%test%',
|
||||||
|
'%setup%',
|
||||||
|
'%cucumber%',
|
||||||
|
'%TestUser%',
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
// Helper to build SQL LIKE clause from patterns
|
||||||
|
function buildLikeClause(patterns) {
|
||||||
|
return patterns.map(p => `name LIKE '${p}'`).join(' OR ');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper to build email LIKE clause
|
||||||
|
function buildEmailLikeClause(patterns) {
|
||||||
|
return patterns.map(p => `email LIKE '${p}'`).join(' OR ');
|
||||||
|
}
|
||||||
|
|
||||||
// Helper to run SQL and log results
|
// Helper to run SQL and log results
|
||||||
function runSQL(sql, description) {
|
function runSQL(sql, description) {
|
||||||
console.log(`\n🔍 ${description}...`);
|
console.log(`\n🔍 ${description}...`);
|
||||||
@@ -42,13 +82,23 @@ function runSQL(sql, description) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper to run multi-line SQL
|
// Helper to run SQL via file (avoids quote escaping issues)
|
||||||
function runMultiLineSQL(sqlLines, description) {
|
function runSQLViaFile(sql, description) {
|
||||||
console.log(`\n🔍 ${description}...`);
|
console.log(`\n🔍 ${description}...`);
|
||||||
|
const fs = require('fs');
|
||||||
|
const os = require('os');
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const sql = sqlLines.join('\n');
|
// Create temp file with SQL
|
||||||
const result = execSync(`psql "${DB_URL}" -c "${sql}"`, { encoding: 'utf8' });
|
const tmpFile = path.join(os.tmpdir(), `cleanup_${Date.now()}.sql`);
|
||||||
|
fs.writeFileSync(tmpFile, sql);
|
||||||
|
|
||||||
|
const result = execSync(`psql "${DB_URL}" -f "${tmpFile}"`, { encoding: 'utf8' });
|
||||||
console.log(result);
|
console.log(result);
|
||||||
|
|
||||||
|
// Clean up temp file
|
||||||
|
fs.unlinkSync(tmpFile);
|
||||||
return true;
|
return true;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`❌ Error: ${error.message}`);
|
console.error(`❌ Error: ${error.message}`);
|
||||||
@@ -56,9 +106,12 @@ function runMultiLineSQL(sqlLines, description) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper to count records matching pattern
|
// Helper to count records matching any of the patterns
|
||||||
function countRecords(table, column, pattern) {
|
function countRecordsByPatterns(table, patterns) {
|
||||||
const sql = `SELECT COUNT(*) FROM ${table} WHERE ${column} LIKE '${pattern}';`;
|
const whereClause = table === 'users'
|
||||||
|
? buildEmailLikeClause(patterns)
|
||||||
|
: buildLikeClause(patterns);
|
||||||
|
const sql = `SELECT COUNT(*) FROM ${table} WHERE ${whereClause};`;
|
||||||
try {
|
try {
|
||||||
const result = execSync(`psql "${DB_URL}" -c "${sql}" -t`, { encoding: 'utf8' }).trim();
|
const result = execSync(`psql "${DB_URL}" -c "${sql}" -t`, { encoding: 'utf8' }).trim();
|
||||||
return parseInt(result);
|
return parseInt(result);
|
||||||
@@ -89,57 +142,67 @@ async function main() {
|
|||||||
|
|
||||||
console.log('\n📋 Checking test records...\n');
|
console.log('\n📋 Checking test records...\n');
|
||||||
|
|
||||||
// Count test players
|
// Count test records using centralized patterns
|
||||||
const testPlayerCount = countRecords('players', 'name', '%Test%') +
|
const testPlayerCount = countRecordsByPatterns('players', TEST_PATTERNS.players);
|
||||||
countRecords('players', 'name', '%Setup%') +
|
|
||||||
countRecords('players', 'name', '%Home Test%') +
|
|
||||||
countRecords('players', 'name', '%Home Match Player%') +
|
|
||||||
countRecords('players', 'name', '%Admin User%');
|
|
||||||
console.log(`Test players found: ${testPlayerCount}`);
|
console.log(`Test players found: ${testPlayerCount}`);
|
||||||
|
|
||||||
// Count test tournaments
|
const testEventCount = countRecordsByPatterns('events', TEST_PATTERNS.events);
|
||||||
const testEventCount = countRecords('events', 'name', '%Test%') +
|
|
||||||
countRecords('events', 'name', '%Setup%') +
|
|
||||||
countRecords('events', 'name', '%Recent%');
|
|
||||||
console.log(`Test tournaments found: ${testEventCount}`);
|
console.log(`Test tournaments found: ${testEventCount}`);
|
||||||
|
|
||||||
// Count test users
|
const testUserCount = countRecordsByPatterns('users', TEST_PATTERNS.users);
|
||||||
const testUserCount = countRecords('users', 'email', '%test%') +
|
|
||||||
countRecords('users', 'email', '%setup%');
|
|
||||||
console.log(`Test users found: ${testUserCount}`);
|
console.log(`Test users found: ${testUserCount}`);
|
||||||
|
|
||||||
console.log('\n🔄 Starting cleanup...\n');
|
console.log('\n🔄 Starting cleanup...\n');
|
||||||
|
|
||||||
// Step 1: Delete test tournaments (with matches due to cascade delete)
|
// Step 1: Delete test tournaments (with matches due to cascade delete)
|
||||||
console.log('1. Deleting test tournaments (matches will be deleted via cascade)...');
|
console.log('1. Deleting test tournaments (matches will be deleted via cascade)...');
|
||||||
runSQL(
|
const eventWhere = buildLikeClause(TEST_PATTERNS.events);
|
||||||
"DELETE FROM events WHERE (name LIKE '%Test%' OR name LIKE '%Setup%' OR name LIKE '%Recent%');",
|
runSQLViaFile(
|
||||||
|
`DELETE FROM events WHERE (${eventWhere});`,
|
||||||
'Deleted test tournaments'
|
'Deleted test tournaments'
|
||||||
);
|
);
|
||||||
|
|
||||||
// Step 2: Delete test players (all of them, since we deleted their matches)
|
// Step 2: Delete test players (all of them, since we deleted their matches)
|
||||||
console.log('\n2. Deleting test players...');
|
console.log('\n2. Deleting test players...');
|
||||||
runSQL(
|
const playerWhere = buildLikeClause(TEST_PATTERNS.players);
|
||||||
"DELETE FROM players WHERE (name LIKE '%Test%' OR name LIKE '%Setup%' OR name LIKE '%Home Test%' OR name LIKE '%Home Match Player%' OR name LIKE '%Admin User%');",
|
runSQLViaFile(
|
||||||
|
`DELETE FROM players WHERE (${playerWhere});`,
|
||||||
'Deleted test players'
|
'Deleted test players'
|
||||||
);
|
);
|
||||||
|
|
||||||
// Step 3: Delete test users (they shouldn't have player associations)
|
// Step 3: Delete test users (they shouldn't have player associations)
|
||||||
console.log('\n3. Deleting test users...');
|
console.log('\n3. Deleting test users...');
|
||||||
runSQL(
|
const userWhere = buildEmailLikeClause(TEST_PATTERNS.users);
|
||||||
"DELETE FROM users WHERE (email LIKE '%test%' OR email LIKE '%setup%') AND \"playerId\" IS NULL;",
|
runSQLViaFile(
|
||||||
|
`DELETE FROM users WHERE (${userWhere}) AND "playerId" IS NULL;`,
|
||||||
'Deleted test users'
|
'Deleted test users'
|
||||||
);
|
);
|
||||||
|
|
||||||
// Summary
|
// Summary
|
||||||
console.log('\n✅ Cleanup complete!');
|
console.log('\n✅ Cleanup complete!');
|
||||||
console.log('\n📊 Remaining test records:');
|
console.log('\n📊 Remaining test records:');
|
||||||
runSQL("SELECT COUNT(*) FROM players WHERE name LIKE '%Test%' OR name LIKE '%Setup%' OR name LIKE '%Home Test%';", 'Remaining test players');
|
|
||||||
runSQL("SELECT COUNT(*) FROM events WHERE name LIKE '%Test%' OR name LIKE '%Setup%';", 'Remaining test tournaments');
|
const remainingPlayerWhere = buildLikeClause(TEST_PATTERNS.players);
|
||||||
runSQL("SELECT COUNT(*) FROM users WHERE email LIKE '%test%' OR email LIKE '%setup%';", 'Remaining test users');
|
runSQLViaFile(
|
||||||
|
`SELECT COUNT(*) FROM players WHERE ${remainingPlayerWhere};`,
|
||||||
|
'Remaining test players'
|
||||||
|
);
|
||||||
|
|
||||||
|
const remainingEventWhere = buildLikeClause(TEST_PATTERNS.events);
|
||||||
|
runSQLViaFile(
|
||||||
|
`SELECT COUNT(*) FROM events WHERE ${remainingEventWhere};`,
|
||||||
|
'Remaining test tournaments'
|
||||||
|
);
|
||||||
|
|
||||||
|
const remainingUserWhere = buildEmailLikeClause(TEST_PATTERNS.users);
|
||||||
|
runSQLViaFile(
|
||||||
|
`SELECT COUNT(*) FROM users WHERE ${remainingUserWhere};`,
|
||||||
|
'Remaining test users'
|
||||||
|
);
|
||||||
|
|
||||||
console.log('\n💡 Note: All test records deleted. Matches are automatically deleted');
|
console.log('\n💡 Note: All test records deleted. Matches are automatically deleted');
|
||||||
console.log(' via cascade delete when their parent tournament is deleted.');
|
console.log(' via cascade delete when their parent tournament is deleted.');
|
||||||
|
console.log('\n📝 To add new test patterns, edit TEST_PATTERNS in this script.');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-3
@@ -1,13 +1,11 @@
|
|||||||
import { PrismaClient } from '@prisma/client'
|
import { PrismaClient } from '@prisma/client'
|
||||||
|
|
||||||
// Load .env file if it exists
|
|
||||||
require('dotenv').config()
|
|
||||||
|
|
||||||
const globalForPrisma = globalThis as unknown as {
|
const globalForPrisma = globalThis as unknown as {
|
||||||
prisma: PrismaClient | undefined
|
prisma: PrismaClient | undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
// Detect database provider from environment (default to sqlite for local development)
|
// Detect database provider from environment (default to sqlite for local development)
|
||||||
|
// Next.js automatically loads environment variables from .env, .env.development, .env.production
|
||||||
const databaseProvider = process.env.DATABASE_PROVIDER || 'sqlite'
|
const databaseProvider = process.env.DATABASE_PROVIDER || 'sqlite'
|
||||||
const databaseUrl = process.env.DATABASE_URL
|
const databaseUrl = process.env.DATABASE_URL
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user