diff --git a/src/components/EmailLink.jsx b/src/components/EmailLink.jsx deleted file mode 100644 index d57ec677..00000000 --- a/src/components/EmailLink.jsx +++ /dev/null @@ -1,17 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; - -import { MailtoLink } from '@edx/paragon'; - -export const EmailLink = ({ address }) => { - if (!address) { - return null; - } - return ( - {address} - ); -}; -EmailLink.defaultProps = { address: null }; -EmailLink.propTypes = { address: PropTypes.string }; - -export default EmailLink; diff --git a/src/components/EmailLink.test.jsx b/src/components/EmailLink.test.jsx deleted file mode 100644 index 2e1ab16e..00000000 --- a/src/components/EmailLink.test.jsx +++ /dev/null @@ -1,16 +0,0 @@ -import { shallow } from 'enzyme'; - -import EmailLink from './EmailLink'; - -describe('EmailLink', () => { - it('renders null when no address is provided', () => { - const wrapper = shallow(); - expect(wrapper).toMatchSnapshot(); - expect(wrapper.isEmptyRender()).toEqual(true); - }); - it('renders a MailtoLink when an address is provided', () => { - const wrapper = shallow(); - expect(wrapper.find('MailtoLink').length).toEqual(1); - expect(wrapper).toMatchSnapshot(); - }); -}); diff --git a/src/components/__snapshots__/EmailLink.test.jsx.snap b/src/components/__snapshots__/EmailLink.test.jsx.snap deleted file mode 100644 index 3515e1d2..00000000 --- a/src/components/__snapshots__/EmailLink.test.jsx.snap +++ /dev/null @@ -1,11 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`EmailLink renders a MailtoLink when an address is provided 1`] = ` - - test@email.com - -`; - -exports[`EmailLink renders null when no address is provided 1`] = `""`; diff --git a/src/containers/CourseCard/components/CourseCardBanners/CertificateBanner.jsx b/src/containers/CourseCard/components/CourseCardBanners/CertificateBanner.jsx index 1bae25fb..70083395 100644 --- a/src/containers/CourseCard/components/CourseCardBanners/CertificateBanner.jsx +++ b/src/containers/CourseCard/components/CourseCardBanners/CertificateBanner.jsx @@ -26,17 +26,14 @@ export const CertificateBanner = ({ cardId }) => { const { formatMessage } = useIntl(); const formatDate = useFormatDate(); - const emailLink = address => address && {address}; + const emailLink = address => {address}; if (certificate.isRestricted) { return ( - {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))} ); } diff --git a/src/containers/CourseCard/components/CourseCardBanners/CertificateBanner.test.jsx b/src/containers/CourseCard/components/CourseCardBanners/CertificateBanner.test.jsx index cf8c20d6..68b8afcc 100644 --- a/src/containers/CourseCard/components/CourseCardBanners/CertificateBanner.test.jsx +++ b/src/containers/CourseCard/components/CourseCardBanners/CertificateBanner.test.jsx @@ -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', @@ -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(); }; /** TODO: Update tests to validate snapshots **/ @@ -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: { @@ -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 }, @@ -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); @@ -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); diff --git a/src/containers/CourseCard/components/CourseCardBanners/CreditBanner/__snapshots__/index.test.jsx.snap b/src/containers/CourseCard/components/CourseCardBanners/CreditBanner/__snapshots__/index.test.jsx.snap index 4096091a..96b1a629 100644 --- a/src/containers/CourseCard/components/CourseCardBanners/CreditBanner/__snapshots__/index.test.jsx.snap +++ b/src/containers/CourseCard/components/CourseCardBanners/CreditBanner/__snapshots__/index.test.jsx.snap @@ -17,9 +17,11 @@ exports[`CreditBanner component render with error state snapshot 1`] = ` } values={ Object { - "supportEmailLink": , + "supportEmailLink": + test-support-email + , } } /> @@ -30,6 +32,21 @@ exports[`CreditBanner component render with error state snapshot 1`] = ` `; +exports[`CreditBanner component render with error state with no email snapshot 1`] = ` + +

+ An error occurred with this transaction. +

