From 6da27ab234ad37b4181951d9b5916eadfc9ac5e5 Mon Sep 17 00:00:00 2001 From: Zrybea Whitfield <66852175+ZrybeaWhitfield@users.noreply.github.com> Date: Sun, 4 Feb 2024 23:39:09 -0500 Subject: [PATCH 1/3] Resolves #63 unit tests for LoginForm --- frontend/__tests__/LoginForm.test.js | 104 ++++++++++++++++++++------- 1 file changed, 77 insertions(+), 27 deletions(-) diff --git a/frontend/__tests__/LoginForm.test.js b/frontend/__tests__/LoginForm.test.js index 270460a..c33d69f 100644 --- a/frontend/__tests__/LoginForm.test.js +++ b/frontend/__tests__/LoginForm.test.js @@ -1,39 +1,89 @@ import React from "react" import "@testing-library/jest-dom" -import { render, screen } from "@testing-library/react" +import { fireEvent, render, screen} from "@testing-library/react" import LoginForm from "../src/components/LoginForm" -//This test suite is tests for the LoginForm component - 'describe' fn is how we instantiate a test suite and the first argument is a string that describes the suite, the second is the cb function which can be another suite or test -describe("Tests for LoginForm Component", () => { - //This individual test is testing whether these elements actually render. 'test' fn instantiates the test, first arg is the test description/name, second is the cb with the test - test("component renders inputs and button", () => { - //Mock these props as there are outside of the scope of this test. jest.fn() is a mock function that simulates the function call since the return doesn't matter, we just need placeholder props - const mockSetUsername = jest.fn() - const mockSetPassword = jest.fn() - const mockAuth = jest.fn() +describe("Tests for LoginForm Component", () => { + //Mocks for setter and authenticate functions + let mockSetUsername = jest.fn() + let mockSetPassword = jest.fn() + let mockAuth = jest.fn() - //This renders the component with empty strings for the un and pw, then calls the mock setter fns - render( - ) + describe("Tests for Rendering Login Form", () => { + test("component should have inputs and button", () => { + render( + + ) - //These variables find the elements in the dom that match the query, (finds the elem by the placeholder text and by the text in this case-there are queries for all the attributes) - const usernameInput = screen.getByPlaceholderText("Username") - const passwordInput = screen.getByPlaceholderText("Password") - const loginButton = screen.getByText("Login") + const usernameInput = screen.getByPlaceholderText("Username") + const passwordInput = screen.getByPlaceholderText("Password") + const loginButton = screen.getByText("Login") + + //Assertions + expect(usernameInput).toBeInTheDocument() + expect(passwordInput).toBeInTheDocument() + expect(loginButton).toBeInTheDocument() + + }) - //Assertions- our test will only pass if all 3 of these assertions are true. We expect an elem with a placeholder text of "Username" to be in the document. - expect(usernameInput).toBeInTheDocument() - expect(passwordInput).toBeInTheDocument() - expect(loginButton).toBeInTheDocument() + + }) + + describe("Tests for LoginForm Interactions", () => { + //Render the loginform into container appended to document.body before each of the following tests + beforeEach(() => { + render( + + ) + }) + + //Clear mocks after each test + afterEach(() => { + jest.clearAllMocks() + }) + test("should call authenticate function on click event", async () => { + const loginButton = screen.getByText("Login") + fireEvent.click(loginButton) + + expect(mockAuth).toHaveBeenCalledTimes(1) + }) + test("should call setUsername with value from username input", () => { + const usernameInput = screen.getByPlaceholderText("Username") + const testUserName = "Test_User" + + fireEvent.change(usernameInput, {target: {value: testUserName}}) + + expect(mockSetUsername).toHaveBeenCalledTimes(1) + expect(mockSetUsername).toHaveBeenCalledWith(testUserName) + }) + + test("should call setPassword with value from password input", () => { + const passwordInput = screen.getByPlaceholderText("Password") + const testPassword = "Test_Password" + + fireEvent.change(passwordInput, {target: {value: testPassword}}) + + expect(mockSetPassword).toHaveBeenCalledTimes(1) + expect(mockSetPassword).toHaveBeenCalledWith(testPassword) + }) + }) + }) From 83c4cf89ca42254c5c7ca7de7a2f975880d4402c Mon Sep 17 00:00:00 2001 From: Zrybea Whitfield <66852175+ZrybeaWhitfield@users.noreply.github.com> Date: Mon, 5 Feb 2024 07:20:02 -0500 Subject: [PATCH 2/3] fix jest lint errors --- frontend/.eslintrc.cjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/.eslintrc.cjs b/frontend/.eslintrc.cjs index 4dcb439..20b73fc 100644 --- a/frontend/.eslintrc.cjs +++ b/frontend/.eslintrc.cjs @@ -1,6 +1,6 @@ module.exports = { root: true, - env: { browser: true, es2020: true }, + env: { browser: true, es2020: true, jest: true }, extends: [ 'eslint:recommended', 'plugin:react/recommended', From 97082ad7b1df30090d1fff6e3210b195497fbb3b Mon Sep 17 00:00:00 2001 From: Zrybea Whitfield <66852175+ZrybeaWhitfield@users.noreply.github.com> Date: Mon, 5 Feb 2024 16:54:38 -0500 Subject: [PATCH 3/3] Edit to README.md --- README.md | 39 ++++++++++++++++++++++++++++++++++++++- frontend/.eslintrc.cjs | 1 + 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 8b111ef..c8d36d3 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,44 @@ The frontend of the Notes App is built with React, Vite.js, and Tailwind CSS. It The backend of the Notes App is powered by Node.js, Express.js, Mongoose, and Docker. It provides a robust API for managing notes, handling user authentication, and interacting with a MongoDB database. The backend follows a modular architecture with routes, controllers, models, and utilities for different aspects of the application logic. ## ๐Ÿงช Testing -A key objective of this project was learning and implementing tests. The READMEs for both the frontend and backend provide detailed insights into the testing strategies and methodologies. +A key objective of this project was learning and implementing tests. The READMEs for both the frontend and backend provide detailed insights into the testing strategies and methodologies. In this project we are utilizing Jest on both the frontend and backend for testing React, and Node.js (ES6). + +- **Unit Test**: Tests that cover isolated modules or "units" of code without depending on outside modules. Typically, these test individual functions or branches of code. + +- **Integration Test**: Tests that cover multiple modules together interacting with each other. + +- **End-to-End Tests**: Tests functionality of an entire software application from start to finish by simulating UI interactions and replicating live data. + +- **Test Case**: A series of tasks/functions that set an environment to verify functionality. It may include mocking data, running functions, and assertions. + +- **Test Suite**: A group of logically similar tests that together cover test cases for one job. + +- **Mocking**: Simulating data or functions in a test environment to avoid using live/production data or functions. + +- **Assertion**: Declares the expected behavior or outcome of a test. + +Here are some methods you may encounter throughout our tests and what they do: + +- `describe()`: Instantiates a test suite. The first argument is a string that describes the suite, which is also the suite's name. The second argument is a callback function that can contain another suite or test. + +- `test()` or `it()`: Instantiates a test. The first argument is the test description or name, and the second argument is a callback function containing the test. Both `test()` and `it()` have the same functionality but use different naming conventions for readability. For example: + ```javascript + test("Should do this thing", () => { + // Test logic here + }) + it("Does this thing", () => { + // Test logic here + }) + ``` +- `jest.fn()`: This function mimics a function. When mocking dependencies within a test, you can use jest.fn() to simulate a function call and mock return data. + +- `expect()`: Instantiates an assertion. expect() takes in a value and provides access to matchers that evaluate whether the value meets specific conditions. For example: + ```javascript + const name = "Notes-App"; + expect(name).toBe("Notes-App") + ``` +For more information about Jest and its capabilities, you can refer to the [Jest documentation](https://jestjs.io/docs/getting-started). + ## ๐Ÿš€ Getting Started 1. Clone the repository: `git clone https://github.com/wadedesir/notes-app.git` diff --git a/frontend/.eslintrc.cjs b/frontend/.eslintrc.cjs index 20b73fc..c4d8d6d 100644 --- a/frontend/.eslintrc.cjs +++ b/frontend/.eslintrc.cjs @@ -6,6 +6,7 @@ module.exports = { 'plugin:react/recommended', 'plugin:react/jsx-runtime', 'plugin:react-hooks/recommended', + 'plugin:cypress/recommended' ], ignorePatterns: ['dist', '.eslintrc.cjs'], parserOptions: { ecmaVersion: 'latest', sourceType: 'module' },