feat: showing course unenroll survey is configurable now (#738)
This commit is contained in:
1
.env
1
.env
@@ -42,5 +42,6 @@ CAREER_LINK_URL=''
|
|||||||
ENABLE_EDX_PERSONAL_DASHBOARD=false
|
ENABLE_EDX_PERSONAL_DASHBOARD=false
|
||||||
ENABLE_PROGRAMS=false
|
ENABLE_PROGRAMS=false
|
||||||
NON_BROWSABLE_COURSES=false
|
NON_BROWSABLE_COURSES=false
|
||||||
|
SHOW_UNENROLL_SURVEY=true
|
||||||
# Fallback in local style files
|
# Fallback in local style files
|
||||||
PARAGON_THEME_URLS={}
|
PARAGON_THEME_URLS={}
|
||||||
|
|||||||
@@ -48,5 +48,6 @@ CAREER_LINK_URL=''
|
|||||||
ENABLE_EDX_PERSONAL_DASHBOARD=false
|
ENABLE_EDX_PERSONAL_DASHBOARD=false
|
||||||
ENABLE_PROGRAMS=false
|
ENABLE_PROGRAMS=false
|
||||||
NON_BROWSABLE_COURSES=false
|
NON_BROWSABLE_COURSES=false
|
||||||
|
SHOW_UNENROLL_SURVEY=true
|
||||||
# Fallback in local style files
|
# Fallback in local style files
|
||||||
PARAGON_THEME_URLS={}
|
PARAGON_THEME_URLS={}
|
||||||
|
|||||||
@@ -47,4 +47,5 @@ CAREER_LINK_URL=''
|
|||||||
ENABLE_EDX_PERSONAL_DASHBOARD=true
|
ENABLE_EDX_PERSONAL_DASHBOARD=true
|
||||||
ENABLE_PROGRAMS=false
|
ENABLE_PROGRAMS=false
|
||||||
NON_BROWSABLE_COURSES=false
|
NON_BROWSABLE_COURSES=false
|
||||||
|
SHOW_UNENROLL_SURVEY=true
|
||||||
PARAGON_THEME_URLS={}
|
PARAGON_THEME_URLS={}
|
||||||
|
|||||||
@@ -70,4 +70,5 @@ module.exports = {
|
|||||||
ACCOUNT_PROFILE_URL: 'http://localhost:1995',
|
ACCOUNT_PROFILE_URL: 'http://localhost:1995',
|
||||||
CAREER_LINK_URL: '',
|
CAREER_LINK_URL: '',
|
||||||
EXPERIMENT_08_23_VAN_PAINTED_DOOR: true,
|
EXPERIMENT_08_23_VAN_PAINTED_DOOR: true,
|
||||||
|
SHOW_UNENROLL_SURVEY: true
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ const configuration = {
|
|||||||
SEARCH_CATALOG_URL: process.env.SEARCH_CATALOG_URL || null,
|
SEARCH_CATALOG_URL: process.env.SEARCH_CATALOG_URL || null,
|
||||||
ENABLE_PROGRAMS: process.env.ENABLE_PROGRAMS === 'true',
|
ENABLE_PROGRAMS: process.env.ENABLE_PROGRAMS === 'true',
|
||||||
NON_BROWSABLE_COURSES: process.env.NON_BROWSABLE_COURSES === 'true',
|
NON_BROWSABLE_COURSES: process.env.NON_BROWSABLE_COURSES === 'true',
|
||||||
|
SHOW_UNENROLL_SURVEY: process.env.SHOW_UNENROLL_SURVEY === 'true',
|
||||||
};
|
};
|
||||||
|
|
||||||
const features = {};
|
const features = {};
|
||||||
|
|||||||
@@ -2,7 +2,9 @@ import React from 'react';
|
|||||||
|
|
||||||
import { StrictDict } from 'utils';
|
import { StrictDict } from 'utils';
|
||||||
|
|
||||||
import { useInitializeLearnerHome } from 'data/hooks';
|
import { useInitializeLearnerHome, useUnenrollFromCourse } from 'data/hooks';
|
||||||
|
import { configuration } from 'config';
|
||||||
|
import { useCourseData } from 'hooks';
|
||||||
import { useUnenrollReasons } from './reasons';
|
import { useUnenrollReasons } from './reasons';
|
||||||
import * as module from '.';
|
import * as module from '.';
|
||||||
|
|
||||||
@@ -18,13 +20,23 @@ export const modalStates = StrictDict({
|
|||||||
|
|
||||||
export const useUnenrollData = ({ closeModal, cardId }) => {
|
export const useUnenrollData = ({ closeModal, cardId }) => {
|
||||||
const [isConfirmed, setIsConfirmed] = module.state.confirmed(false);
|
const [isConfirmed, setIsConfirmed] = module.state.confirmed(false);
|
||||||
const confirm = () => setIsConfirmed(true);
|
|
||||||
const reason = useUnenrollReasons({ cardId });
|
const reason = useUnenrollReasons({ cardId });
|
||||||
const { refetch: refreshList } = useInitializeLearnerHome();
|
const { refetch: refreshList } = useInitializeLearnerHome();
|
||||||
|
const courseData = useCourseData(cardId);
|
||||||
|
const courseId = courseData?.courseRun?.courseId;
|
||||||
|
|
||||||
|
const { mutate: unenrollFromCourse } = useUnenrollFromCourse();
|
||||||
|
|
||||||
|
const confirm = () => {
|
||||||
|
if (!configuration.SHOW_UNENROLL_SURVEY) {
|
||||||
|
unenrollFromCourse({ courseId });
|
||||||
|
}
|
||||||
|
setIsConfirmed(true);
|
||||||
|
};
|
||||||
|
|
||||||
let modalState;
|
let modalState;
|
||||||
if (isConfirmed) {
|
if (isConfirmed) {
|
||||||
modalState = (reason.isSubmitted)
|
modalState = (reason.isSubmitted || !configuration.SHOW_UNENROLL_SURVEY)
|
||||||
? modalStates.finished : modalStates.reason;
|
? modalStates.finished : modalStates.reason;
|
||||||
} else {
|
} else {
|
||||||
modalState = modalStates.confirm;
|
modalState = modalStates.confirm;
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
import { MockUseState } from 'testUtils';
|
import { MockUseState } from 'testUtils';
|
||||||
|
import { configuration } from 'config';
|
||||||
|
|
||||||
import { useInitializeLearnerHome } from 'data/hooks';
|
import { useInitializeLearnerHome, useUnenrollFromCourse } from 'data/hooks';
|
||||||
|
import { useCourseData } from 'hooks';
|
||||||
|
|
||||||
import * as reasons from './reasons';
|
import * as reasons from './reasons';
|
||||||
import * as hooks from '.';
|
import * as hooks from '.';
|
||||||
@@ -11,12 +13,26 @@ jest.mock('./reasons', () => ({
|
|||||||
|
|
||||||
jest.mock('data/hooks', () => ({
|
jest.mock('data/hooks', () => ({
|
||||||
useInitializeLearnerHome: jest.fn(),
|
useInitializeLearnerHome: jest.fn(),
|
||||||
|
useUnenrollFromCourse: jest.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
|
jest.mock('hooks', () => ({
|
||||||
|
useCourseData: jest.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
|
jest.mock('config', () => ({
|
||||||
|
configuration: {
|
||||||
|
SHOW_UNENROLL_SURVEY: true,
|
||||||
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const state = new MockUseState(hooks);
|
const state = new MockUseState(hooks);
|
||||||
const testValue = 'test-value';
|
const testValue = 'test-value';
|
||||||
const mockRefreshList = jest.fn();
|
const mockRefreshList = jest.fn();
|
||||||
|
const unenrollFromCourse = jest.fn();
|
||||||
useInitializeLearnerHome.mockReturnValue({ refetch: mockRefreshList });
|
useInitializeLearnerHome.mockReturnValue({ refetch: mockRefreshList });
|
||||||
|
useUnenrollFromCourse.mockReturnValue({ mutate: unenrollFromCourse });
|
||||||
|
useCourseData.mockReturnValue({ courseRun: { courseId: 'test-course-id' } });
|
||||||
let out;
|
let out;
|
||||||
|
|
||||||
const mockReason = {
|
const mockReason = {
|
||||||
@@ -78,22 +94,66 @@ describe('UnenrollConfirmModal hooks', () => {
|
|||||||
expect(mockRefreshList).toHaveBeenCalled();
|
expect(mockRefreshList).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('modalState', () => {
|
});
|
||||||
it('returns modalStates.finished if confirmed and submitted', () => {
|
|
||||||
|
describe('SHOW_UNENROLL_SURVEY configuration tests', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
state.mock();
|
||||||
|
jest.clearAllMocks();
|
||||||
|
});
|
||||||
|
afterEach(() => {
|
||||||
|
state.restore();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when SHOW_UNENROLL_SURVEY is true (default)', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
configuration.SHOW_UNENROLL_SURVEY = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
test('confirm does not call unenrollFromCourse immediately', () => {
|
||||||
|
out = createUseUnenrollData();
|
||||||
|
out.confirm();
|
||||||
|
expect(unenrollFromCourse).not.toHaveBeenCalled();
|
||||||
|
expect(state.setState.confirmed).toHaveBeenCalledWith(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('modalState returns reason when confirmed but not submitted', () => {
|
||||||
|
state.mockVal(state.keys.confirmed, true);
|
||||||
|
reasons.useUnenrollReasons.mockReturnValueOnce({ ...mockReason, isSubmitted: false });
|
||||||
|
out = createUseUnenrollData();
|
||||||
|
expect(out.modalState).toEqual(hooks.modalStates.reason);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('modalState returns finished when confirmed and submitted', () => {
|
||||||
state.mockVal(state.keys.confirmed, true);
|
state.mockVal(state.keys.confirmed, true);
|
||||||
reasons.useUnenrollReasons.mockReturnValueOnce({ ...mockReason, isSubmitted: true });
|
reasons.useUnenrollReasons.mockReturnValueOnce({ ...mockReason, isSubmitted: true });
|
||||||
out = createUseUnenrollData();
|
out = createUseUnenrollData();
|
||||||
expect(out.modalState).toEqual(hooks.modalStates.finished);
|
expect(out.modalState).toEqual(hooks.modalStates.finished);
|
||||||
});
|
});
|
||||||
it('returns modalStates.reason if confirmed and not submitted', () => {
|
});
|
||||||
state.mockVal(state.keys.confirmed, true);
|
|
||||||
out = createUseUnenrollData();
|
describe('when SHOW_UNENROLL_SURVEY is false', () => {
|
||||||
expect(out.modalState).toEqual(hooks.modalStates.reason);
|
beforeEach(() => {
|
||||||
|
configuration.SHOW_UNENROLL_SURVEY = false;
|
||||||
});
|
});
|
||||||
it('returns modalStates.confirm if not confirmed', () => {
|
|
||||||
state.mockVal(state.keys.confirmed, false);
|
afterEach(() => {
|
||||||
|
// Reset to default
|
||||||
|
configuration.SHOW_UNENROLL_SURVEY = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
test('confirm calls unenrollFromCourse immediately', () => {
|
||||||
out = createUseUnenrollData();
|
out = createUseUnenrollData();
|
||||||
expect(out.modalState).toEqual(hooks.modalStates.confirm);
|
out.confirm();
|
||||||
|
expect(unenrollFromCourse).toHaveBeenCalled();
|
||||||
|
expect(state.setState.confirmed).toHaveBeenCalledWith(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('modalState returns finished when confirmed regardless of submission status', () => {
|
||||||
|
state.mockVal(state.keys.confirmed, true);
|
||||||
|
reasons.useUnenrollReasons.mockReturnValueOnce({ ...mockReason, isSubmitted: false });
|
||||||
|
out = createUseUnenrollData();
|
||||||
|
expect(out.modalState).toEqual(hooks.modalStates.finished);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user