import { describe, it, expect, vi, beforeEach } from "vitest"; import { Test, TestingModule } from "@nestjs/testing"; import { ConfigModule } from "@nestjs/config"; import { MosaicTelemetryModule } from "./mosaic-telemetry.module"; import { MosaicTelemetryService } from "./mosaic-telemetry.service"; import { PrismaService } from "../prisma/prisma.service"; // Mock the telemetry client to avoid real HTTP calls vi.mock("@mosaicstack/telemetry-client", async (importOriginal) => { const actual = await importOriginal(); class MockTelemetryClient { private _isRunning = false; constructor(_config: unknown) { // no-op } get eventBuilder() { return { build: vi.fn().mockReturnValue({ event_id: "test-event-id" }) }; } start(): void { this._isRunning = true; } async stop(): Promise { this._isRunning = false; } track(_event: unknown): void { // no-op } getPrediction(_query: unknown): unknown { return null; } async refreshPredictions(_queries: unknown): Promise { // no-op } get queueSize(): number { return 0; } get isRunning(): boolean { return this._isRunning; } } return { ...actual, TelemetryClient: MockTelemetryClient, }; }); describe("MosaicTelemetryModule", () => { let module: TestingModule; const sharedTestEnv = { ENCRYPTION_KEY: "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef", }; const mockPrismaService = { onModuleInit: vi.fn(), onModuleDestroy: vi.fn(), $connect: vi.fn(), $disconnect: vi.fn(), }; const buildTestModule = async (env: Record): Promise => Test.createTestingModule({ imports: [ ConfigModule.forRoot({ isGlobal: true, envFilePath: [], load: [() => ({ ...env, ...sharedTestEnv })], }), MosaicTelemetryModule, ], }) .overrideProvider(PrismaService) .useValue(mockPrismaService) .compile(); beforeEach(() => { vi.clearAllMocks(); }); describe("module initialization", () => { it("should compile the module successfully", async () => { module = await buildTestModule({ MOSAIC_TELEMETRY_ENABLED: "false", }); expect(module).toBeDefined(); await module.close(); }); it("should provide MosaicTelemetryService", async () => { module = await buildTestModule({ MOSAIC_TELEMETRY_ENABLED: "false", }); const service = module.get(MosaicTelemetryService); expect(service).toBeDefined(); expect(service).toBeInstanceOf(MosaicTelemetryService); await module.close(); }); it("should export MosaicTelemetryService for injection in other modules", async () => { module = await buildTestModule({ MOSAIC_TELEMETRY_ENABLED: "false", }); const service = module.get(MosaicTelemetryService); expect(service).toBeDefined(); await module.close(); }); }); describe("lifecycle integration", () => { it("should initialize service on module init when enabled", async () => { module = await buildTestModule({ MOSAIC_TELEMETRY_ENABLED: "true", MOSAIC_TELEMETRY_SERVER_URL: "https://tel.test.local", MOSAIC_TELEMETRY_API_KEY: "a".repeat(64), MOSAIC_TELEMETRY_INSTANCE_ID: "550e8400-e29b-41d4-a716-446655440000", MOSAIC_TELEMETRY_DRY_RUN: "false", }); await module.init(); const service = module.get(MosaicTelemetryService); expect(service.isEnabled).toBe(true); await module.close(); }); it("should not start client when disabled via env", async () => { module = await buildTestModule({ MOSAIC_TELEMETRY_ENABLED: "false", }); await module.init(); const service = module.get(MosaicTelemetryService); expect(service.isEnabled).toBe(false); await module.close(); }); it("should cleanly shut down on module destroy", async () => { module = await buildTestModule({ MOSAIC_TELEMETRY_ENABLED: "true", MOSAIC_TELEMETRY_SERVER_URL: "https://tel.test.local", MOSAIC_TELEMETRY_API_KEY: "a".repeat(64), MOSAIC_TELEMETRY_INSTANCE_ID: "550e8400-e29b-41d4-a716-446655440000", MOSAIC_TELEMETRY_DRY_RUN: "false", }); await module.init(); const service = module.get(MosaicTelemetryService); expect(service.isEnabled).toBe(true); await expect(module.close()).resolves.not.toThrow(); }); }); });