Skip to content

Commit

Permalink
Merge pull request #132 from edx/azan/PROD-2394
Browse files Browse the repository at this point in the history
refactor: self-contain license component
  • Loading branch information
azanbinzahid authored Jul 1, 2021
2 parents 3e034a7 + 743f88e commit 76fc6ec
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 35 deletions.
3 changes: 1 addition & 2 deletions src/users/UserPage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -167,8 +167,7 @@ export default function UserPage({ location }) {
changeHandler={handleUserSummaryChange}
/>
<Licenses
data={data.licenses.results}
status={data.licenses.status}
userEmail={data.user.email}
expanded={showLicenses}
/>
<Entitlements
Expand Down
3 changes: 0 additions & 3 deletions src/users/data/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,6 @@ export async function getAllUserData(userIdentifier) {
let enrollments = [];
let verificationStatus = null;
let ssoRecords = null;
let licenses = [];
let onboardingStatus = {};
try {
user = await getUser(userIdentifier);
Expand All @@ -242,7 +241,6 @@ export async function getAllUserData(userIdentifier) {
verificationStatus = await getUserVerificationStatus(user.username);
ssoRecords = await getSsoRecords(user.username);
user.passwordStatus = await getUserPasswordStatus(user.username);
licenses = await getLicense(user.email);
onboardingStatus = await getOnboardingStatus(enrollments, user.username);
}

Expand All @@ -253,7 +251,6 @@ export async function getAllUserData(userIdentifier) {
enrollments,
verificationStatus,
ssoRecords,
licenses,
onboardingStatus,
};
}
Expand Down
2 changes: 0 additions & 2 deletions src/users/data/api.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,6 @@ describe('API', () => {
mockAdapter.onGet(verificationDetailsApiUrl).reply(200, {});
mockAdapter.onGet(verificationStatusApiUrl).reply(200, {});
mockAdapter.onGet(passwordStatusApiUrl).reply(200, {});
mockAdapter.onPost(licensesApiUrl, { user_email: testEmail }).reply(200, []);
mockAdapter.onGet(onboardingStatusApiUrl).reply(200, onboardingDefaultResponse);

const response = await api.getAllUserData(testUsername);
Expand All @@ -365,7 +364,6 @@ describe('API', () => {
verificationStatus: { extraData: {} },
enrollments: [],
entitlements: { results: [], next: null },
licenses: { results: [], status: '' },
onboardingStatus: { ...onboardingDefaultResponse, onboardingStatus: 'No Paid Enrollment' },
});
});
Expand Down
3 changes: 1 addition & 2 deletions src/users/data/test/licenses.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const licensesData = {
data: [
results: [
{
status: 'unassigned',
assignedDate: null,
Expand All @@ -22,7 +22,6 @@ const licensesData = {
},
],
status: '',
expanded: true,
};

export default licensesData;
37 changes: 20 additions & 17 deletions src/users/licenses/Licenses.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,37 @@ import React, {
useMemo,
useState,
useCallback,
useEffect,
} from 'react';
import PropTypes from 'prop-types';
import { Collapsible, Badge } from '@edx/paragon';
import { camelCaseObject } from '@edx/frontend-platform';
import Table from '../../Table';
import { formatDate, sort } from '../../utils';
import { getLicense } from '../data/api';

export default function Licenses({
data, status, expanded,
userEmail, expanded,
}) {
const [sortColumn, setSortColumn] = useState('status');
const [sortDirection, setSortDirection] = useState('desc');
const [licenses, setLicensesData] = useState([]);
const [status, setStatus] = useState('Loading...');

useEffect(() => {
getLicense(userEmail).then((data) => {
const camelCaseData = camelCaseObject(data);
setLicensesData(camelCaseData.results);
setStatus(camelCaseData.status);
});
}, [userEmail]);

const responseStatus = useMemo(() => status, [status]);
const tableData = useMemo(() => {
if (data === null || data.length === 0) {
if (licenses === null || licenses.length === 0) {
return [];
}
return data.map(result => ({
return licenses.map(result => ({
status: {
value: result.status,
},
Expand Down Expand Up @@ -50,7 +64,7 @@ export default function Licenses({
value: result.activationLink,
},
}));
}, [data]);
}, [licenses]);

const setSort = useCallback((column) => {
if (sortColumn === column) {
Expand Down Expand Up @@ -122,22 +136,11 @@ export default function Licenses({
}

Licenses.propTypes = {
data: PropTypes.arrayOf(PropTypes.shape({
status: PropTypes.string,
assignedDate: PropTypes.string,
revokedDate: PropTypes.string,
activationDate: PropTypes.string,
subscriptionPlanTitle: PropTypes.string,
lastRemindDate: PropTypes.string,
activationLink: PropTypes.string,
subscriptionPlanExpirationDate: PropTypes.string,
})),
status: PropTypes.string,
userEmail: PropTypes.string,
expanded: PropTypes.bool,
};

Licenses.defaultProps = {
data: null,
status: '',
userEmail: null,
expanded: false,
};
42 changes: 33 additions & 9 deletions src/users/licenses/Licenses.test.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { mount } from 'enzyme';
import React from 'react';

import { waitForComponentToPaint } from '../../setupTest';
import * as api from '../data/api';
import Licenses from './Licenses';
import licensesData from '../data/test/licenses';
import UserMessagesProvider from '../../userMessages/UserMessagesProvider';
Expand All @@ -13,23 +14,46 @@ const LicensesPageWrapper = (props) => (

describe('User Licenses Listing', () => {
let wrapper;
const props = {
userEmail: '[email protected]',
expanded: true,
};

beforeEach(() => {
wrapper = mount(<LicensesPageWrapper {...licensesData} />);
afterEach(() => {
wrapper.unmount();
});

it('default collapsible with enrollment data', () => {
it('License Data Loading', async () => {
const licenseData = { ...licensesData, results: [], status: 'No record found' };
jest.spyOn(api, 'getLicense').mockImplementationOnce(() => Promise.resolve(licenseData));

wrapper = mount(<LicensesPageWrapper {...props} />);
const collapsible = wrapper.find('CollapsibleAdvanced').find('.collapsible-trigger').hostNodes();
expect(collapsible.text()).toEqual('Licenses (2)');
expect(collapsible.text()).toEqual('Licenses (0)Fetch Status: Loading...');
});

it('No License Data', () => {
const licenseData = { ...licensesData, data: [], status: 'No record found' };
wrapper = mount(<Licenses {...licenseData} />);
it('No License Data', async () => {
const licenseData = { ...licensesData, results: [], status: 'No record found' };
jest.spyOn(api, 'getLicense').mockImplementationOnce(() => Promise.resolve(licenseData));

wrapper = mount(<LicensesPageWrapper {...props} />);
await waitForComponentToPaint(wrapper);

const collapsible = wrapper.find('CollapsibleAdvanced').find('.collapsible-trigger').hostNodes();
expect(collapsible.text()).toEqual('Licenses (0)Fetch Status: No record found');
});

beforeEach(async () => {
jest.spyOn(api, 'getLicense').mockImplementationOnce(() => Promise.resolve(licensesData));
wrapper = mount(<LicensesPageWrapper {...props} />);
await waitForComponentToPaint(wrapper);
});

it('default collapsible with enrollment data', () => {
const collapsible = wrapper.find('CollapsibleAdvanced').find('.collapsible-trigger').hostNodes();
expect(collapsible.text()).toEqual('Licenses (2)');
});

it('Sorting Columns Button Enabled by default', () => {
const dataTable = wrapper.find('table.table');
const tableHeaders = dataTable.find('thead tr th');
Expand All @@ -56,6 +80,6 @@ describe('User Licenses Listing', () => {
it('Table Header Lenght', () => {
const dataTable = wrapper.find('table.table');
const tableHeaders = dataTable.find('thead tr th');
expect(tableHeaders).toHaveLength(Object.keys(licensesData.data[0]).length);
expect(tableHeaders).toHaveLength(Object.keys(licensesData.results[0]).length);
});
});

0 comments on commit 76fc6ec

Please sign in to comment.