summaryrefslogtreecommitdiff
path: root/packages/taler-wallet-webextension/src/test-utils.ts
diff options
context:
space:
mode:
Diffstat (limited to 'packages/taler-wallet-webextension/src/test-utils.ts')
-rw-r--r--packages/taler-wallet-webextension/src/test-utils.ts202
1 files changed, 194 insertions, 8 deletions
diff --git a/packages/taler-wallet-webextension/src/test-utils.ts b/packages/taler-wallet-webextension/src/test-utils.ts
index 6bf1be3ff..452cc578e 100644
--- a/packages/taler-wallet-webextension/src/test-utils.ts
+++ b/packages/taler-wallet-webextension/src/test-utils.ts
@@ -1,6 +1,6 @@
/*
This file is part of GNU Taler
- (C) 2021 Taler Systems S.A.
+ (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
@@ -14,15 +14,201 @@
GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/
-import { ComponentChildren, FunctionalComponent, h as render } from 'preact';
+import { NotificationType, TalerBankIntegrationHttpClient, TalerCoreBankHttpClient, TalerRevenueHttpClient, TalerWireGatewayHttpClient, WalletNotification } from "@gnu-taler/taler-util";
+import {
+ WalletCoreApiClient,
+ WalletCoreOpKeys,
+ WalletCoreRequestType,
+ WalletCoreResponseType,
+} from "@gnu-taler/taler-wallet-core";
+import { ApiContextProvider, TranslationProvider, defaultRequestHandler } from "@gnu-taler/web-util/browser";
+import {
+ ComponentChildren,
+ FunctionalComponent,
+ VNode,
+ h as create,
+} from "preact";
+import { AlertProvider } from "./context/alert.js";
+import { BackendProvider } from "./context/backend.js";
+import { strings } from "./i18n/strings.js";
+import { nullFunction } from "./mui/handlers.js";
+import { BackgroundApiClient, wxApi } from "./wxApi.js";
-export function createExample<Props>(Component: FunctionalComponent<Props>, props: Partial<Props>) {
- const r = (args: any) => render(Component, args)
- r.args = props
- return r
+// export const nullFunction: any = () => null;
+
+interface MockHandler {
+ addWalletCallResponse<Op extends WalletCoreOpKeys>(
+ operation: Op,
+ payload?: Partial<WalletCoreRequestType<Op>>,
+ response?: WalletCoreResponseType<Op>,
+ callback?: () => void,
+ ): MockHandler;
+
+ getCallingQueueState(): "empty" | string;
+
+ notifyEventFromWallet(notif: WalletNotification): void;
}
+type CallRecord = WalletCallRecord | BackgroundCallRecord;
+interface WalletCallRecord {
+ source: "wallet";
+ callback: () => void;
+ operation: WalletCoreOpKeys;
+ payload?: WalletCoreRequestType<WalletCoreOpKeys>;
+ response?: WalletCoreResponseType<WalletCoreOpKeys>;
+}
+interface BackgroundCallRecord {
+ source: "background";
+ name: string;
+ args: any;
+ response: any;
+}
+
+type Subscriptions = {
+ [key in NotificationType]?: (d: WalletNotification) => void;
+};
+
+export function createWalletApiMock(): {
+ handler: MockHandler;
+ TestingContext: FunctionalComponent<{ children: ComponentChildren }>;
+} {
+ const calls = new Array<CallRecord>();
+ const subscriptions: Subscriptions = {};
+
+ const mock: typeof wxApi = {
+ wallet: new Proxy<WalletCoreApiClient>({} as any, {
+ get(target, name, receiver) {
+ const functionName = String(name);
+ if (functionName !== "call") {
+ throw Error(
+ `the only method in wallet api should be 'call': ${functionName}`,
+ );
+ }
+ return function (
+ operation: WalletCoreOpKeys,
+ payload: WalletCoreRequestType<WalletCoreOpKeys>,
+ ) {
+ const next = calls.shift();
+
+ if (!next) {
+ throw Error(
+ `wallet operation was called but none was expected: ${operation} (${JSON.stringify(
+ payload,
+ undefined,
+ 2,
+ )})`,
+ );
+ }
+ if (next.source !== "wallet") {
+ throw Error(`wallet operation expected`);
+ }
+ if (operation !== next.operation) {
+ //more checks, deep check payload
+ throw Error(
+ `wallet operation doesn't match: expected ${next.operation} actual ${operation}`,
+ );
+ }
+ next.callback();
+
+ return next.response ?? {};
+ };
+ },
+ }),
+ listener: {
+ trigger: () => {
+
+ },
+ onUpdateNotification(
+ mTypes: NotificationType[],
+ callback: ((d: WalletNotification) => void) | undefined,
+ ): () => void {
+ mTypes.forEach((m) => {
+ subscriptions[m] = callback;
+ });
+ return nullFunction;
+ },
+ },
+ background: new Proxy<BackgroundApiClient>({} as any, {
+ get(target, name, receiver) {
+ const functionName = String(name);
+ return function (...args: any) {
+ const next = calls.shift();
+ if (!next) {
+ throw Error(
+ `background operation was called but none was expected: ${functionName} (${JSON.stringify(
+ args,
+ undefined,
+ 2,
+ )})`,
+ );
+ }
+ if (next.source !== "background" || functionName !== next.name) {
+ //more checks, deep check args
+ throw Error(`background operation doesn't match`);
+ }
+ return next.response;
+ };
+ },
+ }),
+ };
+
+ const handler: MockHandler = {
+ addWalletCallResponse(operation, payload, response, cb) {
+ calls.push({
+ source: "wallet",
+ operation,
+ payload,
+ response,
+ callback: cb
+ ? cb
+ : () => {
+ null;
+ },
+ });
+ return handler;
+ },
+ notifyEventFromWallet(event: WalletNotification): void {
+ const callback = subscriptions[event.type];
+ if (!callback)
+ throw Error(`Expected to have a subscription for ${event}`);
+ return callback(event);
+ },
+ getCallingQueueState() {
+ return calls.length === 0 ? "empty" : `${calls.length} left`;
+ },
+ };
+
+ function TestingContext({
+ children: _cs,
+ }: {
+ children: ComponentChildren;
+ }): VNode {
+ let children = _cs;
+ children = create(AlertProvider, { children }, children);
+ const value = {
+ request: defaultRequestHandler,
+ bankCore: new TalerCoreBankHttpClient("/"),
+ bankIntegration: new TalerBankIntegrationHttpClient("/"),
+ bankWire: new TalerWireGatewayHttpClient("/",""),
+ bankRevenue: new TalerRevenueHttpClient("/"),
+ }
+ children = create(ApiContextProvider, { value, children }, children);
+ children = create(
+ TranslationProvider,
+ { children, source: strings, initial: "en", forceLang: "en" },
+ children,
+ );
+ return create(
+ BackendProvider,
+ {
+ wallet: mock.wallet,
+ background: mock.background,
+ listener: mock.listener,
+ children,
+ },
+ children,
+ );
+ }
-export function NullLink({ children }: { children?: ComponentChildren }) {
- return render('a', { children, href: 'javascript:void(0);' })
+ return { handler, TestingContext };
}