diff --git a/.testing.env b/.testing.env new file mode 100644 index 0000000..f537b74 --- /dev/null +++ b/.testing.env @@ -0,0 +1,3 @@ +REACT_APP_NODE_ENV="test" +REACT_APP_PUBLIC_URL = "http://localhost" +REACT_APP_API_URL = "http://localhost/api/v1/" diff --git a/package.json b/package.json index 944c515..99b5750 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,7 @@ "build:msw": "msw init ./build --no-save", "analyze": "source-map-explorer 'build/static/js/*.js'", "TEST": "------------------------------------------------------------------------", - "test": "npm run test:unit", + "test": "env-cmd -f ./.testing.env npm run test:unit", "test:unit": "npm run tsc:check && node scripts/test.js --watchAll=false", "test:unit:coverage": "npm run test:unit -- --coverage", "LINT": "------------------------------------------------------------------------", diff --git a/src/hooks/useOnClickOutside.spec.ts b/src/hooks/useOnClickOutside.spec.ts index 54dd584..ed9c142 100644 --- a/src/hooks/useOnClickOutside.spec.ts +++ b/src/hooks/useOnClickOutside.spec.ts @@ -27,7 +27,9 @@ describe("useOnClickOutside", () => { return { result: renderHook(() => useOutsideClick({ ref, handler }), { - config: {}, + config: { + withToaster: false, + }, }), handler, ref, @@ -85,7 +87,7 @@ describe("useOnClickOutside", () => { setup(); - expect(addEventListenerSpy).toHaveBeenCalledTimes(2); + expect(addEventListenerSpy).toHaveBeenCalledTimes(1); expect(addEventListenerSpy).toHaveBeenCalledWith("mousedown", expect.any(Function)); addEventListenerSpy.mockRestore(); diff --git a/src/services/mocker/mirage/index.ts b/src/services/mocker/mirage/index.ts index 364a925..85a2a8a 100755 --- a/src/services/mocker/mirage/index.ts +++ b/src/services/mocker/mirage/index.ts @@ -1 +1,4 @@ export * from "./server"; +export * from "./scenarios"; +export * from "./utils"; +export * from "./routes"; diff --git a/src/services/mocker/mirage/routes/reminder.ts b/src/services/mocker/mirage/routes/reminder.ts index db45a55..6d150d6 100644 --- a/src/services/mocker/mirage/routes/reminder.ts +++ b/src/services/mocker/mirage/routes/reminder.ts @@ -2,7 +2,7 @@ import { REMINDER_STATE, TReminder } from "types"; import { TAppMockServer } from "../types"; -import { urlPrefix, resourceNotFoundResponse } from "./utils"; +import { urlPrefix, resourceNotFoundResponse } from "../utils"; export function reminderRoutes(this: TAppMockServer) { this.get(urlPrefix("/reminders"), (schema, request) => { diff --git a/src/services/mocker/mirage/routes/reminderGroup.ts b/src/services/mocker/mirage/routes/reminderGroup.ts index 5ca804a..c5d5702 100644 --- a/src/services/mocker/mirage/routes/reminderGroup.ts +++ b/src/services/mocker/mirage/routes/reminderGroup.ts @@ -2,7 +2,7 @@ import { TReminderGroup } from "types"; import { TAppMockServer } from "../types"; -import { urlPrefix, resourceNotFoundResponse } from "./utils"; +import { urlPrefix, resourceNotFoundResponse } from "../utils"; export function reminderGroupRoutes(this: TAppMockServer) { this.get(urlPrefix("/reminder-groups"), (schema) => { diff --git a/src/services/mocker/mirage/scenarios/index.ts b/src/services/mocker/mirage/scenarios/index.ts index ce3f997..8807e4f 100644 --- a/src/services/mocker/mirage/scenarios/index.ts +++ b/src/services/mocker/mirage/scenarios/index.ts @@ -1,22 +1,16 @@ -import { TNonEmptyArray } from "types"; - import { TAppMockServer } from "../types"; +import { TScenariosBuilder } from "../../types"; + export function buildScenarios(server: TAppMockServer) { - const builder = { + const builder: TScenariosBuilder = { // create reminders without any group - withReminders: (n: number = 10) => { + withReminders: (n = 10) => { server.createList("reminder", n); return builder; }, // create reminders with groups - withReminderGroups: ({ - reminderGroups = ["Work", "Home", "Personal"], - remindersPerGroup = 10, - }: { - reminderGroups?: TNonEmptyArray; - remindersPerGroup?: number; - }) => { + withReminderGroups: ({ reminderGroups = ["Work", "Home", "Personal"], remindersPerGroup = 10 }) => { reminderGroups.forEach((groupName) => { const group = server.create("reminderGroup", { name: groupName }); server.createList("reminder", remindersPerGroup, { group }); diff --git a/src/services/mocker/mirage/server.ts b/src/services/mocker/mirage/server.ts index 2698b5b..2873382 100755 --- a/src/services/mocker/mirage/server.ts +++ b/src/services/mocker/mirage/server.ts @@ -3,20 +3,23 @@ import { createServer } from "miragejs"; import { createRoutes } from "./routes"; import * as models from "./models"; import * as factories from "./factories"; -import { buildScenarios } from "./scenarios"; import { TAppMockServer } from "./types"; import { IdentityManager } from "./identityManager"; +import { buildScenarios } from "./scenarios"; export type TRunMirageServerConfig = { environment?: string; logging?: boolean; timing?: number; + trackRequests?: boolean; + withDefaultScenario?: boolean; }; export function runServer(config: TRunMirageServerConfig = {}): TAppMockServer { - return createServer({ + const server = createServer({ logging: config.logging || true, + trackRequests: config?.trackRequests || false, environment: config?.environment || "development", models, factories, @@ -25,7 +28,9 @@ export function runServer(config: TRunMirageServerConfig = {}): TAppMockServer { }, // mirage's seeds are loaded on initialization seeds(server) { - buildScenarios(server).withReminders(5).withReminderGroups({ remindersPerGroup: 2 }); + if (config?.withDefaultScenario) { + buildScenarios(server).withReminders(5).withReminderGroups({ remindersPerGroup: 2 }); + } }, routes() { @@ -36,4 +41,8 @@ export function runServer(config: TRunMirageServerConfig = {}): TAppMockServer { this.passthrough(); }, }); + + return server; } + +export type TServer = ReturnType; diff --git a/src/services/mocker/mirage/routes/utils.ts b/src/services/mocker/mirage/utils.ts similarity index 100% rename from src/services/mocker/mirage/routes/utils.ts rename to src/services/mocker/mirage/utils.ts diff --git a/src/services/mocker/msw/db.ts b/src/services/mocker/msw/db.ts index 7cd4c9c..8d39554 100644 --- a/src/services/mocker/msw/db.ts +++ b/src/services/mocker/msw/db.ts @@ -29,36 +29,6 @@ export const db = factory({ export type TDb = typeof db; -export const buildScenarios = (db: TDb) => { - const builder = { - withReminders: (n: number = 10) => { - for (let i = 0; i < n; i++) { - db.reminder.create(); - } - - return builder; - }, - withReminderGroups: ({ - reminderGroups = ["Work", "Home", "Personal"], - remindersPerGroup = 10, - }: { - reminderGroups?: string[]; - remindersPerGroup?: number; - }) => { - reminderGroups.forEach((groupName) => { - const group = db.reminderGroup.create({ name: groupName }); - - for (let i = 0; i < remindersPerGroup; i++) { - db.reminder.create({ group }); - } - }); - - return builder; - }, - }; - return builder; -}; - export const dropDb = (db: TDb) => { drop(db); }; diff --git a/src/services/mocker/msw/server.ts b/src/services/mocker/msw/server.ts index f97881e..d7b9601 100755 --- a/src/services/mocker/msw/server.ts +++ b/src/services/mocker/msw/server.ts @@ -1,14 +1,19 @@ import { setupWorker } from "msw/browser"; -import { db, buildScenarios } from "./db"; +import { TScenariosBuilder } from "../types"; + +import { db, TDb } from "./db"; import { setupHandlers } from "./handlers"; const PUBLIC_URL = process.env.REACT_APP_PUBLIC_URL; -export const runServer = () => { - // NOTE: seed data - buildScenarios(db).withReminders(5).withReminderGroups({ remindersPerGroup: 2 }); +export const runServer = (config?: { withDefaultScenario?: boolean }) => { + if (config?.withDefaultScenario) { + buildScenarios(db) + .withReminders(5) + .withReminderGroups({ reminderGroups: ["Work", "Home", "Personal"], remindersPerGroup: 2 }); + } const handlers = setupHandlers(db); @@ -21,3 +26,27 @@ export const runServer = () => { }, }); }; + +export const buildScenarios = (db: TDb) => { + const builder: TScenariosBuilder = { + withReminders: (n = 10) => { + for (let i = 0; i < n; i++) { + db.reminder.create(); + } + + return builder; + }, + withReminderGroups: ({ reminderGroups = ["Work", "Home", "Personal"], remindersPerGroup = 10 }) => { + reminderGroups.forEach((groupName) => { + const group = db.reminderGroup.create({ name: groupName }); + + for (let i = 0; i < remindersPerGroup; i++) { + db.reminder.create({ group }); + } + }); + + return builder; + }, + }; + return builder; +}; diff --git a/src/services/mocker/setupMocker.ts b/src/services/mocker/setupMocker.ts index de19ac8..b963895 100755 --- a/src/services/mocker/setupMocker.ts +++ b/src/services/mocker/setupMocker.ts @@ -5,16 +5,13 @@ export const MOCKER_TYPE = { export type TMocker = (typeof MOCKER_TYPE)[keyof typeof MOCKER_TYPE] | undefined; -const initServer = (module: { runServer: () => void }) => { - const { runServer } = module; - const server = runServer(); - - return server; -}; - export const setupMocker = async ({ type = undefined }: { type: TMocker }) => { if (MOCKER_TYPE[type!]) { - return import(`./${type}`).then(initServer); + const { runServer } = await import(`./${type}/server.ts`); + + return runServer({ + withDefaultScenario: true, + }); } return Promise.resolve(); diff --git a/src/services/mocker/types.ts b/src/services/mocker/types.ts new file mode 100644 index 0000000..b97eb0a --- /dev/null +++ b/src/services/mocker/types.ts @@ -0,0 +1,6 @@ +import { TNonEmptyArray } from "types"; + +export type TScenariosBuilder = { + withReminders: (n: number) => any; + withReminderGroups: (options: { reminderGroups: TNonEmptyArray; remindersPerGroup: number }) => any; +}; diff --git a/src/tests/jest.setupBeforeEnv.ts b/src/tests/jest.setupBeforeEnv.ts index d79e3ce..c007c2b 100644 --- a/src/tests/jest.setupBeforeEnv.ts +++ b/src/tests/jest.setupBeforeEnv.ts @@ -1,7 +1,8 @@ import "./jest.polyfills"; -// mocking the environment variables +// NOTE: alternative to .testing.env file +// mocking the environment variables // @ts-ignore -process.env.REACT_APP_PUBLIC_URL = "http://localhost"; +// process.env.REACT_APP_PUBLIC_URL = "http://localhost"; // @ts-ignore -process.env.REACT_APP_API_URL = "http://localhost/api/v1/"; +// process.env.REACT_APP_API_URL = "http://localhost/api/v1/"; diff --git a/src/tests/utils/Wrapper.tsx b/src/tests/utils/Wrapper.tsx index f22f85d..0f90ac6 100644 --- a/src/tests/utils/Wrapper.tsx +++ b/src/tests/utils/Wrapper.tsx @@ -42,6 +42,7 @@ export const Wrapper: FC> = ({ config = { withI18n: true, withStore: true, + preloadedState: undefined, withRouter: true, withToaster: true, }, diff --git a/src/tests/utils/render.tsx b/src/tests/utils/render.tsx index 9bef650..9b13c99 100644 --- a/src/tests/utils/render.tsx +++ b/src/tests/utils/render.tsx @@ -12,7 +12,7 @@ export const render = (ui: ReactNode, options: TRenderProps = {}) => { const OuterWrapper = () => { const InnerWrapper = renderOptions?.wrapper; - return {InnerWrapper ? {ui} : ui}; + return {InnerWrapper ? {ui} : ui}; }; return _render(ui, { wrapper: OuterWrapper, ...renderOptions }); diff --git a/src/tests/utils/renderHook.tsx b/src/tests/utils/renderHook.tsx index 5a26486..cfbd1ef 100644 --- a/src/tests/utils/renderHook.tsx +++ b/src/tests/utils/renderHook.tsx @@ -15,7 +15,7 @@ export const renderHook = ( const InnerWrapper = options?.wrapper; - return {InnerWrapper ? : children}; + return {InnerWrapper ? : children}; }; return _renderHook(render, { ...options, wrapper: OuterWrapper }); diff --git a/src/tests/utils/testServer.ts b/src/tests/utils/testServer.ts index 8805a5f..a113fbe 100644 --- a/src/tests/utils/testServer.ts +++ b/src/tests/utils/testServer.ts @@ -2,32 +2,72 @@ import { setupServer } from "msw/node"; import { beforeAll, afterEach, afterAll } from "@jest/globals"; +import { runServer, createRoutes } from "services/mocker/mirage"; + import { setupHandlers, db, dropDb } from "services/mocker/msw"; -export const testServer = setupServer(...setupHandlers(db)); +export const createTestMswServer = (logging: boolean = false) => { + const testMswServer = setupServer(...setupHandlers(db)); + + beforeAll(() => { + testMswServer.listen({ + onUnhandledRequest(request) { + // eslint-disable-next-line no-console + console.log("Unhandled %s %s", request.method, request.url); + }, + }); + }); + + afterEach(() => { + testMswServer.resetHandlers(); + dropDb(db); + }); -beforeAll(() => - testServer.listen({ - onUnhandledRequest(request) { + afterAll(() => { + testMswServer.close(); + }); + + if (logging) { + // NOTE: simple outgoing request listener logger + testMswServer.events.on("request:start", ({ request }) => { // eslint-disable-next-line no-console - console.log("Unhandled %s %s", request.method, request.url); - }, - }) -); - -afterEach(() => { - testServer.resetHandlers(); - dropDb(db); -}); - -afterAll(() => { - testServer.close(); -}); - -// NOTE: simple outgoing request listener logger -testServer.events.on("request:start", ({ request }) => { - // eslint-disable-next-line no-console - console.log("MSW intercepted:", request.method, request.url); -}); + console.log("MSW intercepted:", request.method, request.url); + }); + } + + return testMswServer; +}; + +export const createTestMirageServer = () => { + const testMirageServer = runServer({ + environment: "test", + trackRequests: true, + logging: false, + }); + + afterEach(() => { + createRoutes.call(testMirageServer); + testMirageServer.db.emptyData(); + }); + + afterAll(() => { + testMirageServer.shutdown(); + }); + + return testMirageServer; +}; export { HttpResponse, http } from "msw"; + +// NOTE: Alternative +// let testMirageServer: TAppMockServer; + +// beforeEach(() => { +// testMirageServer = runServer({ +// environment: "test", +// }); +// }); + +// afterEach(() => { +// testMirageServer.shutdown(); +// }); diff --git a/src/views/Reminders/ReminderGroupsList/ReminderGroupsList.spec.tsx b/src/views/Reminders/ReminderGroupsList/ReminderGroupsList.spec.tsx index d32e3ce..53eba79 100644 --- a/src/views/Reminders/ReminderGroupsList/ReminderGroupsList.spec.tsx +++ b/src/views/Reminders/ReminderGroupsList/ReminderGroupsList.spec.tsx @@ -4,10 +4,12 @@ import userEvent from "@testing-library/user-event"; import { db, buildScenarios, urlPrefix } from "services/mocker/msw"; -import { render, testServer, HttpResponse, http } from "tests/utils"; +import { render, createTestMswServer, HttpResponse, http } from "tests/utils"; import { ReminderGroupsList } from "./ReminderGroupsList"; +const testMswServer = createTestMswServer(); + describe("ReminderGroupsList", () => { const setup = () => { const getAddListBtn = () => screen.getByRole("button", { name: "Add List" }); @@ -25,9 +27,7 @@ describe("ReminderGroupsList", () => { }; it("should render reminder groups list", async () => { - buildScenarios(db) - .withReminders(5) - .withReminderGroups({ reminderGroups: ["Work", "Home", "Personal"], remindersPerGroup: 2 }); + buildScenarios(db).withReminderGroups({ reminderGroups: ["Work", "Home", "Personal"], remindersPerGroup: 0 }); setup(); @@ -35,13 +35,15 @@ describe("ReminderGroupsList", () => { expect(screen.getByText("All")).toBeInTheDocument(); }); - expect(screen.getAllByRole("listitem")).toHaveLength(4); + await waitFor(() => { + expect(screen.getAllByRole("listitem")).toHaveLength(4); + }); }); it("should handle negative scenario for fetching reminder groups", async () => { - testServer.use( + testMswServer.use( http.get(urlPrefix("/reminder-groups"), () => { - return HttpResponse.json({ message: "Error" }, { status: 404 }); + return HttpResponse.json({ message: "Error" }, { status: 500 }); }) ); @@ -52,7 +54,7 @@ describe("ReminderGroupsList", () => { }); }); - it("should add reminder group", async () => { + it("should be able to add reminder group", async () => { const { getAddListBtn, getTextInput, getSaveBtn } = setup(); await userEvent.click(getAddListBtn()); @@ -71,9 +73,9 @@ describe("ReminderGroupsList", () => { }); it("should handle negative scenario for adding reminder group", async () => { - testServer.use( + testMswServer.use( http.post(urlPrefix("/reminder-groups"), () => { - return HttpResponse.json({ message: "Error" }, { status: 404 }); + return HttpResponse.json({ message: "Error" }, { status: 500 }); }) ); diff --git a/src/views/Reminders/ReminderGroupsList/useReminderGroupsList.ts b/src/views/Reminders/ReminderGroupsList/useReminderGroupsList.ts index 07cc07f..7d0c695 100644 --- a/src/views/Reminders/ReminderGroupsList/useReminderGroupsList.ts +++ b/src/views/Reminders/ReminderGroupsList/useReminderGroupsList.ts @@ -5,14 +5,10 @@ import { toast } from "sonner"; import { useGetReminderGroupsQuery, useCreateReminderGroupMutation, handleAsync } from "shared"; export const useReminderGroupsList = () => { - const getReminderGroupResult = useGetReminderGroupsQuery(); + const getReminderGroupsResult = useGetReminderGroupsQuery(); const [createReminderGroup, createReminderGroupResult] = useCreateReminderGroupMutation(); - const isLoading = createReminderGroupResult.isLoading; - - const isErrored = createReminderGroupResult.isError; - const handleOnSave = useCallback( async (props: Parameters[0]) => { await handleAsync(() => @@ -28,14 +24,12 @@ export const useReminderGroupsList = () => { toast.error("Error creating reminder group"); } - if (getReminderGroupResult.isError) { + if (getReminderGroupsResult.isError) { toast.error("Error fetching reminder groups"); } return { - reminderGroups: getReminderGroupResult.data, + reminderGroups: getReminderGroupsResult.data, handleOnSave, - isLoading, - isErrored, }; }; diff --git a/src/views/Reminders/RemindersList/RemindersList.spec.tsx b/src/views/Reminders/RemindersList/RemindersList.spec.tsx new file mode 100644 index 0000000..071378f --- /dev/null +++ b/src/views/Reminders/RemindersList/RemindersList.spec.tsx @@ -0,0 +1,123 @@ +import { screen, waitFor } from "@testing-library/react"; + +import { Response } from "miragejs"; +import userEvent from "@testing-library/user-event"; + +import { buildScenarios, urlPrefix } from "services/mocker/mirage"; + +import { render, TRenderProps, createTestMirageServer } from "tests/utils"; + +import { RemindersList } from "./RemindersList"; + +const testMirageServer = createTestMirageServer(); + +describe("RemindersList", () => { + const setup = (setupProps: { config?: TRenderProps["config"] } = {}) => { + const getAddItemBtn = () => screen.getByTestId("reminder-list-add-btn"); + const getSaveBtn = () => screen.getByTestId("reminder-item-create-save"); + const getCancelBtn = () => screen.getByTestId("reminder-item-create-cancel"); + const getTextInput = () => screen.getByTestId("reminder-item-create-text"); + + return { + result: render(, { + ...(setupProps?.config ? { config: setupProps?.config } : {}), + }), + getAddItemBtn, + getSaveBtn, + getCancelBtn, + getTextInput, + }; + }; + + it("should render reminders list", async () => { + buildScenarios(testMirageServer).withReminders(5); + + setup(); + + await waitFor(() => { + expect(screen.getByText("All")).toBeInTheDocument(); + }); + + await waitFor(() => { + return expect(screen.getAllByRole("listitem")).toHaveLength(5); + }); + }); + + it("should handle negative scenario for fetching reminders", async () => { + testMirageServer.get(urlPrefix("/reminders"), () => new Response(404)); + + setup(); + + await waitFor(() => { + expect(screen.getByText("Error fetching reminders")).toBeInTheDocument(); + }); + }); + + it("should handle positive scenario for reminders and negative scenario for fetching reminder group", async () => { + const reminderGroup = testMirageServer.create("reminderGroup", { name: "Group 1" }); + testMirageServer.createList("reminder", 5, { group: reminderGroup }); + + const groupId = reminderGroup.id; + const config = { + preloadedState: { + reminders: { + queryParams: { + groupId, + }, + }, + }, + withStore: true, + withToaster: true, + }; + + testMirageServer.get(urlPrefix(`/reminder-groups/${groupId}`), () => new Response(500)); + + setup({ config }); + + await waitFor(() => { + return expect(screen.getAllByRole("listitem")).toHaveLength(5); + }); + + await waitFor(() => { + expect(screen.getByText("Error fetching reminder group")).toBeInTheDocument(); + }); + }); + + it("should be able to add a reminder", async () => { + const { getAddItemBtn, getSaveBtn, getTextInput } = setup(); + + await userEvent.click(getAddItemBtn()); + + await waitFor(() => { + expect(getTextInput()).toBeInTheDocument(); + }); + + await userEvent.type(getTextInput(), "New reminder"); + + await userEvent.click(getSaveBtn()); + + await waitFor(() => { + expect(screen.getByText("New reminder")).toBeInTheDocument(); + }); + }); + + it("should handle negative scenario for adding a reminder", async () => { + testMirageServer.post(urlPrefix(`/reminders`), () => new Response(500)); + + const { getAddItemBtn, getSaveBtn, getTextInput } = setup(); + + await userEvent.click(getAddItemBtn()); + + await waitFor(() => { + expect(getTextInput()).toBeInTheDocument(); + }); + + await userEvent.type(getTextInput(), "New reminder"); + + await userEvent.click(getSaveBtn()); + + await waitFor(() => { + expect(screen.getByText("Error creating reminder")).toBeInTheDocument(); + }); + }); +}); diff --git a/src/views/Reminders/RemindersList/RemindersList.tsx b/src/views/Reminders/RemindersList/RemindersList.tsx index 456a49f..c80ac5b 100644 --- a/src/views/Reminders/RemindersList/RemindersList.tsx +++ b/src/views/Reminders/RemindersList/RemindersList.tsx @@ -31,7 +31,7 @@ export const RemindersList: FC> = () => { size={"icon"} variant={"ghost"} className="hover:text-primary" - data-testid="reminder-list-refetch" + data-testid="reminder-list-refetch-btn" > > = () => { size={"icon"} onClick={() => setIsCreating((isCreating) => !isCreating)} disabled={isCreating} + data-testid="reminder-list-add-btn" /> @@ -79,6 +80,7 @@ export const RemindersList: FC> = () => { testIds={{ cancel: `reminder-item-create-cancel`, save: `reminder-item-create-save`, + text: `reminder-item-create-text`, }} /> )} diff --git a/src/views/Reminders/RemindersList/useRemindersList.ts b/src/views/Reminders/RemindersList/useRemindersList.ts index 37b7e52..6c79d27 100644 --- a/src/views/Reminders/RemindersList/useRemindersList.ts +++ b/src/views/Reminders/RemindersList/useRemindersList.ts @@ -1,5 +1,7 @@ import { useCallback } from "react"; +import { toast } from "sonner"; + import { useGetRemindersQuery, useSelectQueryParams, @@ -11,18 +13,14 @@ import { export const useRemindersList = () => { const queryParams = useSelectQueryParams(); - const { currentData: reminders, refetch } = useGetRemindersQuery(queryParams); + const getRemindersResult = useGetRemindersQuery(queryParams); - const { currentData: reminderGroup } = useGetReminderGroupQuery(queryParams.groupId as string, { + const getReminderGroupResult = useGetReminderGroupQuery(queryParams.groupId as string, { skip: !queryParams.groupId, }); const [createReminder, createReminderResult] = useCreateReminderMutation(); - const isLoading = createReminderResult.isLoading; - - const isErrored = createReminderResult.isError; - const handleOnSave = useCallback( async (props: Parameters[0]) => { await handleAsync(() => @@ -35,12 +33,22 @@ export const useRemindersList = () => { [createReminder] ); + if (getReminderGroupResult.isError) { + toast.error("Error fetching reminder group"); + } + + if (getRemindersResult.isError) { + toast.error("Error fetching reminders"); + } + + if (createReminderResult.isError) { + toast.error("Error creating reminder"); + } + return { - reminders, - reminderGroup, - refetchReminders: refetch, + reminders: getRemindersResult.currentData, + reminderGroup: getReminderGroupResult.currentData, + refetchReminders: getRemindersResult.refetch, handleOnSave, - isLoading, - isErrored, }; }; diff --git a/testing.md b/testing.md index b87d04c..3b571a0 100644 --- a/testing.md +++ b/testing.md @@ -10,3 +10,12 @@ 1. Docs: 1. https://github.com/mswjs/examples/blob/main/examples/with-jest-jsdom/README.md 2. https://mswjs.io/docs/migrations/1.x-to-2.x/#requestresponsetextencoder-is-not-defined-jest + +## RTL + +1. Print whole JSDOM object - `screen.debug(result.container, Infinity);` + +## Mirage + +1. Print all entities in db - `console.log(testMirageServer.db.dump());` +2. [Track requests for assertions](https://miragejs.com/docs/testing/assertions/#asserting-against-handled-requests-and-responses)