Skip to content

Commit

Permalink
feat: subsidy box points to learner credit (#810)
Browse files Browse the repository at this point in the history
  • Loading branch information
sameenfatima78 authored Sep 13, 2023
1 parent 6fc25f0 commit 3637bed
Show file tree
Hide file tree
Showing 13 changed files with 285 additions and 145 deletions.
72 changes: 0 additions & 72 deletions src/components/dashboard/sidebar/EnterpriseOffersSummaryCard.jsx

This file was deleted.

62 changes: 62 additions & 0 deletions src/components/dashboard/sidebar/LearnerCreditSummaryCard.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Badge, Row, Col } from '@edx/paragon';
import dayjs from 'dayjs';
import {
LEARNER_CREDIT_SUMMARY_CARD_TITLE,
LEARNER_CREDIT_ACTIVE_BADGE_LABEL,
LEARNER_CREDIT_ACTIVE_BADGE_VARIANT,
LEARNER_CREDIT_CARD_SUMMARY,
} from './data/constants';
import SidebarCard from './SidebarCard';

const LearnerCreditSummaryCard = ({
className, expirationDate, searchCoursesCta,
}) => (
<SidebarCard
title={
(
<div className="d-flex align-items-center justify-content-between">
<h3 className="m-0">{LEARNER_CREDIT_SUMMARY_CARD_TITLE}</h3>
<Badge
variant={LEARNER_CREDIT_ACTIVE_BADGE_VARIANT}
className="ml-2"
data-testid="learner-credit-status-badge"
>
{LEARNER_CREDIT_ACTIVE_BADGE_LABEL}
</Badge>
</div>
)
}
cardClassNames={className}
>
<p data-testid="learner-credit-summary-text">
{ LEARNER_CREDIT_CARD_SUMMARY }
</p>

{expirationDate && (
<p data-testid="learner-credit-summary-end-date-text">
Available until <b>{dayjs(expirationDate).format('MMM D, YYYY')}</b>
</p>
)}

{searchCoursesCta && (
<Row className="mt-3 d-flex justify-content-end">
<Col xl={12}>{searchCoursesCta}</Col>
</Row>
)}
</SidebarCard>
);

LearnerCreditSummaryCard.propTypes = {
expirationDate: PropTypes.string.isRequired,
className: PropTypes.string,
searchCoursesCta: PropTypes.node,
};

LearnerCreditSummaryCard.defaultProps = {
className: undefined,
searchCoursesCta: undefined,
};

export default LearnerCreditSummaryCard;
28 changes: 23 additions & 5 deletions src/components/dashboard/sidebar/SubsidiesSummary.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,23 @@ import { Button } from '@edx/paragon';
import classNames from 'classnames';
import CouponCodesSummaryCard from './CouponCodesSummaryCard';
import SubscriptionSummaryCard from './SubscriptionSummaryCard';
import EnterpriseOffersSummaryCard from './EnterpriseOffersSummaryCard';
import LearnerCreditSummaryCard from './LearnerCreditSummaryCard';
import { UserSubsidyContext } from '../../enterprise-user-subsidy';
import { LICENSE_STATUS } from '../../enterprise-user-subsidy/data/constants';
import { CATALOG_ACCESS_CARD_BUTTON_TEXT } from './data/constants';
import SidebarCard from './SidebarCard';
import { CourseEnrollmentsContext } from '../main-content/course-enrollments/CourseEnrollmentsContextProvider';
import { SubsidyRequestsContext, SUBSIDY_TYPE } from '../../enterprise-subsidy-requests';
import { getOfferExpiringFirst, getPolicyExpiringFirst } from './utils';

function getLearnerCreditSummaryCardData({ enterpriseOffers, redeemableLearnerCreditPolicies }) {
const enterpriseOfferExpiringFirst = getOfferExpiringFirst(enterpriseOffers);
const learnerCreditPolicyExpiringFirst = getPolicyExpiringFirst(redeemableLearnerCreditPolicies);
return {
expirationDate: learnerCreditPolicyExpiringFirst?.subsidyExpirationDate
|| enterpriseOfferExpiringFirst?.endDatetime,
};
}

