import { Readable } from "node:stream"; import { NotFoundException } from "@nestjs/common"; import { Test, TestingModule } from "@nestjs/testing"; import type { Response } from "express"; import { S3Service } from "../s3/s3.service"; import { MediaController } from "./media.controller"; describe("MediaController", () => { let controller: MediaController; const mockS3Service = { getFileInfo: jest.fn(), getFile: jest.fn(), }; beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ controllers: [MediaController], providers: [{ provide: S3Service, useValue: mockS3Service }], }).compile(); controller = module.get(MediaController); }); it("should be defined", () => { expect(controller).toBeDefined(); }); describe("getFile", () => { it("should stream the file and set headers with path containing slashes", async () => { const res = { setHeader: jest.fn(), } as unknown as Response; const stream = new Readable(); stream.pipe = jest.fn(); const key = "contents/user-id/test.webp"; mockS3Service.getFileInfo.mockResolvedValue({ size: 100, metaData: { "content-type": "image/webp" }, }); mockS3Service.getFile.mockResolvedValue(stream); await controller.getFile(key, res); expect(mockS3Service.getFileInfo).toHaveBeenCalledWith(key); expect(res.setHeader).toHaveBeenCalledWith("Content-Type", "image/webp"); expect(res.setHeader).toHaveBeenCalledWith("Content-Length", 100); expect(stream.pipe).toHaveBeenCalledWith(res); }); it("should throw NotFoundException if path is missing", async () => { const res = {} as unknown as Response; await expect(controller.getFile("", res)).rejects.toThrow(NotFoundException); }); it("should throw NotFoundException if file is not found", async () => { mockS3Service.getFileInfo.mockRejectedValue(new Error("Not found")); const res = {} as unknown as Response; await expect(controller.getFile("invalid", res)).rejects.toThrow( NotFoundException, ); }); }); });