* fix: eslint operator-linebreak issue * fix: eslint quotes issue * fix: react jsx indent and props issues * fix: eslint trailing spaces issues * fix: eslint line around directives issue * fix: eslint semi rule * fix: eslint newline per chain rule * fix: eslint space infix ops rule * fix: eslint space-in-parens issue * fix: eslint space before function paren issue * fix: eslint space before blocks issue * fix: eslint arrow body style issue * fix: eslint dot-location issue * fix: eslint quotes issue * fix: eslint quote props issue * fix: eslint operator assignment issue * fix: eslint new line after import issue * fix: indent issues * fix: operator assignment issue * fix: all autofixable eslint issues * fix: all react related fixable issues * fix: autofixable eslint issues * chore: remove all template literals * fix: remaining autofixable issues * fix: failing js test
517 lines
24 KiB
JavaScript
517 lines
24 KiB
JavaScript
define(['backbone', 'jquery', 'edx-ui-toolkit/js/utils/spec-helpers/ajax-helpers',
|
|
'common/js/spec_helpers/template_helpers',
|
|
'js/discussions_management/views/discussions', 'js/discussions_management/models/course_discussions_detail',
|
|
'js/discussions_management/models/course_discussions_settings'
|
|
],
|
|
function(Backbone, $, AjaxHelpers, TemplateHelpers, DiscussionsView, CourseDiscussionTopicDetailsModel,
|
|
CourseDiscussionsSettingsModel) {
|
|
'use strict';
|
|
|
|
describe('Discussions View', function() {
|
|
var createMockDiscussionsSettingsJson, createDiscussionsView, discussionsView, requests, verifyMessage,
|
|
createMockDiscussionsSettings, createMockDiscussionsJson, createMockDiscussions,
|
|
showAndAssertDiscussionTopics;
|
|
|
|
// Selectors
|
|
var inlineDiscussionsFormCss = '.cohort-inline-discussions-form',
|
|
courseWideDiscussionsFormCss = '.cohort-course-wide-discussions-form',
|
|
courseWideDiscussionsSaveButtonCss = '.cohort-course-wide-discussions-form .action-save',
|
|
inlineDiscussionsSaveButtonCss = '.cohort-inline-discussions-form .action-save';
|
|
|
|
createMockDiscussionsSettingsJson = function(dividedInlineDiscussions,
|
|
dividedCourseWideDiscussions,
|
|
alwaysDivideInlineDiscussions,
|
|
availableDivisionSchemes) {
|
|
return {
|
|
id: 0,
|
|
divided_inline_discussions: dividedInlineDiscussions || [],
|
|
divided_course_wide_discussions: dividedCourseWideDiscussions || [],
|
|
always_divide_inline_discussions: alwaysDivideInlineDiscussions || false,
|
|
available_division_schemes: availableDivisionSchemes || ['cohort']
|
|
};
|
|
};
|
|
|
|
createMockDiscussionsSettings = function(dividedInlineDiscussions,
|
|
dividedCourseWideDiscussions,
|
|
alwaysDivideInlineDiscussions,
|
|
availableDivisionSchemes) {
|
|
return new CourseDiscussionsSettingsModel(
|
|
createMockDiscussionsSettingsJson(dividedInlineDiscussions,
|
|
dividedCourseWideDiscussions,
|
|
alwaysDivideInlineDiscussions,
|
|
availableDivisionSchemes)
|
|
);
|
|
};
|
|
|
|
createMockDiscussionsJson = function(allDivided) {
|
|
return {
|
|
course_wide_discussions: {
|
|
children: [['Topic_C_1', 'entry'], ['Topic_C_2', 'entry']],
|
|
entries: {
|
|
Topic_C_1: {
|
|
sort_key: null,
|
|
is_divided: true,
|
|
id: 'Topic_C_1'
|
|
},
|
|
Topic_C_2: {
|
|
sort_key: null,
|
|
is_divided: false,
|
|
id: 'Topic_C_2'
|
|
}
|
|
}
|
|
},
|
|
inline_discussions: {
|
|
subcategories: {
|
|
Topic_I_1: {
|
|
subcategories: {},
|
|
children: [['Inline_Discussion_1', 'entry'], ['Inline_Discussion_2', 'entry']],
|
|
entries: {
|
|
Inline_Discussion_1: {
|
|
sort_key: null,
|
|
is_divided: true,
|
|
id: 'Inline_Discussion_1'
|
|
},
|
|
Inline_Discussion_2: {
|
|
sort_key: null,
|
|
is_divided: allDivided || false,
|
|
id: 'Inline_Discussion_2'
|
|
}
|
|
}
|
|
}
|
|
},
|
|
children: [['Topic_I_1', 'subcategory']]
|
|
}
|
|
};
|
|
};
|
|
|
|
createMockDiscussions = function(allDivided) {
|
|
return new CourseDiscussionTopicDetailsModel(
|
|
createMockDiscussionsJson(allDivided)
|
|
);
|
|
};
|
|
|
|
verifyMessage = function(expectedTitle, expectedMessageType, expectedAction, hasDetails) {
|
|
expect(discussionsView.$('.message-title').text().trim()).toBe(expectedTitle);
|
|
expect(discussionsView.$('div.message')).toHaveClass('message-' + expectedMessageType);
|
|
if (expectedAction) {
|
|
expect(discussionsView.$('.message-actions .action-primary').text().trim()).toBe(expectedAction);
|
|
} else {
|
|
expect(discussionsView.$('.message-actions .action-primary').length).toBe(0);
|
|
} if (!hasDetails) {
|
|
expect(discussionsView.$('.summary-items').length).toBe(0);
|
|
}
|
|
};
|
|
|
|
createDiscussionsView = function(test, options) {
|
|
var discussionSettings, dividedDiscussions, discussionOptions;
|
|
discussionOptions = options || {};
|
|
discussionSettings = discussionOptions.cohortSettings || createMockDiscussionsSettings();
|
|
discussionSettings.url = '/mock_service/discussions/settings';
|
|
|
|
dividedDiscussions = discussionOptions.dividedDiscussions || createMockDiscussions();
|
|
dividedDiscussions.url = '/mock_service/discussion/topics';
|
|
|
|
requests = AjaxHelpers.requests(test);
|
|
discussionsView = new DiscussionsView({
|
|
el: $('.discussions-management'),
|
|
discussionSettings: discussionSettings,
|
|
context: {
|
|
courseDiscussionTopicDetailsModel: dividedDiscussions
|
|
}
|
|
});
|
|
discussionsView.render();
|
|
};
|
|
|
|
showAndAssertDiscussionTopics = function() {
|
|
var $courseWideDiscussionsForm,
|
|
$inlineDiscussionsForm;
|
|
|
|
$courseWideDiscussionsForm = discussionsView.$(courseWideDiscussionsFormCss);
|
|
$inlineDiscussionsForm = discussionsView.$(inlineDiscussionsFormCss);
|
|
|
|
// Discussions form should not be visible.
|
|
expect($inlineDiscussionsForm.length).toBe(1);
|
|
expect($courseWideDiscussionsForm.length).toBe(1);
|
|
|
|
expect($courseWideDiscussionsForm.text())
|
|
.toContain('Course-Wide Discussion Topics');
|
|
expect($courseWideDiscussionsForm.text())
|
|
.toContain('Select the course-wide discussion topics that you want to divide.');
|
|
|
|
// Should see the inline discussions form and its content
|
|
expect($inlineDiscussionsForm.length).toBe(1);
|
|
expect($inlineDiscussionsForm.text())
|
|
.toContain('Content-Specific Discussion Topics');
|
|
expect($inlineDiscussionsForm.text())
|
|
.toContain('Specify whether content-specific discussion topics are divided.');
|
|
};
|
|
|
|
beforeEach(function() {
|
|
setFixtures('<ul class="instructor-nav">'
|
|
+ '<li class="nav-item"><button type="button" data-section="discussion_management" '
|
|
+ 'class="active-section">Discussions</button></li></ul><div></div>'
|
|
+ '<div class="discussions-management"></div>');
|
|
TemplateHelpers.installTemplate('templates/instructor/instructor_dashboard_2/discussions');
|
|
TemplateHelpers.installTemplate(
|
|
'templates/instructor/instructor_dashboard_2/divided-discussions-course-wide'
|
|
);
|
|
TemplateHelpers.installTemplate(
|
|
'templates/instructor/instructor_dashboard_2/divided-discussions-inline'
|
|
);
|
|
TemplateHelpers.installTemplate(
|
|
'templates/instructor/instructor_dashboard_2/cohort-discussions-category'
|
|
);
|
|
TemplateHelpers.installTemplate(
|
|
'templates/instructor/instructor_dashboard_2/cohort-discussions-subcategory'
|
|
);
|
|
TemplateHelpers.installTemplate('templates/instructor/instructor_dashboard_2/notification');
|
|
});
|
|
|
|
describe('Discussion Topics', function() {
|
|
var courseWideView, assertDividedTopics;
|
|
|
|
assertDividedTopics = function(view, type) {
|
|
expect($('.check-discussion-subcategory-' + type).length).toBe(2);
|
|
expect($('.check-discussion-subcategory-' + type + ':checked').length).toBe(1);
|
|
};
|
|
|
|
it('renders the view properly', function() {
|
|
createDiscussionsView(this);
|
|
showAndAssertDiscussionTopics(this);
|
|
});
|
|
|
|
describe('Course Wide', function() {
|
|
it('shows the "Save" button as disabled initially', function() {
|
|
createDiscussionsView(this);
|
|
expect($(courseWideDiscussionsSaveButtonCss).prop('disabled')).toBeTruthy();
|
|
});
|
|
|
|
it('has one divided and one non-divided topic', function() {
|
|
createDiscussionsView(this);
|
|
assertDividedTopics(courseWideView, 'course-wide');
|
|
|
|
expect($('.course-wide-discussion-topics .divided-discussion-text').length).toBe(2);
|
|
expect($('.course-wide-discussion-topics .divided-discussion-text.hidden').length).toBe(1);
|
|
});
|
|
|
|
it('enables the "Save" button after changing checkbox', function() {
|
|
createDiscussionsView(this);
|
|
// save button is disabled.
|
|
expect($(courseWideDiscussionsSaveButtonCss).prop('disabled')).toBeTruthy();
|
|
|
|
$($('.check-discussion-subcategory-course-wide')[0]).prop('checked', false).change();
|
|
|
|
// save button is enabled.
|
|
expect($(courseWideDiscussionsSaveButtonCss).prop('disabled')).toBeFalsy();
|
|
});
|
|
|
|
it('saves the topic successfully', function() {
|
|
createDiscussionsView(this);
|
|
$($('.check-discussion-subcategory-course-wide')[1]).prop('checked', 'checked').change();
|
|
expect($(courseWideDiscussionsSaveButtonCss).prop('disabled')).toBeFalsy();
|
|
|
|
// Save the updated settings
|
|
$('#cohort-course-wide-discussions-form .action-save').click();
|
|
|
|
// fake requests for discussions settings with PATCH method.
|
|
AjaxHelpers.expectJsonRequest(
|
|
requests, 'PATCH', '/mock_service/discussions/settings',
|
|
{divided_course_wide_discussions: ['Topic_C_1', 'Topic_C_2']}
|
|
);
|
|
AjaxHelpers.respondWithJson(
|
|
requests,
|
|
{divided_course_wide_discussions: ['Topic_C_1', 'Topic_C_2']}
|
|
);
|
|
|
|
// fake request for discussion/topics with GET method.
|
|
AjaxHelpers.expectJsonRequest(
|
|
requests, 'GET', '/mock_service/discussion/topics'
|
|
);
|
|
AjaxHelpers.respondWithJson(
|
|
requests,
|
|
createMockDiscussions()
|
|
);
|
|
|
|
// verify the success message.
|
|
expect($(courseWideDiscussionsSaveButtonCss).prop('disabled')).toBeTruthy();
|
|
verifyMessage('Your changes have been saved.', 'confirmation');
|
|
});
|
|
|
|
it('shows an appropriate message when subsequent "GET" returns HTTP500', function() {
|
|
var expectedTitle;
|
|
createDiscussionsView(this);
|
|
$($('.check-discussion-subcategory-course-wide')[1]).prop('checked', 'checked').change();
|
|
expect($(courseWideDiscussionsSaveButtonCss).prop('disabled')).toBeFalsy();
|
|
|
|
// Save the updated settings
|
|
$('#cohort-course-wide-discussions-form .action-save').click();
|
|
|
|
// fake requests for discussion settings with PATCH method.
|
|
AjaxHelpers.expectJsonRequest(
|
|
requests, 'PATCH', '/mock_service/discussions/settings',
|
|
{divided_course_wide_discussions: ['Topic_C_1', 'Topic_C_2']}
|
|
);
|
|
AjaxHelpers.respondWithJson(
|
|
requests,
|
|
{divided_course_wide_discussions: ['Topic_C_1', 'Topic_C_2']}
|
|
);
|
|
|
|
// fake request for discussion/topics with GET method.
|
|
AjaxHelpers.expectJsonRequest(
|
|
requests, 'GET', '/mock_service/discussion/topics'
|
|
);
|
|
AjaxHelpers.respondWithError(requests, 500);
|
|
|
|
expectedTitle = "We've encountered an error. Refresh your browser and then try again.";
|
|
expect($('.message-title').text().trim()).toBe(expectedTitle);
|
|
});
|
|
|
|
it('shows an appropriate error message for HTTP500', function() {
|
|
var expectedTitle;
|
|
createDiscussionsView(this);
|
|
$($('.check-discussion-subcategory-course-wide')[1]).prop('checked', 'checked').change();
|
|
$('.action-save').click();
|
|
|
|
AjaxHelpers.respondWithError(requests, 500);
|
|
expectedTitle = "We've encountered an error. Refresh your browser and then try again.";
|
|
expect($('.message-title').text().trim()).toBe(expectedTitle);
|
|
});
|
|
});
|
|
|
|
describe('Inline', function() {
|
|
var enableSaveButton, mockGetRequest, verifySuccess, mockPatchRequest;
|
|
|
|
enableSaveButton = function() {
|
|
// enable the inline discussion topics.
|
|
$('.check-cohort-inline-discussions').prop('checked', 'checked').change();
|
|
|
|
$($('.check-discussion-subcategory-inline')[0]).prop('checked', 'checked').change();
|
|
|
|
expect($(inlineDiscussionsSaveButtonCss).prop('disabled')).toBeFalsy();
|
|
};
|
|
|
|
verifySuccess = function() {
|
|
// verify the success message.
|
|
expect($(inlineDiscussionsSaveButtonCss).prop('disabled')).toBeTruthy();
|
|
verifyMessage('Your changes have been saved.', 'confirmation');
|
|
};
|
|
|
|
mockPatchRequest = function(dividededInlineDiscussions) {
|
|
AjaxHelpers.expectJsonRequest(
|
|
requests, 'PATCH', '/mock_service/discussions/settings',
|
|
{
|
|
divided_inline_discussions: dividededInlineDiscussions,
|
|
always_divide_inline_discussions: false
|
|
}
|
|
);
|
|
AjaxHelpers.respondWithJson(
|
|
requests,
|
|
{
|
|
divided_inline_discussions: dividededInlineDiscussions,
|
|
always_divide_inline_discussions: false
|
|
}
|
|
);
|
|
};
|
|
|
|
mockGetRequest = function(alldivided) {
|
|
// fake request for discussion/topics with GET method.
|
|
AjaxHelpers.expectJsonRequest(
|
|
requests, 'GET', '/mock_service/discussion/topics'
|
|
);
|
|
AjaxHelpers.respondWithJson(
|
|
requests,
|
|
createMockDiscussions(alldivided)
|
|
);
|
|
};
|
|
|
|
it('shows the "Save" button as disabled initially', function() {
|
|
createDiscussionsView(this);
|
|
expect($(inlineDiscussionsSaveButtonCss).prop('disabled')).toBeTruthy();
|
|
});
|
|
|
|
it('shows always divide radio button as selected', function() {
|
|
createDiscussionsView(this);
|
|
$('.check-all-inline-discussions').prop('checked', 'checked').change();
|
|
|
|
// verify always divide inline discussions is being selected.
|
|
expect($('.check-all-inline-discussions').prop('checked')).toBeTruthy();
|
|
|
|
// verify that inline topics are disabled
|
|
expect($('.check-discussion-subcategory-inline').prop('disabled')).toBeTruthy();
|
|
expect($('.check-discussion-category').prop('disabled')).toBeTruthy();
|
|
|
|
// verify that divide some topics are not being selected.
|
|
expect($('.check-cohort-inline-discussions').prop('checked')).toBeFalsy();
|
|
});
|
|
|
|
it('shows divide some topics radio button as selected', function() {
|
|
createDiscussionsView(this);
|
|
$('.check-cohort-inline-discussions').prop('checked', 'checked').change();
|
|
|
|
// verify some divide inline discussions radio is being selected.
|
|
expect($('.check-cohort-inline-discussions').prop('checked')).toBeTruthy();
|
|
|
|
// verify always divide radio is not selected.
|
|
expect($('.check-all-inline-discussions').prop('checked')).toBeFalsy();
|
|
|
|
// verify that inline topics are enabled
|
|
expect($('.check-discussion-subcategory-inline').prop('disabled')).toBeFalsy();
|
|
expect($('.check-discussion-category').prop('disabled')).toBeFalsy();
|
|
});
|
|
|
|
it('has divided and non-divided topics', function() {
|
|
createDiscussionsView(this);
|
|
enableSaveButton();
|
|
assertDividedTopics(this, 'inline');
|
|
});
|
|
|
|
it('enables "Save" button after changing from always inline option', function() {
|
|
createDiscussionsView(this);
|
|
enableSaveButton();
|
|
});
|
|
|
|
it('saves the topic', function() {
|
|
createDiscussionsView(this);
|
|
enableSaveButton();
|
|
|
|
// Save the updated settings
|
|
$('.action-save').click();
|
|
|
|
mockPatchRequest(['Inline_Discussion_1']);
|
|
mockGetRequest();
|
|
|
|
verifySuccess();
|
|
});
|
|
|
|
it('selects the parent category when all children are selected', function() {
|
|
createDiscussionsView(this);
|
|
enableSaveButton();
|
|
|
|
// parent category should be indeterminate.
|
|
expect($('.check-discussion-category:checked').length).toBe(0);
|
|
expect($('.check-discussion-category:indeterminate').length).toBe(1);
|
|
|
|
$('.check-discussion-subcategory-inline').prop('checked', 'checked').change();
|
|
// parent should be checked as we checked all children
|
|
expect($('.check-discussion-category:checked').length).toBe(1);
|
|
});
|
|
|
|
it('selects/deselects all children when a parent category is selected/deselected', function() {
|
|
createDiscussionsView(this);
|
|
enableSaveButton();
|
|
|
|
expect($('.check-discussion-category:checked').length).toBe(0);
|
|
|
|
$('.check-discussion-category').prop('checked', 'checked').change();
|
|
|
|
expect($('.check-discussion-category:checked').length).toBe(1);
|
|
expect($('.check-discussion-subcategory-inline:checked').length).toBe(2);
|
|
|
|
// un-check the parent, all children should be unchecd.
|
|
$('.check-discussion-category').prop('checked', false).change();
|
|
expect($('.check-discussion-category:checked').length).toBe(0);
|
|
expect($('.check-discussion-subcategory-inline:checked').length).toBe(0);
|
|
});
|
|
|
|
it('saves correctly when a subset of topics are selected within a category', function() {
|
|
createDiscussionsView(this);
|
|
enableSaveButton();
|
|
|
|
// parent category should be indeterminate.
|
|
expect($('.check-discussion-category:checked').length).toBe(0);
|
|
expect($('.check-discussion-category:indeterminate').length).toBe(1);
|
|
|
|
// Save the updated settings
|
|
$('#cohort-inline-discussions-form .action-save').click();
|
|
|
|
mockPatchRequest(['Inline_Discussion_1']);
|
|
mockGetRequest();
|
|
|
|
verifySuccess();
|
|
// parent category should be indeterminate.
|
|
expect($('.check-discussion-category:indeterminate').length).toBe(1);
|
|
});
|
|
|
|
it('saves correctly when all child topics are selected within a category', function() {
|
|
createDiscussionsView(this);
|
|
enableSaveButton();
|
|
|
|
// parent category should be indeterminate.
|
|
expect($('.check-discussion-category:checked').length).toBe(0);
|
|
expect($('.check-discussion-category:indeterminate').length).toBe(1);
|
|
|
|
$('.check-discussion-subcategory-inline').prop('checked', 'checked').change();
|
|
// Save the updated settings
|
|
$('#cohort-inline-discussions-form .action-save').click();
|
|
|
|
mockPatchRequest(['Inline_Discussion_1', 'Inline_Discussion_2']);
|
|
mockGetRequest(true);
|
|
|
|
verifySuccess();
|
|
// parent category should be checked.
|
|
expect($('.check-discussion-category:checked').length).toBe(1);
|
|
});
|
|
|
|
it('shows an appropriate message when no inline topics exist', function() {
|
|
var topicsJson, options, expectedTitle;
|
|
|
|
topicsJson = {
|
|
course_wide_discussions: {
|
|
children: [['Topic_C_1', 'entry']],
|
|
entries: {
|
|
Topic_C_1: {
|
|
sort_key: null,
|
|
is_divided: true,
|
|
id: 'Topic_C_1'
|
|
}
|
|
}
|
|
},
|
|
inline_discussions: {
|
|
subcategories: {},
|
|
children: []
|
|
}
|
|
};
|
|
options = {dividedDiscussions: new CourseDiscussionTopicDetailsModel(topicsJson)};
|
|
createDiscussionsView(this, options);
|
|
|
|
expectedTitle = 'No content-specific discussion topics exist.';
|
|
expect($('.no-topics').text().trim()).toBe(expectedTitle);
|
|
});
|
|
|
|
it('shows an appropriate message when subsequent "GET" returns HTTP500', function() {
|
|
var expectedTitle;
|
|
createDiscussionsView(this);
|
|
enableSaveButton();
|
|
|
|
// Save the updated settings
|
|
$('#cohort-inline-discussions-form .action-save').click();
|
|
|
|
mockPatchRequest(['Inline_Discussion_1']);
|
|
|
|
// fake request for discussion/topics with GET method.
|
|
AjaxHelpers.expectJsonRequest(
|
|
requests, 'GET', '/mock_service/discussion/topics'
|
|
);
|
|
AjaxHelpers.respondWithError(requests, 500);
|
|
|
|
expectedTitle = "We've encountered an error. Refresh your browser and then try again.";
|
|
expect($('.message-title').text().trim()).toBe(expectedTitle);
|
|
});
|
|
|
|
it('shows an appropriate error message for HTTP500', function() {
|
|
var expectedTitle;
|
|
createDiscussionsView(this);
|
|
enableSaveButton();
|
|
|
|
$($('.check-discussion-subcategory-inline')[1]).prop('checked', 'checked').change();
|
|
$('#cohort-inline-discussions-form .action-save').click();
|
|
|
|
AjaxHelpers.respondWithError(requests, 500);
|
|
expectedTitle = "We've encountered an error. Refresh your browser and then try again.";
|
|
expect($('.message-title').text().trim()).toBe(expectedTitle);
|
|
});
|
|
});
|
|
});
|
|
});
|
|
});
|