Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions src/data/selectors/grades.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,11 @@ export const formatMinAssignmentGrade = (percentGrade, options) => (
* @param {string} label - assignment filter label
* @return {string[]} - list of table headers
*/
export const headingMapper = (category, label = 'All') => {
export const headingMapper = (
category,
label = 'All',
hasMastersTrack = false,
) => {
const filters = {
all: section => section.label,
byCategory: section => section.label && section.category === category,
Expand All @@ -105,17 +109,25 @@ export const headingMapper = (category, label = 'All') => {
} else {
filter = filters.byLabel;
}

const {
username,
fullName,
email,
totalGrade,
} = Headings;
let userIdentificationHeadings;
if (hasMastersTrack) {
userIdentificationHeadings = [username, fullName, email];
} else {
userIdentificationHeadings = [username];
}

const filteredLabels = (entry) => entry.filter(filter).map(s => s.label);

return (entry) => (
entry
? [username, fullName, email, ...filteredLabels(entry), totalGrade]
? [...userIdentificationHeadings, ...filteredLabels(entry), totalGrade]
: []
);
};
Expand Down
50 changes: 30 additions & 20 deletions src/data/selectors/grades.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -182,35 +182,45 @@ describe('grades selectors', () => {
});

describe('headingMapper', () => {
const expectedHeaders = (subsectionLabels) => ([
const expectedMastersHeaders = (subsectionLabels) => ([
USERNAME_HEADING,
FULL_NAME_HEADING,
EMAIL_HEADING,
...subsectionLabels,
TOTAL_COURSE_GRADE_HEADING,
]);

const expectedNonMastersHeaders = (subsectionLabels) => ([
USERNAME_HEADING,
...subsectionLabels,
TOTAL_COURSE_GRADE_HEADING,
]);
const rows = genericResultsRows;
const selector = selectors.headingMapper;
it('creates headers for all assignments when no filtering is applied', () => {
expect(selector('All')(genericResultsRows)).toEqual(
expectedHeaders([rows[0].label, rows[1].label, rows[2].label]),
);
});
it('creates headers for only matching assignment types when type filter is applied', () => {
expect(
selector('Homework')(genericResultsRows),
).toEqual(
expectedHeaders([rows[0].label, rows[1].label]),
);
});
it('creates headers for only matching assignment when label filter is applied', () => {
expect(selector('Homework', rows[1].label)(rows)).toEqual(
expectedHeaders([rows[1].label]),
);
});
it('returns an empty array when no entries are passed', () => {
expect(selector('all')(undefined)).toEqual([]);
[true, false].forEach((isMasters) => {
const expectedHeaders = isMasters ? expectedMastersHeaders : expectedNonMastersHeaders;
describe(isMasters ? 'Masters' : 'Not Masters', () => {
it('creates headers for all assignments when no filtering is applied', () => {
expect(selector('All', 'All', isMasters)(genericResultsRows)).toEqual(
expectedHeaders([rows[0].label, rows[1].label, rows[2].label]),
);
});
it('creates headers for only matching assignment types when type filter is applied', () => {
expect(
selector('Homework', 'All', isMasters)(genericResultsRows),
).toEqual(
expectedHeaders([rows[0].label, rows[1].label]),
);
});
it('creates headers for only matching assignment when label filter is applied', () => {
expect(selector('Homework', rows[1].label, isMasters)(rows)).toEqual(
expectedHeaders([rows[1].label]),
);
});
it('returns an empty array when no entries are passed', () => {
expect(selector('all')(undefined)).toEqual([]);
});
});
});
});

Expand Down
1 change: 1 addition & 0 deletions src/data/selectors/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ export const formattedGradeLimits = (state) => {
export const getHeadings = (state) => grades.headingMapper(
filters.assignmentType(state) || 'All',
filters.selectedAssignmentLabel(state) || 'All',
tracks.stateHasMastersTrack(state),
)(grades.getExampleSectionBreakdown(state));

/**
Expand Down
26 changes: 25 additions & 1 deletion src/data/selectors/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -295,20 +295,27 @@ describe('root selectors', () => {
const selector = moduleSelectors.getHeadings;
beforeEach(() => {
selectors.grades.headingMapper = jest.fn(
(type, label) => (breakdown) => ({ headingMapper: { type, label, breakdown } }),
(type, label, hasMastersTrack) => (breakdown) => ({
headingMapper: {
type, label, hasMastersTrack, breakdown,
},
}),
);
selectors.filters.assignmentType = jest.fn();
selectors.filters.selectedAssignmentLabel = jest.fn();
selectors.tracks.stateHasMastersTrack = jest.fn();
selectors.grades.getExampleSectionBreakdown = mockFn('getExampleSectionBreakdown');
});
describe('no assignmentType or label selected', () => {
it('maps selected filters into getExampleSectionBreakdown', () => {
selectors.filters.assignmentType.mockReturnValue(undefined);
selectors.filters.selectedAssignmentLabel.mockReturnValue(undefined);
selectors.tracks.stateHasMastersTrack.mockReturnValue(false);
expect(selector(testState)).toEqual({
headingMapper: {
type: 'All',
label: 'All',
hasMastersTrack: false,
breakdown: { getExampleSectionBreakdown: testState },
},
});
Expand All @@ -318,10 +325,27 @@ describe('root selectors', () => {
it('maps selected filters into getExampleSectionBreakdown', () => {
selectors.filters.assignmentType.mockReturnValue(mockAssignmentType);
selectors.filters.selectedAssignmentLabel.mockReturnValue(mockAssignmentLabel);
selectors.tracks.stateHasMastersTrack.mockReturnValue(false);
expect(selector(testState)).toEqual({
headingMapper: {
type: mockAssignmentType,
label: mockAssignmentLabel,
hasMastersTrack: false,
breakdown: { getExampleSectionBreakdown: testState },
},
});
});
});
describe('has masters track', () => {
it('maps selected filters into getExampleSectionBreakdown', () => {
selectors.filters.assignmentType.mockReturnValue(undefined);
selectors.filters.selectedAssignmentLabel.mockReturnValue(undefined);
selectors.tracks.stateHasMastersTrack.mockReturnValue(true);
expect(selector(testState)).toEqual({
headingMapper: {
type: 'All',
label: 'All',
hasMastersTrack: true,
breakdown: { getExampleSectionBreakdown: testState },
},
});
Expand Down