const SubsidiesSummary = ({
className, showSearchCoursesCta, totalCoursesEligibleForCertificate, courseEndDate, programProgressPage,
Expand All @@ -35,8 +45,14 @@ const SubsidiesSummary = ({
couponCodes: { couponCodesCount },
enterpriseOffers,
canEnrollWithEnterpriseOffers,
redeemableLearnerCreditPolicies,
} = useContext(UserSubsidyContext);

const learnerCreditSummaryCardData = getLearnerCreditSummaryCardData({
enterpriseOffers,
redeemableLearnerCreditPolicies,
});

const {
requestsBySubsidyType,
} = useContext(SubsidyRequestsContext);
Expand All @@ -54,9 +70,10 @@ const SubsidiesSummary = ({
&& userSubscriptionLicense?.status === LICENSE_STATUS.ACTIVATED) || licenseRequests.length > 0;

const hasAssignedCodesOrCodeRequests = couponCodesCount > 0 || couponCodeRequests.length > 0;
const hasAvailableLearnerCreditPolicies = redeemableLearnerCreditPolicies?.length > 0;

const hasAvailableSubsidyOrRequests = hasActiveLicenseOrLicenseRequest
|| hasAssignedCodesOrCodeRequests || canEnrollWithEnterpriseOffers;
|| hasAssignedCodesOrCodeRequests || canEnrollWithEnterpriseOffers || hasAvailableLearnerCreditPolicies;

if (!hasAvailableSubsidyOrRequests) {
return null;
Expand Down Expand Up @@ -100,10 +117,11 @@ const SubsidiesSummary = ({
className="border-0 shadow-none"
/>
)}
{canEnrollWithEnterpriseOffers && (
<EnterpriseOffersSummaryCard
{(canEnrollWithEnterpriseOffers || hasAvailableLearnerCreditPolicies)
&& learnerCreditSummaryCardData?.expirationDate && (
<LearnerCreditSummaryCard
className="border-0 shadow-none"
offers={enterpriseOffers}
expirationDate={learnerCreditSummaryCardData.expirationDate}
/>
)}
</div>
Expand Down
6 changes: 6 additions & 0 deletions src/components/dashboard/sidebar/data/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ export const ENTERPRISE_OFFER_ACTIVE_BADGE_LABEL = 'Active';
export const ENTERPRISE_OFFER_ACTIVE_BADGE_VARIANT = 'success';
export const ENTERPRISE_OFFER_SUMMARY_CARD_SUMMARY = 'Apply your organization\'s learner credit balance to enroll into courses with no out of pocket cost.';

// LearnerCreditSummaryCard
export const LEARNER_CREDIT_SUMMARY_CARD_TITLE = 'Learner Credit';
export const LEARNER_CREDIT_ACTIVE_BADGE_LABEL = 'Active';
export const LEARNER_CREDIT_ACTIVE_BADGE_VARIANT = 'success';
export const LEARNER_CREDIT_CARD_SUMMARY = 'Apply your organization\'s learner credit balance to enroll into courses with no out of pocket cost.';

// Dashboard Sidebar texts
export const CATALOG_ACCESS_CARD_BUTTON_TEXT = 'Find a course';
export const NEED_HELP_BLOCK_TITLE = 'Need help?';
Expand Down
47 changes: 46 additions & 1 deletion src/components/dashboard/sidebar/tests/DashboardSidebar.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
LICENSE_REQUESTED_NOTICE,
COUPON_CODES_SUMMARY_NOTICE,
ENTERPRISE_OFFER_SUMMARY_CARD_TITLE,
LEARNER_CREDIT_SUMMARY_CARD_TITLE,
} from '../data/constants';
import { LICENSE_STATUS } from '../../../enterprise-user-subsidy/data/constants';
import CourseEnrollmentsContextProvider from '../../main-content/course-enrollments/CourseEnrollmentsContextProvider';
Expand Down Expand Up @@ -61,6 +62,7 @@ describe('<DashboardSidebar />', () => {
couponCodesCount: 0,
},
enterpriseOffers: [],
redeemableLearnerCreditPolicies: undefined,
};
const initialAppState = {
enterpriseConfig: {
Expand Down Expand Up @@ -173,7 +175,7 @@ describe('<DashboardSidebar />', () => {
);
expect(screen.queryByText(SUBSCRIPTION_SUMMARY_CARD_TITLE)).toBeFalsy();
});
test('Enterprise offers summary card is displayed when enterprise has active offers and no subscriptions or coupons', () => {
test('Enterprise offers summary card is displayed when enterprise has active offers and no subscriptions or coupons or learner credit', () => {
renderWithRouter(
<DashboardSidebarWithContext
initialAppState={initialAppState}
Expand Down Expand Up @@ -219,6 +221,49 @@ describe('<DashboardSidebar />', () => {
expect(screen.queryByText(SUBSCRIPTION_SUMMARY_CARD_TITLE)).not.toBeInTheDocument();
expect(screen.queryByText(COUPON_CODES_SUMMARY_NOTICE)).toBeInTheDocument();
});

test('Learner credit summary card is displayed when enterprise has learner credit', () => {
renderWithRouter(
<DashboardSidebarWithContext
initialAppState={initialAppState}
initialUserSubsidyState={{
...defaultUserSubsidyState,
redeemableLearnerCreditPolicies: [{
remainingBalancePerUser: 5,
subsidyExpirationDate: '2030-01-01 12:00:00Z',
active: true,
}],
}}
/>,
);
expect(screen.queryByText(LEARNER_CREDIT_SUMMARY_CARD_TITLE)).toBeInTheDocument();
});

test('Only learner credit summary card is displayed when enterprise has both; learner credit and offers', () => {
const policyExpirationDate = '2030-01-01 12:00:00Z';
const offerEndDate = '2027-10-25';
renderWithRouter(
<DashboardSidebarWithContext
initialAppState={initialAppState}
initialUserSubsidyState={{
...defaultUserSubsidyState,
redeemableLearnerCreditPolicies: [{
remainingBalancePerUser: 5,
subsidyExpirationDate: policyExpirationDate,
active: true,
}],
enterpriseOffers: [{
uuid: 'enterprise-offer-id',
endDatetime: offerEndDate,
}],
canEnrollWithEnterpriseOffers: true,
}}
/>,
);
expect(screen.getByText('2030', { exact: false })).toBeInTheDocument();
expect(screen.queryByText('2027', { exact: false })).toBeFalsy();
});

test('Find a course button is not rendered when user has no coupon codes or license subsidy', () => {
renderWithRouter(
<DashboardSidebarWithContext
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import React from 'react';
import '@testing-library/jest-dom/extend-expect';
import { screen, render } from '@testing-library/react';
import LearnerCreditSummaryCard from '../LearnerCreditSummaryCard';
import { LEARNER_CREDIT_SUMMARY_CARD_TITLE } from '../data/constants';

const TEST_EXPIRATION_DATE = '2022-06-01T00:00:00Z';

describe('<LearnerCreditSummaryCard />', () => {
it('should render searchCoursesCta', () => {
const cta = 'Search Courses';
render(
<LearnerCreditSummaryCard
expirationDate={TEST_EXPIRATION_DATE}
searchCoursesCta={
<button type="button">{cta}</button>
}
/>,
);
expect(screen.getByText(LEARNER_CREDIT_SUMMARY_CARD_TITLE)).toBeInTheDocument();
expect(screen.getByText(cta)).toBeInTheDocument();
});

it('should render default summary text', () => {
render(
<LearnerCreditSummaryCard
expirationDate={TEST_EXPIRATION_DATE}
/>,
);
expect(screen.getByTestId('learner-credit-summary-text')).toBeInTheDocument();
});

it('should render the expiration date passed as prop', () => {
render(
<LearnerCreditSummaryCard
expirationDate={TEST_EXPIRATION_DATE}
/>,
);
expect(screen.getByTestId('learner-credit-summary-end-date-text')).toBeInTheDocument();
expect(screen.getByText('2022', { exact: false })).toBeInTheDocument();
});
});
Loading

0 comments on commit 3637bed

Please sign in to comment.