diff options
author | Sebastian <sebasjm@gmail.com> | 2021-05-07 10:38:28 -0300 |
---|---|---|
committer | Sebastian <sebasjm@gmail.com> | 2021-05-07 10:39:49 -0300 |
commit | 30f86f8748a0d9c23538e972d30270a4f1e83941 (patch) | |
tree | fa32280f2d14d0c63c298b042c7b83941fa91e8f /packages/taler-wallet-webextension | |
parent | b414de853371b98d125a92a4d9e9578be9b0f0d5 (diff) |
migrate to preact
Diffstat (limited to 'packages/taler-wallet-webextension')
20 files changed, 228 insertions, 122 deletions
diff --git a/packages/taler-wallet-webextension/package.json b/packages/taler-wallet-webextension/package.json index 69c504006..f9756fd32 100644 --- a/packages/taler-wallet-webextension/package.json +++ b/packages/taler-wallet-webextension/package.json @@ -9,34 +9,53 @@ "private": false, "scripts": { "clean": "rimraf dist lib tsconfig.tsbuildinfo", + "test": "jest ./tests", "compile": "tsc && rollup -c" }, "dependencies": { - "moment": "^2.29.1", - "@gnu-taler/taler-wallet-core": "workspace:*", "@gnu-taler/taler-util": "workspace:*", + "@gnu-taler/taler-wallet-core": "workspace:*", + "preact": "^10.5.13", + "preact-router": "^3.2.1", "tslib": "^2.1.0" }, "devDependencies": { + "@babel/core": "^7.14.0", + "@babel/plugin-transform-react-jsx-source": "^7.12.13", + "@babel/preset-typescript": "^7.13.0", "@rollup/plugin-commonjs": "^17.0.0", "@rollup/plugin-json": "^4.1.0", "@rollup/plugin-node-resolve": "^11.1.0", "@rollup/plugin-replace": "^2.3.4", + "@testing-library/preact": "^2.0.1", "@types/chrome": "^0.0.128", - "@types/enzyme": "^3.10.8", - "@types/enzyme-adapter-react-16": "^1.0.6", + "@types/jest": "^26.0.23", "@types/node": "^14.14.22", - "@types/react": "^17.0.0", - "@types/react-dom": "^17.0.0", "ava": "3.15.0", + "babel-plugin-transform-react-jsx": "^6.24.1", "enzyme": "^3.11.0", - "react": "^17.0.1", - "react-dom": "^17.0.1", + "enzyme-adapter-preact-pure": "^3.1.0", + "jest": "^26.6.3", + "jest-preset-preact": "^4.0.3", + "preact-cli": "^3.0.5", + "preact-render-to-string": "^5.1.19", "rimraf": "^3.0.2", "rollup": "^2.37.1", "rollup-plugin-ignore": "^1.0.9", "rollup-plugin-sourcemaps": "^0.6.3", "rollup-plugin-terser": "^7.0.2", "typescript": "^4.1.3" + }, + "jest": { + "preset": "jest-preset-preact", + "setupFiles": [ + "<rootDir>/tests/__mocks__/setupTests.ts" + ], + "moduleNameMapper": { + "\\.(css|less)$": "identity-obj-proxy" + }, + "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" + } } } diff --git a/packages/taler-wallet-webextension/src/browserHttpLib.ts b/packages/taler-wallet-webextension/src/browserHttpLib.ts index 5c27becb2..fe12289d2 100644 --- a/packages/taler-wallet-webextension/src/browserHttpLib.ts +++ b/packages/taler-wallet-webextension/src/browserHttpLib.ts @@ -24,7 +24,6 @@ import { HttpRequestOptions, HttpResponse, Headers, - bytesToString, } from "@gnu-taler/taler-wallet-core"; import { TalerErrorCode } from "@gnu-taler/taler-util"; diff --git a/packages/taler-wallet-webextension/src/i18n.tsx b/packages/taler-wallet-webextension/src/i18n.tsx index 86c712b8c..83de768c4 100644 --- a/packages/taler-wallet-webextension/src/i18n.tsx +++ b/packages/taler-wallet-webextension/src/i18n.tsx @@ -21,9 +21,9 @@ /** * Imports */ -import React from "react"; import * as i18nCore from "@gnu-taler/taler-wallet-core"; +import { Component, ComponentChildren, h, JSX, toChildArray, VNode } from "preact"; /** * Convert template strings to a msgid */ @@ -50,7 +50,7 @@ interface TranslateSwitchProps { function stringifyChildren(children: any): string { let n = 1; - const ss = React.Children.map(children, (c) => { + const ss = toChildArray(children).map((c) => { if (typeof c === "string") { return c; } @@ -76,10 +76,10 @@ interface TranslateProps { function getTranslatedChildren( translation: string, - children: React.ReactNode, -): React.ReactNode[] { + children: ComponentChildren, +): ComponentChildren { const tr = translation.split(/%(\d+)\$s/); - const childArray = React.Children.toArray(children); + const childArray = toChildArray(children); // Merge consecutive string children. const placeholderChildren = []; for (let i = 0; i < childArray.length; i++) { @@ -117,15 +117,15 @@ function getTranslatedChildren( * </Translate> * ``` */ -export class Translate extends React.Component<TranslateProps, {}> { - render(): JSX.Element { +export class Translate extends Component<TranslateProps, any> { + render() { const s = stringifyChildren(this.props.children); const translation: string = i18nCore.jed.ngettext(s, s, 1); const result = getTranslatedChildren(translation, this.props.children); if (!this.props.wrap) { return <div>{result}</div>; } - return React.createElement(this.props.wrap, this.props.wrapProps, result); + return h(this.props.wrap, this.props.wrapProps, result); } } @@ -141,16 +141,16 @@ export class Translate extends React.Component<TranslateProps, {}> { * </TranslateSwitch> * ``` */ -export class TranslateSwitch extends React.Component< +export class TranslateSwitch extends Component< TranslateSwitchProps, void > { render(): JSX.Element { - let singular: React.ReactElement<TranslationPluralProps> | undefined; - let plural: React.ReactElement<TranslationPluralProps> | undefined; + let singular: VNode<TranslationPluralProps> | undefined; + let plural: VNode<TranslationPluralProps> | undefined; const children = this.props.children; if (children) { - React.Children.forEach(children, (child: any) => { + toChildArray(children).forEach((child: any) => { if (child.type === TranslatePlural) { plural = child; } @@ -161,7 +161,7 @@ export class TranslateSwitch extends React.Component< } if (!singular || !plural) { console.error("translation not found"); - return React.createElement("span", {}, ["translation not found"]); + return h("span", {}, ["translation not found"]); } singular.props.target = this.props.target; plural.props.target = this.props.target; @@ -178,7 +178,7 @@ interface TranslationPluralProps { /** * See [[TranslateSwitch]]. */ -export class TranslatePlural extends React.Component< +export class TranslatePlural extends Component< TranslationPluralProps, void > { @@ -193,7 +193,7 @@ export class TranslatePlural extends React.Component< /** * See [[TranslateSwitch]]. */ -export class TranslateSingular extends React.Component< +export class TranslateSingular extends Component< TranslationPluralProps, void > { diff --git a/packages/taler-wallet-webextension/src/pageEntryPoint.ts b/packages/taler-wallet-webextension/src/pageEntryPoint.ts index 028ba1058..06dc594c5 100644 --- a/packages/taler-wallet-webextension/src/pageEntryPoint.ts +++ b/packages/taler-wallet-webextension/src/pageEntryPoint.ts @@ -20,7 +20,7 @@ * @author Florian Dold <dold@taler.net> */ -import ReactDOM from "react-dom"; +import {render} from "preact"; import { createPopup } from "./pages/popup"; import { createWithdrawPage } from "./pages/withdraw"; import { createWelcomePage } from "./pages/welcome"; @@ -63,7 +63,7 @@ function main(): void { if (!container) { throw Error("container not found, can't mount page contents"); } - ReactDOM.render(mainElement, container); + render(mainElement, container); } catch (e) { console.error("got error", e); document.body.innerText = `Fatal error: "${e.message}". Please report this bug at https://bugs.gnunet.org/.`; diff --git a/packages/taler-wallet-webextension/src/pages/pay.tsx b/packages/taler-wallet-webextension/src/pages/pay.tsx index 9c6b10951..80d846d67 100644 --- a/packages/taler-wallet-webextension/src/pages/pay.tsx +++ b/packages/taler-wallet-webextension/src/pages/pay.tsx @@ -27,7 +27,7 @@ import * as i18n from "../i18n"; import { renderAmount, ProgressButton } from "../renderHtml"; import * as wxApi from "../wxApi"; -import React, { useState, useEffect } from "react"; +import { useState, useEffect } from "preact/hooks"; import { getJsonI18n } from "@gnu-taler/taler-wallet-core"; import { @@ -39,10 +39,11 @@ import { ContractTerms, ConfirmPayResultType, } from "@gnu-taler/taler-util"; +import { JSX, VNode } from "preact"; function TalerPayDialog({ talerPayUri }: { talerPayUri: string }): JSX.Element { - const [payStatus, setPayStatus] = useState<PreparePayResult | undefined>(); - const [payResult, setPayResult] = useState<ConfirmPayResult | undefined>(); + const [payStatus, setPayStatus] = useState<PreparePayResult | undefined>(undefined); + const [payResult, setPayResult] = useState<ConfirmPayResult | undefined>(undefined); const [payErrMsg, setPayErrMsg] = useState<string | undefined>(""); const [numTries, setNumTries] = useState(0); const [loading, setLoading] = useState(false); @@ -66,8 +67,8 @@ function TalerPayDialog({ talerPayUri }: { talerPayUri: string }): JSX.Element { } if (payStatus.status === PreparePayResultType.PaymentPossible) { - let amountRaw = Amounts.parseOrThrow(payStatus.amountRaw); - let amountEffective: AmountJson = Amounts.parseOrThrow( + const amountRaw = Amounts.parseOrThrow(payStatus.amountRaw); + const amountEffective: AmountJson = Amounts.parseOrThrow( payStatus.amountEffective, ); totalFees = Amounts.sub(amountEffective, amountRaw).amount; @@ -95,7 +96,7 @@ function TalerPayDialog({ talerPayUri }: { talerPayUri: string }): JSX.Element { } } - let contractTerms: ContractTerms = payStatus.contractTerms; + const contractTerms: ContractTerms = payStatus.contractTerms; if (!contractTerms) { return ( @@ -105,7 +106,7 @@ function TalerPayDialog({ talerPayUri }: { talerPayUri: string }): JSX.Element { ); } - let merchantName: React.ReactElement; + let merchantName: VNode; if (contractTerms.merchant && contractTerms.merchant.name) { merchantName = <strong>{contractTerms.merchant.name}</strong>; } else { @@ -200,7 +201,7 @@ function TalerPayDialog({ talerPayUri }: { talerPayUri: string }): JSX.Element { ) : ( <div> <ProgressButton - loading={loading} + isLoading={loading} disabled={insufficientBalance} onClick={() => doPayment()} > diff --git a/packages/taler-wallet-webextension/src/pages/payback.tsx b/packages/taler-wallet-webextension/src/pages/payback.tsx index 5d42f5f47..4233b1f96 100644 --- a/packages/taler-wallet-webextension/src/pages/payback.tsx +++ b/packages/taler-wallet-webextension/src/pages/payback.tsx @@ -14,6 +14,8 @@ TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ +import { JSX } from "preact/jsx-runtime"; + /** * View and edit auditors. * @@ -23,7 +25,6 @@ /** * Imports. */ -import * as React from "react"; export function makePaybackPage(): JSX.Element { return <div>not implemented</div>; diff --git a/packages/taler-wallet-webextension/src/pages/popup.tsx b/packages/taler-wallet-webextension/src/pages/popup.tsx index 4d12d9a83..cf76044ce 100644 --- a/packages/taler-wallet-webextension/src/pages/popup.tsx +++ b/packages/taler-wallet-webextension/src/pages/popup.tsx @@ -41,18 +41,18 @@ import { amountFractionalBase, } from "@gnu-taler/taler-util"; -import { abbrev, renderAmount, PageLink } from "../renderHtml"; +import { renderAmount, PageLink } from "../renderHtml"; import * as wxApi from "../wxApi"; -import React, { Fragment, useState, useEffect } from "react"; +import { useState, useEffect } from "preact/hooks"; -import moment from "moment"; import { PermissionsCheckbox } from "./welcome"; +import { JSXInternal } from "preact/src/jsx"; +import { Component, ComponentChild, ComponentChildren, JSX, toChildArray, VNode } from "preact"; // FIXME: move to newer react functions -/* eslint-disable react/no-deprecated */ -class Router extends React.Component<any, any> { +class Router extends Component<any, any> { static setRoute(s: string): void { window.location.hash = s; } @@ -85,21 +85,21 @@ class Router extends React.Component<any, any> { render(): JSX.Element { const route = window.location.hash.substring(1); console.log("rendering route", route); - let defaultChild: React.ReactChild | null = null; - let foundChild: React.ReactChild | null = null; - React.Children.forEach(this.props.children, (child) => { + let defaultChild: ComponentChild | null = null; + let foundChild: ComponentChild | null = null; + toChildArray(this.props.children).forEach((child) => { const childProps: any = (child as any).props; if (!childProps) { return; } if (childProps.default) { - defaultChild = child as React.ReactChild; + defaultChild = child; } if (childProps.route === route) { - foundChild = child as React.ReactChild; + foundChild = child; } }); - const c: React.ReactChild | null = foundChild || defaultChild; + const c: ComponentChild | null = foundChild || defaultChild; if (!c) { throw Error("unknown route"); } @@ -110,7 +110,7 @@ class Router extends React.Component<any, any> { interface TabProps { target: string; - children?: React.ReactNode; + children?: ComponentChildren; } function Tab(props: TabProps): JSX.Element { @@ -118,7 +118,7 @@ function Tab(props: TabProps): JSX.Element { if (props.target === Router.getRoute()) { cssClass = "active"; } - const onClick = (e: React.MouseEvent<HTMLAnchorElement>): void => { + const onClick = (e: JSXInternal.TargetedMouseEvent<HTMLAnchorElement>): void => { Router.setRoute(props.target); e.preventDefault(); }; @@ -129,7 +129,7 @@ function Tab(props: TabProps): JSX.Element { ); } -class WalletNavBar extends React.Component<any, any> { +class WalletNavBar extends Component<any, any> { private cancelSubscription: any; componentWillMount(): void { @@ -179,7 +179,7 @@ function EmptyBalanceView(): JSX.Element { ); } -class WalletBalanceView extends React.Component<any, any> { +class WalletBalanceView extends Component<any, any> { private balance?: BalancesResponse; private gotError = false; private canceler: (() => void) | undefined = undefined; @@ -323,7 +323,7 @@ function TransactionAmount(props: TransactionAmountProps): JSX.Element { case "unknown": sign = ""; } - const style: React.CSSProperties = { + const style: JSX.AllCSSProperties = { marginLeft: "auto", display: "flex", flexDirection: "column", @@ -476,7 +476,7 @@ function TransactionItem(props: { tx: Transaction }): JSX.Element { function WalletHistory(props: any): JSX.Element { const [transactions, setTransactions] = useState< TransactionsResponse | undefined - >(); + >(undefined); useEffect(() => { const fetchData = async (): Promise<void> => { @@ -484,7 +484,6 @@ function WalletHistory(props: any): JSX.Element { setTransactions(res); }; fetchData(); - // eslint-disable-next-line react-hooks/exhaustive-deps }, []); if (!transactions) { @@ -495,14 +494,14 @@ function WalletHistory(props: any): JSX.Element { return ( <div> - {txs.map((tx) => ( - <TransactionItem tx={tx} /> + {txs.map((tx,i) => ( + <TransactionItem key={i} tx={tx} /> ))} </div> ); } -class WalletSettings extends React.Component<any, any> { +class WalletSettings extends Component<any, any> { render(): JSX.Element { return ( <div> @@ -522,14 +521,14 @@ function reload(): void { } } -function confirmReset(): void { +async function confirmReset(): Promise<void> { if ( confirm( "Do you want to IRREVOCABLY DESTROY everything inside your" + " wallet and LOSE ALL YOUR COINS?", ) ) { - wxApi.resetDb(); + await wxApi.resetDb(); window.close(); } } @@ -554,14 +553,14 @@ function openExtensionPage(page: string) { }; } -function openTab(page: string) { - return (evt: React.SyntheticEvent<any>) => { - evt.preventDefault(); - chrome.tabs.create({ - url: page, - }); - }; -} +// function openTab(page: string) { +// return (evt: React.SyntheticEvent<any>) => { +// evt.preventDefault(); +// chrome.tabs.create({ +// url: page, +// }); +// }; +// } function makeExtensionUrlWithParams( url: string, diff --git a/packages/taler-wallet-webextension/src/pages/refund.tsx b/packages/taler-wallet-webextension/src/pages/refund.tsx index 8096378fc..6525f68c6 100644 --- a/packages/taler-wallet-webextension/src/pages/refund.tsx +++ b/packages/taler-wallet-webextension/src/pages/refund.tsx @@ -20,17 +20,18 @@ * @author Florian Dold */ -import React, { useEffect, useState } from "react"; import * as wxApi from "../wxApi"; import { AmountView } from "../renderHtml"; import { - PurchaseDetails, ApplyRefundResponse, Amounts, } from "@gnu-taler/taler-util"; +// import { h } from 'preact'; +import { useEffect, useState } from "preact/hooks"; +import { JSX } from "preact/jsx-runtime"; function RefundStatusView(props: { talerRefundUri: string }): JSX.Element { - const [applyResult, setApplyResult] = useState<ApplyRefundResponse>(); + const [applyResult, setApplyResult] = useState<ApplyRefundResponse|undefined>(undefined); const [errMsg, setErrMsg] = useState<string | undefined>(undefined); useEffect(() => { diff --git a/packages/taler-wallet-webextension/src/pages/reset-required.tsx b/packages/taler-wallet-webextension/src/pages/reset-required.tsx index 0ef5fe8b7..7f2676263 100644 --- a/packages/taler-wallet-webextension/src/pages/reset-required.tsx +++ b/packages/taler-wallet-webextension/src/pages/reset-required.tsx @@ -20,8 +20,7 @@ * @author Florian Dold */ -import * as React from "react"; - +import { Component, JSX } from "preact"; import * as wxApi from "../wxApi"; interface State { @@ -36,7 +35,7 @@ interface State { resetRequired: boolean; } -class ResetNotification extends React.Component<any, State> { +class ResetNotification extends Component<any, State> { constructor(props: any) { super(props); this.state = { checked: false, resetRequired: true }; @@ -50,7 +49,7 @@ class ResetNotification extends React.Component<any, State> { if (this.state.resetRequired) { return ( <div> - <h1>Manual Reset Reqired</h1> + <h1>Manual Reset Required</h1> <p> The wallet's database in your browser is incompatible with the{" "} currently installed wallet. Please reset manually. @@ -63,7 +62,9 @@ class ResetNotification extends React.Component<any, State> { id="check" type="checkbox" checked={this.state.checked} - onChange={(e) => this.setState({ checked: e.target.checked })} + onChange={() => { + this.setState(prev => ({ checked: prev.checked })) + }} />{" "} <label htmlFor="check"> I understand that I will lose all my data diff --git a/packages/taler-wallet-webextension/src/pages/return-coins.tsx b/packages/taler-wallet-webextension/src/pages/return-coins.tsx index e8cf8c9dd..2273d1454 100644 --- a/packages/taler-wallet-webextension/src/pages/return-coins.tsx +++ b/packages/taler-wallet-webextension/src/pages/return-coins.tsx @@ -14,6 +14,8 @@ TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ +import { JSX } from "preact/jsx-runtime"; + /** * Return coins to own bank account. * @@ -23,8 +25,6 @@ /** * Imports. */ -import * as React from "react"; - export function createReturnCoinsPage(): JSX.Element { return <span>Not implemented yet.</span>; } diff --git a/packages/taler-wallet-webextension/src/pages/tip.tsx b/packages/taler-wallet-webextension/src/pages/tip.tsx index b1ac27228..65ddb3734 100644 --- a/packages/taler-wallet-webextension/src/pages/tip.tsx +++ b/packages/taler-wallet-webextension/src/pages/tip.tsx @@ -20,17 +20,17 @@ * @author Florian Dold <dold@taler.net> */ -import * as React from "react"; -import { useEffect, useState } from "react"; +import { useEffect, useState } from "preact/hooks"; import { PrepareTipResult } from "@gnu-taler/taler-util"; import { AmountView } from "../renderHtml"; import * as wxApi from "../wxApi"; +import { JSX } from "preact/jsx-runtime"; function TalerTipDialog({ talerTipUri }: { talerTipUri: string }): JSX.Element { const [updateCounter, setUpdateCounter] = useState<number>(0); const [prepareTipResult, setPrepareTipResult] = useState< PrepareTipResult | undefined - >(); + >(undefined); const [tipIgnored, setTipIgnored] = useState(false); diff --git a/packages/taler-wallet-webextension/src/pages/welcome.tsx b/packages/taler-wallet-webextension/src/pages/welcome.tsx index dd10ac13c..54819558c 100644 --- a/packages/taler-wallet-webextension/src/pages/welcome.tsx +++ b/packages/taler-wallet-webextension/src/pages/welcome.tsx @@ -20,13 +20,14 @@ * @author Florian Dold */ -import React, { useState, useEffect } from "react"; +import { useState, useEffect } from "preact/hooks"; import { getDiagnostics } from "../wxApi"; import { PageLink } from "../renderHtml"; import * as wxApi from "../wxApi"; import { getPermissionsApi } from "../compat"; import { extendedPermissions } from "../permissions"; import { WalletDiagnostics } from "@gnu-taler/taler-util"; +import { JSX } from "preact/jsx-runtime"; function Diagnostics(): JSX.Element | null { const [timedOut, setTimedOut] = useState(false); @@ -102,9 +103,9 @@ export function PermissionsCheckbox(): JSX.Element { const [extendedPermissionsEnabled, setExtendedPermissionsEnabled] = useState( false, ); - async function handleExtendedPerm(requestedVal: boolean): Promise<void> { + async function handleExtendedPerm(): Promise<void> { let nextVal: boolean | undefined; - if (requestedVal) { + if (extendedPermissionsEnabled) { const granted = await new Promise<boolean>((resolve, reject) => { // We set permissions here, since apparently FF wants this to be done // as the result of an input event ... @@ -141,7 +142,7 @@ export function PermissionsCheckbox(): JSX.Element { <div> <input checked={extendedPermissionsEnabled} - onChange={(x) => handleExtendedPerm(x.target.checked)} + onChange={() => handleExtendedPerm()} type="checkbox" id="checkbox-perm" style={{ width: "1.5em", height: "1.5em", verticalAlign: "middle" }} diff --git a/packages/taler-wallet-webextension/src/pages/withdraw.tsx b/packages/taler-wallet-webextension/src/pages/withdraw.tsx index c4a02817c..1d628be22 100644 --- a/packages/taler-wallet-webextension/src/pages/withdraw.tsx +++ b/packages/taler-wallet-webextension/src/pages/withdraw.tsx @@ -25,19 +25,20 @@ import * as i18n from "../i18n"; import { renderAmount } from "../renderHtml"; -import React, { useState, useEffect } from "react"; +import { useState, useEffect } from "preact/hooks"; import { acceptWithdrawal, onUpdateNotification, getWithdrawalDetailsForUri, } from "../wxApi"; import { WithdrawUriInfoResponse } from "@gnu-taler/taler-util"; +import { JSX } from "preact/jsx-runtime"; function WithdrawalDialog(props: { talerWithdrawUri: string }): JSX.Element { - const [details, setDetails] = useState<WithdrawUriInfoResponse | undefined>(); + const [details, setDetails] = useState<WithdrawUriInfoResponse | undefined>(undefined); const [selectedExchange, setSelectedExchange] = useState< string | undefined - >(); + >(undefined); const talerWithdrawUri = props.talerWithdrawUri; const [cancelled, setCancelled] = useState(false); const [selecting, setSelecting] = useState(false); @@ -48,7 +49,6 @@ function WithdrawalDialog(props: { talerWithdrawUri: string }): JSX.Element { return onUpdateNotification(() => { setUpdateCounter(updateCounter + 1); }); - // eslint-disable-next-line react-hooks/exhaustive-deps }, []); useEffect(() => { diff --git a/packages/taler-wallet-webextension/src/renderHtml.tsx b/packages/taler-wallet-webextension/src/renderHtml.tsx index 3e66e5c5d..5574e96ea 100644 --- a/packages/taler-wallet-webextension/src/renderHtml.tsx +++ b/packages/taler-wallet-webextension/src/renderHtml.tsx @@ -23,12 +23,13 @@ /** * Imports. */ -import React from "react"; import { AmountJson, Amounts, amountFractionalBase, } from "@gnu-taler/taler-util"; +import { Component, ComponentChildren, JSX } from "preact"; +import { JSXInternal } from "preact/src/jsx"; /** * Render amount as HTML, which non-breaking space between @@ -87,7 +88,7 @@ interface CollapsibleProps { * Component that shows/hides its children when clicking * a heading. */ -export class Collapsible extends React.Component< +export class Collapsible extends Component< CollapsibleProps, CollapsibleState > { @@ -139,24 +140,18 @@ export function ExpanderText({ text }: ExpanderTextProps): JSX.Element { return <span>{text}</span>; } -export interface LoadingButtonProps { - loading: boolean; +export interface LoadingButtonProps extends JSX.HTMLAttributes<HTMLButtonElement> { + isLoading: boolean; } -export function ProgressButton( - props: React.PropsWithChildren<LoadingButtonProps> & - React.DetailedHTMLProps< - React.ButtonHTMLAttributes<HTMLButtonElement>, - HTMLButtonElement - >, -): JSX.Element { +export function ProgressButton({isLoading, ...rest}: LoadingButtonProps): JSX.Element { return ( <button className="pure-button pure-button-primary" type="button" - {...props} + {...rest} > - {props.loading ? ( + {isLoading ? ( <span> <object className="svg-icon svg-baseline" @@ -164,13 +159,13 @@ export function ProgressButton( /> </span> ) : null}{" "} - {props.children} + {rest.children} </button> ); } export function PageLink( - props: React.PropsWithChildren<{ pageName: string }>, + props: { pageName: string, children?: ComponentChildren }, ): JSX.Element { const url = chrome.extension.getURL(`/${props.pageName}`); return ( diff --git a/packages/taler-wallet-webextension/src/wxBackend.ts b/packages/taler-wallet-webextension/src/wxBackend.ts index 62cedc9a9..22dd2c0e3 100644 --- a/packages/taler-wallet-webextension/src/wxBackend.ts +++ b/packages/taler-wallet-webextension/src/wxBackend.ts @@ -146,7 +146,7 @@ async function dispatch( } break; } - default: + default: { const w = currentWallet; if (!w) { r = { @@ -163,6 +163,7 @@ async function dispatch( } r = await w.handleCoreApiRequest(req.operation, req.id, req.payload); break; + } } try { diff --git a/packages/taler-wallet-webextension/tests/__mocks__/fileMocks.ts b/packages/taler-wallet-webextension/tests/__mocks__/fileMocks.ts new file mode 100644 index 000000000..0c045e9d1 --- /dev/null +++ b/packages/taler-wallet-webextension/tests/__mocks__/fileMocks.ts @@ -0,0 +1,24 @@ +/* + 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) + */ + +// 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'; diff --git a/packages/taler-wallet-webextension/tests/__mocks__/fileTransformer.js b/packages/taler-wallet-webextension/tests/__mocks__/fileTransformer.js new file mode 100644 index 000000000..e6193f8fd --- /dev/null +++ b/packages/taler-wallet-webextension/tests/__mocks__/fileTransformer.js @@ -0,0 +1,31 @@ +/* + 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__/setupTests.ts b/packages/taler-wallet-webextension/tests/__mocks__/setupTests.ts new file mode 100644 index 000000000..841e0babc --- /dev/null +++ b/packages/taler-wallet-webextension/tests/__mocks__/setupTests.ts @@ -0,0 +1,33 @@ +/* + 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
\ No newline at end of file diff --git a/packages/taler-wallet-webextension/src/i18n-test.tsx b/packages/taler-wallet-webextension/tests/i18n.test.tsx index e17a455ce..adbb6d7d8 100644 --- a/packages/taler-wallet-webextension/src/i18n-test.tsx +++ b/packages/taler-wallet-webextension/tests/i18n.test.tsx @@ -14,12 +14,11 @@ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ -import test from "ava"; -import { internalSetStrings, str, Translate, strings } from "./i18n"; -import React from "react"; -import { render } from "enzyme"; -import { configure } from "enzyme"; -import Adapter from "enzyme-adapter-react-16"; +// import * as test from "ava"; +import { internalSetStrings, str, Translate } from "../src/i18n"; +import { render, configure } from "enzyme"; +import Adapter from 'enzyme-adapter-preact-pure'; +import { h } from "preact"; configure({ adapter: new Adapter() }); @@ -39,30 +38,31 @@ const testStrings = { }, }; -test("str translation", (t) => { +test("str translation", (done) => { + // Alias, so we nly use the function for lookups, not for string extranction. const strAlias = str; const TranslateAlias = Translate; internalSetStrings(testStrings); - t.is(strAlias`str1`, "foo1"); - t.is(strAlias`str2`, "str2"); + expect(strAlias`str1`).toEqual("foo1"); + expect(strAlias`str2`).toEqual("str2"); const a = "a"; const b = "b"; - t.is(strAlias`str3 ${a} / ${b}`, "foo3 b ; a"); + expect(strAlias`str3 ${a} / ${b}`).toEqual("foo3 b ; a"); const r = render(<TranslateAlias>str1</TranslateAlias>); - t.is(r.text(), "foo1"); + expect(r.text()).toEqual("foo1"); const r2 = render( <TranslateAlias> str3 <span>{a}</span> / <span>{b}</span> </TranslateAlias>, ); - t.is(r2.text(), "foo3 b ; a"); + expect(r2.text()).toEqual("foo3 b ; a"); - t.pass(); + done(); }); -test("existing str translation", (t) => { - internalSetStrings(strings); - t.pass(); -}); +// test.default("existing str translation", (t) => { +// internalSetStrings(strings); +// t.pass(); +// }); diff --git a/packages/taler-wallet-webextension/tsconfig.json b/packages/taler-wallet-webextension/tsconfig.json index 417a73b1b..cff3d8857 100644 --- a/packages/taler-wallet-webextension/tsconfig.json +++ b/packages/taler-wallet-webextension/tsconfig.json @@ -2,9 +2,9 @@ "compilerOptions": { "composite": true, "lib": ["es6", "DOM"], - "jsx": "react", + "jsx": "react-jsx", + "jsxImportSource": "preact", "moduleResolution": "Node", - "reactNamespace": "React", "module": "ESNext", "target": "ES6", "noImplicitAny": true, |