diff options
author | Sebastian <sebasjm@gmail.com> | 2022-01-04 17:06:17 -0300 |
---|---|---|
committer | Sebastian <sebasjm@gmail.com> | 2022-01-04 17:06:24 -0300 |
commit | 9f8139e09b21ec12f9b9ba4926ea80557698c559 (patch) | |
tree | dba5aacf50e89176bee35cfdd1002cc61c3f52e5 /packages/taler-wallet-webextension/src | |
parent | 2e71117f59e0ae6106930e705ae6a54a9839281b (diff) |
replace jest with mocha
Diffstat (limited to 'packages/taler-wallet-webextension/src')
43 files changed, 628 insertions, 357 deletions
diff --git a/packages/taler-wallet-webextension/src/NavigationBar.tsx b/packages/taler-wallet-webextension/src/NavigationBar.tsx index e7108679c..c02e48983 100644 --- a/packages/taler-wallet-webextension/src/NavigationBar.tsx +++ b/packages/taler-wallet-webextension/src/NavigationBar.tsx @@ -37,7 +37,7 @@ export enum Pages { deposit = "/deposit/:currency", settings = "/settings", dev = "/dev", - cta = "/cta", + cta = "/cta/:action", backup = "/backup", history = "/history", transaction = "/transaction/:tid", diff --git a/packages/taler-wallet-webextension/src/api/browser.ts b/packages/taler-wallet-webextension/src/api/browser.ts new file mode 100644 index 000000000..bc50853fb --- /dev/null +++ b/packages/taler-wallet-webextension/src/api/browser.ts @@ -0,0 +1,24 @@ + +export async function findTalerUriInActiveTab(): Promise<string | undefined> { + return new Promise((resolve, reject) => { + chrome.tabs.executeScript( + { + code: ` + (() => { + let x = document.querySelector("a[href^='taler://'") || document.querySelector("a[href^='taler+http://'"); + return x ? x.href.toString() : null; + })(); + `, + allFrames: false, + }, + (result) => { + if (chrome.runtime.lastError) { + console.error(chrome.runtime.lastError); + resolve(undefined); + return; + } + resolve(result[0]); + }, + ); + }); +} diff --git a/packages/taler-wallet-webextension/src/compat.js b/packages/taler-wallet-webextension/src/compat.js deleted file mode 100644 index 48e49a0a7..000000000 --- a/packages/taler-wallet-webextension/src/compat.js +++ /dev/null @@ -1,64 +0,0 @@ -"use strict"; -/* - This file is part of TALER - (C) 2017 INRIA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU General Public License as published by the Free Software - Foundation; either version 3, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along with - TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> - */ -Object.defineProperty(exports, "__esModule", { value: true }); -exports.getPermissionsApi = exports.isNode = exports.isFirefox = void 0; -/** - * Compatibility helpers needed for browsers that don't implement - * WebExtension APIs consistently. - */ -function isFirefox() { - const rt = chrome.runtime; - if (typeof rt.getBrowserInfo === "function") { - return true; - } - return false; -} -exports.isFirefox = isFirefox; -/** - * Check if we are running under nodejs. - */ -function isNode() { - return typeof process !== "undefined" && process.release.name === "node"; -} -exports.isNode = isNode; -function getPermissionsApi() { - const myBrowser = globalThis.browser; - if ( - typeof myBrowser === "object" && - typeof myBrowser.permissions === "object" - ) { - return { - addPermissionsListener: () => { - // Not supported yet. - }, - contains: myBrowser.permissions.contains, - request: myBrowser.permissions.request, - remove: myBrowser.permissions.remove, - }; - } else { - return { - addPermissionsListener: chrome.permissions.onAdded.addListener.bind( - chrome.permissions.onAdded, - ), - contains: chrome.permissions.contains, - request: chrome.permissions.request, - remove: chrome.permissions.remove, - }; - } -} -exports.getPermissionsApi = getPermissionsApi; -//# sourceMappingURL=compat.js.map diff --git a/packages/taler-wallet-webextension/src/components/BalanceTable.tsx b/packages/taler-wallet-webextension/src/components/BalanceTable.tsx index cf396e129..05a7d28dd 100644 --- a/packages/taler-wallet-webextension/src/components/BalanceTable.tsx +++ b/packages/taler-wallet-webextension/src/components/BalanceTable.tsx @@ -19,7 +19,7 @@ import { h, VNode } from "preact"; import { ButtonPrimary, TableWithRoundRows as TableWithRoundedRows, -} from "./styled/index"; +} from "./styled"; export function BalanceTable({ balances, diff --git a/packages/taler-wallet-webextension/src/components/CheckboxOutlined.tsx b/packages/taler-wallet-webextension/src/components/CheckboxOutlined.tsx index c22103a85..16909d29a 100644 --- a/packages/taler-wallet-webextension/src/components/CheckboxOutlined.tsx +++ b/packages/taler-wallet-webextension/src/components/CheckboxOutlined.tsx @@ -14,7 +14,7 @@ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ -import { Outlined, StyledCheckboxLabel } from "./styled/index"; +import { Outlined, StyledCheckboxLabel } from "./styled"; import { h, VNode } from "preact"; interface Props { diff --git a/packages/taler-wallet-webextension/src/components/ErrorTalerOperation.tsx b/packages/taler-wallet-webextension/src/components/ErrorTalerOperation.tsx index ae451dcd8..8f61c7133 100644 --- a/packages/taler-wallet-webextension/src/components/ErrorTalerOperation.tsx +++ b/packages/taler-wallet-webextension/src/components/ErrorTalerOperation.tsx @@ -29,10 +29,11 @@ export function ErrorTalerOperation({ }): VNode | null { const { devMode } = useDevContext(); const [showErrorDetail, setShowErrorDetail] = useState(false); - + if (!title || !error) return null; // const errorCode: number | undefined = (error.details as any)?.errorResponse?.code - const errorHint: string | undefined = (error.details as any)?.errorResponse?.hint + const errorHint: string | undefined = (error.details as any)?.errorResponse + ?.hint; return ( <ErrorBox style={{ paddingTop: 0, paddingBottom: 0 }}> @@ -53,11 +54,11 @@ export function ErrorTalerOperation({ <div style={{ padding: 5, textAlign: "left" }}> <div>{error.message}</div> </div> - {errorHint && - <div style={{ padding: 5, textAlign: "left" }}> - <div>{errorHint}</div> - </div> - } + {errorHint && ( + <div style={{ padding: 5, textAlign: "left" }}> + <div>{errorHint}</div> + </div> + )} {devMode && ( <div style={{ textAlign: "left", overflowX: "auto" }}> <pre>{JSON.stringify(error, undefined, 2)}</pre> diff --git a/packages/taler-wallet-webextension/src/components/SelectList.tsx b/packages/taler-wallet-webextension/src/components/SelectList.tsx index 5bb06f9a8..c17b87339 100644 --- a/packages/taler-wallet-webextension/src/components/SelectList.tsx +++ b/packages/taler-wallet-webextension/src/components/SelectList.tsx @@ -15,7 +15,7 @@ */ import { Fragment, h, VNode } from "preact"; -import { NiceSelect } from "./styled/index"; +import { NiceSelect } from "./styled"; interface Props { value?: string; diff --git a/packages/taler-wallet-webextension/src/components/TransactionItem.tsx b/packages/taler-wallet-webextension/src/components/TransactionItem.tsx index 99ca86385..68a4f8fad 100644 --- a/packages/taler-wallet-webextension/src/components/TransactionItem.tsx +++ b/packages/taler-wallet-webextension/src/components/TransactionItem.tsx @@ -34,7 +34,7 @@ import { SmallLightText, LargeText, LightText, -} from "./styled/index"; +} from "./styled"; import { Time } from "./Time"; export function TransactionItem(props: { diff --git a/packages/taler-wallet-webextension/src/context/iocContext.ts b/packages/taler-wallet-webextension/src/context/iocContext.ts new file mode 100644 index 000000000..688e7b488 --- /dev/null +++ b/packages/taler-wallet-webextension/src/context/iocContext.ts @@ -0,0 +1,49 @@ +/* + This file is part of GNU Taler + (C) 2021 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ + +/** + * + * @author Sebastian Javier Marchano (sebasjm) + */ + +import { createContext, h, VNode } from "preact"; +import { useContext } from "preact/hooks"; +import { findTalerUriInActiveTab } from "../api/browser"; + +interface Type { + findTalerUriInActiveTab: () => Promise<string | undefined>; +} +const Context = createContext<Type>({ + findTalerUriInActiveTab: async () => undefined, +}); + +/** + * Inversion of control Context + * + * This context act as a proxy between API that need to be replaced in + * different environments + * + * @returns + */ +export const useIocContext = (): Type => useContext(Context); + +export const IoCProviderForTesting = ({ value, children }: { value: Type, children: any }): VNode => { + return h(Context.Provider, { value, children }); +}; + +export const IoCProviderForRuntime = ({ children }: { children: any }): VNode => { + return h(Context.Provider, { value: { findTalerUriInActiveTab }, children }); +}; diff --git a/packages/taler-wallet-webextension/src/cta/Pay.stories.tsx b/packages/taler-wallet-webextension/src/cta/Pay.stories.tsx index c2d360d3b..a1288c337 100644 --- a/packages/taler-wallet-webextension/src/cta/Pay.stories.tsx +++ b/packages/taler-wallet-webextension/src/cta/Pay.stories.tsx @@ -34,13 +34,13 @@ export const NoBalance = createExample(TestedComponent, { status: PreparePayResultType.InsufficientBalance, noncePriv: "", proposalId: "proposal1234", - contractTerms: ({ + contractTerms: { merchant: { name: "someone", }, summary: "some beers", amount: "USD:10", - } as Partial<ContractTerms>) as any, + } as Partial<ContractTerms> as any, amountRaw: "USD:10", }, }); @@ -50,13 +50,13 @@ export const NoEnoughBalance = createExample(TestedComponent, { status: PreparePayResultType.InsufficientBalance, noncePriv: "", proposalId: "proposal1234", - contractTerms: ({ + contractTerms: { merchant: { name: "someone", }, summary: "some beers", amount: "USD:10", - } as Partial<ContractTerms>) as any, + } as Partial<ContractTerms> as any, amountRaw: "USD:10", }, balance: { @@ -67,42 +67,40 @@ export const NoEnoughBalance = createExample(TestedComponent, { }); export const PaymentPossible = createExample(TestedComponent, { - uri: - "taler://pay/merchant-backend.taler/2021.242-01G2X4275RBWG/?c=66BE594PDZR24744J6EQK52XM0", + uri: "taler://pay/merchant-backend.taler/2021.242-01G2X4275RBWG/?c=66BE594PDZR24744J6EQK52XM0", payStatus: { status: PreparePayResultType.PaymentPossible, amountEffective: "USD:10", amountRaw: "USD:10", noncePriv: "", - contractTerms: ({ + contractTerms: { nonce: "123213123", merchant: { name: "someone", }, amount: "USD:10", summary: "some beers", - } as Partial<ContractTerms>) as any, + } as Partial<ContractTerms> as any, contractTermsHash: "123456", proposalId: "proposal1234", }, }); export const PaymentPossibleWithFee = createExample(TestedComponent, { - uri: - "taler://pay/merchant-backend.taler/2021.242-01G2X4275RBWG/?c=66BE594PDZR24744J6EQK52XM0", + uri: "taler://pay/merchant-backend.taler/2021.242-01G2X4275RBWG/?c=66BE594PDZR24744J6EQK52XM0", payStatus: { status: PreparePayResultType.PaymentPossible, amountEffective: "USD:10.20", amountRaw: "USD:10", noncePriv: "", - contractTerms: ({ + contractTerms: { nonce: "123213123", merchant: { name: "someone", }, amount: "USD:10", summary: "some beers", - } as Partial<ContractTerms>) as any, + } as Partial<ContractTerms> as any, contractTermsHash: "123456", proposalId: "proposal1234", }, @@ -113,7 +111,7 @@ export const AlreadyConfirmedWithFullfilment = createExample(TestedComponent, { status: PreparePayResultType.AlreadyConfirmed, amountEffective: "USD:10", amountRaw: "USD:10", - contractTerms: ({ + contractTerms: { merchant: { name: "someone", }, @@ -121,7 +119,7 @@ export const AlreadyConfirmedWithFullfilment = createExample(TestedComponent, { "congratulations! you are looking at the fulfillment message! ", summary: "some beers", amount: "USD:10", - } as Partial<ContractTerms>) as any, + } as Partial<ContractTerms> as any, contractTermsHash: "123456", proposalId: "proposal1234", paid: false, @@ -135,13 +133,13 @@ export const AlreadyConfirmedWithoutFullfilment = createExample( status: PreparePayResultType.AlreadyConfirmed, amountEffective: "USD:10", amountRaw: "USD:10", - contractTerms: ({ + contractTerms: { merchant: { name: "someone", }, summary: "some beers", amount: "USD:10", - } as Partial<ContractTerms>) as any, + } as Partial<ContractTerms> as any, contractTermsHash: "123456", proposalId: "proposal1234", paid: false, @@ -154,7 +152,7 @@ export const AlreadyPaid = createExample(TestedComponent, { status: PreparePayResultType.AlreadyConfirmed, amountEffective: "USD:10", amountRaw: "USD:10", - contractTerms: ({ + contractTerms: { merchant: { name: "someone", }, @@ -162,7 +160,7 @@ export const AlreadyPaid = createExample(TestedComponent, { "congratulations! you are looking at the fulfillment message! ", summary: "some beers", amount: "USD:10", - } as Partial<ContractTerms>) as any, + } as Partial<ContractTerms> as any, contractTermsHash: "123456", proposalId: "proposal1234", paid: true, diff --git a/packages/taler-wallet-webextension/src/cta/Pay.tsx b/packages/taler-wallet-webextension/src/cta/Pay.tsx index 7b7d940c7..d7419d410 100644 --- a/packages/taler-wallet-webextension/src/cta/Pay.tsx +++ b/packages/taler-wallet-webextension/src/cta/Pay.tsx @@ -135,7 +135,9 @@ export function PayPage({ ? Amounts.parseOrThrow(foundBalance.available) : undefined; // We use a string here so that dependency tracking for useEffect works properly - const foundAmountStr = foundAmount ? Amounts.stringify(foundAmount) : undefined; + const foundAmountStr = foundAmount + ? Amounts.stringify(foundAmount) + : undefined; useEffect(() => { if (!talerPayUri) return; diff --git a/packages/taler-wallet-webextension/src/cta/Refund.stories.tsx b/packages/taler-wallet-webextension/src/cta/Refund.stories.tsx index a0abcea58..e71170ff1 100644 --- a/packages/taler-wallet-webextension/src/cta/Refund.stories.tsx +++ b/packages/taler-wallet-webextension/src/cta/Refund.stories.tsx @@ -35,10 +35,10 @@ export const Complete = createExample(TestedComponent, { amountRefundGone: "USD:0", amountRefundGranted: "USD:2", contractTermsHash: "QWEASDZXC", - info: ({ + info: { summary: "tasty cold beer", contractTermsHash: "QWEASDZXC", - } as Partial<OrderShortInfo>) as any, + } as Partial<OrderShortInfo> as any, pendingAtExchange: false, proposalId: "proposal123", }, @@ -50,10 +50,10 @@ export const Partial = createExample(TestedComponent, { amountRefundGone: "USD:1", amountRefundGranted: "USD:2", contractTermsHash: "QWEASDZXC", - info: ({ + info: { summary: "tasty cold beer", contractTermsHash: "QWEASDZXC", - } as Partial<OrderShortInfo>) as any, + } as Partial<OrderShortInfo> as any, pendingAtExchange: false, proposalId: "proposal123", }, @@ -65,10 +65,10 @@ export const InProgress = createExample(TestedComponent, { amountRefundGone: "USD:1", amountRefundGranted: "USD:2", contractTermsHash: "QWEASDZXC", - info: ({ + info: { summary: "tasty cold beer", contractTermsHash: "QWEASDZXC", - } as Partial<OrderShortInfo>) as any, + } as Partial<OrderShortInfo> as any, pendingAtExchange: true, proposalId: "proposal123", }, diff --git a/packages/taler-wallet-webextension/src/cta/TermsOfServiceSection.tsx b/packages/taler-wallet-webextension/src/cta/TermsOfServiceSection.tsx index 5109055e8..584da6d29 100644 --- a/packages/taler-wallet-webextension/src/cta/TermsOfServiceSection.tsx +++ b/packages/taler-wallet-webextension/src/cta/TermsOfServiceSection.tsx @@ -10,7 +10,7 @@ import { WarningBox, WarningText, } from "../components/styled"; -import { TermsState } from "../utils"; +import { TermsState } from "../utils/index"; interface Props { reviewing: boolean; diff --git a/packages/taler-wallet-webextension/src/cta/Withdraw.stories.tsx b/packages/taler-wallet-webextension/src/cta/Withdraw.stories.tsx index 3915dc126..3f548366a 100644 --- a/packages/taler-wallet-webextension/src/cta/Withdraw.stories.tsx +++ b/packages/taler-wallet-webextension/src/cta/Withdraw.stories.tsx @@ -24,12 +24,16 @@ import { createExample } from "../test-utils"; import { termsHtml, termsPdf, termsPlain, termsXml } from "./termsExample"; import { View as TestedComponent } from "./Withdraw"; +function parseFromString(s: string): Document { + if (typeof window === "undefined") { + return {} as Document; + } + return new window.DOMParser().parseFromString(s, "text/xml"); +} + export default { title: "cta/withdraw", component: TestedComponent, - argTypes: { - onSwitchExchange: { action: "onRetry" }, - }, }; const exchangeList: ExchangeListItem[] = [ @@ -77,7 +81,7 @@ export const NewTerms = createExample(TestedComponent, { terms: { content: { type: "xml", - document: new DOMParser().parseFromString(termsXml, "text/xml"), + document: parseFromString(termsXml), }, status: "new", version: "", @@ -192,7 +196,7 @@ export const TermsReviewingXML = createExample(TestedComponent, { terms: { content: { type: "xml", - document: new DOMParser().parseFromString(termsXml, "text/xml"), + document: parseFromString(termsXml), }, status: "new", version: "", @@ -219,7 +223,7 @@ export const NewTermsAccepted = createExample(TestedComponent, { terms: { content: { type: "xml", - document: new DOMParser().parseFromString(termsXml, "text/xml"), + document: parseFromString(termsXml), }, status: "new", version: "", @@ -247,7 +251,7 @@ export const TermsShowAgainXML = createExample(TestedComponent, { terms: { content: { type: "xml", - document: new DOMParser().parseFromString(termsXml, "text/xml"), + document: parseFromString(termsXml), }, version: "", status: "new", @@ -276,7 +280,7 @@ export const TermsChanged = createExample(TestedComponent, { terms: { content: { type: "xml", - document: new DOMParser().parseFromString(termsXml, "text/xml"), + document: parseFromString(termsXml), }, version: "", status: "changed", @@ -351,7 +355,7 @@ export const WithoutFee = createExample(TestedComponent, { terms: { content: { type: "xml", - document: new DOMParser().parseFromString(termsXml, "text/xml"), + document: parseFromString(termsXml), }, status: "accepted", version: "", diff --git a/packages/taler-wallet-webextension/src/cta/Withdraw.tsx b/packages/taler-wallet-webextension/src/cta/Withdraw.tsx index 4703492cf..0a06bd577 100644 --- a/packages/taler-wallet-webextension/src/cta/Withdraw.tsx +++ b/packages/taler-wallet-webextension/src/cta/Withdraw.tsx @@ -40,7 +40,11 @@ import { WalletAction, } from "../components/styled"; import { useAsyncAsHook } from "../hooks/useAsyncAsHook"; -import { amountToString, buildTermsOfServiceState, TermsState } from "../utils"; +import { + amountToString, + buildTermsOfServiceState, + TermsState, +} from "../utils/index"; import * as wxApi from "../wxApi"; import { TermsOfServiceSection } from "./TermsOfServiceSection"; diff --git a/packages/taler-wallet-webextension/src/hooks/useBackupStatus.ts b/packages/taler-wallet-webextension/src/hooks/useBackupStatus.ts index 8a8fd6f2f..df1e82676 100644 --- a/packages/taler-wallet-webextension/src/hooks/useBackupStatus.ts +++ b/packages/taler-wallet-webextension/src/hooks/useBackupStatus.ts @@ -43,8 +43,8 @@ function getStatusPaidOrder(a: ProviderPaymentPaid, b: ProviderPaymentPaid) { return a.paidUntil.t_ms === "never" ? -1 : b.paidUntil.t_ms === "never" - ? 1 - : a.paidUntil.t_ms - b.paidUntil.t_ms; + ? 1 + : a.paidUntil.t_ms - b.paidUntil.t_ms; } export function useBackupStatus(): BackupStatus | undefined { diff --git a/packages/taler-wallet-webextension/src/hooks/useTalerActionURL.test.ts b/packages/taler-wallet-webextension/src/hooks/useTalerActionURL.test.ts new file mode 100644 index 000000000..99934ef0b --- /dev/null +++ b/packages/taler-wallet-webextension/src/hooks/useTalerActionURL.test.ts @@ -0,0 +1,60 @@ +/* + This file is part of GNU Taler + (C) 2021 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +import { useTalerActionURL } from "./useTalerActionURL" +import { justBrowser_it, mountBrowser } from "../test-utils"; +import { IoCProviderForTesting } from "../context/iocContext"; +import { h, VNode } from "preact"; +import { act } from "preact/test-utils"; + +describe('useTalerActionURL hook', () => { + + // eslint-disable-next-line jest/expect-expect + justBrowser_it('should be set url to undefined when dismiss', async () => { + + const ctx = ({ children }: { children: any }): VNode => { + return h(IoCProviderForTesting, { + value: { + findTalerUriInActiveTab: async () => "asd", + }, children + }) + } + + const { result, waitNextUpdate } = mountBrowser(useTalerActionURL, ctx) + + { + const [url] = result.current! + if (url !== undefined) throw Error('invalid') + } + + await waitNextUpdate() + + { + const [url] = result.current! + if (url !== "asd") throw Error(`invalid: ${url}`) + } + + await act(() => { + const [, setDismissed] = result.current! + setDismissed(true) + }) + + { + const [url] = result.current! + if (url !== undefined) throw Error('invalid') + } + + }) +})
\ No newline at end of file diff --git a/packages/taler-wallet-webextension/src/hooks/useTalerActionURL.ts b/packages/taler-wallet-webextension/src/hooks/useTalerActionURL.ts index 96a278401..53e1e912d 100644 --- a/packages/taler-wallet-webextension/src/hooks/useTalerActionURL.ts +++ b/packages/taler-wallet-webextension/src/hooks/useTalerActionURL.ts @@ -14,8 +14,8 @@ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ -import { classifyTalerUri, TalerUriType } from "@gnu-taler/taler-util"; import { useEffect, useState } from "preact/hooks"; +import { useIocContext } from "../context/iocContext"; export function useTalerActionURL(): [ string | undefined, @@ -25,6 +25,8 @@ export function useTalerActionURL(): [ undefined, ); const [dismissed, setDismissed] = useState(false); + const { findTalerUriInActiveTab } = useIocContext() + useEffect(() => { async function check(): Promise<void> { const talerUri = await findTalerUriInActiveTab(); @@ -35,28 +37,3 @@ export function useTalerActionURL(): [ const url = dismissed ? undefined : talerActionUrl; return [url, setDismissed]; } - -async function findTalerUriInActiveTab(): Promise<string | undefined> { - return new Promise((resolve, reject) => { - chrome.tabs.executeScript( - { - code: ` - (() => { - let x = document.querySelector("a[href^='taler://'") || document.querySelector("a[href^='taler+http://'"); - return x ? x.href.toString() : null; - })(); - `, - allFrames: false, - }, - (result) => { - if (chrome.runtime.lastError) { - console.error(chrome.runtime.lastError); - resolve(undefined); - return; - } - console.log("got result", result); - resolve(result[0]); - }, - ); - }); -} diff --git a/packages/taler-wallet-webextension/src/popup/AddNewActionView.tsx b/packages/taler-wallet-webextension/src/popup/AddNewActionView.tsx index 876b1a83c..d4158973e 100644 --- a/packages/taler-wallet-webextension/src/popup/AddNewActionView.tsx +++ b/packages/taler-wallet-webextension/src/popup/AddNewActionView.tsx @@ -1,11 +1,7 @@ import { classifyTalerUri, TalerUriType } from "@gnu-taler/taler-util"; import { Fragment, h, VNode } from "preact"; import { useState } from "preact/hooks"; -import { - Button, - ButtonSuccess, - InputWithLabel, -} from "../components/styled/index"; +import { Button, ButtonSuccess, InputWithLabel } from "../components/styled"; import { actionForTalerUri } from "../utils/index"; export interface Props { diff --git a/packages/taler-wallet-webextension/src/popup/BalancePage.tsx b/packages/taler-wallet-webextension/src/popup/BalancePage.tsx index 40499b87c..3eb5f4270 100644 --- a/packages/taler-wallet-webextension/src/popup/BalancePage.tsx +++ b/packages/taler-wallet-webextension/src/popup/BalancePage.tsx @@ -17,7 +17,7 @@ import { BalancesResponse, i18n } from "@gnu-taler/taler-util"; import { Fragment, h, VNode } from "preact"; import { BalanceTable } from "../components/BalanceTable"; -import { ButtonPrimary, ErrorBox } from "../components/styled/index"; +import { ButtonPrimary, ErrorBox } from "../components/styled"; import { HookResponse, useAsyncAsHook } from "../hooks/useAsyncAsHook"; import { PageLink } from "../renderHtml"; import * as wxApi from "../wxApi"; diff --git a/packages/taler-wallet-webextension/src/popup/DeveloperPage.stories.tsx b/packages/taler-wallet-webextension/src/popup/DeveloperPage.stories.tsx index ea8a3537a..fb1177251 100644 --- a/packages/taler-wallet-webextension/src/popup/DeveloperPage.stories.tsx +++ b/packages/taler-wallet-webextension/src/popup/DeveloperPage.stories.tsx @@ -32,7 +32,7 @@ export default { }; export const AllOff = createExample(TestedComponent, { - onDownloadDatabase: async () => "this is the content of the database", + onDownloadDatabase: async () => "this is the content of the database", operations: [ { type: PendingTaskType.ExchangeUpdate, diff --git a/packages/taler-wallet-webextension/src/popup/DeveloperPage.tsx b/packages/taler-wallet-webextension/src/popup/DeveloperPage.tsx index b689004cc..aec288dec 100644 --- a/packages/taler-wallet-webextension/src/popup/DeveloperPage.tsx +++ b/packages/taler-wallet-webextension/src/popup/DeveloperPage.tsx @@ -20,7 +20,7 @@ import { format } from "date-fns"; import { Fragment, h, VNode } from "preact"; import { useState } from "preact/hooks"; import { Diagnostics } from "../components/Diagnostics"; -import { NotifyUpdateFadeOut } from "../components/styled/index"; +import { NotifyUpdateFadeOut } from "../components/styled"; import { Time } from "../components/Time"; import { useAsyncAsHook } from "../hooks/useAsyncAsHook"; import { useDiagnostics } from "../hooks/useDiagnostics"; diff --git a/packages/taler-wallet-webextension/src/popup/History.tsx b/packages/taler-wallet-webextension/src/popup/History.tsx index f897299d8..2dfddb8c4 100644 --- a/packages/taler-wallet-webextension/src/popup/History.tsx +++ b/packages/taler-wallet-webextension/src/popup/History.tsx @@ -23,7 +23,7 @@ import { } from "@gnu-taler/taler-util"; import { Fragment, h, VNode } from "preact"; import { useEffect, useState } from "preact/hooks"; -import { ButtonPrimary } from "../components/styled/index"; +import { ButtonPrimary } from "../components/styled"; import { TransactionItem } from "../components/TransactionItem"; import { useAsyncAsHook } from "../hooks/useAsyncAsHook"; import * as wxApi from "../wxApi"; @@ -133,7 +133,7 @@ export function HistoryView({ style={{ color: "darkgreen", textDecoration: "none" }} href={ // eslint-disable-next-line no-undef - chrome.extension + typeof chrome !== "undefined" && chrome.extension ? // eslint-disable-next-line no-undef chrome.extension.getURL(`/static/wallet.html#/history`) : "#" diff --git a/packages/taler-wallet-webextension/src/popup/TalerActionFound.tsx b/packages/taler-wallet-webextension/src/popup/TalerActionFound.tsx index 40e9111fb..45c4203e8 100644 --- a/packages/taler-wallet-webextension/src/popup/TalerActionFound.tsx +++ b/packages/taler-wallet-webextension/src/popup/TalerActionFound.tsx @@ -21,7 +21,7 @@ import { classifyTalerUri, TalerUriType } from "@gnu-taler/taler-util"; import { Fragment, h } from "preact"; -import { ButtonPrimary, ButtonSuccess } from "../components/styled/index"; +import { ButtonPrimary, ButtonSuccess } from "../components/styled"; import { actionForTalerUri } from "../utils/index"; export interface Props { diff --git a/packages/taler-wallet-webextension/src/popup/index.stories.tsx b/packages/taler-wallet-webextension/src/popup/index.stories.tsx new file mode 100644 index 000000000..c3e60c4ed --- /dev/null +++ b/packages/taler-wallet-webextension/src/popup/index.stories.tsx @@ -0,0 +1,29 @@ +/* + This file is part of GNU Taler + (C) 2021 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ + +/** + * + * @author Sebastian Javier Marchano (sebasjm) + */ + +import * as a1 from "./AddNewActionView.stories"; +import * as a2 from "./Balance.stories"; +import * as a3 from "./DeveloperPage.stories"; +import * as a4 from "./History.stories"; +import * as a5 from "./Popup.stories"; +import * as a6 from "./TalerActionFound.stories"; + +export default [a1, a2, a3, a4, a5, a6]; diff --git a/packages/taler-wallet-webextension/src/popupEntryPoint.tsx b/packages/taler-wallet-webextension/src/popupEntryPoint.tsx index ac1872fb1..27372db5e 100644 --- a/packages/taler-wallet-webextension/src/popupEntryPoint.tsx +++ b/packages/taler-wallet-webextension/src/popupEntryPoint.tsx @@ -22,7 +22,7 @@ import { setupI18n } from "@gnu-taler/taler-util"; import { createHashHistory } from "history"; -import { render, h } from "preact"; +import { render, h, VNode, Fragment } from "preact"; import Router, { route, Route } from "preact-router"; import { useEffect } from "preact/hooks"; import { PopupBox } from "./components/styled"; @@ -39,6 +39,7 @@ import { ProviderDetailPage } from "./wallet/ProviderDetailPage"; import { SettingsPage } from "./popup/Settings"; import { TalerActionFound } from "./popup/TalerActionFound"; import { ExchangeAddPage } from "./wallet/ExchangeAddPage"; +import { IoCProviderForRuntime } from "./context/iocContext"; function main(): void { try { @@ -63,87 +64,99 @@ if (document.readyState === "loading") { main(); } -function Application() { - const [talerActionUrl, setDismissed] = useTalerActionURL(); +function CheckTalerActionComponent(): VNode { + const [talerActionUrl] = useTalerActionURL(); useEffect(() => { - if (talerActionUrl) route(Pages.cta); + if (talerActionUrl) + route(Pages.cta.replace(":action", encodeURIComponent(talerActionUrl))); }, [talerActionUrl]); + return <Fragment />; +} + +function Application() { return ( <div> <DevContextProvider> - <WalletNavBar /> - <PopupBox> - <Router history={createHashHistory()}> - <Route path={Pages.dev} component={DeveloperPage} /> - - <Route - path={Pages.balance} - component={BalancePage} - goToWalletManualWithdraw={() => - goToWalletPage(Pages.manual_withdraw) - } - goToWalletDeposit={(currency: string) => - goToWalletPage(Pages.deposit.replace(":currency", currency)) - } - /> - <Route path={Pages.settings} component={SettingsPage} /> - <Route - path={Pages.cta} - component={() => ( - <TalerActionFound - url={talerActionUrl!} - onDismiss={() => { - setDismissed(true); - route(Pages.balance); - }} - /> - )} - /> - - <Route - path={Pages.transaction} - component={({ tid }: { tid: string }) => - goToWalletPage(Pages.transaction.replace(":tid", tid)) - } - /> - - <Route path={Pages.history} component={HistoryPage} /> - - <Route - path={Pages.backup} - component={BackupPage} - onAddProvider={() => { - route(Pages.provider_add); - }} - /> - <Route - path={Pages.provider_detail} - component={ProviderDetailPage} - onBack={() => { - route(Pages.backup); - }} - /> - <Route - path={Pages.provider_add} - component={ProviderAddPage} - onBack={() => { - route(Pages.backup); - }} - /> - - <Route - path={Pages.exchange_add} - component={ExchangeAddPage} - onBack={() => { - route(Pages.balance); - }} - /> - - <Route default component={Redirect} to={Pages.balance} /> - </Router> - </PopupBox> + <IoCProviderForRuntime> + <WalletNavBar /> + <CheckTalerActionComponent /> + <PopupBox> + <Router history={createHashHistory()}> + <Route path={Pages.dev} component={DeveloperPage} /> + + <Route + path={Pages.balance} + component={BalancePage} + goToWalletManualWithdraw={() => + goToWalletPage(Pages.manual_withdraw) + } + goToWalletDeposit={(currency: string) => + goToWalletPage(Pages.deposit.replace(":currency", currency)) + } + /> + <Route path={Pages.settings} component={SettingsPage} /> + <Route + path={Pages.cta} + component={function Action({ action }: { action: string }) { + const [, setDismissed] = useTalerActionURL(); + + return ( + <TalerActionFound + url={decodeURIComponent(action)} + onDismiss={() => { + setDismissed(true); + route(Pages.balance); + }} + /> + ); + }} + /> + + <Route + path={Pages.transaction} + component={({ tid }: { tid: string }) => + goToWalletPage(Pages.transaction.replace(":tid", tid)) + } + /> + + <Route path={Pages.history} component={HistoryPage} /> + + <Route + path={Pages.backup} + component={BackupPage} + onAddProvider={() => { + route(Pages.provider_add); + }} + /> + <Route + path={Pages.provider_detail} + component={ProviderDetailPage} + onBack={() => { + route(Pages.backup); + }} + /> + <Route + path={Pages.provider_add} + component={ProviderAddPage} + onBack={() => { + route(Pages.backup); + }} + /> + + <Route + path={Pages.exchange_add} + component={ExchangeAddPage} + onBack={() => { + route(Pages.balance); + }} + /> + + <Route default component={Redirect} to={Pages.balance} /> + </Router> + </PopupBox> + </IoCProviderForRuntime> </DevContextProvider> </div> ); diff --git a/packages/taler-wallet-webextension/src/stories.test.ts b/packages/taler-wallet-webextension/src/stories.test.ts new file mode 100644 index 000000000..e2d43d5cf --- /dev/null +++ b/packages/taler-wallet-webextension/src/stories.test.ts @@ -0,0 +1,51 @@ +/* + This file is part of GNU Taler + (C) 2021 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ + +/** + * + * @author Sebastian Javier Marchano (sebasjm) + */ +import * as popup from "./popup/index.stories"; +import * as wallet from "./wallet/index.stories"; + +import { setupI18n } from "@gnu-taler/taler-util"; +import { renderNodeOrBrowser } from "./test-utils"; +setupI18n("en", { en: {} }); + +function testThisStory(st: any): any { + describe(`render examples for ${(st as any).default.title}`, () => { + Object.keys(st).forEach((k) => { + const Component = (st as any)[k]; + if (k === "default" || !Component) return; + + + // eslint-disable-next-line jest/expect-expect + it(`example: ${k}`, () => { + renderNodeOrBrowser(Component, Component.args); + }); + }); + }); +} + +describe("render every storybook example", () => { + [popup, wallet].forEach(function testAll(st: any) { + if (Array.isArray(st.default)) { + st.default.forEach(testAll) + } else { + testThisStory(st) + } + }); +}); diff --git a/packages/taler-wallet-webextension/src/test-utils.ts b/packages/taler-wallet-webextension/src/test-utils.ts index 2fe2c43bd..fbb7c56ff 100644 --- a/packages/taler-wallet-webextension/src/test-utils.ts +++ b/packages/taler-wallet-webextension/src/test-utils.ts @@ -14,13 +14,15 @@ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ -import { ComponentChildren, FunctionalComponent, h as render, VNode } from "preact"; +import { PendingTestFunction, TestFunction } from "mocha"; +import { ComponentChildren, Fragment, FunctionalComponent, h as create, render as renderIntoDom, VNode } from "preact"; +import { render as renderToString } from "preact-render-to-string"; export function createExample<Props>( Component: FunctionalComponent<Props>, props: Partial<Props>, ): ComponentChildren { - const Render = (args: any) => render(Component, args); + const Render = (args: any): VNode => create(Component, args); Render.args = props; return Render; } @@ -31,12 +33,89 @@ export function createExampleWithCustomContext<Props, ContextProps>( ContextProvider: FunctionalComponent<ContextProps>, contextProps: Partial<ContextProps>, ): ComponentChildren { - const Render = (args: any): VNode => render(Component, args); - const WithContext = (args: any): VNode => render(ContextProvider, { ...contextProps, children: [Render(args)] } as any); + const Render = (args: any): VNode => create(Component, args); + const WithContext = (args: any): VNode => create(ContextProvider, { ...contextProps, children: [Render(args)] } as any); WithContext.args = props return WithContext } -export function NullLink({ children }: { children?: ComponentChildren }) { - return render("a", { children, href: "javascript:void(0);" }); +export function NullLink({ children }: { children?: ComponentChildren }): VNode { + return create("a", { children, href: "javascript:void(0);" }); } + +export function renderNodeOrBrowser(Component: any, args: any): void { + const vdom = create(Component, args); + if (typeof window === "undefined") { + renderToString(vdom); + } else { + const div = document.createElement("div"); + document.body.appendChild(div); + renderIntoDom(vdom, div); + renderIntoDom(null, div); + document.body.removeChild(div); + } +} + +interface Mounted<T> { + unmount: () => void; + result: { current: T | null }; + waitNextUpdate: () => Promise<void>; +} + +export function mountBrowser<T>(callback: () => T, Context?: ({ children }: { children: any }) => VNode): Mounted<T> { + const result: { current: T | null } = { + current: null + } + const listener: Array<() => void> = [] + + // component that's going to hold the hook + function Component(): VNode { + const hookResult = callback() + // save the hook result + result.current = hookResult + // notify to everyone waiting for an update and clean the queue + listener.splice(0, listener.length).forEach(cb => cb()) + return create(Fragment, {}) + } + + // create the vdom with context if required + const vdom = !Context ? create(Component, {}) : create(Context, { children: [create(Component, {})] },); + + // in non-browser environment (server side rendering) just serialize to + // string and exit + if (typeof window === "undefined") { + renderToString(vdom); + return { unmount: () => null, result } as any + } + + // do the render into the DOM + const div = document.createElement("div"); + document.body.appendChild(div); + renderIntoDom(vdom, div); + + // clean up callback + function unmount(): any { + document.body.removeChild(div); + } + + // waiter callback + async function waitNextUpdate(): Promise<void> { + await new Promise((res, rej) => { + const tid = setTimeout(() => { + rej(Error("waiting for an update but the hook didn't make one")) + }, 100) + + listener.push(() => { + clearTimeout(tid) + res(undefined) + }) + }) + } + + return { + unmount, result, waitNextUpdate + } +} + +export const justBrowser_it: PendingTestFunction | TestFunction = + typeof window === 'undefined' ? it.skip : it
\ No newline at end of file diff --git a/packages/taler-wallet-webextension/src/wallet/BalancePage.tsx b/packages/taler-wallet-webextension/src/wallet/BalancePage.tsx index 52edbbe51..33182a38d 100644 --- a/packages/taler-wallet-webextension/src/wallet/BalancePage.tsx +++ b/packages/taler-wallet-webextension/src/wallet/BalancePage.tsx @@ -17,7 +17,7 @@ import { BalancesResponse, i18n } from "@gnu-taler/taler-util"; import { Fragment, h, VNode } from "preact"; import { BalanceTable } from "../components/BalanceTable"; -import { ButtonPrimary, Centered, ErrorBox } from "../components/styled/index"; +import { ButtonPrimary, Centered, ErrorBox } from "../components/styled"; import { HookResponse, useAsyncAsHook } from "../hooks/useAsyncAsHook"; import { PageLink } from "../renderHtml"; import * as wxApi from "../wxApi"; diff --git a/packages/taler-wallet-webextension/src/wallet/DepositPage.stories.tsx b/packages/taler-wallet-webextension/src/wallet/DepositPage.stories.tsx index 346b85d4f..2e2d4cb3d 100644 --- a/packages/taler-wallet-webextension/src/wallet/DepositPage.stories.tsx +++ b/packages/taler-wallet-webextension/src/wallet/DepositPage.stories.tsx @@ -19,7 +19,7 @@ * @author Sebastian Javier Marchano (sebasjm) */ -import { AmountJson, Amounts, parsePaytoUri } from "@gnu-taler/taler-util"; +import { Amounts, parsePaytoUri } from "@gnu-taler/taler-util"; import { DepositFee } from "@gnu-taler/taler-wallet-core/src/operations/deposits"; import { createExample } from "../test-utils"; import { View as TestedComponent } from "./DepositPage"; diff --git a/packages/taler-wallet-webextension/src/wallet/DepositPage.tsx b/packages/taler-wallet-webextension/src/wallet/DepositPage.tsx index d4759c537..5c931394d 100644 --- a/packages/taler-wallet-webextension/src/wallet/DepositPage.tsx +++ b/packages/taler-wallet-webextension/src/wallet/DepositPage.tsx @@ -108,8 +108,13 @@ export function View({ const currency = balance.currency; const amountStr: AmountString = `${currency}:${amount}`; - const account = knownBankAccounts[accountIdx]; - const accountURI = `payto://${account.targetType}/${account.targetPath}`; + const account = knownBankAccounts.length + ? knownBankAccounts[accountIdx] + : undefined; + const accountURI = !account + ? "" + : `payto://${account.targetType}/${account.targetPath}`; + useEffect(() => { if (amount === undefined) return; onCalculateFee(accountURI, amountStr).then((result) => { diff --git a/packages/taler-wallet-webextension/src/wallet/ExchangeAddConfirm.stories.tsx b/packages/taler-wallet-webextension/src/wallet/ExchangeAddConfirm.stories.tsx index 2e034458a..36b81d24c 100644 --- a/packages/taler-wallet-webextension/src/wallet/ExchangeAddConfirm.stories.tsx +++ b/packages/taler-wallet-webextension/src/wallet/ExchangeAddConfirm.stories.tsx @@ -23,6 +23,17 @@ import { termsXml } from "../cta/termsExample"; import { createExample } from "../test-utils"; import { View as TestedComponent } from "./ExchangeAddConfirm"; +function parseFromString(s: string): Document { + if (typeof window === "undefined") { + return { + querySelector: () => ({ + children: [], + }), + } as any; + } + return new window.DOMParser().parseFromString(s, "text/xml"); +} + export default { title: "wallet/exchange add/confirm", component: TestedComponent, @@ -60,7 +71,7 @@ export const TermsChanged = createExample(TestedComponent, { version: "1", content: { type: "xml", - document: new DOMParser().parseFromString(termsXml, "text/xml"), + document: parseFromString(termsXml), }, }, onAccept: async () => undefined, diff --git a/packages/taler-wallet-webextension/src/wallet/ExchangeAddConfirm.tsx b/packages/taler-wallet-webextension/src/wallet/ExchangeAddConfirm.tsx index 409e0b49e..562a2c956 100644 --- a/packages/taler-wallet-webextension/src/wallet/ExchangeAddConfirm.tsx +++ b/packages/taler-wallet-webextension/src/wallet/ExchangeAddConfirm.tsx @@ -1,14 +1,10 @@ import { i18n } from "@gnu-taler/taler-util"; import { Fragment, h, VNode } from "preact"; import { useState } from "preact/hooks"; -import { - Button, - ButtonSuccess, - ButtonWarning, -} from "../components/styled/index"; +import { Button, ButtonSuccess, ButtonWarning } from "../components/styled"; import { TermsOfServiceSection } from "../cta/TermsOfServiceSection"; import { useAsyncAsHook } from "../hooks/useAsyncAsHook"; -import { buildTermsOfServiceState, TermsState } from "../utils"; +import { buildTermsOfServiceState, TermsState } from "../utils/index"; import * as wxApi from "../wxApi"; export interface Props { diff --git a/packages/taler-wallet-webextension/src/wallet/ExchangeAddPage.tsx b/packages/taler-wallet-webextension/src/wallet/ExchangeAddPage.tsx index 6dbdf4c30..a8ef4549c 100644 --- a/packages/taler-wallet-webextension/src/wallet/ExchangeAddPage.tsx +++ b/packages/taler-wallet-webextension/src/wallet/ExchangeAddPage.tsx @@ -21,7 +21,7 @@ import { import { h, VNode } from "preact"; import { useState } from "preact/hooks"; import { useAsyncAsHook } from "../hooks/useAsyncAsHook"; -import { queryToSlashKeys } from "../utils"; +import { queryToSlashKeys } from "../utils/index"; import * as wxApi from "../wxApi"; import { ExchangeAddConfirmPage } from "./ExchangeAddConfirm"; import { ExchangeSetUrlPage } from "./ExchangeSetUrl"; diff --git a/packages/taler-wallet-webextension/src/wallet/ExchangeAddSetUrl.stories.tsx b/packages/taler-wallet-webextension/src/wallet/ExchangeAddSetUrl.stories.tsx index 6f0a58729..221a9da10 100644 --- a/packages/taler-wallet-webextension/src/wallet/ExchangeAddSetUrl.stories.tsx +++ b/packages/taler-wallet-webextension/src/wallet/ExchangeAddSetUrl.stories.tsx @@ -20,7 +20,7 @@ */ import { createExample } from "../test-utils"; -import { queryToSlashKeys } from "../utils"; +import { queryToSlashKeys } from "../utils/index"; import { ExchangeSetUrlPage as TestedComponent } from "./ExchangeSetUrl"; export default { diff --git a/packages/taler-wallet-webextension/src/wallet/ExchangeSetUrl.tsx b/packages/taler-wallet-webextension/src/wallet/ExchangeSetUrl.tsx index d529d162b..f346d6bf3 100644 --- a/packages/taler-wallet-webextension/src/wallet/ExchangeSetUrl.tsx +++ b/packages/taler-wallet-webextension/src/wallet/ExchangeSetUrl.tsx @@ -7,12 +7,7 @@ import { import { Fragment, h } from "preact"; import { useEffect, useState } from "preact/hooks"; import { ErrorMessage } from "../components/ErrorMessage"; -import { - Button, - ButtonPrimary, - Input, - WarningBox, -} from "../components/styled/index"; +import { Button, ButtonPrimary, Input, WarningBox } from "../components/styled"; export interface Props { initialValue?: string; diff --git a/packages/taler-wallet-webextension/src/wallet/ProviderAddPage.tsx b/packages/taler-wallet-webextension/src/wallet/ProviderAddPage.tsx index 16f239674..44d1049b9 100644 --- a/packages/taler-wallet-webextension/src/wallet/ProviderAddPage.tsx +++ b/packages/taler-wallet-webextension/src/wallet/ProviderAddPage.tsx @@ -30,8 +30,8 @@ import { Input, LightText, SmallLightText, -} from "../components/styled/index"; -import { queryToSlashConfig } from "../utils"; +} from "../components/styled"; +import { queryToSlashConfig } from "../utils/index"; import * as wxApi from "../wxApi"; interface Props { diff --git a/packages/taler-wallet-webextension/src/wallet/ReserveCreated.tsx b/packages/taler-wallet-webextension/src/wallet/ReserveCreated.tsx index f009c5ad0..ae820d8fe 100644 --- a/packages/taler-wallet-webextension/src/wallet/ReserveCreated.tsx +++ b/packages/taler-wallet-webextension/src/wallet/ReserveCreated.tsx @@ -3,7 +3,7 @@ import { Fragment, h, VNode } from "preact"; import { BankDetailsByPaytoType } from "../components/BankDetailsByPaytoType"; import { QR } from "../components/QR"; import { ButtonDestructive, WarningBox } from "../components/styled"; -import { amountToString } from "../utils"; +import { amountToString } from "../utils/index"; export interface Props { reservePub: string; payto: string; diff --git a/packages/taler-wallet-webextension/src/wallet/Settings.tsx b/packages/taler-wallet-webextension/src/wallet/Settings.tsx index 04656acc1..293448785 100644 --- a/packages/taler-wallet-webextension/src/wallet/Settings.tsx +++ b/packages/taler-wallet-webextension/src/wallet/Settings.tsx @@ -29,7 +29,7 @@ import { useBackupDeviceName } from "../hooks/useBackupDeviceName"; import { useExtendedPermissions } from "../hooks/useExtendedPermissions"; import { useLang } from "../hooks/useLang"; import { Pages } from "../NavigationBar"; -import { buildTermsOfServiceStatus } from "../utils"; +import { buildTermsOfServiceStatus } from "../utils/index"; import * as wxApi from "../wxApi"; export function SettingsPage(): VNode { diff --git a/packages/taler-wallet-webextension/src/wallet/Transaction.stories.tsx b/packages/taler-wallet-webextension/src/wallet/Transaction.stories.tsx index 4e8433921..7b6ac1fdc 100644 --- a/packages/taler-wallet-webextension/src/wallet/Transaction.stories.tsx +++ b/packages/taler-wallet-webextension/src/wallet/Transaction.stories.tsx @@ -125,12 +125,13 @@ const exampleData = { const transactionError = { code: 7005, details: { - requestUrl: "http://merchant-backend.taler:9966/orders/2021.340-02AD5XCC97MQM/pay", + requestUrl: + "http://merchant-backend.taler:9966/orders/2021.340-02AD5XCC97MQM/pay", httpStatusCode: 410, errorResponse: { code: 2161, - hint: "The payment is too late, the offer has expired." - } + hint: "The payment is too late, the offer has expired.", + }, }, hint: "Error: WALLET_UNEXPECTED_REQUEST_ERROR", message: "Unexpected error code in response", diff --git a/packages/taler-wallet-webextension/src/wallet/index.stories.tsx b/packages/taler-wallet-webextension/src/wallet/index.stories.tsx new file mode 100644 index 000000000..644ab1c59 --- /dev/null +++ b/packages/taler-wallet-webextension/src/wallet/index.stories.tsx @@ -0,0 +1,37 @@ +/* + This file is part of GNU Taler + (C) 2021 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ + +/** + * + * @author Sebastian Javier Marchano (sebasjm) + */ + +import * as a1 from "./Backup.stories"; +import * as a2 from "./Balance.stories"; +import * as a3 from "./CreateManualWithdraw.stories"; +import * as a4 from "./DepositPage.stories"; +import * as a5 from "./ExchangeAddConfirm.stories"; +import * as a6 from "./ExchangeAddSetUrl.stories"; +import * as a7 from "./History.stories"; +import * as a8 from "./ProviderAddConfirmProvider.stories"; +import * as a9 from "./ProviderAddSetUrl.stories"; +import * as a10 from "./ProviderDetail.stories"; +import * as a11 from "./ReserveCreated.stories"; +import * as a12 from "./Settings.stories"; +import * as a13 from "./Transaction.stories"; +import * as a14 from "./Welcome.stories"; + +export default [a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14]; diff --git a/packages/taler-wallet-webextension/src/walletEntryPoint.tsx b/packages/taler-wallet-webextension/src/walletEntryPoint.tsx index a38add3ca..938892874 100644 --- a/packages/taler-wallet-webextension/src/walletEntryPoint.tsx +++ b/packages/taler-wallet-webextension/src/walletEntryPoint.tsx @@ -46,6 +46,7 @@ import { ProviderDetailPage } from "./wallet/ProviderDetailPage"; import { ProviderAddPage } from "./wallet/ProviderAddPage"; import { ExchangeAddPage } from "./wallet/ExchangeAddPage"; import { DepositPage } from "./wallet/DepositPage"; +import { IoCProviderForRuntime } from "./context/iocContext"; function main(): void { try { @@ -88,103 +89,105 @@ function Application(): VNode { return ( <div> <DevContextProvider> - <Router history={createHashHistory()}> - <Route - path={Pages.welcome} - component={withLogoAndNavBar(WelcomePage)} - /> - - <Route - path={Pages.history} - component={withLogoAndNavBar(HistoryPage)} - /> - <Route - path={Pages.transaction} - component={withLogoAndNavBar(TransactionPage)} - /> - <Route - path={Pages.balance} - component={withLogoAndNavBar(BalancePage)} - goToWalletManualWithdraw={() => route(Pages.manual_withdraw)} - goToWalletDeposit={(currency: string) => - route(Pages.deposit.replace(":currency", currency)) - } - /> - <Route - path={Pages.settings} - component={withLogoAndNavBar(SettingsPage)} - /> - <Route - path={Pages.backup} - component={withLogoAndNavBar(BackupPage)} - onAddProvider={() => { - route(Pages.provider_add); - }} - /> - <Route - path={Pages.provider_detail} - component={withLogoAndNavBar(ProviderDetailPage)} - onBack={() => { - route(Pages.backup); - }} - /> - <Route - path={Pages.provider_add} - component={withLogoAndNavBar(ProviderAddPage)} - onBack={() => { - route(Pages.backup); - }} - /> - - <Route - path={Pages.exchange_add} - component={withLogoAndNavBar(ExchangeAddPage)} - onBack={() => { - route(Pages.balance); - }} - /> - - <Route - path={Pages.manual_withdraw} - component={withLogoAndNavBar(ManualWithdrawPage)} - /> - - <Route - path={Pages.deposit} - component={withLogoAndNavBar(DepositPage)} - /> - <Route - path={Pages.reset_required} - component={() => <div>no yet implemented</div>} - /> - <Route - path={Pages.payback} - component={() => <div>no yet implemented</div>} - /> - <Route - path={Pages.return_coins} - component={() => <div>no yet implemented</div>} - /> - - <Route - path={Pages.dev} - component={withLogoAndNavBar(DeveloperPage)} - /> - - {/** call to action */} - <Route - path={Pages.pay} - component={PayPage} - goToWalletManualWithdraw={() => - goToWalletPage(Pages.manual_withdraw) - } - /> - <Route path={Pages.refund} component={RefundPage} /> - <Route path={Pages.tips} component={TipPage} /> - <Route path={Pages.withdraw} component={WithdrawPage} /> - - <Route default component={Redirect} to={Pages.history} /> - </Router> + <IoCProviderForRuntime> + <Router history={createHashHistory()}> + <Route + path={Pages.welcome} + component={withLogoAndNavBar(WelcomePage)} + /> + + <Route + path={Pages.history} + component={withLogoAndNavBar(HistoryPage)} + /> + <Route + path={Pages.transaction} + component={withLogoAndNavBar(TransactionPage)} + /> + <Route + path={Pages.balance} + component={withLogoAndNavBar(BalancePage)} + goToWalletManualWithdraw={() => route(Pages.manual_withdraw)} + goToWalletDeposit={(currency: string) => + route(Pages.deposit.replace(":currency", currency)) + } + /> + <Route + path={Pages.settings} + component={withLogoAndNavBar(SettingsPage)} + /> + <Route + path={Pages.backup} + component={withLogoAndNavBar(BackupPage)} + onAddProvider={() => { + route(Pages.provider_add); + }} + /> + <Route + path={Pages.provider_detail} + component={withLogoAndNavBar(ProviderDetailPage)} + onBack={() => { + route(Pages.backup); + }} + /> + <Route + path={Pages.provider_add} + component={withLogoAndNavBar(ProviderAddPage)} + onBack={() => { + route(Pages.backup); + }} + /> + + <Route + path={Pages.exchange_add} + component={withLogoAndNavBar(ExchangeAddPage)} + onBack={() => { + route(Pages.balance); + }} + /> + + <Route + path={Pages.manual_withdraw} + component={withLogoAndNavBar(ManualWithdrawPage)} + /> + + <Route + path={Pages.deposit} + component={withLogoAndNavBar(DepositPage)} + /> + <Route + path={Pages.reset_required} + component={() => <div>no yet implemented</div>} + /> + <Route + path={Pages.payback} + component={() => <div>no yet implemented</div>} + /> + <Route + path={Pages.return_coins} + component={() => <div>no yet implemented</div>} + /> + + <Route + path={Pages.dev} + component={withLogoAndNavBar(DeveloperPage)} + /> + + {/** call to action */} + <Route + path={Pages.pay} + component={PayPage} + goToWalletManualWithdraw={() => + goToWalletPage(Pages.manual_withdraw) + } + /> + <Route path={Pages.refund} component={RefundPage} /> + <Route path={Pages.tips} component={TipPage} /> + <Route path={Pages.withdraw} component={WithdrawPage} /> + + <Route default component={Redirect} to={Pages.history} /> + </Router> + </IoCProviderForRuntime> </DevContextProvider> </div> ); diff --git a/packages/taler-wallet-webextension/src/wxApi.ts b/packages/taler-wallet-webextension/src/wxApi.ts index 64a506c13..5fe30bc4b 100644 --- a/packages/taler-wallet-webextension/src/wxApi.ts +++ b/packages/taler-wallet-webextension/src/wxApi.ts @@ -39,7 +39,7 @@ import { } from "@gnu-taler/taler-wallet-core"; import { DepositFee } from "@gnu-taler/taler-wallet-core/src/operations/deposits"; import { ExchangeWithdrawDetails } from "@gnu-taler/taler-wallet-core/src/operations/withdraw"; -import { MessageFromBackend } from "./wxBackend.js"; +import { MessageFromBackend } from "./wxBackend"; export interface ExtendedPermissionsResponse { newValue: boolean; @@ -75,7 +75,7 @@ async function callBackend(operation: string, payload: any): Promise<any> { console.log("Error calling backend"); reject( new Error( - `Error contacting backend: chrome.runtime.lastError.message`, + `Error contacting backend: ${chrome.runtime.lastError.message}`, ), ); } |