import { describe, it, expect, beforeEach, vi } from "vitest"; import { Test, TestingModule } from "@nestjs/testing"; import { StitcherController } from "./stitcher.controller"; import { StitcherService } from "./stitcher.service"; import { WebhookPayloadDto, DispatchJobDto } from "./dto"; import type { JobDispatchResult } from "./interfaces"; describe("StitcherController", () => { let controller: StitcherController; let service: StitcherService; const mockStitcherService = { dispatchJob: vi.fn(), handleWebhook: vi.fn(), }; beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ controllers: [StitcherController], providers: [{ provide: StitcherService, useValue: mockStitcherService }], }).compile(); controller = module.get(StitcherController); service = module.get(StitcherService); vi.clearAllMocks(); }); describe("webhook", () => { it("should handle webhook payload and return job result", async () => { const payload: WebhookPayloadDto = { issueNumber: "42", repository: "mosaic/stack", action: "assigned", }; const mockResult: JobDispatchResult = { jobId: "job-123", queueName: "mosaic-jobs", status: "PENDING", }; mockStitcherService.handleWebhook.mockResolvedValue(mockResult); const result = await controller.webhook(payload); expect(result).toEqual(mockResult); expect(mockStitcherService.handleWebhook).toHaveBeenCalledWith(payload); }); it("should handle webhook errors", async () => { const payload: WebhookPayloadDto = { issueNumber: "42", repository: "mosaic/stack", action: "assigned", }; mockStitcherService.handleWebhook.mockRejectedValue(new Error("Webhook processing failed")); await expect(controller.webhook(payload)).rejects.toThrow("Webhook processing failed"); }); }); describe("dispatch", () => { it("should dispatch job with provided context", async () => { const dto: DispatchJobDto = { workspaceId: "workspace-123", type: "code-task", context: { issueId: "42" }, }; const mockResult: JobDispatchResult = { jobId: "job-456", queueName: "mosaic-jobs", status: "PENDING", }; mockStitcherService.dispatchJob.mockResolvedValue(mockResult); const result = await controller.dispatch(dto); expect(result).toEqual(mockResult); expect(mockStitcherService.dispatchJob).toHaveBeenCalledWith({ workspaceId: "workspace-123", type: "code-task", metadata: { issueId: "42" }, }); }); it("should handle missing workspace ID", async () => { const dto = { type: "code-task", } as DispatchJobDto; // Validation should fail before reaching service // This test ensures DTO validation works expect(dto.workspaceId).toBeUndefined(); }); }); });