diff --git a/apps/server/src/contexts/accounts/domain/services/account-service.integration.test.ts b/apps/server/src/contexts/accounts/domain/services/account-service.integration.test.ts new file mode 100644 index 00000000..aca6c4b0 --- /dev/null +++ b/apps/server/src/contexts/accounts/domain/services/account-service.integration.test.ts @@ -0,0 +1,146 @@ +import { EmailAddress, PhoneNumber, PostalAddress, TINNumber, UniqueID } from "@common/domain"; +import { Maybe, Result } from "@common/helpers"; +import { Account, IAccountProps } from "../aggregates"; +import { IAccountRepository } from "../repositories"; +import { AccountStatus } from "../value-objects"; +import { AccountService } from "./account.service"; + +const mockAccountRepository: IAccountRepository = { + accountExists: jest.fn(), + findAll: jest.fn(), + findByEmail: jest.fn(), + findById: jest.fn(), + create: jest.fn(), + update: jest.fn(), +}; + +const sampleAccountPrimitives = { + id: "c5743279-e1cf-4dd5-baae-6698c8c6183c", + is_freelancer: false, + name: "Empresa XYZ", + trade_name: "XYZ Trading", + tin: "123456789", + street: "Calle Principal 123", + city: "Madrid", + state: "Madrid", + postal_code: "28001", + country: "España", + email: "contacto@xyz.com", + phone: "+34 600 123 456", + fax: "+34 600 654 321", + website: "https://xyz.com", + legal_record: "Registro Mercantil XYZ", + default_tax: 21, + status: "active", + lang_code: "es", + currency_code: "EUR", + logo: "https://xyz.com/logo.png", +}; + +const accountBuilder = (accountData: any) => { + const idOrError = UniqueID.create(sampleAccountPrimitives.id); + const tinOrError = TINNumber.create(sampleAccountPrimitives.tin); + const emailOrError = EmailAddress.create(sampleAccountPrimitives.email); + const phoneOrError = PhoneNumber.create(sampleAccountPrimitives.phone); + const faxOrError = PhoneNumber.createNullable(sampleAccountPrimitives.fax); + const postalAddressOrError = PostalAddress.create({ + street: sampleAccountPrimitives.street, + city: sampleAccountPrimitives.city, + state: sampleAccountPrimitives.state, + postalCode: sampleAccountPrimitives.postal_code, + country: sampleAccountPrimitives.country, + }); + + const result = Result.combine([ + idOrError, + tinOrError, + emailOrError, + phoneOrError, + faxOrError, + postalAddressOrError, + ]); + + if (result.isFailure) { + return Result.fail(result.error); + } + + const validatedData: IAccountProps = { + status: AccountStatus.createInactive(), + isFreelancer: sampleAccountPrimitives.is_freelancer, + name: sampleAccountPrimitives.name, + tradeName: sampleAccountPrimitives.trade_name + ? Maybe.some(sampleAccountPrimitives.trade_name) + : Maybe.none(), + tin: tinOrError.data, + address: postalAddressOrError.data, + email: emailOrError.data, + phone: phoneOrError.data, + fax: faxOrError.data, + website: sampleAccountPrimitives.website + ? Maybe.some(sampleAccountPrimitives.website) + : Maybe.none(), + legalRecord: sampleAccountPrimitives.legal_record, + defaultTax: sampleAccountPrimitives.default_tax, + langCode: sampleAccountPrimitives.lang_code, + currencyCode: sampleAccountPrimitives.currency_code, + logo: sampleAccountPrimitives.logo ? Maybe.some(sampleAccountPrimitives.logo) : Maybe.none(), + }; + + return Account.create(validatedData, idOrError.data); +}; + +describe("AccountService - Integración", () => { + let accountService: AccountService; + let activeSampleAccount: Account; + let inactiveSampleAccount: Account; + let accountId: UniqueID; + + beforeEach(() => { + accountService = new AccountService(mockAccountRepository); + inactiveSampleAccount = accountBuilder(sampleAccountPrimitives).data; + }); + + it("debería activar una cuenta existente", async () => { + const existingAccount = inactiveSampleAccount; + (mockAccountRepository.findById as jest.Mock).mockResolvedValue(Result.ok(existingAccount)); + (mockAccountRepository.update as jest.Mock).mockResolvedValue(undefined); + + const result = await accountService.activateAccount(existingAccount.id); + + console.log(result); + + expect(result.isSuccess).toBe(true); + expect(result.data.isActive).toBeTruthy(); + expect(mockAccountRepository.update).toHaveBeenCalledWith(result.data); + }); + + it("debería desactivar una cuenta existente", async () => { + const existingAccount = Account.update(inactiveSampleAccount, { + status: AccountStatus.createActive(), + }).data; + + (mockAccountRepository.findById as jest.Mock).mockResolvedValue(Result.ok(existingAccount)); + (mockAccountRepository.update as jest.Mock).mockResolvedValue(undefined); + + const result = await accountService.deactivateAccount(existingAccount.id); + expect(result.isSuccess).toBe(true); + expect(result.data.isActive).toBeFalsy(); + expect(mockAccountRepository.update).toHaveBeenCalledWith(result.data); + }); + + it("debería retornar error si la cuenta no existe al activar", async () => { + (mockAccountRepository.findById as jest.Mock).mockResolvedValue(null); + + const result = await accountService.activateAccount(UniqueID.create("", true).data); + expect(result.isFailure).toBe(true); + expect(result.error.message).toBe("Account not found"); + }); + + it("debería retornar error si la cuenta no existe al desactivar", async () => { + (mockAccountRepository.findById as jest.Mock).mockResolvedValue(null); + + const result = await accountService.deactivateAccount(UniqueID.create("", true).data); + expect(result.isFailure).toBe(true); + expect(result.error.message).toBe("Account not found"); + }); +});