@@ -0,0 +1,83 @@
|
||||
// A refusal of the Ledger service reaches the person as the kit's sentence for it, in their language.
|
||||
// Before the kit helper, the module mapped refusals itself and compared a `BusinessErrorCode` with Ledger's
|
||||
// reasons (`unbalanced`, `insufficient-funds`), which it never is: an unbalanced posting was answered
|
||||
// "reload the ledger record". Generated HTTP client with a synthetic binding; no gateway/live acceptance.
|
||||
import type { RequestBusinessBinding } from "@conusai-kit/business"
|
||||
import { describeBusinessRefusal } from "@conusai-kit/business/refusals"
|
||||
import { describe, expect, it } from "vitest"
|
||||
import { sdkLedgerService } from "../adapters/service.js"
|
||||
import { LEDGER_ERRORS } from "../contract/index.js"
|
||||
import type { LedgerService } from "../core/ports.js"
|
||||
import { en } from "../i18n/en.js"
|
||||
import { lt } from "../i18n/lt.js"
|
||||
import { ledgerFailure } from "../ui/errors.js"
|
||||
import { ledgerLabels } from "../ui/labels.js"
|
||||
|
||||
const id = "acc_00000000-0000-4000-8000-000000000001"
|
||||
function refusing(reason: string, status: number) {
|
||||
const binding = {
|
||||
orgSlug: "verified-org",
|
||||
client: (factory: Parameters<RequestBusinessBinding["client"]>[0]) => {
|
||||
const client = factory({ baseUrl: "https://ledger.example.test", auth: "synthetic", throwOnError: false })
|
||||
client.setConfig({
|
||||
fetch: async () =>
|
||||
new Response(
|
||||
JSON.stringify({
|
||||
type: `urn:conusai:ledger:${reason}`,
|
||||
status,
|
||||
code: `LEDGER_${reason.replaceAll("-", "_").toUpperCase()}`,
|
||||
title: "Ledger request refused",
|
||||
}),
|
||||
{ status, headers: { "content-type": "application/json" } },
|
||||
),
|
||||
})
|
||||
return client
|
||||
},
|
||||
} as RequestBusinessBinding
|
||||
return sdkLedgerService(binding)
|
||||
}
|
||||
const terms: Parameters<LedgerService["record"]>[0] = {
|
||||
effectiveAt: "2026-11-03T00:00:00Z",
|
||||
description: "Synthetic",
|
||||
status: "posted",
|
||||
entries: [
|
||||
{ accountId: id, direction: "debit", amountMinor: "100" },
|
||||
{ accountId: id, direction: "credit", amountMinor: "99" },
|
||||
],
|
||||
}
|
||||
|
||||
async function refusalOf(reason: string, status: number): Promise<unknown> {
|
||||
try {
|
||||
await refusing(reason, status).record(terms, "stable-key")
|
||||
} catch (error) {
|
||||
return error
|
||||
}
|
||||
throw new Error("expected a refusal")
|
||||
}
|
||||
|
||||
describe("Ledger refusals through the kit", () => {
|
||||
it("tells the person an unbalanced posting does not balance, in English and Lithuanian", async () => {
|
||||
const error = await refusalOf("unbalanced", 409)
|
||||
expect(error).toHaveProperty("problem.code", "business_unbalanced")
|
||||
expect(error).toHaveProperty("problem.status", 409)
|
||||
expect(describeBusinessRefusal(error, "en")).toBe("Debits and credits do not balance.")
|
||||
expect(describeBusinessRefusal(error, "lt")).toBe("Debetas ir kreditas nesutampa.")
|
||||
})
|
||||
|
||||
it("names insufficient funds and a transaction's state as such", async () => {
|
||||
expect(await refusalOf("insufficient-funds", 409)).toHaveProperty("problem.code", "business_insufficient_funds")
|
||||
expect(await refusalOf("transaction-state", 409)).toHaveProperty("problem.code", "business_transaction_state")
|
||||
})
|
||||
|
||||
it("shows a form the kit's sentence, a conflict in this module's words, and the module's own drift fence", async () => {
|
||||
const labelsOf = (messages: Record<string, string>, locale: "en" | "lt") =>
|
||||
ledgerLabels((key) => messages[key] ?? key, locale)
|
||||
const english = labelsOf(en, "en")
|
||||
const lithuanian = labelsOf(lt, "lt")
|
||||
expect(ledgerFailure(await refusalOf("unbalanced", 409), english)).toBe("Debits and credits do not balance.")
|
||||
expect(ledgerFailure(await refusalOf("unbalanced", 409), lithuanian)).toBe("Debetas ir kreditas nesutampa.")
|
||||
expect(ledgerFailure(await refusalOf("revision-conflict", 409), english)).toBe(en.revisionConflict)
|
||||
expect(ledgerFailure(await refusalOf("idempotency-conflict", 409), lithuanian)).toBe(lt.idempotencyConflict)
|
||||
expect(ledgerFailure({ problem: { code: LEDGER_ERRORS.drift } }, english)).toBe(en.drift)
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user