import { ConflictException, NotFoundException } from "@nestjs/common"; import { Test, TestingModule } from "@nestjs/testing"; import { DatabaseService } from "../database/database.service"; import { FavoritesService } from "./favorites.service"; describe("FavoritesService", () => { let service: FavoritesService; const mockDb = { select: jest.fn(), from: jest.fn(), where: jest.fn(), limit: jest.fn(), offset: jest.fn(), innerJoin: jest.fn(), insert: jest.fn(), values: jest.fn(), delete: jest.fn(), returning: jest.fn(), }; beforeEach(async () => { jest.clearAllMocks(); const chain = { select: jest.fn().mockReturnThis(), from: jest.fn().mockReturnThis(), where: jest.fn().mockReturnThis(), limit: jest.fn().mockReturnThis(), offset: jest.fn().mockReturnThis(), innerJoin: jest.fn().mockReturnThis(), insert: jest.fn().mockReturnThis(), values: jest.fn().mockReturnThis(), delete: jest.fn().mockReturnThis(), returning: jest.fn().mockReturnThis(), }; const mockImplementation = () => Object.assign(Promise.resolve([]), chain); for (const mock of Object.values(chain)) { mock.mockImplementation(mockImplementation); } Object.assign(mockDb, chain); const module: TestingModule = await Test.createTestingModule({ providers: [ FavoritesService, { provide: DatabaseService, useValue: { db: mockDb } }, ], }).compile(); service = module.get(FavoritesService); }); it("should be defined", () => { expect(service).toBeDefined(); }); describe("addFavorite", () => { it("should add a favorite", async () => { mockDb.limit.mockResolvedValue([{ id: "content1" }]); mockDb.returning.mockResolvedValue([ { userId: "u1", contentId: "content1" }, ]); const result = await service.addFavorite("u1", "content1"); expect(result).toEqual([{ userId: "u1", contentId: "content1" }]); }); it("should throw NotFoundException if content does not exist", async () => { mockDb.limit.mockResolvedValue([]); await expect(service.addFavorite("u1", "invalid")).rejects.toThrow( NotFoundException, ); }); it("should throw ConflictException on duplicate favorite", async () => { mockDb.limit.mockResolvedValue([{ id: "content1" }]); mockDb.returning.mockRejectedValue(new Error("Duplicate")); await expect(service.addFavorite("u1", "content1")).rejects.toThrow( ConflictException, ); }); }); describe("removeFavorite", () => { it("should remove a favorite", async () => { mockDb.returning.mockResolvedValue([{ userId: "u1", contentId: "c1" }]); const result = await service.removeFavorite("u1", "c1"); expect(result).toEqual({ userId: "u1", contentId: "c1" }); }); it("should throw NotFoundException if favorite not found", async () => { mockDb.returning.mockResolvedValue([]); await expect(service.removeFavorite("u1", "c1")).rejects.toThrow( NotFoundException, ); }); }); });