feat: redux hooks
This commit is contained in:
@@ -4,7 +4,11 @@ import { actionHook } from './utils';
|
||||
|
||||
const app = StrictDict({
|
||||
useSetLocalFilter: actionHook(actions.app.setLocalFilter),
|
||||
useSetSearchValue: actionHook(actions.app.setSearchValue),
|
||||
useSetShowImportSuccessToast: actionHook(actions.app.setShowImportSuccessToast),
|
||||
useSetView: actionHook(actions.app.setView),
|
||||
useCloseModal: actionHook(actions.app.closeModal),
|
||||
useSetModalState: actionHook(actions.app.setModalState),
|
||||
});
|
||||
|
||||
const filters = StrictDict({
|
||||
@@ -15,12 +19,15 @@ const filters = StrictDict({
|
||||
useUpdateCourseGradeLimits: actionHook(actions.filters.update.courseGradeLimits),
|
||||
useUpdateIncludeCourseRoleMembers: actionHook(actions.filters.update.includeCourseRoleMembers),
|
||||
useUpdateTrack: actionHook(actions.filters.update.track),
|
||||
useResetFilters: actionHook(actions.filters.reset),
|
||||
});
|
||||
|
||||
const grades = StrictDict({
|
||||
downloadReport: {
|
||||
useBulkGrades: actionHook(actions.grades.downloadReport.bulkGrades),
|
||||
},
|
||||
useDoneViewingAssignment: actionHook(actions.grades.doneViewingAssignment),
|
||||
useDownloadBulkGradesReport: actionHook(actions.grades.downloadReport.bulkGrades),
|
||||
useDownloadInterventionReport: actionHook(actions.grades.downloadReport.intervention),
|
||||
useToggleGradeFormat: actionHook(actions.grades.toggleGradeFormat),
|
||||
useCloseBanner: actionHook(actions.grades.banner.close),
|
||||
});
|
||||
|
||||
export default StrictDict({
|
||||
|
||||
@@ -4,23 +4,6 @@ import actions from 'data/actions';
|
||||
import { actionHook } from './utils';
|
||||
import actionHooks from './actions';
|
||||
|
||||
jest.mock('data/actions', () => ({
|
||||
app: {
|
||||
setLocalFilter: jest.fn(),
|
||||
setView: jest.fn(),
|
||||
},
|
||||
filters: {
|
||||
update: {
|
||||
assignment: jest.fn(),
|
||||
assignmentLimits: jest.fn(),
|
||||
},
|
||||
},
|
||||
grades: {
|
||||
downloadReport: {
|
||||
bulkGrades: jest.fn(),
|
||||
},
|
||||
},
|
||||
}));
|
||||
jest.mock('./utils', () => ({
|
||||
actionHook: (action) => ({ actionHook: action }),
|
||||
}));
|
||||
@@ -30,6 +13,7 @@ let hooks;
|
||||
const testActionHook = (hookKey, action) => {
|
||||
test(hookKey, () => {
|
||||
expect(hooks[hookKey]).toEqual(actionHook(action));
|
||||
expect(hooks[hookKey]).not.toEqual(undefined);
|
||||
});
|
||||
};
|
||||
|
||||
@@ -38,7 +22,11 @@ describe('action hooks', () => {
|
||||
const hookKeys = keyStore(actionHooks.app);
|
||||
beforeEach(() => { hooks = actionHooks.app; });
|
||||
testActionHook(hookKeys.useSetLocalFilter, actions.app.setLocalFilter);
|
||||
testActionHook(hookKeys.useSetSearchValue, actions.app.setSearchValue);
|
||||
testActionHook(hookKeys.useSetShowImportSuccessToast, actions.app.setShowImportSuccessToast);
|
||||
testActionHook(hookKeys.useSetView, actions.app.setView);
|
||||
testActionHook(hookKeys.useCloseModal, actions.app.closeModal);
|
||||
testActionHook(hookKeys.useSetModalState, actions.app.setModalState);
|
||||
});
|
||||
describe('filters', () => {
|
||||
const hookKeys = keyStore(actionHooks.filters);
|
||||
@@ -46,19 +34,23 @@ describe('action hooks', () => {
|
||||
beforeEach(() => { hooks = actionHooks.filters; });
|
||||
testActionHook(hookKeys.useUpdateAssignment, actionGroup.assignment);
|
||||
testActionHook(hookKeys.useUpdateAssignmentLimits, actionGroup.assignmentLimits);
|
||||
testActionHook(hookKeys.useUpdateCohort, actionGroup.updateCohort);
|
||||
testActionHook(hookKeys.useUpdateAssignmentType, actionGroup.assignmentType);
|
||||
testActionHook(hookKeys.useUpdateCohort, actionGroup.cohort);
|
||||
testActionHook(hookKeys.useUpdateCourseGradeLimits, actionGroup.courseGradeLimits);
|
||||
testActionHook(
|
||||
hookKeys.useUpdateIncludeCourseRoleMembers,
|
||||
actionGroup.updateIncludeCourseRoleMembers,
|
||||
actionGroup.includeCourseRoleMembers,
|
||||
);
|
||||
testActionHook(hookKeys.useUpdateTrack, actionGroup.updateTrack);
|
||||
testActionHook(hookKeys.useResetFilters, actions.filters.reset);
|
||||
});
|
||||
describe('grades', () => {
|
||||
const hookKeys = keyStore(actionHooks.grades);
|
||||
const actionGroup = actions.grades;
|
||||
beforeEach(() => { hooks = actionHooks.grades; });
|
||||
test('downloadReport.useBulkGrades', () => {
|
||||
expect(hooks.downloadReport.useBulkGrades)
|
||||
.toEqual(actionHook(actions.grades.downloadReport.bulkGrades));
|
||||
});
|
||||
testActionHook(hookKeys.useDoneViewingAssignment, actionGroup.doneViewingAssignment);
|
||||
testActionHook(hookKeys.useDownloadBulkGradesReport, actionGroup.downloadReport.bulkGrades);
|
||||
testActionHook(hookKeys.useDownloadInterventionReport, actionGroup.downloadReport.intervention);
|
||||
testActionHook(hookKeys.useToggleGradeFormat, actionGroup.toggleGradeFormat);
|
||||
testActionHook(hookKeys.useCloseBanner, actionGroup.banner.close);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -3,48 +3,75 @@ import { useSelector } from 'react-redux';
|
||||
import { StrictDict } from 'utils';
|
||||
import selectors from 'data/selectors';
|
||||
|
||||
const selectorHook = (selector) => () => useSelector(selector);
|
||||
|
||||
export const root = StrictDict({
|
||||
useGradeExportUrl: () => useSelector(selectors.root.gradeExportUrl),
|
||||
useSelectedCohortEntry: () => useSelector(selectors.root.selectedCohortEntry),
|
||||
useSelectedTrackEntry: () => useSelector(selectors.root.selectedTrackEntry),
|
||||
useShowBulkManagement: () => useSelector(selectors.root.showBulkManagement),
|
||||
useEditModalPossibleGrade: selectorHook(selectors.root.editModalPossibleGrade),
|
||||
useGetHeadings: selectorHook(selectors.root.getHeadings),
|
||||
useGradeExportUrl: selectorHook(selectors.root.gradeExportUrl),
|
||||
useInterventionExportUrl: selectorHook(selectors.root.interventionExportUrl),
|
||||
useSelectedCohortEntry: selectorHook(selectors.root.selectedCohortEntry),
|
||||
useSelectedTrackEntry: selectorHook(selectors.root.selectedTrackEntry),
|
||||
useShouldShowSpinner: selectorHook(selectors.root.shouldShowSpinner),
|
||||
useShowBulkManagement: selectorHook(selectors.root.showBulkManagement),
|
||||
useFilterBadgeConfig: (filterName) => useSelector(
|
||||
(state) => selectors.root.filterBadgeConfig(state, filterName),
|
||||
),
|
||||
});
|
||||
|
||||
export const app = StrictDict({
|
||||
useActiveView: () => useSelector(selectors.app.activeView),
|
||||
useAssignmentGradeLimits: () => useSelector(selectors.app.assignmentGradeLimits),
|
||||
useAreCourseGradeFiltersValid: () => useSelector(selectors.app.areCourseGradeFiltersValid),
|
||||
useCourseGradeLimits: () => useSelector(selectors.app.courseGradeLimits),
|
||||
useCourseId: () => useSelector(selectors.app.courseId),
|
||||
useActiveView: selectorHook(selectors.app.activeView),
|
||||
useAssignmentGradeLimits: selectorHook(selectors.app.assignmentGradeLimits),
|
||||
useAreCourseGradeFiltersValid: selectorHook(selectors.app.areCourseGradeFiltersValid),
|
||||
useCourseGradeLimits: selectorHook(selectors.app.courseGradeLimits),
|
||||
useCourseGradeFilterValidity: selectorHook(selectors.app.courseGradeFilterValidity),
|
||||
useCourseId: selectorHook(selectors.app.courseId),
|
||||
useModalData: selectorHook(selectors.app.modalData),
|
||||
useSearchValue: selectorHook(selectors.app.searchValue),
|
||||
useShowImportSuccessToast: selectorHook(selectors.app.showImportSuccessToast),
|
||||
});
|
||||
|
||||
export const assignmentTypes = StrictDict({
|
||||
useAllAssignmentTypes: () => useSelector(selectors.assignmentTypes.allAssignmentTypes),
|
||||
useAreGradesFrozen: () => useSelector(selectors.assignmentTypes.areGradesFrozen),
|
||||
useAllAssignmentTypes: selectorHook(selectors.assignmentTypes.allAssignmentTypes),
|
||||
useAreGradesFrozen: selectorHook(selectors.assignmentTypes.areGradesFrozen),
|
||||
});
|
||||
|
||||
export const cohorts = StrictDict({
|
||||
useAllCohorts: () => useSelector(selectors.cohorts.allCohorts),
|
||||
useAllCohorts: selectorHook(selectors.cohorts.allCohorts),
|
||||
// maybe not needed?
|
||||
useCohortsByName: () => useSelector(selectors.cohorts.cohortsByName),
|
||||
useCohortsByName: selectorHook(selectors.cohorts.cohortsByName),
|
||||
});
|
||||
|
||||
export const filters = StrictDict({
|
||||
useData: () => useSelector(selectors.filters.allFilters),
|
||||
useIncludeCourseRoleMembers: () => useSelector(selectors.filters.includeCourseRoleMembers),
|
||||
useSelectableAssignmentLabels: () => useSelector(selectors.filters.selectableAssignmentLabels),
|
||||
useSelectedAssignmentLabel: () => useSelector(selectors.filters.selectedAssignmentLabel),
|
||||
useAssignmentType: () => useSelector(selectors.filters.assignmentType),
|
||||
useData: selectorHook(selectors.filters.allFilters),
|
||||
useIncludeCourseRoleMembers: selectorHook(selectors.filters.includeCourseRoleMembers),
|
||||
useSelectableAssignmentLabels: selectorHook(selectors.filters.selectableAssignmentLabels),
|
||||
useSelectedAssignmentLabel: selectorHook(selectors.filters.selectedAssignmentLabel),
|
||||
useAssignmentType: selectorHook(selectors.filters.assignmentType),
|
||||
});
|
||||
|
||||
export const grades = StrictDict({
|
||||
useAllGrades: selectorHook(selectors.grades.allGrades),
|
||||
useUserCounts: () => ({
|
||||
filteredUsersCount: useSelector(selectors.grades.filteredUsersCount),
|
||||
totalUsersCount: useSelector(selectors.grades.totalUsersCount),
|
||||
}),
|
||||
useGradeData: selectorHook(selectors.grades.gradeData),
|
||||
useHasOverrideErrors: selectorHook(selectors.grades.hasOverrideErrors),
|
||||
useShowSuccess: selectorHook(selectors.grades.showSuccess),
|
||||
useSubsectionGrade: ({ gradeFormat, subsection }) => () => (
|
||||
selectors.grades.subsectionGrade[gradeFormat](subsection)
|
||||
),
|
||||
});
|
||||
|
||||
export const roles = StrictDict({
|
||||
useCanUserViewGradebook: () => useSelector(selectors.roles.canUserViewGradebook),
|
||||
useCanUserViewGradebook: selectorHook(selectors.roles.canUserViewGradebook),
|
||||
});
|
||||
|
||||
export const tracks = StrictDict({
|
||||
useAllTracks: () => useSelector(selectors.tracks.allTracks),
|
||||
useAllTracks: selectorHook(selectors.tracks.allTracks),
|
||||
// maybe not needed?
|
||||
useTracksByName: () => useSelector(selectors.tracks.tracksByName),
|
||||
useTracksByName: selectorHook(selectors.tracks.tracksByName),
|
||||
});
|
||||
|
||||
export default StrictDict({
|
||||
@@ -52,6 +79,7 @@ export default StrictDict({
|
||||
assignmentTypes,
|
||||
cohorts,
|
||||
filters,
|
||||
grades,
|
||||
roles,
|
||||
tracks,
|
||||
root,
|
||||
|
||||
@@ -7,104 +7,102 @@ jest.mock('react-redux', () => ({
|
||||
useSelector: (selector) => ({ useSelector: selector }),
|
||||
}));
|
||||
|
||||
jest.mock('data/selectors', () => ({
|
||||
app: {
|
||||
activeView: jest.fn(),
|
||||
assignmentGradeLimits: jest.fn(),
|
||||
areCourseGradeFiltersValid: jest.fn(),
|
||||
courseGradelimits: jest.fn(),
|
||||
courseId: jest.fn(),
|
||||
},
|
||||
assignmentTypes: {
|
||||
allAssignmentTypes: jest.fn(),
|
||||
areGradesFrozen: jest.fn(),
|
||||
},
|
||||
cohorts: {
|
||||
allCohorts: jest.fn(),
|
||||
cohortsByName: jest.fn(),
|
||||
},
|
||||
filters: {
|
||||
allFilters: jest.fn(),
|
||||
includeCourseRoleMembers: jest.fn(),
|
||||
selectableAssignmentLabels: jest.fn(),
|
||||
selectedAssignmentLabel: jest.fn(),
|
||||
assignmentType: jest.fn(),
|
||||
},
|
||||
roles: {
|
||||
canUserViewGradebook: jest.fn(),
|
||||
},
|
||||
tracks: {
|
||||
allTracks: jest.fn(),
|
||||
tracksByName: jest.fn(),
|
||||
},
|
||||
root: {
|
||||
gradeExportUrl: jest.fn(),
|
||||
selectedCohortEntry: jest.fn(),
|
||||
selectedTrackEntry: jest.fn(),
|
||||
showBulkManagement: jest.fn(),
|
||||
},
|
||||
}));
|
||||
const testValue = 'test-value';
|
||||
const testState = { test: 'state value' };
|
||||
|
||||
let hookKeys;
|
||||
let hooks;
|
||||
const testHook = (hookKey, selector) => {
|
||||
test(hookKey, () => {
|
||||
expect(hooks[hookKey]()).toEqual(useSelector(selector));
|
||||
let selKeys;
|
||||
let selectorGroup;
|
||||
|
||||
const loadSelectorGroup = (hookGroup, selGroup) => {
|
||||
hookKeys = keyStore(hookGroup);
|
||||
selKeys = keyStore(selGroup);
|
||||
beforeEach(() => {
|
||||
hooks = hookGroup;
|
||||
selectorGroup = selGroup;
|
||||
});
|
||||
};
|
||||
|
||||
const testHook = (hookKey, selectorKey) => {
|
||||
test(hookKey, () => {
|
||||
expect(hooks[hookKey]()).toEqual(useSelector(selectorGroup[selectorKey]));
|
||||
});
|
||||
};
|
||||
|
||||
describe('selector hooks', () => {
|
||||
describe('root selectors', () => {
|
||||
const hookKeys = keyStore(selectorHooks.root);
|
||||
beforeEach(() => { hooks = selectorHooks.root; });
|
||||
testHook(hookKeys.useGradeExportUrl, selectors.root.gradeExportUrl);
|
||||
testHook(hookKeys.useSelectedCohortEntry, selectors.root.selectedCohortEntry);
|
||||
testHook(hookKeys.useSelectedTrackEntry, selectors.root.selectedTrackEntry);
|
||||
testHook(hookKeys.useShowBulkManagement, selectors.root.showBulkManagement);
|
||||
loadSelectorGroup(selectorHooks.root, selectors.root);
|
||||
testHook(hookKeys.useEditModalPossibleGrade, selKeys.editModalPossibleGrade);
|
||||
testHook(hookKeys.useGetHeadings, selKeys.getHeadings);
|
||||
testHook(hookKeys.useGradeExportUrl, selKeys.gradeExportUrl);
|
||||
testHook(hookKeys.useInterventionExportUrl, selKeys.interventionExportUrl);
|
||||
testHook(hookKeys.useSelectedCohortEntry, selKeys.selectedCohortEntry);
|
||||
testHook(hookKeys.useSelectedTrackEntry, selKeys.selectedTrackEntry);
|
||||
testHook(hookKeys.useShouldShowSpinner, selKeys.shouldShowSpinner);
|
||||
testHook(hookKeys.useShowBulkManagement, selKeys.showBulkManagement);
|
||||
describe(hookKeys.useFilterBadgeConfig, () => {
|
||||
test('calls filterBadgeConfig selector with passed filterName', () => {
|
||||
const filterBadgeConfig = (state, filterName) => ({
|
||||
filterBadgeConfig: { state, filterName },
|
||||
});
|
||||
const rootKeys = keyStore(selectors.root);
|
||||
jest.spyOn(selectors.root, rootKeys.filterBadgeConfig)
|
||||
.mockImplementation(filterBadgeConfig);
|
||||
const out = hooks.useFilterBadgeConfig(testValue);
|
||||
expect(out.useSelector(testState)).toEqual(filterBadgeConfig(testState, testValue));
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('app', () => {
|
||||
const hookKeys = keyStore(selectorHooks.app);
|
||||
const selGroup = selectors.app;
|
||||
beforeEach(() => { hooks = selectorHooks.app; });
|
||||
testHook(hookKeys.useActiveView, selGroup.activeView);
|
||||
testHook(hookKeys.useAssignmentGradeLimits, selGroup.assignmentGradeLimits);
|
||||
testHook(hookKeys.useAreCourseGradeFiltersValid, selGroup.areCourseGradeFiltersValid);
|
||||
testHook(hookKeys.useCourseGradeLimits, selGroup.courseGradeLimits);
|
||||
testHook(hookKeys.useCourseId, selGroup.courseId);
|
||||
loadSelectorGroup(selectorHooks.app, selectors.app);
|
||||
testHook(hookKeys.useActiveView, selKeys.activeView);
|
||||
testHook(hookKeys.useAssignmentGradeLimits, selKeys.assignmentGradeLimits);
|
||||
testHook(hookKeys.useAreCourseGradeFiltersValid, selKeys.areCourseGradeFiltersValid);
|
||||
testHook(hookKeys.useCourseGradeLimits, selKeys.courseGradeLimits);
|
||||
testHook(hookKeys.useCourseId, selKeys.courseId);
|
||||
testHook(hookKeys.useModalData, selKeys.modalData);
|
||||
testHook(hookKeys.useSearchValue, selKeys.searchValue);
|
||||
testHook(hookKeys.useShowImportSuccessToast, selKeys.showImportSuccessToast);
|
||||
});
|
||||
describe('assignmentTypes', () => {
|
||||
const hookKeys = keyStore(selectorHooks.assignmentTypes);
|
||||
const selGroup = selectors.assignmentTypes;
|
||||
beforeEach(() => { hooks = selectorHooks.assignmentTypes; });
|
||||
testHook(hookKeys.useAllAssignmentTypes, selGroup.allAssignmentTypes);
|
||||
testHook(hookKeys.useAreGradesFrozen, selGroup.areGradesFrozen);
|
||||
loadSelectorGroup(selectorHooks.assignmentTypes, selectors.assignmentTypes);
|
||||
testHook(hookKeys.useAllAssignmentTypes, selKeys.allAssignmentTypes);
|
||||
testHook(hookKeys.useAreGradesFrozen, selKeys.areGradesFrozen);
|
||||
});
|
||||
describe('cohorts', () => {
|
||||
const hookKeys = keyStore(selectorHooks.cohorts);
|
||||
const selGroup = selectors.cohorts;
|
||||
beforeEach(() => { hooks = selectorHooks.cohorts; });
|
||||
testHook(hookKeys.useAllCohorts, selGroup.allCohorts);
|
||||
testHook(hookKeys.useCohortsByName, selGroup.cohortsByName);
|
||||
loadSelectorGroup(selectorHooks.cohorts, selectors.cohorts);
|
||||
testHook(hookKeys.useAllCohorts, selKeys.allCohorts);
|
||||
testHook(hookKeys.useCohortsByName, selKeys.cohortsByName);
|
||||
});
|
||||
describe('filters', () => {
|
||||
const hookKeys = keyStore(selectorHooks.filters);
|
||||
const selGroup = selectors.filters;
|
||||
beforeEach(() => { hooks = selectorHooks.filters; });
|
||||
testHook(hookKeys.useData, selGroup.allFilters);
|
||||
testHook(hookKeys.useIncludeCourseRoleMembers, selGroup.includeCourseRoleMembers);
|
||||
testHook(hookKeys.useSelectableAssignmentLabels, selGroup.selectableAssignmentLabels);
|
||||
testHook(hookKeys.useSelectedAssignmentLabel, selGroup.selectedAssignmentLabel);
|
||||
testHook(hookKeys.useAssignmentType, selGroup.assignmentType);
|
||||
loadSelectorGroup(selectorHooks.filters, selectors.filters);
|
||||
testHook(hookKeys.useData, selKeys.allFilters);
|
||||
testHook(hookKeys.useIncludeCourseRoleMembers, selKeys.includeCourseRoleMembers);
|
||||
testHook(hookKeys.useSelectableAssignmentLabels, selKeys.selectableAssignmentLabels);
|
||||
testHook(hookKeys.useSelectedAssignmentLabel, selKeys.selectedAssignmentLabel);
|
||||
testHook(hookKeys.useAssignmentType, selKeys.assignmentType);
|
||||
});
|
||||
describe('grades', () => {
|
||||
loadSelectorGroup(selectorHooks.grades, selectors.grades);
|
||||
testHook(hookKeys.useAllGrades, selKeys.allGrades);
|
||||
testHook(hookKeys.useGradeData, selKeys.gradeData);
|
||||
testHook(hookKeys.useHasOverrideErrors, selKeys.hasOverrideErrors);
|
||||
testHook(hookKeys.useShowSuccess, selKeys.showSuccess);
|
||||
test(hookKeys.useUserCounts, () => {
|
||||
expect(hooks.useUserCounts()).toEqual({
|
||||
filteredUsersCount: useSelector(selectors.grades.filteredUsersCount),
|
||||
totalUsersCount: useSelector(selectors.grades.totalUsersCount),
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('roles', () => {
|
||||
const hookKeys = keyStore(selectorHooks.roles);
|
||||
const selGroup = selectors.roles;
|
||||
beforeEach(() => { hooks = selectorHooks.roles; });
|
||||
testHook(hookKeys.useCanUserViewGradebook, selGroup.canUserViewGradebook);
|
||||
loadSelectorGroup(selectorHooks.roles, selectors.roles);
|
||||
testHook(hookKeys.useCanUserViewGradebook, selKeys.canUserViewGradebook);
|
||||
});
|
||||
describe('tracks', () => {
|
||||
const hookKeys = keyStore(selectorHooks.tracks);
|
||||
const selGroup = selectors.tracks;
|
||||
beforeEach(() => { hooks = selectorHooks.tracks; });
|
||||
testHook(hookKeys.useAllTracks, selGroup.allTracks);
|
||||
testHook(hookKeys.useTracksByName, selGroup.tracksByName);
|
||||
loadSelectorGroup(selectorHooks.tracks, selectors.tracks);
|
||||
testHook(hookKeys.useAllTracks, selKeys.allTracks);
|
||||
testHook(hookKeys.useTracksByName, selKeys.tracksByName);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -3,15 +3,22 @@ import thunkActions from 'data/thunkActions';
|
||||
import { actionHook } from './utils';
|
||||
|
||||
const app = StrictDict({
|
||||
useCloseFilterMenu: actionHook(thunkActions.app.filterMenu.close),
|
||||
filterMenu: {
|
||||
useCloseMenu: actionHook(thunkActions.app.filterMenu.close),
|
||||
useHandleTransitionEnd: actionHook(thunkActions.app.filterMenu.handleTransitionEnd),
|
||||
useToggleMenu: actionHook(thunkActions.app.filterMenu.toggle),
|
||||
},
|
||||
useSetModalStateFromTable: actionHook(thunkActions.app.setModalStateFromTable),
|
||||
});
|
||||
|
||||
const grades = StrictDict({
|
||||
useFetchGradesIfAssignmentGradeFiltersSet: actionHook(
|
||||
thunkActions.grades.fetchGradesIfAssignmentGradeFiltersSet,
|
||||
),
|
||||
useFetchPrevNextGrades: actionHook(thunkActions.grades.fetchPrevNextGrades),
|
||||
useFetchGrades: actionHook(thunkActions.grades.fetchGrades),
|
||||
useSubmitImportGradesButtonData: actionHook(thunkActions.grades.submitImportGradesButtonData),
|
||||
useUpdateGrades: actionHook(thunkActions.grades.updateGrades),
|
||||
});
|
||||
|
||||
export default StrictDict({
|
||||
|
||||
@@ -5,7 +5,11 @@ import thunkActionHooks from './thunkActions';
|
||||
|
||||
jest.mock('data/thunkActions', () => ({
|
||||
app: {
|
||||
filterMenu: { close: jest.fn() },
|
||||
filterMenu: {
|
||||
close: jest.fn(),
|
||||
handleTransitionEnd: jest.fn(),
|
||||
toggle: jest.fn(),
|
||||
},
|
||||
},
|
||||
grades: {
|
||||
fetchGrades: jest.fn(),
|
||||
@@ -25,24 +29,38 @@ const testActionHook = (hookKey, action) => {
|
||||
expect(hooks[hookKey]).toEqual(actionHook(action));
|
||||
});
|
||||
};
|
||||
let hookKeys;
|
||||
describe('thunkAction hooks', () => {
|
||||
describe('app', () => {
|
||||
const hookKeys = keyStore(thunkActionHooks.app);
|
||||
hookKeys = keyStore(thunkActionHooks.app);
|
||||
beforeEach(() => { hooks = thunkActionHooks.app; });
|
||||
testActionHook(hookKeys.useCloseFilterMenu, thunkActions.app.filterMenu.close);
|
||||
testActionHook(hookKeys.useSetModalStateFromTable, thunkActions.app.setModalStateFromTable);
|
||||
|
||||
describe('filterMenu', () => {
|
||||
hookKeys = keyStore(thunkActionHooks.app.filterMenu);
|
||||
beforeEach(() => { hooks = thunkActionHooks.app.filterMenu; });
|
||||
testActionHook(hookKeys.useCloseMenu, thunkActions.app.filterMenu.close);
|
||||
testActionHook(
|
||||
hookKeys.useHandleTransitionEnd,
|
||||
thunkActions.app.filterMenu.handleTransitionEnd,
|
||||
);
|
||||
testActionHook(hookKeys.useToggleMenu, thunkActions.app.filterMenu.toggle);
|
||||
});
|
||||
});
|
||||
describe('grades', () => {
|
||||
const hookKeys = keyStore(thunkActionHooks.grades);
|
||||
hookKeys = keyStore(thunkActionHooks.grades);
|
||||
const actionGroup = thunkActions.grades;
|
||||
beforeEach(() => { hooks = thunkActionHooks.grades; });
|
||||
testActionHook(hookKeys.useFetchGrades, actionGroup.fetchGrades);
|
||||
testActionHook(
|
||||
hookKeys.useFetchGradesIfAssignmentGradeFiltersSet,
|
||||
actionGroup.fetchGradesIfAssignmentGradeFiltersSet,
|
||||
);
|
||||
testActionHook(hookKeys.useFetchPrevNextGrades, actionGroup.fetchPrevNextGrades);
|
||||
testActionHook(hookKeys.useFetchGrades, actionGroup.fetchGrades);
|
||||
testActionHook(
|
||||
hookKeys.useSubmitImportGradesButtonData,
|
||||
actionGroup.submitImportGradesButtonData,
|
||||
);
|
||||
testActionHook(hookKeys.useUpdateGrades, actionGroup.updateGrades);
|
||||
});
|
||||
});
|
||||
|
||||
31
src/data/redux/transforms.js
Normal file
31
src/data/redux/transforms.js
Normal file
@@ -0,0 +1,31 @@
|
||||
import { StrictDict } from 'utils';
|
||||
import selectors from 'data/selectors';
|
||||
|
||||
// export const root = StrictDict({});
|
||||
// export const app = StrictDict({});
|
||||
export const assignmentTypes = StrictDict({});
|
||||
export const cohorts = StrictDict({});
|
||||
export const filters = StrictDict({});
|
||||
export const grades = StrictDict({
|
||||
subsectionGrade: ({ gradeFormat, subsection }) => () => (
|
||||
selectors.grades.subsectionGrade[gradeFormat](subsection)
|
||||
),
|
||||
roundGrade: selectors.grades.roundGrade,
|
||||
});
|
||||
|
||||
export const roles = StrictDict({
|
||||
});
|
||||
|
||||
export const tracks = StrictDict({
|
||||
});
|
||||
|
||||
export default StrictDict({
|
||||
app,
|
||||
assignmentTypes,
|
||||
cohorts,
|
||||
filters,
|
||||
grades,
|
||||
roles,
|
||||
tracks,
|
||||
root,
|
||||
});
|
||||
@@ -89,6 +89,16 @@ const modalSelectors = simpleSelectorFactory(
|
||||
],
|
||||
);
|
||||
|
||||
const modalData = ({ app: { modalState } }) => ({
|
||||
assignmentName: modalState.assignmentName,
|
||||
adjustedGradePossible: modalState.adjustedGradePossible,
|
||||
adjustedGradeValue: modalState.adjustedGradeValue,
|
||||
open: modalState.open,
|
||||
reasonForChange: modalState.reasonForChange,
|
||||
todaysDate: modalState.todaysDate,
|
||||
updateUserName: modalState.updateUserName,
|
||||
});
|
||||
|
||||
const filterMenuSelectors = simpleSelectorFactory(
|
||||
({ app: { filterMenu } }) => filterMenu,
|
||||
['open', 'transitioning'],
|
||||
@@ -115,6 +125,7 @@ export default StrictDict({
|
||||
isFilterMenuOpening,
|
||||
...simpleSelectors,
|
||||
modalState: StrictDict(modalSelectors),
|
||||
modalData,
|
||||
filterMenu: StrictDict({
|
||||
...filterMenuSelectors,
|
||||
isClosed: isFilterMenuClosed,
|
||||
|
||||
@@ -266,12 +266,26 @@ const simpleSelectors = simpleSelectorFactory(
|
||||
'gradeOverrideHistoryError',
|
||||
'gradeOriginalEarnedGraded',
|
||||
'gradeOriginalPossibleGraded',
|
||||
'nextPage',
|
||||
'prevPage',
|
||||
'showSuccess',
|
||||
],
|
||||
);
|
||||
|
||||
const gradeData = ({ grades }) => ({
|
||||
courseId: grades.courseId,
|
||||
filteredUsersCount: grades.filteredUsersCount,
|
||||
totalUsersCount: grades.totalUsersCount,
|
||||
gradeFormat: grades.gradeFormat,
|
||||
showSpinner: grades.showSpinner,
|
||||
gradeOverrideCurrentEarnedGradedOverride: grades.gradeOverrideCurrentEarnedGradedOverride,
|
||||
gradeOverrideHistoryError: grades.gradeOverrideHistoryError,
|
||||
gradeOverrideHistoryResults: grades.gradeOverrideHistoryResults,
|
||||
gradeOriginalEarnedGraded: grades.gradeOriginalEarnedGraded,
|
||||
gradeOriginalPossibleGraded: grades.gradeOriginalPossibleGraded,
|
||||
nextPage: grades.nextPage,
|
||||
prevPage: grades.prevPage,
|
||||
showSuccess: grades.showSuccess,
|
||||
});
|
||||
|
||||
export default StrictDict({
|
||||
bulkImportError,
|
||||
formatGradeOverrideForDisplay,
|
||||
@@ -286,6 +300,7 @@ export default StrictDict({
|
||||
subsectionGrade,
|
||||
|
||||
...simpleSelectors,
|
||||
gradeData,
|
||||
allGrades,
|
||||
bulkManagementHistoryEntries,
|
||||
getExampleSectionBreakdown,
|
||||
|
||||
Reference in New Issue
Block a user