Deleted unused e2e tests, mocks (`cuid2`, `jose`, `ml-kem`, `sha3`), and their associated jest configurations. Simplified services by ensuring proper dependency imports, resolving circular references, and improving TypeScript type usage for enhanced maintainability and testability. Upgraded Dockerfile base image to match new development standards.
120 lines
3.3 KiB
TypeScript
120 lines
3.3 KiB
TypeScript
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(),
|
|
jwtVerify: jest.fn(),
|
|
}));
|
|
|
|
import { UnauthorizedException } from "@nestjs/common";
|
|
import { Test, TestingModule } from "@nestjs/testing";
|
|
import { HashingService } from "../crypto/services/hashing.service";
|
|
import { JwtService } from "../crypto/services/jwt.service";
|
|
import { SessionsRepository } from "./repositories/sessions.repository";
|
|
import { SessionsService } from "./sessions.service";
|
|
|
|
describe("SessionsService", () => {
|
|
let service: SessionsService;
|
|
let repository: SessionsRepository;
|
|
|
|
const mockSessionsRepository = {
|
|
create: jest.fn(),
|
|
findValidByRefreshToken: jest.fn(),
|
|
update: jest.fn(),
|
|
revoke: jest.fn(),
|
|
revokeAllByUserId: jest.fn(),
|
|
};
|
|
|
|
const mockHashingService = {
|
|
hashIp: jest.fn().mockResolvedValue("hashed-ip"),
|
|
};
|
|
|
|
const mockJwtService = {
|
|
generateJwt: jest.fn().mockResolvedValue("new-token"),
|
|
};
|
|
|
|
beforeEach(async () => {
|
|
jest.clearAllMocks();
|
|
|
|
const module: TestingModule = await Test.createTestingModule({
|
|
providers: [
|
|
SessionsService,
|
|
{ provide: SessionsRepository, useValue: mockSessionsRepository },
|
|
{ provide: HashingService, useValue: mockHashingService },
|
|
{ provide: JwtService, useValue: mockJwtService },
|
|
],
|
|
}).compile();
|
|
|
|
service = module.get<SessionsService>(SessionsService);
|
|
repository = module.get<SessionsRepository>(SessionsRepository);
|
|
});
|
|
|
|
it("should be defined", () => {
|
|
expect(service).toBeDefined();
|
|
});
|
|
|
|
describe("createSession", () => {
|
|
it("should create a session", async () => {
|
|
mockSessionsRepository.create.mockResolvedValue({ id: "s1" });
|
|
const result = await service.createSession("u1", "agent", "1.2.3.4");
|
|
expect(result).toEqual({ id: "s1" });
|
|
expect(repository.create).toHaveBeenCalled();
|
|
});
|
|
});
|
|
|
|
describe("refreshSession", () => {
|
|
it("should refresh a valid session", async () => {
|
|
const expiresAt = new Date();
|
|
expiresAt.setDate(expiresAt.getDate() + 1);
|
|
mockSessionsRepository.findValidByRefreshToken.mockResolvedValue({
|
|
id: "s1",
|
|
userId: "u1",
|
|
expiresAt,
|
|
});
|
|
mockSessionsRepository.update.mockResolvedValue({
|
|
id: "s1",
|
|
refreshToken: "new-token",
|
|
});
|
|
|
|
const result = await service.refreshSession("old-token");
|
|
|
|
expect(result.refreshToken).toBe("new-token");
|
|
expect(repository.update).toHaveBeenCalled();
|
|
});
|
|
|
|
it("should throw if session not found", async () => {
|
|
mockSessionsRepository.findValidByRefreshToken.mockResolvedValue(null);
|
|
await expect(service.refreshSession("invalid")).rejects.toThrow(
|
|
UnauthorizedException,
|
|
);
|
|
});
|
|
|
|
it("should throw and revoke if session expired", async () => {
|
|
const expiresAt = new Date();
|
|
expiresAt.setDate(expiresAt.getDate() - 1);
|
|
mockSessionsRepository.findValidByRefreshToken.mockResolvedValue({
|
|
id: "s1",
|
|
userId: "u1",
|
|
expiresAt,
|
|
});
|
|
|
|
await expect(service.refreshSession("expired")).rejects.toThrow(
|
|
UnauthorizedException,
|
|
);
|
|
expect(repository.revoke).toHaveBeenCalledWith("s1");
|
|
});
|
|
});
|
|
|
|
describe("revokeSession", () => {
|
|
it("should revoke a session", async () => {
|
|
await service.revokeSession("s1");
|
|
expect(repository.revoke).toHaveBeenCalledWith("s1");
|
|
});
|
|
});
|
|
});
|