Skip to content

Commit

Permalink
feat: unlink the enterprise learner in non blocking manner
Browse files Browse the repository at this point in the history
  • Loading branch information
jajjibhai008 committed Oct 30, 2024
1 parent 96970cf commit 0058ab0
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 8 deletions.
13 changes: 13 additions & 0 deletions src/components/app/data/services/enterpriseCustomerUser.js
Original file line number Diff line number Diff line change
Expand Up @@ -204,3 +204,16 @@ export async function updateUserCsodParams({ data }) {
const url = `${getConfig().LMS_BASE_URL}/integrated_channels/api/v1/cornerstone/save-learner-information`;
return getAuthenticatedHttpClient().post(url, data);
}

/**
* Helper function to uunlink enterprise customer user by making a POST API request.
* @param {Object} params - The parameters object.
* @param {Object} params.enterpriseCustomerUser - The enterprise customer user that should be unlinked.
* @returns {Promise} - A promise that resolves when the active enterprise customer user is unlinked.
*/
export async function postUnlinkUserFromEnterprise(enterpriseCustomerUserUUID, userEmail) {
const url = `${getConfig().LMS_BASE_URL}/enterprise/api/v1/enterprise-customer/${enterpriseCustomerUserUUID}/unlink_users/`;
return getAuthenticatedHttpClient().post(url, { user_emails: [userEmail], is_relinkable: true }).catch((error) => {
logError(error);

Check warning on line 217 in src/components/app/data/services/enterpriseCustomerUser.js

View check run for this annotation

Codecov / codecov/patch

src/components/app/data/services/enterpriseCustomerUser.js#L217

Added line #L217 was not covered by tests
});
}
20 changes: 18 additions & 2 deletions src/components/expired-subscription-modal/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,37 @@ import {
useToggle, AlertModal, Button, ActionRow,
} from '@openedx/paragon';
import DOMPurify from 'dompurify';
import { useSubscriptions } from '../app/data';
import { useContext } from 'react';
import { AppContext } from '@edx/frontend-platform/react';
import { postUnlinkUserFromEnterprise, useEnterpriseCustomer, useSubscriptions } from '../app/data';

const ExpiredSubscriptionModal = () => {
const { data: { customerAgreement } } = useSubscriptions();
const {
authenticatedUser: { email: userEmail },
} = useContext(AppContext);
const { data: enterpriseCustomer } = useEnterpriseCustomer();

const [isOpen] = useToggle(true);
if (!customerAgreement?.hasCustomLicenseExpirationMessaging) {
return null;
}
const onClickHandler = (redirectUrl) => async (e) => {
e.preventDefault();

await postUnlinkUserFromEnterprise(enterpriseCustomer.uuid, userEmail);

// Redirect immediately
window.location.href = redirectUrl;

Check warning on line 26 in src/components/expired-subscription-modal/index.jsx

View check run for this annotation

Codecov / codecov/patch

src/components/expired-subscription-modal/index.jsx#L26

Added line #L26 was not covered by tests
};
return (
<AlertModal
title={<h3 className="mb-2">{customerAgreement.modalHeaderText}</h3>}
isOpen={isOpen}
isBlocking
footerNode={(
<ActionRow>
<Button href={customerAgreement.urlForButtonInModal}>
<Button onClick={onClickHandler(customerAgreement.urlForButtonInModal)}>
{customerAgreement.buttonLabelInModal}
</Button>
</ActionRow>
Expand All @@ -31,6 +46,7 @@ const ExpiredSubscriptionModal = () => {
),
}}
/>
<p>{userEmail}{enterpriseCustomer.uuid}</p>
</AlertModal>
);
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,28 @@
import { screen } from '@testing-library/react';
import '@testing-library/jest-dom/extend-expect';
import userEvent from '@testing-library/user-event';
import { AppContext } from '@edx/frontend-platform/react';
import ExpiredSubscriptionModal from '../index';
import { useSubscriptions } from '../../app/data';
import { useEnterpriseCustomer, useSubscriptions } from '../../app/data';
import { renderWithRouter } from '../../../utils/tests';
import { authenticatedUserFactory, enterpriseCustomerFactory } from '../../app/data/services/data/__factories__';

jest.mock('../../app/data', () => ({
...jest.requireActual('../../app/data'),
useSubscriptions: jest.fn(),
useEnterpriseCustomer: jest.fn(),
}));
const mockAuthenticatedUser = authenticatedUserFactory();
const mockEnterpriseCustomer = enterpriseCustomerFactory();

const defaultAppContextValue = { authenticatedUser: mockAuthenticatedUser };
const ExpirationModalWrapper = ({ children, appContextValue = defaultAppContextValue }) => (
<AppContext.Provider value={appContextValue}>
<ExpiredSubscriptionModal>
{children}
</ExpiredSubscriptionModal>
</AppContext.Provider>
);

describe('<ExpiredSubscriptionModal />', () => {
beforeEach(() => {
Expand All @@ -23,10 +37,11 @@ describe('<ExpiredSubscriptionModal />', () => {
},
},
});
useEnterpriseCustomer.mockReturnValue({ data: mockEnterpriseCustomer });
});

test('does not renderwithrouter if `hasCustomLicenseExpirationMessaging` is false', () => {
const { container } = renderWithRouter(<ExpiredSubscriptionModal />);
const { container } = renderWithRouter(<ExpirationModalWrapper />);
expect(container).toBeEmptyDOMElement();
});

Expand All @@ -43,15 +58,15 @@ describe('<ExpiredSubscriptionModal />', () => {
},
});

renderWithRouter(<ExpiredSubscriptionModal />);
renderWithRouter(<ExpirationModalWrapper />);

expect(screen.getByText('Expired Subscription')).toBeInTheDocument();
expect(screen.getByText('Continue Learning')).toBeInTheDocument();
});

test('does not renderwithrouter modal if no customer agreement data is present', () => {
useSubscriptions.mockReturnValue({ data: { customerAgreement: null } });
const { container } = renderWithRouter(<ExpiredSubscriptionModal />);
const { container } = renderWithRouter(<ExpirationModalWrapper />);
expect(container).toBeEmptyDOMElement();
});

Expand All @@ -68,7 +83,7 @@ describe('<ExpiredSubscriptionModal />', () => {
},
});

renderWithRouter(<ExpiredSubscriptionModal />);
renderWithRouter(<ExpirationModalWrapper />);
expect(screen.queryByLabelText(/close/i)).not.toBeInTheDocument();
});
test('clicks on Continue Learning button', () => {
Expand All @@ -86,7 +101,7 @@ describe('<ExpiredSubscriptionModal />', () => {
});

// Render the component
renderWithRouter(<ExpiredSubscriptionModal />);
renderWithRouter(<ExpirationModalWrapper />);

// Find the Continue Learning button
const continueButton = screen.getByText('Continue Learning');
Expand Down

0 comments on commit 0058ab0

Please sign in to comment.