import { describe, it, expect, vi, Mock, beforeAll, afterEach, } from 'vitest'; import { EventEmitter } from 'events'; import { createVideoClipper, VideoClipEventEmitter } from '@modal/webvideo-clip-core'; import SERVER from '../src/server'; import '../src/routes'; import { constants } from 'http2'; class MockEventEmitter extends EventEmitter { process = vi.fn(); } vi.mock('@modal/webvideo-clip-core'); describe('ClipController.clip: POST /clip', () => { let mockEventEmitter: VideoClipEventEmitter; beforeAll(() => { mockEventEmitter = new MockEventEmitter(); (createVideoClipper as Mock).mockReturnValue(mockEventEmitter); }); afterEach(() => { (mockEventEmitter.process as Mock).mockReset(); }); it('returns the clip', async () => { const dummyOutput = 'string content'; (mockEventEmitter.process as Mock).mockImplementationOnce( function mockProcess(this: VideoClipEventEmitter) { this.emit('success', { type: 'video/webm', output: Buffer.from(dummyOutput), }); this.emit('end'); }, ); const response = await SERVER .inject() .post('/clip') .body({ url: 'https://www.youtube.com/watch?v=BaW_jenozKc', start: '00:00:00', end: '00:00:05', }); expect(response.statusCode).toBe(constants.HTTP_STATUS_OK); expect(response.headers['content-type']).toBe('video/webm'); expect(response.headers['content-length']).toBe(dummyOutput.length.toString()); }); it('returns an error when the clip function throws', async () => { (mockEventEmitter.process as Mock).mockImplementationOnce( function mockProcess(this: VideoClipEventEmitter) { this.emit('error', new Error()); this.emit('end'); }, ); const response = await SERVER .inject() .post('/clip') .body({ url: 'https://www.youtube.com/watch?v=BaW_jenozKc', start: '00:00:00', end: '00:00:05', }); expect(response.statusCode).toBe(constants.HTTP_STATUS_INTERNAL_SERVER_ERROR); }); it('returns an error when the URL could not be found', async () => { const response = await SERVER .inject() .post('/clip') .body({}); expect(response.statusCode).toBe(constants.HTTP_STATUS_BAD_REQUEST); }); it('returns an error when the URL is unsupported', async () => { const response = await SERVER .inject() .post('/clip') .body({ url: 'https://unsupported.com', }); expect(response.statusCode).toBe(constants.HTTP_STATUS_UNPROCESSABLE_ENTITY); }); });