Skip to content

Commit

Permalink
tests that fail
Browse files Browse the repository at this point in the history
  • Loading branch information
devksingh4 committed Jan 27, 2025
1 parent 451c7a8 commit f371415
Show file tree
Hide file tree
Showing 2 changed files with 181 additions and 1 deletion.
180 changes: 180 additions & 0 deletions src/ui/pages/profile/ManageProfileComponent.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
import React from 'react';
import { render, screen, act } from '@testing-library/react';
import { MemoryRouter } from 'react-router-dom';
import { MantineProvider } from '@mantine/core';
import { notifications } from '@mantine/notifications';
import userEvent from '@testing-library/user-event';
import { vi } from 'vitest';
import { ManageProfileComponent } from './ManageProfileComponent';

describe('ManageProfileComponent tests', () => {
const renderComponent = async (
getProfile: () => Promise<any>,
setProfile: (data: any) => Promise<any>,
firstTime: boolean = false
) => {
await act(async () => {
render(
<MemoryRouter>
<MantineProvider withGlobalClasses withCssVariables forceColorScheme="light">
<ManageProfileComponent
getProfile={getProfile}
setProfile={setProfile}
firstTime={firstTime}
/>
</MantineProvider>
</MemoryRouter>
);
});
};

beforeEach(() => {
vi.clearAllMocks();
});

it('renders loading overlay when fetching profile', async () => {
const getProfile = vi.fn().mockResolvedValue(new Promise(() => {})); // Never resolves
const setProfile = vi.fn();

await renderComponent(getProfile, setProfile);

expect(screen.getByText(/Loading.../i)).toBeInTheDocument();

Check failure on line 41 in src/ui/pages/profile/ManageProfileComponent.test.tsx

View workflow job for this annotation

GitHub Actions / Run Unit Tests

pages/profile/ManageProfileComponent.test.tsx > ManageProfileComponent tests > renders loading overlay when fetching profile

TestingLibraryElementError: Unable to find an element with the text: /Loading.../i. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible. Ignored nodes: comments, script, style <body> <div> <div class="m_6e45937b mantine-LoadingOverlay-root" style="--lo-z-index: 400;" > <span class="m_b34414df m_e8eb006c mantine-LoadingOverlay-loader m_5ae2e3c mantine-Loader-root" /> <div class="m_df587f17 mantine-LoadingOverlay-overlay m_9814e45f mantine-Overlay-root mantine-dark-hidden" style="--overlay-bg: rgba(255, 255, 255, 0.75); --overlay-z-index: 200;" /> <div class="m_df587f17 mantine-LoadingOverlay-overlay m_9814e45f mantine-Overlay-root mantine-light-hidden" style="--overlay-bg: rgba(59, 59, 59, 0.75); --overlay-z-index: 200;" /> </div> </div> </body> ❯ Object.getElementError ../../node_modules/@testing-library/dom/dist/config.js:37:19 ❯ ../../node_modules/@testing-library/dom/dist/query-helpers.js:76:38 ❯ ../../node_modules/@testing-library/dom/dist/query-helpers.js:52:17 ❯ ../../node_modules/@testing-library/dom/dist/query-helpers.js:95:19 ❯ pages/profile/ManageProfileComponent.test.tsx:41:19
});

it('renders profile form after successfully fetching profile', async () => {
const getProfile = vi.fn().mockResolvedValue({
displayName: 'John Doe',
givenName: 'John',
surname: 'Doe',
mail: 'john.doe@example.com',
discordUsername: 'johndoe#1234',
});
const setProfile = vi.fn();

await renderComponent(getProfile, setProfile);

expect(screen.getByLabelText('Display Name')).toHaveValue('John Doe');

Check failure on line 56 in src/ui/pages/profile/ManageProfileComponent.test.tsx

View workflow job for this annotation

GitHub Actions / Run Unit Tests

pages/profile/ManageProfileComponent.test.tsx > ManageProfileComponent tests > renders profile form after successfully fetching profile

TestingLibraryElementError: Unable to find a label with the text of: Display Name Ignored nodes: comments, script, style <body> <div> <div class="" style="margin-inline: auto;" > <form> <div class="m_46b77525 mantine-InputWrapper-root mantine-TextInput-root" > <label class="m_8fdc1311 mantine-InputWrapper-label mantine-TextInput-label" data-required="true" for="mantine-pzr8ejg1k" id="mantine-pzr8ejg1k-label" > Display Name <span aria-hidden="true" class="m_78a94662 mantine-InputWrapper-required mantine-TextInput-required" > * </span> </label> <div class="m_6c018570 mantine-Input-wrapper mantine-TextInput-wrapper" data-variant="default" > <input aria-invalid="false" class="m_8fb7ebe7 mantine-Input-input mantine-TextInput-input" data-variant="default" id="mantine-pzr8ejg1k" placeholder="John Doe" required="" value="John Doe" /> </div> </div> <div class="m_46b77525 mantine-InputWrapper-root mantine-TextInput-root" > <label class="m_8fdc1311 mantine-InputWrapper-label mantine-TextInput-label" data-required="true" for="mantine-p2u6tcnej" id="mantine-p2u6tcnej-label" > First Name <span aria-hidden="true" class="m_78a94662 mantine-InputWrapper-required mantine-TextInput-required" > * </span> </label> <div class="m_6c018570 mantine-Input-wrapper mantine-TextInput-wrapper" data-variant="default" > <input aria-invalid="false" class="m_8fb7ebe7 mantine-Input-input mantine-TextInput-input" data-variant="default" id="mantine-p2u6tcnej" placeholder="John" required="" value="John" /> </div> </div> <div class="m_46b77525 mantine-InputWrapper-root mantine-TextInput-root" > <label class="m_8fdc1311 mantine-InputWrapper-label mantine-TextInput-label" data-required="true" for="mantine-gtwuz74xp" id="mantine-gtwuz74xp-label" > Last Name <span aria-hidden="true" class="m_78a94662 mantine-InputWrapper-required mantine-TextInput-required" > * </span> </label> <div class="m_6c018570 mantine-Input-wrapper mantine-TextInput-wrapper" data-variant="default" > <input aria-invalid="false" class="m_8fb7ebe7 mantine-Input-input mantine-TextInput-input" data-variant="default" id="mantine-gtwuz74xp" placeholder="Doe" required="" value="Doe" /> </div> </div> <div class="m_46b77525 mantine-InputWrapper-root mantine-TextInput-root" > <label class="m_8fdc1311 mantine-InputWrapper-label mantine-TextInput-label" data-required="true" for="mantine-pmy6tx6mr" id="mantine-pmy6tx6mr-label" > Email <span aria-hidden="true" class="m_78a94662 mantine-InputWrapper-required mantine-TextInput-required" > * </span> </label> <div class="m_6c018570 mantine-Input-wrapper mantine-TextInput-wrapper" data-disabled="true" data-variant="default" > <input aria-invali
expect(screen.getByLabelText('First Name')).toHaveValue('John');
expect(screen.getByLabelText('Last Name')).toHaveValue('Doe');
expect(screen.getByLabelText('Email')).toHaveValue('john.doe@example.com');
expect(screen.getByLabelText('Discord Username')).toHaveValue('johndoe#1234');
});

it('handles profile fetch failure gracefully', async () => {
const notificationsMock = vi.spyOn(notifications, 'show');
const getProfile = vi.fn().mockRejectedValue(new Error('Failed to fetch profile'));
const setProfile = vi.fn();

await renderComponent(getProfile, setProfile);

expect(screen.getByText(/Failed to load user profile/i)).toBeInTheDocument();

Check failure on line 70 in src/ui/pages/profile/ManageProfileComponent.test.tsx

View workflow job for this annotation

GitHub Actions / Run Unit Tests

pages/profile/ManageProfileComponent.test.tsx > ManageProfileComponent tests > handles profile fetch failure gracefully

TestingLibraryElementError: Unable to find an element with the text: /Failed to load user profile/i. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible. Ignored nodes: comments, script, style <body> <div> <div class="" style="margin-inline: auto;" > <form> <div class="m_46b77525 mantine-InputWrapper-root mantine-TextInput-root" > <label class="m_8fdc1311 mantine-InputWrapper-label mantine-TextInput-label" data-required="true" for="mantine-unu7l6vd8" id="mantine-unu7l6vd8-label" > Display Name <span aria-hidden="true" class="m_78a94662 mantine-InputWrapper-required mantine-TextInput-required" > * </span> </label> <div class="m_6c018570 mantine-Input-wrapper mantine-TextInput-wrapper" data-variant="default" > <input aria-invalid="false" class="m_8fb7ebe7 mantine-Input-input mantine-TextInput-input" data-variant="default" id="mantine-unu7l6vd8" required="" value="" /> </div> </div> <div class="m_46b77525 mantine-InputWrapper-root mantine-TextInput-root" > <label class="m_8fdc1311 mantine-InputWrapper-label mantine-TextInput-label" data-required="true" for="mantine-qe3jj0uv7" id="mantine-qe3jj0uv7-label" > First Name <span aria-hidden="true" class="m_78a94662 mantine-InputWrapper-required mantine-TextInput-required" > * </span> </label> <div class="m_6c018570 mantine-Input-wrapper mantine-TextInput-wrapper" data-variant="default" > <input aria-invalid="false" class="m_8fb7ebe7 mantine-Input-input mantine-TextInput-input" data-variant="default" id="mantine-qe3jj0uv7" required="" value="" /> </div> </div> <div class="m_46b77525 mantine-InputWrapper-root mantine-TextInput-root" > <label class="m_8fdc1311 mantine-InputWrapper-label mantine-TextInput-label" data-required="true" for="mantine-71haduiq8" id="mantine-71haduiq8-label" > Last Name <span aria-hidden="true" class="m_78a94662 mantine-InputWrapper-required mantine-TextInput-required" > * </span> </label> <div class="m_6c018570 mantine-Input-wrapper mantine-TextInput-wrapper" data-variant="default" > <input aria-invalid="false" class="m_8fb7ebe7 mantine-Input-input mantine-TextInput-input" data-variant="default" id="mantine-71haduiq8" required="" value="" /> </div> </div> <div class="m_46b77525 mantine-InputWrapper-root mantine-TextInput-root" > <label class="m_8fdc1311 mantine-InputWrapper-label mantine-TextInput-label" data-required="true" for="mantine-mnv0769sq" id="mantine-mnv0769sq-label" > Email <span aria-hidden="true" class="m_78a94662 mantine-InputWrapper-required mantine-TextInput-required" > * </span> </label> <div class="m_6c018570 mantine-Input-wrapper mantine-TextInput-wrapper" data-disabled="true" data-variant
expect(notificationsMock).toHaveBeenCalledWith(
expect.objectContaining({
message: 'Failed to load user profile',
color: 'red',
})
);

notificationsMock.mockRestore();
});

it('allows editing profile fields and saving changes', async () => {
const notificationsMock = vi.spyOn(notifications, 'show');
const getProfile = vi.fn().mockResolvedValue({
displayName: 'John Doe',
givenName: 'John',
surname: 'Doe',
mail: 'john.doe@example.com',
discordUsername: '',
});
const setProfile = vi.fn().mockResolvedValue({});

await renderComponent(getProfile, setProfile);

const user = userEvent.setup();

// Edit fields
await user.clear(screen.getByLabelText('Display Name'));

Check failure on line 97 in src/ui/pages/profile/ManageProfileComponent.test.tsx

View workflow job for this annotation

GitHub Actions / Run Unit Tests

pages/profile/ManageProfileComponent.test.tsx > ManageProfileComponent tests > allows editing profile fields and saving changes

TestingLibraryElementError: Unable to find a label with the text of: Display Name Ignored nodes: comments, script, style <body> <div> <div class="" style="margin-inline: auto;" > <form> <div class="m_46b77525 mantine-InputWrapper-root mantine-TextInput-root" > <label class="m_8fdc1311 mantine-InputWrapper-label mantine-TextInput-label" data-required="true" for="mantine-ozvwv8sr3" id="mantine-ozvwv8sr3-label" > Display Name <span aria-hidden="true" class="m_78a94662 mantine-InputWrapper-required mantine-TextInput-required" > * </span> </label> <div class="m_6c018570 mantine-Input-wrapper mantine-TextInput-wrapper" data-variant="default" > <input aria-invalid="false" class="m_8fb7ebe7 mantine-Input-input mantine-TextInput-input" data-variant="default" id="mantine-ozvwv8sr3" placeholder="John Doe" required="" value="John Doe" /> </div> </div> <div class="m_46b77525 mantine-InputWrapper-root mantine-TextInput-root" > <label class="m_8fdc1311 mantine-InputWrapper-label mantine-TextInput-label" data-required="true" for="mantine-xubeafq75" id="mantine-xubeafq75-label" > First Name <span aria-hidden="true" class="m_78a94662 mantine-InputWrapper-required mantine-TextInput-required" > * </span> </label> <div class="m_6c018570 mantine-Input-wrapper mantine-TextInput-wrapper" data-variant="default" > <input aria-invalid="false" class="m_8fb7ebe7 mantine-Input-input mantine-TextInput-input" data-variant="default" id="mantine-xubeafq75" placeholder="John" required="" value="John" /> </div> </div> <div class="m_46b77525 mantine-InputWrapper-root mantine-TextInput-root" > <label class="m_8fdc1311 mantine-InputWrapper-label mantine-TextInput-label" data-required="true" for="mantine-imin9or86" id="mantine-imin9or86-label" > Last Name <span aria-hidden="true" class="m_78a94662 mantine-InputWrapper-required mantine-TextInput-required" > * </span> </label> <div class="m_6c018570 mantine-Input-wrapper mantine-TextInput-wrapper" data-variant="default" > <input aria-invalid="false" class="m_8fb7ebe7 mantine-Input-input mantine-TextInput-input" data-variant="default" id="mantine-imin9or86" placeholder="Doe" required="" value="Doe" /> </div> </div> <div class="m_46b77525 mantine-InputWrapper-root mantine-TextInput-root" > <label class="m_8fdc1311 mantine-InputWrapper-label mantine-TextInput-label" data-required="true" for="mantine-7rai3nxa4" id="mantine-7rai3nxa4-label" > Email <span aria-hidden="true" class="m_78a94662 mantine-InputWrapper-required mantine-TextInput-required" > * </span> </label> <div class="m_6c018570 mantine-Input-wrapper mantine-TextInput-wrapper" data-disabled="true" data-variant="default" > <input aria-invali
await user.type(screen.getByLabelText('Display Name'), 'Jane Doe');
await user.type(screen.getByLabelText('Discord Username'), 'janedoe#5678');

// Save changes
const saveButton = screen.getByRole('button', { name: 'Save' });
await user.click(saveButton);

expect(setProfile).toHaveBeenCalledWith({
displayName: 'Jane Doe',
givenName: 'John',
surname: 'Doe',
mail: 'john.doe@example.com',
discordUsername: 'janedoe#5678',
});

expect(notificationsMock).toHaveBeenCalledWith(
expect.objectContaining({
title: 'Profile updated successfully',
message: 'Changes may take some time to reflect.',
color: 'green',
})
);

notificationsMock.mockRestore();
});

it('shows first-time user alert when `firstTime` is true', async () => {
const getProfile = vi.fn().mockResolvedValue({
displayName: '',
givenName: '',
surname: '',
mail: 'new.user@example.com',
discordUsername: '',
});
const setProfile = vi.fn();

await renderComponent(getProfile, setProfile, true);

expect(
screen.getByText(
'Your profile is incomplete. Please provide us with the information below and click Save.'
)
).toBeInTheDocument();
});

it('handles profile update failure gracefully', async () => {
const notificationsMock = vi.spyOn(notifications, 'show');
const getProfile = vi.fn().mockResolvedValue({
displayName: 'John Doe',
givenName: 'John',
surname: 'Doe',
mail: 'john.doe@example.com',
discordUsername: '',
});
const setProfile = vi.fn().mockRejectedValue(new Error('Failed to update profile'));

await renderComponent(getProfile, setProfile);

const user = userEvent.setup();

// Attempt to save without any changes
const saveButton = screen.getByRole('button', { name: 'Save' });
await user.click(saveButton);

expect(notificationsMock).toHaveBeenCalledWith(
expect.objectContaining({
message: 'Failed to update profile',
color: 'red',
})
);

notificationsMock.mockRestore();
});

it('disables the save button when no profile data is loaded', async () => {
const getProfile = vi.fn().mockResolvedValue(null);
const setProfile = vi.fn();

await renderComponent(getProfile, setProfile);

expect(screen.getByRole('button', { name: 'Save' })).toBeDisabled();
});
});
2 changes: 1 addition & 1 deletion src/ui/pages/profile/ManageProfileComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ export const ManageProfileComponent: React.FC<ManageProfileComponentProps> = ({
/>

<Group mt="md">
<Button type="submit" loading={loading}>
<Button type="submit" loading={loading} disabled={loading || !userProfile}>
Save
</Button>
</Group>
Expand Down

0 comments on commit f371415

Please sign in to comment.