Skip to content

Commit

Permalink
Merge branch 'master' into runtime-config
Browse files Browse the repository at this point in the history
  • Loading branch information
deborahgu authored Nov 21, 2023
2 parents 4b2d65c + 5ca1e9d commit d1bf6f9
Show file tree
Hide file tree
Showing 17 changed files with 288 additions and 77 deletions.
39 changes: 39 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,45 @@ Some guidelines for writing widgets:
* You can load data from the redux store, but should not add or modify fields in that structure.
* Network events should be managed in component hooks, though can use our `data/constants/requests:requestStates` for ease of tracking the request states.

## License

The code in this repository is licensed under the AGPLv3 unless otherwise
noted.

Please see `LICENSE <LICENSE>`_ for details.

## Getting Help

If you're having trouble, we have discussion forums at
https://discuss.openedx.org where you can connect with others in the community.

Our real-time conversations are on Slack. You can request a `Slack
invitation`_, then join our `community Slack workspace`_. Because this is a
frontend repository, the best place to discuss it would be in the `#wg-frontend
channel`_.

For anything non-trivial, the best path is to open an issue in this repository
with as many details about the issue you are facing as you can provide.

https://github.com/openedx/frontend-app-learner-dashboard/issues

For more information about these options, see the `Getting Help`_ page.

.. _Slack invitation: https://openedx.org/slack
.. _community Slack workspace: https://openedx.slack.com/
.. _#wg-frontend channel: https://openedx.slack.com/archives/C04BM6YC7A6
.. _Getting Help: https://openedx.org/community/connect

## Resources

