-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
ryan/feat(ux: create input loading spinner) (#399)
https://github.com/user-attachments/assets/0577e7e5-846f-4b11-b139-f9ac67ad5109 I created the `LoadingSpinner` component which is designed to be used in buttons when sending data to the database. It has a `min-width/max-width` and `min-height/max-height` equal to tailwind's `w-7/w-9` and `h-7/h-9` so it fits within the smallest and largest size variants of the `Button` component. - [X] When a user clicks a submit button, the text should be replaced by a spinner - [X] When a user clicks a submit button, the button should be disabled from being clicked again Closes #91
- Loading branch information
Showing
5 changed files
with
192 additions
and
96 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,17 @@ | ||
import React from 'react'; | ||
import { render, screen, fireEvent, waitFor } from '@testing-library/react'; | ||
import { act } from 'react-dom/test-utils'; | ||
import { fireEvent, render, screen, waitFor } from '@testing-library/react'; | ||
import Login from './page'; | ||
import React, { useState as useStateMock } from 'react'; | ||
|
||
const getUser = jest.fn(); | ||
const mockLogin = jest.fn(); | ||
const mockPush = jest.fn(); | ||
const getUser = jest.fn(); | ||
const setIsLoading = jest.fn(); | ||
|
||
jest.mock('react', () => ({ | ||
...jest.requireActual('react'), | ||
useState: jest.fn(), | ||
})); | ||
|
||
let continueButton: HTMLElement, | ||
emailInput: HTMLInputElement, | ||
|
@@ -33,44 +40,47 @@ jest.mock('../../../context/AuthContextProvider', () => ({ | |
})); | ||
|
||
describe('Login', () => { | ||
const setIsLoading = jest.fn(); | ||
beforeEach(() => { | ||
jest.clearAllMocks(); | ||
jest | ||
.spyOn(React, 'useState') | ||
.mockImplementation(() => [false, setIsLoading]); | ||
|
||
render(<Login />); | ||
|
||
continueButton = screen.getByTestId('continue-button'); | ||
emailInput = screen.getByTestId('email'); | ||
passwordInput = screen.getByTestId('password'); | ||
continueButton = screen.getByTestId('continue-button'); | ||
}); | ||
test('should render the login page', () => { | ||
it('should render the login page', () => { | ||
expect(continueButton).toBeInTheDocument(); | ||
expect(emailInput).toBeInTheDocument(); | ||
expect(passwordInput).toBeInTheDocument(); | ||
expect(continueButton).toBeInTheDocument(); | ||
}); | ||
|
||
test('should update email state when input value changes', () => { | ||
fireEvent.change(emailInput, { target: { value: '[email protected]' } }); | ||
expect(emailInput).toHaveValue('[email protected]'); | ||
}); | ||
it('should update email and password fields and submit form', async () => { | ||
const form = screen.getByTestId('login-form'); | ||
|
||
test('should update password state when input value changes', () => { | ||
fireEvent.change(passwordInput, { target: { value: 'password123' } }); | ||
expect(passwordInput).toHaveValue('password123'); | ||
}); | ||
await act(async () => { | ||
fireEvent.change(emailInput, { target: { value: '[email protected]' } }); | ||
fireEvent.change(passwordInput, { target: { value: 'password123' } }); | ||
}); | ||
|
||
test('should call loginAccount function with email and password when continue button is clicked', async () => { | ||
fireEvent.change(emailInput, { target: { value: '[email protected]' } }); | ||
fireEvent.change(passwordInput, { target: { value: 'password123' } }); | ||
fireEvent.click(continueButton); | ||
await act(async () => { | ||
fireEvent.submit(form); | ||
}); | ||
|
||
await waitFor(() => { | ||
expect(mockLogin).toHaveBeenCalledTimes(1); | ||
expect(mockLogin).toHaveBeenCalledWith({ | ||
email: '[email protected]', | ||
password: 'password123', | ||
}); | ||
}); | ||
}); | ||
|
||
test('redirects to /weeklyPicks when the button is clicked', () => { | ||
it('redirects to /weeklyPicks when the button is clicked', () => { | ||
mockUseAuthContext.isSignedIn = true; | ||
|
||
render(<Login />); | ||
|
@@ -79,11 +89,44 @@ describe('Login', () => { | |
mockUseAuthContext.isSignedIn = false; | ||
}); | ||
|
||
test('redirects to /league/all when user navigates to /login', async () => { | ||
it('redirects to /league/all when user navigates to /login', async () => { | ||
mockUseAuthContext.isSignedIn = true; | ||
|
||
act(() => { | ||
render(<Login />); | ||
}); | ||
|
||
await waitFor(() => { | ||
expect(mockPush).toHaveBeenCalledWith('/league/all'); | ||
}); | ||
|
||
mockUseAuthContext.isSignedIn = false; | ||
}); | ||
}); | ||
|
||
describe('Login loading spinner', () => { | ||
it('should show the loading spinner', async () => { | ||
(useStateMock as jest.Mock).mockImplementation((init: boolean) => [ | ||
true, | ||
setIsLoading, | ||
]); | ||
|
||
render(<Login />); | ||
|
||
expect(mockPush).toHaveBeenCalledWith('/league/all'); | ||
await waitFor(() => { | ||
expect(screen.queryByTestId('loading-spinner')).toBeInTheDocument(); | ||
}); | ||
}); | ||
it('should not show the loading spinner', async () => { | ||
(useStateMock as jest.Mock).mockImplementation((init: boolean) => [ | ||
false, | ||
setIsLoading, | ||
]); | ||
|
||
render(<Login />); | ||
|
||
await waitFor(() => { | ||
expect(screen.queryByTestId('loading-spinner')).not.toBeInTheDocument(); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.