import { BadRequestException } from '@nestjs/common';
import {
  assertAllowedMediaFile,
  AUDIO_EXTENSIONS,
  AUDIO_MIMETYPES,
  getStaticMediaContentType,
  IMAGE_EXTENSIONS,
  IMAGE_MIMETYPES,
  VIDEO_EXTENSIONS,
  VIDEO_MIMETYPES,
} from './allowed-media';

describe('allowed media contract', () => {
  it('allows posts and collaboration audio formats including ogg and webm', () => {
    expect(
      assertAllowedMediaFile({ originalname: 'take.ogg', mimetype: 'audio/ogg', size: 1 }, 'audio'),
    ).toBe('.ogg');
    expect(
      assertAllowedMediaFile({ originalname: 'take.webm', mimetype: 'audio/webm', size: 1 }, 'audio'),
    ).toBe('.webm');
  });

  it('rejects unsupported image mimetypes even when they start with image', () => {
    expect(() =>
      assertAllowedMediaFile({ originalname: 'vector.svg', mimetype: 'image/svg+xml', size: 1 }, 'image'),
    ).toThrow(BadRequestException);
  });

  it('defines the official image, audio, and video contract', () => {
    expect(IMAGE_EXTENSIONS).toEqual(['.jpg', '.jpeg', '.png', '.webp']);
    expect(IMAGE_MIMETYPES).toEqual(['image/jpeg', 'image/png', 'image/webp']);
    expect(AUDIO_EXTENSIONS).toEqual(['.mp3', '.m4a', '.wav', '.aac', '.ogg', '.webm']);
    expect(AUDIO_MIMETYPES).toEqual([
      'audio/mpeg',
      'audio/mp3',
      'audio/mp4',
      'audio/x-m4a',
      'audio/m4a',
      'audio/wav',
      'audio/x-wav',
      'audio/wave',
      'audio/aac',
      'audio/ogg',
      'audio/webm',
    ]);
    expect(VIDEO_EXTENSIONS).toEqual(['.mp4', '.mov', '.webm']);
    expect(VIDEO_MIMETYPES).toEqual(['video/mp4', 'video/quicktime', 'video/webm']);
  });

  it('allows the official video formats and rejects legacy avi and mkv', () => {
    expect(assertAllowedMediaFile({ originalname: 'clip.mp4', mimetype: 'video/mp4' }, 'video')).toBe(
      '.mp4',
    );
    expect(assertAllowedMediaFile({ originalname: 'clip.mov', mimetype: 'video/quicktime' }, 'video')).toBe(
      '.mov',
    );
    expect(assertAllowedMediaFile({ originalname: 'clip.webm', mimetype: 'video/webm' }, 'video')).toBe(
      '.webm',
    );
    expect(() => assertAllowedMediaFile({ originalname: 'clip.avi', mimetype: 'video/x-msvideo' }, 'video')).toThrow(
      BadRequestException,
    );
    expect(() =>
      assertAllowedMediaFile({ originalname: 'clip.mkv', mimetype: 'video/x-matroska' }, 'video'),
    ).toThrow(BadRequestException);
  });

  it('maps static media content types for mov and webm uploads', () => {
    expect(getStaticMediaContentType('.mov')).toBe('video/quicktime');
    expect(getStaticMediaContentType('.webm', 'uploads/posts/videos/clip.webm')).toBe('video/webm');
    expect(getStaticMediaContentType('.webm', 'uploads/posts/audios/take.webm')).toBe('audio/webm');
    expect(getStaticMediaContentType('.webm', 'uploads/collaboration-requests/audio/take.webm')).toBe(
      'audio/webm',
    );
  });
});
