- Added `lint:fix` scripts for backend, frontend, and documentation. - Enabled `biome check --write` for unsafe fixes in backend scripts. - Fixed imports, formatting, and logging for improved code clarity. - Adjusted service unit tests for better readability and maintainability.
191 lines
5.4 KiB
TypeScript
191 lines
5.4 KiB
TypeScript
jest.mock("uuid", () => ({
|
|
v4: jest.fn(() => "mocked-uuid"),
|
|
}));
|
|
|
|
jest.mock("@noble/post-quantum/ml-kem.js", () => ({
|
|
ml_kem768: {
|
|
keygen: jest.fn(),
|
|
encapsulate: jest.fn(),
|
|
decapsulate: jest.fn(),
|
|
},
|
|
}));
|
|
|
|
jest.mock("jose", () => ({
|
|
SignJWT: jest.fn().mockReturnValue({
|
|
setProtectedHeader: jest.fn().mockReturnThis(),
|
|
setIssuedAt: jest.fn().mockReturnThis(),
|
|
setExpirationTime: jest.fn().mockReturnThis(),
|
|
sign: jest.fn().mockResolvedValue("mocked-jwt"),
|
|
}),
|
|
jwtVerify: jest.fn(),
|
|
}));
|
|
|
|
import { ConfigService } from "@nestjs/config";
|
|
import { Test, TestingModule } from "@nestjs/testing";
|
|
import { AuthController } from "./auth.controller";
|
|
import { AuthService } from "./auth.service";
|
|
import { BootstrapService } from "./bootstrap.service";
|
|
|
|
jest.mock("iron-session", () => ({
|
|
getIronSession: jest.fn().mockResolvedValue({
|
|
save: jest.fn(),
|
|
destroy: jest.fn(),
|
|
}),
|
|
}));
|
|
|
|
describe("AuthController", () => {
|
|
let controller: AuthController;
|
|
let authService: AuthService;
|
|
let _configService: ConfigService;
|
|
|
|
const mockAuthService = {
|
|
register: jest.fn(),
|
|
login: jest.fn(),
|
|
verifyTwoFactorLogin: jest.fn(),
|
|
refresh: jest.fn(),
|
|
};
|
|
|
|
const mockBootstrapService = {
|
|
consumeToken: jest.fn(),
|
|
};
|
|
|
|
const mockConfigService = {
|
|
get: jest
|
|
.fn()
|
|
.mockReturnValue("complex_password_at_least_32_characters_long"),
|
|
};
|
|
|
|
beforeEach(async () => {
|
|
const module: TestingModule = await Test.createTestingModule({
|
|
controllers: [AuthController],
|
|
providers: [
|
|
{ provide: AuthService, useValue: mockAuthService },
|
|
{ provide: BootstrapService, useValue: mockBootstrapService },
|
|
{ provide: ConfigService, useValue: mockConfigService },
|
|
],
|
|
}).compile();
|
|
|
|
controller = module.get<AuthController>(AuthController);
|
|
authService = module.get<AuthService>(AuthService);
|
|
_configService = module.get<ConfigService>(ConfigService);
|
|
});
|
|
|
|
it("should be defined", () => {
|
|
expect(controller).toBeDefined();
|
|
});
|
|
|
|
describe("register", () => {
|
|
it("should call authService.register", async () => {
|
|
const dto = {
|
|
email: "test@example.com",
|
|
password: "password",
|
|
username: "test",
|
|
};
|
|
await controller.register(dto as any);
|
|
expect(authService.register).toHaveBeenCalledWith(dto);
|
|
});
|
|
});
|
|
|
|
describe("login", () => {
|
|
it("should call authService.login and setup session if success", async () => {
|
|
const dto = { email: "test@example.com", password: "password" };
|
|
const req = { ip: "127.0.0.1" } as any;
|
|
const res = { json: jest.fn() } as any;
|
|
const loginResult = {
|
|
access_token: "at",
|
|
refresh_token: "rt",
|
|
userId: "1",
|
|
message: "ok",
|
|
};
|
|
mockAuthService.login.mockResolvedValue(loginResult);
|
|
|
|
await controller.login(dto as any, "ua", req, res);
|
|
|
|
expect(authService.login).toHaveBeenCalledWith(dto, "ua", "127.0.0.1");
|
|
expect(res.json).toHaveBeenCalledWith({ message: "ok", userId: "1" });
|
|
});
|
|
|
|
it("should return result if no access_token", async () => {
|
|
const dto = { email: "test@example.com", password: "password" };
|
|
const req = { ip: "127.0.0.1" } as any;
|
|
const res = { json: jest.fn() } as any;
|
|
const loginResult = { message: "2fa_required", userId: "1" };
|
|
mockAuthService.login.mockResolvedValue(loginResult);
|
|
|
|
await controller.login(dto as any, "ua", req, res);
|
|
|
|
expect(res.json).toHaveBeenCalledWith(loginResult);
|
|
});
|
|
});
|
|
|
|
describe("verifyTwoFactor", () => {
|
|
it("should call authService.verifyTwoFactorLogin and setup session", async () => {
|
|
const dto = { userId: "1", token: "123456" };
|
|
const req = { ip: "127.0.0.1" } as any;
|
|
const res = { json: jest.fn() } as any;
|
|
const verifyResult = {
|
|
access_token: "at",
|
|
refresh_token: "rt",
|
|
message: "ok",
|
|
};
|
|
mockAuthService.verifyTwoFactorLogin.mockResolvedValue(verifyResult);
|
|
|
|
await controller.verifyTwoFactor(dto, "ua", req, res);
|
|
|
|
expect(authService.verifyTwoFactorLogin).toHaveBeenCalledWith(
|
|
"1",
|
|
"123456",
|
|
"ua",
|
|
"127.0.0.1",
|
|
);
|
|
expect(res.json).toHaveBeenCalledWith({ message: "ok" });
|
|
});
|
|
});
|
|
|
|
describe("refresh", () => {
|
|
it("should refresh token if session has refresh token", async () => {
|
|
const { getIronSession } = require("iron-session");
|
|
const session = { refreshToken: "rt", save: jest.fn() };
|
|
getIronSession.mockResolvedValue(session);
|
|
const req = {} as any;
|
|
const res = { json: jest.fn() } as any;
|
|
mockAuthService.refresh.mockResolvedValue({
|
|
access_token: "at2",
|
|
refresh_token: "rt2",
|
|
});
|
|
|
|
await controller.refresh(req, res);
|
|
|
|
expect(authService.refresh).toHaveBeenCalledWith("rt");
|
|
expect(res.json).toHaveBeenCalledWith({ message: "Token refreshed" });
|
|
});
|
|
|
|
it("should return 401 if no refresh token", async () => {
|
|
const { getIronSession } = require("iron-session");
|
|
const session = { save: jest.fn() };
|
|
getIronSession.mockResolvedValue(session);
|
|
const req = {} as any;
|
|
const res = { status: jest.fn().mockReturnThis(), json: jest.fn() } as any;
|
|
|
|
await controller.refresh(req, res);
|
|
|
|
expect(res.status).toHaveBeenCalledWith(401);
|
|
});
|
|
});
|
|
|
|
describe("logout", () => {
|
|
it("should destroy session", async () => {
|
|
const { getIronSession } = require("iron-session");
|
|
const session = { destroy: jest.fn() };
|
|
getIronSession.mockResolvedValue(session);
|
|
const req = {} as any;
|
|
const res = { json: jest.fn() } as any;
|
|
|
|
await controller.logout(req, res);
|
|
|
|
expect(session.destroy).toHaveBeenCalled();
|
|
expect(res.json).toHaveBeenCalledWith({ message: "User logged out" });
|
|
});
|
|
});
|
|
});
|