summaryrefslogtreecommitdiff
path: root/packages/taler-wallet-webextension/src/cta
diff options
context:
space:
mode:
authorSebastian <sebasjm@gmail.com>2022-04-22 16:10:21 -0300
committerSebastian <sebasjm@gmail.com>2022-04-22 16:10:46 -0300
commitc5f484d18a89bd6cda0c7a89eea5ee9d7fe4ba09 (patch)
tree2e8eb89bc2912d4858536b01ce1a5faf3d5fcec5 /packages/taler-wallet-webextension/src/cta
parent8e468ae092212896b16b57f0043df9e2410fc906 (diff)
downloadwallet-core-c5f484d18a89bd6cda0c7a89eea5ee9d7fe4ba09.tar.gz
wallet-core-c5f484d18a89bd6cda0c7a89eea5ee9d7fe4ba09.tar.bz2
wallet-core-c5f484d18a89bd6cda0c7a89eea5ee9d7fe4ba09.zip
deposit test case
Diffstat (limited to 'packages/taler-wallet-webextension/src/cta')
-rw-r--r--packages/taler-wallet-webextension/src/cta/Deposit.stories.tsx140
-rw-r--r--packages/taler-wallet-webextension/src/cta/Deposit.tsx239
-rw-r--r--packages/taler-wallet-webextension/src/cta/Pay.tsx28
-rw-r--r--packages/taler-wallet-webextension/src/cta/Withdraw.stories.tsx20
-rw-r--r--packages/taler-wallet-webextension/src/cta/Withdraw.tsx7
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,