From 4a781bd0dd8828ce152f6ab2c3f1bbd6b5e826f7 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Mon, 9 Jan 2023 20:20:09 -0300 Subject: fix #7153: more error handling if handler do not trap error then fail at compile time, all safe handlers push alert on error errors are typed so they render good information --- .../src/wallet/AddBackupProvider/index.ts | 2 +- .../src/wallet/AddBackupProvider/state.ts | 33 ++--- .../src/wallet/AddBackupProvider/stories.tsx | 16 +-- .../src/wallet/AddBackupProvider/test.ts | 3 +- .../src/wallet/AddNewActionView.stories.tsx | 4 +- .../src/wallet/Backup.stories.tsx | 10 +- .../src/wallet/BackupPage.tsx | 6 +- .../src/wallet/DepositPage/state.ts | 23 ++-- .../src/wallet/DepositPage/stories.tsx | 51 +++---- .../src/wallet/DepositPage/test.ts | 3 +- .../src/wallet/DestinationSelection/state.ts | 31 ++--- .../src/wallet/DestinationSelection/stories.tsx | 8 +- .../src/wallet/DestinationSelection/test.ts | 3 +- .../src/wallet/DeveloperPage.stories.tsx | 4 +- .../src/wallet/EmptyComponentExample/stories.tsx | 4 +- .../src/wallet/ExchangeAddConfirm.stories.tsx | 8 +- .../src/wallet/ExchangeAddSetUrl.stories.tsx | 10 +- .../src/wallet/ExchangeSelection/state.ts | 41 +++--- .../src/wallet/ExchangeSelection/stories.tsx | 14 +- .../src/wallet/History.stories.tsx | 72 +++++----- .../src/wallet/History.tsx | 11 +- .../src/wallet/ManageAccount/state.ts | 19 +-- .../src/wallet/ManageAccount/stories.tsx | 13 +- .../src/wallet/Notifications/stories.tsx | 4 +- .../wallet/ProviderAddConfirmProvider.stories.tsx | 6 +- .../src/wallet/ProviderAddSetUrl.stories.tsx | 12 +- .../src/wallet/ProviderDetail.stories.tsx | 97 +++++++------- .../src/wallet/ProviderDetailPage.tsx | 6 +- .../src/wallet/QrReader.stories.tsx | 4 +- .../src/wallet/ReserveCreated.stories.tsx | 14 +- .../src/wallet/Settings.stories.tsx | 97 ++++++++------ .../src/wallet/Settings.tsx | 24 ++-- .../src/wallet/Transaction.stories.tsx | 147 +++++++++++---------- .../src/wallet/Transaction.tsx | 6 +- .../src/wallet/Welcome.stories.tsx | 8 +- 35 files changed, 407 insertions(+), 407 deletions(-) (limited to 'packages/taler-wallet-webextension/src/wallet') diff --git a/packages/taler-wallet-webextension/src/wallet/AddBackupProvider/index.ts b/packages/taler-wallet-webextension/src/wallet/AddBackupProvider/index.ts index 4ec4c0ffe..e0b79e060 100644 --- a/packages/taler-wallet-webextension/src/wallet/AddBackupProvider/index.ts +++ b/packages/taler-wallet-webextension/src/wallet/AddBackupProvider/index.ts @@ -53,7 +53,7 @@ export namespace State { export interface ConfirmProvider { status: "confirm-provider"; - error: undefined | TalerErrorDetail; + error: undefined; url: string; provider: SyncTermsOfServiceResponse; tos: ToggleHandler; diff --git a/packages/taler-wallet-webextension/src/wallet/AddBackupProvider/state.ts b/packages/taler-wallet-webextension/src/wallet/AddBackupProvider/state.ts index 1b30ed0cd..cf35abac7 100644 --- a/packages/taler-wallet-webextension/src/wallet/AddBackupProvider/state.ts +++ b/packages/taler-wallet-webextension/src/wallet/AddBackupProvider/state.ts @@ -14,16 +14,13 @@ GNU Taler; see the file COPYING. If not, see */ -import { - canonicalizeBaseUrl, - Codec, - TalerErrorDetail, -} from "@gnu-taler/taler-util"; +import { canonicalizeBaseUrl, Codec } from "@gnu-taler/taler-util"; import { codecForSyncTermsOfServiceResponse, WalletApiOperation, } from "@gnu-taler/taler-wallet-core"; import { useEffect, useState } from "preact/hooks"; +import { useAlertContext } from "../../context/alert.js"; import { useBackendContext } from "../../context/backend.js"; import { assertUnreachable } from "../../utils/index.js"; import { Props, State } from "./index.js"; @@ -152,17 +149,15 @@ export function useComponentState({ const [url, setHost] = useState(); const [name, setName] = useState(); const [tos, setTos] = useState(false); + const { pushAlertOnError } = useAlertContext(); const urlState = useUrlState( url, "config", codecForSyncTermsOfServiceResponse(), ); - const [operationError, setOperationError] = useState< - TalerErrorDetail | undefined - >(); const [showConfirm, setShowConfirm] = useState(false); - async function addBackupProvider() { + async function addBackupProvider(): Promise { if (!url || !name) return; const resp = await api.wallet.call(WalletApiOperation.AddBackupProvider, { @@ -178,8 +173,6 @@ export function useComponentState({ } else { return onComplete(url); } - case "error": - return setOperationError(resp.error); case "ok": return onComplete(url); default: @@ -190,18 +183,18 @@ export function useComponentState({ if (showConfirm && urlState && urlState.status === "ok") { return { status: "confirm-provider", - error: operationError, + error: undefined, onAccept: { - onClick: !tos ? undefined : addBackupProvider, + onClick: !tos ? undefined : pushAlertOnError(addBackupProvider), }, onCancel: { - onClick: onBack, + onClick: pushAlertOnError(onBack), }, provider: urlState.result, tos: { value: tos, button: { - onClick: async () => setTos(!tos), + onClick: pushAlertOnError(async () => setTos(!tos)), }, }, url: url ?? "", @@ -213,25 +206,25 @@ export function useComponentState({ error: undefined, name: { value: name || "", - onInput: async (e) => setName(e), + onInput: pushAlertOnError(async (e) => setName(e)), error: name === undefined ? undefined : !name ? "Can't be empty" : undefined, }, onCancel: { - onClick: onBack, + onClick: pushAlertOnError(onBack), }, onConfirm: { onClick: !urlState || urlState.status !== "ok" || !name ? undefined - : async () => { + : pushAlertOnError(async () => { setShowConfirm(true); - }, + }), }, urlOk: urlState?.status === "ok", url: { value: url || "", - onInput: async (e) => setHost(e), + onInput: pushAlertOnError(async (e) => setHost(e)), error: errorString(urlState), }, }; diff --git a/packages/taler-wallet-webextension/src/wallet/AddBackupProvider/stories.tsx b/packages/taler-wallet-webextension/src/wallet/AddBackupProvider/stories.tsx index 887ad235e..9d1656ec6 100644 --- a/packages/taler-wallet-webextension/src/wallet/AddBackupProvider/stories.tsx +++ b/packages/taler-wallet-webextension/src/wallet/AddBackupProvider/stories.tsx @@ -19,14 +19,14 @@ * @author Sebastian Javier Marchano (sebasjm) */ -import { createExample } from "../../test-utils.js"; +import { tests } from "@gnu-taler/web-util/lib/index.browser"; import { ConfirmProviderView, SelectProviderView } from "./views.js"; export default { title: "add backup provider", }; -export const DemoService = createExample(ConfirmProviderView, { +export const DemoService = tests.createExample(ConfirmProviderView, { url: "https://sync.demo.taler.net/", provider: { annual_fee: "KUDOS:0.1", @@ -40,7 +40,7 @@ export const DemoService = createExample(ConfirmProviderView, { onCancel: {}, }); -export const FreeService = createExample(ConfirmProviderView, { +export const FreeService = tests.createExample(ConfirmProviderView, { url: "https://sync.taler:9667/", provider: { annual_fee: "ARS:0", @@ -54,14 +54,14 @@ export const FreeService = createExample(ConfirmProviderView, { onCancel: {}, }); -export const Initial = createExample(SelectProviderView, { +export const Initial = tests.createExample(SelectProviderView, { url: { value: "" }, name: { value: "" }, onCancel: {}, onConfirm: {}, }); -export const WithValue = createExample(SelectProviderView, { +export const WithValue = tests.createExample(SelectProviderView, { url: { value: "sync.demo.taler.net", }, @@ -72,7 +72,7 @@ export const WithValue = createExample(SelectProviderView, { onConfirm: {}, }); -export const WithConnectionError = createExample(SelectProviderView, { +export const WithConnectionError = tests.createExample(SelectProviderView, { url: { value: "sync.demo.taler.net", error: "Network error", @@ -84,7 +84,7 @@ export const WithConnectionError = createExample(SelectProviderView, { onConfirm: {}, }); -export const WithClientError = createExample(SelectProviderView, { +export const WithClientError = tests.createExample(SelectProviderView, { url: { value: "sync.demo.taler.net", error: "URL may not be right: (404) Not Found", @@ -96,7 +96,7 @@ export const WithClientError = createExample(SelectProviderView, { onConfirm: {}, }); -export const WithServerError = createExample(SelectProviderView, { +export const WithServerError = tests.createExample(SelectProviderView, { url: { value: "sync.demo.taler.net", error: "Try another server: (500) Internal Server Error", diff --git a/packages/taler-wallet-webextension/src/wallet/AddBackupProvider/test.ts b/packages/taler-wallet-webextension/src/wallet/AddBackupProvider/test.ts index 3241a3ab0..a939c9268 100644 --- a/packages/taler-wallet-webextension/src/wallet/AddBackupProvider/test.ts +++ b/packages/taler-wallet-webextension/src/wallet/AddBackupProvider/test.ts @@ -21,7 +21,8 @@ import { expect } from "chai"; import { tests } from "../../../../web-util/src/index.browser.js"; -import { createWalletApiMock, nullFunction } from "../../test-utils.js"; +import { nullFunction } from "../../mui/handlers.js"; +import { createWalletApiMock } from "../../test-utils.js"; import { Props } from "./index.js"; import { useComponentState } from "./state.js"; diff --git a/packages/taler-wallet-webextension/src/wallet/AddNewActionView.stories.tsx b/packages/taler-wallet-webextension/src/wallet/AddNewActionView.stories.tsx index f5db3825d..8c45ae050 100644 --- a/packages/taler-wallet-webextension/src/wallet/AddNewActionView.stories.tsx +++ b/packages/taler-wallet-webextension/src/wallet/AddNewActionView.stories.tsx @@ -19,7 +19,7 @@ * @author Sebastian Javier Marchano (sebasjm) */ -import { createExample } from "../test-utils.js"; +import { tests } from "@gnu-taler/web-util/lib/index.browser"; import { AddNewActionView as TestedComponent } from "./AddNewActionView.js"; export default { @@ -30,4 +30,4 @@ export default { }, }; -export const Initial = createExample(TestedComponent, {}); +export const Initial = tests.createExample(TestedComponent, {}); diff --git a/packages/taler-wallet-webextension/src/wallet/Backup.stories.tsx b/packages/taler-wallet-webextension/src/wallet/Backup.stories.tsx index c3a1ea5d6..8ae1a76ce 100644 --- a/packages/taler-wallet-webextension/src/wallet/Backup.stories.tsx +++ b/packages/taler-wallet-webextension/src/wallet/Backup.stories.tsx @@ -25,14 +25,14 @@ import { BackupView as TestedComponent, ShowRecoveryInfo, } from "./BackupPage.js"; -import { createExample } from "../test-utils.js"; +import { tests } from "@gnu-taler/web-util/lib/index.browser"; import { TalerProtocolTimestamp } from "@gnu-taler/taler-util"; export default { title: "backup", }; -export const LotOfProviders = createExample(TestedComponent, { +export const LotOfProviders = tests.createExample(TestedComponent, { providers: [ { active: true, @@ -164,7 +164,7 @@ export const LotOfProviders = createExample(TestedComponent, { ], }); -export const OneProvider = createExample(TestedComponent, { +export const OneProvider = tests.createExample(TestedComponent, { providers: [ { active: true, @@ -190,10 +190,10 @@ export const OneProvider = createExample(TestedComponent, { ], }); -export const Empty = createExample(TestedComponent, { +export const Empty = tests.createExample(TestedComponent, { providers: [], }); -export const Recovery = createExample(ShowRecoveryInfo, { +export const Recovery = tests.createExample(ShowRecoveryInfo, { info: "taler://recovery/ASLDKJASLKDJASD", }); diff --git a/packages/taler-wallet-webextension/src/wallet/BackupPage.tsx b/packages/taler-wallet-webextension/src/wallet/BackupPage.tsx index 48c9c9cb1..c3abb570b 100644 --- a/packages/taler-wallet-webextension/src/wallet/BackupPage.tsx +++ b/packages/taler-wallet-webextension/src/wallet/BackupPage.tsx @@ -29,7 +29,7 @@ import { } from "date-fns"; import { Fragment, h, VNode } from "preact"; import { useEffect, useState } from "preact/hooks"; -import { AlertView } from "../components/CurrentAlerts.js"; +import { ErrorAlertView } from "../components/CurrentAlerts.js"; import { Loading } from "../components/Loading.js"; import { QR } from "../components/QR.js"; import { @@ -118,8 +118,8 @@ export function BackupPage({ onAddProvider }: Props): VNode { } if (status.hasError) { return ( - { + onClick: pushAlertOnError(async () => { setAddingAccount(true); - }, + }), }, }; } @@ -221,27 +222,27 @@ export function useComponentState({ currency, amount: { value: amount, - onInput: updateAmount, + onInput: pushAlertOnError(updateAmount), error: amountError, }, onAddAccount: { - onClick: async () => { + onClick: pushAlertOnError(async () => { setAddingAccount(true); - }, + }), }, account: { list: accountMap, value: stringifyPaytoUri(currentAccount), - onChange: updateAccountFromList, + onChange: pushAlertOnError(updateAccountFromList), }, currentAccount, cancelHandler: { - onClick: async () => { + onClick: pushAlertOnError(async () => { onCancel(currency); - }, + }), }, depositHandler: { - onClick: unableToDeposit ? undefined : doSend, + onClick: unableToDeposit ? undefined : pushAlertOnError(doSend), }, totalFee, totalToDeposit, @@ -263,7 +264,7 @@ async function getFeeForAmount( }); } -export function labelForAccountType(id: string) { +export function labelForAccountType(id: string): string { switch (id) { case "": return "Choose one"; diff --git a/packages/taler-wallet-webextension/src/wallet/DepositPage/stories.tsx b/packages/taler-wallet-webextension/src/wallet/DepositPage/stories.tsx index b4d1060eb..99f08477f 100644 --- a/packages/taler-wallet-webextension/src/wallet/DepositPage/stories.tsx +++ b/packages/taler-wallet-webextension/src/wallet/DepositPage/stories.tsx @@ -19,26 +19,21 @@ * @author Sebastian Javier Marchano (sebasjm) */ -import { Amounts, DepositGroupFees } from "@gnu-taler/taler-util"; -import { createExample } from "../../test-utils.js"; -import { labelForAccountType } from "./state.js"; +import { Amounts } from "@gnu-taler/taler-util"; +import { tests } from "@gnu-taler/web-util/lib/index.browser"; +import { nullFunction } from "../../mui/handlers.js"; import { ReadyView } from "./views.js"; export default { title: "deposit", }; -// const ac = parsePaytoUri("payto://iban/ES8877998399652238")!; -// const accountMap = createLabelsForBankAccount([ac]); - -export const WithNoAccountForIBAN = createExample(ReadyView, { +export const WithNoAccountForIBAN = tests.createExample(ReadyView, { status: "ready", account: { list: {}, value: "", - onChange: async () => { - null; - }, + onChange: nullFunction, }, currentAccount: { isKnown: true, @@ -49,31 +44,25 @@ export const WithNoAccountForIBAN = createExample(ReadyView, { }, currency: "USD", amount: { - onInput: async () => { - null; - }, + onInput: nullFunction, value: Amounts.parseOrThrow("USD:10"), }, onAddAccount: {}, cancelHandler: {}, depositHandler: { - onClick: async () => { - return; - }, + onClick: nullFunction, }, totalFee: Amounts.zeroOfCurrency("USD"), totalToDeposit: Amounts.parseOrThrow("USD:10"), // onCalculateFee: alwaysReturnFeeToOne, }); -export const WithIBANAccountTypeSelected = createExample(ReadyView, { +export const WithIBANAccountTypeSelected = tests.createExample(ReadyView, { status: "ready", account: { list: { asdlkajsdlk: "asdlkajsdlk", qwerqwer: "qwerqwer" }, value: "asdlkajsdlk", - onChange: async () => { - null; - }, + onChange: nullFunction, }, currentAccount: { isKnown: true, @@ -84,31 +73,25 @@ export const WithIBANAccountTypeSelected = createExample(ReadyView, { }, currency: "USD", amount: { - onInput: async () => { - null; - }, + onInput: nullFunction, value: Amounts.parseOrThrow("USD:10"), }, onAddAccount: {}, cancelHandler: {}, depositHandler: { - onClick: async () => { - return; - }, + onClick: nullFunction, }, totalFee: Amounts.zeroOfCurrency("USD"), totalToDeposit: Amounts.parseOrThrow("USD:10"), // onCalculateFee: alwaysReturnFeeToOne, }); -export const NewBitcoinAccountTypeSelected = createExample(ReadyView, { +export const NewBitcoinAccountTypeSelected = tests.createExample(ReadyView, { status: "ready", account: { list: {}, value: "asdlkajsdlk", - onChange: async () => { - null; - }, + onChange: nullFunction, }, currentAccount: { isKnown: true, @@ -120,16 +103,12 @@ export const NewBitcoinAccountTypeSelected = createExample(ReadyView, { onAddAccount: {}, currency: "USD", amount: { - onInput: async () => { - null; - }, + onInput: nullFunction, value: Amounts.parseOrThrow("USD:10"), }, cancelHandler: {}, depositHandler: { - onClick: async () => { - return; - }, + onClick: nullFunction, }, totalFee: Amounts.zeroOfCurrency("USD"), totalToDeposit: Amounts.parseOrThrow("USD:10"), diff --git a/packages/taler-wallet-webextension/src/wallet/DepositPage/test.ts b/packages/taler-wallet-webextension/src/wallet/DepositPage/test.ts index b222709a7..0054ab5af 100644 --- a/packages/taler-wallet-webextension/src/wallet/DepositPage/test.ts +++ b/packages/taler-wallet-webextension/src/wallet/DepositPage/test.ts @@ -28,7 +28,8 @@ import { 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 { nullFunction } from "../../mui/handlers.js"; +import { createWalletApiMock } from "../../test-utils.js"; import { useComponentState } from "./state.js"; diff --git a/packages/taler-wallet-webextension/src/wallet/DestinationSelection/state.ts b/packages/taler-wallet-webextension/src/wallet/DestinationSelection/state.ts index 1fe324c5a..d5015ae1d 100644 --- a/packages/taler-wallet-webextension/src/wallet/DestinationSelection/state.ts +++ b/packages/taler-wallet-webextension/src/wallet/DestinationSelection/state.ts @@ -17,7 +17,7 @@ import { Amounts } from "@gnu-taler/taler-util"; import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; import { useState } from "preact/hooks"; -import { alertFromError } from "../../context/alert.js"; +import { alertFromError, useAlertContext } from "../../context/alert.js"; import { useBackendContext } from "../../context/backend.js"; import { useTranslationContext } from "../../context/translation.js"; import { useAsyncAsHook } from "../../hooks/useAsyncAsHook.js"; @@ -26,6 +26,7 @@ import { Contact, Props, State } from "./index.js"; export function useComponentState(props: Props): RecursiveState { const api = useBackendContext(); + const { pushAlertOnError } = useAlertContext(); const parsedInitialAmount = !props.amount ? undefined : Amounts.parse(props.amount); @@ -108,26 +109,26 @@ export function useComponentState(props: Props): RecursiveState { error: undefined, previous, selectCurrency: { - onClick: async () => { + onClick: pushAlertOnError(async () => { setAmount(undefined); - }, + }), }, goToBank: { onClick: invalid ? undefined - : async () => { + : pushAlertOnError(async () => { props.goToWalletBankDeposit(currencyAndAmount); - }, + }), }, goToWallet: { onClick: invalid ? undefined - : async () => { + : pushAlertOnError(async () => { props.goToWalletWalletSend(currencyAndAmount); - }, + }), }, amountHandler: { - onInput: async (s) => setAmount(s), + onInput: pushAlertOnError(async (s) => setAmount(s)), value: amount, }, type: props.type, @@ -138,26 +139,26 @@ export function useComponentState(props: Props): RecursiveState { error: undefined, previous, selectCurrency: { - onClick: async () => { + onClick: pushAlertOnError(async () => { setAmount(undefined); - }, + }), }, goToBank: { onClick: invalid ? undefined - : async () => { + : pushAlertOnError(async () => { props.goToWalletManualWithdraw(currencyAndAmount); - }, + }), }, goToWallet: { onClick: invalid ? undefined - : async () => { + : pushAlertOnError(async () => { props.goToWalletWalletInvoice(currencyAndAmount); - }, + }), }, amountHandler: { - onInput: async (s) => setAmount(s), + onInput: pushAlertOnError(async (s) => setAmount(s)), value: amount, }, type: props.type, diff --git a/packages/taler-wallet-webextension/src/wallet/DestinationSelection/stories.tsx b/packages/taler-wallet-webextension/src/wallet/DestinationSelection/stories.tsx index ffec8ba36..111f47776 100644 --- a/packages/taler-wallet-webextension/src/wallet/DestinationSelection/stories.tsx +++ b/packages/taler-wallet-webextension/src/wallet/DestinationSelection/stories.tsx @@ -19,14 +19,14 @@ * @author Sebastian Javier Marchano (sebasjm) */ -import { createExample } from "../../test-utils.js"; +import { tests } from "@gnu-taler/web-util/lib/index.browser"; import { ReadyView, SelectCurrencyView } from "./views.js"; export default { title: "destination", }; -export const GetCash = createExample(ReadyView, { +export const GetCash = tests.createExample(ReadyView, { amountHandler: { value: { currency: "EUR", @@ -40,7 +40,7 @@ export const GetCash = createExample(ReadyView, { selectCurrency: {}, type: "get", }); -export const SendCash = createExample(ReadyView, { +export const SendCash = tests.createExample(ReadyView, { amountHandler: { value: { currency: "EUR", @@ -55,7 +55,7 @@ export const SendCash = createExample(ReadyView, { type: "send", }); -export const SelectCurrency = createExample(SelectCurrencyView, { +export const SelectCurrency = tests.createExample(SelectCurrencyView, { currencies: { "": "Select a currency", USD: "USD", diff --git a/packages/taler-wallet-webextension/src/wallet/DestinationSelection/test.ts b/packages/taler-wallet-webextension/src/wallet/DestinationSelection/test.ts index cc511ce65..b079ef0e8 100644 --- a/packages/taler-wallet-webextension/src/wallet/DestinationSelection/test.ts +++ b/packages/taler-wallet-webextension/src/wallet/DestinationSelection/test.ts @@ -28,7 +28,8 @@ import { 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 { nullFunction } from "../../mui/handlers.js"; +import { createWalletApiMock } from "../../test-utils.js"; import { useComponentState } from "./state.js"; const exchangeArs: ExchangeListItem = { diff --git a/packages/taler-wallet-webextension/src/wallet/DeveloperPage.stories.tsx b/packages/taler-wallet-webextension/src/wallet/DeveloperPage.stories.tsx index d9a5a8fd7..d4ccb60e6 100644 --- a/packages/taler-wallet-webextension/src/wallet/DeveloperPage.stories.tsx +++ b/packages/taler-wallet-webextension/src/wallet/DeveloperPage.stories.tsx @@ -20,7 +20,7 @@ */ import { PendingTaskType } from "@gnu-taler/taler-wallet-core"; -import { createExample } from "../test-utils.js"; +import { tests } from "@gnu-taler/web-util/lib/index.browser"; import { View as TestedComponent } from "./DeveloperPage.js"; export default { @@ -31,7 +31,7 @@ export default { }, }; -export const AllOff = createExample(TestedComponent, { +export const AllOff = tests.createExample(TestedComponent, { onDownloadDatabase: async () => "this is the content of the database", operations: [ { diff --git a/packages/taler-wallet-webextension/src/wallet/EmptyComponentExample/stories.tsx b/packages/taler-wallet-webextension/src/wallet/EmptyComponentExample/stories.tsx index 696e424c4..e157e6e6f 100644 --- a/packages/taler-wallet-webextension/src/wallet/EmptyComponentExample/stories.tsx +++ b/packages/taler-wallet-webextension/src/wallet/EmptyComponentExample/stories.tsx @@ -19,11 +19,11 @@ * @author Sebastian Javier Marchano (sebasjm) */ -import { createExample } from "../../test-utils.js"; +import { tests } from "@gnu-taler/web-util/lib/index.browser"; import { ReadyView } from "./views.js"; export default { title: "example", }; -export const Ready = createExample(ReadyView, {}); +export const Ready = tests.createExample(ReadyView, {}); diff --git a/packages/taler-wallet-webextension/src/wallet/ExchangeAddConfirm.stories.tsx b/packages/taler-wallet-webextension/src/wallet/ExchangeAddConfirm.stories.tsx index 8fbecfc4c..216e50385 100644 --- a/packages/taler-wallet-webextension/src/wallet/ExchangeAddConfirm.stories.tsx +++ b/packages/taler-wallet-webextension/src/wallet/ExchangeAddConfirm.stories.tsx @@ -19,7 +19,7 @@ * @author Sebastian Javier Marchano (sebasjm) */ -import { createExample } from "../test-utils.js"; +import { tests } from "@gnu-taler/web-util/lib/index.browser"; import { ExchangeAddConfirmPage as TestedComponent } from "./ExchangeAddConfirm.js"; export default { @@ -32,14 +32,14 @@ export default { }, }; -export const TermsNotFound = createExample(TestedComponent, { +export const TermsNotFound = tests.createExample(TestedComponent, { url: "https://exchange.demo.taler.net/", }); -export const NewTerms = createExample(TestedComponent, { +export const NewTerms = tests.createExample(TestedComponent, { url: "https://exchange.demo.taler.net/", }); -export const TermsChanged = createExample(TestedComponent, { +export const TermsChanged = tests.createExample(TestedComponent, { url: "https://exchange.demo.taler.net/", }); diff --git a/packages/taler-wallet-webextension/src/wallet/ExchangeAddSetUrl.stories.tsx b/packages/taler-wallet-webextension/src/wallet/ExchangeAddSetUrl.stories.tsx index cd86ad8c6..914ca8ae4 100644 --- a/packages/taler-wallet-webextension/src/wallet/ExchangeAddSetUrl.stories.tsx +++ b/packages/taler-wallet-webextension/src/wallet/ExchangeAddSetUrl.stories.tsx @@ -19,7 +19,7 @@ * @author Sebastian Javier Marchano (sebasjm) */ -import { createExample } from "../test-utils.js"; +import { tests } from "@gnu-taler/web-util/lib/index.browser"; import { queryToSlashKeys } from "../utils/index.js"; import { ExchangeSetUrlPage as TestedComponent } from "./ExchangeSetUrl.js"; @@ -27,17 +27,17 @@ export default { title: "exchange add set url", }; -export const ExpectedUSD = createExample(TestedComponent, { +export const ExpectedUSD = tests.createExample(TestedComponent, { expectedCurrency: "USD", onVerify: queryToSlashKeys, }); -export const ExpectedKUDOS = createExample(TestedComponent, { +export const ExpectedKUDOS = tests.createExample(TestedComponent, { expectedCurrency: "KUDOS", onVerify: queryToSlashKeys, }); -export const InitialState = createExample(TestedComponent, { +export const InitialState = tests.createExample(TestedComponent, { onVerify: queryToSlashKeys, }); @@ -55,7 +55,7 @@ const knownExchanges = [ }, ]; -export const WithDemoAsKnownExchange = createExample(TestedComponent, { +export const WithDemoAsKnownExchange = tests.createExample(TestedComponent, { onVerify: async (url) => { const found = knownExchanges.findIndex((e) => e.exchangeBaseUrl === url) !== -1; diff --git a/packages/taler-wallet-webextension/src/wallet/ExchangeSelection/state.ts b/packages/taler-wallet-webextension/src/wallet/ExchangeSelection/state.ts index cfb32cbbb..7ad11e67c 100644 --- a/packages/taler-wallet-webextension/src/wallet/ExchangeSelection/state.ts +++ b/packages/taler-wallet-webextension/src/wallet/ExchangeSelection/state.ts @@ -20,7 +20,7 @@ import { WalletApiOperation, } from "@gnu-taler/taler-wallet-core"; import { useState } from "preact/hooks"; -import { alertFromError } from "../../context/alert.js"; +import { alertFromError, useAlertContext } from "../../context/alert.js"; import { useBackendContext } from "../../context/backend.js"; import { useTranslationContext } from "../../context/translation.js"; import { useAsyncAsHook } from "../../hooks/useAsyncAsHook.js"; @@ -33,6 +33,7 @@ export function useComponentState({ currentExchange, }: Props): State { const api = useBackendContext(); + const { pushAlertOnError } = useAlertContext(); const { i18n } = useTranslationContext(); const initialValue = exchanges.findIndex( (e) => e.exchangeBaseUrl === currentExchange, @@ -115,7 +116,7 @@ export function useComponentState({ status: "showing-privacy", error: undefined, onClose: { - onClick: async () => setShowingPrivacy(undefined), + onClick: pushAlertOnError(async () => setShowingPrivacy(undefined)), }, exchangeUrl: showingPrivacy, }; @@ -125,7 +126,7 @@ export function useComponentState({ status: "showing-tos", error: undefined, onClose: { - onClick: async () => setShowingTos(undefined), + onClick: pushAlertOnError(async () => setShowingTos(undefined)), }, exchangeUrl: showingTos, }; @@ -138,24 +139,24 @@ export function useComponentState({ exchanges: { list: exchangeMap, value: value, - onChange: async (v) => { + onChange: pushAlertOnError(async (v) => { setValue(v); - }, + }), }, error: undefined, onClose: { - onClick: onCancel, + onClick: pushAlertOnError(onCancel), }, selected, onShowPrivacy: { - onClick: async () => { + onClick: pushAlertOnError(async () => { setShowingPrivacy(selected.exchangeBaseUrl); - }, + }), }, onShowTerms: { - onClick: async () => { + onClick: pushAlertOnError(async () => { setShowingTos(selected.exchangeBaseUrl); - }, + }), }, }; } @@ -215,30 +216,30 @@ export function useComponentState({ exchanges: { list: exchangeMap, value: value, - onChange: async (v) => { + onChange: pushAlertOnError(async (v) => { setValue(v); - }, + }), }, error: undefined, onReset: { - onClick: async () => { + onClick: pushAlertOnError(async () => { setValue(String(initialValue)); - }, + }), }, onSelect: { - onClick: async () => { + onClick: pushAlertOnError(async () => { onSelection(selected.exchangeBaseUrl); - }, + }), }, onShowPrivacy: { - onClick: async () => { + onClick: pushAlertOnError(async () => { setShowingPrivacy(selected.exchangeBaseUrl); - }, + }), }, onShowTerms: { - onClick: async () => { + onClick: pushAlertOnError(async () => { setShowingTos(selected.exchangeBaseUrl); - }, + }), }, selected, coinOperationTimeline, diff --git a/packages/taler-wallet-webextension/src/wallet/ExchangeSelection/stories.tsx b/packages/taler-wallet-webextension/src/wallet/ExchangeSelection/stories.tsx index 05765b50a..a65f85c6a 100644 --- a/packages/taler-wallet-webextension/src/wallet/ExchangeSelection/stories.tsx +++ b/packages/taler-wallet-webextension/src/wallet/ExchangeSelection/stories.tsx @@ -19,14 +19,14 @@ * @author Sebastian Javier Marchano (sebasjm) */ -import { createExample } from "../../test-utils.js"; +import { tests } from "@gnu-taler/web-util/lib/index.browser"; import { ComparingView, ReadyView } from "./views.js"; export default { title: "select exchange", }; -export const Bitcoin1 = createExample(ReadyView, { +export const Bitcoin1 = tests.createExample(ReadyView, { exchanges: { list: { "0": "https://exchange.taler.ar" }, value: "0", @@ -43,7 +43,7 @@ export const Bitcoin1 = createExample(ReadyView, { onShowTerms: {}, onClose: {}, }); -export const Bitcoin2 = createExample(ReadyView, { +export const Bitcoin2 = tests.createExample(ReadyView, { exchanges: { list: { "https://exchange.taler.ar": "https://exchange.taler.ar", @@ -64,7 +64,7 @@ export const Bitcoin2 = createExample(ReadyView, { onClose: {}, }); -export const Kudos1 = createExample(ReadyView, { +export const Kudos1 = tests.createExample(ReadyView, { exchanges: { list: { "https://exchange-kudos.taler.ar": "https://exchange-kudos.taler.ar", @@ -83,7 +83,7 @@ export const Kudos1 = createExample(ReadyView, { onShowTerms: {}, onClose: {}, }); -export const Kudos2 = createExample(ReadyView, { +export const Kudos2 = tests.createExample(ReadyView, { exchanges: { list: { "https://exchange-kudos.taler.ar": "https://exchange-kudos.taler.ar", @@ -103,7 +103,7 @@ export const Kudos2 = createExample(ReadyView, { onShowTerms: {}, onClose: {}, }); -export const ComparingBitcoin = createExample(ComparingView, { +export const ComparingBitcoin = tests.createExample(ComparingView, { exchanges: { list: { "http://exchange": "http://exchange" }, value: "http://exchange", @@ -131,7 +131,7 @@ export const ComparingBitcoin = createExample(ComparingView, { missingWireTYpe: [], wireFeeTimeline: {}, }); -export const ComparingKudos = createExample(ComparingView, { +export const ComparingKudos = tests.createExample(ComparingView, { exchanges: { list: { "http://exchange": "http://exchange" }, value: "http://exchange", diff --git a/packages/taler-wallet-webextension/src/wallet/History.stories.tsx b/packages/taler-wallet-webextension/src/wallet/History.stories.tsx index 1674ac135..13f4c8230 100644 --- a/packages/taler-wallet-webextension/src/wallet/History.stories.tsx +++ b/packages/taler-wallet-webextension/src/wallet/History.stories.tsx @@ -37,7 +37,7 @@ import { WithdrawalType, } from "@gnu-taler/taler-util"; import { HistoryView as TestedComponent } from "./History.js"; -import { createExample } from "../test-utils.js"; +import { tests } from "@gnu-taler/web-util/lib/index.browser"; export default { title: "balance", @@ -160,25 +160,28 @@ const exampleData = { } as TransactionPeerPullDebit, }; -export const NoBalance = createExample(TestedComponent, { +export const NoBalance = tests.createExample(TestedComponent, { transactions: [], balances: [], }); -export const SomeBalanceWithNoTransactions = createExample(TestedComponent, { - transactions: [], - balances: [ - { - available: "TESTKUDOS:10", - pendingIncoming: "TESTKUDOS:0", - pendingOutgoing: "TESTKUDOS:0", - hasPendingTransactions: false, - requiresUserInput: false, - }, - ], -}); +export const SomeBalanceWithNoTransactions = tests.createExample( + TestedComponent, + { + transactions: [], + balances: [ + { + available: "TESTKUDOS:10", + pendingIncoming: "TESTKUDOS:0", + pendingOutgoing: "TESTKUDOS:0", + hasPendingTransactions: false, + requiresUserInput: false, + }, + ], + }, +); -export const OneSimpleTransaction = createExample(TestedComponent, { +export const OneSimpleTransaction = tests.createExample(TestedComponent, { transactions: [exampleData.withdraw], balances: [ { @@ -191,20 +194,23 @@ export const OneSimpleTransaction = createExample(TestedComponent, { ], }); -export const TwoTransactionsAndZeroBalance = createExample(TestedComponent, { - transactions: [exampleData.withdraw, exampleData.deposit], - balances: [ - { - available: "USD:0", - pendingIncoming: "USD:0", - pendingOutgoing: "USD:0", - hasPendingTransactions: false, - requiresUserInput: false, - }, - ], -}); +export const TwoTransactionsAndZeroBalance = tests.createExample( + TestedComponent, + { + transactions: [exampleData.withdraw, exampleData.deposit], + balances: [ + { + available: "USD:0", + pendingIncoming: "USD:0", + pendingOutgoing: "USD:0", + hasPendingTransactions: false, + requiresUserInput: false, + }, + ], + }, +); -export const OneTransactionPending = createExample(TestedComponent, { +export const OneTransactionPending = tests.createExample(TestedComponent, { transactions: [ { ...exampleData.withdraw, @@ -222,7 +228,7 @@ export const OneTransactionPending = createExample(TestedComponent, { ], }); -export const SomeTransactions = createExample(TestedComponent, { +export const SomeTransactions = tests.createExample(TestedComponent, { transactions: [ exampleData.withdraw, exampleData.payment, @@ -251,7 +257,7 @@ export const SomeTransactions = createExample(TestedComponent, { ], }); -export const SomeTransactionsWithTwoCurrencies = createExample( +export const SomeTransactionsWithTwoCurrencies = tests.createExample( TestedComponent, { transactions: [ @@ -283,7 +289,7 @@ export const SomeTransactionsWithTwoCurrencies = createExample( }, ); -export const FiveOfficialCurrencies = createExample(TestedComponent, { +export const FiveOfficialCurrencies = tests.createExample(TestedComponent, { transactions: [exampleData.withdraw], balances: [ { @@ -324,7 +330,7 @@ export const FiveOfficialCurrencies = createExample(TestedComponent, { ], }); -export const FiveOfficialCurrenciesWithHighValue = createExample( +export const FiveOfficialCurrenciesWithHighValue = tests.createExample( TestedComponent, { transactions: [exampleData.withdraw], @@ -368,7 +374,7 @@ export const FiveOfficialCurrenciesWithHighValue = createExample( }, ); -export const PeerToPeer = createExample(TestedComponent, { +export const PeerToPeer = tests.createExample(TestedComponent, { transactions: [ exampleData.pull_credit, exampleData.pull_debit, diff --git a/packages/taler-wallet-webextension/src/wallet/History.tsx b/packages/taler-wallet-webextension/src/wallet/History.tsx index 143d3adbb..1d51f835a 100644 --- a/packages/taler-wallet-webextension/src/wallet/History.tsx +++ b/packages/taler-wallet-webextension/src/wallet/History.tsx @@ -23,7 +23,7 @@ import { import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; import { Fragment, h, VNode } from "preact"; import { useEffect, useState } from "preact/hooks"; -import { AlertView } from "../components/CurrentAlerts.js"; +import { ErrorAlertView } from "../components/CurrentAlerts.js"; import { Loading } from "../components/Loading.js"; import { CenteredBoldText, @@ -33,7 +33,7 @@ import { } from "../components/styled/index.js"; import { Time } from "../components/Time.js"; import { TransactionItem } from "../components/TransactionItem.js"; -import { alertFromError } from "../context/alert.js"; +import { alertFromError, useAlertContext } from "../context/alert.js"; import { useBackendContext } from "../context/backend.js"; import { useTranslationContext } from "../context/translation.js"; import { useAsyncAsHook } from "../hooks/useAsyncAsHook.js"; @@ -72,8 +72,8 @@ export function HistoryPage({ if (state.hasError) { return ( - b.available.split(":")[0]); + const { pushAlertOnError } = useAlertContext(); const defaultCurrencyIndex = currencies.findIndex( (c) => c === defaultCurrency, @@ -145,7 +146,7 @@ export function HistoryView({ return ( ); diff --git a/packages/taler-wallet-webextension/src/wallet/ManageAccount/state.ts b/packages/taler-wallet-webextension/src/wallet/ManageAccount/state.ts index 176a8d100..f7383d483 100644 --- a/packages/taler-wallet-webextension/src/wallet/ManageAccount/state.ts +++ b/packages/taler-wallet-webextension/src/wallet/ManageAccount/state.ts @@ -21,7 +21,7 @@ import { } from "@gnu-taler/taler-util"; import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; import { useState } from "preact/hooks"; -import { alertFromError } from "../../context/alert.js"; +import { alertFromError, useAlertContext } from "../../context/alert.js"; import { useBackendContext } from "../../context/backend.js"; import { useTranslationContext } from "../../context/translation.js"; import { useAsyncAsHook } from "../../hooks/useAsyncAsHook.js"; @@ -33,6 +33,7 @@ export function useComponentState({ onCancel, }: Props): State { const api = useBackendContext(); + const { pushAlertOnError } = useAlertContext(); const { i18n } = useTranslationContext(); const hook = useAsyncAsHook(() => api.wallet.call(WalletApiOperation.ListKnownBankAccounts, { currency }), @@ -109,30 +110,30 @@ export function useComponentState({ accountType: { list: accountType, value: type, - onChange: async (v) => { + onChange: pushAlertOnError(async (v) => { setType(v); - }, + }), }, alias: { value: alias, - onInput: async (v) => { + onInput: pushAlertOnError(async (v) => { setAlias(v); - }, + }), }, uri: { value: payto, error: paytoUriError, - onInput: async (v) => { + onInput: pushAlertOnError(async (v) => { setPayto(v); - }, + }), }, accountByType, deleteAccount, onAccountAdded: { - onClick: unableToAdd ? undefined : addAccount, + onClick: unableToAdd ? undefined : pushAlertOnError(addAccount), }, onCancel: { - onClick: async () => onCancel(), + onClick: pushAlertOnError(async () => onCancel()), }, }; } diff --git a/packages/taler-wallet-webextension/src/wallet/ManageAccount/stories.tsx b/packages/taler-wallet-webextension/src/wallet/ManageAccount/stories.tsx index ca6db8be9..e20d4e0e8 100644 --- a/packages/taler-wallet-webextension/src/wallet/ManageAccount/stories.tsx +++ b/packages/taler-wallet-webextension/src/wallet/ManageAccount/stories.tsx @@ -19,18 +19,15 @@ * @author Sebastian Javier Marchano (sebasjm) */ -import { createExample } from "../../test-utils.js"; +import { tests } from "@gnu-taler/web-util/lib/index.browser"; +import { nullFunction } from "../../mui/handlers.js"; import { ReadyView } from "./views.js"; export default { title: "manage account", }; -const nullFunction = async () => { - null; -}; - -export const JustTwoBitcoinAccounts = createExample(ReadyView, { +export const JustTwoBitcoinAccounts = tests.createExample(ReadyView, { status: "ready", currency: "ARS", accountType: { @@ -84,7 +81,7 @@ export const JustTwoBitcoinAccounts = createExample(ReadyView, { onCancel: {}, }); -export const WithAllTypeOfAccounts = createExample(ReadyView, { +export const WithAllTypeOfAccounts = tests.createExample(ReadyView, { status: "ready", currency: "ARS", accountType: { @@ -165,7 +162,7 @@ export const WithAllTypeOfAccounts = createExample(ReadyView, { onCancel: {}, }); -export const AddingIbanAccount = createExample(ReadyView, { +export const AddingIbanAccount = tests.createExample(ReadyView, { status: "ready", currency: "ARS", accountType: { diff --git a/packages/taler-wallet-webextension/src/wallet/Notifications/stories.tsx b/packages/taler-wallet-webextension/src/wallet/Notifications/stories.tsx index c4da99909..bce4a8f41 100644 --- a/packages/taler-wallet-webextension/src/wallet/Notifications/stories.tsx +++ b/packages/taler-wallet-webextension/src/wallet/Notifications/stories.tsx @@ -20,14 +20,14 @@ */ import { AbsoluteTime, AttentionType } from "@gnu-taler/taler-util"; -import { createExample } from "../../test-utils.js"; +import { tests } from "@gnu-taler/web-util/lib/index.browser"; import { ReadyView } from "./views.js"; export default { title: "notifications", }; -export const Ready = createExample(ReadyView, { +export const Ready = tests.createExample(ReadyView, { list: [ { when: AbsoluteTime.now(), diff --git a/packages/taler-wallet-webextension/src/wallet/ProviderAddConfirmProvider.stories.tsx b/packages/taler-wallet-webextension/src/wallet/ProviderAddConfirmProvider.stories.tsx index 9ca397302..55f80a397 100644 --- a/packages/taler-wallet-webextension/src/wallet/ProviderAddConfirmProvider.stories.tsx +++ b/packages/taler-wallet-webextension/src/wallet/ProviderAddConfirmProvider.stories.tsx @@ -19,7 +19,7 @@ * @author Sebastian Javier Marchano (sebasjm) */ -import { createExample } from "../test-utils.js"; +import { tests } from "@gnu-taler/web-util/lib/index.browser"; import { ConfirmProviderView as TestedComponent } from "./ProviderAddPage.js"; export default { @@ -32,7 +32,7 @@ export default { }, }; -export const DemoService = createExample(TestedComponent, { +export const DemoService = tests.createExample(TestedComponent, { url: "https://sync.demo.taler.net/", provider: { annual_fee: "KUDOS:0.1", @@ -41,7 +41,7 @@ export const DemoService = createExample(TestedComponent, { }, }); -export const FreeService = createExample(TestedComponent, { +export const FreeService = tests.createExample(TestedComponent, { url: "https://sync.taler:9667/", provider: { annual_fee: "ARS:0", diff --git a/packages/taler-wallet-webextension/src/wallet/ProviderAddSetUrl.stories.tsx b/packages/taler-wallet-webextension/src/wallet/ProviderAddSetUrl.stories.tsx index a5528c36b..b4f2533bd 100644 --- a/packages/taler-wallet-webextension/src/wallet/ProviderAddSetUrl.stories.tsx +++ b/packages/taler-wallet-webextension/src/wallet/ProviderAddSetUrl.stories.tsx @@ -19,7 +19,7 @@ * @author Sebastian Javier Marchano (sebasjm) */ -import { createExample } from "../test-utils.js"; +import { tests } from "@gnu-taler/web-util/lib/index.browser"; import { SetUrlView as TestedComponent } from "./ProviderAddPage.js"; export default { @@ -32,20 +32,20 @@ export default { }, }; -export const Initial = createExample(TestedComponent, {}); +export const Initial = tests.createExample(TestedComponent, {}); -export const WithValue = createExample(TestedComponent, { +export const WithValue = tests.createExample(TestedComponent, { initialValue: "sync.demo.taler.net", }); -export const WithConnectionError = createExample(TestedComponent, { +export const WithConnectionError = tests.createExample(TestedComponent, { withError: "Network error", }); -export const WithClientError = createExample(TestedComponent, { +export const WithClientError = tests.createExample(TestedComponent, { withError: "URL may not be right: (404) Not Found", }); -export const WithServerError = createExample(TestedComponent, { +export const WithServerError = tests.createExample(TestedComponent, { withError: "Try another server: (500) Internal Server Error", }); diff --git a/packages/taler-wallet-webextension/src/wallet/ProviderDetail.stories.tsx b/packages/taler-wallet-webextension/src/wallet/ProviderDetail.stories.tsx index 98c68e6bd..08f26438f 100644 --- a/packages/taler-wallet-webextension/src/wallet/ProviderDetail.stories.tsx +++ b/packages/taler-wallet-webextension/src/wallet/ProviderDetail.stories.tsx @@ -21,7 +21,7 @@ import { TalerProtocolTimestamp } from "@gnu-taler/taler-util"; import { ProviderPaymentType } from "@gnu-taler/taler-wallet-core"; -import { createExample } from "../test-utils.js"; +import { tests } from "@gnu-taler/web-util/lib/index.browser"; import { ProviderView as TestedComponent } from "./ProviderDetailPage.js"; export default { @@ -34,7 +34,7 @@ export default { }, }; -export const Active = createExample(TestedComponent, { +export const Active = tests.createExample(TestedComponent, { info: { active: true, name: "sync.demo", @@ -58,7 +58,7 @@ export const Active = createExample(TestedComponent, { }, }); -export const ActiveErrorSync = createExample(TestedComponent, { +export const ActiveErrorSync = tests.createExample(TestedComponent, { info: { active: true, name: "sync.demo", @@ -79,6 +79,7 @@ export const ActiveErrorSync = createExample(TestedComponent, { lastError: { code: 2002, details: "details", + when: new Date().toISOString(), hint: "error hint from the server", message: "message", }, @@ -90,34 +91,37 @@ export const ActiveErrorSync = createExample(TestedComponent, { }, }); -export const ActiveBackupProblemUnreadable = createExample(TestedComponent, { - info: { - active: true, - name: "sync.demo", - syncProviderBaseUrl: "http://sync.taler:9967/", - lastSuccessfulBackupTimestamp: - TalerProtocolTimestamp.fromSeconds(1625063925), - paymentProposalIds: [ - "43Q5WWRJPNS4SE9YKS54H9THDS94089EDGXW9EHBPN6E7M184XEG", - ], - paymentStatus: { - type: ProviderPaymentType.Paid, - paidUntil: { - t_ms: 1656599921000, +export const ActiveBackupProblemUnreadable = tests.createExample( + TestedComponent, + { + info: { + active: true, + name: "sync.demo", + syncProviderBaseUrl: "http://sync.taler:9967/", + lastSuccessfulBackupTimestamp: + TalerProtocolTimestamp.fromSeconds(1625063925), + paymentProposalIds: [ + "43Q5WWRJPNS4SE9YKS54H9THDS94089EDGXW9EHBPN6E7M184XEG", + ], + paymentStatus: { + type: ProviderPaymentType.Paid, + paidUntil: { + t_ms: 1656599921000, + }, + }, + backupProblem: { + type: "backup-unreadable", + }, + terms: { + annualFee: "EUR:1", + storageLimitInMegabytes: 16, + supportedProtocolVersion: "0.0", }, - }, - backupProblem: { - type: "backup-unreadable", - }, - terms: { - annualFee: "EUR:1", - storageLimitInMegabytes: 16, - supportedProtocolVersion: "0.0", }, }, -}); +); -export const ActiveBackupProblemDevice = createExample(TestedComponent, { +export const ActiveBackupProblemDevice = tests.createExample(TestedComponent, { info: { active: true, name: "sync.demo", @@ -149,7 +153,7 @@ export const ActiveBackupProblemDevice = createExample(TestedComponent, { }, }); -export const InactiveUnpaid = createExample(TestedComponent, { +export const InactiveUnpaid = tests.createExample(TestedComponent, { info: { active: false, name: "sync.demo", @@ -166,25 +170,28 @@ export const InactiveUnpaid = createExample(TestedComponent, { }, }); -export const InactiveInsufficientBalance = createExample(TestedComponent, { - info: { - active: false, - name: "sync.demo", - syncProviderBaseUrl: "http://sync.demo.taler.net/", - paymentProposalIds: [], - paymentStatus: { - type: ProviderPaymentType.InsufficientBalance, - amount: "EUR:123", - }, - terms: { - annualFee: "EUR:0.1", - storageLimitInMegabytes: 16, - supportedProtocolVersion: "0.0", +export const InactiveInsufficientBalance = tests.createExample( + TestedComponent, + { + info: { + active: false, + name: "sync.demo", + syncProviderBaseUrl: "http://sync.demo.taler.net/", + paymentProposalIds: [], + paymentStatus: { + type: ProviderPaymentType.InsufficientBalance, + amount: "EUR:123", + }, + terms: { + annualFee: "EUR:0.1", + storageLimitInMegabytes: 16, + supportedProtocolVersion: "0.0", + }, }, }, -}); +); -export const InactivePending = createExample(TestedComponent, { +export const InactivePending = tests.createExample(TestedComponent, { info: { active: false, name: "sync.demo", @@ -202,7 +209,7 @@ export const InactivePending = createExample(TestedComponent, { }, }); -export const ActiveTermsChanged = createExample(TestedComponent, { +export const ActiveTermsChanged = tests.createExample(TestedComponent, { info: { active: true, name: "sync.demo", diff --git a/packages/taler-wallet-webextension/src/wallet/ProviderDetailPage.tsx b/packages/taler-wallet-webextension/src/wallet/ProviderDetailPage.tsx index 9b72c0fae..789465a87 100644 --- a/packages/taler-wallet-webextension/src/wallet/ProviderDetailPage.tsx +++ b/packages/taler-wallet-webextension/src/wallet/ProviderDetailPage.tsx @@ -23,7 +23,7 @@ import { WalletApiOperation, } from "@gnu-taler/taler-wallet-core"; import { Fragment, h, VNode } from "preact"; -import { AlertView } from "../components/CurrentAlerts.js"; +import { ErrorAlertView } from "../components/CurrentAlerts.js"; import { ErrorMessage } from "../components/ErrorMessage.js"; import { Loading } from "../components/Loading.js"; import { PaymentStatus, SmallLightText } from "../components/styled/index.js"; @@ -66,8 +66,8 @@ export function ProviderDetailPage({ } if (state.hasError) { return ( - Promise.resolve(), - knownExchanges: [ - { - currency: "USD", - exchangeBaseUrl: "http://exchange1.taler", - tos: { - currentVersion: "1", - acceptedVersion: "1", - content: "content of tos", - contentType: "text/plain", - }, - paytoUris: ["payto://x-taler-bank/bank.rpi.sebasjm.com/exchangeminator"], - }, - { - currency: "USD", - exchangeBaseUrl: "http://exchange2.taler", - tos: { - currentVersion: "2", - acceptedVersion: "1", - content: "content of tos", - contentType: "text/plain", +export const WithExchangeInDifferentState = tests.createExample( + TestedComponent, + { + deviceName: "this-is-the-device-name", + devModeToggle: { value: false, button: {} }, + autoOpenToggle: { value: false, button: {} }, + clipboardToggle: { value: false, button: {} }, + setDeviceName: () => Promise.resolve(), + knownExchanges: [ + { + currency: "USD", + exchangeBaseUrl: "http://exchange1.taler", + tos: { + currentVersion: "1", + acceptedVersion: "1", + content: "content of tos", + contentType: "text/plain", + }, + paytoUris: [ + "payto://x-taler-bank/bank.rpi.sebasjm.com/exchangeminator", + ], }, - paytoUris: ["payto://x-taler-bank/bank.rpi.sebasjm.com/exchangeminator"], - } as any, //TODO: complete with auditors, wireInfo and denominations - { - currency: "USD", - exchangeBaseUrl: "http://exchange3.taler", - tos: { - currentVersion: "1", - content: "content of tos", - contentType: "text/plain", + { + currency: "USD", + exchangeBaseUrl: "http://exchange2.taler", + tos: { + currentVersion: "2", + acceptedVersion: "1", + content: "content of tos", + contentType: "text/plain", + }, + paytoUris: [ + "payto://x-taler-bank/bank.rpi.sebasjm.com/exchangeminator", + ], + } as any, //TODO: complete with auditors, wireInfo and denominations + { + currency: "USD", + exchangeBaseUrl: "http://exchange3.taler", + tos: { + currentVersion: "1", + content: "content of tos", + contentType: "text/plain", + }, + paytoUris: [ + "payto://x-taler-bank/bank.rpi.sebasjm.com/exchangeminator", + ], }, - paytoUris: ["payto://x-taler-bank/bank.rpi.sebasjm.com/exchangeminator"], - }, - ], - ...version, -}); + ], + ...version, + }, +); diff --git a/packages/taler-wallet-webextension/src/wallet/Settings.tsx b/packages/taler-wallet-webextension/src/wallet/Settings.tsx index ed1bc838a..d65f3a095 100644 --- a/packages/taler-wallet-webextension/src/wallet/Settings.tsx +++ b/packages/taler-wallet-webextension/src/wallet/Settings.tsx @@ -22,7 +22,6 @@ import { import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; import { Fragment, h, VNode } from "preact"; import { Checkbox } from "../components/Checkbox.js"; -import { ErrorTalerOperation } from "../components/ErrorTalerOperation.js"; import { JustInDevMode } from "../components/JustInDevMode.js"; import { Part } from "../components/Part.js"; import { SelectList } from "../components/SelectList.js"; @@ -34,6 +33,7 @@ import { SuccessText, WarningText, } from "../components/styled/index.js"; +import { useAlertContext } from "../context/alert.js"; import { useBackendContext } from "../context/backend.js"; import { useDevContext } from "../context/devContext.js"; import { useTranslationContext } from "../context/translation.js"; @@ -50,8 +50,9 @@ const GIT_HASH = typeof __GIT_HASH__ !== "undefined" ? __GIT_HASH__ : undefined; export function SettingsPage(): VNode { const autoOpenToggle = useAutoOpenPermissions(); const clipboardToggle = useClipboardPermissions(); - const { devModeToggle } = useDevContext(); + const { devMode, toggle } = useDevContext(); const { name, update } = useBackupDeviceName(); + const { pushAlertOnError } = useAlertContext(); const webex = platform.getWalletWebExVersion(); const api = useBackendContext(); @@ -72,7 +73,12 @@ export function SettingsPage(): VNode { setDeviceName={update} autoOpenToggle={autoOpenToggle} clipboardToggle={clipboardToggle} - devModeToggle={devModeToggle} + devModeToggle={{ + value: devMode, + button: { + onClick: pushAlertOnError(toggle), + }, + }} webexVersion={{ version: webex.version, hash: GIT_HASH, @@ -109,18 +115,6 @@ export function SettingsView({ return (
- {autoOpenToggle.button.error && ( - - )} - {/* {clipboardToggle.button.error && ( - - )} */} Navigator diff --git a/packages/taler-wallet-webextension/src/wallet/Transaction.stories.tsx b/packages/taler-wallet-webextension/src/wallet/Transaction.stories.tsx index 868d3b0e6..bc941c9af 100644 --- a/packages/taler-wallet-webextension/src/wallet/Transaction.stories.tsx +++ b/packages/taler-wallet-webextension/src/wallet/Transaction.stories.tsx @@ -39,11 +39,13 @@ import { WithdrawalType, } from "@gnu-taler/taler-util"; import { DevContextProviderForTesting } from "../context/devContext.js"; -import { - createExample, - createExampleWithCustomContext as createExampleInCustomContext, -} from "../test-utils.js"; +// import { +// createExample, +// createExampleWithCustomContext as createExampleInCustomContext, +// } from "../test-utils.js"; import { TransactionView as TestedComponent } from "./Transaction.js"; +import { tests } from "@gnu-taler/web-util/lib/index.browser"; +import beer from "../../static-dev/beer.png"; export default { title: "transaction details", @@ -214,24 +216,28 @@ const transactionError = { hint: "The payment is too late, the offer has expired.", }, }, + when: new Date().toISOString(), hint: "Error: WALLET_UNEXPECTED_REQUEST_ERROR", message: "Unexpected error code in response", }; -export const Withdraw = createExample(TestedComponent, { +export const Withdraw = tests.createExample(TestedComponent, { transaction: exampleData.withdraw, }); -export const WithdrawFiveMinutesAgo = createExample(TestedComponent, () => ({ - transaction: { - ...exampleData.withdraw, - timestamp: TalerProtocolTimestamp.fromSeconds( - new Date().getTime() / 1000 - 60 * 5, - ), - }, -})); +export const WithdrawFiveMinutesAgo = tests.createExample( + TestedComponent, + () => ({ + transaction: { + ...exampleData.withdraw, + timestamp: TalerProtocolTimestamp.fromSeconds( + new Date().getTime() / 1000 - 60 * 5, + ), + }, + }), +); -export const WithdrawFiveMinutesAgoAndPending = createExample( +export const WithdrawFiveMinutesAgoAndPending = tests.createExample( TestedComponent, () => ({ transaction: { @@ -244,38 +250,41 @@ export const WithdrawFiveMinutesAgoAndPending = createExample( }), ); -export const WithdrawError = createExample(TestedComponent, { +export const WithdrawError = tests.createExample(TestedComponent, { transaction: { ...exampleData.withdraw, error: transactionError, }, }); -export const WithdrawErrorInDevMode = createExampleInCustomContext( +// export const WithdrawErrorInDevMode = tests.createExampleInCustomContext( +// TestedComponent, +// { +// transaction: { +// ...exampleData.withdraw, +// error: transactionError, +// }, +// }, +// DevContextProviderForTesting, +// { value: true }, +// ); + +export const WithdrawPendingManual = tests.createExample( TestedComponent, - { + () => ({ transaction: { ...exampleData.withdraw, - error: transactionError, + withdrawalDetails: { + type: WithdrawalType.ManualTransfer, + exchangePaytoUris: ["payto://iban/ES8877998399652238"], + reservePub: "A05AJGMFNSK4Q62NXR2FKNDB1J4EXTYQTE7VA4M9GZQ4TR06YBNG", + } as WithdrawalDetails, + pending: true, }, - }, - DevContextProviderForTesting, - { value: true }, + }), ); -export const WithdrawPendingManual = createExample(TestedComponent, () => ({ - transaction: { - ...exampleData.withdraw, - withdrawalDetails: { - type: WithdrawalType.ManualTransfer, - exchangePaytoUris: ["payto://iban/ES8877998399652238"], - reservePub: "A05AJGMFNSK4Q62NXR2FKNDB1J4EXTYQTE7VA4M9GZQ4TR06YBNG", - } as WithdrawalDetails, - pending: true, - }, -})); - -export const WithdrawPendingTalerBankUnconfirmed = createExample( +export const WithdrawPendingTalerBankUnconfirmed = tests.createExample( TestedComponent, { transaction: { @@ -291,7 +300,7 @@ export const WithdrawPendingTalerBankUnconfirmed = createExample( }, ); -export const WithdrawPendingTalerBankConfirmed = createExample( +export const WithdrawPendingTalerBankConfirmed = tests.createExample( TestedComponent, { transaction: { @@ -306,18 +315,18 @@ export const WithdrawPendingTalerBankConfirmed = createExample( }, ); -export const Payment = createExample(TestedComponent, { +export const Payment = tests.createExample(TestedComponent, { transaction: exampleData.payment, }); -export const PaymentError = createExample(TestedComponent, { +export const PaymentError = tests.createExample(TestedComponent, { transaction: { ...exampleData.payment, error: transactionError, }, }); -export const PaymentWithRefund = createExample(TestedComponent, { +export const PaymentWithRefund = tests.createExample(TestedComponent, { transaction: { ...exampleData.payment, amountRaw: "KUDOS:12", @@ -334,7 +343,7 @@ export const PaymentWithRefund = createExample(TestedComponent, { }, }); -export const PaymentWithDeliveryDate = createExample(TestedComponent, { +export const PaymentWithDeliveryDate = tests.createExample(TestedComponent, { transaction: { ...exampleData.payment, amountRaw: "KUDOS:12", @@ -347,7 +356,7 @@ export const PaymentWithDeliveryDate = createExample(TestedComponent, { }, }); -export const PaymentWithDeliveryAddr = createExample(TestedComponent, { +export const PaymentWithDeliveryAddr = tests.createExample(TestedComponent, { transaction: { ...exampleData.payment, amountRaw: "KUDOS:12", @@ -363,7 +372,7 @@ export const PaymentWithDeliveryAddr = createExample(TestedComponent, { }, }); -export const PaymentWithDeliveryFull = createExample(TestedComponent, { +export const PaymentWithDeliveryFull = tests.createExample(TestedComponent, { transaction: { ...exampleData.payment, amountRaw: "KUDOS:12", @@ -382,7 +391,7 @@ export const PaymentWithDeliveryFull = createExample(TestedComponent, { }, }); -export const PaymentWithRefundPending = createExample(TestedComponent, { +export const PaymentWithRefundPending = tests.createExample(TestedComponent, { transaction: { ...exampleData.payment, amountRaw: "KUDOS:12", @@ -392,7 +401,7 @@ export const PaymentWithRefundPending = createExample(TestedComponent, { }, }); -export const PaymentWithFeeAndRefund = createExample(TestedComponent, { +export const PaymentWithFeeAndRefund = tests.createExample(TestedComponent, { transaction: { ...exampleData.payment, amountRaw: "KUDOS:11", @@ -401,7 +410,7 @@ export const PaymentWithFeeAndRefund = createExample(TestedComponent, { }, }); -export const PaymentWithFeeAndRefundFee = createExample(TestedComponent, { +export const PaymentWithFeeAndRefundFee = tests.createExample(TestedComponent, { transaction: { ...exampleData.payment, amountRaw: "KUDOS:11", @@ -410,20 +419,18 @@ export const PaymentWithFeeAndRefundFee = createExample(TestedComponent, { }, }); -export const PaymentWithoutFee = createExample(TestedComponent, { +export const PaymentWithoutFee = tests.createExample(TestedComponent, { transaction: { ...exampleData.payment, amountRaw: "KUDOS:12", }, }); -export const PaymentPending = createExample(TestedComponent, { +export const PaymentPending = tests.createExample(TestedComponent, { transaction: { ...exampleData.payment, pending: true }, }); -import beer from "../../static-dev/beer.png"; - -export const PaymentWithProducts = createExample(TestedComponent, { +export const PaymentWithProducts = tests.createExample(TestedComponent, { transaction: { ...exampleData.payment, info: { @@ -460,7 +467,7 @@ export const PaymentWithProducts = createExample(TestedComponent, { } as TransactionPayment, }); -export const PaymentWithLongSummary = createExample(TestedComponent, { +export const PaymentWithLongSummary = tests.createExample(TestedComponent, { transaction: { ...exampleData.payment, info: { @@ -484,16 +491,16 @@ export const PaymentWithLongSummary = createExample(TestedComponent, { } as TransactionPayment, }); -export const Deposit = createExample(TestedComponent, { +export const Deposit = tests.createExample(TestedComponent, { transaction: exampleData.deposit, }); -export const DepositTalerBank = createExample(TestedComponent, { +export const DepositTalerBank = tests.createExample(TestedComponent, { transaction: { ...exampleData.deposit, targetPaytoUri: "payto://x-taler-bank/bank.demo.taler.net/Exchange", }, }); -export const DepositBitcoin = createExample(TestedComponent, { +export const DepositBitcoin = tests.createExample(TestedComponent, { transaction: { ...exampleData.deposit, amountRaw: "BITCOINBTC:0.0000011", @@ -502,88 +509,88 @@ export const DepositBitcoin = createExample(TestedComponent, { "payto://bitcoin/bcrt1q6ps8qs6v8tkqrnru4xqqqa6rfwcx5ufpdfqht4?amount=BTC:0.1&subject=0ZSX8SH0M30KHX8K3Y1DAMVGDQV82XEF9DG1HC4QMQ3QWYT4AF00", }, }); -export const DepositIBAN = createExample(TestedComponent, { +export const DepositIBAN = tests.createExample(TestedComponent, { transaction: { ...exampleData.deposit, targetPaytoUri: "payto://iban/ES8877998399652238", }, }); -export const DepositError = createExample(TestedComponent, { +export const DepositError = tests.createExample(TestedComponent, { transaction: { ...exampleData.deposit, error: transactionError, }, }); -export const DepositPending = createExample(TestedComponent, { +export const DepositPending = tests.createExample(TestedComponent, { transaction: { ...exampleData.deposit, pending: true }, }); -export const Refresh = createExample(TestedComponent, { +export const Refresh = tests.createExample(TestedComponent, { transaction: exampleData.refresh, }); -export const RefreshError = createExample(TestedComponent, { +export const RefreshError = tests.createExample(TestedComponent, { transaction: { ...exampleData.refresh, error: transactionError, }, }); -export const Tip = createExample(TestedComponent, { +export const Tip = tests.createExample(TestedComponent, { transaction: exampleData.tip, }); -export const TipError = createExample(TestedComponent, { +export const TipError = tests.createExample(TestedComponent, { transaction: { ...exampleData.tip, error: transactionError, }, }); -export const TipPending = createExample(TestedComponent, { +export const TipPending = tests.createExample(TestedComponent, { transaction: { ...exampleData.tip, pending: true }, }); -export const Refund = createExample(TestedComponent, { +export const Refund = tests.createExample(TestedComponent, { transaction: exampleData.refund, }); -export const RefundError = createExample(TestedComponent, { +export const RefundError = tests.createExample(TestedComponent, { transaction: { ...exampleData.refund, error: transactionError, }, }); -export const RefundPending = createExample(TestedComponent, { +export const RefundPending = tests.createExample(TestedComponent, { transaction: { ...exampleData.refund, pending: true }, }); -export const InvoiceCreditComplete = createExample(TestedComponent, { +export const InvoiceCreditComplete = tests.createExample(TestedComponent, { transaction: { ...exampleData.pull_credit }, }); -export const InvoiceCreditIncomplete = createExample(TestedComponent, { +export const InvoiceCreditIncomplete = tests.createExample(TestedComponent, { transaction: { ...exampleData.pull_credit, pending: true, }, }); -export const InvoiceDebit = createExample(TestedComponent, { +export const InvoiceDebit = tests.createExample(TestedComponent, { transaction: { ...exampleData.pull_debit }, }); -export const TransferCredit = createExample(TestedComponent, { +export const TransferCredit = tests.createExample(TestedComponent, { transaction: { ...exampleData.push_credit }, }); -export const TransferDebitComplete = createExample(TestedComponent, { +export const TransferDebitComplete = tests.createExample(TestedComponent, { transaction: { ...exampleData.push_debit }, }); -export const TransferDebitIncomplete = createExample(TestedComponent, { +export const TransferDebitIncomplete = tests.createExample(TestedComponent, { transaction: { ...exampleData.push_debit, pending: true, diff --git a/packages/taler-wallet-webextension/src/wallet/Transaction.tsx b/packages/taler-wallet-webextension/src/wallet/Transaction.tsx index 542694490..f22f3b4ee 100644 --- a/packages/taler-wallet-webextension/src/wallet/Transaction.tsx +++ b/packages/taler-wallet-webextension/src/wallet/Transaction.tsx @@ -44,7 +44,7 @@ import emptyImg from "../../static/img/empty.png"; import { Amount } from "../components/Amount.js"; import { BankDetailsByPaytoType } from "../components/BankDetailsByPaytoType.js"; import { CopyButton } from "../components/CopyButton.js"; -import { AlertView, ErrorAlertView } from "../components/CurrentAlerts.js"; +import { ErrorAlertView } from "../components/CurrentAlerts.js"; import { Loading } from "../components/Loading.js"; import { Kind, Part, PartCollapsible, PartPayto } from "../components/Part.js"; import { QR } from "../components/QR.js"; @@ -99,8 +99,8 @@ export function TransactionPage({ if (state.hasError) { return ( -