/** * Test script to verify partner sync worker integration with SatLoc Application Processor * This test simulates the actual partner sync worker workflow */ const path = require('path'); const fs = require('fs').promises; const mongoose = require('mongoose'); // Import the integrated functions from partner sync worker const SatLocApplicationProcessor = require('./helpers/satloc_application_processor'); // Import models const Application = require('./model/application'); const ApplicationFile = require('./model/application_file'); const ApplicationDetail = require('./model/application_detail'); const JobAssign = require('./model/job_assign'); // Test configuration const testConfig = { logFile: './test-logs/Liquid_IF2_G4.log', taskData: { logId: 'test_partner_log_123', logFileName: 'Liquid_IF2_G4.log', localFilePath: './test-logs/Liquid_IF2_G4.log', partnerCode: 'SATLOC', aircraftId: 'N619LF', customerId: 'test_customer_123' }, contextData: { jobId: 123456, // Use Number for jobId as expected by Application model userId: new mongoose.Types.ObjectId(), // Use proper ObjectId for userId uploadedDate: new Date(), meta: { source: 'partner_sync_test', partnerId: 'SATLOC', aircraftId: 'N619LF' } } }; console.log('๐Ÿš€ Starting Partner Sync Worker Integration Test...'); async function testPartnerSyncIntegration() { let dbConnected = false; try { // Connect to database console.log('\n๐Ÿ“ก Connecting to database...'); await mongoose.connect('mongodb://agm:agm@127.0.0.1:27017/agmission?authSource=agmission'); dbConnected = true; console.log('โœ… Database connected successfully'); // Clean up any existing test data console.log('\n๐Ÿงน Cleaning up existing test data...'); await cleanupTestData(); // Test 1: Simulate partner sync worker processing new file console.log('\n=== Test 1: New File Processing ==='); await testNewFileProcessing(); // Test 2: Simulate retry scenario console.log('\n=== Test 2: Retry File Processing ==='); await testRetryFileProcessing(); // Test 3: Verify data structure console.log('\n=== Test 3: Data Structure Verification ==='); await testDataStructure(); console.log('\n๐ŸŽ‰ All integration tests passed!'); } catch (error) { console.error('โŒ Integration test failed:', error); throw error; } finally { if (dbConnected) { console.log('\n๐Ÿงน Final cleanup...'); await cleanupTestData(); await mongoose.connection.close(); console.log('โœ… Database connection closed'); } } } // Simulate partner sync worker helper functions async function findMatchingAssignmentsForFile(taskData) { // Create a mock assignment for testing return [{ assignment: { _id: new mongoose.Types.ObjectId(), job: testConfig.contextData.jobId, user: testConfig.contextData.userId }, confidence: 0.8, matchCriteria: ['aircraftId'] }]; } async function buildContextDataFromAssignment(assignmentMatch, taskData) { return { jobId: assignmentMatch.assignment.job, userId: assignmentMatch.assignment.user, uploadedDate: new Date(), meta: { source: 'partner_sync_test', partnerId: taskData.partnerCode, aircraftId: taskData.aircraftId, logId: taskData.logId, logFileName: taskData.logFileName, assignmentId: assignmentMatch.assignment._id, confidence: assignmentMatch.confidence, matchCriteria: assignmentMatch.matchCriteria } }; } async function checkForExistingApplicationFile(logFileName, contextData) { const existingFile = await ApplicationFile.findOne({ $or: [ { name: logFileName }, { originalName: logFileName } ] }); return !!existingFile; } // Test processing a new file (simulating partner sync worker logic) async function testNewFileProcessing() { try { // Verify file exists await fs.access(testConfig.taskData.localFilePath); console.log(`โœ… Test file exists: ${testConfig.taskData.localFilePath}`); // Find matching assignments const matchingAssignments = await findMatchingAssignmentsForFile(testConfig.taskData); console.log(`โœ… Found ${matchingAssignments.length} matching assignments`); // Process with Application Processor for (const assignmentMatch of matchingAssignments) { const contextData = await buildContextDataFromAssignment(assignmentMatch, testConfig.taskData); const isRetry = await checkForExistingApplicationFile(testConfig.taskData.logFileName, contextData); console.log(`โœ… Retry check result: ${isRetry ? 'RETRY' : 'NEW'}`); const processor = new SatLocApplicationProcessor({ batchSize: 1000, enableRetryLogic: true, groupingTolerance: 24 * 60 * 60 * 1000, validateChecksums: true }); console.log('โš™๏ธ Processing with SatLoc Application Processor...'); const processingResult = await processor.processLogFile( { filePath: testConfig.taskData.localFilePath }, contextData ); if (processingResult.success) { console.log('โœ… Processing completed successfully!'); console.log(`๐Ÿ“Š Results:`, { applicationId: processingResult.application._id, applicationFileId: processingResult.applicationFile._id, detailsCount: processingResult.applicationDetails.length, statistics: processingResult.statistics }); } else { throw new Error(`Processing failed: ${processingResult.error}`); } } } catch (error) { console.error('โŒ New file processing test failed:', error); throw error; } } // Test retry processing (simulating retry scenario) async function testRetryFileProcessing() { try { console.log('๐Ÿ”„ Testing retry processing...'); const matchingAssignments = await findMatchingAssignmentsForFile(testConfig.taskData); for (const assignmentMatch of matchingAssignments) { const contextData = await buildContextDataFromAssignment(assignmentMatch, testConfig.taskData); const isRetry = await checkForExistingApplicationFile(testConfig.taskData.logFileName, contextData); console.log(`โœ… Retry check result: ${isRetry ? 'RETRY' : 'NEW'}`); if (isRetry) { const processor = new SatLocApplicationProcessor({ batchSize: 1000, enableRetryLogic: true, groupingTolerance: 24 * 60 * 60 * 1000, validateChecksums: true }); console.log('๐Ÿ”„ Processing retry with automatic cleanup...'); const processingResult = await processor.retryLogFile( testConfig.taskData.localFilePath, contextData ); if (processingResult.success) { console.log('โœ… Retry processing completed successfully!'); console.log(`๐Ÿ“Š Retry Results:`, { applicationId: processingResult.application._id, applicationFileId: processingResult.applicationFile._id, detailsCount: processingResult.applicationDetails.length }); } else { throw new Error(`Retry processing failed: ${processingResult.error}`); } } else { console.log('โ„น๏ธ No existing file found, retry test skipped'); } } } catch (error) { console.error('โŒ Retry file processing test failed:', error); throw error; } } // Test data structure created by partner sync integration async function testDataStructure() { try { console.log('๐Ÿ” Verifying data structure...'); // Check Application records const applications = await Application.find({ 'meta.source': 'partner_sync_test' }); console.log(`โœ… Found ${applications.length} test Applications`); // Check ApplicationFile records const applicationFiles = await ApplicationFile.find({ name: testConfig.taskData.logFileName }); console.log(`โœ… Found ${applicationFiles.length} ApplicationFiles`); // Check ApplicationDetail records let totalDetails = 0; for (const appFile of applicationFiles) { const details = await ApplicationDetail.find({ fileId: appFile._id }); totalDetails += details.length; } console.log(`โœ… Found ${totalDetails} ApplicationDetails`); // Verify data structure if (applications.length > 0) { const app = applications[0]; console.log('๐Ÿ“‹ Application structure:'); console.log(` - ID: ${app._id}`); console.log(` - Job ID: ${app.jobId}`); console.log(` - User ID: ${app.byUser}`); console.log(` - Status: ${app.status}`); console.log(` - Meta:`, app.meta); } if (applicationFiles.length > 0) { const appFile = applicationFiles[0]; console.log('๏ฟฝ ApplicationFile structure:'); console.log(` - ID: ${appFile._id}`); console.log(` - Name: ${appFile.name}`); console.log(` - App ID: ${appFile.appId}`); console.log(` - Meta keys:`, Object.keys(appFile.meta || {})); console.log(` - Spray segments: ${appFile.data?.length || 0}`); } console.log('โœ… Data structure verification completed'); } catch (error) { console.error('โŒ Data structure verification failed:', error); throw error; } } // Clean up test data async function cleanupTestData() { try { const testApplications = await Application.find({ 'meta.source': 'partner_sync_test' }); if (testApplications.length > 0) { const applicationIds = testApplications.map(app => app._id); // Delete ApplicationDetails const deletedDetails = await ApplicationDetail.deleteMany({ appId: { $in: applicationIds } }); // Delete ApplicationFiles const deletedFiles = await ApplicationFile.deleteMany({ appId: { $in: applicationIds } }); // Delete Applications const deletedApps = await Application.deleteMany({ _id: { $in: applicationIds } }); console.log(`๐Ÿ—‘๏ธ Cleaned up: ${deletedDetails.deletedCount} details, ${deletedFiles.deletedCount} files, ${deletedApps.deletedCount} applications`); } else { console.log('โ„น๏ธ No test data found to clean'); } } catch (error) { console.warn('โš ๏ธ Cleanup error:', error.message); } } // Run the test if (require.main === module) { testPartnerSyncIntegration() .then(() => { console.log('\n๐ŸŽ‰ Partner Sync Integration Test Completed Successfully!'); process.exit(0); }) .catch((error) => { console.error('\n๐Ÿ’ฅ Partner Sync Integration Test Failed:', error.message); process.exit(1); }); } module.exports = { testPartnerSyncIntegration, findMatchingAssignmentsForFile, buildContextDataFromAssignment, checkForExistingApplicationFile };