import "reflect-metadata"; import { afterEach, beforeEach, describe, expect, it } from "vitest"; import { NoopTracer, NoopLogger } from "@repo/core-shared/instrumentation"; import { RecordingEventBus, RecordingJobQueue } from "@repo/core-testing/instrumentation"; import { bindDevSeedAuth } from "@/di/bind-dev-seed"; import { authContainer } from "@/di/container"; import { AUTH_SYMBOLS } from "@/di/symbols"; import { MockUsersRepository } from "@/infrastructure/repositories/users.repository.mock"; import type { IUsersRepository } from "@/application/repositories/users.repository.interface"; const noop = { tracer: new NoopTracer(), logger: new NoopLogger() }; describe("bindDevSeedAuth", () => { // Each test starts from the default empty-mock binding and tears down // afterwards so the global authContainer state stays clean for siblings. beforeEach(() => { if (authContainer.isBound(AUTH_SYMBOLS.IUsersRepository)) { authContainer.unbind(AUTH_SYMBOLS.IUsersRepository); } authContainer .bind(AUTH_SYMBOLS.IUsersRepository) .to(MockUsersRepository); }); afterEach(() => { if (authContainer.isBound(AUTH_SYMBOLS.IUsersRepository)) { authContainer.unbind(AUTH_SYMBOLS.IUsersRepository); } authContainer .bind(AUTH_SYMBOLS.IUsersRepository) .to(MockUsersRepository); }); it("populates the repository with the dev users", async () => { await bindDevSeedAuth({ ...noop, bus: new RecordingEventBus(), queue: new RecordingJobQueue() }); const repo = authContainer.get( AUTH_SYMBOLS.IUsersRepository, ); const alice = await repo.getUserByUsername("alice"); const bob = await repo.getUserByUsername("bob"); expect(alice).toBeDefined(); expect(bob).toBeDefined(); }); it("seeds alice reachable by username", async () => { await bindDevSeedAuth({ ...noop, bus: new RecordingEventBus(), queue: new RecordingJobQueue() }); const repo = authContainer.get( AUTH_SYMBOLS.IUsersRepository, ); const alice = await repo.getUserByUsername("alice"); expect(alice).toBeDefined(); expect(alice?.id).toBe("alice"); expect(alice?.passwordHash).toBe("hashed_secret_alice"); }); it("is idempotent — calling twice rebuilds a fresh populated repo", async () => { await bindDevSeedAuth({ ...noop, bus: new RecordingEventBus(), queue: new RecordingJobQueue() }); const before = authContainer.get( AUTH_SYMBOLS.IUsersRepository, ); const beforeAlice = await before.getUserByUsername("alice"); await bindDevSeedAuth({ ...noop, bus: new RecordingEventBus(), queue: new RecordingJobQueue() }); const after = authContainer.get( AUTH_SYMBOLS.IUsersRepository, ); const afterAlice = await after.getUserByUsername("alice"); expect(afterAlice?.username).toBe(beforeAlice?.username); // It's a fresh instance — not the previous one. expect(after).not.toBe(before); }); });