diff options
Diffstat (limited to 'packages/taler-wallet-webextension/src/cta/Tip')
3 files changed, 112 insertions, 168 deletions
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"); + }); }); |