diff options
Diffstat (limited to 'packages/taler-wallet-webextension/src/cta/DevExperiment')
5 files changed, 328 insertions, 0 deletions
diff --git a/packages/taler-wallet-webextension/src/cta/DevExperiment/index.ts b/packages/taler-wallet-webextension/src/cta/DevExperiment/index.ts new file mode 100644 index 000000000..ec09fd9f1 --- /dev/null +++ b/packages/taler-wallet-webextension/src/cta/DevExperiment/index.ts @@ -0,0 +1,73 @@ +/* + This file is part of GNU Taler + (C) 2022 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ + +import { ErrorAlertView } from "../../components/CurrentAlerts.js"; +import { Loading } from "../../components/Loading.js"; +import { ErrorAlert } from "../../context/alert.js"; +import { ButtonHandler } from "../../mui/handlers.js"; +import { StateViewMap, compose } from "../../utils/index.js"; +import { useComponentState } from "./state.js"; +import { InsertLostView, InsertPendingRefreshView, UnknownView } from "./views.js"; + +export interface Props { + talerExperimentUri: string | undefined; + onCancel: () => Promise<void>; + onSuccess: () => Promise<void>; +} + +export type State = State.Loading | State.LoadingUriError | State.Unknown | State.InsertLost | State.PendingRefresh; + +export namespace State { + export interface Loading { + status: "loading"; + error: undefined; + } + export interface LoadingUriError { + status: "error"; + error: ErrorAlert; + } + export interface InsertLost { + status: "insertLost"; + error: undefined; + confirm: ButtonHandler; + cancel: () => Promise<void>; + } + export interface PendingRefresh { + status: "pendingRefresh"; + error: undefined; + confirm: ButtonHandler; + cancel: () => Promise<void>; + } + export interface Unknown { + status: "unknown"; + experimentId: string; + error: undefined; + } +} + +const viewMapping: StateViewMap<State> = { + loading: Loading, + error: ErrorAlertView, + pendingRefresh: InsertPendingRefreshView, + insertLost: InsertLostView, + unknown: UnknownView, +}; + +export const DevExperimentPage = compose( + "DevExperiment", + (p: Props) => useComponentState(p), + viewMapping, +); diff --git a/packages/taler-wallet-webextension/src/cta/DevExperiment/state.ts b/packages/taler-wallet-webextension/src/cta/DevExperiment/state.ts new file mode 100644 index 000000000..774a1129d --- /dev/null +++ b/packages/taler-wallet-webextension/src/cta/DevExperiment/state.ts @@ -0,0 +1,83 @@ +/* + This file is part of GNU Taler + (C) 2022 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ + +import { parseDevExperimentUri } from "@gnu-taler/taler-util"; +import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; +import { useTranslationContext } from "@gnu-taler/web-util/browser"; +import { useAlertContext } from "../../context/alert.js"; +import { useBackendContext } from "../../context/backend.js"; +import { Props, State } from "./index.js"; + +export function useComponentState({ + talerExperimentUri, + onCancel, + onSuccess, +}: Props): State { + const api = useBackendContext(); + const { pushAlertOnError } = useAlertContext(); + const { i18n } = useTranslationContext(); + + async function doApply(): Promise<void> { + if (!talerExperimentUri) return; + await api.wallet.call(WalletApiOperation.ApplyDevExperiment, { + devExperimentUri: talerExperimentUri + }) + // const resp = await api.wallet.call(WalletApiOperation.CreateDepositGroup, { + // amount: Amounts.stringify(amount), + // depositPaytoUri: uri, + // }); + onSuccess(); + } + const uri = talerExperimentUri === undefined ? undefined : parseDevExperimentUri(talerExperimentUri); + + if (!uri) { + return { + status: "error", + error: { + type: "error", + message: i18n.str`Invalid dev experiment URI.`, + description: i18n.str`URI: ${talerExperimentUri}`, + cause: {}, + context: {}, + }, + }; + } + if (uri.devExperimentId === "insert-denom-loss") { + return { + status: "insertLost", + error: undefined, + confirm: { + onClick: pushAlertOnError(doApply), + }, + cancel: onCancel, + }; + } + if (uri.devExperimentId === "insert-pending-refresh") { + return { + status: "pendingRefresh", + error: undefined, + confirm: { + onClick: pushAlertOnError(doApply), + }, + cancel: onCancel, + }; + } + return { + status: "unknown", + error: undefined, + experimentId: uri.devExperimentId, + } +} diff --git a/packages/taler-wallet-webextension/src/cta/DevExperiment/stories.tsx b/packages/taler-wallet-webextension/src/cta/DevExperiment/stories.tsx new file mode 100644 index 000000000..c9851495f --- /dev/null +++ b/packages/taler-wallet-webextension/src/cta/DevExperiment/stories.tsx @@ -0,0 +1,33 @@ +/* + This file is part of GNU Taler + (C) 2022 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ + +/** + * + * @author Sebastian Javier Marchano (sebasjm) + */ + +import * as tests from "@gnu-taler/web-util/testing"; +import { InsertLostView } from "./views.js"; + +export default { + title: "dev-experiment", +}; + +export const Ready = tests.createExample(InsertLostView, { + status: "insertLost", + confirm: {}, + error: undefined, +}); diff --git a/packages/taler-wallet-webextension/src/cta/DevExperiment/test.ts b/packages/taler-wallet-webextension/src/cta/DevExperiment/test.ts new file mode 100644 index 000000000..d4f2ca8b1 --- /dev/null +++ b/packages/taler-wallet-webextension/src/cta/DevExperiment/test.ts @@ -0,0 +1,65 @@ +/* + This file is part of GNU Taler + (C) 2022 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ + +/** + * + * @author Sebastian Javier Marchano (sebasjm) + */ + +import * as tests from "@gnu-taler/web-util/testing"; +import { expect } from "chai"; +import { createWalletApiMock } from "../../test-utils.js"; +import { Props } from "./index.js"; +import { useComponentState } from "./state.js"; + +describe("DevExperiment CTA states", () => { + it("should tell the user that the URI is missing", async () => { + const { handler, TestingContext } = createWalletApiMock(); + + const props: Props = { + talerExperimentUri: undefined, + onCancel: async () => { + null; + }, + onSuccess: async () => { + null; + }, + }; + + const hookBehavior = await tests.hookBehaveLikeThis( + useComponentState, + props, + [ + ({ status }) => { + expect(status).equals("error"); + }, + ({ status, error }) => { + expect(status).equals("error"); + + if (!error) expect.fail(); + // if (!error.hasError) expect.fail(); + // if (error.operational) expect.fail(); + // expect(error.description).eq("ERROR_NO-URI-FOR-DEPOSIT"); + }, + ], + TestingContext, + ); + + expect(hookBehavior).deep.equal({ result: "ok" }); + expect(handler.getCallingQueueState()).eq("empty"); + }); + +}); diff --git a/packages/taler-wallet-webextension/src/cta/DevExperiment/views.tsx b/packages/taler-wallet-webextension/src/cta/DevExperiment/views.tsx new file mode 100644 index 000000000..afad17ad1 --- /dev/null +++ b/packages/taler-wallet-webextension/src/cta/DevExperiment/views.tsx @@ -0,0 +1,74 @@ +/* + This file is part of GNU Taler + (C) 2022 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ + +import { Amounts } from "@gnu-taler/taler-util"; +import { useTranslationContext } from "@gnu-taler/web-util/browser"; +import { Fragment, h, VNode } from "preact"; +import { Amount } from "../../components/Amount.js"; +import { Part } from "../../components/Part.js"; +import { Button } from "../../mui/Button.js"; +import { State } from "./index.js"; + +/** + * + * @author sebasjm + */ + +export function InsertLostView(state: State.InsertLost): VNode { + const { i18n } = useTranslationContext(); + return <Fragment> + <section> + <Part + title={i18n.str`Experiment`} + text={i18n.str`Insert lost denomination`} + /> + </section> + <section> + <Button + variant="contained" + color="success" + onClick={state.confirm.onClick} + > + <i18n.Translate>Apply</i18n.Translate> + </Button> + </section> + </Fragment> +} + +export function InsertPendingRefreshView(state: State.PendingRefresh): VNode { + const { i18n } = useTranslationContext(); + return <Fragment> + <section> + <Part + title={i18n.str`Experiment`} + text={i18n.str`Pending refresh`} + /> + </section> + <section> + <Button + variant="contained" + color="success" + onClick={state.confirm.onClick} + > + <i18n.Translate>Apply</i18n.Translate> + </Button> + </section> + </Fragment> +} + +export function UnknownView(state: State.Unknown): VNode { + return <div>unknown experiment "{state.experimentId}"</div> +} |