taler-typescript-core

Wallet core logic and WebUIs for various components
Log | Files | Refs | Submodules | README | LICENSE

commit 973a12881b05086b7a4f68ea903cebdf11ad5a0c
parent d7f0876e4c484537b22f4528a1ac66b71fb12735
Author: Sebastian <sebasjm@gmail.com>
Date:   Mon, 18 Aug 2025 16:04:21 -0300

fixing unit test of webex

Diffstat:
Mpackages/taler-util/src/payto.test.ts | 34++++++++++++++++++++++++++++++++--
Mpackages/taler-wallet-webextension/src/cta/InvoicePay/stories.tsx | 28++++++++++++++++------------
Mpackages/taler-wallet-webextension/src/cta/Payment/state.ts | 5+----
Mpackages/taler-wallet-webextension/src/cta/Payment/stories.tsx | 43+++++++++++++++++++++++++++++--------------
Mpackages/taler-wallet-webextension/src/cta/Payment/test.ts | 215+++++++++++++------------------------------------------------------------------
5 files changed, 112 insertions(+), 213 deletions(-)

diff --git a/packages/taler-util/src/payto.test.ts b/packages/taler-util/src/payto.test.ts @@ -16,7 +16,12 @@ import test from "ava"; -import { PaytoString, addPaytoQueryParams, parsePaytoUri, stringifyPaytoUri } from "./payto.js"; +import { + PaytoString, + addPaytoQueryParams, + parsePaytoUri, + stringifyPaytoUri, +} from "./payto.js"; test("basic payto parsing", (t) => { const r1 = parsePaytoUri("https://example.com/"); @@ -30,6 +35,28 @@ test("basic payto parsing", (t) => { t.is(r3?.targetPath, "123"); }); +test("basic x-taler-bank payto string", (t) => { + const result = parsePaytoUri( + "payto://x-taler-bank/bank.demo.taler.net/accountName", + ); + t.is(result?.targetType, "x-taler-bank"); + t.is(result?.targetPath, "bank.demo.taler.net/accountName"); + if (!result) { + t.fail(); + throw Error(); + } + if (!result.isKnown) { + t.fail(); + throw Error(); + } + if (result.targetType !== "x-taler-bank") { + t.fail(); + throw Error(); + } + t.is(result.host, "bank.demo.taler.net"); + t.is(result.account, "accountName"); +}); + test("parsing payto and stringify again", (t) => { const payto1 = "payto://iban/DE1231231231?reciever-name=John%20Doe" as PaytoString; @@ -52,5 +79,8 @@ test("adding payto query params", (t) => { const out2 = addPaytoQueryParams(payto1, { foo: "42", }); - t.deepEqual(out2, "payto://iban/DE1231231231?receiver-name=John%20Doe&foo=42"); + t.deepEqual( + out2, + "payto://iban/DE1231231231?receiver-name=John%20Doe&foo=42", + ); }); diff --git a/packages/taler-wallet-webextension/src/cta/InvoicePay/stories.tsx b/packages/taler-wallet-webextension/src/cta/InvoicePay/stories.tsx @@ -19,10 +19,9 @@ * @author Sebastian Javier Marchano (sebasjm) */ -import { - AbsoluteTime -} from "@gnu-taler/taler-util"; +import { AbsoluteTime, TransactionIdStr } from "@gnu-taler/taler-util"; import * as tests from "@gnu-taler/web-util/testing"; +import { State } from "../Payment/index.js"; import { ReadyView } from "./views.js"; export default { @@ -30,6 +29,7 @@ export default { }; export const Ready = tests.createExample(ReadyView, { + status: "ready" as const, effective: { currency: "ARS", value: 1, @@ -41,15 +41,19 @@ export const Ready = tests.createExample(ReadyView, { fraction: 0, }, summary: "some subject", - // uri: "taler://pay/merchant.ar/123", - // payStatus: { - // status: PreparePayResultType.PaymentPossible, - // amountEffective: "ARS:1", - // } as PreparePayResult, + expiration: AbsoluteTime.fromMilliseconds( new Date().getTime() + 1000 * 60 * 60, ), - - // accept: {}, - // cancel: {}, -}); + cancel: async () => {}, + goToWalletManualWithdraw: async () => {}, + choices: undefined, + error: undefined, + merchant: undefined, + minimum_age: undefined, + payHandler: { + onClick: undefined, + }, + shareUri: "asdasd", + transactionId: "1" as TransactionIdStr, +} satisfies State.Ready); diff --git a/packages/taler-wallet-webextension/src/cta/Payment/state.ts b/packages/taler-wallet-webextension/src/cta/Payment/state.ts @@ -21,10 +21,8 @@ import { ChoiceSelectionDetailType, ConfirmPayResultType, GetChoicesForPaymentResult, - MerchantContractVersion, NotificationType, - PreparePayResultType, - TalerProtocolTimestamp, + PreparePayResultType } from "@gnu-taler/taler-util"; import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; import { useTranslationContext } from "@gnu-taler/web-util/browser"; @@ -34,7 +32,6 @@ import { useBackendContext } from "../../context/backend.js"; import { useAsyncAsHook } from "../../hooks/useAsyncAsHook.js"; import { ButtonHandler } from "../../mui/handlers.js"; import { Props, State } from "./index.js"; -import { trace } from "console"; export function useComponentState({ talerPayUri, diff --git a/packages/taler-wallet-webextension/src/cta/Payment/stories.tsx b/packages/taler-wallet-webextension/src/cta/Payment/stories.tsx @@ -20,17 +20,10 @@ */ import { - AmountString, - Amounts, - MerchantContractTerms as ContractTerms, - MerchantContractInputType, - MerchantContractOutputType, - PreparePayResultType, - TransactionIdStr, + AbsoluteTime, + Amounts } from "@gnu-taler/taler-util"; import * as tests from "@gnu-taler/web-util/testing"; -import beer from "../../../static-stories/beer.png"; -import merchantIcon from "../../../static-stories/merchant-icon.jpeg"; import { nullFunction } from "../../mui/handlers.js"; import { BaseView } from "./views.js"; @@ -45,6 +38,7 @@ export const NoEnoughBalanceAvailable = tests.createExample(BaseView, { error: undefined, amount: Amounts.parseOrThrow("USD:10"), shareUri: "", + expiration: AbsoluteTime.never(), // payStatus: { // transactionId: " " as TransactionIdStr, // status: PreparePayResultType.InsufficientBalance, @@ -81,6 +75,8 @@ export const NoEnoughBalanceMaterial = tests.createExample(BaseView, { error: undefined, amount: Amounts.parseOrThrow("USD:10"), shareUri: "", + expiration: AbsoluteTime.never(), + // payStatus: { // status: PreparePayResultType.InsufficientBalance, // balanceDetails: { @@ -117,6 +113,8 @@ export const NoEnoughBalanceAgeAcceptable = tests.createExample(BaseView, { error: undefined, amount: Amounts.parseOrThrow("USD:10"), shareUri: "", + expiration: AbsoluteTime.never(), + // payStatus: { // status: PreparePayResultType.InsufficientBalance, // balanceDetails: { @@ -154,6 +152,8 @@ export const NoEnoughBalanceMerchantAcceptable = tests.createExample(BaseView, { error: undefined, amount: Amounts.parseOrThrow("USD:10"), shareUri: "", + expiration: AbsoluteTime.never(), + // payStatus: { // transactionId: // "txn:payment:96YY92RQZGF3V7TJSPN4SF9549QX7BRF88Q5PYFCSBNQ0YK4RPK0" as TransactionIdStr, @@ -192,6 +192,8 @@ export const NoEnoughBalanceMerchantDepositable = tests.createExample( error: undefined, amount: Amounts.parseOrThrow("USD:10"), shareUri: "", + expiration: AbsoluteTime.never(), + // payStatus: { // transactionId: // "txn:payment:96YY92RQZGF3V7TJSPN4SF9549QX7BRF88Q5PYFCSBNQ0YK4RPK0" as TransactionIdStr, @@ -229,6 +231,8 @@ export const NoEnoughBalanceFeeGap = tests.createExample(BaseView, { error: undefined, amount: Amounts.parseOrThrow("USD:10"), shareUri: "", + expiration: AbsoluteTime.never(), + // payStatus: { // transactionId: // "txn:payment:96YY92RQZGF3V7TJSPN4SF9549QX7BRF88Q5PYFCSBNQ0YK4RPK0" as TransactionIdStr, @@ -268,8 +272,10 @@ export const PaymentPossible = tests.createExample(BaseView, { payHandler: { onClick: nullFunction, }, + expiration: AbsoluteTime.never(), - shareUri: "taler://pay/merchant-backend.taler/2021.242-01G2X4275RBWG/?c=66BE594PDZR24744J6EQK52XM0", + shareUri: + "taler://pay/merchant-backend.taler/2021.242-01G2X4275RBWG/?c=66BE594PDZR24744J6EQK52XM0", // payStatus: { // transactionId: // "txn:payment:96YY92RQZGF3V7TJSPN4SF9549QX7BRF88Q5PYFCSBNQ0YK4RPK0" as TransactionIdStr, @@ -355,8 +361,10 @@ export const PaymentPossibleWithFee = tests.createExample(BaseView, { payHandler: { onClick: nullFunction, }, + expiration: AbsoluteTime.never(), - shareUri: "taler://pay/merchant-backend.taler/2021.242-01G2X4275RBWG/?c=66BE594PDZR24744J6EQK52XM0", + shareUri: + "taler://pay/merchant-backend.taler/2021.242-01G2X4275RBWG/?c=66BE594PDZR24744J6EQK52XM0", // payStatus: { // transactionId: // "txn:payment:96YY92RQZGF3V7TJSPN4SF9549QX7BRF88Q5PYFCSBNQ0YK4RPK0" as TransactionIdStr, @@ -388,8 +396,10 @@ export const TicketWithAProductList = tests.createExample(BaseView, { payHandler: { onClick: nullFunction, }, + expiration: AbsoluteTime.never(), - shareUri: "taler://pay/merchant-backend.taler/2021.242-01G2X4275RBWG/?c=66BE594PDZR24744J6EQK52XM0", + shareUri: + "taler://pay/merchant-backend.taler/2021.242-01G2X4275RBWG/?c=66BE594PDZR24744J6EQK52XM0", // payStatus: { // transactionId: // "txn:payment:96YY92RQZGF3V7TJSPN4SF9549QX7BRF88Q5PYFCSBNQ0YK4RPK0" as TransactionIdStr, @@ -440,8 +450,10 @@ export const TicketWithShipping = tests.createExample(BaseView, { payHandler: { onClick: nullFunction, }, + expiration: AbsoluteTime.never(), - shareUri: "taler://pay/merchant-backend.taler/2021.242-01G2X4275RBWG/?c=66BE594PDZR24744J6EQK52XM0", + shareUri: + "taler://pay/merchant-backend.taler/2021.242-01G2X4275RBWG/?c=66BE594PDZR24744J6EQK52XM0", // payStatus: { // transactionId: // "txn:payment:96YY92RQZGF3V7TJSPN4SF9549QX7BRF88Q5PYFCSBNQ0YK4RPK0" as TransactionIdStr, @@ -484,7 +496,10 @@ export const AlreadyConfirmedByOther = tests.createExample(BaseView, { status: "confirmed", error: undefined, amount: Amounts.parseOrThrow("USD:10"), - shareUri: "taler://pay/merchant-backend.taler/2021.242-01G2X4275RBWG/?c=66BE594PDZR24744J6EQK52XM0", + shareUri: + "taler://pay/merchant-backend.taler/2021.242-01G2X4275RBWG/?c=66BE594PDZR24744J6EQK52XM0", + expiration: AbsoluteTime.never(), + // payStatus: { // transactionId: // "txn:payment:96YY92RQZGF3V7TJSPN4SF9549QX7BRF88Q5PYFCSBNQ0YK4RPK0" as TransactionIdStr, diff --git a/packages/taler-wallet-webextension/src/cta/Payment/test.ts b/packages/taler-wallet-webextension/src/cta/Payment/test.ts @@ -20,21 +20,19 @@ */ import { - AmountString, Amounts, ConfirmPayResult, ConfirmPayResultType, + Duration, + MerchantContractTermsV0, NotificationType, PreparePayResultInsufficientBalance, PreparePayResultPaymentPossible, - PreparePayResultType, - ScopeType, - TransactionMajorState, + PreparePayResultType } from "@gnu-taler/taler-util"; import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; -import { expect } from "chai"; import * as tests from "@gnu-taler/web-util/testing"; -import { ErrorAlert, useAlertContext } from "../../context/alert.js"; +import { expect } from "chai"; import { nullFunction } from "../../mui/handlers.js"; import { createWalletApiMock } from "../../test-utils.js"; import { useComponentState } from "./state.js"; @@ -60,8 +58,6 @@ describe("Payment CTA states", () => { ({ status, error }) => { expect(status).equals("error"); if (error === undefined) expect.fail(); - // expect(error.hasError).true; - // expect(error.operational).false; }, ], TestingContext, @@ -86,13 +82,11 @@ describe("Payment CTA states", () => { { status: PreparePayResultType.InsufficientBalance, amountRaw: "USD:10", + contractTerms: { + pay_deadline: Duration.toTalerProtocolDuration(Duration.getForever()), + } as unknown as MerchantContractTermsV0, } as PreparePayResultInsufficientBalance, ); - handler.addWalletCallResponse( - WalletApiOperation.GetBalances, - {}, - { balances: [] }, - ); const hookBehavior = await tests.hookBehaveLikeThis( useComponentState, @@ -133,29 +127,11 @@ describe("Payment CTA states", () => { { status: PreparePayResultType.InsufficientBalance, amountRaw: "USD:10", + contractTerms: { + pay_deadline: Duration.toTalerProtocolDuration(Duration.getForever()), + } as unknown as MerchantContractTermsV0, } as PreparePayResultInsufficientBalance, ); - handler.addWalletCallResponse( - WalletApiOperation.GetBalances, - {}, - { - balances: [ - { - flags: [], - available: "USD:5" as AmountString, - hasPendingTransactions: false, - pendingIncoming: "USD:0" as AmountString, - pendingOutgoing: "USD:0" as AmountString, - requiresUserInput: false, - scopeInfo: { - currency: "USD", - type: ScopeType.Auditor, - url: "", - }, - }, - ], - }, - ); const hookBehavior = await tests.hookBehaveLikeThis( useComponentState, @@ -194,29 +170,12 @@ describe("Payment CTA states", () => { status: PreparePayResultType.PaymentPossible, amountRaw: "USD:10", amountEffective: "USD:10", + contractTerms: { + pay_deadline: Duration.toTalerProtocolDuration(Duration.getForever()), + } as unknown as MerchantContractTermsV0, } as PreparePayResultPaymentPossible, ); - handler.addWalletCallResponse( - WalletApiOperation.GetBalances, - {}, - { - balances: [ - { - flags: [], - available: "USD:15" as AmountString, - hasPendingTransactions: false, - pendingIncoming: "USD:0" as AmountString, - pendingOutgoing: "USD:0" as AmountString, - requiresUserInput: false, - scopeInfo: { - currency: "USD", - type: ScopeType.Auditor, - url: "", - }, - }, - ], - }, - ); + const hookBehavior = await tests.hookBehaveLikeThis( useComponentState, props, @@ -258,29 +217,12 @@ describe("Payment CTA states", () => { status: PreparePayResultType.PaymentPossible, amountRaw: "USD:9", amountEffective: "USD:10", + contractTerms: { + pay_deadline: Duration.toTalerProtocolDuration(Duration.getForever()), + } as unknown as MerchantContractTermsV0, } as PreparePayResultPaymentPossible, ); - handler.addWalletCallResponse( - WalletApiOperation.GetBalances, - {}, - { - balances: [ - { - flags: [], - available: "USD:15" as AmountString, - hasPendingTransactions: false, - pendingIncoming: "USD:0" as AmountString, - pendingOutgoing: "USD:0" as AmountString, - requiresUserInput: false, - scopeInfo: { - currency: "USD", - type: ScopeType.Auditor, - url: "", - }, - }, - ], - }, - ); + const hookBehavior = await tests.hookBehaveLikeThis( useComponentState, props, @@ -319,30 +261,13 @@ describe("Payment CTA states", () => { status: PreparePayResultType.PaymentPossible, amountRaw: "USD:9", amountEffective: "USD:10", + contractTerms: { + pay_deadline: Duration.toTalerProtocolDuration(Duration.getForever()), + } as unknown as MerchantContractTermsV0, } as PreparePayResultPaymentPossible, ); - handler.addWalletCallResponse( - WalletApiOperation.GetBalances, - {}, - { - balances: [ - { - flags: [], - available: "USD:15" as AmountString, - hasPendingTransactions: false, - pendingIncoming: "USD:0" as AmountString, - pendingOutgoing: "USD:0" as AmountString, - requiresUserInput: false, - scopeInfo: { - currency: "USD", - type: ScopeType.Auditor, - url: "", - }, - }, - ], - }, - ); + handler.addWalletCallResponse(WalletApiOperation.ConfirmPay, undefined, { type: ConfirmPayResultType.Done, contractTerms: {}, @@ -389,30 +314,13 @@ describe("Payment CTA states", () => { status: PreparePayResultType.PaymentPossible, amountRaw: "USD:9", amountEffective: "USD:10", + contractTerms: { + pay_deadline: Duration.toTalerProtocolDuration(Duration.getForever()), + } as unknown as MerchantContractTermsV0, } as PreparePayResultPaymentPossible, ); - handler.addWalletCallResponse( - WalletApiOperation.GetBalances, - {}, - { - balances: [ - { - flags: [], - available: "USD:15" as AmountString, - hasPendingTransactions: false, - pendingIncoming: "USD:0" as AmountString, - pendingOutgoing: "USD:0" as AmountString, - requiresUserInput: false, - scopeInfo: { - currency: "USD", - type: ScopeType.Auditor, - url: "", - }, - }, - ], - }, - ); + handler.addWalletCallResponse(WalletApiOperation.ConfirmPay, undefined, { type: ConfirmPayResultType.Pending, lastError: { code: 1 }, @@ -438,21 +346,6 @@ describe("Payment CTA states", () => { if (state.payHandler.onClick === undefined) expect.fail(); state.payHandler.onClick(); }, - // (state) => { - // if (state.status !== "ready") expect.fail(); - // expect(state.balance).deep.equal(Amounts.parseOrThrow("USD:15")); - // expect(state.amount).deep.equal(Amounts.parseOrThrow("USD:9")); - - // // FIXME: check that the error is pushed to the alertContext - // // expect(state.alerts.length).eq(1); - // // const alert = state.alerts[0] - // // if (alert.type !== "error") expect.fail(); - - // // expect(alert.cause.errorDetail.payResult).deep.equal({ - // // type: ConfirmPayResultType.Pending, - // // lastError: { code: 1 }, - // // }); - // }, ], TestingContext, ); @@ -478,63 +371,25 @@ describe("Payment CTA states", () => { status: PreparePayResultType.PaymentPossible, amountRaw: "USD:9", amountEffective: "USD:10", + contractTerms: { + pay_deadline: Duration.toTalerProtocolDuration(Duration.getForever()), + } as unknown as MerchantContractTermsV0, } as PreparePayResultPaymentPossible, ); handler.addWalletCallResponse( - WalletApiOperation.GetBalances, - {}, - { - balances: [ - { - flags: [], - available: "USD:10" as AmountString, - hasPendingTransactions: false, - pendingIncoming: "USD:0" as AmountString, - pendingOutgoing: "USD:0" as AmountString, - requiresUserInput: false, - scopeInfo: { - currency: "USD", - type: ScopeType.Auditor, - url: "", - }, - }, - ], - }, - ); - - handler.addWalletCallResponse( WalletApiOperation.PreparePayForUri, undefined, { status: PreparePayResultType.PaymentPossible, amountRaw: "USD:9", amountEffective: "USD:10", + contractTerms: { + pay_deadline: Duration.toTalerProtocolDuration(Duration.getForever()), + } as unknown as MerchantContractTermsV0, } as PreparePayResultPaymentPossible, ); - handler.addWalletCallResponse( - WalletApiOperation.GetBalances, - {}, - { - balances: [ - { - flags: [], - available: "USD:15" as AmountString, - hasPendingTransactions: false, - pendingIncoming: "USD:0" as AmountString, - pendingOutgoing: "USD:0" as AmountString, - requiresUserInput: false, - scopeInfo: { - currency: "USD", - type: ScopeType.Auditor, - url: "", - }, - }, - ], - }, - ); - const hookBehavior = await tests.hookBehaveLikeThis( useComponentState, props, @@ -553,11 +408,9 @@ describe("Payment CTA states", () => { handler.notifyEventFromWallet({ type: NotificationType.TransactionStateTransition, newTxState: {} as any, - oldTxState: {} as any, + oldTxState: {} as any, transactionId: "123", - } - - ); + }); }, (state) => { if (state.status !== "ready") expect.fail();