From 7beb04f947c8dcf40ff5f25b67bfbb951e56b153 Mon Sep 17 00:00:00 2001 From: Dotta Date: Tue, 28 Apr 2026 14:13:55 -0500 Subject: [PATCH] Fix issue route service mocks Co-Authored-By: Paperclip --- .../issue-activity-events-routes.test.ts | 3 +++ .../issue-closed-workspace-routes.test.ts | 3 +++ .../issue-comment-cancel-routes.test.ts | 3 +++ .../issue-comment-reopen-routes.test.ts | 27 ++++++++++--------- .../issue-dependency-wakeups-routes.test.ts | 3 +++ .../issue-document-restore-routes.test.ts | 3 +++ .../issue-execution-policy-routes.test.ts | 3 +++ .../__tests__/issue-feedback-routes.test.ts | 3 +++ .../__tests__/issue-telemetry-routes.test.ts | 5 +++- .../issue-thread-interaction-routes.test.ts | 3 +++ ...issue-update-comment-wakeup-routes.test.ts | 6 +++++ .../issue-workspace-command-authz.test.ts | 3 +++ .../issues-goal-context-routes.test.ts | 5 ++++ 13 files changed, 56 insertions(+), 14 deletions(-) diff --git a/server/src/__tests__/issue-activity-events-routes.test.ts b/server/src/__tests__/issue-activity-events-routes.test.ts index f5d1ae04cd8..0e385d1c16e 100644 --- a/server/src/__tests__/issue-activity-events-routes.test.ts +++ b/server/src/__tests__/issue-activity-events-routes.test.ts @@ -74,6 +74,9 @@ function registerModuleMocks() { })); vi.doMock("../services/index.js", () => ({ + companyService: () => ({ + getById: vi.fn(async () => ({ id: "company-1", attachmentMaxBytes: 10 * 1024 * 1024 })), + }), accessService: () => mockAccessService, agentService: () => ({ getById: vi.fn(async () => null), diff --git a/server/src/__tests__/issue-closed-workspace-routes.test.ts b/server/src/__tests__/issue-closed-workspace-routes.test.ts index c82586dd3f0..8b4f7f6e7cb 100644 --- a/server/src/__tests__/issue-closed-workspace-routes.test.ts +++ b/server/src/__tests__/issue-closed-workspace-routes.test.ts @@ -74,6 +74,9 @@ function registerServiceMocks() { })); vi.doMock("../services/index.js", () => ({ + companyService: () => ({ + getById: vi.fn(async () => ({ id: "company-1", attachmentMaxBytes: 10 * 1024 * 1024 })), + }), accessService: () => mockAccessService, agentService: () => ({ getById: vi.fn(async () => null), diff --git a/server/src/__tests__/issue-comment-cancel-routes.test.ts b/server/src/__tests__/issue-comment-cancel-routes.test.ts index e7c39b12cf9..e978ae14373 100644 --- a/server/src/__tests__/issue-comment-cancel-routes.test.ts +++ b/server/src/__tests__/issue-comment-cancel-routes.test.ts @@ -74,6 +74,9 @@ function registerModuleMocks() { })); vi.doMock("../services/index.js", () => ({ + companyService: () => ({ + getById: vi.fn(async () => ({ id: "company-1", attachmentMaxBytes: 10 * 1024 * 1024 })), + }), accessService: () => mockAccessService, agentService: () => ({ getById: vi.fn(async () => null) }), documentService: () => ({}), diff --git a/server/src/__tests__/issue-comment-reopen-routes.test.ts b/server/src/__tests__/issue-comment-reopen-routes.test.ts index 3cca0371fb6..922cf658eb8 100644 --- a/server/src/__tests__/issue-comment-reopen-routes.test.ts +++ b/server/src/__tests__/issue-comment-reopen-routes.test.ts @@ -108,6 +108,9 @@ vi.mock("../services/routines.js", () => ({ })); vi.mock("../services/index.js", () => ({ + companyService: () => ({ + getById: vi.fn(async () => ({ id: "company-1", attachmentMaxBytes: 10 * 1024 * 1024 })), + }), accessService: () => mockAccessService, agentService: () => mockAgentService, documentService: () => ({}), @@ -477,7 +480,7 @@ describe.sequential("issue comment reopen routes", () => { )); }); - it("does not implicitly reopen closed issues via POST comments for agent-authored comments", async () => { + it("rejects non-assignee agent POST comments on closed issues", async () => { mockIssueService.getById.mockResolvedValue(makeIssue("done")); mockIssueService.addComment.mockResolvedValue({ id: "comment-1", @@ -500,11 +503,10 @@ describe.sequential("issue comment reopen routes", () => { .post("/api/issues/11111111-1111-4111-8111-111111111111/comments") .send({ body: "hello" }); - expect(res.status).toBe(201); - expect(mockIssueService.update).not.toHaveBeenCalledWith( - "11111111-1111-4111-8111-111111111111", - { status: "todo" }, - ); + expect(res.status).toBe(403); + expect(res.body.error).toBe("Agent cannot mutate another agent's issue"); + expect(mockIssueService.update).not.toHaveBeenCalled(); + expect(mockIssueService.addComment).not.toHaveBeenCalled(); expect(mockHeartbeatService.wakeup).not.toHaveBeenCalled(); }); @@ -625,7 +627,7 @@ describe.sequential("issue comment reopen routes", () => { )); }); - it("does not implicitly reopen closed issues via the PATCH comment path for agent-authored comments", async () => { + it("rejects non-assignee agent PATCH comments on closed issues", async () => { mockIssueService.getById.mockResolvedValue(makeIssue("done")); mockIssueService.addComment.mockResolvedValue({ id: "comment-1", @@ -652,11 +654,10 @@ describe.sequential("issue comment reopen routes", () => { .patch("/api/issues/11111111-1111-4111-8111-111111111111") .send({ comment: "hello" }); - expect(res.status).toBe(200); - expect(mockIssueService.update).not.toHaveBeenCalledWith( - "11111111-1111-4111-8111-111111111111", - expect.objectContaining({ status: "todo" }), - ); + expect(res.status).toBe(403); + expect(res.body.error).toBe("Agent cannot mutate another agent's issue"); + expect(mockIssueService.update).not.toHaveBeenCalled(); + expect(mockIssueService.addComment).not.toHaveBeenCalled(); expect(mockHeartbeatService.wakeup).not.toHaveBeenCalled(); }); @@ -874,7 +875,7 @@ describe.sequential("issue comment reopen routes", () => { .send({ body: "restart someone else's work", resume: true }); expect(res.status).toBe(403); - expect(res.body.error).toBe("Agent cannot request follow-up for another agent's issue"); + expect(res.body.error).toBe("Agent cannot mutate another agent's issue"); expect(mockIssueService.update).not.toHaveBeenCalled(); expect(mockIssueService.addComment).not.toHaveBeenCalled(); expect(mockHeartbeatService.wakeup).not.toHaveBeenCalled(); diff --git a/server/src/__tests__/issue-dependency-wakeups-routes.test.ts b/server/src/__tests__/issue-dependency-wakeups-routes.test.ts index d138ed58b06..5991ae018b1 100644 --- a/server/src/__tests__/issue-dependency-wakeups-routes.test.ts +++ b/server/src/__tests__/issue-dependency-wakeups-routes.test.ts @@ -17,6 +17,9 @@ const mockIssueService = vi.hoisted(() => ({ })); vi.mock("../services/index.js", () => ({ + companyService: () => ({ + getById: vi.fn(async () => ({ id: "company-1", attachmentMaxBytes: 10 * 1024 * 1024 })), + }), accessService: () => ({ canUser: vi.fn(), hasPermission: vi.fn(), diff --git a/server/src/__tests__/issue-document-restore-routes.test.ts b/server/src/__tests__/issue-document-restore-routes.test.ts index 21dba0e2524..efe8916b2a2 100644 --- a/server/src/__tests__/issue-document-restore-routes.test.ts +++ b/server/src/__tests__/issue-document-restore-routes.test.ts @@ -108,6 +108,9 @@ function registerModuleMocks() { })); vi.doMock("../services/index.js", () => ({ + companyService: () => ({ + getById: vi.fn(async () => ({ id: "company-1", attachmentMaxBytes: 10 * 1024 * 1024 })), + }), accessService: () => mockAccessService, agentService: () => mockAgentService, documentService: () => mockDocumentsService, diff --git a/server/src/__tests__/issue-execution-policy-routes.test.ts b/server/src/__tests__/issue-execution-policy-routes.test.ts index 60f1d6e1bcb..f21e7b95c4d 100644 --- a/server/src/__tests__/issue-execution-policy-routes.test.ts +++ b/server/src/__tests__/issue-execution-policy-routes.test.ts @@ -24,6 +24,9 @@ const mockHeartbeatService = vi.hoisted(() => ({ function registerModuleMocks() { vi.doMock("../services/index.js", () => ({ + companyService: () => ({ + getById: vi.fn(async () => ({ id: "company-1", attachmentMaxBytes: 10 * 1024 * 1024 })), + }), accessService: () => ({ canUser: vi.fn(async () => false), hasPermission: vi.fn(async () => false), diff --git a/server/src/__tests__/issue-feedback-routes.test.ts b/server/src/__tests__/issue-feedback-routes.test.ts index ce8cca1fb8d..4c7807b6350 100644 --- a/server/src/__tests__/issue-feedback-routes.test.ts +++ b/server/src/__tests__/issue-feedback-routes.test.ts @@ -82,6 +82,9 @@ function registerModuleMocks() { })); vi.doMock("../services/index.js", () => ({ + companyService: () => ({ + getById: vi.fn(async () => ({ id: "company-1", attachmentMaxBytes: 10 * 1024 * 1024 })), + }), accessService: () => mockAccessService, agentService: () => mockAgentService, documentService: () => ({}), diff --git a/server/src/__tests__/issue-telemetry-routes.test.ts b/server/src/__tests__/issue-telemetry-routes.test.ts index 7adaadb4341..36bd8e84a24 100644 --- a/server/src/__tests__/issue-telemetry-routes.test.ts +++ b/server/src/__tests__/issue-telemetry-routes.test.ts @@ -27,6 +27,9 @@ function registerModuleMocks() { })); vi.doMock("../services/index.js", () => ({ + companyService: () => ({ + getById: vi.fn(async () => ({ id: "company-1", attachmentMaxBytes: 10 * 1024 * 1024 })), + }), accessService: () => ({ canUser: vi.fn(), hasPermission: vi.fn(), @@ -70,7 +73,7 @@ function makeIssue(status: "todo" | "done") { id: "11111111-1111-4111-8111-111111111111", companyId: "company-1", status, - assigneeAgentId: "22222222-2222-4222-8222-222222222222", + assigneeAgentId: "agent-1", assigneeUserId: null, createdByUserId: "local-board", identifier: "PAP-1018", diff --git a/server/src/__tests__/issue-thread-interaction-routes.test.ts b/server/src/__tests__/issue-thread-interaction-routes.test.ts index 666f6a46e48..d873e08078a 100644 --- a/server/src/__tests__/issue-thread-interaction-routes.test.ts +++ b/server/src/__tests__/issue-thread-interaction-routes.test.ts @@ -36,6 +36,9 @@ vi.mock("../telemetry.js", () => ({ function registerModuleMocks() { vi.doMock("../services/index.js", () => ({ + companyService: () => ({ + getById: vi.fn(async () => ({ id: "company-1", attachmentMaxBytes: 10 * 1024 * 1024 })), + }), accessService: () => ({ canUser: vi.fn(async () => true), hasPermission: vi.fn(async () => true), diff --git a/server/src/__tests__/issue-update-comment-wakeup-routes.test.ts b/server/src/__tests__/issue-update-comment-wakeup-routes.test.ts index 657d825ff1f..ee22ed42a94 100644 --- a/server/src/__tests__/issue-update-comment-wakeup-routes.test.ts +++ b/server/src/__tests__/issue-update-comment-wakeup-routes.test.ts @@ -27,6 +27,9 @@ const mockIssueThreadInteractionService = vi.hoisted(() => ({ })); vi.mock("../services/index.js", () => ({ + companyService: () => ({ + getById: vi.fn(async () => ({ id: "company-1", attachmentMaxBytes: 10 * 1024 * 1024 })), + }), accessService: () => ({ canUser: vi.fn(async () => true), hasPermission: vi.fn(async () => true), @@ -82,6 +85,9 @@ vi.mock("../services/index.js", () => ({ function registerModuleMocks() { vi.doMock("../services/index.js", () => ({ + companyService: () => ({ + getById: vi.fn(async () => ({ id: "company-1", attachmentMaxBytes: 10 * 1024 * 1024 })), + }), accessService: () => ({ canUser: vi.fn(async () => true), hasPermission: vi.fn(async () => true), diff --git a/server/src/__tests__/issue-workspace-command-authz.test.ts b/server/src/__tests__/issue-workspace-command-authz.test.ts index b0d8863b8a4..813410e70ad 100644 --- a/server/src/__tests__/issue-workspace-command-authz.test.ts +++ b/server/src/__tests__/issue-workspace-command-authz.test.ts @@ -90,6 +90,9 @@ function registerRouteMocks() { })); vi.doMock("../services/index.js", () => ({ + companyService: () => ({ + getById: vi.fn(async () => ({ id: "company-1", attachmentMaxBytes: 10 * 1024 * 1024 })), + }), accessService: () => mockAccessService, agentService: () => mockAgentService, documentService: () => ({}), diff --git a/server/src/__tests__/issues-goal-context-routes.test.ts b/server/src/__tests__/issues-goal-context-routes.test.ts index ddafeb9fc7f..914006e5c0b 100644 --- a/server/src/__tests__/issues-goal-context-routes.test.ts +++ b/server/src/__tests__/issues-goal-context-routes.test.ts @@ -12,6 +12,7 @@ const mockIssueService = vi.hoisted(() => ({ getCommentCursor: vi.fn(), getComment: vi.fn(), listBlockerAttention: vi.fn(), + listProductivityReviews: vi.fn(), listAttachments: vi.fn(), })); @@ -91,6 +92,9 @@ const mockWorkProductService = vi.hoisted(() => ({ const mockEnvironmentService = vi.hoisted(() => ({})); vi.mock("../services/index.js", () => ({ + companyService: () => ({ + getById: vi.fn(async () => ({ id: "company-1", attachmentMaxBytes: 10 * 1024 * 1024 })), + }), accessService: () => mockAccessService, agentService: () => mockAgentService, documentService: () => mockDocumentsService, @@ -177,6 +181,7 @@ describe.sequential("issue goal context routes", () => { }); mockIssueService.getComment.mockResolvedValue(null); mockIssueService.listBlockerAttention.mockResolvedValue(new Map()); + mockIssueService.listProductivityReviews.mockResolvedValue(new Map()); mockIssueService.listAttachments.mockResolvedValue([]); mockDocumentsService.getIssueDocumentPayload.mockResolvedValue({}); mockDocumentsService.getIssueDocumentByKey.mockResolvedValue(null);