diff --git a/src/components/Gradebook/index.jsx b/src/components/Gradebook/index.jsx
index 182ca79..8551cdf 100644
--- a/src/components/Gradebook/index.jsx
+++ b/src/components/Gradebook/index.jsx
@@ -208,7 +208,7 @@ export default class Gradebook extends React.Component {
- {PageButtons(this.props)}
+
* available for learners in the Master's track only
{
- const assertPageButtonsSnapshot = function assertPageButtonsSnapshot(input) {
- const pb = renderer.create(PageButtons(input));
- const tree = pb.toJSON();
- expect(tree).toMatchSnapshot();
- };
+import { PageButtons, mapStateToProps, mapDispatchToProps } from '.';
- it('prev null, next null', () => {
- assertPageButtonsSnapshot(createInput(null, null));
+jest.mock('@edx/paragon', () => ({
+ Button: () => 'Button',
+}));
+jest.mock('data/selectors', () => ({
+ __esModule: true,
+ default: {
+ grades: {
+ nextPage: jest.fn(state => ({ nextPage: state })),
+ prevPage: jest.fn(state => ({ prevPage: state })),
+ },
+ },
+}));
+
+jest.mock('data/thunkActions', () => ({
+ __esModule: true,
+ default: {
+ grades: {
+ fetchPrevNextGrades: jest.fn(),
+ },
+ },
+}));
+
+let props;
+let el;
+describe('PageButtons component', () => {
+ beforeEach(() => {
+ props = {
+ match: { params: { courseId: 'hogwarts-minerva-txmog101' } },
+ selectedAssignmentType: 'Transmogrification Exams',
+ selectedCohort: { name: 'Slytherin' },
+ selectedTrack: { name: 'Death Eater' },
+ getPrevNextGrades: jest.fn(),
+ nextPage: 'NEXT PAGE',
+ prevPage: 'prev PAGE',
+ };
});
-
- it('prev null, next not null', () => {
- assertPageButtonsSnapshot(createInput(null, 'np'));
+ describe('snapshots', () => {
+ beforeEach(() => {
+ el = shallow();
+ el.instance.fetchNextGrades = jest.fn().mockName('fetchNextGrades');
+ el.instance.fetchPrevGrades = jest.fn().mockName('fetchPrevGrades');
+ });
+ test('buttons enabled with both endpoints provided', () => {
+ expect(el.instance().render()).toMatchSnapshot();
+ });
+ test('nextPage disabled if not provided', () => {
+ el.setProps({ nextPage: undefined });
+ expect(el.instance().render()).toMatchSnapshot();
+ });
+ test('prevPage disabled if not provided', () => {
+ el.setProps({ prevPage: undefined });
+ expect(el.instance().render()).toMatchSnapshot();
+ });
});
-
- it('prev not null, next null', () => {
- assertPageButtonsSnapshot(createInput('pp', null));
+ describe('behavior', () => {
+ beforeEach(() => {
+ el = shallow();
+ });
+ describe('getPrevGrades', () => {
+ it('calls props.getPrevNextGrades with props.prevPage', () => {
+ el.instance().getPrevGrades();
+ expect(props.getPrevNextGrades).toHaveBeenCalledWith(
+ props.prevPage,
+ props.match.params.courseId,
+ props.selectedCohort,
+ props.selectedTrack,
+ props.selectedAssignmentType,
+ );
+ });
+ });
+ describe('getNextGrades', () => {
+ it('calls props.getPrevNextGrades with props.nextPage', () => {
+ el.instance().getNextGrades();
+ expect(props.getPrevNextGrades).toHaveBeenCalledWith(
+ props.nextPage,
+ props.match.params.courseId,
+ props.selectedCohort,
+ props.selectedTrack,
+ props.selectedAssignmentType,
+ );
+ });
+ });
});
-
- it('prev not null, next not null', () => {
- assertPageButtonsSnapshot(createInput('pp', 'np'));
+ describe('mapStateToProps', () => {
+ const testState = { l: 'eeeerroooooy', j: 'jjjjeeeeeeenkins' };
+ let mapped;
+ beforeEach(() => {
+ mapped = mapStateToProps(testState);
+ });
+ test('nextPage from grades.nextPage', () => {
+ expect(mapped.nextPage).toEqual(selectors.grades.nextPage(testState));
+ });
+ test('prevPage from grades.prevPage', () => {
+ expect(mapped.prevPage).toEqual(selectors.grades.prevPage(testState));
+ });
+ });
+ describe('mapDispatchToProps', () => {
+ test('getPrevNextGrades from thunkActions.grades.fetchPrevNextGrades', () => {
+ expect(
+ mapDispatchToProps.getPrevNextGrades,
+ ).toEqual(thunkActions.grades.fetchPrevNextGrades);
+ });
});
});
diff --git a/src/components/PageButtons/__snapshots__/PageButtons.test.jsx.snap b/src/components/PageButtons/__snapshots__/PageButtons.test.jsx.snap
index 9225c65..3630d0d 100644
--- a/src/components/PageButtons/__snapshots__/PageButtons.test.jsx.snap
+++ b/src/components/PageButtons/__snapshots__/PageButtons.test.jsx.snap
@@ -1,6 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
-exports[`PageButtons prev not null, next not null 1`] = `
+exports[`PageButtons component snapshots buttons enabled with both endpoints provided 1`] = `
-
-
`;
-exports[`PageButtons prev not null, next null 1`] = `
+exports[`PageButtons component snapshots nextPage disabled if not provided 1`] = `
-
Previous Page
-
-
+
Next Page
-
+
`;
-exports[`PageButtons prev null, next not null 1`] = `
+exports[`PageButtons component snapshots prevPage disabled if not provided 1`] = `
-
Previous Page
-
-
+
Next Page
-
-
-`;
-
-exports[`PageButtons prev null, next null 1`] = `
-
-
- Previous Page
-
-
- Next Page
-
+
`;
diff --git a/src/components/PageButtons/index.jsx b/src/components/PageButtons/index.jsx
index 89824af..ac8da60 100644
--- a/src/components/PageButtons/index.jsx
+++ b/src/components/PageButtons/index.jsx
@@ -1,75 +1,99 @@
import React from 'react';
import PropTypes from 'prop-types';
+import { connect } from 'react-redux';
+
import { Button } from '@edx/paragon';
-export default function PageButtons({
- prevPage, nextPage, selectedTrack, selectedCohort, selectedAssignmentType,
- getPrevNextGrades, match,
-}) {
- return (
-
-
getPrevNextGrades(
- prevPage,
- match.params.courseId,
- selectedCohort,
- selectedTrack,
- selectedAssignmentType,
- )}
+import selectors from 'data/selectors';
+import thunkActions from 'data/thunkActions';
+
+export class PageButtons extends React.Component {
+ constructor(props) {
+ super(props);
+ this.getPrevGrades = this.getPrevGrades.bind(this);
+ this.getNextGrades = this.getNextGrades.bind(this);
+ }
+
+ getPrevGrades() {
+ this.props.getPrevNextGrades(
+ this.props.prevPage,
+ this.props.match.params.courseId,
+ this.props.selectedCohort,
+ this.props.selectedTrack,
+ this.props.selectedAssignmentType,
+ );
+ }
+
+ getNextGrades() {
+ this.props.getPrevNextGrades(
+ this.props.nextPage,
+ this.props.match.params.courseId,
+ this.props.selectedCohort,
+ this.props.selectedTrack,
+ this.props.selectedAssignmentType,
+ );
+ }
+
+ render() {
+ return (
+
- Previous Page
-
- getPrevNextGrades(
- nextPage,
- match.params.courseId,
- selectedCohort,
- selectedTrack,
- selectedAssignmentType,
- )}
- >
- Next Page
-
-
- );
+
+ Previous Page
+
+
+ Next Page
+
+
+ );
+ }
}
PageButtons.defaultProps = {
match: {
- params: {
- courseId: '',
- },
+ params: { courseId: '' },
},
- nextPage: '',
- prevPage: '',
+ selectedAssignmentType: null,
selectedCohort: null,
selectedTrack: null,
- selectedAssignmentType: null,
+ nextPage: '',
+ prevPage: '',
};
PageButtons.propTypes = {
- getPrevNextGrades: PropTypes.func.isRequired,
match: PropTypes.shape({
params: PropTypes.shape({
courseId: PropTypes.string,
}),
}),
+ selectedAssignmentType: PropTypes.string,
+ selectedCohort: PropTypes.shape({ name: PropTypes.string }),
+ selectedTrack: PropTypes.shape({ name: PropTypes.string }),
+ // redux
+ getPrevNextGrades: PropTypes.func.isRequired,
nextPage: PropTypes.string,
prevPage: PropTypes.string,
- selectedAssignmentType: PropTypes.string,
- selectedCohort: PropTypes.shape({
- name: PropTypes.string,
- }),
- selectedTrack: PropTypes.shape({
- name: PropTypes.string,
- }),
};
+
+export const mapStateToProps = (state) => ({
+ nextPage: selectors.grades.nextPage(state),
+ prevPage: selectors.grades.prevPage(state),
+});
+
+export const mapDispatchToProps = {
+ getPrevNextGrades: thunkActions.grades.fetchPrevNextGrades,
+};
+
+export default connect(mapStateToProps, mapDispatchToProps)(PageButtons);
diff --git a/src/data/selectors/grades.js b/src/data/selectors/grades.js
index 02504fe..16d220c 100644
--- a/src/data/selectors/grades.js
+++ b/src/data/selectors/grades.js
@@ -205,6 +205,8 @@ const simpleSelectors = simpleSelectorFactory(
'filteredUsersCount',
'totalUsersCount',
'gradeFormat',
+ 'nextPage',
+ 'prevPage',
'showSpinner',
'gradeOverrideCurrentEarnedGradedOverride',
'gradeOverrideHistoryError',
diff --git a/src/data/selectors/grades.test.js b/src/data/selectors/grades.test.js
index ce0c559..8cc88bb 100644
--- a/src/data/selectors/grades.test.js
+++ b/src/data/selectors/grades.test.js
@@ -287,6 +287,8 @@ describe('grades selectors', () => {
testSimpleSelector('filteredUsersCount');
testSimpleSelector('totalUsersCount');
testSimpleSelector('gradeFormat');
+ testSimpleSelector('nextPage');
+ testSimpleSelector('prevPage');
testSimpleSelector('showSpinner');
testSimpleSelector('gradeOverrideCurrentEarnedGradedOverride');
testSimpleSelector('gradeOverrideHistoryError');