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 | |
parent | 2e71117f59e0ae6106930e705ae6a54a9839281b (diff) |
replace jest with mocha
Diffstat (limited to 'packages/taler-wallet-webextension')
54 files changed, 740 insertions, 666 deletions
diff --git a/packages/taler-wallet-webextension/.storybook/main.js b/packages/taler-wallet-webextension/.storybook/main.js index c648a9088..d3f216922 100644 --- a/packages/taler-wallet-webextension/.storybook/main.js +++ b/packages/taler-wallet-webextension/.storybook/main.js @@ -48,14 +48,14 @@ module.exports = { webpackFinal: (config) => { // should be removed after storybook 6.3 // https://github.com/storybookjs/storybook/issues/12853#issuecomment-821576113 - // removing workaround since this creates another problem - // https://github.com/storybookjs/storybook/issues/16623 - // https://github.com/nodejs/node/issues/33460 - // FIXME: remove this comments in 2022 if no problem arise -// config.resolve.alias = { -// react: "preact/compat", -// "react-dom": "preact/compat", -// }; + // removing workaround since this creates another problem + // https://github.com/storybookjs/storybook/issues/16623 + // https://github.com/nodejs/node/issues/33460 + // FIXME: remove this comments in 2022 if no problem arise + // config.resolve.alias = { + // react: "preact/compat", + // "react-dom": "preact/compat", + // }; // we need to add @linaria loader AFTER the babel-loader // https://github.com/callstack/linaria/blob/master/docs/BUNDLERS_INTEGRATION.md#webpack @@ -65,7 +65,7 @@ module.exports = { use: [ { ...(config.module.rules[0].use[0]), - loader: 'babel-loader', + loader: 'babel-loader', }, { loader: '@linaria/webpack-loader', @@ -74,7 +74,7 @@ module.exports = { babelOptions: { presets: config.module.rules[0].use[0].options.presets, } - // Pass the current babel options to linaria's babel instance + // Pass the current babel options to linaria's babel instance } } ] diff --git a/packages/taler-wallet-webextension/.storybook/preview.js b/packages/taler-wallet-webextension/.storybook/preview.js index 25f9f46ba..6331a7fa8 100644 --- a/packages/taler-wallet-webextension/.storybook/preview.js +++ b/packages/taler-wallet-webextension/.storybook/preview.js @@ -21,7 +21,6 @@ import { TranslationProvider } from '../src/context/translation' import { PopupBox, WalletBox } from '../src/components/styled' export const parameters = { controls: { expanded: true }, - actions: { argTypesRegex: "^on[A-Z].*" }, } export const globalTypes = { diff --git a/packages/taler-wallet-webextension/clean_and_build_fast.sh b/packages/taler-wallet-webextension/clean_and_build_fast.sh index bac758c92..a7681d268 100755 --- a/packages/taler-wallet-webextension/clean_and_build_fast.sh +++ b/packages/taler-wallet-webextension/clean_and_build_fast.sh @@ -2,6 +2,7 @@ # This file is in the public domain. set -e +mv node_modules{,_saved} rm -rf dist lib tsconfig.tsbuildinfo (cd ../.. && rm -rf build/web && ./contrib/build-fast-web.sh) rm -rf extension/ @@ -9,3 +10,4 @@ rm -rf extension/ (cd extension/v2 && unzip taler*.zip) (cd extension/v3 && unzip taler*.zip) +mv node_modules{_saved,} diff --git a/packages/taler-wallet-webextension/package.json b/packages/taler-wallet-webextension/package.json index 41d65e88e..179cd94db 100644 --- a/packages/taler-wallet-webextension/package.json +++ b/packages/taler-wallet-webextension/package.json @@ -9,8 +9,9 @@ "private": false, "scripts": { "clean": "rimraf dist lib tsconfig.tsbuildinfo", - "test": "jest ./tests", - "compile": "tsc && rollup -c", + "test": "mocha --enable-source-maps 'dist/**/*.test.js'", + "test:coverage": "nyc pnpm test", + "compile": "rollup -c -m", "build-storybook": "build-storybook", "storybook": "start-storybook -s . -p 6006", "pretty": "prettier --write src", @@ -41,22 +42,21 @@ "@rollup/plugin-json": "^4.1.0", "@rollup/plugin-node-resolve": "^11.1.0", "@rollup/plugin-replace": "^2.3.4", + "@rollup/plugin-typescript": "^8.3.0", "@storybook/addon-a11y": "^6.2.9", "@storybook/addon-essentials": "^6.2.9", - "@storybook/preact": "^6.2.9", + "@storybook/preact": "6.4.9", "@testing-library/preact": "^2.0.1", + "@testing-library/preact-hooks": "^1.1.0", "@types/chrome": "^0.0.128", - "@types/enzyme": "^3.10.10", "@types/history": "^4.7.8", - "@types/jest": "^26.0.23", + "@types/mocha": "^9.0.0", "@types/node": "^14.14.22", "ava": "3.15.0", "babel-loader": "^8.2.2", "babel-plugin-transform-react-jsx": "^6.24.1", - "enzyme": "^3.11.0", - "enzyme-adapter-preact-pure": "^3.1.0", - "jest": "^26.6.3", - "jest-preset-preact": "^4.0.2", + "mocha": "^9.1.3", + "nyc": "^15.1.0", "preact-cli": "^3.0.5", "preact-render-to-string": "^5.1.19", "rimraf": "^3.0.2", @@ -68,17 +68,10 @@ "storybook-dark-mode": "^1.0.8", "typescript": "^4.1.3" }, - "jest": { - "preset": "jest-preset-preact", - "setupFiles": [ - "<rootDir>/tests/__mocks__/setupTests.ts" + "nyc": { + "include": [ + "**" ], - "moduleNameMapper": { - "\\.(css|less)$": "identity-obj-proxy", - "@linaria/react": "<rootDir>/tests/__mocks__/linaria.ts" - }, - "transform": { - "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga|po)$": "<rootDir>/tests/__mocks__/fileTransformer.js" - } + "exclude": [] } -}
\ No newline at end of file +} diff --git a/packages/taler-wallet-webextension/rollup.config.js b/packages/taler-wallet-webextension/rollup.config.js index 150db1fff..edbc69622 100644 --- a/packages/taler-wallet-webextension/rollup.config.js +++ b/packages/taler-wallet-webextension/rollup.config.js @@ -8,48 +8,77 @@ import nodeResolve from "@rollup/plugin-node-resolve"; import replace from "@rollup/plugin-replace"; import css from 'rollup-plugin-css-only'; import ignore from "rollup-plugin-ignore"; +import typescript from '@rollup/plugin-typescript'; + +import path from 'path'; +import fs from 'fs'; + +function fromDir(startPath, regex) { + if (!fs.existsSync(startPath)) { + return; + } + const files = fs.readdirSync(startPath); + const result = files.flatMap(file => { + const filename = path.join(startPath, file); + + const stat = fs.lstatSync(filename); + if (stat.isDirectory()) { + return fromDir(filename, regex); + } + else if (regex.test(filename)) { + return filename + } + }).filter(x => !!x) + + return result +} const makePlugins = () => [ - alias({ - entries: [ - { find: 'react', replacement: 'preact/compat' }, - { find: 'react-dom', replacement: 'preact/compat' } - ] - }), + typescript({ + outputToFilesystem: false, + }), - ignore(["module", "os"]), - nodeResolve({ - browser: true, - preferBuiltins: true, - }), + alias({ + entries: [ + { find: 'react', replacement: 'preact/compat' }, + { find: 'react-dom', replacement: 'preact/compat' } + ] + }), - //terser(), - + ignore(["module", "os"]), + nodeResolve({ + browser: true, + preferBuiltins: true, + }), - replace({ - "process.env.NODE_ENV": JSON.stringify("production"), - "__filename": "'__webextension__'", - }), + //terser(), - commonjs({ - include: [/node_modules/, /dist/], - extensions: [".js"], - ignoreGlobal: true, - sourceMap: true, - }), - json(), - image(), + replace({ + "process.env.NODE_ENV": JSON.stringify("production"), + // "__filename": "'__webextension__'", + preventAssignment: true + }), + + commonjs({ + include: [/node_modules/, /dist/], + extensions: [".js"], + ignoreGlobal: true, + sourceMap: true, + }), + + json(), + image(), + + linaria({ + sourceMap: process.env.NODE_ENV !== 'production', + }), - linaria({ - sourceMap: process.env.NODE_ENV !== 'production', - }), - ]; const webExtensionWalletEntryPoint = { - input: "lib/walletEntryPoint.js", + input: "src/walletEntryPoint.tsx", output: { file: "dist/walletEntryPoint.js", format: "iife", @@ -60,12 +89,12 @@ const webExtensionWalletEntryPoint = { ...makePlugins(), css({ output: 'walletEntryPoint.css', - }), - ], + }), + ], }; const webExtensionPopupEntryPoint = { - input: "lib/popupEntryPoint.js", + input: "src/popupEntryPoint.tsx", output: { file: "dist/popupEntryPoint.js", format: "iife", @@ -76,12 +105,12 @@ const webExtensionPopupEntryPoint = { ...makePlugins(), css({ output: 'popupEntryPoint.css', - }), - ], + }), + ], }; const webExtensionBackgroundPageScript = { - input: "lib/background.js", + input: "src/background.ts", output: { file: "dist/background.js", format: "iife", @@ -92,7 +121,7 @@ const webExtensionBackgroundPageScript = { }; const webExtensionCryptoWorker = { - input: "lib/browserWorkerEntry.js", + input: "src/browserWorkerEntry.ts", output: { file: "dist/browserWorkerEntry.js", format: "iife", @@ -102,9 +131,26 @@ const webExtensionCryptoWorker = { plugins: makePlugins(), }; +const tests = fromDir('./src', /.test.ts$/).map(test => ({ + input: test, + output: { + file: test.replace(/^src/, 'dist').replace(/\.ts$/, '.js'), + format: "iife", + exports: "none", + name: test, + }, + plugins: [ + ...makePlugins(), + css({ + output: 'walletEntryPoint.css', + }), + ], +})) + export default [ webExtensionPopupEntryPoint, webExtensionWalletEntryPoint, webExtensionBackgroundPageScript, webExtensionCryptoWorker, + ...tests, ]; diff --git a/packages/taler-wallet-webextension/run-test-in-browser.html b/packages/taler-wallet-webextension/run-test-in-browser.html new file mode 100644 index 000000000..0c7d9f6f0 --- /dev/null +++ b/packages/taler-wallet-webextension/run-test-in-browser.html @@ -0,0 +1,23 @@ +<!DOCTYPE html> +<html> + <head> + <title>Mocha Tests</title> + <link rel="stylesheet" href="node_modules/mocha/mocha.css"> + </head> + <body> + <div id="mocha"></div> + <script src="node_modules/mocha/mocha.js"></script> + <script>mocha.setup('bdd')</script> + + <!-- load code you want to test here --> + + <!-- script src="dist/stories.test.js"></script --> + <script src="dist/hooks/useTalerActionURL.test.js"></script> + <!-- load your test files here --> + + <script> + mocha.run(); + </script> + </body> +</html> + 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/tests/__mocks__/fileMocks.ts b/packages/taler-wallet-webextension/src/popup/index.stories.tsx index 0c045e9d1..c3e60c4ed 100644 --- a/packages/taler-wallet-webextension/tests/__mocks__/fileMocks.ts +++ b/packages/taler-wallet-webextension/src/popup/index.stories.tsx @@ -14,11 +14,16 @@ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ - /** +/** * * @author Sebastian Javier Marchano (sebasjm) */ -// This fixed an error related to the CSS and loading gif breaking my Jest test -// See https://facebook.github.io/jest/docs/en/webpack.html#handling-static-assets -export default 'test-file-stub'; +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}`, ), ); } diff --git a/packages/taler-wallet-webextension/tests/__mocks__/fileTransformer.js b/packages/taler-wallet-webextension/tests/__mocks__/fileTransformer.js deleted file mode 100644 index e6193f8fd..000000000 --- a/packages/taler-wallet-webextension/tests/__mocks__/fileTransformer.js +++ /dev/null @@ -1,31 +0,0 @@ -/* - 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) -*/ -// fileTransformer.js - -// eslint-disable-next-line @typescript-eslint/no-var-requires -const path = require('path'); - -module.exports = { - process(src, filename, config, options) { - return 'module.exports = ' + JSON.stringify(path.basename(filename)) + ';'; - }, -}; - diff --git a/packages/taler-wallet-webextension/tests/__mocks__/linaria.ts b/packages/taler-wallet-webextension/tests/__mocks__/linaria.ts deleted file mode 100644 index 398ac0ec1..000000000 --- a/packages/taler-wallet-webextension/tests/__mocks__/linaria.ts +++ /dev/null @@ -1,33 +0,0 @@ -/* - 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) -*/ - -/** - * Here we are mocking the linaria runtime since it should not be used in - * runtime. - */ -export const styled = new Proxy(function (tag: any) { - return jest.fn(() => `mock-styled.${tag}`); -}, { - get(o, prop) { - return o(prop); - }, -}) - diff --git a/packages/taler-wallet-webextension/tests/__mocks__/setupTests.ts b/packages/taler-wallet-webextension/tests/__mocks__/setupTests.ts deleted file mode 100644 index bae5c128f..000000000 --- a/packages/taler-wallet-webextension/tests/__mocks__/setupTests.ts +++ /dev/null @@ -1,34 +0,0 @@ -/* - 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 'regenerator-runtime/runtime' -import { configure } from 'enzyme'; -import Adapter from 'enzyme-adapter-preact-pure'; - -configure({ - adapter: new Adapter() -}); - -// Polyfill for encoding which isn't present globally in jsdom -import { TextEncoder, TextDecoder } from 'util' -global.TextEncoder = TextEncoder; -global.TextDecoder = TextDecoder; -(global as any).chrome = {};
\ No newline at end of file diff --git a/packages/taler-wallet-webextension/tests/i18n.test.tsx b/packages/taler-wallet-webextension/tests/i18n.test.tsx deleted file mode 100644 index ae8b44bb0..000000000 --- a/packages/taler-wallet-webextension/tests/i18n.test.tsx +++ /dev/null @@ -1,68 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2020 Taler Systems SA - - 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 * as test from "ava"; -import { internalSetStrings, i18n, Translate } from "@gnu-taler/taler-util"; -import { render, configure } from "enzyme"; -import { h } from 'preact'; -import Adapter from 'enzyme-adapter-preact-pure'; - -configure({ adapter: new Adapter() }); - -const testStrings = { - domain: "messages", - locale_data: { - messages: { - str1: ["foo1"], - str2: [""], - "str3 %1$s / %2$s": ["foo3 %2$s ; %1$s"], - "": { - domain: "messages", - plural_forms: "nplurals=2; plural=(n != 1);", - lang: "", - }, - }, - }, -}; - -test("str translation", (done) => { - - // Alias, so we nly use the function for lookups, not for string extranction. - const strAlias = i18n.str; - const TranslateAlias = Translate; - internalSetStrings(testStrings); - expect(strAlias`str1`).toEqual("foo1"); - expect(strAlias`str2`).toEqual("str2"); - const a = "a"; - const b = "b"; - expect(strAlias`str3 ${a} / ${b}`).toEqual("foo3 b ; a"); - const r = render(<Translate>str1</Translate>); - expect(r.text()).toEqual("foo1"); - - const r2 = render( - <TranslateAlias> - str3 <span>{a}</span> / <span>{b}</span> - </TranslateAlias>, - ); - expect(r2.text()).toEqual("foo3 b ; a"); - - done(); -}); - -// test.default("existing str translation", (t) => { -// internalSetStrings(strings); -// t.pass(); -// }); diff --git a/packages/taler-wallet-webextension/tests/stories.test.tsx b/packages/taler-wallet-webextension/tests/stories.test.tsx deleted file mode 100644 index 0122dfaeb..000000000 --- a/packages/taler-wallet-webextension/tests/stories.test.tsx +++ /dev/null @@ -1,70 +0,0 @@ -/* - 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 { mount } from 'enzyme'; -import { h } from 'preact'; - -import fs from 'fs'; - -function getFiles(dir: string, files_: string[] = []) { - const files = fs.readdirSync(dir); - for (const i in files) { - const name = dir + '/' + files[i]; - if (fs.statSync(name).isDirectory()) { - getFiles(name, files_); - } else { - files_.push(name); - } - } - return files_; -} - -const re = RegExp('.*\.stories.tsx') - -import { setupI18n } from '@gnu-taler/taler-util'; -setupI18n('en',{'en':{}}) - -it('render every story', () => { - // jest.spyOn(i18n, 'useTranslationContext').mockImplementation(() => ({ changeLanguage: () => null, lang: 'en' })); - - getFiles('./src').filter(f => re.test(f)).map(f => { - // const f = "./src/paths/instance/transfers/list/List.stories.tsx"; - // eslint-disable-next-line @typescript-eslint/no-var-requires - const s = require(`../${f}`) - - delete s.default - - Object.keys(s).forEach(k => { - const Component = s[k]; - expect(() => { - try { - let p = mount(<Component {...Component.args} /> as any) - p.mount() - p.unmount() - p.mount(); - } catch (e) { - console.log(e) - throw e - } - }).not.toThrow() //`problem rendering ${f} example ${k}` - - }) - }) -}); |