import { describe, it, expect, beforeEach, vi } from "vitest"; import { Test, TestingModule } from "@nestjs/testing"; import { ProjectsController } from "./projects.controller"; import { ProjectsService } from "./projects.service"; import { ProjectStatus } from "@prisma/client"; import { AuthGuard } from "../auth/guards/auth.guard"; import { ExecutionContext } from "@nestjs/common"; describe("ProjectsController", () => { let controller: ProjectsController; let service: ProjectsService; const mockProjectsService = { create: vi.fn(), findAll: vi.fn(), findOne: vi.fn(), update: vi.fn(), remove: vi.fn(), }; const mockAuthGuard = { canActivate: vi.fn((context: ExecutionContext) => { const request = context.switchToHttp().getRequest(); request.user = { id: "550e8400-e29b-41d4-a716-446655440002", workspaceId: "550e8400-e29b-41d4-a716-446655440001", }; return true; }), }; const mockWorkspaceId = "550e8400-e29b-41d4-a716-446655440001"; const mockUserId = "550e8400-e29b-41d4-a716-446655440002"; const mockProjectId = "550e8400-e29b-41d4-a716-446655440003"; const mockRequest = { user: { id: mockUserId, workspaceId: mockWorkspaceId, }, }; const mockProject = { id: mockProjectId, workspaceId: mockWorkspaceId, name: "Test Project", description: "Test Description", status: ProjectStatus.PLANNING, startDate: new Date("2026-02-01"), endDate: new Date("2026-03-01"), creatorId: mockUserId, color: "#FF5733", metadata: {}, createdAt: new Date(), updatedAt: new Date(), }; beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ controllers: [ProjectsController], providers: [ { provide: ProjectsService, useValue: mockProjectsService, }, ], }) .overrideGuard(AuthGuard) .useValue(mockAuthGuard) .compile(); controller = module.get(ProjectsController); service = module.get(ProjectsService); vi.clearAllMocks(); }); it("should be defined", () => { expect(controller).toBeDefined(); }); describe("create", () => { it("should create a project", async () => { const createDto = { name: "New Project", description: "Project description", }; mockProjectsService.create.mockResolvedValue(mockProject); const result = await controller.create(createDto, mockRequest); expect(result).toEqual(mockProject); expect(service.create).toHaveBeenCalledWith( mockWorkspaceId, mockUserId, createDto ); }); it("should throw UnauthorizedException if workspaceId not found", async () => { const requestWithoutWorkspace = { user: { id: mockUserId }, }; await expect( controller.create({ name: "Test" }, requestWithoutWorkspace) ).rejects.toThrow("Authentication required"); }); }); describe("findAll", () => { it("should return paginated projects", async () => { const query = { workspaceId: mockWorkspaceId, }; const paginatedResult = { data: [mockProject], meta: { total: 1, page: 1, limit: 50, totalPages: 1, }, }; mockProjectsService.findAll.mockResolvedValue(paginatedResult); const result = await controller.findAll(query, mockRequest); expect(result).toEqual(paginatedResult); }); it("should throw UnauthorizedException if workspaceId not found", async () => { const requestWithoutWorkspace = { user: { id: mockUserId }, }; await expect( controller.findAll({}, requestWithoutWorkspace as any) ).rejects.toThrow("Authentication required"); }); }); describe("findOne", () => { it("should return a project by id", async () => { mockProjectsService.findOne.mockResolvedValue(mockProject); const result = await controller.findOne(mockProjectId, mockRequest); expect(result).toEqual(mockProject); }); it("should throw UnauthorizedException if workspaceId not found", async () => { const requestWithoutWorkspace = { user: { id: mockUserId }, }; await expect( controller.findOne(mockProjectId, requestWithoutWorkspace) ).rejects.toThrow("Authentication required"); }); }); describe("update", () => { it("should update a project", async () => { const updateDto = { name: "Updated Project", }; const updatedProject = { ...mockProject, ...updateDto }; mockProjectsService.update.mockResolvedValue(updatedProject); const result = await controller.update(mockProjectId, updateDto, mockRequest); expect(result).toEqual(updatedProject); }); it("should throw UnauthorizedException if workspaceId not found", async () => { const requestWithoutWorkspace = { user: { id: mockUserId }, }; await expect( controller.update(mockProjectId, { name: "Test" }, requestWithoutWorkspace) ).rejects.toThrow("Authentication required"); }); }); describe("remove", () => { it("should delete a project", async () => { mockProjectsService.remove.mockResolvedValue(undefined); await controller.remove(mockProjectId, mockRequest); expect(service.remove).toHaveBeenCalledWith( mockProjectId, mockWorkspaceId, mockUserId ); }); it("should throw UnauthorizedException if workspaceId not found", async () => { const requestWithoutWorkspace = { user: { id: mockUserId }, }; await expect( controller.remove(mockProjectId, requestWithoutWorkspace) ).rejects.toThrow("Authentication required"); }); }); });