fix(tests): Resolve pipeline #243 test failures
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
ci/woodpecker/pr/woodpecker Pipeline failed

Fixed 27 test failures by addressing several categories of issues:

Security spec tests (coordinator-integration, stitcher):
- Changed async test assertions to synchronous since ApiKeyGuard.canActivate
  is synchronous and throws directly rather than returning rejected promises
- Use expect(() => fn()).toThrow() instead of await expect(fn()).rejects.toThrow()

Federation controller tests:
- Added CsrfGuard and WorkspaceGuard mock overrides to test module
- Set DEFAULT_WORKSPACE_ID environment variable for handleIncomingConnection tests
- Added proper afterEach cleanup for environment variable restoration

Federation service tests:
- Updated RSA key generation tests to use Vitest 4.x timeout syntax
  (second argument as options object, not third argument)

Prisma service tests:
- Replaced vi.spyOn for $transaction and setWorkspaceContext with direct
  method assignment to avoid spy restoration issues
- Added vi.clearAllMocks() in afterEach to properly reset between tests

Integration tests (job-events, fulltext-search):
- Added conditional skip when DATABASE_URL is not set to prevent failures
  in environments without database access

Remaining 7 failures are pre-existing fulltext-search integration tests
that require specific PostgreSQL triggers not present in test database.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Jason Woltje
2026-02-06 12:15:21 -06:00
parent 519093f42e
commit 10b49c4afb
7 changed files with 133 additions and 54 deletions

View File

@@ -15,6 +15,7 @@ describe("PrismaService", () => {
afterEach(async () => {
await service.$disconnect();
vi.clearAllMocks();
});
it("should be defined", () => {
@@ -126,14 +127,19 @@ describe("PrismaService", () => {
const workspaceId = "workspace-456";
const executeRawSpy = vi.spyOn(service, "$executeRaw").mockResolvedValue(0);
await service.$transaction(async (tx) => {
await service.setWorkspaceContext(userId, workspaceId, tx);
// Mock $transaction to execute the callback with a mock tx client
const mockTx = {
$executeRaw: vi.fn().mockResolvedValue(0),
};
vi.spyOn(service, "$transaction").mockImplementation(async (fn) => {
return fn(mockTx as never);
});
expect(executeRawSpy).toHaveBeenCalledTimes(2);
// Check that both session variables were set
expect(executeRawSpy).toHaveBeenNthCalledWith(1, expect.anything());
expect(executeRawSpy).toHaveBeenNthCalledWith(2, expect.anything());
await service.$transaction(async (tx) => {
await service.setWorkspaceContext(userId, workspaceId, tx as never);
});
expect(mockTx.$executeRaw).toHaveBeenCalledTimes(2);
});
it("should work when called outside transaction using default client", async () => {
@@ -151,20 +157,48 @@ describe("PrismaService", () => {
it("should execute function with workspace context set", async () => {
const userId = "user-123";
const workspaceId = "workspace-456";
const executeRawSpy = vi.spyOn(service, "$executeRaw").mockResolvedValue(0);
// Mock $transaction to execute the callback with a mock tx client that has $executeRaw
const mockTx = {
$executeRaw: vi.fn().mockResolvedValue(0),
};
// Mock both methods at the same time to avoid spy issues
const originalSetContext = service.setWorkspaceContext.bind(service);
const setContextCalls: [string, string, unknown][] = [];
service.setWorkspaceContext = vi.fn().mockImplementation((uid, wid, tx) => {
setContextCalls.push([uid, wid, tx]);
return Promise.resolve();
}) as typeof service.setWorkspaceContext;
service.$transaction = vi.fn().mockImplementation(async (fn) => {
return fn(mockTx as never);
}) as typeof service.$transaction;
const result = await service.withWorkspaceContext(userId, workspaceId, async () => {
return "test-result";
});
expect(result).toBe("test-result");
expect(executeRawSpy).toHaveBeenCalledTimes(2);
expect(setContextCalls).toHaveLength(1);
expect(setContextCalls[0]).toEqual([userId, workspaceId, mockTx]);
});
it("should pass transaction client to callback", async () => {
const userId = "user-123";
const workspaceId = "workspace-456";
vi.spyOn(service, "$executeRaw").mockResolvedValue(0);
// Mock $transaction to execute the callback with a mock tx client
const mockTx = {
$executeRaw: vi.fn().mockResolvedValue(0),
};
service.setWorkspaceContext = vi
.fn()
.mockResolvedValue(undefined) as typeof service.setWorkspaceContext;
service.$transaction = vi.fn().mockImplementation(async (fn) => {
return fn(mockTx as never);
}) as typeof service.$transaction;
let receivedClient: unknown = null;
await service.withWorkspaceContext(userId, workspaceId, async (tx) => {
@@ -179,7 +213,18 @@ describe("PrismaService", () => {
it("should handle errors from callback", async () => {
const userId = "user-123";
const workspaceId = "workspace-456";
vi.spyOn(service, "$executeRaw").mockResolvedValue(0);
// Mock $transaction to execute the callback with a mock tx client
const mockTx = {
$executeRaw: vi.fn().mockResolvedValue(0),
};
service.setWorkspaceContext = vi
.fn()
.mockResolvedValue(undefined) as typeof service.setWorkspaceContext;
service.$transaction = vi.fn().mockImplementation(async (fn) => {
return fn(mockTx as never);
}) as typeof service.$transaction;
const error = new Error("Callback error");
await expect(
@@ -192,13 +237,19 @@ describe("PrismaService", () => {
describe("clearWorkspaceContext", () => {
it("should clear workspace context variables", async () => {
const executeRawSpy = vi.spyOn(service, "$executeRaw").mockResolvedValue(0);
await service.$transaction(async (tx) => {
await service.clearWorkspaceContext(tx);
// Mock $transaction to execute the callback with a mock tx client
const mockTx = {
$executeRaw: vi.fn().mockResolvedValue(0),
};
vi.spyOn(service, "$transaction").mockImplementation(async (fn) => {
return fn(mockTx as never);
});
expect(executeRawSpy).toHaveBeenCalledTimes(2);
await service.$transaction(async (tx) => {
await service.clearWorkspaceContext(tx as never);
});
expect(mockTx.$executeRaw).toHaveBeenCalledTimes(2);
});
});
});