Files
frontend-app-authn/src/progressive-profiling/tests/ProgressiveProfiling.test.jsx
2023-03-10 18:05:02 +05:00

250 lines
8.7 KiB
JavaScript

import React from 'react';
import { Provider } from 'react-redux';
import { getConfig, mergeConfig } from '@edx/frontend-platform';
import * as analytics from '@edx/frontend-platform/analytics';
import * as auth from '@edx/frontend-platform/auth';
import { configure, injectIntl, IntlProvider } from '@edx/frontend-platform/i18n';
import * as logging from '@edx/frontend-platform/logging';
import { mount } from 'enzyme';
import { createMemoryHistory } from 'history';
import { act } from 'react-dom/test-utils';
import { MemoryRouter, Router } from 'react-router-dom';
import configureStore from 'redux-mock-store';
import {
COMPLETE_STATE, DEFAULT_REDIRECT_URL, FAILURE_STATE, RECOMMENDATIONS,
} from '../../data/constants';
import { saveUserProfile } from '../data/actions';
import ProgressiveProfiling from '../ProgressiveProfiling';
const IntlProgressiveProfilingPage = injectIntl(ProgressiveProfiling);
const mockStore = configureStore();
jest.mock('@edx/frontend-platform/analytics');
jest.mock('@edx/frontend-platform/auth');
jest.mock('@edx/frontend-platform/logging');
analytics.sendTrackEvent = jest.fn();
analytics.sendPageEvent = jest.fn();
analytics.identifyAuthenticatedUser = jest.fn();
logging.getLoggingService = jest.fn();
auth.configure = jest.fn();
auth.ensureAuthenticatedUser = jest.fn().mockImplementation(() => Promise.resolve(true));
auth.hydrateAuthenticatedUser = jest.fn().mockImplementation(() => Promise.resolve(true));
const history = createMemoryHistory();
describe('ProgressiveProfilingTests', () => {
mergeConfig({
AUTHN_PROGRESSIVE_PROFILING_SUPPORT_LINK: 'http://localhost:1999/welcome',
});
const registrationResult = { redirectUrl: getConfig().LMS_BASE_URL + DEFAULT_REDIRECT_URL, success: true };
const fields = {
company: { name: 'company', type: 'text', label: 'Company' },
gender: {
name: 'gender',
type: 'select',
label: 'Gender',
options: [['m', 'Male'], ['f', 'Female'], ['o', 'Other/Prefer Not to Say']],
},
};
const extendedProfile = ['company'];
const optionalFields = { fields, extended_profile: extendedProfile };
let props = {};
let store = {};
const DASHBOARD_URL = getConfig().LMS_BASE_URL.concat(DEFAULT_REDIRECT_URL);
const initialState = {
welcomePage: {
formRenderState: COMPLETE_STATE,
},
};
const reduxWrapper = children => (
<IntlProvider locale="en">
<MemoryRouter>
<Provider store={store}>{children}</Provider>
</MemoryRouter>
</IntlProvider>
);
const getProgressiveProfilingPage = async () => {
const progressiveProfilingPage = mount(reduxWrapper(
<Router history={history}>
<IntlProgressiveProfilingPage {...props} />
</Router>,
));
await act(async () => {
await Promise.resolve(progressiveProfilingPage);
await new Promise(resolve => setImmediate(resolve));
progressiveProfilingPage.update();
});
return progressiveProfilingPage;
};
beforeEach(() => {
store = mockStore(initialState);
configure({
loggingService: { logError: jest.fn() },
config: {
ENVIRONMENT: 'production',
LANGUAGE_PREFERENCE_COOKIE_NAME: 'yum',
},
messages: { 'es-419': {}, de: {}, 'en-us': {} },
});
props = {
getFieldData: jest.fn(),
location: {
state: {
registrationResult,
optionalFields,
},
},
};
});
it('not should display button "Learn more about how we use this information."', async () => {
mergeConfig({
AUTHN_PROGRESSIVE_PROFILING_SUPPORT_LINK: '',
});
const progressiveProfilingPage = await getProgressiveProfilingPage();
expect(progressiveProfilingPage.find('a.pgn__hyperlink').exists()).toBeFalsy();
});
it('should display button "Learn more about how we use this information."', async () => {
mergeConfig({
AUTHN_PROGRESSIVE_PROFILING_SUPPORT_LINK: 'http://localhost:1999/support',
});
const progressiveProfilingPage = await getProgressiveProfilingPage();
expect(progressiveProfilingPage.find('a.pgn__hyperlink').text()).toEqual('Learn more about how we use this information.');
});
it('should render fields returned by backend api', async () => {
const progressiveProfilingPage = await getProgressiveProfilingPage();
expect(progressiveProfilingPage.find('#gender').exists()).toBeTruthy();
});
it('should make identify call to segment on progressive profiling page', async () => {
await getProgressiveProfilingPage();
expect(analytics.identifyAuthenticatedUser).toHaveBeenCalled();
});
it('should submit user profile details on form submission', async () => {
auth.getAuthenticatedUser = jest.fn(() => ({ userId: 3, username: 'abc123' }));
const formPayload = {
gender: 'm',
extended_profile: [{ field_name: 'company', field_value: 'test company' }],
};
store.dispatch = jest.fn(store.dispatch);
const progressiveProfilingPage = await getProgressiveProfilingPage();
progressiveProfilingPage.find('select#gender').simulate('change', { target: { value: 'm', name: 'gender' } });
progressiveProfilingPage.find('input#company').simulate('change', { target: { value: 'test company', name: 'company' } });
progressiveProfilingPage.find('button.btn-brand').simulate('click');
expect(store.dispatch).toHaveBeenCalledWith(saveUserProfile('abc123', formPayload));
});
it('should open modal on pressing skip for now button', async () => {
const progressiveProfilingPage = await getProgressiveProfilingPage();
progressiveProfilingPage.find('button.btn-link').simulate('click');
expect(progressiveProfilingPage.find('.pgn__modal-content-container').exists()).toBeTruthy();
expect(analytics.sendTrackEvent).toHaveBeenCalledWith('edx.bi.welcome.page.skip.link.clicked');
});
it('should send analytic event for support link click', async () => {
const progressiveProfilingPage = await getProgressiveProfilingPage();
progressiveProfilingPage.find('.progressive-profiling-support a[target="_blank"]').simulate('click');
expect(analytics.sendTrackEvent).toHaveBeenCalledWith('edx.bi.welcome.page.support.link.clicked');
});
it('should show error message when patch request fails', async () => {
store = mockStore({
welcomePage: {
...initialState.welcomePage,
showError: true,
},
});
const progressiveProfilingPage = await getProgressiveProfilingPage();
expect(progressiveProfilingPage.find('#pp-page-errors').exists()).toBeTruthy();
});
it('should redirect to dashboard if no form fields are configured', async () => {
store = mockStore({
welcomePage: {
formRenderState: FAILURE_STATE,
},
});
delete window.location;
window.location = {
href: getConfig().BASE_URL,
assign: jest.fn().mockImplementation((value) => { window.location.href = value; }),
};
await getProgressiveProfilingPage();
expect(window.location.href).toBe(DASHBOARD_URL);
});
describe('Recommendations test', () => {
mergeConfig({
ENABLE_PERSONALIZED_RECOMMENDATIONS: true,
});
it.skip('should redirect to recommendations page if recommendations are enabled', async () => {
store = mockStore({
welcomePage: {
...initialState.welcomePage,
success: true,
},
});
auth.getAuthenticatedUser = jest.fn(() => ({ userId: 3, username: 'abc123' }));
const progressiveProfilingPage = await getProgressiveProfilingPage();
expect(progressiveProfilingPage.find('button.btn-brand').text()).toEqual('Next');
expect(history.location.pathname).toEqual(RECOMMENDATIONS);
});
it('should not redirect to recommendations page if user is on its way to enroll in a course', async () => {
delete window.location;
window.location = {
href: getConfig().BASE_URL,
assign: jest.fn().mockImplementation((value) => { window.location.href = value; }),
};
const redirectUrl = `${getConfig().LMS_BASE_URL}${DEFAULT_REDIRECT_URL}?enrollment_action=1`;
props = {
getFieldData: jest.fn(),
location: {
state: {
registrationResult: {
redirectUrl,
success: true,
},
optionalFields,
},
},
};
store = mockStore({
welcomePage: {
...initialState.welcomePage,
success: true,
},
});
auth.getAuthenticatedUser = jest.fn(() => ({ userId: 3, username: 'abc123' }));
const progressiveProfilingPage = await getProgressiveProfilingPage();
expect(progressiveProfilingPage.find('button.btn-brand').text()).toEqual('Submit');
expect(window.location.href).toEqual(redirectUrl);
});
});
});