Fix QA validation issues and add M7.1 security fixes (#318)
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed

Co-authored-by: Jason Woltje <jason@diversecanvas.com>
Co-committed-by: Jason Woltje <jason@diversecanvas.com>
This commit was merged in pull request #318.
This commit is contained in:
2026-02-04 03:08:09 +00:00
committed by jason.woltje
parent 482507ce4d
commit a1973e6419
178 changed files with 4902 additions and 74 deletions

View File

@@ -119,9 +119,14 @@ describe("CoordinatorIntegrationService - Concurrency", () => {
expect(result.status).toBe(RunnerJobStatus.RUNNING);
// Verify SELECT FOR UPDATE was used
expect(mockTxClient.$queryRaw).toHaveBeenCalledWith(
expect.anything() // Raw SQL with FOR UPDATE
);
expect(mockTxClient.$queryRaw).toHaveBeenCalled();
const sqlCall = mockTxClient.$queryRaw.mock.calls[0];
expect(sqlCall).toBeDefined();
// Verify the SQL contains FOR UPDATE (raw SQL is passed as template parts)
const sqlString = sqlCall?.toString() ?? "";
expect(
sqlString.includes("FOR UPDATE") || sqlCall?.[0]?.toString().includes("FOR UPDATE")
).toBe(true);
});
it("should handle concurrent status updates by coordinator and API", async () => {
@@ -313,8 +318,11 @@ describe("CoordinatorIntegrationService - Concurrency", () => {
version: mockJob.version + 1,
};
vi.mocked(prisma.runnerJob.findUnique).mockResolvedValue(mockJob as any);
// First findUnique returns the current job state
vi.mocked(prisma.runnerJob.findUnique).mockResolvedValueOnce(mockJob as any);
// updateMany succeeds
vi.mocked(prisma.runnerJob.updateMany).mockResolvedValue({ count: 1 });
// Second findUnique returns the updated job state
vi.mocked(prisma.runnerJob.findUnique).mockResolvedValueOnce(updatedJob as any);
const result = await service.updateJobProgress(jobId, {

View File

@@ -58,7 +58,10 @@ describe("CoordinatorIntegrationService", () => {
create: vi.fn(),
findUnique: vi.fn(),
update: vi.fn(),
updateMany: vi.fn(),
},
$transaction: vi.fn(),
$queryRaw: vi.fn(),
};
const mockJobEventsService = {
@@ -97,6 +100,9 @@ describe("CoordinatorIntegrationService", () => {
jobEventsService = module.get<JobEventsService>(JobEventsService);
heraldService = module.get<HeraldService>(HeraldService);
bullMqService = module.get<BullMqService>(BullMqService);
// Set default mock return values
mockPrismaService.runnerJob.updateMany.mockResolvedValue({ count: 1 });
});
describe("createJob", () => {
@@ -145,8 +151,26 @@ describe("CoordinatorIntegrationService", () => {
it("should update job status to RUNNING", async () => {
const updatedJob = { ...mockJob, status: RunnerJobStatus.RUNNING, startedAt: new Date() };
mockPrismaService.runnerJob.findUnique.mockResolvedValue(mockJob);
mockPrismaService.runnerJob.update.mockResolvedValue(updatedJob);
// Mock transaction that passes through the callback
mockPrismaService.$transaction.mockImplementation(async (callback) => {
const mockTx = {
$queryRaw: vi
.fn()
.mockResolvedValue([
{
id: mockJob.id,
status: mockJob.status,
workspace_id: mockJob.workspaceId,
version: 1,
},
]),
runnerJob: {
update: vi.fn().mockResolvedValue(updatedJob),
},
};
return callback(mockTx);
});
mockJobEventsService.emitJobStarted.mockResolvedValue(mockEvent);
mockHeraldService.broadcastJobEvent.mockResolvedValue(undefined);
@@ -160,7 +184,16 @@ describe("CoordinatorIntegrationService", () => {
});
it("should throw NotFoundException if job does not exist", async () => {
mockPrismaService.runnerJob.findUnique.mockResolvedValue(null);
// Mock transaction with empty result
mockPrismaService.$transaction.mockImplementation(async (callback) => {
const mockTx = {
$queryRaw: vi.fn().mockResolvedValue([]),
runnerJob: {
update: vi.fn(),
},
};
return callback(mockTx);
});
await expect(
service.updateJobStatus("non-existent", { status: "RUNNING" as const })
@@ -168,8 +201,25 @@ describe("CoordinatorIntegrationService", () => {
});
it("should throw BadRequestException for invalid status transition", async () => {
const completedJob = { ...mockJob, status: RunnerJobStatus.COMPLETED };
mockPrismaService.runnerJob.findUnique.mockResolvedValue(completedJob);
// Mock transaction with completed job
mockPrismaService.$transaction.mockImplementation(async (callback) => {
const mockTx = {
$queryRaw: vi
.fn()
.mockResolvedValue([
{
id: mockJob.id,
status: RunnerJobStatus.COMPLETED,
workspace_id: mockJob.workspaceId,
version: 1,
},
]),
runnerJob: {
update: vi.fn(),
},
};
return callback(mockTx);
});
await expect(
service.updateJobStatus("job-123", { status: "RUNNING" as const })
@@ -179,11 +229,12 @@ describe("CoordinatorIntegrationService", () => {
describe("updateJobProgress", () => {
it("should update job progress percentage", async () => {
const runningJob = { ...mockJob, status: RunnerJobStatus.RUNNING };
const updatedJob = { ...runningJob, progressPercent: 50 };
const runningJob = { ...mockJob, status: RunnerJobStatus.RUNNING, version: 1 };
const updatedJob = { ...runningJob, progressPercent: 50, version: 2 };
mockPrismaService.runnerJob.findUnique.mockResolvedValue(runningJob);
mockPrismaService.runnerJob.update.mockResolvedValue(updatedJob);
mockPrismaService.runnerJob.updateMany.mockResolvedValue({ count: 1 });
mockPrismaService.runnerJob.findUnique.mockResolvedValue(updatedJob);
mockJobEventsService.emitEvent.mockResolvedValue(mockEvent);
const result = await service.updateJobProgress("job-123", {
@@ -217,8 +268,26 @@ describe("CoordinatorIntegrationService", () => {
completedAt: new Date(),
};
mockPrismaService.runnerJob.findUnique.mockResolvedValue(runningJob);
mockPrismaService.runnerJob.update.mockResolvedValue(completedJob);
// Mock transaction with running job
mockPrismaService.$transaction.mockImplementation(async (callback) => {
const mockTx = {
$queryRaw: vi
.fn()
.mockResolvedValue([
{
id: mockJob.id,
status: RunnerJobStatus.RUNNING,
workspace_id: mockJob.workspaceId,
version: 1,
},
]),
runnerJob: {
update: vi.fn().mockResolvedValue(completedJob),
},
};
return callback(mockTx);
});
mockJobEventsService.emitJobCompleted.mockResolvedValue(mockEvent);
mockHeraldService.broadcastJobEvent.mockResolvedValue(undefined);
@@ -243,8 +312,26 @@ describe("CoordinatorIntegrationService", () => {
completedAt: new Date(),
};
mockPrismaService.runnerJob.findUnique.mockResolvedValue(runningJob);
mockPrismaService.runnerJob.update.mockResolvedValue(failedJob);
// Mock transaction with running job
mockPrismaService.$transaction.mockImplementation(async (callback) => {
const mockTx = {
$queryRaw: vi
.fn()
.mockResolvedValue([
{
id: mockJob.id,
status: RunnerJobStatus.RUNNING,
workspace_id: mockJob.workspaceId,
version: 1,
},
]),
runnerJob: {
update: vi.fn().mockResolvedValue(failedJob),
},
};
return callback(mockTx);
});
mockJobEventsService.emitJobFailed.mockResolvedValue(mockEvent);
mockHeraldService.broadcastJobEvent.mockResolvedValue(undefined);