diff options
author | Sebastian <sebasjm@gmail.com> | 2022-04-22 16:10:21 -0300 |
---|---|---|
committer | Sebastian <sebasjm@gmail.com> | 2022-04-22 16:10:46 -0300 |
commit | c5f484d18a89bd6cda0c7a89eea5ee9d7fe4ba09 (patch) | |
tree | 2e8eb89bc2912d4858536b01ce1a5faf3d5fcec5 /packages/taler-wallet-webextension/src/cta | |
parent | 8e468ae092212896b16b57f0043df9e2410fc906 (diff) | |
download | wallet-core-c5f484d18a89bd6cda0c7a89eea5ee9d7fe4ba09.tar.xz |
deposit test case
Diffstat (limited to 'packages/taler-wallet-webextension/src/cta')
5 files changed, 52 insertions, 382 deletions
diff --git a/packages/taler-wallet-webextension/src/cta/Deposit.stories.tsx b/packages/taler-wallet-webextension/src/cta/Deposit.stories.tsx index 923ea9e96..6432d532d 100644 --- a/packages/taler-wallet-webextension/src/cta/Deposit.stories.tsx +++ b/packages/taler-wallet-webextension/src/cta/Deposit.stories.tsx @@ -21,7 +21,7 @@ import { ContractTerms, PreparePayResultType } from "@gnu-taler/taler-util"; import { createExample } from "../test-utils.js"; -import { PaymentRequestView as TestedComponent } from "./Deposit.js"; +import { View as TestedComponent } from "./Deposit.js"; export default { title: "cta/deposit", @@ -29,140 +29,6 @@ export default { argTypes: {}, }; -export const NoBalance = createExample(TestedComponent, { - payStatus: { - status: PreparePayResultType.InsufficientBalance, - noncePriv: "", - proposalId: "proposal1234", - contractTerms: { - merchant: { - name: "someone", - }, - summary: "some beers", - amount: "USD:10", - } as Partial<ContractTerms> as any, - amountRaw: "USD:10", - }, -}); - -export const NoEnoughBalance = createExample(TestedComponent, { - payStatus: { - status: PreparePayResultType.InsufficientBalance, - noncePriv: "", - proposalId: "proposal1234", - contractTerms: { - merchant: { - name: "someone", - }, - summary: "some beers", - amount: "USD:10", - } as Partial<ContractTerms> as any, - amountRaw: "USD:10", - }, - balance: { - currency: "USD", - fraction: 40000000, - value: 9, - }, -}); - -export const PaymentPossible = createExample(TestedComponent, { - uri: "taler://pay/merchant-backend.taler/2021.242-01G2X4275RBWG/?c=66BE594PDZR24744J6EQK52XM0", - payStatus: { - status: PreparePayResultType.PaymentPossible, - amountEffective: "USD:10", - amountRaw: "USD:10", - noncePriv: "", - contractTerms: { - nonce: "123213123", - merchant: { - name: "someone", - }, - amount: "USD:10", - summary: "some beers", - } as Partial<ContractTerms> as any, - contractTermsHash: "123456", - proposalId: "proposal1234", - }, -}); - -export const PaymentPossibleWithFee = createExample(TestedComponent, { - uri: "taler://pay/merchant-backend.taler/2021.242-01G2X4275RBWG/?c=66BE594PDZR24744J6EQK52XM0", - payStatus: { - status: PreparePayResultType.PaymentPossible, - amountEffective: "USD:10.20", - amountRaw: "USD:10", - noncePriv: "", - contractTerms: { - nonce: "123213123", - merchant: { - name: "someone", - }, - amount: "USD:10", - summary: "some beers", - } as Partial<ContractTerms> as any, - contractTermsHash: "123456", - proposalId: "proposal1234", - }, -}); - -export const AlreadyConfirmedWithFullfilment = createExample(TestedComponent, { - payStatus: { - status: PreparePayResultType.AlreadyConfirmed, - amountEffective: "USD:10", - amountRaw: "USD:10", - contractTerms: { - merchant: { - name: "someone", - }, - fulfillment_message: - "congratulations! you are looking at the fulfillment message! ", - summary: "some beers", - amount: "USD:10", - } as Partial<ContractTerms> as any, - contractTermsHash: "123456", - proposalId: "proposal1234", - paid: false, - }, -}); - -export const AlreadyConfirmedWithoutFullfilment = createExample( - TestedComponent, - { - payStatus: { - status: PreparePayResultType.AlreadyConfirmed, - amountEffective: "USD:10", - amountRaw: "USD:10", - contractTerms: { - merchant: { - name: "someone", - }, - summary: "some beers", - amount: "USD:10", - } as Partial<ContractTerms> as any, - contractTermsHash: "123456", - proposalId: "proposal1234", - paid: false, - }, - }, -); - -export const AlreadyPaid = createExample(TestedComponent, { - payStatus: { - status: PreparePayResultType.AlreadyConfirmed, - amountEffective: "USD:10", - amountRaw: "USD:10", - contractTerms: { - merchant: { - name: "someone", - }, - fulfillment_message: - "congratulations! you are looking at the fulfillment message! ", - summary: "some beers", - amount: "USD:10", - } as Partial<ContractTerms> as any, - contractTermsHash: "123456", - proposalId: "proposal1234", - paid: true, - }, +export const Simple = createExample(TestedComponent, { + state: { status: "ready" }, }); diff --git a/packages/taler-wallet-webextension/src/cta/Deposit.tsx b/packages/taler-wallet-webextension/src/cta/Deposit.tsx index 541bc733b..23c557b0c 100644 --- a/packages/taler-wallet-webextension/src/cta/Deposit.tsx +++ b/packages/taler-wallet-webextension/src/cta/Deposit.tsx @@ -39,6 +39,8 @@ import { TalerError } from "@gnu-taler/taler-wallet-core"; import { Fragment, h, VNode } from "preact"; import { useEffect, useState } from "preact/hooks"; import { ErrorTalerOperation } from "../components/ErrorTalerOperation.js"; +import { Loading } from "../components/Loading.js"; +import { LoadingError } from "../components/LoadingError.js"; import { LogoHeader } from "../components/LogoHeader.js"; import { Part } from "../components/Part.js"; import { @@ -49,157 +51,50 @@ import { WarningBox, } from "../components/styled/index.js"; import { useTranslationContext } from "../context/translation.js"; -import { useAsyncAsHook } from "../hooks/useAsyncAsHook.js"; +import { HookError, useAsyncAsHook } from "../hooks/useAsyncAsHook.js"; import * as wxApi from "../wxApi.js"; interface Props { - talerPayUri?: string; + talerDepositUri?: string; goBack: () => void; } -export function DepositPage({ talerPayUri, goBack }: Props): VNode { - const { i18n } = useTranslationContext(); - const [payStatus, setPayStatus] = useState<PreparePayResult | undefined>( - undefined, - ); - const [payResult, setPayResult] = useState<ConfirmPayResult | undefined>( - undefined, - ); - const [payErrMsg, setPayErrMsg] = useState<TalerError | string | undefined>( - undefined, - ); - - const balance = useAsyncAsHook(wxApi.getBalance, [ - NotificationType.CoinWithdrawn, - ]); - const balanceWithoutError = balance?.hasError - ? [] - : balance?.response.balances || []; - - const foundBalance = balanceWithoutError.find( - (b) => - payStatus && - Amounts.parseOrThrow(b.available).currency === - Amounts.parseOrThrow(payStatus?.amountRaw).currency, - ); - const foundAmount = foundBalance - ? Amounts.parseOrThrow(foundBalance.available) - : undefined; - // We use a string here so that dependency tracking for useEffect works properly - const foundAmountStr = foundAmount - ? Amounts.stringify(foundAmount) - : undefined; +type State = Loading | Ready; +interface Loading { + status: "loading"; + hook: HookError | undefined; +} +interface Ready { + status: "ready"; +} - useEffect(() => { - if (!talerPayUri) return; - const doFetch = async (): Promise<void> => { - try { - const p = await wxApi.preparePay(talerPayUri); - setPayStatus(p); - } catch (e) { - console.log("Got error while trying to pay", e); - if (e instanceof TalerError) { - setPayErrMsg(e); - } - if (e instanceof Error) { - setPayErrMsg(e.message); - } - } - }; - doFetch(); - }, [talerPayUri, foundAmountStr]); +function useComponentState(uri: string | undefined): State { + return { + status: "loading", + hook: undefined, + }; +} - if (!talerPayUri) { - return ( - <span> - <i18n.Translate>missing pay uri</i18n.Translate> - </span> - ); - } +export function DepositPage({ talerDepositUri, goBack }: Props): VNode { + const { i18n } = useTranslationContext(); - if (!payStatus) { - if (payErrMsg instanceof TalerError) { - return ( - <WalletAction> - <LogoHeader /> - <SubTitle> - <i18n.Translate>Digital cash payment</i18n.Translate> - </SubTitle> - <section> - <ErrorTalerOperation - title={ - <i18n.Translate> - Could not get the payment information for this order - </i18n.Translate> - } - error={payErrMsg?.errorDetail} - /> - </section> - </WalletAction> - ); - } - if (payErrMsg) { - return ( - <WalletAction> - <LogoHeader /> - <SubTitle> - <i18n.Translate>Digital cash payment</i18n.Translate> - </SubTitle> - <section> - <p> - <i18n.Translate> - Could not get the payment information for this order - </i18n.Translate> - </p> - <ErrorBox>{payErrMsg}</ErrorBox> - </section> - </WalletAction> - ); - } + const state = useComponentState(talerDepositUri); + if (state.status === "loading") { + if (!state.hook) return <Loading />; return ( - <span> - <i18n.Translate>Loading payment information</i18n.Translate> ... - </span> + <LoadingError + title={<i18n.Translate>Could not load pay status</i18n.Translate>} + error={state.hook} + /> ); } - - const onClick = async (): Promise<void> => { - // try { - // const res = await doPayment(payStatus); - // setPayResult(res); - // } catch (e) { - // console.error(e); - // if (e instanceof Error) { - // setPayErrMsg(e.message); - // } - // } - }; - - return ( - <PaymentRequestView - uri={talerPayUri} - payStatus={payStatus} - payResult={payResult} - onClick={onClick} - balance={foundAmount} - /> - ); + return <View state={state} />; } -export interface PaymentRequestViewProps { - payStatus: PreparePayResult; - payResult?: ConfirmPayResult; - onClick: () => void; - payErrMsg?: string; - uri: string; - balance: AmountJson | undefined; +export interface ViewProps { + state: State; } -export function PaymentRequestView({ - payStatus, - payResult, -}: PaymentRequestViewProps): VNode { - const totalFees: AmountJson = Amounts.getZero(payStatus.amountRaw); - const contractTerms: ContractTerms = payStatus.contractTerms; +export function View({ state }: ViewProps): VNode { const { i18n } = useTranslationContext(); return ( @@ -209,78 +104,6 @@ export function PaymentRequestView({ <SubTitle> <i18n.Translate>Digital cash deposit</i18n.Translate> </SubTitle> - {payStatus.status === PreparePayResultType.AlreadyConfirmed && - (payStatus.paid ? ( - <SuccessBox> - <i18n.Translate>Already paid</i18n.Translate> - </SuccessBox> - ) : ( - <WarningBox> - <i18n.Translate>Already claimed</i18n.Translate> - </WarningBox> - ))} - {payResult && payResult.type === ConfirmPayResultType.Done && ( - <SuccessBox> - <h3> - <i18n.Translate>Payment complete</i18n.Translate> - </h3> - <p> - {!payResult.contractTerms.fulfillment_message ? ( - <i18n.Translate> - You will now be sent back to the merchant you came from. - </i18n.Translate> - ) : ( - payResult.contractTerms.fulfillment_message - )} - </p> - </SuccessBox> - )} - <section> - {payStatus.status !== PreparePayResultType.InsufficientBalance && - Amounts.isNonZero(totalFees) && ( - <Part - big - title={<i18n.Translate>Total to pay</i18n.Translate>} - text={amountToPretty( - Amounts.parseOrThrow(payStatus.amountEffective), - )} - kind="negative" - /> - )} - <Part - big - title={<i18n.Translate>Purchase amount</i18n.Translate>} - text={amountToPretty(Amounts.parseOrThrow(payStatus.amountRaw))} - kind="neutral" - /> - {Amounts.isNonZero(totalFees) && ( - <Fragment> - <Part - big - title={<i18n.Translate>Fee</i18n.Translate>} - text={amountToPretty(totalFees)} - kind="negative" - /> - </Fragment> - )} - <Part - title={<i18n.Translate>Merchant</i18n.Translate>} - text={contractTerms.merchant.name} - kind="neutral" - /> - <Part - title={<i18n.Translate>Purchase</i18n.Translate>} - text={contractTerms.summary} - kind="neutral" - /> - {contractTerms.order_id && ( - <Part - title={<i18n.Translate>Receipt</i18n.Translate>} - text={`#${contractTerms.order_id}`} - kind="neutral" - /> - )} - </section> </WalletAction> ); } diff --git a/packages/taler-wallet-webextension/src/cta/Pay.tsx b/packages/taler-wallet-webextension/src/cta/Pay.tsx index 0d5d57378..832b4879c 100644 --- a/packages/taler-wallet-webextension/src/cta/Pay.tsx +++ b/packages/taler-wallet-webextension/src/cta/Pay.tsx @@ -65,7 +65,7 @@ import { useAsyncAsHook, useAsyncAsHook2, } from "../hooks/useAsyncAsHook.js"; -import { ButtonHandler } from "../wallet/CreateManualWithdraw.js"; +import { ButtonHandler } from "../mui/handlers.js"; import * as wxApi from "../wxApi.js"; interface Props { @@ -74,32 +74,6 @@ interface Props { goBack: () => void; } -async function doPayment( - payStatus: PreparePayResult, - api: typeof wxApi, -): Promise<ConfirmPayResultDone> { - if (payStatus.status !== "payment-possible") { - throw TalerError.fromUncheckedDetail({ - code: TalerErrorCode.GENERIC_CLIENT_INTERNAL_ERROR, - hint: `payment is not possible: ${payStatus.status}`, - }); - } - const proposalId = payStatus.proposalId; - const res = await api.confirmPay(proposalId, undefined); - if (res.type !== ConfirmPayResultType.Done) { - throw TalerError.fromUncheckedDetail({ - code: TalerErrorCode.GENERIC_CLIENT_INTERNAL_ERROR, - hint: `could not confirm payment`, - payResult: res, - }); - } - const fu = res.contractTerms.fulfillment_url; - if (fu) { - document.location.href = fu; - } - return res; -} - type State = Loading | Ready | Confirmed; interface Loading { status: "loading"; diff --git a/packages/taler-wallet-webextension/src/cta/Withdraw.stories.tsx b/packages/taler-wallet-webextension/src/cta/Withdraw.stories.tsx index 2191205c2..f2bc14f76 100644 --- a/packages/taler-wallet-webextension/src/cta/Withdraw.stories.tsx +++ b/packages/taler-wallet-webextension/src/cta/Withdraw.stories.tsx @@ -66,7 +66,9 @@ export const TermsOfServiceNotYetLoaded = createExample(TestedComponent, { exchange: { list: exchangeList, value: "exchange.demo.taler.net", - onChange: () => null, + onChange: async () => { + null; + }, }, showExchangeSelection: false, mustAcceptFirst: false, @@ -99,7 +101,9 @@ export const WithSomeFee = createExample(TestedComponent, { exchange: { list: exchangeList, value: "exchange.demo.taler.net", - onChange: () => null, + onChange: async () => { + null; + }, }, showExchangeSelection: false, mustAcceptFirst: false, @@ -133,7 +137,9 @@ export const WithoutFee = createExample(TestedComponent, { exchange: { list: exchangeList, value: "exchange.demo.taler.net", - onChange: () => null, + onChange: async () => { + null; + }, }, showExchangeSelection: false, mustAcceptFirst: false, @@ -167,7 +173,9 @@ export const EditExchangeUntouched = createExample(TestedComponent, { exchange: { list: exchangeList, value: "exchange.demo.taler.net", - onChange: () => null, + onChange: async () => { + null; + }, }, showExchangeSelection: true, mustAcceptFirst: false, @@ -202,7 +210,9 @@ export const EditExchangeModified = createExample(TestedComponent, { list: exchangeList, isDirty: true, value: "exchange.test.taler.net", - onChange: () => null, + onChange: async () => { + null; + }, }, showExchangeSelection: true, mustAcceptFirst: false, diff --git a/packages/taler-wallet-webextension/src/cta/Withdraw.tsx b/packages/taler-wallet-webextension/src/cta/Withdraw.tsx index 2293d6508..21f98ec9a 100644 --- a/packages/taler-wallet-webextension/src/cta/Withdraw.tsx +++ b/packages/taler-wallet-webextension/src/cta/Withdraw.tsx @@ -42,10 +42,7 @@ import { import { useTranslationContext } from "../context/translation.js"; import { HookError, useAsyncAsHook } from "../hooks/useAsyncAsHook.js"; import { buildTermsOfServiceState } from "../utils/index.js"; -import { - ButtonHandler, - SelectFieldHandler, -} from "../wallet/CreateManualWithdraw.js"; +import { ButtonHandler, SelectFieldHandler } from "../mui/handlers.js"; import * as wxApi from "../wxApi.js"; import { Props as TermsOfServiceSectionProps, @@ -258,7 +255,7 @@ export function useComponentState( } const exchangeHandler: SelectFieldHandler = { - onChange: setNextExchange, + onChange: async (e) => setNextExchange(e), value: nextExchange ?? thisExchange, list: exchanges, isDirty: nextExchange !== undefined, |