Skip to content

Commit

Permalink
Merge pull request #144 from edx/aakbar/PROD-2393
Browse files Browse the repository at this point in the history
refactor: self contain user summary and move modals
  • Loading branch information
Ali-D-Akbar authored Sep 1, 2021
2 parents 7e2c068 + 7f6a2c5 commit f482f77
Show file tree
Hide file tree
Showing 10 changed files with 417 additions and 275 deletions.
153 changes: 17 additions & 136 deletions src/users/UserSummary.jsx
Original file line number Diff line number Diff line change
@@ -1,41 +1,22 @@
import React, { useState } from 'react';
import React from 'react';
import PropTypes from 'prop-types';
import { Modal, Button, Input } from '@edx/paragon';
import { postTogglePasswordStatus, postResetPassword } from './data/api';
import Table from '../Table';
import { formatDate } from '../utils';
import { getAccountActivationUrl } from './data/urls';
import IdentityVerificationStatus from './IdentityVerificationStatus';
import OnboardingStatus from './OnboardingStatus';
import SingleSignOnRecords from './SingleSignOnRecords';
import TogglePasswordStatus from './account-actions/TogglePasswordStatus';
import ResetPassword from './account-actions/ResetPassword';
import PasswordHistory from './account-actions/PasswordHistory';

