Skip to content

Commit

Permalink
chore: add test
Browse files Browse the repository at this point in the history
  • Loading branch information
brobro10000 committed Feb 24, 2025
1 parent 0b98259 commit 9f7bae7
Show file tree
Hide file tree
Showing 4 changed files with 183 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ export function authenticatedUserFactory(overrides = {}) {
Factory.define('enterpriseCustomer')
.attr('active', true)
.attr('created', dayjs().toISOString())
.attr('uuid', uuidv4())
.attr('auth_org_id', uuidv4())
.attr('uuid', () => uuidv4())
.attr('auth_org_id', () => uuidv4())
.attr('slug', faker.lorem.slug())
.attr('name', faker.company.name())
.attr('contact_email', faker.internet.email())
Expand Down
137 changes: 136 additions & 1 deletion src/components/app/routes/data/utils.test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,19 @@
import { transformEnterpriseCustomer } from '../../data';
import { waitFor } from '@testing-library/react';
import {
queryEnterpriseLearnerDashboardBFF,
resolveBFFQuery,
transformEnterpriseCustomer,
updateUserActiveEnterprise,
} from '../../data';
import { ensureActiveEnterpriseCustomerUser } from './utils';
import { authenticatedUserFactory, enterpriseCustomerFactory } from '../../data/services/data/__factories__';
import { generateTestPermutations } from '../../../../utils/tests';

jest.mock('../../data', () => ({
...jest.requireActual('../../data'),
updateUserActiveEnterprise: jest.fn(),
resolveBFFQuery: jest.fn(),
}));

describe('transformEnterpriseCustomer', () => {
it('returns null with disabled learner portal', () => {
Expand Down Expand Up @@ -64,3 +79,123 @@ describe('transformEnterpriseCustomer', () => {
});
});
});

describe('ensureActiveEnterpriseCustomerUser', () => {
// active enterprise customer
const mockEnterpriseCustomerOne = enterpriseCustomerFactory({

});
// inactive enterprise customer
const mockEnterpriseCustomerTwo = enterpriseCustomerFactory({
active: false,
});

const mockEnterpriseSlugOne = mockEnterpriseCustomerOne.slug;

const mockActiveEnterpriseCustomer = mockEnterpriseCustomerOne;

const mockAllLinkedEnterpriseCustomerUsers = [
{
id: 1,
enterpriseCustomer: mockEnterpriseCustomerOne,
active: true,
},
{
id: 2,
enterpriseCustomer: mockEnterpriseCustomerTwo,
active: false,
},
];
const mockShouldUpdateActiveEnterpriseCustomerUser = false;
const mockEnterpriseLearnerData = {
enterpriseCustomer: mockEnterpriseCustomerOne,
activeEnterpriseCustomer: mockActiveEnterpriseCustomer,
allLinkedEnterpriseCustomerUsers: mockAllLinkedEnterpriseCustomerUsers,
shouldUpdateActiveEnterpriseCustomerUser: mockShouldUpdateActiveEnterpriseCustomerUser,
};

const mockRequestUrl = new URL(`/${mockEnterpriseSlugOne}`, 'http://localhost');

const mockAuthenticatedUser = authenticatedUserFactory();

const mockQueryClient = {
ensureQueryData: jest.fn().mockResolvedValue(),
getQueryData: jest.fn(),
setQueryData: jest.fn(),
};

beforeEach(() => {
jest.resetAllMocks();
});

it.each(generateTestPermutations({
isBFFData: [true, false],
shouldUpdateActiveEnterpriseCustomerUser: [true, false],
}))('should update active enterprise customer if shouldUpdateActiveEnterpriseCustomerUser is (%s)', async ({
isBFFData,
shouldUpdateActiveEnterpriseCustomerUser,
}) => {
resolveBFFQuery.mockReturnValue(isBFFData ? queryEnterpriseLearnerDashboardBFF : null);
const updatedEnterpriseCustomerMetadata = shouldUpdateActiveEnterpriseCustomerUser
// If the customer is updated, we update expected output from ensureActiveEnterpriseCustomerUser and
// verify the active customer is updated
? {
expectedEnterpriseCustomer: mockEnterpriseCustomerTwo,
timesUpdateActiveEnterpriseCustomerCalled: 1,
expectedAllLinkedEnterpriseCustomers: [
{
id: 1,
enterpriseCustomer: mockEnterpriseCustomerOne,
active: false,
},
{
id: 2,
enterpriseCustomer: mockEnterpriseCustomerTwo,
active: true,
},
],
}
// If the customer is not updated, it should return the current enterprise customer and
// not update the active enterprise
: {
expectedEnterpriseCustomer: mockEnterpriseCustomerOne,
timesUpdateActiveEnterpriseCustomerCalled: 0,
expectedAllLinkedEnterpriseCustomers: mockAllLinkedEnterpriseCustomerUsers,
};
// If we need to update the active enterprise customer, set the inactive customer to the current enterprise customer
const updatedMockEnterpriseLearnerData = {
...mockEnterpriseLearnerData,
enterpriseCustomer: updatedEnterpriseCustomerMetadata.expectedEnterpriseCustomer,
shouldUpdateActiveEnterpriseCustomerUser,
};

const {
enterpriseCustomer,
allLinkedEnterpriseCustomerUsers,
} = await ensureActiveEnterpriseCustomerUser({
enterpriseLearnerData: updatedMockEnterpriseLearnerData,
enterpriseSlug: mockEnterpriseSlugOne,
isBFFData,
requestUrl: mockRequestUrl,
authenticatedUser: mockAuthenticatedUser,
queryClient: mockQueryClient,
});

await waitFor(
() => {
expect(updateUserActiveEnterprise).toHaveBeenCalledTimes(
updatedEnterpriseCustomerMetadata.timesUpdateActiveEnterpriseCustomerCalled,
);
if (shouldUpdateActiveEnterpriseCustomerUser) {
expect(updateUserActiveEnterprise).toHaveBeenCalledWith({
enterpriseCustomer: updatedEnterpriseCustomerMetadata.expectedEnterpriseCustomer,
});
}
},
);
expect(enterpriseCustomer).toEqual(updatedEnterpriseCustomerMetadata.expectedEnterpriseCustomer);
expect(allLinkedEnterpriseCustomerUsers).toEqual(
updatedEnterpriseCustomerMetadata.expectedAllLinkedEnterpriseCustomers,
);
});
});
17 changes: 11 additions & 6 deletions src/components/executive-education-2u/UserEnrollmentForm.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ import {
LEARNER_CREDIT_SUBSIDY_TYPE,
queryCanRedeemContextQueryKey,
queryEnterpriseCourseEnrollments,
queryEnterpriseLearnerDashboardBFF,
queryRedeemablePolicies,
useCourseMetadata,
useEnterpriseCourseEnrollments,
useEnterpriseCustomer,
queryEnterpriseLearnerDashboardBFF,
useIsBFFEnabled,
} from '../app/data';
import { authenticatedUserFactory, enterpriseCustomerFactory } from '../app/data/services/data/__factories__';
Expand Down Expand Up @@ -259,8 +259,11 @@ describe('UserEnrollmentForm', () => {
subsidyType: LEARNER_CREDIT_SUBSIDY_TYPE,
},
});
const expectedEnterpriseCustomer = isDSCEnabled
? mockEnterpriseCustomer
: mockEnterpriseCustomerWithDisabledDataSharingConsent;
if (!isDSCEnabled) {
useEnterpriseCustomer.mockReturnValue({ data: mockEnterpriseCustomerWithDisabledDataSharingConsent });
useEnterpriseCustomer.mockReturnValue({ data: expectedEnterpriseCustomer });
}

