summaryrefslogtreecommitdiff
path: root/packages/taler-wallet-webextension/src/cta
diff options
context:
space:
mode:
authorSebastian <sebasjm@gmail.com>2022-12-15 17:11:24 -0300
committerSebastian <sebasjm@gmail.com>2022-12-15 17:11:24 -0300
commitf93bd51499ed34844b666bf6d333227adf4368bf (patch)
treeed3cf0c38b7db54276436d1743a6085c94f71977 /packages/taler-wallet-webextension/src/cta
parent8d8d71807df6b775e5b0335eb1b2526a56d42ac6 (diff)
downloadwallet-core-f93bd51499ed34844b666bf6d333227adf4368bf.tar.gz
wallet-core-f93bd51499ed34844b666bf6d333227adf4368bf.tar.bz2
wallet-core-f93bd51499ed34844b666bf6d333227adf4368bf.zip
wxApi from context and using the new testing sdk
Diffstat (limited to 'packages/taler-wallet-webextension/src/cta')
-rw-r--r--packages/taler-wallet-webextension/src/cta/Deposit/index.ts3
-rw-r--r--packages/taler-wallet-webextension/src/cta/Deposit/state.ts4
-rw-r--r--packages/taler-wallet-webextension/src/cta/Deposit/test.ts80
-rw-r--r--packages/taler-wallet-webextension/src/cta/InvoiceCreate/index.ts3
-rw-r--r--packages/taler-wallet-webextension/src/cta/InvoiceCreate/state.ts8
-rw-r--r--packages/taler-wallet-webextension/src/cta/InvoicePay/index.ts5
-rw-r--r--packages/taler-wallet-webextension/src/cta/InvoicePay/state.ts4
-rw-r--r--packages/taler-wallet-webextension/src/cta/Payment/index.ts5
-rw-r--r--packages/taler-wallet-webextension/src/cta/Payment/state.ts4
-rw-r--r--packages/taler-wallet-webextension/src/cta/Payment/test.ts404
-rw-r--r--packages/taler-wallet-webextension/src/cta/Recovery/index.ts3
-rw-r--r--packages/taler-wallet-webextension/src/cta/Recovery/state.ts6
-rw-r--r--packages/taler-wallet-webextension/src/cta/Refund/index.ts5
-rw-r--r--packages/taler-wallet-webextension/src/cta/Refund/state.ts4
-rw-r--r--packages/taler-wallet-webextension/src/cta/Refund/test.ts349
-rw-r--r--packages/taler-wallet-webextension/src/cta/Tip/index.ts5
-rw-r--r--packages/taler-wallet-webextension/src/cta/Tip/state.ts4
-rw-r--r--packages/taler-wallet-webextension/src/cta/Tip/test.ts271
-rw-r--r--packages/taler-wallet-webextension/src/cta/TransferCreate/index.ts3
-rw-r--r--packages/taler-wallet-webextension/src/cta/TransferCreate/state.ts12
-rw-r--r--packages/taler-wallet-webextension/src/cta/TransferPickup/index.ts5
-rw-r--r--packages/taler-wallet-webextension/src/cta/TransferPickup/state.ts6
-rw-r--r--packages/taler-wallet-webextension/src/cta/Withdraw/index.ts7
-rw-r--r--packages/taler-wallet-webextension/src/cta/Withdraw/state.ts20
-rw-r--r--packages/taler-wallet-webextension/src/cta/Withdraw/test.ts230
25 files changed, 553 insertions, 897 deletions
diff --git a/packages/taler-wallet-webextension/src/cta/Deposit/index.ts b/packages/taler-wallet-webextension/src/cta/Deposit/index.ts
index 539709821..9ff3ddd1d 100644
--- a/packages/taler-wallet-webextension/src/cta/Deposit/index.ts
+++ b/packages/taler-wallet-webextension/src/cta/Deposit/index.ts
@@ -19,7 +19,6 @@ import { Loading } from "../../components/Loading.js";
import { HookError } from "../../hooks/useAsyncAsHook.js";
import { ButtonHandler } from "../../mui/handlers.js";
import { compose, StateViewMap } from "../../utils/index.js";
-import { wxApi } from "../../wxApi.js";
import { useComponentState } from "./state.js";
import { LoadingUriView, ReadyView } from "./views.js";
@@ -64,6 +63,6 @@ const viewMapping: StateViewMap<State> = {
export const DepositPage = compose(
"Deposit",
- (p: Props) => useComponentState(p, wxApi),
+ (p: Props) => useComponentState(p),
viewMapping,
);
diff --git a/packages/taler-wallet-webextension/src/cta/Deposit/state.ts b/packages/taler-wallet-webextension/src/cta/Deposit/state.ts
index 77e918ca9..fbcd107ef 100644
--- a/packages/taler-wallet-webextension/src/cta/Deposit/state.ts
+++ b/packages/taler-wallet-webextension/src/cta/Deposit/state.ts
@@ -16,14 +16,14 @@
import { Amounts } from "@gnu-taler/taler-util";
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
+import { useBackendContext } from "../../context/backend.js";
import { useAsyncAsHook } from "../../hooks/useAsyncAsHook.js";
-import { wxApi } from "../../wxApi.js";
import { Props, State } from "./index.js";
export function useComponentState(
{ talerDepositUri, amountStr, cancel, onSuccess }: Props,
- api: typeof wxApi,
): State {
+ const api = useBackendContext()
const info = useAsyncAsHook(async () => {
if (!talerDepositUri) throw Error("ERROR_NO-URI-FOR-DEPOSIT");
if (!amountStr) throw Error("ERROR_NO-AMOUNT-FOR-DEPOSIT");
diff --git a/packages/taler-wallet-webextension/src/cta/Deposit/test.ts b/packages/taler-wallet-webextension/src/cta/Deposit/test.ts
index a5bfed4a8..1c8d4708d 100644
--- a/packages/taler-wallet-webextension/src/cta/Deposit/test.ts
+++ b/packages/taler-wallet-webextension/src/cta/Deposit/test.ts
@@ -20,16 +20,18 @@
*/
import { Amounts } from "@gnu-taler/taler-util";
-import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
import { expect } from "chai";
-import { mountHook } from "../../test-utils.js";
import { createWalletApiMock } from "../../test-utils.js";
import { useComponentState } from "./state.js";
+import { tests } from "@gnu-taler/web-util/lib/index.browser";
+import { Props } from "./index.js";
+import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
describe("Deposit CTA states", () => {
it("should tell the user that the URI is missing", async () => {
- const { handler, mock } = createWalletApiMock();
- const props = {
+ const { handler, TestingContext } = createWalletApiMock();
+
+ const props: Props = {
talerDepositUri: undefined,
amountStr: undefined,
cancel: async () => {
@@ -39,32 +41,28 @@ describe("Deposit CTA states", () => {
null;
},
};
- const { pullLastResultOrThrow, waitForStateUpdate, assertNoPendingUpdate } =
- mountHook(() => useComponentState(props, mock));
- {
- const { status } = pullLastResultOrThrow();
- expect(status).equals("loading");
- }
-
- expect(await waitForStateUpdate()).true;
-
- {
- const { status, error } = pullLastResultOrThrow();
+ const hookBehavior = await tests.hookBehaveLikeThis(useComponentState, props, [
+ ({ status }) => {
+ expect(status).equals("loading");
+ },
+ ({ status, error }) => {
+ expect(status).equals("loading-uri");
- expect(status).equals("loading-uri");
+ if (!error) expect.fail();
+ if (!error.hasError) expect.fail();
+ if (error.operational) expect.fail();
+ expect(error.message).eq("ERROR_NO-URI-FOR-DEPOSIT");
+ },
+ ], TestingContext)
- if (!error) expect.fail();
- if (!error.hasError) expect.fail();
- if (error.operational) expect.fail();
- expect(error.message).eq("ERROR_NO-URI-FOR-DEPOSIT");
- }
- await assertNoPendingUpdate();
+ expect(hookBehavior).deep.equal({ result: "ok" })
expect(handler.getCallingQueueState()).eq("empty");
});
it("should be ready after loading", async () => {
- const { handler, mock } = createWalletApiMock();
+ const { handler, TestingContext } = createWalletApiMock();
+
handler.addWalletCallResponse(
WalletApiOperation.PrepareDeposit,
undefined,
@@ -73,6 +71,7 @@ describe("Deposit CTA states", () => {
totalDepositCost: "EUR:1.2",
},
);
+
const props = {
talerDepositUri: "payto://refund/asdasdas",
amountStr: "EUR:1",
@@ -84,28 +83,21 @@ describe("Deposit CTA states", () => {
},
};
- const { pullLastResultOrThrow, waitForStateUpdate, assertNoPendingUpdate } =
- mountHook(() => useComponentState(props, mock));
-
- {
- const { status } = pullLastResultOrThrow();
- expect(status).equals("loading");
- }
-
- expect(await waitForStateUpdate()).true;
-
- {
- const state = pullLastResultOrThrow();
-
- if (state.status !== "ready") expect.fail();
- if (state.error) expect.fail();
- expect(state.confirm.onClick).not.undefined;
- expect(state.cost).deep.eq(Amounts.parseOrThrow("EUR:1.2"));
- expect(state.fee).deep.eq(Amounts.parseOrThrow("EUR:0.2"));
- expect(state.effective).deep.eq(Amounts.parseOrThrow("EUR:1"));
- }
+ const hookBehavior = await tests.hookBehaveLikeThis(useComponentState, props, [
+ ({ status }) => {
+ expect(status).equals("loading");
+ },
+ (state) => {
+ if (state.status !== "ready") expect.fail();
+ if (state.error) expect.fail();
+ expect(state.confirm.onClick).not.undefined;
+ expect(state.cost).deep.eq(Amounts.parseOrThrow("EUR:1.2"));
+ expect(state.fee).deep.eq(Amounts.parseOrThrow("EUR:0.2"));
+ expect(state.effective).deep.eq(Amounts.parseOrThrow("EUR:1"));
+ },
+ ], TestingContext)
- await assertNoPendingUpdate();
+ expect(hookBehavior).deep.equal({ result: "ok" })
expect(handler.getCallingQueueState()).eq("empty");
});
});
diff --git a/packages/taler-wallet-webextension/src/cta/InvoiceCreate/index.ts b/packages/taler-wallet-webextension/src/cta/InvoiceCreate/index.ts
index 01dbb6d6d..0569e8e5f 100644
--- a/packages/taler-wallet-webextension/src/cta/InvoiceCreate/index.ts
+++ b/packages/taler-wallet-webextension/src/cta/InvoiceCreate/index.ts
@@ -22,7 +22,6 @@ import { ButtonHandler, TextFieldHandler } from "../../mui/handlers.js";
import { compose, StateViewMap } from "../../utils/index.js";
import { ExchangeSelectionPage } from "../../wallet/ExchangeSelection/index.js";
import { NoExchangesView } from "../../wallet/ExchangeSelection/views.js";
-import { wxApi } from "../../wxApi.js";
import { useComponentState } from "./state.js";
import { LoadingUriView, ReadyView } from "./views.js";
@@ -78,6 +77,6 @@ const viewMapping: StateViewMap<State> = {
export const InvoiceCreatePage = compose(
"InvoiceCreatePage",
- (p: Props) => useComponentState(p, wxApi),
+ (p: Props) => useComponentState(p),
viewMapping,
);
diff --git a/packages/taler-wallet-webextension/src/cta/InvoiceCreate/state.ts b/packages/taler-wallet-webextension/src/cta/InvoiceCreate/state.ts
index 6007b5193..a26167f8e 100644
--- a/packages/taler-wallet-webextension/src/cta/InvoiceCreate/state.ts
+++ b/packages/taler-wallet-webextension/src/cta/InvoiceCreate/state.ts
@@ -23,17 +23,17 @@ import {
import { TalerError, WalletApiOperation } from "@gnu-taler/taler-wallet-core";
import { isFuture, parse } from "date-fns";
import { useState } from "preact/hooks";
+import { useBackendContext } from "../../context/backend.js";
import { useAsyncAsHook } from "../../hooks/useAsyncAsHook.js";
import { useSelectedExchange } from "../../hooks/useSelectedExchange.js";
import { RecursiveState } from "../../utils/index.js";
-import { wxApi } from "../../wxApi.js";
import { Props, State } from "./index.js";
export function useComponentState(
{ amount: amountStr, onClose, onSuccess }: Props,
- api: typeof wxApi,
): RecursiveState<State> {
const amount = Amounts.parseOrThrow(amountStr);
+ const api = useBackendContext()
const hook = useAsyncAsHook(() =>
api.wallet.call(WalletApiOperation.ListExchanges, {}),
@@ -158,8 +158,8 @@ export function useComponentState(
subject === undefined
? undefined
: !subject
- ? "Can't be empty"
- : undefined,
+ ? "Can't be empty"
+ : undefined,
value: subject ?? "",
onInput: async (e) => setSubject(e),
},
diff --git a/packages/taler-wallet-webextension/src/cta/InvoicePay/index.ts b/packages/taler-wallet-webextension/src/cta/InvoicePay/index.ts
index 6e16b528c..78f244964 100644
--- a/packages/taler-wallet-webextension/src/cta/InvoicePay/index.ts
+++ b/packages/taler-wallet-webextension/src/cta/InvoicePay/index.ts
@@ -18,13 +18,12 @@ import {
AbsoluteTime,
AmountJson,
PreparePayResult,
- TalerErrorDetail,
+ TalerErrorDetail
} from "@gnu-taler/taler-util";
import { Loading } from "../../components/Loading.js";
import { HookError } from "../../hooks/useAsyncAsHook.js";
import { ButtonHandler } from "../../mui/handlers.js";
import { compose, StateViewMap } from "../../utils/index.js";
-import { wxApi } from "../../wxApi.js";
import { useComponentState } from "./state.js";
import { LoadingUriView, ReadyView } from "./views.js";
@@ -92,6 +91,6 @@ const viewMapping: StateViewMap<State> = {
export const InvoicePayPage = compose(
"InvoicePayPage",
- (p: Props) => useComponentState(p, wxApi),
+ (p: Props) => useComponentState(p),
viewMapping,
);
diff --git a/packages/taler-wallet-webextension/src/cta/InvoicePay/state.ts b/packages/taler-wallet-webextension/src/cta/InvoicePay/state.ts
index c7fb48958..eb50ba748 100644
--- a/packages/taler-wallet-webextension/src/cta/InvoicePay/state.ts
+++ b/packages/taler-wallet-webextension/src/cta/InvoicePay/state.ts
@@ -25,14 +25,14 @@ import {
} from "@gnu-taler/taler-util";
import { TalerError, WalletApiOperation } from "@gnu-taler/taler-wallet-core";
import { useEffect, useState } from "preact/hooks";
+import { useBackendContext } from "../../context/backend.js";
import { useAsyncAsHook } from "../../hooks/useAsyncAsHook.js";
-import { wxApi } from "../../wxApi.js";
import { Props, State } from "./index.js";
export function useComponentState(
{ talerPayPullUri, onClose, goToWalletManualWithdraw, onSuccess }: Props,
- api: typeof wxApi,
): State {
+ const api = useBackendContext()
const hook = useAsyncAsHook(async () => {
const p2p = await api.wallet.call(WalletApiOperation.CheckPeerPullPayment, {
talerUri: talerPayPullUri,
diff --git a/packages/taler-wallet-webextension/src/cta/Payment/index.ts b/packages/taler-wallet-webextension/src/cta/Payment/index.ts
index 9bca8f74f..45e4a5b88 100644
--- a/packages/taler-wallet-webextension/src/cta/Payment/index.ts
+++ b/packages/taler-wallet-webextension/src/cta/Payment/index.ts
@@ -19,13 +19,12 @@ import {
PreparePayResult,
PreparePayResultAlreadyConfirmed,
PreparePayResultInsufficientBalance,
- PreparePayResultPaymentPossible,
+ PreparePayResultPaymentPossible
} from "@gnu-taler/taler-util";
import { Loading } from "../../components/Loading.js";
import { HookError } from "../../hooks/useAsyncAsHook.js";
import { ButtonHandler } from "../../mui/handlers.js";
import { compose, StateViewMap } from "../../utils/index.js";
-import { wxApi } from "../../wxApi.js";
import { useComponentState } from "./state.js";
import { BaseView, LoadingUriView } from "./views.js";
@@ -96,6 +95,6 @@ const viewMapping: StateViewMap<State> = {
export const PaymentPage = compose(
"Payment",
- (p: Props) => useComponentState(p, wxApi),
+ (p: Props) => useComponentState(p),
viewMapping,
);
diff --git a/packages/taler-wallet-webextension/src/cta/Payment/state.ts b/packages/taler-wallet-webextension/src/cta/Payment/state.ts
index 970af5b81..7690910e6 100644
--- a/packages/taler-wallet-webextension/src/cta/Payment/state.ts
+++ b/packages/taler-wallet-webextension/src/cta/Payment/state.ts
@@ -23,16 +23,16 @@ import {
} from "@gnu-taler/taler-util";
import { TalerError, WalletApiOperation } from "@gnu-taler/taler-wallet-core";
import { useEffect, useState } from "preact/hooks";
+import { useBackendContext } from "../../context/backend.js";
import { useAsyncAsHook } from "../../hooks/useAsyncAsHook.js";
import { ButtonHandler } from "../../mui/handlers.js";
-import { wxApi } from "../../wxApi.js";
import { Props, State } from "./index.js";
export function useComponentState(
{ talerPayUri, cancel, goToWalletManualWithdraw, onSuccess }: Props,
- api: typeof wxApi,
): State {
const [payErrMsg, setPayErrMsg] = useState<TalerError | undefined>(undefined);
+ const api = useBackendContext()
const hook = useAsyncAsHook(async () => {
if (!talerPayUri) throw Error("ERROR_NO-URI-FOR-PAYMENT");
diff --git a/packages/taler-wallet-webextension/src/cta/Payment/test.ts b/packages/taler-wallet-webextension/src/cta/Payment/test.ts
index b02ac6274..aba76fcf4 100644
--- a/packages/taler-wallet-webextension/src/cta/Payment/test.ts
+++ b/packages/taler-wallet-webextension/src/cta/Payment/test.ts
@@ -30,54 +30,46 @@ import {
} from "@gnu-taler/taler-util";
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
import { expect } from "chai";
+import { tests } from "../../../../web-util/src/index.browser.js";
import { mountHook, nullFunction } from "../../test-utils.js";
import { createWalletApiMock } from "../../test-utils.js";
import { useComponentState } from "./state.js";
describe("Payment CTA states", () => {
it("should tell the user that the URI is missing", async () => {
- const { handler, mock } = createWalletApiMock();
+ const { handler, TestingContext } = createWalletApiMock();
const props = {
talerPayUri: undefined,
cancel: nullFunction,
goToWalletManualWithdraw: nullFunction,
- onSuccess: async () => {
- null;
- },
+ onSuccess: nullFunction,
};
- const { pullLastResultOrThrow, waitForStateUpdate, assertNoPendingUpdate } =
- mountHook(() => useComponentState(props, mock));
-
- {
- const { status, error } = pullLastResultOrThrow();
- expect(status).equals("loading");
- expect(error).undefined;
- }
-
- expect(await waitForStateUpdate()).true;
- {
- const { status, error } = pullLastResultOrThrow();
-
- expect(status).equals("loading-uri");
- if (error === undefined) expect.fail();
- expect(error.hasError).true;
- expect(error.operational).false;
- }
+ const hookBehavior = await tests.hookBehaveLikeThis(useComponentState, props, [
+ ({ status, error }) => {
+ expect(status).equals("loading");
+ expect(error).undefined;
+ },
+ ({ status, error }) => {
+ expect(status).equals("loading-uri");
+ if (error === undefined) expect.fail();
+ expect(error.hasError).true;
+ expect(error.operational).false;
+ },
+ ], TestingContext)
- await assertNoPendingUpdate();
+ expect(hookBehavior).deep.equal({ result: "ok" })
expect(handler.getCallingQueueState()).eq("empty");
+
});
it("should response with no balance", async () => {
- const { handler, mock } = createWalletApiMock();
+ const { handler, TestingContext } = createWalletApiMock();
const props = {
talerPayUri: "taller://pay",
cancel: nullFunction,
goToWalletManualWithdraw: nullFunction,
- onSuccess: async () => {
- null;
- },
+ onSuccess: nullFunction,
};
handler.addWalletCallResponse(
@@ -94,41 +86,34 @@ describe("Payment CTA states", () => {
{ balances: [] },
);
- const { pullLastResultOrThrow, waitForStateUpdate, assertNoPendingUpdate } =
- mountHook(() => useComponentState(props, mock));
-
- {
- const { status, error } = pullLastResultOrThrow();
- expect(status).equals("loading");
- expect(error).undefined;
- }
-
- expect(await waitForStateUpdate()).true;
-
- {
- const r = pullLastResultOrThrow();
- if (r.status !== "no-balance-for-currency") {
- expect(r).eq({});
- return;
- }
- expect(r.balance).undefined;
- expect(r.amount).deep.equal(Amounts.parseOrThrow("USD:10"));
- }
+ const hookBehavior = await tests.hookBehaveLikeThis(useComponentState, props, [
+ ({ status, error }) => {
+ expect(status).equals("loading");
+ expect(error).undefined;
+ },
+ (state) => {
+ if (state.status !== "no-balance-for-currency") {
+ expect(state).eq({});
+ return;
+ }
+ expect(state.balance).undefined;
+ expect(state.amount).deep.equal(Amounts.parseOrThrow("USD:10"));
+ },
+ ], TestingContext)
- await assertNoPendingUpdate();
+ expect(hookBehavior).deep.equal({ result: "ok" })
expect(handler.getCallingQueueState()).eq("empty");
});
it("should not be able to pay if there is no enough balance", async () => {
- const { handler, mock } = createWalletApiMock();
+ const { handler, TestingContext } = createWalletApiMock();
const props = {
talerPayUri: "taller://pay",
cancel: nullFunction,
goToWalletManualWithdraw: nullFunction,
- onSuccess: async () => {
- null;
- },
+ onSuccess: nullFunction,
};
+
handler.addWalletCallResponse(
WalletApiOperation.PreparePayForUri,
undefined,
@@ -153,38 +138,31 @@ describe("Payment CTA states", () => {
},
);
- const { pullLastResultOrThrow, waitForStateUpdate, assertNoPendingUpdate } =
- mountHook(() => useComponentState(props, mock));
-
- {
- const { status, error } = pullLastResultOrThrow();
- expect(status).equals("loading");
- expect(error).undefined;
- }
-
- expect(await waitForStateUpdate()).true;
-
- {
- const r = pullLastResultOrThrow();
- if (r.status !== "no-enough-balance") expect.fail();
- expect(r.balance).deep.equal(Amounts.parseOrThrow("USD:5"));
- expect(r.amount).deep.equal(Amounts.parseOrThrow("USD:10"));
- }
+ const hookBehavior = await tests.hookBehaveLikeThis(useComponentState, props, [
+ ({ status, error }) => {
+ expect(status).equals("loading");
+ expect(error).undefined;
+ },
+ (state) => {
+ if (state.status !== "no-enough-balance") expect.fail();
+ expect(state.balance).deep.equal(Amounts.parseOrThrow("USD:5"));
+ expect(state.amount).deep.equal(Amounts.parseOrThrow("USD:10"));
+ },
+ ], TestingContext)
- await assertNoPendingUpdate();
+ expect(hookBehavior).deep.equal({ result: "ok" })
expect(handler.getCallingQueueState()).eq("empty");
});
it("should be able to pay (without fee)", async () => {
- const { handler, mock } = createWalletApiMock();
+ const { handler, TestingContext } = createWalletApiMock();
const props = {
talerPayUri: "taller://pay",
cancel: nullFunction,
goToWalletManualWithdraw: nullFunction,
- onSuccess: async () => {
- null;
- },
+ onSuccess: nullFunction,
};
+
handler.addWalletCallResponse(
WalletApiOperation.PreparePayForUri,
undefined,
@@ -209,42 +187,36 @@ describe("Payment CTA states", () => {
],
},
);
- const { pullLastResultOrThrow, waitForStateUpdate, assertNoPendingUpdate } =
- mountHook(() => useComponentState(props, mock));
-
- {
- const { status, error } = pullLastResultOrThrow();
- expect(status).equals("loading");
- expect(error).undefined;
- }
-
- expect(await waitForStateUpdate()).true;
-
- {
- const r = pullLastResultOrThrow();
- if (r.status !== "ready") {
- expect(r).eq({});
- return;
- }
- expect(r.balance).deep.equal(Amounts.parseOrThrow("USD:15"));
- expect(r.amount).deep.equal(Amounts.parseOrThrow("USD:10"));
- expect(r.payHandler.onClick).not.undefined;
- }
-
- await assertNoPendingUpdate();
+ const hookBehavior = await tests.hookBehaveLikeThis(useComponentState, props, [
+ ({ status, error }) => {
+ expect(status).equals("loading");
+ expect(error).undefined;
+ },
+ (state) => {
+ if (state.status !== "ready") {
+ expect(state).eq({});
+ return;
+ }
+ expect(state.balance).deep.equal(Amounts.parseOrThrow("USD:15"));
+ expect(state.amount).deep.equal(Amounts.parseOrThrow("USD:10"));
+ expect(state.payHandler.onClick).not.undefined;
+ },
+ ], TestingContext)
+
+ expect(hookBehavior).deep.equal({ result: "ok" })
expect(handler.getCallingQueueState()).eq("empty");
+
});
it("should be able to pay (with fee)", async () => {
- const { handler, mock } = createWalletApiMock();
+ const { handler, TestingContext } = createWalletApiMock();
const props = {
talerPayUri: "taller://pay",
cancel: nullFunction,
goToWalletManualWithdraw: nullFunction,
- onSuccess: async () => {
- null;
- },
+ onSuccess: nullFunction,
};
+
handler.addWalletCallResponse(
WalletApiOperation.PreparePayForUri,
undefined,
@@ -269,39 +241,32 @@ describe("Payment CTA states", () => {
],
},
);
- const { pullLastResultOrThrow, waitForStateUpdate, assertNoPendingUpdate } =
- mountHook(() => useComponentState(props, mock));
-
- {
- const { status, error } = pullLastResultOrThrow();
- expect(status).equals("loading");
- expect(error).undefined;
- }
-
- expect(await waitForStateUpdate()).true;
-
- {
- const r = pullLastResultOrThrow();
- if (r.status !== "ready") expect.fail();
- expect(r.balance).deep.equal(Amounts.parseOrThrow("USD:15"));
- expect(r.amount).deep.equal(Amounts.parseOrThrow("USD:9"));
- expect(r.payHandler.onClick).not.undefined;
- }
-
- await assertNoPendingUpdate();
+ const hookBehavior = await tests.hookBehaveLikeThis(useComponentState, props, [
+ ({ status, error }) => {
+ expect(status).equals("loading");
+ expect(error).undefined;
+ },
+ (state) => {
+ if (state.status !== "ready") expect.fail();
+ expect(state.balance).deep.equal(Amounts.parseOrThrow("USD:15"));
+ expect(state.amount).deep.equal(Amounts.parseOrThrow("USD:9"));
+ expect(state.payHandler.onClick).not.undefined;
+ },
+ ], TestingContext)
+
+ expect(hookBehavior).deep.equal({ result: "ok" })
expect(handler.getCallingQueueState()).eq("empty");
});
it("should get confirmation done after pay successfully", async () => {
- const { handler, mock } = createWalletApiMock();
+ const { handler, TestingContext } = createWalletApiMock();
const props = {
talerPayUri: "taller://pay",
cancel: nullFunction,
goToWalletManualWithdraw: nullFunction,
- onSuccess: async () => {
- null;
- },
+ onSuccess: nullFunction,
};
+
handler.addWalletCallResponse(
WalletApiOperation.PreparePayForUri,
undefined,
@@ -332,35 +297,30 @@ describe("Payment CTA states", () => {
contractTerms: {},
} as ConfirmPayResult);
- const { pullLastResultOrThrow, waitForStateUpdate, assertNoPendingUpdate } =
- mountHook(() => useComponentState(props, mock));
-
- {
- const { status, error } = pullLastResultOrThrow();
- expect(status).equals("loading");
- expect(error).undefined;
- }
-
- expect(await waitForStateUpdate()).true;
-
- {
- const r = pullLastResultOrThrow();
- if (r.status !== "ready") {
- expect(r).eq({});
- return;
- }
- expect(r.balance).deep.equal(Amounts.parseOrThrow("USD:15"));
- expect(r.amount).deep.equal(Amounts.parseOrThrow("USD:9"));
- if (r.payHandler.onClick === undefined) expect.fail();
- r.payHandler.onClick();
- }
-
- await assertNoPendingUpdate();
+ const hookBehavior = await tests.hookBehaveLikeThis(useComponentState, props, [
+ ({ status, error }) => {
+ expect(status).equals("loading");
+ expect(error).undefined;
+ },
+ (state) => {
+ if (state.status !== "ready") {
+ expect(state).eq({});
+ return;
+ }
+ expect(state.balance).deep.equal(Amounts.parseOrThrow("USD:15"));
+ expect(state.amount).deep.equal(Amounts.parseOrThrow("USD:9"));
+ if (state.payHandler.onClick === undefined) expect.fail();
+ state.payHandler.onClick();
+ },
+ ], TestingContext)
+
+ expect(hookBehavior).deep.equal({ result: "ok" })
expect(handler.getCallingQueueState()).eq("empty");
+
});
it("should not stay in ready state after pay with error", async () => {
- const { handler, mock } = createWalletApiMock();
+ const { handler, TestingContext } = createWalletApiMock();
const props = {
talerPayUri: "taller://pay",
cancel: nullFunction,
@@ -397,62 +357,50 @@ describe("Payment CTA states", () => {
lastError: { code: 1 },
} as ConfirmPayResult);
- const { pullLastResultOrThrow, waitForStateUpdate, assertNoPendingUpdate } =
- mountHook(() => useComponentState(props, mock));
-
- {
- const { status, error } = pullLastResultOrThrow();
- expect(status).equals("loading");
- expect(error).undefined;
- }
-
- expect(await waitForStateUpdate()).true;
-
- {
- const r = pullLastResultOrThrow();
- if (r.status !== "ready") expect.fail();
- expect(r.balance).deep.equal(Amounts.parseOrThrow("USD:15"));
- expect(r.amount).deep.equal(Amounts.parseOrThrow("USD:9"));
- // expect(r.totalFees).deep.equal(Amounts.parseOrThrow("USD:1"));
- if (r.payHandler.onClick === undefined) expect.fail();
- r.payHandler.onClick();
- }
-
- expect(await waitForStateUpdate()).true;
-
- {
- const r = pullLastResultOrThrow();
- if (r.status !== "ready") expect.fail();
- expect(r.balance).deep.equal(Amounts.parseOrThrow("USD:15"));
- expect(r.amount).deep.equal(Amounts.parseOrThrow("USD:9"));
- // expect(r.totalFees).deep.equal(Amounts.parseOrThrow("USD:1"));
- expect(r.payHandler.onClick).undefined;
- if (r.payHandler.error === undefined) expect.fail();
- //FIXME: error message here is bad
- expect(r.payHandler.error.errorDetail.hint).eq(
- "could not confirm payment",
- );
- expect(r.payHandler.error.errorDetail.payResult).deep.equal({
- type: ConfirmPayResultType.Pending,
- lastError: { code: 1 },
- });
- }
-
- await assertNoPendingUpdate();
+ const hookBehavior = await tests.hookBehaveLikeThis(useComponentState, props, [
+ ({ status, error }) => {
+ expect(status).equals("loading");
+ expect(error).undefined;
+ },
+ (state) => {
+ if (state.status !== "ready") expect.fail();
+ expect(state.balance).deep.equal(Amounts.parseOrThrow("USD:15"));
+ expect(state.amount).deep.equal(Amounts.parseOrThrow("USD:9"));
+ // expect(r.totalFees).deep.equal(Amounts.parseOrThrow("USD:1"));
+ if (state.payHandler.onClick === undefined) expect.fail();
+ state.payHandler.onClick();
+ },
+ (state) => {
+ if (state.status !== "ready") expect.fail();
+ expect(state.balance).deep.equal(Amounts.parseOrThrow("USD:15"));
+ expect(state.amount).deep.equal(Amounts.parseOrThrow("USD:9"));
+ // expect(r.totalFees).deep.equal(Amounts.parseOrThrow("USD:1"));
+ expect(state.payHandler.onClick).undefined;
+ if (state.payHandler.error === undefined) expect.fail();
+ //FIXME: error message here is bad
+ expect(state.payHandler.error.errorDetail.hint).eq(
+ "could not confirm payment",
+ );
+ expect(state.payHandler.error.errorDetail.payResult).deep.equal({
+ type: ConfirmPayResultType.Pending,
+ lastError: { code: 1 },
+ });
+ },
+ ], TestingContext)
+ expect(hookBehavior).deep.equal({ result: "ok" })
expect(handler.getCallingQueueState()).eq("empty");
+
});
it("should update balance if a coins is withdraw", async () => {
- const { handler, mock } = createWalletApiMock();
+ const { handler, TestingContext } = createWalletApiMock();
const props = {
talerPayUri: "taller://pay",
cancel: nullFunction,
goToWalletManualWithdraw: nullFunction,
- onSuccess: async () => {
- null;
- },
+ onSuccess: nullFunction,
};
handler.addWalletCallResponse(
@@ -507,46 +455,30 @@ describe("Payment CTA states", () => {
},
);
- const { pullLastResultOrThrow, waitForStateUpdate, assertNoPendingUpdate } =
- mountHook(() => useComponentState(props, mock));
-
- {
- const { status, error } = pullLastResultOrThrow();
- expect(status).equals("loading");
- expect(error).undefined;
- }
-
- expect(await waitForStateUpdate()).true;
-
- {
- const r = pullLastResultOrThrow();
- if (r.status !== "ready") {
- expect(r).eq({});
- return;
- }
- expect(r.balance).deep.equal(Amounts.parseOrThrow("USD:10"));
- expect(r.amount).deep.equal(Amounts.parseOrThrow("USD:9"));
- // expect(r.totalFees).deep.equal(Amounts.parseOrThrow("USD:1"));
- expect(r.payHandler.onClick).not.undefined;
-
- handler.notifyEventFromWallet(NotificationType.CoinWithdrawn);
- }
-
- expect(await waitForStateUpdate()).true;
-
- {
- const r = pullLastResultOrThrow();
- if (r.status !== "ready") {
- expect(r).eq({});
- return;
- }
- expect(r.balance).deep.equal(Amounts.parseOrThrow("USD:15"));
- expect(r.amount).deep.equal(Amounts.parseOrThrow("USD:9"));
- // expect(r.totalFees).deep.equal(Amounts.parseOrThrow("USD:1"));
- expect(r.payHandler.onClick).not.undefined;
- }
-
- await assertNoPendingUpdate();
+ const hookBehavior = await tests.hookBehaveLikeThis(useComponentState, props, [
+ ({ status, error }) => {
+ expect(status).equals("loading");
+ expect(error).undefined;
+ },
+ (state) => {
+ if (state.status !== "ready") expect.fail()
+ expect(state.balance).deep.equal(Amounts.parseOrThrow("USD:10"));
+ expect(state.amount).deep.equal(Amounts.parseOrThrow("USD:9"));
+ // expect(r.totalFees).deep.equal(Amounts.parseOrThrow("USD:1"));
+ expect(state.payHandler.onClick).not.undefined;
+
+ handler.notifyEventFromWallet(NotificationType.CoinWithdrawn);
+ },
+ (state) => {
+ if (state.status !== "ready") expect.fail()
+ expect(state.balance).deep.equal(Amounts.parseOrThrow("USD:15"));
+ expect(state.amount).deep.equal(Amounts.parseOrThrow("USD:9"));
+ // expect(r.totalFees).deep.equal(Amounts.parseOrThrow("USD:1"));
+ expect(state.payHandler.onClick).not.undefined;
+ },
+ ], TestingContext)
+
+ expect(hookBehavior).deep.equal({ result: "ok" })
expect(handler.getCallingQueueState()).eq("empty");
});
});
diff --git a/packages/taler-wallet-webextension/src/cta/Recovery/index.ts b/packages/taler-wallet-webextension/src/cta/Recovery/index.ts
index 4a65c571b..4a6fc79c9 100644
--- a/packages/taler-wallet-webextension/src/cta/Recovery/index.ts
+++ b/packages/taler-wallet-webextension/src/cta/Recovery/index.ts
@@ -18,7 +18,6 @@ import { Loading } from "../../components/Loading.js";
import { HookError } from "../../hooks/useAsyncAsHook.js";
import { ButtonHandler } from "../../mui/handlers.js";
import { compose, StateViewMap } from "../../utils/index.js";
-import { wxApi } from "../../wxApi.js";
import { useComponentState } from "./state.js";
import { LoadingUriView, ReadyView } from "./views.js";
@@ -60,6 +59,6 @@ const viewMapping: StateViewMap<State> = {
export const RecoveryPage = compose(
"Recovery",
- (p: Props) => useComponentState(p, wxApi),
+ (p: Props) => useComponentState(p),
viewMapping,
);
diff --git a/packages/taler-wallet-webextension/src/cta/Recovery/state.ts b/packages/taler-wallet-webextension/src/cta/Recovery/state.ts
index 3a5d94e2e..018d61c03 100644
--- a/packages/taler-wallet-webextension/src/cta/Recovery/state.ts
+++ b/packages/taler-wallet-webextension/src/cta/Recovery/state.ts
@@ -16,13 +16,13 @@
import { parseRecoveryUri } from "@gnu-taler/taler-util";
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
-import { wxApi } from "../../wxApi.js";
+import { useBackendContext } from "../../context/backend.js";
import { Props, State } from "./index.js";
export function useComponentState(
{ talerRecoveryUri, onCancel, onSuccess }: Props,
- api: typeof wxApi,
): State {
+ const api = useBackendContext()
if (!talerRecoveryUri) {
return {
status: "loading-uri",
@@ -48,7 +48,7 @@ export function useComponentState(
const recovery = info;
async function recoverBackup(): Promise<void> {
- await wxApi.wallet.call(WalletApiOperation.ImportBackupRecovery, {
+ await api.wallet.call(WalletApiOperation.ImportBackupRecovery, {
recovery,
});
onSuccess();
diff --git a/packages/taler-wallet-webextension/src/cta/Refund/index.ts b/packages/taler-wallet-webextension/src/cta/Refund/index.ts
index 099f72919..158f5c179 100644
--- a/packages/taler-wallet-webextension/src/cta/Refund/index.ts
+++ b/packages/taler-wallet-webextension/src/cta/Refund/index.ts
@@ -19,13 +19,12 @@ import { Loading } from "../../components/Loading.js";
import { HookError } from "../../hooks/useAsyncAsHook.js";
import { ButtonHandler } from "../../mui/handlers.js";
import { compose, StateViewMap } from "../../utils/index.js";
-import { wxApi } from "../../wxApi.js";
import { useComponentState } from "./state.js";
import {
IgnoredView,
InProgressView,
LoadingUriView,
- ReadyView,
+ ReadyView
} from "./views.js";
export interface Props {
@@ -90,6 +89,6 @@ const viewMapping: StateViewMap<State> = {
export const RefundPage = compose(
"Refund",
- (p: Props) => useComponentState(p, wxApi),
+ (p: Props) => useComponentState(p),
viewMapping,
);
diff --git a/packages/taler-wallet-webextension/src/cta/Refund/state.ts b/packages/taler-wallet-webextension/src/cta/Refund/state.ts
index 94c5567d6..624ab2fb2 100644
--- a/packages/taler-wallet-webextension/src/cta/Refund/state.ts
+++ b/packages/taler-wallet-webextension/src/cta/Refund/state.ts
@@ -17,14 +17,14 @@
import { Amounts, NotificationType } from "@gnu-taler/taler-util";
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
import { useEffect, useState } from "preact/hooks";
+import { useBackendContext } from "../../context/backend.js";
import { useAsyncAsHook } from "../../hooks/useAsyncAsHook.js";
-import { wxApi } from "../../wxApi.js";
import { Props, State } from "./index.js";
export function useComponentState(
{ talerRefundUri, cancel, onSuccess }: Props,
- api: typeof wxApi,
): State {
+ const api = useBackendContext()
const [ignored, setIgnored] = useState(false);
const info = useAsyncAsHook(async () => {
diff --git a/packages/taler-wallet-webextension/src/cta/Refund/test.ts b/packages/taler-wallet-webextension/src/cta/Refund/test.ts
index 927c45981..5fbf3743e 100644
--- a/packages/taler-wallet-webextension/src/cta/Refund/test.ts
+++ b/packages/taler-wallet-webextension/src/cta/Refund/test.ts
@@ -20,75 +20,50 @@
*/
import {
- AmountJson,
Amounts,
NotificationType,
- OrderShortInfo,
- PrepareRefundResult,
+ OrderShortInfo
} from "@gnu-taler/taler-util";
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
import { expect } from "chai";
-import { mountHook } from "../../test-utils.js";
-import { createWalletApiMock } from "../../test-utils.js";
+import { tests } from "../../../../web-util/src/index.browser.js";
+import { createWalletApiMock, mountHook, nullFunction } from "../../test-utils.js";
import { useComponentState } from "./state.js";
describe("Refund CTA states", () => {
it("should tell the user that the URI is missing", async () => {
- const { handler, mock } = createWalletApiMock();
+ const { handler, TestingContext } = createWalletApiMock();
- const { pullLastResultOrThrow, waitForStateUpdate, assertNoPendingUpdate } =
- mountHook(() =>
- useComponentState(
- {
- talerRefundUri: undefined,
- cancel: async () => {
- null;
- },
- onSuccess: async () => {
- null;
- },
- },
- mock,
- // {
- // prepareRefund: async () => ({}),
- // applyRefund: async () => ({}),
- // onUpdateNotification: async () => ({}),
- // } as any,
- ),
- );
-
- {
- const { status, error } = pullLastResultOrThrow();
- expect(status).equals("loading");
- expect(error).undefined;
+ const props = {
+ talerRefundUri: undefined,
+ cancel: nullFunction,
+ onSuccess: nullFunction,
}
- expect(await waitForStateUpdate()).true;
-
- {
- const { status, error } = pullLastResultOrThrow();
-
- expect(status).equals("loading-uri");
- if (!error) expect.fail();
- if (!error.hasError) expect.fail();
- if (error.operational) expect.fail();
- expect(error.message).eq("ERROR_NO-URI-FOR-REFUND");
- }
+ const hookBehavior = await tests.hookBehaveLikeThis(useComponentState, props, [
+ ({ status, error }) => {
+ expect(status).equals("loading");
+ expect(error).undefined;
+ },
+ ({ status, error }) => {
+ expect(status).equals("loading-uri");
+ if (!error) expect.fail();
+ if (!error.hasError) expect.fail();
+ if (error.operational) expect.fail();
+ expect(error.message).eq("ERROR_NO-URI-FOR-REFUND");
+ },
+ ], TestingContext)
- await assertNoPendingUpdate();
+ expect(hookBehavior).deep.equal({ result: "ok" })
expect(handler.getCallingQueueState()).eq("empty");
});
it("should be ready after loading", async () => {
- const { handler, mock } = createWalletApiMock();
+ const { handler, TestingContext } = createWalletApiMock();
const props = {
talerRefundUri: "taler://refund/asdasdas",
- cancel: async () => {
- null;
- },
- onSuccess: async () => {
- null;
- },
+ cancel: nullFunction,
+ onSuccess: nullFunction,
};
handler.addWalletCallResponse(WalletApiOperation.PrepareRefund, undefined, {
@@ -108,61 +83,28 @@ describe("Refund CTA states", () => {
} as OrderShortInfo,
});
- const { pullLastResultOrThrow, waitForStateUpdate, assertNoPendingUpdate } =
- mountHook(() =>
- useComponentState(
- props,
- mock,
- // {
- // prepareRefund: async () =>
- // ({
- // effectivePaid: "EUR:2",
- // awaiting: "EUR:2",
- // gone: "EUR:0",
- // granted: "EUR:0",
- // pending: false,
- // proposalId: "1",
- // info: {
- // contractTermsHash: "123",
- // merchant: {
- // name: "the merchant name",
- // },
- // orderId: "orderId1",
- // summary: "the summary",
- // },
- // } as PrepareRefundResult as any),
- // applyRefund: async () => ({}),
- // onUpdateNotification: async () => ({}),
- // } as any,
- ),
- );
-
- {
- const { status, error } = pullLastResultOrThrow();
- expect(status).equals("loading");
- expect(error).undefined;
- }
-
- expect(await waitForStateUpdate()).true;
-
- {
- const state = pullLastResultOrThrow();
-
- if (state.status !== "ready") expect.fail();
- if (state.error) expect.fail();
- expect(state.accept.onClick).not.undefined;
- expect(state.ignore.onClick).not.undefined;
- expect(state.merchantName).eq("the merchant name");
- expect(state.orderId).eq("orderId1");
- expect(state.products).undefined;
- }
+ const hookBehavior = await tests.hookBehaveLikeThis(useComponentState, props, [
+ ({ status, error }) => {
+ expect(status).equals("loading");
+ expect(error).undefined;
+ },
+ (state) => {
+ if (state.status !== "ready") expect.fail();
+ if (state.error) expect.fail();
+ expect(state.accept.onClick).not.undefined;
+ expect(state.ignore.onClick).not.undefined;
+ expect(state.merchantName).eq("the merchant name");
+ expect(state.orderId).eq("orderId1");
+ expect(state.products).undefined;
+ },
+ ], TestingContext)
- await assertNoPendingUpdate();
+ expect(hookBehavior).deep.equal({ result: "ok" })
expect(handler.getCallingQueueState()).eq("empty");
});
it("should be ignored after clicking the ignore button", async () => {
- const { handler, mock } = createWalletApiMock();
+ const { handler, TestingContext } = createWalletApiMock();
const props = {
talerRefundUri: "taler://refund/asdasdas",
cancel: async () => {
@@ -189,102 +131,36 @@ describe("Refund CTA states", () => {
summary: "the summary",
} as OrderShortInfo,
});
- // handler.addWalletCall(WalletApiOperation.ApplyRefund)
- // handler.addWalletCall(WalletApiOperation.PrepareRefund, undefined, {
- // awaiting: "EUR:1",
- // effectivePaid: "EUR:2",
- // gone: "EUR:0",
- // granted: "EUR:1",
- // pending: true,
- // proposalId: "1",
- // info: {
- // contractTermsHash: "123",
- // merchant: {
- // name: "the merchant name",
- // },
- // orderId: "orderId1",
- // summary: "the summary",
- // } as OrderShortInfo,
- // })
- const { pullLastResultOrThrow, waitForStateUpdate, assertNoPendingUpdate } =
- mountHook(() =>
- useComponentState(
- props,
- mock,
- // {
- // prepareRefund: async () =>
- // ({
- // effectivePaid: "EUR:2",
- // awaiting: "EUR:2",
- // gone: "EUR:0",
- // granted: "EUR:0",
- // pending: false,
- // proposalId: "1",
- // info: {
- // contractTermsHash: "123",
- // merchant: {
- // name: "the merchant name",
- // },
- // orderId: "orderId1",
- // summary: "the summary",
- // },
- // } as PrepareRefundResult as any),
- // applyRefund: async () => ({}),
- // onUpdateNotification: async () => ({}),
- // } as any,
- ),
- );
- {
- const { status, error } = pullLastResultOrThrow();
- expect(status).equals("loading");
- expect(error).undefined;
- }
-
- expect(await waitForStateUpdate()).true;
-
- {
- const state = pullLastResultOrThrow();
-
- if (state.status !== "ready") {
- expect(state).eq({});
- return;
- }
- if (state.error) {
- expect(state).eq({});
- return;
- }
- expect(state.accept.onClick).not.undefined;
- expect(state.merchantName).eq("the merchant name");
- expect(state.orderId).eq("orderId1");
- expect(state.products).undefined;
-
- if (state.ignore.onClick === undefined) expect.fail();
- state.ignore.onClick();
- }
-
- expect(await waitForStateUpdate()).true;
-
- {
- const state = pullLastResultOrThrow();
-
- if (state.status !== "ignored") {
- expect(state).eq({});
- return;
- }
- if (state.error) {
- expect(state).eq({});
- return;
- }
- expect(state.merchantName).eq("the merchant name");
- }
+ const hookBehavior = await tests.hookBehaveLikeThis(useComponentState, props, [
+ ({ status, error }) => {
+ expect(status).equals("loading");
+ expect(error).undefined;
+ },
+ (state) => {
+ if (state.status !== "ready") expect.fail()
+ if (state.error) expect.fail()
+ expect(state.accept.onClick).not.undefined;
+ expect(state.merchantName).eq("the merchant name");
+ expect(state.orderId).eq("orderId1");
+ expect(state.products).undefined;
+
+ if (state.ignore.onClick === undefined) expect.fail();
+ state.ignore.onClick();
+ },
+ (state) => {
+ if (state.status !== "ignored") expect.fail()
+ if (state.error) expect.fail()
+ expect(state.merchantName).eq("the merchant name");
+ },
+ ], TestingContext)
- await assertNoPendingUpdate();
+ expect(hookBehavior).deep.equal({ result: "ok" })
expect(handler.getCallingQueueState()).eq("empty");
});
it("should be in progress when doing refresh", async () => {
- const { handler, mock } = createWalletApiMock();
+ const { handler, TestingContext } = createWalletApiMock();
const props = {
talerRefundUri: "taler://refund/asdasdas",
cancel: async () => {
@@ -344,67 +220,42 @@ describe("Refund CTA states", () => {
} as OrderShortInfo,
});
- const { pullLastResultOrThrow, waitForStateUpdate, assertNoPendingUpdate } =
- mountHook(() => useComponentState(props, mock));
-
- {
- const { status, error } = pullLastResultOrThrow();
- expect(status).equals("loading");
- expect(error).undefined;
- }
-
- expect(await waitForStateUpdate()).true;
-
- {
- const state = pullLastResultOrThrow();
-
- if (state.status !== "in-progress") {
- expect(state).eq({});
- return;
- }
- if (state.error) expect.fail();
- expect(state.merchantName).eq("the merchant name");
- expect(state.products).undefined;
- expect(state.amount).deep.eq(Amounts.parseOrThrow("EUR:2"));
- // expect(state.progress).closeTo(1 / 3, 0.01)
-
- handler.notifyEventFromWallet(NotificationType.RefreshMelted);
- }
-
- expect(await waitForStateUpdate()).true;
-
- {
- const state = pullLastResultOrThrow();
-
- if (state.status !== "in-progress") {
- expect(state).eq({});
- return;
- }
- if (state.error) expect.fail();
- expect(state.merchantName).eq("the merchant name");
- expect(state.products).undefined;
- expect(state.amount).deep.eq(Amounts.parseOrThrow("EUR:2"));
- // expect(state.progress).closeTo(2 / 3, 0.01)
-
- handler.notifyEventFromWallet(NotificationType.RefreshMelted);
- }
-
- expect(await waitForStateUpdate()).true;
-
- {
- const state = pullLastResultOrThrow();
+ const hookBehavior = await tests.hookBehaveLikeThis(useComponentState, props, [
+ ({ status, error }) => {
+ expect(status).equals("loading");
+ expect(error).undefined;
+ },
+ (state) => {
+ if (state.status !== "in-progress") expect.fail()
+ if (state.error) expect.fail();
+ expect(state.merchantName).eq("the merchant name");
+ expect(state.products).undefined;
+ expect(state.amount).deep.eq(Amounts.parseOrThrow("EUR:2"));
+ // expect(state.progress).closeTo(1 / 3, 0.01)
+
+ handler.notifyEventFromWallet(NotificationType.RefreshMelted);
+ },
+ (state) => {
+ if (state.status !== "in-progress") expect.fail()
+ if (state.error) expect.fail();
+ expect(state.merchantName).eq("the merchant name");
+ expect(state.products).undefined;
+ expect(state.amount).deep.eq(Amounts.parseOrThrow("EUR:2"));
+ // expect(state.progress).closeTo(2 / 3, 0.01)
+
+ handler.notifyEventFromWallet(NotificationType.RefreshMelted);
+ },
+ (state) => {
+ if (state.status !== "ready") expect.fail()
+ if (state.error) expect.fail();
+ expect(state.merchantName).eq("the merchant name");
+ expect(state.products).undefined;
+ expect(state.amount).deep.eq(Amounts.parseOrThrow("EUR:2"));
- if (state.status !== "ready") {
- expect(state).eq({});
- return;
- }
- if (state.error) expect.fail();
- expect(state.merchantName).eq("the merchant name");
- expect(state.products).undefined;
- expect(state.amount).deep.eq(Amounts.parseOrThrow("EUR:2"));
- }
+ },
+ ], TestingContext)
- await assertNoPendingUpdate();
+ expect(hookBehavior).deep.equal({ result: "ok" })
expect(handler.getCallingQueueState()).eq("empty");
});
});
diff --git a/packages/taler-wallet-webextension/src/cta/Tip/index.ts b/packages/taler-wallet-webextension/src/cta/Tip/index.ts
index ff917008f..a29a3eadb 100644
--- a/packages/taler-wallet-webextension/src/cta/Tip/index.ts
+++ b/packages/taler-wallet-webextension/src/cta/Tip/index.ts
@@ -19,13 +19,12 @@ import { Loading } from "../../components/Loading.js";
import { HookError } from "../../hooks/useAsyncAsHook.js";
import { ButtonHandler } from "../../mui/handlers.js";
import { compose, StateViewMap } from "../../utils/index.js";
-import { wxApi } from "../../wxApi.js";
import { useComponentState } from "./state.js";
import {
AcceptedView,
IgnoredView,
LoadingUriView,
- ReadyView,
+ ReadyView
} from "./views.js";
export interface Props {
@@ -84,6 +83,6 @@ const viewMapping: StateViewMap<State> = {
export const TipPage = compose(
"Tip",
- (p: Props) => useComponentState(p, wxApi),
+ (p: Props) => useComponentState(p),
viewMapping,
);
diff --git a/packages/taler-wallet-webextension/src/cta/Tip/state.ts b/packages/taler-wallet-webextension/src/cta/Tip/state.ts
index ea9ba1b37..0ca213b01 100644
--- a/packages/taler-wallet-webextension/src/cta/Tip/state.ts
+++ b/packages/taler-wallet-webextension/src/cta/Tip/state.ts
@@ -16,14 +16,14 @@
import { Amounts } from "@gnu-taler/taler-util";
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
+import { useBackendContext } from "../../context/backend.js";
import { useAsyncAsHook } from "../../hooks/useAsyncAsHook.js";
-import { wxApi } from "../../wxApi.js";
import { Props, State } from "./index.js";
export function useComponentState(
{ talerTipUri, onCancel, onSuccess }: Props,
- api: typeof wxApi,
): State {
+ const api = useBackendContext()
const tipInfo = useAsyncAsHook(async () => {
if (!talerTipUri) throw Error("ERROR_NO-URI-FOR-TIP");
const tip = await api.wallet.call(WalletApiOperation.PrepareTip, {
diff --git a/packages/taler-wallet-webextension/src/cta/Tip/test.ts b/packages/taler-wallet-webextension/src/cta/Tip/test.ts
index e57b9ec4d..21ed95218 100644
--- a/packages/taler-wallet-webextension/src/cta/Tip/test.ts
+++ b/packages/taler-wallet-webextension/src/cta/Tip/test.ts
@@ -22,54 +22,42 @@
import { Amounts } from "@gnu-taler/taler-util";
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
import { expect } from "chai";
-import { mountHook } from "../../test-utils.js";
+import { tests } from "../../../../web-util/src/index.browser.js";
+import { mountHook, nullFunction } from "../../test-utils.js";
import { createWalletApiMock } from "../../test-utils.js";
+import { Props } from "./index.js";
import { useComponentState } from "./state.js";
describe("Tip CTA states", () => {
it("should tell the user that the URI is missing", async () => {
- const { handler, mock } = createWalletApiMock();
+ const { handler, TestingContext } = createWalletApiMock();
- const { pullLastResultOrThrow, waitForStateUpdate, assertNoPendingUpdate } =
- mountHook(() =>
- useComponentState(
- {
- talerTipUri: undefined,
- onCancel: async () => {
- null;
- },
- onSuccess: async () => {
- null;
- },
- },
- mock,
- ),
- );
-
- {
- const { status, error } = pullLastResultOrThrow();
- expect(status).equals("loading");
- expect(error).undefined;
+ const props: Props = {
+ talerTipUri: undefined,
+ onCancel: nullFunction,
+ onSuccess: nullFunction,
}
- expect(await waitForStateUpdate()).true;
-
- {
- const { status, error } = pullLastResultOrThrow();
-
- expect(status).equals("loading-uri");
- if (!error) expect.fail();
- if (!error.hasError) expect.fail();
- if (error.operational) expect.fail();
- expect(error.message).eq("ERROR_NO-URI-FOR-TIP");
- }
+ const hookBehavior = await tests.hookBehaveLikeThis(useComponentState, props, [
+ ({ status, error }) => {
+ expect(status).equals("loading");
+ expect(error).undefined;
+ },
+ ({ status, error }) => {
+ expect(status).equals("loading-uri");
+ if (!error) expect.fail();
+ if (!error.hasError) expect.fail();
+ if (error.operational) expect.fail();
+ expect(error.message).eq("ERROR_NO-URI-FOR-TIP");
+ },
+ ], TestingContext)
- await assertNoPendingUpdate();
+ expect(hookBehavior).deep.equal({ result: "ok" })
expect(handler.getCallingQueueState()).eq("empty");
});
it("should be ready for accepting the tip", async () => {
- const { handler, mock } = createWalletApiMock();
+ const { handler, TestingContext } = createWalletApiMock();
handler.addWalletCallResponse(WalletApiOperation.PrepareTip, undefined, {
accepted: false,
@@ -83,78 +71,59 @@ describe("Tip CTA states", () => {
tipAmountRaw: "",
});
- const { pullLastResultOrThrow, waitForStateUpdate, assertNoPendingUpdate } =
- mountHook(() =>
- useComponentState(
- {
- talerTipUri: "taler://tip/asd",
- onCancel: async () => {
- null;
- },
- onSuccess: async () => {
- null;
- },
- },
- mock,
- ),
- );
-
- {
- const { status, error } = pullLastResultOrThrow();
- expect(status).equals("loading");
- expect(error).undefined;
+ const props: Props = {
+ talerTipUri: "taler://tip/asd",
+ onCancel: nullFunction,
+ onSuccess: nullFunction,
}
- expect(await waitForStateUpdate()).true;
-
- {
- const state = pullLastResultOrThrow();
-
- if (state.status !== "ready") {
- expect(state).eq({ status: "ready" });
- return;
- }
- if (state.error) expect.fail();
- expect(state.amount).deep.eq(Amounts.parseOrThrow("EUR:1"));
- expect(state.merchantBaseUrl).eq("merchant url");
- expect(state.exchangeBaseUrl).eq("exchange url");
- if (state.accept.onClick === undefined) expect.fail();
-
- handler.addWalletCallResponse(WalletApiOperation.AcceptTip);
- state.accept.onClick();
- }
-
- handler.addWalletCallResponse(WalletApiOperation.PrepareTip, undefined, {
- accepted: true,
- exchangeBaseUrl: "exchange url",
- merchantBaseUrl: "merchant url",
- tipAmountEffective: "EUR:1",
- walletTipId: "tip_id",
- expirationTimestamp: {
- t_s: 1,
+ const hookBehavior = await tests.hookBehaveLikeThis(useComponentState, props, [
+ ({ status, error }) => {
+ expect(status).equals("loading");
+ expect(error).undefined;
},
- tipAmountRaw: "",
- });
- expect(await waitForStateUpdate()).true;
+ (state) => {
+ if (state.status !== "ready") {
+ expect(state).eq({ status: "ready" });
+ return;
+ }
+ if (state.error) expect.fail();
+ expect(state.amount).deep.eq(Amounts.parseOrThrow("EUR:1"));
+ expect(state.merchantBaseUrl).eq("merchant url");
+ expect(state.exchangeBaseUrl).eq("exchange url");
+ if (state.accept.onClick === undefined) expect.fail();
+
+ handler.addWalletCallResponse(WalletApiOperation.AcceptTip);
+ state.accept.onClick();
+
+ handler.addWalletCallResponse(WalletApiOperation.PrepareTip, undefined, {
+ accepted: true,
+ exchangeBaseUrl: "exchange url",
+ merchantBaseUrl: "merchant url",
+ tipAmountEffective: "EUR:1",
+ walletTipId: "tip_id",
+ expirationTimestamp: {
+ t_s: 1,
+ },
+ tipAmountRaw: "",
+ });
- {
- const state = pullLastResultOrThrow();
+ },
+ (state) => {
+ if (state.status !== "accepted") expect.fail()
+ if (state.error) expect.fail();
+ expect(state.amount).deep.eq(Amounts.parseOrThrow("EUR:1"));
+ expect(state.merchantBaseUrl).eq("merchant url");
+ expect(state.exchangeBaseUrl).eq("exchange url");
+ },
+ ], TestingContext)
- if (state.status !== "accepted") {
- expect(state).eq({ status: "accepted" });
- return;
- }
- if (state.error) expect.fail();
- expect(state.amount).deep.eq(Amounts.parseOrThrow("EUR:1"));
- expect(state.merchantBaseUrl).eq("merchant url");
- expect(state.exchangeBaseUrl).eq("exchange url");
- }
- await assertNoPendingUpdate();
+ expect(hookBehavior).deep.equal({ result: "ok" })
expect(handler.getCallingQueueState()).eq("empty");
});
- it("should be ignored after clicking the ignore button", async () => {
- const { handler, mock } = createWalletApiMock();
+ it.skip("should be ignored after clicking the ignore button", async () => {
+ const { handler, TestingContext } = createWalletApiMock();
handler.addWalletCallResponse(WalletApiOperation.PrepareTip, undefined, {
exchangeBaseUrl: "exchange url",
merchantBaseUrl: "merchant url",
@@ -167,46 +136,34 @@ describe("Tip CTA states", () => {
tipAmountRaw: "",
});
- const { pullLastResultOrThrow, waitForStateUpdate, assertNoPendingUpdate } =
- mountHook(() =>
- useComponentState(
- {
- talerTipUri: "taler://tip/asd",
- onCancel: async () => {
- null;
- },
- onSuccess: async () => {
- null;
- },
- },
- mock,
- ),
- );
-
- {
- const { status, error } = pullLastResultOrThrow();
- expect(status).equals("loading");
- expect(error).undefined;
+ const props: Props = {
+ talerTipUri: "taler://tip/asd",
+ onCancel: nullFunction,
+ onSuccess: nullFunction,
}
- expect(await waitForStateUpdate()).true;
-
- {
- const state = pullLastResultOrThrow();
-
- if (state.status !== "ready") expect.fail();
- if (state.error) expect.fail();
- expect(state.amount).deep.eq(Amounts.parseOrThrow("EUR:1"));
- expect(state.merchantBaseUrl).eq("merchant url");
- expect(state.exchangeBaseUrl).eq("exchange url");
- }
+ const hookBehavior = await tests.hookBehaveLikeThis(useComponentState, props, [
+ ({ status, error }) => {
+ expect(status).equals("loading");
+ expect(error).undefined;
+ },
+ (state) => {
+ if (state.status !== "ready") expect.fail();
+ if (state.error) expect.fail();
+ expect(state.amount).deep.eq(Amounts.parseOrThrow("EUR:1"));
+ expect(state.merchantBaseUrl).eq("merchant url");
+ expect(state.exchangeBaseUrl).eq("exchange url");
+
+ //FIXME: add ignore button
+ },
+ ], TestingContext)
- await assertNoPendingUpdate();
+ expect(hookBehavior).deep.equal({ result: "ok" })
expect(handler.getCallingQueueState()).eq("empty");
});
it("should render accepted if the tip has been used previously", async () => {
- const { handler, mock } = createWalletApiMock();
+ const { handler, TestingContext } = createWalletApiMock();
handler.addWalletCallResponse(WalletApiOperation.PrepareTip, undefined, {
accepted: true,
@@ -220,40 +177,28 @@ describe("Tip CTA states", () => {
tipAmountRaw: "",
});
- const { pullLastResultOrThrow, waitForStateUpdate, assertNoPendingUpdate } =
- mountHook(() =>
- useComponentState(
- {
- talerTipUri: "taler://tip/asd",
- onCancel: async () => {
- null;
- },
- onSuccess: async () => {
- null;
- },
- },
- mock,
- ),
- );
-
- {
- const { status, error } = pullLastResultOrThrow();
- expect(status).equals("loading");
- expect(error).undefined;
+ const props: Props = {
+ talerTipUri: "taler://tip/asd",
+ onCancel: nullFunction,
+ onSuccess: nullFunction,
}
- expect(await waitForStateUpdate()).true;
-
- {
- const state = pullLastResultOrThrow();
+ const hookBehavior = await tests.hookBehaveLikeThis(useComponentState, props, [
+ ({ status, error }) => {
+ expect(status).equals("loading");
+ expect(error).undefined;
+ },
+ (state) => {
+ if (state.status !== "accepted") expect.fail();
+ if (state.error) expect.fail();
+ expect(state.amount).deep.eq(Amounts.parseOrThrow("EUR:1"));
+ expect(state.merchantBaseUrl).eq("merchant url");
+ expect(state.exchangeBaseUrl).eq("exchange url");
+ },
+ ], TestingContext)
- if (state.status !== "accepted") expect.fail();
- if (state.error) expect.fail();
- expect(state.amount).deep.eq(Amounts.parseOrThrow("EUR:1"));
- expect(state.merchantBaseUrl).eq("merchant url");
- expect(state.exchangeBaseUrl).eq("exchange url");
- }
- await assertNoPendingUpdate();
+ expect(hookBehavior).deep.equal({ result: "ok" })
expect(handler.getCallingQueueState()).eq("empty");
+
});
});
diff --git a/packages/taler-wallet-webextension/src/cta/TransferCreate/index.ts b/packages/taler-wallet-webextension/src/cta/TransferCreate/index.ts
index 8d51ff3e0..0715bb60e 100644
--- a/packages/taler-wallet-webextension/src/cta/TransferCreate/index.ts
+++ b/packages/taler-wallet-webextension/src/cta/TransferCreate/index.ts
@@ -19,7 +19,6 @@ import { Loading } from "../../components/Loading.js";
import { HookError } from "../../hooks/useAsyncAsHook.js";
import { ButtonHandler, TextFieldHandler } from "../../mui/handlers.js";
import { compose, StateViewMap } from "../../utils/index.js";
-import { wxApi } from "../../wxApi.js";
import { useComponentState } from "./state.js";
import { LoadingUriView, ReadyView } from "./views.js";
@@ -66,6 +65,6 @@ const viewMapping: StateViewMap<State> = {
export const TransferCreatePage = compose(
"TransferCreatePage",
- (p: Props) => useComponentState(p, wxApi),
+ (p: Props) => useComponentState(p),
viewMapping,
);
diff --git a/packages/taler-wallet-webextension/src/cta/TransferCreate/state.ts b/packages/taler-wallet-webextension/src/cta/TransferCreate/state.ts
index c5e143f42..3536014da 100644
--- a/packages/taler-wallet-webextension/src/cta/TransferCreate/state.ts
+++ b/packages/taler-wallet-webextension/src/cta/TransferCreate/state.ts
@@ -17,19 +17,19 @@
import {
Amounts,
TalerErrorDetail,
- TalerProtocolTimestamp,
+ TalerProtocolTimestamp
} from "@gnu-taler/taler-util";
import { TalerError, WalletApiOperation } from "@gnu-taler/taler-wallet-core";
-import { format, isFuture, parse } from "date-fns";
+import { isFuture, parse } from "date-fns";
import { useState } from "preact/hooks";
+import { useBackendContext } from "../../context/backend.js";
import { useAsyncAsHook } from "../../hooks/useAsyncAsHook.js";
-import { wxApi } from "../../wxApi.js";
import { Props, State } from "./index.js";
export function useComponentState(
{ amount: amountStr, onClose, onSuccess }: Props,
- api: typeof wxApi,
): State {
+ const api = useBackendContext()
const amount = Amounts.parseOrThrow(amountStr);
const [subject, setSubject] = useState<string | undefined>();
@@ -124,8 +124,8 @@ export function useComponentState(
subject === undefined
? undefined
: !subject
- ? "Can't be empty"
- : undefined,
+ ? "Can't be empty"
+ : undefined,
value: subject ?? "",
onInput: async (e) => setSubject(e),
},
diff --git a/packages/taler-wallet-webextension/src/cta/TransferPickup/index.ts b/packages/taler-wallet-webextension/src/cta/TransferPickup/index.ts
index 399f1e290..de6ad3b79 100644
--- a/packages/taler-wallet-webextension/src/cta/TransferPickup/index.ts
+++ b/packages/taler-wallet-webextension/src/cta/TransferPickup/index.ts
@@ -17,13 +17,12 @@
import {
AbsoluteTime,
AmountJson,
- TalerErrorDetail,
+ TalerErrorDetail
} from "@gnu-taler/taler-util";
import { Loading } from "../../components/Loading.js";
import { HookError } from "../../hooks/useAsyncAsHook.js";
import { ButtonHandler } from "../../mui/handlers.js";
import { compose, StateViewMap } from "../../utils/index.js";
-import { wxApi } from "../../wxApi.js";
import { useComponentState } from "./state.js";
import { LoadingUriView, ReadyView } from "./views.js";
@@ -69,6 +68,6 @@ const viewMapping: StateViewMap<State> = {
export const TransferPickupPage = compose(
"TransferPickupPage",
- (p: Props) => useComponentState(p, wxApi),
+ (p: Props) => useComponentState(p),
viewMapping,
);
diff --git a/packages/taler-wallet-webextension/src/cta/TransferPickup/state.ts b/packages/taler-wallet-webextension/src/cta/TransferPickup/state.ts
index e8fb99ab7..45bec28fb 100644
--- a/packages/taler-wallet-webextension/src/cta/TransferPickup/state.ts
+++ b/packages/taler-wallet-webextension/src/cta/TransferPickup/state.ts
@@ -18,18 +18,18 @@ import {
AbsoluteTime,
Amounts,
TalerErrorDetail,
- TalerProtocolTimestamp,
+ TalerProtocolTimestamp
} from "@gnu-taler/taler-util";
import { TalerError, WalletApiOperation } from "@gnu-taler/taler-wallet-core";
import { useState } from "preact/hooks";
+import { useBackendContext } from "../../context/backend.js";
import { useAsyncAsHook } from "../../hooks/useAsyncAsHook.js";
-import { wxApi } from "../../wxApi.js";
import { Props, State } from "./index.js";
export function useComponentState(
{ talerPayPushUri, onClose, onSuccess }: Props,
- api: typeof wxApi,
): State {
+ const api = useBackendContext()
const hook = useAsyncAsHook(async () => {
return await api.wallet.call(WalletApiOperation.CheckPeerPushPayment, {
talerUri: talerPayPushUri,
diff --git a/packages/taler-wallet-webextension/src/cta/Withdraw/index.ts b/packages/taler-wallet-webextension/src/cta/Withdraw/index.ts
index 68b314c07..9e5943161 100644
--- a/packages/taler-wallet-webextension/src/cta/Withdraw/index.ts
+++ b/packages/taler-wallet-webextension/src/cta/Withdraw/index.ts
@@ -20,10 +20,9 @@ import { HookError } from "../../hooks/useAsyncAsHook.js";
import { State as SelectExchangeState } from "../../hooks/useSelectedExchange.js";
import { ButtonHandler, SelectFieldHandler } from "../../mui/handlers.js";
import { compose, StateViewMap } from "../../utils/index.js";
-import { wxApi } from "../../wxApi.js";
import {
useComponentStateFromParams,
- useComponentStateFromURI,
+ useComponentStateFromURI
} from "./state.js";
import { ExchangeSelectionPage } from "../../wallet/ExchangeSelection/index.js";
@@ -96,11 +95,11 @@ const viewMapping: StateViewMap<State> = {
export const WithdrawPageFromURI = compose(
"WithdrawPageFromURI",
- (p: PropsFromURI) => useComponentStateFromURI(p, wxApi),
+ (p: PropsFromURI) => useComponentStateFromURI(p),
viewMapping,
);
export const WithdrawPageFromParams = compose(
"WithdrawPageFromParams",
- (p: PropsFromParams) => useComponentStateFromParams(p, wxApi),
+ (p: PropsFromParams) => useComponentStateFromParams(p),
viewMapping,
);
diff --git a/packages/taler-wallet-webextension/src/cta/Withdraw/state.ts b/packages/taler-wallet-webextension/src/cta/Withdraw/state.ts
index 9bb29fbd6..4420221fc 100644
--- a/packages/taler-wallet-webextension/src/cta/Withdraw/state.ts
+++ b/packages/taler-wallet-webextension/src/cta/Withdraw/state.ts
@@ -19,20 +19,20 @@ import {
AmountJson,
Amounts,
ExchangeListItem,
- ExchangeTosStatus,
+ ExchangeTosStatus
} from "@gnu-taler/taler-util";
import { TalerError, WalletApiOperation } from "@gnu-taler/taler-wallet-core";
import { useState } from "preact/hooks";
+import { useBackendContext } from "../../context/backend.js";
import { useAsyncAsHook } from "../../hooks/useAsyncAsHook.js";
import { useSelectedExchange } from "../../hooks/useSelectedExchange.js";
import { RecursiveState } from "../../utils/index.js";
-import { wxApi } from "../../wxApi.js";
import { PropsFromParams, PropsFromURI, State } from "./index.js";
export function useComponentStateFromParams(
{ amount, cancel, onSuccess }: PropsFromParams,
- api: typeof wxApi,
): RecursiveState<State> {
+ const api = useBackendContext()
const uriInfoHook = useAsyncAsHook(async () => {
const exchanges = await api.wallet.call(
WalletApiOperation.ListExchanges,
@@ -84,14 +84,13 @@ export function useComponentStateFromParams(
chosenAmount,
exchangeList,
undefined,
- api,
);
}
export function useComponentStateFromURI(
{ talerWithdrawUri, cancel, onSuccess }: PropsFromURI,
- api: typeof wxApi,
): RecursiveState<State> {
+ const api = useBackendContext()
/**
* Ask the wallet about the withdraw URI
*/
@@ -158,7 +157,6 @@ export function useComponentStateFromURI(
chosenAmount,
exchangeList,
defaultExchange,
- api,
);
}
@@ -176,8 +174,8 @@ function exchangeSelectionState(
chosenAmount: AmountJson,
exchangeList: ExchangeListItem[],
defaultExchange: string | undefined,
- api: typeof wxApi,
): RecursiveState<State> {
+ const api = useBackendContext()
const selectedExchange = useSelectedExchange({
currency: chosenAmount.currency,
defaultExchange,
@@ -278,10 +276,10 @@ function exchangeSelectionState(
//TODO: calculate based on exchange info
const ageRestriction = ageRestrictionEnabled
? {
- list: ageRestrictionOptions,
- value: String(ageRestricted),
- onChange: async (v: string) => setAgeRestricted(parseInt(v, 10)),
- }
+ list: ageRestrictionOptions,
+ value: String(ageRestricted),
+ onChange: async (v: string) => setAgeRestricted(parseInt(v, 10)),
+ }
: undefined;
return {
diff --git a/packages/taler-wallet-webextension/src/cta/Withdraw/test.ts b/packages/taler-wallet-webextension/src/cta/Withdraw/test.ts
index 7fd8188ce..084b4368c 100644
--- a/packages/taler-wallet-webextension/src/cta/Withdraw/test.ts
+++ b/packages/taler-wallet-webextension/src/cta/Withdraw/test.ts
@@ -27,6 +27,7 @@ import {
} from "@gnu-taler/taler-util";
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
import { expect } from "chai";
+import { tests } from "../../../../web-util/src/index.browser.js";
import { mountHook } from "../../test-utils.js";
import { createWalletApiMock } from "../../test-utils.js";
import { useComponentStateFromURI } from "./state.js";
@@ -61,53 +62,45 @@ const exchanges: ExchangeListItem[] = [
} as Partial<ExchangeListItem> as ExchangeListItem,
];
+const nullFunction = async (): Promise<void> => {
+ null;
+}
+
describe("Withdraw CTA states", () => {
it("should tell the user that the URI is missing", async () => {
- const { handler, mock } = createWalletApiMock();
+ const { handler, TestingContext } = createWalletApiMock();
+
const props = {
talerWithdrawUri: undefined,
- cancel: async () => {
- null;
- },
- onSuccess: async () => {
- null;
- },
+ cancel: nullFunction,
+ onSuccess: nullFunction,
};
- const { pullLastResultOrThrow, waitForStateUpdate, assertNoPendingUpdate } =
- mountHook(() => useComponentStateFromURI(props, mock));
-
- {
- const { status } = pullLastResultOrThrow();
- expect(status).equals("loading");
- }
-
- expect(await waitForStateUpdate()).true;
- {
- const { status, error } = pullLastResultOrThrow();
-
- if (status != "uri-error") expect.fail();
- if (!error) expect.fail();
- if (!error.hasError) expect.fail();
- if (error.operational) expect.fail();
- expect(error.message).eq("ERROR_NO-URI-FOR-WITHDRAWAL");
- }
+ const hookBehavior = await tests.hookBehaveLikeThis(useComponentStateFromURI, props, [
+ ({ status }) => {
+ expect(status).equals("loading");
+ },
+ ({ status, error }) => {
+ if (status != "uri-error") expect.fail();
+ if (!error) expect.fail();
+ if (!error.hasError) expect.fail();
+ if (error.operational) expect.fail();
+ expect(error.message).eq("ERROR_NO-URI-FOR-WITHDRAWAL");
+ },
+ ], TestingContext)
- await assertNoPendingUpdate();
+ expect(hookBehavior).deep.equal({ result: "ok" })
expect(handler.getCallingQueueState()).eq("empty");
});
it("should tell the user that there is not known exchange", async () => {
- const { handler, mock } = createWalletApiMock();
+ const { handler, TestingContext } = createWalletApiMock();
const props = {
talerWithdrawUri: "taler-withdraw://",
- cancel: async () => {
- null;
- },
- onSuccess: async () => {
- null;
- },
+ cancel: nullFunction,
+ onSuccess: nullFunction,
};
+
handler.addWalletCallResponse(
WalletApiOperation.GetWithdrawalDetailsForUri,
undefined,
@@ -117,39 +110,28 @@ describe("Withdraw CTA states", () => {
},
);
- const { pullLastResultOrThrow, waitForStateUpdate, assertNoPendingUpdate } =
- mountHook(() => useComponentStateFromURI(props, mock));
-
- {
- const { status } = pullLastResultOrThrow();
- expect(status).equals("loading", "1");
- }
-
- expect(await waitForStateUpdate()).true;
-
- {
- const { status, error } = pullLastResultOrThrow();
-
- expect(status).equals("no-exchange", "3");
-
- expect(error).undefined;
- }
+ const hookBehavior = await tests.hookBehaveLikeThis(useComponentStateFromURI, props, [
+ ({ status }) => {
+ expect(status).equals("loading");
+ },
+ ({ status, error }) => {
+ expect(status).equals("no-exchange");
+ expect(error).undefined;
+ },
+ ], TestingContext)
- await assertNoPendingUpdate();
+ expect(hookBehavior).deep.equal({ result: "ok" })
expect(handler.getCallingQueueState()).eq("empty");
});
it("should be able to withdraw if tos are ok", async () => {
- const { handler, mock } = createWalletApiMock();
+ const { handler, TestingContext } = createWalletApiMock();
const props = {
talerWithdrawUri: "taler-withdraw://",
- cancel: async () => {
- null;
- },
- onSuccess: async () => {
- null;
- },
+ cancel: nullFunction,
+ onSuccess: nullFunction,
};
+
handler.addWalletCallResponse(
WalletApiOperation.GetWithdrawalDetailsForUri,
undefined,
@@ -171,54 +153,38 @@ describe("Withdraw CTA states", () => {
},
);
- const { pullLastResultOrThrow, waitForStateUpdate, assertNoPendingUpdate } =
- mountHook(() => useComponentStateFromURI(props, mock));
-
- {
- const { status, error } = pullLastResultOrThrow();
- expect(status).equals("loading");
- expect(error).undefined;
- }
-
- expect(await waitForStateUpdate()).true;
-
- {
- const { status, error } = pullLastResultOrThrow();
-
- expect(status).equals("loading");
-
- expect(error).undefined;
- }
-
- expect(await waitForStateUpdate()).true;
-
- {
- const state = pullLastResultOrThrow();
- expect(state.status).equals("success");
- if (state.status !== "success") return;
+ const hookBehavior = await tests.hookBehaveLikeThis(useComponentStateFromURI, props, [
+ ({ status }) => {
+ expect(status).equals("loading");
+ },
+ ({ status, error }) => {
+ expect(status).equals("loading");
+ expect(error).undefined;
+ },
+ (state) => {
+ expect(state.status).equals("success");
+ if (state.status !== "success") return;
- expect(state.toBeReceived).deep.equal(Amounts.parseOrThrow("ARS:2"));
- expect(state.withdrawalFee).deep.equal(Amounts.parseOrThrow("ARS:0"));
- expect(state.chosenAmount).deep.equal(Amounts.parseOrThrow("ARS:2"));
+ expect(state.toBeReceived).deep.equal(Amounts.parseOrThrow("ARS:2"));
+ expect(state.withdrawalFee).deep.equal(Amounts.parseOrThrow("ARS:0"));
+ expect(state.chosenAmount).deep.equal(Amounts.parseOrThrow("ARS:2"));
- expect(state.doWithdrawal.onClick).not.undefined;
- }
+ expect(state.doWithdrawal.onClick).not.undefined;
+ },
+ ], TestingContext)
- await assertNoPendingUpdate();
+ expect(hookBehavior).deep.equal({ result: "ok" })
expect(handler.getCallingQueueState()).eq("empty");
});
it("should accept the tos before withdraw", async () => {
- const { handler, mock } = createWalletApiMock();
+ const { handler, TestingContext } = createWalletApiMock();
const props = {
talerWithdrawUri: "taler-withdraw://",
- cancel: async () => {
- null;
- },
- onSuccess: async () => {
- null;
- },
+ cancel: nullFunction,
+ onSuccess: nullFunction,
};
+
const exchangeWithNewTos = exchanges.map((e) => ({
...e,
tosStatus: ExchangeTosStatus.New,
@@ -255,57 +221,39 @@ describe("Withdraw CTA states", () => {
},
);
- const { pullLastResultOrThrow, waitForStateUpdate, assertNoPendingUpdate } =
- mountHook(() => useComponentStateFromURI(props, mock));
-
- {
- const { status, error } = pullLastResultOrThrow();
- expect(status).equals("loading");
- expect(error).undefined;
- }
-
- expect(await waitForStateUpdate()).true;
-
- {
- const { status, error } = pullLastResultOrThrow();
-
- expect(status).equals("loading");
-
- expect(error).undefined;
- }
-
- expect(await waitForStateUpdate()).true;
-
- {
- const state = pullLastResultOrThrow();
- expect(state.status).equals("success");
- if (state.status !== "success") return;
-
- expect(state.toBeReceived).deep.equal(Amounts.parseOrThrow("ARS:2"));
- expect(state.withdrawalFee).deep.equal(Amounts.parseOrThrow("ARS:0"));
- expect(state.chosenAmount).deep.equal(Amounts.parseOrThrow("ARS:2"));
-
- expect(state.doWithdrawal.onClick).undefined;
+ const hookBehavior = await tests.hookBehaveLikeThis(useComponentStateFromURI, props, [
+ ({ status }) => {
+ expect(status).equals("loading");
+ },
+ ({ status, error }) => {
+ expect(status).equals("loading");
+ expect(error).undefined;
+ },
+ (state) => {
+ expect(state.status).equals("success");
+ if (state.status !== "success") return;
- // updateAcceptedVersionToCurrentVersion();
- state.onTosUpdate();
- }
+ expect(state.toBeReceived).deep.equal(Amounts.parseOrThrow("ARS:2"));
+ expect(state.withdrawalFee).deep.equal(Amounts.parseOrThrow("ARS:0"));
+ expect(state.chosenAmount).deep.equal(Amounts.parseOrThrow("ARS:2"));
- expect(await waitForStateUpdate()).true;
+ expect(state.doWithdrawal.onClick).undefined;
- {
- const state = pullLastResultOrThrow();
- expect(state.status).equals("success");
- if (state.status !== "success") return;
+ state.onTosUpdate();
+ },
+ (state) => {
+ expect(state.status).equals("success");
+ if (state.status !== "success") return;
- expect(state.toBeReceived).deep.equal(Amounts.parseOrThrow("ARS:2"));
- expect(state.withdrawalFee).deep.equal(Amounts.parseOrThrow("ARS:0"));
- expect(state.chosenAmount).deep.equal(Amounts.parseOrThrow("ARS:2"));
+ expect(state.toBeReceived).deep.equal(Amounts.parseOrThrow("ARS:2"));
+ expect(state.withdrawalFee).deep.equal(Amounts.parseOrThrow("ARS:0"));
+ expect(state.chosenAmount).deep.equal(Amounts.parseOrThrow("ARS:2"));
- expect(state.doWithdrawal.onClick).not.undefined;
- }
+ expect(state.doWithdrawal.onClick).not.undefined;
+ },
+ ], TestingContext)
- await assertNoPendingUpdate();
+ expect(hookBehavior).deep.equal({ result: "ok" })
expect(handler.getCallingQueueState()).eq("empty");
});
});