Skip to content

Commit

Permalink
fix: sort licenses by whether they are current in ascending order bef…
Browse files Browse the repository at this point in the history
…ore processing (#1154)
  • Loading branch information
adamstankiewicz authored Aug 16, 2024
1 parent 8dafafc commit f0d0c7e
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 1 deletion.
15 changes: 14 additions & 1 deletion src/components/app/data/services/subsidies/subscriptions.js
Original file line number Diff line number Diff line change
Expand Up @@ -233,8 +233,19 @@ export async function fetchSubscriptions(enterpriseUUID) {
if (customerAgreement) {
subscriptionsData.customerAgreement = customerAgreement;
}
subscriptionsData.subscriptionLicenses = subscriptionLicenses;
subscriptionsData.showExpirationNotifications = !(customerAgreement?.disableExpirationNotifications);

// Sort licenses within each license status by whether the associated subscription plans
// are current; current plans should be prioritized over non-current plans.
subscriptionLicenses.sort((a, b) => {
const aIsCurrent = a.subscriptionPlan.isCurrent;
const bIsCurrent = b.subscriptionPlan.isCurrent;
if (aIsCurrent && bIsCurrent) { return 0; }
return aIsCurrent ? -1 : 1;
});
subscriptionsData.subscriptionLicenses = subscriptionLicenses;

// Group licenses by status.
subscriptionLicenses.forEach((license) => {
const { subscriptionPlan, status } = license;
const isUnassignedLicense = status === LICENSE_STATUS.UNASSIGNED;
Expand All @@ -243,6 +254,8 @@ export async function fetchSubscriptions(enterpriseUUID) {
}
licensesByStatus[license.status].push(license);
});

// Extracts a single subscription license for the user, from the ordered licenses by status.
const applicableSubscriptionLicense = Object.values(licensesByStatus).flat()[0];
if (applicableSubscriptionLicense) {
subscriptionsData.subscriptionLicense = applicableSubscriptionLicense;
Expand Down
63 changes: 63 additions & 0 deletions src/components/app/data/services/subsidies/subscriptions.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,69 @@ describe('fetchSubscriptions', () => {
};
expect(response).toEqual(expectedResult);
});

it('handles learner with multiple activated licenses due to a scheduled renewal', async () => {
const mockRenewalStartDate = dayjs().add(15, 'days');
const mockRenewalEndDate = mockRenewalStartDate.add(1, 'year');
const mockSubscriptionLicenseRenewal = {
uuid: 'test-license-uuid-1',
status: LICENSE_STATUS.ACTIVATED,
subscriptionPlan: {
uuid: 'test-subscription-plan-uuid-1',
isActive: true,
isCurrent: false,
daysUntilExpiration: mockRenewalEndDate.diff(mockRenewalStartDate, 'days'),
startDate: mockRenewalStartDate.toISOString(),
expirationDate: mockRenewalEndDate.toISOString(),
},
};
const mockCurrentStartDate = mockRenewalStartDate.subtract(30, 'days');
const mockSubscriptionLicenseCurrent = {
uuid: 'test-license-uuid-2',
status: LICENSE_STATUS.ACTIVATED,
subscriptionPlan: {
uuid: 'test-subscription-plan-uuid-2',
isActive: true,
isCurrent: true,
daysUntilExpiration: mockRenewalStartDate.diff(mockCurrentStartDate, 'days'),
startDate: mockCurrentStartDate.toISOString(),
expirationDate: mockRenewalStartDate.toISOString(),
},
};
const mockResponse = {
customerAgreement: {
uuid: 'test-customer-agreement-uuid',
disableExpirationNotifications: false,
},
results: [mockSubscriptionLicenseRenewal, mockSubscriptionLicenseCurrent],
};
const queryParams = new URLSearchParams({
enterprise_customer_uuid: mockEnterpriseId,
include_revoked: true,
current_plans_only: false,
});
const SUBSCRIPTIONS_URL = `${APP_CONFIG.LICENSE_MANAGER_URL}/api/v1/learner-licenses/?${queryParams.toString()}`;
axiosMock.onGet(SUBSCRIPTIONS_URL).reply(200, mockResponse);
const response = await fetchSubscriptions(mockEnterpriseId);
const expectedLicensesByStatus = {
[LICENSE_STATUS.ACTIVATED]: [],
[LICENSE_STATUS.ASSIGNED]: [],
[LICENSE_STATUS.REVOKED]: [],
};
expectedLicensesByStatus[LICENSE_STATUS.ACTIVATED].push(mockSubscriptionLicenseCurrent);
expectedLicensesByStatus[LICENSE_STATUS.ACTIVATED].push(mockSubscriptionLicenseRenewal);

const expectedResult = {
customerAgreement: mockResponse.customerAgreement,
licensesByStatus: expectedLicensesByStatus,
subscriptionPlan: mockSubscriptionLicenseCurrent.subscriptionPlan,
subscriptionLicense: mockSubscriptionLicenseCurrent,
subscriptionLicenses: [mockSubscriptionLicenseCurrent, mockSubscriptionLicenseRenewal],
shouldShowActivationSuccessMessage: false,
showExpirationNotifications: true,
};
expect(response).toEqual(expectedResult);
});
});

describe('activateOrAutoApplySubscriptionLicense', () => {
Expand Down

0 comments on commit f0d0c7e

Please sign in to comment.