* [Learner Home project info at the Open edX Wiki](https://openedx.atlassian.net/wiki/spaces/OEPM/pages/3575906333/Learner+Home)

## The Open edX Code of Conduct

All community members are expected to follow the `Open edX Code of Conduct`_.

.. _Open edX Code of Conduct: https://openedx.org/code-of-conduct/

## Reporting Security Issues

Please do not report security issues in public. Please email [email protected].
17 changes: 0 additions & 17 deletions src/components/EmailLink.jsx

This file was deleted.

16 changes: 0 additions & 16 deletions src/components/EmailLink.test.jsx

This file was deleted.

11 changes: 0 additions & 11 deletions src/components/__snapshots__/EmailLink.test.jsx.snap

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,14 @@ export const CertificateBanner = ({ cardId }) => {
const { formatMessage } = useIntl();
const formatDate = useFormatDate();

const emailLink = address => address && <MailtoLink to={address}>{address}</MailtoLink>;
const emailLink = address => <MailtoLink to={address}>{address}</MailtoLink>;

if (certificate.isRestricted) {
return (
<Banner variant="danger">
{formatMessage(messages.certRestricted, { supportEmail: emailLink(supportEmail) })}
{ supportEmail ? formatMessage(messages.certRestricted, { supportEmail: emailLink(supportEmail) }) : formatMessage(messages.certRestrictedNoEmail)}
{isVerified && ' '}
{isVerified && formatMessage(
messages.certRefundContactBilling,
{ billingEmail: emailLink(billingEmail) },
)}
{isVerified && (billingEmail ? formatMessage(messages.certRefundContactBilling, { billingEmail: emailLink(billingEmail) }) : formatMessage(messages.certRefundContactBillingNoEmail))}
</Banner>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,6 @@ jest.mock('components/Banner', () => 'Banner');

describe('CertificateBanner', () => {
const props = { cardId: 'cardId' };
reduxHooks.usePlatformSettingsData.mockReturnValue({
supportEmail: 'suport@email',
billingEmail: 'billing@email',
});
reduxHooks.useCardCourseRunData.mockReturnValue({
minPassingGrade: 0.8,
progressUrl: 'progressUrl',
Expand All @@ -42,16 +38,19 @@ describe('CertificateBanner', () => {
};
const defaultCourseRun = { isArchived: false };
const defaultGrade = { isPassing: false };
const defaultPlatformSettings = {};
const createWrapper = ({
certificate = {},
enrollment = {},
grade = {},
courseRun = {},
platformSettings = {},
}) => {
reduxHooks.useCardGradeData.mockReturnValueOnce({ ...defaultGrade, ...grade });
reduxHooks.useCardCertificateData.mockReturnValueOnce({ ...defaultCertificate, ...certificate });
reduxHooks.useCardEnrollmentData.mockReturnValueOnce({ ...defaultEnrollment, ...enrollment });
reduxHooks.useCardCourseRunData.mockReturnValueOnce({ ...defaultCourseRun, ...courseRun });
reduxHooks.usePlatformSettingsData.mockReturnValueOnce({ ...defaultPlatformSettings, ...platformSettings });
return shallow(<CertificateBanner {...props} />);
};
/** TODO: Update tests to validate snapshots **/
Expand All @@ -64,6 +63,28 @@ describe('CertificateBanner', () => {
});
expect(wrapper).toMatchSnapshot();
});
test('is restricted with support email', () => {
const wrapper = createWrapper({
certificate: {
isRestricted: true,
},
platformSettings: {
supportEmail: 'suport@email',
},
});
expect(wrapper).toMatchSnapshot();
});
test('is restricted with billing email', () => {
const wrapper = createWrapper({
certificate: {
isRestricted: true,
},
platformSettings: {
billingEmail: 'billing@email',
},
});
expect(wrapper).toMatchSnapshot();
});
test('is restricted and verified', () => {
const wrapper = createWrapper({
certificate: {
Expand All @@ -75,6 +96,49 @@ describe('CertificateBanner', () => {
});
expect(wrapper).toMatchSnapshot();
});
test('is restricted and verified with support email', () => {
const wrapper = createWrapper({
certificate: {
isRestricted: true,
},
enrollment: {
isVerified: true,
},
platformSettings: {
supportEmail: 'suport@email',
},
});
expect(wrapper).toMatchSnapshot();
});
test('is restricted and verified with billing email', () => {
const wrapper = createWrapper({
certificate: {
isRestricted: true,
},
enrollment: {
isVerified: true,
},
platformSettings: {
billingEmail: 'billing@email',
},
});
expect(wrapper).toMatchSnapshot();
});
test('is restricted and verified with support and billing email', () => {
const wrapper = createWrapper({
certificate: {
isRestricted: true,
},
enrollment: {
isVerified: true,
},
platformSettings: {
supportEmail: 'suport@email',
billingEmail: 'billing@email',
},
});
expect(wrapper).toMatchSnapshot();
});
test('is passing and is downloadable', () => {
const wrapper = createWrapper({
grade: { isPassing: true },
Expand Down Expand Up @@ -133,6 +197,10 @@ describe('CertificateBanner', () => {
certificate: {
isRestricted: true,
},
platformSettings: {
supportEmail: 'suport@email',
billingEmail: 'billing@email',
},
});
const bannerMessage = wrapper.find('format-message-function').map(el => el.prop('message').defaultMessage).join('\n');
expect(bannerMessage).toEqual(messages.certRestricted.defaultMessage);
Expand All @@ -146,6 +214,10 @@ describe('CertificateBanner', () => {
enrollment: {
isVerified: true,
},
platformSettings: {
supportEmail: 'suport@email',
billingEmail: 'billing@email',
},
});
const bannerMessage = wrapper.find('format-message-function').map(el => el.prop('message').defaultMessage).join('\n');
expect(bannerMessage).toContain(messages.certRestricted.defaultMessage);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,11 @@ exports[`CreditBanner component render with error state snapshot 1`] = `
}
values={
Object {
"supportEmailLink": <EmailLink
address="test-support-email"
/>,
"supportEmailLink": <MailtoLink
to="test-support-email"
>
test-support-email
</MailtoLink>,
}
}
/>
Expand All @@ -30,6 +32,21 @@ exports[`CreditBanner component render with error state snapshot 1`] = `
</Banner>
`;

exports[`CreditBanner component render with error state with no email snapshot 1`] = `
<Banner
variant="danger"
>
<p
className="credit-error-msg"
>
An error occurred with this transaction.
</p>
<ContentComponent
cardId="test-card-id"
/>
</Banner>
`;

exports[`CreditBanner component render with no error state snapshot 1`] = `
<Banner>
<ContentComponent
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import PropTypes from 'prop-types';
import { useIntl } from '@edx/frontend-platform/i18n';

import Banner from 'components/Banner';
import EmailLink from 'components/EmailLink';

import { MailtoLink } from '@edx/paragon';
import hooks from './hooks';
import messages from './messages';

Expand All @@ -15,13 +15,14 @@ export const CreditBanner = ({ cardId }) => {
if (hookData === null) {
return null;
}

const { ContentComponent, error, supportEmail } = hookData;
const supportEmailLink = (<EmailLink address={supportEmail} />);
const supportEmailLink = (<MailtoLink to={supportEmail}>{supportEmail}</MailtoLink>);
return (
<Banner {...(error && { variant: 'danger' })}>
{error && (
<p className="credit-error-msg">
{formatMessage(messages.error, { supportEmailLink })}
{supportEmail ? formatMessage(messages.error, { supportEmailLink }) : formatMessage(messages.errorNoEmail)}
</p>
)}
<ContentComponent cardId={cardId} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,13 @@ import React from 'react';
import { shallow } from 'enzyme';

import { formatMessage } from 'testUtils';

import EmailLink from 'components/EmailLink';
import { MailtoLink } from '@edx/paragon';

import hooks from './hooks';
import messages from './messages';
import CreditBanner from '.';

jest.mock('components/Banner', () => 'Banner');
jest.mock('components/EmailLink', () => 'EmailLink');

jest.mock('./hooks', () => ({
useCreditBannerData: jest.fn(),
Expand Down Expand Up @@ -54,14 +52,33 @@ describe('CreditBanner component', () => {
it('includes credit-error-msg with support email link', () => {
expect(el.find('.credit-error-msg').containsMatchingElement(
formatMessage(messages.error, {
supportEmailLink: (<EmailLink address={supportEmail} />),
supportEmailLink: (<MailtoLink to={supportEmail}>{supportEmail}</MailtoLink>),
}),
)).toEqual(true);
});
it('loads ContentComponent with cardId', () => {
expect(el.find('ContentComponent').props().cardId).toEqual(cardId);
});
});

describe('with error state with no email', () => {
beforeEach(() => {
hooks.useCreditBannerData.mockReturnValue({
error: true,
ContentComponent,
});
el = shallow(<CreditBanner cardId={cardId} />);
});
test('snapshot', () => {
expect(el).toMatchSnapshot();
});
it('includes credit-error-msg without support email link', () => {
expect(el.find('.credit-error-msg').containsMatchingElement(
formatMessage(messages.errorNoEmail),
)).toEqual(true);
});
});

describe('with no error state', () => {
beforeEach(() => {
hooks.useCreditBannerData.mockReturnValue({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ export const messages = StrictDict({
description: '',
defaultMessage: 'An error occurred with this transaction. For help, contact {supportEmailLink}.',
},
errorNoEmail: {
id: 'learner-dash.courseCard.banners.credit.errorNoEmail',
description: '',
defaultMessage: 'An error occurred with this transaction.',
},
});

export default messages;
Loading

0 comments on commit d1bf6f9

Please sign in to comment.