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

Fix user profile buttons layout and added form validation #1064

Merged
merged 7 commits into from
Nov 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions src/components/LeftDrawer/LeftDrawer.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import 'jest-localstorage-mock';
import { I18nextProvider } from 'react-i18next';
import { BrowserRouter } from 'react-router-dom';

import { toast } from 'react-toastify';
import i18nForTest from 'utils/i18nForTest';
import type { InterfaceLeftDrawerProps } from './LeftDrawer';
import LeftDrawer from './LeftDrawer';
Expand Down Expand Up @@ -89,7 +88,6 @@ describe('Testing Left Drawer component for SUPERADMIN', () => {

// Coming soon
userEvent.click(screen.getByTestId(/profileBtn/i));
expect(toast.success).toHaveBeenCalledWith('Profile page coming soon!');

// Send to roles screen
userEvent.click(rolesBtn);
Expand Down Expand Up @@ -234,7 +232,6 @@ describe('Testing Left Drawer component for ADMIN', () => {

// Coming soon
userEvent.click(screen.getByTestId(/profileBtn/i));
expect(toast.success).toHaveBeenCalledWith('Profile page coming soon!');

// Send to roles screen
userEvent.click(orgsBtn);
Expand Down
5 changes: 2 additions & 3 deletions src/components/LeftDrawer/LeftDrawer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import React from 'react';
import Button from 'react-bootstrap/Button';
import { useTranslation } from 'react-i18next';
import { useHistory } from 'react-router-dom';
import { toast } from 'react-toastify';
import { ReactComponent as AngleRightIcon } from 'assets/svgs/angleRight.svg';
import { ReactComponent as LogoutIcon } from 'assets/svgs/logout.svg';
import { ReactComponent as OrganizationsIcon } from 'assets/svgs/organizations.svg';
Expand All @@ -28,7 +27,7 @@ const leftDrawer = ({
const firstName = localStorage.getItem('FirstName');
const lastName = localStorage.getItem('LastName');
const userImage = localStorage.getItem('UserImage');

const userId = localStorage.getItem('id');
const history = useHistory();

const logout = (): void => {
Expand Down Expand Up @@ -135,7 +134,7 @@ const leftDrawer = ({
className={styles.profileContainer}
data-testid="profileBtn"
onClick={(): void => {
toast.success('Profile page coming soon!');
history.push(`/member/id=${userId}`);
}}
>
<div className={styles.imageContainer}>
Expand Down
2 changes: 0 additions & 2 deletions src/components/LeftDrawerEvent/LeftDrawerEvent.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import userEvent from '@testing-library/user-event';
import 'jest-localstorage-mock';
import { I18nextProvider } from 'react-i18next';
import { BrowserRouter } from 'react-router-dom';
import { toast } from 'react-toastify';
import i18nForTest from 'utils/i18nForTest';
import LeftDrawerEvent, {
type InterfaceLeftDrawerProps,
Expand Down Expand Up @@ -138,7 +137,6 @@ describe('Testing Left Drawer component for the Event Dashboard', () => {
expect(props.setShowAddEventProjectModal).toHaveBeenCalled();

fireEvent.click(queryByTestId(/profileBtn/i) as HTMLElement);
expect(toast.success).toHaveBeenCalledWith('Profile page coming soon!');
});

test('Testing Drawer when hideDrawer is null', () => {
Expand Down
4 changes: 2 additions & 2 deletions src/components/LeftDrawerEvent/LeftDrawerEvent.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import React from 'react';
import Button from 'react-bootstrap/Button';
import { useHistory } from 'react-router-dom';
import { toast } from 'react-toastify';
import { ReactComponent as AngleRightIcon } from 'assets/svgs/angleRight.svg';
import { ReactComponent as LogoutIcon } from 'assets/svgs/logout.svg';
import { ReactComponent as TalawaLogo } from 'assets/svgs/talawa.svg';
Expand Down Expand Up @@ -35,6 +34,7 @@ const leftDrawerEvent = ({
const firstName = localStorage.getItem('FirstName');
const lastName = localStorage.getItem('LastName');
const userImage = localStorage.getItem('UserImage');
const userId = localStorage.getItem('id');

const history = useHistory();
const logout = (): void => {
Expand Down Expand Up @@ -152,7 +152,7 @@ const leftDrawerEvent = ({
className={styles.profileContainer}
data-testid="profileBtn"
onClick={(): void => {
toast.success('Profile page coming soon!');
history.push(`/member/id=${userId}`);
}}
>
<div className={styles.imageContainer}>
Expand Down
2 changes: 0 additions & 2 deletions src/components/LeftDrawerOrg/LeftDrawerOrg.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import 'jest-localstorage-mock';
import { I18nextProvider } from 'react-i18next';
import { BrowserRouter } from 'react-router-dom';

import { toast } from 'react-toastify';
import i18nForTest from 'utils/i18nForTest';
import type { InterfaceLeftDrawerProps } from './LeftDrawerOrg';
import LeftDrawerOrg from './LeftDrawerOrg';
Expand Down Expand Up @@ -267,7 +266,6 @@ describe('Testing Left Drawer component for SUPERADMIN', () => {
await wait();
expect(screen.getByTestId(/orgBtn/i)).toBeInTheDocument();
userEvent.click(screen.getByTestId(/profileBtn/i));
expect(toast.success).toHaveBeenCalledWith('Profile page coming soon!');
});

test('Testing Menu Buttons', async () => {
Expand Down
5 changes: 2 additions & 3 deletions src/components/LeftDrawerOrg/LeftDrawerOrg.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import React, { useEffect, useState } from 'react';
import Button from 'react-bootstrap/Button';
import { useTranslation } from 'react-i18next';
import { useHistory } from 'react-router-dom';
import { toast } from 'react-toastify';
import type { TargetsType } from 'state/reducers/routesReducer';
import type { InterfaceQueryOrganizationsListObject } from 'utils/interfaces';
import { ReactComponent as AngleRightIcon } from 'assets/svgs/angleRight.svg';
Expand Down Expand Up @@ -49,7 +48,7 @@ const leftDrawerOrg = ({
const firstName = localStorage.getItem('FirstName');
const lastName = localStorage.getItem('LastName');
const userImage = localStorage.getItem('UserImage');

const userId = localStorage.getItem('id');
const history = useHistory();

// Set organization data
Expand Down Expand Up @@ -184,7 +183,7 @@ const leftDrawerOrg = ({
className={styles.profileContainer}
data-testid="profileBtn"
onClick={(): void => {
toast.success('Profile page coming soon!');
history.push(`/member/id=${userId}`);
}}
>
<div className={styles.imageContainer}>
Expand Down
28 changes: 26 additions & 2 deletions src/components/UserUpdate/UserUpdate.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@ import { act, render, screen } from '@testing-library/react';
import { MockedProvider } from '@apollo/react-testing';
import userEvent from '@testing-library/user-event';
import { I18nextProvider } from 'react-i18next';

import { BrowserRouter as Router } from 'react-router-dom';
import UserUpdate from './UserUpdate';
import { UPDATE_USER_MUTATION } from 'GraphQl/Mutations/mutations';
import i18nForTest from 'utils/i18nForTest';
import { USER_DETAILS } from 'GraphQl/Queries/Queries';
import { StaticMockLink } from 'utils/StaticMockLink';
import { toast } from 'react-toastify';

const MOCKS = [
{
Expand Down Expand Up @@ -95,7 +96,9 @@ describe('Testing User Update', () => {
render(
<MockedProvider addTypename={false} link={link}>
<I18nextProvider i18n={i18nForTest}>
<UserUpdate {...props} />
<Router>
<UserUpdate {...props} />
</Router>
</I18nextProvider>
</MockedProvider>
);
Expand Down Expand Up @@ -131,4 +134,25 @@ describe('Testing User Update', () => {
expect(screen.getByPlaceholderText(/Email/i)).toBeInTheDocument();
expect(screen.getByText(/Display Image/i)).toBeInTheDocument();
});
test('should display warnings for blank form submission', async () => {
jest.spyOn(toast, 'warning');

render(
<MockedProvider addTypename={false} link={link}>
<I18nextProvider i18n={i18nForTest}>
<Router>
<UserUpdate {...props} />
</Router>
</I18nextProvider>
</MockedProvider>
);

await wait();

userEvent.click(screen.getByText(/Save Changes/i));

expect(toast.warning).toHaveBeenCalledWith('First Name cannot be blank!');
expect(toast.warning).toHaveBeenCalledWith('Last Name cannot be blank!');
expect(toast.warning).toHaveBeenCalledWith('Email cannot be blank!');
});
});
32 changes: 26 additions & 6 deletions src/components/UserUpdate/UserUpdate.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import Button from 'react-bootstrap/Button';
import styles from './UserUpdate.module.css';
import convertToBase64 from 'utils/convertToBase64';
import { USER_DETAILS } from 'GraphQl/Queries/Queries';
import { useLocation } from 'react-router-dom';

import { languages } from 'utils/languages';
import { toast } from 'react-toastify';
Expand All @@ -21,7 +22,8 @@ interface InterfaceUserUpdateProps {
const UserUpdate: React.FC<InterfaceUserUpdateProps> = ({
id,
}): JSX.Element => {
const currentUrl = localStorage.getItem('id');
const location = useLocation<InterfaceUserUpdateProps>();
const currentUrl = location.state?.id || localStorage.getItem('id') || id;
const { t } = useTranslation('translation', {
keyPrefix: 'userUpdate',
});
Expand All @@ -41,7 +43,7 @@ const UserUpdate: React.FC<InterfaceUserUpdateProps> = ({
loading: loading,
error: error,
} = useQuery(USER_DETAILS, {
variables: { id: localStorage.getItem('id') ?? id }, // For testing we are sending the id as a prop
variables: { id: currentUrl }, // For testing we are sending the id as a prop
});
React.useEffect(() => {
if (data) {
Expand All @@ -65,13 +67,31 @@ const UserUpdate: React.FC<InterfaceUserUpdateProps> = ({

const loginLink = async (): Promise<void> => {
try {
const firstName = formState.firstName;
const lastName = formState.lastName;
const email = formState.email;
const file = formState.file;
let toSubmit = true;
if (firstName.trim().length == 0 || !firstName) {
toast.warning('First Name cannot be blank!');
toSubmit = false;
}
if (lastName.trim().length == 0 || !lastName) {
toast.warning('Last Name cannot be blank!');
toSubmit = false;
}
if (email.trim().length == 0 || !email) {
toast.warning('Email cannot be blank!');
toSubmit = false;
}
if (!toSubmit) return;
const { data } = await updateUser({
variables: {
//Currently on these fields are supported by the api
firstName: formState.firstName,
lastName: formState.lastName,
email: formState.email,
file: formState.file,
firstName,
lastName,
email,
file,
},
});
/* istanbul ignore next */
Expand Down
19 changes: 14 additions & 5 deletions src/screens/MemberDetail/MemberDetail.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,16 @@
justify-content: space-between;
}

.flexclm {
display: flex;
flex-direction: column;
}

.btngroup {
display: flex;
gap: 2rem;
margin-bottom: 2rem;
}
@media screen and (max-width: 1200px) {
.justifysp {
padding-left: 55px;
Expand Down Expand Up @@ -336,13 +346,12 @@
border-color: #31bb6b;
background-color: #31bb6b;
color: white;
padding-right: 10px;
padding-left: 10px;
justify-content: flex-end;
float: right;
text-align: right;
box-shadow: none;
height: 2.5rem;
width: max-content;
display: flex;
justify-content: center;
align-items: center;
}

.userImage {
Expand Down
44 changes: 39 additions & 5 deletions src/screens/MemberDetail/MemberDetail.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -159,8 +159,8 @@ describe('MemberDetail', () => {
expect(screen.getAllByText(/Last name/i)).toBeTruthy();
expect(screen.getAllByText(/Member of Organization/i)).toBeTruthy();
expect(screen.getAllByText(/Language/i)).toBeTruthy();
expect(screen.getAllByText(/Admin approved/i)).toBeTruthy();
expect(screen.getAllByText(/Plugin creation allowed/i)).toBeTruthy();
expect(screen.getByText(/Admin approved/i)).toBeInTheDocument();
expect(screen.getByText(/Plugin creation allowed/i)).toBeInTheDocument();
expect(screen.getAllByText(/Created on/i)).toBeTruthy();
expect(screen.getAllByText(/Admin for organizations/i)).toBeTruthy();
expect(screen.getAllByText(/Membership requests/i)).toBeTruthy();
Expand All @@ -172,6 +172,8 @@ describe('MemberDetail', () => {
expect(screen.getAllByText(/Role/i)).toHaveLength(2);
expect(screen.getAllByText(/Created/i)).toHaveLength(4);
expect(screen.getAllByText(/Joined/i)).toHaveLength(2);
expect(screen.getByTestId('stateBtn')).toBeInTheDocument();
userEvent.click(screen.getByTestId('stateBtn'));
});
test('prettyDate function should work properly', () => {
// If the date is provided
Expand Down Expand Up @@ -250,12 +252,10 @@ describe('MemberDetail', () => {
)
);
});

test('should call setState with 2 when button is clicked', async () => {
const props = {
id: 'rishav-jha-mech',
};

const { container } = render(
<MockedProvider addTypename={false} link={link1}>
<BrowserRouter>
Expand All @@ -270,6 +270,40 @@ describe('MemberDetail', () => {

expect(container.textContent).not.toBe('Loading data...');

waitFor(() => userEvent.click(screen.getByText(/edit/i)));
waitFor(() => userEvent.click(screen.getByText(/Edit Profile/i)));
});
test('should show Yes if plugin creation is allowed and admin approved', async () => {
const props = {
id: 'rishav-jha-mech',
};
render(
<MockedProvider addTypename={false} link={link1}>
<BrowserRouter>
<Provider store={store}>
<I18nextProvider i18n={i18nForTest}>
<MemberDetail {...props} />
</I18nextProvider>
</Provider>
</BrowserRouter>
</MockedProvider>
);
waitFor(() => expect(screen.getByText('Yes')).toHaveLength(2));
});
test('should show No if plugin creation is not allowed and not admin approved', async () => {
const props = {
id: 'rishav-jha-mech',
};
render(
<MockedProvider addTypename={false} link={link2}>
<BrowserRouter>
<Provider store={store}>
<I18nextProvider i18n={i18nForTest}>
<MemberDetail {...props} />
</I18nextProvider>
</Provider>
</BrowserRouter>
</MockedProvider>
);
waitFor(() => expect(screen.getAllByText('No')).toHaveLength(2));
});
});
Loading
Loading