Skip to content

Commit

Permalink
Merge pull request #339 from openedx/aakbar/PROD-3163
Browse files Browse the repository at this point in the history
feat: add order history table
  • Loading branch information
Ali-D-Akbar authored Jun 20, 2023
2 parents b9a73c5 + 2e7f503 commit f397748
Show file tree
Hide file tree
Showing 11 changed files with 1,457 additions and 93 deletions.
1,074 changes: 992 additions & 82 deletions package-lock.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
"@edx/browserslist-config": "^1.1.0",
"@edx/frontend-build": "^12.4.15",
"@edx/reactifex": "^1.0.3",
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "10.3.0",
"@types/react-table": "^7.7.2",
"axios-mock-adapter": "^1.19.0",
Expand Down
6 changes: 6 additions & 0 deletions src/users/LearnerInformation.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import Licenses from './licenses/Licenses';
import EntitlementsAndEnrollmentsContainer from './EntitlementsAndEnrollmentsContainer';
import LearnerCredentials from './LearnerCredentials';
import LearnerRecords from './LearnerRecords';
import LearnerPurchases from './LearnerPurchases';

export default function LearnerInformation({
user, changeHandler,
Expand All @@ -31,6 +32,11 @@ export default function LearnerInformation({
<EntitlementsAndEnrollmentsContainer user={user.username} />
</Tab>

<Tab eventKey="learner-purchases" title="Learner Purchases">
<br />
<LearnerPurchases user={user.username} />
</Tab>

<Tab eventKey="sso" title="SSO/License Info">
<br />
<SingleSignOnRecords
Expand Down
45 changes: 35 additions & 10 deletions src/users/LearnerInformation.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ describe('Learners and Enrollments component', () => {
let wrapper;
const props = {
user: UserSummaryData.userData,
changeHandler: jest.fn(() => {}),
changeHandler: jest.fn(() => { }),
};

beforeEach(async () => {
Expand Down Expand Up @@ -57,9 +57,10 @@ describe('Learners and Enrollments component', () => {

expect(tabs.at(0).text()).toEqual('Account Information');
expect(tabs.at(1).text()).toEqual('Enrollments/Entitlements');
expect(tabs.at(2).text()).toEqual('SSO/License Info');
expect(tabs.at(3).text()).toEqual('Learner Credentials');
expect(tabs.at(4).text()).toEqual('Learner Records');
expect(tabs.at(2).text()).toEqual('Learner Purchases');
expect(tabs.at(3).text()).toEqual('SSO/License Info');
expect(tabs.at(4).text()).toEqual('Learner Credentials');
expect(tabs.at(5).text()).toEqual('Learner Records');
});

it('Account Information Tab', () => {
Expand All @@ -72,6 +73,7 @@ describe('Learners and Enrollments component', () => {
expect(tabs.at(2).html()).not.toEqual(expect.stringContaining('active'));
expect(tabs.at(3).html()).not.toEqual(expect.stringContaining('active'));
expect(tabs.at(4).html()).not.toEqual(expect.stringContaining('active'));
expect(tabs.at(5).html()).not.toEqual(expect.stringContaining('active'));

const accountInfo = wrapper.find('.tab-content div#learner-information-tabpane-account');
expect(accountInfo.html()).toEqual(expect.stringContaining('active'));
Expand All @@ -88,14 +90,15 @@ describe('Learners and Enrollments component', () => {
expect(tabs.at(2).html()).not.toEqual(expect.stringContaining('active'));
expect(tabs.at(3).html()).not.toEqual(expect.stringContaining('active'));
expect(tabs.at(4).html()).not.toEqual(expect.stringContaining('active'));
expect(tabs.at(5).html()).not.toEqual(expect.stringContaining('active'));

const enrollmentsEntitlements = wrapper.find('.tab-content div#learner-information-tabpane-enrollments-entitlements');
expect(enrollmentsEntitlements.html()).toEqual(expect.stringContaining('active'));
expect(enrollmentsEntitlements.html()).toEqual(expect.stringContaining('Entitlements (2)'));
expect(enrollmentsEntitlements.html()).toEqual(expect.stringContaining('Enrollments (2)'));
});

it('SSO Tab', () => {
it('Learner Purchases Tab', () => {
let tabs = wrapper.find('nav.nav-tabs a');

tabs.at(2).simulate('click');
Expand All @@ -105,6 +108,26 @@ describe('Learners and Enrollments component', () => {
expect(tabs.at(2).html()).toEqual(expect.stringContaining('active'));
expect(tabs.at(3).html()).not.toEqual(expect.stringContaining('active'));
expect(tabs.at(4).html()).not.toEqual(expect.stringContaining('active'));
expect(tabs.at(5).html()).not.toEqual(expect.stringContaining('active'));

const learnerPurchases = wrapper.find('.tab-content div#learner-information-tabpane-learner-purchases');
expect(learnerPurchases.html()).toEqual(expect.stringContaining('active'));
expect(learnerPurchases.html()).toEqual(
expect.stringContaining('Order History'),
);
});

it('SSO Tab', () => {
let tabs = wrapper.find('nav.nav-tabs a');

tabs.at(3).simulate('click');
tabs = wrapper.find('nav.nav-tabs a');
expect(tabs.at(0).html()).not.toEqual(expect.stringContaining('active'));
expect(tabs.at(1).html()).not.toEqual(expect.stringContaining('active'));
expect(tabs.at(2).html()).not.toEqual(expect.stringContaining('active'));
expect(tabs.at(3).html()).toEqual(expect.stringContaining('active'));
expect(tabs.at(4).html()).not.toEqual(expect.stringContaining('active'));
expect(tabs.at(5).html()).not.toEqual(expect.stringContaining('active'));

const ssoRecords = wrapper.find('.tab-content div#learner-information-tabpane-sso');
expect(ssoRecords.html()).toEqual(expect.stringContaining('active'));
Expand All @@ -119,13 +142,14 @@ describe('Learners and Enrollments component', () => {
it('Learner Credentials Tab', () => {
let tabs = wrapper.find('nav.nav-tabs a');

tabs.at(3).simulate('click');
tabs.at(4).simulate('click');
tabs = wrapper.find('nav.nav-tabs a');
expect(tabs.at(0).html()).not.toEqual(expect.stringContaining('active'));
expect(tabs.at(1).html()).not.toEqual(expect.stringContaining('active'));
expect(tabs.at(2).html()).not.toEqual(expect.stringContaining('active'));
expect(tabs.at(3).html()).toEqual(expect.stringContaining('active'));
expect(tabs.at(4).html()).not.toEqual(expect.stringContaining('active'));
expect(tabs.at(3).html()).not.toEqual(expect.stringContaining('active'));
expect(tabs.at(4).html()).toEqual(expect.stringContaining('active'));
expect(tabs.at(5).html()).not.toEqual(expect.stringContaining('active'));

const credentials = wrapper.find(
'.tab-content div#learner-information-tabpane-credentials',
Expand All @@ -139,13 +163,14 @@ describe('Learners and Enrollments component', () => {
it('Learner Records Tab', () => {
let tabs = wrapper.find('nav.nav-tabs a');

tabs.at(4).simulate('click');
tabs.at(5).simulate('click');
tabs = wrapper.find('nav.nav-tabs a');
expect(tabs.at(0).html()).not.toEqual(expect.stringContaining('active'));
expect(tabs.at(1).html()).not.toEqual(expect.stringContaining('active'));
expect(tabs.at(2).html()).not.toEqual(expect.stringContaining('active'));
expect(tabs.at(3).html()).not.toEqual(expect.stringContaining('active'));
expect(tabs.at(4).html()).toEqual(expect.stringContaining('active'));
expect(tabs.at(4).html()).not.toEqual(expect.stringContaining('active'));
expect(tabs.at(5).html()).toEqual(expect.stringContaining('active'));

const records = wrapper.find(
'.tab-content div#learner-information-tabpane-records',
Expand Down
19 changes: 19 additions & 0 deletions src/users/LearnerPurchases.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import React from 'react';
import PropTypes from 'prop-types';
import OrderHistory from './orderHistory/OrderHistory';

export default function LearnerPurchases({
user,
}) {
return (
<div id="learnerPurchasesContainer">
<OrderHistory
username={user}
/>
</div>
);
}

LearnerPurchases.propTypes = {
user: PropTypes.string.isRequired,
};
25 changes: 25 additions & 0 deletions src/users/LearnerPurchases.test.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import React from 'react';
import { render, queryByAttribute } from '@testing-library/react';
import '@testing-library/jest-dom';
import LearnerPurchases from './LearnerPurchases';
import UserMessagesProvider from '../userMessages/UserMessagesProvider';

const LearnerPurchasesWrapper = (props) => (
<UserMessagesProvider>
<LearnerPurchases {...props} />
</UserMessagesProvider>
);

describe('LearnerPurchases', () => {
it('renders the component with the provided user prop', () => {
const user = 'John Doe';
const getById = queryByAttribute.bind(null, 'id');
const document = render(<LearnerPurchasesWrapper user={user} />);
const { getByText } = document;

// Assert that the LearnerPurchasesContainer div is rendered
const container = getById(document.container, 'learnerPurchasesContainer');
expect(container).toBeInTheDocument();
expect(getByText('Order History (0)')).toBeInTheDocument();
});
});
19 changes: 19 additions & 0 deletions src/users/data/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -762,3 +762,22 @@ export async function getLearnerRecords(username) {
};
}
}

export async function getOrderHistory(username) {
try {
const { data } = await getAuthenticatedHttpClient().get(`${AppUrls.getOrderHistoryUrl()}/?username=${username}`);
return data.results;
} catch (error) {
return {
errors: [
{
code: null,
dismissible: true,
text: 'There was an error retrieving order history for the user',
type: 'danger',
topic: 'orderHistory',
},
],
};
}
}
55 changes: 55 additions & 0 deletions src/users/data/api.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ describe('API', () => {
const getEnterpriseCustomerUsersUrl = urls.getEnterpriseCustomerUsersUrl(testUsername);
const programRecordsUrl = urls.getLearnerRecordsUrl();
const retirementApiUrl = urls.userRetirementUrl();
const orderHistoryApiUrl = urls.getOrderHistoryUrl();

let mockAdapter;

Expand Down Expand Up @@ -1212,4 +1213,58 @@ describe('API', () => {
expect(response.errors[0].text).toEqual('Unable to connect to the service');
});
});

describe('getOrderHistory', () => {
it('should return order history data when successful', async () => {
const expectedData = {
results: [
{
status: 'completed',
number: '12345',
datePlaced: 'Jun 12, 2023 12:00 AM',
productTracking: 'tracking123',
lines: [
{
product: {
url: 'https://example.com/product1',
title: 'Product 1',
expires: '2023-12-31',
attributeValues: [
{ value: 'Type A' },
],
},
quantity: 1,
status: 'completed',
},
],
},
],
};

mockAdapter.onGet(`${orderHistoryApiUrl}/?username=${testUsername}`).reply(200, expectedData);

const result = await api.getOrderHistory(testUsername);

expect(result).toEqual(expectedData.results);
});

it('should return an empty array when an error occurs', async () => {
const expectedError = {
errors: [
{
code: null,
dismissible: true,
text: 'There was an error retrieving order history for the user',
type: 'danger',
topic: 'orderHistory',
},
],
};
mockAdapter.onGet(`${orderHistoryApiUrl}/?username=${testUsername}`).reply(() => throwError(404, ''));

const result = await api.getOrderHistory(testUsername);

expect(result).toEqual(expectedError);
});
});
});
4 changes: 3 additions & 1 deletion src/users/data/urls.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { getConfig } from '@edx/frontend-platform';
import { isEmail, isValidLMSUserID, isValidUsername } from '../../utils/index';

const { LMS_BASE_URL, CREDENTIALS_BASE_URL } = getConfig();
const { LMS_BASE_URL, CREDENTIALS_BASE_URL, ECOMMERCE_BASE_URL } = getConfig();

export const getEnrollmentsUrl = username => `${
LMS_BASE_URL
Expand Down Expand Up @@ -109,3 +109,5 @@ export const regenerateCertificateUrl = () => `${
export const getUserCredentialsUrl = () => `${CREDENTIALS_BASE_URL}/api/v2/credentials`;

export const getLearnerRecordsUrl = () => `${CREDENTIALS_BASE_URL}/records/api/v1/program_records`;

export const getOrderHistoryUrl = () => `${ECOMMERCE_BASE_URL}/api/v2/orders`;
Loading

0 comments on commit f397748

Please sign in to comment.