import { Test, TestingModule } from "@nestjs/testing"; import { DatabaseService } from "../../database/database.service"; import { UsersRepository } from "./users.repository"; describe("UsersRepository", () => { let repository: UsersRepository; let _databaseService: DatabaseService; const mockDb = { insert: jest.fn().mockReturnThis(), values: jest.fn().mockReturnThis(), returning: jest.fn().mockResolvedValue([{ uuid: "u1" }]), select: jest.fn().mockReturnThis(), from: jest.fn().mockReturnThis(), where: jest.fn().mockReturnThis(), limit: jest.fn().mockReturnThis(), offset: jest.fn().mockReturnThis(), update: jest.fn().mockReturnThis(), set: jest.fn().mockReturnThis(), delete: jest.fn().mockReturnThis(), transaction: jest.fn(), }; beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ providers: [ UsersRepository, { provide: DatabaseService, useValue: { db: mockDb }, }, ], }).compile(); repository = module.get(UsersRepository); _databaseService = module.get(DatabaseService); jest.clearAllMocks(); }); it("should be defined", () => { expect(repository).toBeDefined(); }); describe("create", () => { it("should insert a user", async () => { const data = { username: "u", email: "e", passwordHash: "p", emailHash: "eh", }; await repository.create(data); expect(mockDb.insert).toHaveBeenCalled(); expect(mockDb.values).toHaveBeenCalledWith(data); }); }); describe("findByEmailHash", () => { it("should select user by email hash", async () => { mockDb.limit.mockResolvedValueOnce([{ uuid: "u1" }]); const result = await repository.findByEmailHash("hash"); expect(result.uuid).toBe("u1"); expect(mockDb.select).toHaveBeenCalled(); expect(mockDb.where).toHaveBeenCalled(); }); }); describe("findOneWithPrivateData", () => { it("should select user with private data", async () => { mockDb.limit.mockResolvedValueOnce([{ uuid: "u1" }]); const result = await repository.findOneWithPrivateData("u1"); expect(result.uuid).toBe("u1"); }); }); describe("countAll", () => { it("should return count", async () => { mockDb.from.mockResolvedValueOnce([{ count: 5 }]); const result = await repository.countAll(); expect(result).toBe(5); }); }); describe("findAll", () => { it("should select users with limit and offset", async () => { mockDb.offset.mockResolvedValueOnce([{ uuid: "u1" }]); const result = await repository.findAll(10, 0); expect(result[0].uuid).toBe("u1"); expect(mockDb.limit).toHaveBeenCalledWith(10); expect(mockDb.offset).toHaveBeenCalledWith(0); }); }); describe("findByUsername", () => { it("should find by username", async () => { mockDb.limit.mockResolvedValueOnce([{ uuid: "u1" }]); const result = await repository.findByUsername("u"); expect(result.uuid).toBe("u1"); }); }); describe("update", () => { it("should update user", async () => { mockDb.returning.mockResolvedValueOnce([{ uuid: "u1" }]); await repository.update("u1", { displayName: "New" }); expect(mockDb.update).toHaveBeenCalled(); expect(mockDb.set).toHaveBeenCalled(); }); }); describe("getTwoFactorSecret", () => { it("should return secret", async () => { mockDb.limit.mockResolvedValueOnce([{ secret: "s" }]); const result = await repository.getTwoFactorSecret("u1"); expect(result).toBe("s"); }); }); describe("getUserContents", () => { it("should return contents", async () => { mockDb.where.mockResolvedValueOnce([{ id: "c1" }]); const result = await repository.getUserContents("u1"); expect(result[0].id).toBe("c1"); }); }); describe("softDeleteUserAndContents", () => { it("should run transaction", async () => { const mockTx = { update: jest.fn().mockReturnThis(), set: jest.fn().mockReturnThis(), where: jest.fn().mockReturnThis(), returning: jest.fn().mockResolvedValue([{ uuid: "u1" }]), }; mockDb.transaction.mockImplementation(async (cb) => cb(mockTx)); const result = await repository.softDeleteUserAndContents("u1"); expect(result[0].uuid).toBe("u1"); expect(mockTx.update).toHaveBeenCalledTimes(2); }); }); describe("purgeDeleted", () => { it("should delete old deleted users", async () => { mockDb.returning.mockResolvedValueOnce([{ uuid: "u1" }]); const _result = await repository.purgeDeleted(new Date()); expect(mockDb.delete).toHaveBeenCalled(); }); }); });