/** * Cross-Schema Data Validation Tests * Validates data consistency between CONTAFIN_ORACLE authentication schema * and ROMFAST company data, ensuring proper Oracle data flow */ import { test, expect } from '@playwright/test'; import { authenticateWithRealCredentials, getRealCompanies, selectCompany, REAL_CREDENTIALS, API_ENDPOINTS } from '../../utils/real-auth.js'; import { setupConsoleCapture, assertNoCriticalErrors, generateErrorReport } from '../../utils/console-monitor.js'; test.describe('Oracle Cross-Schema Data Consistency', () => { test.beforeEach(async ({ page }) => { setupConsoleCapture(page); }); test.afterEach(async ({ page }) => { const report = generateErrorReport(page, test.info().title); if (report.summary.classifications.critical > 0) { console.warn('🚨 Critical errors in data consistency test:', report.details.criticalErrors); } }); test('should validate CONTAFIN_ORACLE → ROMFAST data flow', async ({ page }) => { console.log('🔄 Testing Oracle cross-schema data flow...'); // Authenticate with CONTAFIN_ORACLE schema credentials const authResult = await authenticateWithRealCredentials(page); expect(authResult.success, 'CONTAFIN_ORACLE authentication failed').toBe(true); console.log('✅ CONTAFIN_ORACLE authentication successful'); // Test companies endpoint returns ROMFAST from NOM_FIRME table console.log('đŸĸ Validating companies data from NOM_FIRME...'); const companiesResponse = await page.request.get(`${API_ENDPOINTS.backend}${API_ENDPOINTS.companies}`); expect(companiesResponse.status()).toBe(200); const companies = await companiesResponse.json(); expect(companies).toBeInstanceOf(Array); expect(companies.length).toBeGreaterThan(0); console.log(`📊 Found ${companies.length} companies in NOM_FIRME table`); // Validate ROMFAST company exists const romfast = companies.find(c => c.id_firma === 'ROMFAST'); expect(romfast, 'ROMFAST company not found in NOM_FIRME table').toBeDefined(); expect(romfast.name).toContain('ROMFAST'); console.log('✅ ROMFAST company validated in NOM_FIRME table:', romfast); // Validate company data structure matches Oracle schema expect(romfast).toHaveProperty('id_firma'); expect(romfast).toHaveProperty('name'); // Additional Oracle-specific fields that might be present const oracleFields = ['cui', 'reg_com', 'adresa', 'telefon', 'email']; oracleFields.forEach(field => { if (romfast.hasOwnProperty(field)) { console.log(`â„šī¸ Oracle field '${field}' present:`, romfast[field]); } }); console.log('✅ Cross-schema authentication and company data flow validated'); }); test('should validate invoice schema consistency', async ({ page }) => { console.log('📋 Validating invoice data schema consistency...'); await authenticateWithRealCredentials(page); await selectCompany(page, REAL_CREDENTIALS.company); // Get invoices data for ROMFAST console.log('đŸ“Ĩ Fetching ROMFAST invoice data...'); const invoicesResponse = await page.request.get(`${API_ENDPOINTS.backend}/api/invoices/ROMFAST`); expect(invoicesResponse.status()).toBe(200); const invoicesData = await invoicesResponse.json(); expect(invoicesData).toHaveProperty('data'); expect(invoicesData.data).toBeInstanceOf(Array); if (invoicesData.data.length > 0) { const sampleInvoice = invoicesData.data[0]; console.log('📋 Sample invoice structure:', Object.keys(sampleInvoice)); // Validate Oracle-specific invoice fields are present const requiredOracleFields = [ 'numar_factura', // Invoice number 'data_scadenta', // Due date 'suma_totala' // Total amount ]; requiredOracleFields.forEach(field => { expect(sampleInvoice, `Missing Oracle field: ${field}`).toHaveProperty(field); console.log(`✅ Oracle field '${field}':`, sampleInvoice[field]); }); // Validate data types expect(typeof sampleInvoice.numar_factura).toBe('string'); expect(sampleInvoice.suma_totala).toBeGreaterThanOrEqual(0); // Validate date format (should be ISO string or valid date) if (sampleInvoice.data_scadenta) { const date = new Date(sampleInvoice.data_scadenta); expect(date.toString()).not.toBe('Invalid Date'); console.log(`✅ Date validation passed: ${sampleInvoice.data_scadenta}`); } console.log(`✅ Invoice schema validation passed (${invoicesData.data.length} invoices)`); } else { console.log('â„šī¸ No invoice data found for ROMFAST - schema validation skipped'); } // Check for console errors during data retrieval assertNoCriticalErrors(page, expect); }); test('should validate payment schema consistency', async ({ page }) => { console.log('💰 Validating payment data schema consistency...'); await authenticateWithRealCredentials(page); await selectCompany(page, REAL_CREDENTIALS.company); // Get payments data for ROMFAST console.log('đŸ’ŗ Fetching ROMFAST payment data...'); const paymentsResponse = await page.request.get(`${API_ENDPOINTS.backend}/api/payments/ROMFAST`); expect(paymentsResponse.status()).toBe(200); const paymentsData = await paymentsResponse.json(); expect(paymentsData).toHaveProperty('data'); expect(paymentsData.data).toBeInstanceOf(Array); if (paymentsData.data.length > 0) { const samplePayment = paymentsData.data[0]; console.log('đŸ’ŗ Sample payment structure:', Object.keys(samplePayment)); // Validate Oracle-specific payment fields const requiredOracleFields = [ 'numar_plata', // Payment number 'data_plata', // Payment date 'suma_plata' // Payment amount ]; requiredOracleFields.forEach(field => { expect(samplePayment, `Missing Oracle payment field: ${field}`).toHaveProperty(field); console.log(`✅ Oracle payment field '${field}':`, samplePayment[field]); }); // Validate payment data types expect(typeof samplePayment.numar_plata).toBe('string'); expect(samplePayment.suma_plata).toBeGreaterThanOrEqual(0); // Validate payment date if (samplePayment.data_plata) { const date = new Date(samplePayment.data_plata); expect(date.toString()).not.toBe('Invalid Date'); console.log(`✅ Payment date validation passed: ${samplePayment.data_plata}`); } console.log(`✅ Payment schema validation passed (${paymentsData.data.length} payments)`); } else { console.log('â„šī¸ No payment data found for ROMFAST - schema validation skipped'); } // Check for console errors during data retrieval assertNoCriticalErrors(page, expect); }); test('should validate user permissions across schemas', async ({ page }) => { console.log('🔐 Validating user permissions across Oracle schemas...'); const authResult = await authenticateWithRealCredentials(page); expect(authResult.success).toBe(true); // Test access to different endpoints with authenticated user const endpointsToTest = [ { url: '/api/companies', name: 'Companies List', expectAccess: true }, { url: '/api/invoices/ROMFAST', name: 'ROMFAST Invoices', expectAccess: true }, { url: '/api/payments/ROMFAST', name: 'ROMFAST Payments', expectAccess: true }, { url: '/api/user/profile', name: 'User Profile', expectAccess: true }, { url: '/api/admin/users', name: 'Admin Users', expectAccess: false } // Should fail ]; const accessResults = []; for (const endpoint of endpointsToTest) { console.log(`🔍 Testing access to ${endpoint.name}...`); try { const response = await page.request.get(`${API_ENDPOINTS.backend}${endpoint.url}`); const hasAccess = response.status() < 400; accessResults.push({ endpoint: endpoint.name, url: endpoint.url, status: response.status(), hasAccess: hasAccess, expectAccess: endpoint.expectAccess }); if (endpoint.expectAccess) { expect(hasAccess, `Expected access to ${endpoint.name} but got ${response.status()}`).toBe(true); console.log(`✅ ${endpoint.name}: Access granted (${response.status()})`); } else { expect(hasAccess, `Expected no access to ${endpoint.name} but got ${response.status()}`).toBe(false); console.log(`✅ ${endpoint.name}: Access denied as expected (${response.status()})`); } } catch (error) { console.log(`âš ī¸ ${endpoint.name}: Request failed - ${error.message}`); accessResults.push({ endpoint: endpoint.name, url: endpoint.url, error: error.message, hasAccess: false, expectAccess: endpoint.expectAccess }); } } // Summary of access results console.log('📊 Permission Validation Summary:'); accessResults.forEach(result => { const status = result.hasAccess === result.expectAccess ? '✅' : '❌'; console.log(` ${status} ${result.endpoint}: ${result.hasAccess ? 'Access' : 'No Access'}`); }); console.log('✅ User permission validation completed'); }); test('should validate data relationships between tables', async ({ page }) => { console.log('🔗 Validating data relationships between Oracle tables...'); await authenticateWithRealCredentials(page); // Get company data const companiesResponse = await page.request.get(`${API_ENDPOINTS.backend}${API_ENDPOINTS.companies}`); const companies = await companiesResponse.json(); const romfast = companies.find(c => c.id_firma === 'ROMFAST'); expect(romfast).toBeDefined(); // Get invoices for ROMFAST const invoicesResponse = await page.request.get(`${API_ENDPOINTS.backend}/api/invoices/ROMFAST`); const invoicesData = await invoicesResponse.json(); // Get payments for ROMFAST const paymentsResponse = await page.request.get(`${API_ENDPOINTS.backend}/api/payments/ROMFAST`); const paymentsData = await paymentsResponse.json(); console.log('📊 Data relationship summary:'); console.log(` Company: ${romfast.name} (${romfast.id_firma})`); console.log(` Invoices: ${invoicesData.data?.length || 0}`); console.log(` Payments: ${paymentsData.data?.length || 0}`); // Validate referential integrity if (invoicesData.data && invoicesData.data.length > 0) { const sampleInvoice = invoicesData.data[0]; // Invoice should reference the company if (sampleInvoice.cod_firma) { expect(sampleInvoice.cod_firma).toBe(romfast.id_firma); console.log('✅ Invoice-Company relationship validated'); } // Check if there are related payments if (paymentsData.data && paymentsData.data.length > 0) { console.log('✅ Payment data exists for company with invoices'); // Look for potential invoice-payment relationships const samplePayment = paymentsData.data[0]; if (samplePayment.cod_firma) { expect(samplePayment.cod_firma).toBe(romfast.id_firma); console.log('✅ Payment-Company relationship validated'); } } } // Validate data consistency const totalInvoicesFromApi = invoicesData.data?.length || 0; const totalPaymentsFromApi = paymentsData.data?.length || 0; // These should be reasonable numbers for a real company if (totalInvoicesFromApi > 0) { console.log(`✅ Company has ${totalInvoicesFromApi} invoices`); } if (totalPaymentsFromApi > 0) { console.log(`✅ Company has ${totalPaymentsFromApi} payments`); } // Check for console errors during relationship validation assertNoCriticalErrors(page, expect); console.log('✅ Data relationship validation completed'); }); test('should validate Oracle connection persistence during operations', async ({ page }) => { console.log('🔄 Testing Oracle connection persistence...'); await authenticateWithRealCredentials(page); // Perform multiple operations to test connection persistence const operations = [ { name: 'Companies Load', action: () => page.request.get(`${API_ENDPOINTS.backend}${API_ENDPOINTS.companies}`) }, { name: 'Invoice Load', action: () => page.request.get(`${API_ENDPOINTS.backend}/api/invoices/ROMFAST`) }, { name: 'Payment Load', action: () => page.request.get(`${API_ENDPOINTS.backend}/api/payments/ROMFAST`) }, { name: 'Health Check', action: () => page.request.get(`${API_ENDPOINTS.backend}${API_ENDPOINTS.health}`) } ]; const connectionResults = []; for (let cycle = 1; cycle <= 3; cycle++) { console.log(`🔄 Connection persistence test cycle ${cycle}/3`); for (const operation of operations) { const startTime = Date.now(); try { const response = await operation.action(); const responseTime = Date.now() - startTime; const success = response.status() < 400; connectionResults.push({ cycle, operation: operation.name, success, status: response.status(), responseTime }); if (success) { console.log(` ✅ ${operation.name}: ${response.status()} (${responseTime}ms)`); } else { console.log(` ❌ ${operation.name}: ${response.status()} (${responseTime}ms)`); } // Brief delay between operations await new Promise(resolve => setTimeout(resolve, 500)); } catch (error) { console.log(` ❌ ${operation.name}: ${error.message}`); connectionResults.push({ cycle, operation: operation.name, success: false, error: error.message }); } } // Delay between cycles await new Promise(resolve => setTimeout(resolve, 1000)); } // Analyze connection persistence const totalOperations = connectionResults.length; const successfulOperations = connectionResults.filter(r => r.success).length; const successRate = (successfulOperations / totalOperations) * 100; console.log('📊 Connection Persistence Analysis:'); console.log(` Total Operations: ${totalOperations}`); console.log(` Successful: ${successfulOperations}`); console.log(` Success Rate: ${successRate.toFixed(1)}%`); // Connection should be persistent (>90% success rate) expect(successRate, 'Oracle connection not persistent enough').toBeGreaterThan(90); // No connection should fail in the same cycle const cycleFailures = {}; connectionResults.filter(r => !r.success).forEach(r => { cycleFailures[r.cycle] = (cycleFailures[r.cycle] || 0) + 1; }); Object.entries(cycleFailures).forEach(([cycle, failures]) => { if (failures === operations.length) { throw new Error(`Complete connection failure in cycle ${cycle}`); } }); console.log('✅ Oracle connection persistence validated'); }); });