diff --git a/src/handlers/update-xero-bank-transaction.handler.test.ts b/src/handlers/update-xero-bank-transaction.handler.test.ts new file mode 100644 index 00000000..acd8aad0 --- /dev/null +++ b/src/handlers/update-xero-bank-transaction.handler.test.ts @@ -0,0 +1,107 @@ +import { beforeEach, describe, expect, it, vi } from "vitest"; +import { BankTransaction } from "xero-node"; + +const authenticateMock = vi.fn(); +const getBankTransactionMock = vi.fn(); +const updateBankTransactionMock = vi.fn(); +const getClientHeadersMock = vi.fn(() => ({ "x-test": "header" })); + +vi.mock("../clients/xero-client.js", () => ({ + xeroClient: { + tenantId: "tenant-123", + authenticate: authenticateMock, + accountingApi: { + getBankTransaction: getBankTransactionMock, + updateBankTransaction: updateBankTransactionMock, + }, + }, +})); + +vi.mock("../helpers/get-client-headers.js", () => ({ + getClientHeaders: getClientHeadersMock, +})); + +describe("updateXeroBankTransaction", () => { + beforeEach(() => { + vi.clearAllMocks(); + }); + + it("sends a minimal update payload when line items are provided", async () => { + const existingBankTransaction: Partial = { + bankTransactionID: "btx-123", + reference: "old-ref", + date: "2026-06-01", + lineItems: [ + { + description: "Old item", + quantity: 1, + unitAmount: 10, + accountCode: "200", + taxType: "NONE", + }, + ], + status: BankTransaction.StatusEnum.AUTHORISED, + }; + + const newLineItems = [ + { + description: "Updated item", + quantity: 2, + unitAmount: 25, + accountCode: "310", + taxType: "OUTPUT2", + }, + ]; + + getBankTransactionMock.mockResolvedValue({ + body: { bankTransactions: [existingBankTransaction] }, + }); + updateBankTransactionMock.mockResolvedValue({ + body: { + bankTransactions: [ + { + bankTransactionID: "btx-123", + lineItems: newLineItems, + }, + ], + }, + }); + + const { updateXeroBankTransaction } = await import( + "./update-xero-bank-transaction.handler.js" + ); + + const result = await updateXeroBankTransaction( + "btx-123", + undefined, + undefined, + newLineItems, + "new-ref", + "2026-06-12", + ); + + expect(result.isError).toBe(false); + expect(authenticateMock).toHaveBeenCalledTimes(1); + expect(updateBankTransactionMock).toHaveBeenCalledWith( + "tenant-123", + "btx-123", + { + bankTransactions: [ + { + lineItems: newLineItems, + reference: "new-ref", + date: "2026-06-12", + }, + ], + }, + undefined, + undefined, + { "x-test": "header" }, + ); + + const payload = updateBankTransactionMock.mock.calls[0][2].bankTransactions[0]; + expect(payload).not.toHaveProperty("status"); + expect(payload).not.toHaveProperty("currencyCode"); + expect(payload).not.toHaveProperty("bankTransactionID"); + }); +}); diff --git a/src/handlers/update-xero-bank-transaction.handler.ts b/src/handlers/update-xero-bank-transaction.handler.ts index 8dfdd529..043f72af 100644 --- a/src/handlers/update-xero-bank-transaction.handler.ts +++ b/src/handlers/update-xero-bank-transaction.handler.ts @@ -29,7 +29,6 @@ async function getBankTransaction(bankTransactionId: string): Promise { const bankTransaction: BankTransaction = { - ...existingBankTransaction, - bankTransactionID: bankTransactionId, - type: type ? BankTransaction.TypeEnum[type] : existingBankTransaction.type, - contact: contactId ? { contactID: contactId } : existingBankTransaction.contact, - lineItems: lineItems ? lineItems : existingBankTransaction.lineItems, - reference: reference ? reference : existingBankTransaction.reference, - date: date ? date : existingBankTransaction.date + ...(type ? { type: BankTransaction.TypeEnum[type] } : {}), + ...(contactId ? { contact: { contactID: contactId } } : {}), + ...(lineItems ? { lineItems } : {}), + ...(reference ? { reference } : {}), + ...(date ? { date } : {}), }; const response = await xeroClient.accountingApi.updateBankTransaction( @@ -75,7 +72,6 @@ export async function updateXeroBankTransaction( const updatedBankTransaction = await updateBankTransaction( bankTransactionId, - existingBankTransaction, type, contactId, lineItems, @@ -99,4 +95,4 @@ export async function updateXeroBankTransaction( error: formatError(error), }; } -} \ No newline at end of file +}