+ +
+`; + exports[`CreditBanner component render with no error state snapshot 1`] = ` { if (hookData === null) { return null; } + const { ContentComponent, error, supportEmail } = hookData; - const supportEmailLink = (); + const supportEmailLink = ({supportEmail}); return ( {error && (

- {formatMessage(messages.error, { supportEmailLink })} + {supportEmail ? formatMessage(messages.error, { supportEmailLink }) : formatMessage(messages.errorNoEmail)}

)} diff --git a/src/containers/CourseCard/components/CourseCardBanners/CreditBanner/index.test.jsx b/src/containers/CourseCard/components/CourseCardBanners/CreditBanner/index.test.jsx index f8fea3c2..68f285bf 100644 --- a/src/containers/CourseCard/components/CourseCardBanners/CreditBanner/index.test.jsx +++ b/src/containers/CourseCard/components/CourseCardBanners/CreditBanner/index.test.jsx @@ -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(), @@ -54,7 +52,7 @@ describe('CreditBanner component', () => { it('includes credit-error-msg with support email link', () => { expect(el.find('.credit-error-msg').containsMatchingElement( formatMessage(messages.error, { - supportEmailLink: (), + supportEmailLink: ({supportEmail}), }), )).toEqual(true); }); @@ -62,6 +60,25 @@ describe('CreditBanner component', () => { expect(el.find('ContentComponent').props().cardId).toEqual(cardId); }); }); + + describe('with error state with no email', () => { + beforeEach(() => { + hooks.useCreditBannerData.mockReturnValue({ + error: true, + ContentComponent, + }); + el = shallow(); + }); + 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({ diff --git a/src/containers/CourseCard/components/CourseCardBanners/CreditBanner/messages.js b/src/containers/CourseCard/components/CourseCardBanners/CreditBanner/messages.js index bf0adaaa..7c1d3973 100644 --- a/src/containers/CourseCard/components/CourseCardBanners/CreditBanner/messages.js +++ b/src/containers/CourseCard/components/CourseCardBanners/CreditBanner/messages.js @@ -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; diff --git a/src/containers/CourseCard/components/CourseCardBanners/__snapshots__/CertificateBanner.test.jsx.snap b/src/containers/CourseCard/components/CourseCardBanners/__snapshots__/CertificateBanner.test.jsx.snap index b3375327..077fe8d4 100644 --- a/src/containers/CourseCard/components/CourseCardBanners/__snapshots__/CertificateBanner.test.jsx.snap +++ b/src/containers/CourseCard/components/CourseCardBanners/__snapshots__/CertificateBanner.test.jsx.snap @@ -21,20 +21,40 @@ exports[`CertificateBanner snapshot is restricted 1`] = ` + Your Certificate of Achievement is being held pending confirmation that the issuance of your Certificate is in compliance with strict U.S. embargoes on Iran, Cuba, Syria, and Sudan. If you think our system has mistakenly identified you as being connected with one of those countries, please let us know. + +`; + +exports[`CertificateBanner snapshot is restricted and verified 1`] = ` + + Your Certificate of Achievement is being held pending confirmation that the issuance of your Certificate is in compliance with strict U.S. embargoes on Iran, Cuba, Syria, and Sudan. If you think our system has mistakenly identified you as being connected with one of those countries, please let us know. + + If you would like a refund on your Certificate of Achievement, please contact us. + +`; + +exports[`CertificateBanner snapshot is restricted and verified with billing email 1`] = ` + + Your Certificate of Achievement is being held pending confirmation that the issuance of your Certificate is in compliance with strict U.S. embargoes on Iran, Cuba, Syria, and Sudan. If you think our system has mistakenly identified you as being connected with one of those countries, please let us know. + - suport@email + billing@email , } } @@ -42,7 +62,7 @@ exports[`CertificateBanner snapshot is restricted 1`] = ` `; -exports[`CertificateBanner snapshot is restricted and verified 1`] = ` +exports[`CertificateBanner snapshot is restricted and verified with support and billing email 1`] = ` @@ -86,6 +106,66 @@ exports[`CertificateBanner snapshot is restricted and verified 1`] = ` `; +exports[`CertificateBanner snapshot is restricted and verified with support email 1`] = ` + + + suport@email + , + } + } + /> + + If you would like a refund on your Certificate of Achievement, please contact us. + +`; + +exports[`CertificateBanner snapshot is restricted with billing email 1`] = ` + + Your Certificate of Achievement is being held pending confirmation that the issuance of your Certificate is in compliance with strict U.S. embargoes on Iran, Cuba, Syria, and Sudan. If you think our system has mistakenly identified you as being connected with one of those countries, please let us know. + +`; + +exports[`CertificateBanner snapshot is restricted with support email 1`] = ` + + + suport@email + , + } + } + /> + +`; + exports[`CertificateBanner snapshot not passing and audit 1`] = ` Grade required to pass the course: 0.8‏% diff --git a/src/containers/CourseCard/components/CourseCardBanners/messages.js b/src/containers/CourseCard/components/CourseCardBanners/messages.js index 7a9b8a82..525f4b24 100644 --- a/src/containers/CourseCard/components/CourseCardBanners/messages.js +++ b/src/containers/CourseCard/components/CourseCardBanners/messages.js @@ -31,11 +31,21 @@ export const messages = StrictDict({ description: 'Restricted certificate warning message', defaultMessage: 'Your Certificate of Achievement is being held pending confirmation that the issuance of your Certificate is in compliance with strict U.S. embargoes on Iran, Cuba, Syria, and Sudan. If you think our system has mistakenly identified you as being connected with one of those countries, please let us know by contacting {supportEmail}.', }, + certRestrictedNoEmail: { + id: 'learner-dash.courseCard.banners.certificateRestrictedNoEmail', + description: 'Restricted certificate warning message', + defaultMessage: 'Your Certificate of Achievement is being held pending confirmation that the issuance of your Certificate is in compliance with strict U.S. embargoes on Iran, Cuba, Syria, and Sudan. If you think our system has mistakenly identified you as being connected with one of those countries, please let us know.', + }, certRefundContactBilling: { id: 'learner-dash.courseCard.banners.certificateRefundContactBilling', description: 'Message to learners to contact billing for certificate refunds', defaultMessage: 'If you would like a refund on your Certificate of Achievement, please contact our billing address {billingEmail}', }, + certRefundContactBillingNoEmail: { + id: 'learner-dash.courseCard.banners.certificateRefundContactBillingNoEmail', + description: 'Message to learners to contact billing for certificate refunds', + defaultMessage: 'If you would like a refund on your Certificate of Achievement, please contact us.', + }, passingGrade: { id: 'learner-dash.courseCard.banners.passingGrade', description: 'Message to learners with minimum passing grade for the course',