Skip to content

Commit

Permalink
Merge pull request #232 from edx/mroytman/checklist-comment-section
Browse files Browse the repository at this point in the history
mroytman/checklist comment section
  • Loading branch information
MichaelRoytman authored Jul 12, 2018
2 parents 30204f8 + 49824b6 commit f43cc29
Show file tree
Hide file tree
Showing 20 changed files with 473 additions and 139 deletions.
2 changes: 1 addition & 1 deletion src/SFE.scss
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
font-weight: inherit;
line-height: inherit;
color: inherit;
text-align: left;
text-align: inherit;
background-color: inherit;
cursor: inherit;
}
Expand Down
35 changes: 33 additions & 2 deletions src/components/CourseChecklist/CourseChecklist.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,42 @@
@import "~bootstrap/scss/_buttons";
@import "~bootstrap/scss/utilities/_screenreaders";

$light-color: theme-color("light");
$lightest-color: theme-color("lightest");
$primary-color: theme-color("primary");
$success-color: theme-color("success");

.assignment-list-item {
list-style: none;
display: inline-block;

&:after {
content: ",";
}

&:last-child {
&:after {
content: "";
}
}
}

.assignment-list {
display: inline;
padding-inline-start: map-get($spacers, 3);
}

.checklist-item-link {
text-decoration: none;
}

.checklist-item {
&:not(:hover) {
.checklist-item-link {
@include sr_only();
}
}
}

//complete checklist item style
.checklist-item-complete {
box-shadow: -5px 0 0 0 $success-color;
Expand All @@ -25,7 +52,7 @@ $success-color: theme-color("success");
box-shadow: -5px 0 0 0 $lightest-color;

.checklist-icon-incomplete {
color: $light-color;
color: $gray-600;
}

&:hover {
Expand All @@ -36,3 +63,7 @@ $success-color: theme-color("success");
}
}
}

.comment-icon {
color: $gray-400;
}
196 changes: 191 additions & 5 deletions src/components/CourseChecklist/CourseChecklist.test.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Icon, Hyperlink } from '@edx/paragon';
import { IntlProvider, FormattedMessage } from 'react-intl';
import { IntlProvider, FormattedMessage, FormattedNumber } from 'react-intl';
import React from 'react';

import CourseChecklist from '.';
Expand Down Expand Up @@ -46,8 +46,13 @@ const { intl } = intlProvider.getChildContext();
let wrapper;

const testData = {
data: {
is_self_paced: true,
assignments: {
assignments_with_dates_after_end: [],
assignments_with_dates_before_start: [],
},
is_self_paced: true,
grades: {
sum_of_weights: 1,
},
};

Expand All @@ -57,9 +62,10 @@ const defaultProps = {
dataList: testChecklistData,
idPrefix: 'test',
links: {
certificates: 'certificatesTest',
course_outline: 'courseOutlineTest',
course_updates: 'welcomeMessageTest',
grading_policy: 'gradingPolicyTest',
certificates: 'certificatesTest',
settings: 'settingsTest',
},
};
Expand Down Expand Up @@ -192,6 +198,182 @@ describe('CourseChecklist', () => {
});
});
});

