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

662/asterner profile tests #673

Merged
merged 12 commits into from
Aug 30, 2024
4 changes: 3 additions & 1 deletion src/pages/Profile.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,9 @@ const Profile = () => {
width: isSmallScreen ? '100%' : 'auto'
}}
>
<Typography sx={{ fontWeight: 'bold', fontSize: '18px' }}>My Profile</Typography>
<Typography variant="h1" sx={{ fontWeight: 'bold', fontSize: '18px' }}>
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This change makes this text into a proper heading without modifying the visual rendering

Copy link
Member

Choose a reason for hiding this comment

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

Looking over it, I'm not certain whether we need it to say "My Profile" at the top at all. The breadcrumb basically covers the same role already and we don't really apply this same concept to other pages (such as the Contacts page). But that's a different discussion

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Agreed. I attempted to make minimal changes to the page itself. This seems like something we can take a look at post MVP.

My Profile
</Typography>
{/* TODO: Determine whether this Box is needed */}
{/* <Box
sx={{
Expand Down
39 changes: 6 additions & 33 deletions test/components/Profile/ProfileComponent.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,37 +4,16 @@ import { cleanup, render, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { afterEach, describe, expect, it, vi } from 'vitest';
import { ProfileComponent } from '@components/Profile';
import { SignedInUserContext } from '@contexts';
import * as profileHelper from '../../../src/model-helpers/Profile';
import '@testing-library/jest-dom/extend-expect';
import createMatchMedia from '../../helpers/createMatchMedia';
import MockSignedInUserContext from '../../mocks/contexts/MockSignedInUserContext';

const profileInfo = {
profileName: null,
nickname: null,
profileImg: null
};

const mockSignedInUserContextMemo = {
updateProfileInfo: vi.fn(),
setProfileData: vi.fn(),
profileData: {
profileInfo: {
profileName: null,
nickname: null,
profileImg: null
}
},
fetchProfileInfo: vi.spyOn(profileHelper, 'fetchProfileInfo').mockResolvedValue({
profileData: profileInfo
})
};
const renderTest = () =>
const renderTest = (contactProfile = null) =>
render(
<BrowserRouter>
<SignedInUserContext.Provider value={mockSignedInUserContextMemo}>
<ProfileComponent contactProfile={null} />
</SignedInUserContext.Provider>
<MockSignedInUserContext>
<ProfileComponent contactProfile={contactProfile} />
</MockSignedInUserContext>
</BrowserRouter>
);

Expand Down Expand Up @@ -90,13 +69,7 @@ describe('ProfileComponent', () => {
});

it('renders no edit button for ProfileInputFields if contactProfile is not null', async () => {
const { queryByRole } = render(
<BrowserRouter>
<SignedInUserContext.Provider value={mockSignedInUserContextMemo}>
<ProfileComponent contactProfile={{}} />
</SignedInUserContext.Provider>
</BrowserRouter>
);
const { queryByRole } = renderTest({});
await waitFor(() => {
const editButton = queryByRole('button', { name: 'Edit' });

Expand Down
1 change: 1 addition & 0 deletions test/helpers/setup-vitest.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/* eslint-disable */
import { afterEach } from 'vitest';
import createMatchMedia from './createMatchMedia';
import '@testing-library/jest-dom';

process.env.VITE_SOLID_IDENTITY_PROVIDER = 'https://solidcommunity.net';
process.env.VITE_SUGGESTED_OIDC_OPTIONS =
Expand Down
32 changes: 32 additions & 0 deletions test/mocks/contexts/MockSignedInUserContext.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import React from 'react';
Copy link
Contributor

Choose a reason for hiding this comment

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

I see we're making mock contexts for the tests. I'm fine with this since it'll be useful in case multiple tests need the same context.

import { vi } from 'vitest';
import { SignedInUserContext } from '@contexts';
import * as profileHelper from '../../../src/model-helpers/Profile';

Copy link
Member

Choose a reason for hiding this comment

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

If we're going to keep this, we can leave a TODO note here to import it elsewhere. I'm pretty sure there are other tests that can make use of this but not as part of this PR

Copy link
Contributor Author

Choose a reason for hiding this comment

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

What would you like to add as a TODO?

I don't see the SignedInUserContext used in other tests (other than the tests for the context itself).

Copy link
Member

Choose a reason for hiding this comment

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

I'll put a pin in that idea. I want to think it over more

const profileInfo = {
profileName: null,
nickname: null,
profileImg: null
};

const mockSignedInUserContextMemo = {
updateProfileInfo: vi.fn(),
setProfileData: vi.fn(),
profileData: profileInfo,
fetchProfileInfo: vi.spyOn(profileHelper, 'fetchProfileInfo').mockResolvedValue({
profileData: profileInfo
})
};

/**
* @param {object} props - The properties of the component
* @param {React.JSX.Element} [props.children] - The child elements to be rendered inside the main content area
* @returns {React.JSX.Element} SignedInUserContext - an element which allows querying profile info
*/
const MockSignedInUserContext = ({ children }) => (
<SignedInUserContext.Provider value={mockSignedInUserContextMemo}>
{children}
</SignedInUserContext.Provider>
);

export default MockSignedInUserContext;
78 changes: 78 additions & 0 deletions test/pages/Profile.test.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import React from 'react';
import { BrowserRouter } from 'react-router-dom';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { act } from 'react-dom/test-utils';
import { render, screen, cleanup, waitForElementToBeRemoved } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { describe, expect, it, beforeEach, afterEach } from 'vitest';
import { Profile } from '@pages';
import MockSignedInUserContext from '../mocks/contexts/MockSignedInUserContext';

const queryClient = new QueryClient();

const renderProfile = () =>
render(
<QueryClientProvider client={queryClient}>
<MockSignedInUserContext>
<BrowserRouter>
<Profile />
</BrowserRouter>
</MockSignedInUserContext>
</QueryClientProvider>
);

describe('Profile Page', () => {
afterEach(() => {
cleanup();
});

beforeEach(() => {
act(() => {
renderProfile();
});
});

it('renders', async () => {
const heading = await screen.findByRole('heading', { name: 'My Profile' }, { timeout: 2000 });
expect(heading).toHaveAccessibleName('My Profile');
});

it('can show and hide the share documents modal', async () => {
const user = userEvent.setup();

const shareDocumentsButton = await screen.findByRole(
'button',
{ name: 'Share Documents' },
{ timeout: 2000 }
);
expect(shareDocumentsButton).toHaveAccessibleName('Share Documents');

// Open share document modal
user.click(shareDocumentsButton);
const shareHeading = await screen.findByRole('heading', { name: 'Share All Documents' });
expect(shareHeading).toBeVisible();

// Close share document modal
user.keyboard('{escape}');
await waitForElementToBeRemoved(shareHeading, { timeout: 5000 });
});

it('can show and hide the add document modal', async () => {
const user = userEvent.setup();

const addDocumentButton = await screen.findByRole(
'button',
{ name: 'Add Document' },
{ timeout: 2000 }
);
expect(addDocumentButton).toHaveAccessibleName('Add Document');

// Open add document modal
user.click(addDocumentButton);
const addHeading = await screen.findByRole('heading', { name: 'Upload Document' });

// close add document modal
user.keyboard('{escape}');
await waitForElementToBeRemoved(addHeading, { timeout: 5000 });
});
});
Loading