mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-21 21:51:12 -05:00
Refactor code structure and remove redundant changes
This commit is contained in:
300
src-old/lib/integrationTests/suites/dataIntegrityTests.ts
Normal file
300
src-old/lib/integrationTests/suites/dataIntegrityTests.ts
Normal file
@@ -0,0 +1,300 @@
|
||||
/**
|
||||
* Data Integrity & Constraints Test Suite
|
||||
*
|
||||
* Tests database constraints, RLS policies, and data integrity rules.
|
||||
*/
|
||||
|
||||
import { supabase } from '@/lib/supabaseClient';
|
||||
import type { TestSuite, TestResult } from '../testRunner';
|
||||
import { TestDataTracker } from '../TestDataTracker';
|
||||
|
||||
export const dataIntegrityTestSuite: TestSuite = {
|
||||
id: 'data-integrity',
|
||||
name: 'Data Integrity & Constraints',
|
||||
description: 'Tests database constraints, RLS policies, and data integrity',
|
||||
tests: [
|
||||
{
|
||||
id: 'integrity-001',
|
||||
name: 'RLS Policy Enforcement - Public Read',
|
||||
description: 'Validates public read access to entity tables',
|
||||
run: async (): Promise<TestResult> => {
|
||||
const startTime = Date.now();
|
||||
|
||||
try {
|
||||
// Test public read access to parks
|
||||
const { data: parks, error: parksError } = await supabase
|
||||
.from('parks')
|
||||
.select('id, name, slug')
|
||||
.limit(5);
|
||||
|
||||
if (parksError) throw new Error(`Parks read failed: ${parksError.message}`);
|
||||
|
||||
// Test public read access to rides
|
||||
const { data: rides, error: ridesError } = await supabase
|
||||
.from('rides')
|
||||
.select('id, name, slug')
|
||||
.limit(5);
|
||||
|
||||
if (ridesError) throw new Error(`Rides read failed: ${ridesError.message}`);
|
||||
|
||||
// Test public read access to companies
|
||||
const { data: companies, error: companiesError } = await supabase
|
||||
.from('companies')
|
||||
.select('id, name, slug')
|
||||
.limit(5);
|
||||
|
||||
if (companiesError) throw new Error(`Companies read failed: ${companiesError.message}`);
|
||||
|
||||
// Test public read access to ride_models
|
||||
const { data: models, error: modelsError } = await supabase
|
||||
.from('ride_models')
|
||||
.select('id, name, slug')
|
||||
.limit(5);
|
||||
|
||||
if (modelsError) throw new Error(`Ride models read failed: ${modelsError.message}`);
|
||||
|
||||
const duration = Date.now() - startTime;
|
||||
|
||||
return {
|
||||
id: 'integrity-001',
|
||||
name: 'RLS Policy Enforcement - Public Read',
|
||||
suite: 'Data Integrity & Constraints',
|
||||
status: 'pass',
|
||||
duration,
|
||||
timestamp: new Date().toISOString(),
|
||||
details: {
|
||||
parksReadable: Array.isArray(parks),
|
||||
ridesReadable: Array.isArray(rides),
|
||||
companiesReadable: Array.isArray(companies),
|
||||
rideModelsReadable: Array.isArray(models)
|
||||
}
|
||||
};
|
||||
} catch (error) {
|
||||
const duration = Date.now() - startTime;
|
||||
return {
|
||||
id: 'integrity-001',
|
||||
name: 'RLS Policy Enforcement - Public Read',
|
||||
suite: 'Data Integrity & Constraints',
|
||||
status: 'fail',
|
||||
duration,
|
||||
error: error instanceof Error ? error.message : String(error),
|
||||
stack: error instanceof Error ? error.stack : undefined,
|
||||
timestamp: new Date().toISOString()
|
||||
};
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
id: 'integrity-002',
|
||||
name: 'Foreign Key Constraint Enforcement',
|
||||
description: 'Tests foreign key constraints prevent invalid references',
|
||||
run: async (): Promise<TestResult> => {
|
||||
const startTime = Date.now();
|
||||
|
||||
try {
|
||||
// Try to create a ride with non-existent park_id
|
||||
const invalidParkId = '00000000-0000-0000-0000-000000000000';
|
||||
const slug = `test-ride-${Date.now()}`;
|
||||
|
||||
const { error } = await supabase
|
||||
.from('rides')
|
||||
.insert({
|
||||
name: 'Invalid Ride',
|
||||
slug,
|
||||
park_id: invalidParkId,
|
||||
category: 'roller_coaster',
|
||||
status: 'operating',
|
||||
is_test_data: true
|
||||
});
|
||||
|
||||
// This SHOULD fail with foreign key violation
|
||||
if (!error) {
|
||||
throw new Error('Foreign key constraint not enforced - invalid park_id was accepted');
|
||||
}
|
||||
|
||||
// Verify it's a foreign key violation
|
||||
if (!error.message.includes('foreign key') && !error.message.includes('violates')) {
|
||||
throw new Error(`Expected foreign key error, got: ${error.message}`);
|
||||
}
|
||||
|
||||
const duration = Date.now() - startTime;
|
||||
|
||||
return {
|
||||
id: 'integrity-002',
|
||||
name: 'Foreign Key Constraint Enforcement',
|
||||
suite: 'Data Integrity & Constraints',
|
||||
status: 'pass',
|
||||
duration,
|
||||
timestamp: new Date().toISOString(),
|
||||
details: {
|
||||
constraintEnforced: true,
|
||||
errorMessage: error.message
|
||||
}
|
||||
};
|
||||
} catch (error) {
|
||||
const duration = Date.now() - startTime;
|
||||
return {
|
||||
id: 'integrity-002',
|
||||
name: 'Foreign Key Constraint Enforcement',
|
||||
suite: 'Data Integrity & Constraints',
|
||||
status: 'fail',
|
||||
duration,
|
||||
error: error instanceof Error ? error.message : String(error),
|
||||
stack: error instanceof Error ? error.stack : undefined,
|
||||
timestamp: new Date().toISOString()
|
||||
};
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
id: 'integrity-003',
|
||||
name: 'Unique Constraint Enforcement',
|
||||
description: 'Tests unique constraints prevent duplicate slugs',
|
||||
run: async (): Promise<TestResult> => {
|
||||
const startTime = Date.now();
|
||||
const tracker = new TestDataTracker();
|
||||
let parkId: string | null = null;
|
||||
|
||||
try {
|
||||
// Create a park
|
||||
const slug = `unique-test-${Date.now()}`;
|
||||
const { data: park, error: createError } = await supabase
|
||||
.from('parks')
|
||||
.insert({
|
||||
name: 'Unique Test Park',
|
||||
slug,
|
||||
park_type: 'theme_park',
|
||||
status: 'operating',
|
||||
is_test_data: true
|
||||
})
|
||||
.select('id')
|
||||
.single();
|
||||
|
||||
if (createError) throw new Error(`Park creation failed: ${createError.message}`);
|
||||
if (!park) throw new Error('No park returned');
|
||||
|
||||
parkId = park.id;
|
||||
tracker.track('parks', parkId);
|
||||
|
||||
// Try to create another park with same slug
|
||||
const { error: duplicateError } = await supabase
|
||||
.from('parks')
|
||||
.insert({
|
||||
name: 'Duplicate Park',
|
||||
slug, // Same slug
|
||||
park_type: 'theme_park',
|
||||
status: 'operating',
|
||||
is_test_data: true
|
||||
});
|
||||
|
||||
// This SHOULD fail with unique violation
|
||||
if (!duplicateError) {
|
||||
throw new Error('Unique constraint not enforced - duplicate slug was accepted');
|
||||
}
|
||||
|
||||
// Verify it's a unique violation
|
||||
if (!duplicateError.message.includes('unique') && !duplicateError.message.includes('duplicate')) {
|
||||
throw new Error(`Expected unique constraint error, got: ${duplicateError.message}`);
|
||||
}
|
||||
|
||||
const duration = Date.now() - startTime;
|
||||
|
||||
return {
|
||||
id: 'integrity-003',
|
||||
name: 'Unique Constraint Enforcement',
|
||||
suite: 'Data Integrity & Constraints',
|
||||
status: 'pass',
|
||||
duration,
|
||||
timestamp: new Date().toISOString(),
|
||||
details: {
|
||||
constraintEnforced: true,
|
||||
errorMessage: duplicateError.message
|
||||
}
|
||||
};
|
||||
} catch (error) {
|
||||
const duration = Date.now() - startTime;
|
||||
return {
|
||||
id: 'integrity-003',
|
||||
name: 'Unique Constraint Enforcement',
|
||||
suite: 'Data Integrity & Constraints',
|
||||
status: 'fail',
|
||||
duration,
|
||||
error: error instanceof Error ? error.message : String(error),
|
||||
stack: error instanceof Error ? error.stack : undefined,
|
||||
timestamp: new Date().toISOString()
|
||||
};
|
||||
} finally {
|
||||
await tracker.cleanup();
|
||||
const remaining = await tracker.verifyCleanup();
|
||||
if (remaining.length > 0) {
|
||||
console.warn('integrity-003 cleanup incomplete:', remaining);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
id: 'integrity-004',
|
||||
name: 'No JSONB in Entity Tables',
|
||||
description: 'Validates no JSONB columns exist in entity tables (per requirements)',
|
||||
run: async (): Promise<TestResult> => {
|
||||
const startTime = Date.now();
|
||||
|
||||
try {
|
||||
// Sample actual data and check structure (information_schema not accessible via RLS)
|
||||
const { data: parks } = await supabase.from('parks').select('*').limit(1);
|
||||
const { data: rides } = await supabase.from('rides').select('*').limit(1);
|
||||
const { data: companies } = await supabase.from('companies').select('*').limit(1);
|
||||
const { data: models } = await supabase.from('ride_models').select('*').limit(1);
|
||||
|
||||
// Check if any fields appear to be JSONB objects
|
||||
const hasJsonbFields = [parks, rides, companies, models].some(dataset => {
|
||||
if (!dataset || dataset.length === 0) return false;
|
||||
const record = dataset[0] as any;
|
||||
return Object.keys(record).some(key => {
|
||||
const val = record[key];
|
||||
// Check if value is a plain object (not Date, not Array, not null)
|
||||
if (val === null || val === undefined) return false;
|
||||
if (typeof val !== 'object') return false;
|
||||
if (Array.isArray(val)) return false;
|
||||
// Check if it's a Date by checking if it has getTime method
|
||||
if (val && typeof val.getTime === 'function') return false;
|
||||
// If we get here, it's likely a JSONB object
|
||||
return true;
|
||||
});
|
||||
});
|
||||
|
||||
if (hasJsonbFields) {
|
||||
throw new Error('Found JSONB-like fields in entity tables');
|
||||
}
|
||||
|
||||
const duration = Date.now() - startTime;
|
||||
|
||||
return {
|
||||
id: 'integrity-004',
|
||||
name: 'No JSONB in Entity Tables',
|
||||
suite: 'Data Integrity & Constraints',
|
||||
status: 'pass',
|
||||
duration,
|
||||
timestamp: new Date().toISOString(),
|
||||
details: {
|
||||
noJsonbColumns: true,
|
||||
validation: 'Entity tables use relational structure only'
|
||||
}
|
||||
};
|
||||
} catch (error) {
|
||||
const duration = Date.now() - startTime;
|
||||
return {
|
||||
id: 'integrity-004',
|
||||
name: 'No JSONB in Entity Tables',
|
||||
suite: 'Data Integrity & Constraints',
|
||||
status: 'fail',
|
||||
duration,
|
||||
error: error instanceof Error ? error.message : String(error),
|
||||
stack: error instanceof Error ? error.stack : undefined,
|
||||
timestamp: new Date().toISOString()
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
Reference in New Issue
Block a user