media-pipeline.test.ts 3.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. import { getMediaStatus, uploadMedia } from '../../src/actions/media';
  2. import { mediaQueue } from '../../src/lib/queue/index';
  3. import { startMediaWorker } from '../../src/workers/media-processor';
  4. import * as fs from 'fs';
  5. import * as path from 'path';
  6. import * as os from 'os';
  7. async function runTest() {
  8. console.log('🧪 Starting Media Pipeline Integration Test...');
  9. let exitCode = 1;
  10. // 1. Setup: Create a dummy video file (mp4)
  11. const testDir = fs.mkdtempSync(path.join(os.tmpdir(), 'test-media-'));
  12. const testFilePath = path.join(testDir, 'test_video.mp4');
  13. // Note: In a real environment, we'd use a real small mp4.
  14. // For this test, we'll assume a file exists or create a dummy one if possible.
  15. if (!fs.existsSync('test_sample.mp4')) {
  16. console.error('❌ Error: Please place a small "test_sample.mp4" file in the project root for testing.');
  17. process.exit(1);
  18. }
  19. fs.copyFileSync('test_sample.mp4', testFilePath);
  20. try {
  21. await mediaQueue.drain(true);
  22. await mediaQueue.clean(0, 1000, 'failed');
  23. await mediaQueue.clean(0, 1000, 'completed');
  24. console.log('✅ Queue cleaned');
  25. // 2. Start Worker
  26. const worker = await startMediaWorker();
  27. console.log('✅ Worker started');
  28. // 3. Simulate Upload (Producer)
  29. console.log('📤 Simulating upload...');
  30. const fileMock = {
  31. name: 'test_sample.mp4',
  32. type: 'video/mp4',
  33. size: fs.statSync(testFilePath).size,
  34. arrayBuffer: async () => {
  35. const fileBuffer = fs.readFileSync(testFilePath);
  36. return fileBuffer.buffer.slice(
  37. fileBuffer.byteOffset,
  38. fileBuffer.byteOffset + fileBuffer.byteLength
  39. );
  40. },
  41. };
  42. const record = await uploadMedia(fileMock as any);
  43. console.log(`✅ Uploaded. Media ID: ${record.media.id}, Status: ${record.media.status}`);
  44. // 4. Wait for Worker to process (Polling)
  45. console.log('⏳ Waiting for worker to complete processing...');
  46. let attempts = 0;
  47. const maxAttempts = 60; // ~60 seconds
  48. let completed = false;
  49. while (attempts < maxAttempts) {
  50. await new Promise(r => setTimeout(r, 1000));
  51. const updatedRecord = await getMediaStatus(record.media.id);
  52. if (updatedRecord?.status === 'completed') {
  53. console.log('🎉 Success! Media status is COMPLETED');
  54. console.log('Metadata:', updatedRecord.metadata);
  55. console.log('HLS URL generated:', Boolean(updatedRecord.hlsUrl));
  56. completed = true;
  57. break;
  58. } else if (updatedRecord?.status === 'failed') {
  59. console.error('❌ Processing failed according to DB status');
  60. break;
  61. }
  62. attempts++;
  63. process.stdout.write('.');
  64. }
  65. if (!completed) {
  66. console.error('\n❌ Timeout: Worker did not complete processing in time.');
  67. } else {
  68. console.log('\n✨ Integration Test Passed!');
  69. exitCode = 0;
  70. }
  71. await worker.close();
  72. } catch (err) {
  73. console.error('❌ Test failed with error:', err);
  74. } finally {
  75. // Cleanup
  76. fs.rmSync(testDir, { recursive: true, force: true });
  77. await mediaQueue.close();
  78. process.exit(exitCode);
  79. }
  80. }
  81. runTest();