Commit 94614db4 by David Ormsbee Committed by Calen Pennington

CoffeeScript tests migration: Remove implicit returns

parent 0880502f
/*
* decaffeinate suggestions:
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
define(["js/models/course"], Course => define(["js/models/course"], Course =>
describe("Course", () => describe("Course", () =>
describe("basic", function() { describe("basic", function() {
beforeEach(function() { beforeEach(function() {
return this.model = new Course({ this.model = new Course({
name: "Greek Hero" name: "Greek Hero"
}); });
}); });
return it("should take a name argument", function() { it("should take a name argument", function() {
return expect(this.model.get("name")).toEqual("Greek Hero"); expect(this.model.get("name")).toEqual("Greek Hero");
}); });
}) })
) )
......
/*
* decaffeinate suggestions:
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
define(["js/models/metadata"], Metadata => define(["js/models/metadata"], Metadata =>
describe("Metadata", function() { describe("Metadata", function() {
it("knows when the value has not been modified", function() { it("knows when the value has not been modified", function() {
...@@ -13,7 +8,7 @@ define(["js/models/metadata"], Metadata => ...@@ -13,7 +8,7 @@ define(["js/models/metadata"], Metadata =>
model = new Metadata( model = new Metadata(
{'value': 'original', 'explicitly_set': true}); {'value': 'original', 'explicitly_set': true});
model.setValue('original'); model.setValue('original');
return expect(model.isModified()).toBeFalsy(); expect(model.isModified()).toBeFalsy();
}); });
it("knows when the value has been modified", function() { it("knows when the value has been modified", function() {
...@@ -25,7 +20,7 @@ define(["js/models/metadata"], Metadata => ...@@ -25,7 +20,7 @@ define(["js/models/metadata"], Metadata =>
model = new Metadata( model = new Metadata(
{'value': 'original', 'explicitly_set': true}); {'value': 'original', 'explicitly_set': true});
model.setValue('modified'); model.setValue('modified');
return expect(model.isModified()).toBeTruthy(); expect(model.isModified()).toBeTruthy();
}); });
it("tracks when values have been explicitly set", function() { it("tracks when values have been explicitly set", function() {
...@@ -33,7 +28,7 @@ define(["js/models/metadata"], Metadata => ...@@ -33,7 +28,7 @@ define(["js/models/metadata"], Metadata =>
{'value': 'original', 'explicitly_set': false}); {'value': 'original', 'explicitly_set': false});
expect(model.isExplicitlySet()).toBeFalsy(); expect(model.isExplicitlySet()).toBeFalsy();
model.setValue('original'); model.setValue('original');
return expect(model.isExplicitlySet()).toBeTruthy(); expect(model.isExplicitlySet()).toBeTruthy();
}); });
it("has both 'display value' and a 'value' methods", function() { it("has both 'display value' and a 'value' methods", function() {
...@@ -43,7 +38,7 @@ define(["js/models/metadata"], Metadata => ...@@ -43,7 +38,7 @@ define(["js/models/metadata"], Metadata =>
expect(model.getDisplayValue()).toBe('default'); expect(model.getDisplayValue()).toBe('default');
model.setValue('modified'); model.setValue('modified');
expect(model.getValue()).toBe('modified'); expect(model.getValue()).toBe('modified');
return expect(model.getDisplayValue()).toBe('modified'); expect(model.getDisplayValue()).toBe('modified');
}); });
it("has a clear method for reverting to the default", function() { it("has a clear method for reverting to the default", function() {
...@@ -52,22 +47,22 @@ define(["js/models/metadata"], Metadata => ...@@ -52,22 +47,22 @@ define(["js/models/metadata"], Metadata =>
model.clear(); model.clear();
expect(model.getValue()).toBeNull; expect(model.getValue()).toBeNull;
expect(model.getDisplayValue()).toBe('default'); expect(model.getDisplayValue()).toBe('default');
return expect(model.isExplicitlySet()).toBeFalsy(); expect(model.isExplicitlySet()).toBeFalsy();
}); });
it("has a getter for field name", function() { it("has a getter for field name", function() {
const model = new Metadata({'field_name': 'foo'}); const model = new Metadata({'field_name': 'foo'});
return expect(model.getFieldName()).toBe('foo'); expect(model.getFieldName()).toBe('foo');
}); });
it("has a getter for options", function() { it("has a getter for options", function() {
const model = new Metadata({'options': ['foo', 'bar']}); const model = new Metadata({'options': ['foo', 'bar']});
return expect(model.getOptions()).toEqual(['foo', 'bar']); expect(model.getOptions()).toEqual(['foo', 'bar']);
}); });
return it("has a getter for type", function() { it("has a getter for type", function() {
const model = new Metadata({'type': 'Integer'}); const model = new Metadata({'type': 'Integer'});
return expect(model.getType()).toBe(Metadata.INTEGER_TYPE); expect(model.getType()).toBe(Metadata.INTEGER_TYPE);
}); });
}) })
); );
......
...@@ -7,26 +7,26 @@ define(["js/models/section", "edx-ui-toolkit/js/utils/spec-helpers/ajax-helpers" ...@@ -7,26 +7,26 @@ define(["js/models/section", "edx-ui-toolkit/js/utils/spec-helpers/ajax-helpers"
describe("Section", function() { describe("Section", function() {
describe("basic", function() { describe("basic", function() {
beforeEach(function() { beforeEach(function() {
return this.model = new Section({ this.model = new Section({
id: 42, id: 42,
name: "Life, the Universe, and Everything" name: "Life, the Universe, and Everything"
}); });
}); });
it("should take an id argument", function() { it("should take an id argument", function() {
return expect(this.model.get("id")).toEqual(42); expect(this.model.get("id")).toEqual(42);
}); });
it("should take a name argument", function() { it("should take a name argument", function() {
return expect(this.model.get("name")).toEqual("Life, the Universe, and Everything"); expect(this.model.get("name")).toEqual("Life, the Universe, and Everything");
}); });
it("should have a URL set", function() { it("should have a URL set", function() {
return expect(this.model.url()).toEqual(ModuleUtils.getUpdateUrl(42)); expect(this.model.url()).toEqual(ModuleUtils.getUpdateUrl(42));
}); });
return it("should serialize to JSON correctly", function() { it("should serialize to JSON correctly", function() {
return expect(this.model.toJSON()).toEqual({ expect(this.model.toJSON()).toEqual({
metadata: metadata:
{ {
display_name: "Life, the Universe, and Everything" display_name: "Life, the Universe, and Everything"
...@@ -35,11 +35,11 @@ define(["js/models/section", "edx-ui-toolkit/js/utils/spec-helpers/ajax-helpers" ...@@ -35,11 +35,11 @@ define(["js/models/section", "edx-ui-toolkit/js/utils/spec-helpers/ajax-helpers"
}); });
}); });
return describe("XHR", function() { describe("XHR", function() {
beforeEach(function() { beforeEach(function() {
spyOn(Section.prototype, 'showNotification'); spyOn(Section.prototype, 'showNotification');
spyOn(Section.prototype, 'hideNotification'); spyOn(Section.prototype, 'hideNotification');
return this.model = new Section({ this.model = new Section({
id: 42, id: 42,
name: "Life, the Universe, and Everything" name: "Life, the Universe, and Everything"
}); });
...@@ -51,16 +51,16 @@ define(["js/models/section", "edx-ui-toolkit/js/utils/spec-helpers/ajax-helpers" ...@@ -51,16 +51,16 @@ define(["js/models/section", "edx-ui-toolkit/js/utils/spec-helpers/ajax-helpers"
this.model.save(); this.model.save();
expect(Section.prototype.showNotification).toHaveBeenCalled(); expect(Section.prototype.showNotification).toHaveBeenCalled();
server.respond(); server.respond();
return expect(Section.prototype.hideNotification).toHaveBeenCalled(); expect(Section.prototype.hideNotification).toHaveBeenCalled();
}); });
return it("don't hide notification when saving fails", function() { it("don't hide notification when saving fails", function() {
// this is handled by the global AJAX error handler // this is handled by the global AJAX error handler
const server = AjaxHelpers.server([500, {"Content-Type": "application/json"}, "{}"]); const server = AjaxHelpers.server([500, {"Content-Type": "application/json"}, "{}"]);
this.model.save(); this.model.save();
server.respond(); server.respond();
return expect(Section.prototype.hideNotification).not.toHaveBeenCalled(); expect(Section.prototype.hideNotification).not.toHaveBeenCalled();
}); });
}); });
}) })
......
/*
* decaffeinate suggestions:
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
define(["js/models/settings/course_grader"], CourseGrader => define(["js/models/settings/course_grader"], CourseGrader =>
describe("CourseGraderModel", () => describe("CourseGraderModel", () =>
describe("parseWeight", function() { describe("parseWeight", function() {
...@@ -10,29 +5,29 @@ define(["js/models/settings/course_grader"], CourseGrader => ...@@ -10,29 +5,29 @@ define(["js/models/settings/course_grader"], CourseGrader =>
const model = new CourseGrader({weight: 7.0001, min_count: 3.67, drop_count: 1.88}, {parse:true}); const model = new CourseGrader({weight: 7.0001, min_count: 3.67, drop_count: 1.88}, {parse:true});
expect(model.get('weight')).toBe(7); expect(model.get('weight')).toBe(7);
expect(model.get('min_count')).toBe(4); expect(model.get('min_count')).toBe(4);
return expect(model.get('drop_count')).toBe(2); expect(model.get('drop_count')).toBe(2);
}); });
it("converts float value of weight to an integer with rounding", function() { it("converts float value of weight to an integer with rounding", function() {
const model = new CourseGrader({weight: 28.999999999999996}, {parse:true}); const model = new CourseGrader({weight: 28.999999999999996}, {parse:true});
return expect(model.get('weight')).toBe(29); expect(model.get('weight')).toBe(29);
}); });
it("converts a string to an integer", function() { it("converts a string to an integer", function() {
const model = new CourseGrader({weight: '7.0001', min_count: '3.67', drop_count: '1.88'}, {parse:true}); const model = new CourseGrader({weight: '7.0001', min_count: '3.67', drop_count: '1.88'}, {parse:true});
expect(model.get('weight')).toBe(7); expect(model.get('weight')).toBe(7);
expect(model.get('min_count')).toBe(4); expect(model.get('min_count')).toBe(4);
return expect(model.get('drop_count')).toBe(2); expect(model.get('drop_count')).toBe(2);
}); });
it("does a no-op for integers", function() { it("does a no-op for integers", function() {
const model = new CourseGrader({weight: 7, min_count: 3, drop_count: 1}, {parse:true}); const model = new CourseGrader({weight: 7, min_count: 3, drop_count: 1}, {parse:true});
expect(model.get('weight')).toBe(7); expect(model.get('weight')).toBe(7);
expect(model.get('min_count')).toBe(3); expect(model.get('min_count')).toBe(3);
return expect(model.get('drop_count')).toBe(1); expect(model.get('drop_count')).toBe(1);
}); });
return it("gives validation error if min_count is less than 1 or drop_count is NaN", function() { it("gives validation error if min_count is less than 1 or drop_count is NaN", function() {
const model = new CourseGrader(); const model = new CourseGrader();
let errors = model.validate({min_count: 0, drop_count: ''}, {validate:true}); let errors = model.validate({min_count: 0, drop_count: ''}, {validate:true});
expect(errors.min_count).toBe('Please enter an integer greater than 0.'); expect(errors.min_count).toBe('Please enter an integer greater than 0.');
...@@ -44,7 +39,7 @@ define(["js/models/settings/course_grader"], CourseGrader => ...@@ -44,7 +39,7 @@ define(["js/models/settings/course_grader"], CourseGrader =>
// don't allow floats // don't allow floats
errors = model.validate({min_count: 12.2, drop_count: 1.5}, {validate:true}); errors = model.validate({min_count: 12.2, drop_count: 1.5}, {validate:true});
expect(errors.min_count).toBe('Please enter an integer greater than 0.'); expect(errors.min_count).toBe('Please enter an integer greater than 0.');
return expect(errors.drop_count).toBe('Please enter non-negative integer.'); expect(errors.drop_count).toBe('Please enter non-negative integer.');
}); });
}) })
) )
......
/*
* decaffeinate suggestions:
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
define(["underscore", "js/models/settings/course_grading_policy"], (_, CourseGradingPolicy) => define(["underscore", "js/models/settings/course_grading_policy"], (_, CourseGradingPolicy) =>
describe("CourseGradingPolicy", function() { describe("CourseGradingPolicy", function() {
beforeEach(function() { beforeEach(function() {
...@@ -12,7 +7,7 @@ define(["underscore", "js/models/settings/course_grading_policy"], (_, CourseGra ...@@ -12,7 +7,7 @@ define(["underscore", "js/models/settings/course_grading_policy"], (_, CourseGra
describe("parse", () => describe("parse", () =>
it("sets a null grace period to 00:00", function() { it("sets a null grace period to 00:00", function() {
const attrs = this.model.parse({grace_period: null}); const attrs = this.model.parse({grace_period: null});
return expect(attrs.grace_period).toEqual({ expect(attrs.grace_period).toEqual({
hours: 0, hours: 0,
minutes: 0 minutes: 0
}); });
...@@ -22,30 +17,30 @@ define(["underscore", "js/models/settings/course_grading_policy"], (_, CourseGra ...@@ -22,30 +17,30 @@ define(["underscore", "js/models/settings/course_grading_policy"], (_, CourseGra
describe("parseGracePeriod", function() { describe("parseGracePeriod", function() {
it("parses a time in HH:MM format", function() { it("parses a time in HH:MM format", function() {
const time = this.model.parseGracePeriod("07:19"); const time = this.model.parseGracePeriod("07:19");
return expect(time).toEqual({ expect(time).toEqual({
hours: 7, hours: 7,
minutes: 19 minutes: 19
}); });
}); });
return it("returns null on an incorrectly formatted string", function() { it("returns null on an incorrectly formatted string", function() {
expect(this.model.parseGracePeriod("asdf")).toBe(null); expect(this.model.parseGracePeriod("asdf")).toBe(null);
expect(this.model.parseGracePeriod("7:19")).toBe(null); expect(this.model.parseGracePeriod("7:19")).toBe(null);
return expect(this.model.parseGracePeriod("1000:00")).toBe(null); expect(this.model.parseGracePeriod("1000:00")).toBe(null);
}); });
}); });
return describe("validate", function() { describe("validate", function() {
it("enforces that the passing grade is <= the minimum grade to receive credit if credit is enabled", function() { it("enforces that the passing grade is <= the minimum grade to receive credit if credit is enabled", function() {
this.model.set({minimum_grade_credit: 0.8, grace_period: '01:00', is_credit_course: true}); this.model.set({minimum_grade_credit: 0.8, grace_period: '01:00', is_credit_course: true});
this.model.set('grade_cutoffs', [0.9], {validate: true}); this.model.set('grade_cutoffs', [0.9], {validate: true});
return expect(_.keys(this.model.validationError)).toContain('minimum_grade_credit'); expect(_.keys(this.model.validationError)).toContain('minimum_grade_credit');
}); });
return it("does not enforce the passing grade limit in non-credit courses", function() { it("does not enforce the passing grade limit in non-credit courses", function() {
this.model.set({minimum_grade_credit: 0.8, grace_period: '01:00', is_credit_course: false}); this.model.set({minimum_grade_credit: 0.8, grace_period: '01:00', is_credit_course: false});
this.model.set({grade_cutoffs: [0.9]}, {validate: true}); this.model.set({grade_cutoffs: [0.9]}, {validate: true});
return expect(this.model.validationError).toBe(null); expect(this.model.validationError).toBe(null);
}); });
}); });
}) })
......
/*
* decaffeinate suggestions:
* DS102: Remove unnecessary code created because of implicit returns
* DS203: Remove `|| {}` from converted for-own loops
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
define(["backbone", "js/models/textbook", "js/collections/textbook", "js/models/chapter", "js/collections/chapter", "cms/js/main"], define(["backbone", "js/models/textbook", "js/collections/textbook", "js/models/chapter", "js/collections/chapter", "cms/js/main"],
function(Backbone, Textbook, TextbookSet, Chapter, ChapterSet, main) { function(Backbone, Textbook, TextbookSet, Chapter, ChapterSet, main) {
...@@ -12,55 +5,55 @@ function(Backbone, Textbook, TextbookSet, Chapter, ChapterSet, main) { ...@@ -12,55 +5,55 @@ function(Backbone, Textbook, TextbookSet, Chapter, ChapterSet, main) {
beforeEach(function() { beforeEach(function() {
main(); main();
this.model = new Textbook(); this.model = new Textbook();
return CMS.URL.TEXTBOOKS = "/textbooks"; CMS.URL.TEXTBOOKS = "/textbooks";
}); });
afterEach(() => delete CMS.URL.TEXTBOOKS); afterEach(() => delete CMS.URL.TEXTBOOKS);
describe("Basic", function() { describe("Basic", function() {
it("should have an empty name by default", function() { it("should have an empty name by default", function() {
return expect(this.model.get("name")).toEqual(""); expect(this.model.get("name")).toEqual("");
}); });
it("should not show chapters by default", function() { it("should not show chapters by default", function() {
return expect(this.model.get("showChapters")).toBeFalsy(); expect(this.model.get("showChapters")).toBeFalsy();
}); });
it("should have a ChapterSet with one chapter by default", function() { it("should have a ChapterSet with one chapter by default", function() {
const chapters = this.model.get("chapters"); const chapters = this.model.get("chapters");
expect(chapters).toBeInstanceOf(ChapterSet); expect(chapters).toBeInstanceOf(ChapterSet);
expect(chapters.length).toEqual(1); expect(chapters.length).toEqual(1);
return expect(chapters.at(0).isEmpty()).toBeTruthy(); expect(chapters.at(0).isEmpty()).toBeTruthy();
}); });
it("should be empty by default", function() { it("should be empty by default", function() {
return expect(this.model.isEmpty()).toBeTruthy(); expect(this.model.isEmpty()).toBeTruthy();
}); });
it("should have a URL root", function() { it("should have a URL root", function() {
const urlRoot = _.result(this.model, 'urlRoot'); const urlRoot = _.result(this.model, 'urlRoot');
return expect(urlRoot).toBeTruthy(); expect(urlRoot).toBeTruthy();
}); });
it("should be able to reset itself", function() { it("should be able to reset itself", function() {
this.model.set("name", "foobar"); this.model.set("name", "foobar");
this.model.reset(); this.model.reset();
return expect(this.model.get("name")).toEqual(""); expect(this.model.get("name")).toEqual("");
}); });
it("should not be dirty by default", function() { it("should not be dirty by default", function() {
return expect(this.model.isDirty()).toBeFalsy(); expect(this.model.isDirty()).toBeFalsy();
}); });
it("should be dirty after it's been changed", function() { it("should be dirty after it's been changed", function() {
this.model.set("name", "foobar"); this.model.set("name", "foobar");
return expect(this.model.isDirty()).toBeTruthy(); expect(this.model.isDirty()).toBeTruthy();
}); });
return it("should not be dirty after calling setOriginalAttributes", function() { it("should not be dirty after calling setOriginalAttributes", function() {
this.model.set("name", "foobar"); this.model.set("name", "foobar");
this.model.setOriginalAttributes(); this.model.setOriginalAttributes();
return expect(this.model.isDirty()).toBeFalsy(); expect(this.model.isDirty()).toBeFalsy();
}); });
}); });
...@@ -74,7 +67,7 @@ function(Backbone, Textbook, TextbookSet, Chapter, ChapterSet, main) { ...@@ -74,7 +67,7 @@ function(Backbone, Textbook, TextbookSet, Chapter, ChapterSet, main) {
return _.map(obj, deepAttributes); return _.map(obj, deepAttributes);
} else if (_.isObject(obj)) { } else if (_.isObject(obj)) {
const attributes = {}; const attributes = {};
for (let prop of Object.keys(obj || {})) { for (let prop of Object.keys(obj)) {
const val = obj[prop]; const val = obj[prop];
attributes[prop] = deepAttributes(val); attributes[prop] = deepAttributes(val);
} }
...@@ -84,7 +77,7 @@ function(Backbone, Textbook, TextbookSet, Chapter, ChapterSet, main) { ...@@ -84,7 +77,7 @@ function(Backbone, Textbook, TextbookSet, Chapter, ChapterSet, main) {
} }
}; };
return it("should match server model to client model", function() { it("should match server model to client model", function() {
const serverModelSpec = { const serverModelSpec = {
"tab_title": "My Textbook", "tab_title": "My Textbook",
"chapters": [ "chapters": [
...@@ -110,20 +103,20 @@ function(Backbone, Textbook, TextbookSet, Chapter, ChapterSet, main) { ...@@ -110,20 +103,20 @@ function(Backbone, Textbook, TextbookSet, Chapter, ChapterSet, main) {
const model = new Textbook(serverModelSpec, {parse: true}); const model = new Textbook(serverModelSpec, {parse: true});
expect(deepAttributes(model)).toEqual(clientModelSpec); expect(deepAttributes(model)).toEqual(clientModelSpec);
return expect(model.toJSON()).toEqual(serverModelSpec); expect(model.toJSON()).toEqual(serverModelSpec);
}); });
}); });
return describe("Validation", function() { describe("Validation", function() {
it("requires a name", function() { it("requires a name", function() {
const model = new Textbook({name: ""}); const model = new Textbook({name: ""});
return expect(model.isValid()).toBeFalsy(); expect(model.isValid()).toBeFalsy();
}); });
it("requires at least one chapter", function() { it("requires at least one chapter", function() {
const model = new Textbook({name: "foo"}); const model = new Textbook({name: "foo"});
model.get("chapters").reset(); model.get("chapters").reset();
return expect(model.isValid()).toBeFalsy(); expect(model.isValid()).toBeFalsy();
}); });
it("requires a valid chapter", function() { it("requires a valid chapter", function() {
...@@ -131,7 +124,7 @@ function(Backbone, Textbook, TextbookSet, Chapter, ChapterSet, main) { ...@@ -131,7 +124,7 @@ function(Backbone, Textbook, TextbookSet, Chapter, ChapterSet, main) {
chapter.isValid = () => false; chapter.isValid = () => false;
const model = new Textbook({name: "foo"}); const model = new Textbook({name: "foo"});
model.get("chapters").reset([chapter]); model.get("chapters").reset([chapter]);
return expect(model.isValid()).toBeFalsy(); expect(model.isValid()).toBeFalsy();
}); });
it("requires all chapters to be valid", function() { it("requires all chapters to be valid", function() {
...@@ -141,15 +134,15 @@ function(Backbone, Textbook, TextbookSet, Chapter, ChapterSet, main) { ...@@ -141,15 +134,15 @@ function(Backbone, Textbook, TextbookSet, Chapter, ChapterSet, main) {
chapter2.isValid = () => false; chapter2.isValid = () => false;
const model = new Textbook({name: "foo"}); const model = new Textbook({name: "foo"});
model.get("chapters").reset([chapter1, chapter2]); model.get("chapters").reset([chapter1, chapter2]);
return expect(model.isValid()).toBeFalsy(); expect(model.isValid()).toBeFalsy();
}); });
return it("can pass validation", function() { it("can pass validation", function() {
const chapter = new Chapter(); const chapter = new Chapter();
chapter.isValid = () => true; chapter.isValid = () => true;
const model = new Textbook({name: "foo"}); const model = new Textbook({name: "foo"});
model.get("chapters").reset([chapter]); model.get("chapters").reset([chapter]);
return expect(model.isValid()).toBeTruthy(); expect(model.isValid()).toBeTruthy();
}); });
}); });
}); });
...@@ -158,80 +151,80 @@ function(Backbone, Textbook, TextbookSet, Chapter, ChapterSet, main) { ...@@ -158,80 +151,80 @@ function(Backbone, Textbook, TextbookSet, Chapter, ChapterSet, main) {
describe("Textbook collection", function() { describe("Textbook collection", function() {
beforeEach(function() { beforeEach(function() {
CMS.URL.TEXTBOOKS = "/textbooks"; CMS.URL.TEXTBOOKS = "/textbooks";
return this.collection = new TextbookSet(); this.collection = new TextbookSet();
}); });
afterEach(() => delete CMS.URL.TEXTBOOKS); afterEach(() => delete CMS.URL.TEXTBOOKS);
return it("should have a url set", function() { it("should have a url set", function() {
const url = _.result(this.collection, 'url'); const url = _.result(this.collection, 'url');
return expect(url).toEqual("/textbooks"); expect(url).toEqual("/textbooks");
}); });
}); });
describe("Chapter model", function() { describe("Chapter model", function() {
beforeEach(function() { beforeEach(function() {
return this.model = new Chapter(); this.model = new Chapter();
}); });
describe("Basic", function() { describe("Basic", function() {
it("should have a name by default", function() { it("should have a name by default", function() {
return expect(this.model.get("name")).toEqual(""); expect(this.model.get("name")).toEqual("");
}); });
it("should have an asset_path by default", function() { it("should have an asset_path by default", function() {
return expect(this.model.get("asset_path")).toEqual(""); expect(this.model.get("asset_path")).toEqual("");
}); });
it("should have an order by default", function() { it("should have an order by default", function() {
return expect(this.model.get("order")).toEqual(1); expect(this.model.get("order")).toEqual(1);
}); });
return it("should be empty by default", function() { it("should be empty by default", function() {
return expect(this.model.isEmpty()).toBeTruthy(); expect(this.model.isEmpty()).toBeTruthy();
}); });
}); });
return describe("Validation", function() { describe("Validation", function() {
it("requires a name", function() { it("requires a name", function() {
const model = new Chapter({name: "", asset_path: "a.pdf"}); const model = new Chapter({name: "", asset_path: "a.pdf"});
return expect(model.isValid()).toBeFalsy(); expect(model.isValid()).toBeFalsy();
}); });
it("requires an asset_path", function() { it("requires an asset_path", function() {
const model = new Chapter({name: "a", asset_path: ""}); const model = new Chapter({name: "a", asset_path: ""});
return expect(model.isValid()).toBeFalsy(); expect(model.isValid()).toBeFalsy();
}); });
return it("can pass validation", function() { it("can pass validation", function() {
const model = new Chapter({name: "a", asset_path: "a.pdf"}); const model = new Chapter({name: "a", asset_path: "a.pdf"});
return expect(model.isValid()).toBeTruthy(); expect(model.isValid()).toBeTruthy();
}); });
}); });
}); });
return describe("Chapter collection", function() { describe("Chapter collection", function() {
beforeEach(function() { beforeEach(function() {
return this.collection = new ChapterSet(); this.collection = new ChapterSet();
}); });
it("is empty by default", function() { it("is empty by default", function() {
return expect(this.collection.isEmpty()).toBeTruthy(); expect(this.collection.isEmpty()).toBeTruthy();
}); });
it("is empty if all chapters are empty", function() { it("is empty if all chapters are empty", function() {
this.collection.add([{}, {}, {}]); this.collection.add([{}, {}, {}]);
return expect(this.collection.isEmpty()).toBeTruthy(); expect(this.collection.isEmpty()).toBeTruthy();
}); });
it("is not empty if a chapter is not empty", function() { it("is not empty if a chapter is not empty", function() {
this.collection.add([{}, {name: "full"}, {}]); this.collection.add([{}, {name: "full"}, {}]);
return expect(this.collection.isEmpty()).toBeFalsy(); expect(this.collection.isEmpty()).toBeFalsy();
}); });
return it("should have a nextOrder function", function() { it("should have a nextOrder function", function() {
expect(this.collection.nextOrder()).toEqual(1); expect(this.collection.nextOrder()).toEqual(1);
this.collection.add([{}]); this.collection.add([{}]);
expect(this.collection.nextOrder()).toEqual(2); expect(this.collection.nextOrder()).toEqual(2);
...@@ -241,7 +234,7 @@ function(Backbone, Textbook, TextbookSet, Chapter, ChapterSet, main) { ...@@ -241,7 +234,7 @@ function(Backbone, Textbook, TextbookSet, Chapter, ChapterSet, main) {
expect(this.collection.nextOrder()).toEqual(3); expect(this.collection.nextOrder()).toEqual(3);
// try going back one // try going back one
this.collection.remove(this.collection.last()); this.collection.remove(this.collection.last());
return expect(this.collection.nextOrder()).toEqual(2); expect(this.collection.nextOrder()).toEqual(2);
}); });
}); });
}); });
/*
* decaffeinate suggestions:
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
define(["js/models/uploads"], FileUpload => define(["js/models/uploads"], FileUpload =>
describe("FileUpload", function() { describe("FileUpload", function() {
beforeEach(function() { beforeEach(function() {
return this.model = new FileUpload(); this.model = new FileUpload();
}); });
it("is unfinished by default", function() { it("is unfinished by default", function() {
return expect(this.model.get("finished")).toBeFalsy(); expect(this.model.get("finished")).toBeFalsy();
}); });
it("is not uploading by default", function() { it("is not uploading by default", function() {
return expect(this.model.get("uploading")).toBeFalsy(); expect(this.model.get("uploading")).toBeFalsy();
}); });
it("is valid by default", function() { it("is valid by default", function() {
return expect(this.model.isValid()).toBeTruthy(); expect(this.model.isValid()).toBeTruthy();
}); });
it("is valid for text files by default", function() { it("is valid for text files by default", function() {
const file = {"type": "text/plain", "name": "filename.txt"}; const file = {"type": "text/plain", "name": "filename.txt"};
this.model.set("selectedFile", file); this.model.set("selectedFile", file);
return expect(this.model.isValid()).toBeTruthy(); expect(this.model.isValid()).toBeTruthy();
}); });
it("is valid for PNG files by default", function() { it("is valid for PNG files by default", function() {
const file = {"type": "image/png", "name": "filename.png"}; const file = {"type": "image/png", "name": "filename.png"};
this.model.set("selectedFile", file); this.model.set("selectedFile", file);
return expect(this.model.isValid()).toBeTruthy(); expect(this.model.isValid()).toBeTruthy();
}); });
it("can accept a file type when explicitly set", function() { it("can accept a file type when explicitly set", function() {
const file = {"type": "image/png", "name": "filename.png"}; const file = {"type": "image/png", "name": "filename.png"};
this.model.set({"mimeTypes": ["image/png"]}); this.model.set({"mimeTypes": ["image/png"]});
this.model.set("selectedFile", file); this.model.set("selectedFile", file);
return expect(this.model.isValid()).toBeTruthy(); expect(this.model.isValid()).toBeTruthy();
}); });
it("can accept a file format when explicitly set", function() { it("can accept a file format when explicitly set", function() {
const file = {"type": "", "name": "filename.png"}; const file = {"type": "", "name": "filename.png"};
this.model.set({"fileFormats": ["png"]}); this.model.set({"fileFormats": ["png"]});
this.model.set("selectedFile", file); this.model.set("selectedFile", file);
return expect(this.model.isValid()).toBeTruthy(); expect(this.model.isValid()).toBeTruthy();
}); });
it("can accept multiple file types", function() { it("can accept multiple file types", function() {
const file = {"type": "image/gif", "name": "filename.gif"}; const file = {"type": "image/gif", "name": "filename.gif"};
this.model.set({"mimeTypes": ["image/png", "image/jpeg", "image/gif"]}); this.model.set({"mimeTypes": ["image/png", "image/jpeg", "image/gif"]});
this.model.set("selectedFile", file); this.model.set("selectedFile", file);
return expect(this.model.isValid()).toBeTruthy(); expect(this.model.isValid()).toBeTruthy();
}); });
it("can accept multiple file formats", function() { it("can accept multiple file formats", function() {
const file = {"type": "image/gif", "name": "filename.gif"}; const file = {"type": "image/gif", "name": "filename.gif"};
this.model.set({"fileFormats": ["png", "jpeg", "gif"]}); this.model.set({"fileFormats": ["png", "jpeg", "gif"]});
this.model.set("selectedFile", file); this.model.set("selectedFile", file);
return expect(this.model.isValid()).toBeTruthy(); expect(this.model.isValid()).toBeTruthy();
}); });
describe("fileTypes", () => describe("fileTypes", () =>
it("returns a list of the uploader's file types", function() { it("returns a list of the uploader's file types", function() {
this.model.set('mimeTypes', ['image/png', 'application/json']); this.model.set('mimeTypes', ['image/png', 'application/json']);
this.model.set('fileFormats', ['gif', 'srt']); this.model.set('fileFormats', ['gif', 'srt']);
return expect(this.model.fileTypes()).toEqual(['PNG', 'JSON', 'GIF', 'SRT']); expect(this.model.fileTypes()).toEqual(['PNG', 'JSON', 'GIF', 'SRT']);
}) })
); );
return describe("formatValidTypes", function() { describe("formatValidTypes", function() {
it("returns a map of formatted file types and extensions", function() { it("returns a map of formatted file types and extensions", function() {
this.model.set('mimeTypes', ['image/png', 'image/jpeg', 'application/json']); this.model.set('mimeTypes', ['image/png', 'image/jpeg', 'application/json']);
const formatted = this.model.formatValidTypes(); const formatted = this.model.formatValidTypes();
return expect(formatted).toEqual({ expect(formatted).toEqual({
fileTypes: 'PNG, JPEG or JSON', fileTypes: 'PNG, JPEG or JSON',
fileExtensions: '.png, .jpeg or .json' fileExtensions: '.png, .jpeg or .json'
}); });
}); });
return it("does not format with only one mime type", function() { it("does not format with only one mime type", function() {
this.model.set('mimeTypes', ['application/pdf']); this.model.set('mimeTypes', ['application/pdf']);
const formatted = this.model.formatValidTypes(); const formatted = this.model.formatValidTypes();
return expect(formatted).toEqual({ expect(formatted).toEqual({
fileTypes: 'PDF', fileTypes: 'PDF',
fileExtensions: '.pdf' fileExtensions: '.pdf'
}); });
......
/*
* decaffeinate suggestions:
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
define(["jquery", "edx-ui-toolkit/js/utils/spec-helpers/ajax-helpers", "squire"], define(["jquery", "edx-ui-toolkit/js/utils/spec-helpers/ajax-helpers", "squire"],
function($, AjaxHelpers, Squire) { function($, AjaxHelpers, Squire) {
...@@ -35,7 +30,7 @@ function($, AjaxHelpers, Squire) { ...@@ -35,7 +30,7 @@ function($, AjaxHelpers, Squire) {
"Mini": this.savingSpies.constructor "Mini": this.savingSpies.constructor
}); });
return this.injector.require(["js/models/asset", "js/collections/asset", "js/views/asset"], this.injector.require(["js/models/asset", "js/collections/asset", "js/views/asset"],
(AssetModel, AssetCollection, AssetView) => { (AssetModel, AssetCollection, AssetView) => {
this.model = new AssetModel({ this.model = new AssetModel({
display_name: "test asset", display_name: "test asset",
...@@ -61,7 +56,7 @@ function($, AjaxHelpers, Squire) { ...@@ -61,7 +56,7 @@ function($, AjaxHelpers, Squire) {
afterEach(function() { afterEach(function() {
this.injector.clean(); this.injector.clean();
return this.injector.remove(); this.injector.remove();
}); });
describe("Basic", function() { describe("Basic", function() {
...@@ -69,10 +64,10 @@ function($, AjaxHelpers, Squire) { ...@@ -69,10 +64,10 @@ function($, AjaxHelpers, Squire) {
let requests; let requests;
({view: this.view, requests} = this.createAssetView()); ({view: this.view, requests} = this.createAssetView());
this.view.render(); this.view.render();
return expect(this.view.$el).toContainText("test asset"); expect(this.view.$el).toContainText("test asset");
}); });
return it("should pop a delete confirmation when the delete button is clicked", function() { it("should pop a delete confirmation when the delete button is clicked", function() {
let requests; let requests;
({view: this.view, requests} = this.createAssetView()); ({view: this.view, requests} = this.createAssetView());
this.view.render().$(".remove-asset-button").click(); this.view.render().$(".remove-asset-button").click();
...@@ -81,11 +76,11 @@ function($, AjaxHelpers, Squire) { ...@@ -81,11 +76,11 @@ function($, AjaxHelpers, Squire) {
expect(ctorOptions.title).toMatch('Delete File Confirmation'); expect(ctorOptions.title).toMatch('Delete File Confirmation');
// hasn't actually been removed // hasn't actually been removed
expect(this.model.destroy).not.toHaveBeenCalled(); expect(this.model.destroy).not.toHaveBeenCalled();
return expect(this.collection).toContain(this.model); expect(this.collection).toContain(this.model);
}); });
}); });
return describe("AJAX", function() { describe("AJAX", function() {
it("should destroy itself on confirmation", function() { it("should destroy itself on confirmation", function() {
let requests; let requests;
({view: this.view, requests} = this.createAssetView(this)); ({view: this.view, requests} = this.createAssetView(this));
...@@ -105,7 +100,7 @@ function($, AjaxHelpers, Squire) { ...@@ -105,7 +100,7 @@ function($, AjaxHelpers, Squire) {
expect(this.confirmationSpies.show).toHaveBeenCalled(); expect(this.confirmationSpies.show).toHaveBeenCalled();
const savingOptions = this.confirmationSpies.constructor.calls.mostRecent().args[0]; const savingOptions = this.confirmationSpies.constructor.calls.mostRecent().args[0];
expect(savingOptions.title).toMatch("Your file has been deleted."); expect(savingOptions.title).toMatch("Your file has been deleted.");
return expect(this.collection.contains(this.model)).toBeFalsy(); expect(this.collection.contains(this.model)).toBeFalsy();
}); });
it("should not destroy itself if server errors", function() { it("should not destroy itself if server errors", function() {
...@@ -121,7 +116,7 @@ function($, AjaxHelpers, Squire) { ...@@ -121,7 +116,7 @@ function($, AjaxHelpers, Squire) {
// return an error response // return an error response
requests[0].respond(404); requests[0].respond(404);
expect(this.confirmationSpies.constructor).not.toHaveBeenCalled(); expect(this.confirmationSpies.constructor).not.toHaveBeenCalled();
return expect(this.collection.contains(this.model)).toBeTruthy(); expect(this.collection.contains(this.model)).toBeTruthy();
}); });
it("should lock the asset on confirmation", function() { it("should lock the asset on confirmation", function() {
...@@ -140,10 +135,10 @@ function($, AjaxHelpers, Squire) { ...@@ -140,10 +135,10 @@ function($, AjaxHelpers, Squire) {
// return a success response // return a success response
requests[0].respond(204); requests[0].respond(204);
expect(this.savingSpies.hide).toHaveBeenCalled(); expect(this.savingSpies.hide).toHaveBeenCalled();
return expect(this.model.get("locked")).toBeTruthy(); expect(this.model.get("locked")).toBeTruthy();
}); });
return it("should not lock the asset if server errors", function() { it("should not lock the asset if server errors", function() {
let requests; let requests;
({view: this.view, requests} = this.createAssetView(this)); ({view: this.view, requests} = this.createAssetView(this));
...@@ -152,12 +147,12 @@ function($, AjaxHelpers, Squire) { ...@@ -152,12 +147,12 @@ function($, AjaxHelpers, Squire) {
requests[0].respond(404); requests[0].respond(404);
// Don't call hide because that closes the notification showing the server error. // Don't call hide because that closes the notification showing the server error.
expect(this.savingSpies.hide).not.toHaveBeenCalled(); expect(this.savingSpies.hide).not.toHaveBeenCalled();
return expect(this.model.get("locked")).toBeFalsy(); expect(this.model.get("locked")).toBeFalsy();
}); });
}); });
}); });
return describe("Assets view", function() { describe("Assets view", function() {
beforeEach(function(done) { beforeEach(function(done) {
setFixtures($("<script>", {id: "asset-library-tpl", type: "text/template"}).text(assetLibraryTpl)); setFixtures($("<script>", {id: "asset-library-tpl", type: "text/template"}).text(assetLibraryTpl));
appendSetFixtures($("<script>", {id: "asset-tpl", type: "text/template"}).text(assetTpl)); appendSetFixtures($("<script>", {id: "asset-tpl", type: "text/template"}).text(assetTpl));
...@@ -224,7 +219,7 @@ function($, AjaxHelpers, Squire) { ...@@ -224,7 +219,7 @@ function($, AjaxHelpers, Squire) {
delete window.course_location_analytics; delete window.course_location_analytics;
this.injector.clean(); this.injector.clean();
return this.injector.remove(); this.injector.remove();
}); });
const addMockAsset = function(requests) { const addMockAsset = function(requests) {
...@@ -277,7 +272,7 @@ function($, AjaxHelpers, Squire) { ...@@ -277,7 +272,7 @@ function($, AjaxHelpers, Squire) {
setup.call(this, requests); setup.call(this, requests);
expect(this.view.showUploadModal).not.toHaveBeenCalled(); expect(this.view.showUploadModal).not.toHaveBeenCalled();
this.view.showUploadModal(clickEvent(".upload-button")); this.view.showUploadModal(clickEvent(".upload-button"));
return expect(this.view.showUploadModal).toHaveBeenCalled(); expect(this.view.showUploadModal).toHaveBeenCalled();
}); });
it("should show file selection menu on choose file button", function() { it("should show file selection menu on choose file button", function() {
...@@ -287,7 +282,7 @@ function($, AjaxHelpers, Squire) { ...@@ -287,7 +282,7 @@ function($, AjaxHelpers, Squire) {
setup.call(this, requests); setup.call(this, requests);
expect(this.view.showFileSelectionMenu).not.toHaveBeenCalled(); expect(this.view.showFileSelectionMenu).not.toHaveBeenCalled();
this.view.showFileSelectionMenu(clickEvent(".choose-file-button")); this.view.showFileSelectionMenu(clickEvent(".choose-file-button"));
return expect(this.view.showFileSelectionMenu).toHaveBeenCalled(); expect(this.view.showFileSelectionMenu).toHaveBeenCalled();
}); });
it("should hide upload modal on clicking close button", function() { it("should hide upload modal on clicking close button", function() {
...@@ -297,7 +292,7 @@ function($, AjaxHelpers, Squire) { ...@@ -297,7 +292,7 @@ function($, AjaxHelpers, Squire) {
setup.call(this, requests); setup.call(this, requests);
expect(this.view.hideModal).not.toHaveBeenCalled(); expect(this.view.hideModal).not.toHaveBeenCalled();
this.view.hideModal(clickEvent(".close-button")); this.view.hideModal(clickEvent(".close-button"));
return expect(this.view.hideModal).toHaveBeenCalled(); expect(this.view.hideModal).toHaveBeenCalled();
}); });
it("should show a status indicator while loading", function() { it("should show a status indicator while loading", function() {
...@@ -306,7 +301,7 @@ function($, AjaxHelpers, Squire) { ...@@ -306,7 +301,7 @@ function($, AjaxHelpers, Squire) {
appendSetFixtures('<div class="ui-loading"/>'); appendSetFixtures('<div class="ui-loading"/>');
expect($('.ui-loading').is(':visible')).toBe(true); expect($('.ui-loading').is(':visible')).toBe(true);
setup.call(this, requests); setup.call(this, requests);
return expect($('.ui-loading').is(':visible')).toBe(false); expect($('.ui-loading').is(':visible')).toBe(false);
}); });
it("should hide the status indicator if an error occurs while loading", function() { it("should hide the status indicator if an error occurs while loading", function() {
...@@ -316,7 +311,7 @@ function($, AjaxHelpers, Squire) { ...@@ -316,7 +311,7 @@ function($, AjaxHelpers, Squire) {
expect($('.ui-loading').is(':visible')).toBe(true); expect($('.ui-loading').is(':visible')).toBe(true);
this.view.pagingView.setPage(1); this.view.pagingView.setPage(1);
AjaxHelpers.respondWithError(requests); AjaxHelpers.respondWithError(requests);
return expect($('.ui-loading').is(':visible')).toBe(false); expect($('.ui-loading').is(':visible')).toBe(false);
}); });
it("should render both assets", function() { it("should render both assets", function() {
...@@ -324,7 +319,7 @@ function($, AjaxHelpers, Squire) { ...@@ -324,7 +319,7 @@ function($, AjaxHelpers, Squire) {
({view: this.view, requests} = this.createAssetsView(this)); ({view: this.view, requests} = this.createAssetsView(this));
setup.call(this, requests); setup.call(this, requests);
expect(this.view.$el).toContainText("test asset 1"); expect(this.view.$el).toContainText("test asset 1");
return expect(this.view.$el).toContainText("test asset 2"); expect(this.view.$el).toContainText("test asset 2");
}); });
it("should remove the deleted asset from the view", function() { it("should remove the deleted asset from the view", function() {
...@@ -337,7 +332,7 @@ function($, AjaxHelpers, Squire) { ...@@ -337,7 +332,7 @@ function($, AjaxHelpers, Squire) {
this.promptSpies.constructor.calls.mostRecent().args[0].actions.primary.click(this.promptSpies); this.promptSpies.constructor.calls.mostRecent().args[0].actions.primary.click(this.promptSpies);
AjaxHelpers.respondWithNoContent(requests); AjaxHelpers.respondWithNoContent(requests);
expect(this.view.$el).toContainText("test asset 1"); expect(this.view.$el).toContainText("test asset 1");
return expect(this.view.$el).not.toContainText("test asset 2"); expect(this.view.$el).not.toContainText("test asset 2");
}); });
it("does not remove asset if deletion failed", function() { it("does not remove asset if deletion failed", function() {
...@@ -349,7 +344,7 @@ function($, AjaxHelpers, Squire) { ...@@ -349,7 +344,7 @@ function($, AjaxHelpers, Squire) {
this.promptSpies.constructor.calls.mostRecent().args[0].actions.primary.click(this.promptSpies); this.promptSpies.constructor.calls.mostRecent().args[0].actions.primary.click(this.promptSpies);
AjaxHelpers.respondWithError(requests); AjaxHelpers.respondWithError(requests);
expect(this.view.$el).toContainText("test asset 1"); expect(this.view.$el).toContainText("test asset 1");
return expect(this.view.$el).toContainText("test asset 2"); expect(this.view.$el).toContainText("test asset 2");
}); });
it("adds an asset if asset does not already exist", function() { it("adds an asset if asset does not already exist", function() {
...@@ -358,21 +353,21 @@ function($, AjaxHelpers, Squire) { ...@@ -358,21 +353,21 @@ function($, AjaxHelpers, Squire) {
setup.call(this, requests); setup.call(this, requests);
addMockAsset.call(this, requests); addMockAsset.call(this, requests);
expect(this.view.$el).toContainText("new asset"); expect(this.view.$el).toContainText("new asset");
return expect(this.collection.models.length).toBe(3); expect(this.collection.models.length).toBe(3);
}); });
return it("does not add an asset if asset already exists", function() { it("does not add an asset if asset already exists", function() {
let requests; let requests;
({view: this.view, requests} = this.createAssetsView(this)); ({view: this.view, requests} = this.createAssetsView(this));
setup.call(this, requests); setup.call(this, requests);
spyOn(this.collection, "add").and.callThrough(); spyOn(this.collection, "add").and.callThrough();
const model = this.collection.models[1]; const model = this.collection.models[1];
this.view.addAsset(model); this.view.addAsset(model);
return expect(this.collection.add).not.toHaveBeenCalled(); expect(this.collection.add).not.toHaveBeenCalled();
}); });
}); });
return describe("Sorting", function() { describe("Sorting", function() {
// Separate setup method to work-around mis-parenting of beforeEach methods // Separate setup method to work-around mis-parenting of beforeEach methods
const setup = function(requests) { const setup = function(requests) {
this.view.pagingView.setPage(1); this.view.pagingView.setPage(1);
...@@ -384,7 +379,7 @@ function($, AjaxHelpers, Squire) { ...@@ -384,7 +379,7 @@ function($, AjaxHelpers, Squire) {
({view: this.view, requests} = this.createAssetsView(this)); ({view: this.view, requests} = this.createAssetsView(this));
setup.call(this, requests); setup.call(this, requests);
expect(this.view.pagingView.sortDisplayName()).toBe("Date Added"); expect(this.view.pagingView.sortDisplayName()).toBe("Date Added");
return expect(this.view.collection.sortDirection).toBe("desc"); expect(this.view.collection.sortDirection).toBe("desc");
}); });
it("should toggle the sort order when clicking on the currently sorted column", function() { it("should toggle the sort order when clicking on the currently sorted column", function() {
...@@ -400,7 +395,7 @@ function($, AjaxHelpers, Squire) { ...@@ -400,7 +395,7 @@ function($, AjaxHelpers, Squire) {
this.view.$("#js-asset-date-col").click(); this.view.$("#js-asset-date-col").click();
AjaxHelpers.respondWithJson(requests, this.mockAssetsResponse); AjaxHelpers.respondWithJson(requests, this.mockAssetsResponse);
expect(this.view.pagingView.sortDisplayName()).toBe("Date Added"); expect(this.view.pagingView.sortDisplayName()).toBe("Date Added");
return expect(this.view.collection.sortDirection).toBe("desc"); expect(this.view.collection.sortDirection).toBe("desc");
}); });
it("should switch the sort order when clicking on a different column", function() { it("should switch the sort order when clicking on a different column", function() {
...@@ -414,10 +409,10 @@ function($, AjaxHelpers, Squire) { ...@@ -414,10 +409,10 @@ function($, AjaxHelpers, Squire) {
this.view.$("#js-asset-name-col").click(); this.view.$("#js-asset-name-col").click();
AjaxHelpers.respondWithJson(requests, this.mockAssetsResponse); AjaxHelpers.respondWithJson(requests, this.mockAssetsResponse);
expect(this.view.pagingView.sortDisplayName()).toBe("Name"); expect(this.view.pagingView.sortDisplayName()).toBe("Name");
return expect(this.view.collection.sortDirection).toBe("desc"); expect(this.view.collection.sortDirection).toBe("desc");
}); });
return it("should switch sort to most recent date added when a new asset is added", function() { it("should switch sort to most recent date added when a new asset is added", function() {
let requests; let requests;
({view: this.view, requests} = this.createAssetsView(this)); ({view: this.view, requests} = this.createAssetsView(this));
setup.call(this, requests); setup.call(this, requests);
...@@ -426,7 +421,7 @@ function($, AjaxHelpers, Squire) { ...@@ -426,7 +421,7 @@ function($, AjaxHelpers, Squire) {
addMockAsset.call(this, requests); addMockAsset.call(this, requests);
AjaxHelpers.respondWithJson(requests, this.mockAssetsResponse); AjaxHelpers.respondWithJson(requests, this.mockAssetsResponse);
expect(this.view.pagingView.sortDisplayName()).toBe("Date Added"); expect(this.view.pagingView.sortDisplayName()).toBe("Date Added");
return expect(this.view.collection.sortDirection).toBe("desc"); expect(this.view.collection.sortDirection).toBe("desc");
}); });
}); });
}); });
......
/*
* decaffeinate suggestions:
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
define(["js/views/course_info_handout", "js/views/course_info_update", "js/models/module_info", define(["js/views/course_info_handout", "js/views/course_info_update", "js/models/module_info",
"js/collections/course_update", "edx-ui-toolkit/js/utils/spec-helpers/ajax-helpers"], "js/collections/course_update", "edx-ui-toolkit/js/utils/spec-helpers/ajax-helpers"],
(CourseInfoHandoutsView, CourseInfoUpdateView, ModuleInfo, CourseUpdateCollection, AjaxHelpers) => (CourseInfoHandoutsView, CourseInfoUpdateView, ModuleInfo, CourseUpdateCollection, AjaxHelpers) =>
...@@ -22,12 +17,12 @@ define(["js/views/course_info_handout", "js/views/course_info_update", "js/model ...@@ -22,12 +17,12 @@ define(["js/views/course_info_handout", "js/views/course_info_update", "js/model
beforeEach(function() { beforeEach(function() {
window.analytics = jasmine.createSpyObj('analytics', ['track']); window.analytics = jasmine.createSpyObj('analytics', ['track']);
return window.course_location_analytics = jasmine.createSpy(); window.course_location_analytics = jasmine.createSpy();
}); });
afterEach(function() { afterEach(function() {
delete window.analytics; delete window.analytics;
return delete window.course_location_analytics; delete window.course_location_analytics;
}); });
describe("Course Updates without Push notification", function() { describe("Course Updates without Push notification", function() {
...@@ -73,7 +68,7 @@ define(["js/views/course_info_handout", "js/views/course_info_update", "js/model ...@@ -73,7 +68,7 @@ define(["js/views/course_info_handout", "js/views/course_info_update", "js/model
expect(this.courseInfoEdit.$modalCover.hide).toHaveBeenCalled(); expect(this.courseInfoEdit.$modalCover.hide).toHaveBeenCalled();
expect(model.save).not.toHaveBeenCalled(); expect(model.save).not.toHaveBeenCalled();
const previewContents = this.courseInfoEdit.$el.find('.update-contents').html(); const previewContents = this.courseInfoEdit.$el.find('.update-contents').html();
return expect(previewContents).not.toEqual('unsaved changes'); expect(previewContents).not.toEqual('unsaved changes');
}; };
this.doNotCloseNewCourseInfo = function() { this.doNotCloseNewCourseInfo = function() {
...@@ -87,7 +82,7 @@ define(["js/views/course_info_handout", "js/views/course_info_update", "js/model ...@@ -87,7 +82,7 @@ define(["js/views/course_info_handout", "js/views/course_info_update", "js/model
cancelEditingUpdate(this.courseInfoEdit, this.courseInfoEdit.$modalCover, false); cancelEditingUpdate(this.courseInfoEdit, this.courseInfoEdit.$modalCover, false);
expect(model.save).not.toHaveBeenCalled(); expect(model.save).not.toHaveBeenCalled();
return expect(this.courseInfoEdit.$modalCover.hide).not.toHaveBeenCalled(); expect(this.courseInfoEdit.$modalCover.hide).not.toHaveBeenCalled();
}; };
this.cancelExistingCourseInfo = function(useCancelButton) { this.cancelExistingCourseInfo = function(useCancelButton) {
...@@ -104,7 +99,7 @@ define(["js/views/course_info_handout", "js/views/course_info_update", "js/model ...@@ -104,7 +99,7 @@ define(["js/views/course_info_handout", "js/views/course_info_update", "js/model
expect(this.courseInfoEdit.$modalCover.hide).toHaveBeenCalled(); expect(this.courseInfoEdit.$modalCover.hide).toHaveBeenCalled();
expect(model.save).not.toHaveBeenCalled(); expect(model.save).not.toHaveBeenCalled();
const previewContents = this.courseInfoEdit.$el.find('.update-contents').html(); const previewContents = this.courseInfoEdit.$el.find('.update-contents').html();
return expect(previewContents).toEqual('existing update'); expect(previewContents).toEqual('existing update');
}; };
this.testInvalidDateValue = function(value) { this.testInvalidDateValue = function(value) {
...@@ -113,7 +108,7 @@ define(["js/views/course_info_handout", "js/views/course_info_update", "js/model ...@@ -113,7 +108,7 @@ define(["js/views/course_info_handout", "js/views/course_info_update", "js/model
this.courseInfoEdit.$el.find('input.date').val(value).trigger("change"); this.courseInfoEdit.$el.find('input.date').val(value).trigger("change");
expect(this.courseInfoEdit.$el.find('.save-button').hasClass("is-disabled")).toEqual(true); expect(this.courseInfoEdit.$el.find('.save-button').hasClass("is-disabled")).toEqual(true);
this.courseInfoEdit.$el.find('input.date').val("01/01/16").trigger("change"); this.courseInfoEdit.$el.find('input.date').val("01/01/16").trigger("change");
return expect(this.courseInfoEdit.$el.find('.save-button').hasClass("is-disabled")).toEqual(false); expect(this.courseInfoEdit.$el.find('.save-button').hasClass("is-disabled")).toEqual(false);
}; };
return cancelEditingUpdate = function(update, modalCover, useCancelButton) { return cancelEditingUpdate = function(update, modalCover, useCancelButton) {
...@@ -149,7 +144,7 @@ define(["js/views/course_info_handout", "js/views/course_info_update", "js/model ...@@ -149,7 +144,7 @@ define(["js/views/course_info_handout", "js/views/course_info_update", "js/model
expect(requestSent.content).toEqual('/static/image.jpg'); expect(requestSent.content).toEqual('/static/image.jpg');
// Verify that analytics are sent // Verify that analytics are sent
return expect(window.analytics.track).toHaveBeenCalled(); expect(window.analytics.track).toHaveBeenCalled();
}); });
it("does rewrite links for preview", function() { it("does rewrite links for preview", function() {
...@@ -158,7 +153,7 @@ define(["js/views/course_info_handout", "js/views/course_info_update", "js/model ...@@ -158,7 +153,7 @@ define(["js/views/course_info_handout", "js/views/course_info_update", "js/model
// Verify the link is rewritten for preview purposes. // Verify the link is rewritten for preview purposes.
const previewContents = this.courseInfoEdit.$el.find('.update-contents').html(); const previewContents = this.courseInfoEdit.$el.find('.update-contents').html();
return expect(previewContents).toEqual('base-asset-url/image.jpg'); expect(previewContents).toEqual('base-asset-url/image.jpg');
}); });
it("shows static links in edit mode", function() { it("shows static links in edit mode", function() {
...@@ -166,31 +161,31 @@ define(["js/views/course_info_handout", "js/views/course_info_update", "js/model ...@@ -166,31 +161,31 @@ define(["js/views/course_info_handout", "js/views/course_info_update", "js/model
// Click edit and verify CodeMirror contents. // Click edit and verify CodeMirror contents.
this.courseInfoEdit.$el.find('.edit-button').click(); this.courseInfoEdit.$el.find('.edit-button').click();
return expect(this.courseInfoEdit.$codeMirror.getValue()).toEqual('/static/image.jpg'); expect(this.courseInfoEdit.$codeMirror.getValue()).toEqual('/static/image.jpg');
}); });
it("removes newly created course info on cancel", function() { it("removes newly created course info on cancel", function() {
return this.cancelNewCourseInfo(true); this.cancelNewCourseInfo(true);
}); });
it("do not close new course info on click outside modal", function() { it("do not close new course info on click outside modal", function() {
return this.doNotCloseNewCourseInfo(); this.doNotCloseNewCourseInfo();
}); });
it("does not remove existing course info on cancel", function() { it("does not remove existing course info on cancel", function() {
return this.cancelExistingCourseInfo(true); this.cancelExistingCourseInfo(true);
}); });
it("does not remove existing course info on click outside modal", function() { it("does not remove existing course info on click outside modal", function() {
return this.cancelExistingCourseInfo(false); this.cancelExistingCourseInfo(false);
}); });
it("does not allow updates to be saved with an invalid date", function() { it("does not allow updates to be saved with an invalid date", function() {
return this.testInvalidDateValue("Marchtober 40, 2048"); this.testInvalidDateValue("Marchtober 40, 2048");
}); });
return it("does not allow updates to be saved with a blank date", function() { it("does not allow updates to be saved with a blank date", function() {
return this.testInvalidDateValue(""); this.testInvalidDateValue("");
}); });
}); });
...@@ -211,11 +206,11 @@ define(["js/views/course_info_handout", "js/views/course_info_update", "js/model ...@@ -211,11 +206,11 @@ define(["js/views/course_info_handout", "js/views/course_info_update", "js/model
}); });
this.courseInfoEdit.render(); this.courseInfoEdit.render();
this.event = {preventDefault() { return 'no op'; }}; this.event = {preventDefault() { return 'no op'; }};
return this.courseInfoEdit.onNew(this.event); this.courseInfoEdit.onNew(this.event);
}); });
it("shows push notification checkbox as selected by default", function() { it("shows push notification checkbox as selected by default", function() {
return expect(this.courseInfoEdit.$el.find('.toggle-checkbox')).toBeChecked(); expect(this.courseInfoEdit.$el.find('.toggle-checkbox')).toBeChecked();
}); });
it("sends correct default value for push_notification_selected", function() { it("sends correct default value for push_notification_selected", function() {
...@@ -226,10 +221,10 @@ define(["js/views/course_info_handout", "js/views/course_info_update", "js/model ...@@ -226,10 +221,10 @@ define(["js/views/course_info_handout", "js/views/course_info_update", "js/model
// Check that analytics send push_notification info // Check that analytics send push_notification info
const analytics_payload = window.analytics.track.calls.first().args[1]; const analytics_payload = window.analytics.track.calls.first().args[1];
return expect(analytics_payload).toEqual(jasmine.objectContaining({'push_notification_selected': true})); expect(analytics_payload).toEqual(jasmine.objectContaining({'push_notification_selected': true}));
}); });
return it("sends correct value for push_notification_selected when it is unselected", function() { it("sends correct value for push_notification_selected when it is unselected", function() {
const requests = AjaxHelpers.requests(this); const requests = AjaxHelpers.requests(this);
// unselect push notification // unselect push notification
this.courseInfoEdit.$el.find('.toggle-checkbox').attr('checked', false); this.courseInfoEdit.$el.find('.toggle-checkbox').attr('checked', false);
...@@ -239,11 +234,11 @@ define(["js/views/course_info_handout", "js/views/course_info_update", "js/model ...@@ -239,11 +234,11 @@ define(["js/views/course_info_handout", "js/views/course_info_update", "js/model
// Check that analytics send push_notification info // Check that analytics send push_notification info
const analytics_payload = window.analytics.track.calls.first().args[1]; const analytics_payload = window.analytics.track.calls.first().args[1];
return expect(analytics_payload).toEqual(jasmine.objectContaining({'push_notification_selected': false})); expect(analytics_payload).toEqual(jasmine.objectContaining({'push_notification_selected': false}));
}); });
}); });
return describe("Course Handouts", function() { describe("Course Handouts", function() {
const handoutsTemplate = readFixtures('course_info_handouts.underscore'); const handoutsTemplate = readFixtures('course_info_handouts.underscore');
beforeEach(function() { beforeEach(function() {
...@@ -261,7 +256,7 @@ define(["js/views/course_info_handout", "js/views/course_info_update", "js/model ...@@ -261,7 +256,7 @@ define(["js/views/course_info_handout", "js/views/course_info_update", "js/model
base_asset_url: 'base-asset-url/' base_asset_url: 'base-asset-url/'
}); });
return this.handoutsEdit.render(); this.handoutsEdit.render();
}); });
it("saves <ol></ol> when content left empty", function() { it("saves <ol></ol> when content left empty", function() {
...@@ -276,7 +271,7 @@ define(["js/views/course_info_handout", "js/views/course_info_update", "js/model ...@@ -276,7 +271,7 @@ define(["js/views/course_info_handout", "js/views/course_info_update", "js/model
expect(this.model.save).toHaveBeenCalled(); expect(this.model.save).toHaveBeenCalled();
const contentSaved = JSON.parse(requests[requests.length - 1].requestBody).data; const contentSaved = JSON.parse(requests[requests.length - 1].requestBody).data;
return expect(contentSaved).toEqual('<ol></ol>'); expect(contentSaved).toEqual('<ol></ol>');
}); });
it("does not rewrite links on save", function() { it("does not rewrite links on save", function() {
...@@ -291,11 +286,11 @@ define(["js/views/course_info_handout", "js/views/course_info_update", "js/model ...@@ -291,11 +286,11 @@ define(["js/views/course_info_handout", "js/views/course_info_update", "js/model
expect(this.model.save).toHaveBeenCalled(); expect(this.model.save).toHaveBeenCalled();
const contentSaved = JSON.parse(requests[requests.length - 1].requestBody).data; const contentSaved = JSON.parse(requests[requests.length - 1].requestBody).data;
return expect(contentSaved).toEqual('/static/image.jpg'); expect(contentSaved).toEqual('/static/image.jpg');
}); });
it("does rewrite links in initial content", function() { it("does rewrite links in initial content", function() {
return expect(this.handoutsEdit.$preview.html().trim()).toBe('base-asset-url/fromServer.jpg'); expect(this.handoutsEdit.$preview.html().trim()).toBe('base-asset-url/fromServer.jpg');
}); });
it("does rewrite links after edit", function() { it("does rewrite links after edit", function() {
...@@ -305,16 +300,16 @@ define(["js/views/course_info_handout", "js/views/course_info_update", "js/model ...@@ -305,16 +300,16 @@ define(["js/views/course_info_handout", "js/views/course_info_update", "js/model
this.handoutsEdit.$el.find('.save-button').click(); this.handoutsEdit.$el.find('.save-button').click();
// Verify preview text. // Verify preview text.
return expect(this.handoutsEdit.$preview.html().trim()).toBe('base-asset-url/image.jpg'); expect(this.handoutsEdit.$preview.html().trim()).toBe('base-asset-url/image.jpg');
}); });
it("shows static links in edit mode", function() { it("shows static links in edit mode", function() {
// Click edit and verify CodeMirror contents. // Click edit and verify CodeMirror contents.
this.handoutsEdit.$el.find('.edit-button').click(); this.handoutsEdit.$el.find('.edit-button').click();
return expect(this.handoutsEdit.$codeMirror.getValue().trim()).toEqual('/static/fromServer.jpg'); expect(this.handoutsEdit.$codeMirror.getValue().trim()).toEqual('/static/fromServer.jpg');
}); });
return it("can open course handouts with bad html on edit", function() { it("can open course handouts with bad html on edit", function() {
// Enter some bad html in handouts section, verifying that the // Enter some bad html in handouts section, verifying that the
// model/handoutform opens when "Edit" is clicked // model/handoutform opens when "Edit" is clicked
...@@ -332,7 +327,7 @@ define(["js/views/course_info_handout", "js/views/course_info_update", "js/model ...@@ -332,7 +327,7 @@ define(["js/views/course_info_handout", "js/views/course_info_update", "js/model
expect($('.edit-handouts-form').is(':hidden')).toEqual(true); expect($('.edit-handouts-form').is(':hidden')).toEqual(true);
this.handoutsEdit.$el.find('.edit-button').click(); this.handoutsEdit.$el.find('.edit-button').click();
expect(this.handoutsEdit.$codeMirror.getValue()).toEqual('<p><a href="[URL OF FILE]>[LINK TEXT]</a></p>'); expect(this.handoutsEdit.$codeMirror.getValue()).toEqual('<p><a href="[URL OF FILE]>[LINK TEXT]</a></p>');
return expect($('.edit-handouts-form').is(':hidden')).toEqual(false); expect($('.edit-handouts-form').is(':hidden')).toEqual(false);
}); });
}); });
}) })
......
/* /*
* decaffeinate suggestions: * decaffeinate suggestions:
* DS102: Remove unnecessary code created because of implicit returns
* DS207: Consider shorter variations of null checks * DS207: Consider shorter variations of null checks
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/ */
...@@ -13,10 +12,10 @@ function(MetadataModel, MetadataCollection, MetadataView, main) { ...@@ -13,10 +12,10 @@ function(MetadataModel, MetadataCollection, MetadataView, main) {
if ((expectedType === 'number') && (input.type !== 'number')) { if ((expectedType === 'number') && (input.type !== 'number')) {
expectedType = 'text'; expectedType = 'text';
} }
return expect(input.type).toBe(expectedType); expect(input.type).toBe(expectedType);
}; };
return describe("Test Metadata Editor", function() { describe("Test Metadata Editor", function() {
const editorTemplate = readFixtures('metadata-editor.underscore'); const editorTemplate = readFixtures('metadata-editor.underscore');
const numberEntryTemplate = readFixtures('metadata-number-entry.underscore'); const numberEntryTemplate = readFixtures('metadata-number-entry.underscore');
const stringEntryTemplate = readFixtures('metadata-string-entry.underscore'); const stringEntryTemplate = readFixtures('metadata-string-entry.underscore');
...@@ -30,7 +29,7 @@ function(MetadataModel, MetadataCollection, MetadataView, main) { ...@@ -30,7 +29,7 @@ function(MetadataModel, MetadataCollection, MetadataView, main) {
appendSetFixtures($("<script>", {id: "metadata-string-entry", type: "text/template"}).text(stringEntryTemplate)); appendSetFixtures($("<script>", {id: "metadata-string-entry", type: "text/template"}).text(stringEntryTemplate));
appendSetFixtures($("<script>", {id: "metadata-option-entry", type: "text/template"}).text(optionEntryTemplate)); appendSetFixtures($("<script>", {id: "metadata-option-entry", type: "text/template"}).text(optionEntryTemplate));
appendSetFixtures($("<script>", {id: "metadata-list-entry", type: "text/template"}).text(listEntryTemplate)); appendSetFixtures($("<script>", {id: "metadata-list-entry", type: "text/template"}).text(listEntryTemplate));
return appendSetFixtures($("<script>", {id: "metadata-dict-entry", type: "text/template"}).text(dictEntryTemplate)); appendSetFixtures($("<script>", {id: "metadata-dict-entry", type: "text/template"}).text(dictEntryTemplate));
}); });
const genericEntry = { const genericEntry = {
...@@ -125,7 +124,7 @@ function(MetadataModel, MetadataCollection, MetadataView, main) { ...@@ -125,7 +124,7 @@ function(MetadataModel, MetadataCollection, MetadataView, main) {
// Test for the editor that creates the individual views. // Test for the editor that creates the individual views.
describe("MetadataView.Editor creates editors for each field", function() { describe("MetadataView.Editor creates editors for each field", function() {
beforeEach(function() { beforeEach(function() {
return this.model = new MetadataCollection( this.model = new MetadataCollection(
[ [
integerEntry, integerEntry,
floatEntry, floatEntry,
...@@ -161,7 +160,7 @@ function(MetadataModel, MetadataCollection, MetadataView, main) { ...@@ -161,7 +160,7 @@ function(MetadataModel, MetadataCollection, MetadataView, main) {
const verifyEntry = function(index, display_name, type) { const verifyEntry = function(index, display_name, type) {
expect(childModels[index].get('display_name')).toBe(display_name); expect(childModels[index].get('display_name')).toBe(display_name);
return verifyInputType(childViews[index], type); verifyInputType(childViews[index], type);
}; };
verifyEntry(0, 'Display Name', 'text'); verifyEntry(0, 'Display Name', 'text');
...@@ -171,12 +170,12 @@ function(MetadataModel, MetadataCollection, MetadataView, main) { ...@@ -171,12 +170,12 @@ function(MetadataModel, MetadataCollection, MetadataView, main) {
verifyEntry(4, 'Show Answer', 'select-one'); verifyEntry(4, 'Show Answer', 'select-one');
verifyEntry(5, 'Time', 'text'); verifyEntry(5, 'Time', 'text');
verifyEntry(6, 'Unknown', 'text'); verifyEntry(6, 'Unknown', 'text');
return verifyEntry(7, 'Weight', 'number'); verifyEntry(7, 'Weight', 'number');
}); });
it("returns its display name", function() { it("returns its display name", function() {
const view = new MetadataView.Editor({collection: this.model}); const view = new MetadataView.Editor({collection: this.model});
return expect(view.getDisplayName()).toBe("Word cloud"); expect(view.getDisplayName()).toBe("Word cloud");
}); });
it("returns an empty string if there is no display name property with a valid value", function() { it("returns an empty string if there is no display name property with a valid value", function() {
...@@ -196,20 +195,20 @@ function(MetadataModel, MetadataCollection, MetadataView, main) { ...@@ -196,20 +195,20 @@ function(MetadataModel, MetadataCollection, MetadataView, main) {
}]) }])
}); });
return expect(view.getDisplayName()).toBe(""); expect(view.getDisplayName()).toBe("");
}); });
it("has no modified values by default", function() { it("has no modified values by default", function() {
const view = new MetadataView.Editor({collection: this.model}); const view = new MetadataView.Editor({collection: this.model});
return expect(view.getModifiedMetadataValues()).toEqual({}); expect(view.getModifiedMetadataValues()).toEqual({});
}); });
return it("returns modified values only", function() { it("returns modified values only", function() {
const view = new MetadataView.Editor({collection: this.model}); const view = new MetadataView.Editor({collection: this.model});
const childModels = view.collection.models; const childModels = view.collection.models;
childModels[0].setValue('updated display name'); childModels[0].setValue('updated display name');
childModels[1].setValue(20); childModels[1].setValue(20);
return expect(view.getModifiedMetadataValues()).toEqual({ expect(view.getModifiedMetadataValues()).toEqual({
display_name : 'updated display name', display_name : 'updated display name',
num_inputs: 20 num_inputs: 20
}); });
...@@ -220,14 +219,14 @@ function(MetadataModel, MetadataCollection, MetadataView, main) { ...@@ -220,14 +219,14 @@ function(MetadataModel, MetadataCollection, MetadataView, main) {
const assertInputType = function(view, expectedType) { const assertInputType = function(view, expectedType) {
const input = view.$el.find('.setting-input'); const input = view.$el.find('.setting-input');
expect(input.length).toEqual(1); expect(input.length).toEqual(1);
return verifyInputType(input[0], expectedType); verifyInputType(input[0], expectedType);
}; };
const assertValueInView = (view, expectedValue) => expect(view.getValueFromEditor()).toEqual(expectedValue); const assertValueInView = (view, expectedValue) => expect(view.getValueFromEditor()).toEqual(expectedValue);
const assertCanUpdateView = function(view, newValue) { const assertCanUpdateView = function(view, newValue) {
view.setValueInEditor(newValue); view.setValueInEditor(newValue);
return expect(view.getValueFromEditor()).toEqual(newValue); expect(view.getValueFromEditor()).toEqual(newValue);
}; };
const assertClear = function(view, modelValue, editorValue) { const assertClear = function(view, modelValue, editorValue) {
...@@ -235,72 +234,72 @@ function(MetadataModel, MetadataCollection, MetadataView, main) { ...@@ -235,72 +234,72 @@ function(MetadataModel, MetadataCollection, MetadataView, main) {
view.clear(); view.clear();
expect(view.model.getValue()).toBe(null); expect(view.model.getValue()).toBe(null);
expect(view.model.getDisplayValue()).toEqual(modelValue); expect(view.model.getDisplayValue()).toEqual(modelValue);
return expect(view.getValueFromEditor()).toEqual(editorValue); expect(view.getValueFromEditor()).toEqual(editorValue);
}; };
const assertUpdateModel = function(view, originalValue, newValue) { const assertUpdateModel = function(view, originalValue, newValue) {
view.setValueInEditor(newValue); view.setValueInEditor(newValue);
expect(view.model.getValue()).toEqual(originalValue); expect(view.model.getValue()).toEqual(originalValue);
view.updateModel(); view.updateModel();
return expect(view.model.getValue()).toEqual(newValue); expect(view.model.getValue()).toEqual(newValue);
}; };
describe("MetadataView.String is a basic string input with clear functionality", function() { describe("MetadataView.String is a basic string input with clear functionality", function() {
beforeEach(function() { beforeEach(function() {
const model = new MetadataModel(genericEntry); const model = new MetadataModel(genericEntry);
return this.view = new MetadataView.String({model}); this.view = new MetadataView.String({model});
}); });
it("uses a text input type", function() { it("uses a text input type", function() {
return assertInputType(this.view, 'text'); assertInputType(this.view, 'text');
}); });
it("returns the intial value upon initialization", function() { it("returns the intial value upon initialization", function() {
return assertValueInView(this.view, 'Word cloud'); assertValueInView(this.view, 'Word cloud');
}); });
it("can update its value in the view", function() { it("can update its value in the view", function() {
return assertCanUpdateView(this.view, "updated ' \" &"); assertCanUpdateView(this.view, "updated ' \" &");
}); });
it("has a clear method to revert to the model default", function() { it("has a clear method to revert to the model default", function() {
return assertClear(this.view, 'default value'); assertClear(this.view, 'default value');
}); });
return it("has an update model method", function() { it("has an update model method", function() {
return assertUpdateModel(this.view, 'Word cloud', 'updated'); assertUpdateModel(this.view, 'Word cloud', 'updated');
}); });
}); });
describe("MetadataView.Option is an option input type with clear functionality", function() { describe("MetadataView.Option is an option input type with clear functionality", function() {
beforeEach(function() { beforeEach(function() {
const model = new MetadataModel(selectEntry); const model = new MetadataModel(selectEntry);
return this.view = new MetadataView.Option({model}); this.view = new MetadataView.Option({model});
}); });
it("uses a select input type", function() { it("uses a select input type", function() {
return assertInputType(this.view, 'select-one'); assertInputType(this.view, 'select-one');
}); });
it("returns the intial value upon initialization", function() { it("returns the intial value upon initialization", function() {
return assertValueInView(this.view, 'always'); assertValueInView(this.view, 'always');
}); });
it("can update its value in the view", function() { it("can update its value in the view", function() {
return assertCanUpdateView(this.view, "never"); assertCanUpdateView(this.view, "never");
}); });
it("has a clear method to revert to the model default", function() { it("has a clear method to revert to the model default", function() {
return assertClear(this.view, 'answered'); assertClear(this.view, 'answered');
}); });
it("has an update model method", function() { it("has an update model method", function() {
return assertUpdateModel(this.view, null, 'never'); assertUpdateModel(this.view, null, 'never');
}); });
return it("does not update to a value that is not an option", function() { it("does not update to a value that is not an option", function() {
this.view.setValueInEditor("not an option"); this.view.setValueInEditor("not an option");
return expect(this.view.getValueFromEditor()).toBe('always'); expect(this.view.getValueFromEditor()).toBe('always');
}); });
}); });
...@@ -308,7 +307,7 @@ function(MetadataModel, MetadataCollection, MetadataView, main) { ...@@ -308,7 +307,7 @@ function(MetadataModel, MetadataCollection, MetadataView, main) {
const verifyValueAfterChanged = function(view, value, expectedResult) { const verifyValueAfterChanged = function(view, value, expectedResult) {
view.setValueInEditor(value); view.setValueInEditor(value);
view.changed(); view.changed();
return expect(view.getValueFromEditor()).toBe(expectedResult); expect(view.getValueFromEditor()).toBe(expectedResult);
}; };
beforeEach(function() { beforeEach(function() {
...@@ -316,37 +315,37 @@ function(MetadataModel, MetadataCollection, MetadataView, main) { ...@@ -316,37 +315,37 @@ function(MetadataModel, MetadataCollection, MetadataView, main) {
this.integerView = new MetadataView.Number({model: integerModel}); this.integerView = new MetadataView.Number({model: integerModel});
const floatModel = new MetadataModel(floatEntry); const floatModel = new MetadataModel(floatEntry);
return this.floatView = new MetadataView.Number({model: floatModel}); this.floatView = new MetadataView.Number({model: floatModel});
}); });
it("uses a number input type", function() { it("uses a number input type", function() {
assertInputType(this.integerView, 'number'); assertInputType(this.integerView, 'number');
return assertInputType(this.floatView, 'number'); assertInputType(this.floatView, 'number');
}); });
it("returns the intial value upon initialization", function() { it("returns the intial value upon initialization", function() {
assertValueInView(this.integerView, '5'); assertValueInView(this.integerView, '5');
return assertValueInView(this.floatView, '10.2'); assertValueInView(this.floatView, '10.2');
}); });
it("can update its value in the view", function() { it("can update its value in the view", function() {
assertCanUpdateView(this.integerView, "12"); assertCanUpdateView(this.integerView, "12");
return assertCanUpdateView(this.floatView, "-2.4"); assertCanUpdateView(this.floatView, "-2.4");
}); });
it("has a clear method to revert to the model default", function() { it("has a clear method to revert to the model default", function() {
assertClear(this.integerView, 6, '6'); assertClear(this.integerView, 6, '6');
return assertClear(this.floatView, 2.7, '2.7'); assertClear(this.floatView, 2.7, '2.7');
}); });
it("has an update model method", function() { it("has an update model method", function() {
assertUpdateModel(this.integerView, null, '90'); assertUpdateModel(this.integerView, null, '90');
return assertUpdateModel(this.floatView, 10.2, '-9.5'); assertUpdateModel(this.floatView, 10.2, '-9.5');
}); });
it("knows the difference between integer and float", function() { it("knows the difference between integer and float", function() {
expect(this.integerView.isIntegerField()).toBeTruthy(); expect(this.integerView.isIntegerField()).toBeTruthy();
return expect(this.floatView.isIntegerField()).toBeFalsy(); expect(this.floatView.isIntegerField()).toBeFalsy();
}); });
it("sets attribtues related to min, max, and step", function() { it("sets attribtues related to min, max, and step", function() {
...@@ -355,12 +354,12 @@ function(MetadataModel, MetadataCollection, MetadataView, main) { ...@@ -355,12 +354,12 @@ function(MetadataModel, MetadataCollection, MetadataView, main) {
expect(Number(inputEntry.attr('min'))).toEqual(min); expect(Number(inputEntry.attr('min'))).toEqual(min);
expect(Number(inputEntry.attr('step'))).toEqual(step); expect(Number(inputEntry.attr('step'))).toEqual(step);
if (max === !null) { if (max === !null) {
return expect(Number(inputEntry.attr('max'))).toEqual(max); expect(Number(inputEntry.attr('max'))).toEqual(max);
} }
}; };
verifyAttributes(this.integerView, 1, 1); verifyAttributes(this.integerView, 1, 1);
return verifyAttributes(this.floatView, 1.3, .1, 100.2); verifyAttributes(this.floatView, 1.3, .1, 100.2);
}); });
it("corrects values that are out of range", function() { it("corrects values that are out of range", function() {
...@@ -373,15 +372,15 @@ function(MetadataModel, MetadataCollection, MetadataView, main) { ...@@ -373,15 +372,15 @@ function(MetadataModel, MetadataCollection, MetadataView, main) {
verifyValueAfterChanged(this.floatView, '1.3', '1.3'); verifyValueAfterChanged(this.floatView, '1.3', '1.3');
verifyValueAfterChanged(this.floatView, '1.2', '1.3'); verifyValueAfterChanged(this.floatView, '1.2', '1.3');
verifyValueAfterChanged(this.floatView, '100.2', '100.2'); verifyValueAfterChanged(this.floatView, '100.2', '100.2');
return verifyValueAfterChanged(this.floatView, '100.3', '100.2'); verifyValueAfterChanged(this.floatView, '100.3', '100.2');
}); });
it("sets default values for integer and float fields that are empty", function() { it("sets default values for integer and float fields that are empty", function() {
verifyValueAfterChanged(this.integerView, '', '6'); verifyValueAfterChanged(this.integerView, '', '6');
return verifyValueAfterChanged(this.floatView, '', '2.7'); verifyValueAfterChanged(this.floatView, '', '2.7');
}); });
return it("disallows invalid characters", function() { it("disallows invalid characters", function() {
const verifyValueAfterKeyPressed = function(view, character, reject) { const verifyValueAfterKeyPressed = function(view, character, reject) {
const event = { const event = {
type : 'keypress', type : 'keypress',
...@@ -392,9 +391,9 @@ function(MetadataModel, MetadataCollection, MetadataView, main) { ...@@ -392,9 +391,9 @@ function(MetadataModel, MetadataCollection, MetadataView, main) {
spyOn(event, 'preventDefault'); spyOn(event, 'preventDefault');
view.$el.find('input').trigger(event); view.$el.find('input').trigger(event);
if (reject) { if (reject) {
return expect(event.preventDefault).toHaveBeenCalled(); expect(event.preventDefault).toHaveBeenCalled();
} else { } else {
return expect(event.preventDefault).not.toHaveBeenCalled(); expect(event.preventDefault).not.toHaveBeenCalled();
} }
}; };
...@@ -404,12 +403,12 @@ function(MetadataModel, MetadataCollection, MetadataView, main) { ...@@ -404,12 +403,12 @@ function(MetadataModel, MetadataCollection, MetadataView, main) {
verifyValueAfterKeyPressed(view, '[', true); verifyValueAfterKeyPressed(view, '[', true);
verifyValueAfterKeyPressed(view, '@', true); verifyValueAfterKeyPressed(view, '@', true);
return [0, 1, 2, 3, 4, 5, 6, 7, 8].map((i) => [0, 1, 2, 3, 4, 5, 6, 7, 8].map((i) =>
verifyValueAfterKeyPressed(view, String(i), false)); verifyValueAfterKeyPressed(view, String(i), false));
}; };
verifyDisallowedChars(this.integerView); verifyDisallowedChars(this.integerView);
return verifyDisallowedChars(this.floatView); verifyDisallowedChars(this.floatView);
}); });
}); });
...@@ -418,68 +417,68 @@ function(MetadataModel, MetadataCollection, MetadataView, main) { ...@@ -418,68 +417,68 @@ function(MetadataModel, MetadataCollection, MetadataView, main) {
const listModel = new MetadataModel(listEntry); const listModel = new MetadataModel(listEntry);
this.listView = new MetadataView.List({model: listModel}); this.listView = new MetadataView.List({model: listModel});
this.el = this.listView.$el; this.el = this.listView.$el;
return main(); main();
}); });
it("returns the initial value upon initialization", function() { it("returns the initial value upon initialization", function() {
return assertValueInView(this.listView, ['the first display value', 'the second']); assertValueInView(this.listView, ['the first display value', 'the second']);
}); });
it("updates its value correctly", function() { it("updates its value correctly", function() {
return assertCanUpdateView(this.listView, ['a new item', 'another new item', 'a third']); assertCanUpdateView(this.listView, ['a new item', 'another new item', 'a third']);
}); });
it("has a clear method to revert to the model default", function() { it("has a clear method to revert to the model default", function() {
this.el.find('.create-setting').click(); this.el.find('.create-setting').click();
assertClear(this.listView, ['a thing', 'another thing']); assertClear(this.listView, ['a thing', 'another thing']);
return expect(this.el.find('.create-setting')).not.toHaveClass('is-disabled'); expect(this.el.find('.create-setting')).not.toHaveClass('is-disabled');
}); });
it("has an update model method", function() { it("has an update model method", function() {
return assertUpdateModel(this.listView, null, ['a new value']); assertUpdateModel(this.listView, null, ['a new value']);
}); });
it("can add an entry", function() { it("can add an entry", function() {
expect(this.listView.model.get('value').length).toEqual(2); expect(this.listView.model.get('value').length).toEqual(2);
this.el.find('.create-setting').click(); this.el.find('.create-setting').click();
return expect(this.el.find('input.input').length).toEqual(3); expect(this.el.find('input.input').length).toEqual(3);
}); });
it("can remove an entry", function() { it("can remove an entry", function() {
expect(this.listView.model.get('value').length).toEqual(2); expect(this.listView.model.get('value').length).toEqual(2);
this.el.find('.remove-setting').first().click(); this.el.find('.remove-setting').first().click();
return expect(this.listView.model.get('value').length).toEqual(1); expect(this.listView.model.get('value').length).toEqual(1);
}); });
it("only allows one blank entry at a time", function() { it("only allows one blank entry at a time", function() {
expect(this.el.find('input').length).toEqual(2); expect(this.el.find('input').length).toEqual(2);
this.el.find('.create-setting').click(); this.el.find('.create-setting').click();
this.el.find('.create-setting').click(); this.el.find('.create-setting').click();
return expect(this.el.find('input').length).toEqual(3); expect(this.el.find('input').length).toEqual(3);
}); });
return it("re-enables the add setting button after entering a new value", function() { it("re-enables the add setting button after entering a new value", function() {
expect(this.el.find('input').length).toEqual(2); expect(this.el.find('input').length).toEqual(2);
this.el.find('.create-setting').click(); this.el.find('.create-setting').click();
expect(this.el.find('.create-setting')).toHaveClass('is-disabled'); expect(this.el.find('.create-setting')).toHaveClass('is-disabled');
this.el.find('input').last().val('third setting'); this.el.find('input').last().val('third setting');
this.el.find('input').last().trigger('input'); this.el.find('input').last().trigger('input');
return expect(this.el.find('.create-setting')).not.toHaveClass('is-disabled'); expect(this.el.find('.create-setting')).not.toHaveClass('is-disabled');
}); });
}); });
describe("MetadataView.RelativeTime allows the user to enter time string in HH:mm:ss format", function() { describe("MetadataView.RelativeTime allows the user to enter time string in HH:mm:ss format", function() {
beforeEach(function() { beforeEach(function() {
const model = new MetadataModel(timeEntry); const model = new MetadataModel(timeEntry);
return this.view = new MetadataView.RelativeTime({model}); this.view = new MetadataView.RelativeTime({model});
}); });
it("uses a text input type", function() { it("uses a text input type", function() {
return assertInputType(this.view, 'text'); assertInputType(this.view, 'text');
}); });
it("returns the intial value upon initialization", function() { it("returns the intial value upon initialization", function() {
return assertValueInView(this.view, '12:12:12'); assertValueInView(this.view, '12:12:12');
}); });
it("value is converted correctly", function() { it("value is converted correctly", function() {
...@@ -563,35 +562,35 @@ function(MetadataModel, MetadataCollection, MetadataView, main) { ...@@ -563,35 +562,35 @@ function(MetadataModel, MetadataCollection, MetadataView, main) {
} }
]; ];
return $.each(cases, (index, data) => expect(view.parseRelativeTime(data.input)).toBe(data.output)); $.each(cases, (index, data) => expect(view.parseRelativeTime(data.input)).toBe(data.output));
}); });
it("can update its value in the view", function() { it("can update its value in the view", function() {
assertCanUpdateView(this.view, "23:59:59"); assertCanUpdateView(this.view, "23:59:59");
this.view.setValueInEditor("33:59:59"); this.view.setValueInEditor("33:59:59");
this.view.updateModel(); this.view.updateModel();
return assertValueInView(this.view, "23:59:59"); assertValueInView(this.view, "23:59:59");
}); });
it("has a clear method to revert to the model default", function() { it("has a clear method to revert to the model default", function() {
return assertClear(this.view, '00:00:00'); assertClear(this.view, '00:00:00');
}); });
return it("has an update model method", function() { it("has an update model method", function() {
return assertUpdateModel(this.view, '12:12:12', '23:59:59'); assertUpdateModel(this.view, '12:12:12', '23:59:59');
}); });
}); });
return describe("MetadataView.Dict allows the user to enter key-value pairs of strings", function() { describe("MetadataView.Dict allows the user to enter key-value pairs of strings", function() {
beforeEach(function() { beforeEach(function() {
const dictModel = new MetadataModel($.extend(true, {}, dictEntry)); const dictModel = new MetadataModel($.extend(true, {}, dictEntry));
this.dictView = new MetadataView.Dict({model: dictModel}); this.dictView = new MetadataView.Dict({model: dictModel});
this.el = this.dictView.$el; this.el = this.dictView.$el;
return main(); main();
}); });
it("returns the initial value upon initialization", function() { it("returns the initial value upon initialization", function() {
return assertValueInView(this.dictView, { assertValueInView(this.dictView, {
'en': 'English', 'en': 'English',
'ru': 'Русский', 'ru': 'Русский',
'ua': 'Українська', 'ua': 'Українська',
...@@ -600,7 +599,7 @@ function(MetadataModel, MetadataCollection, MetadataView, main) { ...@@ -600,7 +599,7 @@ function(MetadataModel, MetadataCollection, MetadataView, main) {
}); });
it("updates its value correctly", function() { it("updates its value correctly", function() {
return assertCanUpdateView(this.dictView, { assertCanUpdateView(this.dictView, {
'ru': 'Русский', 'ru': 'Русский',
'ua': 'Українська', 'ua': 'Українська',
'fr': 'Français' 'fr': 'Français'
...@@ -613,30 +612,30 @@ function(MetadataModel, MetadataCollection, MetadataView, main) { ...@@ -613,30 +612,30 @@ function(MetadataModel, MetadataCollection, MetadataView, main) {
'en': 'English', 'en': 'English',
'ru': 'Русский' 'ru': 'Русский'
}); });
return expect(this.el.find('.create-setting')).not.toHaveClass('is-disabled'); expect(this.el.find('.create-setting')).not.toHaveClass('is-disabled');
}); });
it("has an update model method", function() { it("has an update model method", function() {
return assertUpdateModel(this.dictView, null, {'fr': 'Français'}); assertUpdateModel(this.dictView, null, {'fr': 'Français'});
}); });
it("can add an entry", function() { it("can add an entry", function() {
expect(_.keys(this.dictView.model.get('value')).length).toEqual(4); expect(_.keys(this.dictView.model.get('value')).length).toEqual(4);
this.el.find('.create-setting').click(); this.el.find('.create-setting').click();
return expect(this.el.find('input.input-key').length).toEqual(5); expect(this.el.find('input.input-key').length).toEqual(5);
}); });
it("can remove an entry", function() { it("can remove an entry", function() {
expect(_.keys(this.dictView.model.get('value')).length).toEqual(4); expect(_.keys(this.dictView.model.get('value')).length).toEqual(4);
this.el.find('.remove-setting').first().click(); this.el.find('.remove-setting').first().click();
return expect(_.keys(this.dictView.model.get('value')).length).toEqual(3); expect(_.keys(this.dictView.model.get('value')).length).toEqual(3);
}); });
it("only allows one blank entry at a time", function() { it("only allows one blank entry at a time", function() {
expect(this.el.find('input.input-key').length).toEqual(4); expect(this.el.find('input.input-key').length).toEqual(4);
this.el.find('.create-setting').click(); this.el.find('.create-setting').click();
this.el.find('.create-setting').click(); this.el.find('.create-setting').click();
return expect(this.el.find('input.input-key').length).toEqual(5); expect(this.el.find('input.input-key').length).toEqual(5);
}); });
it("only allows unique keys", function() { it("only allows unique keys", function() {
...@@ -667,7 +666,7 @@ function(MetadataModel, MetadataCollection, MetadataView, main) { ...@@ -667,7 +666,7 @@ function(MetadataModel, MetadataCollection, MetadataView, main) {
} }
]; ];
return _.each(data, ((d, index) => { _.each(data, ((d, index) => {
this.dictView.setValueInEditor(d.initialValue); this.dictView.setValueInEditor(d.initialValue);
this.dictView.updateModel(); this.dictView.updateModel();
this.el.find('.create-setting').click(); this.el.find('.create-setting').click();
...@@ -675,18 +674,18 @@ function(MetadataModel, MetadataCollection, MetadataView, main) { ...@@ -675,18 +674,18 @@ function(MetadataModel, MetadataCollection, MetadataView, main) {
item.find('.input-key').val(d.testValue.key); item.find('.input-key').val(d.testValue.key);
item.find('.input-value').val(d.testValue.value); item.find('.input-value').val(d.testValue.value);
return expect(this.dictView.getValueFromEditor()).toEqual(d.expectedValue); expect(this.dictView.getValueFromEditor()).toEqual(d.expectedValue);
}) })
); );
}); });
return it("re-enables the add setting button after entering a new value", function() { it("re-enables the add setting button after entering a new value", function() {
expect(this.el.find('input.input-key').length).toEqual(4); expect(this.el.find('input.input-key').length).toEqual(4);
this.el.find('.create-setting').click(); this.el.find('.create-setting').click();
expect(this.el.find('.create-setting')).toHaveClass('is-disabled'); expect(this.el.find('.create-setting')).toHaveClass('is-disabled');
this.el.find('input.input-key').last().val('third setting'); this.el.find('input.input-key').last().val('third setting');
this.el.find('input.input-key').last().trigger('input'); this.el.find('input.input-key').last().trigger('input');
return expect(this.el.find('.create-setting')).not.toHaveClass('is-disabled'); expect(this.el.find('.create-setting')).not.toHaveClass('is-disabled');
}); });
}); });
}); });
......
/*
* decaffeinate suggestions:
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
define(["js/models/textbook", "js/models/chapter", "js/collections/chapter", "js/models/course", define(["js/models/textbook", "js/models/chapter", "js/collections/chapter", "js/models/course",
"js/collections/textbook", "js/views/show_textbook", "js/views/edit_textbook", "js/views/list_textbooks", "js/collections/textbook", "js/views/show_textbook", "js/views/edit_textbook", "js/views/list_textbooks",
"js/views/edit_chapter", "common/js/components/views/feedback_prompt", "js/views/edit_chapter", "common/js/components/views/feedback_prompt",
...@@ -26,7 +21,7 @@ define(["js/models/textbook", "js/models/chapter", "js/collections/chapter", "js ...@@ -26,7 +21,7 @@ define(["js/models/textbook", "js/models/chapter", "js/collections/chapter", "js
this.promptSpies = jasmine.stealth.spyOnConstructor(Prompt, "Warning", ["show", "hide"]); this.promptSpies = jasmine.stealth.spyOnConstructor(Prompt, "Warning", ["show", "hide"]);
this.promptSpies.show.and.returnValue(this.promptSpies); this.promptSpies.show.and.returnValue(this.promptSpies);
return window.course = new Course({ window.course = new Course({
id: "5", id: "5",
name: "Course Name", name: "Course Name",
url_name: "course_name", url_name: "course_name",
...@@ -41,12 +36,12 @@ define(["js/models/textbook", "js/models/chapter", "js/collections/chapter", "js ...@@ -41,12 +36,12 @@ define(["js/models/textbook", "js/models/chapter", "js/collections/chapter", "js
describe("Basic", function() { describe("Basic", function() {
it("should render properly", function() { it("should render properly", function() {
this.view.render(); this.view.render();
return expect(this.view.$el).toContainText("Life Sciences"); expect(this.view.$el).toContainText("Life Sciences");
}); });
it("should set the 'editing' property on the model when the edit button is clicked", function() { it("should set the 'editing' property on the model when the edit button is clicked", function() {
this.view.render().$(".edit").click(); this.view.render().$(".edit").click();
return expect(this.model.get("editing")).toBeTruthy(); expect(this.model.get("editing")).toBeTruthy();
}); });
it("should pop a delete confirmation when the delete button is clicked", function() { it("should pop a delete confirmation when the delete button is clicked", function() {
...@@ -56,35 +51,35 @@ define(["js/models/textbook", "js/models/chapter", "js/collections/chapter", "js ...@@ -56,35 +51,35 @@ define(["js/models/textbook", "js/models/chapter", "js/collections/chapter", "js
expect(ctorOptions.title).toMatch(/Life Sciences/); expect(ctorOptions.title).toMatch(/Life Sciences/);
// hasn't actually been removed // hasn't actually been removed
expect(this.model.destroy).not.toHaveBeenCalled(); expect(this.model.destroy).not.toHaveBeenCalled();
return expect(this.collection).toContain(this.model); expect(this.collection).toContain(this.model);
}); });
it("should show chapters appropriately", function() { it("should show chapters appropriately", function() {
this.model.get("chapters").add([{}, {}, {}]); this.model.get("chapters").add([{}, {}, {}]);
this.model.set('showChapters', false); this.model.set('showChapters', false);
this.view.render().$(".show-chapters").click(); this.view.render().$(".show-chapters").click();
return expect(this.model.get('showChapters')).toBeTruthy(); expect(this.model.get('showChapters')).toBeTruthy();
}); });
return it("should hide chapters appropriately", function() { it("should hide chapters appropriately", function() {
this.model.get("chapters").add([{}, {}, {}]); this.model.get("chapters").add([{}, {}, {}]);
this.model.set('showChapters', true); this.model.set('showChapters', true);
this.view.render().$(".hide-chapters").click(); this.view.render().$(".hide-chapters").click();
return expect(this.model.get('showChapters')).toBeFalsy(); expect(this.model.get('showChapters')).toBeFalsy();
}); });
}); });
return describe("AJAX", function() { describe("AJAX", function() {
beforeEach(function() { beforeEach(function() {
this.savingSpies = jasmine.stealth.spyOnConstructor(Notification, "Mini", this.savingSpies = jasmine.stealth.spyOnConstructor(Notification, "Mini",
["show", "hide"]); ["show", "hide"]);
this.savingSpies.show.and.returnValue(this.savingSpies); this.savingSpies.show.and.returnValue(this.savingSpies);
return CMS.URL.TEXTBOOKS = "/textbooks"; CMS.URL.TEXTBOOKS = "/textbooks";
}); });
afterEach(() => delete CMS.URL.TEXTBOOKS); afterEach(() => delete CMS.URL.TEXTBOOKS);
return it("should destroy itself on confirmation", function() { it("should destroy itself on confirmation", function() {
const requests = AjaxHelpers["requests"](this); const requests = AjaxHelpers["requests"](this);
this.view.render().$(".delete").click(); this.view.render().$(".delete").click();
...@@ -102,7 +97,7 @@ define(["js/models/textbook", "js/models/chapter", "js/collections/chapter", "js ...@@ -102,7 +97,7 @@ define(["js/models/textbook", "js/models/chapter", "js/collections/chapter", "js
// return a success response // return a success response
requests[0].respond(204); requests[0].respond(204);
expect(this.savingSpies.hide).toHaveBeenCalled(); expect(this.savingSpies.hide).toHaveBeenCalled();
return expect(this.collection.contains(this.model)).toBeFalsy(); expect(this.collection.contains(this.model)).toBeFalsy();
}); });
}); });
}); });
...@@ -120,12 +115,12 @@ define(["js/models/textbook", "js/models/chapter", "js/collections/chapter", "js ...@@ -120,12 +115,12 @@ define(["js/models/textbook", "js/models/chapter", "js/collections/chapter", "js
this.collection = new TextbookSet(); this.collection = new TextbookSet();
this.collection.add(this.model); this.collection.add(this.model);
this.view = new EditTextbook({model: this.model}); this.view = new EditTextbook({model: this.model});
return spyOn(this.view, 'render').and.callThrough(); spyOn(this.view, 'render').and.callThrough();
}); });
it("should render properly", function() { it("should render properly", function() {
this.view.render(); this.view.render();
return expect(this.view.$("input[name=textbook-name]").val()).toEqual("Life Sciences"); expect(this.view.$("input[name=textbook-name]").val()).toEqual("Life Sciences");
}); });
it("should allow you to create new empty chapters", function() { it("should allow you to create new empty chapters", function() {
...@@ -133,7 +128,7 @@ define(["js/models/textbook", "js/models/chapter", "js/collections/chapter", "js ...@@ -133,7 +128,7 @@ define(["js/models/textbook", "js/models/chapter", "js/collections/chapter", "js
const numChapters = this.model.get("chapters").length; const numChapters = this.model.get("chapters").length;
this.view.$(".action-add-chapter").click(); this.view.$(".action-add-chapter").click();
expect(this.model.get("chapters").length).toEqual(numChapters+1); expect(this.model.get("chapters").length).toEqual(numChapters+1);
return expect(this.model.get("chapters").last().isEmpty()).toBeTruthy(); expect(this.model.get("chapters").last().isEmpty()).toBeTruthy();
}); });
it("should save properly", function() { it("should save properly", function() {
...@@ -146,7 +141,7 @@ define(["js/models/textbook", "js/models/chapter", "js/collections/chapter", "js ...@@ -146,7 +141,7 @@ define(["js/models/textbook", "js/models/chapter", "js/collections/chapter", "js
const chapter = this.model.get("chapters").first(); const chapter = this.model.get("chapters").first();
expect(chapter.get("name")).toEqual("wallflower"); expect(chapter.get("name")).toEqual("wallflower");
expect(chapter.get("asset_path")).toEqual("foobar"); expect(chapter.get("asset_path")).toEqual("foobar");
return expect(this.model.save).toHaveBeenCalled(); expect(this.model.save).toHaveBeenCalled();
}); });
it("should not save on invalid", function() { it("should not save on invalid", function() {
...@@ -155,7 +150,7 @@ define(["js/models/textbook", "js/models/chapter", "js/collections/chapter", "js ...@@ -155,7 +150,7 @@ define(["js/models/textbook", "js/models/chapter", "js/collections/chapter", "js
this.view.$("input[name=chapter1-asset-path]").val("foobar.pdf"); this.view.$("input[name=chapter1-asset-path]").val("foobar.pdf");
this.view.$("form").submit(); this.view.$("form").submit();
expect(this.model.validationError).toBeTruthy(); expect(this.model.validationError).toBeTruthy();
return expect(this.model.save).not.toHaveBeenCalled(); expect(this.model.save).not.toHaveBeenCalled();
}); });
it("does not save on cancel", function() { it("does not save on cancel", function() {
...@@ -167,7 +162,7 @@ define(["js/models/textbook", "js/models/chapter", "js/collections/chapter", "js ...@@ -167,7 +162,7 @@ define(["js/models/textbook", "js/models/chapter", "js/collections/chapter", "js
expect(this.model.get("name")).not.toEqual("starfish"); expect(this.model.get("name")).not.toEqual("starfish");
const chapter = this.model.get("chapters").first(); const chapter = this.model.get("chapters").first();
expect(chapter.get("asset_path")).not.toEqual("foobar"); expect(chapter.get("asset_path")).not.toEqual("foobar");
return expect(this.model.save).not.toHaveBeenCalled(); expect(this.model.save).not.toHaveBeenCalled();
}); });
it("should be possible to correct validation errors", function() { it("should be possible to correct validation errors", function() {
...@@ -181,7 +176,7 @@ define(["js/models/textbook", "js/models/chapter", "js/collections/chapter", "js ...@@ -181,7 +176,7 @@ define(["js/models/textbook", "js/models/chapter", "js/collections/chapter", "js
this.view.$("input[name=chapter1-name]").val("foobar"); this.view.$("input[name=chapter1-name]").val("foobar");
this.view.$("form").submit(); this.view.$("form").submit();
expect(this.model.validationError).toBeFalsy(); expect(this.model.validationError).toBeFalsy();
return expect(this.model.save).toHaveBeenCalled(); expect(this.model.save).toHaveBeenCalled();
}); });
it("removes all empty chapters on cancel if the model has a non-empty chapter", function() { it("removes all empty chapters on cancel if the model has a non-empty chapter", function() {
...@@ -193,16 +188,16 @@ define(["js/models/textbook", "js/models/chapter", "js/collections/chapter", "js ...@@ -193,16 +188,16 @@ define(["js/models/textbook", "js/models/chapter", "js/collections/chapter", "js
expect(chapters.length).toEqual(4); expect(chapters.length).toEqual(4);
this.view.$(".action-cancel").click(); this.view.$(".action-cancel").click();
expect(chapters.length).toEqual(1); expect(chapters.length).toEqual(1);
return expect(chapters.first().get('name')).toEqual("non-empty"); expect(chapters.first().get('name')).toEqual("non-empty");
}); });
return it("removes all empty chapters on cancel except one if the model has no non-empty chapters", function() { it("removes all empty chapters on cancel except one if the model has no non-empty chapters", function() {
const chapters = this.model.get("chapters"); const chapters = this.model.get("chapters");
this.view.render(); this.view.render();
chapters.add([{}, {}, {}]); // add three empty chapters chapters.add([{}, {}, {}]); // add three empty chapters
expect(chapters.length).toEqual(4); expect(chapters.length).toEqual(4);
this.view.$(".action-cancel").click(); this.view.$(".action-cancel").click();
return expect(chapters.length).toEqual(1); expect(chapters.length).toEqual(1);
}); });
}) })
); );
...@@ -216,7 +211,7 @@ define(["js/models/textbook", "js/models/chapter", "js/collections/chapter", "js ...@@ -216,7 +211,7 @@ define(["js/models/textbook", "js/models/chapter", "js/collections/chapter", "js
appendSetFixtures($("<script>", {id: "edit-textbook-tpl", type: "text/template"}).text(editTextbooktpl)); appendSetFixtures($("<script>", {id: "edit-textbook-tpl", type: "text/template"}).text(editTextbooktpl));
this.collection = new TextbookSet; this.collection = new TextbookSet;
this.view = new ListTextbooks({collection: this.collection}); this.view = new ListTextbooks({collection: this.collection});
return this.view.render(); this.view.render();
}); });
it("should scroll to newly added textbook", function() { it("should scroll to newly added textbook", function() {
...@@ -224,10 +219,10 @@ define(["js/models/textbook", "js/models/chapter", "js/collections/chapter", "js ...@@ -224,10 +219,10 @@ define(["js/models/textbook", "js/models/chapter", "js/collections/chapter", "js
this.view.$(".new-button").click(); this.view.$(".new-button").click();
const $sectionEl = this.view.$el.find('section:last'); const $sectionEl = this.view.$el.find('section:last');
expect($sectionEl.length).toEqual(1); expect($sectionEl.length).toEqual(1);
return expect(ViewUtils.setScrollOffset).toHaveBeenCalledWith($sectionEl, 0); expect(ViewUtils.setScrollOffset).toHaveBeenCalledWith($sectionEl, 0);
}); });
return it("should focus first input element of newly added textbook", function() { it("should focus first input element of newly added textbook", function() {
spyOn(jQuery.fn, 'focus').and.callThrough(); spyOn(jQuery.fn, 'focus').and.callThrough();
jasmine.addMatchers({ jasmine.addMatchers({
toHaveBeenCalledOnJQueryObject() { toHaveBeenCalledOnJQueryObject() {
...@@ -248,7 +243,7 @@ define(["js/models/textbook", "js/models/chapter", "js/collections/chapter", "js ...@@ -248,7 +243,7 @@ define(["js/models/textbook", "js/models/chapter", "js/collections/chapter", "js
// and the following doesn't seem to work // and the following doesn't seem to work
// expect($inputEl).toBeFocused() // expect($inputEl).toBeFocused()
// expect($inputEl.find(':focus').length).toEqual(1) // expect($inputEl.find(':focus').length).toEqual(1)
return expect(jQuery.fn.focus).toHaveBeenCalledOnJQueryObject($inputEl); expect(jQuery.fn.focus).toHaveBeenCalledOnJQueryObject($inputEl);
}); });
}); });
...@@ -324,7 +319,7 @@ define(["js/models/textbook", "js/models/chapter", "js/collections/chapter", "js ...@@ -324,7 +319,7 @@ define(["js/models/textbook", "js/models/chapter", "js/collections/chapter", "js
// expect(@view.$el).not.toContain(@showSpies.$el) // expect(@view.$el).not.toContain(@showSpies.$el)
return describe("EditChapter", function() { describe("EditChapter", function() {
beforeEach(function() { beforeEach(function() {
modal_helpers.installModalTemplates(); modal_helpers.installModalTemplates();
this.model = new Chapter({ this.model = new Chapter({
...@@ -336,24 +331,24 @@ define(["js/models/textbook", "js/models/chapter", "js/collections/chapter", "js ...@@ -336,24 +331,24 @@ define(["js/models/textbook", "js/models/chapter", "js/collections/chapter", "js
this.view = new EditChapter({model: this.model}); this.view = new EditChapter({model: this.model});
spyOn(this.view, "remove").and.callThrough(); spyOn(this.view, "remove").and.callThrough();
CMS.URL.UPLOAD_ASSET = "/upload"; CMS.URL.UPLOAD_ASSET = "/upload";
return window.course = new Course({name: "abcde"}); window.course = new Course({name: "abcde"});
}); });
afterEach(function() { afterEach(function() {
delete CMS.URL.UPLOAD_ASSET; delete CMS.URL.UPLOAD_ASSET;
return delete window.course; delete window.course;
}); });
it("can render", function() { it("can render", function() {
this.view.render(); this.view.render();
expect(this.view.$("input.chapter-name").val()).toEqual("Chapter 1"); expect(this.view.$("input.chapter-name").val()).toEqual("Chapter 1");
return expect(this.view.$("input.chapter-asset-path").val()).toEqual("/ch1.pdf"); expect(this.view.$("input.chapter-asset-path").val()).toEqual("/ch1.pdf");
}); });
it("can delete itself", function() { it("can delete itself", function() {
this.view.render().$(".action-close").click(); this.view.render().$(".action-close").click();
expect(this.collection.length).toEqual(0); expect(this.collection.length).toEqual(0);
return expect(this.view.remove).toHaveBeenCalled(); expect(this.view.remove).toHaveBeenCalled();
}); });
// it "can open an upload dialog", -> // it "can open an upload dialog", ->
...@@ -368,13 +363,13 @@ define(["js/models/textbook", "js/models/chapter", "js/collections/chapter", "js ...@@ -368,13 +363,13 @@ define(["js/models/textbook", "js/models/chapter", "js/collections/chapter", "js
// Disabling because this test does not close the modal dialog. This can cause // Disabling because this test does not close the modal dialog. This can cause
// tests that run after it to fail (see STUD-1963). // tests that run after it to fail (see STUD-1963).
return xit("saves content when opening upload dialog", function() { xit("saves content when opening upload dialog", function() {
this.view.render(); this.view.render();
this.view.$("input.chapter-name").val("rainbows"); this.view.$("input.chapter-name").val("rainbows");
this.view.$("input.chapter-asset-path").val("unicorns"); this.view.$("input.chapter-asset-path").val("unicorns");
this.view.$(".action-upload").click(); this.view.$(".action-upload").click();
expect(this.model.get("name")).toEqual("rainbows"); expect(this.model.get("name")).toEqual("rainbows");
return expect(this.model.get("asset_path")).toEqual("unicorns"); expect(this.model.get("asset_path")).toEqual("unicorns");
}); });
}); });
}); });
/*
* decaffeinate suggestions:
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
define(["sinon", "js/models/uploads", "js/views/uploads", "js/models/chapter", define(["sinon", "js/models/uploads", "js/views/uploads", "js/models/chapter",
"edx-ui-toolkit/js/utils/spec-helpers/ajax-helpers", "js/spec_helpers/modal_helpers"], "edx-ui-toolkit/js/utils/spec-helpers/ajax-helpers", "js/spec_helpers/modal_helpers"],
(sinon, FileUpload, UploadDialog, Chapter, AjaxHelpers, modal_helpers) => (sinon, FileUpload, UploadDialog, Chapter, AjaxHelpers, modal_helpers) =>
...@@ -19,11 +14,11 @@ define(["sinon", "js/models/uploads", "js/views/uploads", "js/models/chapter", ...@@ -19,11 +14,11 @@ define(["sinon", "js/models/uploads", "js/views/uploads", "js/models/chapter",
mimeTypes: ['application/pdf'] mimeTypes: ['application/pdf']
}); });
this.dialogResponse = (dialogResponse = []); this.dialogResponse = (dialogResponse = []);
return this.mockFiles = [];}); this.mockFiles = [];});
afterEach(function() { afterEach(function() {
delete CMS.URL.UPLOAD_ASSET; delete CMS.URL.UPLOAD_ASSET;
return modal_helpers.cancelModalIfShowing(); modal_helpers.cancelModalIfShowing();
}); });
const createTestView = function(test) { const createTestView = function(test) {
...@@ -49,7 +44,8 @@ define(["sinon", "js/models/uploads", "js/views/uploads", "js/models/chapter", ...@@ -49,7 +44,8 @@ define(["sinon", "js/models/uploads", "js/views/uploads", "js/models/chapter",
return originalView$.apply(this, arguments); return originalView$.apply(this, arguments);
} }
}); });
return this.lastView = view; this.lastView = view;
return view;
}; };
describe("Basic", function() { describe("Basic", function() {
...@@ -57,7 +53,7 @@ define(["sinon", "js/models/uploads", "js/views/uploads", "js/models/chapter", ...@@ -57,7 +53,7 @@ define(["sinon", "js/models/uploads", "js/views/uploads", "js/models/chapter",
const view = createTestView(this); const view = createTestView(this);
view.render(); view.render();
expect(view.$el).toContainElement("input[type=file]"); expect(view.$el).toContainElement("input[type=file]");
return expect(view.$(".action-upload")).toHaveClass("disabled"); expect(view.$(".action-upload")).toHaveClass("disabled");
}); });
it("should render with a PDF selected", function() { it("should render with a PDF selected", function() {
...@@ -68,7 +64,7 @@ define(["sinon", "js/models/uploads", "js/views/uploads", "js/models/chapter", ...@@ -68,7 +64,7 @@ define(["sinon", "js/models/uploads", "js/views/uploads", "js/models/chapter",
view.render(); view.render();
expect(view.$el).toContainElement("input[type=file]"); expect(view.$el).toContainElement("input[type=file]");
expect(view.$el).not.toContainElement("#upload_error"); expect(view.$el).not.toContainElement("#upload_error");
return expect(view.$(".action-upload")).not.toHaveClass("disabled"); expect(view.$(".action-upload")).not.toHaveClass("disabled");
}); });
it("should render an error with an invalid file type selected", function() { it("should render an error with an invalid file type selected", function() {
...@@ -79,10 +75,10 @@ define(["sinon", "js/models/uploads", "js/views/uploads", "js/models/chapter", ...@@ -79,10 +75,10 @@ define(["sinon", "js/models/uploads", "js/views/uploads", "js/models/chapter",
view.render(); view.render();
expect(view.$el).toContainElement("input[type=file]"); expect(view.$el).toContainElement("input[type=file]");
expect(view.$el).toContainElement("#upload_error"); expect(view.$el).toContainElement("#upload_error");
return expect(view.$(".action-upload")).toHaveClass("disabled"); expect(view.$(".action-upload")).toHaveClass("disabled");
}); });
return it("should render an error with an invalid file type after a correct file type selected", function() { it("should render an error with an invalid file type after a correct file type selected", function() {
const view = createTestView(this); const view = createTestView(this);
const correctFile = {name: "fake.pdf", "type": "application/pdf"}; const correctFile = {name: "fake.pdf", "type": "application/pdf"};
const inCorrectFile = {name: "fake.png", "type": "image/png"}; const inCorrectFile = {name: "fake.png", "type": "image/png"};
...@@ -109,18 +105,18 @@ define(["sinon", "js/models/uploads", "js/views/uploads", "js/models/chapter", ...@@ -109,18 +105,18 @@ define(["sinon", "js/models/uploads", "js/views/uploads", "js/models/chapter",
view.selectFile(event); view.selectFile(event);
expect(view.$el).toContainElement("input[type=file]"); expect(view.$el).toContainElement("input[type=file]");
expect(view.$el).toContainElement("#upload_error"); expect(view.$el).toContainElement("#upload_error");
return expect(view.$(".action-upload")).toHaveClass("disabled"); expect(view.$(".action-upload")).toHaveClass("disabled");
}); });
}); });
return describe("Uploads", function() { describe("Uploads", function() {
beforeEach(function() { beforeEach(function() {
return this.clock = sinon.useFakeTimers(); this.clock = sinon.useFakeTimers();
}); });
afterEach(function() { afterEach(function() {
modal_helpers.cancelModalIfShowing(); modal_helpers.cancelModalIfShowing();
return this.clock.restore(); this.clock.restore();
}); });
it("can upload correctly", function() { it("can upload correctly", function() {
...@@ -133,7 +129,7 @@ define(["sinon", "js/models/uploads", "js/views/uploads", "js/models/chapter", ...@@ -133,7 +129,7 @@ define(["sinon", "js/models/uploads", "js/views/uploads", "js/models/chapter",
AjaxHelpers.respondWithJson(requests, { response: "dummy_response"}); AjaxHelpers.respondWithJson(requests, { response: "dummy_response"});
expect(this.model.get("uploading")).toBeFalsy(); expect(this.model.get("uploading")).toBeFalsy();
expect(this.model.get("finished")).toBeTruthy(); expect(this.model.get("finished")).toBeTruthy();
return expect(this.dialogResponse.pop()).toEqual("dummy_response"); expect(this.dialogResponse.pop()).toEqual("dummy_response");
}); });
it("can handle upload errors", function() { it("can handle upload errors", function() {
...@@ -143,10 +139,10 @@ define(["sinon", "js/models/uploads", "js/views/uploads", "js/models/chapter", ...@@ -143,10 +139,10 @@ define(["sinon", "js/models/uploads", "js/views/uploads", "js/models/chapter",
view.upload(); view.upload();
AjaxHelpers.respondWithError(requests); AjaxHelpers.respondWithError(requests);
expect(this.model.get("title")).toMatch(/error/); expect(this.model.get("title")).toMatch(/error/);
return expect(view.remove).not.toHaveBeenCalled(); expect(view.remove).not.toHaveBeenCalled();
}); });
return it("removes itself after two seconds on successful upload", function() { it("removes itself after two seconds on successful upload", function() {
const requests = AjaxHelpers.requests(this); const requests = AjaxHelpers.requests(this);
const view = createTestView(this); const view = createTestView(this);
view.render(); view.render();
...@@ -154,7 +150,7 @@ define(["sinon", "js/models/uploads", "js/views/uploads", "js/models/chapter", ...@@ -154,7 +150,7 @@ define(["sinon", "js/models/uploads", "js/views/uploads", "js/models/chapter",
AjaxHelpers.respondWithJson(requests, { response: "dummy_response"}); AjaxHelpers.respondWithJson(requests, { response: "dummy_response"});
expect(modal_helpers.isShowingModal(view)).toBeTruthy(); expect(modal_helpers.isShowingModal(view)).toBeTruthy();
this.clock.tick(2001); this.clock.tick(2001);
return expect(modal_helpers.isShowingModal(view)).toBeFalsy(); expect(modal_helpers.isShowingModal(view)).toBeFalsy();
}); });
}); });
}) })
......
/* /*
* decaffeinate suggestions: * decaffeinate suggestions:
* DS102: Remove unnecessary code created because of implicit returns
* DS207: Consider shorter variations of null checks * DS207: Consider shorter variations of null checks
* DS208: Avoid top-level this * DS208: Avoid top-level this
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
...@@ -18,7 +17,7 @@ class XProblemGenerator { ...@@ -18,7 +17,7 @@ class XProblemGenerator {
generate() { generate() {
return console.error("Abstract method called: XProblemGenerator.generate"); console.error("Abstract method called: XProblemGenerator.generate");
} }
} }
...@@ -36,16 +35,16 @@ class XProblemDisplay { ...@@ -36,16 +35,16 @@ class XProblemDisplay {
render() { render() {
return console.error("Abstract method called: XProblemDisplay.render"); console.error("Abstract method called: XProblemDisplay.render");
} }
updateSubmission() { updateSubmission() {
return this.submissionField.val(JSON.stringify(this.getCurrentSubmission())); this.submissionField.val(JSON.stringify(this.getCurrentSubmission()));
} }
getCurrentSubmission() { getCurrentSubmission() {
return console.error("Abstract method called: XProblemDisplay.getCurrentSubmission"); console.error("Abstract method called: XProblemDisplay.getCurrentSubmission");
} }
} }
...@@ -63,12 +62,12 @@ class XProblemGrader { ...@@ -63,12 +62,12 @@ class XProblemGrader {
solve() { solve() {
return console.error("Abstract method called: XProblemGrader.solve"); console.error("Abstract method called: XProblemGrader.solve");
} }
grade() { grade() {
return console.error("Abstract method called: XProblemGrader.grade"); console.error("Abstract method called: XProblemGrader.grade");
} }
} }
......
/*
* decaffeinate suggestions:
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
describe('Annotatable', function() { describe('Annotatable', function() {
beforeEach(() => loadFixtures('annotatable.html')); beforeEach(() => loadFixtures('annotatable.html'));
return describe('constructor', function() { describe('constructor', function() {
const el = $('.xblock-student_view.xmodule_AnnotatableModule'); const el = $('.xblock-student_view.xmodule_AnnotatableModule');
beforeEach(function() { beforeEach(function() {
return this.annotatable = new Annotatable(el); this.annotatable = new Annotatable(el);
}); });
return it('works', () => expect(1).toBe(1)); it('works', () => expect(1).toBe(1));
}); });
}); });
/* /*
* decaffeinate suggestions: * decaffeinate suggestions:
* DS101: Remove unnecessary use of Array.from * DS101: Remove unnecessary use of Array.from
* DS102: Remove unnecessary code created because of implicit returns
* DS207: Consider shorter variations of null checks * DS207: Consider shorter variations of null checks
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/ */
...@@ -29,7 +28,7 @@ describe('Problem', function() { ...@@ -29,7 +28,7 @@ describe('Problem', function() {
loadFixtures('problem.html'); loadFixtures('problem.html');
spyOn(Logger, 'log'); spyOn(Logger, 'log');
return spyOn($.fn, 'load').and.callFake(function(url, callback) { spyOn($.fn, 'load').and.callFake(function(url, callback) {
$(this).html(readFixtures('problem_content.html')); $(this).html(readFixtures('problem_content.html'));
return callback(); return callback();
}); });
...@@ -48,12 +47,12 @@ data-url='/problem/quiz/'> \ ...@@ -48,12 +47,12 @@ data-url='/problem/quiz/'> \
</section>\ </section>\
`) `)
); );
return expect(this.problem999.element_id).toBe('problem_999'); expect(this.problem999.element_id).toBe('problem_999');
}); });
return it('set the element from loadFixtures', function() { it('set the element from loadFixtures', function() {
this.problem1 = new Problem($('.xblock-student_view')); this.problem1 = new Problem($('.xblock-student_view'));
return expect(this.problem1.element_id).toBe('problem_1'); expect(this.problem1.element_id).toBe('problem_1');
}); });
}); });
...@@ -61,7 +60,7 @@ data-url='/problem/quiz/'> \ ...@@ -61,7 +60,7 @@ data-url='/problem/quiz/'> \
beforeEach(function() { beforeEach(function() {
spyOn(window, 'update_schematics'); spyOn(window, 'update_schematics');
MathJax.Hub.getAllJax.and.returnValue([this.stubbedJax]); MathJax.Hub.getAllJax.and.returnValue([this.stubbedJax]);
return this.problem = new Problem($('.xblock-student_view')); this.problem = new Problem($('.xblock-student_view'));
}); });
it('set mathjax typeset', () => expect(MathJax.Hub.Queue).toHaveBeenCalled()); it('set mathjax typeset', () => expect(MathJax.Hub.Queue).toHaveBeenCalled());
...@@ -69,27 +68,27 @@ data-url='/problem/quiz/'> \ ...@@ -69,27 +68,27 @@ data-url='/problem/quiz/'> \
it('update schematics', () => expect(window.update_schematics).toHaveBeenCalled()); it('update schematics', () => expect(window.update_schematics).toHaveBeenCalled());
it('bind answer refresh on button click', function() { it('bind answer refresh on button click', function() {
return expect($('div.action button')).toHandleWith('click', this.problem.refreshAnswers); expect($('div.action button')).toHandleWith('click', this.problem.refreshAnswers);
}); });
it('bind the submit button', function() { it('bind the submit button', function() {
return expect($('.action .submit')).toHandleWith('click', this.problem.submit_fd); expect($('.action .submit')).toHandleWith('click', this.problem.submit_fd);
}); });
it('bind the reset button', function() { it('bind the reset button', function() {
return expect($('div.action button.reset')).toHandleWith('click', this.problem.reset); expect($('div.action button.reset')).toHandleWith('click', this.problem.reset);
}); });
it('bind the show button', function() { it('bind the show button', function() {
return expect($('.action .show')).toHandleWith('click', this.problem.show); expect($('.action .show')).toHandleWith('click', this.problem.show);
}); });
it('bind the save button', function() { it('bind the save button', function() {
return expect($('div.action button.save')).toHandleWith('click', this.problem.save); expect($('div.action button.save')).toHandleWith('click', this.problem.save);
}); });
return it('bind the math input', function() { it('bind the math input', function() {
return expect($('input.math')).toHandleWith('keyup', this.problem.refreshMath); expect($('input.math')).toHandleWith('keyup', this.problem.refreshMath);
}); });
}); });
...@@ -102,18 +101,18 @@ data-url='/problem/quiz/'> \ ...@@ -102,18 +101,18 @@ data-url='/problem/quiz/'> \
}); });
it('bind the submit button', function() { it('bind the submit button', function() {
return expect($('.action .submit')).toHandleWith('click', this.problem.submit_fd); expect($('.action .submit')).toHandleWith('click', this.problem.submit_fd);
}); });
return it('bind the show button', function() { it('bind the show button', function() {
return expect($('div.action button.show')).toHandleWith('click', this.problem.show); expect($('div.action button.show')).toHandleWith('click', this.problem.show);
}); });
}); });
describe('renderProgressState', function() { describe('renderProgressState', function() {
beforeEach(function() { beforeEach(function() {
return this.problem = new Problem($('.xblock-student_view')); this.problem = new Problem($('.xblock-student_view'));
}); });
const testProgessData = function(problem, score, total_possible, attempts, graded, expected_progress_after_render) { const testProgessData = function(problem, score, total_possible, attempts, graded, expected_progress_after_render) {
...@@ -123,88 +122,88 @@ data-url='/problem/quiz/'> \ ...@@ -123,88 +122,88 @@ data-url='/problem/quiz/'> \
problem.el.data('graded', graded); problem.el.data('graded', graded);
expect(problem.$('.problem-progress').html()).toEqual(""); expect(problem.$('.problem-progress').html()).toEqual("");
problem.renderProgressState(); problem.renderProgressState();
return expect(problem.$('.problem-progress').html()).toEqual(expected_progress_after_render); expect(problem.$('.problem-progress').html()).toEqual(expected_progress_after_render);
}; };
describe('with a status of "none"', function() { describe('with a status of "none"', function() {
it('reports the number of points possible and graded', function() { it('reports the number of points possible and graded', function() {
return testProgessData(this.problem, 0, 1, 0, "True", "1 point possible (graded)"); testProgessData(this.problem, 0, 1, 0, "True", "1 point possible (graded)");
}); });
it('displays the number of points possible when rendering happens with the content', function() { it('displays the number of points possible when rendering happens with the content', function() {
return testProgessData(this.problem, 0, 2, 0, "True", "2 points possible (graded)"); testProgessData(this.problem, 0, 2, 0, "True", "2 points possible (graded)");
}); });
it('reports the number of points possible and ungraded', function() { it('reports the number of points possible and ungraded', function() {
return testProgessData(this.problem, 0, 1, 0, "False", "1 point possible (ungraded)"); testProgessData(this.problem, 0, 1, 0, "False", "1 point possible (ungraded)");
}); });
it('displays ungraded if number of points possible is 0', function() { it('displays ungraded if number of points possible is 0', function() {
return testProgessData(this.problem, 0, 0, 0, "False", "0 points possible (ungraded)"); testProgessData(this.problem, 0, 0, 0, "False", "0 points possible (ungraded)");
}); });
it('displays ungraded if number of points possible is 0, even if graded value is True', function() { it('displays ungraded if number of points possible is 0, even if graded value is True', function() {
return testProgessData(this.problem, 0, 0, 0, "True", "0 points possible (ungraded)"); testProgessData(this.problem, 0, 0, 0, "True", "0 points possible (ungraded)");
}); });
it('reports the correct score with status none and >0 attempts', function() { it('reports the correct score with status none and >0 attempts', function() {
return testProgessData(this.problem, 0, 1, 1, "True", "0/1 point (graded)"); testProgessData(this.problem, 0, 1, 1, "True", "0/1 point (graded)");
}); });
return it('reports the correct score with >1 weight, status none, and >0 attempts', function() { it('reports the correct score with >1 weight, status none, and >0 attempts', function() {
return testProgessData(this.problem, 0, 2, 2, "True", "0/2 points (graded)"); testProgessData(this.problem, 0, 2, 2, "True", "0/2 points (graded)");
}); });
}); });
describe('with any other valid status', function() { describe('with any other valid status', function() {
it('reports the current score', function() { it('reports the current score', function() {
return testProgessData(this.problem, 1, 1, 1, "True", "1/1 point (graded)"); testProgessData(this.problem, 1, 1, 1, "True", "1/1 point (graded)");
}); });
it('shows current score when rendering happens with the content', function() { it('shows current score when rendering happens with the content', function() {
return testProgessData(this.problem, 2, 2, 1, "True", "2/2 points (graded)"); testProgessData(this.problem, 2, 2, 1, "True", "2/2 points (graded)");
}); });
return it('reports the current score even if problem is ungraded', function() { it('reports the current score even if problem is ungraded', function() {
return testProgessData(this.problem, 1, 1, 1, "False", "1/1 point (ungraded)"); testProgessData(this.problem, 1, 1, 1, "False", "1/1 point (ungraded)");
}); });
}); });
describe('with valid status and string containing an integer like "0" for detail', () => describe('with valid status and string containing an integer like "0" for detail', () =>
// These tests are to address a failure specific to Chrome 51 and 52 + // These tests are to address a failure specific to Chrome 51 and 52 +
it('shows 0 points possible for the detail', function() { it('shows 0 points possible for the detail', function() {
return testProgessData(this.problem, 0, 0, 1, "False", "0 points possible (ungraded)"); testProgessData(this.problem, 0, 0, 1, "False", "0 points possible (ungraded)");
}) })
); );
return describe('with a score of null (show_correctness == false)', function() { describe('with a score of null (show_correctness == false)', function() {
it('reports the number of points possible and graded, results hidden', function() { it('reports the number of points possible and graded, results hidden', function() {
return testProgessData(this.problem, null, 1, 0, "True", "1 point possible (graded, results hidden)"); testProgessData(this.problem, null, 1, 0, "True", "1 point possible (graded, results hidden)");
}); });
it('reports the number of points possible (plural) and graded, results hidden', function() { it('reports the number of points possible (plural) and graded, results hidden', function() {
return testProgessData(this.problem, null, 2, 0, "True", "2 points possible (graded, results hidden)"); testProgessData(this.problem, null, 2, 0, "True", "2 points possible (graded, results hidden)");
}); });
it('reports the number of points possible and ungraded, results hidden', function() { it('reports the number of points possible and ungraded, results hidden', function() {
return testProgessData(this.problem, null, 1, 0, "False", "1 point possible (ungraded, results hidden)"); testProgessData(this.problem, null, 1, 0, "False", "1 point possible (ungraded, results hidden)");
}); });
it('displays ungraded if number of points possible is 0, results hidden', function() { it('displays ungraded if number of points possible is 0, results hidden', function() {
return testProgessData(this.problem, null, 0, 0, "False", "0 points possible (ungraded, results hidden)"); testProgessData(this.problem, null, 0, 0, "False", "0 points possible (ungraded, results hidden)");
}); });
it('displays ungraded if number of points possible is 0, even if graded value is True, results hidden', function() { it('displays ungraded if number of points possible is 0, even if graded value is True, results hidden', function() {
return testProgessData(this.problem, null, 0, 0, "True", "0 points possible (ungraded, results hidden)"); testProgessData(this.problem, null, 0, 0, "True", "0 points possible (ungraded, results hidden)");
}); });
it('reports the correct score with status none and >0 attempts, results hidden', function() { it('reports the correct score with status none and >0 attempts, results hidden', function() {
return testProgessData(this.problem, null, 1, 1, "True", "1 point possible (graded, results hidden)"); testProgessData(this.problem, null, 1, 1, "True", "1 point possible (graded, results hidden)");
}); });
return it('reports the correct score with >1 weight, status none, and >0 attempts, results hidden', function() { it('reports the correct score with >1 weight, status none, and >0 attempts, results hidden', function() {
return testProgessData(this.problem, null, 2, 2, "True", "2 points possible (graded, results hidden)"); testProgessData(this.problem, null, 2, 2, "True", "2 points possible (graded, results hidden)");
}); });
}); });
}); });
...@@ -213,35 +212,35 @@ data-url='/problem/quiz/'> \ ...@@ -213,35 +212,35 @@ data-url='/problem/quiz/'> \
beforeEach(function() { beforeEach(function() {
this.problem = new Problem($('.xblock-student_view')); this.problem = new Problem($('.xblock-student_view'));
this.bind = this.problem.bind; this.bind = this.problem.bind;
return spyOn(this.problem, 'bind'); spyOn(this.problem, 'bind');
}); });
describe('with content given', function() { describe('with content given', function() {
beforeEach(function() { beforeEach(function() {
return this.problem.render('Hello World'); this.problem.render('Hello World');
}); });
it('render the content', function() { it('render the content', function() {
return expect(this.problem.el.html()).toEqual('Hello World'); expect(this.problem.el.html()).toEqual('Hello World');
}); });
return it('re-bind the content', function() { it('re-bind the content', function() {
return expect(this.problem.bind).toHaveBeenCalled(); expect(this.problem.bind).toHaveBeenCalled();
}); });
}); });
return describe('with no content given', function() { describe('with no content given', function() {
beforeEach(function() { beforeEach(function() {
spyOn($, 'postWithPrefix').and.callFake((url, callback) => callback({html: "Hello World"})); spyOn($, 'postWithPrefix').and.callFake((url, callback) => callback({html: "Hello World"}));
return this.problem.render(); this.problem.render();
}); });
it('load the content via ajax', function() { it('load the content via ajax', function() {
return expect(this.problem.el.html()).toEqual('Hello World'); expect(this.problem.el.html()).toEqual('Hello World');
}); });
return it('re-bind the content', function() { it('re-bind the content', function() {
return expect(this.problem.bind).toHaveBeenCalled(); expect(this.problem.bind).toHaveBeenCalled();
}); });
}); });
}); });
...@@ -251,31 +250,32 @@ data-url='/problem/quiz/'> \ ...@@ -251,31 +250,32 @@ data-url='/problem/quiz/'> \
// Insert an input of type file outside of the problem. // Insert an input of type file outside of the problem.
$('.xblock-student_view').after('<input type="file" />'); $('.xblock-student_view').after('<input type="file" />');
this.problem = new Problem($('.xblock-student_view')); this.problem = new Problem($('.xblock-student_view'));
return spyOn(this.problem, 'submit'); spyOn(this.problem, 'submit');
}); });
return it('submit method is called if input of type file is not in problem', function() { it('submit method is called if input of type file is not in problem', function() {
this.problem.submit_fd(); this.problem.submit_fd();
return expect(this.problem.submit).toHaveBeenCalled(); expect(this.problem.submit).toHaveBeenCalled();
}); });
}); });
describe('submit', function() { describe('submit', function() {
beforeEach(function() { beforeEach(function() {
this.problem = new Problem($('.xblock-student_view')); this.problem = new Problem($('.xblock-student_view'));
return this.problem.answers = 'foo=1&bar=2'; this.problem.answers = 'foo=1&bar=2';
}); });
it('log the problem_check event', function() { it('log the problem_check event', function() {
spyOn($, 'postWithPrefix').and.callFake(function(url, answers, callback) { spyOn($, 'postWithPrefix').and.callFake(function(url, answers, callback) {
let promise; let promise;
return promise = { promise = {
always(callable) { return callable(); }, always(callable) { return callable(); },
done(callable) { return callable(); } done(callable) { return callable(); }
}; };
return promise;
}); });
this.problem.submit(); this.problem.submit();
return expect(Logger.log).toHaveBeenCalledWith('problem_check', 'foo=1&bar=2'); expect(Logger.log).toHaveBeenCalledWith('problem_check', 'foo=1&bar=2');
}); });
it('log the problem_graded event, after the problem is done grading.', function() { it('log the problem_graded event, after the problem is done grading.', function() {
...@@ -286,25 +286,27 @@ data-url='/problem/quiz/'> \ ...@@ -286,25 +286,27 @@ data-url='/problem/quiz/'> \
contents: 'mock grader response' contents: 'mock grader response'
}; };
callback(response); callback(response);
return promise = { promise = {
always(callable) { return callable(); }, always(callable) { return callable(); },
done(callable) { return callable(); } done(callable) { return callable(); }
}; };
return promise;
}); });
this.problem.submit(); this.problem.submit();
return expect(Logger.log).toHaveBeenCalledWith('problem_graded', ['foo=1&bar=2', 'mock grader response'], this.problem.id); expect(Logger.log).toHaveBeenCalledWith('problem_graded', ['foo=1&bar=2', 'mock grader response'], this.problem.id);
}); });
it('submit the answer for submit', function() { it('submit the answer for submit', function() {
spyOn($, 'postWithPrefix').and.callFake(function(url, answers, callback) { spyOn($, 'postWithPrefix').and.callFake(function(url, answers, callback) {
let promise; let promise;
return promise = { promise = {
always(callable) { return callable(); }, always(callable) { return callable(); },
done(callable) { return callable(); } done(callable) { return callable(); }
}; };
return promise;
}); });
this.problem.submit(); this.problem.submit();
return expect($.postWithPrefix).toHaveBeenCalledWith('/problem/Problem1/problem_check', expect($.postWithPrefix).toHaveBeenCalledWith('/problem/Problem1/problem_check',
'foo=1&bar=2', jasmine.any(Function)); 'foo=1&bar=2', jasmine.any(Function));
}); });
...@@ -315,14 +317,15 @@ data-url='/problem/quiz/'> \ ...@@ -315,14 +317,15 @@ data-url='/problem/quiz/'> \
spyOn($, 'postWithPrefix').and.callFake(function(url, answers, callback) { spyOn($, 'postWithPrefix').and.callFake(function(url, answers, callback) {
let promise; let promise;
callback({success: 'correct', contents}); callback({success: 'correct', contents});
return promise = { promise = {
always(callable) { return callable(); }, always(callable) { return callable(); },
done(callable) { return callable(); } done(callable) { return callable(); }
}; };
return promise;
}); });
this.problem.submit(); this.problem.submit();
expect(this.problem.el).toHaveHtml(contents); expect(this.problem.el).toHaveHtml(contents);
return expect(window.SR.readTexts).toHaveBeenCalledWith(['Question 1: excellent', 'Question 2: correct']); expect(window.SR.readTexts).toHaveBeenCalledWith(['Question 1: excellent', 'Question 2: correct']);
}) })
); );
...@@ -332,18 +335,19 @@ data-url='/problem/quiz/'> \ ...@@ -332,18 +335,19 @@ data-url='/problem/quiz/'> \
spyOn($, 'postWithPrefix').and.callFake(function(url, answers, callback) { spyOn($, 'postWithPrefix').and.callFake(function(url, answers, callback) {
let promise; let promise;
callback({success: 'incorrect', contents}); callback({success: 'incorrect', contents});
return promise = { promise = {
always(callable) { return callable(); }, always(callable) { return callable(); },
done(callable) { return callable(); } done(callable) { return callable(); }
}; };
return promise;
}); });
this.problem.submit(); this.problem.submit();
expect(this.problem.el).toHaveHtml(contents); expect(this.problem.el).toHaveHtml(contents);
return expect(window.SR.readTexts).toHaveBeenCalledWith(['no, try again']); expect(window.SR.readTexts).toHaveBeenCalledWith(['no, try again']);
}) })
); );
return it('tests if the submit button is disabled while submitting and the text changes on the button', function() { it('tests if the submit button is disabled while submitting and the text changes on the button', function() {
const self = this; const self = this;
const curr_html = this.problem.el.html(); const curr_html = this.problem.el.html();
spyOn($, 'postWithPrefix').and.callFake(function(url, answers, callback) { spyOn($, 'postWithPrefix').and.callFake(function(url, answers, callback) {
...@@ -355,10 +359,11 @@ data-url='/problem/quiz/'> \ ...@@ -355,10 +359,11 @@ data-url='/problem/quiz/'> \
success: 'incorrect', // does not matter if correct or incorrect here success: 'incorrect', // does not matter if correct or incorrect here
contents: curr_html contents: curr_html
}); });
return promise = { promise = {
always(callable) { return callable(); }, always(callable) { return callable(); },
done(callable) { return callable(); } done(callable) { return callable(); }
}; };
return promise;
}); });
// Make sure the submit button is enabled before submitting // Make sure the submit button is enabled before submitting
$('#input_example_1').val('test').trigger('input'); $('#input_example_1').val('test').trigger('input');
...@@ -366,7 +371,7 @@ data-url='/problem/quiz/'> \ ...@@ -366,7 +371,7 @@ data-url='/problem/quiz/'> \
this.problem.submit(); this.problem.submit();
// After submit, the button should not be disabled and should have text as 'Submit' // After submit, the button should not be disabled and should have text as 'Submit'
expect(this.problem.submitButtonLabel.text()).toBe('Submit'); expect(this.problem.submitButtonLabel.text()).toBe('Submit');
return expect(this.problem.submitButton).not.toHaveAttr('disabled'); expect(this.problem.submitButton).not.toHaveAttr('disabled');
}); });
}); });
...@@ -374,11 +379,11 @@ data-url='/problem/quiz/'> \ ...@@ -374,11 +379,11 @@ data-url='/problem/quiz/'> \
beforeEach(function() { beforeEach(function() {
this.problem = new Problem($('.xblock-student_view')); this.problem = new Problem($('.xblock-student_view'));
return this.submitDisabled = disabled => { this.submitDisabled = disabled => {
if (disabled) { if (disabled) {
return expect(this.problem.submitButton).toHaveAttr('disabled'); expect(this.problem.submitButton).toHaveAttr('disabled');
} else { } else {
return expect(this.problem.submitButton).not.toHaveAttr('disabled'); expect(this.problem.submitButton).not.toHaveAttr('disabled');
} }
}; };
}); });
...@@ -388,11 +393,11 @@ data-url='/problem/quiz/'> \ ...@@ -388,11 +393,11 @@ data-url='/problem/quiz/'> \
$('#input_example_1').val('test').trigger('input'); $('#input_example_1').val('test').trigger('input');
this.submitDisabled(false); this.submitDisabled(false);
$('#input_example_1').val('').trigger('input'); $('#input_example_1').val('').trigger('input');
return this.submitDisabled(true); this.submitDisabled(true);
}) })
); );
return describe('some advanced tests for submit button', function() { describe('some advanced tests for submit button', function() {
const radioButtonProblemHtml = readFixtures('radiobutton_problem.html'); const radioButtonProblemHtml = readFixtures('radiobutton_problem.html');
const checkboxProblemHtml = readFixtures('checkbox_problem.html'); const checkboxProblemHtml = readFixtures('checkbox_problem.html');
...@@ -403,7 +408,7 @@ data-url='/problem/quiz/'> \ ...@@ -403,7 +408,7 @@ data-url='/problem/quiz/'> \
$('#input_1_1_1').click(); $('#input_1_1_1').click();
this.submitDisabled(false); this.submitDisabled(false);
$('#input_1_1_1').click(); $('#input_1_1_1').click();
return this.submitDisabled(true); this.submitDisabled(true);
}); });
it('should become enabled after a radiobutton is checked', function() { it('should become enabled after a radiobutton is checked', function() {
...@@ -413,7 +418,7 @@ data-url='/problem/quiz/'> \ ...@@ -413,7 +418,7 @@ data-url='/problem/quiz/'> \
$('#input_1_1_1').attr('checked', true).trigger('click'); $('#input_1_1_1').attr('checked', true).trigger('click');
this.submitDisabled(false); this.submitDisabled(false);
$('#input_1_1_1').attr('checked', false).trigger('click'); $('#input_1_1_1').attr('checked', false).trigger('click');
return this.submitDisabled(true); this.submitDisabled(true);
}); });
it('should become enabled after a value is selected in a selector', function() { it('should become enabled after a value is selected in a selector', function() {
...@@ -432,7 +437,7 @@ data-url='/problem/quiz/'> \ ...@@ -432,7 +437,7 @@ data-url='/problem/quiz/'> \
$("#problem_sel select").val("val2").trigger('change'); $("#problem_sel select").val("val2").trigger('change');
this.submitDisabled(false); this.submitDisabled(false);
$("#problem_sel select").val("val0").trigger('change'); $("#problem_sel select").val("val0").trigger('change');
return this.submitDisabled(true); this.submitDisabled(true);
}); });
it('should become enabled after a radiobutton is checked and a value is entered into the text box', function() { it('should become enabled after a radiobutton is checked and a value is entered into the text box', function() {
...@@ -444,44 +449,46 @@ data-url='/problem/quiz/'> \ ...@@ -444,44 +449,46 @@ data-url='/problem/quiz/'> \
$('#input_example_1').val('111').trigger('input'); $('#input_example_1').val('111').trigger('input');
this.submitDisabled(false); this.submitDisabled(false);
$('#input_1_1_1').attr('checked', false).trigger('click'); $('#input_1_1_1').attr('checked', false).trigger('click');
return this.submitDisabled(true); this.submitDisabled(true);
}); });
return it('should become enabled if there are only hidden input fields', function() { it('should become enabled if there are only hidden input fields', function() {
const html = `\ const html = `\
<input type="text" name="test" id="test" aria-describedby="answer_test" value="" style="display:none;">\ <input type="text" name="test" id="test" aria-describedby="answer_test" value="" style="display:none;">\
`; `;
$('#input_example_1').replaceWith(html); $('#input_example_1').replaceWith(html);
this.problem.submitAnswersAndSubmitButton(true); this.problem.submitAnswersAndSubmitButton(true);
return this.submitDisabled(false); this.submitDisabled(false);
}); });
}); });
}); });
describe('reset', function() { describe('reset', function() {
beforeEach(function() { beforeEach(function() {
return this.problem = new Problem($('.xblock-student_view')); this.problem = new Problem($('.xblock-student_view'));
}); });
it('log the problem_reset event', function() { it('log the problem_reset event', function() {
spyOn($, 'postWithPrefix').and.callFake(function(url, answers, callback) { spyOn($, 'postWithPrefix').and.callFake(function(url, answers, callback) {
let promise; let promise;
return promise = promise =
{always(callable) { return callable(); }}; {always(callable) { return callable(); }};
return promise;
}); });
this.problem.answers = 'foo=1&bar=2'; this.problem.answers = 'foo=1&bar=2';
this.problem.reset(); this.problem.reset();
return expect(Logger.log).toHaveBeenCalledWith('problem_reset', 'foo=1&bar=2'); expect(Logger.log).toHaveBeenCalledWith('problem_reset', 'foo=1&bar=2');
}); });
it('POST to the problem reset page', function() { it('POST to the problem reset page', function() {
spyOn($, 'postWithPrefix').and.callFake(function(url, answers, callback) { spyOn($, 'postWithPrefix').and.callFake(function(url, answers, callback) {
let promise; let promise;
return promise = promise =
{always(callable) { return callable(); }}; {always(callable) { return callable(); }};
return promise;
}); });
this.problem.reset(); this.problem.reset();
return expect($.postWithPrefix).toHaveBeenCalledWith('/problem/Problem1/problem_reset', expect($.postWithPrefix).toHaveBeenCalledWith('/problem/Problem1/problem_reset',
{ id: 'i4x://edX/101/problem/Problem1' }, jasmine.any(Function)); { id: 'i4x://edX/101/problem/Problem1' }, jasmine.any(Function));
}); });
...@@ -489,36 +496,39 @@ data-url='/problem/quiz/'> \ ...@@ -489,36 +496,39 @@ data-url='/problem/quiz/'> \
spyOn($, 'postWithPrefix').and.callFake(function(url, answers, callback) { spyOn($, 'postWithPrefix').and.callFake(function(url, answers, callback) {
let promise; let promise;
callback({html: "Reset", success: true}); callback({html: "Reset", success: true});
return promise = promise =
{always(callable) { return callable(); }}; {always(callable) { return callable(); }};
return promise;
}); });
this.problem.reset(); this.problem.reset();
return expect(this.problem.el.html()).toEqual('Reset'); expect(this.problem.el.html()).toEqual('Reset');
}); });
it('sends a message to the window SR element', function() { it('sends a message to the window SR element', function() {
spyOn($, 'postWithPrefix').and.callFake(function(url, answers, callback) { spyOn($, 'postWithPrefix').and.callFake(function(url, answers, callback) {
let promise; let promise;
callback({html: "Reset", success: true}); callback({html: "Reset", success: true});
return promise = promise =
{always(callable) { return callable(); }}; {always(callable) { return callable(); }};
return promise;
}); });
this.problem.reset(); this.problem.reset();
return expect(window.SR.readText).toHaveBeenCalledWith('This problem has been reset.'); expect(window.SR.readText).toHaveBeenCalledWith('This problem has been reset.');
}); });
it('shows a notification on error', function() { it('shows a notification on error', function() {
spyOn($, 'postWithPrefix').and.callFake(function(url, answers, callback) { spyOn($, 'postWithPrefix').and.callFake(function(url, answers, callback) {
let promise; let promise;
callback({msg: "Error on reset.", success: false}); callback({msg: "Error on reset.", success: false});
return promise = promise =
{always(callable) { return callable(); }}; {always(callable) { return callable(); }};
return promise;
}); });
this.problem.reset(); this.problem.reset();
return expect($('.notification-gentle-alert .notification-message').text()).toEqual("Error on reset."); expect($('.notification-gentle-alert .notification-message').text()).toEqual("Error on reset.");
}); });
return it('tests that reset does not enable submit or modify the text while resetting', function() { it('tests that reset does not enable submit or modify the text while resetting', function() {
const self = this; const self = this;
const curr_html = this.problem.el.html(); const curr_html = this.problem.el.html();
spyOn($, 'postWithPrefix').and.callFake(function(url, answers, callback) { spyOn($, 'postWithPrefix').and.callFake(function(url, answers, callback) {
...@@ -527,39 +537,40 @@ data-url='/problem/quiz/'> \ ...@@ -527,39 +537,40 @@ data-url='/problem/quiz/'> \
expect(self.problem.submitButton).toHaveAttr('disabled'); expect(self.problem.submitButton).toHaveAttr('disabled');
expect(self.problem.submitButtonLabel.text()).toBe('Submit'); expect(self.problem.submitButtonLabel.text()).toBe('Submit');
callback({success: 'correct', html: curr_html}); callback({success: 'correct', html: curr_html});
return promise = promise =
{always(callable) { return callable(); }}; {always(callable) { return callable(); }};
return promise;
}); });
// Submit should be disabled // Submit should be disabled
expect(this.problem.submitButton).toHaveAttr('disabled'); expect(this.problem.submitButton).toHaveAttr('disabled');
this.problem.reset(); this.problem.reset();
// Submit should remain disabled // Submit should remain disabled
expect(self.problem.submitButton).toHaveAttr('disabled'); expect(self.problem.submitButton).toHaveAttr('disabled');
return expect(self.problem.submitButtonLabel.text()).toBe('Submit'); expect(self.problem.submitButtonLabel.text()).toBe('Submit');
}); });
}); });
describe('show', function() { describe('show', function() {
beforeEach(function() { beforeEach(function() {
this.problem = new Problem($('.xblock-student_view')); this.problem = new Problem($('.xblock-student_view'));
return this.problem.el.prepend('<div id="answer_1_1" /><div id="answer_1_2" />'); this.problem.el.prepend('<div id="answer_1_1" /><div id="answer_1_2" />');
}); });
return describe('when the answer has not yet shown', function() { describe('when the answer has not yet shown', function() {
beforeEach(function() { beforeEach(function() {
return expect(this.problem.el.find('.show').attr('disabled')).not.toEqual('disabled'); expect(this.problem.el.find('.show').attr('disabled')).not.toEqual('disabled');
}); });
it('log the problem_show event', function() { it('log the problem_show event', function() {
this.problem.show(); this.problem.show();
return expect(Logger.log).toHaveBeenCalledWith('problem_show', expect(Logger.log).toHaveBeenCalledWith('problem_show',
{problem: 'i4x://edX/101/problem/Problem1'}); {problem: 'i4x://edX/101/problem/Problem1'});
}); });
it('fetch the answers', function() { it('fetch the answers', function() {
spyOn($, 'postWithPrefix'); spyOn($, 'postWithPrefix');
this.problem.show(); this.problem.show();
return expect($.postWithPrefix).toHaveBeenCalledWith('/problem/Problem1/problem_show', expect($.postWithPrefix).toHaveBeenCalledWith('/problem/Problem1/problem_show',
jasmine.any(Function)); jasmine.any(Function));
}); });
...@@ -567,13 +578,13 @@ data-url='/problem/quiz/'> \ ...@@ -567,13 +578,13 @@ data-url='/problem/quiz/'> \
spyOn($, 'postWithPrefix').and.callFake((url, callback) => callback({answers: {'1_1': 'One', '1_2': 'Two'}})); spyOn($, 'postWithPrefix').and.callFake((url, callback) => callback({answers: {'1_1': 'One', '1_2': 'Two'}}));
this.problem.show(); this.problem.show();
expect($('#answer_1_1')).toHaveHtml('One'); expect($('#answer_1_1')).toHaveHtml('One');
return expect($('#answer_1_2')).toHaveHtml('Two'); expect($('#answer_1_2')).toHaveHtml('Two');
}); });
it('disables the show answer button', function() { it('disables the show answer button', function() {
spyOn($, 'postWithPrefix').and.callFake((url, callback) => callback({answers: {}})); spyOn($, 'postWithPrefix').and.callFake((url, callback) => callback({answers: {}}));
this.problem.show(); this.problem.show();
return expect(this.problem.el.find('.show').attr('disabled')).toEqual('disabled'); expect(this.problem.el.find('.show').attr('disabled')).toEqual('disabled');
}); });
describe('radio text question', function() { describe('radio text question', function() {
...@@ -606,7 +617,7 @@ data-url='/problem/quiz/'> \ ...@@ -606,7 +617,7 @@ data-url='/problem/quiz/'> \
`; `;
beforeEach(function() { beforeEach(function() {
// Append a radiotextresponse problem to the problem, so we can check it's javascript functionality // Append a radiotextresponse problem to the problem, so we can check it's javascript functionality
return this.problem.el.prepend(radio_text_xml); this.problem.el.prepend(radio_text_xml);
}); });
it('sets the correct class on the section for the correct choice', function() { it('sets the correct class on the section for the correct choice', function() {
...@@ -617,20 +628,20 @@ data-url='/problem/quiz/'> \ ...@@ -617,20 +628,20 @@ data-url='/problem/quiz/'> \
'choicetextgroup_show_correct'); 'choicetextgroup_show_correct');
expect($('#answer_1_2_1_choiceinput_0bc').text()).toEqual('3'); expect($('#answer_1_2_1_choiceinput_0bc').text()).toEqual('3');
expect($('#answer_1_2_1_choiceinput_1bc').text()).toEqual(''); expect($('#answer_1_2_1_choiceinput_1bc').text()).toEqual('');
return expect($('#answer_1_2_1_choiceinput_2bc').text()).toEqual(''); expect($('#answer_1_2_1_choiceinput_2bc').text()).toEqual('');
}); });
return it('Should not disable input fields', function() { it('Should not disable input fields', function() {
spyOn($, 'postWithPrefix').and.callFake((url, callback) => callback({answers: {"1_2_1": ["1_2_1_choiceinput_0bc"], "1_2_1_choiceinput_0bc": "3"}})); spyOn($, 'postWithPrefix').and.callFake((url, callback) => callback({answers: {"1_2_1": ["1_2_1_choiceinput_0bc"], "1_2_1_choiceinput_0bc": "3"}}));
this.problem.show(); this.problem.show();
expect($('input#1_2_1_choiceinput_0bc').attr('disabled')).not.toEqual('disabled'); expect($('input#1_2_1_choiceinput_0bc').attr('disabled')).not.toEqual('disabled');
expect($('input#1_2_1_choiceinput_1bc').attr('disabled')).not.toEqual('disabled'); expect($('input#1_2_1_choiceinput_1bc').attr('disabled')).not.toEqual('disabled');
expect($('input#1_2_1_choiceinput_2bc').attr('disabled')).not.toEqual('disabled'); expect($('input#1_2_1_choiceinput_2bc').attr('disabled')).not.toEqual('disabled');
return expect($('input#1_2_1').attr('disabled')).not.toEqual('disabled'); expect($('input#1_2_1').attr('disabled')).not.toEqual('disabled');
}); });
}); });
return describe('imageinput', function() { describe('imageinput', function() {
let el, height, width; let el, height, width;
const imageinput_html = readFixtures('imageinput.underscore'); const imageinput_html = readFixtures('imageinput.underscore');
...@@ -642,22 +653,22 @@ data-url='/problem/quiz/'> \ ...@@ -642,22 +653,22 @@ data-url='/problem/quiz/'> \
beforeEach(function() { beforeEach(function() {
this.problem = new Problem($('.xblock-student_view')); this.problem = new Problem($('.xblock-student_view'));
return this.problem.el.prepend(_.template(imageinput_html)(DEFAULTS)); this.problem.el.prepend(_.template(imageinput_html)(DEFAULTS));
}); });
const assertAnswer = (problem, data) => { const assertAnswer = (problem, data) => {
stubRequest(data); stubRequest(data);
problem.show(); problem.show();
return $.each(data['answers'], (id, answer) => { $.each(data['answers'], (id, answer) => {
const img = getImage(answer); const img = getImage(answer);
el = $(`#inputtype_${id}`); el = $(`#inputtype_${id}`);
return expect(img).toImageDiffEqual(el.find('canvas')[0]); expect(img).toImageDiffEqual(el.find('canvas')[0]);
}); });
}; };
var stubRequest = data => { var stubRequest = data => {
return spyOn($, 'postWithPrefix').and.callFake((url, callback) => callback(data)); spyOn($, 'postWithPrefix').and.callFake((url, callback) => callback(data));
}; };
var getImage = (coords, c_width, c_height) => { var getImage = (coords, c_width, c_height) => {
...@@ -679,7 +690,7 @@ data-url='/problem/quiz/'> \ ...@@ -679,7 +690,7 @@ data-url='/problem/quiz/'> \
}); });
ctx.stroke(); ctx.stroke();
return ctx.fill(); ctx.fill();
}, },
regions: coords => { regions: coords => {
...@@ -705,7 +716,7 @@ data-url='/problem/quiz/'> \ ...@@ -705,7 +716,7 @@ data-url='/problem/quiz/'> \
ctx.closePath(); ctx.closePath();
ctx.stroke(); ctx.stroke();
return ctx.fill(); ctx.fill();
}); });
} }
}; };
...@@ -717,7 +728,7 @@ data-url='/problem/quiz/'> \ ...@@ -717,7 +728,7 @@ data-url='/problem/quiz/'> \
if (canvas.getContext) { if (canvas.getContext) {
ctx = canvas.getContext('2d'); ctx = canvas.getContext('2d');
} else { } else {
return console.log('Canvas is not supported.'); console.log('Canvas is not supported.');
} }
ctx.fillStyle = 'rgba(255,255,255,.3)'; ctx.fillStyle = 'rgba(255,255,255,.3)';
...@@ -732,7 +743,7 @@ data-url='/problem/quiz/'> \ ...@@ -732,7 +743,7 @@ data-url='/problem/quiz/'> \
}; };
it('rectangle is drawn correctly', function() { it('rectangle is drawn correctly', function() {
return assertAnswer(this.problem, { assertAnswer(this.problem, {
'answers': { 'answers': {
'12345': { '12345': {
'rectangle': '(10,10)-(30,30)', 'rectangle': '(10,10)-(30,30)',
...@@ -743,7 +754,7 @@ data-url='/problem/quiz/'> \ ...@@ -743,7 +754,7 @@ data-url='/problem/quiz/'> \
}); });
it('region is drawn correctly', function() { it('region is drawn correctly', function() {
return assertAnswer(this.problem, { assertAnswer(this.problem, {
'answers': { 'answers': {
'12345': { '12345': {
'rectangle': null, 'rectangle': null,
...@@ -754,7 +765,7 @@ data-url='/problem/quiz/'> \ ...@@ -754,7 +765,7 @@ data-url='/problem/quiz/'> \
}); });
it('mixed shapes are drawn correctly', function() { it('mixed shapes are drawn correctly', function() {
return assertAnswer(this.problem, { assertAnswer(this.problem, {
'answers': {'12345': { 'answers': {'12345': {
'rectangle': '(10,10)-(30,30);(5,5)-(20,20)', 'rectangle': '(10,10)-(30,30);(5,5)-(20,20)',
'regions': `[ 'regions': `[
...@@ -774,7 +785,7 @@ data-url='/problem/quiz/'> \ ...@@ -774,7 +785,7 @@ data-url='/problem/quiz/'> \
}; };
this.problem.el.prepend(_.template(imageinput_html)(data)); this.problem.el.prepend(_.template(imageinput_html)(data));
return assertAnswer(this.problem, { assertAnswer(this.problem, {
'answers': { 'answers': {
'12345': { '12345': {
'rectangle': null, 'rectangle': null,
...@@ -788,13 +799,13 @@ data-url='/problem/quiz/'> \ ...@@ -788,13 +799,13 @@ data-url='/problem/quiz/'> \
}); });
}); });
return it('dictionary with answers doesn\'t contain answer for current id', function() { it('dictionary with answers doesn\'t contain answer for current id', function() {
spyOn(console, 'log'); spyOn(console, 'log');
stubRequest({'answers':{}}); stubRequest({'answers':{}});
this.problem.show(); this.problem.show();
el = $('#inputtype_12345'); el = $('#inputtype_12345');
expect(el.find('canvas')).not.toExist(); expect(el.find('canvas')).not.toExist();
return expect(console.log).toHaveBeenCalledWith('Answer is absent for image input with id=12345'); expect(console.log).toHaveBeenCalledWith('Answer is absent for image input with id=12345');
}); });
}); });
}); });
...@@ -803,27 +814,29 @@ data-url='/problem/quiz/'> \ ...@@ -803,27 +814,29 @@ data-url='/problem/quiz/'> \
describe('save', function() { describe('save', function() {
beforeEach(function() { beforeEach(function() {
this.problem = new Problem($('.xblock-student_view')); this.problem = new Problem($('.xblock-student_view'));
return this.problem.answers = 'foo=1&bar=2'; this.problem.answers = 'foo=1&bar=2';
}); });
it('log the problem_save event', function() { it('log the problem_save event', function() {
spyOn($, 'postWithPrefix').and.callFake(function(url, answers, callback) { spyOn($, 'postWithPrefix').and.callFake(function(url, answers, callback) {
let promise; let promise;
return promise = promise =
{always(callable) { return callable(); }}; {always(callable) { return callable(); }};
return promise;
}); });
this.problem.save(); this.problem.save();
return expect(Logger.log).toHaveBeenCalledWith('problem_save', 'foo=1&bar=2'); expect(Logger.log).toHaveBeenCalledWith('problem_save', 'foo=1&bar=2');
}); });
it('POST to save problem', function() { it('POST to save problem', function() {
spyOn($, 'postWithPrefix').and.callFake(function(url, answers, callback) { spyOn($, 'postWithPrefix').and.callFake(function(url, answers, callback) {
let promise; let promise;
return promise = promise =
{always(callable) { return callable(); }}; {always(callable) { return callable(); }};
return promise;
}); });
this.problem.save(); this.problem.save();
return expect($.postWithPrefix).toHaveBeenCalledWith('/problem/Problem1/problem_save', expect($.postWithPrefix).toHaveBeenCalledWith('/problem/Problem1/problem_save',
'foo=1&bar=2', jasmine.any(Function)); 'foo=1&bar=2', jasmine.any(Function));
}); });
...@@ -836,8 +849,9 @@ data-url='/problem/quiz/'> \ ...@@ -836,8 +849,9 @@ data-url='/problem/quiz/'> \
expect(self.problem.submitButton).toHaveAttr('disabled'); expect(self.problem.submitButton).toHaveAttr('disabled');
expect(self.problem.submitButtonLabel.text()).toBe('Submit'); expect(self.problem.submitButtonLabel.text()).toBe('Submit');
callback({success: 'correct', html: curr_html}); callback({success: 'correct', html: curr_html});
return promise = promise =
{always(callable) { return callable(); }}; {always(callable) { return callable(); }};
return promise;
}); });
// Expect submit to be disabled and labeled properly at the start // Expect submit to be disabled and labeled properly at the start
expect(this.problem.submitButton).toHaveAttr('disabled'); expect(this.problem.submitButton).toHaveAttr('disabled');
...@@ -845,10 +859,10 @@ data-url='/problem/quiz/'> \ ...@@ -845,10 +859,10 @@ data-url='/problem/quiz/'> \
this.problem.save(); this.problem.save();
// Submit button should have the same state after save has completed // Submit button should have the same state after save has completed
expect(this.problem.submitButton).toHaveAttr('disabled'); expect(this.problem.submitButton).toHaveAttr('disabled');
return expect(this.problem.submitButtonLabel.text()).toBe('Submit'); expect(this.problem.submitButtonLabel.text()).toBe('Submit');
}); });
return it('tests that save does not disable the submit button or change the text when submit is originally enabled', function() { it('tests that save does not disable the submit button or change the text when submit is originally enabled', function() {
const self = this; const self = this;
const curr_html = this.problem.el.html(); const curr_html = this.problem.el.html();
spyOn($, 'postWithPrefix').and.callFake(function(url, answers, callback) { spyOn($, 'postWithPrefix').and.callFake(function(url, answers, callback) {
...@@ -857,8 +871,9 @@ data-url='/problem/quiz/'> \ ...@@ -857,8 +871,9 @@ data-url='/problem/quiz/'> \
expect(self.problem.submitButton).toHaveAttr('disabled'); expect(self.problem.submitButton).toHaveAttr('disabled');
expect(self.problem.submitButtonLabel.text()).toBe('Submit'); expect(self.problem.submitButtonLabel.text()).toBe('Submit');
callback({success: 'correct', html: curr_html}); callback({success: 'correct', html: curr_html});
return promise = promise =
{always(callable) { return callable(); }}; {always(callable) { return callable(); }};
return promise;
}); });
// Expect submit to be enabled and labeled properly at the start after adding an input // Expect submit to be enabled and labeled properly at the start after adding an input
$('#input_example_1').val('test').trigger('input'); $('#input_example_1').val('test').trigger('input');
...@@ -867,7 +882,7 @@ data-url='/problem/quiz/'> \ ...@@ -867,7 +882,7 @@ data-url='/problem/quiz/'> \
this.problem.save(); this.problem.save();
// Submit button should have the same state after save has completed // Submit button should have the same state after save has completed
expect(this.problem.submitButton).not.toHaveAttr('disabled'); expect(this.problem.submitButton).not.toHaveAttr('disabled');
return expect(this.problem.submitButtonLabel.text()).toBe('Submit'); expect(this.problem.submitButtonLabel.text()).toBe('Submit');
}); });
}); });
...@@ -875,11 +890,11 @@ data-url='/problem/quiz/'> \ ...@@ -875,11 +890,11 @@ data-url='/problem/quiz/'> \
beforeEach(function() { beforeEach(function() {
this.problem = new Problem($('.xblock-student_view')); this.problem = new Problem($('.xblock-student_view'));
$('#input_example_1').val('E=mc^2'); $('#input_example_1').val('E=mc^2');
return this.problem.refreshMath({target: $('#input_example_1').get(0)}); this.problem.refreshMath({target: $('#input_example_1').get(0)});
}); });
return it('should queue the conversion and MathML element update', function() { it('should queue the conversion and MathML element update', function() {
return expect(MathJax.Hub.Queue).toHaveBeenCalledWith(['Text', this.stubbedJax, 'E=mc^2'], expect(MathJax.Hub.Queue).toHaveBeenCalledWith(['Text', this.stubbedJax, 'E=mc^2'],
[this.problem.updateMathML, this.stubbedJax, $('#input_example_1').get(0)]); [this.problem.updateMathML, this.stubbedJax, $('#input_example_1').get(0)]);
}); });
}); });
...@@ -887,27 +902,27 @@ data-url='/problem/quiz/'> \ ...@@ -887,27 +902,27 @@ data-url='/problem/quiz/'> \
describe('updateMathML', function() { describe('updateMathML', function() {
beforeEach(function() { beforeEach(function() {
this.problem = new Problem($('.xblock-student_view')); this.problem = new Problem($('.xblock-student_view'));
return this.stubbedJax.root.toMathML.and.returnValue('<MathML>'); this.stubbedJax.root.toMathML.and.returnValue('<MathML>');
}); });
describe('when there is no exception', function() { describe('when there is no exception', function() {
beforeEach(function() { beforeEach(function() {
return this.problem.updateMathML(this.stubbedJax, $('#input_example_1').get(0)); this.problem.updateMathML(this.stubbedJax, $('#input_example_1').get(0));
}); });
return it('convert jax to MathML', () => expect($('#input_example_1_dynamath')).toHaveValue('<MathML>')); it('convert jax to MathML', () => expect($('#input_example_1_dynamath')).toHaveValue('<MathML>'));
}); });
return describe('when there is an exception', function() { describe('when there is an exception', function() {
beforeEach(function() { beforeEach(function() {
const error = new Error(); const error = new Error();
error.restart = true; error.restart = true;
this.stubbedJax.root.toMathML.and.throwError(error); this.stubbedJax.root.toMathML.and.throwError(error);
return this.problem.updateMathML(this.stubbedJax, $('#input_example_1').get(0)); this.problem.updateMathML(this.stubbedJax, $('#input_example_1').get(0));
}); });
return it('should queue up the exception', function() { it('should queue up the exception', function() {
return expect(MathJax.Callback.After).toHaveBeenCalledWith([this.problem.refreshMath, this.stubbedJax], true); expect(MathJax.Callback.After).toHaveBeenCalledWith([this.problem.refreshMath, this.stubbedJax], true);
}); });
}); });
}); });
...@@ -925,17 +940,17 @@ data-url='/problem/quiz/'> \ ...@@ -925,17 +940,17 @@ data-url='/problem/quiz/'> \
this.stubSchematic = { update_value: jasmine.createSpy('schematic') }; this.stubSchematic = { update_value: jasmine.createSpy('schematic') };
this.stubCodeMirror = { save: jasmine.createSpy('CodeMirror') }; this.stubCodeMirror = { save: jasmine.createSpy('CodeMirror') };
$('input.schematic').get(0).schematic = this.stubSchematic; $('input.schematic').get(0).schematic = this.stubSchematic;
return $('textarea.CodeMirror').get(0).CodeMirror = this.stubCodeMirror; $('textarea.CodeMirror').get(0).CodeMirror = this.stubCodeMirror;
}); });
it('update each schematic', function() { it('update each schematic', function() {
this.problem.refreshAnswers(); this.problem.refreshAnswers();
return expect(this.stubSchematic.update_value).toHaveBeenCalled(); expect(this.stubSchematic.update_value).toHaveBeenCalled();
}); });
return it('update each code block', function() { it('update each code block', function() {
this.problem.refreshAnswers(); this.problem.refreshAnswers();
return expect(this.stubCodeMirror.save).toHaveBeenCalled(); expect(this.stubCodeMirror.save).toHaveBeenCalled();
}); });
}); });
...@@ -944,12 +959,12 @@ data-url='/problem/quiz/'> \ ...@@ -944,12 +959,12 @@ data-url='/problem/quiz/'> \
beforeEach(function() { beforeEach(function() {
this.problem = new Problem($('.xblock-student_view')); this.problem = new Problem($('.xblock-student_view'));
return this.problem.render(jsinput_html); this.problem.render(jsinput_html);
}); });
return it('submit_save_waitfor should return false', function() { it('submit_save_waitfor should return false', function() {
$(this.problem.inputs[0]).data('waitfor', function() {}); $(this.problem.inputs[0]).data('waitfor', function() {});
return expect(this.problem.submit_save_waitfor()).toEqual(false); expect(this.problem.submit_save_waitfor()).toEqual(false);
}); });
}); });
...@@ -961,12 +976,12 @@ data-url='/problem/quiz/'> \ ...@@ -961,12 +976,12 @@ data-url='/problem/quiz/'> \
jasmine.clock().install(); jasmine.clock().install();
this.problem = new Problem($('.xblock-student_view')); this.problem = new Problem($('.xblock-student_view'));
spyOn(this.problem, 'poll').and.callThrough(); spyOn(this.problem, 'poll').and.callThrough();
return this.problem.render(matlabinput_html); this.problem.render(matlabinput_html);
}); });
afterEach(() => jasmine.clock().uninstall()); afterEach(() => jasmine.clock().uninstall());
return it('check that we stop polling after a fixed amount of time', function() { it('check that we stop polling after a fixed amount of time', function() {
expect(this.problem.poll).not.toHaveBeenCalled(); expect(this.problem.poll).not.toHaveBeenCalled();
jasmine.clock().tick(1); jasmine.clock().tick(1);
const time_steps = [1000, 2000, 4000, 8000, 16000, 32000]; const time_steps = [1000, 2000, 4000, 8000, 16000, 32000];
...@@ -975,7 +990,7 @@ data-url='/problem/quiz/'> \ ...@@ -975,7 +990,7 @@ data-url='/problem/quiz/'> \
(time_step => { (time_step => {
jasmine.clock().tick(time_step); jasmine.clock().tick(time_step);
expect(this.problem.poll.calls.count()).toEqual(num_calls); expect(this.problem.poll.calls.count()).toEqual(num_calls);
return num_calls += 1; num_calls += 1;
})(time_step); })(time_step);
} }
...@@ -983,7 +998,7 @@ data-url='/problem/quiz/'> \ ...@@ -983,7 +998,7 @@ data-url='/problem/quiz/'> \
jasmine.clock().tick(64000); jasmine.clock().tick(64000);
expect(this.problem.poll.calls.count()).toEqual(6); expect(this.problem.poll.calls.count()).toEqual(6);
return expect($('.notification-gentle-alert .notification-message').text()).toEqual("The grading process is still running. Refresh the page to see updates."); expect($('.notification-gentle-alert .notification-message').text()).toEqual("The grading process is still running. Refresh the page to see updates.");
}); });
}); });
...@@ -993,10 +1008,10 @@ data-url='/problem/quiz/'> \ ...@@ -993,10 +1008,10 @@ data-url='/problem/quiz/'> \
beforeEach(function() { beforeEach(function() {
spyOn($, 'postWithPrefix').and.callFake((url, callback) => callback({html: codeinputProblemHtml})); spyOn($, 'postWithPrefix').and.callFake((url, callback) => callback({html: codeinputProblemHtml}));
this.problem = new Problem($('.xblock-student_view')); this.problem = new Problem($('.xblock-student_view'));
return this.problem.render(codeinputProblemHtml); this.problem.render(codeinputProblemHtml);
}); });
return it('has rendered with correct a11y info', function() { it('has rendered with correct a11y info', function() {
const CodeMirrorTextArea = $('textarea')[1]; const CodeMirrorTextArea = $('textarea')[1];
const CodeMirrorTextAreaId = 'cm-textarea-101'; const CodeMirrorTextAreaId = 'cm-textarea-101';
...@@ -1007,12 +1022,12 @@ data-url='/problem/quiz/'> \ ...@@ -1007,12 +1022,12 @@ data-url='/problem/quiz/'> \
expect($(CodeMirrorTextArea).attr('id')).toEqual(CodeMirrorTextAreaId); expect($(CodeMirrorTextArea).attr('id')).toEqual(CodeMirrorTextAreaId);
// verify that codemirror textarea has correct `aria-describedby` attribute value // verify that codemirror textarea has correct `aria-describedby` attribute value
return expect($(CodeMirrorTextArea).attr('aria-describedby')).toEqual('cm-editor-exit-message-101 status_101'); expect($(CodeMirrorTextArea).attr('aria-describedby')).toEqual('cm-editor-exit-message-101 status_101');
}); });
}); });
return describe('show answer button', function() { describe('show answer button', function() {
const radioButtonProblemHtml = readFixtures('radiobutton_problem.html'); const radioButtonProblemHtml = readFixtures('radiobutton_problem.html');
const checkboxProblemHtml = readFixtures('checkbox_problem.html'); const checkboxProblemHtml = readFixtures('checkbox_problem.html');
...@@ -1020,7 +1035,7 @@ data-url='/problem/quiz/'> \ ...@@ -1020,7 +1035,7 @@ data-url='/problem/quiz/'> \
beforeEach(function() { beforeEach(function() {
this.problem = new Problem($('.xblock-student_view')); this.problem = new Problem($('.xblock-student_view'));
return this.checkAssertionsAfterClickingAnotherOption = () => { this.checkAssertionsAfterClickingAnotherOption = () => {
// verify that 'show answer button is no longer disabled' // verify that 'show answer button is no longer disabled'
expect(this.problem.el.find('.show').attr('disabled')).not.toEqual('disabled'); expect(this.problem.el.find('.show').attr('disabled')).not.toEqual('disabled');
...@@ -1028,7 +1043,7 @@ data-url='/problem/quiz/'> \ ...@@ -1028,7 +1043,7 @@ data-url='/problem/quiz/'> \
expect(this.problem.el.find('div.choicegroup')).not.toHaveClass('choicegroup_correct'); expect(this.problem.el.find('div.choicegroup')).not.toHaveClass('choicegroup_correct');
// verify that radio/checkbox label has no span having class '.status.correct' // verify that radio/checkbox label has no span having class '.status.correct'
return expect(this.problem.el.find('div.choicegroup')).not.toHaveAttr('span.status.correct'); expect(this.problem.el.find('div.choicegroup')).not.toHaveAttr('span.status.correct');
}; };
}); });
...@@ -1041,15 +1056,15 @@ data-url='/problem/quiz/'> \ ...@@ -1041,15 +1056,15 @@ data-url='/problem/quiz/'> \
this.problem.submitAnswersAndSubmitButton(true); this.problem.submitAnswersAndSubmitButton(true);
// selects option 2 // selects option 2
$('#input_1_1_2').attr('checked', true).trigger('click'); $('#input_1_1_2').attr('checked', true).trigger('click');
return this.checkAssertionsAfterClickingAnotherOption(); this.checkAssertionsAfterClickingAnotherOption();
}); });
return it('should become enabled after a checkbox is selected', function() { it('should become enabled after a checkbox is selected', function() {
$('#input_example_1').replaceWith(checkboxProblemHtml); $('#input_example_1').replaceWith(checkboxProblemHtml);
this.problem.el.find('.show').attr('disabled', 'disabled'); this.problem.el.find('.show').attr('disabled', 'disabled');
this.problem.submitAnswersAndSubmitButton(true); this.problem.submitAnswersAndSubmitButton(true);
$('#input_1_1_2').click(); $('#input_1_1_2').click();
return this.checkAssertionsAfterClickingAnotherOption(); this.checkAssertionsAfterClickingAnotherOption();
}); });
}); });
}); });
/*
* decaffeinate suggestions:
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
describe('HTMLEditingDescriptor', function() { describe('HTMLEditingDescriptor', function() {
beforeEach(() => window.baseUrl = "/static/deadbeef"); beforeEach(() => window.baseUrl = "/static/deadbeef");
afterEach(() => delete window.baseUrl); afterEach(() => delete window.baseUrl);
describe('Visual HTML Editor', function() { describe('Visual HTML Editor', function() {
beforeEach(function() { beforeEach(function() {
loadFixtures('html-edit-visual.html'); loadFixtures('html-edit-visual.html');
return this.descriptor = new HTMLEditingDescriptor($('.test-component')); this.descriptor = new HTMLEditingDescriptor($('.test-component'));
}); });
it('Returns data from Visual Editor if text has changed', function() { it('Returns data from Visual Editor if text has changed', function() {
const visualEditorStub = const visualEditorStub =
{getContent() { return 'from visual editor'; }}; {getContent() { return 'from visual editor'; }};
spyOn(this.descriptor, 'getVisualEditor').and.callFake(() => visualEditorStub); spyOn(this.descriptor, 'getVisualEditor').and.callFake(() => visualEditorStub);
const { data } = this.descriptor.save(); const { data } = this.descriptor.save();
return expect(data).toEqual('from visual editor'); expect(data).toEqual('from visual editor');
}); });
it('Returns data from Raw Editor if text has not changed', function() { it('Returns data from Raw Editor if text has not changed', function() {
const visualEditorStub = const visualEditorStub =
{getContent() { return '<p>original visual text</p>'; }}; {getContent() { return '<p>original visual text</p>'; }};
spyOn(this.descriptor, 'getVisualEditor').and.callFake(() => visualEditorStub); spyOn(this.descriptor, 'getVisualEditor').and.callFake(() => visualEditorStub);
const { data } = this.descriptor.save(); const { data } = this.descriptor.save();
return expect(data).toEqual('raw text'); expect(data).toEqual('raw text');
}); });
it('Performs link rewriting for static assets when saving', function() { it('Performs link rewriting for static assets when saving', function() {
const visualEditorStub = const visualEditorStub =
{getContent() { return 'from visual editor with /c4x/foo/bar/asset/image.jpg'; }}; {getContent() { return 'from visual editor with /c4x/foo/bar/asset/image.jpg'; }};
spyOn(this.descriptor, 'getVisualEditor').and.callFake(() => visualEditorStub); spyOn(this.descriptor, 'getVisualEditor').and.callFake(() => visualEditorStub);
const { data } = this.descriptor.save(); const { data } = this.descriptor.save();
return expect(data).toEqual('from visual editor with /static/image.jpg'); expect(data).toEqual('from visual editor with /static/image.jpg');
}); });
it('When showing visual editor links are rewritten to c4x format', function() { it('When showing visual editor links are rewritten to c4x format', function() {
const visualEditorStub = { const visualEditorStub = {
content: 'text /static/image.jpg', content: 'text /static/image.jpg',
startContent: 'text /static/image.jpg', startContent: 'text /static/image.jpg',
focus() {}, focus() {},
setContent(x) { return this.content = x; }, setContent(x) { this.content = x; },
getContent() { return this.content; } getContent() { return this.content; }
}; };
this.descriptor.initInstanceCallback(visualEditorStub); this.descriptor.initInstanceCallback(visualEditorStub);
return expect(visualEditorStub.getContent()).toEqual('text /c4x/foo/bar/asset/image.jpg'); expect(visualEditorStub.getContent()).toEqual('text /c4x/foo/bar/asset/image.jpg');
}); });
return it('Enables spellcheck', () => expect($('.html-editor iframe')[0].contentDocument.body.spellcheck).toBe(true)); it('Enables spellcheck', () => expect($('.html-editor iframe')[0].contentDocument.body.spellcheck).toBe(true));
}); });
return describe('Raw HTML Editor', function() { describe('Raw HTML Editor', function() {
beforeEach(function() { beforeEach(function() {
loadFixtures('html-editor-raw.html'); loadFixtures('html-editor-raw.html');
return this.descriptor = new HTMLEditingDescriptor($('.test-component')); this.descriptor = new HTMLEditingDescriptor($('.test-component'));
}); });
return it('Returns data from raw editor', function() { it('Returns data from raw editor', function() {
const { data } = this.descriptor.save(); const { data } = this.descriptor.save();
return expect(data).toEqual('raw text'); expect(data).toEqual('raw text');
}); });
}); });
}); });
/*
* decaffeinate suggestions:
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
describe('MarkdownEditingDescriptor', function() { describe('MarkdownEditingDescriptor', function() {
describe('save stores the correct data', function() { describe('save stores the correct data', function() {
it('saves markdown from markdown editor', function() { it('saves markdown from markdown editor', function() {
...@@ -10,7 +5,7 @@ describe('MarkdownEditingDescriptor', function() { ...@@ -10,7 +5,7 @@ describe('MarkdownEditingDescriptor', function() {
this.descriptor = new MarkdownEditingDescriptor($('.problem-editor')); this.descriptor = new MarkdownEditingDescriptor($('.problem-editor'));
const saveResult = this.descriptor.save(); const saveResult = this.descriptor.save();
expect(saveResult.metadata.markdown).toEqual('markdown'); expect(saveResult.metadata.markdown).toEqual('markdown');
return expect(saveResult.data).toXMLEqual('<problem>\n <p>markdown</p>\n</problem>'); expect(saveResult.data).toXMLEqual('<problem>\n <p>markdown</p>\n</problem>');
}); });
it('clears markdown when xml editor is selected', function() { it('clears markdown when xml editor is selected', function() {
loadFixtures('problem-with-markdown.html'); loadFixtures('problem-with-markdown.html');
...@@ -18,14 +13,14 @@ describe('MarkdownEditingDescriptor', function() { ...@@ -18,14 +13,14 @@ describe('MarkdownEditingDescriptor', function() {
this.descriptor.createXMLEditor('replace with markdown'); this.descriptor.createXMLEditor('replace with markdown');
const saveResult = this.descriptor.save(); const saveResult = this.descriptor.save();
expect(saveResult.nullout).toEqual(['markdown']); expect(saveResult.nullout).toEqual(['markdown']);
return expect(saveResult.data).toEqual('replace with markdown'); expect(saveResult.data).toEqual('replace with markdown');
}); });
return it('saves xml from the xml editor', function() { it('saves xml from the xml editor', function() {
loadFixtures('problem-without-markdown.html'); loadFixtures('problem-without-markdown.html');
this.descriptor = new MarkdownEditingDescriptor($('.problem-editor')); this.descriptor = new MarkdownEditingDescriptor($('.problem-editor'));
const saveResult = this.descriptor.save(); const saveResult = this.descriptor.save();
expect(saveResult.nullout).toEqual(['markdown']); expect(saveResult.nullout).toEqual(['markdown']);
return expect(saveResult.data).toEqual('xml only'); expect(saveResult.data).toEqual('xml only');
}); });
}); });
...@@ -39,30 +34,30 @@ describe('MarkdownEditingDescriptor', function() { ...@@ -39,30 +34,30 @@ describe('MarkdownEditingDescriptor', function() {
this.descriptor.onShowXMLButton(e); this.descriptor.onShowXMLButton(e);
expect(e.preventDefault).toHaveBeenCalled(); expect(e.preventDefault).toHaveBeenCalled();
expect(this.descriptor.confirmConversionToXml).toHaveBeenCalled(); expect(this.descriptor.confirmConversionToXml).toHaveBeenCalled();
return expect($('.editor-bar').length).toEqual(0); expect($('.editor-bar').length).toEqual(0);
}) })
); );
describe('insertMultipleChoice', function() { describe('insertMultipleChoice', function() {
it('inserts the template if selection is empty', function() { it('inserts the template if selection is empty', function() {
const revisedSelection = MarkdownEditingDescriptor.insertMultipleChoice(''); const revisedSelection = MarkdownEditingDescriptor.insertMultipleChoice('');
return expect(revisedSelection).toEqual(MarkdownEditingDescriptor.multipleChoiceTemplate); expect(revisedSelection).toEqual(MarkdownEditingDescriptor.multipleChoiceTemplate);
}); });
it('wraps existing text', function() { it('wraps existing text', function() {
const revisedSelection = MarkdownEditingDescriptor.insertMultipleChoice('foo\nbar'); const revisedSelection = MarkdownEditingDescriptor.insertMultipleChoice('foo\nbar');
return expect(revisedSelection).toEqual('( ) foo\n( ) bar\n'); expect(revisedSelection).toEqual('( ) foo\n( ) bar\n');
}); });
it('recognizes x as a selection if there is non-whitespace after x', function() { it('recognizes x as a selection if there is non-whitespace after x', function() {
const revisedSelection = MarkdownEditingDescriptor.insertMultipleChoice('a\nx b\nc\nx \nd\n x e'); const revisedSelection = MarkdownEditingDescriptor.insertMultipleChoice('a\nx b\nc\nx \nd\n x e');
return expect(revisedSelection).toEqual('( ) a\n(x) b\n( ) c\n( ) x \n( ) d\n(x) e\n'); expect(revisedSelection).toEqual('( ) a\n(x) b\n( ) c\n( ) x \n( ) d\n(x) e\n');
}); });
it('recognizes x as a selection if it is first non whitespace and has whitespace with other non-whitespace', function() { it('recognizes x as a selection if it is first non whitespace and has whitespace with other non-whitespace', function() {
const revisedSelection = MarkdownEditingDescriptor.insertMultipleChoice(' x correct\n x \nex post facto\nb x c\nx c\nxxp'); const revisedSelection = MarkdownEditingDescriptor.insertMultipleChoice(' x correct\n x \nex post facto\nb x c\nx c\nxxp');
return expect(revisedSelection).toEqual('(x) correct\n( ) x \n( ) ex post facto\n( ) b x c\n(x) c\n( ) xxp\n'); expect(revisedSelection).toEqual('(x) correct\n( ) x \n( ) ex post facto\n( ) b x c\n(x) c\n( ) xxp\n');
}); });
return it('removes multiple newlines but not last one', function() { it('removes multiple newlines but not last one', function() {
const revisedSelection = MarkdownEditingDescriptor.insertMultipleChoice('a\nx b\n\n\nc\n'); const revisedSelection = MarkdownEditingDescriptor.insertMultipleChoice('a\nx b\n\n\nc\n');
return expect(revisedSelection).toEqual('( ) a\n(x) b\n( ) c\n'); expect(revisedSelection).toEqual('( ) a\n(x) b\n( ) c\n');
}); });
}); });
...@@ -70,73 +65,73 @@ describe('MarkdownEditingDescriptor', function() { ...@@ -70,73 +65,73 @@ describe('MarkdownEditingDescriptor', function() {
// Note, shares code with insertMultipleChoice. Therefore only doing smoke test. // Note, shares code with insertMultipleChoice. Therefore only doing smoke test.
it('inserts the template if selection is empty', function() { it('inserts the template if selection is empty', function() {
const revisedSelection = MarkdownEditingDescriptor.insertCheckboxChoice(''); const revisedSelection = MarkdownEditingDescriptor.insertCheckboxChoice('');
return expect(revisedSelection).toEqual(MarkdownEditingDescriptor.checkboxChoiceTemplate); expect(revisedSelection).toEqual(MarkdownEditingDescriptor.checkboxChoiceTemplate);
}); });
return it('wraps existing text', function() { it('wraps existing text', function() {
const revisedSelection = MarkdownEditingDescriptor.insertCheckboxChoice('foo\nbar'); const revisedSelection = MarkdownEditingDescriptor.insertCheckboxChoice('foo\nbar');
return expect(revisedSelection).toEqual('[ ] foo\n[ ] bar\n'); expect(revisedSelection).toEqual('[ ] foo\n[ ] bar\n');
}); });
}); });
describe('insertStringInput', function() { describe('insertStringInput', function() {
it('inserts the template if selection is empty', function() { it('inserts the template if selection is empty', function() {
const revisedSelection = MarkdownEditingDescriptor.insertStringInput(''); const revisedSelection = MarkdownEditingDescriptor.insertStringInput('');
return expect(revisedSelection).toEqual(MarkdownEditingDescriptor.stringInputTemplate); expect(revisedSelection).toEqual(MarkdownEditingDescriptor.stringInputTemplate);
}); });
return it('wraps existing text', function() { it('wraps existing text', function() {
const revisedSelection = MarkdownEditingDescriptor.insertStringInput('my text'); const revisedSelection = MarkdownEditingDescriptor.insertStringInput('my text');
return expect(revisedSelection).toEqual('= my text'); expect(revisedSelection).toEqual('= my text');
}); });
}); });
describe('insertNumberInput', function() { describe('insertNumberInput', function() {
it('inserts the template if selection is empty', function() { it('inserts the template if selection is empty', function() {
const revisedSelection = MarkdownEditingDescriptor.insertNumberInput(''); const revisedSelection = MarkdownEditingDescriptor.insertNumberInput('');
return expect(revisedSelection).toEqual(MarkdownEditingDescriptor.numberInputTemplate); expect(revisedSelection).toEqual(MarkdownEditingDescriptor.numberInputTemplate);
}); });
return it('wraps existing text', function() { it('wraps existing text', function() {
const revisedSelection = MarkdownEditingDescriptor.insertNumberInput('my text'); const revisedSelection = MarkdownEditingDescriptor.insertNumberInput('my text');
return expect(revisedSelection).toEqual('= my text'); expect(revisedSelection).toEqual('= my text');
}); });
}); });
describe('insertSelect', function() { describe('insertSelect', function() {
it('inserts the template if selection is empty', function() { it('inserts the template if selection is empty', function() {
const revisedSelection = MarkdownEditingDescriptor.insertSelect(''); const revisedSelection = MarkdownEditingDescriptor.insertSelect('');
return expect(revisedSelection).toEqual(MarkdownEditingDescriptor.selectTemplate); expect(revisedSelection).toEqual(MarkdownEditingDescriptor.selectTemplate);
}); });
return it('wraps existing text', function() { it('wraps existing text', function() {
const revisedSelection = MarkdownEditingDescriptor.insertSelect('my text'); const revisedSelection = MarkdownEditingDescriptor.insertSelect('my text');
return expect(revisedSelection).toEqual('[[my text]]'); expect(revisedSelection).toEqual('[[my text]]');
}); });
}); });
describe('insertHeader', function() { describe('insertHeader', function() {
it('inserts the template if selection is empty', function() { it('inserts the template if selection is empty', function() {
const revisedSelection = MarkdownEditingDescriptor.insertHeader(''); const revisedSelection = MarkdownEditingDescriptor.insertHeader('');
return expect(revisedSelection).toEqual(MarkdownEditingDescriptor.headerTemplate); expect(revisedSelection).toEqual(MarkdownEditingDescriptor.headerTemplate);
}); });
return it('wraps existing text', function() { it('wraps existing text', function() {
const revisedSelection = MarkdownEditingDescriptor.insertHeader('my text'); const revisedSelection = MarkdownEditingDescriptor.insertHeader('my text');
return expect(revisedSelection).toEqual('my text\n====\n'); expect(revisedSelection).toEqual('my text\n====\n');
}); });
}); });
describe('insertExplanation', function() { describe('insertExplanation', function() {
it('inserts the template if selection is empty', function() { it('inserts the template if selection is empty', function() {
const revisedSelection = MarkdownEditingDescriptor.insertExplanation(''); const revisedSelection = MarkdownEditingDescriptor.insertExplanation('');
return expect(revisedSelection).toEqual(MarkdownEditingDescriptor.explanationTemplate); expect(revisedSelection).toEqual(MarkdownEditingDescriptor.explanationTemplate);
}); });
return it('wraps existing text', function() { it('wraps existing text', function() {
const revisedSelection = MarkdownEditingDescriptor.insertExplanation('my text'); const revisedSelection = MarkdownEditingDescriptor.insertExplanation('my text');
return expect(revisedSelection).toEqual('[explanation]\nmy text\n[explanation]'); expect(revisedSelection).toEqual('[explanation]\nmy text\n[explanation]');
}); });
}); });
return describe('markdownToXml', function() { describe('markdownToXml', function() {
it('converts raw text to paragraph', function() { it('converts raw text to paragraph', function() {
const data = MarkdownEditingDescriptor.markdownToXml('foo'); const data = MarkdownEditingDescriptor.markdownToXml('foo');
return expect(data).toXMLEqual('<problem>\n <p>foo</p>\n</problem>'); expect(data).toXMLEqual('<problem>\n <p>foo</p>\n</problem>');
}); });
// test default templates // test default templates
it('converts numerical response to xml', function() { it('converts numerical response to xml', function() {
...@@ -169,7 +164,7 @@ Although you can get an exact value by typing 502*9 into a calculator, the resul ...@@ -169,7 +164,7 @@ Although you can get an exact value by typing 502*9 into a calculator, the resul
If you look at your hand, you can count that you have five fingers. If you look at your hand, you can count that you have five fingers.
[Explanation]\ [Explanation]\
`); `);
return expect(data).toXMLEqual(`<problem> expect(data).toXMLEqual(`<problem>
<p>A numerical response problem accepts a line of text input from the student, and evaluates the input for correctness based on its numerical value.</p> <p>A numerical response problem accepts a line of text input from the student, and evaluates the input for correctness based on its numerical value.</p>
<p>The answer is correct if it is within a specified numerical tolerance of the expected answer.</p> <p>The answer is correct if it is within a specified numerical tolerance of the expected answer.</p>
<p>Enter the numerical value of Pi:</p> <p>Enter the numerical value of Pi:</p>
...@@ -215,7 +210,7 @@ If you look at your hand, you can count that you have five fingers. ...@@ -215,7 +210,7 @@ If you look at your hand, you can count that you have five fingers.
Enter 0 with a tolerance: Enter 0 with a tolerance:
= 0 +- .02\ = 0 +- .02\
`); `);
return expect(data).toXMLEqual(`<problem> expect(data).toXMLEqual(`<problem>
<numericalresponse answer="0"> <numericalresponse answer="0">
<p>Enter 0 with a tolerance:</p> <p>Enter 0 with a tolerance:</p>
<responseparam type="tolerance" default=".02"/> <responseparam type="tolerance" default=".02"/>
...@@ -231,7 +226,7 @@ Enter 1 with a tolerance: ...@@ -231,7 +226,7 @@ Enter 1 with a tolerance:
= 1 +- .02 = 1 +- .02
or= 2\ or= 2\
`); `);
return expect(data).toXMLEqual(`<problem> expect(data).toXMLEqual(`<problem>
<numericalresponse answer="1"> <numericalresponse answer="1">
<p>Enter 1 with a tolerance:</p> <p>Enter 1 with a tolerance:</p>
<responseparam type="tolerance" default=".02"/> <responseparam type="tolerance" default=".02"/>
...@@ -249,7 +244,7 @@ Enter 1 with a tolerance: ...@@ -249,7 +244,7 @@ Enter 1 with a tolerance:
or= 2 or= 2
or= 3\ or= 3\
`); `);
return expect(data).toXMLEqual(`<problem> expect(data).toXMLEqual(`<problem>
<numericalresponse answer="1"> <numericalresponse answer="1">
<p>Enter 1 with a tolerance:</p> <p>Enter 1 with a tolerance:</p>
<responseparam type="tolerance" default=".02"/> <responseparam type="tolerance" default=".02"/>
...@@ -271,7 +266,7 @@ or= [4,6] ...@@ -271,7 +266,7 @@ or= [4,6]
or= ABC or= ABC
or= 7\ or= 7\
`); `);
return expect(data).toXMLEqual(`<problem> expect(data).toXMLEqual(`<problem>
<numericalresponse answer="1"> <numericalresponse answer="1">
<p>Enter 1 with a tolerance:</p> <p>Enter 1 with a tolerance:</p>
<responseparam type="tolerance" default=".02"/> <responseparam type="tolerance" default=".02"/>
...@@ -289,7 +284,7 @@ Enter 1 with a tolerance: ...@@ -289,7 +284,7 @@ Enter 1 with a tolerance:
= 100 +- .02 {{ main feedback }} = 100 +- .02 {{ main feedback }}
or= 10 {{ additional feedback }}\ or= 10 {{ additional feedback }}\
`); `);
return expect(data).toXMLEqual(`<problem> expect(data).toXMLEqual(`<problem>
<numericalresponse answer="100"> <numericalresponse answer="100">
<p>Enter 1 with a tolerance:</p> <p>Enter 1 with a tolerance:</p>
<responseparam type="tolerance" default=".02"/> <responseparam type="tolerance" default=".02"/>
...@@ -320,7 +315,7 @@ One of the main elements that goes into a good multiple choice question is the e ...@@ -320,7 +315,7 @@ One of the main elements that goes into a good multiple choice question is the e
The release of the iPod allowed consumers to carry their entire music library with them in a format that did not rely on fragile and energy-intensive spinning disks. The release of the iPod allowed consumers to carry their entire music library with them in a format that did not rely on fragile and energy-intensive spinning disks.
[Explanation]\ [Explanation]\
`); `);
return expect(data).toXMLEqual(`<problem> expect(data).toXMLEqual(`<problem>
<multiplechoiceresponse> <multiplechoiceresponse>
<p>A multiple choice problem presents radio buttons for student input. Students can only select a single option presented. Multiple Choice questions have been the subject of many areas of research due to the early invention and adoption of bubble sheets.</p> <p>A multiple choice problem presents radio buttons for student input. Students can only select a single option presented. Multiple Choice questions have been the subject of many areas of research due to the early invention and adoption of bubble sheets.</p>
<p>One of the main elements that goes into a good multiple choice question is the existence of good distractors. That is, each of the alternate responses presented to the student should be the result of a plausible mistake that a student might make.</p> <p>One of the main elements that goes into a good multiple choice question is the existence of good distractors. That is, each of the alternate responses presented to the student should be the result of a plausible mistake that a student might make.</p>
...@@ -359,7 +354,7 @@ What Apple device competed with the portable CD player? ...@@ -359,7 +354,7 @@ What Apple device competed with the portable CD player?
The release of the iPod allowed consumers to carry their entire music library with them in a format that did not rely on fragile and energy-intensive spinning disks. The release of the iPod allowed consumers to carry their entire music library with them in a format that did not rely on fragile and energy-intensive spinning disks.
[Explanation]\ [Explanation]\
`); `);
return expect(data).toXMLEqual(`\ expect(data).toXMLEqual(`\
<problem> <problem>
<multiplechoiceresponse> <multiplechoiceresponse>
<p>A multiple choice problem presents radio buttons for student input. Students can only select a single option presented. Multiple Choice questions have been the subject of many areas of research due to the early invention and adoption of bubble sheets.</p> <p>A multiple choice problem presents radio buttons for student input. Students can only select a single option presented. Multiple Choice questions have been the subject of many areas of research due to the early invention and adoption of bubble sheets.</p>
...@@ -400,7 +395,7 @@ testa ...@@ -400,7 +395,7 @@ testa
When the student is ready, the explanation appears. When the student is ready, the explanation appears.
[Explanation]\ [Explanation]\
`); `);
return expect(data).toXMLEqual(`\ expect(data).toXMLEqual(`\
<problem> <problem>
<p>bleh</p> <p>bleh</p>
<multiplechoiceresponse> <multiplechoiceresponse>
...@@ -447,7 +442,7 @@ Translation between Option Response and __________ is extremely straightforward: ...@@ -447,7 +442,7 @@ Translation between Option Response and __________ is extremely straightforward:
Multiple Choice also allows students to select from a variety of pre-written responses, although the format makes it easier for students to read very long response options. Optionresponse also differs slightly because students are more likely to think of an answer and then search for it rather than relying purely on recognition to answer the question. Multiple Choice also allows students to select from a variety of pre-written responses, although the format makes it easier for students to read very long response options. Optionresponse also differs slightly because students are more likely to think of an answer and then search for it rather than relying purely on recognition to answer the question.
[Explanation]\ [Explanation]\
`); `);
return expect(data).toXMLEqual(`\ expect(data).toXMLEqual(`\
<problem> <problem>
<optionresponse> <optionresponse>
<p>OptionResponse gives a limited set of options for students to respond with, and presents those options in a format that encourages them to search for a specific answer rather than being immediately presented with options from which to recognize the correct answer.</p> <p>OptionResponse gives a limited set of options for students to respond with, and presents those options in a format that encourages them to search for a specific answer rather than being immediately presented with options from which to recognize the correct answer.</p>
...@@ -475,7 +470,7 @@ Which US state has Lansing as its capital? ...@@ -475,7 +470,7 @@ Which US state has Lansing as its capital?
Lansing is the capital of Michigan, although it is not Michgan's largest city, or even the seat of the county in which it resides. Lansing is the capital of Michigan, although it is not Michgan's largest city, or even the seat of the county in which it resides.
[Explanation]\ [Explanation]\
`); `);
return expect(data).toXMLEqual(`\ expect(data).toXMLEqual(`\
<problem> <problem>
<stringresponse answer="Michigan" type="ci"> <stringresponse answer="Michigan" type="ci">
<p>A string response problem accepts a line of text input from the student, and evaluates the input for correctness based on an expected answer within each input box.</p> <p>A string response problem accepts a line of text input from the student, and evaluates the input for correctness based on an expected answer within each input box.</p>
...@@ -499,7 +494,7 @@ Lansing is the capital of Michigan, although it is not Michgan's largest city, o ...@@ -499,7 +494,7 @@ Lansing is the capital of Michigan, although it is not Michgan's largest city, o
Test Explanation. Test Explanation.
[Explanation]\ [Explanation]\
`); `);
return expect(data).toXMLEqual(`\ expect(data).toXMLEqual(`\
<problem> <problem>
<stringresponse answer="w*.?s*Luther Kings*.*" type="ci regexp"> <stringresponse answer="w*.?s*Luther Kings*.*" type="ci regexp">
<p>Who lead the civil right movement in the United States of America?</p> <p>Who lead the civil right movement in the United States of America?</p>
...@@ -524,7 +519,7 @@ or= Martin Luther King Junior ...@@ -524,7 +519,7 @@ or= Martin Luther King Junior
Test Explanation. Test Explanation.
[Explanation]\ [Explanation]\
`); `);
return expect(data).toXMLEqual(`\ expect(data).toXMLEqual(`\
<problem> <problem>
<stringresponse answer="Dr. Martin Luther King Jr." type="ci"> <stringresponse answer="Dr. Martin Luther King Jr." type="ci">
<p>Who lead the civil right movement in the United States of America?</p> <p>Who lead the civil right movement in the United States of America?</p>
...@@ -552,7 +547,7 @@ or= ^4|Four$ ...@@ -552,7 +547,7 @@ or= ^4|Four$
Test Explanation. Test Explanation.
[Explanation]\ [Explanation]\
`); `);
return expect(data).toXMLEqual(`\ expect(data).toXMLEqual(`\
<problem> <problem>
<stringresponse answer="^One$" type="ci regexp"> <stringresponse answer="^One$" type="ci regexp">
<p>Write a number from 1 to 4.</p> <p>Write a number from 1 to 4.</p>
...@@ -578,7 +573,7 @@ Test Explanation. ...@@ -578,7 +573,7 @@ Test Explanation.
Test Explanation. Test Explanation.
[Explanation]\ [Explanation]\
`); `);
return expect(data).toXMLEqual(`\ expect(data).toXMLEqual(`\
<problem> <problem>
<stringresponse answer="w*.?s*Luther Kings*.*" type="ci regexp"> <stringresponse answer="w*.?s*Luther Kings*.*" type="ci regexp">
<label>Who lead the civil right movement in the United States of America?</label> <label>Who lead the civil right movement in the United States of America?</label>
...@@ -607,7 +602,7 @@ Germany is a country in Europe, too. ...@@ -607,7 +602,7 @@ Germany is a country in Europe, too.
(x) Berlin (x) Berlin
( ) Donut\ ( ) Donut\
`); `);
return expect(data).toXMLEqual(`\ expect(data).toXMLEqual(`\
<problem> <problem>
<p>France is a country in Europe.</p> <p>France is a country in Europe.</p>
...@@ -644,7 +639,7 @@ What is the capital of Germany? ...@@ -644,7 +639,7 @@ What is the capital of Germany?
(x) Berlin (x) Berlin
( ) Donut\ ( ) Donut\
`); `);
return expect(data).toXMLEqual(`\ expect(data).toXMLEqual(`\
<problem> <problem>
<p>France is a country in Europe.</p> <p>France is a country in Europe.</p>
...@@ -672,7 +667,7 @@ What is the capital of Germany? ...@@ -672,7 +667,7 @@ What is the capital of Germany?
>>Enter the numerical value of Pi:<< >>Enter the numerical value of Pi:<<
= 3.14159 +- .02\ = 3.14159 +- .02\
`); `);
return expect(data).toXMLEqual(`<problem> expect(data).toXMLEqual(`<problem>
<numericalresponse answer="3.14159"> <numericalresponse answer="3.14159">
<label>Enter the numerical value of Pi:</label> <label>Enter the numerical value of Pi:</label>
<responseparam type="tolerance" default=".02"/> <responseparam type="tolerance" default=".02"/>
...@@ -734,7 +729,7 @@ bad tests require drivel ...@@ -734,7 +729,7 @@ bad tests require drivel
Code should be nicely monospaced. Code should be nicely monospaced.
[/code]\ [/code]\
`); `);
return expect(data).toXMLEqual(`\ expect(data).toXMLEqual(`\
<problem> <problem>
<p>Not a header</p> <p>Not a header</p>
<h3 class="hd hd-2 problem-header">A header</h3> <h3 class="hd hd-2 problem-header">A header</h3>
...@@ -831,7 +826,7 @@ Urdu, Marathi, and French are all Indo-European languages, while Finnish and Hun ...@@ -831,7 +826,7 @@ Urdu, Marathi, and French are all Indo-European languages, while Finnish and Hun
[explanation] [explanation]
\ \
`); `);
return expect(data).toXMLEqual(`\ expect(data).toXMLEqual(`\
<problem> <problem>
<multiplechoiceresponse> <multiplechoiceresponse>
<p>Multiple choice problems allow learners to select only one option. Learners can see all the options along with the problem text.</p> <p>Multiple choice problems allow learners to select only one option. Learners can see all the options along with the problem text.</p>
...@@ -897,7 +892,7 @@ The population of Russia is approximately 146 million. ...@@ -897,7 +892,7 @@ The population of Russia is approximately 146 million.
The population of Germany is approximately 81 million. The population of Germany is approximately 81 million.
[explanation]\ [explanation]\
`); `);
return expect(data).toXMLEqual(`\ expect(data).toXMLEqual(`\
<problem> <problem>
<p>Multiple choice problems allow learners to select only one option. Learners can see all the options along with the problem text.</p> <p>Multiple choice problems allow learners to select only one option. Learners can see all the options along with the problem text.</p>
...@@ -942,7 +937,7 @@ The population of Germany is approximately 81 million. ...@@ -942,7 +937,7 @@ The population of Germany is approximately 81 million.
(x) Indonesia (x) Indonesia
( ) Russia\ ( ) Russia\
`); `);
return expect(data).toXMLEqual(`\ expect(data).toXMLEqual(`\
<problem> <problem>
<choiceresponse> <choiceresponse>
<label>The following languages are in the Indo-European family:</label> <label>The following languages are in the Indo-European family:</label>
...@@ -981,7 +976,7 @@ The population of Germany is approximately 81 million. ...@@ -981,7 +976,7 @@ The population of Germany is approximately 81 million.
[x] French [x] French
[ ] Hungarian\ [ ] Hungarian\
`); `);
return expect(data).toXMLEqual(`\ expect(data).toXMLEqual(`\
<problem> <problem>
<choiceresponse> <choiceresponse>
<label>The following languages are in the Indo-European family:</label> <label>The following languages are in the Indo-European family:</label>
...@@ -1011,7 +1006,7 @@ third ...@@ -1011,7 +1006,7 @@ third
[ ] Finnish [ ] Finnish
[x] Marathi\ [x] Marathi\
`); `);
return expect(data).toXMLEqual(`\ expect(data).toXMLEqual(`\
<problem> <problem>
<choiceresponse> <choiceresponse>
<label>The following languages are in the Indo-European family:</label> <label>The following languages are in the Indo-European family:</label>
...@@ -1026,13 +1021,13 @@ third ...@@ -1026,13 +1021,13 @@ third
`); `);
}); });
return it('will not add empty description', function() { it('will not add empty description', function() {
const data = MarkdownEditingDescriptor.markdownToXml(`\ const data = MarkdownEditingDescriptor.markdownToXml(`\
>>The following languages are in the Indo-European family:||<< >>The following languages are in the Indo-European family:||<<
[x] Urdu [x] Urdu
[ ] Finnish\ [ ] Finnish\
`); `);
return expect(data).toXMLEqual(`\ expect(data).toXMLEqual(`\
<problem> <problem>
<choiceresponse> <choiceresponse>
<label>The following languages are in the Indo-European family:</label> <label>The following languages are in the Indo-European family:</label>
......
/*
* decaffeinate suggestions:
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
// This file tests the parsing of extended-hints, double bracket sections {{ .. }} // This file tests the parsing of extended-hints, double bracket sections {{ .. }}
// for all sorts of markdown. // for all sorts of markdown.
describe('Markdown to xml extended hint dropdown', function() { describe('Markdown to xml extended hint dropdown', function() {
...@@ -30,7 +25,7 @@ Clowns have funny _________ to make people laugh. ...@@ -30,7 +25,7 @@ Clowns have funny _________ to make people laugh.
]] ]]
\ \
`); `);
return expect(data).toXMLEqual(`\ expect(data).toXMLEqual(`\
<problem> <problem>
<p>Translation between Dropdown and ________ is straightforward.</p> <p>Translation between Dropdown and ________ is straightforward.</p>
<optionresponse> <optionresponse>
...@@ -82,7 +77,7 @@ Translation between Dropdown and ________ is straightforward. ...@@ -82,7 +77,7 @@ Translation between Dropdown and ________ is straightforward.
|| 1) one || || 1) one ||
|| 2) two ||\ || 2) two ||\
`); `);
return expect(data).toXMLEqual(`\ expect(data).toXMLEqual(`\
<problem> <problem>
<optionresponse> <optionresponse>
<p>Translation between Dropdown and ________ is straightforward.</p> <p>Translation between Dropdown and ________ is straightforward.</p>
...@@ -113,7 +108,7 @@ A Question ________ is answered. ...@@ -113,7 +108,7 @@ A Question ________ is answered.
|| 0) zero || || 0) zero ||
|| 1) one ||\ || 1) one ||\
`); `);
return expect(data).toXMLEqual(`\ expect(data).toXMLEqual(`\
<problem> <problem>
<optionresponse> <optionresponse>
<p>A Question ________ is answered.</p> <p>A Question ________ is answered.</p>
...@@ -135,7 +130,7 @@ A Question ________ is answered. ...@@ -135,7 +130,7 @@ A Question ________ is answered.
bb bb
cc {{ hint2 }} ]]\ cc {{ hint2 }} ]]\
`); `);
return expect(data).toXMLEqual(`\ expect(data).toXMLEqual(`\
<problem> <problem>
<optionresponse> <optionresponse>
<label>q1</label> <label>q1</label>
...@@ -153,7 +148,7 @@ A Question ________ is answered. ...@@ -153,7 +148,7 @@ A Question ________ is answered.
`); `);
}); });
return it('produces xml even with lots of whitespace', function() { it('produces xml even with lots of whitespace', function() {
const data = MarkdownEditingDescriptor.markdownToXml(`\ const data = MarkdownEditingDescriptor.markdownToXml(`\
>>q1<< >>q1<<
[[ [[
...@@ -166,7 +161,7 @@ A Question ________ is answered. ...@@ -166,7 +161,7 @@ A Question ________ is answered.
]]\ ]]\
`); `);
return expect(data).toXMLEqual(`\ expect(data).toXMLEqual(`\
<problem> <problem>
<optionresponse> <optionresponse>
<label>q1</label> <label>q1</label>
...@@ -212,7 +207,7 @@ describe('Markdown to xml extended hint checkbox', function() { ...@@ -212,7 +207,7 @@ describe('Markdown to xml extended hint checkbox', function() {
{{ ((A*B)) Making a banana split? }} {{ ((A*B)) Making a banana split? }}
{{ ((B*D)) That will make a horrible dessert: a brussel sprout split? }}\ {{ ((B*D)) That will make a horrible dessert: a brussel sprout split? }}\
`); `);
return expect(data).toXMLEqual(`\ expect(data).toXMLEqual(`\
<problem> <problem>
<label>Select all the fruits from the list</label> <label>Select all the fruits from the list</label>
<choiceresponse> <choiceresponse>
...@@ -263,7 +258,7 @@ describe('Markdown to xml extended hint checkbox', function() { ...@@ -263,7 +258,7 @@ describe('Markdown to xml extended hint checkbox', function() {
`); `);
}); });
return it('produces xml also with demand hints', function() { it('produces xml also with demand hints', function() {
const data = MarkdownEditingDescriptor.markdownToXml(`\ const data = MarkdownEditingDescriptor.markdownToXml(`\
>>Select all the fruits from the list<< >>Select all the fruits from the list<<
...@@ -290,7 +285,7 @@ describe('Markdown to xml extended hint checkbox', function() { ...@@ -290,7 +285,7 @@ describe('Markdown to xml extended hint checkbox', function() {
|| Hint two. || || Hint two. ||
|| Hint three. ||\ || Hint three. ||\
`); `);
return expect(data).toXMLEqual(`\ expect(data).toXMLEqual(`\
<problem> <problem>
<label>Select all the fruits from the list</label> <label>Select all the fruits from the list</label>
<choiceresponse> <choiceresponse>
...@@ -364,7 +359,7 @@ describe('Markdown to xml extended hint multiple choice', function() { ...@@ -364,7 +359,7 @@ describe('Markdown to xml extended hint multiple choice', function() {
(x) Potato {{ Potato is a root vegetable. }} (x) Potato {{ Potato is a root vegetable. }}
() Apple {{ OOPS::Apple is a fruit.}}\ () Apple {{ OOPS::Apple is a fruit.}}\
`); `);
return expect(data).toXMLEqual(`\ expect(data).toXMLEqual(`\
<problem> <problem>
<label>Select the fruit from the list</label> <label>Select the fruit from the list</label>
<multiplechoiceresponse> <multiplechoiceresponse>
...@@ -397,7 +392,7 @@ describe('Markdown to xml extended hint multiple choice', function() { ...@@ -397,7 +392,7 @@ describe('Markdown to xml extended hint multiple choice', function() {
`); `);
}); });
return it('produces xml with demand hints', function() { it('produces xml with demand hints', function() {
const data = MarkdownEditingDescriptor.markdownToXml(`\ const data = MarkdownEditingDescriptor.markdownToXml(`\
>>Select the fruit from the list<< >>Select the fruit from the list<<
...@@ -417,7 +412,7 @@ describe('Markdown to xml extended hint multiple choice', function() { ...@@ -417,7 +412,7 @@ describe('Markdown to xml extended hint multiple choice', function() {
|| 2) where are the lions? || || 2) where are the lions? ||
\ \
`); `);
return expect(data).toXMLEqual(`\ expect(data).toXMLEqual(`\
<problem> <problem>
<label>Select the fruit from the list</label> <label>Select the fruit from the list</label>
<multiplechoiceresponse> <multiplechoiceresponse>
...@@ -464,7 +459,7 @@ describe('Markdown to xml extended hint text input', function() { ...@@ -464,7 +459,7 @@ describe('Markdown to xml extended hint text input', function() {
= France {{ BRAVO::Viva la France! }} = France {{ BRAVO::Viva la France! }}
\ \
`); `);
return expect(data).toXMLEqual(`\ expect(data).toXMLEqual(`\
<problem> <problem>
<stringresponse answer="France" type="ci"> <stringresponse answer="France" type="ci">
<label>In which country would you find the city of Paris?</label> <label>In which country would you find the city of Paris?</label>
...@@ -483,7 +478,7 @@ describe('Markdown to xml extended hint text input', function() { ...@@ -483,7 +478,7 @@ describe('Markdown to xml extended hint text input', function() {
or= USA {{ meh::hint2 }} or= USA {{ meh::hint2 }}
\ \
`); `);
return expect(data).toXMLEqual(`\ expect(data).toXMLEqual(`\
<problem> <problem>
<stringresponse answer="France" type="ci"> <stringresponse answer="France" type="ci">
<label>Where Paris?</label> <label>Where Paris?</label>
...@@ -504,7 +499,7 @@ or= USA {{ meh::hint2 }} ...@@ -504,7 +499,7 @@ or= USA {{ meh::hint2 }}
not= warm {{feedback2}} not= warm {{feedback2}}
\ \
`); `);
return expect(data).toXMLEqual(`\ expect(data).toXMLEqual(`\
<problem> <problem>
<stringresponse answer="cold" type="ci"> <stringresponse answer="cold" type="ci">
<label>Revenge is a dish best served</label> <label>Revenge is a dish best served</label>
...@@ -523,7 +518,7 @@ not= warm {{feedback2}} ...@@ -523,7 +518,7 @@ not= warm {{feedback2}}
s= 2 {{feedback1}} s= 2 {{feedback1}}
\ \
`); `);
return expect(data).toXMLEqual(`\ expect(data).toXMLEqual(`\
<problem> <problem>
<stringresponse answer="2" type="ci"> <stringresponse answer="2" type="ci">
<label>q</label> <label>q</label>
...@@ -544,7 +539,7 @@ not= no {{feedback2}} ...@@ -544,7 +539,7 @@ not= no {{feedback2}}
or= ccc or= ccc
\ \
`); `);
return expect(data).toXMLEqual(`\ expect(data).toXMLEqual(`\
<problem> <problem>
<stringresponse answer="aaa" type="ci"> <stringresponse answer="aaa" type="ci">
<label>q</label> <label>q</label>
...@@ -567,7 +562,7 @@ or= bbb {{feedback2}} ...@@ -567,7 +562,7 @@ or= bbb {{feedback2}}
or= ccc or= ccc
\ \
`); `);
return expect(data).toXMLEqual(`\ expect(data).toXMLEqual(`\
<problem> <problem>
<stringresponse answer="2" type="ci"> <stringresponse answer="2" type="ci">
<label>q</label> <label>q</label>
...@@ -590,7 +585,7 @@ or= ccc ...@@ -590,7 +585,7 @@ or= ccc
or= bbb or= bbb
s= ccc\ s= ccc\
`); `);
return expect(data).toXMLEqual(`\ expect(data).toXMLEqual(`\
<problem> <problem>
<label>q</label> <label>q</label>
<stringresponse answer="aaa" type="ci"> <stringresponse answer="aaa" type="ci">
...@@ -616,7 +611,7 @@ s= ccc ...@@ -616,7 +611,7 @@ s= ccc
paragraph 2 paragraph 2
\ \
`); `);
return expect(data).toXMLEqual(`\ expect(data).toXMLEqual(`\
<problem> <problem>
<p>paragraph</p> <p>paragraph</p>
<label>q</label> <label>q</label>
...@@ -640,7 +635,7 @@ or= aaa ...@@ -640,7 +635,7 @@ or= aaa
paragraph 2 paragraph 2
\ \
`); `);
return expect(data).toXMLEqual(`\ expect(data).toXMLEqual(`\
<problem> <problem>
<p>paragraph</p> <p>paragraph</p>
<label>q</label> <label>q</label>
...@@ -658,7 +653,7 @@ or= bbb {{feedback1}} ...@@ -658,7 +653,7 @@ or= bbb {{feedback1}}
= ccc {{feedback2}} = ccc {{feedback2}}
\ \
`); `);
return expect(data).toXMLEqual(`\ expect(data).toXMLEqual(`\
<problem> <problem>
<label>q</label> <label>q</label>
<stringresponse answer="aaa" type="ci"> <stringresponse answer="aaa" type="ci">
...@@ -675,7 +670,7 @@ or= bbb {{feedback1}} ...@@ -675,7 +670,7 @@ or= bbb {{feedback1}}
`); `);
}); });
return it('produces xml with demand hints', function() { it('produces xml with demand hints', function() {
const data = MarkdownEditingDescriptor.markdownToXml(`>>Where Paris?<< const data = MarkdownEditingDescriptor.markdownToXml(`>>Where Paris?<<
= France {{ BRAVO::hint1 }} = France {{ BRAVO::hint1 }}
...@@ -683,7 +678,7 @@ or= bbb {{feedback1}} ...@@ -683,7 +678,7 @@ or= bbb {{feedback1}}
|| Paris is the capital of one of those countries. || || Paris is the capital of one of those countries. ||
\ \
`); `);
return expect(data).toXMLEqual(`\ expect(data).toXMLEqual(`\
<problem> <problem>
<stringresponse answer="France" type="ci"> <stringresponse answer="France" type="ci">
<label>Where Paris?</label> <label>Where Paris?</label>
...@@ -713,7 +708,7 @@ describe('Markdown to xml extended hint numeric input', function() { ...@@ -713,7 +708,7 @@ describe('Markdown to xml extended hint numeric input', function() {
= 5 = 5
\ \
`); `);
return expect(data).toXMLEqual(`\ expect(data).toXMLEqual(`\
<problem> <problem>
<label>Enter the numerical value of Pi:</label> <label>Enter the numerical value of Pi:</label>
<numericalresponse answer="3.14159"> <numericalresponse answer="3.14159">
...@@ -739,7 +734,7 @@ describe('Markdown to xml extended hint numeric input', function() { ...@@ -739,7 +734,7 @@ describe('Markdown to xml extended hint numeric input', function() {
// The output xml here shows some of the quirks of how historical markdown parsing does or does not put // The output xml here shows some of the quirks of how historical markdown parsing does or does not put
// in blank lines. // in blank lines.
return it('numeric input with hints and demand hints', function() { it('numeric input with hints and demand hints', function() {
const data = MarkdownEditingDescriptor.markdownToXml(`\ const data = MarkdownEditingDescriptor.markdownToXml(`\
>>text1<< >>text1<<
= 1 {{ hint1 }} = 1 {{ hint1 }}
...@@ -750,7 +745,7 @@ describe('Markdown to xml extended hint numeric input', function() { ...@@ -750,7 +745,7 @@ describe('Markdown to xml extended hint numeric input', function() {
|| hintB || || hintB ||
\ \
`); `);
return expect(data).toXMLEqual(`\ expect(data).toXMLEqual(`\
<problem> <problem>
<label>text1</label> <label>text1</label>
<numericalresponse answer="1"> <numericalresponse answer="1">
...@@ -820,7 +815,7 @@ hint ...@@ -820,7 +815,7 @@ hint
|| ccc || || ccc ||
\ \
`); `);
return expect(data).toXMLEqual(`\ expect(data).toXMLEqual(`\
<problem> <problem>
<label>Checkboxes</label> <label>Checkboxes</label>
<choiceresponse> <choiceresponse>
...@@ -902,7 +897,7 @@ describe('Markdown to xml extended hint with tricky syntax cases', function() { ...@@ -902,7 +897,7 @@ describe('Markdown to xml extended hint with tricky syntax cases', function() {
|| Ø || || Ø ||
\ \
`); `);
return expect(data).toXMLEqual(`\ expect(data).toXMLEqual(`\
<problem> <problem>
<multiplechoiceresponse> <multiplechoiceresponse>
<label>á and Ø</label> <label>á and Ø</label>
...@@ -928,7 +923,7 @@ describe('Markdown to xml extended hint with tricky syntax cases', function() { ...@@ -928,7 +923,7 @@ describe('Markdown to xml extended hint with tricky syntax cases', function() {
(x) "isn't" {{ "hello" }} (x) "isn't" {{ "hello" }}
\ \
`); `);
return expect(data).toXMLEqual(`\ expect(data).toXMLEqual(`\
<problem> <problem>
<multiplechoiceresponse> <multiplechoiceresponse>
<label>"quotes" aren't \`fun\`</label> <label>"quotes" aren't \`fun\`</label>
...@@ -953,7 +948,7 @@ this (x) ...@@ -953,7 +948,7 @@ this (x)
(x) b (x) b
that (y)\ that (y)\
`); `);
return expect(data).toXMLEqual(`\ expect(data).toXMLEqual(`\
<problem> <problem>
<multiplechoiceresponse> <multiplechoiceresponse>
<label>q1</label> <label>q1</label>
...@@ -980,7 +975,7 @@ this [x] ...@@ -980,7 +975,7 @@ this [x]
[x] b {{ this hint passes through }} [x] b {{ this hint passes through }}
that []\ that []\
`); `);
return expect(data).toXMLEqual(`\ expect(data).toXMLEqual(`\
<problem> <problem>
<choiceresponse> <choiceresponse>
<label>q1</label> <label>q1</label>
...@@ -999,7 +994,7 @@ that []\ ...@@ -999,7 +994,7 @@ that []\
// It's sort of a pain to edit DOS line endings without some editor or other "fixing" them // It's sort of a pain to edit DOS line endings without some editor or other "fixing" them
// for you. Therefore, we construct DOS line endings on the fly just for the test. // for you. Therefore, we construct DOS line endings on the fly just for the test.
return it('produces xml with DOS \r\n line endings', function() { it('produces xml with DOS \r\n line endings', function() {
let markdown = `\ let markdown = `\
>>q22<< >>q22<<
...@@ -1015,7 +1010,7 @@ that []\ ...@@ -1015,7 +1010,7 @@ that []\
`; `;
markdown = markdown.replace(/\n/g, '\r\n'); // make DOS line endings markdown = markdown.replace(/\n/g, '\r\n'); // make DOS line endings
const data = MarkdownEditingDescriptor.markdownToXml(markdown); const data = MarkdownEditingDescriptor.markdownToXml(markdown);
return expect(data).toXMLEqual(`\ expect(data).toXMLEqual(`\
<problem> <problem>
<optionresponse> <optionresponse>
<label>q22</label> <label>q22</label>
......
/*
* decaffeinate suggestions:
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
describe("TabsEditingDescriptor", function() { describe("TabsEditingDescriptor", function() {
beforeEach(function() { beforeEach(function() {
this.isInactiveClass = "is-inactive"; this.isInactiveClass = "is-inactive";
...@@ -22,7 +17,7 @@ describe("TabsEditingDescriptor", function() { ...@@ -22,7 +17,7 @@ describe("TabsEditingDescriptor", function() {
spyOn($.fn, 'hide').and.callThrough(); spyOn($.fn, 'hide').and.callThrough();
spyOn($.fn, 'show').and.callThrough(); spyOn($.fn, 'show').and.callThrough();
spyOn(TabsEditingDescriptor.Model, 'initialize'); spyOn(TabsEditingDescriptor.Model, 'initialize');
return spyOn(TabsEditingDescriptor.Model, 'updateValue'); spyOn(TabsEditingDescriptor.Model, 'updateValue');
}); });
afterEach(() => TabsEditingDescriptor.Model.modules= {}); afterEach(() => TabsEditingDescriptor.Model.modules= {});
...@@ -30,7 +25,7 @@ describe("TabsEditingDescriptor", function() { ...@@ -30,7 +25,7 @@ describe("TabsEditingDescriptor", function() {
describe("constructor", () => describe("constructor", () =>
it("first tab should be visible", function() { it("first tab should be visible", function() {
expect(this.descriptor.$tabs.first()).toHaveClass(this.isCurrent); expect(this.descriptor.$tabs.first()).toHaveClass(this.isCurrent);
return expect(this.descriptor.$content.first()).not.toHaveClass(this.isInactiveClass); expect(this.descriptor.$content.first()).not.toHaveClass(this.isInactiveClass);
}) })
); );
...@@ -41,7 +36,7 @@ describe("TabsEditingDescriptor", function() { ...@@ -41,7 +36,7 @@ describe("TabsEditingDescriptor", function() {
expect(this.descriptor.$content.eq(0)).toHaveClass(this.isInactiveClass); expect(this.descriptor.$content.eq(0)).toHaveClass(this.isInactiveClass);
expect(this.descriptor.$tabs.eq(1)).toHaveClass(this.isCurrent); expect(this.descriptor.$tabs.eq(1)).toHaveClass(this.isCurrent);
expect(this.descriptor.$content.eq(1)).not.toHaveClass(this.isInactiveClass); expect(this.descriptor.$content.eq(1)).not.toHaveClass(this.isInactiveClass);
return expect(this.tab_1_switch).toHaveBeenCalled(); expect(this.tab_1_switch).toHaveBeenCalled();
}); });
it("if click on current tab, nothing should happen", function() { it("if click on current tab, nothing should happen", function() {
...@@ -49,27 +44,27 @@ describe("TabsEditingDescriptor", function() { ...@@ -49,27 +44,27 @@ describe("TabsEditingDescriptor", function() {
const currentTab = this.descriptor.$tabs.filter(`.${this.isCurrent}`); const currentTab = this.descriptor.$tabs.filter(`.${this.isCurrent}`);
this.descriptor.$tabs.eq(0).trigger("click"); this.descriptor.$tabs.eq(0).trigger("click");
expect(this.descriptor.$tabs.filter(`.${this.isCurrent}`)).toEqual(currentTab); expect(this.descriptor.$tabs.filter(`.${this.isCurrent}`)).toEqual(currentTab);
return expect($.fn.trigger.calls.count()).toEqual(1); expect($.fn.trigger.calls.count()).toEqual(1);
}); });
return it("onSwitch function call", function() { it("onSwitch function call", function() {
this.descriptor.$tabs.eq(1).trigger("click"); this.descriptor.$tabs.eq(1).trigger("click");
expect(TabsEditingDescriptor.Model.updateValue).toHaveBeenCalled(); expect(TabsEditingDescriptor.Model.updateValue).toHaveBeenCalled();
return expect(this.tab_1_switch).toHaveBeenCalled(); expect(this.tab_1_switch).toHaveBeenCalled();
}); });
}); });
return describe("save", function() { describe("save", function() {
it("function for current tab should be called", function() { it("function for current tab should be called", function() {
this.descriptor.$tabs.eq(1).trigger("click"); this.descriptor.$tabs.eq(1).trigger("click");
const { data } = this.descriptor.save(); const { data } = this.descriptor.save();
return expect(this.tab_1_modelUpdate).toHaveBeenCalled(); expect(this.tab_1_modelUpdate).toHaveBeenCalled();
}); });
return it("detach click event", function() { it("detach click event", function() {
spyOn($.fn, "off"); spyOn($.fn, "off");
this.descriptor.save(); this.descriptor.save();
return expect($.fn.off).toHaveBeenCalledWith( expect($.fn.off).toHaveBeenCalledWith(
'click', 'click',
'.editor-tabs .tab', '.editor-tabs .tab',
this.descriptor.onSwitchEditor this.descriptor.onSwitchEditor
...@@ -84,28 +79,28 @@ describe("TabsEditingDescriptor special save cases", function() { ...@@ -84,28 +79,28 @@ describe("TabsEditingDescriptor special save cases", function() {
this.isCurrent = "current"; this.isCurrent = "current";
loadFixtures('tabs-edit.html'); loadFixtures('tabs-edit.html');
this.descriptor = new window.TabsEditingDescriptor($('.xblock')); this.descriptor = new window.TabsEditingDescriptor($('.xblock'));
return this.html_id = 'test_id'; this.html_id = 'test_id';
}); });
return describe("save", function() { describe("save", function() {
it("case: no init", function() { it("case: no init", function() {
const { data } = this.descriptor.save(); const { data } = this.descriptor.save();
return expect(data).toEqual(null); expect(data).toEqual(null);
}); });
it("case: no function in model update", function() { it("case: no function in model update", function() {
TabsEditingDescriptor.Model.initialize(this.html_id); TabsEditingDescriptor.Model.initialize(this.html_id);
const { data } = this.descriptor.save(); const { data } = this.descriptor.save();
return expect(data).toEqual(null); expect(data).toEqual(null);
}); });
return it("case: no function in model update, but value presented", function() { it("case: no function in model update, but value presented", function() {
this.tab_0_modelUpdate = jasmine.createSpy('tab_0_modelUpdate').and.returnValue(1); this.tab_0_modelUpdate = jasmine.createSpy('tab_0_modelUpdate').and.returnValue(1);
TabsEditingDescriptor.Model.addModelUpdate(this.html_id, 'Tab 0 Editor', this.tab_0_modelUpdate); TabsEditingDescriptor.Model.addModelUpdate(this.html_id, 'Tab 0 Editor', this.tab_0_modelUpdate);
this.descriptor.$tabs.eq(1).trigger("click"); this.descriptor.$tabs.eq(1).trigger("click");
expect(this.tab_0_modelUpdate).toHaveBeenCalled(); expect(this.tab_0_modelUpdate).toHaveBeenCalled();
const { data } = this.descriptor.save(); const { data } = this.descriptor.save();
return expect(data).toEqual(1); expect(data).toEqual(1);
}); });
}); });
}); });
/*
* decaffeinate suggestions:
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
describe("$.immediateDescendents", function() { describe("$.immediateDescendents", function() {
beforeEach(function() { beforeEach(function() {
setFixtures(`\ setFixtures(`\
...@@ -17,22 +12,22 @@ describe("$.immediateDescendents", function() { ...@@ -17,22 +12,22 @@ describe("$.immediateDescendents", function() {
` `
); );
return this.descendents = $('#jasmine-fixtures').immediateDescendents(".xblock").get(); this.descendents = $('#jasmine-fixtures').immediateDescendents(".xblock").get();
}); });
it("finds non-immediate children", function() { it("finds non-immediate children", function() {
return expect(this.descendents).toContain($('#grandchild').get(0)); expect(this.descendents).toContain($('#grandchild').get(0));
}); });
it("finds immediate children", function() { it("finds immediate children", function() {
return expect(this.descendents).toContain($('#child').get(0)); expect(this.descendents).toContain($('#child').get(0));
}); });
it("skips nested descendents", function() { it("skips nested descendents", function() {
return expect(this.descendents).not.toContain($('#nested').get(0)); expect(this.descendents).not.toContain($('#nested').get(0));
}); });
return it("finds 2 children", function() { it("finds 2 children", function() {
return expect(this.descendents.length).toBe(2); expect(this.descendents.length).toBe(2);
}); });
}); });
\ No newline at end of file
/*
* decaffeinate suggestions:
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
describe('Calculator', function() { describe('Calculator', function() {
const KEY = { const KEY = {
...@@ -19,16 +14,16 @@ describe('Calculator', function() { ...@@ -19,16 +14,16 @@ describe('Calculator', function() {
beforeEach(function() { beforeEach(function() {
loadFixtures('coffee/fixtures/calculator.html'); loadFixtures('coffee/fixtures/calculator.html');
return this.calculator = new Calculator; this.calculator = new Calculator;
}); });
describe('bind', function() { describe('bind', function() {
it('bind the calculator button', function() { it('bind the calculator button', function() {
return expect($('.calc')).toHandleWith('click', this.calculator.toggle); expect($('.calc')).toHandleWith('click', this.calculator.toggle);
}); });
it('bind key up on calculator', function() { it('bind key up on calculator', function() {
return expect($('#calculator_wrapper')).toHandle('keyup', this.calculator.handleKeyUpOnHint); expect($('#calculator_wrapper')).toHandle('keyup', this.calculator.handleKeyUpOnHint);
}); });
it('bind the help button', () => it('bind the help button', () =>
...@@ -37,10 +32,10 @@ describe('Calculator', function() { ...@@ -37,10 +32,10 @@ describe('Calculator', function() {
); );
it('bind the calculator submit', function() { it('bind the calculator submit', function() {
return expect($('form#calculator')).toHandleWith('submit', this.calculator.calculate); expect($('form#calculator')).toHandleWith('submit', this.calculator.calculate);
}); });
return xit('prevent default behavior on form submit', function() { xit('prevent default behavior on form submit', function() {
jasmine.stubRequests(); jasmine.stubRequests();
$('form#calculator').submit(function(e) { $('form#calculator').submit(function(e) {
expect(e.isDefaultPrevented()).toBeTruthy(); expect(e.isDefaultPrevented()).toBeTruthy();
...@@ -66,16 +61,16 @@ describe('Calculator', function() { ...@@ -66,16 +61,16 @@ describe('Calculator', function() {
return deferred.promise(); return deferred.promise();
}; };
return focus().then( focus().then(
() => expect($('#calculator_wrapper #calculator_input').focus).toHaveBeenCalled()).always(done); () => expect($('#calculator_wrapper #calculator_input').focus).toHaveBeenCalled()).always(done);
}); });
return it('toggle the close button on the calculator button', function() { it('toggle the close button on the calculator button', function() {
this.calculator.toggle(jQuery.Event("click")); this.calculator.toggle(jQuery.Event("click"));
expect($('.calc')).toHaveClass('closed'); expect($('.calc')).toHaveClass('closed');
this.calculator.toggle(jQuery.Event("click")); this.calculator.toggle(jQuery.Event("click"));
return expect($('.calc')).not.toHaveClass('closed'); expect($('.calc')).not.toHaveClass('closed');
}); });
}); });
...@@ -83,7 +78,7 @@ describe('Calculator', function() { ...@@ -83,7 +78,7 @@ describe('Calculator', function() {
it('show the help overlay', function() { it('show the help overlay', function() {
this.calculator.showHint(); this.calculator.showHint();
expect($('.help')).toHaveClass('shown'); expect($('.help')).toHaveClass('shown');
return expect($('.help')).toHaveAttr('aria-hidden', 'false'); expect($('.help')).toHaveAttr('aria-hidden', 'false');
}) })
); );
...@@ -92,7 +87,7 @@ describe('Calculator', function() { ...@@ -92,7 +87,7 @@ describe('Calculator', function() {
it('show the help overlay', function() { it('show the help overlay', function() {
this.calculator.hideHint(); this.calculator.hideHint();
expect($('.help')).not.toHaveClass('shown'); expect($('.help')).not.toHaveClass('shown');
return expect($('.help')).toHaveAttr('aria-hidden', 'true'); expect($('.help')).toHaveAttr('aria-hidden', 'true');
}) })
); );
...@@ -100,7 +95,7 @@ describe('Calculator', function() { ...@@ -100,7 +95,7 @@ describe('Calculator', function() {
it('on click hint button hint popup becomes visible ', function() { it('on click hint button hint popup becomes visible ', function() {
const e = jQuery.Event('click'); const e = jQuery.Event('click');
$('#calculator_hint').trigger(e); $('#calculator_hint').trigger(e);
return expect($('.help')).toHaveClass('shown'); expect($('.help')).toHaveClass('shown');
}) })
); );
...@@ -109,7 +104,7 @@ describe('Calculator', function() { ...@@ -109,7 +104,7 @@ describe('Calculator', function() {
this.calculator.showHint(); this.calculator.showHint();
const e = jQuery.Event('click'); const e = jQuery.Event('click');
$(document).trigger(e); $(document).trigger(e);
return expect($('.help')).not.toHaveClass('shown'); expect($('.help')).not.toHaveClass('shown');
}) })
); );
...@@ -118,7 +113,7 @@ describe('Calculator', function() { ...@@ -118,7 +113,7 @@ describe('Calculator', function() {
this.calculator.showHint(); this.calculator.showHint();
const e = jQuery.Event('click'); const e = jQuery.Event('click');
$('#calculator_input_help').trigger(e); $('#calculator_input_help').trigger(e);
return expect($('.help')).toHaveClass('shown'); expect($('.help')).toHaveClass('shown');
}) })
); );
...@@ -130,17 +125,17 @@ describe('Calculator', function() { ...@@ -130,17 +125,17 @@ describe('Calculator', function() {
expect(element.focus).toHaveBeenCalled(); expect(element.focus).toHaveBeenCalled();
expect(this.calculator.activeHint).toEqual(element); expect(this.calculator.activeHint).toEqual(element);
return expect(this.calculator.hintPopup).toHaveAttr('data-calculator-hint', element.attr('id')); expect(this.calculator.hintPopup).toHaveAttr('data-calculator-hint', element.attr('id'));
}); });
it('select the first hint if argument element is not passed', function() { it('select the first hint if argument element is not passed', function() {
this.calculator.selectHint(); this.calculator.selectHint();
return expect(this.calculator.activeHint.attr('id')).toEqual($('.hint-item').first().attr('id')); expect(this.calculator.activeHint.attr('id')).toEqual($('.hint-item').first().attr('id'));
}); });
return it('select the first hint if argument element is empty', function() { it('select the first hint if argument element is empty', function() {
this.calculator.selectHint([]); this.calculator.selectHint([]);
return expect(this.calculator.activeHint.attr('id')).toBe($('.hint-item').first().attr('id')); expect(this.calculator.activeHint.attr('id')).toBe($('.hint-item').first().attr('id'));
}); });
}); });
...@@ -150,28 +145,28 @@ describe('Calculator', function() { ...@@ -150,28 +145,28 @@ describe('Calculator', function() {
this.calculator.activeHint = $('.hint-item').eq(1); this.calculator.activeHint = $('.hint-item').eq(1);
this.calculator.prevHint(); this.calculator.prevHint();
return expect(this.calculator.activeHint.attr('id')).toBe($('.hint-item').eq(0).attr('id')); expect(this.calculator.activeHint.attr('id')).toBe($('.hint-item').eq(0).attr('id'));
}); });
it('if this was the second item, select the first one', function() { it('if this was the second item, select the first one', function() {
this.calculator.activeHint = $('.hint-item').eq(1); this.calculator.activeHint = $('.hint-item').eq(1);
this.calculator.prevHint(); this.calculator.prevHint();
return expect(this.calculator.activeHint.attr('id')).toBe($('.hint-item').eq(0).attr('id')); expect(this.calculator.activeHint.attr('id')).toBe($('.hint-item').eq(0).attr('id'));
}); });
it('if this was the first item, select the last one', function() { it('if this was the first item, select the last one', function() {
this.calculator.activeHint = $('.hint-item').eq(0); this.calculator.activeHint = $('.hint-item').eq(0);
this.calculator.prevHint(); this.calculator.prevHint();
return expect(this.calculator.activeHint.attr('id')).toBe($('.hint-item').eq(2).attr('id')); expect(this.calculator.activeHint.attr('id')).toBe($('.hint-item').eq(2).attr('id'));
}); });
return it('if this was the last item, select the second last', function() { it('if this was the last item, select the second last', function() {
this.calculator.activeHint = $('.hint-item').eq(2); this.calculator.activeHint = $('.hint-item').eq(2);
this.calculator.prevHint(); this.calculator.prevHint();
return expect(this.calculator.activeHint.attr('id')).toBe($('.hint-item').eq(1).attr('id')); expect(this.calculator.activeHint.attr('id')).toBe($('.hint-item').eq(1).attr('id'));
}); });
}); });
...@@ -181,21 +176,21 @@ describe('Calculator', function() { ...@@ -181,21 +176,21 @@ describe('Calculator', function() {
this.calculator.activeHint = $('.hint-item').eq(0); this.calculator.activeHint = $('.hint-item').eq(0);
this.calculator.nextHint(); this.calculator.nextHint();
return expect(this.calculator.activeHint.attr('id')).toBe($('.hint-item').eq(1).attr('id')); expect(this.calculator.activeHint.attr('id')).toBe($('.hint-item').eq(1).attr('id'));
}); });
it('If this was the second item, select the last one', function() { it('If this was the second item, select the last one', function() {
this.calculator.activeHint = $('.hint-item').eq(1); this.calculator.activeHint = $('.hint-item').eq(1);
this.calculator.nextHint(); this.calculator.nextHint();
return expect(this.calculator.activeHint.attr('id')).toBe($('.hint-item').eq(2).attr('id')); expect(this.calculator.activeHint.attr('id')).toBe($('.hint-item').eq(2).attr('id'));
}); });
return it('If this was the last item, select the first one', function() { it('If this was the last item, select the first one', function() {
this.calculator.activeHint = $('.hint-item').eq(2); this.calculator.activeHint = $('.hint-item').eq(2);
this.calculator.nextHint(); this.calculator.nextHint();
return expect(this.calculator.activeHint.attr('id')).toBe($('.hint-item').eq(0).attr('id')); expect(this.calculator.activeHint.attr('id')).toBe($('.hint-item').eq(0).attr('id'));
}); });
}); });
...@@ -208,7 +203,7 @@ describe('Calculator', function() { ...@@ -208,7 +203,7 @@ describe('Calculator', function() {
expect(calc.hideHint).toHaveBeenCalled; expect(calc.hideHint).toHaveBeenCalled;
expect(value).toBeFalsy(); expect(value).toBeFalsy();
return expect(e.isDefaultPrevented()).toBeTruthy(); expect(e.isDefaultPrevented()).toBeTruthy();
}; };
const assertHintIsVisible = function(calc, key) { const assertHintIsVisible = function(calc, key) {
...@@ -220,7 +215,7 @@ describe('Calculator', function() { ...@@ -220,7 +215,7 @@ describe('Calculator', function() {
expect(calc.showHint).toHaveBeenCalled; expect(calc.showHint).toHaveBeenCalled;
expect(value).toBeFalsy(); expect(value).toBeFalsy();
expect(e.isDefaultPrevented()).toBeTruthy(); expect(e.isDefaultPrevented()).toBeTruthy();
return expect(calc.activeHint.focus).toHaveBeenCalled(); expect(calc.activeHint.focus).toHaveBeenCalled();
}; };
const assertNothingHappens = function(calc, key) { const assertNothingHappens = function(calc, key) {
...@@ -230,31 +225,31 @@ describe('Calculator', function() { ...@@ -230,31 +225,31 @@ describe('Calculator', function() {
expect(calc.showHint).not.toHaveBeenCalled; expect(calc.showHint).not.toHaveBeenCalled;
expect(value).toBeTruthy(); expect(value).toBeTruthy();
return expect(e.isDefaultPrevented()).toBeFalsy(); expect(e.isDefaultPrevented()).toBeFalsy();
}; };
it('hint popup becomes hidden on press ENTER', function() { it('hint popup becomes hidden on press ENTER', function() {
return assertHintIsHidden(this.calculator, KEY.ENTER); assertHintIsHidden(this.calculator, KEY.ENTER);
}); });
it('hint popup becomes visible on press ENTER', function() { it('hint popup becomes visible on press ENTER', function() {
return assertHintIsVisible(this.calculator, KEY.ENTER); assertHintIsVisible(this.calculator, KEY.ENTER);
}); });
it('hint popup becomes hidden on press SPACE', function() { it('hint popup becomes hidden on press SPACE', function() {
return assertHintIsHidden(this.calculator, KEY.SPACE); assertHintIsHidden(this.calculator, KEY.SPACE);
}); });
it('hint popup becomes visible on press SPACE', function() { it('hint popup becomes visible on press SPACE', function() {
return assertHintIsVisible(this.calculator, KEY.SPACE); assertHintIsVisible(this.calculator, KEY.SPACE);
}); });
it('Nothing happens on press ALT', function() { it('Nothing happens on press ALT', function() {
return assertNothingHappens(this.calculator, KEY.ALT); assertNothingHappens(this.calculator, KEY.ALT);
}); });
return it('Nothing happens on press any other button', function() { it('Nothing happens on press any other button', function() {
return assertNothingHappens(this.calculator, KEY.DOWN); assertNothingHappens(this.calculator, KEY.DOWN);
}); });
}); });
...@@ -389,7 +384,7 @@ describe('Calculator', function() { ...@@ -389,7 +384,7 @@ describe('Calculator', function() {
} }
}; };
return $.each(cases, function(key, data) { $.each(cases, function(key, data) {
calc.hideHint.calls.reset(); calc.hideHint.calls.reset();
calc.prevHint.calls.reset(); calc.prevHint.calls.reset();
calc.nextHint.calls.reset(); calc.nextHint.calls.reset();
...@@ -412,16 +407,16 @@ describe('Calculator', function() { ...@@ -412,16 +407,16 @@ describe('Calculator', function() {
expect(e.isPropagationStopped()).toBeFalsy(); expect(e.isPropagationStopped()).toBeFalsy();
} }
return expect(value).toBe(data.returnedValue); expect(value).toBe(data.returnedValue);
}); });
}) })
); );
return describe('calculate', function() { describe('calculate', function() {
beforeEach(function() { beforeEach(function() {
$('#calculator_input').val('1+2'); $('#calculator_input').val('1+2');
spyOn($, 'getWithPrefix').and.callFake((url, data, callback) => callback({ result: 3 })); spyOn($, 'getWithPrefix').and.callFake((url, data, callback) => callback({ result: 3 }));
return this.calculator.calculate(); this.calculator.calculate();
}); });
it('send data to /calculate', () => it('send data to /calculate', () =>
...@@ -430,6 +425,6 @@ describe('Calculator', function() { ...@@ -430,6 +425,6 @@ describe('Calculator', function() {
, jasmine.any(Function)) , jasmine.any(Function))
); );
return it('update the calculator output', () => expect($('#calculator_output').val()).toEqual('3')); it('update the calculator output', () => expect($('#calculator_output').val()).toEqual('3'));
}); });
}); });
/*
* decaffeinate suggestions:
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
describe('Courseware', function() { describe('Courseware', function() {
describe('start', () => describe('start', () =>
it('binds the Logger', function() { it('binds the Logger', function() {
spyOn(Logger, 'bind'); spyOn(Logger, 'bind');
Courseware.start(); Courseware.start();
return expect(Logger.bind).toHaveBeenCalled(); expect(Logger.bind).toHaveBeenCalled();
}) })
); );
return describe('render', function() { describe('render', function() {
beforeEach(function() { beforeEach(function() {
jasmine.stubRequests(); jasmine.stubRequests();
this.courseware = new Courseware; this.courseware = new Courseware;
...@@ -30,11 +25,11 @@ describe('Courseware', function() { ...@@ -30,11 +25,11 @@ describe('Courseware', function() {
</div>\ </div>\
` `
); );
return this.courseware.render(); this.courseware.render();
}); });
it('ensure that the XModules have been loaded', () => expect(XBlock.initializeBlocks).toHaveBeenCalled()); it('ensure that the XModules have been loaded', () => expect(XBlock.initializeBlocks).toHaveBeenCalled());
return it('detect the histrogram element and convert it', () => expect(window.Histogram).toHaveBeenCalledWith('3', [[0, 1]])); it('detect the histrogram element and convert it', () => expect(window.Histogram).toHaveBeenCalledWith('3', [[0, 1]]));
}); });
}); });
/*
* decaffeinate suggestions:
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
describe('FeedbackForm', function() { describe('FeedbackForm', function() {
beforeEach(() => loadFixtures('coffee/fixtures/feedback_form.html')); beforeEach(() => loadFixtures('coffee/fixtures/feedback_form.html'));
return describe('constructor', function() { describe('constructor', function() {
beforeEach(function() { beforeEach(function() {
new FeedbackForm; new FeedbackForm;
return spyOn($, 'postWithPrefix').and.callFake((url, data, callback, format) => callback()); spyOn($, 'postWithPrefix').and.callFake((url, data, callback, format) => callback());
}); });
it('post data to /send_feedback on click', function() { it('post data to /send_feedback on click', function() {
...@@ -17,17 +12,17 @@ describe('FeedbackForm', function() { ...@@ -17,17 +12,17 @@ describe('FeedbackForm', function() {
$('#feedback_message').val('This site is really good.'); $('#feedback_message').val('This site is really good.');
$('#feedback_button').click(); $('#feedback_button').click();
return expect($.postWithPrefix).toHaveBeenCalledWith('/send_feedback', { expect($.postWithPrefix).toHaveBeenCalledWith('/send_feedback', {
subject: 'Awesome!', subject: 'Awesome!',
message: 'This site is really good.', message: 'This site is really good.',
url: window.location.href url: window.location.href
}, jasmine.any(Function), 'json'); }, jasmine.any(Function), 'json');
}); });
return it('replace the form with a thank you message', function() { it('replace the form with a thank you message', function() {
$('#feedback_button').click(); $('#feedback_button').click();
return expect($('#feedback_div').html()).toEqual('Feedback submitted. Thank you'); expect($('#feedback_div').html()).toEqual('Feedback submitted. Thank you');
}); });
}); });
}); });
/* /*
* decaffeinate suggestions: * decaffeinate suggestions:
* DS102: Remove unnecessary code created because of implicit returns
* DS207: Consider shorter variations of null checks * DS207: Consider shorter variations of null checks
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/ */
......
/*
* decaffeinate suggestions:
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
describe('Histogram', function() { describe('Histogram', function() {
beforeEach(() => spyOn($, 'plot')); beforeEach(() => spyOn($, 'plot'));
...@@ -11,29 +6,29 @@ describe('Histogram', function() { ...@@ -11,29 +6,29 @@ describe('Histogram', function() {
const histogram = new Histogram(1, []); const histogram = new Histogram(1, []);
expect(histogram.xTicks).toEqual([]); expect(histogram.xTicks).toEqual([]);
expect(histogram.yTicks).toEqual([]); expect(histogram.yTicks).toEqual([]);
return expect(histogram.data).toEqual([]); expect(histogram.data).toEqual([]);
}) })
); );
describe('calculate', function() { describe('calculate', function() {
beforeEach(function() { beforeEach(function() {
return this.histogram = new Histogram(1, [[null, 1], [1, 1], [2, 2], [3, 3]]); this.histogram = new Histogram(1, [[null, 1], [1, 1], [2, 2], [3, 3]]);
}); });
it('store the correct value for data', function() { it('store the correct value for data', function() {
return expect(this.histogram.data).toEqual([[1, Math.log(2)], [2, Math.log(3)], [3, Math.log(4)]]); expect(this.histogram.data).toEqual([[1, Math.log(2)], [2, Math.log(3)], [3, Math.log(4)]]);
}); });
it('store the correct value for x ticks', function() { it('store the correct value for x ticks', function() {
return expect(this.histogram.xTicks).toEqual([[1, '1'], [2, '2'], [3, '3']]); expect(this.histogram.xTicks).toEqual([[1, '1'], [2, '2'], [3, '3']]);
}); });
return it('store the correct value for y ticks', function() { it('store the correct value for y ticks', function() {
return expect(this.histogram.yTicks).toEqual; expect(this.histogram.yTicks).toEqual;
}); });
}); });
return describe('render', () => describe('render', () =>
it('call flot with correct option', function() { it('call flot with correct option', function() {
new Histogram(1, [[1, 1], [2, 2], [3, 3]]); new Histogram(1, [[1, 1], [2, 2], [3, 3]]);
...@@ -53,7 +48,7 @@ describe('Histogram', function() { ...@@ -53,7 +48,7 @@ describe('Histogram', function() {
color: "#b72121" color: "#b72121"
} }
]); ]);
return expect(thirdArg).toEqual({ expect(thirdArg).toEqual({
xaxis: { xaxis: {
min: -1, min: -1,
max: 4, max: 4,
......
/*
* decaffeinate suggestions:
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
describe('Tab', function() { describe('Tab', function() {
beforeEach(function() { beforeEach(function() {
loadFixtures('coffee/fixtures/tab.html'); loadFixtures('coffee/fixtures/tab.html');
return this.items = $.parseJSON(readFixtures('coffee/fixtures/items.json')); this.items = $.parseJSON(readFixtures('coffee/fixtures/items.json'));
}); });
describe('constructor', function() { describe('constructor', function() {
beforeEach(function() { beforeEach(function() {
spyOn($.fn, 'tabs'); spyOn($.fn, 'tabs');
return this.tab = new Tab(1, this.items); this.tab = new Tab(1, this.items);
}); });
it('set the element', function() { it('set the element', function() {
return expect(this.tab.el).toEqual($('#tab_1')); expect(this.tab.el).toEqual($('#tab_1'));
}); });
it('build the tabs', function() { it('build the tabs', function() {
const links = $('.navigation li>a').map(function() { return $(this).attr('href'); }).get(); const links = $('.navigation li>a').map(function() { return $(this).attr('href'); }).get();
return expect(links).toEqual(['#tab-1-0', '#tab-1-1', '#tab-1-2']); expect(links).toEqual(['#tab-1-0', '#tab-1-1', '#tab-1-2']);
}); });
it('build the container', function() { it('build the container', function() {
const containers = $('section').map(function() { return $(this).attr('id'); }).get(); const containers = $('section').map(function() { return $(this).attr('id'); }).get();
return expect(containers).toEqual(['tab-1-0', 'tab-1-1', 'tab-1-2']); expect(containers).toEqual(['tab-1-0', 'tab-1-1', 'tab-1-2']);
}); });
return it('bind the tabs', function() { it('bind the tabs', function() {
return expect($.fn.tabs).toHaveBeenCalledWith({show: this.tab.onShow}); expect($.fn.tabs).toHaveBeenCalledWith({show: this.tab.onShow});
}); });
}); });
...@@ -39,23 +34,23 @@ describe('Tab', function() { ...@@ -39,23 +34,23 @@ describe('Tab', function() {
// The code below tests that onShow does what is expected, // The code below tests that onShow does what is expected,
// but note that onShow will NOT be called when the user // but note that onShow will NOT be called when the user
// clicks on the tab if we're using jQuery version >= 1.9 // clicks on the tab if we're using jQuery version >= 1.9
return describe('onShow', function() { describe('onShow', function() {
beforeEach(function() { beforeEach(function() {
this.tab = new Tab(1, this.items); this.tab = new Tab(1, this.items);
return this.tab.onShow($('#tab-1-0'), {'index': 1}); this.tab.onShow($('#tab-1-0'), {'index': 1});
}); });
it('replace content in the container', function() { it('replace content in the container', function() {
this.tab.onShow($('#tab-1-1'), {'index': 1}); this.tab.onShow($('#tab-1-1'), {'index': 1});
expect($('#tab-1-0').html()).toEqual(''); expect($('#tab-1-0').html()).toEqual('');
expect($('#tab-1-1').html()).toEqual('Video 2'); expect($('#tab-1-1').html()).toEqual('Video 2');
return expect($('#tab-1-2').html()).toEqual(''); expect($('#tab-1-2').html()).toEqual('');
}); });
return it('trigger contentChanged event on the element', function() { it('trigger contentChanged event on the element', function() {
spyOnEvent(this.tab.el, 'contentChanged'); spyOnEvent(this.tab.el, 'contentChanged');
this.tab.onShow($('#tab-1-1'), {'index': 1}); this.tab.onShow($('#tab-1-1'), {'index': 1});
return expect('contentChanged').toHaveBeenTriggeredOn(this.tab.el); expect('contentChanged').toHaveBeenTriggeredOn(this.tab.el);
}); });
}); });
}); });
...@@ -42,10 +42,10 @@ describe("RequireJS namespacing", function() { ...@@ -42,10 +42,10 @@ describe("RequireJS namespacing", function() {
it("check that the RequireJS object is present in the global namespace", function() { it("check that the RequireJS object is present in the global namespace", function() {
expect(RequireJS).toEqual(jasmine.any(Object)); expect(RequireJS).toEqual(jasmine.any(Object));
return expect(window.RequireJS).toEqual(jasmine.any(Object)); expect(window.RequireJS).toEqual(jasmine.any(Object));
}); });
return it("check that requirejs(), require(), and define() are not in the global namespace", function() { it("check that requirejs(), require(), and define() are not in the global namespace", function() {
// The custom matchers that we defined in the beforeEach() function do // The custom matchers that we defined in the beforeEach() function do
// not operate on an object. We pass a dummy empty object {} not to // not operate on an object. We pass a dummy empty object {} not to
...@@ -55,7 +55,7 @@ describe("RequireJS namespacing", function() { ...@@ -55,7 +55,7 @@ describe("RequireJS namespacing", function() {
expect({}).defineTobeUndefined(); expect({}).defineTobeUndefined();
expect(window.requirejs).not.toBeDefined(); expect(window.requirejs).not.toBeDefined();
expect(window.require).not.toBeDefined(); expect(window.require).not.toBeDefined();
return expect(window.define).not.toBeDefined(); expect(window.define).not.toBeDefined();
}); });
}); });
...@@ -63,7 +63,7 @@ describe("RequireJS namespacing", function() { ...@@ -63,7 +63,7 @@ describe("RequireJS namespacing", function() {
describe("RequireJS module creation", function() { describe("RequireJS module creation", function() {
let inDefineCallback = undefined; let inDefineCallback = undefined;
let inRequireCallback = undefined; let inRequireCallback = undefined;
return it("check that we can use RequireJS to define() and require() a module", function(done) { it("check that we can use RequireJS to define() and require() a module", function(done) {
const d1 = $.Deferred(); const d1 = $.Deferred();
const d2 = $.Deferred(); const d2 = $.Deferred();
// Because Require JS works asynchronously when defining and requiring // Because Require JS works asynchronously when defining and requiring
...@@ -105,10 +105,10 @@ describe("RequireJS module creation", function() { ...@@ -105,10 +105,10 @@ describe("RequireJS module creation", function() {
func(); func();
// We will wait before checking if our module was defined and that we were able to require() the module. // We will wait before checking if our module was defined and that we were able to require() the module.
return $.when(d1, d2).done(function() { $.when(d1, d2).done(function() {
// The final test behavior // The final test behavior
expect(inDefineCallback).toBeTruthy(); expect(inDefineCallback).toBeTruthy();
return expect(inRequireCallback).toBeTruthy(); expect(inRequireCallback).toBeTruthy();
}).always(done); }).always(done);
}); });
}); });
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