describe('welcomeMessage check with', () => {
it('no comment section', () => {
wrapper = shallowWithIntl(<CourseChecklist {...defaultProps} />);
const comment = wrapper.find('#checklist-item-welcomeMessage').find('[data-identifier="comment"]');

expect(comment).toHaveLength(0);
});
});
describe('gradingPolicy check with', () => {
it('no comment section if sum of weights is equal to 1', () => {
wrapper = shallowWithIntl(<CourseChecklist {...defaultProps} />);
const comment = wrapper.find('#checklist-item-gradingPolicy').find('[data-identifier="comment"]');

expect(comment).toHaveLength(0);
});

describe('a comment section with', () => {
const sumOfWeights = 0.5;

beforeEach(() => {
wrapper = shallowWithIntl(<CourseChecklist {...defaultProps} />);

const newProps = {
...defaultProps,
};
newProps.data.grades.sum_of_weights = sumOfWeights;

wrapper.setProps({
newProps,
});
});

it('a comment section if sum of weights is not equal to 1', () => {
const comment = wrapper.find('#checklist-item-gradingPolicy').find('[data-identifier="comment"]');

expect(comment).toHaveLength(1);
});

it('a comment section with a comment icon', () => {
const comment = wrapper.find('#checklist-item-gradingPolicy').find('[data-identifier="comment"]');

const icon = comment.find(Icon);

expect(icon).toHaveLength(1);
});

it('a comment section with correct props', () => {
const comment = wrapper.find('#checklist-item-gradingPolicy').find('[data-identifier="comment"]');

const icon = comment.find(Icon);

expect(icon.prop('className')[0]).toEqual(expect.stringContaining('fa'));
expect(icon.prop('className')[0]).toEqual(expect.stringContaining('fa-lg'));
expect(icon.prop('className')[0]).toEqual(expect.stringContaining('fa-comment'));
expect(icon.prop('className')[0]).toEqual(expect.stringContaining('comment'));
});

it('a comment section with correct message', () => {
const comment = wrapper.find('#checklist-item-gradingPolicy').find('[data-identifier="comment"]');

const message = comment.find(WrappedMessage);

expect(message).toHaveLength(1);
expect(message.prop('message')).toEqual(messages.gradingPolicyComment);
expect(message.prop('values').percent).toEqual(
<FormattedNumber
maximumFractionDigits={2}
minimumFractionDigits={2}
value={(sumOfWeights * 100).toFixed(2)}
/>,
);
});
});
});
describe('certificate check with', () => {
it('no comment section', () => {
wrapper = shallowWithIntl(<CourseChecklist {...defaultProps} />);
const comment = wrapper.find('#checklist-item-certificate').find('[data-identifier="comment"]');

expect(comment).toHaveLength(0);
});
});
describe('courseDates check with', () => {
it('no comment section', () => {
wrapper = shallowWithIntl(<CourseChecklist {...defaultProps} />);
const comment = wrapper.find('#checklist-item-courseDates').find('[data-identifier="comment"]');

expect(comment).toHaveLength(0);
});
});
describe('assignmentDeadlines check with', () => {
it('no comment section if assignments with dates before start and after end are empty', () => {
wrapper = shallowWithIntl(<CourseChecklist {...defaultProps} />);
const comment = wrapper.find('#checklist-item-assignmentDeadlines').find('[data-identifier="comment"]');

expect(comment).toHaveLength(0);
});

describe('a comment section with', () => {
const assignmentsWithDatesAfterEnd = [{ display_name: 'test1', id: 'test1' }];
const assignmentsWithDatesBeforeStart = [{ display_name: 'test2', id: 'test2' }];

beforeEach(() => {
wrapper = shallowWithIntl(<CourseChecklist {...defaultProps} />);

const newProps = {
...defaultProps,
};
newProps.data.assignments.assignments_with_dates_after_end =
assignmentsWithDatesAfterEnd;
newProps.data.assignments.assignments_with_dates_before_start =
assignmentsWithDatesBeforeStart;

wrapper.setProps({
newProps,
});
});

it('a comment if assignments with dates before start and after end are not empty', () => {
const comment = wrapper.find('#checklist-item-assignmentDeadlines').find('[data-identifier="comment"]');

expect(comment).toHaveLength(1);
});

it('a comment section with a comment icon', () => {
const comment = wrapper.find('#checklist-item-assignmentDeadlines').find('[data-identifier="comment"]');

const icon = comment.find(Icon);

expect(icon).toHaveLength(1);
});

it('a comment section with correct props', () => {
const comment = wrapper.find('#checklist-item-assignmentDeadlines').find('[data-identifier="comment"]');

const icon = comment.find(Icon);

expect(icon.prop('className')[0]).toEqual(expect.stringContaining('fa'));
expect(icon.prop('className')[0]).toEqual(expect.stringContaining('fa-lg'));
expect(icon.prop('className')[0]).toEqual(expect.stringContaining('fa-comment'));
expect(icon.prop('className')[0]).toEqual(expect.stringContaining('comment'));
});

it('a comment section with correct message', () => {
const comment = wrapper.find('#checklist-item-assignmentDeadlines').find('[data-identifier="comment"]');

const message = comment.find(WrappedMessage);

expect(message).toHaveLength(1);
expect(message.prop('message')).toEqual(messages.assignmentDeadlinesComment);
});

it('a comment section message with a Hyperlink for each assignment', () => {
const comment = wrapper.find('#checklist-item-assignmentDeadlines').find('[data-identifier="comment"]');

const assignmentList = comment.find('ul');
expect(assignmentList).toHaveLength(1);

const assignments = assignmentList.find('li');
expect(assignments).toHaveLength(
assignmentsWithDatesAfterEnd.length + assignmentsWithDatesBeforeStart.length,
);

assignments.find(Hyperlink).forEach((assignmentLink) => {
const content = assignmentLink.prop('content');
expect(content === assignmentsWithDatesAfterEnd[0].display_name ||
content === assignmentsWithDatesBeforeStart[0].display_name).toEqual(true);

const destination = assignmentLink.prop('destination');
expect(destination === `${defaultProps.links.course_outline}#${assignmentsWithDatesAfterEnd[0].id}` ||
destination === `${defaultProps.links.course_outline}#${assignmentsWithDatesBeforeStart[0].id}`).toEqual(true);
});
});
});
});
});

describe('behaves', () => {
Expand Down Expand Up @@ -236,8 +418,12 @@ describe('CourseChecklist', () => {
expect(wrapper.state('values')).toEqual(validatedValues);
});

it('getUpdateLinkDestination returns null for unknown checklist item', () => {
it('getUpdateLinkDestination returns null for unknown checklist item id', () => {
expect(wrapper.instance().getUpdateLinkDestination('test')).toBeNull();
});

it('getCommentSection returns null for unknown checklist item id', () => {
expect(wrapper.instance().getCommentSection('test')).toBeNull();
});
});
});
10 changes: 10 additions & 0 deletions src/components/CourseChecklist/displayMessages.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ const messages = defineMessages({
defaultMessage: 'Establish your grading policy, including assignment types and passing score. All assignments add up to 100%.',
description: 'Description for a section that prompts a user to enter a grading policy for a course',
},
gradingPolicyComment: {
id: 'gradingPolicyComment',
defaultMessage: 'Your current grading policy adds up to {percent}%.',
description: 'Description for a section that displays a course\'s grading policy total',
},
certificateShortDescription: {
id: 'certificateShortDescription',
defaultMessage: 'Enable Your Certificate',
Expand Down Expand Up @@ -51,6 +56,11 @@ const messages = defineMessages({
defaultMessage: 'Ensure all assignment deadlines are between course start and end dates.',
description: 'Description for a section that prompts a user to enter course assignment deadlines',
},
assignmentDeadlinesComment: {
id: 'assignmentDeadlinesComment',
defaultMessage: 'The following assignments have deadlines that do not fall between course start and end date:',
description: 'Description for a section that displays which assignments are outside of a course\'s start and end date',
},
videoDurationShortDescription: {
id: 'videoDurationShortDescription',
defaultMessage: 'Video Duration',
Expand Down
Loading

0 comments on commit f43cc29

Please sign in to comment.