import { TaxService } from "../src/tax/tax.service"; import { createPrismaMock } from "./utils/mock-prisma"; describe("TaxService", () => { it("saves and submits complete intake as ready", async () => { const prisma = createPrismaMock(); const createdAt = new Date("2026-07-16T00:00:00.000Z"); prisma.taxReturn.findFirst.mockResolvedValue({ id: "return_1", userId: "user_1", taxYear: 2026, filingType: "individual", jurisdictions: ["CA"], status: "draft", summary: {}, createdAt, updatedAt: createdAt, }); prisma.taxReturn.update.mockResolvedValue({ id: "return_1", status: "ready", summary: {}, }); prisma.auditLog.create.mockResolvedValue({}); const service = new TaxService(prisma as any); const result = await service.saveIntake("user_1", "return_1", { taxpayer: { name: "Jane Doe", filingStatus: "Single", address: "1 Main St" }, income: { total: 120000 }, deductions: { standard: true }, credits: {}, }, true); expect(result.readiness.complete).toBe(true); expect(prisma.taxReturn.update).toHaveBeenCalledWith({ where: { id: "return_1" }, data: expect.objectContaining({ status: "ready", summary: expect.objectContaining({ intake: expect.any(Object), intakeReadiness: expect.objectContaining({ complete: true }), }), }), }); expect(prisma.auditLog.create).toHaveBeenCalledWith({ data: expect.objectContaining({ action: "tax.intake_submit", }), }); }); it("exports a versioned package with hash, manifest, and audit log", async () => { const prisma = createPrismaMock(); const createdAt = new Date("2026-07-16T00:00:00.000Z"); prisma.taxReturn.findFirst.mockResolvedValue({ id: "return_1", userId: "user_1", taxYear: 2026, filingType: "individual", jurisdictions: ["CA"], status: "draft", summary: { grossIncome: 1000 }, createdAt, updatedAt: createdAt, documents: [ { id: "doc_1", taxReturnId: "return_1", docType: "w2_or_1099", metadata: { source: "upload" }, createdAt, }, ], }); prisma.taxReturn.update.mockResolvedValue({}); prisma.auditLog.create.mockResolvedValue({}); const service = new TaxService(prisma as any); const result = await service.exportReturn("user_1", "return_1"); expect(result.packageId).toMatch(/^taxpkg_/); expect(result.packageVersion).toBe("2026.1"); expect(result.packageHash).toMatch(/^[a-f0-9]{64}$/); expect(result.manifest).toEqual(expect.objectContaining({ taxReturnId: "return_1", taxYear: 2026, filingType: "individual", documentCount: 1, readiness: "needs_documents", })); expect(result.return.status).toBe("exported"); expect(result.documents).toHaveLength(1); expect(prisma.auditLog.create).toHaveBeenCalledWith({ data: expect.objectContaining({ userId: "user_1", action: "tax.export_package", metadata: expect.objectContaining({ taxReturnId: "return_1", packageHash: result.packageHash, }), }), }); }); it("submits a ready return to the sandbox e-file provider", async () => { const prisma = createPrismaMock(); const createdAt = new Date("2026-07-16T00:00:00.000Z"); prisma.taxReturn.findFirst.mockResolvedValue({ id: "return_1", userId: "user_1", taxYear: 2026, filingType: "individual", jurisdictions: ["CA"], status: "ready", summary: { intake: { taxpayer: { name: "Jane Doe", filingStatus: "Single", address: "1 Main St" }, income: { total: 120000 }, }, }, createdAt, updatedAt: createdAt, documents: [ { id: "doc_1", docType: "w2_or_1099", metadata: {}, createdAt }, { id: "doc_2", docType: "interest_and_dividend_forms", metadata: {}, createdAt }, { id: "doc_3", docType: "deduction_support", metadata: {}, createdAt }, { id: "doc_4", docType: "identity_information", metadata: {}, createdAt }, ], }); prisma.taxReturn.update.mockResolvedValue({ id: "return_1", status: "efile_submitted", summary: {}, }); prisma.auditLog.create.mockResolvedValue({}); const service = new TaxService(prisma as any); const result = await service.submitEFile("user_1", "return_1", true); expect(result.eFile.provider).toBe("sandbox"); expect(result.eFile.status).toBe("submitted"); expect(result.eFile.submissionId).toMatch(/^efile_/); expect(result.eFile.packageHash).toMatch(/^[a-f0-9]{64}$/); expect(prisma.taxReturn.update).toHaveBeenCalledWith({ where: { id: "return_1" }, data: expect.objectContaining({ status: "efile_submitted", summary: expect.objectContaining({ eFile: expect.objectContaining({ provider: "sandbox", status: "submitted", }), }), }), }); expect(prisma.auditLog.create).toHaveBeenCalledWith({ data: expect.objectContaining({ action: "tax.efile_submit", }), }); }); it("blocks e-file submission when intake or documents are incomplete", async () => { const prisma = createPrismaMock(); prisma.taxReturn.findFirst.mockResolvedValue({ id: "return_1", userId: "user_1", taxYear: 2026, filingType: "individual", jurisdictions: ["CA"], status: "draft", summary: { intake: { taxpayer: { name: "Jane Doe" }, income: {} } }, documents: [], }); const service = new TaxService(prisma as any); await expect(service.submitEFile("user_1", "return_1", true)).rejects.toThrow( "Tax return is not ready for e-file submission.", ); expect(prisma.taxReturn.update).not.toHaveBeenCalled(); }); });