/** * JavaScript Mix Payloads Sender Test * Tests the smartsend function with mixed payload types */ const NATSBridge = require('../src/natsbridge.js'); const crypto = require('crypto'); const TEST_SUBJECT = '/test/mix'; const TEST_BROKER_URL = process.env.NATS_URL || 'nats.yiem.cc'; const TEST_FILESERVER_URL = process.env.FILESERVER_URL || 'http://192.168.88.104:8080'; async function runTest() { console.log('=== JavaScript Mix Payloads Sender Test ===\n'); const correlationId = crypto.randomUUID(); console.log(`Correlation ID: ${correlationId}`); console.log(`Subject: ${TEST_SUBJECT}`); console.log(`Broker URL: ${TEST_BROKER_URL}\n`); // Test data - mixed payload types const textData = 'Hello, NATSBridge!'; const dictData = { key1: 'value1', key2: 42, nested: { a: 1, b: 2 } }; const binaryData = Buffer.from([0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A]); // PNG header // Table data const tableData = [ { id: 1, name: 'Alice', age: 30 }, { id: 2, name: 'Bob', age: 25 }, { id: 3, name: 'Charlie', age: 35 } ]; const testData = [ ['message', textData, 'text'], ['config', dictData, 'dictionary'], ['image', binaryData, 'image'], ['users', tableData, 'table'] ]; try { // Send the message console.log('Sending mixed payloads...'); const [env, envJsonStr] = await NATSBridge.smartsend( TEST_SUBJECT, testData, { broker_url: TEST_BROKER_URL, fileserver_url: TEST_FILESERVER_URL, correlation_id: correlationId, msg_purpose: 'test', sender_name: 'js-mix-test', is_publish: false } ); console.log('\n=== Envelope Created ==='); console.log(`Correlation ID: ${env.correlation_id}`); console.log(`Message ID: ${env.msg_id}`); console.log(`Timestamp: ${env.timestamp}`); console.log(`Subject: ${env.send_to}`); console.log(`Purpose: ${env.msg_purpose}`); console.log(`Sender: ${env.sender_name}`); console.log(`Payloads: ${env.payloads.length}\n`); // Validate envelope structure console.log('=== Validation ==='); let passed = true; if (env.payloads.length !== 4) { console.log(`❌ Expected 4 payloads, got ${env.payloads.length}`); passed = false; } else { console.log('✅ Correct number of payloads'); } // Test each payload const expectedDatanames = ['message', 'config', 'image', 'users']; const expectedTypes = ['text', 'dictionary', 'image', 'table']; const expectedData = [textData, dictData, binaryData, tableData]; for (let i = 0; i < env.payloads.length; i++) { const payload = env.payloads[i]; if (payload.dataname !== expectedDatanames[i]) { console.log(`❌ Payload ${i + 1}: Expected dataname '${expectedDatanames[i]}', got '${payload.dataname}'`); passed = false; } else { console.log(`✅ Payload ${i + 1}: Correct dataname`); } if (payload.payload_type !== expectedTypes[i]) { console.log(`❌ Payload ${i + 1}: Expected type '${expectedTypes[i]}', got '${payload.payload_type}'`); passed = false; } else { console.log(`✅ Payload ${i + 1}: Correct type`); } if (payload.transport !== 'direct') { console.log(`❌ Payload ${i + 1}: Expected transport 'direct', got '${payload.transport}'`); passed = false; } else { console.log(`✅ Payload ${i + 1}: Correct transport`); } if (payload.encoding !== 'base64') { console.log(`❌ Payload ${i + 1}: Expected encoding 'base64', got '${payload.encoding}'`); passed = false; } else { console.log(`✅ Payload ${i + 1}: Correct encoding`); } // Verify data integrity based on type if (expectedTypes[i] === 'text') { const decodedData = Buffer.from(payload.data, 'base64').toString('utf8'); if (decodedData !== expectedData[i]) { console.log(`❌ Payload ${i + 1}: Data integrity mismatch`); passed = false; } else { console.log(`✅ Payload ${i + 1}: Data integrity verified`); } } else if (expectedTypes[i] === 'dictionary') { const decodedData = JSON.parse(Buffer.from(payload.data, 'base64').toString('utf8')); if (JSON.stringify(decodedData) !== JSON.stringify(expectedData[i])) { console.log(`❌ Payload ${i + 1}: Data integrity mismatch`); passed = false; } else { console.log(`✅ Payload ${i + 1}: Data integrity verified`); } } else if (expectedTypes[i] === 'image') { const decodedData = Buffer.from(payload.data, 'base64'); if (decodedData.length !== expectedData[i].length) { console.log(`❌ Payload ${i + 1}: Length mismatch`); passed = false; } else { let dataMatch = true; for (let j = 0; j < expectedData[i].length; j++) { if (decodedData[j] !== expectedData[i][j]) { dataMatch = false; break; } } if (dataMatch) { console.log(`✅ Payload ${i + 1}: Data integrity verified`); } else { console.log(`❌ Payload ${i + 1}: Data integrity mismatch`); passed = false; } } } else if (expectedTypes[i] === 'table') { const decodedData = Buffer.from(payload.data, 'base64'); if (decodedData.length > 0) { console.log(`✅ Payload ${i + 1}: Arrow IPC data present (${decodedData.length} bytes)`); } else { console.log(`❌ Payload ${i + 1}: Arrow IPC data is empty`); passed = false; } } console.log(` Size: ${payload.size} bytes\n`); } // Test with chat-like payload (text + image + audio) console.log('=== Chat-like Payload Test ==='); const chatData = [ ['text', 'Hello!', 'text'], ['image', Buffer.from([0xFF, 0xD8, 0xFF, 0xE0]), 'image'], ['audio', Buffer.from([0x46, 0x4C, 0x41, 0x43]), 'audio'] ]; const [chatEnv, _] = await NATSBridge.smartsend( TEST_SUBJECT, chatData, { broker_url: TEST_BROKER_URL, fileserver_url: TEST_FILESERVER_URL, correlation_id: 'chat-' + correlationId, is_publish: false } ); if (chatEnv.payloads.length === 3) { console.log('✅ Chat-like payloads handled correctly'); } else { console.log('❌ Chat-like payloads handling failed'); passed = false; } // Final result console.log('\n=== Test Result ==='); if (passed) { console.log('✅ ALL TESTS PASSED'); process.exit(0); } else { console.log('❌ SOME TESTS FAILED'); process.exit(1); } } catch (error) { console.error('❌ Test failed with error:', error.message); console.error(error.stack); process.exit(1); } } runTest();