Files
thrilltrack-explorer/src-old/lib/integrationTests/suites/moderationLockTests.ts

295 lines
10 KiB
TypeScript

/**
* Moderation Lock Management Integration Tests
*
* Tests for submission locking, claiming, extending, and release mechanisms
*/
import { supabase } from '@/lib/supabaseClient';
import type { TestSuite, TestResult } from '../testRunner';
export const moderationLockTestSuite: TestSuite = {
id: 'moderation-locks',
name: 'Moderation Lock Management',
description: 'Tests for submission locking, claiming, and release mechanisms',
tests: [
{
id: 'lock-001',
name: 'Claim Submission Creates Active Lock',
description: 'Verifies that claiming a submission creates a lock with correct expiry',
run: async (): Promise<TestResult> => {
const startTime = Date.now();
try {
const { data: userData } = await supabase.auth.getUser();
if (!userData.user) throw new Error('No authenticated user');
// 1. Create test submission
const { data: submission, error: createError } = await supabase
.from('content_submissions')
.insert({
user_id: userData.user.id,
submission_type: 'park',
status: 'pending',
content: { test: true }
})
.select()
.single();
if (createError) throw createError;
// 2. Claim the submission (manual update for testing)
const { error: lockError } = await supabase
.from('content_submissions')
.update({
assigned_to: userData.user.id,
locked_until: new Date(Date.now() + 15 * 60 * 1000).toISOString()
})
.eq('id', submission.id);
if (lockError) throw new Error(`Claim failed: ${lockError.message}`);
// 3. Verify lock exists
const { data: lockedSubmission, error: fetchError } = await supabase
.from('content_submissions')
.select('assigned_to, locked_until')
.eq('id', submission.id)
.single();
if (fetchError) throw fetchError;
// 4. Assertions
if (lockedSubmission.assigned_to !== userData.user.id) {
throw new Error('Submission not assigned to current user');
}
if (!lockedSubmission.locked_until) {
throw new Error('locked_until not set');
}
const lockedUntil = new Date(lockedSubmission.locked_until);
const now = new Date();
const diffMinutes = (lockedUntil.getTime() - now.getTime()) / (1000 * 60);
if (diffMinutes < 14 || diffMinutes > 16) {
throw new Error(`Lock duration incorrect: ${diffMinutes} minutes`);
}
// Cleanup
await supabase.from('content_submissions').delete().eq('id', submission.id);
return {
id: 'lock-001',
name: 'Claim Submission Creates Active Lock',
suite: 'Moderation Lock Management',
status: 'pass',
duration: Date.now() - startTime,
timestamp: new Date().toISOString(),
details: {
submissionId: submission.id,
lockDurationMinutes: diffMinutes,
assignedTo: lockedSubmission.assigned_to
}
};
} catch (error) {
return {
id: 'lock-001',
name: 'Claim Submission Creates Active Lock',
suite: 'Moderation Lock Management',
status: 'fail',
duration: Date.now() - startTime,
error: error instanceof Error ? error.message : String(error),
timestamp: new Date().toISOString()
};
}
}
},
{
id: 'lock-002',
name: 'Release Lock Clears Assignment',
description: 'Verifies that releasing a lock clears assigned_to and locked_until',
run: async (): Promise<TestResult> => {
const startTime = Date.now();
try {
const { data: userData } = await supabase.auth.getUser();
if (!userData.user) throw new Error('No authenticated user');
// Create and claim submission
const { data: submission, error: createError } = await supabase
.from('content_submissions')
.insert({
user_id: userData.user.id,
submission_type: 'park',
status: 'pending',
content: { test: true }
})
.select()
.single();
if (createError) throw createError;
await supabase
.from('content_submissions')
.update({
assigned_to: userData.user.id,
locked_until: new Date(Date.now() + 15 * 60 * 1000).toISOString()
})
.eq('id', submission.id);
// Release lock
const { error: releaseError } = await supabase
.from('content_submissions')
.update({
assigned_to: null,
locked_until: null
})
.eq('id', submission.id);
if (releaseError) throw new Error(`release_lock failed: ${releaseError.message}`);
// Verify lock cleared
const { data: releasedSubmission, error: fetchError } = await supabase
.from('content_submissions')
.select('assigned_to, locked_until')
.eq('id', submission.id)
.single();
if (fetchError) throw fetchError;
if (releasedSubmission.assigned_to !== null) {
throw new Error('assigned_to not cleared');
}
if (releasedSubmission.locked_until !== null) {
throw new Error('locked_until not cleared');
}
// Cleanup
await supabase.from('content_submissions').delete().eq('id', submission.id);
return {
id: 'lock-002',
name: 'Release Lock Clears Assignment',
suite: 'Moderation Lock Management',
status: 'pass',
duration: Date.now() - startTime,
timestamp: new Date().toISOString()
};
} catch (error) {
return {
id: 'lock-002',
name: 'Release Lock Clears Assignment',
suite: 'Moderation Lock Management',
status: 'fail',
duration: Date.now() - startTime,
error: error instanceof Error ? error.message : String(error),
timestamp: new Date().toISOString()
};
}
}
},
{
id: 'lock-003',
name: 'Extend Lock Adds 15 Minutes',
description: 'Verifies that extending a lock adds correct duration',
run: async (): Promise<TestResult> => {
const startTime = Date.now();
try {
const { data: userData } = await supabase.auth.getUser();
if (!userData.user) throw new Error('No authenticated user');
// Create and claim submission
const { data: submission, error: createError } = await supabase
.from('content_submissions')
.insert({
user_id: userData.user.id,
submission_type: 'park',
status: 'pending',
content: { test: true }
})
.select()
.single();
if (createError) throw createError;
const initialLockTime = new Date(Date.now() + 15 * 60 * 1000);
await supabase
.from('content_submissions')
.update({
assigned_to: userData.user.id,
locked_until: initialLockTime.toISOString()
})
.eq('id', submission.id);
// Get initial lock time
const { data: initialLock } = await supabase
.from('content_submissions')
.select('locked_until')
.eq('id', submission.id)
.single();
// Extend lock (add 15 more minutes)
const extendedLockTime = new Date(initialLockTime.getTime() + 15 * 60 * 1000);
const { error: extendError } = await supabase
.from('content_submissions')
.update({
locked_until: extendedLockTime.toISOString()
})
.eq('id', submission.id);
if (extendError) throw new Error(`extend_lock failed: ${extendError.message}`);
// Verify extended lock
const { data: extendedLock, error: fetchError } = await supabase
.from('content_submissions')
.select('locked_until')
.eq('id', submission.id)
.single();
if (fetchError) throw fetchError;
if (!initialLock?.locked_until || !extendedLock.locked_until) {
throw new Error('Lock times not found');
}
const initialTime = new Date(initialLock.locked_until);
const extendedTime = new Date(extendedLock.locked_until);
const diffMinutes = (extendedTime.getTime() - initialTime.getTime()) / (1000 * 60);
if (diffMinutes < 14 || diffMinutes > 16) {
throw new Error(`Extension duration incorrect: ${diffMinutes} minutes`);
}
// Cleanup
await supabase.from('content_submissions').delete().eq('id', submission.id);
return {
id: 'lock-003',
name: 'Extend Lock Adds 15 Minutes',
suite: 'Moderation Lock Management',
status: 'pass',
duration: Date.now() - startTime,
timestamp: new Date().toISOString(),
details: {
extensionMinutes: diffMinutes
}
};
} catch (error) {
return {
id: 'lock-003',
name: 'Extend Lock Adds 15 Minutes',
suite: 'Moderation Lock Management',
status: 'fail',
duration: Date.now() - startTime,
error: error instanceof Error ? error.message : String(error),
timestamp: new Date().toISOString()
};
}
}
}
]
};