diff options
author | Sebastian <sebasjm@gmail.com> | 2022-10-25 12:23:08 -0300 |
---|---|---|
committer | Sebastian <sebasjm@gmail.com> | 2022-10-25 12:23:52 -0300 |
commit | 3f2db7707fdf4eb4c1dfdb527d5726dd1694e126 (patch) | |
tree | 4366d443db56eb200ba29760bf1f4a0b9def6c97 /packages/taler-wallet-webextension/src/cta/Withdraw | |
parent | 587674dd10bd714b68ff5a6e836eb21113c0337a (diff) | |
download | wallet-core-3f2db7707fdf4eb4c1dfdb527d5726dd1694e126.tar.xz |
using new wallet api (typed interface)
Diffstat (limited to 'packages/taler-wallet-webextension/src/cta/Withdraw')
3 files changed, 142 insertions, 163 deletions
diff --git a/packages/taler-wallet-webextension/src/cta/Withdraw/index.ts b/packages/taler-wallet-webextension/src/cta/Withdraw/index.ts index a3b3df8b3..9a7acf9f1 100644 --- a/packages/taler-wallet-webextension/src/cta/Withdraw/index.ts +++ b/packages/taler-wallet-webextension/src/cta/Withdraw/index.ts @@ -20,15 +20,15 @@ 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 * as wxApi from "../../wxApi.js"; +import { wxApi } from "../../wxApi.js"; import { useComponentStateFromParams, - useComponentStateFromURI, + useComponentStateFromURI } from "./state.js"; import { ExchangeSelectionPage } from "../../wallet/ExchangeSelection/index.js"; -import { LoadingInfoView, LoadingUriView, SuccessView } from "./views.js"; import { NoExchangesView } from "../../wallet/ExchangeSelection/views.js"; +import { LoadingInfoView, LoadingUriView, SuccessView } from "./views.js"; export interface PropsFromURI { talerWithdrawUri: string | undefined; diff --git a/packages/taler-wallet-webextension/src/cta/Withdraw/state.ts b/packages/taler-wallet-webextension/src/cta/Withdraw/state.ts index c542d8aae..704ef1ac3 100644 --- a/packages/taler-wallet-webextension/src/cta/Withdraw/state.ts +++ b/packages/taler-wallet-webextension/src/cta/Withdraw/state.ts @@ -19,13 +19,13 @@ import { AmountJson, Amounts, ExchangeListItem, - ExchangeTosStatus, + ExchangeTosStatus } from "@gnu-taler/taler-util"; -import { TalerError } from "@gnu-taler/taler-wallet-core"; +import { TalerError, WalletApiOperation } from "@gnu-taler/taler-wallet-core"; import { useState } from "preact/hooks"; import { useAsyncAsHook } from "../../hooks/useAsyncAsHook.js"; import { useSelectedExchange } from "../../hooks/useSelectedExchange.js"; -import * as wxApi from "../../wxApi.js"; +import { wxApi } from "../../wxApi.js"; import { PropsFromParams, PropsFromURI, State } from "./index.js"; type RecursiveState<S extends object> = S | (() => RecursiveState<S>); @@ -35,7 +35,7 @@ export function useComponentStateFromParams( api: typeof wxApi, ): RecursiveState<State> { const uriInfoHook = useAsyncAsHook(async () => { - const exchanges = await api.listExchanges(); + const exchanges = await api.wallet.call(WalletApiOperation.ListExchanges, {}); return { amount: Amounts.parseOrThrow(amount), exchanges }; }); @@ -58,11 +58,11 @@ export function useComponentStateFromParams( transactionId: string; confirmTransferUrl: string | undefined; }> { - const res = await api.acceptManualWithdrawal( - exchange, - Amounts.stringify(chosenAmount), - ageRestricted, - ); + const res = await api.wallet.call(WalletApiOperation.AcceptManualWithdrawal, { + exchangeBaseUrl: exchange, + amount: Amounts.stringify(chosenAmount), + restrictAge: ageRestricted, + }); return { confirmTransferUrl: undefined, transactionId: res.transactionId, @@ -93,16 +93,15 @@ export function useComponentStateFromURI( const uriInfoHook = useAsyncAsHook(async () => { if (!talerWithdrawUri) throw Error("ERROR_NO-URI-FOR-WITHDRAWAL"); - const uriInfo = await api.getWithdrawalDetailsForUri({ + const uriInfo = await api.wallet.call(WalletApiOperation.GetWithdrawalDetailsForUri, { talerWithdrawUri, }); - const exchanges = await api.listExchanges(); const { amount, defaultExchangeBaseUrl } = uriInfo; return { talerWithdrawUri, amount: Amounts.parseOrThrow(amount), thisExchange: defaultExchangeBaseUrl, - exchanges, + exchanges: uriInfo.possibleExchanges, }; }); @@ -118,7 +117,7 @@ export function useComponentStateFromURI( const uri = uriInfoHook.response.talerWithdrawUri; const chosenAmount = uriInfoHook.response.amount; const defaultExchange = uriInfoHook.response.thisExchange; - const exchangeList = uriInfoHook.response.exchanges.exchanges; + const exchangeList = uriInfoHook.response.exchanges; async function doManagedWithdraw( exchange: string, @@ -127,7 +126,11 @@ export function useComponentStateFromURI( transactionId: string; confirmTransferUrl: string | undefined; }> { - const res = await api.acceptWithdrawal(uri, exchange, ageRestricted); + const res = await api.wallet.call(WalletApiOperation.AcceptBankIntegratedWithdrawal, { + exchangeBaseUrl: exchange, + talerWithdrawUri: uri, + restrictAge: ageRestricted + }); return { confirmTransferUrl: res.confirmTransferUrl, transactionId: res.transactionId, @@ -186,7 +189,7 @@ function exchangeSelectionState( * about the withdrawal */ const amountHook = useAsyncAsHook(async () => { - const info = await api.getWithdrawalDetailsForAmount({ + const info = await api.wallet.call(WalletApiOperation.GetWithdrawalDetailsForAmount, { exchangeBaseUrl: currentExchange.exchangeBaseUrl, amount: Amounts.stringify(chosenAmount), restrictAge: ageRestricted, @@ -261,10 +264,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 977faa03a..b4ba32f8a 100644 --- a/packages/taler-wallet-webextension/src/cta/Withdraw/test.ts +++ b/packages/taler-wallet-webextension/src/cta/Withdraw/test.ts @@ -21,16 +21,12 @@ import { Amounts, - ExchangeEntryStatus, - ExchangeFullDetails, - ExchangeListItem, - ExchangesListResponse, - ExchangeTosStatus, - GetExchangeTosResult, - ManualWithdrawalDetails, + ExchangeEntryStatus, ExchangeListItem, ExchangeTosStatus } 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 { useComponentStateFromURI } from "./state.js"; const exchanges: ExchangeListItem[] = [ @@ -65,39 +61,32 @@ const exchanges: ExchangeListItem[] = [ describe("Withdraw CTA states", () => { it("should tell the user that the URI is missing", async () => { - const { getLastResultOrThrow, waitNextUpdate, assertNoPendingUpdate } = + const { handler, mock } = createWalletApiMock(); + const props = { + talerWithdrawUri: undefined, + cancel: async () => { + null; + }, + onSuccess: async () => { + null; + }, + } + const { pullLastResultOrThrow, waitForStateUpdate, assertNoPendingUpdate } = mountHook(() => useComponentStateFromURI( - { - talerWithdrawUri: undefined, - cancel: async () => { - null; - }, - onSuccess: async () => { - null; - }, - }, - { - listExchanges: async () => ({ exchanges }), - getWithdrawalDetailsForAmount: async ({ - talerWithdrawUri, - }: any) => ({ - amount: "ARS:2", - possibleExchanges: exchanges, - }), - } as any, + props, mock ), ); { - const { status } = getLastResultOrThrow(); + const { status } = pullLastResultOrThrow(); expect(status).equals("loading"); } - await waitNextUpdate(); + expect(await waitForStateUpdate()).true; { - const { status, error } = getLastResultOrThrow(); + const { status, error } = pullLastResultOrThrow(); if (status != "uri-error") expect.fail(); if (!error) expect.fail(); @@ -107,40 +96,41 @@ describe("Withdraw CTA states", () => { } await assertNoPendingUpdate(); + expect(handler.getCallingQueueState()).eq("empty") }); it("should tell the user that there is not known exchange", async () => { - const { getLastResultOrThrow, waitNextUpdate, assertNoPendingUpdate } = + const { handler, mock } = createWalletApiMock(); + const props = { + talerWithdrawUri: "taler-withdraw://", + cancel: async () => { + null; + }, + onSuccess: async () => { + null; + }, + } + handler.addWalletCallResponse(WalletApiOperation.GetWithdrawalDetailsForUri, undefined, { + amount: "EUR:2", + possibleExchanges: [], + }) + + const { pullLastResultOrThrow, waitForStateUpdate, assertNoPendingUpdate } = mountHook(() => useComponentStateFromURI( - { - talerWithdrawUri: "taler-withdraw://", - cancel: async () => { - null; - }, - onSuccess: async () => { - null; - }, - }, - { - listExchanges: async () => ({ exchanges }), - getWithdrawalDetailsForUri: async ({ talerWithdrawUri }: any) => ({ - amount: "EUR:2", - possibleExchanges: [], - }), - } as any, + props, mock ), ); { - const { status } = getLastResultOrThrow(); + const { status } = pullLastResultOrThrow(); expect(status).equals("loading", "1"); } - await waitNextUpdate(); + expect(await waitForStateUpdate()).true; { - const { status, error } = getLastResultOrThrow(); + const { status, error } = pullLastResultOrThrow(); expect(status).equals("no-exchange", "3"); @@ -148,65 +138,60 @@ describe("Withdraw CTA states", () => { } await assertNoPendingUpdate(); + expect(handler.getCallingQueueState()).eq("empty") }); it("should be able to withdraw if tos are ok", async () => { - const { getLastResultOrThrow, waitNextUpdate, assertNoPendingUpdate } = + const { handler, mock } = createWalletApiMock(); + const props = { + talerWithdrawUri: "taler-withdraw://", + cancel: async () => { + null; + }, + onSuccess: async () => { + null; + }, + } + handler.addWalletCallResponse(WalletApiOperation.GetWithdrawalDetailsForUri, undefined, { + amount: "ARS:2", + possibleExchanges: exchanges, + defaultExchangeBaseUrl: exchanges[0].exchangeBaseUrl + }) + handler.addWalletCallResponse(WalletApiOperation.GetWithdrawalDetailsForAmount, undefined, { + amountRaw: "ARS:2", + amountEffective: "ARS:2", + paytoUris: ["payto://"], + tosAccepted: true, + ageRestrictionOptions: [] + }) + + const { pullLastResultOrThrow, waitForStateUpdate, assertNoPendingUpdate } = mountHook(() => useComponentStateFromURI( - { - talerWithdrawUri: "taler-withdraw://", - cancel: async () => { - null; - }, - onSuccess: async () => { - null; - }, - }, - { - listExchanges: async () => ({ exchanges }), - getWithdrawalDetailsForUri: async ({ talerWithdrawUri }: any) => ({ - amount: "ARS:2", - possibleExchanges: exchanges, - defaultExchangeBaseUrl: exchanges[0].exchangeBaseUrl, - }), - getWithdrawalDetailsForAmount: - async (): Promise<ManualWithdrawalDetails> => - ({ - amountRaw: "ARS:2", - amountEffective: "ARS:2", - } as any), - getExchangeTos: async (): Promise<GetExchangeTosResult> => ({ - contentType: "text", - content: "just accept", - acceptedEtag: "v1", - currentEtag: "v1", - tosStatus: ExchangeTosStatus.Accepted, - }), - } as any, + props, mock ), ); { - const { status, error } = getLastResultOrThrow(); + const { status, error } = pullLastResultOrThrow(); expect(status).equals("loading"); expect(error).undefined; } - await waitNextUpdate(); + expect(await waitForStateUpdate()).true; { - const { status, error } = getLastResultOrThrow(); + const { status, error } = pullLastResultOrThrow(); expect(status).equals("loading"); expect(error).undefined; } - await waitNextUpdate(); + expect(await waitForStateUpdate()).true; { - const state = getLastResultOrThrow(); + const state = pullLastResultOrThrow(); expect(state.status).equals("success"); if (state.status !== "success") return; @@ -218,82 +203,72 @@ describe("Withdraw CTA states", () => { } await assertNoPendingUpdate(); + expect(handler.getCallingQueueState()).eq("empty") }); - it("should be accept the tos before withdraw", async () => { - const listExchangesResponse: ExchangesListResponse = { - exchanges: exchanges.map((e) => ({ - ...e, - tosStatus: ExchangeTosStatus.New, - })), - }; - - function updateAcceptedVersionToCurrentVersion(): void { - listExchangesResponse.exchanges = listExchangesResponse.exchanges.map( - (e) => ({ - ...e, - tosStatus: ExchangeTosStatus.Accepted, - }), - ); + it("should accept the tos before withdraw", async () => { + const { handler, mock } = createWalletApiMock(); + const props = { + talerWithdrawUri: "taler-withdraw://", + cancel: async () => { + null; + }, + onSuccess: async () => { + null; + }, } - - const { getLastResultOrThrow, waitNextUpdate, assertNoPendingUpdate } = + const exchangeWithNewTos = exchanges.map((e) => ({ + ...e, + tosStatus: ExchangeTosStatus.New, + })); + + handler.addWalletCallResponse(WalletApiOperation.GetWithdrawalDetailsForUri, undefined, { + amount: "ARS:2", + possibleExchanges: exchangeWithNewTos, + defaultExchangeBaseUrl: exchangeWithNewTos[0].exchangeBaseUrl + }) + handler.addWalletCallResponse(WalletApiOperation.GetWithdrawalDetailsForAmount, undefined, { + amountRaw: "ARS:2", + amountEffective: "ARS:2", + paytoUris: ["payto://"], + tosAccepted: false, + ageRestrictionOptions: [] + }) + + + handler.addWalletCallResponse(WalletApiOperation.GetWithdrawalDetailsForUri, undefined, { + amount: "ARS:2", + possibleExchanges: exchanges, + defaultExchangeBaseUrl: exchanges[0].exchangeBaseUrl + }) + + const { pullLastResultOrThrow, waitForStateUpdate, assertNoPendingUpdate } = mountHook(() => useComponentStateFromURI( - { - talerWithdrawUri: "taler-withdraw://", - cancel: async () => { - null; - }, - onSuccess: async () => { - null; - }, - }, - { - listExchanges: async () => listExchangesResponse, - getWithdrawalDetailsForUri: async ({ talerWithdrawUri }: any) => ({ - amount: "ARS:2", - possibleExchanges: exchanges, - defaultExchangeBaseUrl: exchanges[0].exchangeBaseUrl, - }), - getWithdrawalDetailsForAmount: - async (): Promise<ManualWithdrawalDetails> => - ({ - amountRaw: "ARS:2", - amountEffective: "ARS:2", - } as any), - getExchangeTos: async (): Promise<GetExchangeTosResult> => ({ - contentType: "text", - content: "just accept", - acceptedEtag: "v1", - currentEtag: "v2", - tosStatus: ExchangeTosStatus.Changed, - }), - setExchangeTosAccepted: async () => ({}), - } as any, + props, mock ), ); { - const { status, error } = getLastResultOrThrow(); + const { status, error } = pullLastResultOrThrow(); expect(status).equals("loading"); expect(error).undefined; } - await waitNextUpdate(); + expect(await waitForStateUpdate()).true; { - const { status, error } = getLastResultOrThrow(); + const { status, error } = pullLastResultOrThrow(); expect(status).equals("loading"); expect(error).undefined; } - await waitNextUpdate(); + expect(await waitForStateUpdate()).true; { - const state = getLastResultOrThrow(); + const state = pullLastResultOrThrow(); expect(state.status).equals("success"); if (state.status !== "success") return; @@ -303,14 +278,14 @@ describe("Withdraw CTA states", () => { expect(state.doWithdrawal.onClick).undefined; - updateAcceptedVersionToCurrentVersion(); + // updateAcceptedVersionToCurrentVersion(); state.onTosUpdate(); } - await waitNextUpdate(); + expect(await waitForStateUpdate()).true; { - const state = getLastResultOrThrow(); + const state = pullLastResultOrThrow(); expect(state.status).equals("success"); if (state.status !== "success") return; @@ -322,5 +297,6 @@ describe("Withdraw CTA states", () => { } await assertNoPendingUpdate(); + expect(handler.getCallingQueueState()).eq("empty") }); }); |