refactor: interventsions report component

This commit is contained in:
Ben Warzeski
2023-04-05 10:34:25 -04:00
parent f76f3d64c9
commit f2bb0d7c2a
6 changed files with 207 additions and 0 deletions

View File

@@ -0,0 +1,30 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`InterventionsReport component output snapshot 1`] = `
<div>
<h4
className="mt-0"
>
Interventions Report
</h4>
<div
className="d-flex justify-content-between align-items-center"
>
<div
className="intervention-report-description"
>
Need to find students who may be falling behind? Download the interventions report to obtain engagement metrics such as section attempts and visits.
</div>
<NetworkButton
label={
Object {
"defaultMessage": "Download Interventions",
"description": "The labeled button to download the Intervention report from the Grades View",
"id": "gradebook.GradesView.InterventionsReport.downloadBtn",
}
}
onClick={[MockFunction]}
/>
</div>
</div>
`;

View File

@@ -0,0 +1,19 @@
import { actions, selectors } from 'data/redux/hooks';
const useInterventionsReportData = () => {
const interventionExportUrl = selectors.root.useInterventionExportUrl();
const showBulkManagement = selectors.root.useShowBulkManagement();
const downloadInterventionReport = actions.grades.useDownloadInterventionReport();
const handleClick = () => {
downloadInterventionReport();
window.location.assign(interventionExportUrl);
};
return {
show: showBulkManagement,
handleClick,
};
};
export default useInterventionsReportData;

View File

@@ -0,0 +1,56 @@
import { actions, selectors } from 'data/redux/hooks';
import useInterventionsReportData from './hooks';
jest.mock('data/redux/hooks', () => ({
actions: {
grades: {
useDownloadInterventionReport: jest.fn(),
},
},
selectors: {
root: {
useInterventionExportUrl: jest.fn(),
useShowBulkManagement: jest.fn(),
},
},
}));
const downloadReport = jest.fn();
actions.grades.useDownloadInterventionReport.mockReturnValue(downloadReport);
selectors.root.useShowBulkManagement.mockReturnValue(true);
const exportUrl = 'test-intervention-export-url';
selectors.root.useInterventionExportUrl.mockReturnValue(exportUrl);
let hook;
let oldLocation;
describe('useInterventionsReportData hooks', () => {
beforeEach(() => {
oldLocation = window.location;
delete window.location;
window.location = { assign: jest.fn() };
hook = useInterventionsReportData();
});
afterEach(() => {
window.location = oldLocation;
});
describe('behavior', () => {
it('initializes hooks', () => {
expect(selectors.root.useInterventionExportUrl).toHaveBeenCalled();
expect(selectors.root.useShowBulkManagement).toHaveBeenCalled();
expect(actions.grades.useDownloadInterventionReport).toHaveBeenCalled();
});
});
describe('output', () => {
test('show from showBulkManagement selector', () => {
expect(hook.show).toEqual(true);
});
describe('handleClick', () => {
it('downloads interventions report and navigates to export url', () => {
hook.handleClick();
expect(downloadReport).toHaveBeenCalled();
expect(window.location.assign).toHaveBeenCalledWith(exportUrl);
});
});
});
});

View File

@@ -0,0 +1,39 @@
import React from 'react';
import { useIntl } from '@edx/frontend-platform/i18n';
import NetworkButton from 'components/NetworkButton';
import messages from './messages';
import useInterventionsReportData from './hooks';
/**
* <InterventionsReport />
* Provides download buttons for Bulk Management and Intervention reports, only if
* showBulkManagement is set in redus.
*/
export const InterventionsReport = () => {
const { show, handleClick } = useInterventionsReportData();
const { formatMessage } = useIntl();
return show && (
<div>
<h4 className="mt-0">
{formatMessage(messages.title)}
</h4>
<div
className="d-flex justify-content-between align-items-center"
>
<div className="intervention-report-description">
{formatMessage(messages.description)}
</div>
<NetworkButton
label={messages.downloadBtn}
onClick={handleClick}
/>
</div>
</div>
);
};
export default InterventionsReport;

View File

@@ -0,0 +1,42 @@
import React from 'react';
import { shallow } from 'enzyme';
import { useIntl } from '@edx/frontend-platform/i18n';
import NetworkButton from 'components/NetworkButton';
import messages from './messages';
import useInterventionsReportData from './hooks';
import InterventionsReport from '.';
jest.mock('components/NetworkButton', () => 'NetworkButton');
jest.mock('./hooks', () => jest.fn());
const hookProps = { show: true, handleClick: jest.fn() };
useInterventionsReportData.mockReturnValue(hookProps);
let el;
describe('InterventionsReport component', () => {
beforeEach(() => {
el = shallow(<InterventionsReport />);
});
describe('behavior', () => {
it('initializes hooks', () => {
expect(useInterventionsReportData).toHaveBeenCalledWith();
expect(useIntl).toHaveBeenCalledWith();
});
});
describe('output', () => {
it('does now render if show is false', () => {
useInterventionsReportData.mockReturnValueOnce({ ...hookProps, show: false });
el = shallow(<InterventionsReport />);
expect(el.isEmptyRender()).toEqual(true);
});
test('snapshot', () => {
expect(el).toMatchSnapshot();
const btnProps = el.find(NetworkButton).props();
expect(btnProps.label).toEqual(messages.downloadBtn);
expect(btnProps.onClick).toEqual(hookProps.handleClick);
});
});
});

View File

@@ -0,0 +1,21 @@
import { defineMessages } from '@edx/frontend-platform/i18n';
const messages = defineMessages({
title: {
id: 'gradebook.GradesView.InterventionsReport.title',
defaultMessage: 'Interventions Report',
description: 'The title for the Intervention report subsection',
},
description: {
id: 'gradebook.GradesView.InterventionsReport.description',
defaultMessage: 'Need to find students who may be falling behind? Download the interventions report to obtain engagement metrics such as section attempts and visits.',
description: 'The description for the Intervention report subsection',
},
downloadBtn: {
id: 'gradebook.GradesView.InterventionsReport.downloadBtn',
defaultMessage: 'Download Interventions',
description: 'The labeled button to download the Intervention report from the Grades View',
},
});
export default messages;