From 7d7d5ab75aebac7fce616657c0c85fe3fb4b96f1 Mon Sep 17 00:00:00 2001 From: "Ziyuan (Jerry) Zhang" Date: Fri, 1 Mar 2024 17:18:43 -0500 Subject: [PATCH] wip, all tests --- demo/package.json | 1 + demo/src/MemoryModels.tsx | 12 +- demo/src/__tests__/MemoryModels.spec.tsx | 141 ++++++++++++++--------- package-lock.json | 14 +++ 4 files changed, 111 insertions(+), 57 deletions(-) diff --git a/demo/package.json b/demo/package.json index 1b378d40..bdcdac6c 100644 --- a/demo/package.json +++ b/demo/package.json @@ -25,6 +25,7 @@ "@babel/preset-react": "^7.23.3", "@babel/preset-typescript": "^7.23.3", "@testing-library/react": "^14.2.1", + "@testing-library/user-event": "^14.5.2", "@types/react": "^18.2.45", "@types/react-dom": "^18.2.18", "babel-jest": "^29.7.0", diff --git a/demo/src/MemoryModels.tsx b/demo/src/MemoryModels.tsx index b87ef2db..aa04de2e 100644 --- a/demo/src/MemoryModels.tsx +++ b/demo/src/MemoryModels.tsx @@ -24,7 +24,7 @@ function MemoryModelsFileInput(props: MemoryModelsInputPropTypes) { const onChange = (event) => { try { const uploadedFile = event.target.files[0]; - const fileReader = new FileReader(); + const fileReader = new global.FileReader(); fileReader.readAsText(uploadedFile, "UTF-8"); fileReader.onload = (event) => { const fileString = event.target.result as string; @@ -40,6 +40,7 @@ function MemoryModelsFileInput(props: MemoryModelsInputPropTypes) { }; const onReapplyBtnClick = () => { + console.log("reached"); props.setTextData(uploadedFileString); }; @@ -47,9 +48,11 @@ function MemoryModelsFileInput(props: MemoryModelsInputPropTypes) { @@ -75,7 +78,8 @@ function MemoryModelsTextInput(props: MemoryModelsInputPropTypes) { return ( { @@ -79,65 +79,100 @@ describe("MemoryModelsUserInput", () => { /> ); }); - it("works", () => { - const fileInput = screen.getByTestId("file-input"); - expect(fileInput).toBeDefined(); - }); - }); -}); - -import React from "react"; -import { render, fireEvent, screen } from "@testing-library/react"; -import MemoryModelsFileInput from "./MemoryModelsFileInput"; -describe("MemoryModelsFileInput component", () => { - test("uploads a file and updates text data", () => { - const mockSetTextData = jest.fn(); - render(); - - const file = new File(["test content"], "test.json", { - type: "application/json", + afterEach(() => { + // spies / mocks need to be manually restored to not fail subsequent tests + jest.restoreAllMocks(); }); - const input = screen.getByTestId("file-input"); - fireEvent.change(input, { target: { files: [file] } }); - - expect(mockSetTextData).toHaveBeenCalledWith("test content"); - }); - test("reapplies uploaded file content to text box", () => { - const mockSetTextData = jest.fn(); - render(); + it("renders an enabled input and disabled reapply button", () => { + const input: HTMLInputElement = screen.getByTestId("file-input"); + expect(input).toHaveProperty("disabled", false); - const fileContent = "test content"; - const file = new File([fileContent], "test.json", { - type: "application/json", + const reapplyBtn = screen.getByTestId("file-input-reapply-button"); + expect(reapplyBtn).toHaveProperty("disabled", true); }); - const input = screen.getByTestId("file-input"); - fireEvent.change(input, { target: { files: [file] } }); - - const reapplyButton = screen.getByTestId("file-input-reapply-button"); - fireEvent.click(reapplyButton); - expect(mockSetTextData).toHaveBeenCalledWith(fileContent); - }); - - test("reapply button is disabled when no file is uploaded", () => { - render( {}} />); - - const reapplyButton = screen.getByTestId("file-input-reapply-button"); - expect(reapplyButton).toBeDisabled(); - }); - - test("reapply button is enabled when a file is uploaded", () => { - render( {}} />); - - const file = new File(["test content"], "test.json", { - type: "application/json", + it("calls console error and setTextData when file upload fails", async () => { + const mockErrorMessage = "Mock error message"; + const fileReaderSpy = jest + .spyOn(global, "FileReader") + .mockImplementationOnce(() => { + throw new Error(mockErrorMessage); + }); + const consoleErrorSpy = jest.spyOn(console, "error"); + + const file = new File( + [JSON.stringify({ id: 1, uuid: 2 })], + "test.json", + { + type: "application/json", + } + ); + const input: HTMLInputElement = screen.getByTestId("file-input"); + fireEvent.change(input, { target: { files: [file] } }); + await waitFor(() => { + expect(consoleErrorSpy).toHaveBeenNthCalledWith( + 1, + `Error parsing uploaded File as JSON: ${mockErrorMessage}` + ); + expect(setTextDataMock).toHaveBeenNthCalledWith(1, null); + }); }); - const input = screen.getByTestId("file-input"); - fireEvent.change(input, { target: { files: [file] } }); - const reapplyButton = screen.getByTestId("file-input-reapply-button"); - expect(reapplyButton).toBeEnabled(); + describe("when a file is uploaded", () => { + const fileString = JSON.stringify({ id: 1, uuid: 2 }); + let input: HTMLInputElement; + + beforeEach(() => { + const file = new File([fileString], "test.json", { + type: "application/json", + }); + input = screen.getByTestId("file-input"); + fireEvent.change(input, { target: { files: [file] } }); + }); + + it("calls setTextData", async () => { + await waitFor(() => { + expect(setTextDataMock).toHaveBeenNthCalledWith( + 1, + fileString + ); + }); + }); + + it("enabled reapply Button", () => { + const reapplyBtn = screen.getByTestId( + "file-input-reapply-button" + ); + expect(reapplyBtn).toHaveProperty("disabled", true); + }); + + it("clicking reapply button calls setTextData", async () => { + const reapplyBtn = screen.getByTestId( + "file-input-reapply-button" + ); + fireEvent.click(reapplyBtn); + + await waitFor(() => { + // reapply original fileString + expect(setTextDataMock).toHaveBeenNthCalledWith( + 1, + fileString + ); + }); + }); + + it("clicking reapply button doesn't call setTextData if there hasn't been a text change", async () => { + const reapplyBtn = screen.getByTestId( + "file-input-reapply-button" + ); + fireEvent.click(reapplyBtn); + + await waitFor(() => { + expect(setTextDataMock).not.toHaveBeenCalled(); + }); + }); + }); }); }); diff --git a/package-lock.json b/package-lock.json index d0e17ae7..2f7accd6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -53,6 +53,7 @@ "@babel/preset-react": "^7.23.3", "@babel/preset-typescript": "^7.23.3", "@testing-library/react": "^14.2.1", + "@testing-library/user-event": "^14.5.2", "@types/react": "^18.2.45", "@types/react-dom": "^18.2.18", "babel-jest": "^29.7.0", @@ -4748,6 +4749,19 @@ "react-dom": "^18.0.0" } }, + "node_modules/@testing-library/user-event": { + "version": "14.5.2", + "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.5.2.tgz", + "integrity": "sha512-YAh82Wh4TIrxYLmfGcixwD18oIjyC1pFQC2Y01F2lzV2HTMiYrI0nze0FD0ocB//CKS/7jIUgae+adPqxK5yCQ==", + "dev": true, + "engines": { + "node": ">=12", + "npm": ">=6" + }, + "peerDependencies": { + "@testing-library/dom": ">=7.21.4" + } + }, "node_modules/@tootallnate/once": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz",