fix(SEC-ORCH-16): Implement real health and readiness checks
- Add ping() method to ValkeyClient and ValkeyService for health checks - Update HealthService to check Valkey connectivity before reporting ready - /health/ready now returns 503 if dependencies are unhealthy - Add detailed checks object showing individual dependency status - Update tests with ValkeyService mock Refs #339 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,13 +1,21 @@
|
||||
import { describe, it, expect, beforeEach } from "vitest";
|
||||
import { describe, it, expect, beforeEach, vi } from "vitest";
|
||||
import { HttpException, HttpStatus } from "@nestjs/common";
|
||||
import { HealthController } from "./health.controller";
|
||||
import { HealthService } from "./health.service";
|
||||
import { ValkeyService } from "../../valkey/valkey.service";
|
||||
|
||||
// Mock ValkeyService
|
||||
const mockValkeyService = {
|
||||
ping: vi.fn(),
|
||||
} as unknown as ValkeyService;
|
||||
|
||||
describe("HealthController", () => {
|
||||
let controller: HealthController;
|
||||
let service: HealthService;
|
||||
|
||||
beforeEach(() => {
|
||||
service = new HealthService();
|
||||
vi.clearAllMocks();
|
||||
service = new HealthService(mockValkeyService);
|
||||
controller = new HealthController(service);
|
||||
});
|
||||
|
||||
@@ -83,17 +91,46 @@ describe("HealthController", () => {
|
||||
});
|
||||
|
||||
describe("GET /health/ready", () => {
|
||||
it("should return ready status", () => {
|
||||
const result = controller.ready();
|
||||
it("should return ready status with checks when all dependencies are healthy", async () => {
|
||||
vi.mocked(mockValkeyService.ping).mockResolvedValue(true);
|
||||
|
||||
const result = await controller.ready();
|
||||
|
||||
expect(result).toBeDefined();
|
||||
expect(result).toHaveProperty("ready");
|
||||
expect(result).toHaveProperty("checks");
|
||||
expect(result.ready).toBe(true);
|
||||
expect(result.checks.valkey).toBe(true);
|
||||
});
|
||||
|
||||
it("should return ready as true", () => {
|
||||
const result = controller.ready();
|
||||
it("should throw 503 when Valkey is unhealthy", async () => {
|
||||
vi.mocked(mockValkeyService.ping).mockResolvedValue(false);
|
||||
|
||||
expect(result.ready).toBe(true);
|
||||
await expect(controller.ready()).rejects.toThrow(HttpException);
|
||||
|
||||
try {
|
||||
await controller.ready();
|
||||
} catch (error) {
|
||||
expect(error).toBeInstanceOf(HttpException);
|
||||
expect((error as HttpException).getStatus()).toBe(HttpStatus.SERVICE_UNAVAILABLE);
|
||||
const response = (error as HttpException).getResponse() as { ready: boolean };
|
||||
expect(response.ready).toBe(false);
|
||||
}
|
||||
});
|
||||
|
||||
it("should return checks object with individual dependency status", async () => {
|
||||
vi.mocked(mockValkeyService.ping).mockResolvedValue(true);
|
||||
|
||||
const result = await controller.ready();
|
||||
|
||||
expect(result.checks).toBeDefined();
|
||||
expect(typeof result.checks.valkey).toBe("boolean");
|
||||
});
|
||||
|
||||
it("should handle Valkey ping errors gracefully", async () => {
|
||||
vi.mocked(mockValkeyService.ping).mockRejectedValue(new Error("Connection refused"));
|
||||
|
||||
await expect(controller.ready()).rejects.toThrow(HttpException);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user