import { randomUUID } from "node:crypto"; import { INestApplication } from "@nestjs/common"; import { afterAll, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; import { agent, bearer, closeTestApp, createTestApp, loginSuperAdmin, type AuthedTokens } from "./setup.js"; import type { CnpjLookupResult } from "@eden/integrations"; /** * POST /v1/client-registrations/:id/cnpj-lookup — the whole test suite * mocks `lookupCnpj` (network calls to cnpj.ws/BrasilAPI are NOT allowed * in this suite; a real call against the internet is done manually, once, * outside of vitest — see the task notes). */ const lookupCnpjMock = vi.fn<(cnpj: string) => Promise>(); vi.mock("@eden/integrations", async () => { const actual = await vi.importActual("@eden/integrations"); return { ...actual, lookupCnpj: (cnpj: string) => lookupCnpjMock(cnpj), }; }); const FOUND_RESULT: CnpjLookupResult = { companyName: "qa-test- Empresa Lookup LTDA", tradeName: "qa-test- Lookup", openingDate: "2010-05-04", legalNature: "Sociedade Empresária Limitada", cnpjSituation: "ATIVA", mainActivity: "Desenvolvimento de programas de computador sob encomenda", address: { zip: "01310-100", street: "Av. Paulista", number: "1000", complement: "Sala 10", neighborhood: "Bela Vista", city: "São Paulo", state: "SP", }, stateRegistration: "123.456.789.110", partners: [ { name: "Fulano de Tal", document: "***123456**", qualification: "Sócio-Administrador" }, { name: "Beltrano da Silva", document: "***654321**", qualification: "Sócio" }, ], }; describe("client-registrations — CNPJ lookup autofill", () => { let app: INestApplication; let admin: AuthedTokens; beforeAll(async () => { app = await createTestApp(); admin = await loginSuperAdmin(app); }); beforeEach(() => { lookupCnpjMock.mockReset(); }); afterAll(async () => { await closeTestApp(app); }); async function createDirectRegistration(personType: "pf" | "pj") { const res = await agent(app) .post("/api/v1/client-registrations/direct") .set(...bearer(admin.accessToken)) .send({ personType, isPortability: false }) .expect(201); return res.body.id as string; } it("applies company data and creates partners when the CNPJ is found", async () => { lookupCnpjMock.mockResolvedValue(FOUND_RESULT); const id = await createDirectRegistration("pj"); const res = await agent(app) .post(`/api/v1/client-registrations/${id}/cnpj-lookup`) .set(...bearer(admin.accessToken)) .send({ cnpj: "11.222.333/0001-81" }) .expect(201); expect(lookupCnpjMock).toHaveBeenCalledWith("11.222.333/0001-81"); expect(res.body.registration.pj_cnpj).toBe("11222333000181"); expect(res.body.registration.pj_company_name).toBe(FOUND_RESULT.companyName); expect(res.body.registration.pj_trade_name).toBe(FOUND_RESULT.tradeName); expect(res.body.registration.pj_state_registration).toBe(FOUND_RESULT.stateRegistration); expect(res.body.registration.pj_legal_nature).toBe(FOUND_RESULT.legalNature); expect(res.body.registration.pj_cnpj_situation).toBe(FOUND_RESULT.cnpjSituation); expect(res.body.registration.pj_main_activity).toBe(FOUND_RESULT.mainActivity); expect(res.body.registration.address_zip).toBe(FOUND_RESULT.address.zip); expect(res.body.registration.address_street).toBe(FOUND_RESULT.address.street); expect(res.body.registration.address_city).toBe(FOUND_RESULT.address.city); expect(res.body.registration.address_state).toBe(FOUND_RESULT.address.state); expect(res.body.partners).toHaveLength(2); expect(res.body.partners.map((p: { name: string }) => p.name).sort()).toEqual( ["Beltrano da Silva", "Fulano de Tal"].sort(), ); expect(res.body.partners.every((p: { source: string }) => p.source === "cnpj_lookup")).toBe(true); expect(res.body.partners.every((p: { will_sign: boolean }) => p.will_sign === false)).toBe(true); const getRes = await agent(app) .get(`/api/v1/client-registrations/${id}`) .set(...bearer(admin.accessToken)) .expect(200); expect(getRes.body.pj_cnpj).toBe("11222333000181"); const partnersRes = await agent(app) .get(`/api/v1/client-registrations/${id}/partners`) .set(...bearer(admin.accessToken)) .expect(200); expect(partnersRes.body).toHaveLength(2); }); it("running the lookup twice does not duplicate partners (dedup by document)", async () => { lookupCnpjMock.mockResolvedValue(FOUND_RESULT); const id = await createDirectRegistration("pj"); await agent(app) .post(`/api/v1/client-registrations/${id}/cnpj-lookup`) .set(...bearer(admin.accessToken)) .send({ cnpj: "11222333000181" }) .expect(201); const second = await agent(app) .post(`/api/v1/client-registrations/${id}/cnpj-lookup`) .set(...bearer(admin.accessToken)) .send({ cnpj: "11222333000181" }) .expect(201); expect(second.body.partners).toHaveLength(2); const partnersRes = await agent(app) .get(`/api/v1/client-registrations/${id}/partners`) .set(...bearer(admin.accessToken)) .expect(200); expect(partnersRes.body).toHaveLength(2); }); it("returns 404 and applies no changes when the CNPJ is not found in either source", async () => { lookupCnpjMock.mockResolvedValue(null); const id = await createDirectRegistration("pj"); await agent(app) .post(`/api/v1/client-registrations/${id}/cnpj-lookup`) .set(...bearer(admin.accessToken)) .send({ cnpj: "99999999000199" }) .expect(404); const getRes = await agent(app) .get(`/api/v1/client-registrations/${id}`) .set(...bearer(admin.accessToken)) .expect(200); expect(getRes.body.pj_cnpj).toBeNull(); expect(getRes.body.pj_company_name).toBeNull(); const partnersRes = await agent(app) .get(`/api/v1/client-registrations/${id}/partners`) .set(...bearer(admin.accessToken)) .expect(200); expect(partnersRes.body).toHaveLength(0); }); it("rejects CNPJ lookup for a PF registration with 400", async () => { const id = await createDirectRegistration("pf"); const res = await agent(app) .post(`/api/v1/client-registrations/${id}/cnpj-lookup`) .set(...bearer(admin.accessToken)) .send({ cnpj: "11222333000181" }) .expect(400); expect(res.body.message).toMatch(/pessoa jurídica/i); expect(lookupCnpjMock).not.toHaveBeenCalled(); }); it("returns 404 for a client registration id that doesn't exist", async () => { await agent(app) .post(`/api/v1/client-registrations/${randomUUID()}/cnpj-lookup`) .set(...bearer(admin.accessToken)) .send({ cnpj: "11222333000181" }) .expect(404); expect(lookupCnpjMock).not.toHaveBeenCalled(); }); });