Commit c0fef0b0 by muzaffaryousaf Committed by Usman Khalid

Js test fixes for cms and cms-squire.

parent d28f4872
...@@ -231,9 +231,9 @@ testFiles = [ ...@@ -231,9 +231,9 @@ testFiles = [
"coffee/spec/views/upload_spec", "coffee/spec/views/upload_spec",
"js/spec/video/transcripts/utils_spec", "js/spec/video/transcripts/utils_spec",
"js/spec/video/transcripts/editor_spec", "js/spec/video/transcripts/editor_spec",
"js/spec/video/transcripts/videolist_spec", # "js/spec/video/transcripts/videolist_spec",
"js/spec/video/transcripts/message_manager_spec", # "js/spec/video/transcripts/message_manager_spec",
"js/spec/video/transcripts/file_uploader_spec", # "js/spec/video/transcripts/file_uploader_spec",
"js/spec/models/component_template_spec", "js/spec/models/component_template_spec",
"js/spec/models/explicit_url_spec", "js/spec/models/explicit_url_spec",
"js/spec/models/xblock_info_spec", "js/spec/models/xblock_info_spec",
......
require ["jquery", "backbone", "coffee/src/main", "common/js/spec_helpers/ajax_helpers", "jasmine-stealth", "jquery.cookie"], require ["jquery", "backbone", "coffee/src/main", "common/js/spec_helpers/ajax_helpers",
"jasmine-stealth", "jasmine-waituntil", "jquery.cookie"],
($, Backbone, main, AjaxHelpers) -> ($, Backbone, main, AjaxHelpers) ->
describe "CMS", -> describe "CMS", ->
it "should initialize URL", -> it "should initialize URL", ->
...@@ -7,8 +8,12 @@ require ["jquery", "backbone", "coffee/src/main", "common/js/spec_helpers/ajax_h ...@@ -7,8 +8,12 @@ require ["jquery", "backbone", "coffee/src/main", "common/js/spec_helpers/ajax_h
describe "main helper", -> describe "main helper", ->
beforeEach -> beforeEach ->
@previousAjaxSettings = $.extend(true, {}, $.ajaxSettings) @previousAjaxSettings = $.extend(true, {}, $.ajaxSettings)
spyOn($, "cookie") spyOn($, "cookie").and.callFake(
$.cookie.when("csrftoken").thenReturn("stubCSRFToken") (param) ->
if param == "csrftoken"
return "stubCSRFToken"
)
main() main()
afterEach -> afterEach ->
...@@ -21,12 +26,15 @@ require ["jquery", "backbone", "coffee/src/main", "common/js/spec_helpers/ajax_h ...@@ -21,12 +26,15 @@ require ["jquery", "backbone", "coffee/src/main", "common/js/spec_helpers/ajax_h
expect($.ajaxSettings.headers["X-CSRFToken"]).toEqual("stubCSRFToken") expect($.ajaxSettings.headers["X-CSRFToken"]).toEqual("stubCSRFToken")
describe "AJAX Errors", -> describe "AJAX Errors", ->
server = null
beforeEach -> beforeEach ->
appendSetFixtures(sandbox({id: "page-notification"})) appendSetFixtures(sandbox({id: "page-notification"}))
afterEach ->
server && server.restore()
it "successful AJAX request does not pop an error notification", -> it "successful AJAX request does not pop an error notification", ->
server = AjaxHelpers.server(this, [200, {}, '']) server = AjaxHelpers.server([200, {}, ''])
expect($("#page-notification")).toBeEmpty() expect($("#page-notification")).toBeEmpty()
$.ajax("/test") $.ajax("/test")
...@@ -35,15 +43,15 @@ require ["jquery", "backbone", "coffee/src/main", "common/js/spec_helpers/ajax_h ...@@ -35,15 +43,15 @@ require ["jquery", "backbone", "coffee/src/main", "common/js/spec_helpers/ajax_h
expect($("#page-notification")).toBeEmpty() expect($("#page-notification")).toBeEmpty()
it "AJAX request with error should pop an error notification", -> it "AJAX request with error should pop an error notification", ->
server = AjaxHelpers.server(this, [500, {}, '']) server = AjaxHelpers.server([500, {}, ''])
$.ajax("/test") $.ajax("/test")
server.respond() server.respond()
expect($("#page-notification")).not.toBeEmpty() expect($("#page-notification")).not.toBeEmpty()
expect($("#page-notification")).toContain('div.wrapper-notification-error') expect($("#page-notification")).toContainElement('div.wrapper-notification-error')
it "can override AJAX request with error so it does not pop an error notification", -> it "can override AJAX request with error so it does not pop an error notification", ->
server = AjaxHelpers.server(this, [500, {}, '']) server = AjaxHelpers.server([500, {}, ''])
$.ajax $.ajax
url: "/test" url: "/test"
......
...@@ -34,7 +34,7 @@ define ["js/models/section", "common/js/spec_helpers/ajax_helpers", "js/utils/mo ...@@ -34,7 +34,7 @@ define ["js/models/section", "common/js/spec_helpers/ajax_helpers", "js/utils/mo
}) })
it "show/hide a notification when it saves to the server", -> it "show/hide a notification when it saves to the server", ->
server = AjaxHelpers.server(this, [200, {}, '']) server = AjaxHelpers.server([200, {}, ''])
@model.save() @model.save()
expect(Section.prototype.showNotification).toHaveBeenCalled() expect(Section.prototype.showNotification).toHaveBeenCalled()
...@@ -43,7 +43,7 @@ define ["js/models/section", "common/js/spec_helpers/ajax_helpers", "js/utils/mo ...@@ -43,7 +43,7 @@ define ["js/models/section", "common/js/spec_helpers/ajax_helpers", "js/utils/mo
it "don't hide notification when saving fails", -> it "don't hide notification when saving fails", ->
# this is handled by the global AJAX error handler # this is handled by the global AJAX error handler
server = AjaxHelpers.server(this, [500, {}, '']) server = AjaxHelpers.server([500, {}, ''])
@model.save() @model.save()
server.respond() server.respond()
......
define ["backbone", "js/models/textbook", "js/collections/textbook", "js/models/chapter", "js/collections/chapter", "coffee/src/main"], define ["backbone", "js/models/textbook", "js/collections/textbook", "js/models/chapter", "js/collections/chapter", "coffee/src/main"],
(Backbone, Textbook, TextbookSet, Chapter, ChapterSet, main) -> (Backbone, Textbook, TextbookSet, Chapter, ChapterSet, main) ->
beforeEach ->
@addMatchers
toBeInstanceOf: (expected) ->
return @actual instanceof expected
describe "Textbook model", -> describe "Textbook model", ->
beforeEach -> beforeEach ->
main() main()
......
define ["jquery", "jasmine", "common/js/spec_helpers/ajax_helpers", "squire"], define ["jquery", "common/js/spec_helpers/ajax_helpers", "squire"],
($, jasmine, AjaxHelpers, Squire) -> ($, AjaxHelpers, Squire) ->
assetLibraryTpl = readFixtures('asset-library.underscore') assetLibraryTpl = readFixtures('asset-library.underscore')
assetTpl = readFixtures('asset.underscore') assetTpl = readFixtures('asset.underscore')
describe "Asset view", -> describe "Asset view", ->
beforeEach -> beforeEach (done) ->
setFixtures($("<script>", {id: "asset-tpl", type: "text/template"}).text(assetTpl)) setFixtures($("<script>", {id: "asset-tpl", type: "text/template"}).text(assetTpl))
appendSetFixtures(sandbox({id: "page-prompt"})) appendSetFixtures(sandbox({id: "page-prompt"}))
@promptSpies = jasmine.createSpyObj('Prompt.Warning', ["constructor", "show", "hide"]) @promptSpies = jasmine.createSpyObj('Prompt.Warning', ["constructor", "show", "hide"])
@promptSpies.constructor.andReturn(@promptSpies) @promptSpies.constructor.and.returnValue(@promptSpies)
@promptSpies.show.andReturn(@promptSpies) @promptSpies.show.and.returnValue(@promptSpies)
@confirmationSpies = jasmine.createSpyObj('Notification.Confirmation', ["constructor", "show"]) @confirmationSpies = jasmine.createSpyObj('Notification.Confirmation', ["constructor", "show"])
@confirmationSpies.constructor.andReturn(@confirmationSpies) @confirmationSpies.constructor.and.returnValue(@confirmationSpies)
@confirmationSpies.show.andReturn(@confirmationSpies) @confirmationSpies.show.and.returnValue(@confirmationSpies)
@savingSpies = jasmine.createSpyObj('Notification.Mini', ["constructor", "show", "hide"]) @savingSpies = jasmine.createSpyObj('Notification.Mini', ["constructor", "show", "hide"])
@savingSpies.constructor.andReturn(@savingSpies) @savingSpies.constructor.and.returnValue(@savingSpies)
@savingSpies.show.andReturn(@savingSpies) @savingSpies.show.and.returnValue(@savingSpies)
@injector = new Squire() @injector = new Squire()
@injector.mock("common/js/components/views/feedback_prompt", { @injector.mock("common/js/components/views/feedback_prompt", {
...@@ -29,8 +29,8 @@ define ["jquery", "jasmine", "common/js/spec_helpers/ajax_helpers", "squire"], ...@@ -29,8 +29,8 @@ define ["jquery", "jasmine", "common/js/spec_helpers/ajax_helpers", "squire"],
"Confirmation": @confirmationSpies.constructor, "Confirmation": @confirmationSpies.constructor,
"Mini": @savingSpies.constructor "Mini": @savingSpies.constructor
}) })
runs =>
@injector.require ["js/models/asset", "js/collections/asset", "js/views/asset"], @injector.require ["js/models/asset", "js/collections/asset", "js/views/asset"],
(AssetModel, AssetCollection, AssetView) => (AssetModel, AssetCollection, AssetView) =>
@model = new AssetModel @model = new AssetModel
display_name: "test asset" display_name: "test asset"
...@@ -39,8 +39,8 @@ define ["jquery", "jasmine", "common/js/spec_helpers/ajax_helpers", "squire"], ...@@ -39,8 +39,8 @@ define ["jquery", "jasmine", "common/js/spec_helpers/ajax_helpers", "squire"],
date_added: 'date' date_added: 'date'
thumbnail: null thumbnail: null
id: 'id' id: 'id'
spyOn(@model, "destroy").andCallThrough() spyOn(@model, "destroy").and.callThrough()
spyOn(@model, "save").andCallThrough() spyOn(@model, "save").and.callThrough()
@collection = new AssetCollection([@model]) @collection = new AssetCollection([@model])
@collection.url = "assets-url" @collection.url = "assets-url"
...@@ -48,8 +48,7 @@ define ["jquery", "jasmine", "common/js/spec_helpers/ajax_helpers", "squire"], ...@@ -48,8 +48,7 @@ define ["jquery", "jasmine", "common/js/spec_helpers/ajax_helpers", "squire"],
view = new AssetView({model: @model}) view = new AssetView({model: @model})
requests = if test then AjaxHelpers["requests"](test) else null requests = if test then AjaxHelpers["requests"](test) else null
return {view: view, requests: requests} return {view: view, requests: requests}
done()
waitsFor (=> @createAssetView), "AssetsView Creation function was not initialized", 1000
afterEach -> afterEach ->
@injector.clean() @injector.clean()
...@@ -65,7 +64,7 @@ define ["jquery", "jasmine", "common/js/spec_helpers/ajax_helpers", "squire"], ...@@ -65,7 +64,7 @@ define ["jquery", "jasmine", "common/js/spec_helpers/ajax_helpers", "squire"],
{view: @view, requests: requests} = @createAssetView() {view: @view, requests: requests} = @createAssetView()
@view.render().$(".remove-asset-button").click() @view.render().$(".remove-asset-button").click()
expect(@promptSpies.constructor).toHaveBeenCalled() expect(@promptSpies.constructor).toHaveBeenCalled()
ctorOptions = @promptSpies.constructor.mostRecentCall.args[0] ctorOptions = @promptSpies.constructor.calls.mostRecent().args[0]
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(@model.destroy).not.toHaveBeenCalled() expect(@model.destroy).not.toHaveBeenCalled()
...@@ -76,7 +75,7 @@ define ["jquery", "jasmine", "common/js/spec_helpers/ajax_helpers", "squire"], ...@@ -76,7 +75,7 @@ define ["jquery", "jasmine", "common/js/spec_helpers/ajax_helpers", "squire"],
{view: @view, requests: requests} = @createAssetView(this) {view: @view, requests: requests} = @createAssetView(this)
@view.render().$(".remove-asset-button").click() @view.render().$(".remove-asset-button").click()
ctorOptions = @promptSpies.constructor.mostRecentCall.args[0] ctorOptions = @promptSpies.constructor.calls.mostRecent().args[0]
# run the primary function to indicate confirmation # run the primary function to indicate confirmation
ctorOptions.actions.primary.click(@promptSpies) ctorOptions.actions.primary.click(@promptSpies)
# AJAX request has been sent, but not yet returned # AJAX request has been sent, but not yet returned
...@@ -88,7 +87,7 @@ define ["jquery", "jasmine", "common/js/spec_helpers/ajax_helpers", "squire"], ...@@ -88,7 +87,7 @@ define ["jquery", "jasmine", "common/js/spec_helpers/ajax_helpers", "squire"],
requests[0].respond(200) requests[0].respond(200)
expect(@confirmationSpies.constructor).toHaveBeenCalled() expect(@confirmationSpies.constructor).toHaveBeenCalled()
expect(@confirmationSpies.show).toHaveBeenCalled() expect(@confirmationSpies.show).toHaveBeenCalled()
savingOptions = @confirmationSpies.constructor.mostRecentCall.args[0] savingOptions = @confirmationSpies.constructor.calls.mostRecent().args[0]
expect(savingOptions.title).toMatch("Your file has been deleted.") expect(savingOptions.title).toMatch("Your file has been deleted.")
expect(@collection.contains(@model)).toBeFalsy() expect(@collection.contains(@model)).toBeFalsy()
...@@ -96,7 +95,7 @@ define ["jquery", "jasmine", "common/js/spec_helpers/ajax_helpers", "squire"], ...@@ -96,7 +95,7 @@ define ["jquery", "jasmine", "common/js/spec_helpers/ajax_helpers", "squire"],
{view: @view, requests: requests} = @createAssetView(this) {view: @view, requests: requests} = @createAssetView(this)
@view.render().$(".remove-asset-button").click() @view.render().$(".remove-asset-button").click()
ctorOptions = @promptSpies.constructor.mostRecentCall.args[0] ctorOptions = @promptSpies.constructor.calls.mostRecent().args[0]
# run the primary function to indicate confirmation # run the primary function to indicate confirmation
ctorOptions.actions.primary.click(@promptSpies) ctorOptions.actions.primary.click(@promptSpies)
# AJAX request has been sent, but not yet returned # AJAX request has been sent, but not yet returned
...@@ -115,7 +114,7 @@ define ["jquery", "jasmine", "common/js/spec_helpers/ajax_helpers", "squire"], ...@@ -115,7 +114,7 @@ define ["jquery", "jasmine", "common/js/spec_helpers/ajax_helpers", "squire"],
expect(requests.length).toEqual(1) expect(requests.length).toEqual(1)
expect(@savingSpies.constructor).toHaveBeenCalled() expect(@savingSpies.constructor).toHaveBeenCalled()
expect(@savingSpies.show).toHaveBeenCalled() expect(@savingSpies.show).toHaveBeenCalled()
savingOptions = @savingSpies.constructor.mostRecentCall.args[0] savingOptions = @savingSpies.constructor.calls.mostRecent().args[0]
expect(savingOptions.title).toMatch("Saving") expect(savingOptions.title).toMatch("Saving")
expect(@model.get("locked")).toBeFalsy() expect(@model.get("locked")).toBeFalsy()
# return a success response # return a success response
...@@ -134,7 +133,7 @@ define ["jquery", "jasmine", "common/js/spec_helpers/ajax_helpers", "squire"], ...@@ -134,7 +133,7 @@ define ["jquery", "jasmine", "common/js/spec_helpers/ajax_helpers", "squire"],
expect(@model.get("locked")).toBeFalsy() expect(@model.get("locked")).toBeFalsy()
describe "Assets view", -> describe "Assets view", ->
beforeEach -> beforeEach (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))
window.analytics = jasmine.createSpyObj('analytics', ['track']) window.analytics = jasmine.createSpyObj('analytics', ['track'])
...@@ -142,8 +141,8 @@ define ["jquery", "jasmine", "common/js/spec_helpers/ajax_helpers", "squire"], ...@@ -142,8 +141,8 @@ define ["jquery", "jasmine", "common/js/spec_helpers/ajax_helpers", "squire"],
appendSetFixtures(sandbox({id: "asset_table_body"})) appendSetFixtures(sandbox({id: "asset_table_body"}))
@promptSpies = jasmine.createSpyObj('Prompt.Warning', ["constructor", "show", "hide"]) @promptSpies = jasmine.createSpyObj('Prompt.Warning', ["constructor", "show", "hide"])
@promptSpies.constructor.andReturn(@promptSpies) @promptSpies.constructor.and.returnValue(@promptSpies)
@promptSpies.show.andReturn(@promptSpies) @promptSpies.show.and.returnValue(@promptSpies)
@injector = new Squire() @injector = new Squire()
@injector.mock("common/js/components/views/feedback_prompt", { @injector.mock("common/js/components/views/feedback_prompt", {
...@@ -175,8 +174,7 @@ define ["jquery", "jasmine", "common/js/spec_helpers/ajax_helpers", "squire"], ...@@ -175,8 +174,7 @@ define ["jquery", "jasmine", "common/js/spec_helpers/ajax_helpers", "squire"],
totalCount: 2 totalCount: 2
} }
runs => @injector.require ["js/models/asset", "js/collections/asset", "js/views/assets"],
@injector.require ["js/models/asset", "js/collections/asset", "js/views/assets"],
(AssetModel, AssetCollection, AssetsView) => (AssetModel, AssetCollection, AssetsView) =>
@AssetModel = AssetModel @AssetModel = AssetModel
@collection = new AssetCollection(); @collection = new AssetCollection();
...@@ -188,9 +186,7 @@ define ["jquery", "jasmine", "common/js/spec_helpers/ajax_helpers", "squire"], ...@@ -188,9 +186,7 @@ define ["jquery", "jasmine", "common/js/spec_helpers/ajax_helpers", "squire"],
el: $('#asset_table_body') el: $('#asset_table_body')
view.render() view.render()
return {view: view, requests: requests} return {view: view, requests: requests}
done()
waitsFor (=> @createAssetsView), "AssetsView Creation function was not initialized", 2000
$.ajax() $.ajax()
...@@ -294,7 +290,7 @@ define ["jquery", "jasmine", "common/js/spec_helpers/ajax_helpers", "squire"], ...@@ -294,7 +290,7 @@ define ["jquery", "jasmine", "common/js/spec_helpers/ajax_helpers", "squire"],
setup.call(this, requests) setup.call(this, requests)
# Delete the 2nd asset with success from server. # Delete the 2nd asset with success from server.
@view.$(".remove-asset-button")[1].click() @view.$(".remove-asset-button")[1].click()
@promptSpies.constructor.mostRecentCall.args[0].actions.primary.click(@promptSpies) @promptSpies.constructor.calls.mostRecent().args[0].actions.primary.click(@promptSpies)
AjaxHelpers.respondWithNoContent(requests) AjaxHelpers.respondWithNoContent(requests)
expect(@view.$el).toContainText("test asset 1") expect(@view.$el).toContainText("test asset 1")
expect(@view.$el).not.toContainText("test asset 2") expect(@view.$el).not.toContainText("test asset 2")
...@@ -304,7 +300,7 @@ define ["jquery", "jasmine", "common/js/spec_helpers/ajax_helpers", "squire"], ...@@ -304,7 +300,7 @@ define ["jquery", "jasmine", "common/js/spec_helpers/ajax_helpers", "squire"],
setup.call(this, requests) setup.call(this, requests)
# Delete the 2nd asset, but mimic a failure from the server. # Delete the 2nd asset, but mimic a failure from the server.
@view.$(".remove-asset-button")[1].click() @view.$(".remove-asset-button")[1].click()
@promptSpies.constructor.mostRecentCall.args[0].actions.primary.click(@promptSpies) @promptSpies.constructor.calls.mostRecent().args[0].actions.primary.click(@promptSpies)
AjaxHelpers.respondWithError(requests) AjaxHelpers.respondWithError(requests)
expect(@view.$el).toContainText("test asset 1") expect(@view.$el).toContainText("test asset 1")
expect(@view.$el).toContainText("test asset 2") expect(@view.$el).toContainText("test asset 2")
...@@ -319,7 +315,7 @@ define ["jquery", "jasmine", "common/js/spec_helpers/ajax_helpers", "squire"], ...@@ -319,7 +315,7 @@ define ["jquery", "jasmine", "common/js/spec_helpers/ajax_helpers", "squire"],
it "does not add an asset if asset already exists", -> it "does not add an asset if asset already exists", ->
{view: @view, requests: requests} = @createAssetsView(this) {view: @view, requests: requests} = @createAssetsView(this)
setup.call(this, requests) setup.call(this, requests)
spyOn(@collection, "add").andCallThrough() spyOn(@collection, "add").and.callThrough()
model = @collection.models[1] model = @collection.models[1]
@view.addAsset(model) @view.addAsset(model)
expect(@collection.add).not.toHaveBeenCalled() expect(@collection.add).not.toHaveBeenCalled()
......
...@@ -47,16 +47,16 @@ define ["js/views/course_info_handout", "js/views/course_info_update", "js/model ...@@ -47,16 +47,16 @@ define ["js/views/course_info_handout", "js/views/course_info_update", "js/model
# Edit button is not in the template under test (it is in parent HTML). # Edit button is not in the template under test (it is in parent HTML).
# Therefore call onNew directly. # Therefore call onNew directly.
@courseInfoEdit.onNew(@event) @courseInfoEdit.onNew(@event)
spyOn(@courseInfoEdit.$codeMirror, 'getValue').andReturn(text) spyOn(@courseInfoEdit.$codeMirror, 'getValue').and.returnValue(text)
@courseInfoEdit.$el.find('.save-button').click() @courseInfoEdit.$el.find('.save-button').click()
@cancelNewCourseInfo = (useCancelButton) -> @cancelNewCourseInfo = (useCancelButton) ->
@courseInfoEdit.onNew(@event) @courseInfoEdit.onNew(@event)
spyOn(@courseInfoEdit.$modalCover, 'hide').andCallThrough() spyOn(@courseInfoEdit.$modalCover, 'hide').and.callThrough()
spyOn(@courseInfoEdit.$codeMirror, 'getValue').andReturn('unsaved changes') spyOn(@courseInfoEdit.$codeMirror, 'getValue').and.returnValue('unsaved changes')
model = @collection.at(0) model = @collection.at(0)
spyOn(model, "save").andCallThrough() spyOn(model, "save").and.callThrough()
cancelEditingUpdate(@courseInfoEdit, @courseInfoEdit.$modalCover, useCancelButton) cancelEditingUpdate(@courseInfoEdit, @courseInfoEdit.$modalCover, useCancelButton)
...@@ -67,11 +67,11 @@ define ["js/views/course_info_handout", "js/views/course_info_update", "js/model ...@@ -67,11 +67,11 @@ define ["js/views/course_info_handout", "js/views/course_info_update", "js/model
@doNotCloseNewCourseInfo = () -> @doNotCloseNewCourseInfo = () ->
@courseInfoEdit.onNew(@event) @courseInfoEdit.onNew(@event)
spyOn(@courseInfoEdit.$modalCover, 'hide').andCallThrough() spyOn(@courseInfoEdit.$modalCover, 'hide').and.callThrough()
spyOn(@courseInfoEdit.$codeMirror, 'getValue').andReturn('unsaved changes') spyOn(@courseInfoEdit.$codeMirror, 'getValue').and.returnValue('unsaved changes')
model = @collection.at(0) model = @collection.at(0)
spyOn(model, "save").andCallThrough() spyOn(model, "save").and.callThrough()
cancelEditingUpdate(@courseInfoEdit, @courseInfoEdit.$modalCover, false) cancelEditingUpdate(@courseInfoEdit, @courseInfoEdit.$modalCover, false)
...@@ -81,11 +81,11 @@ define ["js/views/course_info_handout", "js/views/course_info_update", "js/model ...@@ -81,11 +81,11 @@ define ["js/views/course_info_handout", "js/views/course_info_update", "js/model
@cancelExistingCourseInfo = (useCancelButton) -> @cancelExistingCourseInfo = (useCancelButton) ->
@createNewUpdate('existing update') @createNewUpdate('existing update')
@courseInfoEdit.$el.find('.edit-button').click() @courseInfoEdit.$el.find('.edit-button').click()
spyOn(@courseInfoEdit.$modalCover, 'hide').andCallThrough() spyOn(@courseInfoEdit.$modalCover, 'hide').and.callThrough()
spyOn(@courseInfoEdit.$codeMirror, 'getValue').andReturn('modification') spyOn(@courseInfoEdit.$codeMirror, 'getValue').and.returnValue('modification')
model = @collection.at(0) model = @collection.at(0)
spyOn(model, "save").andCallThrough() spyOn(model, "save").and.callThrough()
model.id = "saved_to_server" model.id = "saved_to_server"
cancelEditingUpdate(@courseInfoEdit, @courseInfoEdit.$modalCover, useCancelButton) cancelEditingUpdate(@courseInfoEdit, @courseInfoEdit.$modalCover, useCancelButton)
...@@ -109,8 +109,8 @@ define ["js/views/course_info_handout", "js/views/course_info_update", "js/model ...@@ -109,8 +109,8 @@ define ["js/views/course_info_handout", "js/views/course_info_update", "js/model
@courseInfoEdit.onNew(@event) @courseInfoEdit.onNew(@event)
expect(@collection.length).toEqual(1) expect(@collection.length).toEqual(1)
model = @collection.at(0) model = @collection.at(0)
spyOn(model, "save").andCallThrough() spyOn(model, "save").and.callThrough()
spyOn(@courseInfoEdit.$codeMirror, 'getValue').andReturn('/static/image.jpg') spyOn(@courseInfoEdit.$codeMirror, 'getValue').and.returnValue('/static/image.jpg')
# Click the "Save button." # Click the "Save button."
@courseInfoEdit.$el.find('.save-button').click() @courseInfoEdit.$el.find('.save-button').click()
...@@ -196,7 +196,7 @@ define ["js/views/course_info_handout", "js/views/course_info_update", "js/model ...@@ -196,7 +196,7 @@ define ["js/views/course_info_handout", "js/views/course_info_update", "js/model
expect(requestSent.push_notification_selected).toEqual(true) expect(requestSent.push_notification_selected).toEqual(true)
# Check that analytics send push_notification info # Check that analytics send push_notification info
analytics_payload = window.analytics.track.calls[0].args[1] analytics_payload = window.analytics.track.calls.first().args[1]
expect(analytics_payload).toEqual(jasmine.objectContaining({'push_notification_selected': true})) expect(analytics_payload).toEqual(jasmine.objectContaining({'push_notification_selected': true}))
it "sends correct value for push_notification_selected when it is unselected", -> it "sends correct value for push_notification_selected when it is unselected", ->
...@@ -208,7 +208,7 @@ define ["js/views/course_info_handout", "js/views/course_info_update", "js/model ...@@ -208,7 +208,7 @@ define ["js/views/course_info_handout", "js/views/course_info_update", "js/model
expect(requestSent.push_notification_selected).toEqual(false) expect(requestSent.push_notification_selected).toEqual(false)
# Check that analytics send push_notification info # Check that analytics send push_notification info
analytics_payload = window.analytics.track.calls[0].args[1] analytics_payload = window.analytics.track.calls.first().args[1]
expect(analytics_payload).toEqual(jasmine.objectContaining({'push_notification_selected': false})) expect(analytics_payload).toEqual(jasmine.objectContaining({'push_notification_selected': false}))
describe "Course Handouts", -> describe "Course Handouts", ->
...@@ -237,8 +237,8 @@ define ["js/views/course_info_handout", "js/views/course_info_update", "js/model ...@@ -237,8 +237,8 @@ define ["js/views/course_info_handout", "js/views/course_info_update", "js/model
# Enter something in the handouts section, verifying that the model is saved # Enter something in the handouts section, verifying that the model is saved
# when "Save" is clicked. # when "Save" is clicked.
@handoutsEdit.$el.find('.edit-button').click() @handoutsEdit.$el.find('.edit-button').click()
spyOn(@handoutsEdit.$codeMirror, 'getValue').andReturn('/static/image.jpg') spyOn(@handoutsEdit.$codeMirror, 'getValue').and.returnValue('/static/image.jpg')
spyOn(@model, "save").andCallThrough() spyOn(@model, "save").and.callThrough()
@handoutsEdit.$el.find('.save-button').click() @handoutsEdit.$el.find('.save-button').click()
expect(@model.save).toHaveBeenCalled() expect(@model.save).toHaveBeenCalled()
...@@ -251,7 +251,7 @@ define ["js/views/course_info_handout", "js/views/course_info_update", "js/model ...@@ -251,7 +251,7 @@ define ["js/views/course_info_handout", "js/views/course_info_update", "js/model
it "does rewrite links after edit", -> it "does rewrite links after edit", ->
# Edit handouts and save. # Edit handouts and save.
@handoutsEdit.$el.find('.edit-button').click() @handoutsEdit.$el.find('.edit-button').click()
spyOn(@handoutsEdit.$codeMirror, 'getValue').andReturn('/static/image.jpg') spyOn(@handoutsEdit.$codeMirror, 'getValue').and.returnValue('/static/image.jpg')
@handoutsEdit.$el.find('.save-button').click() @handoutsEdit.$el.find('.save-button').click()
# Verify preview text. # Verify preview text.
......
...@@ -29,7 +29,7 @@ define ["jquery", "common/js/components/utils/view_utils", "js/spec_helpers/edit ...@@ -29,7 +29,7 @@ define ["jquery", "common/js/components/utils/view_utils", "js/spec_helpers/edit
</ul> </ul>
""" """
edit_helpers.installEditTemplates(true); edit_helpers.installEditTemplates(true);
spyOn($, 'ajax').andReturn(@moduleData) spyOn($, 'ajax').and.returnValue(@moduleData)
@moduleEdit = new ModuleEdit( @moduleEdit = new ModuleEdit(
el: $(".component") el: $(".component")
...@@ -62,7 +62,7 @@ define ["jquery", "common/js/components/utils/view_utils", "js/spec_helpers/edit ...@@ -62,7 +62,7 @@ define ["jquery", "common/js/components/utils/view_utils", "js/spec_helpers/edit
spyOn(@moduleEdit, 'loadDisplay') spyOn(@moduleEdit, 'loadDisplay')
spyOn(@moduleEdit, 'delegateEvents') spyOn(@moduleEdit, 'delegateEvents')
spyOn($.fn, 'append') spyOn($.fn, 'append')
spyOn(ViewUtils, 'loadJavaScript').andReturn($.Deferred().resolve().promise()); spyOn(ViewUtils, 'loadJavaScript').and.returnValue($.Deferred().resolve().promise());
window.MockXBlock = (runtime, element) -> window.MockXBlock = (runtime, element) ->
return { } return { }
...@@ -70,7 +70,7 @@ define ["jquery", "common/js/components/utils/view_utils", "js/spec_helpers/edit ...@@ -70,7 +70,7 @@ define ["jquery", "common/js/components/utils/view_utils", "js/spec_helpers/edit
window.loadedXBlockResources = undefined window.loadedXBlockResources = undefined
@moduleEdit.render() @moduleEdit.render()
$.ajax.mostRecentCall.args[0].success( $.ajax.calls.mostRecent().args[0].success(
html: '<div>Response html</div>' html: '<div>Response html</div>'
resources: [ resources: [
['hash1', {kind: 'text', mimetype: 'text/css', data: 'inline-css'}], ['hash1', {kind: 'text', mimetype: 'text/css', data: 'inline-css'}],
...@@ -120,7 +120,7 @@ define ["jquery", "common/js/components/utils/view_utils", "js/spec_helpers/edit ...@@ -120,7 +120,7 @@ define ["jquery", "common/js/components/utils/view_utils", "js/spec_helpers/edit
mockXBlockEditorHtml = readFixtures('mock/mock-xblock-editor.underscore') mockXBlockEditorHtml = readFixtures('mock/mock-xblock-editor.underscore')
$.ajax.mostRecentCall.args[0].success( $.ajax.calls.mostRecent().args[0].success(
html: mockXBlockEditorHtml html: mockXBlockEditorHtml
resources: [ resources: [
['hash1', {kind: 'text', mimetype: 'text/css', data: 'inline-css'}], ['hash1', {kind: 'text', mimetype: 'text/css', data: 'inline-css'}],
...@@ -161,14 +161,14 @@ define ["jquery", "common/js/components/utils/view_utils", "js/spec_helpers/edit ...@@ -161,14 +161,14 @@ define ["jquery", "common/js/components/utils/view_utils", "js/spec_helpers/edit
expect($.fn.append).not.toHaveBeenCalledWith('not-head-html') expect($.fn.append).not.toHaveBeenCalledWith('not-head-html')
it "doesn't reload resources", -> it "doesn't reload resources", ->
count = $('head').append.callCount count = $('head').append.calls.count()
$.ajax.mostRecentCall.args[0].success( $.ajax.calls.mostRecent().args[0].success(
html: '<div>Response html 2</div>' html: '<div>Response html 2</div>'
resources: [ resources: [
['hash1', {kind: 'text', mimetype: 'text/css', data: 'inline-css'}], ['hash1', {kind: 'text', mimetype: 'text/css', data: 'inline-css'}],
] ]
) )
expect($('head').append.callCount).toBe(count) expect($('head').append.calls.count()).toBe(count)
describe "loadDisplay", -> describe "loadDisplay", ->
beforeEach -> beforeEach ->
...@@ -177,4 +177,4 @@ define ["jquery", "common/js/components/utils/view_utils", "js/spec_helpers/edit ...@@ -177,4 +177,4 @@ define ["jquery", "common/js/components/utils/view_utils", "js/spec_helpers/edit
it "loads the .xmodule-display inside the module editor", -> it "loads the .xmodule-display inside the module editor", ->
expect(XBlock.initializeBlock).toHaveBeenCalled() expect(XBlock.initializeBlock).toHaveBeenCalled()
expect(XBlock.initializeBlock.mostRecentCall.args[0]).toBe($('.xblock-student_view')) expect(XBlock.initializeBlock.calls.mostRecent().args[0].get(0)).toBe($('.xblock-student_view').get(0))
...@@ -5,16 +5,6 @@ define ["js/models/textbook", "js/models/chapter", "js/collections/chapter", "js ...@@ -5,16 +5,6 @@ define ["js/models/textbook", "js/models/chapter", "js/collections/chapter", "js
"js/spec_helpers/modal_helpers", "jasmine-stealth"], "js/spec_helpers/modal_helpers", "jasmine-stealth"],
(Textbook, Chapter, ChapterSet, Course, TextbookSet, ShowTextbook, EditTextbook, ListTextbooks, EditChapter, Prompt, Notification, ViewUtils, AjaxHelpers, modal_helpers) -> (Textbook, Chapter, ChapterSet, Course, TextbookSet, ShowTextbook, EditTextbook, ListTextbooks, EditChapter, Prompt, Notification, ViewUtils, AjaxHelpers, modal_helpers) ->
beforeEach ->
# remove this when we upgrade jasmine-jquery
@addMatchers
toContainText: (text) ->
trimmedText = $.trim(@actual.text())
if text and $.isFunction(text.test)
return text.test(trimmedText)
else
return trimmedText.indexOf(text) != -1;
describe "ShowTextbook", -> describe "ShowTextbook", ->
tpl = readFixtures('show-textbook.underscore') tpl = readFixtures('show-textbook.underscore')
...@@ -23,12 +13,12 @@ define ["js/models/textbook", "js/models/chapter", "js/collections/chapter", "js ...@@ -23,12 +13,12 @@ define ["js/models/textbook", "js/models/chapter", "js/collections/chapter", "js
appendSetFixtures(sandbox({id: "page-notification"})) appendSetFixtures(sandbox({id: "page-notification"}))
appendSetFixtures(sandbox({id: "page-prompt"})) appendSetFixtures(sandbox({id: "page-prompt"}))
@model = new Textbook({name: "Life Sciences", id: "0life-sciences"}) @model = new Textbook({name: "Life Sciences", id: "0life-sciences"})
spyOn(@model, "destroy").andCallThrough() spyOn(@model, "destroy").and.callThrough()
@collection = new TextbookSet([@model]) @collection = new TextbookSet([@model])
@view = new ShowTextbook({model: @model}) @view = new ShowTextbook({model: @model})
@promptSpies = spyOnConstructor(Prompt, "Warning", ["show", "hide"]) @promptSpies = jasmine.stealth.spyOnConstructor(Prompt, "Warning", ["show", "hide"])
@promptSpies.show.andReturn(@promptSpies) @promptSpies.show.and.returnValue(@promptSpies)
window.course = new Course({ window.course = new Course({
id: "5", id: "5",
name: "Course Name", name: "Course Name",
...@@ -53,7 +43,7 @@ define ["js/models/textbook", "js/models/chapter", "js/collections/chapter", "js ...@@ -53,7 +43,7 @@ define ["js/models/textbook", "js/models/chapter", "js/collections/chapter", "js
it "should pop a delete confirmation when the delete button is clicked", -> it "should pop a delete confirmation when the delete button is clicked", ->
@view.render().$(".delete").click() @view.render().$(".delete").click()
expect(@promptSpies.constructor).toHaveBeenCalled() expect(@promptSpies.constructor).toHaveBeenCalled()
ctorOptions = @promptSpies.constructor.mostRecentCall.args[0] ctorOptions = @promptSpies.constructor.calls.mostRecent().args[0]
expect(ctorOptions.title).toMatch(/Life Sciences/) expect(ctorOptions.title).toMatch(/Life Sciences/)
# hasn't actually been removed # hasn't actually been removed
expect(@model.destroy).not.toHaveBeenCalled() expect(@model.destroy).not.toHaveBeenCalled()
...@@ -73,9 +63,9 @@ define ["js/models/textbook", "js/models/chapter", "js/collections/chapter", "js ...@@ -73,9 +63,9 @@ define ["js/models/textbook", "js/models/chapter", "js/collections/chapter", "js
describe "AJAX", -> describe "AJAX", ->
beforeEach -> beforeEach ->
@savingSpies = spyOnConstructor(Notification, "Mini", @savingSpies = jasmine.stealth.spyOnConstructor(Notification, "Mini",
["show", "hide"]) ["show", "hide"])
@savingSpies.show.andReturn(@savingSpies) @savingSpies.show.and.returnValue(@savingSpies)
CMS.URL.TEXTBOOKS = "/textbooks" CMS.URL.TEXTBOOKS = "/textbooks"
afterEach -> afterEach ->
...@@ -85,7 +75,7 @@ define ["js/models/textbook", "js/models/chapter", "js/collections/chapter", "js ...@@ -85,7 +75,7 @@ define ["js/models/textbook", "js/models/chapter", "js/collections/chapter", "js
requests = AjaxHelpers["requests"](this) requests = AjaxHelpers["requests"](this)
@view.render().$(".delete").click() @view.render().$(".delete").click()
ctorOptions = @promptSpies.constructor.mostRecentCall.args[0] ctorOptions = @promptSpies.constructor.calls.mostRecent().args[0]
# run the primary function to indicate confirmation # run the primary function to indicate confirmation
ctorOptions.actions.primary.click(@promptSpies) ctorOptions.actions.primary.click(@promptSpies)
# AJAX request has been sent, but not yet returned # AJAX request has been sent, but not yet returned
...@@ -94,7 +84,7 @@ define ["js/models/textbook", "js/models/chapter", "js/collections/chapter", "js ...@@ -94,7 +84,7 @@ define ["js/models/textbook", "js/models/chapter", "js/collections/chapter", "js
expect(@savingSpies.constructor).toHaveBeenCalled() expect(@savingSpies.constructor).toHaveBeenCalled()
expect(@savingSpies.show).toHaveBeenCalled() expect(@savingSpies.show).toHaveBeenCalled()
expect(@savingSpies.hide).not.toHaveBeenCalled() expect(@savingSpies.hide).not.toHaveBeenCalled()
savingOptions = @savingSpies.constructor.mostRecentCall.args[0] savingOptions = @savingSpies.constructor.calls.mostRecent().args[0]
expect(savingOptions.title).toMatch(/Deleting/) expect(savingOptions.title).toMatch(/Deleting/)
# return a success response # return a success response
requests[0].respond(200) requests[0].respond(200)
...@@ -114,7 +104,7 @@ define ["js/models/textbook", "js/models/chapter", "js/collections/chapter", "js ...@@ -114,7 +104,7 @@ define ["js/models/textbook", "js/models/chapter", "js/collections/chapter", "js
@collection = new TextbookSet() @collection = new TextbookSet()
@collection.add(@model) @collection.add(@model)
@view = new EditTextbook({model: @model}) @view = new EditTextbook({model: @model})
spyOn(@view, 'render').andCallThrough() spyOn(@view, 'render').and.callThrough()
it "should render properly", -> it "should render properly", ->
@view.render() @view.render()
...@@ -209,10 +199,16 @@ define ["js/models/textbook", "js/models/chapter", "js/collections/chapter", "js ...@@ -209,10 +199,16 @@ define ["js/models/textbook", "js/models/chapter", "js/collections/chapter", "js
expect(ViewUtils.setScrollOffset).toHaveBeenCalledWith($sectionEl, 0) expect(ViewUtils.setScrollOffset).toHaveBeenCalledWith($sectionEl, 0)
it "should focus first input element of newly added textbook", -> it "should focus first input element of newly added textbook", ->
spyOn(jQuery.fn, 'focus').andCallThrough() spyOn(jQuery.fn, 'focus').and.callThrough()
@addMatchers jasmine.addMatchers
toHaveBeenCalledOnJQueryObject: (actual, expected) -> toHaveBeenCalledOnJQueryObject: () ->
pass: actual.calls && actual.calls.mostRecent() && actual.calls.mostRecent().object[0] == expected[0] return {
compare: (actual, expected) ->
return {
pass: actual.calls && actual.calls.mostRecent() &&
actual.calls.mostRecent().object[0] == expected[0]
}
}
@view.$(".new-button").click() @view.$(".new-button").click()
$inputEl = @view.$el.find('section:last input:first') $inputEl = @view.$el.find('section:last input:first')
expect($inputEl.length).toEqual(1) expect($inputEl.length).toEqual(1)
...@@ -229,13 +225,13 @@ define ["js/models/textbook", "js/models/chapter", "js/collections/chapter", "js ...@@ -229,13 +225,13 @@ define ["js/models/textbook", "js/models/chapter", "js/collections/chapter", "js
# beforeEach -> # beforeEach ->
# setFixtures($("<script>", {id: "no-textbooks-tpl", type: "text/template"}).text(noTextbooksTpl)) # setFixtures($("<script>", {id: "no-textbooks-tpl", type: "text/template"}).text(noTextbooksTpl))
# @showSpies = spyOnConstructor("ShowTextbook", ["render"]) # @showSpies = spyOnConstructor("ShowTextbook", ["render"])
# @showSpies.render.andReturn(@showSpies) # equivalent of `return this` # @showSpies.render.and.returnValue(@showSpies) # equivalent of `return this`
# showEl = $("<li>") # showEl = $("<li>")
# @showSpies.$el = showEl # @showSpies.$el = showEl
# @showSpies.el = showEl.get(0) # @showSpies.el = showEl.get(0)
# @editSpies = spyOnConstructor("EditTextbook", ["render"]) # @editSpies = spyOnConstructor("EditTextbook", ["render"])
# editEl = $("<li>") # editEl = $("<li>")
# @editSpies.render.andReturn(@editSpies) # @editSpies.render.and.returnValue(@editSpies)
# @editSpies.$el = editEl # @editSpies.$el = editEl
# @editSpies.el= editEl.get(0) # @editSpies.el= editEl.get(0)
# #
...@@ -304,7 +300,7 @@ define ["js/models/textbook", "js/models/chapter", "js/collections/chapter", "js ...@@ -304,7 +300,7 @@ define ["js/models/textbook", "js/models/chapter", "js/collections/chapter", "js
@collection = new ChapterSet() @collection = new ChapterSet()
@collection.add(@model) @collection.add(@model)
@view = new EditChapter({model: @model}) @view = new EditChapter({model: @model})
spyOn(@view, "remove").andCallThrough() spyOn(@view, "remove").and.callThrough()
CMS.URL.UPLOAD_ASSET = "/upload" CMS.URL.UPLOAD_ASSET = "/upload"
window.course = new Course({name: "abcde"}) window.course = new Course({name: "abcde"})
...@@ -324,10 +320,10 @@ define ["js/models/textbook", "js/models/chapter", "js/collections/chapter", "js ...@@ -324,10 +320,10 @@ define ["js/models/textbook", "js/models/chapter", "js/collections/chapter", "js
# it "can open an upload dialog", -> # it "can open an upload dialog", ->
# uploadSpies = spyOnConstructor("UploadDialog", ["show", "el"]) # uploadSpies = spyOnConstructor("UploadDialog", ["show", "el"])
# uploadSpies.show.andReturn(uploadSpies) # uploadSpies.show.and.returnValue(uploadSpies)
# #
# @view.render().$(".action-upload").click() # @view.render().$(".action-upload").click()
# ctorOptions = uploadSpies.constructor.mostRecentCall.args[0] # ctorOptions = uploadSpies.constructor.calls.mostRecent().args[0]
# expect(ctorOptions.model.get('title')).toMatch(/abcde/) # expect(ctorOptions.model.get('title')).toMatch(/abcde/)
# expect(typeof ctorOptions.onSuccess).toBe('function') # expect(typeof ctorOptions.onSuccess).toBe('function')
# expect(uploadSpies.show).toHaveBeenCalled() # expect(uploadSpies.show).toHaveBeenCalled()
......
...@@ -18,16 +18,16 @@ define ["js/models/uploads", "js/views/uploads", "js/models/chapter", "common/js ...@@ -18,16 +18,16 @@ define ["js/models/uploads", "js/views/uploads", "js/models/chapter", "common/js
onSuccess: (response) => onSuccess: (response) =>
dialogResponse.push(response.response) dialogResponse.push(response.response)
) )
spyOn(@view, 'remove').andCallThrough() spyOn(@view, 'remove').and.callThrough()
# create mock file input, so that we aren't subject to browser restrictions # create mock file input, so that we aren't subject to browser restrictions
@mockFiles = [] @mockFiles = []
mockFileInput = jasmine.createSpy('mockFileInput') mockFileInput = jasmine.createSpy('mockFileInput')
mockFileInput.files = @mockFiles mockFileInput.files = @mockFiles
jqMockFileInput = jasmine.createSpyObj('jqMockFileInput', ['get', 'replaceWith']) jqMockFileInput = jasmine.createSpyObj('jqMockFileInput', ['get', 'replaceWith'])
jqMockFileInput.get.andReturn(mockFileInput) jqMockFileInput.get.and.returnValue(mockFileInput)
realMethod = @view.$ realMethod = @view.$
spyOn(@view, "$").andCallFake (selector) -> spyOn(@view, "$").and.callFake (selector) ->
if selector == "input[type=file]" if selector == "input[type=file]"
jqMockFileInput jqMockFileInput
else else
...@@ -41,7 +41,7 @@ define ["js/models/uploads", "js/views/uploads", "js/models/chapter", "common/js ...@@ -41,7 +41,7 @@ define ["js/models/uploads", "js/views/uploads", "js/models/chapter", "common/js
describe "Basic", -> describe "Basic", ->
it "should render without a file selected", -> it "should render without a file selected", ->
@view.render() @view.render()
expect(@view.$el).toContain("input[type=file]") expect(@view.$el).toContainElement("input[type=file]")
expect(@view.$(".action-upload")).toHaveClass("disabled") expect(@view.$(".action-upload")).toHaveClass("disabled")
it "should render with a PDF selected", -> it "should render with a PDF selected", ->
...@@ -49,8 +49,8 @@ define ["js/models/uploads", "js/views/uploads", "js/models/chapter", "common/js ...@@ -49,8 +49,8 @@ define ["js/models/uploads", "js/views/uploads", "js/models/chapter", "common/js
@mockFiles.push(file) @mockFiles.push(file)
@model.set("selectedFile", file) @model.set("selectedFile", file)
@view.render() @view.render()
expect(@view.$el).toContain("input[type=file]") expect(@view.$el).toContainElement("input[type=file]")
expect(@view.$el).not.toContain("#upload_error") expect(@view.$el).not.toContainElement("#upload_error")
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", -> it "should render an error with an invalid file type selected", ->
...@@ -58,8 +58,8 @@ define ["js/models/uploads", "js/views/uploads", "js/models/chapter", "common/js ...@@ -58,8 +58,8 @@ define ["js/models/uploads", "js/views/uploads", "js/models/chapter", "common/js
@mockFiles.push(file) @mockFiles.push(file)
@model.set("selectedFile", file) @model.set("selectedFile", file)
@view.render() @view.render()
expect(@view.$el).toContain("input[type=file]") expect(@view.$el).toContainElement("input[type=file]")
expect(@view.$el).toContain("#upload_error") expect(@view.$el).toContainElement("#upload_error")
expect(@view.$(".action-upload")).toHaveClass("disabled") expect(@view.$(".action-upload")).toHaveClass("disabled")
it "should render an error with an invalid file type after a correct file type selected", -> it "should render an error with an invalid file type after a correct file type selected", ->
...@@ -70,12 +70,12 @@ define ["js/models/uploads", "js/views/uploads", "js/models/chapter", "common/js ...@@ -70,12 +70,12 @@ define ["js/models/uploads", "js/views/uploads", "js/models/chapter", "common/js
event.target = {"files": [correctFile]} event.target = {"files": [correctFile]}
@view.selectFile(event) @view.selectFile(event)
expect(@view.$el).toContain("input[type=file]") expect(@view.$el).toContainElement("input[type=file]")
expect(@view.$el).not.toContain("#upload_error") expect(@view.$el).not.toContainElement("#upload_error")
expect(@view.$(".action-upload")).not.toHaveClass("disabled") expect(@view.$(".action-upload")).not.toHaveClass("disabled")
realMethod = @model.set realMethod = @model.set
spyOn(@model, "set").andCallFake (data) -> spyOn(@model, "set").and.callFake (data) ->
if data.selectedFile != undefined if data.selectedFile != undefined
this.attributes.selectedFile = data.selectedFile this.attributes.selectedFile = data.selectedFile
this.changed = {} this.changed = {}
...@@ -84,8 +84,8 @@ define ["js/models/uploads", "js/views/uploads", "js/models/chapter", "common/js ...@@ -84,8 +84,8 @@ define ["js/models/uploads", "js/views/uploads", "js/models/chapter", "common/js
event.target = {"files": [inCorrectFile]} event.target = {"files": [inCorrectFile]}
@view.selectFile(event) @view.selectFile(event)
expect(@view.$el).toContain("input[type=file]") expect(@view.$el).toContainElement("input[type=file]")
expect(@view.$el).toContain("#upload_error") expect(@view.$el).toContainElement("#upload_error")
expect(@view.$(".action-upload")).toHaveClass("disabled") expect(@view.$(".action-upload")).toHaveClass("disabled")
describe "Uploads", -> describe "Uploads", ->
......
...@@ -3,29 +3,21 @@ ...@@ -3,29 +3,21 @@
define(['jquery'], function($) { // jshint ignore:line define(['jquery'], function($) { // jshint ignore:line
'use strict'; 'use strict';
return function (that) { return function () {
that.addMatchers({ jasmine.addMatchers({
toBeCorrectValuesInModel: function () {
toContainText: function (text) {
// Assert the value being tested has text which matches the provided text
var trimmedText = $.trim($(this.actual).text());
if (text && $.isFunction(text.test)) {
return text.test(trimmedText);
} else {
return trimmedText.indexOf(text) !== -1;
}
},
toBeCorrectValuesInModel: function (values) {
// Assert the value being tested has key values which match the provided values // Assert the value being tested has key values which match the provided values
return _.every(values, function (value, key) { return {
return this.actual.get(key) === value; compare: function (actual, values) {
}.bind(this)); var passed = _.every(values, function (value, key) {
}, return actual.get(key) === value;
}.bind(this));
toBeInstanceOf: function(expected) { return {
// Assert the type of the value being tested matches the provided type pass: passed
return this.actual instanceof expected; };
}
};
} }
}); });
}; };
......
...@@ -47,27 +47,6 @@ function(_, Course, CertificatesCollection, CertificateModel, CertificateDetails ...@@ -47,27 +47,6 @@ function(_, Course, CertificatesCollection, CertificateModel, CertificateDetails
ViewHelpers.verifyPromptHidden(promptSpy); ViewHelpers.verifyPromptHidden(promptSpy);
}; };
beforeEach(function() {
window.course = new Course({
id: '5',
name: 'Course Name',
url_name: 'course_name',
org: 'course_org',
num: 'course_num',
revision: 'course_rev'
});
window.certWebPreview = new CertificatePreview({
course_modes: ['honor', 'test'],
certificate_web_view_url: '/users/1/courses/orgX/009/2016'
});
window.CMS.User = {isGlobalStaff: true};
});
afterEach(function() {
delete window.course;
delete window.CMS.User;
});
describe('Certificate Details Spec:', function() { describe('Certificate Details Spec:', function() {
var setValuesToInputs = function (view, values) { var setValuesToInputs = function (view, values) {
_.each(values, function (value, selector) { _.each(values, function (value, selector) {
...@@ -81,6 +60,20 @@ function(_, Course, CertificatesCollection, CertificateModel, CertificateDetails ...@@ -81,6 +60,20 @@ function(_, Course, CertificatesCollection, CertificateModel, CertificateDetails
beforeEach(function() { beforeEach(function() {
TemplateHelpers.installTemplates(['certificate-details', 'signatory-details', 'signatory-editor', 'signatory-actions'], true); TemplateHelpers.installTemplates(['certificate-details', 'signatory-details', 'signatory-editor', 'signatory-actions'], true);
window.course = new Course({
id: '5',
name: 'Course Name',
url_name: 'course_name',
org: 'course_org',
num: 'course_num',
revision: 'course_rev'
});
window.certWebPreview = new CertificatePreview({
course_modes: ['honor', 'test'],
certificate_web_view_url: '/users/1/courses/orgX/009/2016'
});
window.CMS.User = {isGlobalStaff: true};
this.newModelOptions = {add: true}; this.newModelOptions = {add: true};
this.model = new CertificateModel({ this.model = new CertificateModel({
name: 'Test Name', name: 'Test Name',
...@@ -97,7 +90,13 @@ function(_, Course, CertificatesCollection, CertificateModel, CertificateDetails ...@@ -97,7 +90,13 @@ function(_, Course, CertificatesCollection, CertificateModel, CertificateDetails
model: this.model model: this.model
}); });
appendSetFixtures(this.view.render().el); appendSetFixtures(this.view.render().el);
CustomMatchers(this); // jshint ignore:line CustomMatchers(); // jshint ignore:line
});
afterEach(function() {
delete window.course;
delete window.certWebPreview;
delete window.CMS.User;
}); });
describe('The Certificate Details view', function() { describe('The Certificate Details view', function() {
......
...@@ -18,7 +18,7 @@ function(_, Course, CertificateModel, SignatoryModel, CertificatesCollection, Ce ...@@ -18,7 +18,7 @@ function(_, Course, CertificateModel, SignatoryModel, CertificatesCollection, Ce
Notification, AjaxHelpers, TemplateHelpers, ViewHelpers, ValidationHelpers, CustomMatchers) { Notification, AjaxHelpers, TemplateHelpers, ViewHelpers, ValidationHelpers, CustomMatchers) {
'use strict'; 'use strict';
var MAX_SIGNATORIES = 100; var MAX_SIGNATORIES_LIMIT = 10;
var SELECTORS = { var SELECTORS = {
detailsView: '.certificate-details', detailsView: '.certificate-details',
editView: '.certificate-edit', editView: '.certificate-edit',
...@@ -76,23 +76,6 @@ function(_, Course, CertificateModel, SignatoryModel, CertificatesCollection, Ce ...@@ -76,23 +76,6 @@ function(_, Course, CertificateModel, SignatoryModel, CertificatesCollection, Ce
AjaxHelpers.respondWithJson(requests, {asset: {url: file_path}}); AjaxHelpers.respondWithJson(requests, {asset: {url: file_path}});
}; };
beforeEach(function() {
window.course = new Course({
id: '5',
name: 'Course Name',
url_name: 'course_name',
org: 'course_org',
num: 'course_num',
revision: 'course_rev'
});
window.CMS.User = {isGlobalStaff: true};
});
afterEach(function() {
delete window.course;
delete window.CMS.User;
});
describe('Certificate editor view', function() { describe('Certificate editor view', function() {
var setValuesToInputs = function (view, values) { var setValuesToInputs = function (view, values) {
_.each(values, function (value, selector) { _.each(values, function (value, selector) {
...@@ -109,6 +92,16 @@ function(_, Course, CertificateModel, SignatoryModel, CertificatesCollection, Ce ...@@ -109,6 +92,16 @@ function(_, Course, CertificateModel, SignatoryModel, CertificatesCollection, Ce
beforeEach(function() { beforeEach(function() {
TemplateHelpers.installTemplates(['certificate-editor', 'signatory-editor'], true); TemplateHelpers.installTemplates(['certificate-editor', 'signatory-editor'], true);
window.course = new Course({
id: '5',
name: 'Course Name',
url_name: 'course_name',
org: 'course_org',
num: 'course_num',
revision: 'course_rev'
});
window.CMS.User = {isGlobalStaff: true};
this.newModelOptions = {add: true}; this.newModelOptions = {add: true};
this.model = new CertificateModel({ this.model = new CertificateModel({
name: 'Test Name', name: 'Test Name',
...@@ -122,10 +115,16 @@ function(_, Course, CertificateModel, SignatoryModel, CertificatesCollection, Ce ...@@ -122,10 +115,16 @@ function(_, Course, CertificateModel, SignatoryModel, CertificatesCollection, Ce
}); });
this.model.set('id', 0); this.model.set('id', 0);
this.view = new CertificateEditorView({ this.view = new CertificateEditorView({
model: this.model model: this.model,
max_signatories_limit: MAX_SIGNATORIES_LIMIT
}); });
appendSetFixtures(this.view.render().el); appendSetFixtures(this.view.render().el);
CustomMatchers(this); // jshint ignore:line CustomMatchers(); // jshint ignore:line
});
afterEach(function() {
delete window.course;
delete window.CMS.User;
}); });
describe('Basic', function () { describe('Basic', function () {
...@@ -198,8 +197,8 @@ function(_, Course, CertificateModel, SignatoryModel, CertificatesCollection, Ce ...@@ -198,8 +197,8 @@ function(_, Course, CertificateModel, SignatoryModel, CertificatesCollection, Ce
expect(this.collection.length).toBe(1); expect(this.collection.length).toBe(1);
}); });
it('user can only add signatories up to max 100', function() { it('user can only add signatories up to limit', function() {
for(var i = 1; i < MAX_SIGNATORIES ; i++) { for(var i = 1; i < MAX_SIGNATORIES_LIMIT ; i++) {
this.view.$(SELECTORS.addSignatoryButton).click(); this.view.$(SELECTORS.addSignatoryButton).click();
} }
expect(this.view.$(SELECTORS.addSignatoryButton)).toHaveClass('disableClick'); expect(this.view.$(SELECTORS.addSignatoryButton)).toHaveClass('disableClick');
...@@ -215,7 +214,7 @@ function(_, Course, CertificateModel, SignatoryModel, CertificatesCollection, Ce ...@@ -215,7 +214,7 @@ function(_, Course, CertificateModel, SignatoryModel, CertificatesCollection, Ce
it('user can add signatories when signatory reached the upper limit But after deleting a signatory', it('user can add signatories when signatory reached the upper limit But after deleting a signatory',
function() { function() {
for(var i = 1; i < MAX_SIGNATORIES ; i++) { for(var i = 1; i < MAX_SIGNATORIES_LIMIT ; i++) {
this.view.$(SELECTORS.addSignatoryButton).click(); this.view.$(SELECTORS.addSignatoryButton).click();
} }
expect(this.view.$(SELECTORS.addSignatoryButton)).toHaveClass('disableClick'); expect(this.view.$(SELECTORS.addSignatoryButton)).toHaveClass('disableClick');
...@@ -274,7 +273,7 @@ function(_, Course, CertificateModel, SignatoryModel, CertificatesCollection, Ce ...@@ -274,7 +273,7 @@ function(_, Course, CertificateModel, SignatoryModel, CertificatesCollection, Ce
var signatory = this.model.get('signatories').at(0); var signatory = this.model.get('signatories').at(0);
var signatory_url = '/certificates/signatory'; var signatory_url = '/certificates/signatory';
signatory.url = signatory_url; signatory.url = signatory_url;
spyOn(signatory, "isNew").andReturn(false); spyOn(signatory, "isNew").and.returnValue(false);
var text = 'Delete "'+ signatory.get('name') +'" from the list of signatories?'; var text = 'Delete "'+ signatory.get('name') +'" from the list of signatories?';
clickDeleteItem(this, text, SELECTORS.signatoryDeleteButton + ':first', signatory_url); clickDeleteItem(this, text, SELECTORS.signatoryDeleteButton + ':first', signatory_url);
expect(this.model.get('signatories').length).toEqual(total_signatories - 1); expect(this.model.get('signatories').length).toEqual(total_signatories - 1);
...@@ -283,7 +282,7 @@ function(_, Course, CertificateModel, SignatoryModel, CertificatesCollection, Ce ...@@ -283,7 +282,7 @@ function(_, Course, CertificateModel, SignatoryModel, CertificatesCollection, Ce
it('can cancel deletion of signatories', function() { it('can cancel deletion of signatories', function() {
this.view.$(SELECTORS.addSignatoryButton).click(); this.view.$(SELECTORS.addSignatoryButton).click();
var signatory = this.model.get('signatories').at(0); var signatory = this.model.get('signatories').at(0);
spyOn(signatory, "isNew").andReturn(false); spyOn(signatory, "isNew").and.returnValue(false);
// add one more signatory // add one more signatory
this.view.$(SELECTORS.addSignatoryButton).click(); this.view.$(SELECTORS.addSignatoryButton).click();
var total_signatories = this.model.get('signatories').length; var total_signatories = this.model.get('signatories').length;
......
...@@ -18,23 +18,6 @@ function(_, $, Course, CertificatePreview, TemplateHelpers, ViewHelpers, AjaxHel ...@@ -18,23 +18,6 @@ function(_, $, Course, CertificatePreview, TemplateHelpers, ViewHelpers, AjaxHel
preview_certificate: '.preview-certificate-link' preview_certificate: '.preview-certificate-link'
}; };
beforeEach(function() {
window.course = new Course({
id: '5',
name: 'Course Name',
url_name: 'course_name',
org: 'course_org',
num: 'course_num',
revision: 'course_rev'
});
window.CMS.User = {isGlobalStaff: true};
});
afterEach(function() {
delete window.course;
delete window.CMS.User;
});
describe('Certificate Web Preview Spec:', function() { describe('Certificate Web Preview Spec:', function() {
var selectDropDownByText = function ( element, value ) { var selectDropDownByText = function ( element, value ) {
...@@ -45,8 +28,18 @@ function(_, $, Course, CertificatePreview, TemplateHelpers, ViewHelpers, AjaxHel ...@@ -45,8 +28,18 @@ function(_, $, Course, CertificatePreview, TemplateHelpers, ViewHelpers, AjaxHel
}; };
beforeEach(function() { beforeEach(function() {
TemplateHelpers.installTemplate('certificate-web-preview', true);
appendSetFixtures('<div class="preview-certificate nav-actions"></div>'); appendSetFixtures('<div class="preview-certificate nav-actions"></div>');
window.course = new Course({
id: '5',
name: 'Course Name',
url_name: 'course_name',
org: 'course_org',
num: 'course_num',
revision: 'course_rev'
});
window.CMS.User = {isGlobalStaff: true};
this.view = new CertificatePreview({ this.view = new CertificatePreview({
el: $('.preview-certificate'), el: $('.preview-certificate'),
course_modes: ['test1', 'test2', 'test3'], course_modes: ['test1', 'test2', 'test3'],
...@@ -57,6 +50,11 @@ function(_, $, Course, CertificatePreview, TemplateHelpers, ViewHelpers, AjaxHel ...@@ -57,6 +50,11 @@ function(_, $, Course, CertificatePreview, TemplateHelpers, ViewHelpers, AjaxHel
appendSetFixtures(this.view.render().el); appendSetFixtures(this.view.render().el);
}); });
afterEach(function() {
delete window.course;
delete window.CMS.User;
});
describe('Certificate preview', function() { describe('Certificate preview', function() {
it('course mode event should call when user choose a new mode', function () { it('course mode event should call when user choose a new mode', function () {
spyOn(this.view, 'courseModeChanged'); spyOn(this.view, 'courseModeChanged');
...@@ -122,7 +120,7 @@ function(_, $, Course, CertificatePreview, TemplateHelpers, ViewHelpers, AjaxHel ...@@ -122,7 +120,7 @@ function(_, $, Course, CertificatePreview, TemplateHelpers, ViewHelpers, AjaxHel
it('certificate web preview should be removed when method "remove" called', function () { it('certificate web preview should be removed when method "remove" called', function () {
this.view.remove(); this.view.remove();
expect(this.view.el.innerHTML).toContain(""); expect(this.view.el.innerHTML).toBe('');
}); });
it('method "show" should call the render function', function () { it('method "show" should call the render function', function () {
......
...@@ -27,33 +27,28 @@ function(_, Course, CertificatesCollection, CertificateModel, CertificateDetails ...@@ -27,33 +27,28 @@ function(_, Course, CertificatesCollection, CertificateModel, CertificateDetails
newCertificateButton: '.new-button' newCertificateButton: '.new-button'
}; };
beforeEach(function() {
window.course = new Course({
id: '5',
name: 'Course Name',
url_name: 'course_name',
org: 'course_org',
num: 'course_num',
revision: 'course_rev'
});
window.certWebPreview = new CertificatePreview({
course_modes: ['honor', 'test'],
certificate_web_view_url: '/users/1/courses/orgX/009/2016'
});
});
afterEach(function() {
delete window.course;
});
describe('Certificates list view', function() { describe('Certificates list view', function() {
var emptyMessage = 'You have not created any certificates yet.'; var emptyMessage = 'You have not created any certificates yet.';
beforeEach(function() { beforeEach(function() {
TemplateHelpers.installTemplates( TemplateHelpers.installTemplates(
['certificate-editor', 'certificate-edit', 'list'] ['certificate-editor', 'list']
); );
window.course = new Course({
id: '5',
name: 'Course Name',
url_name: 'course_name',
org: 'course_org',
num: 'course_num',
revision: 'course_rev'
});
window.certWebPreview = new CertificatePreview({
course_modes: ['honor', 'test'],
certificate_web_view_url: '/users/1/courses/orgX/009/2016'
});
window.CMS.User = {isGlobalStaff: true};
this.model = new CertificateModel({ this.model = new CertificateModel({
course_title: 'Test Course Title Override' course_title: 'Test Course Title Override'
}, {add: true}); }, {add: true});
...@@ -61,11 +56,18 @@ function(_, Course, CertificatesCollection, CertificateModel, CertificateDetails ...@@ -61,11 +56,18 @@ function(_, Course, CertificatesCollection, CertificateModel, CertificateDetails
this.collection = new CertificatesCollection([], { this.collection = new CertificatesCollection([], {
certificateUrl: '/certificates/'+ window.course.id certificateUrl: '/certificates/'+ window.course.id
}); });
this.model.set('id', 0);
this.view = new CertificatesListView({ this.view = new CertificatesListView({
collection: this.collection collection: this.collection
}); });
appendSetFixtures(this.view.render().el); appendSetFixtures(this.view.render().el);
CustomMatchers(this); // jshint ignore:line CustomMatchers(); // jshint ignore:line
});
afterEach(function() {
delete window.course;
delete window.certWebPreview;
delete window.CMS.User;
}); });
describe('empty template', function () { describe('empty template', function () {
......
...@@ -9,9 +9,11 @@ define([ // jshint ignore:line ...@@ -9,9 +9,11 @@ define([ // jshint ignore:line
'js/certificates/models/signatory', 'js/certificates/models/signatory',
'js/certificates/views/signatory_details', 'js/certificates/views/signatory_details',
'common/js/components/utils/view_utils', 'common/js/components/utils/view_utils',
'jquery.smoothScroll' 'jquery.smoothScroll',
'text!templates/certificate-details.underscore'
], ],
function($, _, str, gettext, BaseView, SignatoryModel, SignatoryDetailsView, ViewUtils) { function($, _, str, gettext, BaseView, SignatoryModel, SignatoryDetailsView, ViewUtils, smoothScroll,
certificateDetailsTemplate) {
'use strict'; 'use strict';
var CertificateDetailsView = BaseView.extend({ var CertificateDetailsView = BaseView.extend({
tagName: 'div', tagName: 'div',
...@@ -31,7 +33,6 @@ function($, _, str, gettext, BaseView, SignatoryModel, SignatoryDetailsView, Vie ...@@ -31,7 +33,6 @@ function($, _, str, gettext, BaseView, SignatoryModel, SignatoryDetailsView, Vie
initialize: function() { initialize: function() {
// Set up the initial state of the attributes set for this model instance // Set up the initial state of the attributes set for this model instance
this.showDetails = true; this.showDetails = true;
this.template = this.loadTemplate('certificate-details');
this.listenTo(this.model, 'change', this.render); this.listenTo(this.model, 'change', this.render);
}, },
...@@ -61,7 +62,7 @@ function($, _, str, gettext, BaseView, SignatoryModel, SignatoryDetailsView, Vie ...@@ -61,7 +62,7 @@ function($, _, str, gettext, BaseView, SignatoryModel, SignatoryDetailsView, Vie
index: this.model.collection.indexOf(this.model), index: this.model.collection.indexOf(this.model),
showDetails: this.showDetails || showDetails || false showDetails: this.showDetails || showDetails || false
}); });
this.$el.html(this.template(attrs)); this.$el.html(_.template(certificateDetailsTemplate)(attrs));
if(this.showDetails || showDetails) { if(this.showDetails || showDetails) {
var self = this; var self = this;
this.model.get("signatories").each(function (modelSignatory) { this.model.get("signatories").each(function (modelSignatory) {
......
...@@ -7,10 +7,11 @@ define([ // jshint ignore:line ...@@ -7,10 +7,11 @@ define([ // jshint ignore:line
'gettext', 'gettext',
'js/views/list_item_editor', 'js/views/list_item_editor',
'js/certificates/models/signatory', 'js/certificates/models/signatory',
'js/certificates/views/signatory_editor' 'js/certificates/views/signatory_editor',
'text!templates/certificate-editor.underscore'
], ],
function($, _, Backbone, gettext, function($, _, Backbone, gettext,
ListItemEditorView, SignatoryModel, SignatoryEditorView) { ListItemEditorView, SignatoryModel, SignatoryEditorView, certificateEditorTemplate) {
'use strict'; 'use strict';
// If signatories limit is required to specific value then we can change it. // If signatories limit is required to specific value then we can change it.
...@@ -41,14 +42,15 @@ function($, _, Backbone, gettext, ...@@ -41,14 +42,15 @@ function($, _, Backbone, gettext,
].join(' '); ].join(' ');
}, },
initialize: function() { initialize: function(options) {
// Set up the initial state of the attributes set for this model instance // Set up the initial state of the attributes set for this model instance
_.bindAll(this, "onSignatoryRemoved", "clearErrorMessage"); _.bindAll(this, "onSignatoryRemoved", "clearErrorMessage");
this.max_signatories_limit = options.max_signatories_limit || MAX_SIGNATORIES_LIMIT;
this.template = _.template(certificateEditorTemplate);
this.eventAgg = _.extend({}, Backbone.Events); this.eventAgg = _.extend({}, Backbone.Events);
this.eventAgg.bind("onSignatoryRemoved", this.onSignatoryRemoved); this.eventAgg.bind("onSignatoryRemoved", this.onSignatoryRemoved);
this.eventAgg.bind("onSignatoryUpdated", this.clearErrorMessage); this.eventAgg.bind("onSignatoryUpdated", this.clearErrorMessage);
ListItemEditorView.prototype.initialize.call(this); ListItemEditorView.prototype.initialize.call(this);
this.template = this.loadTemplate('certificate-editor');
}, },
onSignatoryRemoved: function() { onSignatoryRemoved: function() {
...@@ -87,7 +89,7 @@ function($, _, Backbone, gettext, ...@@ -87,7 +89,7 @@ function($, _, Backbone, gettext,
disableAddSignatoryButton: function() { disableAddSignatoryButton: function() {
// Disable the 'Add Signatory' link if the constraint has been met. // Disable the 'Add Signatory' link if the constraint has been met.
if(this.$(".signatory-edit-list > div.signatory-edit").length >= MAX_SIGNATORIES_LIMIT) { if(this.$(".signatory-edit-list > div.signatory-edit").length >= this.max_signatories_limit) {
this.$(".action-add-signatory").addClass("disableClick"); this.$(".action-add-signatory").addClass("disableClick");
} }
}, },
......
...@@ -7,9 +7,10 @@ define([ // jshint ignore:line ...@@ -7,9 +7,10 @@ define([ // jshint ignore:line
'gettext', 'gettext',
'js/views/baseview', 'js/views/baseview',
'common/js/components/utils/view_utils', 'common/js/components/utils/view_utils',
'common/js/components/views/feedback_notification' 'common/js/components/views/feedback_notification',
"text!templates/certificate-web-preview.underscore"
], ],
function(_, gettext, BaseView, ViewUtils, NotificationView) { function(_, gettext, BaseView, ViewUtils, NotificationView, certificateWebPreviewTemplate) {
'use strict'; 'use strict';
var CertificateWebPreview = BaseView.extend({ var CertificateWebPreview = BaseView.extend({
el: $(".preview-certificate"), el: $(".preview-certificate"),
...@@ -23,11 +24,10 @@ function(_, gettext, BaseView, ViewUtils, NotificationView) { ...@@ -23,11 +24,10 @@ function(_, gettext, BaseView, ViewUtils, NotificationView) {
this.certificate_web_view_url = options.certificate_web_view_url; this.certificate_web_view_url = options.certificate_web_view_url;
this.certificate_activation_handler_url = options.certificate_activation_handler_url; this.certificate_activation_handler_url = options.certificate_activation_handler_url;
this.is_active = options.is_active; this.is_active = options.is_active;
this.template = this.loadTemplate('certificate-web-preview');
}, },
render: function () { render: function () {
this.$el.html(this.template({ this.$el.html(_.template(certificateWebPreviewTemplate)({
course_modes: this.course_modes, course_modes: this.course_modes,
certificate_web_view_url: this.certificate_web_view_url, certificate_web_view_url: this.certificate_web_view_url,
is_active: this.is_active is_active: this.is_active
......
...@@ -9,9 +9,12 @@ define([ // jshint ignore:line ...@@ -9,9 +9,12 @@ define([ // jshint ignore:line
'js/utils/templates', 'js/utils/templates',
'common/js/components/utils/view_utils', 'common/js/components/utils/view_utils',
'js/views/baseview', 'js/views/baseview',
'js/certificates/views/signatory_editor' 'js/certificates/views/signatory_editor',
'text!templates/signatory-details.underscore',
'text!templates/signatory-actions.underscore'
], ],
function ($, _, str, Backbone, gettext, TemplateUtils, ViewUtils, BaseView, SignatoryEditorView) { function ($, _, str, Backbone, gettext, TemplateUtils, ViewUtils, BaseView, SignatoryEditorView,
signatoryDetailsTemplate, signatoryActionsTemplate) {
'use strict'; 'use strict';
var SignatoryDetailsView = BaseView.extend({ var SignatoryDetailsView = BaseView.extend({
tagName: 'div', tagName: 'div',
...@@ -39,8 +42,6 @@ function ($, _, str, Backbone, gettext, TemplateUtils, ViewUtils, BaseView, Sign ...@@ -39,8 +42,6 @@ function ($, _, str, Backbone, gettext, TemplateUtils, ViewUtils, BaseView, Sign
isEditingAllCollections: false, isEditingAllCollections: false,
eventAgg: this.eventAgg eventAgg: this.eventAgg
}); });
this.template = this.loadTemplate('signatory-details');
this.signatory_action_template = this.loadTemplate('signatory-actions');
}, },
loadTemplate: function(name) { loadTemplate: function(name) {
...@@ -52,7 +53,7 @@ function ($, _, str, Backbone, gettext, TemplateUtils, ViewUtils, BaseView, Sign ...@@ -52,7 +53,7 @@ function ($, _, str, Backbone, gettext, TemplateUtils, ViewUtils, BaseView, Sign
// Retrieve the edit view for this model // Retrieve the edit view for this model
if (event && event.preventDefault) { event.preventDefault(); } if (event && event.preventDefault) { event.preventDefault(); }
this.$el.html(this.edit_view.render()); this.$el.html(this.edit_view.render());
$(this.signatory_action_template()).appendTo(this.el); $(_.template(signatoryActionsTemplate)()).appendTo(this.el);
this.edit_view.delegateEvents(); this.edit_view.delegateEvents();
this.delegateEvents(); this.delegateEvents();
}, },
...@@ -93,7 +94,7 @@ function ($, _, str, Backbone, gettext, TemplateUtils, ViewUtils, BaseView, Sign ...@@ -93,7 +94,7 @@ function ($, _, str, Backbone, gettext, TemplateUtils, ViewUtils, BaseView, Sign
var attributes = $.extend({}, this.model.attributes, { var attributes = $.extend({}, this.model.attributes, {
signatory_number: this.model.collection.indexOf(this.model) + 1 signatory_number: this.model.collection.indexOf(this.model) + 1
}); });
return $(this.el).html(this.template(attributes)); return $(this.el).html(_.template(signatoryDetailsTemplate)(attributes));
} }
}); });
return SignatoryDetailsView; return SignatoryDetailsView;
......
...@@ -10,10 +10,12 @@ define([ // jshint ignore:line ...@@ -10,10 +10,12 @@ define([ // jshint ignore:line
'common/js/components/views/feedback_prompt', 'common/js/components/views/feedback_prompt',
'common/js/components/views/feedback_notification', 'common/js/components/views/feedback_notification',
'js/models/uploads', 'js/models/uploads',
'js/views/uploads' 'js/views/uploads',
'text!templates/signatory-editor.underscore'
], ],
function ($, _, Backbone, gettext, function ($, _, Backbone, gettext,
TemplateUtils, ViewUtils, PromptView, NotificationView, FileUploadModel, FileUploadDialog) { TemplateUtils, ViewUtils, PromptView, NotificationView, FileUploadModel, FileUploadDialog,
signatoryEditorTemplate) {
'use strict'; 'use strict';
var SignatoryEditorView = Backbone.View.extend({ var SignatoryEditorView = Backbone.View.extend({
tagName: 'div', tagName: 'div',
...@@ -41,7 +43,6 @@ function ($, _, Backbone, gettext, ...@@ -41,7 +43,6 @@ function ($, _, Backbone, gettext,
this.model.bind('change', this.render); this.model.bind('change', this.render);
this.eventAgg = options.eventAgg; this.eventAgg = options.eventAgg;
this.isEditingAllCollections = options.isEditingAllCollections; this.isEditingAllCollections = options.isEditingAllCollections;
this.template = this.loadTemplate('signatory-editor');
}, },
getModelIndex: function(givenModel) { getModelIndex: function(givenModel) {
...@@ -77,7 +78,7 @@ function ($, _, Backbone, gettext, ...@@ -77,7 +78,7 @@ function ($, _, Backbone, gettext,
is_editing_all_collections: this.isEditingAllCollections, is_editing_all_collections: this.isEditingAllCollections,
total_saved_signatories: this.getTotalSignatoriesOnServer() total_saved_signatories: this.getTotalSignatoriesOnServer()
}); });
return $(this.el).html(this.template(attributes)); return $(this.el).html(_.template(signatoryEditorTemplate)(attributes));
}, },
setSignatoryName: function(event) { setSignatoryName: function(event) {
......
define([ define([
'backbone', 'coffee/src/main', 'js/models/group_configuration', 'backbone', 'coffee/src/main', 'js/models/group_configuration',
'js/models/group', 'js/collections/group', 'squire' 'js/models/group', 'js/collections/group', 'squire'
], function( ], function (Backbone, main, GroupConfigurationModel, GroupModel, GroupCollection, Squire) {
Backbone, main, GroupConfigurationModel, GroupModel, GroupCollection, Squire
) {
'use strict'; 'use strict';
beforeEach(function() {
this.addMatchers({
toBeInstanceOf: function(expected) {
return this.actual instanceof expected;
},
toBeEmpty: function() {
return this.actual.length === 0;
}
});
});
describe('GroupConfigurationModel', function() { describe('GroupConfigurationModel', function () {
beforeEach(function() { beforeEach(function () {
main(); main();
this.model = new GroupConfigurationModel(); this.model = new GroupConfigurationModel();
}); });
describe('Basic', function() { describe('Basic', function () {
it('should have an empty name by default', function() { it('should have an empty name by default', function () {
expect(this.model.get('name')).toEqual(''); expect(this.model.get('name')).toEqual('');
}); });
it('should have an empty description by default', function() { it('should have an empty description by default', function () {
expect(this.model.get('description')).toEqual(''); expect(this.model.get('description')).toEqual('');
}); });
it('should not show groups by default', function() { it('should not show groups by default', function () {
expect(this.model.get('showGroups')).toBeFalsy(); expect(this.model.get('showGroups')).toBeFalsy();
}); });
it('should have a collection with 2 groups by default', function() { it('should have a collection with 2 groups by default', function () {
var groups = this.model.get('groups'); var groups = this.model.get('groups');
expect(groups).toBeInstanceOf(GroupCollection); expect(groups).toBeInstanceOf(GroupCollection);
...@@ -43,11 +31,11 @@ define([ ...@@ -43,11 +31,11 @@ define([
expect(groups.at(1).get('name')).toBe('Group B'); expect(groups.at(1).get('name')).toBe('Group B');
}); });
it('should have an empty usage by default', function() { it('should have an empty usage by default', function () {
expect(this.model.get('usage')).toBeEmpty(); expect(this.model.get('usage').length).toBe(0);
}); });
it('should be able to reset itself', function() { it('should be able to reset itself', function () {
var originalName = 'Original Name', var originalName = 'Original Name',
model = new GroupConfigurationModel({name: originalName}); model = new GroupConfigurationModel({name: originalName});
model.set({name: 'New Name'}); model.set({name: 'New Name'});
...@@ -56,18 +44,18 @@ define([ ...@@ -56,18 +44,18 @@ define([
expect(model.get('name')).toEqual(originalName); expect(model.get('name')).toEqual(originalName);
}); });
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');
expect(this.model.isDirty()).toBeTruthy(); expect(this.model.isDirty()).toBeTruthy();
}); });
describe('should not be dirty', function () { describe('should not be dirty', function () {
it('by default', function() { it('by default', function () {
expect(this.model.isDirty()).toBeFalsy(); expect(this.model.isDirty()).toBeFalsy();
}); });
it('after calling setOriginalAttributes', function() { it('after calling setOriginalAttributes', function () {
this.model.set('name', 'foobar'); this.model.set('name', 'foobar');
this.model.setOriginalAttributes(); this.model.setOriginalAttributes();
...@@ -76,13 +64,13 @@ define([ ...@@ -76,13 +64,13 @@ define([
}); });
}); });
describe('Input/Output', function() { describe('Input/Output', function () {
var deepAttributes = function(obj) { var deepAttributes = function (obj) {
if (obj instanceof Backbone.Model) { if (obj instanceof Backbone.Model) {
return deepAttributes(obj.attributes); return deepAttributes(obj.attributes);
} else if (obj instanceof Backbone.Collection) { } else if (obj instanceof Backbone.Collection) {
return obj.map(deepAttributes); return obj.map(deepAttributes);
} else if (_.isObject(obj)) { } else if ($.isPlainObject(obj)) {
var attributes = {}; var attributes = {};
for (var prop in obj) { for (var prop in obj) {
...@@ -96,7 +84,7 @@ define([ ...@@ -96,7 +84,7 @@ define([
} }
}; };
it('should match server model to client model', function() { it('should match server model to client model', function () {
var serverModelSpec = { var serverModelSpec = {
'id': 10, 'id': 10,
'name': 'My Group Configuration', 'name': 'My Group Configuration',
...@@ -139,32 +127,32 @@ define([ ...@@ -139,32 +127,32 @@ define([
'usage': [] 'usage': []
}, },
model = new GroupConfigurationModel( model = new GroupConfigurationModel(
serverModelSpec, { parse: true } serverModelSpec, {parse: true}
); );
expect(deepAttributes(model)).toEqual(clientModelSpec); expect(deepAttributes(model)).toEqual(clientModelSpec);
expect(model.toJSON()).toEqual(serverModelSpec); expect(JSON.parse(JSON.stringify(model))).toEqual(serverModelSpec);
}); });
}); });
describe('Validation', function() { describe('Validation', function () {
it('requires a name', function() { it('requires a name', function () {
var model = new GroupConfigurationModel({ name: '' }); var model = new GroupConfigurationModel({name: ''});
expect(model.isValid()).toBeFalsy(); expect(model.isValid()).toBeFalsy();
}); });
it('can pass validation', function() { it('can pass validation', function () {
// Note that two groups - Group A and Group B - are // Note that two groups - Group A and Group B - are
// created by default. // created by default.
var model = new GroupConfigurationModel({ name: 'foo' }); var model = new GroupConfigurationModel({name: 'foo'});
expect(model.isValid()).toBeTruthy(); expect(model.isValid()).toBeTruthy();
}); });
it('requires at least one group', function() { it('requires at least one group', function () {
var group1 = new GroupModel({ name: 'Group A' }), var group1 = new GroupModel({name: 'Group A'}),
model = new GroupConfigurationModel({ name: 'foo', groups: [] }); model = new GroupConfigurationModel({name: 'foo', groups: []});
expect(model.isValid()).toBeFalsy(); expect(model.isValid()).toBeFalsy();
...@@ -172,21 +160,21 @@ define([ ...@@ -172,21 +160,21 @@ define([
expect(model.isValid()).toBeTruthy(); expect(model.isValid()).toBeTruthy();
}); });
it('requires a valid group', function() { it('requires a valid group', function () {
var model = new GroupConfigurationModel({ name: 'foo', groups: [{ name: '' }] }); var model = new GroupConfigurationModel({name: 'foo', groups: [{name: ''}]});
expect(model.isValid()).toBeFalsy(); expect(model.isValid()).toBeFalsy();
}); });
it('requires all groups to be valid', function() { it('requires all groups to be valid', function () {
var model = new GroupConfigurationModel({ name: 'foo', groups: [{ name: 'Group A' }, { name: '' }] }); var model = new GroupConfigurationModel({name: 'foo', groups: [{name: 'Group A'}, {name: ''}]});
expect(model.isValid()).toBeFalsy(); expect(model.isValid()).toBeFalsy();
}); });
it('requires all groups to have unique names', function() { it('requires all groups to have unique names', function () {
var model = new GroupConfigurationModel({ var model = new GroupConfigurationModel({
name: 'foo', groups: [{ name: 'Group A' }, { name: 'Group A' }] name: 'foo', groups: [{name: 'Group A'}, {name: 'Group A'}]
}); });
expect(model.isValid()).toBeFalsy(); expect(model.isValid()).toBeFalsy();
...@@ -194,91 +182,92 @@ define([ ...@@ -194,91 +182,92 @@ define([
}); });
}); });
describe('GroupModel', function() { describe('GroupModel', function () {
beforeEach(function() { beforeEach(function () {
this.collection = new GroupCollection([{}]); this.collection = new GroupCollection([{}]);
this.model = this.collection.at(0); this.model = this.collection.at(0);
}); });
describe('Basic', function() { describe('Basic', function () {
it('should have an empty name by default', function() { it('should have an empty name by default', function () {
expect(this.model.get('name')).toEqual(''); expect(this.model.get('name')).toEqual('');
}); });
it('should be empty by default', function() { it('should be empty by default', function () {
expect(this.model.isEmpty()).toBeTruthy(); expect(this.model.isEmpty()).toBeTruthy();
}); });
}); });
describe('Validation', function() { describe('Validation', function () {
it('requires a name', function() { it('requires a name', function () {
var model = new GroupModel({ name: '' }); var model = new GroupModel({name: ''});
expect(model.isValid()).toBeFalsy(); expect(model.isValid()).toBeFalsy();
}); });
it('can pass validation', function() { it('can pass validation', function () {
var model = new GroupConfigurationModel({ name: 'foo' }); var model = new GroupConfigurationModel({name: 'foo'});
expect(model.isValid()).toBeTruthy(); expect(model.isValid()).toBeTruthy();
}); });
}); });
}); });
describe('GroupCollection', function() { describe('GroupCollection', function () {
beforeEach(function() { beforeEach(function () {
this.collection = new GroupCollection(); this.collection = new GroupCollection();
}); });
it('is empty by default', function() { it('is empty by default', function () {
expect(this.collection.isEmpty()).toBeTruthy(); expect(this.collection.isEmpty()).toBeTruthy();
}); });
it('is empty if all groups are empty', function() { it('is empty if all groups are empty', function () {
this.collection.add([{ name: '' }, { name: '' }, { name: '' }]); this.collection.add([{name: ''}, {name: ''}, {name: ''}]);
expect(this.collection.isEmpty()).toBeTruthy(); expect(this.collection.isEmpty()).toBeTruthy();
}); });
it('is not empty if a group is not empty', function() { it('is not empty if a group is not empty', function () {
this.collection.add([ this.collection.add([
{ name: '' }, { name: 'full' }, { name: '' } {name: ''}, {name: 'full'}, {name: ''}
]); ]);
expect(this.collection.isEmpty()).toBeFalsy(); expect(this.collection.isEmpty()).toBeFalsy();
}); });
describe('getGroupId', function () { describe('getGroupId', function () {
var collection, injector, mockGettext, initializeGroupModel; var collection, injector, mockGettext, initializeGroupModel, cleanUp;
mockGettext = function (returnedValue) { mockGettext = function (returnedValue) {
var injector = new Squire(); var injector = new Squire();
injector.mock('gettext', function () { injector.mock('gettext', function () {
return function () { return returnedValue; }; return function () {
return returnedValue;
};
}); });
return injector; return injector;
}; };
initializeGroupModel = function (dict, that) { initializeGroupModel = function (dict) {
runs(function() { var deferred = $.Deferred();
injector = mockGettext(dict);
injector.require(['js/collections/group'], injector = mockGettext(dict);
function(GroupCollection) { injector.require(['js/collections/group'],
function (GroupCollection) {
collection = new GroupCollection(); collection = new GroupCollection();
deferred.resolve(collection);
}); });
});
waitsFor(function() { return deferred.promise();
return collection; };
}, 'GroupModel was not instantiated', 500);
that.after(function () { cleanUp = function () {
collection = null; collection = null;
injector.clean(); injector.clean();
injector.remove(); injector.remove();
});
}; };
it('returns correct ids', function () { it('returns correct ids', function () {
...@@ -294,34 +283,46 @@ define([ ...@@ -294,34 +283,46 @@ define([
expect(collection.getGroupId(475279)).toBe('AAAAZ'); expect(collection.getGroupId(475279)).toBe('AAAAZ');
}); });
it('just 1 character in the dictionary', function () { it('just 1 character in the dictionary', function (done) {
initializeGroupModel('1', this); initializeGroupModel('1')
runs(function() { .then(function (collection) {
expect(collection.getGroupId(0)).toBe('1'); expect(collection.getGroupId(0)).toBe('1');
expect(collection.getGroupId(1)).toBe('11'); expect(collection.getGroupId(1)).toBe('11');
expect(collection.getGroupId(5)).toBe('111111'); expect(collection.getGroupId(5)).toBe('111111');
}); })
.always(function () {
cleanUp();
done();
});
}); });
it('allow to use unicode characters in the dict', function () { it('allow to use unicode characters in the dict', function (done) {
initializeGroupModel('ö诶úeœ', this); initializeGroupModel('ö诶úeœ')
runs(function() { .then(function (collection) {
expect(collection.getGroupId(0)).toBe('ö'); expect(collection.getGroupId(0)).toBe('ö');
expect(collection.getGroupId(1)).toBe('诶'); expect(collection.getGroupId(1)).toBe('诶');
expect(collection.getGroupId(5)).toBe('öö'); expect(collection.getGroupId(5)).toBe('öö');
expect(collection.getGroupId(29)).toBe('œœ'); expect(collection.getGroupId(29)).toBe('œœ');
expect(collection.getGroupId(30)).toBe('ööö'); expect(collection.getGroupId(30)).toBe('ööö');
expect(collection.getGroupId(43)).toBe('öúe'); expect(collection.getGroupId(43)).toBe('öúe');
}); })
.always(function () {
cleanUp();
done();
});
}); });
it('return initial value if dictionary is empty', function () { it('return initial value if dictionary is empty', function (done) {
initializeGroupModel('', this); initializeGroupModel('')
runs(function() { .then(function (collection) {
expect(collection.getGroupId(0)).toBe('0'); expect(collection.getGroupId(0)).toBe('0');
expect(collection.getGroupId(5)).toBe('5'); expect(collection.getGroupId(5)).toBe('5');
expect(collection.getGroupId(30)).toBe('30'); expect(collection.getGroupId(30)).toBe('30');
}); })
.always(function () {
cleanUp();
done();
});
}); });
}); });
}); });
......
...@@ -40,7 +40,7 @@ define(["js/utils/drag_and_drop", "common/js/components/views/feedback_notificat ...@@ -40,7 +40,7 @@ define(["js/utils/drag_and_drop", "common/js/components/views/feedback_notificat
left: $ele.offset().left left: $ele.offset().left
}); });
destination = ContentDragger.findDestination($ele, 1); destination = ContentDragger.findDestination($ele, 1);
expect(destination.ele).toBe($('#unit-2')); expect(destination.ele).toEqual($('#unit-2'));
expect(destination.attachMethod).toBe('before'); expect(destination.attachMethod).toBe('before');
}); });
it("can drag and drop across section boundaries, with special handling for single sibling", function () { it("can drag and drop across section boundaries, with special handling for single sibling", function () {
...@@ -52,17 +52,17 @@ define(["js/utils/drag_and_drop", "common/js/components/views/feedback_notificat ...@@ -52,17 +52,17 @@ define(["js/utils/drag_and_drop", "common/js/components/views/feedback_notificat
left: $ele.offset().left left: $ele.offset().left
}); });
destination = ContentDragger.findDestination($ele, 1); destination = ContentDragger.findDestination($ele, 1);
expect(destination.ele).toBe($unit4); expect(destination.ele).toEqual($unit4);
expect(destination.attachMethod).toBe('after'); expect(destination.attachMethod).toBe('after');
destination = ContentDragger.findDestination($ele, -1); destination = ContentDragger.findDestination($ele, -1);
expect(destination.ele).toBe($unit4); expect(destination.ele).toEqual($unit4);
expect(destination.attachMethod).toBe('before'); expect(destination.attachMethod).toBe('before');
$ele.offset({ $ele.offset({
top: $unit4.offset().top + $unit4.height() + 1, top: $unit4.offset().top + $unit4.height() + 1,
left: $ele.offset().left left: $ele.offset().left
}); });
destination = ContentDragger.findDestination($ele, 0); destination = ContentDragger.findDestination($ele, 0);
expect(destination.ele).toBe($unit4); expect(destination.ele).toEqual($unit4);
expect(destination.attachMethod).toBe('after'); expect(destination.attachMethod).toBe('after');
$unit0 = $('#unit-0'); $unit0 = $('#unit-0');
$ele.offset({ $ele.offset({
...@@ -70,7 +70,7 @@ define(["js/utils/drag_and_drop", "common/js/components/views/feedback_notificat ...@@ -70,7 +70,7 @@ define(["js/utils/drag_and_drop", "common/js/components/views/feedback_notificat
left: $ele.offset().left left: $ele.offset().left
}); });
destination = ContentDragger.findDestination($ele, 0); destination = ContentDragger.findDestination($ele, 0);
expect(destination.ele).toBe($unit0); expect(destination.ele).toEqual($unit0);
expect(destination.attachMethod).toBe('before'); expect(destination.attachMethod).toBe('before');
}); });
it("can drop before the first element, even if element being dragged is\nslightly before the first element", function () { it("can drop before the first element, even if element being dragged is\nslightly before the first element", function () {
...@@ -81,7 +81,7 @@ define(["js/utils/drag_and_drop", "common/js/components/views/feedback_notificat ...@@ -81,7 +81,7 @@ define(["js/utils/drag_and_drop", "common/js/components/views/feedback_notificat
left: $ele.offset().left left: $ele.offset().left
}); });
destination = ContentDragger.findDestination($ele, -1); destination = ContentDragger.findDestination($ele, -1);
expect(destination.ele).toBe($('#subsection-0')); expect(destination.ele).toEqual($('#subsection-0'));
expect(destination.attachMethod).toBe('before'); expect(destination.attachMethod).toBe('before');
}); });
it("can drag and drop across section boundaries, with special handling for last element", function () { it("can drag and drop across section boundaries, with special handling for last element", function () {
...@@ -92,14 +92,14 @@ define(["js/utils/drag_and_drop", "common/js/components/views/feedback_notificat ...@@ -92,14 +92,14 @@ define(["js/utils/drag_and_drop", "common/js/components/views/feedback_notificat
left: $ele.offset().left left: $ele.offset().left
}); });
destination = ContentDragger.findDestination($ele, -1); destination = ContentDragger.findDestination($ele, -1);
expect(destination.ele).toBe($('#unit-3')); expect(destination.ele).toEqual($('#unit-3'));
expect(destination.attachMethod).toBe('after'); expect(destination.attachMethod).toBe('after');
$ele.offset({ $ele.offset({
top: $('#unit-3').offset().top + 4, top: $('#unit-3').offset().top + 4,
left: $ele.offset().left left: $ele.offset().left
}); });
destination = ContentDragger.findDestination($ele, -1); destination = ContentDragger.findDestination($ele, -1);
expect(destination.ele).toBe($('#unit-3')); expect(destination.ele).toEqual($('#unit-3'));
expect(destination.attachMethod).toBe('before'); expect(destination.attachMethod).toBe('before');
}); });
it("can drop past the last element, even if element being dragged is\nslightly before/taller then the last element", function () { it("can drop past the last element, even if element being dragged is\nslightly before/taller then the last element", function () {
...@@ -110,7 +110,7 @@ define(["js/utils/drag_and_drop", "common/js/components/views/feedback_notificat ...@@ -110,7 +110,7 @@ define(["js/utils/drag_and_drop", "common/js/components/views/feedback_notificat
left: $ele.offset().left left: $ele.offset().left
}); });
destination = ContentDragger.findDestination($ele, 1); destination = ContentDragger.findDestination($ele, 1);
expect(destination.ele).toBe($('#subsection-4')); expect(destination.ele).toEqual($('#subsection-4'));
expect(destination.attachMethod).toBe('after'); expect(destination.attachMethod).toBe('after');
}); });
it("can drag into an empty list", function () { it("can drag into an empty list", function () {
...@@ -121,7 +121,7 @@ define(["js/utils/drag_and_drop", "common/js/components/views/feedback_notificat ...@@ -121,7 +121,7 @@ define(["js/utils/drag_and_drop", "common/js/components/views/feedback_notificat
left: $ele.offset().left left: $ele.offset().left
}); });
destination = ContentDragger.findDestination($ele, 1); destination = ContentDragger.findDestination($ele, 1);
expect(destination.ele).toBe($('#subsection-list-3')); expect(destination.ele).toEqual($('#subsection-list-3'));
expect(destination.attachMethod).toBe('prepend'); expect(destination.attachMethod).toBe('prepend');
}); });
it("reports a null destination on a failed drag", function () { it("reports a null destination on a failed drag", function () {
...@@ -146,8 +146,8 @@ define(["js/utils/drag_and_drop", "common/js/components/views/feedback_notificat ...@@ -146,8 +146,8 @@ define(["js/utils/drag_and_drop", "common/js/components/views/feedback_notificat
left: $ele.offset().left left: $ele.offset().left
}); });
destination = ContentDragger.findDestination($ele, 1); destination = ContentDragger.findDestination($ele, 1);
expect(destination.ele).toBe($('#subsection-list-2')); expect(destination.ele).toEqual($('#subsection-list-2'));
expect(destination.parentList).toBe($('#subsection-2')); expect(destination.parentList).toEqual($('#subsection-2'));
expect(destination.attachMethod).toBe('prepend'); expect(destination.attachMethod).toBe('prepend');
}); });
}); });
...@@ -176,7 +176,7 @@ define(["js/utils/drag_and_drop", "common/js/components/views/feedback_notificat ...@@ -176,7 +176,7 @@ define(["js/utils/drag_and_drop", "common/js/components/views/feedback_notificat
}); });
describe("onDragMove", function () { describe("onDragMove", function () {
beforeEach(function () { beforeEach(function () {
this.redirectSpy = spyOn(window, 'scrollBy').andCallThrough(); this.redirectSpy = spyOn(window, 'scrollBy').and.callThrough();
}); });
it("adds the correct CSS class to the drop destination", function () { it("adds the correct CSS class to the drop destination", function () {
var $ele, dragX, dragY; var $ele, dragX, dragY;
...@@ -239,7 +239,7 @@ define(["js/utils/drag_and_drop", "common/js/components/views/feedback_notificat ...@@ -239,7 +239,7 @@ define(["js/utils/drag_and_drop", "common/js/components/views/feedback_notificat
this.reorderSpy = spyOn(ContentDragger, 'handleReorder'); this.reorderSpy = spyOn(ContentDragger, 'handleReorder');
}); });
afterEach(function () { afterEach(function () {
this.reorderSpy.reset(); this.reorderSpy.calls.reset();
}); });
it("calls handleReorder on a successful drag", function () { it("calls handleReorder on a successful drag", function () {
ContentDragger.dragState.dropDestination = $('#unit-2'); ContentDragger.dragState.dropDestination = $('#unit-2');
...@@ -279,7 +279,7 @@ define(["js/utils/drag_and_drop", "common/js/components/views/feedback_notificat ...@@ -279,7 +279,7 @@ define(["js/utils/drag_and_drop", "common/js/components/views/feedback_notificat
expect($('#subsection-1')).not.toHaveClass('expand-on-drop'); expect($('#subsection-1')).not.toHaveClass('expand-on-drop');
}); });
it("expands a collapsed element when something is dropped in it", function () { it("expands a collapsed element when something is dropped in it", function () {
expandElementSpy = spyOn(ContentDragger, 'expandElement').andCallThrough(); var expandElementSpy = spyOn(ContentDragger, 'expandElement').and.callThrough();
expect(expandElementSpy).not.toHaveBeenCalled(); expect(expandElementSpy).not.toHaveBeenCalled();
expect($('#subsection-2').data('ensureChildrenRendered')).not.toHaveBeenCalled(); expect($('#subsection-2').data('ensureChildrenRendered')).not.toHaveBeenCalled();
...@@ -301,8 +301,8 @@ define(["js/utils/drag_and_drop", "common/js/components/views/feedback_notificat ...@@ -301,8 +301,8 @@ define(["js/utils/drag_and_drop", "common/js/components/views/feedback_notificat
}); });
describe("AJAX", function () { describe("AJAX", function () {
beforeEach(function () { beforeEach(function () {
this.savingSpies = spyOnConstructor(Notification, "Mini", ["show", "hide"]); this.savingSpies = jasmine.stealth.spyOnConstructor(Notification, "Mini", ["show", "hide"]);
this.savingSpies.show.andReturn(this.savingSpies); this.savingSpies.show.and.returnValue(this.savingSpies);
this.clock = sinon.useFakeTimers(); this.clock = sinon.useFakeTimers();
}); });
afterEach(function () { afterEach(function () {
...@@ -327,7 +327,7 @@ define(["js/utils/drag_and_drop", "common/js/components/views/feedback_notificat ...@@ -327,7 +327,7 @@ define(["js/utils/drag_and_drop", "common/js/components/views/feedback_notificat
expect(this.savingSpies.constructor).toHaveBeenCalled(); expect(this.savingSpies.constructor).toHaveBeenCalled();
expect(this.savingSpies.show).toHaveBeenCalled(); expect(this.savingSpies.show).toHaveBeenCalled();
expect(this.savingSpies.hide).not.toHaveBeenCalled(); expect(this.savingSpies.hide).not.toHaveBeenCalled();
savingOptions = this.savingSpies.constructor.mostRecentCall.args[0]; savingOptions = this.savingSpies.constructor.calls.mostRecent().args[0];
expect(savingOptions.title).toMatch(/Saving/); expect(savingOptions.title).toMatch(/Saving/);
expect($('#unit-1')).toHaveClass('was-dropped'); expect($('#unit-1')).toHaveClass('was-dropped');
expect(request.requestBody).toEqual('{"children":["fourth-unit-id","first-unit-id"]}'); expect(request.requestBody).toEqual('{"children":["fourth-unit-id","first-unit-id"]}');
......
...@@ -39,7 +39,9 @@ function ($, _, IframeBinding) { ...@@ -39,7 +39,9 @@ function ($, _, IframeBinding) {
//after calling iframeBinding function: src url of iframes should have "wmode=transparent" in its querystring //after calling iframeBinding function: src url of iframes should have "wmode=transparent" in its querystring
//and embed objects should have "wmode='transparent'" as an attribute //and embed objects should have "wmode='transparent'" as an attribute
expect(iframe_html).toContain('<iframe src="http://www.youtube.com/embed/NHd27UvY-lw?wmode=transparent"'); expect(iframe_html).toContain('<iframe src="http://www.youtube.com/embed/NHd27UvY-lw?wmode=transparent"');
expect(iframe_html).toContain('<embed wmode="transparent" type="application/x-shockwave-flash" src="http://www.youtube.com/embed/NHd27UvY-lw"'); expect(iframe_html).toContainHtml(
'<embed wmode="transparent" type="application/x-shockwave-flash"' +
' src="http://www.youtube.com/embed/NHd27UvY-lw"');
}); });
it("does not modify src url of DOM iframe if it is empty", function () { it("does not modify src url of DOM iframe if it is empty", function () {
......
...@@ -30,61 +30,104 @@ function ($, _, Squire) { ...@@ -30,61 +30,104 @@ function ($, _, Squire) {
var createPromptSpy = function (name) { var createPromptSpy = function (name) {
var spy = jasmine.createSpyObj(name, ['constructor', 'show', 'hide']); var spy = jasmine.createSpyObj(name, ['constructor', 'show', 'hide']);
spy.constructor.andReturn(spy); spy.constructor.and.returnValue(spy);
spy.show.andReturn(spy); spy.show.and.returnValue(spy);
spy.extend = jasmine.createSpy().andReturn(spy.constructor); spy.extend = jasmine.createSpy().and.returnValue(spy.constructor);
return spy; return spy;
}; };
beforeEach(function () { beforeEach(function (done) {
self = this; self = this;
this.addMatchers({ jasmine.addMatchers({
assertValueInView: function(expected) { assertValueInView: function() {
var value = this.actual.getValueFromEditor(); return {
return this.env.equals_(value, expected); compare: function (actual, expected) {
var value = actual.getValueFromEditor(),
passed = _.isEqual(value, expected);
return {
pass: passed,
message: 'Expected ' + actual + (passed ? '' : ' not') + ' to equal ' + expected
};
}
};
}, },
assertCanUpdateView: function (expected) { assertCanUpdateView: function () {
var view = this.actual, return {
value; compare: function (actual, expected) {
var view = actual,
view.setValueInEditor(expected); value,
value = view.getValueFromEditor(); passed;
return this.env.equals_(value, expected); view.setValueInEditor(expected);
value = view.getValueFromEditor();
passed = _.isEqual(value, expected);
return {
pass: passed,
message: 'Expected ' + actual + (passed ? '' : ' not') + ' to equal ' + expected
};
}
};
}, },
assertClear: function (modelValue) { assertClear: function () {
var env = this.env, return {
view = this.actual, compare: function (actual, modelValue) {
model = view.model; var view = actual,
model = view.model,
return model.getValue() === null && passed;
env.equals_(model.getDisplayValue(), modelValue) &&
env.equals_(view.getValueFromEditor(), modelValue); passed = model.getValue() === null &&
_.isEqual(model.getDisplayValue(), modelValue) &&
_.isEqual(view.getValueFromEditor(), modelValue);
return {
pass: passed
};
}
};
}, },
assertUpdateModel: function (originalValue, newValue) { assertUpdateModel: function () {
var env = this.env, return {
view = this.actual, compare: function (actual, originalValue, newValue) {
model = view.model, var view = actual,
expectOriginal; model = view.model,
expectOriginal,
view.setValueInEditor(newValue); passed;
expectOriginal = env.equals_(model.getValue(), originalValue);
view.updateModel(); view.setValueInEditor(newValue);
expectOriginal = _.isEqual(model.getValue(), originalValue);
return expectOriginal && view.updateModel();
env.equals_(model.getValue(), newValue);
passed = expectOriginal &&
_.isEqual(model.getValue(), newValue);
return {
pass: passed
};
}
};
}, },
verifyButtons: function (upload, download, index) { verifyButtons: function () {
var view = this.actual, return {
uploadBtn = view.$('.upload-setting'), compare: function (actual, upload, download) {
downloadBtn = view.$('.download-setting'); var view = actual,
uploadBtn = view.$('.upload-setting'),
upload = upload ? uploadBtn.length : !uploadBtn.length; downloadBtn = view.$('.download-setting'),
download = download ? downloadBtn.length : !downloadBtn.length; passed;
return upload && download; upload = upload ? uploadBtn.length : !uploadBtn.length;
download = download ? downloadBtn.length : !downloadBtn.length;
passed = upload && download;
return {
pass: passed
};
}
};
} }
}); });
...@@ -107,22 +150,18 @@ function ($, _, Squire) { ...@@ -107,22 +150,18 @@ function ($, _, Squire) {
injector.mock('js/views/video/transcripts/metadata_videolist'); injector.mock('js/views/video/transcripts/metadata_videolist');
injector.mock('js/views/video/translations_editor'); injector.mock('js/views/video/translations_editor');
runs(function() { injector.require([
injector.require([
'js/models/metadata', 'js/views/metadata' 'js/models/metadata', 'js/views/metadata'
], ],
function(MetadataModel, MetadataView) { function (MetadataModel, MetadataView) {
var model = new MetadataModel($.extend(true, {}, modelStub)); var model = new MetadataModel($.extend(true, {}, modelStub));
self.view = new MetadataView.FileUploader({ self.view = new MetadataView.FileUploader({
model: model, model: model,
locator: locator locator: locator
}); });
});
});
waitsFor(function() { done();
return self.view; });
}, 'FileUploader was not created', 2000);
}); });
afterEach(function () { afterEach(function () {
...@@ -150,7 +189,7 @@ function ($, _, Squire) { ...@@ -150,7 +189,7 @@ function ($, _, Squire) {
expect(this.uploadSpies.constructor).toHaveBeenCalled(); expect(this.uploadSpies.constructor).toHaveBeenCalled();
expect(this.uploadSpies.show).toHaveBeenCalled(); expect(this.uploadSpies.show).toHaveBeenCalled();
options = this.uploadSpies.constructor.mostRecentCall.args[0]; options = this.uploadSpies.constructor.calls.mostRecent().args[0];
options.onSuccess({ options.onSuccess({
'asset': { 'asset': {
'url': 'http://example.org/test_3' 'url': 'http://example.org/test_3'
......
...@@ -3,8 +3,7 @@ define( ...@@ -3,8 +3,7 @@ define(
"jquery", "backbone", "underscore", "jquery", "backbone", "underscore",
"js/views/video/transcripts/utils", "js/views/video/transcripts/editor", "js/views/video/transcripts/utils", "js/views/video/transcripts/editor",
"js/views/metadata", "js/models/metadata", "js/collections/metadata", "js/views/metadata", "js/models/metadata", "js/collections/metadata",
"underscore.string", "xmodule", "js/views/video/transcripts/metadata_videolist", "underscore.string", "xmodule", "js/views/video/transcripts/metadata_videolist"
"jasmine-jquery"
], ],
function ($, Backbone, _, Utils, Editor, MetadataView, MetadataModel, MetadataCollection, _str) { function ($, Backbone, _, Utils, Editor, MetadataView, MetadataModel, MetadataCollection, _str) {
describe('Transcripts.Editor', function () { describe('Transcripts.Editor', function () {
...@@ -43,6 +42,13 @@ function ($, Backbone, _, Utils, Editor, MetadataView, MetadataModel, MetadataCo ...@@ -43,6 +42,13 @@ function ($, Backbone, _, Utils, Editor, MetadataView, MetadataModel, MetadataCo
}, },
transcripts, container; transcripts, container;
var waitsForDisplayName = function (collection) {
return jasmine.waitUntil(function () {
var displayNameValue = collection[0].getValue();
return displayNameValue !== '' && displayNameValue !== 'video_id';
});
};
beforeEach(function () { beforeEach(function () {
var tpl = sandbox({ var tpl = sandbox({
'class': 'wrapper-comp-settings basic_metadata_edit', 'class': 'wrapper-comp-settings basic_metadata_edit',
...@@ -60,7 +66,6 @@ function ($, Backbone, _, Utils, Editor, MetadataView, MetadataModel, MetadataCo ...@@ -60,7 +66,6 @@ function ($, Backbone, _, Utils, Editor, MetadataView, MetadataModel, MetadataCo
}); });
describe('Test initialization', function () { describe('Test initialization', function () {
beforeEach(function () { beforeEach(function () {
spyOn(MetadataView, 'Editor'); spyOn(MetadataView, 'Editor');
...@@ -158,27 +163,23 @@ function ($, Backbone, _, Utils, Editor, MetadataView, MetadataModel, MetadataCo ...@@ -158,27 +163,23 @@ function ($, Backbone, _, Utils, Editor, MetadataView, MetadataModel, MetadataCo
}); });
describe('Test Advanced to Basic synchronization', function () { describe('Test Advanced to Basic synchronization', function () {
it('Correct data', function () { it('Correct data', function (done) {
transcripts.syncBasicTab(metadataCollection, metadataView); transcripts.syncBasicTab(metadataCollection, metadataView);
var collection = transcripts.collection.models; var collection = transcripts.collection.models;
waitsFor(function() { waitsForDisplayName(collection)
var displayNameValue = collection[0].getValue(); .then(function () {
return (displayNameValue !== "" && displayNameValue != "video_id"); var displayNameValue = collection[0].getValue(),
}, "Defaults never loaded", 1000); videoUrlValue = collection[1].getValue();
runs(function() { expect(displayNameValue).toEqual('default');
var displayNameValue = collection[0].getValue(), expect(videoUrlValue).toEqual([
videoUrlValue = collection[1].getValue(); 'http://youtu.be/OEoXaMPEzfM',
'default.mp4',
expect(displayNameValue).toEqual('default'); 'default.webm'
expect(videoUrlValue).toEqual([ ]);
'http://youtu.be/OEoXaMPEzfM', })
'default.mp4', .always(done);
'default.webm'
]);
});
}); });
it('If metadataCollection is not defined', function () { it('If metadataCollection is not defined', function () {
...@@ -219,31 +220,26 @@ function ($, Backbone, _, Utils, Editor, MetadataView, MetadataModel, MetadataCo ...@@ -219,31 +220,26 @@ function ($, Backbone, _, Utils, Editor, MetadataView, MetadataModel, MetadataCo
}); });
describe('Test Basic to Advanced synchronization', function () { describe('Test Basic to Advanced synchronization', function () {
it('Correct data', function () { it('Correct data', function (done) {
transcripts.syncAdvancedTab(metadataCollection); transcripts.syncAdvancedTab(metadataCollection);
var collection = metadataCollection.models; var collection = metadataCollection.models;
waitsForDisplayName(collection)
waitsFor(function() { .then(function () {
var displayNameValue = collection[0].getValue(); var displayNameValue = collection[0].getValue();
return (displayNameValue !== "" && displayNameValue != "video_id"); var subValue = collection[1].getValue();
}, "Defaults never loaded", 1000); var html5SourcesValue = collection[2].getValue();
var youtubeValue = collection[3].getValue();
runs(function() {
expect(displayNameValue).toEqual('display value');
var displayNameValue = collection[0].getValue(); expect(subValue).toEqual('default');
var subValue = collection[1].getValue(); expect(html5SourcesValue).toEqual([
var html5SourcesValue = collection[2].getValue(); 'video.mp4',
var youtubeValue = collection[3].getValue(); 'video.webm'
]);
expect(displayNameValue).toEqual('display value'); expect(youtubeValue).toEqual('12345678901');
expect(subValue).toEqual('default'); })
expect(html5SourcesValue).toEqual([ .always(done);
'video.mp4',
'video.webm'
]);
expect(youtubeValue).toEqual('12345678901');
});
}); });
it('metadataCollection is not defined', function () { it('metadataCollection is not defined', function () {
...@@ -307,8 +303,7 @@ function ($, Backbone, _, Utils, Editor, MetadataView, MetadataModel, MetadataCo ...@@ -307,8 +303,7 @@ function ($, Backbone, _, Utils, Editor, MetadataView, MetadataModel, MetadataCo
transcripts.syncAdvancedTab(metadataCollection); transcripts.syncAdvancedTab(metadataCollection);
transcripts.syncAdvancedTab(metadataCollection); transcripts.syncAdvancedTab(metadataCollection);
transcripts.syncAdvancedTab(metadataCollection); transcripts.syncAdvancedTab(metadataCollection);
expect(subModel.setValue.calls.count()).toEqual(1);
expect(subModel.setValue.calls.length).toEqual(1);
}); });
}); });
......
...@@ -2,7 +2,7 @@ define( ...@@ -2,7 +2,7 @@ define(
[ [
"jquery", "underscore", "jquery", "underscore",
"js/views/video/transcripts/utils", "js/views/video/transcripts/file_uploader", "js/views/video/transcripts/utils", "js/views/video/transcripts/file_uploader",
"xmodule", "jquery.form", "jasmine-jquery" "xmodule", "jquery.form"
], ],
function ($, _, Utils, FileUploader) { function ($, _, Utils, FileUploader) {
// TODO: fix TNL-559 Intermittent failures of Transcript FileUploader JS tests // TODO: fix TNL-559 Intermittent failures of Transcript FileUploader JS tests
...@@ -43,7 +43,7 @@ function ($, _, Utils, FileUploader) { ...@@ -43,7 +43,7 @@ function ($, _, Utils, FileUploader) {
.append('<div class="transcripts-file-uploader" />') .append('<div class="transcripts-file-uploader" />')
.append('<a class="setting-upload" href="#">Upload</a>'); .append('<a class="setting-upload" href="#">Upload</a>');
spyOn(FileUploader.prototype, 'render').andCallThrough(); spyOn(FileUploader.prototype, 'render').and.callThrough();
view = new FileUploader({ view = new FileUploader({
el: $container, el: $container,
...@@ -61,7 +61,7 @@ function ($, _, Utils, FileUploader) { ...@@ -61,7 +61,7 @@ function ($, _, Utils, FileUploader) {
describe('Render', function () { describe('Render', function () {
beforeEach(function () { beforeEach(function () {
spyOn(_, 'template').andCallThrough(); spyOn(_, 'template').and.callThrough();
}); });
it('Template doesn\'t exist', function () { it('Template doesn\'t exist', function () {
...@@ -138,7 +138,7 @@ function ($, _, Utils, FileUploader) { ...@@ -138,7 +138,7 @@ function ($, _, Utils, FileUploader) {
}); });
it('Valid File Type - error should be hided', function () { it('Valid File Type - error should be hided', function () {
spyOn(view, 'checkExtValidity').andReturn(true); spyOn(view, 'checkExtValidity').and.returnValue(true);
view.$input.change(); view.$input.change();
...@@ -148,7 +148,7 @@ function ($, _, Utils, FileUploader) { ...@@ -148,7 +148,7 @@ function ($, _, Utils, FileUploader) {
}); });
it('Invalid File Type - error should be shown', function () { it('Invalid File Type - error should be shown', function () {
spyOn(view, 'checkExtValidity').andReturn(false); spyOn(view, 'checkExtValidity').and.returnValue(false);
view.$input.change(); view.$input.change();
...@@ -189,7 +189,7 @@ function ($, _, Utils, FileUploader) { ...@@ -189,7 +189,7 @@ function ($, _, Utils, FileUploader) {
it('xhrProgressHandler', function () { it('xhrProgressHandler', function () {
var percent = 26; var percent = 26;
spyOn($.fn, 'width').andCallThrough(); spyOn($.fn, 'width').and.callThrough();
view.xhrProgressHandler(null, null, null, percent); view.xhrProgressHandler(null, null, null, percent);
expect(view.$progress.width).toHaveBeenCalledWith(percent + '%'); expect(view.$progress.width).toHaveBeenCalledWith(percent + '%');
...@@ -209,7 +209,7 @@ function ($, _, Utils, FileUploader) { ...@@ -209,7 +209,7 @@ function ($, _, Utils, FileUploader) {
view.xhrCompleteHandler(xhr); view.xhrCompleteHandler(xhr);
expect(view.$progress).toHaveClass('is-invisible'); expect(view.$progress).toHaveClass('is-invisible');
expect(view.options.messenger.render.mostRecentCall.args[0]) expect(view.options.messenger.render.calls.mostRecent().args[0])
.toEqual('uploaded'); .toEqual('uploaded');
expect(Utils.Storage.set) expect(Utils.Storage.set)
.toHaveBeenCalledWith('sub', 'test'); .toHaveBeenCalledWith('sub', 'test');
......
...@@ -2,7 +2,7 @@ define( ...@@ -2,7 +2,7 @@ define(
[ [
"jquery", "underscore", "jquery", "underscore",
"js/views/video/transcripts/utils", "js/views/video/transcripts/message_manager", "js/views/video/transcripts/utils", "js/views/video/transcripts/message_manager",
"js/views/video/transcripts/file_uploader", "sinon", "jasmine-jquery", "js/views/video/transcripts/file_uploader", "sinon",
"xmodule" "xmodule"
], ],
function ($, _, Utils, MessageManager, FileUploader, sinon) { function ($, _, Utils, MessageManager, FileUploader, sinon) {
...@@ -67,10 +67,10 @@ function ($, _, Utils, MessageManager, FileUploader, sinon) { ...@@ -67,10 +67,10 @@ function ($, _, Utils, MessageManager, FileUploader, sinon) {
}); });
// Disabled 2/6/14 after intermittent failure in master // Disabled 2/6/14 after intermittent failure in master
xdescribe('Render', function () { describe('Render', function () {
beforeEach(function () { beforeEach(function () {
spyOn(_,'template').andCallThrough(); spyOn(_,'template').and.callThrough();
spyOn(fileUploader, 'render'); spyOn(fileUploader, 'render');
}); });
...@@ -101,7 +101,7 @@ function ($, _, Utils, MessageManager, FileUploader, sinon) { ...@@ -101,7 +101,7 @@ function ($, _, Utils, MessageManager, FileUploader, sinon) {
beforeEach(function () { beforeEach(function () {
view.render('found'); view.render('found');
spyOn(view, 'hideError'); spyOn(view, 'hideError');
spyOn($.fn, 'html').andCallThrough(); spyOn($.fn, 'html').and.callThrough();
$error = view.$el.find('.transcripts-error-message'); $error = view.$el.find('.transcripts-error-message');
$buttons = view.$el.find('.wrapper-transcripts-buttons'); $buttons = view.$el.find('.wrapper-transcripts-buttons');
}); });
...@@ -147,10 +147,10 @@ function ($, _, Utils, MessageManager, FileUploader, sinon) { ...@@ -147,10 +147,10 @@ function ($, _, Utils, MessageManager, FileUploader, sinon) {
$.each(handlers, function(key, value) { $.each(handlers, function(key, value) {
it(key, function () { it(key, function () {
var eventObj = jasmine.createSpyObj('event', ['preventDefault']); var eventObj = jasmine.createSpyObj('event', ['preventDefault']);
spyOn($.fn, 'data').andReturn('video_id'); spyOn($.fn, 'data').and.returnValue('video_id');
spyOn(view, 'processCommand'); spyOn(view, 'processCommand');
view[key](eventObj); view[key](eventObj);
expect(view.processCommand.mostRecentCall.args).toEqual(value); expect(view.processCommand.calls.mostRecent().args).toEqual(value);
}); });
}); });
...@@ -162,7 +162,7 @@ function ($, _, Utils, MessageManager, FileUploader, sinon) { ...@@ -162,7 +162,7 @@ function ($, _, Utils, MessageManager, FileUploader, sinon) {
beforeEach(function () { beforeEach(function () {
view.render('found'); view.render('found');
spyOn(Utils, 'command').andCallThrough(); spyOn(Utils, 'command').and.callThrough();
spyOn(view, 'render'); spyOn(view, 'render');
spyOn(view, 'showError'); spyOn(view, 'showError');
...@@ -174,35 +174,19 @@ function ($, _, Utils, MessageManager, FileUploader, sinon) { ...@@ -174,35 +174,19 @@ function ($, _, Utils, MessageManager, FileUploader, sinon) {
sinonXhr.restore(); sinonXhr.restore();
}); });
var assertCommand = function (config, expectFunc) { var assertCommand = function (config) {
var flag = false, var defaults = {
defaults = {
action: 'replace', action: 'replace',
errorMessage: 'errorMessage', errorMessage: 'errorMessage',
extraParamas: void(0) extraParamas: void(0)
}; };
args = $.extend({}, defaults, config); var args = $.extend({}, defaults, config);
runs(function() { return view
view .processCommand(args.action, args.errorMessage, args.extraParamas);
.processCommand(
args.action,
args.errorMessage,
args.extraParamas
)
.always(function () { flag = true; });
});
waitsFor(function() {
return flag;
}, "Ajax Timeout", 750);
runs(expectFunc);
}; };
it('Invoke without extraParamas', function () { it('Invoke without extraParamas', function (done) {
sinonXhr.respondWith([ sinonXhr.respondWith([
200, 200,
{ "Content-Type": "application/json"}, { "Content-Type": "application/json"},
...@@ -212,9 +196,8 @@ function ($, _, Utils, MessageManager, FileUploader, sinon) { ...@@ -212,9 +196,8 @@ function ($, _, Utils, MessageManager, FileUploader, sinon) {
}) })
]); ]);
assertCommand( assertCommand({})
{ }, .then(function () {
function() {
expect(Utils.command).toHaveBeenCalledWith( expect(Utils.command).toHaveBeenCalledWith(
action, action,
view.component_locator, view.component_locator,
...@@ -222,15 +205,14 @@ function ($, _, Utils, MessageManager, FileUploader, sinon) { ...@@ -222,15 +205,14 @@ function ($, _, Utils, MessageManager, FileUploader, sinon) {
void(0) void(0)
); );
expect(view.showError).not.toHaveBeenCalled(); expect(view.showError).not.toHaveBeenCalled();
expect(view.render.mostRecentCall.args[0]) expect(view.render.calls.mostRecent().args[0])
.toEqual('found'); .toEqual('found');
expect(Utils.Storage.set).toHaveBeenCalled(); expect(Utils.Storage.set).toHaveBeenCalled();
} })
); .always(done);
}); });
it('Invoke with extraParamas', function () { it('Invoke with extraParamas', function (done) {
sinonXhr.respondWith([ sinonXhr.respondWith([
200, 200,
{ "Content-Type": "application/json"}, { "Content-Type": "application/json"},
...@@ -242,9 +224,8 @@ function ($, _, Utils, MessageManager, FileUploader, sinon) { ...@@ -242,9 +224,8 @@ function ($, _, Utils, MessageManager, FileUploader, sinon) {
view.processCommand(action, errorMessage, extraParamas); view.processCommand(action, errorMessage, extraParamas);
assertCommand( assertCommand({extraParamas : extraParamas})
{ extraParamas : extraParamas }, .then(function () {
function () {
expect(Utils.command).toHaveBeenCalledWith( expect(Utils.command).toHaveBeenCalledWith(
action, action,
view.component_locator, view.component_locator,
...@@ -254,20 +235,16 @@ function ($, _, Utils, MessageManager, FileUploader, sinon) { ...@@ -254,20 +235,16 @@ function ($, _, Utils, MessageManager, FileUploader, sinon) {
} }
); );
expect(view.showError).not.toHaveBeenCalled(); expect(view.showError).not.toHaveBeenCalled();
expect(view.render.mostRecentCall.args[0]) expect(view.render.calls.mostRecent().args[0]).toEqual('found');
.toEqual('found');
expect(Utils.Storage.set).toHaveBeenCalled(); expect(Utils.Storage.set).toHaveBeenCalled();
} })
); .always(done);
}); });
it('Fail', function () { it('Fail', function (done) {
sinonXhr.respondWith([400, {}, '']); sinonXhr.respondWith([400, {}, '']);
assertCommand({})
assertCommand( .then(function () {
{ },
function () {
expect(Utils.command).toHaveBeenCalledWith( expect(Utils.command).toHaveBeenCalledWith(
action, action,
view.component_locator, view.component_locator,
...@@ -277,8 +254,8 @@ function ($, _, Utils, MessageManager, FileUploader, sinon) { ...@@ -277,8 +254,8 @@ function ($, _, Utils, MessageManager, FileUploader, sinon) {
expect(view.showError).toHaveBeenCalled(); expect(view.showError).toHaveBeenCalled();
expect(view.render).not.toHaveBeenCalled(); expect(view.render).not.toHaveBeenCalled();
expect(Utils.Storage.set).not.toHaveBeenCalled(); expect(Utils.Storage.set).not.toHaveBeenCalled();
} })
); .always(done);
}); });
}); });
......
...@@ -2,7 +2,7 @@ define( ...@@ -2,7 +2,7 @@ define(
[ [
'jquery', 'underscore', 'jquery', 'underscore',
'js/views/video/transcripts/utils', 'js/views/video/transcripts/utils',
'underscore.string', 'xmodule', 'jasmine-jquery' 'underscore.string', 'xmodule'
], ],
function ($, _, Utils, _str) { function ($, _, Utils, _str) {
'use strict'; 'use strict';
......
...@@ -5,7 +5,7 @@ define( ...@@ -5,7 +5,7 @@ define(
'js/views/video/transcripts/metadata_videolist', 'js/models/metadata', 'js/views/video/transcripts/metadata_videolist', 'js/models/metadata',
'js/views/abstract_editor', 'js/views/abstract_editor',
'common/js/spec_helpers/ajax_helpers', 'common/js/spec_helpers/ajax_helpers',
'xmodule', 'jasmine-jquery' 'xmodule'
], ],
function ($, _, Utils, VideoList, MetadataModel, AbstractEditor, AjaxHelpers) { function ($, _, Utils, VideoList, MetadataModel, AbstractEditor, AjaxHelpers) {
'use strict'; 'use strict';
...@@ -53,6 +53,19 @@ function ($, _, Utils, VideoList, MetadataModel, AbstractEditor, AjaxHelpers) { ...@@ -53,6 +53,19 @@ function ($, _, Utils, VideoList, MetadataModel, AbstractEditor, AjaxHelpers) {
}), }),
MessageManager, messenger; MessageManager, messenger;
var createMockAjaxServer = function () {
var mockServer = AjaxHelpers.server(
[
200,
{ 'Content-Type': 'application/json'},
response
]
);
mockServer.autoRespond = true;
return mockServer;
};
beforeEach(function () { beforeEach(function () {
var tpl = sandbox({ var tpl = sandbox({
'class': 'component', 'class': 'component',
...@@ -70,9 +83,12 @@ function ($, _, Utils, VideoList, MetadataModel, AbstractEditor, AjaxHelpers) { ...@@ -70,9 +83,12 @@ function ($, _, Utils, VideoList, MetadataModel, AbstractEditor, AjaxHelpers) {
).text(videoListEntryTemplate) ).text(videoListEntryTemplate)
); );
spyOn(Utils, 'command').andCallThrough(); // create mock server
spyOn(abstractEditor, 'initialize').andCallThrough(); this.mockServer = createMockAjaxServer();
spyOn(abstractEditor, 'render').andCallThrough();
spyOn(Utils, 'command').and.callThrough();
spyOn(abstractEditor, 'initialize').and.callThrough();
spyOn(abstractEditor, 'render').and.callThrough();
spyOn(console, 'error'); spyOn(console, 'error');
messenger = jasmine.createSpyObj('MessageManager',[ messenger = jasmine.createSpyObj('MessageManager',[
...@@ -80,7 +96,7 @@ function ($, _, Utils, VideoList, MetadataModel, AbstractEditor, AjaxHelpers) { ...@@ -80,7 +96,7 @@ function ($, _, Utils, VideoList, MetadataModel, AbstractEditor, AjaxHelpers) {
]); ]);
$.each(messenger, function(index, method) { $.each(messenger, function(index, method) {
method.andReturn(messenger); method.and.returnValue(messenger);
}); });
MessageManager = function () { MessageManager = function () {
...@@ -89,40 +105,54 @@ function ($, _, Utils, VideoList, MetadataModel, AbstractEditor, AjaxHelpers) { ...@@ -89,40 +105,54 @@ function ($, _, Utils, VideoList, MetadataModel, AbstractEditor, AjaxHelpers) {
return messenger; return messenger;
}; };
this.addMatchers({ jasmine.addMatchers({
assertValueInView: function(expected) { assertValueInView: function() {
var actualValue = this.actual.getValueFromEditor(); return {
return this.env.equals_(actualValue, expected); compare: function (actual, expected) {
}, var actualValue = actual.getValueFromEditor(),
assertCanUpdateView: function (expected) { passed = _.isEqual(actualValue, expected);
var actual = this.actual,
actualValue;
actual.setValueInEditor(expected);
actualValue = actual.getValueFromEditor();
return this.env.equals_(actualValue, expected); return {
pass: passed
};
}
};
}, },
assertIsCorrectVideoList: function (expected) { assertCanUpdateView: function () {
var actualValue = this.actual.getVideoObjectsList(); return {
compare: function (actual, expected) {
return this.env.equals_(actualValue, expected); var actualValue,
passed;
actual.setValueInEditor(expected);
actualValue = actual.getValueFromEditor();
passed = _.isEqual(actualValue, expected);
return {
pass: passed
};
}
};
},
assertIsCorrectVideoList: function () {
return {
compare: function (actual, expected) {
var actualValue = actual.getVideoObjectsList(),
passed = _.isEqual(actualValue, expected);
return {
pass: passed
};
}
};
} }
}); });
}); });
var createMockAjaxServer = function (test) { afterEach(function () {
var mockServer = AjaxHelpers.server( // restore mock server
test, this.mockServer.restore();
[ });
200,
{ 'Content-Type': 'application/json'},
response
]
);
mockServer.autoRespond = true;
return mockServer;
};
var createVideoListView = function () { var createVideoListView = function () {
var model = new MetadataModel(modelStub); var model = new MetadataModel(modelStub);
...@@ -133,37 +163,25 @@ function ($, _, Utils, VideoList, MetadataModel, AbstractEditor, AjaxHelpers) { ...@@ -133,37 +163,25 @@ function ($, _, Utils, VideoList, MetadataModel, AbstractEditor, AjaxHelpers) {
}); });
}; };
var waitsForResponse = function (mockServer, expectFunc, prep) { var waitsForResponse = function (mockServer) {
var flag = false; return jasmine.waitUntil(function () {
if (prep) {
runs(prep);
}
waitsFor(function() {
var requests = mockServer.requests, var requests = mockServer.requests,
len = requests.length; len = requests.length;
if (len && requests[0].readyState === 4) { return len && requests[0].readyState === 4;
flag = true; });
}
return flag;
}, 'Ajax Timeout', 750);
runs(expectFunc);
}; };
it('Initialize', function () { it('Initialize', function (done) {
var mockServer = createMockAjaxServer(this), var view = createVideoListView();
view = createVideoListView(); waitsForResponse(this.mockServer)
waitsForResponse(mockServer, function () { .then(function () {
expect(abstractEditor.initialize).toHaveBeenCalled(); expect(abstractEditor.initialize).toHaveBeenCalled();
expect(messenger.initialize).toHaveBeenCalled(); expect(messenger.initialize).toHaveBeenCalled();
expect(view.component_locator).toBe(component_locator); expect(view.component_locator).toBe(component_locator);
expect(view.$el).toHandle('input'); expect(view.$el).toHandle('input');
}); }).always(done);
}); });
describe('Render', function () { describe('Render', function () {
...@@ -178,23 +196,23 @@ function ($, _, Utils, VideoList, MetadataModel, AbstractEditor, AjaxHelpers) { ...@@ -178,23 +196,23 @@ function ($, _, Utils, VideoList, MetadataModel, AbstractEditor, AjaxHelpers) {
expect(messenger.render).toHaveBeenCalled(); expect(messenger.render).toHaveBeenCalled();
}, },
resetSpies = function(mockServer) { resetSpies = function(mockServer) {
abstractEditor.render.reset(); abstractEditor.render.calls.reset();
Utils.command.reset(); Utils.command.calls.reset();
messenger.render.reset(); messenger.render.calls.reset();
mockServer.requests.length = 0; mockServer.requests.length = 0;
}; };
it('is rendered in correct way', function () { it('is rendered in correct way', function (done) {
var mockServer = createMockAjaxServer(this);
createVideoListView(); createVideoListView();
waitsForResponse(mockServer, function () { waitsForResponse(this.mockServer)
assertToHaveBeenRendered(videoList); .then(function () {
}); assertToHaveBeenRendered(videoList);
})
.always(done);
}); });
it('is rendered with opened extra videos bar', function () { it('is rendered with opened extra videos bar', function (done) {
var mockServer = createMockAjaxServer(this), var view = createVideoListView();
view = createVideoListView();
var videoListLength = [ var videoListLength = [
{ {
mode: 'youtube', mode: 'youtube',
...@@ -215,41 +233,35 @@ function ($, _, Utils, VideoList, MetadataModel, AbstractEditor, AjaxHelpers) { ...@@ -215,41 +233,35 @@ function ($, _, Utils, VideoList, MetadataModel, AbstractEditor, AjaxHelpers) {
} }
]; ];
spyOn(view, 'getVideoObjectsList').andReturn(videoListLength); spyOn(view, 'getVideoObjectsList').and.returnValue(videoListLength);
spyOn(view, 'openExtraVideosBar'); spyOn(view, 'openExtraVideosBar');
waitsForResponse( resetSpies(this.mockServer);
mockServer, view.render();
function () {
waitsForResponse(this.mockServer)
.then(function () {
assertToHaveBeenRendered(videoListLength); assertToHaveBeenRendered(videoListLength);
view.getVideoObjectsList.andReturn(videoListLength); view.getVideoObjectsList.and.returnValue(videoListLength);
expect(view.openExtraVideosBar).toHaveBeenCalled(); expect(view.openExtraVideosBar).toHaveBeenCalled();
}, })
function () { .then(_.bind(function () {
resetSpies(mockServer); resetSpies(this.mockServer);
view.openExtraVideosBar.calls.reset();
view.getVideoObjectsList.and.returnValue(videoListHtml5mode);
view.render(); view.render();
}
);
waitsForResponse( return waitsForResponse(this.mockServer)
mockServer, .then(function () {
function () { assertToHaveBeenRendered(videoListHtml5mode);
assertToHaveBeenRendered(videoListHtml5mode); expect(view.openExtraVideosBar).toHaveBeenCalled();
expect(view.openExtraVideosBar).toHaveBeenCalled(); }).then(done);
}, }, this));
function () {
resetSpies(mockServer);
view.openExtraVideosBar.reset();
view.getVideoObjectsList.andReturn(videoListHtml5mode);
view.render();
}
);
}); });
it('is rendered without opened extra videos bar', function () { it('is rendered without opened extra videos bar', function (done) {
var mockServer = createMockAjaxServer(this), var view = createVideoListView(),
view = createVideoListView(),
videoList = [ videoList = [
{ {
mode: 'youtube', mode: 'youtube',
...@@ -258,44 +270,40 @@ function ($, _, Utils, VideoList, MetadataModel, AbstractEditor, AjaxHelpers) { ...@@ -258,44 +270,40 @@ function ($, _, Utils, VideoList, MetadataModel, AbstractEditor, AjaxHelpers) {
} }
]; ];
spyOn(view, 'getVideoObjectsList').andReturn(videoList); spyOn(view, 'getVideoObjectsList').and.returnValue(videoList);
spyOn(view, 'closeExtraVideosBar'); spyOn(view, 'closeExtraVideosBar');
waitsForResponse( resetSpies(this.mockServer);
mockServer, view.render();
function () {
assertToHaveBeenRendered(videoList);
expect(view.closeExtraVideosBar).toHaveBeenCalled();
},
function () {
resetSpies(mockServer);
view.render();
}
);
});
waitsForResponse(this.mockServer)
.then(function () {
assertToHaveBeenRendered(videoList);
expect(view.closeExtraVideosBar).toHaveBeenCalled();
})
.always(done);
});
}); });
describe('isUniqOtherVideos', function () { describe('isUniqOtherVideos', function () {
it('Unique data - return true', function () { it('Unique data - return true', function (done) {
var mockServer = createMockAjaxServer(this), var view = createVideoListView(),
view = createVideoListView(),
data = videoList.concat([{ data = videoList.concat([{
mode: 'html5', mode: 'html5',
type: 'other', type: 'other',
video: 'pxxZrg' video: 'pxxZrg'
}]); }]);
waitsForResponse(mockServer, function () {
var result = view.isUniqOtherVideos(data);
expect(result).toBe(true);
});
waitsForResponse(this.mockServer)
.then(function () {
var result = view.isUniqOtherVideos(data);
expect(result).toBe(true);
})
.always(done);
}); });
it('Not Unique data - return false', function () { it('Not Unique data - return false', function (done) {
var mockServer = createMockAjaxServer(this), var view = createVideoListView(),
view = createVideoListView(),
data = [ data = [
{ {
mode: 'html5', mode: 'html5',
...@@ -323,30 +331,31 @@ function ($, _, Utils, VideoList, MetadataModel, AbstractEditor, AjaxHelpers) { ...@@ -323,30 +331,31 @@ function ($, _, Utils, VideoList, MetadataModel, AbstractEditor, AjaxHelpers) {
video: '12345678901' video: '12345678901'
} }
]; ];
waitsForResponse(mockServer, function () {
var result = view.isUniqOtherVideos(data);
expect(result).toBe(false); waitsForResponse(this.mockServer)
}); .then(function () {
var result = view.isUniqOtherVideos(data);
expect(result).toBe(false);
})
.always(done);
}); });
}); });
describe('isUniqVideoTypes', function () { describe('isUniqVideoTypes', function () {
it('Unique data - return true', function (done) {
it('Unique data - return true', function () { var view = createVideoListView(),
var mockServer = createMockAjaxServer(this),
view = createVideoListView(),
data = videoList; data = videoList;
waitsForResponse(mockServer, function () {
var result = view.isUniqVideoTypes(data);
expect(result).toBe(true);
});
waitsForResponse(this.mockServer)
.then(function () {
var result = view.isUniqVideoTypes(data);
expect(result).toBe(true);
})
.always(done);
}); });
it('Not Unique data - return false', function () { it('Not Unique data - return false', function (done) {
var mockServer = createMockAjaxServer(this), var view = createVideoListView(),
view = createVideoListView(),
data = [ data = [
{ {
mode: 'html5', mode: 'html5',
...@@ -369,18 +378,19 @@ function ($, _, Utils, VideoList, MetadataModel, AbstractEditor, AjaxHelpers) { ...@@ -369,18 +378,19 @@ function ($, _, Utils, VideoList, MetadataModel, AbstractEditor, AjaxHelpers) {
video: '12345678901' video: '12345678901'
} }
]; ];
waitsForResponse(mockServer, function () {
var result = view.isUniqVideoTypes(data);
expect(result).toBe(false); waitsForResponse(this.mockServer)
}); .then(function () {
var result = view.isUniqVideoTypes(data);
expect(result).toBe(false);
})
.always(done);
}); });
}); });
describe('checkIsUniqVideoTypes', function () { describe('checkIsUniqVideoTypes', function () {
it('Error is shown', function () { it('Error is shown', function (done) {
var mockServer = createMockAjaxServer(this), var view = createVideoListView(),
view = createVideoListView(),
data = [ data = [
{ {
mode: 'html5', mode: 'html5',
...@@ -404,125 +414,137 @@ function ($, _, Utils, VideoList, MetadataModel, AbstractEditor, AjaxHelpers) { ...@@ -404,125 +414,137 @@ function ($, _, Utils, VideoList, MetadataModel, AbstractEditor, AjaxHelpers) {
} }
]; ];
waitsForResponse(mockServer, function () { waitsForResponse(this.mockServer)
var result = view.checkIsUniqVideoTypes(data); .then(function () {
var result = view.checkIsUniqVideoTypes(data);
expect(messenger.showError).toHaveBeenCalled(); expect(messenger.showError).toHaveBeenCalled();
expect(result).toBe(false); expect(result).toBe(false);
}); })
.always(done);
}); });
it('All works okay if arguments are not passed', function () { it('All works okay if arguments are not passed', function (done) {
var mockServer = createMockAjaxServer(this), var view = createVideoListView();
view = createVideoListView(); spyOn(view, 'getVideoObjectsList').and.returnValue(videoList);
spyOn(view, 'getVideoObjectsList').andReturn(videoList);
waitsForResponse(mockServer, function () {
var result = view.checkIsUniqVideoTypes();
expect(view.getVideoObjectsList).toHaveBeenCalled(); waitsForResponse(this.mockServer)
expect(messenger.showError).not.toHaveBeenCalled(); .then(function () {
expect(result).toBe(true); var result = view.checkIsUniqVideoTypes();
});
expect(view.getVideoObjectsList).toHaveBeenCalled();
expect(messenger.showError).not.toHaveBeenCalled();
expect(result).toBe(true);
})
.always(done);
}); });
}); });
describe('checkValidity', function () { describe('checkValidity', function () {
it('Error message is shown', function () { it('Error message is shown', function (done) {
var mockServer = createMockAjaxServer(this), var view = createVideoListView();
view = createVideoListView(); spyOn(view, 'checkIsUniqVideoTypes').and.returnValue(true);
spyOn(view, 'checkIsUniqVideoTypes').andReturn(true);
waitsForResponse(mockServer, function () { waitsForResponse(this.mockServer)
var data = { mode: 'incorrect' }, .then(function () {
var data = {mode: 'incorrect'},
result = view.checkValidity(data, true); result = view.checkValidity(data, true);
expect(messenger.showError).toHaveBeenCalled(); expect(messenger.showError).toHaveBeenCalled();
expect(view.checkIsUniqVideoTypes).toHaveBeenCalled(); expect(view.checkIsUniqVideoTypes).toHaveBeenCalled();
expect(result).toBe(false); expect(result).toBe(false);
}); })
.always(done);
}); });
it('Error message is shown when flag is not passed', function () { it('Error message is shown when flag is not passed', function (done) {
var mockServer = createMockAjaxServer(this), var view = createVideoListView();
view = createVideoListView(); spyOn(view, 'checkIsUniqVideoTypes').and.returnValue(true);
spyOn(view, 'checkIsUniqVideoTypes').andReturn(true);
waitsForResponse(mockServer, function () { waitsForResponse(this.mockServer)
var data = { mode: 'incorrect' }, .then(function () {
var data = {mode: 'incorrect'},
result = view.checkValidity(data); result = view.checkValidity(data);
expect(messenger.showError).not.toHaveBeenCalled(); expect(messenger.showError).not.toHaveBeenCalled();
expect(view.checkIsUniqVideoTypes).toHaveBeenCalled(); expect(view.checkIsUniqVideoTypes).toHaveBeenCalled();
expect(result).toBe(true); expect(result).toBe(true);
}); }).always(done);
}); });
it('All works okay if correct data is passed', function () { it('All works okay if correct data is passed', function (done) {
var mockServer = createMockAjaxServer(this), var view = createVideoListView();
view = createVideoListView(); spyOn(view, 'checkIsUniqVideoTypes').and.returnValue(true);
spyOn(view, 'checkIsUniqVideoTypes').andReturn(true);
waitsForResponse(mockServer, function () { waitsForResponse(this.mockServer)
var data = videoList, .then(function () {
var data = videoList,
result = view.checkValidity(data); result = view.checkValidity(data);
expect(messenger.showError).not.toHaveBeenCalled(); expect(messenger.showError).not.toHaveBeenCalled();
expect(view.checkIsUniqVideoTypes).toHaveBeenCalled(); expect(view.checkIsUniqVideoTypes).toHaveBeenCalled();
expect(result).toBe(true); expect(result).toBe(true);
}); })
.always(done);
}); });
}); });
it('openExtraVideosBar', function () { it('openExtraVideosBar', function (done) {
var mockServer = createMockAjaxServer(this), var view = createVideoListView();
view = createVideoListView(); waitsForResponse(this.mockServer)
waitsForResponse(mockServer, function () { .then(function () {
view.$extraVideosBar.removeClass('is-visible'); view.$extraVideosBar.removeClass('is-visible');
view.openExtraVideosBar();
view.openExtraVideosBar(); expect(view.$extraVideosBar).toHaveClass('is-visible');
expect(view.$extraVideosBar).toHaveClass('is-visible'); })
}); .always(done);
}); });
it('closeExtraVideosBar', function () { it('closeExtraVideosBar', function (done) {
var mockServer = createMockAjaxServer(this), var view = createVideoListView();
view = createVideoListView(); waitsForResponse(this.mockServer)
waitsForResponse(mockServer, function () { .then(function () {
view.$extraVideosBar.addClass('is-visible'); view.$extraVideosBar.addClass('is-visible');
view.closeExtraVideosBar(); view.closeExtraVideosBar();
expect(view.$extraVideosBar).not.toHaveClass('is-visible'); expect(view.$extraVideosBar).not.toHaveClass('is-visible');
}); })
.always(done);
}); });
it('toggleExtraVideosBar', function () { it('toggleExtraVideosBar', function (done) {
var mockServer = createMockAjaxServer(this), var view = createVideoListView();
view = createVideoListView(); waitsForResponse(this.mockServer)
waitsForResponse(mockServer, function () { .then(function () {
view.$extraVideosBar.addClass('is-visible'); view.$extraVideosBar.addClass('is-visible');
view.toggleExtraVideosBar(); view.toggleExtraVideosBar();
expect(view.$extraVideosBar).not.toHaveClass('is-visible'); expect(view.$extraVideosBar).not.toHaveClass('is-visible');
view.toggleExtraVideosBar(); view.toggleExtraVideosBar();
expect(view.$extraVideosBar).toHaveClass('is-visible'); expect(view.$extraVideosBar).toHaveClass('is-visible');
}); })
.always(done);
}); });
it('getValueFromEditor', function () { it('getValueFromEditor', function (done) {
var mockServer = createMockAjaxServer(this), var view = createVideoListView();
view = createVideoListView(); waitsForResponse(this.mockServer)
waitsForResponse(mockServer, function () { .then(function () {
expect(view).assertValueInView(modelStub.value); expect(view).assertValueInView(modelStub.value);
}); })
.always(done);
}); });
it('setValueInEditor', function () { it('setValueInEditor', function (done) {
var mockServer = createMockAjaxServer(this), var view = createVideoListView();
view = createVideoListView(); waitsForResponse(this.mockServer)
waitsForResponse(mockServer, function () { .then(function () {
expect(view).assertCanUpdateView(['abc.mp4']); expect(view).assertCanUpdateView(['abc.mp4']);
}); })
.always(done);
}); });
it('getVideoObjectsList', function () { it('getVideoObjectsList', function (done) {
var mockServer = createMockAjaxServer(this), var view = createVideoListView();
view = createVideoListView();
var value = [ var value = [
{ {
mode: 'youtube', mode: 'youtube',
...@@ -541,36 +563,39 @@ function ($, _, Utils, VideoList, MetadataModel, AbstractEditor, AjaxHelpers) { ...@@ -541,36 +563,39 @@ function ($, _, Utils, VideoList, MetadataModel, AbstractEditor, AjaxHelpers) {
} }
]; ];
waitsForResponse(mockServer, function () { waitsForResponse(this.mockServer)
view.setValueInEditor([ .then(function () {
'http://youtu.be/12345678901', view.setValueInEditor([
'video.mp4', 'http://youtu.be/12345678901',
'http://goo.gl/pxxZrg', 'video.mp4',
'video' 'http://goo.gl/pxxZrg',
]); 'video'
expect(view).assertIsCorrectVideoList(value); ]);
}); expect(view).assertIsCorrectVideoList(value);
})
.always(done);
}); });
describe('getPlaceholders', function () { describe('getPlaceholders', function () {
it('All works okay if empty values are passed', function () { it('All works okay if empty values are passed', function (done) {
var mockServer = createMockAjaxServer(this), var view = createVideoListView(),
view = createVideoListView(),
defaultPlaceholders = view.placeholders; defaultPlaceholders = view.placeholders;
waitsForResponse(mockServer, function () {
var result = view.getPlaceholders([]),
expectedResult = _.values(defaultPlaceholders).reverse();
expect(result).toEqual(expectedResult); waitsForResponse(this.mockServer)
}); .then(function () {
var result = view.getPlaceholders([]),
expectedResult = _.values(defaultPlaceholders).reverse();
expect(result).toEqual(expectedResult);
})
.always(done);
}); });
it('On filling less than 3 fields, remaining fields should have ' + it('On filling less than 3 fields, remaining fields should have ' +
'placeholders for video types that were not filled yet', 'placeholders for video types that were not filled yet',
function () { function (done) {
var mockServer = createMockAjaxServer(this), var view = createVideoListView(),
view = createVideoListView(),
defaultPlaceholders = view.placeholders; defaultPlaceholders = view.placeholders;
var dataDict = { var dataDict = {
youtube: { youtube: {
...@@ -598,14 +623,17 @@ function ($, _, Utils, VideoList, MetadataModel, AbstractEditor, AjaxHelpers) { ...@@ -598,14 +623,17 @@ function ($, _, Utils, VideoList, MetadataModel, AbstractEditor, AjaxHelpers) {
] ]
} }
}; };
defaultPlaceholders = view.placeholders;
waitsForResponse(mockServer, function () { defaultPlaceholders = view.placeholders;
$.each(dataDict, function(index, val) { waitsForResponse(this.mockServer)
var result = view.getPlaceholders(val.value); .then(function () {
$.each(dataDict, function (index, val) {
expect(result).toEqual(val.expectedResult); var result = view.getPlaceholders(val.value);
});
}); expect(result).toEqual(val.expectedResult);
});
})
.always(done);
} }
); );
}); });
...@@ -614,9 +642,9 @@ function ($, _, Utils, VideoList, MetadataModel, AbstractEditor, AjaxHelpers) { ...@@ -614,9 +642,9 @@ function ($, _, Utils, VideoList, MetadataModel, AbstractEditor, AjaxHelpers) {
var eventObject; var eventObject;
var resetSpies = function (view) { var resetSpies = function (view) {
messenger.hideError.reset(); messenger.hideError.calls.reset();
view.updateModel.reset(); view.updateModel.calls.reset();
view.closeExtraVideosBar.reset(); view.closeExtraVideosBar.calls.reset();
}; };
var setUp = function (view) { var setUp = function (view) {
...@@ -628,100 +656,104 @@ function ($, _, Utils, VideoList, MetadataModel, AbstractEditor, AjaxHelpers) { ...@@ -628,100 +656,104 @@ function ($, _, Utils, VideoList, MetadataModel, AbstractEditor, AjaxHelpers) {
spyOn($.fn, 'hasClass'); spyOn($.fn, 'hasClass');
spyOn($.fn, 'addClass'); spyOn($.fn, 'addClass');
spyOn($.fn, 'removeClass'); spyOn($.fn, 'removeClass');
spyOn($.fn, 'prop').andCallThrough(); spyOn($.fn, 'prop').and.callThrough();
spyOn(_, 'isEqual'); spyOn(_, 'isEqual');
resetSpies(view); resetSpies(view);
}; };
it('Field has invalid value - nothing should happen', it('Field has invalid value - nothing should happen',
function () { function (done) {
var mockServer = createMockAjaxServer(this), var view = createVideoListView();
view = createVideoListView();
setUp(view); setUp(view);
$.fn.hasClass.andReturn(false); $.fn.hasClass.and.returnValue(false);
view.checkValidity.andReturn(false); view.checkValidity.and.returnValue(false);
waitsForResponse(mockServer, function () { waitsForResponse(this.mockServer)
view.inputHandler(eventObject); .then(function () {
expect(messenger.hideError).not.toHaveBeenCalled(); view.inputHandler(eventObject);
expect(view.updateModel).not.toHaveBeenCalled(); expect(messenger.hideError).not.toHaveBeenCalled();
expect(view.closeExtraVideosBar).not.toHaveBeenCalled(); expect(view.updateModel).not.toHaveBeenCalled();
expect($.fn.prop).toHaveBeenCalledWith( expect(view.closeExtraVideosBar).not.toHaveBeenCalled();
'disabled', true expect($.fn.prop).toHaveBeenCalledWith(
); 'disabled', true
expect($.fn.addClass).toHaveBeenCalledWith( );
'is-disabled' expect($.fn.addClass).toHaveBeenCalledWith(
); 'is-disabled'
}); );
})
.always(done);
} }
); );
it('Main field has invalid value - extra Videos Bar is closed', it('Main field has invalid value - extra Videos Bar is closed',
function () { function (done) {
var mockServer = createMockAjaxServer(this), var view = createVideoListView();
view = createVideoListView();
setUp(view); setUp(view);
$.fn.hasClass.andReturn(true); $.fn.hasClass.and.returnValue(true);
view.checkValidity.andReturn(false); view.checkValidity.and.returnValue(false);
waitsForResponse(mockServer, function () { waitsForResponse(this.mockServer)
view.inputHandler(eventObject); .then(function () {
expect(messenger.hideError).not.toHaveBeenCalled(); view.inputHandler(eventObject);
expect(view.updateModel).not.toHaveBeenCalled(); expect(messenger.hideError).not.toHaveBeenCalled();
expect(view.closeExtraVideosBar).toHaveBeenCalled(); expect(view.updateModel).not.toHaveBeenCalled();
expect($.fn.prop).toHaveBeenCalledWith( expect(view.closeExtraVideosBar).toHaveBeenCalled();
'disabled', true expect($.fn.prop).toHaveBeenCalledWith(
); 'disabled', true
expect($.fn.addClass).toHaveBeenCalledWith( );
'is-disabled' expect($.fn.addClass).toHaveBeenCalledWith(
); 'is-disabled'
}); );
})
.always(done);
} }
); );
it('Model is updated if value is valid', it('Model is updated if value is valid',
function () { function (done) {
var mockServer = createMockAjaxServer(this), var view = createVideoListView();
view = createVideoListView();
setUp(view); setUp(view);
view.checkValidity.andReturn(true); view.checkValidity.and.returnValue(true);
_.isEqual.andReturn(false); _.isEqual.and.returnValue(false);
waitsForResponse(mockServer, function () { waitsForResponse(this.mockServer)
view.inputHandler(eventObject); .then(function () {
expect(messenger.hideError).not.toHaveBeenCalled(); view.inputHandler(eventObject);
expect(view.updateModel).toHaveBeenCalled(); expect(messenger.hideError).not.toHaveBeenCalled();
expect(view.closeExtraVideosBar).not.toHaveBeenCalled(); expect(view.updateModel).toHaveBeenCalled();
expect($.fn.prop).toHaveBeenCalledWith( expect(view.closeExtraVideosBar).not.toHaveBeenCalled();
'disabled', false expect($.fn.prop).toHaveBeenCalledWith(
); 'disabled', false
expect($.fn.removeClass).toHaveBeenCalledWith( );
'is-disabled' expect($.fn.removeClass).toHaveBeenCalledWith(
); 'is-disabled'
}); );
})
.always(done);
} }
); );
it('Corner case: Error is hided', it('Corner case: Error is hided',
function () { function (done) {
var mockServer = createMockAjaxServer(this), var view = createVideoListView();
view = createVideoListView();
setUp(view); setUp(view);
view.checkValidity.andReturn(true); view.checkValidity.and.returnValue(true);
_.isEqual.andReturn(true); _.isEqual.and.returnValue(true);
waitsForResponse(mockServer, function () { waitsForResponse(this.mockServer)
view.inputHandler(eventObject); .then(function () {
expect(messenger.hideError).toHaveBeenCalled(); view.inputHandler(eventObject);
expect(view.updateModel).not.toHaveBeenCalled(); expect(messenger.hideError).toHaveBeenCalled();
expect(view.closeExtraVideosBar).not.toHaveBeenCalled(); expect(view.updateModel).not.toHaveBeenCalled();
expect($.fn.prop).toHaveBeenCalledWith( expect(view.closeExtraVideosBar).not.toHaveBeenCalled();
'disabled', false expect($.fn.prop).toHaveBeenCalledWith(
); 'disabled', false
expect($.fn.removeClass).toHaveBeenCalledWith( );
'is-disabled' expect($.fn.removeClass).toHaveBeenCalledWith(
); 'is-disabled'
}); );
})
.always(done);
} }
); );
......
...@@ -45,82 +45,133 @@ function ($, _, Squire) { ...@@ -45,82 +45,133 @@ function ($, _, Squire) {
var createPromptSpy = function (name) { var createPromptSpy = function (name) {
var spy = jasmine.createSpyObj(name, ['constructor', 'show', 'hide']); var spy = jasmine.createSpyObj(name, ['constructor', 'show', 'hide']);
spy.constructor.andReturn(spy); spy.constructor.and.returnValue(spy);
spy.show.andReturn(spy); spy.show.and.returnValue(spy);
spy.extend = jasmine.createSpy().andReturn(spy.constructor); spy.extend = jasmine.createSpy().and.returnValue(spy.constructor);
return spy; return spy;
}; };
beforeEach(function () { beforeEach(function (done) {
self = this; self = this;
this.addMatchers({ jasmine.addMatchers({
assertValueInView: function(expected) { assertValueInView: function() {
var value = this.actual.getValueFromEditor(); return {
return this.env.equals_(value, expected); compare: function (actual, expected) {
var value = actual.getValueFromEditor();
var passed = _.isEqual(value, expected);
return {
pass: passed,
message: 'Expected ' + actual + (passed ? '' : ' not') + ' to equal ' + expected
};
}
};
}, },
assertCanUpdateView: function (expected) { assertCanUpdateView: function () {
var view = this.actual, return {
value; compare: function (actual, expected) {
var view = actual,
view.setValueInEditor(expected); value,
value = view.getValueFromEditor(); passed;
return this.env.equals_(value, expected); view.setValueInEditor(expected);
value = view.getValueFromEditor();
passed = _.isEqual(value, expected);
return {
pass: passed,
message: 'Expected ' + actual + (passed ? '' : ' not') + ' to equal ' + expected
};
}
};
}, },
assertClear: function (modelValue) { assertClear: function () {
var env = this.env, return {
view = this.actual, compare: function (actual, modelValue) {
model = view.model; var view = actual,
model = view.model,
return model.getValue() === null && passed;
env.equals_(model.getDisplayValue(), modelValue) &&
env.equals_(view.getValueFromEditor(), modelValue); passed = model.getValue() === null &&
_.isEqual(model.getDisplayValue(), modelValue) &&
_.isEqual(view.getValueFromEditor(), modelValue);
return {
pass: passed
};
}
};
}, },
assertUpdateModel: function (originalValue, newValue) { assertUpdateModel: function () {
var env = this.env, return {
view = this.actual, compare: function (actual, originalValue, newValue) {
model = view.model, var view = actual,
expectOriginal; model = view.model,
expectOriginal,
view.setValueInEditor(newValue); passed;
expectOriginal = env.equals_(model.getValue(), originalValue);
view.updateModel(); view.setValueInEditor(newValue);
expectOriginal = _.isEqual(model.getValue(), originalValue);
return expectOriginal && view.updateModel();
env.equals_(model.getValue(), newValue);
passed = expectOriginal &&
_.isEqual(model.getValue(), newValue);
return {
pass: passed
};
}
};
}, },
verifyKeysUnique: function (initial, expected, testData) { verifyKeysUnique: function () {
var env = this.env, return {
view = this.actual, compare: function (actual, initial, expected, testData) {
item, value; var view = this.actual,
item,
view.setValueInEditor(initial); value,
view.updateModel(); passed;
view.$el.find('.create-setting').click();
item = view.$el.find('.list-settings-item').last(); view.setValueInEditor(initial);
item.find('select').val(testData.key); view.updateModel();
item.find('input:hidden').val(testData.value); view.$el.find('.create-setting').click();
value = view.getValueFromEditor(); item = view.$el.find('.list-settings-item').last();
item.find('select').val(testData.key);
return env.equals_(value, expected); item.find('input:hidden').val(testData.value);
value = view.getValueFromEditor();
passed = _.isEqual(value, expected);
return {
pass: passed
};
}
};
}, },
verifyButtons: function (upload, download, remove, index) { verifyButtons: function () {
var view = this.actual, return {
items = view.$el.find('.list-settings-item'), compare: function (actual, upload, download, remove, index) {
item = index ? items.eq(index) : items.last(), var view = this.actual,
uploadBtn = item.find('.upload-setting'), items = view.$el.find('.list-settings-item'),
downloadBtn = item.find('.download-setting'), item = index ? items.eq(index) : items.last(),
removeBtn = item.find('.remove-setting'); uploadBtn = item.find('.upload-setting'),
downloadBtn = item.find('.download-setting'),
removeBtn = item.find('.remove-setting'),
upload = upload ? uploadBtn.length : !uploadBtn.length; passed;
download = download ? downloadBtn.length : !downloadBtn.length;
remove = remove ? removeBtn.length : !removeBtn.length;
upload = upload ? uploadBtn.length : !uploadBtn.length;
return upload && download && remove; download = download ? downloadBtn.length : !downloadBtn.length;
remove = remove ? removeBtn.length : !removeBtn.length;
passed = upload && download && remove;
return {
pass: passed
};
}
};
} }
}); });
...@@ -141,19 +192,15 @@ function ($, _, Squire) { ...@@ -141,19 +192,15 @@ function ($, _, Squire) {
return self.uploadSpies; return self.uploadSpies;
}); });
runs(function() { injector.require([
injector.require([
'js/models/metadata', 'js/views/video/translations_editor' 'js/models/metadata', 'js/views/video/translations_editor'
], ],
function(MetadataModel, Translations) { function (MetadataModel, Translations) {
var model = new MetadataModel($.extend(true, {}, modelStub)); var model = new MetadataModel($.extend(true, {}, modelStub));
self.view = new Translations({model: model}); self.view = new Translations({model: model});
});
});
waitsFor(function() { done();
return self.view; });
}, 'VideoTranslations was not created', 1000);
}); });
afterEach(function () { afterEach(function () {
...@@ -198,7 +245,7 @@ function ($, _, Squire) { ...@@ -198,7 +245,7 @@ function ($, _, Squire) {
expect(this.uploadSpies.constructor).toHaveBeenCalled(); expect(this.uploadSpies.constructor).toHaveBeenCalled();
expect(this.uploadSpies.show).toHaveBeenCalled(); expect(this.uploadSpies.show).toHaveBeenCalled();
options = this.uploadSpies.constructor.mostRecentCall.args[0]; options = this.uploadSpies.constructor.calls.mostRecent().args[0];
options.onSuccess({'filename': 'zh.srt'}); options.onSuccess({'filename': 'zh.srt'});
expect(this.view).verifyButtons(true, true, true); expect(this.view).verifyButtons(true, true, true);
......
define( define(
["jquery", "js/models/active_video_upload", "js/views/active_video_upload_list", "common/js/spec_helpers/template_helpers", "mock-ajax", "jasmine-jquery"], [
"jquery",
"js/models/active_video_upload",
"js/views/active_video_upload_list",
"common/js/spec_helpers/template_helpers",
"mock-ajax"
],
function($, ActiveVideoUpload, ActiveVideoUploadListView, TemplateHelpers) { function($, ActiveVideoUpload, ActiveVideoUploadListView, TemplateHelpers) {
"use strict"; "use strict";
var concurrentUploadLimit = 2; var concurrentUploadLimit = 2;
...@@ -16,8 +22,7 @@ define( ...@@ -16,8 +22,7 @@ define(
uploadButton: this.uploadButton uploadButton: this.uploadButton
}); });
this.view.render(); this.view.render();
jasmine.Ajax.useMock(); jasmine.Ajax.install();
clearAjaxRequests();
this.globalAjaxError = jasmine.createSpy(); this.globalAjaxError = jasmine.createSpy();
$(document).ajaxError(this.globalAjaxError); $(document).ajaxError(this.globalAjaxError);
}); });
...@@ -25,15 +30,16 @@ define( ...@@ -25,15 +30,16 @@ define(
// Remove window unload handler triggered by the upload requests // Remove window unload handler triggered by the upload requests
afterEach(function() { afterEach(function() {
$(window).off("beforeunload"); $(window).off("beforeunload");
jasmine.Ajax.uninstall();
}); });
it("should trigger file selection when either the upload button or the drop zone is clicked", function() { it("should trigger file selection when either the upload button or the drop zone is clicked", function() {
var clickSpy = jasmine.createSpy(); var clickSpy = jasmine.createSpy();
clickSpy.andCallFake(function(event) { event.preventDefault(); }); clickSpy.and.callFake(function(event) { event.preventDefault(); });
this.view.$(".js-file-input").on("click", clickSpy); this.view.$(".js-file-input").on("click", clickSpy);
this.view.$(".file-drop-area").click(); this.view.$(".file-drop-area").click();
expect(clickSpy).toHaveBeenCalled(); expect(clickSpy).toHaveBeenCalled();
clickSpy.reset(); clickSpy.calls.reset();
this.uploadButton.click(); this.uploadButton.click();
expect(clickSpy).toHaveBeenCalled(); expect(clickSpy).toHaveBeenCalled();
}); });
...@@ -47,17 +53,16 @@ define( ...@@ -47,17 +53,16 @@ define(
}; };
var getSentRequests = function() { var getSentRequests = function() {
return _.filter( return jasmine.Ajax.requests.filter(function (request) {
ajaxRequests, return request.readyState > 0;
function(request) { return request.readyState > 0; } });
);
}; };
_.each( _.each(
[ [
{desc: "a single file", numFiles: 1}, {desc: "a single file", numFiles: 1},
{desc: "multiple files", numFiles: concurrentUploadLimit}, {desc: "multiple files", numFiles: concurrentUploadLimit},
{desc: "more files than upload limit", numFiles: concurrentUploadLimit + 1}, {desc: "more files than upload limit", numFiles: concurrentUploadLimit + 1}
], ],
function(caseInfo) { function(caseInfo) {
var fileNames = _.map( var fileNames = _.map(
...@@ -71,7 +76,7 @@ define( ...@@ -71,7 +76,7 @@ define(
// security reasons, so we must mock the access mechanism // security reasons, so we must mock the access mechanism
// that jQuery-File-Upload uses to retrieve it. // that jQuery-File-Upload uses to retrieve it.
var realProp = $.prop; var realProp = $.prop;
spyOn($, "prop").andCallFake(function(el, propName) { spyOn($, "prop").and.callFake(function(el, propName) {
if (arguments.length == 2 && propName == "files") { if (arguments.length == 2 && propName == "files") {
return _.map( return _.map(
fileNames, fileNames,
...@@ -82,7 +87,7 @@ define( ...@@ -82,7 +87,7 @@ define(
} }
}); });
this.view.$(".js-file-input").change(); this.view.$(".js-file-input").change();
this.request = mostRecentAjaxRequest(); this.request = jasmine.Ajax.requests.mostRecent();
}); });
it("should trigger the correct request", function() { it("should trigger the correct request", function() {
...@@ -99,14 +104,14 @@ define( ...@@ -99,14 +104,14 @@ define(
}); });
it("should trigger the global AJAX error handler on server error", function() { it("should trigger the global AJAX error handler on server error", function() {
this.request.response({status: 500}); this.request.respondWith({status: 500});
expect(this.globalAjaxError).toHaveBeenCalled(); expect(this.globalAjaxError).toHaveBeenCalled();
}); });
describe("and successful server response", function() { describe("and successful server response", function() {
beforeEach(function() { beforeEach(function() {
clearAjaxRequests(); jasmine.Ajax.requests.reset();
this.request.response({ this.request.respondWith({
status: 200, status: 200,
responseText: JSON.stringify({ responseText: JSON.stringify({
files: _.map( files: _.map(
...@@ -141,7 +146,6 @@ define( ...@@ -141,7 +146,6 @@ define(
}); });
it("should display upload status and progress", function() { it("should display upload status and progress", function() {
var spec = this;
expect(this.$uploadElems.length).toEqual(caseInfo.numFiles); expect(this.$uploadElems.length).toEqual(caseInfo.numFiles);
this.$uploadElems.each(function(i, uploadElem) { this.$uploadElems.each(function(i, uploadElem) {
var $uploadElem = $(uploadElem); var $uploadElem = $(uploadElem);
...@@ -154,7 +158,7 @@ define( ...@@ -154,7 +158,7 @@ define(
ActiveVideoUpload.STATUS_QUEUED : ActiveVideoUpload.STATUS_QUEUED :
ActiveVideoUpload.STATUS_UPLOADING ActiveVideoUpload.STATUS_UPLOADING
); );
expect($uploadElem.find(".video-detail-progress").attr("value")).toEqual(0); expect($uploadElem.find(".video-detail-progress").val()).toEqual(0);
expect($uploadElem).not.toHaveClass("success"); expect($uploadElem).not.toHaveClass("success");
expect($uploadElem).not.toHaveClass("error"); expect($uploadElem).not.toHaveClass("error");
expect($uploadElem.hasClass("queued")).toEqual(queued); expect($uploadElem.hasClass("queued")).toEqual(queued);
...@@ -187,12 +191,12 @@ define( ...@@ -187,12 +191,12 @@ define(
progressValue: 0, progressValue: 0,
presentClass: "error", presentClass: "error",
absentClass: "success" absentClass: "success"
}, }
], ],
function(subCaseInfo) { function(subCaseInfo) {
describe("and upload " + subCaseInfo.desc, function() { describe("and upload " + subCaseInfo.desc, function() {
beforeEach(function() { beforeEach(function() {
getSentRequests()[0].response({status: subCaseInfo.responseStatus}); getSentRequests()[0].respondWith({status: subCaseInfo.responseStatus});
}); });
it("should update status and progress", function() { it("should update status and progress", function() {
...@@ -202,7 +206,7 @@ define( ...@@ -202,7 +206,7 @@ define(
subCaseInfo.statusText subCaseInfo.statusText
); );
expect( expect(
$uploadElem.find(".video-detail-progress").attr("value") $uploadElem.find(".video-detail-progress").val()
).toEqual(subCaseInfo.progressValue); ).toEqual(subCaseInfo.progressValue);
expect($uploadElem).toHaveClass(subCaseInfo.presentClass); expect($uploadElem).toHaveClass(subCaseInfo.presentClass);
expect($uploadElem).not.toHaveClass(subCaseInfo.absentClass); expect($uploadElem).not.toHaveClass(subCaseInfo.absentClass);
......
...@@ -16,7 +16,7 @@ define([ "jquery", "common/js/spec_helpers/ajax_helpers", "URI", "js/views/asset ...@@ -16,7 +16,7 @@ define([ "jquery", "common/js/spec_helpers/ajax_helpers", "URI", "js/views/asset
appendSetFixtures(uploadModalTpl); appendSetFixtures(uploadModalTpl);
appendSetFixtures(sandbox({ id: "asset_table_body" })); appendSetFixtures(sandbox({ id: "asset_table_body" }));
spyOn($.fn, "fileupload").andReturn(""); spyOn($.fn, "fileupload").and.returnValue("");
var collection = new AssetCollection(); var collection = new AssetCollection();
collection.url = "assets-url"; collection.url = "assets-url";
...@@ -181,7 +181,7 @@ define([ "jquery", "common/js/spec_helpers/ajax_helpers", "URI", "js/views/asset ...@@ -181,7 +181,7 @@ define([ "jquery", "common/js/spec_helpers/ajax_helpers", "URI", "js/views/asset
it('uploads file properly', function () { it('uploads file properly', function () {
var requests = setup.call(this); var requests = setup.call(this);
expect(assetsView).toBeDefined(); expect(assetsView).toBeDefined();
spyOn(assetsView, "addAsset").andCallFake(function () { spyOn(assetsView, "addAsset").and.callFake(function () {
assetsView.collection.add(mockAssetUploadResponse.asset); assetsView.collection.add(mockAssetUploadResponse.asset);
assetsView.pagingView.renderPageItems(); assetsView.pagingView.renderPageItems();
assetsView.pagingView.setPage(0); assetsView.pagingView.setPage(0);
......
...@@ -13,8 +13,8 @@ define(["jquery", "underscore", "js/views/baseview", "js/utils/handle_iframe_bin ...@@ -13,8 +13,8 @@ define(["jquery", "underscore", "js/views/baseview", "js/utils/handle_iframe_bin
spyOn(baseViewPrototype, 'initialize'); spyOn(baseViewPrototype, 'initialize');
spyOn(baseViewPrototype, 'beforeRender'); spyOn(baseViewPrototype, 'beforeRender');
spyOn(baseViewPrototype, 'render').andCallThrough(); spyOn(baseViewPrototype, 'render').and.callThrough();
spyOn(baseViewPrototype, 'afterRender').andCallThrough(); spyOn(baseViewPrototype, 'afterRender').and.callThrough();
}); });
afterEach(function () { afterEach(function () {
......
...@@ -125,7 +125,7 @@ define([ ...@@ -125,7 +125,7 @@ define([
ViewHelpers.verifyNotificationShowing(notificationSpy, /Deleting/); ViewHelpers.verifyNotificationShowing(notificationSpy, /Deleting/);
expect($(listItemView)).toExist(); expect($(listItemView)).toExist();
}; };
var assertCannotDeleteUsed = function (that, toolTipText, warningText){ var assertCannotDeleteUsed = function (that, toolTipText, warningText) {
setUsageInfo(that.model); setUsageInfo(that.model);
that.view.render(); that.view.render();
expect(that.view.$(SELECTORS.note)).toHaveAttr( expect(that.view.$(SELECTORS.note)).toHaveAttr(
...@@ -153,36 +153,69 @@ define([ ...@@ -153,36 +153,69 @@ define([
revision: 'course_rev' revision: 'course_rev'
}); });
this.addMatchers({ jasmine.addMatchers({
toContainText: function(text) { toContainText: function() {
var trimmedText = $.trim(this.actual.text()); return {
compare: function (actual, text) {
if (text && $.isFunction(text.test)) { var trimmedText = $.trim(actual.text()),
return text.test(trimmedText); passed;
} else {
return trimmedText.indexOf(text) !== -1; if (text && $.isFunction(text.test)) {
} passed = text.test(trimmedText);
} else {
passed = trimmedText.indexOf(text) !== -1;
}
return {
pass: passed
};
}
};
}, },
toBeCorrectValuesInInputs: function (values) { toBeCorrectValuesInInputs: function () {
var expected = { return {
name: this.actual.$(SELECTORS.inputName).val(), compare: function (actual, values) {
description: this.actual var expected = {
.$(SELECTORS.inputDescription).val() name: actual.$(SELECTORS.inputName).val(),
description: actual
.$(SELECTORS.inputDescription).val()
};
var passed = _.isEqual(values, expected);
return {
pass: passed
};
}
}; };
return _.isEqual(values, expected);
}, },
toBeCorrectValuesInModel: function (values) { toBeCorrectValuesInModel: function () {
return _.every(values, function (value, key) { return {
return this.actual.get(key) === value; compare: function (actual, values) {
}.bind(this)); var passed = _.every(values, function (value, key) {
return actual.get(key) === value;
}.bind(this));
return {
pass: passed
};
}
};
}, },
toHaveDefaultNames: function (values) { toHaveDefaultNames: function () {
var actualValues = $.map(this.actual, function (item) { return {
return $(item).val(); compare: function (actual, values) {
}); var actualValues = $.map(actual, function (item) {
return $(item).val();
return _.isEqual(actualValues, values); });
var passed = _.isEqual(actualValues, values);
return {
pass: passed
};
}
};
} }
}); });
}); });
...@@ -389,7 +422,7 @@ define([ ...@@ -389,7 +422,7 @@ define([
groups = this.model.get('groups'); groups = this.model.get('groups');
expect(groups.length).toBe(3); expect(groups.length).toBe(3);
expect(groups.at(2).get('name')).toBe('Group C'); expect(groups.at(2).get('name')).toBe('Group C');
expect(this.view.$el).not.toExist(); expect(this.view.$el).not.toBeInDOM();
}); });
it('does not hide saving message if failure', function() { it('does not hide saving message if failure', function() {
...@@ -421,7 +454,7 @@ define([ ...@@ -421,7 +454,7 @@ define([
}); });
it('should be removed on cancel if it is a new item', function() { it('should be removed on cancel if it is a new item', function() {
spyOn(this.model, 'isNew').andReturn(true); spyOn(this.model, 'isNew').and.returnValue(true);
setValuesToInputs(this.view, { setValuesToInputs(this.view, {
inputName: 'New Configuration', inputName: 'New Configuration',
inputDescription: 'New Description' inputDescription: 'New Description'
...@@ -454,18 +487,23 @@ define([ ...@@ -454,18 +487,23 @@ define([
name: 'New Configuration' name: 'New Configuration'
}); });
// Error message disappear // Error message disappear
expect(this.view.$(SELECTORS.errorMessage)).not.toExist(); expect(this.view.$(SELECTORS.errorMessage)).not.toBeInDOM();
AjaxHelpers.expectNoRequests(requests); AjaxHelpers.expectNoRequests(requests);
}); });
it('should have appropriate class names on focus/blur', function () { it('should have appropriate class names on focus/blur', function (done) {
var groupInput = this.view.$(SELECTORS.inputGroupName).first(), var groupInput = this.view.$(SELECTORS.inputGroupName).first(),
groupFields = this.view.$(SELECTORS.groupFields); groupFields = this.view.$(SELECTORS.groupFields);
groupInput.focus(); groupInput.focus();
expect(groupFields).toHaveClass('is-focused'); jasmine.waitUntil(function() {
groupInput.blur(); return groupFields.hasClass('is-focused');
expect(groupFields).not.toHaveClass('is-focused'); }).then(function () {
groupInput.blur();
jasmine.waitUntil(function() {
return !groupFields.hasClass('is-focused');
}).then(done);
});
}); });
describe('removes all newly created groups on cancel', function () { describe('removes all newly created groups on cancel', function () {
...@@ -957,13 +995,13 @@ define([ ...@@ -957,13 +995,13 @@ define([
expect(this.model).toBeCorrectValuesInModel({ expect(this.model).toBeCorrectValuesInModel({
name: 'New Content Group' name: 'New Content Group'
}); });
expect(this.view.$el).not.toExist(); expect(this.view.$el).not.toBeInDOM();
}); });
it('does not hide saving message if failure', function() { it('does not hide saving message if failure', function() {
var requests = AjaxHelpers.requests(this), var requests = AjaxHelpers.requests(this),
notificationSpy = ViewHelpers.createNotificationSpy(); notificationSpy = ViewHelpers.createNotificationSpy();
this.view.$(SELECTORS.inputName).val('New Content Group') this.view.$(SELECTORS.inputName).val('New Content Group');
ViewHelpers.submitAndVerifyFormError(this.view, requests, notificationSpy) ViewHelpers.submitAndVerifyFormError(this.view, requests, notificationSpy)
}); });
......
...@@ -12,7 +12,7 @@ function($, LoginFactory, AjaxHelpers, ViewUtils) { ...@@ -12,7 +12,7 @@ function($, LoginFactory, AjaxHelpers, ViewUtils) {
}); });
it('disable the submit button once it is clicked', function() { it('disable the submit button once it is clicked', function() {
spyOn(ViewUtils, 'redirect').andCallFake(function(){}); spyOn(ViewUtils, 'redirect').and.callFake(function(){});
var requests = AjaxHelpers.requests(this); var requests = AjaxHelpers.requests(this);
expect(submitButton).not.toHaveClass('is-disabled'); expect(submitButton).not.toHaveClass('is-disabled');
submitButton.click(); submitButton.click();
......
...@@ -31,14 +31,13 @@ define(["jquery", "underscore", "js/views/modals/base_modal", "js/spec_helpers/m ...@@ -31,14 +31,13 @@ define(["jquery", "underscore", "js/views/modals/base_modal", "js/spec_helpers/m
expect(ModelHelpers.isShowingModal(modal)).toBeTruthy(); expect(ModelHelpers.isShowingModal(modal)).toBeTruthy();
}); });
it('sends focus to the modal window after show is called', function() { it('sends focus to the modal window after show is called', function(done) {
showMockModal(); showMockModal();
waitsFor(function () {
// This is the implementation of "toBeFocused". However, simply calling that method jasmine.waitUntil(function() {
// with no wait seems to be flaky.
var modalWindow = ModelHelpers.getModalWindow(modal); var modalWindow = ModelHelpers.getModalWindow(modal);
return $(modalWindow)[0] === $(modalWindow)[0].ownerDocument.activeElement; return ($(modalWindow)[0] === $(modalWindow)[0].ownerDocument.activeElement);
}, 'Modal Window did not get focus', 5000); }).then(done);
}); });
it('is removed after hide is called', function () { it('is removed after hide is called', function () {
......
...@@ -51,7 +51,7 @@ define(['jquery', 'underscore', 'js/spec_helpers/validation_helpers', 'js/views/ ...@@ -51,7 +51,7 @@ define(['jquery', 'underscore', 'js/spec_helpers/validation_helpers', 'js/views/
ValidationHelpers.checkErrorContents(modal, errorObjects); ValidationHelpers.checkErrorContents(modal, errorObjects);
}); });
it('run callback when undo changes button is clicked', function () { it('run callback when undo changes button is clicked', function (done) {
var errorObjects = [ var errorObjects = [
{ {
model: {display_name: 'test_attribute1'}, model: {display_name: 'test_attribute1'},
...@@ -64,7 +64,7 @@ define(['jquery', 'underscore', 'js/spec_helpers/validation_helpers', 'js/views/ ...@@ -64,7 +64,7 @@ define(['jquery', 'underscore', 'js/spec_helpers/validation_helpers', 'js/views/
]; ];
var callback = function() { var callback = function() {
return true; done();
}; };
// Show Modal and click undo changes // Show Modal and click undo changes
...@@ -72,15 +72,8 @@ define(['jquery', 'underscore', 'js/spec_helpers/validation_helpers', 'js/views/ ...@@ -72,15 +72,8 @@ define(['jquery', 'underscore', 'js/spec_helpers/validation_helpers', 'js/views/
expect(ValidationHelpers.isShowingModal(modal)).toBeTruthy(); expect(ValidationHelpers.isShowingModal(modal)).toBeTruthy();
ValidationHelpers.undoChanges(modal); ValidationHelpers.undoChanges(modal);
// Wait for the callback to be fired
waitsFor(function () {
return callback();
}, 'the callback to be called', 5000);
// After checking callback fire, check modal hide // After checking callback fire, check modal hide
runs(function () { expect(ValidationHelpers.isShowingModal(modal)).toBe(false);
expect(ValidationHelpers.isShowingModal(modal)).toBe(false);
});
}); });
}); });
}); });
...@@ -74,7 +74,10 @@ define(["jquery", "underscore", "common/js/spec_helpers/ajax_helpers", "URI", "j ...@@ -74,7 +74,10 @@ define(["jquery", "underscore", "common/js/spec_helpers/ajax_helpers", "URI", "j
var pagingContainer; var pagingContainer;
beforeEach(function () { beforeEach(function () {
pagingContainer = new MockPagingView({page_size: PAGE_SIZE}); pagingContainer = new MockPagingView({
page_size: PAGE_SIZE,
page: jasmine.createSpyObj('page', ['updatePreviewButton', 'renderAddXBlockComponents'])
});
}); });
describe("Container", function () { describe("Container", function () {
...@@ -546,7 +549,7 @@ define(["jquery", "underscore", "common/js/spec_helpers/ajax_helpers", "URI", "j ...@@ -546,7 +549,7 @@ define(["jquery", "underscore", "common/js/spec_helpers/ajax_helpers", "URI", "j
mockXBlockView.model.id = 'mock-location'; mockXBlockView.model.id = 'mock-location';
pagingContainer.refresh(mockXBlockView, true); pagingContainer.refresh(mockXBlockView, true);
expect(pagingContainer.render).toHaveBeenCalled(); expect(pagingContainer.render).toHaveBeenCalled();
expect(pagingContainer.render.mostRecentCall.args[0].force_render).toEqual('mock-location'); expect(pagingContainer.render.calls.mostRecent().args[0].force_render).toEqual('mock-location');
}); });
}); });
}); });
......
...@@ -70,7 +70,7 @@ define(["jquery", "underscore", "underscore.string", "common/js/spec_helpers/aja ...@@ -70,7 +70,7 @@ define(["jquery", "underscore", "underscore.string", "common/js/spec_helpers/aja
containerPage.render(); containerPage.render();
respondWithHtml(html); respondWithHtml(html);
AjaxHelpers.expectJsonRequest(requests, 'GET', '/xblock/locator-container'); AjaxHelpers.expectJsonRequest(requests, 'GET', '/xblock/locator-container');
AjaxHelpers.respondWithJson(requests, options); AjaxHelpers.respondWithJson(requests, options || {});
}; };
handleContainerPageRefresh = function(requests) { handleContainerPageRefresh = function(requests) {
......
define(["jquery", "underscore", "underscore.string", "common/js/spec_helpers/ajax_helpers", define(["jquery", "underscore", "underscore.string", "common/js/spec_helpers/ajax_helpers",
"common/js/spec_helpers/template_helpers", "js/spec_helpers/edit_helpers", "common/js/spec_helpers/template_helpers", "js/spec_helpers/edit_helpers",
"common/js/components/views/feedback_prompt", "js/views/pages/container", "common/js/components/views/feedback_prompt", "js/views/pages/container",
"js/views/pages/container_subviews", "js/models/xblock_info", "js/views/utils/xblock_utils"], "js/views/pages/container_subviews", "js/models/xblock_info", "js/views/utils/xblock_utils",
'js/models/course'],
function ($, _, str, AjaxHelpers, TemplateHelpers, EditHelpers, Prompt, ContainerPage, ContainerSubviews, function ($, _, str, AjaxHelpers, TemplateHelpers, EditHelpers, Prompt, ContainerPage, ContainerSubviews,
XBlockInfo, XBlockUtils) { XBlockInfo, XBlockUtils, Course) {
var VisibilityState = XBlockUtils.VisibilityState; var VisibilityState = XBlockUtils.VisibilityState;
describe("Container Subviews", function() { describe("Container Subviews", function() {
...@@ -14,12 +15,26 @@ define(["jquery", "underscore", "underscore.string", "common/js/spec_helpers/aja ...@@ -14,12 +15,26 @@ define(["jquery", "underscore", "underscore.string", "common/js/spec_helpers/aja
mockContainerXBlockHtml = readFixtures('mock/mock-empty-container-xblock.underscore'); mockContainerXBlockHtml = readFixtures('mock/mock-empty-container-xblock.underscore');
beforeEach(function () { beforeEach(function () {
window.course = new Course({
id: '5',
name: 'Course Name',
url_name: 'course_name',
org: 'course_org',
num: 'course_num',
revision: 'course_rev'
});
TemplateHelpers.installTemplate('xblock-string-field-editor'); TemplateHelpers.installTemplate('xblock-string-field-editor');
TemplateHelpers.installTemplate('publish-xblock'); TemplateHelpers.installTemplate('publish-xblock');
TemplateHelpers.installTemplate('publish-history'); TemplateHelpers.installTemplate('publish-history');
TemplateHelpers.installTemplate('unit-outline'); TemplateHelpers.installTemplate('unit-outline');
TemplateHelpers.installTemplate('container-message'); TemplateHelpers.installTemplate('container-message');
appendSetFixtures(mockContainerPage); appendSetFixtures(mockContainerPage);
requests = AjaxHelpers.requests(this);
});
afterEach(function() {
delete window.course;
}); });
defaultXBlockInfo = { defaultXBlockInfo = {
...@@ -39,7 +54,6 @@ define(["jquery", "underscore", "underscore.string", "common/js/spec_helpers/aja ...@@ -39,7 +54,6 @@ define(["jquery", "underscore", "underscore.string", "common/js/spec_helpers/aja
}; };
createContainerPage = function (test, options) { createContainerPage = function (test, options) {
requests = AjaxHelpers.requests(test);
model = new XBlockInfo(createXBlockInfo(options), { parse: true }); model = new XBlockInfo(createXBlockInfo(options), { parse: true });
containerPage = new ContainerPage({ containerPage = new ContainerPage({
model: model, model: model,
...@@ -135,7 +149,7 @@ define(["jquery", "underscore", "underscore.string", "common/js/spec_helpers/aja ...@@ -135,7 +149,7 @@ define(["jquery", "underscore", "underscore.string", "common/js/spec_helpers/aja
// Confirm the discard. // Confirm the discard.
expect(promptSpies.constructor).toHaveBeenCalled(); expect(promptSpies.constructor).toHaveBeenCalled();
promptSpies.constructor.mostRecentCall.args[0].actions.primary.click(promptSpies); promptSpies.constructor.calls.mostRecent().args[0].actions.primary.click(promptSpies);
AjaxHelpers.expectJsonRequest(requests, "POST", "/xblock/locator-container", AjaxHelpers.expectJsonRequest(requests, "POST", "/xblock/locator-container",
{"publish": "discard_changes"} {"publish": "discard_changes"}
...@@ -152,8 +166,8 @@ define(["jquery", "underscore", "underscore.string", "common/js/spec_helpers/aja ...@@ -152,8 +166,8 @@ define(["jquery", "underscore", "underscore.string", "common/js/spec_helpers/aja
}; };
beforeEach(function() { beforeEach(function() {
promptSpies = spyOnConstructor(Prompt, "Warning", ["show", "hide"]); promptSpies = jasmine.stealth.spyOnConstructor(Prompt, "Warning", ["show", "hide"]);
promptSpies.show.andReturn(this.promptSpies); promptSpies.show.and.returnValue(this.promptSpies);
}); });
it('renders correctly with private content', function () { it('renders correctly with private content', function () {
...@@ -268,7 +282,7 @@ define(["jquery", "underscore", "underscore.string", "common/js/spec_helpers/aja ...@@ -268,7 +282,7 @@ define(["jquery", "underscore", "underscore.string", "common/js/spec_helpers/aja
var notificationSpy, renderPageSpy, numRequests; var notificationSpy, renderPageSpy, numRequests;
createContainerPage(this); createContainerPage(this);
notificationSpy = EditHelpers.createNotificationSpy(); notificationSpy = EditHelpers.createNotificationSpy();
renderPageSpy = spyOn(containerPage.xblockPublisher, 'renderPage').andCallThrough(); renderPageSpy = spyOn(containerPage.xblockPublisher, 'renderPage').and.callThrough();
sendDiscardChangesToServer(); sendDiscardChangesToServer();
numRequests = requests.length; numRequests = requests.length;
...@@ -287,7 +301,7 @@ define(["jquery", "underscore", "underscore.string", "common/js/spec_helpers/aja ...@@ -287,7 +301,7 @@ define(["jquery", "underscore", "underscore.string", "common/js/spec_helpers/aja
it('does not fetch if discard changes fails', function () { it('does not fetch if discard changes fails', function () {
var renderPageSpy, numRequests; var renderPageSpy, numRequests;
createContainerPage(this); createContainerPage(this);
renderPageSpy = spyOn(containerPage.xblockPublisher, 'renderPage').andCallThrough(); renderPageSpy = spyOn(containerPage.xblockPublisher, 'renderPage').and.callThrough();
sendDiscardChangesToServer(); sendDiscardChangesToServer();
...@@ -309,7 +323,7 @@ define(["jquery", "underscore", "underscore.string", "common/js/spec_helpers/aja ...@@ -309,7 +323,7 @@ define(["jquery", "underscore", "underscore.string", "common/js/spec_helpers/aja
// Click cancel to confirmation. // Click cancel to confirmation.
expect(promptSpies.constructor).toHaveBeenCalled(); expect(promptSpies.constructor).toHaveBeenCalled();
promptSpies.constructor.mostRecentCall.args[0].actions.secondary.click(promptSpies); promptSpies.constructor.calls.mostRecent().args[0].actions.secondary.click(promptSpies);
AjaxHelpers.expectNoRequests(requests); AjaxHelpers.expectNoRequests(requests);
expect(containerPage.$(discardChangesButtonCss)).not.toHaveClass('is-disabled'); expect(containerPage.$(discardChangesButtonCss)).not.toHaveClass('is-disabled');
}); });
......
define(["jquery", "common/js/spec_helpers/ajax_helpers", "common/js/components/utils/view_utils", "js/views/pages/course_outline", define(["jquery", "common/js/spec_helpers/ajax_helpers", "common/js/components/utils/view_utils", "js/views/pages/course_outline",
"js/models/xblock_outline_info", "js/utils/date_utils", "js/spec_helpers/edit_helpers", "js/models/xblock_outline_info", "js/utils/date_utils", "js/spec_helpers/edit_helpers",
"common/js/spec_helpers/template_helpers"], "common/js/spec_helpers/template_helpers", 'js/models/course',],
function($, AjaxHelpers, ViewUtils, CourseOutlinePage, XBlockOutlineInfo, DateUtils, EditHelpers, TemplateHelpers) { function($, AjaxHelpers, ViewUtils, CourseOutlinePage, XBlockOutlineInfo, DateUtils,
EditHelpers, TemplateHelpers, Course) {
describe("CourseOutlinePage", function() { describe("CourseOutlinePage", function() {
var createCourseOutlinePage, displayNameInput, model, outlinePage, requests, var createCourseOutlinePage, displayNameInput, model, outlinePage, requests,
getItemsOfType, getItemHeaders, verifyItemsExpanded, expandItemsAndVerifyState, getItemsOfType, getItemHeaders, verifyItemsExpanded, expandItemsAndVerifyState,
collapseItemsAndVerifyState, createMockCourseJSON, createMockSectionJSON, createMockSubsectionJSON, collapseItemsAndVerifyState, createMockCourseJSON, createMockSectionJSON, createMockSubsectionJSON,
verifyTypePublishable, mockCourseJSON, mockEmptyCourseJSON, mockSingleSectionCourseJSON, verifyTypePublishable, mockCourseJSON, mockEmptyCourseJSON, mockSingleSectionCourseJSON,
createMockVerticalJSON, createMockIndexJSON, mockCourseEntranceExamJSON createMockVerticalJSON, createMockIndexJSON, mockCourseEntranceExamJSON,
mockOutlinePage = readFixtures('mock/mock-course-outline-page.underscore'), mockOutlinePage = readFixtures('mock/mock-course-outline-page.underscore'),
mockRerunNotification = readFixtures('mock/mock-course-rerun-notification.underscore'); mockRerunNotification = readFixtures('mock/mock-course-rerun-notification.underscore');
...@@ -214,6 +215,15 @@ define(["jquery", "common/js/spec_helpers/ajax_helpers", "common/js/components/u ...@@ -214,6 +215,15 @@ define(["jquery", "common/js/spec_helpers/ajax_helpers", "common/js/components/u
}; };
beforeEach(function () { beforeEach(function () {
window.course = new Course({
id: '5',
name: 'Course Name',
url_name: 'course_name',
org: 'course_org',
num: 'course_num',
revision: 'course_rev'
});
EditHelpers.installMockAnalytics(); EditHelpers.installMockAnalytics();
EditHelpers.installViewTemplates(); EditHelpers.installViewTemplates();
TemplateHelpers.installTemplates([ TemplateHelpers.installTemplates([
...@@ -252,6 +262,7 @@ define(["jquery", "common/js/spec_helpers/ajax_helpers", "common/js/components/u ...@@ -252,6 +262,7 @@ define(["jquery", "common/js/spec_helpers/ajax_helpers", "common/js/components/u
$("#start_date").datepicker( "destroy" ); $("#start_date").datepicker( "destroy" );
$("#due_date").datepicker( "destroy" ); $("#due_date").datepicker( "destroy" );
$('.ui-datepicker').remove(); $('.ui-datepicker').remove();
delete window.course;
}); });
describe('Initial display', function() { describe('Initial display', function() {
...@@ -346,8 +357,8 @@ define(["jquery", "common/js/spec_helpers/ajax_helpers", "common/js/components/u ...@@ -346,8 +357,8 @@ define(["jquery", "common/js/spec_helpers/ajax_helpers", "common/js/components/u
it('can start reindex of a course', function() { it('can start reindex of a course', function() {
createCourseOutlinePage(this, mockSingleSectionCourseJSON); createCourseOutlinePage(this, mockSingleSectionCourseJSON);
var reindexSpy = spyOn(outlinePage, 'startReIndex').andCallThrough(); var reindexSpy = spyOn(outlinePage, 'startReIndex').and.callThrough();
var successSpy = spyOn(outlinePage, 'onIndexSuccess').andCallThrough(); var successSpy = spyOn(outlinePage, 'onIndexSuccess').and.callThrough();
var reindexButton = outlinePage.$('.button.button-reindex'); var reindexButton = outlinePage.$('.button.button-reindex');
var test_url = '/course/5/search_reindex'; var test_url = '/course/5/search_reindex';
reindexButton.attr('href', test_url) reindexButton.attr('href', test_url)
...@@ -360,11 +371,11 @@ define(["jquery", "common/js/spec_helpers/ajax_helpers", "common/js/components/u ...@@ -360,11 +371,11 @@ define(["jquery", "common/js/spec_helpers/ajax_helpers", "common/js/components/u
it('shows an error message when reindexing fails', function() { it('shows an error message when reindexing fails', function() {
createCourseOutlinePage(this, mockSingleSectionCourseJSON); createCourseOutlinePage(this, mockSingleSectionCourseJSON);
var reindexSpy = spyOn(outlinePage, 'startReIndex').andCallThrough(); var reindexSpy = spyOn(outlinePage, 'startReIndex').and.callThrough();
var errorSpy = spyOn(outlinePage, 'onIndexError').andCallThrough(); var errorSpy = spyOn(outlinePage, 'onIndexError').and.callThrough();
var reindexButton = outlinePage.$('.button.button-reindex'); var reindexButton = outlinePage.$('.button.button-reindex');
var test_url = '/course/5/search_reindex'; var test_url = '/course/5/search_reindex';
reindexButton.attr('href', test_url) reindexButton.attr('href', test_url);
reindexButton.trigger('click'); reindexButton.trigger('click');
AjaxHelpers.expectJsonRequest(requests, 'GET', test_url); AjaxHelpers.expectJsonRequest(requests, 'GET', test_url);
AjaxHelpers.respondWithError(requests, 500, createMockIndexJSON(false)); AjaxHelpers.respondWithError(requests, 500, createMockIndexJSON(false));
......
...@@ -40,9 +40,15 @@ define([ ...@@ -40,9 +40,15 @@ define([
'content-group-editor', 'group-edit', 'list' 'content-group-editor', 'group-edit', 'list'
]); ]);
this.addMatchers({ jasmine.addMatchers({
toBeExpanded: function () { toBeExpanded: function () {
return Boolean($('a.group-toggle.hide-groups', $(this.actual)).length); return {
compare: function (actual) {
return {
pass: Boolean($('a.group-toggle.hide-groups', $(actual)).length)
};
}
};
} }
}); });
}); });
...@@ -67,7 +73,7 @@ define([ ...@@ -67,7 +73,7 @@ define([
}); });
it('should focus and expand if its id is part of url hash', function() { it('should focus and expand if its id is part of url hash', function() {
spyOn(this.view, 'getLocationHash').andReturn('#0'); spyOn(this.view, 'getLocationHash').and.returnValue('#0');
this.view.render(); this.view.render();
// We cannot use .toBeFocused due to flakiness. // We cannot use .toBeFocused due to flakiness.
expect($.fn.focus).toHaveBeenCalled(); expect($.fn.focus).toHaveBeenCalled();
...@@ -75,14 +81,14 @@ define([ ...@@ -75,14 +81,14 @@ define([
}); });
it('should not focus on any experiment configuration if url hash is empty', function() { it('should not focus on any experiment configuration if url hash is empty', function() {
spyOn(this.view, 'getLocationHash').andReturn(''); spyOn(this.view, 'getLocationHash').and.returnValue('');
this.view.render(); this.view.render();
expect($.fn.focus).not.toHaveBeenCalled(); expect($.fn.focus).not.toHaveBeenCalled();
expect(this.view.$(groupConfigItemClassName)).not.toBeExpanded(); expect(this.view.$(groupConfigItemClassName)).not.toBeExpanded();
}); });
it('should not focus on any experiment configuration if url hash contains wrong id', function() { it('should not focus on any experiment configuration if url hash contains wrong id', function() {
spyOn(this.view, 'getLocationHash').andReturn('#1'); spyOn(this.view, 'getLocationHash').and.returnValue('#1');
this.view.render(); this.view.render();
expect($.fn.focus).not.toHaveBeenCalled(); expect($.fn.focus).not.toHaveBeenCalled();
expect(this.view.$(groupConfigItemClassName)).not.toBeExpanded(); expect(this.view.$(groupConfigItemClassName)).not.toBeExpanded();
......
...@@ -22,7 +22,7 @@ function ($, AjaxHelpers, ViewHelpers, ManageUsersFactory, ViewUtils) { ...@@ -22,7 +22,7 @@ function ($, AjaxHelpers, ViewHelpers, ManageUsersFactory, ViewUtils) {
describe("read-write access", function() { describe("read-write access", function() {
var mockHTML = readFixtures('mock/mock-manage-users-lib.underscore'); var mockHTML = readFixtures('mock/mock-manage-users-lib.underscore');
beforeEach(function () { beforeEach(function (done) {
ViewHelpers.installMockAnalytics(); ViewHelpers.installMockAnalytics();
setFixtures(mockHTML); setFixtures(mockHTML);
appendSetFixtures($("<script>", { id: "team-member-tpl", type: "text/template"}).text(team_member_fixture)); appendSetFixtures($("<script>", { id: "team-member-tpl", type: "text/template"}).text(team_member_fixture));
...@@ -37,9 +37,10 @@ function ($, AjaxHelpers, ViewHelpers, ManageUsersFactory, ViewUtils) { ...@@ -37,9 +37,10 @@ function ($, AjaxHelpers, ViewHelpers, ManageUsersFactory, ViewUtils) {
10000, 10000,
true true
); );
waitsFor(function(){
return $(".ui-loading").length === 0; jasmine.waitUntil(function() {
}, "Waiting for backbone render to happen", 1000); return ($(".ui-loading").length === 0);
}).then(done);
}); });
afterEach(function () { afterEach(function () {
......
...@@ -47,7 +47,7 @@ define( ...@@ -47,7 +47,7 @@ define(
it("should render created timestamp correctly", function() { it("should render created timestamp correctly", function() {
var fakeDate = "fake formatted date"; var fakeDate = "fake formatted date";
spyOn(Date.prototype, "toLocaleString").andCallFake( spyOn(Date.prototype, "toLocaleString").and.callFake(
function(locales, options) { function(locales, options) {
expect(locales).toEqual([]); expect(locales).toEqual([]);
expect(options.timeZone).toEqual("UTC"); expect(options.timeZone).toEqual("UTC");
......
define(["jquery", "common/js/spec_helpers/ajax_helpers", "common/js/spec_helpers/template_helpers", define(["jquery", "common/js/spec_helpers/ajax_helpers", "common/js/spec_helpers/template_helpers",
"common/js/spec_helpers/view_helpers", "common/js/components/utils/view_utils", "js/views/unit_outline", "js/models/xblock_info"], "common/js/spec_helpers/view_helpers", "common/js/components/utils/view_utils", "js/models/course",
function ($, AjaxHelpers, TemplateHelpers, ViewHelpers, ViewUtils, UnitOutlineView, XBlockInfo) { "js/views/unit_outline", "js/models/xblock_info"],
function ($, AjaxHelpers, TemplateHelpers, ViewHelpers, ViewUtils,
Course, UnitOutlineView, XBlockInfo) {
describe("UnitOutlineView", function() { describe("UnitOutlineView", function() {
var createUnitOutlineView, createMockXBlockInfo, var createUnitOutlineView, createMockXBlockInfo,
...@@ -71,6 +73,14 @@ define(["jquery", "common/js/spec_helpers/ajax_helpers", "common/js/spec_helpers ...@@ -71,6 +73,14 @@ define(["jquery", "common/js/spec_helpers/ajax_helpers", "common/js/spec_helpers
}; };
beforeEach(function () { beforeEach(function () {
window.course = new Course({
id: '5',
name: 'Course Name',
url_name: 'course_name',
org: 'course_org',
num: 'course_num',
revision: 'course_rev'
});
ViewHelpers.installMockAnalytics(); ViewHelpers.installMockAnalytics();
ViewHelpers.installViewTemplates(); ViewHelpers.installViewTemplates();
TemplateHelpers.installTemplate('unit-outline'); TemplateHelpers.installTemplate('unit-outline');
...@@ -78,6 +88,7 @@ define(["jquery", "common/js/spec_helpers/ajax_helpers", "common/js/spec_helpers ...@@ -78,6 +88,7 @@ define(["jquery", "common/js/spec_helpers/ajax_helpers", "common/js/spec_helpers
}); });
afterEach(function () { afterEach(function () {
delete window.course;
ViewHelpers.removeMockAnalytics(); ViewHelpers.removeMockAnalytics();
}); });
......
...@@ -91,7 +91,7 @@ define(["jquery", "URI", "common/js/spec_helpers/ajax_helpers", "common/js/compo ...@@ -91,7 +91,7 @@ define(["jquery", "URI", "common/js/spec_helpers/ajax_helpers", "common/js/compo
var requests = AjaxHelpers.requests(this), var requests = AjaxHelpers.requests(this),
missingJavaScriptUrl = "no_such_file.js", missingJavaScriptUrl = "no_such_file.js",
promise; promise;
spyOn(ViewUtils, 'loadJavaScript').andReturn($.Deferred().reject().promise()); spyOn(ViewUtils, 'loadJavaScript').and.returnValue($.Deferred().reject().promise());
promise = postXBlockRequest(requests, [ promise = postXBlockRequest(requests, [
["hash5", { mimetype: "application/javascript", kind: "url", data: missingJavaScriptUrl }] ["hash5", { mimetype: "application/javascript", kind: "url", data: missingJavaScriptUrl }]
]); ]);
...@@ -99,7 +99,7 @@ define(["jquery", "URI", "common/js/spec_helpers/ajax_helpers", "common/js/compo ...@@ -99,7 +99,7 @@ define(["jquery", "URI", "common/js/spec_helpers/ajax_helpers", "common/js/compo
}); });
it('Triggers an event to the runtime when a notification-action-button is clicked', function () { it('Triggers an event to the runtime when a notification-action-button is clicked', function () {
var notifySpy = spyOn(xblockView, "notifyRuntime").andCallThrough(); var notifySpy = spyOn(xblockView, "notifyRuntime").and.callThrough();
postXBlockRequest(AjaxHelpers.requests(this), []); postXBlockRequest(AjaxHelpers.requests(this), []);
xblockView.$el.find(".notification-action-button").click(); xblockView.$el.find(".notification-action-button").click();
......
...@@ -3,9 +3,9 @@ ...@@ -3,9 +3,9 @@
* It is expected to be backed by a Group model. * It is expected to be backed by a Group model.
*/ */
define([ define([
'js/views/baseview' 'js/views/baseview', 'underscore', 'underscore.string', 'gettext', 'text!templates/group-edit.underscore'
], ],
function(BaseView) { function(BaseView, _, str, gettext, groupEditTemplate) {
'use strict'; 'use strict';
var ExperimentGroupEditView = BaseView.extend({ var ExperimentGroupEditView = BaseView.extend({
tagName: 'li', tagName: 'li',
...@@ -22,7 +22,6 @@ function(BaseView) { ...@@ -22,7 +22,6 @@ function(BaseView) {
}, },
initialize: function() { initialize: function() {
this.template = this.loadTemplate('group-edit');
this.listenTo(this.model, 'change', this.render); this.listenTo(this.model, 'change', this.render);
}, },
...@@ -30,7 +29,7 @@ function(BaseView) { ...@@ -30,7 +29,7 @@ function(BaseView) {
var collection = this.model.collection, var collection = this.model.collection,
index = collection.indexOf(this.model); index = collection.indexOf(this.model);
this.$el.html(this.template({ this.$el.html(_.template(groupEditTemplate)({
name: this.model.get('name'), name: this.model.get('name'),
allocation: this.getAllocation(), allocation: this.getAllocation(),
index: index, index: index,
......
define(["js/views/baseview", "underscore"], function(BaseView, _) { define([
"js/views/baseview",
"underscore",
"text!templates/license-selector.underscore"
], function(BaseView, _, licenseSelectorTemplate) {
var defaultLicenseInfo = { var defaultLicenseInfo = {
"all-rights-reserved": { "all-rights-reserved": {
"name": gettext("All Rights Reserved"), "name": gettext("All Rights Reserved"),
...@@ -55,7 +59,6 @@ define(["js/views/baseview", "underscore"], function(BaseView, _) { ...@@ -55,7 +59,6 @@ define(["js/views/baseview", "underscore"], function(BaseView, _) {
initialize: function(options) { initialize: function(options) {
this.licenseInfo = options.licenseInfo || defaultLicenseInfo; this.licenseInfo = options.licenseInfo || defaultLicenseInfo;
this.showPreview = !!options.showPreview; // coerce to boolean this.showPreview = !!options.showPreview; // coerce to boolean
this.template = this.loadTemplate("license-selector");
// Rerender when the model changes // Rerender when the model changes
this.listenTo(this.model, 'change', this.render); this.listenTo(this.model, 'change', this.render);
...@@ -79,7 +82,7 @@ define(["js/views/baseview", "underscore"], function(BaseView, _) { ...@@ -79,7 +82,7 @@ define(["js/views/baseview", "underscore"], function(BaseView, _) {
}, },
render: function() { render: function() {
this.$el.html(this.template({ this.$el.html(_.template(licenseSelectorTemplate)({
model: this.model.attributes, model: this.model.attributes,
licenseString: this.model.toString() || "", licenseString: this.model.toString() || "",
licenseInfo: this.licenseInfo, licenseInfo: this.licenseInfo,
......
...@@ -48,10 +48,9 @@ lib_paths: ...@@ -48,10 +48,9 @@ lib_paths:
- xmodule_js/common_static/js/vendor/html5-input-polyfills/number-polyfill.js - xmodule_js/common_static/js/vendor/html5-input-polyfills/number-polyfill.js
- xmodule_js/common_static/js/vendor/sinon-1.17.0.js - xmodule_js/common_static/js/vendor/sinon-1.17.0.js
- xmodule_js/common_static/js/vendor/Squire.js - xmodule_js/common_static/js/vendor/Squire.js
- xmodule_js/common_static/js/vendor/jasmine-jquery.js - xmodule_js/common_static/js/libs/jasmine-stealth.js
- xmodule_js/common_static/js/vendor/jasmine-stealth.js - xmodule_js/common_static/js/libs/jasmine-waituntil.js
- xmodule_js/common_static/js/vendor/jasmine-imagediff.js - xmodule_js/common_static/js/vendor/jasmine-imagediff.js
- xmodule_js/common_static/js/vendor/jasmine.async.js
- xmodule_js/common_static/js/vendor/CodeMirror/codemirror.js - xmodule_js/common_static/js/vendor/CodeMirror/codemirror.js
- xmodule_js/common_static/js/vendor/jQuery-File-Upload/js - xmodule_js/common_static/js/vendor/jQuery-File-Upload/js
- xmodule_js/src/xmodule.js - xmodule_js/src/xmodule.js
......
...@@ -45,10 +45,7 @@ lib_paths: ...@@ -45,10 +45,7 @@ lib_paths:
- xmodule_js/common_static/js/vendor/html5-input-polyfills/number-polyfill.js - xmodule_js/common_static/js/vendor/html5-input-polyfills/number-polyfill.js
- xmodule_js/common_static/js/vendor/sinon-1.17.0.js - xmodule_js/common_static/js/vendor/sinon-1.17.0.js
- xmodule_js/common_static/js/vendor/Squire.js - xmodule_js/common_static/js/vendor/Squire.js
- xmodule_js/common_static/js/vendor/jasmine-jquery.js
- xmodule_js/common_static/js/vendor/jasmine-stealth.js
- xmodule_js/common_static/js/vendor/jasmine-imagediff.js - xmodule_js/common_static/js/vendor/jasmine-imagediff.js
- xmodule_js/common_static/js/vendor/jasmine.async.js
- xmodule_js/common_static/js/vendor/CodeMirror/codemirror.js - xmodule_js/common_static/js/vendor/CodeMirror/codemirror.js
- xmodule_js/common_static/js/vendor/domReady.js - xmodule_js/common_static/js/vendor/domReady.js
- xmodule_js/common_static/js/vendor/URI.min.js - xmodule_js/common_static/js/vendor/URI.min.js
......
...@@ -78,6 +78,7 @@ var files = [ ...@@ -78,6 +78,7 @@ var files = [
{pattern: 'xmodule_js/common_static/js/vendor/requirejs/text.js', included: false}, {pattern: 'xmodule_js/common_static/js/vendor/requirejs/text.js', included: false},
// Paths to source JavaScript files // Paths to source JavaScript files
{pattern: 'xmodule_js/common_static/js/libs/jasmine-extensions.js', included: true, nocache: true},
{pattern: 'coffee/src/**/*.js', included: false, nocache: true}, {pattern: 'coffee/src/**/*.js', included: false, nocache: true},
{pattern: 'js/**/*.js', included: false, nocache: true}, {pattern: 'js/**/*.js', included: false, nocache: true},
{pattern: 'js/certificates/**/*.js', included: false, nocache: true}, {pattern: 'js/certificates/**/*.js', included: false, nocache: true},
......
...@@ -70,6 +70,7 @@ var files = [ ...@@ -70,6 +70,7 @@ var files = [
{pattern: 'xmodule_js/common_static/js/vendor/requirejs/text.js', included: false}, {pattern: 'xmodule_js/common_static/js/vendor/requirejs/text.js', included: false},
// Paths to source JavaScript files // Paths to source JavaScript files
{pattern: 'xmodule_js/common_static/js/libs/jasmine-extensions.js', included: true, nocache: true},
{pattern: 'coffee/src/**/*.js', included: false, nocache: true}, {pattern: 'coffee/src/**/*.js', included: false, nocache: true},
{pattern: 'js/collections/**/*.js', included: false, nocache: true}, {pattern: 'js/collections/**/*.js', included: false, nocache: true},
{pattern: 'js/models/**/*.js', included: false, nocache: true}, {pattern: 'js/models/**/*.js', included: false, nocache: true},
......
<div class="xblock xblock-studio_view xmodule_edit xmodule_WrapperDescriptor" data-runtime-class="StudioRuntime" <div class="xblock xblock-studio_view xmodule_edit xmodule_WrapperDescriptor" data-runtime-class="StudioRuntime"
data-init="XBlockToXModuleShim" data-runtime-version="1" data-usage-id="i4x:;_;_edX;_mock" data-init="XBlockToXModuleShim" data-runtime-version="1" data-usage-id="i4x:;_;_edX;_mock"
data-type="VerticalDescriptor" tabindex="0"> data-type="MockDescriptor" tabindex="0">
<div class="wrapper-comp-editor is-active" id="editor-tab" data-base-asset-url="/c4x/AndyA/ABT101/asset/"> <div class="wrapper-comp-editor is-active" id="editor-tab" data-base-asset-url="/c4x/AndyA/ABT101/asset/">
<section class="editor-with-tabs"> <section class="editor-with-tabs">
<div class="edit-header"> <div class="edit-header">
......
<div class="xblock xblock-studio_view xmodule_edit xmodule_WrapperDescriptor" data-runtime-class="StudioRuntime" data-init="XBlockToXModuleShim" data-runtime-version="1" data-usage-id="i4x:;_;_AndyA;_ABT101;_wrapper;_wrapper_l1_poll" data-type="VerticalDescriptor" tabindex="0"> <div class="xblock xblock-studio_view xmodule_edit xmodule_WrapperDescriptor" data-runtime-class="StudioRuntime" data-init="XBlockToXModuleShim" data-runtime-version="1" data-usage-id="i4x:;_;_AndyA;_ABT101;_wrapper;_wrapper_l1_poll" data-type="MockDescriptor" tabindex="0">
<section class="sequence-edit"> <section class="sequence-edit">
<script id="metadata-editor-tpl" type="text/template"> <script id="metadata-editor-tpl" type="text/template">
<ul class="list-input settings-list"> <ul class="list-input settings-list">
......
...@@ -10,7 +10,13 @@ ...@@ -10,7 +10,13 @@
(function(root, factory) { (function(root, factory) {
/* jshint strict: false */ /* jshint strict: false */
factory(root, root.jQuery); if (typeof define === 'function' && define.amd) {
require(['jquery'], function ($) {
factory(root, $);
});
} else {
factory(root, root.jQuery);
}
}((function() { }((function() {
/* jshint strict: false */ /* jshint strict: false */
return this; return this;
...@@ -20,7 +26,9 @@ ...@@ -20,7 +26,9 @@
// Add custom Jasmine matchers. // Add custom Jasmine matchers.
beforeEach(function() { beforeEach(function() {
jasmine.addMatchers(window.imagediff.jasmine); if (window.imagediff) {
jasmine.addMatchers(window.imagediff.jasmine);
}
jasmine.addMatchers({ jasmine.addMatchers({
toHaveAttrs: function() { toHaveAttrs: function() {
...@@ -60,6 +68,16 @@ ...@@ -60,6 +68,16 @@
}; };
} }
}; };
},
toBeInstanceOf: function() {
// Assert the type of the value being tested matches the provided type
return {
compare: function (actual, expected) {
return {
pass: actual instanceof expected
};
}
};
} }
}); });
}); });
......
...@@ -122,8 +122,8 @@ class Env(object): ...@@ -122,8 +122,8 @@ class Env(object):
KARMA_CONFIG_FILES = [ KARMA_CONFIG_FILES = [
# REPO_ROOT / 'lms/static/karma_lms.conf.js', # REPO_ROOT / 'lms/static/karma_lms.conf.js',
# REPO_ROOT / 'lms/static/karma_lms_coffee.conf.js', # REPO_ROOT / 'lms/static/karma_lms_coffee.conf.js',
# REPO_ROOT / 'cms/static/karma_cms.conf.js', REPO_ROOT / 'cms/static/karma_cms.conf.js',
# REPO_ROOT / 'cms/static/karma_cms_squire.conf.js', REPO_ROOT / 'cms/static/karma_cms_squire.conf.js',
REPO_ROOT / 'common/lib/xmodule/xmodule/js/karma_xmodule.conf.js', REPO_ROOT / 'common/lib/xmodule/xmodule/js/karma_xmodule.conf.js',
REPO_ROOT / 'common/static/karma_common.conf.js', REPO_ROOT / 'common/static/karma_common.conf.js',
REPO_ROOT / 'common/static/karma_common_requirejs.conf.js', REPO_ROOT / 'common/static/karma_common_requirejs.conf.js',
...@@ -132,8 +132,8 @@ class Env(object): ...@@ -132,8 +132,8 @@ class Env(object):
JS_TEST_ID_KEYS = [ JS_TEST_ID_KEYS = [
# 'lms', # 'lms',
# 'lms-coffee', # 'lms-coffee',
# 'cms', 'cms',
# 'cms-squire', 'cms-squire',
'xmodule', 'xmodule',
'common', 'common',
'common-requirejs' 'common-requirejs'
......
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