import { describe, it, expect, jest, beforeEach } from "bun:test"; import { AccountNotFoundError, AccountAlreadyExistsError, BadPasswordError, } from "../../src/domain/account/errors/AccountErrors"; import AccountService from "../../src/domain/account/service/AccountService"; import { AccountEntity } from "../../src/domain/account/entity/AccountEntity"; describe("AccountService", () => { let accountService: AccountService; let mockAccountRepository: { findByUsername: ReturnType; insert: ReturnType; findById: ReturnType; }; beforeEach(() => { mockAccountRepository = { findByUsername: jest.fn(() => Promise.resolve(null)), insert: jest.fn(() => Promise.resolve("123")), findById: jest.fn(() => Promise.resolve(null)), }; accountService = new AccountService(mockAccountRepository as any); }); describe("createAccount", () => { it("should create a new account successfully", async () => { const username = "testusername"; const password = "password123"; mockAccountRepository.findByUsername.mockImplementation(() => Promise.resolve(null), ); mockAccountRepository.findById.mockImplementation(() => Promise.resolve( new AccountEntity( 123, username, "hashedpassword", 1, new Date(), new Date(), ), ), ); mockAccountRepository.insert.mockImplementation(() => Promise.resolve(123), ); const result = await accountService.register(username, password); expect(result).toBeInstanceOf(AccountEntity); expect(result.username).toBe(username); expect(mockAccountRepository.findByUsername).toHaveBeenCalledWith( username, ); }); it("should throw error if account already exists", async () => { const username = "testusername"; const password = "password123"; const existingAccount = await AccountEntity.create(username, password); mockAccountRepository.findByUsername.mockImplementation(() => Promise.resolve(existingAccount), ); expect(accountService.register(username, password)).rejects.toThrow( AccountAlreadyExistsError, ); }); }); describe("login", () => { it("should login successfully with correct credentials", async () => { const username = "testaccount"; const password = "password123"; const createAccount = await AccountEntity.create(username, password); const account = new AccountEntity( 1, createAccount.username, createAccount.hashedPassword, createAccount.roleId, new Date(), new Date(), ); mockAccountRepository.findByUsername.mockImplementation(() => Promise.resolve(account), ); const result = await accountService.login(username, password); expect({ username: result.username, roleId: result.roleId }).toEqual({ username: account.username, roleId: account.roleId, }); expect(mockAccountRepository.findByUsername).toHaveBeenCalledWith( username, ); }); it("should throw error if account not found", async () => { const username = "testaccount"; const password = "password123"; mockAccountRepository.findByUsername.mockImplementation(() => Promise.resolve(null), ); expect(accountService.login(username, password)).rejects.toThrow( AccountNotFoundError, ); }); it("should throw error if password is incorrect", async () => { const username = "testaccount"; const password = "password123"; const wrongPassword = "wrongpassword"; const createAccount = await AccountEntity.create(username, password); const account = new AccountEntity( 1, createAccount.username, createAccount.hashedPassword, createAccount.roleId, new Date(), new Date(), ); mockAccountRepository.findByUsername.mockImplementation(() => Promise.resolve(account), ); expect(accountService.login(username, wrongPassword)).rejects.toThrow( BadPasswordError, ); }); }); });