/* This file is part of GNU Taler (C) 2021 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 */ import { ComponentChildren, FunctionalComponent, h, VNode } from "preact"; import { MockEnvironment } from "./mock.js"; import { SWRConfig } from "swr"; import * as swr__internal from "swr/_internal"; import { Logger } from "@gnu-taler/taler-util"; import { buildRequestFailed, RequestError } from "../index.browser.js"; const logger = new Logger("tests/swr.ts"); /** * Helper for hook that use SWR inside. * * buildTestingContext() will return a testing context * */ export class SwrMockEnvironment extends MockEnvironment { constructor(debug = false) { super(debug); } public buildTestingContext(): FunctionalComponent<{ children: ComponentChildren; }> { const __SAVE_REQUEST_AND_GET_MOCKED_RESPONSE = this.saveRequestAndGetMockedResponse.bind(this); function testingFetcher(params: any): any { const url = JSON.stringify(params); const mocked = __SAVE_REQUEST_AND_GET_MOCKED_RESPONSE( { method: "get", url, }, {}, ); //unexpected query if (!mocked.expectedQuery) return undefined; const status = mocked.expectedQuery.query.code ?? 200; const requestPayload = mocked.expectedQuery.params?.request; const responsePayload = mocked.expectedQuery.params?.response; //simulated error if (status >= 400) { const error = buildRequestFailed( url, JSON.stringify(responsePayload), status, requestPayload, ); //example error handling from https://swr.vercel.app/docs/error-handling throw new RequestError(error); } return responsePayload; } const value: Partial & { provider: () => Map; } = { use: [ (useSWRNext) => { return (key, fetcher, config) => { //prevent the request //use the testing fetcher instead return useSWRNext(key, testingFetcher, config); }; }, ], fetcher: testingFetcher, //These options are set for ending the test faster //otherwise SWR will create timeouts that will live after the test finished loadingTimeout: 0, dedupingInterval: 0, shouldRetryOnError: false, errorRetryInterval: 0, errorRetryCount: 0, //clean cache for every test provider: () => new Map(), }; return function TestingContext({ children, }: { children: ComponentChildren; }): VNode { return h(SWRConfig, { value }, children); }; } }