feat(auth): add per-feature InversifyJS container with constructor-injected service
This commit is contained in:
51
packages/auth/src/di/container.test.ts
Normal file
51
packages/auth/src/di/container.test.ts
Normal file
@@ -0,0 +1,51 @@
|
||||
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
||||
import { authContainer } from "./container";
|
||||
import { AUTH_SYMBOLS } from "./symbols";
|
||||
import { AuthModule } from "./module";
|
||||
import { MockUsersRepository } from "@/infrastructure/repositories/mock-users.repository";
|
||||
import { MockAuthenticationService } from "@/infrastructure/services/mock-authentication.service";
|
||||
import type { IUsersRepository } from "@/application/repositories/users-repository.interface";
|
||||
import type { IAuthenticationService } from "@/application/services/authentication-service.interface";
|
||||
|
||||
describe("authContainer", () => {
|
||||
beforeEach(() => {
|
||||
authContainer.unbindAll();
|
||||
authContainer.load(AuthModule);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
authContainer.unbindAll();
|
||||
});
|
||||
|
||||
it("resolves IUsersRepository to MockUsersRepository by default", () => {
|
||||
const repo = authContainer.get<IUsersRepository>(
|
||||
AUTH_SYMBOLS.IUsersRepository,
|
||||
);
|
||||
expect(repo).toBeInstanceOf(MockUsersRepository);
|
||||
});
|
||||
|
||||
it("resolves IAuthenticationService to MockAuthenticationService by default", () => {
|
||||
const service = authContainer.get<IAuthenticationService>(
|
||||
AUTH_SYMBOLS.IAuthenticationService,
|
||||
);
|
||||
expect(service).toBeInstanceOf(MockAuthenticationService);
|
||||
});
|
||||
|
||||
it("authentication service receives users repository via constructor injection", async () => {
|
||||
const service = authContainer.get<IAuthenticationService>(
|
||||
AUTH_SYMBOLS.IAuthenticationService,
|
||||
);
|
||||
// The service should be able to validate against the seeded users
|
||||
const { session, cookie } = await service.createSession({
|
||||
id: "1",
|
||||
username: "alice",
|
||||
passwordHash: "hashed_password_alice",
|
||||
});
|
||||
expect(session.userId).toBe("1");
|
||||
expect(cookie.value).toBe(session.id);
|
||||
|
||||
// After session creation, validateSession should resolve user via the repo
|
||||
const validated = await service.validateSession(session.id);
|
||||
expect(validated.user.username).toBe("alice");
|
||||
});
|
||||
});
|
||||
6
packages/auth/src/di/container.ts
Normal file
6
packages/auth/src/di/container.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
import "reflect-metadata";
|
||||
import { Container } from "inversify";
|
||||
import { AuthModule } from "./module";
|
||||
|
||||
export const authContainer = new Container({ defaultScope: "Singleton" });
|
||||
authContainer.load(AuthModule);
|
||||
14
packages/auth/src/di/module.ts
Normal file
14
packages/auth/src/di/module.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { ContainerModule, type interfaces } from "inversify";
|
||||
|
||||
import type { IUsersRepository } from "../application/repositories/users-repository.interface";
|
||||
import type { IAuthenticationService } from "../application/services/authentication-service.interface";
|
||||
import { MockUsersRepository } from "../infrastructure/repositories/mock-users.repository";
|
||||
import { MockAuthenticationService } from "../infrastructure/services/mock-authentication.service";
|
||||
import { AUTH_SYMBOLS } from "./symbols";
|
||||
|
||||
export const AuthModule = new ContainerModule((bind: interfaces.Bind) => {
|
||||
bind<IUsersRepository>(AUTH_SYMBOLS.IUsersRepository).to(MockUsersRepository);
|
||||
bind<IAuthenticationService>(AUTH_SYMBOLS.IAuthenticationService).to(
|
||||
MockAuthenticationService,
|
||||
);
|
||||
});
|
||||
4
packages/auth/src/di/symbols.ts
Normal file
4
packages/auth/src/di/symbols.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
export const AUTH_SYMBOLS = {
|
||||
IUsersRepository: Symbol.for("auth:IUsersRepository"),
|
||||
IAuthenticationService: Symbol.for("auth:IAuthenticationService"),
|
||||
} as const;
|
||||
Reference in New Issue
Block a user