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