From c5d40d07df05acd41a6609fe7ee9c523461d1c57 Mon Sep 17 00:00:00 2001 From: "gpt-engineer-app[bot]" <159125892+gpt-engineer-app[bot]@users.noreply.github.com> Date: Mon, 10 Nov 2025 18:20:22 +0000 Subject: [PATCH] Connect to Lovable Cloud Apply quick wins and pipeline fixes for integration tests: - Remove is_test_data flag from location inserts - Increase test delay from 2.5s to 5s and add delays between suites to curb rate limiting - Replace [object Object] error formatting with formatTestError across 10 test suites (31 edits) and add import - Refactor unit/conversion tests and performance tests to use the approval pipeline - Extend edge function handling by ensuring item_ids are included in idempotency key inserts (edge function fix) - Update auth, data integrity, edgeFunction, moderation, performance, submission, unitConversion, and versioning test files accordingly --- .../helpers/approvalTestHelpers.ts | 1 - src/lib/integrationTests/suites/authTests.ts | 9 +- .../suites/dataIntegrityTests.ts | 9 +- .../suites/edgeFunctionTests.ts | 7 +- .../suites/moderationDependencyTests.ts | 5 +- .../suites/moderationLockTests.ts | 7 +- .../suites/moderationTests.ts | 3 +- .../suites/performanceTests.ts | 51 +++-- .../suites/submissionTests.ts | 9 +- .../suites/unitConversionTests.ts | 213 +++++++++++------- .../suites/versioningTests.ts | 9 +- src/lib/integrationTests/testRunner.ts | 37 ++- .../process-selective-approval/index.ts | 1 + .../process-selective-rejection/index.ts | 1 + 14 files changed, 233 insertions(+), 129 deletions(-) diff --git a/src/lib/integrationTests/helpers/approvalTestHelpers.ts b/src/lib/integrationTests/helpers/approvalTestHelpers.ts index 36bf6916..0ba2caeb 100644 --- a/src/lib/integrationTests/helpers/approvalTestHelpers.ts +++ b/src/lib/integrationTests/helpers/approvalTestHelpers.ts @@ -550,7 +550,6 @@ export async function createParkDirectly( country: data.location.country, latitude: data.location.latitude, longitude: data.location.longitude, - is_test_data: true, }) .select() .single(); diff --git a/src/lib/integrationTests/suites/authTests.ts b/src/lib/integrationTests/suites/authTests.ts index cf79aa2f..f658a31b 100644 --- a/src/lib/integrationTests/suites/authTests.ts +++ b/src/lib/integrationTests/suites/authTests.ts @@ -6,6 +6,7 @@ import { supabase } from '@/lib/supabaseClient'; import type { TestSuite, TestResult } from '../testRunner'; +import { formatTestError } from '../formatTestError'; export const authTestSuite: TestSuite = { id: 'auth', @@ -64,7 +65,7 @@ export const authTestSuite: TestSuite = { suite: 'Authentication & Authorization', status: 'fail', duration, - error: error instanceof Error ? error.message : String(error), + error: formatTestError(error), stack: error instanceof Error ? error.stack : undefined, timestamp: new Date().toISOString() }; @@ -137,7 +138,7 @@ export const authTestSuite: TestSuite = { suite: 'Authentication & Authorization', status: 'fail', duration, - error: error instanceof Error ? error.message : String(error), + error: formatTestError(error), stack: error instanceof Error ? error.stack : undefined, timestamp: new Date().toISOString() }; @@ -187,7 +188,7 @@ export const authTestSuite: TestSuite = { suite: 'Authentication & Authorization', status: 'fail', duration, - error: error instanceof Error ? error.message : String(error), + error: formatTestError(error), stack: error instanceof Error ? error.stack : undefined, timestamp: new Date().toISOString() }; @@ -248,7 +249,7 @@ export const authTestSuite: TestSuite = { suite: 'Authentication & Authorization', status: 'fail', duration, - error: error instanceof Error ? error.message : String(error), + error: formatTestError(error), stack: error instanceof Error ? error.stack : undefined, timestamp: new Date().toISOString() }; diff --git a/src/lib/integrationTests/suites/dataIntegrityTests.ts b/src/lib/integrationTests/suites/dataIntegrityTests.ts index f9a1186e..c3e79e87 100644 --- a/src/lib/integrationTests/suites/dataIntegrityTests.ts +++ b/src/lib/integrationTests/suites/dataIntegrityTests.ts @@ -7,6 +7,7 @@ import { supabase } from '@/lib/supabaseClient'; import type { TestSuite, TestResult } from '../testRunner'; import { TestDataTracker } from '../TestDataTracker'; +import { formatTestError } from '../formatTestError'; export const dataIntegrityTestSuite: TestSuite = { id: 'data-integrity', @@ -77,7 +78,7 @@ export const dataIntegrityTestSuite: TestSuite = { suite: 'Data Integrity & Constraints', status: 'fail', duration, - error: error instanceof Error ? error.message : String(error), + error: formatTestError(error), stack: error instanceof Error ? error.stack : undefined, timestamp: new Date().toISOString() }; @@ -139,7 +140,7 @@ export const dataIntegrityTestSuite: TestSuite = { suite: 'Data Integrity & Constraints', status: 'fail', duration, - error: error instanceof Error ? error.message : String(error), + error: formatTestError(error), stack: error instanceof Error ? error.stack : undefined, timestamp: new Date().toISOString() }; @@ -239,7 +240,7 @@ export const dataIntegrityTestSuite: TestSuite = { suite: 'Data Integrity & Constraints', status: 'fail', duration, - error: error instanceof Error ? error.message : String(error), + error: formatTestError(error), stack: error instanceof Error ? error.stack : undefined, timestamp: new Date().toISOString() }; @@ -305,7 +306,7 @@ export const dataIntegrityTestSuite: TestSuite = { suite: 'Data Integrity & Constraints', status: 'fail', duration, - error: error instanceof Error ? error.message : String(error), + error: formatTestError(error), stack: error instanceof Error ? error.stack : undefined, timestamp: new Date().toISOString() }; diff --git a/src/lib/integrationTests/suites/edgeFunctionTests.ts b/src/lib/integrationTests/suites/edgeFunctionTests.ts index 50ece444..9d36f893 100644 --- a/src/lib/integrationTests/suites/edgeFunctionTests.ts +++ b/src/lib/integrationTests/suites/edgeFunctionTests.ts @@ -6,6 +6,7 @@ import { supabase } from '@/lib/supabaseClient'; import type { TestSuite, TestResult } from '../testRunner'; +import { formatTestError } from '../formatTestError'; export const edgeFunctionTestSuite: TestSuite = { id: 'edge-functions', @@ -68,7 +69,7 @@ export const edgeFunctionTestSuite: TestSuite = { suite: 'Edge Function Tests', status: 'fail', duration: Date.now() - startTime, - error: error instanceof Error ? error.message : String(error), + error: formatTestError(error), timestamp: new Date().toISOString() }; } @@ -121,7 +122,7 @@ export const edgeFunctionTestSuite: TestSuite = { suite: 'Edge Function Tests', status: 'fail', duration: Date.now() - startTime, - error: error instanceof Error ? error.message : String(error), + error: formatTestError(error), timestamp: new Date().toISOString() }; } @@ -187,7 +188,7 @@ export const edgeFunctionTestSuite: TestSuite = { suite: 'Edge Function Tests', status: 'fail', duration: Date.now() - startTime, - error: error instanceof Error ? error.message : String(error), + error: formatTestError(error), timestamp: new Date().toISOString() }; } diff --git a/src/lib/integrationTests/suites/moderationDependencyTests.ts b/src/lib/integrationTests/suites/moderationDependencyTests.ts index 63019a84..07f367e8 100644 --- a/src/lib/integrationTests/suites/moderationDependencyTests.ts +++ b/src/lib/integrationTests/suites/moderationDependencyTests.ts @@ -6,6 +6,7 @@ import { supabase } from '@/lib/supabaseClient'; import type { TestSuite, TestResult } from '../testRunner'; +import { formatTestError } from '../formatTestError'; export const moderationDependencyTestSuite: TestSuite = { id: 'moderation-dependencies', @@ -102,7 +103,7 @@ export const moderationDependencyTestSuite: TestSuite = { suite: 'Multi-Item Dependency Resolution', status: 'fail', duration: Date.now() - startTime, - error: error instanceof Error ? error.message : String(error), + error: formatTestError(error), timestamp: new Date().toISOString() }; } @@ -144,7 +145,7 @@ export const moderationDependencyTestSuite: TestSuite = { suite: 'Multi-Item Dependency Resolution', status: 'fail', duration: Date.now() - startTime, - error: error instanceof Error ? error.message : String(error), + error: formatTestError(error), timestamp: new Date().toISOString() }; } diff --git a/src/lib/integrationTests/suites/moderationLockTests.ts b/src/lib/integrationTests/suites/moderationLockTests.ts index 77885dae..0ad8cc73 100644 --- a/src/lib/integrationTests/suites/moderationLockTests.ts +++ b/src/lib/integrationTests/suites/moderationLockTests.ts @@ -6,6 +6,7 @@ import { supabase } from '@/lib/supabaseClient'; import type { TestSuite, TestResult } from '../testRunner'; +import { formatTestError } from '../formatTestError'; export const moderationLockTestSuite: TestSuite = { id: 'moderation-locks', @@ -97,7 +98,7 @@ export const moderationLockTestSuite: TestSuite = { suite: 'Moderation Lock Management', status: 'fail', duration: Date.now() - startTime, - error: error instanceof Error ? error.message : String(error), + error: formatTestError(error), timestamp: new Date().toISOString() }; } @@ -183,7 +184,7 @@ export const moderationLockTestSuite: TestSuite = { suite: 'Moderation Lock Management', status: 'fail', duration: Date.now() - startTime, - error: error instanceof Error ? error.message : String(error), + error: formatTestError(error), timestamp: new Date().toISOString() }; } @@ -284,7 +285,7 @@ export const moderationLockTestSuite: TestSuite = { suite: 'Moderation Lock Management', status: 'fail', duration: Date.now() - startTime, - error: error instanceof Error ? error.message : String(error), + error: formatTestError(error), timestamp: new Date().toISOString() }; } diff --git a/src/lib/integrationTests/suites/moderationTests.ts b/src/lib/integrationTests/suites/moderationTests.ts index 53a0d72c..a7e469ee 100644 --- a/src/lib/integrationTests/suites/moderationTests.ts +++ b/src/lib/integrationTests/suites/moderationTests.ts @@ -6,6 +6,7 @@ import { supabase } from '@/lib/supabaseClient'; import type { TestSuite, TestResult } from '../testRunner'; +import { formatTestError } from '../formatTestError'; export const moderationTestSuite: TestSuite = { id: 'moderation', @@ -53,7 +54,7 @@ export const moderationTestSuite: TestSuite = { suite: 'Moderation Queue & Workflow', status: 'fail', duration: Date.now() - startTime, - error: error instanceof Error ? error.message : String(error), + error: formatTestError(error), timestamp: new Date().toISOString() }; } diff --git a/src/lib/integrationTests/suites/performanceTests.ts b/src/lib/integrationTests/suites/performanceTests.ts index c43dc0aa..2254d421 100644 --- a/src/lib/integrationTests/suites/performanceTests.ts +++ b/src/lib/integrationTests/suites/performanceTests.ts @@ -7,6 +7,7 @@ import { supabase } from '@/lib/supabaseClient'; import type { TestSuite, TestResult } from '../testRunner'; import { TestDataTracker } from '../TestDataTracker'; +import { formatTestError } from '../formatTestError'; export const performanceTestSuite: TestSuite = { id: 'performance', @@ -96,7 +97,7 @@ export const performanceTestSuite: TestSuite = { suite: 'Performance & Scalability', status: 'fail', duration: Date.now() - startTime, - error: error instanceof Error ? error.message : String(error), + error: formatTestError(error), timestamp: new Date().toISOString() }; } @@ -112,22 +113,36 @@ export const performanceTestSuite: TestSuite = { let parkId: string | null = null; try { - // Create test park - const parkSlug = `test-park-perf-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`; - const { data: park, error: parkError } = await supabase - .from('parks') - .insert({ - name: 'Test Park Performance', - slug: parkSlug, - park_type: 'theme_park', - status: 'operating', - is_test_data: true - }) - .select('id') - .single(); + // Import helpers and create park via pipeline + const { + getCurrentUserId, + getAuthToken, + generateUniqueParkData, + createTestParkSubmission, + approveSubmission + } = await import('../helpers/approvalTestHelpers'); + + const userId = await getCurrentUserId(); + const authToken = await getAuthToken(); + const parkData = generateUniqueParkData('perf-002'); - if (parkError) throw new Error(`Park creation failed: ${parkError.message}`); - parkId = park.id; + const { submissionId, itemId } = await createTestParkSubmission(parkData, userId, tracker); + const approval = await approveSubmission(submissionId, [itemId], authToken); + + if (!approval.success) { + throw new Error(`Park creation failed: ${approval.error || 'Unknown error'}`); + } + + // Get park ID from submission item + const { data: parkItem } = await supabase + .from('submission_items') + .select('approved_entity_id') + .eq('id', itemId) + .single(); + + parkId = parkItem?.approved_entity_id || null; + if (!parkId) throw new Error('No park ID after approval'); + tracker.track('parks', parkId); // Create multiple versions (updates) @@ -182,7 +197,7 @@ export const performanceTestSuite: TestSuite = { suite: 'Performance & Scalability', status: 'fail', duration: Date.now() - startTime, - error: error instanceof Error ? error.message : String(error), + error: formatTestError(error), timestamp: new Date().toISOString() }; } finally { @@ -265,7 +280,7 @@ export const performanceTestSuite: TestSuite = { suite: 'Performance & Scalability', status: 'fail', duration: Date.now() - startTime, - error: error instanceof Error ? error.message : String(error), + error: formatTestError(error), timestamp: new Date().toISOString() }; } diff --git a/src/lib/integrationTests/suites/submissionTests.ts b/src/lib/integrationTests/suites/submissionTests.ts index 21c36bd3..bc1d4b27 100644 --- a/src/lib/integrationTests/suites/submissionTests.ts +++ b/src/lib/integrationTests/suites/submissionTests.ts @@ -8,6 +8,7 @@ import { supabase } from '@/lib/supabaseClient'; import type { TestSuite, TestResult } from '../testRunner'; import { TestDataTracker } from '../TestDataTracker'; +import { formatTestError } from '../formatTestError'; import { generateUniqueParkData, generateUniqueRideData, @@ -115,7 +116,7 @@ export const submissionTestSuite: TestSuite = { suite: 'Entity Submission & Validation', status: 'fail', duration: Date.now() - startTime, - error: error instanceof Error ? error.message : String(error), + error: formatTestError(error), timestamp: new Date().toISOString() }; } finally { @@ -208,7 +209,7 @@ export const submissionTestSuite: TestSuite = { suite: 'Entity Submission & Validation', status: 'fail', duration: Date.now() - startTime, - error: error instanceof Error ? error.message : String(error), + error: formatTestError(error), timestamp: new Date().toISOString() }; } finally { @@ -295,7 +296,7 @@ export const submissionTestSuite: TestSuite = { suite: 'Entity Submission & Validation', status: 'fail', duration: Date.now() - startTime, - error: error instanceof Error ? error.message : String(error), + error: formatTestError(error), timestamp: new Date().toISOString() }; } finally { @@ -404,7 +405,7 @@ export const submissionTestSuite: TestSuite = { suite: 'Entity Submission & Validation', status: 'fail', duration: Date.now() - startTime, - error: error instanceof Error ? error.message : String(error), + error: formatTestError(error), timestamp: new Date().toISOString() }; } finally { diff --git a/src/lib/integrationTests/suites/unitConversionTests.ts b/src/lib/integrationTests/suites/unitConversionTests.ts index 63fe8ee0..34ad89f9 100644 --- a/src/lib/integrationTests/suites/unitConversionTests.ts +++ b/src/lib/integrationTests/suites/unitConversionTests.ts @@ -7,6 +7,7 @@ import { supabase } from '@/lib/supabaseClient'; import type { TestSuite, TestResult } from '../testRunner'; import { TestDataTracker } from '../TestDataTracker'; +import { formatTestError } from '../formatTestError'; export const unitConversionTestSuite: TestSuite = { id: 'unit-conversion', @@ -24,65 +25,93 @@ export const unitConversionTestSuite: TestSuite = { let rideId: string | null = null; try { - // Create test park - const parkSlug = `test-park-units-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`; - const { data: park, error: parkError } = await supabase - .from('parks') - .insert({ - name: 'Test Park Units', - slug: parkSlug, - park_type: 'theme_park', - status: 'operating', - is_test_data: true - }) - .select('id') - .single(); + // Import helpers and create via pipeline + const { + getCurrentUserId, + getAuthToken, + generateUniqueParkData, + generateUniqueRideData, + createTestParkSubmission, + createTestRideSubmission, + approveSubmission + } = await import('../helpers/approvalTestHelpers'); + + const userId = await getCurrentUserId(); + const authToken = await getAuthToken(); + + // Create and approve park + const parkData = generateUniqueParkData('unit-001-park'); + const { submissionId: parkSubId, itemId: parkItemId } = await createTestParkSubmission(parkData, userId, tracker); + const parkApproval = await approveSubmission(parkSubId, [parkItemId], authToken); - if (parkError) throw new Error(`Park creation failed: ${parkError.message}`); - parkId = park.id; + if (!parkApproval.success) { + throw new Error(`Park creation failed: ${parkApproval.error || 'Unknown error'}`); + } + + // Get park ID from submission item + const { data: parkItem } = await supabase + .from('submission_items') + .select('approved_entity_id') + .eq('id', parkItemId) + .single(); + + parkId = parkItem?.approved_entity_id || null; + if (!parkId) throw new Error('No park ID after approval'); + tracker.track('parks', parkId); - // Create ride with metric values - const rideSlug = `test-ride-units-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`; - const testData = { - name: 'Test Ride Metric', - slug: rideSlug, - park_id: parkId, - category: 'roller_coaster', - status: 'operating', - max_speed_kmh: 100.0, // km/h (metric) - max_height_meters: 50.0, // meters (metric) - length_meters: 1000.0, // meters (metric) - drop_height_meters: 45.0, // meters (metric) - height_requirement: 120 // cm (metric) + // Create and approve ride with metric values + const rideData = { + ...generateUniqueRideData(parkId, 'unit-001-ride'), + max_speed_kmh: 100.0, + max_height_meters: 50.0, + length_meters: 1000.0, + drop_height_meters: 45.0, + height_requirement: 120 }; + + const { submissionId: rideSubId, itemId: rideItemId } = await createTestRideSubmission(rideData, userId, tracker); + const rideApproval = await approveSubmission(rideSubId, [rideItemId], authToken); - const { data: ride, error: rideError } = await supabase - .from('rides') - .insert({ ...testData, is_test_data: true }) - .select('id, max_speed_kmh, max_height_meters, length_meters, drop_height_meters, height_requirement') + if (!rideApproval.success) { + throw new Error(`Ride creation failed: ${rideApproval.error || 'Unknown error'}`); + } + + // Get ride ID from submission item + const { data: rideItem } = await supabase + .from('submission_items') + .select('approved_entity_id') + .eq('id', rideItemId) .single(); - if (rideError) throw new Error(`Ride creation failed: ${rideError.message}`); - if (!ride) throw new Error('Ride not returned'); - - rideId = ride.id; + rideId = rideItem?.approved_entity_id || null; + if (!rideId) throw new Error('No ride ID after approval'); + tracker.track('rides', rideId); + + // Fetch ride data for validation + const { data: ride, error: rideError } = await supabase + .from('rides') + .select('id, max_speed_kmh, max_height_meters, length_meters, drop_height_meters, height_requirement') + .eq('id', rideId) + .single(); + + if (rideError || !ride) throw new Error('Ride not found after creation'); // Validate values are stored in metric - const tolerance = 0.01; // Allow small floating point differences + const tolerance = 0.01; - if (Math.abs((ride.max_speed_kmh ?? 0) - testData.max_speed_kmh) > tolerance) { - throw new Error(`max_speed_kmh mismatch: expected ${testData.max_speed_kmh}, got ${ride.max_speed_kmh}`); + if (Math.abs((ride.max_speed_kmh ?? 0) - 100.0) > tolerance) { + throw new Error(`max_speed_kmh mismatch: expected 100.0, got ${ride.max_speed_kmh}`); } - if (Math.abs((ride.max_height_meters ?? 0) - testData.max_height_meters) > tolerance) { - throw new Error(`max_height_meters mismatch: expected ${testData.max_height_meters}, got ${ride.max_height_meters}`); + if (Math.abs((ride.max_height_meters ?? 0) - 50.0) > tolerance) { + throw new Error(`max_height_meters mismatch: expected 50.0, got ${ride.max_height_meters}`); } - if (Math.abs((ride.length_meters ?? 0) - testData.length_meters) > tolerance) { - throw new Error(`length_meters mismatch: expected ${testData.length_meters}, got ${ride.length_meters}`); + if (Math.abs((ride.length_meters ?? 0) - 1000.0) > tolerance) { + throw new Error(`length_meters mismatch: expected 1000.0, got ${ride.length_meters}`); } - if (Math.abs((ride.height_requirement ?? 0) - testData.height_requirement) > tolerance) { - throw new Error(`height_requirement mismatch: expected ${testData.height_requirement} cm, got ${ride.height_requirement}`); + if (Math.abs((ride.height_requirement ?? 0) - 120) > tolerance) { + throw new Error(`height_requirement mismatch: expected 120 cm, got ${ride.height_requirement}`); } const duration = Date.now() - startTime; @@ -108,7 +137,7 @@ export const unitConversionTestSuite: TestSuite = { suite: 'Unit Conversion Tests', status: 'fail', duration: Date.now() - startTime, - error: error instanceof Error ? error.message : String(error), + error: formatTestError(error), timestamp: new Date().toISOString() }; } finally { @@ -131,44 +160,66 @@ export const unitConversionTestSuite: TestSuite = { let rideId: string | null = null; try { - // Create test park - const parkSlug = `test-park-ver-units-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`; - const { data: park, error: parkError } = await supabase - .from('parks') - .insert({ - name: 'Test Park Version Units', - slug: parkSlug, - park_type: 'theme_park', - status: 'operating', - is_test_data: true - }) - .select('id') - .single(); + // Import helpers and create via pipeline + const { + getCurrentUserId, + getAuthToken, + generateUniqueParkData, + generateUniqueRideData, + createTestParkSubmission, + createTestRideSubmission, + approveSubmission + } = await import('../helpers/approvalTestHelpers'); + + const userId = await getCurrentUserId(); + const authToken = await getAuthToken(); + + // Create and approve park + const parkData = generateUniqueParkData('unit-002-park'); + const { submissionId: parkSubId, itemId: parkItemId } = await createTestParkSubmission(parkData, userId, tracker); + const parkApproval = await approveSubmission(parkSubId, [parkItemId], authToken); - if (parkError) throw new Error(`Park creation failed: ${parkError.message}`); - parkId = park.id; + if (!parkApproval.success) { + throw new Error(`Park creation failed: ${parkApproval.error || 'Unknown error'}`); + } + + // Get park ID from submission item + const { data: parkItem } = await supabase + .from('submission_items') + .select('approved_entity_id') + .eq('id', parkItemId) + .single(); + + parkId = parkItem?.approved_entity_id || null; + if (!parkId) throw new Error('No park ID after approval'); + tracker.track('parks', parkId); - // Create ride with metric values - const rideSlug = `test-ride-ver-units-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`; - const { data: ride, error: rideError } = await supabase - .from('rides') - .insert({ - name: 'Test Ride Version Metric', - slug: rideSlug, - park_id: parkId, - category: 'roller_coaster', - status: 'operating', - max_speed_kmh: 120.0, - max_height_meters: 60.0, - height_requirement: 140, - is_test_data: true - }) - .select('id') + // Create and approve ride with metric values + const rideData = { + ...generateUniqueRideData(parkId, 'unit-002-ride'), + max_speed_kmh: 120.0, + max_height_meters: 60.0, + height_requirement: 140 + }; + + const { submissionId: rideSubId, itemId: rideItemId } = await createTestRideSubmission(rideData, userId, tracker); + const rideApproval = await approveSubmission(rideSubId, [rideItemId], authToken); + + if (!rideApproval.success) { + throw new Error(`Ride creation failed: ${rideApproval.error || 'Unknown error'}`); + } + + // Get ride ID from submission item + const { data: rideItem } = await supabase + .from('submission_items') + .select('approved_entity_id') + .eq('id', rideItemId) .single(); - if (rideError) throw new Error(`Ride creation failed: ${rideError.message}`); - rideId = ride.id; + rideId = rideItem?.approved_entity_id || null; + if (!rideId) throw new Error('No ride ID after approval'); + tracker.track('rides', rideId); // Poll for version creation @@ -226,7 +277,7 @@ export const unitConversionTestSuite: TestSuite = { suite: 'Unit Conversion Tests', status: 'fail', duration: Date.now() - startTime, - error: error instanceof Error ? error.message : String(error), + error: formatTestError(error), timestamp: new Date().toISOString() }; } finally { @@ -307,7 +358,7 @@ export const unitConversionTestSuite: TestSuite = { suite: 'Unit Conversion Tests', status: 'fail', duration: Date.now() - startTime, - error: error instanceof Error ? error.message : String(error), + error: formatTestError(error), timestamp: new Date().toISOString() }; } diff --git a/src/lib/integrationTests/suites/versioningTests.ts b/src/lib/integrationTests/suites/versioningTests.ts index 63e1ff3b..d74e15d0 100644 --- a/src/lib/integrationTests/suites/versioningTests.ts +++ b/src/lib/integrationTests/suites/versioningTests.ts @@ -10,6 +10,7 @@ import { supabase } from '@/lib/supabaseClient'; import type { TestSuite, TestResult } from '../testRunner'; import { TestDataTracker } from '../TestDataTracker'; +import { formatTestError } from '../formatTestError'; import { generateUniqueParkData, createTestParkSubmission, @@ -106,7 +107,7 @@ export const versioningTestSuite: TestSuite = { suite: 'Versioning & Rollback', status: 'fail', duration, - error: error instanceof Error ? error.message : String(error), + error: formatTestError(error), stack: error instanceof Error ? error.stack : undefined, timestamp: new Date().toISOString() }; @@ -211,7 +212,7 @@ export const versioningTestSuite: TestSuite = { suite: 'Versioning & Rollback', status: 'fail', duration, - error: error instanceof Error ? error.message : String(error), + error: formatTestError(error), stack: error instanceof Error ? error.stack : undefined, timestamp: new Date().toISOString() }; @@ -304,7 +305,7 @@ export const versioningTestSuite: TestSuite = { suite: 'Versioning & Rollback', status: 'fail', duration, - error: error instanceof Error ? error.message : String(error), + error: formatTestError(error), stack: error instanceof Error ? error.stack : undefined, timestamp: new Date().toISOString() }; @@ -441,7 +442,7 @@ export const versioningTestSuite: TestSuite = { suite: 'Versioning & Rollback', status: 'fail', duration, - error: error instanceof Error ? error.message : String(error), + error: formatTestError(error), stack: error instanceof Error ? error.stack : undefined, timestamp: new Date().toISOString() }; diff --git a/src/lib/integrationTests/testRunner.ts b/src/lib/integrationTests/testRunner.ts index 3bc4ebc9..7f8abc7e 100644 --- a/src/lib/integrationTests/testRunner.ts +++ b/src/lib/integrationTests/testRunner.ts @@ -53,9 +53,9 @@ export class IntegrationTestRunner { private onProgress?: (result: TestResult) => void; private delayBetweenTests: number; - constructor(onProgress?: (result: TestResult) => void, delayBetweenTests: number = 2500) { + constructor(onProgress?: (result: TestResult) => void, delayBetweenTests: number = 5000) { this.onProgress = onProgress; - this.delayBetweenTests = delayBetweenTests; // Default 2.5 seconds to prevent rate limiting + this.delayBetweenTests = delayBetweenTests; // Default 5 seconds to prevent rate limiting } /** @@ -189,12 +189,41 @@ export class IntegrationTestRunner { this.isRunning = true; this.shouldStop = false; - for (const suite of suites) { - await this.runSuite(suite); + for (let i = 0; i < suites.length; i++) { + await this.runSuite(suites[i]); if (this.shouldStop) { break; } + + // Add delay between suites to prevent rate limiting + if (i < suites.length - 1 && this.delayBetweenTests > 0) { + const delaySeconds = this.delayBetweenTests / 1000; + const delayResult: TestResult = { + id: `suite-delay-${Date.now()}`, + name: `⏳ Suite completion delay: ${delaySeconds}s`, + suite: 'System', + status: 'running', + duration: 0, + timestamp: new Date().toISOString(), + details: { reason: 'Pausing between suites to prevent rate limiting' } + }; + + if (this.onProgress) { + this.onProgress(delayResult); + } + + await this.delay(this.delayBetweenTests); + + if (this.onProgress) { + this.onProgress({ + ...delayResult, + status: 'skip', + duration: this.delayBetweenTests, + details: { reason: 'Suite delay completed' } + }); + } + } } this.isRunning = false; diff --git a/supabase/functions/process-selective-approval/index.ts b/supabase/functions/process-selective-approval/index.ts index 2fed9865..c5d3997f 100644 --- a/supabase/functions/process-selective-approval/index.ts +++ b/supabase/functions/process-selective-approval/index.ts @@ -259,6 +259,7 @@ const handler = async (req: Request) => { idempotency_key: idempotencyKey, submission_id: submissionId, moderator_id: user.id, + item_ids: itemIds, status: 'processing' }) .select() diff --git a/supabase/functions/process-selective-rejection/index.ts b/supabase/functions/process-selective-rejection/index.ts index 133cf831..9cb817cb 100644 --- a/supabase/functions/process-selective-rejection/index.ts +++ b/supabase/functions/process-selective-rejection/index.ts @@ -262,6 +262,7 @@ const handler = async (req: Request) => { idempotency_key: idempotencyKey, submission_id: submissionId, moderator_id: user.id, + item_ids: itemIds, status: 'processing' }) .select()