const mockExternalEnrollmentUrl = `/${mockEnterpriseCustomer.slug}/executive-education-2u/course/${mockCourseKey}/enroll/${mockCourseRunKey}`;
Expand Down Expand Up @@ -319,12 +322,14 @@ describe('UserEnrollmentForm', () => {
useStatefulEnroll.mock.calls[0][0].onSuccess(newTransaction);
});

const canRedeemQueryKey = queryCanRedeemContextQueryKey(mockEnterpriseCustomer.uuid, mockCourseKey);
const canRedeemQueryKey = queryCanRedeemContextQueryKey(expectedEnterpriseCustomer.uuid, mockCourseKey);
const redeemablePoliciesQueryKey = queryRedeemablePolicies({
enterpriseUuid: mockEnterpriseCustomer.uuid,
enterpriseUuid: expectedEnterpriseCustomer.uuid,
lmsUserId: mockAuthenticatedUser.userId,
}).queryKey;
const enterpriseCourseEnrollmentsQueryKey = queryEnterpriseCourseEnrollments(mockEnterpriseCustomer.uuid).queryKey;
const enterpriseCourseEnrollmentsQueryKey = queryEnterpriseCourseEnrollments(
expectedEnterpriseCustomer.uuid,
).queryKey;
const expectedQueriesToInvalidate = [
canRedeemQueryKey,
redeemablePoliciesQueryKey,
Expand All @@ -333,7 +338,7 @@ describe('UserEnrollmentForm', () => {

if (isBFFEnabled) {
const dashboardBFFQueryKey = queryEnterpriseLearnerDashboardBFF({
enterpriseSlug: mockEnterpriseCustomer.slug,
enterpriseSlug: expectedEnterpriseCustomer.slug,
}).queryKey;
const expectedBFFQueriesToInvalidate = [dashboardBFFQueryKey];
expectedQueriesToInvalidate.push(...expectedBFFQueriesToInvalidate);
Expand Down
35 changes: 34 additions & 1 deletion src/utils/tests.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { isValidElement } from 'react';
import { BrowserRouter as Router, RouterProvider, createMemoryRouter } from 'react-router-dom';
import { BrowserRouter as Router, createMemoryRouter, RouterProvider } from 'react-router-dom';
import { createMemoryHistory } from 'history';
import dayjs from 'dayjs';
import { render } from '@testing-library/react'; // eslint-disable-line import/no-extraneous-dependencies
Expand Down Expand Up @@ -119,3 +119,36 @@ export function queryClient(defaultOptions = {}) {
},
});
}

/**
* Generates all possible permutations of an object where each key has multiple possible values.
*
* @param {Object.<string, any[]>} options - An object where each key has an array of possible values.
* @returns {Object[]} - An array of objects containing all possible combinations of the input values.
*
* @example
* const input = {
* shouldUpdateActiveEnterpriseCustomerUser: [true, false],
* isBFFData: [true, false],
* anotherFlag: ["A", "B"]
* };
*
* const result = generatePermutations(input);
* console.log(result);
*
* // Output:
* // [
* // { shouldUpdateActiveEnterpriseCustomerUser: true, isBFFData: true, anotherFlag: "A" },
* // { shouldUpdateActiveEnterpriseCustomerUser: true, isBFFData: true, anotherFlag: "B" },
* // { shouldUpdateActiveEnterpriseCustomerUser: true, isBFFData: false, anotherFlag: "A" },
* // { shouldUpdateActiveEnterpriseCustomerUser: true, isBFFData: false, anotherFlag: "B" },
* // { shouldUpdateActiveEnterpriseCustomerUser: false, isBFFData: true, anotherFlag: "A" },
* // { shouldUpdateActiveEnterpriseCustomerUser: false, isBFFData: true, anotherFlag: "B" },
* // { shouldUpdateActiveEnterpriseCustomerUser: false, isBFFData: false, anotherFlag: "A" },
* // { shouldUpdateActiveEnterpriseCustomerUser: false, isBFFData: false, anotherFlag: "B" }
* // ]
*/
export const generateTestPermutations = (options) => Object.entries(options).reduce(
(acc, [key, values]) => acc.flatMap(prev => values.map(value => ({ ...prev, [key]: value }))),
[{}],
);

0 comments on commit 9f7bae7

Please sign in to comment.