fix(#182): fix Prisma enum import in job-steps tests
Fixed failing tests in job-steps.service.spec.ts and job-steps.controller.spec.ts caused by undefined Prisma enum imports in the test environment. Root cause: When importing JobStepPhase, JobStepType, and JobStepStatus from @prisma/client in the test environment with mocked Prisma, the enums were undefined, causing "Cannot read properties of undefined" errors. Solution: Used vi.mock() with importOriginal to mock the @prisma/client module and explicitly provide enum values while preserving other exports like PrismaClient. Changes: - Added vi.mock() for @prisma/client in both test files - Defined all three enums (JobStepPhase, JobStepType, JobStepStatus) with their values - Moved imports after the mock setup to ensure proper initialization Test results: All 16 job-steps tests now passing (13 service + 3 controller) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,12 +1,41 @@
|
|||||||
import { describe, it, expect, beforeEach, vi } from "vitest";
|
import { describe, it, expect, beforeEach, vi } from "vitest";
|
||||||
import { Test, TestingModule } from "@nestjs/testing";
|
import { Test, TestingModule } from "@nestjs/testing";
|
||||||
|
import { ExecutionContext } from "@nestjs/common";
|
||||||
|
|
||||||
|
// Mock @prisma/client BEFORE importing other modules
|
||||||
|
vi.mock("@prisma/client", async (importOriginal) => {
|
||||||
|
const actual = await importOriginal<typeof import("@prisma/client")>();
|
||||||
|
return {
|
||||||
|
...actual,
|
||||||
|
JobStepPhase: {
|
||||||
|
SETUP: "SETUP",
|
||||||
|
EXECUTION: "EXECUTION",
|
||||||
|
VALIDATION: "VALIDATION",
|
||||||
|
CLEANUP: "CLEANUP",
|
||||||
|
},
|
||||||
|
JobStepType: {
|
||||||
|
COMMAND: "COMMAND",
|
||||||
|
AI_ACTION: "AI_ACTION",
|
||||||
|
GATE: "GATE",
|
||||||
|
ARTIFACT: "ARTIFACT",
|
||||||
|
},
|
||||||
|
JobStepStatus: {
|
||||||
|
PENDING: "PENDING",
|
||||||
|
RUNNING: "RUNNING",
|
||||||
|
COMPLETED: "COMPLETED",
|
||||||
|
FAILED: "FAILED",
|
||||||
|
SKIPPED: "SKIPPED",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
// Import after mocking
|
||||||
import { JobStepsController } from "./job-steps.controller";
|
import { JobStepsController } from "./job-steps.controller";
|
||||||
import { JobStepsService } from "./job-steps.service";
|
import { JobStepsService } from "./job-steps.service";
|
||||||
import { JobStepPhase, JobStepType, JobStepStatus } from "@prisma/client";
|
import { JobStepPhase, JobStepType, JobStepStatus } from "@prisma/client";
|
||||||
import { AuthGuard } from "../auth/guards/auth.guard";
|
import { AuthGuard } from "../auth/guards/auth.guard";
|
||||||
import { WorkspaceGuard } from "../common/guards/workspace.guard";
|
import { WorkspaceGuard } from "../common/guards/workspace.guard";
|
||||||
import { PermissionGuard } from "../common/guards/permission.guard";
|
import { PermissionGuard } from "../common/guards/permission.guard";
|
||||||
import { ExecutionContext } from "@nestjs/common";
|
|
||||||
|
|
||||||
describe("JobStepsController", () => {
|
describe("JobStepsController", () => {
|
||||||
let controller: JobStepsController;
|
let controller: JobStepsController;
|
||||||
|
|||||||
@@ -1,11 +1,42 @@
|
|||||||
import { describe, it, expect, beforeEach, vi } from "vitest";
|
import { describe, it, expect, beforeEach, vi } from "vitest";
|
||||||
import { Test, TestingModule } from "@nestjs/testing";
|
import { Test, TestingModule } from "@nestjs/testing";
|
||||||
import { JobStepsService } from "./job-steps.service";
|
|
||||||
import { PrismaService } from "../prisma/prisma.service";
|
|
||||||
import { JobStepPhase, JobStepType, JobStepStatus } from "@prisma/client";
|
|
||||||
import { NotFoundException } from "@nestjs/common";
|
import { NotFoundException } from "@nestjs/common";
|
||||||
import { CreateStepDto, UpdateStepDto } from "./dto";
|
import { CreateStepDto, UpdateStepDto } from "./dto";
|
||||||
|
|
||||||
|
// Mock @prisma/client BEFORE importing the service
|
||||||
|
vi.mock("@prisma/client", async (importOriginal) => {
|
||||||
|
const actual = await importOriginal<typeof import("@prisma/client")>();
|
||||||
|
return {
|
||||||
|
...actual,
|
||||||
|
JobStepPhase: {
|
||||||
|
SETUP: "SETUP",
|
||||||
|
EXECUTION: "EXECUTION",
|
||||||
|
VALIDATION: "VALIDATION",
|
||||||
|
CLEANUP: "CLEANUP",
|
||||||
|
},
|
||||||
|
JobStepType: {
|
||||||
|
COMMAND: "COMMAND",
|
||||||
|
AI_ACTION: "AI_ACTION",
|
||||||
|
GATE: "GATE",
|
||||||
|
ARTIFACT: "ARTIFACT",
|
||||||
|
},
|
||||||
|
JobStepStatus: {
|
||||||
|
PENDING: "PENDING",
|
||||||
|
RUNNING: "RUNNING",
|
||||||
|
COMPLETED: "COMPLETED",
|
||||||
|
FAILED: "FAILED",
|
||||||
|
SKIPPED: "SKIPPED",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
// Import after mocking
|
||||||
|
import { JobStepsService } from "./job-steps.service";
|
||||||
|
import { PrismaService } from "../prisma/prisma.service";
|
||||||
|
|
||||||
|
// Re-import the enums from the mock for use in tests
|
||||||
|
import { JobStepPhase, JobStepType, JobStepStatus } from "@prisma/client";
|
||||||
|
|
||||||
describe("JobStepsService", () => {
|
describe("JobStepsService", () => {
|
||||||
let service: JobStepsService;
|
let service: JobStepsService;
|
||||||
let prisma: PrismaService;
|
let prisma: PrismaService;
|
||||||
|
|||||||
101
docs/scratchpads/182-fix-prisma-enum-tests.md
Normal file
101
docs/scratchpads/182-fix-prisma-enum-tests.md
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
# Issue #182: [BLOCKER] Fix failing Prisma enum import tests in job-steps.service.spec.ts
|
||||||
|
|
||||||
|
## Objective
|
||||||
|
|
||||||
|
Fix Prisma enum import issues in job-steps.service.spec.ts that are causing test failures and blocking other work.
|
||||||
|
|
||||||
|
## Approach
|
||||||
|
|
||||||
|
1. Read the failing test file to understand the issue
|
||||||
|
2. Check the Prisma schema to understand the correct enum definitions
|
||||||
|
3. Fix the enum imports and usage in the test file
|
||||||
|
4. Run tests to verify the fix
|
||||||
|
5. Ensure 85% coverage is maintained
|
||||||
|
|
||||||
|
## Progress
|
||||||
|
|
||||||
|
- [x] Read job-steps.service.spec.ts
|
||||||
|
- [x] Read Prisma schema to verify enum definitions
|
||||||
|
- [x] Identify the root cause of the import failures
|
||||||
|
- [x] Fix enum imports and usage
|
||||||
|
- [x] Run tests to verify fix
|
||||||
|
- [x] Run full test suite to check for regressions
|
||||||
|
- [x] Verify test coverage (16/16 tests passing)
|
||||||
|
- [ ] Commit changes
|
||||||
|
|
||||||
|
## Root Cause Analysis
|
||||||
|
|
||||||
|
The test file imports `JobStepPhase`, `JobStepType`, and `JobStepStatus` from `@prisma/client`:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import { JobStepPhase, JobStepType, JobStepStatus } from "@prisma/client";
|
||||||
|
```
|
||||||
|
|
||||||
|
However, in the test environment with mocked Prisma, these enum imports are undefined, causing errors like:
|
||||||
|
|
||||||
|
- `Cannot read properties of undefined (reading 'SETUP')`
|
||||||
|
- `Cannot read properties of undefined (reading 'COMPLETED')`
|
||||||
|
|
||||||
|
The Prisma schema defines these enums at lines 147-167:
|
||||||
|
|
||||||
|
- `JobStepPhase`: SETUP, EXECUTION, VALIDATION, CLEANUP
|
||||||
|
- `JobStepType`: COMMAND, AI_ACTION, GATE, ARTIFACT
|
||||||
|
- `JobStepStatus`: PENDING, RUNNING, COMPLETED, FAILED, SKIPPED
|
||||||
|
|
||||||
|
## Solution
|
||||||
|
|
||||||
|
Instead of importing from `@prisma/client`, we need to manually define these enums in the test file or import them from the DTOs which properly export the types. Since the DTOs already import from `@prisma/client`, we'll define the enum constants directly in the test file to avoid circular dependencies.
|
||||||
|
|
||||||
|
### Implementation
|
||||||
|
|
||||||
|
Used `vi.mock()` with `importOriginal` to mock the `@prisma/client` module and provide the enum values:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
vi.mock("@prisma/client", async (importOriginal) => {
|
||||||
|
const actual = await importOriginal<typeof import("@prisma/client")>();
|
||||||
|
return {
|
||||||
|
...actual,
|
||||||
|
JobStepPhase: {
|
||||||
|
SETUP: "SETUP",
|
||||||
|
EXECUTION: "EXECUTION",
|
||||||
|
VALIDATION: "VALIDATION",
|
||||||
|
CLEANUP: "CLEANUP",
|
||||||
|
},
|
||||||
|
JobStepType: {
|
||||||
|
COMMAND: "COMMAND",
|
||||||
|
AI_ACTION: "AI_ACTION",
|
||||||
|
GATE: "GATE",
|
||||||
|
ARTIFACT: "ARTIFACT",
|
||||||
|
},
|
||||||
|
JobStepStatus: {
|
||||||
|
PENDING: "PENDING",
|
||||||
|
RUNNING: "RUNNING",
|
||||||
|
COMPLETED: "COMPLETED",
|
||||||
|
FAILED: "FAILED",
|
||||||
|
SKIPPED: "SKIPPED",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
This approach:
|
||||||
|
|
||||||
|
1. Imports the actual Prisma client using `importOriginal`
|
||||||
|
2. Spreads the actual exports to preserve PrismaClient and other types
|
||||||
|
3. Overrides only the enum values that were undefined in the test environment
|
||||||
|
4. Must be placed BEFORE importing any modules that depend on @prisma/client
|
||||||
|
|
||||||
|
### Files Modified
|
||||||
|
|
||||||
|
- `/home/localadmin/src/mosaic-stack/apps/api/src/job-steps/job-steps.service.spec.ts`
|
||||||
|
- `/home/localadmin/src/mosaic-stack/apps/api/src/job-steps/job-steps.controller.spec.ts`
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
|
||||||
|
- Run unit tests: `pnpm test:api`
|
||||||
|
- Verify coverage: `pnpm test:coverage`
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
- This is a BLOCKER issue - must be resolved before other work can proceed
|
||||||
|
- Need to maintain minimum 85% coverage
|
||||||
Reference in New Issue
Block a user