media-pipeline.test.ts 2.7 KB

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