diff options
author | Sebastian <sebasjm@gmail.com> | 2022-12-15 17:12:03 -0300 |
---|---|---|
committer | Sebastian <sebasjm@gmail.com> | 2022-12-15 17:12:03 -0300 |
commit | f1f8f818dbe631fbeeba64af9dfcae1aa7842615 (patch) | |
tree | 856d3b443556ce271c3e9fdab6aed7ae7728ab65 | |
parent | f93bd51499ed34844b666bf6d333227adf4368bf (diff) |
pretty
45 files changed, 1023 insertions, 826 deletions
diff --git a/packages/taler-wallet-webextension/src/components/TermsOfService/index.ts b/packages/taler-wallet-webextension/src/components/TermsOfService/index.ts index 5d5ad3ba2..d7716f208 100644 --- a/packages/taler-wallet-webextension/src/components/TermsOfService/index.ts +++ b/packages/taler-wallet-webextension/src/components/TermsOfService/index.ts @@ -25,7 +25,7 @@ import { LoadingUriView, ShowButtonsAcceptedTosView, ShowButtonsNonAcceptedTosView, - ShowTosContentView + ShowTosContentView, } from "./views.js"; export interface Props { diff --git a/packages/taler-wallet-webextension/src/components/TermsOfService/state.ts b/packages/taler-wallet-webextension/src/components/TermsOfService/state.ts index 5006cefce..3b75965d3 100644 --- a/packages/taler-wallet-webextension/src/components/TermsOfService/state.ts +++ b/packages/taler-wallet-webextension/src/components/TermsOfService/state.ts @@ -21,10 +21,8 @@ import { useAsyncAsHook } from "../../hooks/useAsyncAsHook.js"; import { Props, State } from "./index.js"; import { buildTermsOfServiceState } from "./utils.js"; -export function useComponentState( - { exchangeUrl, onChange }: Props, -): State { - const api = useBackendContext() +export function useComponentState({ exchangeUrl, onChange }: Props): State { + const api = useBackendContext(); const readOnly = !onChange; const [showContent, setShowContent] = useState<boolean>(readOnly); const [errorAccepting, setErrorAccepting] = useState<Error | undefined>( diff --git a/packages/taler-wallet-webextension/src/context/backend.ts b/packages/taler-wallet-webextension/src/context/backend.ts index 3e9e1f0ab..e00a70080 100644 --- a/packages/taler-wallet-webextension/src/context/backend.ts +++ b/packages/taler-wallet-webextension/src/context/backend.ts @@ -23,7 +23,7 @@ import { ComponentChildren, createContext, h, VNode } from "preact"; import { useContext } from "preact/hooks"; import { wxApi, WxApiType } from "../wxApi.js"; -type Type = WxApiType +type Type = WxApiType; const initial = wxApi; @@ -31,7 +31,7 @@ const Context = createContext<Type>(initial); type Props = Partial<WxApiType> & { children: ComponentChildren; -} +}; export const BackendProvider = ({ wallet, @@ -39,12 +39,11 @@ export const BackendProvider = ({ listener, children, }: Props): VNode => { - return h(Context.Provider, { value: { wallet: wallet ?? initial.wallet, background: background ?? initial.background, - listener: listener ?? initial.listener + listener: listener ?? initial.listener, }, children, }); diff --git a/packages/taler-wallet-webextension/src/cta/Deposit/state.ts b/packages/taler-wallet-webextension/src/cta/Deposit/state.ts index fbcd107ef..dba435611 100644 --- a/packages/taler-wallet-webextension/src/cta/Deposit/state.ts +++ b/packages/taler-wallet-webextension/src/cta/Deposit/state.ts @@ -20,10 +20,13 @@ import { useBackendContext } from "../../context/backend.js"; import { useAsyncAsHook } from "../../hooks/useAsyncAsHook.js"; import { Props, State } from "./index.js"; -export function useComponentState( - { talerDepositUri, amountStr, cancel, onSuccess }: Props, -): State { - const api = useBackendContext() +export function useComponentState({ + talerDepositUri, + amountStr, + cancel, + onSuccess, +}: Props): State { + const api = useBackendContext(); const info = useAsyncAsHook(async () => { if (!talerDepositUri) throw Error("ERROR_NO-URI-FOR-DEPOSIT"); if (!amountStr) throw Error("ERROR_NO-AMOUNT-FOR-DEPOSIT"); diff --git a/packages/taler-wallet-webextension/src/cta/Deposit/test.ts b/packages/taler-wallet-webextension/src/cta/Deposit/test.ts index 1c8d4708d..6a896fb7f 100644 --- a/packages/taler-wallet-webextension/src/cta/Deposit/test.ts +++ b/packages/taler-wallet-webextension/src/cta/Deposit/test.ts @@ -42,21 +42,26 @@ describe("Deposit CTA states", () => { }, }; - const hookBehavior = await tests.hookBehaveLikeThis(useComponentState, props, [ - ({ status }) => { - expect(status).equals("loading"); - }, - ({ status, error }) => { - expect(status).equals("loading-uri"); + const hookBehavior = await tests.hookBehaveLikeThis( + useComponentState, + props, + [ + ({ status }) => { + expect(status).equals("loading"); + }, + ({ status, error }) => { + expect(status).equals("loading-uri"); - if (!error) expect.fail(); - if (!error.hasError) expect.fail(); - if (error.operational) expect.fail(); - expect(error.message).eq("ERROR_NO-URI-FOR-DEPOSIT"); - }, - ], TestingContext) + if (!error) expect.fail(); + if (!error.hasError) expect.fail(); + if (error.operational) expect.fail(); + expect(error.message).eq("ERROR_NO-URI-FOR-DEPOSIT"); + }, + ], + TestingContext, + ); - expect(hookBehavior).deep.equal({ result: "ok" }) + expect(hookBehavior).deep.equal({ result: "ok" }); expect(handler.getCallingQueueState()).eq("empty"); }); @@ -83,21 +88,26 @@ describe("Deposit CTA states", () => { }, }; - const hookBehavior = await tests.hookBehaveLikeThis(useComponentState, props, [ - ({ status }) => { - expect(status).equals("loading"); - }, - (state) => { - if (state.status !== "ready") expect.fail(); - if (state.error) expect.fail(); - expect(state.confirm.onClick).not.undefined; - expect(state.cost).deep.eq(Amounts.parseOrThrow("EUR:1.2")); - expect(state.fee).deep.eq(Amounts.parseOrThrow("EUR:0.2")); - expect(state.effective).deep.eq(Amounts.parseOrThrow("EUR:1")); - }, - ], TestingContext) + const hookBehavior = await tests.hookBehaveLikeThis( + useComponentState, + props, + [ + ({ status }) => { + expect(status).equals("loading"); + }, + (state) => { + if (state.status !== "ready") expect.fail(); + if (state.error) expect.fail(); + expect(state.confirm.onClick).not.undefined; + expect(state.cost).deep.eq(Amounts.parseOrThrow("EUR:1.2")); + expect(state.fee).deep.eq(Amounts.parseOrThrow("EUR:0.2")); + expect(state.effective).deep.eq(Amounts.parseOrThrow("EUR:1")); + }, + ], + TestingContext, + ); - expect(hookBehavior).deep.equal({ result: "ok" }) + expect(hookBehavior).deep.equal({ result: "ok" }); expect(handler.getCallingQueueState()).eq("empty"); }); }); diff --git a/packages/taler-wallet-webextension/src/cta/InvoiceCreate/state.ts b/packages/taler-wallet-webextension/src/cta/InvoiceCreate/state.ts index a26167f8e..998270e53 100644 --- a/packages/taler-wallet-webextension/src/cta/InvoiceCreate/state.ts +++ b/packages/taler-wallet-webextension/src/cta/InvoiceCreate/state.ts @@ -29,11 +29,13 @@ import { useSelectedExchange } from "../../hooks/useSelectedExchange.js"; import { RecursiveState } from "../../utils/index.js"; import { Props, State } from "./index.js"; -export function useComponentState( - { amount: amountStr, onClose, onSuccess }: Props, -): RecursiveState<State> { +export function useComponentState({ + amount: amountStr, + onClose, + onSuccess, +}: Props): RecursiveState<State> { const amount = Amounts.parseOrThrow(amountStr); - const api = useBackendContext() + const api = useBackendContext(); const hook = useAsyncAsHook(() => api.wallet.call(WalletApiOperation.ListExchanges, {}), @@ -158,8 +160,8 @@ export function useComponentState( subject === undefined ? undefined : !subject - ? "Can't be empty" - : undefined, + ? "Can't be empty" + : undefined, value: subject ?? "", onInput: async (e) => setSubject(e), }, diff --git a/packages/taler-wallet-webextension/src/cta/InvoicePay/index.ts b/packages/taler-wallet-webextension/src/cta/InvoicePay/index.ts index 78f244964..f3de0885d 100644 --- a/packages/taler-wallet-webextension/src/cta/InvoicePay/index.ts +++ b/packages/taler-wallet-webextension/src/cta/InvoicePay/index.ts @@ -18,7 +18,7 @@ import { AbsoluteTime, AmountJson, PreparePayResult, - TalerErrorDetail + TalerErrorDetail, } from "@gnu-taler/taler-util"; import { Loading } from "../../components/Loading.js"; import { HookError } from "../../hooks/useAsyncAsHook.js"; diff --git a/packages/taler-wallet-webextension/src/cta/InvoicePay/state.ts b/packages/taler-wallet-webextension/src/cta/InvoicePay/state.ts index eb50ba748..c0b97c106 100644 --- a/packages/taler-wallet-webextension/src/cta/InvoicePay/state.ts +++ b/packages/taler-wallet-webextension/src/cta/InvoicePay/state.ts @@ -29,10 +29,13 @@ import { useBackendContext } from "../../context/backend.js"; import { useAsyncAsHook } from "../../hooks/useAsyncAsHook.js"; import { Props, State } from "./index.js"; -export function useComponentState( - { talerPayPullUri, onClose, goToWalletManualWithdraw, onSuccess }: Props, -): State { - const api = useBackendContext() +export function useComponentState({ + talerPayPullUri, + onClose, + goToWalletManualWithdraw, + onSuccess, +}: Props): State { + const api = useBackendContext(); const hook = useAsyncAsHook(async () => { const p2p = await api.wallet.call(WalletApiOperation.CheckPeerPullPayment, { talerUri: talerPayPullUri, diff --git a/packages/taler-wallet-webextension/src/cta/Payment/index.ts b/packages/taler-wallet-webextension/src/cta/Payment/index.ts index 45e4a5b88..2dc6b6741 100644 --- a/packages/taler-wallet-webextension/src/cta/Payment/index.ts +++ b/packages/taler-wallet-webextension/src/cta/Payment/index.ts @@ -19,7 +19,7 @@ import { PreparePayResult, PreparePayResultAlreadyConfirmed, PreparePayResultInsufficientBalance, - PreparePayResultPaymentPossible + PreparePayResultPaymentPossible, } from "@gnu-taler/taler-util"; import { Loading } from "../../components/Loading.js"; import { HookError } from "../../hooks/useAsyncAsHook.js"; diff --git a/packages/taler-wallet-webextension/src/cta/Payment/state.ts b/packages/taler-wallet-webextension/src/cta/Payment/state.ts index 7690910e6..d4adf4bcb 100644 --- a/packages/taler-wallet-webextension/src/cta/Payment/state.ts +++ b/packages/taler-wallet-webextension/src/cta/Payment/state.ts @@ -28,11 +28,14 @@ import { useAsyncAsHook } from "../../hooks/useAsyncAsHook.js"; import { ButtonHandler } from "../../mui/handlers.js"; import { Props, State } from "./index.js"; -export function useComponentState( - { talerPayUri, cancel, goToWalletManualWithdraw, onSuccess }: Props, -): State { +export function useComponentState({ + talerPayUri, + cancel, + goToWalletManualWithdraw, + onSuccess, +}: Props): State { const [payErrMsg, setPayErrMsg] = useState<TalerError | undefined>(undefined); - const api = useBackendContext() + const api = useBackendContext(); const hook = useAsyncAsHook(async () => { if (!talerPayUri) throw Error("ERROR_NO-URI-FOR-PAYMENT"); diff --git a/packages/taler-wallet-webextension/src/cta/Payment/test.ts b/packages/taler-wallet-webextension/src/cta/Payment/test.ts index aba76fcf4..077930972 100644 --- a/packages/taler-wallet-webextension/src/cta/Payment/test.ts +++ b/packages/taler-wallet-webextension/src/cta/Payment/test.ts @@ -45,22 +45,26 @@ describe("Payment CTA states", () => { onSuccess: nullFunction, }; - const hookBehavior = await tests.hookBehaveLikeThis(useComponentState, props, [ - ({ status, error }) => { - expect(status).equals("loading"); - expect(error).undefined; - }, - ({ status, error }) => { - expect(status).equals("loading-uri"); - if (error === undefined) expect.fail(); - expect(error.hasError).true; - expect(error.operational).false; - }, - ], TestingContext) + const hookBehavior = await tests.hookBehaveLikeThis( + useComponentState, + props, + [ + ({ status, error }) => { + expect(status).equals("loading"); + expect(error).undefined; + }, + ({ status, error }) => { + expect(status).equals("loading-uri"); + if (error === undefined) expect.fail(); + expect(error.hasError).true; + expect(error.operational).false; + }, + ], + TestingContext, + ); - expect(hookBehavior).deep.equal({ result: "ok" }) + expect(hookBehavior).deep.equal({ result: "ok" }); expect(handler.getCallingQueueState()).eq("empty"); - }); it("should response with no balance", async () => { @@ -86,22 +90,27 @@ describe("Payment CTA states", () => { { balances: [] }, ); - const hookBehavior = await tests.hookBehaveLikeThis(useComponentState, props, [ - ({ status, error }) => { - expect(status).equals("loading"); - expect(error).undefined; - }, - (state) => { - if (state.status !== "no-balance-for-currency") { - expect(state).eq({}); - return; - } - expect(state.balance).undefined; - expect(state.amount).deep.equal(Amounts.parseOrThrow("USD:10")); - }, - ], TestingContext) + const hookBehavior = await tests.hookBehaveLikeThis( + useComponentState, + props, + [ + ({ status, error }) => { + expect(status).equals("loading"); + expect(error).undefined; + }, + (state) => { + if (state.status !== "no-balance-for-currency") { + expect(state).eq({}); + return; + } + expect(state.balance).undefined; + expect(state.amount).deep.equal(Amounts.parseOrThrow("USD:10")); + }, + ], + TestingContext, + ); - expect(hookBehavior).deep.equal({ result: "ok" }) + expect(hookBehavior).deep.equal({ result: "ok" }); expect(handler.getCallingQueueState()).eq("empty"); }); @@ -138,19 +147,24 @@ describe("Payment CTA states", () => { }, ); - const hookBehavior = await tests.hookBehaveLikeThis(useComponentState, props, [ - ({ status, error }) => { - expect(status).equals("loading"); - expect(error).undefined; - }, - (state) => { - if (state.status !== "no-enough-balance") expect.fail(); - expect(state.balance).deep.equal(Amounts.parseOrThrow("USD:5")); - expect(state.amount).deep.equal(Amounts.parseOrThrow("USD:10")); - }, - ], TestingContext) + const hookBehavior = await tests.hookBehaveLikeThis( + useComponentState, + props, + [ + ({ status, error }) => { + expect(status).equals("loading"); + expect(error).undefined; + }, + (state) => { + if (state.status !== "no-enough-balance") expect.fail(); + expect(state.balance).deep.equal(Amounts.parseOrThrow("USD:5")); + expect(state.amount).deep.equal(Amounts.parseOrThrow("USD:10")); + }, + ], + TestingContext, + ); - expect(hookBehavior).deep.equal({ result: "ok" }) + expect(hookBehavior).deep.equal({ result: "ok" }); expect(handler.getCallingQueueState()).eq("empty"); }); @@ -187,25 +201,29 @@ describe("Payment CTA states", () => { ], }, ); - const hookBehavior = await tests.hookBehaveLikeThis(useComponentState, props, [ - ({ status, error }) => { - expect(status).equals("loading"); - expect(error).undefined; - }, - (state) => { - if (state.status !== "ready") { - expect(state).eq({}); - return; - } - expect(state.balance).deep.equal(Amounts.parseOrThrow("USD:15")); - expect(state.amount).deep.equal(Amounts.parseOrThrow("USD:10")); - expect(state.payHandler.onClick).not.undefined; - }, - ], TestingContext) + const hookBehavior = await tests.hookBehaveLikeThis( + useComponentState, + props, + [ + ({ status, error }) => { + expect(status).equals("loading"); + expect(error).undefined; + }, + (state) => { + if (state.status !== "ready") { + expect(state).eq({}); + return; + } + expect(state.balance).deep.equal(Amounts.parseOrThrow("USD:15")); + expect(state.amount).deep.equal(Amounts.parseOrThrow("USD:10")); + expect(state.payHandler.onClick).not.undefined; + }, + ], + TestingContext, + ); - expect(hookBehavior).deep.equal({ result: "ok" }) + expect(hookBehavior).deep.equal({ result: "ok" }); expect(handler.getCallingQueueState()).eq("empty"); - }); it("should be able to pay (with fee)", async () => { @@ -241,20 +259,25 @@ describe("Payment CTA states", () => { ], }, ); - const hookBehavior = await tests.hookBehaveLikeThis(useComponentState, props, [ - ({ status, error }) => { - expect(status).equals("loading"); - expect(error).undefined; - }, - (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")); - expect(state.payHandler.onClick).not.undefined; - }, - ], TestingContext) + const hookBehavior = await tests.hookBehaveLikeThis( + useComponentState, + props, + [ + ({ status, error }) => { + expect(status).equals("loading"); + expect(error).undefined; + }, + (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")); + expect(state.payHandler.onClick).not.undefined; + }, + ], + TestingContext, + ); - expect(hookBehavior).deep.equal({ result: "ok" }) + expect(hookBehavior).deep.equal({ result: "ok" }); expect(handler.getCallingQueueState()).eq("empty"); }); @@ -297,26 +320,30 @@ describe("Payment CTA states", () => { contractTerms: {}, } as ConfirmPayResult); - const hookBehavior = await tests.hookBehaveLikeThis(useComponentState, props, [ - ({ status, error }) => { - expect(status).equals("loading"); - expect(error).undefined; - }, - (state) => { - if (state.status !== "ready") { - expect(state).eq({}); - return; - } - expect(state.balance).deep.equal(Amounts.parseOrThrow("USD:15")); - expect(state.amount).deep.equal(Amounts.parseOrThrow("USD:9")); - if (state.payHandler.onClick === undefined) expect.fail(); - state.payHandler.onClick(); - }, - ], TestingContext) + const hookBehavior = await tests.hookBehaveLikeThis( + useComponentState, + props, + [ + ({ status, error }) => { + expect(status).equals("loading"); + expect(error).undefined; + }, + (state) => { + if (state.status !== "ready") { + expect(state).eq({}); + return; + } + expect(state.balance).deep.equal(Amounts.parseOrThrow("USD:15")); + expect(state.amount).deep.equal(Amounts.parseOrThrow("USD:9")); + if (state.payHandler.onClick === undefined) expect.fail(); + state.payHandler.onClick(); + }, + ], + TestingContext, + ); - expect(hookBehavior).deep.equal({ result: "ok" }) + expect(hookBehavior).deep.equal({ result: "ok" }); expect(handler.getCallingQueueState()).eq("empty"); - }); it("should not stay in ready state after pay with error", async () => { @@ -357,40 +384,44 @@ describe("Payment CTA states", () => { lastError: { code: 1 }, } as ConfirmPayResult); - const hookBehavior = await tests.hookBehaveLikeThis(useComponentState, props, [ - ({ status, error }) => { - expect(status).equals("loading"); - expect(error).undefined; - }, - (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")); - // expect(r.totalFees).deep.equal(Amounts.parseOrThrow("USD:1")); - 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")); - // expect(r.totalFees).deep.equal(Amounts.parseOrThrow("USD:1")); - expect(state.payHandler.onClick).undefined; - if (state.payHandler.error === undefined) expect.fail(); - //FIXME: error message here is bad - expect(state.payHandler.error.errorDetail.hint).eq( - "could not confirm payment", - ); - expect(state.payHandler.error.errorDetail.payResult).deep.equal({ - type: ConfirmPayResultType.Pending, - lastError: { code: 1 }, - }); - }, - ], TestingContext) + const hookBehavior = await tests.hookBehaveLikeThis( + useComponentState, + props, + [ + ({ status, error }) => { + expect(status).equals("loading"); + expect(error).undefined; + }, + (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")); + // expect(r.totalFees).deep.equal(Amounts.parseOrThrow("USD:1")); + 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")); + // expect(r.totalFees).deep.equal(Amounts.parseOrThrow("USD:1")); + expect(state.payHandler.onClick).undefined; + if (state.payHandler.error === undefined) expect.fail(); + //FIXME: error message here is bad + expect(state.payHandler.error.errorDetail.hint).eq( + "could not confirm payment", + ); + expect(state.payHandler.error.errorDetail.payResult).deep.equal({ + type: ConfirmPayResultType.Pending, + lastError: { code: 1 }, + }); + }, + ], + TestingContext, + ); - expect(hookBehavior).deep.equal({ result: "ok" }) + expect(hookBehavior).deep.equal({ result: "ok" }); expect(handler.getCallingQueueState()).eq("empty"); - }); it("should update balance if a coins is withdraw", async () => { @@ -455,30 +486,35 @@ describe("Payment CTA states", () => { }, ); - const hookBehavior = await tests.hookBehaveLikeThis(useComponentState, props, [ - ({ status, error }) => { - expect(status).equals("loading"); - expect(error).undefined; - }, - (state) => { - if (state.status !== "ready") expect.fail() - expect(state.balance).deep.equal(Amounts.parseOrThrow("USD:10")); - expect(state.amount).deep.equal(Amounts.parseOrThrow("USD:9")); - // expect(r.totalFees).deep.equal(Amounts.parseOrThrow("USD:1")); - expect(state.payHandler.onClick).not.undefined; - - handler.notifyEventFromWallet(NotificationType.CoinWithdrawn); - }, - (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")); - // expect(r.totalFees).deep.equal(Amounts.parseOrThrow("USD:1")); - expect(state.payHandler.onClick).not.undefined; - }, - ], TestingContext) + const hookBehavior = await tests.hookBehaveLikeThis( + useComponentState, + props, + [ + ({ status, error }) => { + expect(status).equals("loading"); + expect(error).undefined; + }, + (state) => { + if (state.status !== "ready") expect.fail(); + expect(state.balance).deep.equal(Amounts.parseOrThrow("USD:10")); + expect(state.amount).deep.equal(Amounts.parseOrThrow("USD:9")); + // expect(r.totalFees).deep.equal(Amounts.parseOrThrow("USD:1")); + expect(state.payHandler.onClick).not.undefined; + + handler.notifyEventFromWallet(NotificationType.CoinWithdrawn); + }, + (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")); + // expect(r.totalFees).deep.equal(Amounts.parseOrThrow("USD:1")); + expect(state.payHandler.onClick).not.undefined; + }, + ], + TestingContext, + ); - expect(hookBehavior).deep.equal({ result: "ok" }) + expect(hookBehavior).deep.equal({ result: "ok" }); expect(handler.getCallingQueueState()).eq("empty"); }); }); diff --git a/packages/taler-wallet-webextension/src/cta/Recovery/state.ts b/packages/taler-wallet-webextension/src/cta/Recovery/state.ts index 018d61c03..4fef2c862 100644 --- a/packages/taler-wallet-webextension/src/cta/Recovery/state.ts +++ b/packages/taler-wallet-webextension/src/cta/Recovery/state.ts @@ -19,10 +19,12 @@ import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; import { useBackendContext } from "../../context/backend.js"; import { Props, State } from "./index.js"; -export function useComponentState( - { talerRecoveryUri, onCancel, onSuccess }: Props, -): State { - const api = useBackendContext() +export function useComponentState({ + talerRecoveryUri, + onCancel, + onSuccess, +}: Props): State { + const api = useBackendContext(); if (!talerRecoveryUri) { return { status: "loading-uri", diff --git a/packages/taler-wallet-webextension/src/cta/Refund/index.ts b/packages/taler-wallet-webextension/src/cta/Refund/index.ts index 158f5c179..f79a77680 100644 --- a/packages/taler-wallet-webextension/src/cta/Refund/index.ts +++ b/packages/taler-wallet-webextension/src/cta/Refund/index.ts @@ -24,7 +24,7 @@ import { IgnoredView, InProgressView, LoadingUriView, - ReadyView + ReadyView, } from "./views.js"; export interface Props { diff --git a/packages/taler-wallet-webextension/src/cta/Refund/state.ts b/packages/taler-wallet-webextension/src/cta/Refund/state.ts index 624ab2fb2..9e3311b65 100644 --- a/packages/taler-wallet-webextension/src/cta/Refund/state.ts +++ b/packages/taler-wallet-webextension/src/cta/Refund/state.ts @@ -21,10 +21,12 @@ import { useBackendContext } from "../../context/backend.js"; import { useAsyncAsHook } from "../../hooks/useAsyncAsHook.js"; import { Props, State } from "./index.js"; -export function useComponentState( - { talerRefundUri, cancel, onSuccess }: Props, -): State { - const api = useBackendContext() +export function useComponentState({ + talerRefundUri, + cancel, + onSuccess, +}: Props): State { + const api = useBackendContext(); const [ignored, setIgnored] = useState(false); const info = useAsyncAsHook(async () => { diff --git a/packages/taler-wallet-webextension/src/cta/Refund/test.ts b/packages/taler-wallet-webextension/src/cta/Refund/test.ts index 5fbf3743e..24d483a9a 100644 --- a/packages/taler-wallet-webextension/src/cta/Refund/test.ts +++ b/packages/taler-wallet-webextension/src/cta/Refund/test.ts @@ -22,12 +22,16 @@ import { Amounts, NotificationType, - OrderShortInfo + OrderShortInfo, } from "@gnu-taler/taler-util"; import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; import { expect } from "chai"; import { tests } from "../../../../web-util/src/index.browser.js"; -import { createWalletApiMock, mountHook, nullFunction } from "../../test-utils.js"; +import { + createWalletApiMock, + mountHook, + nullFunction, +} from "../../test-utils.js"; import { useComponentState } from "./state.js"; describe("Refund CTA states", () => { @@ -38,23 +42,28 @@ describe("Refund CTA states", () => { talerRefundUri: undefined, cancel: nullFunction, onSuccess: nullFunction, - } + }; - const hookBehavior = await tests.hookBehaveLikeThis(useComponentState, props, [ - ({ status, error }) => { - expect(status).equals("loading"); - expect(error).undefined; - }, - ({ status, error }) => { - expect(status).equals("loading-uri"); - if (!error) expect.fail(); - if (!error.hasError) expect.fail(); - if (error.operational) expect.fail(); - expect(error.message).eq("ERROR_NO-URI-FOR-REFUND"); - }, - ], TestingContext) + const hookBehavior = await tests.hookBehaveLikeThis( + useComponentState, + props, + [ + ({ status, error }) => { + expect(status).equals("loading"); + expect(error).undefined; + }, + ({ status, error }) => { + expect(status).equals("loading-uri"); + if (!error) expect.fail(); + if (!error.hasError) expect.fail(); + if (error.operational) expect.fail(); + expect(error.message).eq("ERROR_NO-URI-FOR-REFUND"); + }, + ], + TestingContext, + ); - expect(hookBehavior).deep.equal({ result: "ok" }) + expect(hookBehavior).deep.equal({ result: "ok" }); expect(handler.getCallingQueueState()).eq("empty"); }); @@ -83,23 +92,28 @@ describe("Refund CTA states", () => { } as OrderShortInfo, }); - const hookBehavior = await tests.hookBehaveLikeThis(useComponentState, props, [ - ({ status, error }) => { - expect(status).equals("loading"); - expect(error).undefined; - }, - (state) => { - if (state.status !== "ready") expect.fail(); - if (state.error) expect.fail(); - expect(state.accept.onClick).not.undefined; - expect(state.ignore.onClick).not.undefined; - expect(state.merchantName).eq("the merchant name"); - expect(state.orderId).eq("orderId1"); - expect(state.products).undefined; - }, - ], TestingContext) + const hookBehavior = await tests.hookBehaveLikeThis( + useComponentState, + props, + [ + ({ status, error }) => { + expect(status).equals("loading"); + expect(error).undefined; + }, + (state) => { + if (state.status !== "ready") expect.fail(); + if (state.error) expect.fail(); + expect(state.accept.onClick).not.undefined; + expect(state.ignore.onClick).not.undefined; + expect(state.merchantName).eq("the merchant name"); + expect(state.orderId).eq("orderId1"); + expect(state.products).undefined; + }, + ], + TestingContext, + ); - expect(hookBehavior).deep.equal({ result: "ok" }) + expect(hookBehavior).deep.equal({ result: "ok" }); expect(handler.getCallingQueueState()).eq("empty"); }); @@ -132,30 +146,35 @@ describe("Refund CTA states", () => { } as OrderShortInfo, }); - const hookBehavior = await tests.hookBehaveLikeThis(useComponentState, props, [ - ({ status, error }) => { - expect(status).equals("loading"); - expect(error).undefined; - }, - (state) => { - if (state.status !== "ready") expect.fail() - if (state.error) expect.fail() - expect(state.accept.onClick).not.undefined; - expect(state.merchantName).eq("the merchant name"); - expect(state.orderId).eq("orderId1"); - expect(state.products).undefined; + const hookBehavior = await tests.hookBehaveLikeThis( + useComponentState, + props, + [ + ({ status, error }) => { + expect(status).equals("loading"); + expect(error).undefined; + }, + (state) => { + if (state.status !== "ready") expect.fail(); + if (state.error) expect.fail(); + expect(state.accept.onClick).not.undefined; + expect(state.merchantName).eq("the merchant name"); + expect(state.orderId).eq("orderId1"); + expect(state.products).undefined; - if (state.ignore.onClick === undefined) expect.fail(); - state.ignore.onClick(); - }, - (state) => { - if (state.status !== "ignored") expect.fail() - if (state.error) expect.fail() - expect(state.merchantName).eq("the merchant name"); - }, - ], TestingContext) + if (state.ignore.onClick === undefined) expect.fail(); + state.ignore.onClick(); + }, + (state) => { + if (state.status !== "ignored") expect.fail(); + if (state.error) expect.fail(); + expect(state.merchantName).eq("the merchant name"); + }, + ], + TestingContext, + ); - expect(hookBehavior).deep.equal({ result: "ok" }) + expect(hookBehavior).deep.equal({ result: "ok" }); expect(handler.getCallingQueueState()).eq("empty"); }); @@ -220,42 +239,46 @@ describe("Refund CTA states", () => { } as OrderShortInfo, }); - const hookBehavior = await tests.hookBehaveLikeThis(useComponentState, props, [ - ({ status, error }) => { - expect(status).equals("loading"); - expect(error).undefined; - }, - (state) => { - if (state.status !== "in-progress") expect.fail() - if (state.error) expect.fail(); - expect(state.merchantName).eq("the merchant name"); - expect(state.products).undefined; - expect(state.amount).deep.eq(Amounts.parseOrThrow("EUR:2")); - // expect(state.progress).closeTo(1 / 3, 0.01) - - handler.notifyEventFromWallet(NotificationType.RefreshMelted); - }, - (state) => { - if (state.status !== "in-progress") expect.fail() - if (state.error) expect.fail(); - expect(state.merchantName).eq("the merchant name"); - expect(state.products).undefined; - expect(state.amount).deep.eq(Amounts.parseOrThrow("EUR:2")); - // expect(state.progress).closeTo(2 / 3, 0.01) + const hookBehavior = await tests.hookBehaveLikeThis( + useComponentState, + props, + [ + ({ status, error }) => { + expect(status).equals("loading"); + expect(error).undefined; + }, + (state) => { + if (state.status !== "in-progress") expect.fail(); + if (state.error) expect.fail(); + expect(state.merchantName).eq("the merchant name"); + expect(state.products).undefined; + expect(state.amount).deep.eq(Amounts.parseOrThrow("EUR:2")); + // expect(state.progress).closeTo(1 / 3, 0.01) - handler.notifyEventFromWallet(NotificationType.RefreshMelted); - }, - (state) => { - if (state.status !== "ready") expect.fail() - if (state.error) expect.fail(); - expect(state.merchantName).eq("the merchant name"); - expect(state.products).undefined; - expect(state.amount).deep.eq(Amounts.parseOrThrow("EUR:2")); + handler.notifyEventFromWallet(NotificationType.RefreshMelted); + }, + (state) => { + if (state.status !== "in-progress") expect.fail(); + if (state.error) expect.fail(); + expect(state.merchantName).eq("the merchant name"); + expect(state.products).undefined; + expect(state.amount).deep.eq(Amounts.parseOrThrow("EUR:2")); + // expect(state.progress).closeTo(2 / 3, 0.01) - }, - ], TestingContext) + handler.notifyEventFromWallet(NotificationType.RefreshMelted); + }, + (state) => { + if (state.status !== "ready") expect.fail(); + if (state.error) expect.fail(); + expect(state.merchantName).eq("the merchant name"); + expect(state.products).undefined; + expect(state.amount).deep.eq(Amounts.parseOrThrow("EUR:2")); + }, + ], + TestingContext, + ); - expect(hookBehavior).deep.equal({ result: "ok" }) + expect(hookBehavior).deep.equal({ result: "ok" }); expect(handler.getCallingQueueState()).eq("empty"); }); }); diff --git a/packages/taler-wallet-webextension/src/cta/Tip/index.ts b/packages/taler-wallet-webextension/src/cta/Tip/index.ts index a29a3eadb..62e0688be 100644 --- a/packages/taler-wallet-webextension/src/cta/Tip/index.ts +++ b/packages/taler-wallet-webextension/src/cta/Tip/index.ts @@ -24,7 +24,7 @@ import { AcceptedView, IgnoredView, LoadingUriView, - ReadyView + ReadyView, } from "./views.js"; export interface Props { diff --git a/packages/taler-wallet-webextension/src/cta/Tip/state.ts b/packages/taler-wallet-webextension/src/cta/Tip/state.ts index 0ca213b01..e83755119 100644 --- a/packages/taler-wallet-webextension/src/cta/Tip/state.ts +++ b/packages/taler-wallet-webextension/src/cta/Tip/state.ts @@ -20,10 +20,12 @@ import { useBackendContext } from "../../context/backend.js"; import { useAsyncAsHook } from "../../hooks/useAsyncAsHook.js"; import { Props, State } from "./index.js"; -export function useComponentState( - { talerTipUri, onCancel, onSuccess }: Props, -): State { - const api = useBackendContext() +export function useComponentState({ + talerTipUri, + onCancel, + onSuccess, +}: Props): State { + const api = useBackendContext(); const tipInfo = useAsyncAsHook(async () => { if (!talerTipUri) throw Error("ERROR_NO-URI-FOR-TIP"); const tip = await api.wallet.call(WalletApiOperation.PrepareTip, { diff --git a/packages/taler-wallet-webextension/src/cta/Tip/test.ts b/packages/taler-wallet-webextension/src/cta/Tip/test.ts index 21ed95218..5688d82a9 100644 --- a/packages/taler-wallet-webextension/src/cta/Tip/test.ts +++ b/packages/taler-wallet-webextension/src/cta/Tip/test.ts @@ -36,23 +36,28 @@ describe("Tip CTA states", () => { talerTipUri: undefined, onCancel: nullFunction, onSuccess: nullFunction, - } - - const hookBehavior = await tests.hookBehaveLikeThis(useComponentState, props, [ - ({ status, error }) => { - expect(status).equals("loading"); - expect(error).undefined; - }, - ({ status, error }) => { - expect(status).equals("loading-uri"); - if (!error) expect.fail(); - if (!error.hasError) expect.fail(); - if (error.operational) expect.fail(); - expect(error.message).eq("ERROR_NO-URI-FOR-TIP"); - }, - ], TestingContext) - - expect(hookBehavior).deep.equal({ result: "ok" }) + }; + + const hookBehavior = await tests.hookBehaveLikeThis( + useComponentState, + props, + [ + ({ status, error }) => { + expect(status).equals("loading"); + expect(error).undefined; + }, + ({ status, error }) => { + expect(status).equals("loading-uri"); + if (!error) expect.fail(); + if (!error.hasError) expect.fail(); + if (error.operational) expect.fail(); + expect(error.message).eq("ERROR_NO-URI-FOR-TIP"); + }, + ], + TestingContext, + ); + + expect(hookBehavior).deep.equal({ result: "ok" }); expect(handler.getCallingQueueState()).eq("empty"); }); @@ -75,50 +80,58 @@ describe("Tip CTA states", () => { talerTipUri: "taler://tip/asd", onCancel: nullFunction, onSuccess: nullFunction, - } - - const hookBehavior = await tests.hookBehaveLikeThis(useComponentState, props, [ - ({ status, error }) => { - expect(status).equals("loading"); - expect(error).undefined; - }, - (state) => { - if (state.status !== "ready") { - expect(state).eq({ status: "ready" }); - return; - } - if (state.error) expect.fail(); - expect(state.amount).deep.eq(Amounts.parseOrThrow("EUR:1")); - expect(state.merchantBaseUrl).eq("merchant url"); - expect(state.exchangeBaseUrl).eq("exchange url"); - if (state.accept.onClick === undefined) expect.fail(); - - handler.addWalletCallResponse(WalletApiOperation.AcceptTip); - state.accept.onClick(); - - handler.addWalletCallResponse(WalletApiOperation.PrepareTip, undefined, { - accepted: true, - exchangeBaseUrl: "exchange url", - merchantBaseUrl: "merchant url", - tipAmountEffective: "EUR:1", - walletTipId: "tip_id", - expirationTimestamp: { - t_s: 1, - }, - tipAmountRaw: "", - }); - - }, - (state) => { - if (state.status !== "accepted") expect.fail() - if (state.error) expect.fail(); - expect(state.amount).deep.eq(Amounts.parseOrThrow("EUR:1")); - expect(state.merchantBaseUrl).eq("merchant url"); - expect(state.exchangeBaseUrl).eq("exchange url"); - }, - ], TestingContext) - - expect(hookBehavior).deep.equal({ result: "ok" }) + }; + + const hookBehavior = await tests.hookBehaveLikeThis( + useComponentState, + props, + [ + ({ status, error }) => { + expect(status).equals("loading"); + expect(error).undefined; + }, + (state) => { + if (state.status !== "ready") { + expect(state).eq({ status: "ready" }); + return; + } + if (state.error) expect.fail(); + expect(state.amount).deep.eq(Amounts.parseOrThrow("EUR:1")); + expect(state.merchantBaseUrl).eq("merchant url"); + expect(state.exchangeBaseUrl).eq("exchange url"); + if (state.accept.onClick === undefined) expect.fail(); + + handler.addWalletCallResponse(WalletApiOperation.AcceptTip); + state.accept.onClick(); + + handler.addWalletCallResponse( + WalletApiOperation.PrepareTip, + undefined, + { + accepted: true, + exchangeBaseUrl: "exchange url", + merchantBaseUrl: "merchant url", + tipAmountEffective: "EUR:1", + walletTipId: "tip_id", + expirationTimestamp: { + t_s: 1, + }, + tipAmountRaw: "", + }, + ); + }, + (state) => { + if (state.status !== "accepted") expect.fail(); + if (state.error) expect.fail(); + expect(state.amount).deep.eq(Amounts.parseOrThrow("EUR:1")); + expect(state.merchantBaseUrl).eq("merchant url"); + expect(state.exchangeBaseUrl).eq("exchange url"); + }, + ], + TestingContext, + ); + + expect(hookBehavior).deep.equal({ result: "ok" }); expect(handler.getCallingQueueState()).eq("empty"); }); @@ -140,25 +153,30 @@ describe("Tip CTA states", () => { talerTipUri: "taler://tip/asd", onCancel: nullFunction, onSuccess: nullFunction, - } - - const hookBehavior = await tests.hookBehaveLikeThis(useComponentState, props, [ - ({ status, error }) => { - expect(status).equals("loading"); - expect(error).undefined; - }, - (state) => { - if (state.status !== "ready") expect.fail(); - if (state.error) expect.fail(); - expect(state.amount).deep.eq(Amounts.parseOrThrow("EUR:1")); - expect(state.merchantBaseUrl).eq("merchant url"); - expect(state.exchangeBaseUrl).eq("exchange url"); - - //FIXME: add ignore button - }, - ], TestingContext) - - expect(hookBehavior).deep.equal({ result: "ok" }) + }; + + const hookBehavior = await tests.hookBehaveLikeThis( + useComponentState, + props, + [ + ({ status, error }) => { + expect(status).equals("loading"); + expect(error).undefined; + }, + (state) => { + if (state.status !== "ready") expect.fail(); + if (state.error) expect.fail(); + expect(state.amount).deep.eq(Amounts.parseOrThrow("EUR:1")); + expect(state.merchantBaseUrl).eq("merchant url"); + expect(state.exchangeBaseUrl).eq("exchange url"); + + //FIXME: add ignore button + }, + ], + TestingContext, + ); + + expect(hookBehavior).deep.equal({ result: "ok" }); expect(handler.getCallingQueueState()).eq("empty"); }); @@ -181,24 +199,28 @@ describe("Tip CTA states", () => { talerTipUri: "taler://tip/asd", onCancel: nullFunction, onSuccess: nullFunction, - } - - const hookBehavior = await tests.hookBehaveLikeThis(useComponentState, props, [ - ({ status, error }) => { - expect(status).equals("loading"); - expect(error).undefined; - }, - (state) => { - if (state.status !== "accepted") expect.fail(); - if (state.error) expect.fail(); - expect(state.amount).deep.eq(Amounts.parseOrThrow("EUR:1")); - expect(state.merchantBaseUrl).eq("merchant url"); - expect(state.exchangeBaseUrl).eq("exchange url"); - }, - ], TestingContext) - - expect(hookBehavior).deep.equal({ result: "ok" }) + }; + + const hookBehavior = await tests.hookBehaveLikeThis( + useComponentState, + props, + [ + ({ status, error }) => { + expect(status).equals("loading"); + expect(error).undefined; + }, + (state) => { + if (state.status !== "accepted") expect.fail(); + if (state.error) expect.fail(); + expect(state.amount).deep.eq(Amounts.parseOrThrow("EUR:1")); + expect(state.merchantBaseUrl).eq("merchant url"); + expect(state.exchangeBaseUrl).eq("exchange url"); + }, + ], + TestingContext, + ); + + expect(hookBehavior).deep.equal({ result: "ok" }); expect(handler.getCallingQueueState()).eq("empty"); - }); }); diff --git a/packages/taler-wallet-webextension/src/cta/TransferCreate/state.ts b/packages/taler-wallet-webextension/src/cta/TransferCreate/state.ts index 3536014da..c09a524c8 100644 --- a/packages/taler-wallet-webextension/src/cta/TransferCreate/state.ts +++ b/packages/taler-wallet-webextension/src/cta/TransferCreate/state.ts @@ -17,7 +17,7 @@ import { Amounts, TalerErrorDetail, - TalerProtocolTimestamp + TalerProtocolTimestamp, } from "@gnu-taler/taler-util"; import { TalerError, WalletApiOperation } from "@gnu-taler/taler-wallet-core"; import { isFuture, parse } from "date-fns"; @@ -26,10 +26,12 @@ import { useBackendContext } from "../../context/backend.js"; import { useAsyncAsHook } from "../../hooks/useAsyncAsHook.js"; import { Props, State } from "./index.js"; -export function useComponentState( - { amount: amountStr, onClose, onSuccess }: Props, -): State { - const api = useBackendContext() +export function useComponentState({ + amount: amountStr, + onClose, + onSuccess, +}: Props): State { + const api = useBackendContext(); const amount = Amounts.parseOrThrow(amountStr); const [subject, setSubject] = useState<string | undefined>(); @@ -124,8 +126,8 @@ export function useComponentState( subject === undefined ? undefined : !subject - ? "Can't be empty" - : undefined, + ? "Can't be empty" + : undefined, value: subject ?? "", onInput: async (e) => setSubject(e), }, diff --git a/packages/taler-wallet-webextension/src/cta/TransferPickup/index.ts b/packages/taler-wallet-webextension/src/cta/TransferPickup/index.ts index de6ad3b79..fe6fb2ada 100644 --- a/packages/taler-wallet-webextension/src/cta/TransferPickup/index.ts +++ b/packages/taler-wallet-webextension/src/cta/TransferPickup/index.ts @@ -17,7 +17,7 @@ import { AbsoluteTime, AmountJson, - TalerErrorDetail + TalerErrorDetail, } from "@gnu-taler/taler-util"; import { Loading } from "../../components/Loading.js"; import { HookError } from "../../hooks/useAsyncAsHook.js"; diff --git a/packages/taler-wallet-webextension/src/cta/TransferPickup/state.ts b/packages/taler-wallet-webextension/src/cta/TransferPickup/state.ts index 45bec28fb..82c95b0c6 100644 --- a/packages/taler-wallet-webextension/src/cta/TransferPickup/state.ts +++ b/packages/taler-wallet-webextension/src/cta/TransferPickup/state.ts @@ -18,7 +18,7 @@ import { AbsoluteTime, Amounts, TalerErrorDetail, - TalerProtocolTimestamp + TalerProtocolTimestamp, } from "@gnu-taler/taler-util"; import { TalerError, WalletApiOperation } from "@gnu-taler/taler-wallet-core"; import { useState } from "preact/hooks"; @@ -26,10 +26,12 @@ import { useBackendContext } from "../../context/backend.js"; import { useAsyncAsHook } from "../../hooks/useAsyncAsHook.js"; import { Props, State } from "./index.js"; -export function useComponentState( - { talerPayPushUri, onClose, onSuccess }: Props, -): State { - const api = useBackendContext() +export function useComponentState({ + talerPayPushUri, + onClose, + onSuccess, +}: Props): State { + const api = useBackendContext(); const hook = useAsyncAsHook(async () => { return await api.wallet.call(WalletApiOperation.CheckPeerPushPayment, { talerUri: talerPayPushUri, diff --git a/packages/taler-wallet-webextension/src/cta/Withdraw/index.ts b/packages/taler-wallet-webextension/src/cta/Withdraw/index.ts index 9e5943161..25d4e44e5 100644 --- a/packages/taler-wallet-webextension/src/cta/Withdraw/index.ts +++ b/packages/taler-wallet-webextension/src/cta/Withdraw/index.ts @@ -22,7 +22,7 @@ import { ButtonHandler, SelectFieldHandler } from "../../mui/handlers.js"; import { compose, StateViewMap } from "../../utils/index.js"; import { useComponentStateFromParams, - useComponentStateFromURI + useComponentStateFromURI, } from "./state.js"; import { ExchangeSelectionPage } from "../../wallet/ExchangeSelection/index.js"; diff --git a/packages/taler-wallet-webextension/src/cta/Withdraw/state.ts b/packages/taler-wallet-webextension/src/cta/Withdraw/state.ts index 4420221fc..1ecf05eca 100644 --- a/packages/taler-wallet-webextension/src/cta/Withdraw/state.ts +++ b/packages/taler-wallet-webextension/src/cta/Withdraw/state.ts @@ -19,7 +19,7 @@ import { AmountJson, Amounts, ExchangeListItem, - ExchangeTosStatus + ExchangeTosStatus, } from "@gnu-taler/taler-util"; import { TalerError, WalletApiOperation } from "@gnu-taler/taler-wallet-core"; import { useState } from "preact/hooks"; @@ -29,10 +29,12 @@ import { useSelectedExchange } from "../../hooks/useSelectedExchange.js"; import { RecursiveState } from "../../utils/index.js"; import { PropsFromParams, PropsFromURI, State } from "./index.js"; -export function useComponentStateFromParams( - { amount, cancel, onSuccess }: PropsFromParams, -): RecursiveState<State> { - const api = useBackendContext() +export function useComponentStateFromParams({ + amount, + cancel, + onSuccess, +}: PropsFromParams): RecursiveState<State> { + const api = useBackendContext(); const uriInfoHook = useAsyncAsHook(async () => { const exchanges = await api.wallet.call( WalletApiOperation.ListExchanges, @@ -87,10 +89,12 @@ export function useComponentStateFromParams( ); } -export function useComponentStateFromURI( - { talerWithdrawUri, cancel, onSuccess }: PropsFromURI, -): RecursiveState<State> { - const api = useBackendContext() +export function useComponentStateFromURI({ + talerWithdrawUri, + cancel, + onSuccess, +}: PropsFromURI): RecursiveState<State> { + const api = useBackendContext(); /** * Ask the wallet about the withdraw URI */ @@ -175,7 +179,7 @@ function exchangeSelectionState( exchangeList: ExchangeListItem[], defaultExchange: string | undefined, ): RecursiveState<State> { - const api = useBackendContext() + const api = useBackendContext(); const selectedExchange = useSelectedExchange({ currency: chosenAmount.currency, defaultExchange, @@ -276,10 +280,10 @@ function exchangeSelectionState( //TODO: calculate based on exchange info const ageRestriction = ageRestrictionEnabled ? { - list: ageRestrictionOptions, - value: String(ageRestricted), - onChange: async (v: string) => setAgeRestricted(parseInt(v, 10)), - } + list: ageRestrictionOptions, + value: String(ageRestricted), + onChange: async (v: string) => setAgeRestricted(parseInt(v, 10)), + } : undefined; return { diff --git a/packages/taler-wallet-webextension/src/cta/Withdraw/test.ts b/packages/taler-wallet-webextension/src/cta/Withdraw/test.ts index 084b4368c..3277ac18d 100644 --- a/packages/taler-wallet-webextension/src/cta/Withdraw/test.ts +++ b/packages/taler-wallet-webextension/src/cta/Withdraw/test.ts @@ -64,7 +64,7 @@ const exchanges: ExchangeListItem[] = [ const nullFunction = async (): Promise<void> => { null; -} +}; describe("Withdraw CTA states", () => { it("should tell the user that the URI is missing", async () => { @@ -76,20 +76,25 @@ describe("Withdraw CTA states", () => { onSuccess: nullFunction, }; - const hookBehavior = await tests.hookBehaveLikeThis(useComponentStateFromURI, props, [ - ({ status }) => { - expect(status).equals("loading"); - }, - ({ status, error }) => { - if (status != "uri-error") expect.fail(); - if (!error) expect.fail(); - if (!error.hasError) expect.fail(); - if (error.operational) expect.fail(); - expect(error.message).eq("ERROR_NO-URI-FOR-WITHDRAWAL"); - }, - ], TestingContext) + const hookBehavior = await tests.hookBehaveLikeThis( + useComponentStateFromURI, + props, + [ + ({ status }) => { + expect(status).equals("loading"); + }, + ({ status, error }) => { + if (status != "uri-error") expect.fail(); + if (!error) expect.fail(); + if (!error.hasError) expect.fail(); + if (error.operational) expect.fail(); + expect(error.message).eq("ERROR_NO-URI-FOR-WITHDRAWAL"); + }, + ], + TestingContext, + ); - expect(hookBehavior).deep.equal({ result: "ok" }) + expect(hookBehavior).deep.equal({ result: "ok" }); expect(handler.getCallingQueueState()).eq("empty"); }); @@ -110,17 +115,22 @@ describe("Withdraw CTA states", () => { }, ); - const hookBehavior = await tests.hookBehaveLikeThis(useComponentStateFromURI, props, [ - ({ status }) => { - expect(status).equals("loading"); - }, - ({ status, error }) => { - expect(status).equals("no-exchange"); - expect(error).undefined; - }, - ], TestingContext) + const hookBehavior = await tests.hookBehaveLikeThis( + useComponentStateFromURI, + props, + [ + ({ status }) => { + expect(status).equals("loading"); + }, + ({ status, error }) => { + expect(status).equals("no-exchange"); + expect(error).undefined; + }, + ], + TestingContext, + ); - expect(hookBehavior).deep.equal({ result: "ok" }) + expect(hookBehavior).deep.equal({ result: "ok" }); expect(handler.getCallingQueueState()).eq("empty"); }); @@ -153,27 +163,32 @@ describe("Withdraw CTA states", () => { }, ); - const hookBehavior = await tests.hookBehaveLikeThis(useComponentStateFromURI, props, [ - ({ status }) => { - expect(status).equals("loading"); - }, - ({ status, error }) => { - expect(status).equals("loading"); - expect(error).undefined; - }, - (state) => { - expect(state.status).equals("success"); - if (state.status !== "success") return; - - expect(state.toBeReceived).deep.equal(Amounts.parseOrThrow("ARS:2")); - expect(state.withdrawalFee).deep.equal(Amounts.parseOrThrow("ARS:0")); - expect(state.chosenAmount).deep.equal(Amounts.parseOrThrow("ARS:2")); - - expect(state.doWithdrawal.onClick).not.undefined; - }, - ], TestingContext) + const hookBehavior = await tests.hookBehaveLikeThis( + useComponentStateFromURI, + props, + [ + ({ status }) => { + expect(status).equals("loading"); + }, + ({ status, error }) => { + expect(status).equals("loading"); + expect(error).undefined; + }, + (state) => { + expect(state.status).equals("success"); + if (state.status !== "success") return; + + expect(state.toBeReceived).deep.equal(Amounts.parseOrThrow("ARS:2")); + expect(state.withdrawalFee).deep.equal(Amounts.parseOrThrow("ARS:0")); + expect(state.chosenAmount).deep.equal(Amounts.parseOrThrow("ARS:2")); + + expect(state.doWithdrawal.onClick).not.undefined; + }, + ], + TestingContext, + ); - expect(hookBehavior).deep.equal({ result: "ok" }) + expect(hookBehavior).deep.equal({ result: "ok" }); expect(handler.getCallingQueueState()).eq("empty"); }); @@ -221,39 +236,44 @@ describe("Withdraw CTA states", () => { }, ); - const hookBehavior = await tests.hookBehaveLikeThis(useComponentStateFromURI, props, [ - ({ status }) => { - expect(status).equals("loading"); - }, - ({ status, error }) => { - expect(status).equals("loading"); - expect(error).undefined; - }, - (state) => { - expect(state.status).equals("success"); - if (state.status !== "success") return; - - expect(state.toBeReceived).deep.equal(Amounts.parseOrThrow("ARS:2")); - expect(state.withdrawalFee).deep.equal(Amounts.parseOrThrow("ARS:0")); - expect(state.chosenAmount).deep.equal(Amounts.parseOrThrow("ARS:2")); - - expect(state.doWithdrawal.onClick).undefined; - - state.onTosUpdate(); - }, - (state) => { - expect(state.status).equals("success"); - if (state.status !== "success") return; - - expect(state.toBeReceived).deep.equal(Amounts.parseOrThrow("ARS:2")); - expect(state.withdrawalFee).deep.equal(Amounts.parseOrThrow("ARS:0")); - expect(state.chosenAmount).deep.equal(Amounts.parseOrThrow("ARS:2")); - - expect(state.doWithdrawal.onClick).not.undefined; - }, - ], TestingContext) + const hookBehavior = await tests.hookBehaveLikeThis( + useComponentStateFromURI, + props, + [ + ({ status }) => { + expect(status).equals("loading"); + }, + ({ status, error }) => { + expect(status).equals("loading"); + expect(error).undefined; + }, + (state) => { + expect(state.status).equals("success"); + if (state.status !== "success") return; + + expect(state.toBeReceived).deep.equal(Amounts.parseOrThrow("ARS:2")); + expect(state.withdrawalFee).deep.equal(Amounts.parseOrThrow("ARS:0")); + expect(state.chosenAmount).deep.equal(Amounts.parseOrThrow("ARS:2")); + + expect(state.doWithdrawal.onClick).undefined; + + state.onTosUpdate(); + }, + (state) => { + expect(state.status).equals("success"); + if (state.status !== "success") return; + + expect(state.toBeReceived).deep.equal(Amounts.parseOrThrow("ARS:2")); + expect(state.withdrawalFee).deep.equal(Amounts.parseOrThrow("ARS:0")); + expect(state.chosenAmount).deep.equal(Amounts.parseOrThrow("ARS:2")); + + expect(state.doWithdrawal.onClick).not.undefined; + }, + ], + TestingContext, + ); - expect(hookBehavior).deep.equal({ result: "ok" }) + expect(hookBehavior).deep.equal({ result: "ok" }); expect(handler.getCallingQueueState()).eq("empty"); }); }); diff --git a/packages/taler-wallet-webextension/src/hooks/useAutoOpenPermissions.ts b/packages/taler-wallet-webextension/src/hooks/useAutoOpenPermissions.ts index 1a48cdca7..cb90ec853 100644 --- a/packages/taler-wallet-webextension/src/hooks/useAutoOpenPermissions.ts +++ b/packages/taler-wallet-webextension/src/hooks/useAutoOpenPermissions.ts @@ -25,9 +25,11 @@ export function useAutoOpenPermissions(): ToggleHandler { const [enabled, setEnabled] = useState(false); const [error, setError] = useState<TalerError | undefined>(); const toggle = async (): Promise<void> => { - return handleAutoOpenPerm(enabled, setEnabled, api.background).catch((e) => { - setError(TalerError.fromException(e)); - }); + return handleAutoOpenPerm(enabled, setEnabled, api.background).catch( + (e) => { + setError(TalerError.fromException(e)); + }, + ); }; useEffect(() => { diff --git a/packages/taler-wallet-webextension/src/hooks/useBackupDeviceName.ts b/packages/taler-wallet-webextension/src/hooks/useBackupDeviceName.ts index 585a643a9..6288b6986 100644 --- a/packages/taler-wallet-webextension/src/hooks/useBackupDeviceName.ts +++ b/packages/taler-wallet-webextension/src/hooks/useBackupDeviceName.ts @@ -28,7 +28,7 @@ export function useBackupDeviceName(): BackupDeviceName { name: "", update: () => Promise.resolve(), }); - const api = useBackendContext() + const api = useBackendContext(); useEffect(() => { async function run(): Promise<void> { diff --git a/packages/taler-wallet-webextension/src/hooks/useClipboardPermissions.ts b/packages/taler-wallet-webextension/src/hooks/useClipboardPermissions.ts index 649def599..eda2afd8d 100644 --- a/packages/taler-wallet-webextension/src/hooks/useClipboardPermissions.ts +++ b/packages/taler-wallet-webextension/src/hooks/useClipboardPermissions.ts @@ -23,12 +23,14 @@ import { platform } from "../platform/api.js"; export function useClipboardPermissions(): ToggleHandler { const [enabled, setEnabled] = useState(false); const [error, setError] = useState<TalerError | undefined>(); - const api = useBackendContext() + const api = useBackendContext(); const toggle = async (): Promise<void> => { - return handleClipboardPerm(enabled, setEnabled, api.background).catch((e) => { - setError(TalerError.fromException(e)); - }); + return handleClipboardPerm(enabled, setEnabled, api.background).catch( + (e) => { + setError(TalerError.fromException(e)); + }, + ); }; useEffect(() => { diff --git a/packages/taler-wallet-webextension/src/platform/chrome.ts b/packages/taler-wallet-webextension/src/platform/chrome.ts index 4b9caa714..aac3b546c 100644 --- a/packages/taler-wallet-webextension/src/platform/chrome.ts +++ b/packages/taler-wallet-webextension/src/platform/chrome.ts @@ -444,8 +444,8 @@ function registerTalerHeaderListener( info: chrome.tabs.TabChangeInfo, ): Promise<void> { if (tabId < 0) return; - const tabLocationHasBeenUpdated = info.status === "complete" - const tabTitleHasBeenUpdated = info.title !== undefined + const tabLocationHasBeenUpdated = info.status === "complete"; + const tabTitleHasBeenUpdated = info.title !== undefined; if (tabLocationHasBeenUpdated || tabTitleHasBeenUpdated) { const uri = await findTalerUriInTab(tabId); if (!uri) return; @@ -543,26 +543,26 @@ function setAlertedIcon(): void { interface OffscreenCanvasRenderingContext2D extends CanvasState, - CanvasTransform, - CanvasCompositing, - CanvasImageSmoothing, - CanvasFillStrokeStyles, - CanvasShadowStyles, - CanvasFilters, - CanvasRect, - CanvasDrawPath, - CanvasUserInterface, - CanvasText, - CanvasDrawImage, - CanvasImageData, - CanvasPathDrawingStyles, - CanvasTextDrawingStyles, - CanvasPath { + CanvasTransform, + CanvasCompositing, + CanvasImageSmoothing, + CanvasFillStrokeStyles, + CanvasShadowStyles, + CanvasFilters, + CanvasRect, + CanvasDrawPath, + CanvasUserInterface, + CanvasText, + CanvasDrawImage, + CanvasImageData, + CanvasPathDrawingStyles, + CanvasTextDrawingStyles, + CanvasPath { readonly canvas: OffscreenCanvas; } declare const OffscreenCanvasRenderingContext2D: { prototype: OffscreenCanvasRenderingContext2D; - new(): OffscreenCanvasRenderingContext2D; + new (): OffscreenCanvasRenderingContext2D; }; interface OffscreenCanvas extends EventTarget { @@ -575,7 +575,7 @@ interface OffscreenCanvas extends EventTarget { } declare const OffscreenCanvas: { prototype: OffscreenCanvas; - new(width: number, height: number): OffscreenCanvas; + new (width: number, height: number): OffscreenCanvas; }; function createCanvas(size: number): OffscreenCanvas { diff --git a/packages/taler-wallet-webextension/src/stories.test.ts b/packages/taler-wallet-webextension/src/stories.test.ts index 9277530a3..bd8ac0b24 100644 --- a/packages/taler-wallet-webextension/src/stories.test.ts +++ b/packages/taler-wallet-webextension/src/stories.test.ts @@ -34,18 +34,21 @@ setupI18n("en", { en: {} }); setupPlatform(chromeAPI); describe("All the examples:", () => { - const cms = parseGroupImport({ popup, wallet, cta, mui, components }) - cms.forEach(group => { + const cms = parseGroupImport({ popup, wallet, cta, mui, components }); + cms.forEach((group) => { describe(`Example for group "${group.title}:"`, () => { - group.list.forEach(component => { + group.list.forEach((component) => { describe(`Component ${component.name}:`, () => { - component.examples.forEach(example => { + component.examples.forEach((example) => { it(`should render example: ${example.name}`, () => { - renderNodeOrBrowser(example.render.component, example.render.props) - }) - }) - }) - }) - }) - }) + renderNodeOrBrowser( + example.render.component, + example.render.props, + ); + }); + }); + }); + }); + }); + }); }); diff --git a/packages/taler-wallet-webextension/src/test-utils.ts b/packages/taler-wallet-webextension/src/test-utils.ts index 791773c42..379513782 100644 --- a/packages/taler-wallet-webextension/src/test-utils.ts +++ b/packages/taler-wallet-webextension/src/test-utils.ts @@ -54,7 +54,7 @@ export function createExample<Props>( return { component: Render, - props: evaluatedProps + props: evaluatedProps, }; } @@ -74,7 +74,7 @@ export function createExampleWithCustomContext<Props, ContextProps>( return { component: WithContext, - props: evaluatedProps + props: evaluatedProps, }; } @@ -253,7 +253,7 @@ type Subscriptions = { export function createWalletApiMock(): { handler: MockHandler; - TestingContext: FunctionalComponent<{ children: ComponentChildren }> + TestingContext: FunctionalComponent<{ children: ComponentChildren }>; } { const calls = new Array<CallRecord>(); const subscriptions: Subscriptions = {}; @@ -342,8 +342,8 @@ export function createWalletApiMock(): { callback: cb ? cb : () => { - null; - }, + null; + }, }); return handler; }, @@ -358,13 +358,21 @@ export function createWalletApiMock(): { }, }; - function TestingContext({ children }: { children: ComponentChildren }): VNode { - return create(BackendProvider, { - wallet: mock.wallet, - background: mock.background, - listener: mock.listener, + function TestingContext({ + children, + }: { + children: ComponentChildren; + }): VNode { + return create( + BackendProvider, + { + wallet: mock.wallet, + background: mock.background, + listener: mock.listener, + children, + }, children, - }, children) + ); } return { handler, TestingContext }; diff --git a/packages/taler-wallet-webextension/src/wallet/AddBackupProvider/index.ts b/packages/taler-wallet-webextension/src/wallet/AddBackupProvider/index.ts index 2adcc9f74..94020069b 100644 --- a/packages/taler-wallet-webextension/src/wallet/AddBackupProvider/index.ts +++ b/packages/taler-wallet-webextension/src/wallet/AddBackupProvider/index.ts @@ -14,22 +14,21 @@ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ -import { - TalerErrorDetail -} from "@gnu-taler/taler-util"; +import { TalerErrorDetail } from "@gnu-taler/taler-util"; import { SyncTermsOfServiceResponse } from "@gnu-taler/taler-wallet-core"; import { Loading } from "../../components/Loading.js"; import { HookError } from "../../hooks/useAsyncAsHook.js"; import { ButtonHandler, TextFieldHandler, - ToggleHandler + ToggleHandler, } from "../../mui/handlers.js"; import { compose, StateViewMap } from "../../utils/index.js"; import { useComponentState } from "./state.js"; import { - ConfirmProviderView, LoadingUriView, - SelectProviderView + ConfirmProviderView, + LoadingUriView, + SelectProviderView, } from "./views.js"; export interface Props { diff --git a/packages/taler-wallet-webextension/src/wallet/AddBackupProvider/state.ts b/packages/taler-wallet-webextension/src/wallet/AddBackupProvider/state.ts index 271a1bf98..32c48be91 100644 --- a/packages/taler-wallet-webextension/src/wallet/AddBackupProvider/state.ts +++ b/packages/taler-wallet-webextension/src/wallet/AddBackupProvider/state.ts @@ -17,11 +17,11 @@ import { canonicalizeBaseUrl, Codec, - TalerErrorDetail + TalerErrorDetail, } from "@gnu-taler/taler-util"; import { codecForSyncTermsOfServiceResponse, - WalletApiOperation + WalletApiOperation, } from "@gnu-taler/taler-wallet-core"; import { useEffect, useState } from "preact/hooks"; import { useBackendContext } from "../../context/backend.js"; @@ -106,47 +106,50 @@ function useUrlState<T>( constHref == undefined ? undefined : async () => { - const req = await fetch(constHref).catch((e) => { - return setState({ - status: "network-error", - href: constHref, + const req = await fetch(constHref).catch((e) => { + return setState({ + status: "network-error", + href: constHref, + }); }); - }); - if (!req) return; + if (!req) return; - if (req.status >= 400 && req.status < 500) { - setState({ - status: "client-error", - code: req.status, - }); - return; - } - if (req.status > 500) { - setState({ - status: "server-error", - code: req.status, - }); - return; - } + if (req.status >= 400 && req.status < 500) { + setState({ + status: "client-error", + code: req.status, + }); + return; + } + if (req.status > 500) { + setState({ + status: "server-error", + code: req.status, + }); + return; + } - const json = await req.json(); - try { - const result = codec.decode(json); - setState({ status: "ok", result }); - } catch (e: any) { - setState({ status: "parsing-error", json }); - } - }, + const json = await req.json(); + try { + const result = codec.decode(json); + setState({ status: "ok", result }); + } catch (e: any) { + setState({ status: "parsing-error", json }); + } + }, [host, path], ); return state; } -export function useComponentState( - { currency, onBack, onComplete, onPaymentRequired }: Props, -): State { - const api = useBackendContext() +export function useComponentState({ + currency, + onBack, + onComplete, + onPaymentRequired, +}: Props): State { + const api = useBackendContext(); const [url, setHost] = useState<string | undefined>(); const [name, setName] = useState<string | undefined>(); const [tos, setTos] = useState(false); @@ -223,8 +226,8 @@ export function useComponentState( !urlState || urlState.status !== "ok" || !name ? undefined : async () => { - setShowConfirm(true); - }, + setShowConfirm(true); + }, }, urlOk: urlState?.status === "ok", url: { diff --git a/packages/taler-wallet-webextension/src/wallet/AddBackupProvider/test.ts b/packages/taler-wallet-webextension/src/wallet/AddBackupProvider/test.ts index 929e051cb..9abb672fa 100644 --- a/packages/taler-wallet-webextension/src/wallet/AddBackupProvider/test.ts +++ b/packages/taler-wallet-webextension/src/wallet/AddBackupProvider/test.ts @@ -21,9 +21,7 @@ import { expect } from "chai"; import { tests } from "../../../../web-util/src/index.browser.js"; -import { - createWalletApiMock, nullFunction -} from "../../test-utils.js"; +import { createWalletApiMock, nullFunction } from "../../test-utils.js"; import { Props } from "./index.js"; import { useComponentState } from "./state.js"; @@ -34,21 +32,24 @@ const props: Props = { onPaymentRequired: nullFunction, }; describe("AddBackupProvider states", () => { - it("should start in 'select-provider' state", async () => { const { handler, TestingContext } = createWalletApiMock(); - const hookBehavior = await tests.hookBehaveLikeThis(useComponentState, props, [ - (state) => { - expect(state.status).equal("select-provider"); - if (state.status !== "select-provider") return; - expect(state.name.value).eq(""); - expect(state.url.value).eq(""); - }, - ], TestingContext) - - expect(hookBehavior).deep.equal({ result: "ok" }) + const hookBehavior = await tests.hookBehaveLikeThis( + useComponentState, + props, + [ + (state) => { + expect(state.status).equal("select-provider"); + if (state.status !== "select-provider") return; + expect(state.name.value).eq(""); + expect(state.url.value).eq(""); + }, + ], + TestingContext, + ); + + expect(hookBehavior).deep.equal({ result: "ok" }); expect(handler.getCallingQueueState()).eq("empty"); - }); }); diff --git a/packages/taler-wallet-webextension/src/wallet/DepositPage/index.ts b/packages/taler-wallet-webextension/src/wallet/DepositPage/index.ts index ad4c759bf..6ffbccc27 100644 --- a/packages/taler-wallet-webextension/src/wallet/DepositPage/index.ts +++ b/packages/taler-wallet-webextension/src/wallet/DepositPage/index.ts @@ -20,7 +20,7 @@ import { HookError } from "../../hooks/useAsyncAsHook.js"; import { AmountFieldHandler, ButtonHandler, - SelectFieldHandler + SelectFieldHandler, } from "../../mui/handlers.js"; import { compose, StateViewMap } from "../../utils/index.js"; import { ManageAccountPage } from "../ManageAccount/index.js"; @@ -30,7 +30,7 @@ import { LoadingErrorView, NoAccountToDepositView, NoEnoughBalanceView, - ReadyView + ReadyView, } from "./views.js"; export interface Props { diff --git a/packages/taler-wallet-webextension/src/wallet/DepositPage/state.ts b/packages/taler-wallet-webextension/src/wallet/DepositPage/state.ts index 5ad0841dc..02e85a1c7 100644 --- a/packages/taler-wallet-webextension/src/wallet/DepositPage/state.ts +++ b/packages/taler-wallet-webextension/src/wallet/DepositPage/state.ts @@ -21,7 +21,7 @@ import { KnownBankAccountsInfo, parsePaytoUri, PaytoUri, - stringifyPaytoUri + stringifyPaytoUri, } from "@gnu-taler/taler-util"; import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; import { useState } from "preact/hooks"; @@ -29,10 +29,13 @@ import { useBackendContext } from "../../context/backend.js"; import { useAsyncAsHook } from "../../hooks/useAsyncAsHook.js"; import { Props, State } from "./index.js"; -export function useComponentState( - { amount: amountStr, currency: currencyStr, onCancel, onSuccess }: Props, -): State { - const api = useBackendContext() +export function useComponentState({ + amount: amountStr, + currency: currencyStr, + onCancel, + onSuccess, +}: Props): State { + const api = useBackendContext(); const parsed = amountStr === undefined ? undefined : Amounts.parse(amountStr); const currency = parsed !== undefined ? parsed.currency : currencyStr; @@ -55,8 +58,8 @@ export function useComponentState( parsed !== undefined ? parsed : currency !== undefined - ? Amounts.zeroOfCurrency(currency) - : undefined; + ? Amounts.zeroOfCurrency(currency) + : undefined; // const [accountIdx, setAccountIdx] = useState<number>(0); const [amount, setAmount] = useState<AmountJson>(initialValue ?? ({} as any)); const [selectedAccount, setSelectedAccount] = useState<PaytoUri>(); @@ -162,7 +165,11 @@ export function useComponentState( async function updateAmount(newAmount: AmountJson): Promise<void> { // const parsed = Amounts.parse(`${currency}:${numStr}`); try { - const result = await getFeeForAmount(currentAccount, newAmount, api.wallet); + const result = await getFeeForAmount( + currentAccount, + newAmount, + api.wallet, + ); setAmount(newAmount); setFee(result); } catch (e) { @@ -185,8 +192,8 @@ export function useComponentState( const amountError = !isDirty ? undefined : Amounts.cmp(balance, amount) === -1 - ? `Too much, your current balance is ${Amounts.stringifyValue(balance)}` - : undefined; + ? `Too much, your current balance is ${Amounts.stringifyValue(balance)}` + : undefined; const unableToDeposit = Amounts.isZero(totalToDeposit) || //deposit may be zero because of fee diff --git a/packages/taler-wallet-webextension/src/wallet/DepositPage/test.ts b/packages/taler-wallet-webextension/src/wallet/DepositPage/test.ts index 90ac020b7..b222709a7 100644 --- a/packages/taler-wallet-webextension/src/wallet/DepositPage/test.ts +++ b/packages/taler-wallet-webextension/src/wallet/DepositPage/test.ts @@ -23,14 +23,12 @@ import { Amounts, DepositGroupFees, parsePaytoUri, - stringifyPaytoUri + stringifyPaytoUri, } from "@gnu-taler/taler-util"; import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; import { expect } from "chai"; import { tests } from "../../../../web-util/src/index.browser.js"; -import { - createWalletApiMock, nullFunction -} from "../../test-utils.js"; +import { createWalletApiMock, nullFunction } from "../../test-utils.js"; import { useComponentState } from "./state.js"; @@ -71,16 +69,21 @@ describe("DepositPage states", () => { }, ); - const hookBehavior = await tests.hookBehaveLikeThis(useComponentState, props, [ - ({ status }) => { - expect(status).equal("loading"); - }, - ({ status }) => { - expect(status).equal("no-enough-balance"); - }, - ], TestingContext) + const hookBehavior = await tests.hookBehaveLikeThis( + useComponentState, + props, + [ + ({ status }) => { + expect(status).equal("loading"); + }, + ({ status }) => { + expect(status).equal("no-enough-balance"); + }, + ], + TestingContext, + ); - expect(hookBehavior).deep.equal({ result: "ok" }) + expect(hookBehavior).deep.equal({ result: "ok" }); expect(handler.getCallingQueueState()).eq("empty"); }); @@ -107,16 +110,21 @@ describe("DepositPage states", () => { }, ); - const hookBehavior = await tests.hookBehaveLikeThis(useComponentState, props, [ - ({ status }) => { - expect(status).equal("loading"); - }, - ({ status }) => { - expect(status).equal("no-accounts"); - }, - ], TestingContext) + const hookBehavior = await tests.hookBehaveLikeThis( + useComponentState, + props, + [ + ({ status }) => { + expect(status).equal("loading"); + }, + ({ status }) => { + expect(status).equal("no-accounts"); + }, + ], + TestingContext, + ); - expect(hookBehavior).deep.equal({ result: "ok" }) + expect(hookBehavior).deep.equal({ result: "ok" }); expect(handler.getCallingQueueState()).eq("empty"); }); @@ -161,24 +169,29 @@ describe("DepositPage states", () => { withoutFee(), ); - const hookBehavior = await tests.hookBehaveLikeThis(useComponentState, props, [ - ({ status }) => { - expect(status).equal("loading"); - }, - ({ status }) => { - expect(status).equal("loading"); - }, - (state) => { - if (state.status !== "ready") expect.fail(); - expect(state.cancelHandler.onClick).not.undefined; - expect(state.currency).eq(currency); - expect(state.account.value).eq(stringifyPaytoUri(ibanPayto.uri)); - expect(state.amount.value).deep.eq(Amounts.parseOrThrow("EUR:0")); - expect(state.depositHandler.onClick).undefined; - }, - ], TestingContext) + const hookBehavior = await tests.hookBehaveLikeThis( + useComponentState, + props, + [ + ({ status }) => { + expect(status).equal("loading"); + }, + ({ status }) => { + expect(status).equal("loading"); + }, + (state) => { + if (state.status !== "ready") expect.fail(); + expect(state.cancelHandler.onClick).not.undefined; + expect(state.currency).eq(currency); + expect(state.account.value).eq(stringifyPaytoUri(ibanPayto.uri)); + expect(state.amount.value).deep.eq(Amounts.parseOrThrow("EUR:0")); + expect(state.depositHandler.onClick).undefined; + }, + ], + TestingContext, + ); - expect(hookBehavior).deep.equal({ result: "ok" }) + expect(hookBehavior).deep.equal({ result: "ok" }); expect(handler.getCallingQueueState()).eq("empty"); }); @@ -218,37 +231,42 @@ describe("DepositPage states", () => { const accountSelected = stringifyPaytoUri(ibanPayto.uri); - const hookBehavior = await tests.hookBehaveLikeThis(useComponentState, props, [ - ({ status }) => { - expect(status).equal("loading"); - }, - ({ status }) => { - expect(status).equal("loading"); - }, - (state) => { - if (state.status !== "ready") expect.fail(); - expect(state.cancelHandler.onClick).not.undefined; - expect(state.currency).eq(currency); - expect(state.account.value).eq(stringifyPaytoUri(talerBankPayto.uri)); - expect(state.amount.value).deep.eq(Amounts.parseOrThrow("EUR:0")); - expect(state.depositHandler.onClick).undefined; - expect(state.totalFee).deep.eq(Amounts.parseOrThrow(`${currency}:0`)); - expect(state.account.onChange).not.undefined; - - state.account.onChange!(accountSelected); - }, - (state) => { - if (state.status !== "ready") expect.fail(); - expect(state.cancelHandler.onClick).not.undefined; - expect(state.currency).eq(currency); - expect(state.account.value).eq(accountSelected); - expect(state.amount.value).deep.eq(Amounts.parseOrThrow("EUR:0")); - expect(state.totalFee).deep.eq(Amounts.parseOrThrow(`${currency}:0`)); - expect(state.depositHandler.onClick).undefined; - }, - ], TestingContext) + const hookBehavior = await tests.hookBehaveLikeThis( + useComponentState, + props, + [ + ({ status }) => { + expect(status).equal("loading"); + }, + ({ status }) => { + expect(status).equal("loading"); + }, + (state) => { + if (state.status !== "ready") expect.fail(); + expect(state.cancelHandler.onClick).not.undefined; + expect(state.currency).eq(currency); + expect(state.account.value).eq(stringifyPaytoUri(talerBankPayto.uri)); + expect(state.amount.value).deep.eq(Amounts.parseOrThrow("EUR:0")); + expect(state.depositHandler.onClick).undefined; + expect(state.totalFee).deep.eq(Amounts.parseOrThrow(`${currency}:0`)); + expect(state.account.onChange).not.undefined; + + state.account.onChange!(accountSelected); + }, + (state) => { + if (state.status !== "ready") expect.fail(); + expect(state.cancelHandler.onClick).not.undefined; + expect(state.currency).eq(currency); + expect(state.account.value).eq(accountSelected); + expect(state.amount.value).deep.eq(Amounts.parseOrThrow("EUR:0")); + expect(state.totalFee).deep.eq(Amounts.parseOrThrow(`${currency}:0`)); + expect(state.depositHandler.onClick).undefined; + }, + ], + TestingContext, + ); - expect(hookBehavior).deep.equal({ result: "ok" }) + expect(hookBehavior).deep.equal({ result: "ok" }); expect(handler.getCallingQueueState()).eq("empty"); }); @@ -292,52 +310,58 @@ describe("DepositPage states", () => { const accountSelected = stringifyPaytoUri(ibanPayto.uri); - const hookBehavior = await tests.hookBehaveLikeThis(useComponentState, props, [ - ({ status }) => { - expect(status).equal("loading"); - }, - ({ status }) => { - expect(status).equal("loading"); - }, - (state) => { - if (state.status !== "ready") expect.fail(); - expect(state.cancelHandler.onClick).not.undefined; - expect(state.currency).eq(currency); - expect(state.account.value).eq(stringifyPaytoUri(talerBankPayto.uri)); - expect(state.amount.value).deep.eq(Amounts.parseOrThrow("EUR:0")); - expect(state.depositHandler.onClick).undefined; - expect(state.totalFee).deep.eq(Amounts.parseOrThrow(`${currency}:0`)); - expect(state.account.onChange).not.undefined; - - state.account.onChange!(accountSelected); - }, - (state) => { - if (state.status !== "ready") expect.fail(); - expect(state.cancelHandler.onClick).not.undefined; - expect(state.currency).eq(currency); - expect(state.account.value).eq(accountSelected); - expect(state.amount.value).deep.eq(Amounts.parseOrThrow("EUR:0")); - expect(state.depositHandler.onClick).undefined; - expect(state.totalFee).deep.eq(Amounts.parseOrThrow(`${currency}:3`)); - - expect(state.amount.onInput).not.undefined; - if (!state.amount.onInput) return; - state.amount.onInput(Amounts.parseOrThrow("EUR:10")); - }, - (state) => { - if (state.status !== "ready") expect.fail(); - expect(state.cancelHandler.onClick).not.undefined; - expect(state.currency).eq(currency); - expect(state.account.value).eq(accountSelected); - expect(state.amount.value).deep.eq(Amounts.parseOrThrow("EUR:10")); - expect(state.totalFee).deep.eq(Amounts.parseOrThrow(`${currency}:3`)); - expect(state.totalToDeposit).deep.eq(Amounts.parseOrThrow(`${currency}:7`)); - expect(state.depositHandler.onClick).not.undefined; - }, - ], TestingContext) + const hookBehavior = await tests.hookBehaveLikeThis( + useComponentState, + props, + [ + ({ status }) => { + expect(status).equal("loading"); + }, + ({ status }) => { + expect(status).equal("loading"); + }, + (state) => { + if (state.status !== "ready") expect.fail(); + expect(state.cancelHandler.onClick).not.undefined; + expect(state.currency).eq(currency); + expect(state.account.value).eq(stringifyPaytoUri(talerBankPayto.uri)); + expect(state.amount.value).deep.eq(Amounts.parseOrThrow("EUR:0")); + expect(state.depositHandler.onClick).undefined; + expect(state.totalFee).deep.eq(Amounts.parseOrThrow(`${currency}:0`)); + expect(state.account.onChange).not.undefined; + + state.account.onChange!(accountSelected); + }, + (state) => { + if (state.status !== "ready") expect.fail(); + expect(state.cancelHandler.onClick).not.undefined; + expect(state.currency).eq(currency); + expect(state.account.value).eq(accountSelected); + expect(state.amount.value).deep.eq(Amounts.parseOrThrow("EUR:0")); + expect(state.depositHandler.onClick).undefined; + expect(state.totalFee).deep.eq(Amounts.parseOrThrow(`${currency}:3`)); + + expect(state.amount.onInput).not.undefined; + if (!state.amount.onInput) return; + state.amount.onInput(Amounts.parseOrThrow("EUR:10")); + }, + (state) => { + if (state.status !== "ready") expect.fail(); + expect(state.cancelHandler.onClick).not.undefined; + expect(state.currency).eq(currency); + expect(state.account.value).eq(accountSelected); + expect(state.amount.value).deep.eq(Amounts.parseOrThrow("EUR:10")); + expect(state.totalFee).deep.eq(Amounts.parseOrThrow(`${currency}:3`)); + expect(state.totalToDeposit).deep.eq( + Amounts.parseOrThrow(`${currency}:7`), + ); + expect(state.depositHandler.onClick).not.undefined; + }, + ], + TestingContext, + ); - expect(hookBehavior).deep.equal({ result: "ok" }) + expect(hookBehavior).deep.equal({ result: "ok" }); expect(handler.getCallingQueueState()).eq("empty"); - }); }); diff --git a/packages/taler-wallet-webextension/src/wallet/DestinationSelection/state.ts b/packages/taler-wallet-webextension/src/wallet/DestinationSelection/state.ts index 0621d3304..dd711f406 100644 --- a/packages/taler-wallet-webextension/src/wallet/DestinationSelection/state.ts +++ b/packages/taler-wallet-webextension/src/wallet/DestinationSelection/state.ts @@ -22,10 +22,8 @@ import { useAsyncAsHook } from "../../hooks/useAsyncAsHook.js"; import { assertUnreachable, RecursiveState } from "../../utils/index.js"; import { Contact, Props, State } from "./index.js"; -export function useComponentState( - props: Props, -): RecursiveState<State> { - const api = useBackendContext() +export function useComponentState(props: Props): RecursiveState<State> { + const api = useBackendContext(); const parsedInitialAmount = !props.amount ? undefined : Amounts.parse(props.amount); @@ -41,22 +39,22 @@ export function useComponentState( const previous: Contact[] = true ? [] : [ - { - name: "International Bank", - icon_type: 'bank', - description: "account ending with 3454", - }, - { - name: "Max", - icon_type: 'bank', - description: "account ending with 3454", - }, - { - name: "Alex", - icon_type: 'bank', - description: "account ending with 3454", - }, - ]; + { + name: "International Bank", + icon_type: "bank", + description: "account ending with 3454", + }, + { + name: "Max", + icon_type: "bank", + description: "account ending with 3454", + }, + { + name: "Alex", + icon_type: "bank", + description: "account ending with 3454", + }, + ]; if (!amount) { return () => { @@ -114,15 +112,15 @@ export function useComponentState( onClick: invalid ? undefined : async () => { - props.goToWalletBankDeposit(currencyAndAmount); - }, + props.goToWalletBankDeposit(currencyAndAmount); + }, }, goToWallet: { onClick: invalid ? undefined : async () => { - props.goToWalletWalletSend(currencyAndAmount); - }, + props.goToWalletWalletSend(currencyAndAmount); + }, }, amountHandler: { onInput: async (s) => setAmount(s), @@ -144,15 +142,15 @@ export function useComponentState( onClick: invalid ? undefined : async () => { - props.goToWalletManualWithdraw(currencyAndAmount); - }, + props.goToWalletManualWithdraw(currencyAndAmount); + }, }, goToWallet: { onClick: invalid ? undefined : async () => { - props.goToWalletWalletInvoice(currencyAndAmount); - }, + props.goToWalletWalletInvoice(currencyAndAmount); + }, }, amountHandler: { onInput: async (s) => setAmount(s), diff --git a/packages/taler-wallet-webextension/src/wallet/DestinationSelection/test.ts b/packages/taler-wallet-webextension/src/wallet/DestinationSelection/test.ts index afba5db35..cc511ce65 100644 --- a/packages/taler-wallet-webextension/src/wallet/DestinationSelection/test.ts +++ b/packages/taler-wallet-webextension/src/wallet/DestinationSelection/test.ts @@ -23,7 +23,7 @@ import { Amounts, ExchangeEntryStatus, ExchangeListItem, - ExchangeTosStatus + ExchangeTosStatus, } from "@gnu-taler/taler-util"; import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; import { expect } from "chai"; @@ -59,33 +59,39 @@ describe("Destination selection states", () => { goToWalletWalletInvoice: nullFunction, }; - const hookBehavior = await tests.hookBehaveLikeThis(useComponentState, props, [ - ({ status }) => { - expect(status).equal("loading"); - }, - (state) => { - if (state.status !== "select-currency") expect.fail(); - if (state.error) expect.fail(); - expect(state.currencies).deep.eq({ - ARS: "ARS", - "": "Select a currency", - }); - - state.onCurrencySelected(exchangeArs.currency!); - }, - (state) => { - if (state.status !== "ready") expect.fail(); - if (state.error) expect.fail(); - expect(state.goToBank.onClick).eq(undefined); - expect(state.goToWallet.onClick).eq(undefined); - - expect(state.amountHandler.value).deep.eq(Amounts.parseOrThrow("ARS:0")); - }, - ], TestingContext) + const hookBehavior = await tests.hookBehaveLikeThis( + useComponentState, + props, + [ + ({ status }) => { + expect(status).equal("loading"); + }, + (state) => { + if (state.status !== "select-currency") expect.fail(); + if (state.error) expect.fail(); + expect(state.currencies).deep.eq({ + ARS: "ARS", + "": "Select a currency", + }); + + state.onCurrencySelected(exchangeArs.currency!); + }, + (state) => { + if (state.status !== "ready") expect.fail(); + if (state.error) expect.fail(); + expect(state.goToBank.onClick).eq(undefined); + expect(state.goToWallet.onClick).eq(undefined); + + expect(state.amountHandler.value).deep.eq( + Amounts.parseOrThrow("ARS:0"), + ); + }, + ], + TestingContext, + ); - expect(hookBehavior).deep.equal({ result: "ok" }) + expect(hookBehavior).deep.equal({ result: "ok" }); expect(handler.getCallingQueueState()).eq("empty"); - }); it("should be possible to start with an amount specified in request params", async () => { @@ -98,22 +104,28 @@ describe("Destination selection states", () => { amount: "ARS:2", }; - const hookBehavior = await tests.hookBehaveLikeThis(useComponentState, props, [ - // ({ status }) => { - // expect(status).equal("loading"); - // }, - (state) => { - if (state.status !== "ready") expect.fail(); - if (state.error) expect.fail(); - expect(state.goToBank.onClick).not.eq(undefined); - expect(state.goToWallet.onClick).not.eq(undefined); - - expect(state.amountHandler.value).deep.eq(Amounts.parseOrThrow("ARS:2")); - }, - ], TestingContext) + const hookBehavior = await tests.hookBehaveLikeThis( + useComponentState, + props, + [ + // ({ status }) => { + // expect(status).equal("loading"); + // }, + (state) => { + if (state.status !== "ready") expect.fail(); + if (state.error) expect.fail(); + expect(state.goToBank.onClick).not.eq(undefined); + expect(state.goToWallet.onClick).not.eq(undefined); + + expect(state.amountHandler.value).deep.eq( + Amounts.parseOrThrow("ARS:2"), + ); + }, + ], + TestingContext, + ); - expect(hookBehavior).deep.equal({ result: "ok" }) + expect(hookBehavior).deep.equal({ result: "ok" }); expect(handler.getCallingQueueState()).eq("empty"); - }); }); diff --git a/packages/taler-wallet-webextension/src/wallet/ExchangeSelection/index.ts b/packages/taler-wallet-webextension/src/wallet/ExchangeSelection/index.ts index 661fa5286..1bb4fb314 100644 --- a/packages/taler-wallet-webextension/src/wallet/ExchangeSelection/index.ts +++ b/packages/taler-wallet-webextension/src/wallet/ExchangeSelection/index.ts @@ -18,7 +18,7 @@ import { DenomOperationMap, ExchangeFullDetails, ExchangeListItem, - FeeDescriptionPair + FeeDescriptionPair, } from "@gnu-taler/taler-util"; import { Loading } from "../../components/Loading.js"; import { HookError } from "../../hooks/useAsyncAsHook.js"; @@ -32,7 +32,7 @@ import { NoExchangesView, PrivacyContentView, ReadyView, - TosContentView + TosContentView, } from "./views.js"; export interface Props { diff --git a/packages/taler-wallet-webextension/src/wallet/ExchangeSelection/state.ts b/packages/taler-wallet-webextension/src/wallet/ExchangeSelection/state.ts index 585050413..378556b94 100644 --- a/packages/taler-wallet-webextension/src/wallet/ExchangeSelection/state.ts +++ b/packages/taler-wallet-webextension/src/wallet/ExchangeSelection/state.ts @@ -17,17 +17,20 @@ import { DenomOperationMap, FeeDescription } from "@gnu-taler/taler-util"; import { createPairTimeline, - WalletApiOperation + WalletApiOperation, } from "@gnu-taler/taler-wallet-core"; import { useState } from "preact/hooks"; import { useBackendContext } from "../../context/backend.js"; import { useAsyncAsHook } from "../../hooks/useAsyncAsHook.js"; import { Props, State } from "./index.js"; -export function useComponentState( - { onCancel, onSelection, list: exchanges, currentExchange }: Props, -): State { - const api = useBackendContext() +export function useComponentState({ + onCancel, + onSelection, + list: exchanges, + currentExchange, +}: Props): State { + const api = useBackendContext(); const initialValue = exchanges.findIndex( (e) => e.exchangeBaseUrl === currentExchange, ); @@ -52,14 +55,14 @@ export function useComponentState( const selected = !selectedExchange ? undefined : await api.wallet.call(WalletApiOperation.GetExchangeDetailedInfo, { - exchangeBaseUrl: selectedExchange.exchangeBaseUrl, - }); + exchangeBaseUrl: selectedExchange.exchangeBaseUrl, + }); const original = !initialExchange ? undefined : await api.wallet.call(WalletApiOperation.GetExchangeDetailedInfo, { - exchangeBaseUrl: initialExchange.exchangeBaseUrl, - }); + exchangeBaseUrl: initialExchange.exchangeBaseUrl, + }); return { exchanges, diff --git a/packages/taler-wallet-webextension/src/wallet/ManageAccount/index.ts b/packages/taler-wallet-webextension/src/wallet/ManageAccount/index.ts index 0ee6472d6..8541821b7 100644 --- a/packages/taler-wallet-webextension/src/wallet/ManageAccount/index.ts +++ b/packages/taler-wallet-webextension/src/wallet/ManageAccount/index.ts @@ -20,7 +20,7 @@ import { HookError } from "../../hooks/useAsyncAsHook.js"; import { ButtonHandler, SelectFieldHandler, - TextFieldHandler + TextFieldHandler, } from "../../mui/handlers.js"; import { compose, StateViewMap } from "../../utils/index.js"; import { useComponentState } from "./state.js"; diff --git a/packages/taler-wallet-webextension/src/wallet/ManageAccount/state.ts b/packages/taler-wallet-webextension/src/wallet/ManageAccount/state.ts index d60ef962b..9690a5c79 100644 --- a/packages/taler-wallet-webextension/src/wallet/ManageAccount/state.ts +++ b/packages/taler-wallet-webextension/src/wallet/ManageAccount/state.ts @@ -17,7 +17,7 @@ import { KnownBankAccountsInfo, parsePaytoUri, - stringifyPaytoUri + stringifyPaytoUri, } from "@gnu-taler/taler-util"; import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; import { useState } from "preact/hooks"; @@ -25,10 +25,12 @@ import { useBackendContext } from "../../context/backend.js"; import { useAsyncAsHook } from "../../hooks/useAsyncAsHook.js"; import { AccountByType, Props, State } from "./index.js"; -export function useComponentState( - { currency, onAccountAdded, onCancel }: Props, -): State { - const api = useBackendContext() +export function useComponentState({ + currency, + onAccountAdded, + onCancel, +}: Props): State { + const api = useBackendContext(); const hook = useAsyncAsHook(() => api.wallet.call(WalletApiOperation.ListKnownBankAccounts, { currency }), ); diff --git a/packages/taler-wallet-webextension/src/wallet/Notifications/index.ts b/packages/taler-wallet-webextension/src/wallet/Notifications/index.ts index 3791b8967..4697ca549 100644 --- a/packages/taler-wallet-webextension/src/wallet/Notifications/index.ts +++ b/packages/taler-wallet-webextension/src/wallet/Notifications/index.ts @@ -21,7 +21,7 @@ import { compose, StateViewMap } from "../../utils/index.js"; import { useComponentState } from "./state.js"; import { LoadingUriView, ReadyView } from "./views.js"; -export type Props = object +export type Props = object; export type State = State.Loading | State.LoadingUriError | State.Ready; diff --git a/packages/taler-wallet-webextension/src/wallet/Notifications/state.ts b/packages/taler-wallet-webextension/src/wallet/Notifications/state.ts index 1042dea9f..648e490ce 100644 --- a/packages/taler-wallet-webextension/src/wallet/Notifications/state.ts +++ b/packages/taler-wallet-webextension/src/wallet/Notifications/state.ts @@ -20,7 +20,7 @@ import { useAsyncAsHook } from "../../hooks/useAsyncAsHook.js"; import { Props, State } from "./index.js"; export function useComponentState(p: Props): State { - const api = useBackendContext() + const api = useBackendContext(); const hook = useAsyncAsHook(async () => { return await api.wallet.call( WalletApiOperation.GetUserAttentionRequests, diff --git a/packages/taler-wallet-webextension/src/wxApi.ts b/packages/taler-wallet-webextension/src/wxApi.ts index d304a42a5..991cbb5fe 100644 --- a/packages/taler-wallet-webextension/src/wxApi.ts +++ b/packages/taler-wallet-webextension/src/wxApi.ts @@ -156,8 +156,8 @@ export type WxApiType = { background: BackgroundApiClient; listener: { onUpdateNotification: typeof onUpdateNotification; - } -} + }; +}; export const wxApi = { wallet: new WxWalletCoreApiClient(), |