Commit 85111ceb by Carlos de la Guardia

Add jasmine tests for ccx schedule code.

parent ae819b0e
......@@ -6,8 +6,6 @@ var edx = edx || {};
edx.ccx = edx.ccx || {};
edx.ccx.schedule = edx.ccx.schedule || {};
var syncErrorMessage = gettext("The data could not be saved.");
var self;
edx.ccx.schedule.reloadPage = function() {
......@@ -42,8 +40,8 @@ var edx = edx || {};
this.schedule = {};
this.schedule_collection.bind('reset', this.render);
this.schedule_collection.fetch({reset: true});
this.chapter_select = $('form#add-unit select[name="chapter"]'),
this.sequential_select = $('form#add-unit select[name="sequential"]'),
this.chapter_select = $('form#add-unit select[name="chapter"]');
this.sequential_select = $('form#add-unit select[name="sequential"]');
this.vertical_select = $('form#add-unit select[name="vertical"]');
this.dirty = false;
self = this;
......@@ -56,7 +54,7 @@ var edx = edx || {};
});
// Add unit handlers
this.chapter_select.on('change', function(event) {
this.chapter_select.on('change', function() {
var chapter_location = self.chapter_select.val();
self.vertical_select.html('').prop('disabled', true);
if (chapter_location !== 'none') {
......@@ -74,7 +72,7 @@ var edx = edx || {};
}
});
this.sequential_select.on('change', function(event) {
this.sequential_select.on('change', function() {
var sequential_location = self.sequential_select.val();
if (sequential_location !== 'all') {
var chapter = self.chapter_select.val(),
......@@ -91,7 +89,7 @@ var edx = edx || {};
}
});
this.vertical_select.on('change', function(event) {
this.vertical_select.on('change', function() {
var vertical_location = self.vertical_select.val();
if (vertical_location !== 'all') {
var chapter = self.chapter_select.val(),
......@@ -111,15 +109,15 @@ var edx = edx || {};
vertical = self.vertical_select.val(),
units = self.find_lineage(self.schedule,
chapter,
sequential == 'all' ? null : sequential,
vertical == 'all' ? null: vertical),
sequential === 'all' ? null : sequential,
vertical === 'all' ? null: vertical),
start = self.get_datetime('start'),
due = self.get_datetime('due');
units.map(self.show);
var unit = units[units.length - 1]
var unit = units[units.length - 1];
self.schedule_apply([unit], self.show);
if (unit !== undefined && start) unit.start = start;
if (unit !== undefined && due) unit.due = due;
if (unit !== undefined && start) { unit.start = start; }
if (unit !== undefined && due) { unit.due = due; }
self.schedule_collection.set(self.schedule);
self.dirty = true;
self.render();
......@@ -136,9 +134,9 @@ var edx = edx || {};
render: function() {
self.schedule = this.schedule_collection.toJSON();
self.hidden = this.pruned(self.schedule, function(node) {
return node.hidden || node.category !== 'vertical'});
return node.hidden || node.category !== 'vertical';});
this.showing = this.pruned(self.schedule, function(node) {
return !node.hidden});
return !node.hidden;});
this.$el.html(schedule_template({chapters: this.showing}));
$('table.ccx-schedule .sequential,.vertical').hide();
$('table.ccx-schedule .toggle-collapse').on('click', this.toggle_collapse);
......@@ -164,7 +162,7 @@ var edx = edx || {};
self.render();
});
// Remove unit handler
$('table.ccx-schedule a.remove-unit').on('click', function(event) {
$('table.ccx-schedule a.remove-unit').on('click', function() {
var row = $(this).closest('tr'),
path = row.data('location').split(' '),
unit = self.find_unit(self.schedule, path[0], path[1], path[2]);
......@@ -193,8 +191,8 @@ var edx = edx || {};
}
// Show or hide save button
if (this.dirty) $('#dirty-schedule').show()
else $('#dirty-schedule').hide();
if (this.dirty) {$('#dirty-schedule').show();}
else {$('#dirty-schedule').hide();}
$('#ajax-error').hide();
......@@ -211,7 +209,7 @@ var edx = edx || {};
type: 'POST',
contentType: 'application/json',
data: JSON.stringify(self.schedule),
success: function(data, textStatus, jqXHR) {
success: function(data) {
self.dirty = false;
self.render();
button.prop('disabled', false).text(gettext("Save changes"));
......@@ -220,7 +218,7 @@ var edx = edx || {};
// may have changed.
$('#grading-policy').text(data.grading_policy);
},
error: function(jqXHR, textStatus, error) {
error: function(jqXHR) {
console.log(jqXHR.responseText);
$('#ajax-error').show();
$('#dirty-schedule').hide();
......@@ -245,8 +243,8 @@ var edx = edx || {};
get_datetime: function(which) {
var date = $('form#add-unit input[name=' + which + '_date]').val();
var time = $('form#add-unit input[name=' + which + '_time]').val();
if (date && time)
return date + ' ' + time;
if (date && time) {
return date + ' ' + time; }
return null;
},
......@@ -269,7 +267,7 @@ var edx = edx || {};
schedule_apply: function(nodes, f) {
nodes.map(function(node) {
f(node);
if (node !== undefined && node.children !== undefined) self.schedule_apply(node.children, f);
if (node !== undefined && node.children !== undefined) { self.schedule_apply(node.children, f); }
});
},
......@@ -278,7 +276,7 @@ var edx = edx || {};
.map(function(node) {
var copy = {};
$.extend(copy, node);
if (node.children) copy.children = self.pruned(node.children, filter);
if (node.children) {copy.children = self.pruned(node.children, filter);}
return copy;
})
.filter(function(node) {
......@@ -308,13 +306,13 @@ var edx = edx || {};
},
enterNewDate: function(what) {
return function(event) {
return function() {
var row = $(this).closest('tr');
var modal = $('#enter-date-modal')
.data('what', what)
.data('location', row.data('location'));
modal.find('h2').text(
what == 'due' ? gettext("Enter Due Date") :
what === 'due' ? gettext("Enter Due Date") :
gettext("Enter Start Date"));
modal.find('label').text(row.find('td:first').text());
......@@ -341,7 +339,7 @@ var edx = edx || {};
alert('Please enter a valid time');
return;
}
if (what == 'start') {
if (what === 'start') {
unit.start = date + ' ' + time;
} else {
unit.due = date + ' ' + time;
......@@ -351,7 +349,7 @@ var edx = edx || {};
self.schedule_collection.set(self.schedule);
self.render();
});
}
};
},
find_unit: function(tree, chapter, sequential, vertical) {
......@@ -361,18 +359,18 @@ var edx = edx || {};
find_lineage: function(tree, chapter, sequential, vertical) {
function find_in(seq, location) {
for (var i = 0; i < seq.length; i++)
if (seq[i].location === location)
return seq[i];
}
for (var i = 0; i < seq.length; i++) {
if (seq[i].location === location) {
return seq[i];}
}}
var units = [],
unit = find_in(tree, chapter);
units[units.length] = unit;
if (sequential) {
units[units.length] = unit = find_in(unit.children, sequential);
if (vertical)
units[units.length] = unit = find_in(unit.children, vertical);
if (vertical) {
units[units.length] = unit = find_in(unit.children, vertical);}
}
return units;
......
<div class="ccx-schedule-container">
<div id="ccx-schedule"></div>
<div id="new-ccx-schedule"></div>
</div>
<section id="enter-date-modal" class="modal" aria-hidden="true">
<div class="inner-wrapper" role="dialog">
<button class="close-modal">
<i class="fa-remove"></i>
<span class="sr">
Close
</span>
</button>
<header>
<h2></h2>
</header>
<form role="form">
<div class="field datepair">
<label></label>
<input placeholder="Date" class="date" type="text" name="date"/ size="11">
<input placeholder="Time" class="time" type="text" name="time"/ size="6">
</div>
<div class="field">
<button type="submit" class="btn btn-primary">Set date</button>
</div>
</form>
</div>
</section>
<div class="ccx-schedule-sidebar">
<div class="ccx-sidebar-panel" id="dirty-schedule">
<h2>Save changes</h2>
<form role="form">
<p>You have unsaved changes.</p>
<div class="field">
<br/>
<button id="save-changes">Save changes</button>
</div>
</form>
</div>
<div class="ccx-sidebar-panel" id="ajax-error">
<h2>Error</h2>
<p>There was an error saving changes.</p>
</div>
<div class="ccx-sidebar-panel">
<h2>Schedule a Unit</h2>
<form role="form" id="add-unit" name="add-unit" class="ccx-form">
<div class="field">
<b>Section</b><br/>
<select name="chapter"></select>
</div>
<div class="field">
<b>Subsection</b><br/>
<select name="sequential"></select>
</div>
<div class="field">
<b>Unit</b><br/>
<select name="vertical"></select>
</div>
<div class="field datepair">
<b>Start Date</b><br/>
<input placeholder="Date" type="date" class="date" name="start_date"/>
<input placeholder="time" type="time" class="time" name="start_time"/>
</div>
<div class="field datepair">
<b>Due Date</b> (Optional)<br/>
<input placeholder="Date" type="date" class="date" name="due_date"/>
<input placeholder="time" type="time" class="time" name="due_time"/>
</div>
<div class="field">
<br/>
<button id="add-unit-button">Add Unit</button>
</div>
<div class="field">
<br/>
<button id="add-all">Add All Units</button>
</div>
</form>
<div id="all-units-added">
All units have been added.
</div>
</div>
</div>
define(['js/common_helpers/ajax_helpers', 'js/ccx/schedule'],
function(AjaxHelpers) {
describe("edx.ccx.schedule.ScheduleView", function() {
var view = null;
beforeEach(function() {
loadFixtures("js/fixtures/ccx/schedule.html");
var scheduleFixture = readFixtures("templates/ccx/schedule.underscore");
appendSetFixtures("<div id=\"schedule_template\">" + scheduleFixture + "</div>");
schedule_template = _.template($('#schedule_template').html());
save_url = 'save_ccx';
$.fn.leanModal = function(param) {
return true;
}
data = [{
"category": "chapter",
"display_name": "Introduction",
"due": null,
"start": null,
"location": "i4x://edX/DemoX/chapter/d8a6192ade314473a78242dfeedfbf5b",
"hidden": true,
"children": [
{
"category": "sequential",
"display_name": "Demo Course Overview",
"due": null,
"start": null,
"location": "i4x://edX/DemoX/sequential/edx_introduction",
"hidden": true,
"children": [
{
"category": "vertical",
"display_name": "Introduction: Video and Sequences",
"due": null,
"start": null,
"location": "i4x://edX/DemoX/vertical/vertical_0270f6de40fc",
"hidden": true
}
]
}
]
}];
view = new edx.ccx.schedule.ScheduleView({el: $('#new-ccx-schedule')});
view.schedule_collection.set(data)
view.render();
});
it("verifies correct view setup", function() {
expect(view.dirty).toBe(false);
expect(view.showing).toEqual([]);
expect(view.hidden).toEqual(data);
expect(view.schedule).toEqual(data);
});
it("finds a unit", function() {
var unit = view.find_unit(view.schedule, 'i4x://edX/DemoX/chapter/d8a6192ade314473a78242dfeedfbf5b');
expect(unit).toEqual(data[0]);
});
it("hides a unit", function() {
var unit = view.find_unit(view.schedule, 'i4x://edX/DemoX/chapter/d8a6192ade314473a78242dfeedfbf5b');
unit.hidden = false;
view.hide(unit);
expect(unit.hidden).toBe(true);
});
it("shows a unit", function() {
var unit = view.find_unit(view.schedule, 'i4x://edX/DemoX/chapter/d8a6192ade314473a78242dfeedfbf5b');
view.show(unit);
expect(unit.hidden).toBe(false);
});
it("applies function to schedule nodes", function() {
var unit = view.find_unit(view.schedule, 'i4x://edX/DemoX/chapter/d8a6192ade314473a78242dfeedfbf5b');
expect(unit.hidden).toBe(true);
view.schedule_apply(view.schedule, view.show)
expect(unit.hidden).toBe(false);
});
it("adds all units to schedule", function() {
expect(view.showing).toEqual([]);
expect(view.hidden.length).toEqual(1);
$('#add-all').click();
expect(view.showing.length).toEqual(1);
expect(view.hidden).toEqual([]);
});
it("selects a chapter and adds units to dropdown", function() {
expect(view.sequential_select.children('option').length).toEqual(0);
view.chapter_select.change();
expect(view.sequential_select.prop('disabled')).toEqual(true);
var val = 'i4x://edX/DemoX/chapter/d8a6192ade314473a78242dfeedfbf5b';
view.chapter_select.val(val);
view.chapter_select.change();
expect(view.chapter_select.val()).toEqual(val);
expect(view.sequential_select.prop('disabled')).toEqual(false);
expect(view.sequential_select.children('option').length).toEqual(2);
});
it("selects a unit and adds sections to dropdown", function() {
var val = 'i4x://edX/DemoX/chapter/d8a6192ade314473a78242dfeedfbf5b';
view.chapter_select.val(val);
view.chapter_select.change();
expect(view.vertical_select.children('option').length).toEqual(0);
view.sequential_select.change();
expect(view.vertical_select.prop('disabled')).toEqual(true);
val = "i4x://edX/DemoX/sequential/edx_introduction";
view.sequential_select.val(val);
view.sequential_select.change();
expect(view.sequential_select.val()).toEqual(val);
expect(view.vertical_select.prop('disabled')).toEqual(false);
expect(view.vertical_select.children('option').length).toEqual(2);
});
it("selects a section", function() {
var val = 'i4x://edX/DemoX/chapter/d8a6192ade314473a78242dfeedfbf5b';
view.chapter_select.val(val);
view.chapter_select.change();
val = "i4x://edX/DemoX/sequential/edx_introduction";
view.sequential_select.val(val);
view.sequential_select.change();
val = "i4x://edX/DemoX/vertical/vertical_0270f6de40fc",
view.vertical_select.val(val);
view.vertical_select.change();
expect(view.vertical_select.val()).toEqual(val);
});
it("adds a unit", function() {
var val = 'i4x://edX/DemoX/chapter/d8a6192ade314473a78242dfeedfbf5b';
view.chapter_select.val(val);
view.chapter_select.change();
val = "i4x://edX/DemoX/sequential/edx_introduction";
view.sequential_select.val(val);
view.sequential_select.change();
val = "i4x://edX/DemoX/vertical/vertical_0270f6de40fc",
view.vertical_select.val(val);
view.vertical_select.change();
var unit = view.find_unit(view.schedule, 'i4x://edX/DemoX/chapter/d8a6192ade314473a78242dfeedfbf5b');
expect(unit.hidden).toBe(true);
$('#add-unit-button').click();
expect(unit.hidden).toBe(false);
});
it("gets a datetime string from date and time fields", function() {
view.set_datetime('start', '2015-12-12 10:45');
expect($('form#add-unit input[name=start_date]')).toHaveValue('2015-12-12');
expect($('form#add-unit input[name=start_time]')).toHaveValue('10:45');
});
it("sets date and time fields from datetime string", function() {
$('form#add-unit input[name=start_date]').val('2015-12-12');
$('form#add-unit input[name=start_time]').val('10:45');
var datetime = view.get_datetime('start');
expect(datetime).toBe('2015-12-12 10:45');
});
it("saves schedule changes", function() {
requests = AjaxHelpers["requests"](this)
view.save();
expect(requests.length).toEqual(1)
AjaxHelpers.expectJsonRequest(requests, 'POST', 'save_ccx', view.schedule);
expect($('#dirty-schedule #save-changes').text()).toEqual("Saving...");
AjaxHelpers.respondWithJson(requests, {
data: view.schedule
});
expect($('#dirty-schedule #save-changes').text()).toEqual("Save changes");
expect($('#ajax-error')).toHaveCss({display: 'none'});
});
it("displays an error if the sync fails", function() {
requests = AjaxHelpers["requests"](this)
view.save();
requests[0].respond(500);
expect($('#ajax-error')).toHaveCss({display: 'block'});
});
});
}
);
......@@ -94,6 +94,7 @@
'js/student_profile/views/learner_profile_fields': 'js/student_profile/views/learner_profile_fields',
'js/student_profile/views/learner_profile_factory': 'js/student_profile/views/learner_profile_factory',
'js/student_profile/views/learner_profile_view': 'js/student_profile/views/learner_profile_view',
'js/ccx/schedule': 'js/ccx/schedule',
// edxnotes
'annotator_1.2.9': 'xmodule_js/common_static/js/vendor/edxnotes/annotator-full.min',
......@@ -298,6 +299,10 @@
exports: 'js/shoppingcart/shoppingcart',
deps: ['jquery', 'underscore', 'gettext']
},
'js/ccx/schedule': {
exports: 'js/ccx/schedule',
deps: ['jquery', 'underscore', 'backbone', 'gettext']
},
// Backbone classes loaded explicitly until they are converted to use RequireJS
'js/instructor_dashboard/ecommerce': {
......@@ -633,7 +638,8 @@
'lms/include/js/spec/edxnotes/plugins/caret_navigation_spec.js',
'lms/include/js/spec/edxnotes/collections/notes_spec.js',
'lms/include/js/spec/search/search_spec.js',
'lms/include/js/spec/discovery/discovery_spec.js'
'lms/include/js/spec/discovery/discovery_spec.js',
'lms/include/js/spec/ccx/schedule_spec.js'
]);
}).call(this, requirejs, define);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment