336 lines
11 KiB
JavaScript
336 lines
11 KiB
JavaScript
/**
|
||
* 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('<27> 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
|
||
};
|