using the test to fine tune the withdraw process
This commit is contained in:
parent
1ae4a44a3a
commit
d34eeb5c8c
@ -53,13 +53,6 @@ describe("Withdraw CTA states", () => {
|
|||||||
|
|
||||||
await waitNextUpdate()
|
await waitNextUpdate()
|
||||||
|
|
||||||
{
|
|
||||||
const { status, hook } = getLastResultOrThrow()
|
|
||||||
|
|
||||||
expect(status).equals('loading-uri')
|
|
||||||
expect(hook).deep.equals({ "hasError": true, "operational": false, "message": "ERROR_NO-URI-FOR-WITHDRAWAL" });
|
|
||||||
}
|
|
||||||
await waitNextUpdate()
|
|
||||||
{
|
{
|
||||||
const { status, hook } = getLastResultOrThrow()
|
const { status, hook } = getLastResultOrThrow()
|
||||||
|
|
||||||
@ -89,25 +82,6 @@ describe("Withdraw CTA states", () => {
|
|||||||
|
|
||||||
await waitNextUpdate()
|
await waitNextUpdate()
|
||||||
|
|
||||||
{
|
|
||||||
const { status, hook } = getLastResultOrThrow()
|
|
||||||
|
|
||||||
expect(status).equals('loading-exchange')
|
|
||||||
expect(hook).undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
await waitNextUpdate()
|
|
||||||
|
|
||||||
{
|
|
||||||
const { status, hook } = getLastResultOrThrow()
|
|
||||||
|
|
||||||
expect(status).equals('loading-exchange')
|
|
||||||
|
|
||||||
expect(hook).deep.equals({ "hasError": true, "operational": false, "message": "ERROR_NO-DEFAULT-EXCHANGE" });
|
|
||||||
}
|
|
||||||
|
|
||||||
await waitNextUpdate()
|
|
||||||
|
|
||||||
{
|
{
|
||||||
const { status, hook } = getLastResultOrThrow()
|
const { status, hook } = getLastResultOrThrow()
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
import { AmountJson, Amounts } from "@gnu-taler/taler-util";
|
import { AmountJson, Amounts } from "@gnu-taler/taler-util";
|
||||||
import { TalerError } from "@gnu-taler/taler-wallet-core";
|
import { TalerError } from "@gnu-taler/taler-wallet-core";
|
||||||
import { Fragment, h, VNode } from "preact";
|
import { Fragment, h, VNode } from "preact";
|
||||||
import { useState } from "preact/hooks";
|
import { useMemo, useState } from "preact/hooks";
|
||||||
import { Amount } from "../components/Amount.js";
|
import { Amount } from "../components/Amount.js";
|
||||||
import { ErrorTalerOperation } from "../components/ErrorTalerOperation.js";
|
import { ErrorTalerOperation } from "../components/ErrorTalerOperation.js";
|
||||||
import { Loading } from "../components/Loading.js";
|
import { Loading } from "../components/Loading.js";
|
||||||
@ -116,44 +116,44 @@ export function useComponentState(
|
|||||||
/**
|
/**
|
||||||
* Get the amount and select one exchange
|
* Get the amount and select one exchange
|
||||||
*/
|
*/
|
||||||
const exchangeAndAmount = useAsyncAsHook(
|
const uriHookDep =
|
||||||
async () => {
|
!uriInfoHook || uriInfoHook.hasError || !uriInfoHook.response
|
||||||
if (!uriInfoHook || uriInfoHook.hasError || !uriInfoHook.response) return;
|
? undefined
|
||||||
const { uriInfo, knownExchanges } = uriInfoHook.response;
|
: uriInfoHook;
|
||||||
|
|
||||||
const amount = Amounts.parseOrThrow(uriInfo.amount);
|
const { amount, thisExchange, thisCurrencyExchanges } = useMemo(() => {
|
||||||
|
if (!uriHookDep)
|
||||||
|
return {
|
||||||
|
amount: undefined,
|
||||||
|
thisExchange: undefined,
|
||||||
|
thisCurrencyExchanges: [],
|
||||||
|
};
|
||||||
|
|
||||||
const thisCurrencyExchanges = knownExchanges.filter(
|
const { uriInfo, knownExchanges } = uriHookDep.response;
|
||||||
(ex) => ex.currency === amount.currency,
|
|
||||||
);
|
|
||||||
|
|
||||||
const thisExchange: string | undefined =
|
const amount = uriInfo ? Amounts.parseOrThrow(uriInfo.amount) : undefined;
|
||||||
customExchange ??
|
const thisCurrencyExchanges =
|
||||||
uriInfo.defaultExchangeBaseUrl ??
|
!amount || !knownExchanges
|
||||||
(thisCurrencyExchanges[0]
|
? []
|
||||||
? thisCurrencyExchanges[0].exchangeBaseUrl
|
: knownExchanges.filter((ex) => ex.currency === amount.currency);
|
||||||
: undefined);
|
|
||||||
|
|
||||||
if (!thisExchange) throw Error("ERROR_NO-DEFAULT-EXCHANGE");
|
const thisExchange: string | undefined =
|
||||||
|
customExchange ??
|
||||||
|
uriInfo?.defaultExchangeBaseUrl ??
|
||||||
|
(thisCurrencyExchanges && thisCurrencyExchanges[0]
|
||||||
|
? thisCurrencyExchanges[0].exchangeBaseUrl
|
||||||
|
: undefined);
|
||||||
|
|
||||||
return { amount, thisExchange, thisCurrencyExchanges };
|
return { amount, thisExchange, thisCurrencyExchanges };
|
||||||
},
|
}, [uriHookDep, customExchange]);
|
||||||
[],
|
|
||||||
[!uriInfoHook || uriInfoHook.hasError ? undefined : uriInfoHook],
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For the exchange selected, bring the status of the terms of service
|
* For the exchange selected, bring the status of the terms of service
|
||||||
*/
|
*/
|
||||||
const terms = useAsyncAsHook(
|
const terms = useAsyncAsHook(
|
||||||
async () => {
|
async () => {
|
||||||
if (
|
if (!thisExchange) return false;
|
||||||
!exchangeAndAmount ||
|
|
||||||
exchangeAndAmount.hasError ||
|
|
||||||
!exchangeAndAmount.response
|
|
||||||
)
|
|
||||||
return;
|
|
||||||
const { thisExchange } = exchangeAndAmount.response;
|
|
||||||
const exchangeTos = await api.getExchangeTos(thisExchange, ["text/xml"]);
|
const exchangeTos = await api.getExchangeTos(thisExchange, ["text/xml"]);
|
||||||
|
|
||||||
const state = buildTermsOfServiceState(exchangeTos);
|
const state = buildTermsOfServiceState(exchangeTos);
|
||||||
@ -161,11 +161,7 @@ export function useComponentState(
|
|||||||
return { state };
|
return { state };
|
||||||
},
|
},
|
||||||
[],
|
[],
|
||||||
[
|
[thisExchange],
|
||||||
!exchangeAndAmount || exchangeAndAmount.hasError
|
|
||||||
? undefined
|
|
||||||
: exchangeAndAmount,
|
|
||||||
],
|
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -174,13 +170,7 @@ export function useComponentState(
|
|||||||
*/
|
*/
|
||||||
const info = useAsyncAsHook(
|
const info = useAsyncAsHook(
|
||||||
async () => {
|
async () => {
|
||||||
if (
|
if (!thisExchange || !amount) return false;
|
||||||
!exchangeAndAmount ||
|
|
||||||
exchangeAndAmount.hasError ||
|
|
||||||
!exchangeAndAmount.response
|
|
||||||
)
|
|
||||||
return;
|
|
||||||
const { thisExchange, amount } = exchangeAndAmount.response;
|
|
||||||
|
|
||||||
const info = await api.getExchangeWithdrawalInfo({
|
const info = await api.getExchangeWithdrawalInfo({
|
||||||
exchangeBaseUrl: thisExchange,
|
exchangeBaseUrl: thisExchange,
|
||||||
@ -196,11 +186,7 @@ export function useComponentState(
|
|||||||
return { info, withdrawalFee };
|
return { info, withdrawalFee };
|
||||||
},
|
},
|
||||||
[],
|
[],
|
||||||
[
|
[thisExchange, amount],
|
||||||
!exchangeAndAmount || exchangeAndAmount.hasError
|
|
||||||
? undefined
|
|
||||||
: exchangeAndAmount,
|
|
||||||
],
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const [reviewing, setReviewing] = useState<boolean>(false);
|
const [reviewing, setReviewing] = useState<boolean>(false);
|
||||||
@ -221,26 +207,27 @@ export function useComponentState(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!exchangeAndAmount || exchangeAndAmount.hasError) {
|
if (!thisExchange || !amount) {
|
||||||
return {
|
return {
|
||||||
status: "loading-exchange",
|
status: "loading-exchange",
|
||||||
hook: exchangeAndAmount,
|
hook: {
|
||||||
|
hasError: true,
|
||||||
|
operational: false,
|
||||||
|
message: "ERROR_NO-DEFAULT-EXCHANGE",
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if (!exchangeAndAmount.response) {
|
|
||||||
return {
|
const selectedExchange = thisExchange;
|
||||||
status: "loading-exchange",
|
|
||||||
hook: undefined,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
const { thisExchange, thisCurrencyExchanges, amount } =
|
|
||||||
exchangeAndAmount.response;
|
|
||||||
|
|
||||||
async function doWithdrawAndCheckError(): Promise<void> {
|
async function doWithdrawAndCheckError(): Promise<void> {
|
||||||
try {
|
try {
|
||||||
setConfirmDisabled(true);
|
setConfirmDisabled(true);
|
||||||
if (!talerWithdrawUri) return;
|
if (!talerWithdrawUri) return;
|
||||||
const res = await api.acceptWithdrawal(talerWithdrawUri, thisExchange);
|
const res = await api.acceptWithdrawal(
|
||||||
|
talerWithdrawUri,
|
||||||
|
selectedExchange,
|
||||||
|
);
|
||||||
if (res.confirmTransferUrl) {
|
if (res.confirmTransferUrl) {
|
||||||
document.location.href = res.confirmTransferUrl;
|
document.location.href = res.confirmTransferUrl;
|
||||||
}
|
}
|
||||||
@ -308,7 +295,7 @@ export function useComponentState(
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
await api.setExchangeTosAccepted(
|
await api.setExchangeTosAccepted(
|
||||||
thisExchange,
|
selectedExchange,
|
||||||
accepted ? termsState.version : undefined,
|
accepted ? termsState.version : undefined,
|
||||||
);
|
);
|
||||||
setReviewed(accepted);
|
setReviewed(accepted);
|
||||||
|
@ -42,7 +42,7 @@ export interface HookOperationalError {
|
|||||||
export type HookResponse<T> = HookOk<T> | HookError | undefined;
|
export type HookResponse<T> = HookOk<T> | HookError | undefined;
|
||||||
|
|
||||||
export function useAsyncAsHook<T>(
|
export function useAsyncAsHook<T>(
|
||||||
fn: () => Promise<T>,
|
fn: () => Promise<T | false>,
|
||||||
updateOnNotification?: Array<NotificationType>,
|
updateOnNotification?: Array<NotificationType>,
|
||||||
deps?: any[],
|
deps?: any[],
|
||||||
): HookResponse<T> {
|
): HookResponse<T> {
|
||||||
@ -57,6 +57,7 @@ export function useAsyncAsHook<T>(
|
|||||||
async function doAsync(): Promise<void> {
|
async function doAsync(): Promise<void> {
|
||||||
try {
|
try {
|
||||||
const response = await args.fn();
|
const response = await args.fn();
|
||||||
|
if (response === false) return;
|
||||||
setHookResponse({ hasError: false, response });
|
setHookResponse({ hasError: false, response });
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e instanceof TalerError) {
|
if (e instanceof TalerError) {
|
||||||
|
Loading…
Reference in New Issue
Block a user