Clip Web videos.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

93 lines
2.6 KiB

  1. import {
  2. describe, it, expect, vi, Mock, beforeAll, afterEach,
  3. } from 'vitest';
  4. import { EventEmitter } from 'events';
  5. import { createVideoClipper, VideoClipEventEmitter } from '@modal/webvideo-clip-core';
  6. import SERVER from '../src/server';
  7. import '../src/routes';
  8. import { constants } from 'http2';
  9. class MockEventEmitter extends EventEmitter {
  10. process = vi.fn();
  11. }
  12. vi.mock('@modal/webvideo-clip-core');
  13. describe('ClipController.clip: POST /clip', () => {
  14. let mockEventEmitter: VideoClipEventEmitter;
  15. beforeAll(() => {
  16. mockEventEmitter = new MockEventEmitter();
  17. (createVideoClipper as Mock).mockReturnValue(mockEventEmitter);
  18. });
  19. afterEach(() => {
  20. (mockEventEmitter.process as Mock).mockReset();
  21. });
  22. it('returns the clip', async () => {
  23. const dummyOutput = 'string content';
  24. (mockEventEmitter.process as Mock).mockImplementationOnce(
  25. function mockProcess(this: VideoClipEventEmitter) {
  26. this.emit('success', {
  27. type: 'video/webm',
  28. output: Buffer.from(dummyOutput),
  29. });
  30. this.emit('end');
  31. },
  32. );
  33. const response = await SERVER
  34. .inject()
  35. .post('/clip')
  36. .body({
  37. url: 'https://www.youtube.com/watch?v=BaW_jenozKc',
  38. start: '00:00:00',
  39. end: '00:00:05',
  40. });
  41. expect(response.statusCode).toBe(constants.HTTP_STATUS_OK);
  42. expect(response.headers['content-type']).toBe('video/webm');
  43. expect(response.headers['content-length']).toBe(dummyOutput.length.toString());
  44. });
  45. it('returns an error when the clip function throws', async () => {
  46. (mockEventEmitter.process as Mock).mockImplementationOnce(
  47. function mockProcess(this: VideoClipEventEmitter) {
  48. this.emit('error', new Error());
  49. this.emit('end');
  50. },
  51. );
  52. const response = await SERVER
  53. .inject()
  54. .post('/clip')
  55. .body({
  56. url: 'https://www.youtube.com/watch?v=BaW_jenozKc',
  57. start: '00:00:00',
  58. end: '00:00:05',
  59. });
  60. expect(response.statusCode).toBe(constants.HTTP_STATUS_INTERNAL_SERVER_ERROR);
  61. });
  62. it('returns an error when the URL could not be found', async () => {
  63. const response = await SERVER
  64. .inject()
  65. .post('/clip')
  66. .body({});
  67. expect(response.statusCode).toBe(constants.HTTP_STATUS_BAD_REQUEST);
  68. });
  69. it('returns an error when the URL is unsupported', async () => {
  70. const response = await SERVER
  71. .inject()
  72. .post('/clip')
  73. .body({
  74. url: 'https://unsupported.com',
  75. });
  76. expect(response.statusCode).toBe(constants.HTTP_STATUS_UNPROCESSABLE_ENTITY);
  77. });
  78. });