export default function UserSummary({
userData,
changeHandler,
}) {
const [disableUserModalIsOpen, setDisableUserModalIsOpen] = useState(false);
const [disableHistoryModalIsOpen, setDisableHistoryModalIsOpen] = useState(false);
const [resetPasswordModalIsOpen, setResetPasswordModalIsOpen] = useState(false);
const [comment, setComment] = useState('');
const [userPasswordHistoryData, setUserPasswordHistoryData] = useState([]);
const userToggleVisible = true;
// TO-DO: Only expose "Disable/Enable User" for specific roles

const PASSWORD_STATUS = {
USABLE: 'Usable',
UNUSABLE: 'Unusable',
};

const togglePasswordStatus = () => {
postTogglePasswordStatus(userData.username, comment);
changeHandler();
};

const resetPassword = () => {
postResetPassword(userData.email);
changeHandler();
};

const userAccountData = [
{
dataName: 'Full Name',
Expand Down Expand Up @@ -86,36 +67,6 @@ export default function UserSummary({
},
];

const userPasswordHistoryColumns = [
{
label: 'Date',
key: 'created',
},
{
label: 'Comment',
key: 'comment',
},
{
label: 'Action',
key: 'disabled',
},
{
label: 'By',
key: 'createdBy',
},
];

const openHistoryModel = () => {
const tableData = userData.passwordStatus.passwordToggleHistory.map(result => ({
created: formatDate(result.created),
comment: result.comment,
disabled: result.disabled ? 'Disabled' : 'Enabled',
createdBy: result.createdBy,
}));
setUserPasswordHistoryData(tableData);
setDisableHistoryModalIsOpen(true);
};

if (!userData.isActive) {
let dataValue;
if (userData.activationKey !== null) {
Expand Down Expand Up @@ -144,29 +95,19 @@ export default function UserSummary({
columns={columns}
/>
{userToggleVisible && (
<div>
<Button
id="toggle-password"
variant={`${userData.passwordStatus.status === PASSWORD_STATUS.USABLE ? 'danger' : 'primary'}`}
onClick={() => setDisableUserModalIsOpen(true)}
>
{userData.passwordStatus.status === PASSWORD_STATUS.USABLE ? 'Disable User' : 'Enable User'}
</Button>
<Button
id="reset-password"
variant="btn btn-danger ml-1"
onClick={() => setResetPasswordModalIsOpen(true)}
>Reset Password
</Button>
{userData.passwordStatus.passwordToggleHistory.length > 0 && (
<Button
id="toggle-password-history"
variant="outline-primary ml-1"
onClick={() => openHistoryModel()}
>
Show History
</Button>
)}
<div className="row ml-2">
<TogglePasswordStatus
username={userData.username}
passwordStatus={userData.passwordStatus}
changeHandler={changeHandler}
/>
<ResetPassword
email={userData.email}
changeHandler={changeHandler}
/>
<PasswordHistory
passwordStatus={userData.passwordStatus}
/>
</div>
)}
</div>
Expand All @@ -178,66 +119,6 @@ export default function UserSummary({
<SingleSignOnRecords username={userData.username} />
</div>
</div>
<Modal
open={disableHistoryModalIsOpen}
onClose={() => setDisableHistoryModalIsOpen(false)}
title="Enable/Disable History"
id="password-history"
body={(
<Table
data={userPasswordHistoryData}
columns={userPasswordHistoryColumns}
/>
)}
/>
<Modal
open={disableUserModalIsOpen}
id="user-account-status-toggle"
buttons={[
<Button
variant="danger"
onClick={togglePasswordStatus}
>
Confirm
</Button>,
]}
onClose={() => setDisableUserModalIsOpen(false)}
title={`${userData.passwordStatus.status === PASSWORD_STATUS.USABLE ? 'Disable user confirmation' : 'Enable user confirmation'}`}
body={(
<div>
<label htmlFor="comment">Reason: </label>
<Input
name="comment"
type="text"
value={comment}
onChange={(event) => setComment(event.target.value)}
/>
</div>
)}
/>
<Modal
open={resetPasswordModalIsOpen}
id="user-account-reset-password"
buttons={[
<Button
variant="danger"
onClick={resetPassword}
>
Confirm
</Button>,
]}
onClose={() => setResetPasswordModalIsOpen(false)}
title="Reset Password"
body={(
<div>
{ /* eslint-disable-next-line jsx-a11y/label-has-associated-control */ }
<label>
We will send a message with password recovery instructions to this email address {userData.email}.
Do you wish to proceed?
</label>
</div>
)}
/>
</div>
</section>
);
Expand Down
138 changes: 0 additions & 138 deletions src/users/UserSummary.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -96,142 +96,4 @@ describe('User Summary Component Tests', () => {
expect(rowValue.text()).toEqual('N/A');
});
});

describe('Disable User Button', () => {
it('Disable User button for active user', () => {
const passwordActionButton = wrapper.find('#toggle-password').hostNodes();
expect(passwordActionButton.text()).toEqual('Disable User');
expect(passwordActionButton.disabled).toBeFalsy();
});

it('Disable User Modal', () => {
const mockApiCall = jest.spyOn(api, 'postTogglePasswordStatus').mockImplementation(() => {});
const passwordActionButton = wrapper.find('#toggle-password').hostNodes();
let disableDialogModal = wrapper.find('Modal#user-account-status-toggle');

expect(disableDialogModal.prop('open')).toEqual(false);
expect(passwordActionButton.text()).toEqual('Disable User');
expect(passwordActionButton.disabled).toBeFalsy();

passwordActionButton.simulate('click');
disableDialogModal = wrapper.find('Modal#user-account-status-toggle');

expect(disableDialogModal.prop('open')).toEqual(true);
expect(disableDialogModal.prop('title')).toEqual('Disable user confirmation');
disableDialogModal.find('input[name="comment"]').simulate('change', { target: { value: 'Disable Test User' } });
disableDialogModal.find('button.btn-danger').hostNodes().simulate('click');

expect(UserSummaryData.changeHandler).toHaveBeenCalled();
disableDialogModal.find('button.btn-link').simulate('click');
disableDialogModal = wrapper.find('Modal#user-account-status-toggle');
expect(disableDialogModal.prop('open')).toEqual(false);
mockApiCall.mockRestore();
});
});

describe('Enable User Button', () => {
beforeEach(() => {
const passwordStatusData = { ...UserSummaryData.userData.passwordStatus, status: 'Unusable' };
const userData = { ...UserSummaryData.userData, passwordStatus: passwordStatusData };
mountUserSummaryWrapper({ ...UserSummaryData, userData });
});

it('Enable User button for disabled user', () => {
const passwordActionButton = wrapper.find('#toggle-password').hostNodes();
expect(passwordActionButton.text()).toEqual('Enable User');
expect(passwordActionButton.disabled).toBeFalsy();
});

it('Enable User Modal', () => {
const mockApiCall = jest.spyOn(api, 'postTogglePasswordStatus').mockImplementation(() => {});
const passwordActionButton = wrapper.find('#toggle-password').hostNodes();
let enableUserModal = wrapper.find('Modal#user-account-status-toggle');

expect(enableUserModal.prop('open')).toEqual(false);
expect(passwordActionButton.text()).toEqual('Enable User');
expect(passwordActionButton.disabled).toBeFalsy();

passwordActionButton.simulate('click');
enableUserModal = wrapper.find('Modal#user-account-status-toggle');

expect(enableUserModal.prop('open')).toEqual(true);
expect(enableUserModal.prop('title')).toEqual('Enable user confirmation');
enableUserModal.find('input[name="comment"]').simulate('change', { target: { value: 'Enable Test User' } });
enableUserModal.find('button.btn-danger').hostNodes().simulate('click');

expect(UserSummaryData.changeHandler).toHaveBeenCalled();
mockApiCall.mockRestore();
});
});

describe('Reset Password Button', () => {
it('Reset Password button for a User', () => {
const passwordResetButton = wrapper.find('#reset-password').hostNodes();
expect(passwordResetButton.text()).toEqual('Reset Password');
});

it('Reset Password Modal', () => {
const mockApiCall = jest.spyOn(api, 'postResetPassword').mockImplementation(() => {});
const passwordResetButton = wrapper.find('#reset-password').hostNodes();
let resetPasswordModal = wrapper.find('Modal#user-account-reset-password');

expect(resetPasswordModal.prop('open')).toEqual(false);
expect(passwordResetButton.text()).toEqual('Reset Password');

passwordResetButton.simulate('click');
resetPasswordModal = wrapper.find('Modal#user-account-reset-password');

expect(resetPasswordModal.prop('open')).toEqual(true);
expect(resetPasswordModal.prop('title')).toEqual('Reset Password');
const confirmLabel = resetPasswordModal.find('label');
expect(confirmLabel.text()).toContain('Do you wish to proceed?');
resetPasswordModal.find('button.btn-danger').hostNodes().simulate('click');

expect(UserSummaryData.changeHandler).toHaveBeenCalled();
resetPasswordModal.find('button.btn-link').simulate('click');
resetPasswordModal = wrapper.find('Modal#user-account-reset-password');
expect(resetPasswordModal.prop('open')).toEqual(false);
mockApiCall.mockRestore();
});
});

describe('Password Toggle History', () => {
beforeEach(() => {
const passwordHistory = [
{
created: Date().toLocaleString(),
comment: 'Test Disabled',
disabled: false,
createdBy: 'staff',
},
{
created: Date().toLocaleString(),
comment: 'Test Enable',
disabled: true,
createdBy: 'staff',
},
];
const passwordStatusData = { ...UserSummaryData.userData.passwordStatus, passwordToggleHistory: passwordHistory };
const userData = { ...UserSummaryData.userData, passwordStatus: passwordStatusData };
mountUserSummaryWrapper({ ...UserSummaryData, userData });
});
it('Password History Modal', () => {
const passwordHistoryButton = wrapper.find('button#toggle-password-history');
let historyModal = wrapper.find('Modal#password-history');

expect(historyModal.prop('open')).toEqual(false);
expect(passwordHistoryButton.text()).toEqual('Show History');
expect(passwordHistoryButton.disabled).toBeFalsy();

passwordHistoryButton.simulate('click');
historyModal = wrapper.find('Modal#password-history');

expect(historyModal.prop('open')).toEqual(true);
expect(historyModal.find('table tbody tr')).toHaveLength(2);

historyModal.find('button.btn-link').simulate('click');
historyModal = wrapper.find('Modal#password-history');
expect(historyModal.prop('open')).toEqual(false);
});
});
});
Loading

0 comments on commit f482f77

Please sign in to comment.