[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[taler-merchant-backoffice] 03/03: fixing hook testing
From: |
gnunet |
Subject: |
[taler-merchant-backoffice] 03/03: fixing hook testing |
Date: |
Thu, 09 Dec 2021 19:03:38 +0100 |
This is an automated email from the git hooks/post-receive script.
sebasjm pushed a commit to branch master
in repository merchant-backoffice.
commit 7948aee7d14323946b29ccafc838edeb1190963a
Author: Sebastian <sebasjm@gmail.com>
AuthorDate: Thu Dec 9 15:03:17 2021 -0300
fixing hook testing
---
.../src/components/product/ProductList.tsx | 4 +-
packages/merchant-backoffice/src/hooks/admin.ts | 3 +-
packages/merchant-backoffice/src/hooks/backend.ts | 40 +++-
packages/merchant-backoffice/src/hooks/instance.ts | 4 +-
packages/merchant-backoffice/src/hooks/order.ts | 9 +-
packages/merchant-backoffice/src/hooks/product.ts | 99 +++++-----
packages/merchant-backoffice/src/hooks/tips.ts | 3 +-
packages/merchant-backoffice/src/hooks/transfer.ts | 3 +-
packages/merchant-backoffice/tests/axiosMock.ts | 216 +++++++++++++++++++++
.../merchant-backoffice/tests/declarations.d.ts | 10 +-
packages/merchant-backoffice/tests/header.test.tsx | 16 +-
.../tests/hooks/swr/order-create.test.tsx | 97 +++++----
.../tests/hooks/swr/order-pagination.test.tsx | 38 ++--
.../tests/hooks/swr/product-create.test.tsx | 113 ++++++-----
.../tests/hooks/swr/product-delete.test.tsx | 110 +++++------
.../hooks/swr/product-details-update.test.tsx | 78 ++++----
.../tests/hooks/swr/product-update.test.tsx | 113 ++++++-----
.../merchant-backoffice/tests/stories.test.tsx | 65 ++++---
packages/merchant-backoffice/tests/util.ts | 62 ------
19 files changed, 682 insertions(+), 401 deletions(-)
diff --git
a/packages/merchant-backoffice/src/components/product/ProductList.tsx
b/packages/merchant-backoffice/src/components/product/ProductList.tsx
index b1c03c6..ff141bb 100644
--- a/packages/merchant-backoffice/src/components/product/ProductList.tsx
+++ b/packages/merchant-backoffice/src/components/product/ProductList.tsx
@@ -13,10 +13,10 @@
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 { h, VNode } from "preact";
-import { MerchantBackend } from "../../declaration";
-import { AmountJson, Amounts } from "@gnu-taler/taler-util";
import emptyImage from "../../assets/empty.png";
+import { MerchantBackend } from "../../declaration";
import { Translate } from "../../i18n";
interface Props {
diff --git a/packages/merchant-backoffice/src/hooks/admin.ts
b/packages/merchant-backoffice/src/hooks/admin.ts
index 918bca0..1ac9e69 100644
--- a/packages/merchant-backoffice/src/hooks/admin.ts
+++ b/packages/merchant-backoffice/src/hooks/admin.ts
@@ -15,10 +15,11 @@
*/
import { MerchantBackend } from "../declaration";
import { useBackendContext } from "../context/backend";
-import { request, mutateAll } from "./backend";
+import { request, useMatchMutate } from "./backend";
export function useAdminAPI(): AdminAPI {
const { url, token } = useBackendContext();
+ const mutateAll = useMatchMutate();
const createInstance = async (
instance: MerchantBackend.Instances.InstanceConfigurationMessage
diff --git a/packages/merchant-backoffice/src/hooks/backend.ts
b/packages/merchant-backoffice/src/hooks/backend.ts
index b1544bd..59bd0b6 100644
--- a/packages/merchant-backoffice/src/hooks/backend.ts
+++ b/packages/merchant-backoffice/src/hooks/backend.ts
@@ -19,22 +19,36 @@
* @author Sebastian Javier Marchano (sebasjm)
*/
-import { mutate, cache } from "swr";
+import { useSWRConfig } from "swr";
import axios, { AxiosError, AxiosResponse } from "axios";
import { MerchantBackend } from "../declaration";
import { useBackendContext } from "../context/backend";
import { useEffect, useState } from "preact/hooks";
import { DEFAULT_REQUEST_TIMEOUT } from "../utils/constants";
-export function mutateAll(re: RegExp, value?: unknown): Array<Promise<any>> {
- return cache
- .keys()
- .filter((key) => {
- return re.test(key);
- })
- .map((key) => {
- return mutate(key, value);
+export function useMatchMutate(): (
+ re: RegExp,
+ value?: unknown
+) => Promise<any> {
+ const { cache, mutate } = useSWRConfig();
+
+ if (!(cache instanceof Map)) {
+ throw new Error(
+ "matchMutate requires the cache provider to be a Map instance"
+ );
+ }
+
+ return function matchRegexMutate(re: RegExp, value?: unknown) {
+ const allKeys = Array.from(cache.keys());
+ // console.log(allKeys)
+ const keys = allKeys.filter((key) => re.test(key));
+ // console.log(allKeys.length, keys.length)
+ const mutations = keys.map((key) => {
+ // console.log(key)
+ mutate(key, value, true);
});
+ return Promise.all(mutations);
+ };
}
export type HttpResponse<T> =
@@ -261,6 +275,14 @@ export async function request<T>(
}
}
+export function multiFetcher<T>(
+ urls: string[],
+ token: string,
+ backend: string
+): Promise<HttpResponseOk<T>[]> {
+ return Promise.all(urls.map((url) => fetcher<T>(url, token, backend)));
+}
+
export function fetcher<T>(
url: string,
token: string,
diff --git a/packages/merchant-backoffice/src/hooks/instance.ts
b/packages/merchant-backoffice/src/hooks/instance.ts
index 2d15464..2f4923e 100644
--- a/packages/merchant-backoffice/src/hooks/instance.ts
+++ b/packages/merchant-backoffice/src/hooks/instance.ts
@@ -23,7 +23,7 @@ import {
request,
SwrError,
} from "./backend";
-import useSWR, { mutate } from "swr";
+import useSWR, { useSWRConfig } from "swr";
import { useInstanceContext } from "../context/instance";
interface InstanceAPI {
@@ -36,6 +36,7 @@ interface InstanceAPI {
}
export function useManagementAPI(instanceId: string): InstanceAPI {
+ const { mutate } = useSWRConfig();
const { url, token } = useBackendContext();
const updateInstance = async (
@@ -83,6 +84,7 @@ export function useManagementAPI(instanceId: string):
InstanceAPI {
}
export function useInstanceAPI(): InstanceAPI {
+ const { mutate } = useSWRConfig();
const { url: baseUrl, token: adminToken } = useBackendContext();
const { token: instanceToken, id, admin } = useInstanceContext();
diff --git a/packages/merchant-backoffice/src/hooks/order.ts
b/packages/merchant-backoffice/src/hooks/order.ts
index 91d34c8..c0cf5b9 100644
--- a/packages/merchant-backoffice/src/hooks/order.ts
+++ b/packages/merchant-backoffice/src/hooks/order.ts
@@ -14,7 +14,7 @@
GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/
import { useEffect, useState } from "preact/hooks";
-import useSWR from "swr";
+import useSWR, { useSWRConfig } from "swr";
import { useBackendContext } from "../context/backend";
import { useInstanceContext } from "../context/instance";
import { MerchantBackend } from "../declaration";
@@ -25,8 +25,8 @@ import {
HttpResponse,
HttpResponseOk,
HttpResponsePaginated,
- mutateAll,
request,
+ useMatchMutate,
} from "./backend";
export interface OrderAPI {
@@ -72,6 +72,8 @@ export function orderFetcher<T>(
}
export function useOrderAPI(): OrderAPI {
+ const mutateAll = useMatchMutate();
+ // const { mutate } = useSWRConfig();
const { url: baseUrl, token: adminToken } = useBackendContext();
const { token: instanceToken, id, admin } = useInstanceContext();
@@ -96,7 +98,8 @@ export function useOrderAPI(): OrderAPI {
data,
}
);
- await mutateAll(/@"\/private\/orders"@/);
+ await mutateAll(/.*private\/orders.*/);
+ // mutate('')
return res;
};
const refundOrder = async (
diff --git a/packages/merchant-backoffice/src/hooks/product.ts
b/packages/merchant-backoffice/src/hooks/product.ts
index 04cbea8..b2cc21c 100644
--- a/packages/merchant-backoffice/src/hooks/product.ts
+++ b/packages/merchant-backoffice/src/hooks/product.ts
@@ -14,7 +14,8 @@
GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/
import { useEffect } from "preact/hooks";
-import useSWR, { trigger, useSWRInfinite, cache, mutate } from "swr";
+import useSWR, { useSWRConfig } from "swr";
+import useSWRInfinite, { SWRInfiniteConfiguration } from "swr/infinite";
import { useBackendContext } from "../context/backend";
// import { useFetchContext } from '../context/fetch';
import { useInstanceContext } from "../context/instance";
@@ -24,8 +25,9 @@ import {
HttpError,
HttpResponse,
HttpResponseOk,
- mutateAll,
+ multiFetcher,
request,
+ useMatchMutate,
} from "./backend";
export interface ProductAPI {
@@ -44,6 +46,9 @@ export interface ProductAPI {
}
export function useProductAPI(): ProductAPI {
+ const mutateAll = useMatchMutate();
+ const { mutate } = useSWRConfig();
+ // const { mutate } = SWRInfiniteConfiguration();
const { url: baseUrl, token: adminToken } = useBackendContext();
const { token: instanceToken, id, admin } = useInstanceContext();
@@ -60,13 +65,13 @@ export function useProductAPI(): ProductAPI {
const createProduct = async (
data: MerchantBackend.Products.ProductAddDetail
): Promise<void> => {
- await request(`${url}/private/products`, {
+ const res = await request(`${url}/private/products`, {
method: "post",
token,
data,
});
- await mutateAll(/@"\/private\/products"@/, null);
+ return await mutateAll(/.*private\/products.*/);
};
const updateProduct = async (
@@ -79,6 +84,10 @@ export function useProductAPI(): ProductAPI {
data,
});
+ // await mutate([`/private/products`, token, url])
+ // await mutate([`/private/products/${productId}`, token, url], undefined,
true);
+ return await mutateAll(/.*"\/private\/products.*/);
+ return Promise.resolve();
/**
* There is some inconsistency in how the cache is evicted.
* I'm keeping this for later inspection
@@ -114,12 +123,12 @@ export function useProductAPI(): ProductAPI {
// await mutate([`/private/products/${productId}`, token, url])
// await mutateAll(/@"\/private\/products"@/);
- await mutateAll(/@"\/private\/products\/.*"@/);
+ // await mutateAll(/@"\/private\/products\/.*"@/);
// return true
// return r
// -- FIXME: why this un-break the tests?
- return Promise.resolve();
+ // return Promise.resolve()
};
const deleteProduct = async (productId: string): Promise<void> => {
@@ -127,8 +136,7 @@ export function useProductAPI(): ProductAPI {
method: "delete",
token,
});
-
- await mutateAll(/@"\/private\/products"@/);
+ await mutate([`/private/products`, token, url]);
};
const lockProduct = async (
@@ -164,11 +172,7 @@ export function useInstanceProducts(): HttpResponse<
token: instanceToken,
};
- const {
- data: list,
- error: listError,
- isValidating: listLoading,
- } = useSWR<
+ const { data: list, error: listError } = useSWR<
HttpResponseOk<MerchantBackend.Products.InventorySummaryResponse>,
HttpError
>([`/private/products`, token, url], fetcher, {
@@ -179,42 +183,48 @@ export function useInstanceProducts(): HttpResponse<
refreshWhenOffline: false,
});
- const {
- data: products,
- error: productError,
- setSize,
- size,
- } = useSWRInfinite<
- HttpResponseOk<MerchantBackend.Products.ProductDetail>,
- HttpError
- >(
- (pageIndex: number) => {
- if (!list?.data || !list.data.products.length || listError ||
listLoading)
- return null;
- return [
- `/private/products/${list.data.products[pageIndex].product_id}`,
- token,
- url,
- ];
- },
- fetcher,
- {
- revalidateAll: true,
- }
+ // const dataLength = list?.data.products.length || 0
+ // const prods: Array<MerchantBackend.Products.InventoryEntry>[] = []
+ // prods[0] = list?.data.products || []
+
+ // const { data: products, error: productError, setSize } =
useSWRInfinite<HttpResponseOk<MerchantBackend.Products.ProductDetail>,
HttpError>((pageIndex: number) => {
+ // console.log('fetcher', prods[0], pageIndex)
+ // if (!list?.data || !prods[0].length || listError) return null
+
+ // console.log(`/private/products/${prods[0][pageIndex].product_id}`)
+ // return [`/private/products/${prods[0][pageIndex].product_id}`, token,
url]
+ // }, fetcher, {
+ // initialSize: dataLength,
+ // revalidateAll: true,
+ // })
+ // [`/private/products`]
+ const paths = (list?.data.products || []).map(
+ (p) => `/private/products/${p.product_id}`
);
+ const { data: products, error: productError } = useSWR<
+ HttpResponseOk<MerchantBackend.Products.ProductDetail>[],
+ HttpError
+ >([paths, token, url], multiFetcher, {
+ refreshInterval: 0,
+ refreshWhenHidden: false,
+ revalidateOnFocus: false,
+ revalidateOnReconnect: false,
+ refreshWhenOffline: false,
+ });
- useEffect(() => {
- if (list?.data && list.data.products.length > 0) {
- setSize(list.data.products.length);
- }
- }, [list?.data.products.length, listLoading]);
+ // console.log('data length', dataLength, list?.data)
+ // useEffect(() => {
+ // if (dataLength > 0) {
+ // console.log('set size', dataLength)
+ // setSize(dataLength)
+ // }
+ // }, [dataLength, setSize])
- if (listLoading) return { loading: true, data: [] };
if (listError) return listError;
if (productError) return productError;
- if (list?.data && list.data.products.length === 0) {
- return { ok: true, data: [] };
- }
+ // if (dataLength === 0) {
+ // return { ok: true, data: [] }
+ // }
if (products) {
const dataWithId = products.map((d) => {
//take the id from the queried url
@@ -223,6 +233,7 @@ export function useInstanceProducts(): HttpResponse<
id: d.info?.url.replace(/.*\/private\/products\//, "") || "",
};
});
+ // console.log('data with id', dataWithId)
return { ok: true, data: dataWithId };
}
return { loading: true };
diff --git a/packages/merchant-backoffice/src/hooks/tips.ts
b/packages/merchant-backoffice/src/hooks/tips.ts
index 821b794..a632e34 100644
--- a/packages/merchant-backoffice/src/hooks/tips.ts
+++ b/packages/merchant-backoffice/src/hooks/tips.ts
@@ -22,11 +22,12 @@ import {
HttpError,
HttpResponse,
HttpResponseOk,
- mutateAll,
request,
+ useMatchMutate,
} from "./backend";
export function useReservesAPI(): ReserveMutateAPI {
+ const mutateAll = useMatchMutate();
const { url: baseUrl, token: adminToken } = useBackendContext();
const { token: instanceToken, id, admin } = useInstanceContext();
diff --git a/packages/merchant-backoffice/src/hooks/transfer.ts
b/packages/merchant-backoffice/src/hooks/transfer.ts
index bdd64fe..c455b0c 100644
--- a/packages/merchant-backoffice/src/hooks/transfer.ts
+++ b/packages/merchant-backoffice/src/hooks/transfer.ts
@@ -17,11 +17,11 @@ import { MerchantBackend } from "../declaration";
import { useBackendContext } from "../context/backend";
import {
request,
- mutateAll,
HttpResponse,
HttpError,
HttpResponseOk,
HttpResponsePaginated,
+ useMatchMutate,
} from "./backend";
import useSWR from "swr";
import { useInstanceContext } from "../context/instance";
@@ -54,6 +54,7 @@ async function transferFetcher<T>(
}
export function useTransferAPI(): TransferAPI {
+ const mutateAll = useMatchMutate();
const { url: baseUrl, token: adminToken } = useBackendContext();
const { token: instanceToken, id, admin } = useInstanceContext();
diff --git a/packages/merchant-backoffice/tests/axiosMock.ts
b/packages/merchant-backoffice/tests/axiosMock.ts
new file mode 100644
index 0000000..c38bc44
--- /dev/null
+++ b/packages/merchant-backoffice/tests/axiosMock.ts
@@ -0,0 +1,216 @@
+/*
+ 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 <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+import * as axios from 'axios';
+import { MerchantBackend } from '../src/declaration';
+import { setAxiosRequestAsTestingEnvironment } from "../src/hooks/backend";
+
+export type Query<Req, Res> = (GetQuery | PostQuery | DeleteQuery |
PatchQuery) & RequestResponse<Req, Res>
+
+interface RequestResponse<Req, Res> {
+ code?: number,
+}
+interface GetQuery { get: string }
+interface PostQuery { post: string }
+interface DeleteQuery { delete: string }
+interface PatchQuery { patch: string }
+
+setAxiosRequestAsTestingEnvironment();
+
+const JEST_DEBUG_LOG = process.env['JEST_DEBUG_LOG'] !== undefined
+
+type TestValues = [axios.AxiosRequestConfig | undefined, { query: Query<any,
any>; params?: { request?: any, qparam?: any, response?: any } } | undefined]
+
+const defaultCallback = (actualQuery?: axios.AxiosRequestConfig) => {
+ if (JEST_DEBUG_LOG) {
+ console.log('UNEXPECTED QUERY', actualQuery)
+ }
+}
+
+export class AxiosMockEnvironment {
+ expectations: Array<{ query: Query<any, any>, params?: { request?: any,
qparam?: any, response?: any } } | undefined> = []
+ axiosMock: jest.MockedFunction<axios.AxiosStatic>
+
+ constructor() {
+ this.axiosMock = (axios.default as
jest.MockedFunction<axios.AxiosStatic>).mockImplementation(defaultCallback as
any)
+ }
+
+ addRequestExpectation<RequestType, ResponseType>(expectedQuery?:
Query<RequestType, ResponseType> | undefined, params?: { request?: RequestType,
qparam?: any, response?: ResponseType }): void {
+ this.expectations.push(expectedQuery ? { query: expectedQuery, params } :
undefined)
+ this.axiosMock = this.axiosMock.mockImplementationOnce(function
(actualQuery?: axios.AxiosRequestConfig): axios.AxiosPromise {
+
+ if (JEST_DEBUG_LOG) {
+ console.log('query to the backend is made', actualQuery)
+ }
+ if (!expectedQuery) {
+ return Promise.reject()
+ }
+ if (JEST_DEBUG_LOG) {
+ console.log('expected query:', params?.request)
+ console.log('expected qparams:', params?.qparam)
+ console.log('sending response:', params?.response)
+ }
+
+ const responseCode = expectedQuery.code || 200
+
+ //This response is what buildRequestOk is expecting in file
hook/backend.ts
+ if (responseCode >= 200 && responseCode < 300) {
+ return Promise.resolve({
+ data: params?.response, config: {
+ data: params?.response,
+ params: actualQuery?.params || {},
+ }, request: { params: actualQuery?.params || {} }
+ } as any);
+ }
+ //This response is what buildRequestFailed is expecting in file
hook/backend.ts
+ return Promise.reject({
+ response: {
+ status: responseCode
+ },
+ request: {
+ data: params?.response,
+ params: actualQuery?.params || {},
+ }
+ })
+
+ } as any)
+ }
+
+ getLastTestValues(): TestValues {
+ const lastCall = this.axiosMock.mock.calls[0]
+ if (lastCall === undefined) {
+ const expectedQuery = this.expectations.shift()
+ return [undefined, expectedQuery]
+ }
+ const actualQuery = lastCall[0] as axios.AxiosRequestConfig
+
+ //Remove values from the last call
+ const expectedQuery = this.expectations.shift()
+ this.axiosMock.mock.calls.shift()
+ this.axiosMock.mock.results.shift()
+
+ return [
+ actualQuery, expectedQuery
+ ]
+ }
+
+}
+
+export function testAllExpectedRequestAndNoMore(env: AxiosMockEnvironment):
void {
+ let size = env.expectations.length
+ while (size-- > 0) {
+ testOneRequestToBackend(env)
+ }
+ testNoOtherRequestWasMade(env)
+}
+
+export function testNoOtherRequestWasMade(env: AxiosMockEnvironment): void {
+ const [actualQuery, expectedQuery] = env.getLastTestValues()
+
+ expect(actualQuery).toBeUndefined();
+ expect(expectedQuery).toBeUndefined();
+}
+
+export function testOneRequestToBackend(env: AxiosMockEnvironment): void {
+ const [actualQuery, expectedQuery] = env.getLastTestValues()
+
+ if (!actualQuery) {
+ expect(actualQuery).toBe(expectedQuery);
+
+ // throw Error('actual query was undefined');
+ return
+ }
+
+ if (!expectedQuery) {
+ const errorMessage = 'a query was made to the backend but the test
explicitly expected no query';
+ if (JEST_DEBUG_LOG) {
+ console.log(errorMessage, actualQuery)
+ }
+ throw Error(errorMessage)
+ }
+ if ('get' in expectedQuery.query) {
+ expect(actualQuery.method).toBe('get');
+ expect(actualQuery.url).toBe(expectedQuery.query.get);
+ }
+ if ('post' in expectedQuery.query) {
+ expect(actualQuery.method).toBe('post');
+ expect(actualQuery.url).toBe(expectedQuery.query.post);
+ if (actualQuery.method !== 'post') throw Error('tu vieja')
+ }
+ if ('delete' in expectedQuery.query) {
+ expect(actualQuery.method).toBe('delete');
+ expect(actualQuery.url).toBe(expectedQuery.query.delete);
+ }
+ if ('patch' in expectedQuery.query) {
+ expect(actualQuery.method).toBe('patch');
+ expect(actualQuery.url).toBe(expectedQuery.query.patch);
+ }
+
+ if (expectedQuery.params?.request) {
+ expect(actualQuery.data).toMatchObject(expectedQuery.params.request)
+ }
+ if (expectedQuery.params?.qparam) {
+ expect(actualQuery.params).toMatchObject(expectedQuery.params.qparam)
+ }
+
+}
+
+export const API_LIST_PRODUCTS: Query<
+ unknown,
+ MerchantBackend.Products.InventorySummaryResponse
+> = {
+ get: "http://backend/instances/default/private/products",
+};
+
+export const API_LIST_ORDERS: Query<
+ unknown,
+ MerchantBackend.Orders.OrderHistory
+> = {
+ get: "http://backend/instances/default/private/orders",
+};
+
+export const API_CREATE_PRODUCT: Query<
+ MerchantBackend.Products.ProductAddDetail,
+ unknown
+> = {
+ post: "http://backend/instances/default/private/products",
+};
+
+export const API_CREATE_ORDER: Query<
+ MerchantBackend.Orders.PostOrderRequest,
+ MerchantBackend.Orders.PostOrderResponse
+> = {
+ post: "http://backend/instances/default/private/orders",
+};
+
+export const API_GET_PRODUCT_BY_ID = (
+ id: string
+): Query<unknown, MerchantBackend.Products.InventorySummaryResponse> => ({
+ get: `http://backend/instances/default/private/products/${id}`,
+});
+
+export const API_UPDATE_PRODUCT_BY_ID = (
+ id: string
+): Query<
+ Partial<MerchantBackend.Products.ProductPatchDetail>,
+ MerchantBackend.Products.InventorySummaryResponse
+> => ({
+ patch: `http://backend/instances/default/private/products/${id}`,
+});
diff --git a/packages/merchant-backoffice/tests/declarations.d.ts
b/packages/merchant-backoffice/tests/declarations.d.ts
index 097a30e..61a53dc 100644
--- a/packages/merchant-backoffice/tests/declarations.d.ts
+++ b/packages/merchant-backoffice/tests/declarations.d.ts
@@ -19,6 +19,10 @@
* @author Sebastian Javier Marchano (sebasjm)
*/
-// Enable enzyme adapter's integration with TypeScript
-// See:
https://github.com/preactjs/enzyme-adapter-preact-pure#usage-with-typescript
-/// <reference types="enzyme-adapter-preact-pure" />
+declare global {
+ namespace jest {
+ interface Matchers<R> {
+ toBeWithinRange(a: number, b: number): R;
+ }
+ }
+}
diff --git a/packages/merchant-backoffice/tests/header.test.tsx
b/packages/merchant-backoffice/tests/header.test.tsx
index c705eef..f098b70 100644
--- a/packages/merchant-backoffice/tests/header.test.tsx
+++ b/packages/merchant-backoffice/tests/header.test.tsx
@@ -22,17 +22,27 @@
import { h } from "preact";
import { ProductList } from "../src/components/product/ProductList";
// See: https://github.com/preactjs/enzyme-adapter-preact-pure
-import { shallow } from "enzyme";
+// import { shallow } from 'enzyme';
import * as backend from "../src/context/config";
+import { render, findAllByText } from "@testing-library/preact";
+import * as i18n from "../src/context/translation";
+
+import * as jedLib from "jed";
+const handler = new jedLib.Jed("en");
describe("Initial Test of the Sidebar", () => {
beforeEach(() => {
jest
.spyOn(backend, "useConfigContext")
.mockImplementation(() => ({ version: "", currency: "" }));
+ jest.spyOn(i18n, "useTranslationContext").mockImplementation(() => ({
+ changeLanguage: () => null,
+ handler,
+ lang: "en",
+ }));
});
test("Product list renders a table", () => {
- const context = shallow(
+ const context = render(
<ProductList
list={[
{
@@ -47,7 +57,7 @@ describe("Initial Test of the Sidebar", () => {
/>
);
- expect(context.find("table")).toBeDefined();
+ expect(context.findAllByText("description of the product")).toBeDefined();
// expect(context.find('table tr td img').map(img =>
img.prop('src'))).toEqual('');
});
});
diff --git a/packages/merchant-backoffice/tests/hooks/swr/order-create.test.tsx
b/packages/merchant-backoffice/tests/hooks/swr/order-create.test.tsx
index ad46612..0defaec 100644
--- a/packages/merchant-backoffice/tests/hooks/swr/order-create.test.tsx
+++ b/packages/merchant-backoffice/tests/hooks/swr/order-create.test.tsx
@@ -20,15 +20,17 @@
*/
import { renderHook } from "@testing-library/preact-hooks";
-import * as axios from "axios";
+import { act } from "preact/test-utils";
import * as backend from "../../../src/context/backend";
import * as instance from "../../../src/context/instance";
-import { MerchantBackend } from "../../../src/declaration";
-import { setAxiosRequestAsTestingEnvironment } from
"../../../src/hooks/backend";
import { useInstanceOrders, useOrderAPI } from "../../../src/hooks/order";
-import { simulateBackendResponse } from "../../util";
-
-setAxiosRequestAsTestingEnvironment();
+import {
+ API_CREATE_ORDER,
+ API_LIST_ORDERS,
+ AxiosMockEnvironment,
+ testNoOtherRequestWasMade,
+ testOneRequestToBackend,
+} from "../../axiosMock";
jest.mock("axios");
@@ -47,19 +49,18 @@ describe("order api", () => {
});
it("should not have problem with cache after an creation", async () => {
- simulateBackendResponse<unknown, MerchantBackend.Orders.OrderHistory>({
- get: "http://backend/instances/default/private/orders",
- params: { delta: 0, paid: "yes" },
+ const env = new AxiosMockEnvironment();
+ env.addRequestExpectation(API_LIST_ORDERS, {
+ qparam: { delta: 0, paid: "yes" },
response: {
- orders: [{ order_id: "1" } as any],
+ orders: [{ order_id: "1" }],
},
});
- simulateBackendResponse<unknown, MerchantBackend.Orders.OrderHistory>({
- get: "http://backend/instances/default/private/orders",
- params: { delta: -20, paid: "yes" },
+ env.addRequestExpectation(API_LIST_ORDERS, {
+ qparam: { delta: -20, paid: "yes" },
response: {
- orders: [{ order_id: "2" } as any],
+ orders: [{ order_id: "2" }],
},
});
@@ -67,58 +68,70 @@ describe("order api", () => {
console.log("new date", d);
};
- const { result, waitForNextUpdate } = renderHook(() =>
- useInstanceOrders({ paid: "yes" }, newDate)
- ); // get products -> loading
+ const { result, waitForNextUpdate } = renderHook(() => {
+ const query = useInstanceOrders({ paid: "yes" }, newDate);
+ const api = useOrderAPI();
+
+ return { query, api };
+ }); // get products -> loading
+
+ if (!result.current) {
+ expect(result.current).toBeDefined();
+ return;
+ }
- await waitForNextUpdate(); // get info of every product, -> loading
- await waitForNextUpdate(); // loading product -> products
- // await waitForNextUpdate(); // loading product -> products
+ expect(result.current.query.loading).toBeTruthy();
+ await waitForNextUpdate();
+ testOneRequestToBackend(env);
+ testOneRequestToBackend(env);
+ testNoOtherRequestWasMade(env);
- expect(result.current?.ok).toBeTruthy();
- if (!result.current?.ok) return;
+ expect(result.current.query.loading).toBeFalsy();
+ expect(result.current?.query.ok).toBeTruthy();
+ if (!result.current?.query.ok) return;
- expect(result.current.data).toEqual({
+ expect(result.current.query.data).toEqual({
orders: [{ order_id: "1" }, { order_id: "2" }],
});
- const { createOrder } = useOrderAPI();
-
- simulateBackendResponse<
- MerchantBackend.Orders.PostOrderRequest,
- MerchantBackend.Orders.PostOrderResponse
- >({
- post: "http://backend/instances/default/private/orders",
+ env.addRequestExpectation(API_CREATE_ORDER, {
request: {
order: { amount: "ARS:12", summary: "pay me" },
},
response: { order_id: "3" },
});
- simulateBackendResponse<unknown, MerchantBackend.Orders.OrderHistory>({
- get: "http://backend/instances/default/private/orders",
- params: { delta: 0, paid: "yes" },
+ env.addRequestExpectation(API_LIST_ORDERS, {
+ qparam: { delta: 0, paid: "yes" },
response: {
orders: [{ order_id: "1" } as any],
},
});
- simulateBackendResponse<unknown, MerchantBackend.Orders.OrderHistory>({
- get: "http://backend/instances/default/private/orders",
- params: { delta: -20, paid: "yes" },
+ env.addRequestExpectation(API_LIST_ORDERS, {
+ qparam: { delta: -20, paid: "yes" },
response: {
orders: [{ order_id: "2" } as any, { order_id: "3" } as any],
},
});
- await createOrder({
- order: { amount: "ARS:12", summary: "pay me" },
- } as any);
+ act(async () => {
+ await result.current?.api.createOrder({
+ order: { amount: "ARS:12", summary: "pay me" },
+ } as any);
+ });
+
+ testOneRequestToBackend(env); //post
+ await waitForNextUpdate();
+ testOneRequestToBackend(env); //get
+ testOneRequestToBackend(env); //get
+ testNoOtherRequestWasMade(env);
- await waitForNextUpdate(); // loading product -> products
- await waitForNextUpdate(); // loading product -> products
+ expect(result.current.query.loading).toBeFalsy();
+ expect(result.current?.query.ok).toBeTruthy();
+ if (!result.current?.query.ok) return;
- expect(result.current.data).toEqual({
+ expect(result.current.query.data).toEqual({
orders: [{ order_id: "1" }, { order_id: "2" }, { order_id: "3" }],
});
});
diff --git
a/packages/merchant-backoffice/tests/hooks/swr/order-pagination.test.tsx
b/packages/merchant-backoffice/tests/hooks/swr/order-pagination.test.tsx
index f02fa46..d62ead7 100644
--- a/packages/merchant-backoffice/tests/hooks/swr/order-pagination.test.tsx
+++ b/packages/merchant-backoffice/tests/hooks/swr/order-pagination.test.tsx
@@ -20,13 +20,17 @@
*/
import { act, renderHook } from "@testing-library/preact-hooks";
-import * as axios from "axios";
import * as backend from "../../../src/context/backend";
import * as instance from "../../../src/context/instance";
import { MerchantBackend } from "../../../src/declaration";
import { setAxiosRequestAsTestingEnvironment } from
"../../../src/hooks/backend";
import { useInstanceOrders } from "../../../src/hooks/order";
-import { simulateBackendResponse } from "../../util";
+import {
+ API_LIST_ORDERS,
+ AxiosMockEnvironment,
+ testNoOtherRequestWasMade,
+ testOneRequestToBackend,
+} from "../../axiosMock";
setAxiosRequestAsTestingEnvironment();
@@ -47,17 +51,16 @@ describe("order pagination", () => {
});
it("should change pagination", async () => {
- simulateBackendResponse<unknown, MerchantBackend.Orders.OrderHistory>({
- get: "http://backend/instances/default/private/orders",
- params: { delta: 20, wired: "yes", date_ms: 12 },
+ const env = new AxiosMockEnvironment();
+ env.addRequestExpectation(API_LIST_ORDERS, {
+ qparam: { delta: 20, wired: "yes", date_ms: 12 },
response: {
orders: [{ order_id: "1" } as any],
},
});
- simulateBackendResponse<unknown, MerchantBackend.Orders.OrderHistory>({
- get: "http://backend/instances/default/private/orders",
- params: { delta: -20, wired: "yes", date_ms: 13 },
+ env.addRequestExpectation(API_LIST_ORDERS, {
+ qparam: { delta: -20, wired: "yes", date_ms: 13 },
response: {
orders: [{ order_id: "2" } as any],
},
@@ -72,6 +75,10 @@ describe("order pagination", () => {
useInstanceOrders({ wired: "yes", date }, newDate)
); // get products -> loading
+ testOneRequestToBackend(env);
+ testOneRequestToBackend(env);
+ testNoOtherRequestWasMade(env);
+
await waitForNextUpdate(); // get info of every product, -> loading
expect(result.current?.ok).toBeTruthy();
@@ -81,23 +88,24 @@ describe("order pagination", () => {
orders: [{ order_id: "1" }, { order_id: "2" }],
});
- simulateBackendResponse<unknown, MerchantBackend.Orders.OrderHistory>({
- get: "http://backend/instances/default/private/orders",
- params: { delta: -40, wired: "yes", date_ms: 13 },
+ env.addRequestExpectation(API_LIST_ORDERS, {
+ qparam: { delta: -40, wired: "yes", date_ms: 13 },
response: {
orders: [{ order_id: "2" } as any, { order_id: "3" } as any],
},
});
+
await act(() => {
if (!result.current?.ok) throw Error("not ok");
result.current.loadMore();
});
await waitForNextUpdate(); // loading product -> products
// await waitForNextUpdate(); // loading product -> products
+ testOneRequestToBackend(env);
+ testNoOtherRequestWasMade(env);
- simulateBackendResponse<unknown, MerchantBackend.Orders.OrderHistory>({
- get: "http://backend/instances/default/private/orders",
- params: { delta: 40, wired: "yes", date_ms: 12 },
+ env.addRequestExpectation(API_LIST_ORDERS, {
+ qparam: { delta: 40, wired: "yes", date_ms: 12 },
response: {
orders: [{ order_id: "1" } as any, { order_id: "0" } as any],
},
@@ -107,6 +115,8 @@ describe("order pagination", () => {
result.current.loadMorePrev();
});
await waitForNextUpdate(); // loading product -> products
+ testOneRequestToBackend(env);
+ testNoOtherRequestWasMade(env);
expect(result.current.data).toEqual({
orders: [
diff --git
a/packages/merchant-backoffice/tests/hooks/swr/product-create.test.tsx
b/packages/merchant-backoffice/tests/hooks/swr/product-create.test.tsx
index ec9c0ab..611a470 100644
--- a/packages/merchant-backoffice/tests/hooks/swr/product-create.test.tsx
+++ b/packages/merchant-backoffice/tests/hooks/swr/product-create.test.tsx
@@ -20,19 +20,21 @@
*/
import { renderHook } from "@testing-library/preact-hooks";
-import * as axios from "axios";
+import { act } from "preact/test-utils";
import * as backend from "../../../src/context/backend";
import * as instance from "../../../src/context/instance";
-import { MerchantBackend } from "../../../src/declaration";
-import { setAxiosRequestAsTestingEnvironment } from
"../../../src/hooks/backend";
import { useInstanceProducts, useProductAPI } from
"../../../src/hooks/product";
-import { simulateBackendResponse } from "../../util";
-
-setAxiosRequestAsTestingEnvironment();
+import {
+ API_CREATE_PRODUCT,
+ API_LIST_PRODUCTS,
+ API_GET_PRODUCT_BY_ID,
+ AxiosMockEnvironment,
+ testAllExpectedRequestAndNoMore,
+} from "../../axiosMock";
jest.mock("axios");
-describe("product api", () => {
+describe("product create api", () => {
beforeEach(() => {
jest
.spyOn(backend, "useBackendContext")
@@ -46,76 +48,85 @@ describe("product api", () => {
);
});
- it.skip("should not have problem with cache after an creation", async () => {
- simulateBackendResponse<
- unknown,
- MerchantBackend.Products.InventorySummaryResponse
- >({
- get: "http://backend/instances/default/private/products",
+ it("should not have problem with cache after an creation", async () => {
+ const env = new AxiosMockEnvironment();
+
+ env.addRequestExpectation(API_LIST_PRODUCTS, {
response: {
products: [{ product_id: "1234" }],
},
});
- simulateBackendResponse<
- unknown,
- Partial<MerchantBackend.Products.ProductDetail>
- >({
- get: "http://backend/instances/default/private/products/1234",
+ env.addRequestExpectation(API_GET_PRODUCT_BY_ID("1234"), {
response: { price: "ARS:33" },
});
- const { result, waitForNextUpdate } = renderHook(() =>
- useInstanceProducts()
- ); // get products -> loading
+ const { result, waitForNextUpdate } = renderHook(() => {
+ const api = useProductAPI();
+ const query = useInstanceProducts();
- await waitForNextUpdate(); // get info of every product, -> loading
- await waitForNextUpdate(); // loading product -> products
+ return { query, api };
+ }); // get products -> loading
- expect(result.current?.ok).toBeTruthy();
- if (!result.current?.ok) return;
+ if (!result.current) {
+ expect(result.current).toBeDefined();
+ return;
+ }
+ expect(result.current.query.loading).toBeTruthy();
- expect(result.current.data).toEqual([
- {
- id: "1234",
- price: "ARS:33",
- },
- ]);
+ await waitForNextUpdate(); // first query to list products
+ expect(result.current.query.loading).toBeTruthy();
+
+ await waitForNextUpdate(); // second query to get product details
+ testAllExpectedRequestAndNoMore(env);
+
+ expect(result.current.query.loading).toBeFalsy();
+ expect(result.current?.query.ok).toBeTruthy();
+ if (!result.current?.query.ok) return;
- const { createProduct } = useProductAPI();
+ expect(result.current.query.data).toEqual([
+ { id: "1234", price: "ARS:33" },
+ ]);
- simulateBackendResponse<
- Partial<MerchantBackend.Products.ProductAddDetail>,
- unknown
- >({
- post: "http://backend/instances/default/private/products",
+ env.addRequestExpectation(API_CREATE_PRODUCT, {
request: { price: "ARS:3333" },
});
- simulateBackendResponse<
- unknown,
- MerchantBackend.Products.InventorySummaryResponse
- >({
- get: "http://backend/instances/default/private/products",
+ act(async () => {
+ return await result.current?.api.createProduct({
+ price: "ARS:3333",
+ } as any);
+ });
+
+ testAllExpectedRequestAndNoMore(env);
+
+ env.addRequestExpectation(API_LIST_PRODUCTS, {
response: {
products: [{ product_id: "1234" }, { product_id: "2222" }],
},
});
- simulateBackendResponse<
- unknown,
- Partial<MerchantBackend.Products.ProductDetail>
- >({
- get: "http://backend/instances/default/private/products/2222",
- response: { price: "ARS:3333" },
+
+ env.addRequestExpectation(API_GET_PRODUCT_BY_ID("1234"), {
+ response: { price: "ARS:33" },
+ });
+ env.addRequestExpectation(API_GET_PRODUCT_BY_ID("1234"), {
+ response: { price: "ARS:33" },
});
- await createProduct({ price: "ARS:3333" } as any);
+ env.addRequestExpectation(API_GET_PRODUCT_BY_ID("2222"), {
+ response: { price: "ARS:3333" },
+ });
+ expect(result.current.query.loading).toBeFalsy();
await waitForNextUpdate(); // loading product -> products
await waitForNextUpdate(); // loading product -> products
- await waitForNextUpdate(); // loading product -> products
- expect(result.current.data).toEqual([
+ testAllExpectedRequestAndNoMore(env);
+
+ expect(result.current.query.loading).toBeFalsy();
+ expect(result.current.query.ok).toBeTruthy();
+
+ expect(result.current.query.data).toEqual([
{
id: "1234",
price: "ARS:33",
diff --git
a/packages/merchant-backoffice/tests/hooks/swr/product-delete.test.tsx
b/packages/merchant-backoffice/tests/hooks/swr/product-delete.test.tsx
index b7df9b6..4c67ec1 100644
--- a/packages/merchant-backoffice/tests/hooks/swr/product-delete.test.tsx
+++ b/packages/merchant-backoffice/tests/hooks/swr/product-delete.test.tsx
@@ -20,22 +20,21 @@
*/
import { renderHook } from "@testing-library/preact-hooks";
+import { act } from "preact/test-utils";
import * as backend from "../../../src/context/backend";
import * as instance from "../../../src/context/instance";
-import { MerchantBackend } from "../../../src/declaration";
import { useInstanceProducts, useProductAPI } from
"../../../src/hooks/product";
-import { simulateBackendResponse } from "../../util";
-
-// eslint-disable-next-line @typescript-eslint/no-unused-vars
-import * as axios from "axios";
-import { setAxiosRequestAsTestingEnvironment } from
"../../../src/hooks/backend";
-
-setAxiosRequestAsTestingEnvironment();
+import {
+ API_LIST_PRODUCTS,
+ API_GET_PRODUCT_BY_ID,
+ AxiosMockEnvironment,
+ testAllExpectedRequestAndNoMore,
+ testOneRequestToBackend,
+} from "../../axiosMock";
jest.mock("axios");
-axios.default;
-describe("product api", () => {
+describe("product delete api", () => {
beforeEach(() => {
jest
.spyOn(backend, "useBackendContext")
@@ -50,89 +49,78 @@ describe("product api", () => {
// console.log("CLEAR")
});
- it.skip("should not have problem with cache after a delete", async () => {
- simulateBackendResponse<
- unknown,
- MerchantBackend.Products.InventorySummaryResponse
- >({
- get: "http://backend/instances/default/private/products",
+ it("should not have problem with cache after a delete", async () => {
+ const env = new AxiosMockEnvironment();
+
+ env.addRequestExpectation(API_LIST_PRODUCTS, {
response: {
products: [{ product_id: "1234" }, { product_id: "2345" }],
},
});
- simulateBackendResponse<
- unknown,
- Partial<MerchantBackend.Products.ProductDetail>
- >({
- get: "http://backend/instances/default/private/products/1234",
+ env.addRequestExpectation(API_GET_PRODUCT_BY_ID("1234"), {
response: { price: "ARS:12" },
});
- simulateBackendResponse<
- unknown,
- Partial<MerchantBackend.Products.ProductDetail>
- >({
- get: "http://backend/instances/default/private/products/2345",
+ env.addRequestExpectation(API_GET_PRODUCT_BY_ID("2345"), {
response: { price: "ARS:23" },
});
- const { result, waitForNextUpdate } = renderHook(() =>
- useInstanceProducts()
- ); // get products -> loading
+ // env.addRequestExpectation(API_GET_PRODUCT_BY_ID("1234"), {
+ // response: { price: "ARS:12" },
+ // });
+
+ // env.addRequestExpectation(API_GET_PRODUCT_BY_ID("2345"), {
+ // response: { price: "ARS:23" },
+ // });
+
+ const { result, waitForNextUpdate } = renderHook(() => {
+ const query = useInstanceProducts();
+ const api = useProductAPI();
+ return { query, api };
+ }); // get products -> loading
await waitForNextUpdate(); // get info of every product, -> loading
await waitForNextUpdate(); // loading product -> products
- await waitForNextUpdate(); // loading product -> products
+ testAllExpectedRequestAndNoMore(env);
+ // await waitForNextUpdate(); // loading product -> products
- expect(result.current?.ok).toBeTruthy();
- if (!result.current?.ok) return;
+ expect(result.current?.query.ok).toBeTruthy();
+ if (!result.current?.query.ok) return;
- expect(result.current.data).toEqual([
- {
- id: "1234",
- price: "ARS:12",
- },
- {
- id: "2345",
- price: "ARS:23",
- },
+ expect(result.current.query.data).toEqual([
+ { id: "1234", price: "ARS:12" },
+ { id: "2345", price: "ARS:23" },
]);
- const { deleteProduct } = useProductAPI();
-
- simulateBackendResponse({
+ env.addRequestExpectation({
delete: "http://backend/instances/default/private/products/1234",
});
- simulateBackendResponse<
- unknown,
- MerchantBackend.Products.InventorySummaryResponse
- >({
- get: "http://backend/instances/default/private/products",
+ env.addRequestExpectation(API_LIST_PRODUCTS, {
response: {
- products: [
- {
- product_id: "2345",
- },
- ],
+ products: [{ product_id: "2345" }],
},
});
- simulateBackendResponse<
- unknown,
- Partial<MerchantBackend.Products.ProductDetail>
- >({
- get: "http://backend/instances/default/private/products/2345",
+ env.addRequestExpectation(API_GET_PRODUCT_BY_ID("2345"), {
response: { price: "ARS:23" },
});
- await deleteProduct("1234");
+ // env.addRequestExpectation(API_GET_PRODUCT_BY_ID("2345"), {
+ // response: { price: "ARS:23" },
+ // });
+
+ act(async () => {
+ await result.current?.api.deleteProduct("1234");
+ });
+ testOneRequestToBackend(env);
await waitForNextUpdate();
await waitForNextUpdate();
+ testAllExpectedRequestAndNoMore(env);
- expect(result.current.data).toEqual([
+ expect(result.current.query.data).toEqual([
{
id: "2345",
price: "ARS:23",
diff --git
a/packages/merchant-backoffice/tests/hooks/swr/product-details-update.test.tsx
b/packages/merchant-backoffice/tests/hooks/swr/product-details-update.test.tsx
index 45b33a8..f5941f3 100644
---
a/packages/merchant-backoffice/tests/hooks/swr/product-details-update.test.tsx
+++
b/packages/merchant-backoffice/tests/hooks/swr/product-details-update.test.tsx
@@ -19,20 +19,23 @@
* @author Sebastian Javier Marchano (sebasjm)
*/
-import { renderHook } from "@testing-library/preact-hooks";
-import * as axios from "axios";
+import { renderHook, act } from "@testing-library/preact-hooks";
+
import * as backend from "../../../src/context/backend";
import * as instance from "../../../src/context/instance";
import { MerchantBackend } from "../../../src/declaration";
-import { setAxiosRequestAsTestingEnvironment } from
"../../../src/hooks/backend";
import { useProductAPI, useProductDetails } from "../../../src/hooks/product";
-import { simulateBackendResponse } from "../../util";
-
-setAxiosRequestAsTestingEnvironment();
+import {
+ API_GET_PRODUCT_BY_ID,
+ API_UPDATE_PRODUCT_BY_ID,
+ AxiosMockEnvironment,
+ testAllExpectedRequestAndNoMore,
+ testOneRequestToBackend,
+} from "../../axiosMock";
jest.mock("axios");
-describe("product api", () => {
+describe("product details api", () => {
beforeEach(() => {
jest
.spyOn(backend, "useBackendContext")
@@ -47,50 +50,59 @@ describe("product api", () => {
});
it("should not have problem with cache after an update", async () => {
- simulateBackendResponse<
- unknown,
- Partial<MerchantBackend.Products.ProductDetail>
- >({
- get: "http://backend/instances/default/private/products/12",
+ const env = new AxiosMockEnvironment();
+
+ env.addRequestExpectation(API_GET_PRODUCT_BY_ID("12"), {
response: { description: "this is a description" },
});
- const { result, waitForNextUpdate } = renderHook(() =>
- useProductDetails("12")
- ); // get products -> loading
+ const { result, waitForNextUpdate } = renderHook(() => {
+ const query = useProductDetails("12");
+ const api = useProductAPI();
+ return { query, api };
+ });
+ if (!result.current) {
+ expect(result.current).toBeDefined();
+ return;
+ }
+ expect(result.current.query.loading).toBeTruthy();
await waitForNextUpdate();
- expect(result.current?.ok).toBeTruthy();
- if (!result.current?.ok) return;
+ testAllExpectedRequestAndNoMore(env);
+
+ expect(result.current.query.loading).toBeFalsy();
+ expect(result.current?.query.ok).toBeTruthy();
+ if (!result.current?.query.ok) return;
- expect(result.current.data).toEqual({
+ expect(result.current.query.data).toEqual({
description: "this is a description",
});
- const { updateProduct } = useProductAPI();
-
- simulateBackendResponse<
- unknown,
- MerchantBackend.Products.InventorySummaryResponse
- >({
- patch: "http://backend/instances/default/private/products/12",
+ env.addRequestExpectation(API_UPDATE_PRODUCT_BY_ID("12"), {
request: { description: "other description" },
});
- simulateBackendResponse<
- unknown,
- Partial<MerchantBackend.Products.ProductDetail>
- >({
- get: "http://backend/instances/default/private/products/12",
+ env.addRequestExpectation(API_GET_PRODUCT_BY_ID("12"), {
response: { description: "other description" },
});
- await updateProduct("12", { description: "other description" } as any);
+ act(async () => {
+ return await result.current?.api.updateProduct("12", {
+ description: "other description",
+ } as any);
+ });
+
+ testOneRequestToBackend(env);
+ await waitForNextUpdate();
+
+ testAllExpectedRequestAndNoMore(env);
- // await waitForNextUpdate();
+ expect(result.current.query.loading).toBeFalsy();
+ expect(result.current?.query.ok).toBeTruthy();
+ if (!result.current?.query.ok) return;
- expect(result.current.data).toEqual({
+ expect(result.current.query.data).toEqual({
description: "other description",
});
});
diff --git
a/packages/merchant-backoffice/tests/hooks/swr/product-update.test.tsx
b/packages/merchant-backoffice/tests/hooks/swr/product-update.test.tsx
index 940852c..d3a106b 100644
--- a/packages/merchant-backoffice/tests/hooks/swr/product-update.test.tsx
+++ b/packages/merchant-backoffice/tests/hooks/swr/product-update.test.tsx
@@ -20,19 +20,22 @@
*/
import { renderHook } from "@testing-library/preact-hooks";
-import * as axios from "axios";
+import { act } from "preact/test-utils";
import * as backend from "../../../src/context/backend";
import * as instance from "../../../src/context/instance";
-import { MerchantBackend } from "../../../src/declaration";
-import { setAxiosRequestAsTestingEnvironment } from
"../../../src/hooks/backend";
import { useInstanceProducts, useProductAPI } from
"../../../src/hooks/product";
-import { simulateBackendResponse } from "../../util";
-
-setAxiosRequestAsTestingEnvironment();
+import {
+ API_GET_PRODUCT_BY_ID,
+ API_LIST_PRODUCTS,
+ API_UPDATE_PRODUCT_BY_ID,
+ AxiosMockEnvironment,
+ testAllExpectedRequestAndNoMore,
+ testOneRequestToBackend,
+} from "../../axiosMock";
jest.mock("axios");
-describe("product api", () => {
+describe("product list api", () => {
beforeEach(() => {
jest
.spyOn(backend, "useBackendContext")
@@ -44,66 +47,88 @@ describe("product api", () => {
.mockImplementation(
() => ({ token: "token", id: "default", admin: true } as any)
);
- // console.log("CLEAR")
});
it("should not have problem with cache after an update", async () => {
- simulateBackendResponse<
- unknown,
- MerchantBackend.Products.InventorySummaryResponse
- >({
- get: "http://backend/instances/default/private/products",
+ const env = new AxiosMockEnvironment();
+
+ env.addRequestExpectation(API_LIST_PRODUCTS, {
response: {
products: [{ product_id: "1234" }],
},
});
- simulateBackendResponse<
- unknown,
- Partial<MerchantBackend.Products.ProductDetail>
- >({
- get: "http://backend/instances/default/private/products/1234",
+ env.addRequestExpectation(API_GET_PRODUCT_BY_ID("1234"), {
response: { price: "ARS:12" },
});
- const { result, waitForNextUpdate, waitFor } = renderHook(() =>
- useInstanceProducts()
- ); // get products -> loading
+ const { result, waitForNextUpdate } = renderHook(() => {
+ const query = useInstanceProducts();
+ const api = useProductAPI();
+ return { api, query };
+ }); // get products -> loading
- await waitForNextUpdate(); // get info of every product, -> loading
- await waitForNextUpdate(); // loading product -> products
+ if (!result.current) {
+ expect(result.current).toBeDefined();
+ return;
+ }
+ expect(result.current.query.loading).toBeTruthy();
+ await waitForNextUpdate();
- expect(result.current?.ok).toBeTruthy();
- if (!result.current?.ok) return;
+ await waitForNextUpdate();
+ testAllExpectedRequestAndNoMore(env);
- expect(result.current.data).toEqual([
- {
- id: "1234",
- price: "ARS:12",
- },
- ]);
+ expect(result.current.query.loading).toBeFalsy();
+ expect(result.current.query.ok).toBeTruthy();
+ if (!result.current?.query.ok) return;
- const { updateProduct } = useProductAPI();
+ expect(result.current.query.data).toEqual([
+ { id: "1234", price: "ARS:12" },
+ ]);
- simulateBackendResponse<
- unknown,
- MerchantBackend.Products.InventorySummaryResponse
- >({
- patch: "http://backend/instances/default/private/products/1234",
+ env.addRequestExpectation(API_UPDATE_PRODUCT_BY_ID("1234"), {
request: { price: "ARS:13" },
});
- simulateBackendResponse<
- unknown,
- Partial<MerchantBackend.Products.ProductDetail>
- >({
- get: "http://backend/instances/default/private/products/1234",
+ env.addRequestExpectation(API_LIST_PRODUCTS, {
+ response: {
+ products: [{ product_id: "1234" }],
+ },
+ });
+ env.addRequestExpectation(API_GET_PRODUCT_BY_ID("1234"), {
response: { price: "ARS:13" },
});
+ // env.addRequestExpectation(API_GET_PRODUCT_BY_ID("1234"), {
+ // request: { price: "ARS:13" },
+ // });
+ // env.addRequestExpectation(API_GET_PRODUCT_BY_ID("1234"), {
+ // request: { price: "ARS:13" },
+ // });
+ // env.addRequestExpectation(API_GET_PRODUCT_BY_ID("1234"), {
+ // request: { price: "ARS:13" },
+ // });
+ // env.addRequestExpectation(API_GET_PRODUCT_BY_ID("1234"), {
+ // request: { price: "ARS:13" },
+ // });
+
+ act(async () => {
+ await result.current?.api.updateProduct("1234", {
+ price: "ARS:13",
+ } as any);
+ });
+
+ testOneRequestToBackend(env);
+ await waitForNextUpdate();
+ // await waitForNextUpdate();
+
+ // testAllExpectedRequestAndNoMore(env);
+ // await waitForNextUpdate();
- await updateProduct("1234", { price: "ARS:13" } as any);
+ expect(result.current.query.loading).toBeFalsy();
+ expect(result.current?.query.ok).toBeTruthy();
+ if (!result.current?.query.ok) return;
- expect(result.current.data).toEqual([
+ expect(result.current.query.data).toEqual([
{
id: "1234",
price: "ARS:13",
diff --git a/packages/merchant-backoffice/tests/stories.test.tsx
b/packages/merchant-backoffice/tests/stories.test.tsx
index 0b48cd7..5fb3483 100644
--- a/packages/merchant-backoffice/tests/stories.test.tsx
+++ b/packages/merchant-backoffice/tests/stories.test.tsx
@@ -18,10 +18,11 @@
*
* @author Sebastian Javier Marchano (sebasjm)
*/
-import { mount } from "enzyme";
-import { h } from "preact";
+import { h, VNode } from "preact";
import * as config from "../src/context/config";
import * as i18n from "../src/context/translation";
+import { cleanup, render as originalRender } from "@testing-library/preact";
+import { SWRConfig } from "swr";
import fs from "fs";
@@ -38,39 +39,51 @@ function getFiles(dir: string, files_: string[] = []) {
return files_;
}
-const re = RegExp(".*.stories.tsx");
+const STORIES_NAME_REGEX = RegExp(".*.stories.tsx");
+
+function render(vnode: VNode) {
+ return originalRender(
+ <SWRConfig
+ value={{
+ provider: () => new Map(),
+ }}
+ >
+ {vnode}
+ </SWRConfig>
+ );
+}
import * as jedLib from "jed";
const handler = new jedLib.Jed("en");
-it("render every story", () => {
- jest
- .spyOn(config, "useConfigContext")
- .mockImplementation(() => ({ version: "1.0.0", currency: "EUR" }));
- jest
- .spyOn(i18n, "useTranslationContext")
- .mockImplementation(() => ({
+describe("storybook testing", () => {
+ it("render every story", () => {
+ jest
+ .spyOn(config, "useConfigContext")
+ .mockImplementation(() => ({ version: "1.0.0", currency: "EUR" }));
+ jest.spyOn(i18n, "useTranslationContext").mockImplementation(() => ({
changeLanguage: () => null,
handler,
lang: "en",
}));
- getFiles("./src")
- .filter((f) => re.test(f))
- .map((f) => {
- // const f = "./src/paths/instance/transfers/list/List.stories.tsx";
- // eslint-disable-next-line @typescript-eslint/no-var-requires
- const s = require(`../${f}`);
+ getFiles("./src")
+ .filter((f) => STORIES_NAME_REGEX.test(f))
+ .map((f) => {
+ // const f = "./src/paths/instance/transfers/list/List.stories.tsx";
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
+ const s = require(`../${f}`);
- delete s.default;
- Object.keys(s).forEach((k) => {
- const Component = s[k];
- expect(() => {
- mount(<Component {...Component.args} />)
- .mount()
- .unmount()
- .mount();
- }).not.toThrow(); //`problem rendering ${f} example ${k}`
+ delete s.default;
+ Object.keys(s).forEach((k) => {
+ const Component = s[k];
+ const vdom = <Component {...Component.args} />;
+ expect(() => {
+ const { unmount } = render(vdom);
+ unmount();
+ }).not.toThrow(); //`problem rendering ${f} example ${k}`
+ cleanup();
+ });
});
- });
+ });
});
diff --git a/packages/merchant-backoffice/tests/util.ts
b/packages/merchant-backoffice/tests/util.ts
deleted file mode 100644
index 14b82b5..0000000
--- a/packages/merchant-backoffice/tests/util.ts
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- 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 <http://www.gnu.org/licenses/>
- */
-
-/**
-*
-* @author Sebastian Javier Marchano (sebasjm)
-*/
-import * as axios from 'axios';
-
-type Query<Req, Res> = (GetQuery | PostQuery | DeleteQuery | PatchQuery) &
RequestResponse<Req, Res>
-
-interface RequestResponse<Req, Res> {
- request?: Req,
- params?: any,
- response?: Res,
-}
-interface GetQuery { get: string }
-interface PostQuery { post: string }
-interface DeleteQuery { delete: string }
-interface PatchQuery { patch: string }
-
-export function simulateBackendResponse<R, T>(query: Query<R, T>): void {
- (axios.default as
jest.MockedFunction<axios.AxiosStatic>).mockImplementationOnce(function (opt?:
axios.AxiosRequestConfig): axios.AxiosPromise {
- // console.log(opt, JSON.stringify(query,undefined,2))
- expect(opt).toBeDefined();
- if (!opt)
- return Promise.reject();
-
- // expect(query.request).toStrictEqual(opt.data);
- // expect(query.params).toStrictEqual(opt.params);
- if ('get' in query) {
- expect(opt.method).toBe('get');
- expect(opt.url).toBe(query.get);
- }
- if ('post' in query) {
- expect(opt.method).toBe('post');
- expect(opt.url).toBe(query.post);
- }
- if ('delete' in query) {
- expect(opt.method).toBe('delete');
- expect(opt.url).toBe(query.delete);
- }
- if ('patch' in query) {
- expect(opt.method).toBe('patch');
- expect(opt.url).toBe(query.patch);
- }
- return ({ data: query.response, config: {} } as any);
- } as any)
-}
--
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.