Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IssueId #222311 feat: Writing Test Cases for LoginPage Component in ALL #104

Open
wants to merge 6 commits into
base: all-automation
Choose a base branch
from
35 changes: 15 additions & 20 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@
"@reduxjs/toolkit": "^2.2.0",
"@testing-library/user-event": "^13.5.0",
"axios": "^1.6.5",
"axios-mock-adapter": "^1.22.0",
"canvas-confetti": "^1.9.2",
"character-error-rate": "^1.1.4",
"classnames": "^2.3.1",
"eslint": "^8.46.0",
"eslint-plugin-import": "^2.28.0",
"eslint-plugin-jsx-a11y": "^6.7.1",
"eslint-plugin-react": "^7.33.1",
"eslint-plugin-import": "^2.29.1",
"eslint-plugin-jsx-a11y": "^6.9.0",
"eslint-plugin-react": "^7.34.3",
"faker": "^5.5.3",
"homophones": "^1.0.1",
"jwt-decode": "^4.0.0",
Expand All @@ -43,10 +43,7 @@
"sass": "^1.44.0",
"split-graphemes": "^0.5.0",
"use-sound": "^4.0.1",
"web-vitals": "^2.1.4",
"eslint-plugin-import": "^2.28.0",
"eslint-plugin-jsx-a11y": "^6.7.1",
"eslint-plugin-react": "^7.33.1"
"web-vitals": "^2.1.4"
},
"scripts": {
"start": "react-scripts start",
Expand All @@ -70,11 +67,8 @@
"react-app/jest"
],
"ignorePatterns": [

"build/",

"public/js/jquery-3.7.0.min.js"

]
},
"browserslist": {
Expand All @@ -90,30 +84,31 @@
]
},
"devDependencies": {
"eslint": "^7.32.0",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why this is removed from dev dependencies?

"prettier": "^2.3.2",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-prettier": "^3.4.0",
"husky": "^9.0.11",
"lint-staged": "^11.0.0",
"react": "^18.2.0",
"@mui/styles": "^5.15.10",
"@babel/core": "^7.24.7",
"@babel/preset-env": "^7.24.7",
"@babel/preset-react": "^7.24.7",
"@babel/preset-typescript": "^7.24.7",
"@mui/styles": "^5.15.10",
"@testing-library/dom": "^8.0.0",
"@testing-library/jest-dom": "^6.4.6",
"@testing-library/react": "^16.0.0",
"babel-jest": "^29.7.0",
"eslint": "^7.32.0",
"eslint-config-prettier": "^8.10.0",
"eslint-config-react-app": "^7.0.1",
"eslint-plugin-prettier": "^3.4.1",
"husky": "^9.0.11",
"identity-obj-proxy": "^3.0.0",
"jest": "^29.7.0",
"jest-environment-jsdom": "^29.7.0",
"lint-staged": "^11.0.0",
"prettier": "^2.3.2",
"react": "^18.2.0",
"react-redux": "^9.1.2",
"react-scripts": "^5.0.1",
"redux-mock-store": "^1.5.4"
},
"lint-staged": {
"lint-staged": {
"src/**/*.{js,jsx}": [
"npx eslint --fix",
"npx prettier --write"
Expand Down
1 change: 0 additions & 1 deletion src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,6 @@ const App = () => {
<StyledEngineProvider injectFirst>
<ThemeProvider theme={theme}>
<Router>
<a>Learn React</a>
<AppContent routes={routes} />
</Router>
</ThemeProvider>
Expand Down
2 changes: 0 additions & 2 deletions src/App.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,4 @@ test("renders learn react link", () => {
<App />
</Provider>
);
const linkElement = screen.getByText(/learn react/i);
expect(linkElement).toBeInTheDocument();
});
193 changes: 193 additions & 0 deletions src/views/LoginPage/LoginPage.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
import React from "react";
import { render, fireEvent, screen, waitFor } from "@testing-library/react";
import axios from "axios";
import MockAdapter from "axios-mock-adapter";
import { BrowserRouter } from "react-router-dom";
import LoginPage from "./LoginPage";
import config from "../../utils/urlConstants.json";
import { useNavigate } from "react-router-dom";

jest.spyOn(window, "alert").mockImplementation(() => {});

jest.mock("react-router-dom", () => ({
...jest.requireActual("react-router-dom"),
useNavigate: jest.fn(),
}));

describe("LoginPage", () => {
let mockNavigate;
let mockAxios;

beforeEach(() => {
mockNavigate = jest.fn();
useNavigate.mockReturnValue(mockNavigate);
mockAxios = new MockAdapter(axios);
});

afterEach(() => {
mockAxios.reset();
jest.clearAllMocks();
});

test("shows alert when fields are empty", () => {
ajinkyapandetekdi marked this conversation as resolved.
Show resolved Hide resolved
// Given the LoginPage is rendered
render(
<BrowserRouter>
<LoginPage />
</BrowserRouter>
);

// When the login button is clicked
fireEvent.click(screen.getByRole("button", { name: "Login" }));

// Then an alert should be shown indicating fields are empty
expect(window.alert).toHaveBeenCalledWith("Please fill in all fields");
});

test("navigates to /discover-start on successful login", async () => {
// Given the LoginPage is rendered
mockAxios
.onPost(
`${process.env.REACT_APP_VIRTUAL_ID_HOST}/${config.URLS.GET_VIRTUAL_ID}?username=testuser`
)
.reply(200, { result: { virtualID: "12345" } });

render(
<BrowserRouter>
<LoginPage />
</BrowserRouter>
);

// When the user enters a valid username and password and clicks login
fireEvent.change(screen.getByLabelText("Username"), {
target: { value: "testuser" },
});
fireEvent.change(screen.getByLabelText("Password"), {
target: { value: "testpassword" },
});
fireEvent.click(screen.getByRole("button", { name: "Login" }));

// Then localStorage should be set with the username and virtualId
await waitFor(() =>
expect(localStorage.getItem("profileName")).toBe("testuser")
);
await waitFor(() =>
expect(localStorage.getItem("virtualId")).toBe("12345")
);

// And the user should be navigated to /discover-start
expect(mockNavigate).toHaveBeenCalledWith("/discover-start");
});

test("displays entered username", () => {
// Given the LoginPage is rendered
render(
<BrowserRouter>
<LoginPage />
</BrowserRouter>
);

// When the user enters a username
const usernameInput = screen.getByLabelText("Username");
fireEvent.change(usernameInput, { target: { value: "testuser" } });

// Then the username input should display the entered value
expect(usernameInput.value).toBe("testuser");
});

test("displays entered password", () => {
// Given the LoginPage is rendered
render(
<BrowserRouter>
<LoginPage />
</BrowserRouter>
);

// When the user enters a password
const passwordInput = screen.getByLabelText("Password");
fireEvent.change(passwordInput, { target: { value: "testpassword" } });

// Then the password input should display the entered value
expect(passwordInput.value).toBe("testpassword");
});

test("shows alert on API error", async () => {
// Given the LoginPage is rendered
mockAxios
.onPost(
`${process.env.REACT_APP_VIRTUAL_ID_HOST}/${config.URLS.GET_VIRTUAL_ID}?username=testuser`
)
.networkError();

render(
<BrowserRouter>
<LoginPage />
</BrowserRouter>
);

// When the user enters a valid username and password and clicks login
fireEvent.change(screen.getByLabelText("Username"), {
target: { value: "testuser" },
});
fireEvent.change(screen.getByLabelText("Password"), {
target: { value: "testpassword" },
});
fireEvent.click(screen.getByRole("button", { name: "Login" }));

// Then an alert should be shown indicating an API error
await waitFor(() =>
expect(window.alert).toHaveBeenCalledWith(
"An error occurred. Please try again later."
)
);
});

test("Set localStorage on form submission", async () => {
// Given the LoginPage is rendered and localStorage has initial values
mockAxios
.onPost(
`${process.env.REACT_APP_VIRTUAL_ID_HOST}/${config.URLS.GET_VIRTUAL_ID}?username=testuser`
)
.reply(200, { result: { virtualID: "12345" } });

localStorage.setItem("profileName", "oldProfileName");
localStorage.setItem("virtualId", "oldVirtualId");

render(
<BrowserRouter>
<LoginPage />
</BrowserRouter>
);

// When the user enters a valid username and password and clicks login
fireEvent.change(screen.getByLabelText("Username"), {
target: { value: "testuser" },
});
fireEvent.change(screen.getByLabelText("Password"), {
target: { value: "testpassword" },
});
fireEvent.click(screen.getByRole("button", { name: "Login" }));

// Then localStorage should be updated with the new values
await waitFor(() =>
expect(localStorage.getItem("profileName")).toBe("testuser")
);
await waitFor(() =>
expect(localStorage.getItem("virtualId")).toBe("12345")
);
});

test("renders form fields correctly", () => {
// Given the LoginPage is rendered
render(
<BrowserRouter>
<LoginPage />
</BrowserRouter>
);

// Then the username, password fields and login button should be in the document
expect(screen.getByLabelText("Username")).toBeInTheDocument();
expect(screen.getByLabelText("Password")).toBeInTheDocument();
expect(screen.getByRole("button", { name: "Login" })).toBeInTheDocument();
});
});