Commit 51c5b981 by Usman Khalid

Merge pull request #12204 from edx/fedx/krma-conf-tnl4102

Use Karma as test runner with Jasmine 2.4.
parents 0cc0a454 5b12f7d3
requirejs.config({
baseUrl: '/base/',
paths: {
"gettext": "xmodule_js/common_static/js/test/i18n",
"mustache": "xmodule_js/common_static/js/vendor/mustache",
......@@ -42,10 +43,9 @@ requirejs.config({
"accessibility": "xmodule_js/common_static/js/src/accessibility_tools",
"sinon": "xmodule_js/common_static/js/vendor/sinon-1.17.0",
"squire": "xmodule_js/common_static/js/vendor/Squire",
"jasmine-jquery": "xmodule_js/common_static/js/vendor/jasmine-jquery",
"jasmine-imagediff": "xmodule_js/common_static/js/vendor/jasmine-imagediff",
"jasmine-stealth": "xmodule_js/common_static/js/vendor/jasmine-stealth",
"jasmine.async": "xmodule_js/common_static/js/vendor/jasmine.async",
"jasmine-stealth": "xmodule_js/common_static/js/libs/jasmine-stealth",
"jasmine-waituntil": "xmodule_js/common_static/js/libs/jasmine-waituntil",
"draggabilly": "xmodule_js/common_static/js/vendor/draggabilly",
"domReady": "xmodule_js/common_static/js/vendor/domReady",
"URI": "xmodule_js/common_static/js/vendor/URI.min",
......@@ -158,17 +158,17 @@ requirejs.config({
"mathjax": {
exports: "MathJax",
init: ->
MathJax.Hub.Config
tex2jax:
inlineMath: [
["\\(","\\)"],
['[mathjaxinline]','[/mathjaxinline]']
]
displayMath: [
["\\[","\\]"],
['[mathjax]','[/mathjax]']
]
MathJax.Hub.Configured()
MathJax.Hub.Config
tex2jax:
inlineMath: [
["\\(", "\\)"],
['[mathjaxinline]', '[/mathjaxinline]']
]
displayMath: [
["\\[", "\\]"],
['[mathjax]', '[/mathjax]']
]
MathJax.Hub.Configured()
},
"URI": {
exports: "URI"
......@@ -179,18 +179,12 @@ requirejs.config({
"sinon": {
exports: "sinon"
},
"jasmine-jquery": {
deps: ["jasmine"]
},
"jasmine-imagediff": {
deps: ["jasmine"]
},
"jasmine-imagediff": {},
"jasmine-stealth": {
deps: ["jasmine"]
deps: ["underscore", "underscore.string"]
},
"jasmine.async": {
deps: ["jasmine"],
exports: "AsyncSpec"
"jasmine-waituntil": {
deps: ["jquery"]
},
"xblock/core": {
exports: "XBlock",
......@@ -201,7 +195,7 @@ requirejs.config({
deps: ["xblock/core"]
},
"mock-ajax": {
deps: ["jasmine", "jquery"]
deps: ["jquery"]
}
"coffee/src/main": {
......@@ -221,35 +215,33 @@ requirejs.config({
jasmine.getFixtures().fixturesPath += 'coffee/fixtures'
define([
testFiles = [
"coffee/spec/main_spec",
"coffee/spec/models/course_spec", "coffee/spec/models/metadata_spec",
"coffee/spec/models/course_spec",
"coffee/spec/models/metadata_spec",
"coffee/spec/models/section_spec",
"coffee/spec/models/settings_course_grader_spec",
"coffee/spec/models/settings_grading_spec", "coffee/spec/models/textbook_spec",
"coffee/spec/models/settings_grading_spec",
"coffee/spec/models/textbook_spec",
"coffee/spec/models/upload_spec",
"coffee/spec/views/course_info_spec",
"coffee/spec/views/metadata_edit_spec",
"coffee/spec/views/module_edit_spec",
"coffee/spec/views/textbook_spec",
"coffee/spec/views/upload_spec",
"js/spec/video/transcripts/utils_spec", "js/spec/video/transcripts/editor_spec",
"js/spec/video/transcripts/videolist_spec", "js/spec/video/transcripts/message_manager_spec",
"js/spec/video/transcripts/file_uploader_spec",
"js/spec/video/transcripts/utils_spec",
"js/spec/video/transcripts/editor_spec",
# "js/spec/video/transcripts/videolist_spec",
# "js/spec/video/transcripts/message_manager_spec",
# "js/spec/video/transcripts/file_uploader_spec",
"js/spec/models/component_template_spec",
"js/spec/models/explicit_url_spec",
"js/spec/models/xblock_info_spec",
"js/spec/models/xblock_validation_spec",
"js/spec/models/license_spec",
"js/spec/utils/drag_and_drop_spec",
"js/spec/utils/handle_iframe_binding_spec",
"js/spec/utils/module_spec",
"js/spec/views/active_video_upload_list_spec",
"js/spec/views/previous_video_upload_spec",
"js/spec/views/previous_video_upload_list_spec",
......@@ -266,7 +258,6 @@ define([
"js/spec/views/license_spec",
"js/spec/views/paging_spec",
"js/spec/views/login_studio_spec",
"js/spec/views/pages/container_spec",
"js/spec/views/pages/container_subviews_spec",
"js/spec/views/pages/group_configurations_spec",
......@@ -274,25 +265,24 @@ define([
"js/spec/views/pages/course_rerun_spec",
"js/spec/views/pages/index_spec",
"js/spec/views/pages/library_users_spec",
"js/spec/views/modals/base_modal_spec",
"js/spec/views/modals/edit_xblock_spec",
"js/spec/views/modals/validation_error_modal_spec",
"js/spec/views/settings/main_spec",
"js/spec/factories/xblock_validation_spec",
"js/spec/xblock/cms.runtime.v1_spec",
# Certificates application test suite mappings
"js/certificates/spec/models/certificate_spec",
"js/certificates/spec/views/certificate_details_spec",
"js/certificates/spec/views/certificate_editor_spec",
"js/certificates/spec/views/certificates_list_spec",
"js/certificates/spec/views/certificate_preview_spec",
"js/certificates/spec/views/certificate_preview_spec"
]
i = 0
while i < testFiles.length
testFiles[i] = '/base/' + testFiles[i] + '.js'
i++
# these tests are run separately in the cms-squire suite, due to process
# isolation issues with Squire.js
# "coffee/spec/views/assets_spec"
])
require testFiles, ->
# start test run, once Require.js is done
window.__karma__.start()
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) ->
describe "CMS", ->
it "should initialize URL", ->
......@@ -7,8 +8,12 @@ require ["jquery", "backbone", "coffee/src/main", "common/js/spec_helpers/ajax_h
describe "main helper", ->
beforeEach ->
@previousAjaxSettings = $.extend(true, {}, $.ajaxSettings)
spyOn($, "cookie")
$.cookie.when("csrftoken").thenReturn("stubCSRFToken")
spyOn($, "cookie").and.callFake(
(param) ->
if param == "csrftoken"
return "stubCSRFToken"
)
main()
afterEach ->
......@@ -21,12 +26,15 @@ require ["jquery", "backbone", "coffee/src/main", "common/js/spec_helpers/ajax_h
expect($.ajaxSettings.headers["X-CSRFToken"]).toEqual("stubCSRFToken")
describe "AJAX Errors", ->
server = null
beforeEach ->
appendSetFixtures(sandbox({id: "page-notification"}))
afterEach ->
server && server.restore()
it "successful AJAX request does not pop an error notification", ->
server = AjaxHelpers.server(this, [200, {}, ''])
server = AjaxHelpers.server([200, {}, ''])
expect($("#page-notification")).toBeEmpty()
$.ajax("/test")
......@@ -35,15 +43,15 @@ require ["jquery", "backbone", "coffee/src/main", "common/js/spec_helpers/ajax_h
expect($("#page-notification")).toBeEmpty()
it "AJAX request with error should pop an error notification", ->
server = AjaxHelpers.server(this, [500, {}, ''])
server = AjaxHelpers.server([500, {}, ''])
$.ajax("/test")
server.respond()
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", ->
server = AjaxHelpers.server(this, [500, {}, ''])
server = AjaxHelpers.server([500, {}, ''])
$.ajax
url: "/test"
......
requirejs.config({
baseUrl: '/base/',
paths: {
"gettext": "xmodule_js/common_static/js/test/i18n",
"mustache": "xmodule_js/common_static/js/vendor/mustache",
......@@ -22,8 +24,8 @@ requirejs.config({
"datepair": "xmodule_js/common_static/js/vendor/timepicker/datepair",
"date": "xmodule_js/common_static/js/vendor/date",
"text": "xmodule_js/common_static/js/vendor/requirejs/text",
"underscore": "xmodule_js/common_static/common/js/vendor/underscore",
"underscore.string": "xmodule_js/common_static/common/js/vendor/underscore.string",
"underscore": "common/js/vendor/underscore",
"underscore.string": "common/js/vendor/underscore.string",
"backbone": "xmodule_js/common_static/js/vendor/backbone-min",
"backbone.associations": "xmodule_js/common_static/js/vendor/backbone-associations-min",
"backbone.paginator": "xmodule_js/common_static/js/vendor/backbone.paginator.min",
......@@ -36,11 +38,11 @@ requirejs.config({
"utility": "xmodule_js/common_static/js/src/utility",
"sinon": "xmodule_js/common_static/js/vendor/sinon-1.17.0",
"squire": "xmodule_js/common_static/js/vendor/Squire",
"jasmine-stealth": "xmodule_js/common_static/js/vendor/jasmine-stealth",
"jasmine.async": "xmodule_js/common_static/js/vendor/jasmine.async",
"modernizr": "xmodule_js/common_static/edx-pattern-library/js/modernizr-custom",
"afontgarde": "xmodule_js/common_static/edx-pattern-library/js/afontgarde",
"edxicons": "xmodule_js/common_static/edx-pattern-library/js/edx-icons",
"jasmine-stealth": "xmodule_js/common_static/js/libs/jasmine-stealth",
"jasmine-waituntil": "xmodule_js/common_static/js/libs/jasmine-waituntil",
"draggabilly": "xmodule_js/common_static/js/vendor/draggabilly",
"domReady": "xmodule_js/common_static/js/vendor/domReady",
"URI": "xmodule_js/common_static/js/vendor/URI.min",
......@@ -159,11 +161,10 @@ requirejs.config({
exports: "sinon"
},
"jasmine-stealth": {
deps: ["jasmine"]
deps: ["underscore", "underscore.string"]
},
"jasmine.async": {
deps: ["jasmine"],
exports: "AsyncSpec"
"jasmine-waituntil": {
deps: ["jquery"]
},
"xblock/core": {
exports: "XBlock",
......@@ -191,9 +192,16 @@ requirejs.config({
jasmine.getFixtures().fixturesPath += 'coffee/fixtures'
define([
"coffee/spec/views/assets_spec",
"js/spec/video/translations_editor_spec",
"js/spec/video/file_uploader_editor_spec",
"js/spec/models/group_configuration_spec"
])
testFiles = [
'coffee/spec/views/assets_spec',
'js/spec/video/translations_editor_spec',
'js/spec/video/file_uploader_editor_spec',
'js/spec/models/group_configuration_spec'
]
i = 0
while i < testFiles.length
testFiles[i] = '/base/' + testFiles[i] + '.js'
i++
require testFiles, ->
# start test run, once Require.js is done
window.__karma__.start()
......@@ -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", ->
server = AjaxHelpers.server(this, [200, {}, ''])
server = AjaxHelpers.server([200, {}, ''])
@model.save()
expect(Section.prototype.showNotification).toHaveBeenCalled()
......@@ -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", ->
# this is handled by the global AJAX error handler
server = AjaxHelpers.server(this, [500, {}, ''])
server = AjaxHelpers.server([500, {}, ''])
@model.save()
server.respond()
......
define ["backbone", "js/models/textbook", "js/collections/textbook", "js/models/chapter", "js/collections/chapter", "coffee/src/main"],
(Backbone, Textbook, TextbookSet, Chapter, ChapterSet, main) ->
beforeEach ->
@addMatchers
toBeInstanceOf: (expected) ->
return @actual instanceof expected
describe "Textbook model", ->
beforeEach ->
main()
......
......@@ -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).
# Therefore call onNew directly.
@courseInfoEdit.onNew(@event)
spyOn(@courseInfoEdit.$codeMirror, 'getValue').andReturn(text)
spyOn(@courseInfoEdit.$codeMirror, 'getValue').and.returnValue(text)
@courseInfoEdit.$el.find('.save-button').click()
@cancelNewCourseInfo = (useCancelButton) ->
@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)
spyOn(model, "save").andCallThrough()
spyOn(model, "save").and.callThrough()
cancelEditingUpdate(@courseInfoEdit, @courseInfoEdit.$modalCover, useCancelButton)
......@@ -67,11 +67,11 @@ define ["js/views/course_info_handout", "js/views/course_info_update", "js/model
@doNotCloseNewCourseInfo = () ->
@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)
spyOn(model, "save").andCallThrough()
spyOn(model, "save").and.callThrough()
cancelEditingUpdate(@courseInfoEdit, @courseInfoEdit.$modalCover, false)
......@@ -81,11 +81,11 @@ define ["js/views/course_info_handout", "js/views/course_info_update", "js/model
@cancelExistingCourseInfo = (useCancelButton) ->
@createNewUpdate('existing update')
@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)
spyOn(model, "save").andCallThrough()
spyOn(model, "save").and.callThrough()
model.id = "saved_to_server"
cancelEditingUpdate(@courseInfoEdit, @courseInfoEdit.$modalCover, useCancelButton)
......@@ -94,6 +94,20 @@ define ["js/views/course_info_handout", "js/views/course_info_update", "js/model
previewContents = @courseInfoEdit.$el.find('.update-contents').html()
expect(previewContents).toEqual('existing update')
@testInvalidDateValue = (value) ->
@courseInfoEdit.onNew(@event)
expect(@courseInfoEdit.$el.find('.save-button').hasClass("is-disabled")).toEqual(false)
@courseInfoEdit.$el.find('input.date').val(value).trigger("change")
courseInfoEdit = @courseInfoEdit
jasmine.waitUntil(->
courseInfoEdit.$el.find('.save-button').hasClass('is-disabled') == true
).then ->
courseInfoEdit.$el.find('input.date').val('01/01/16').trigger 'change'
jasmine.waitUntil(->
courseInfoEdit.$el.find('.save-button').hasClass('is-disabled') == false
).always done
return
cancelEditingUpdate = (update, modalCover, useCancelButton) ->
if useCancelButton
update.$el.find('.cancel-button').click()
......@@ -109,8 +123,8 @@ define ["js/views/course_info_handout", "js/views/course_info_update", "js/model
@courseInfoEdit.onNew(@event)
expect(@collection.length).toEqual(1)
model = @collection.at(0)
spyOn(model, "save").andCallThrough()
spyOn(@courseInfoEdit.$codeMirror, 'getValue').andReturn('/static/image.jpg')
spyOn(model, "save").and.callThrough()
spyOn(@courseInfoEdit.$codeMirror, 'getValue').and.returnValue('/static/image.jpg')
# Click the "Save button."
@courseInfoEdit.$el.find('.save-button').click()
......@@ -153,14 +167,6 @@ define ["js/views/course_info_handout", "js/views/course_info_update", "js/model
it "does not remove existing course info on click outside modal", ->
@cancelExistingCourseInfo(false)
@testInvalidDateValue: (value) ->
@courseInfoEdit.onNew(@event)
expect(@courseInfoEdit.$el.find('.save-button').hasClass("is-disabled")).toEqual(false)
@courseInfoEdit.$el.find('input.date').val(value).trigger("change")
expect(@courseInfoEdit.$el.find('.save-button').hasClass("is-disabled")).toEqual(true)
@courseInfoEdit.$el.find('input.date').val("01/01/16").trigger("change")
expect(@courseInfoEdit.$el.find('.save-button').hasClass("is-disabled")).toEqual(false)
it "does not allow updates to be saved with an invalid date", ->
@testInvalidDateValue("Marchtober 40, 2048")
......@@ -196,7 +202,7 @@ define ["js/views/course_info_handout", "js/views/course_info_update", "js/model
expect(requestSent.push_notification_selected).toEqual(true)
# 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}))
it "sends correct value for push_notification_selected when it is unselected", ->
......@@ -208,7 +214,7 @@ define ["js/views/course_info_handout", "js/views/course_info_update", "js/model
expect(requestSent.push_notification_selected).toEqual(false)
# 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}))
describe "Course Handouts", ->
......@@ -237,8 +243,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
# when "Save" is clicked.
@handoutsEdit.$el.find('.edit-button').click()
spyOn(@handoutsEdit.$codeMirror, 'getValue').andReturn('/static/image.jpg')
spyOn(@model, "save").andCallThrough()
spyOn(@handoutsEdit.$codeMirror, 'getValue').and.returnValue('/static/image.jpg')
spyOn(@model, "save").and.callThrough()
@handoutsEdit.$el.find('.save-button').click()
expect(@model.save).toHaveBeenCalled()
......@@ -251,7 +257,7 @@ define ["js/views/course_info_handout", "js/views/course_info_update", "js/model
it "does rewrite links after edit", ->
# Edit handouts and save.
@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()
# Verify preview text.
......
......@@ -29,7 +29,7 @@ define ["jquery", "common/js/components/utils/view_utils", "js/spec_helpers/edit
</ul>
"""
edit_helpers.installEditTemplates(true);
spyOn($, 'ajax').andReturn(@moduleData)
spyOn($, 'ajax').and.returnValue(@moduleData)
@moduleEdit = new ModuleEdit(
el: $(".component")
......@@ -62,7 +62,7 @@ define ["jquery", "common/js/components/utils/view_utils", "js/spec_helpers/edit
spyOn(@moduleEdit, 'loadDisplay')
spyOn(@moduleEdit, 'delegateEvents')
spyOn($.fn, 'append')
spyOn(ViewUtils, 'loadJavaScript').andReturn($.Deferred().resolve().promise());
spyOn(ViewUtils, 'loadJavaScript').and.returnValue($.Deferred().resolve().promise());
window.MockXBlock = (runtime, element) ->
return { }
......@@ -70,7 +70,7 @@ define ["jquery", "common/js/components/utils/view_utils", "js/spec_helpers/edit
window.loadedXBlockResources = undefined
@moduleEdit.render()
$.ajax.mostRecentCall.args[0].success(
$.ajax.calls.mostRecent().args[0].success(
html: '<div>Response html</div>'
resources: [
['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
mockXBlockEditorHtml = readFixtures('mock/mock-xblock-editor.underscore')
$.ajax.mostRecentCall.args[0].success(
$.ajax.calls.mostRecent().args[0].success(
html: mockXBlockEditorHtml
resources: [
['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
expect($.fn.append).not.toHaveBeenCalledWith('not-head-html')
it "doesn't reload resources", ->
count = $('head').append.callCount
$.ajax.mostRecentCall.args[0].success(
count = $('head').append.calls.count()
$.ajax.calls.mostRecent().args[0].success(
html: '<div>Response html 2</div>'
resources: [
['hash1', {kind: 'text', mimetype: 'text/css', data: 'inline-css'}],
]
)
expect($('head').append.callCount).toBe(count)
expect($('head').append.calls.count()).toBe(count)
describe "loadDisplay", ->
beforeEach ->
......@@ -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", ->
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
"js/spec_helpers/modal_helpers", "jasmine-stealth"],
(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", ->
tpl = readFixtures('show-textbook.underscore')
......@@ -23,12 +13,12 @@ define ["js/models/textbook", "js/models/chapter", "js/collections/chapter", "js
appendSetFixtures(sandbox({id: "page-notification"}))
appendSetFixtures(sandbox({id: "page-prompt"}))
@model = new Textbook({name: "Life Sciences", id: "0life-sciences"})
spyOn(@model, "destroy").andCallThrough()
spyOn(@model, "destroy").and.callThrough()
@collection = new TextbookSet([@model])
@view = new ShowTextbook({model: @model})
@promptSpies = spyOnConstructor(Prompt, "Warning", ["show", "hide"])
@promptSpies.show.andReturn(@promptSpies)
@promptSpies = jasmine.stealth.spyOnConstructor(Prompt, "Warning", ["show", "hide"])
@promptSpies.show.and.returnValue(@promptSpies)
window.course = new Course({
id: "5",
name: "Course Name",
......@@ -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", ->
@view.render().$(".delete").click()
expect(@promptSpies.constructor).toHaveBeenCalled()
ctorOptions = @promptSpies.constructor.mostRecentCall.args[0]
ctorOptions = @promptSpies.constructor.calls.mostRecent().args[0]
expect(ctorOptions.title).toMatch(/Life Sciences/)
# hasn't actually been removed
expect(@model.destroy).not.toHaveBeenCalled()
......@@ -73,9 +63,9 @@ define ["js/models/textbook", "js/models/chapter", "js/collections/chapter", "js
describe "AJAX", ->
beforeEach ->
@savingSpies = spyOnConstructor(Notification, "Mini",
@savingSpies = jasmine.stealth.spyOnConstructor(Notification, "Mini",
["show", "hide"])
@savingSpies.show.andReturn(@savingSpies)
@savingSpies.show.and.returnValue(@savingSpies)
CMS.URL.TEXTBOOKS = "/textbooks"
afterEach ->
......@@ -85,7 +75,7 @@ define ["js/models/textbook", "js/models/chapter", "js/collections/chapter", "js
requests = AjaxHelpers["requests"](this)
@view.render().$(".delete").click()
ctorOptions = @promptSpies.constructor.mostRecentCall.args[0]
ctorOptions = @promptSpies.constructor.calls.mostRecent().args[0]
# run the primary function to indicate confirmation
ctorOptions.actions.primary.click(@promptSpies)
# AJAX request has been sent, but not yet returned
......@@ -94,7 +84,7 @@ define ["js/models/textbook", "js/models/chapter", "js/collections/chapter", "js
expect(@savingSpies.constructor).toHaveBeenCalled()
expect(@savingSpies.show).toHaveBeenCalled()
expect(@savingSpies.hide).not.toHaveBeenCalled()
savingOptions = @savingSpies.constructor.mostRecentCall.args[0]
savingOptions = @savingSpies.constructor.calls.mostRecent().args[0]
expect(savingOptions.title).toMatch(/Deleting/)
# return a success response
requests[0].respond(200)
......@@ -114,7 +104,7 @@ define ["js/models/textbook", "js/models/chapter", "js/collections/chapter", "js
@collection = new TextbookSet()
@collection.add(@model)
@view = new EditTextbook({model: @model})
spyOn(@view, 'render').andCallThrough()
spyOn(@view, 'render').and.callThrough()
it "should render properly", ->
@view.render()
......@@ -209,10 +199,16 @@ define ["js/models/textbook", "js/models/chapter", "js/collections/chapter", "js
expect(ViewUtils.setScrollOffset).toHaveBeenCalledWith($sectionEl, 0)
it "should focus first input element of newly added textbook", ->
spyOn(jQuery.fn, 'focus').andCallThrough()
@addMatchers
toHaveBeenCalledOnJQueryObject: (actual, expected) ->
pass: actual.calls && actual.calls.mostRecent() && actual.calls.mostRecent().object[0] == expected[0]
spyOn(jQuery.fn, 'focus').and.callThrough()
jasmine.addMatchers
toHaveBeenCalledOnJQueryObject: () ->
return {
compare: (actual, expected) ->
return {
pass: actual.calls && actual.calls.mostRecent() &&
actual.calls.mostRecent().object[0] == expected[0]
}
}
@view.$(".new-button").click()
$inputEl = @view.$el.find('section:last input:first')
expect($inputEl.length).toEqual(1)
......@@ -229,13 +225,13 @@ define ["js/models/textbook", "js/models/chapter", "js/collections/chapter", "js
# beforeEach ->
# setFixtures($("<script>", {id: "no-textbooks-tpl", type: "text/template"}).text(noTextbooksTpl))
# @showSpies = spyOnConstructor("ShowTextbook", ["render"])
# @showSpies.render.andReturn(@showSpies) # equivalent of `return this`
# @showSpies.render.and.returnValue(@showSpies) # equivalent of `return this`
# showEl = $("<li>")
# @showSpies.$el = showEl
# @showSpies.el = showEl.get(0)
# @editSpies = spyOnConstructor("EditTextbook", ["render"])
# editEl = $("<li>")
# @editSpies.render.andReturn(@editSpies)
# @editSpies.render.and.returnValue(@editSpies)
# @editSpies.$el = editEl
# @editSpies.el= editEl.get(0)
#
......@@ -304,7 +300,7 @@ define ["js/models/textbook", "js/models/chapter", "js/collections/chapter", "js
@collection = new ChapterSet()
@collection.add(@model)
@view = new EditChapter({model: @model})
spyOn(@view, "remove").andCallThrough()
spyOn(@view, "remove").and.callThrough()
CMS.URL.UPLOAD_ASSET = "/upload"
window.course = new Course({name: "abcde"})
......@@ -324,10 +320,10 @@ define ["js/models/textbook", "js/models/chapter", "js/collections/chapter", "js
# it "can open an upload dialog", ->
# uploadSpies = spyOnConstructor("UploadDialog", ["show", "el"])
# uploadSpies.show.andReturn(uploadSpies)
# uploadSpies.show.and.returnValue(uploadSpies)
#
# @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(typeof ctorOptions.onSuccess).toBe('function')
# expect(uploadSpies.show).toHaveBeenCalled()
......
......@@ -7,75 +7,80 @@ define ["js/models/uploads", "js/views/uploads", "js/models/chapter", "common/js
modal_helpers.installModalTemplates()
appendSetFixtures($("<script>", {id: "upload-dialog-tpl", type: "text/template"}).text(tpl))
CMS.URL.UPLOAD_ASSET = "/upload"
@model = new FileUpload(
mimeTypes: ['application/pdf']
)
@dialogResponse = dialogResponse = []
@view = new UploadDialog(
model: @model,
@mockFiles = []
afterEach ->
delete CMS.URL.UPLOAD_ASSET
modal_helpers.cancelModalIfShowing()
createTestView = (test) ->
view = new UploadDialog(
model: test.model,
url: CMS.URL.UPLOAD_ASSET,
onSuccess: (response) =>
dialogResponse.push(response.response)
test.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
@mockFiles = []
mockFileInput = jasmine.createSpy('mockFileInput')
mockFileInput.files = @mockFiles
mockFileInput.files = test.mockFiles
jqMockFileInput = jasmine.createSpyObj('jqMockFileInput', ['get', 'replaceWith'])
jqMockFileInput.get.andReturn(mockFileInput)
realMethod = @view.$
spyOn(@view, "$").andCallFake (selector) ->
jqMockFileInput.get.and.returnValue(mockFileInput)
originalView$ = view.$
spyOn(view, "$").and.callFake (selector) ->
if selector == "input[type=file]"
jqMockFileInput
else
realMethod.apply(this, arguments)
afterEach ->
delete CMS.URL.UPLOAD_ASSET
if (@view && modal_helpers.isShowingModal(@view))
@view.hide()
originalView$.apply(this, arguments)
@lastView = view
describe "Basic", ->
it "should render without a file selected", ->
@view.render()
expect(@view.$el).toContain("input[type=file]")
expect(@view.$(".action-upload")).toHaveClass("disabled")
view = createTestView(this)
view.render()
expect(view.$el).toContainElement("input[type=file]")
expect(view.$(".action-upload")).toHaveClass("disabled")
it "should render with a PDF selected", ->
view = createTestView(this)
file = {name: "fake.pdf", "type": "application/pdf"}
@mockFiles.push(file)
@model.set("selectedFile", file)
@view.render()
expect(@view.$el).toContain("input[type=file]")
expect(@view.$el).not.toContain("#upload_error")
expect(@view.$(".action-upload")).not.toHaveClass("disabled")
view.render()
expect(view.$el).toContainElement("input[type=file]")
expect(view.$el).not.toContainElement("#upload_error")
expect(view.$(".action-upload")).not.toHaveClass("disabled")
it "should render an error with an invalid file type selected", ->
view = createTestView(this)
file = {name: "fake.png", "type": "image/png"}
@mockFiles.push(file)
@model.set("selectedFile", file)
@view.render()
expect(@view.$el).toContain("input[type=file]")
expect(@view.$el).toContain("#upload_error")
expect(@view.$(".action-upload")).toHaveClass("disabled")
view.render()
expect(view.$el).toContainElement("input[type=file]")
expect(view.$el).toContainElement("#upload_error")
expect(view.$(".action-upload")).toHaveClass("disabled")
it "should render an error with an invalid file type after a correct file type selected", ->
view = createTestView(this)
correctFile = {name: "fake.pdf", "type": "application/pdf"}
inCorrectFile = {name: "fake.png", "type": "image/png"}
event = {}
@view.render()
view.render()
event.target = {"files": [correctFile]}
@view.selectFile(event)
expect(@view.$el).toContain("input[type=file]")
expect(@view.$el).not.toContain("#upload_error")
expect(@view.$(".action-upload")).not.toHaveClass("disabled")
view.selectFile(event)
expect(view.$el).toContainElement("input[type=file]")
expect(view.$el).not.toContainElement("#upload_error")
expect(view.$(".action-upload")).not.toHaveClass("disabled")
realMethod = @model.set
spyOn(@model, "set").andCallFake (data) ->
spyOn(@model, "set").and.callFake (data) ->
if data.selectedFile != undefined
this.attributes.selectedFile = data.selectedFile
this.changed = {}
......@@ -83,51 +88,46 @@ define ["js/models/uploads", "js/views/uploads", "js/models/chapter", "common/js
realMethod.apply(this, arguments)
event.target = {"files": [inCorrectFile]}
@view.selectFile(event)
expect(@view.$el).toContain("input[type=file]")
expect(@view.$el).toContain("#upload_error")
expect(@view.$(".action-upload")).toHaveClass("disabled")
view.selectFile(event)
expect(view.$el).toContainElement("input[type=file]")
expect(view.$el).toContainElement("#upload_error")
expect(view.$(".action-upload")).toHaveClass("disabled")
describe "Uploads", ->
beforeEach ->
@clock = sinon.useFakeTimers()
afterEach ->
modal_helpers.cancelModalIfShowing()
@clock.restore()
it "can upload correctly", ->
requests = AjaxHelpers["requests"](this)
@view.render()
@view.upload()
requests = AjaxHelpers.requests(this);
view = createTestView(this)
view.render()
view.upload()
expect(@model.get("uploading")).toBeTruthy()
expect(requests.length).toEqual(1)
request = requests[0]
expect(request.url).toEqual("/upload")
expect(request.method).toEqual("POST")
request.respond(200, {"Content-Type": "application/json"},
'{"response": "dummy_response"}')
AjaxHelpers.expectRequest(requests, "POST", "/upload")
AjaxHelpers.respondWithJson(requests, { response: "dummy_response"})
expect(@model.get("uploading")).toBeFalsy()
expect(@model.get("finished")).toBeTruthy()
expect(@dialogResponse.pop()).toEqual("dummy_response")
it "can handle upload errors", ->
requests = AjaxHelpers["requests"](this)
@view.render()
@view.upload()
requests[0].respond(500)
requests = AjaxHelpers.requests(this);
view = createTestView(this)
view.render()
view.upload()
AjaxHelpers.respondWithError(requests)
expect(@model.get("title")).toMatch(/error/)
expect(@view.remove).not.toHaveBeenCalled()
expect(view.remove).not.toHaveBeenCalled()
it "removes itself after two seconds on successful upload", ->
requests = AjaxHelpers["requests"](this)
@view.render()
@view.upload()
requests[0].respond(200, {"Content-Type": "application/json"},
'{"response": "dummy_response"}')
expect(modal_helpers.isShowingModal(@view)).toBeTruthy();
requests = AjaxHelpers.requests(this);
view = createTestView(this)
view.render()
view.upload()
AjaxHelpers.respondWithJson(requests, { response: "dummy_response"})
expect(modal_helpers.isShowingModal(view)).toBeTruthy();
@clock.tick(2001)
expect(modal_helpers.isShowingModal(@view)).toBeFalsy();
expect(modal_helpers.isShowingModal(view)).toBeFalsy();
......@@ -3,29 +3,21 @@
define(['jquery'], function($) { // jshint ignore:line
'use strict';
return function (that) {
that.addMatchers({
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) {
return function () {
jasmine.addMatchers({
toBeCorrectValuesInModel: function () {
// Assert the value being tested has key values which match the provided values
return _.every(values, function (value, key) {
return this.actual.get(key) === value;
}.bind(this));
},
return {
compare: function (actual, values) {
var passed = _.every(values, function (value, key) {
return actual.get(key) === value;
}.bind(this));
toBeInstanceOf: function(expected) {
// Assert the type of the value being tested matches the provided type
return this.actual instanceof expected;
return {
pass: passed
};
}
};
}
});
};
......
......@@ -47,27 +47,6 @@ function(_, Course, CertificatesCollection, CertificateModel, CertificateDetails
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() {
var setValuesToInputs = function (view, values) {
_.each(values, function (value, selector) {
......@@ -81,6 +60,20 @@ function(_, Course, CertificatesCollection, CertificateModel, CertificateDetails
beforeEach(function() {
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.model = new CertificateModel({
name: 'Test Name',
......@@ -97,7 +90,13 @@ function(_, Course, CertificatesCollection, CertificateModel, CertificateDetails
model: this.model
});
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() {
......
......@@ -18,7 +18,7 @@ function(_, Course, CertificateModel, SignatoryModel, CertificatesCollection, Ce
Notification, AjaxHelpers, TemplateHelpers, ViewHelpers, ValidationHelpers, CustomMatchers) {
'use strict';
var MAX_SIGNATORIES = 100;
var MAX_SIGNATORIES_LIMIT = 10;
var SELECTORS = {
detailsView: '.certificate-details',
editView: '.certificate-edit',
......@@ -76,23 +76,6 @@ function(_, Course, CertificateModel, SignatoryModel, CertificatesCollection, Ce
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() {
var setValuesToInputs = function (view, values) {
_.each(values, function (value, selector) {
......@@ -109,6 +92,16 @@ function(_, Course, CertificateModel, SignatoryModel, CertificatesCollection, Ce
beforeEach(function() {
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.model = new CertificateModel({
name: 'Test Name',
......@@ -122,10 +115,16 @@ function(_, Course, CertificateModel, SignatoryModel, CertificatesCollection, Ce
});
this.model.set('id', 0);
this.view = new CertificateEditorView({
model: this.model
model: this.model,
max_signatories_limit: MAX_SIGNATORIES_LIMIT
});
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 () {
......@@ -198,8 +197,8 @@ function(_, Course, CertificateModel, SignatoryModel, CertificatesCollection, Ce
expect(this.collection.length).toBe(1);
});
it('user can only add signatories up to max 100', function() {
for(var i = 1; i < MAX_SIGNATORIES ; i++) {
it('user can only add signatories up to limit', function() {
for(var i = 1; i < MAX_SIGNATORIES_LIMIT ; i++) {
this.view.$(SELECTORS.addSignatoryButton).click();
}
expect(this.view.$(SELECTORS.addSignatoryButton)).toHaveClass('disableClick');
......@@ -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',
function() {
for(var i = 1; i < MAX_SIGNATORIES ; i++) {
for(var i = 1; i < MAX_SIGNATORIES_LIMIT ; i++) {
this.view.$(SELECTORS.addSignatoryButton).click();
}
expect(this.view.$(SELECTORS.addSignatoryButton)).toHaveClass('disableClick');
......@@ -274,7 +273,7 @@ function(_, Course, CertificateModel, SignatoryModel, CertificatesCollection, Ce
var signatory = this.model.get('signatories').at(0);
var signatory_url = '/certificates/signatory';
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?';
clickDeleteItem(this, text, SELECTORS.signatoryDeleteButton + ':first', signatory_url);
expect(this.model.get('signatories').length).toEqual(total_signatories - 1);
......@@ -283,7 +282,7 @@ function(_, Course, CertificateModel, SignatoryModel, CertificatesCollection, Ce
it('can cancel deletion of signatories', function() {
this.view.$(SELECTORS.addSignatoryButton).click();
var signatory = this.model.get('signatories').at(0);
spyOn(signatory, "isNew").andReturn(false);
spyOn(signatory, "isNew").and.returnValue(false);
// add one more signatory
this.view.$(SELECTORS.addSignatoryButton).click();
var total_signatories = this.model.get('signatories').length;
......
......@@ -18,23 +18,6 @@ function(_, $, Course, CertificatePreview, TemplateHelpers, ViewHelpers, AjaxHel
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() {
var selectDropDownByText = function ( element, value ) {
......@@ -45,8 +28,18 @@ function(_, $, Course, CertificatePreview, TemplateHelpers, ViewHelpers, AjaxHel
};
beforeEach(function() {
TemplateHelpers.installTemplate('certificate-web-preview', true);
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({
el: $('.preview-certificate'),
course_modes: ['test1', 'test2', 'test3'],
......@@ -57,6 +50,11 @@ function(_, $, Course, CertificatePreview, TemplateHelpers, ViewHelpers, AjaxHel
appendSetFixtures(this.view.render().el);
});
afterEach(function() {
delete window.course;
delete window.CMS.User;
});
describe('Certificate preview', function() {
it('course mode event should call when user choose a new mode', function () {
spyOn(this.view, 'courseModeChanged');
......@@ -122,7 +120,7 @@ function(_, $, Course, CertificatePreview, TemplateHelpers, ViewHelpers, AjaxHel
it('certificate web preview should be removed when method "remove" called', function () {
this.view.remove();
expect(this.view.el.innerHTML).toContain("");
expect(this.view.el.innerHTML).toBe('');
});
it('method "show" should call the render function', function () {
......
......@@ -27,33 +27,28 @@ function(_, Course, CertificatesCollection, CertificateModel, CertificateDetails
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() {
var emptyMessage = 'You have not created any certificates yet.';
beforeEach(function() {
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({
course_title: 'Test Course Title Override'
}, {add: true});
......@@ -61,11 +56,18 @@ function(_, Course, CertificatesCollection, CertificateModel, CertificateDetails
this.collection = new CertificatesCollection([], {
certificateUrl: '/certificates/'+ window.course.id
});
this.model.set('id', 0);
this.view = new CertificatesListView({
collection: this.collection
});
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 () {
......
......@@ -9,9 +9,11 @@ define([ // jshint ignore:line
'js/certificates/models/signatory',
'js/certificates/views/signatory_details',
'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';
var CertificateDetailsView = BaseView.extend({
tagName: 'div',
......@@ -31,7 +33,6 @@ function($, _, str, gettext, BaseView, SignatoryModel, SignatoryDetailsView, Vie
initialize: function() {
// Set up the initial state of the attributes set for this model instance
this.showDetails = true;
this.template = this.loadTemplate('certificate-details');
this.listenTo(this.model, 'change', this.render);
},
......@@ -61,7 +62,7 @@ function($, _, str, gettext, BaseView, SignatoryModel, SignatoryDetailsView, Vie
index: this.model.collection.indexOf(this.model),
showDetails: this.showDetails || showDetails || false
});
this.$el.html(this.template(attrs));
this.$el.html(_.template(certificateDetailsTemplate)(attrs));
if(this.showDetails || showDetails) {
var self = this;
this.model.get("signatories").each(function (modelSignatory) {
......
......@@ -7,10 +7,11 @@ define([ // jshint ignore:line
'gettext',
'js/views/list_item_editor',
'js/certificates/models/signatory',
'js/certificates/views/signatory_editor'
'js/certificates/views/signatory_editor',
'text!templates/certificate-editor.underscore'
],
function($, _, Backbone, gettext,
ListItemEditorView, SignatoryModel, SignatoryEditorView) {
ListItemEditorView, SignatoryModel, SignatoryEditorView, certificateEditorTemplate) {
'use strict';
// If signatories limit is required to specific value then we can change it.
......@@ -41,14 +42,15 @@ function($, _, Backbone, gettext,
].join(' ');
},
initialize: function() {
initialize: function(options) {
// Set up the initial state of the attributes set for this model instance
_.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.bind("onSignatoryRemoved", this.onSignatoryRemoved);
this.eventAgg.bind("onSignatoryUpdated", this.clearErrorMessage);
ListItemEditorView.prototype.initialize.call(this);
this.template = this.loadTemplate('certificate-editor');
},
onSignatoryRemoved: function() {
......@@ -87,7 +89,7 @@ function($, _, Backbone, gettext,
disableAddSignatoryButton: function() {
// 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");
}
},
......
......@@ -7,9 +7,10 @@ define([ // jshint ignore:line
'gettext',
'js/views/baseview',
'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';
var CertificateWebPreview = BaseView.extend({
el: $(".preview-certificate"),
......@@ -23,11 +24,10 @@ function(_, gettext, BaseView, ViewUtils, NotificationView) {
this.certificate_web_view_url = options.certificate_web_view_url;
this.certificate_activation_handler_url = options.certificate_activation_handler_url;
this.is_active = options.is_active;
this.template = this.loadTemplate('certificate-web-preview');
},
render: function () {
this.$el.html(this.template({
this.$el.html(_.template(certificateWebPreviewTemplate)({
course_modes: this.course_modes,
certificate_web_view_url: this.certificate_web_view_url,
is_active: this.is_active
......
......@@ -9,9 +9,12 @@ define([ // jshint ignore:line
'js/utils/templates',
'common/js/components/utils/view_utils',
'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';
var SignatoryDetailsView = BaseView.extend({
tagName: 'div',
......@@ -39,8 +42,6 @@ function ($, _, str, Backbone, gettext, TemplateUtils, ViewUtils, BaseView, Sign
isEditingAllCollections: false,
eventAgg: this.eventAgg
});
this.template = this.loadTemplate('signatory-details');
this.signatory_action_template = this.loadTemplate('signatory-actions');
},
loadTemplate: function(name) {
......@@ -52,7 +53,7 @@ function ($, _, str, Backbone, gettext, TemplateUtils, ViewUtils, BaseView, Sign
// Retrieve the edit view for this model
if (event && event.preventDefault) { event.preventDefault(); }
this.$el.html(this.edit_view.render());
$(this.signatory_action_template()).appendTo(this.el);
$(_.template(signatoryActionsTemplate)()).appendTo(this.el);
this.edit_view.delegateEvents();
this.delegateEvents();
},
......@@ -93,7 +94,7 @@ function ($, _, str, Backbone, gettext, TemplateUtils, ViewUtils, BaseView, Sign
var attributes = $.extend({}, this.model.attributes, {
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;
......
......@@ -10,10 +10,12 @@ define([ // jshint ignore:line
'common/js/components/views/feedback_prompt',
'common/js/components/views/feedback_notification',
'js/models/uploads',
'js/views/uploads'
'js/views/uploads',
'text!templates/signatory-editor.underscore'
],
function ($, _, Backbone, gettext,
TemplateUtils, ViewUtils, PromptView, NotificationView, FileUploadModel, FileUploadDialog) {
TemplateUtils, ViewUtils, PromptView, NotificationView, FileUploadModel, FileUploadDialog,
signatoryEditorTemplate) {
'use strict';
var SignatoryEditorView = Backbone.View.extend({
tagName: 'div',
......@@ -41,7 +43,6 @@ function ($, _, Backbone, gettext,
this.model.bind('change', this.render);
this.eventAgg = options.eventAgg;
this.isEditingAllCollections = options.isEditingAllCollections;
this.template = this.loadTemplate('signatory-editor');
},
getModelIndex: function(givenModel) {
......@@ -77,7 +78,7 @@ function ($, _, Backbone, gettext,
is_editing_all_collections: this.isEditingAllCollections,
total_saved_signatories: this.getTotalSignatoriesOnServer()
});
return $(this.el).html(this.template(attributes));
return $(this.el).html(_.template(signatoryEditorTemplate)(attributes));
},
setSignatoryName: function(event) {
......
......@@ -40,7 +40,7 @@ define(["js/utils/drag_and_drop", "common/js/components/views/feedback_notificat
left: $ele.offset().left
});
destination = ContentDragger.findDestination($ele, 1);
expect(destination.ele).toBe($('#unit-2'));
expect(destination.ele).toEqual($('#unit-2'));
expect(destination.attachMethod).toBe('before');
});
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
left: $ele.offset().left
});
destination = ContentDragger.findDestination($ele, 1);
expect(destination.ele).toBe($unit4);
expect(destination.ele).toEqual($unit4);
expect(destination.attachMethod).toBe('after');
destination = ContentDragger.findDestination($ele, -1);
expect(destination.ele).toBe($unit4);
expect(destination.ele).toEqual($unit4);
expect(destination.attachMethod).toBe('before');
$ele.offset({
top: $unit4.offset().top + $unit4.height() + 1,
left: $ele.offset().left
});
destination = ContentDragger.findDestination($ele, 0);
expect(destination.ele).toBe($unit4);
expect(destination.ele).toEqual($unit4);
expect(destination.attachMethod).toBe('after');
$unit0 = $('#unit-0');
$ele.offset({
......@@ -70,7 +70,7 @@ define(["js/utils/drag_and_drop", "common/js/components/views/feedback_notificat
left: $ele.offset().left
});
destination = ContentDragger.findDestination($ele, 0);
expect(destination.ele).toBe($unit0);
expect(destination.ele).toEqual($unit0);
expect(destination.attachMethod).toBe('before');
});
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
left: $ele.offset().left
});
destination = ContentDragger.findDestination($ele, -1);
expect(destination.ele).toBe($('#subsection-0'));
expect(destination.ele).toEqual($('#subsection-0'));
expect(destination.attachMethod).toBe('before');
});
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
left: $ele.offset().left
});
destination = ContentDragger.findDestination($ele, -1);
expect(destination.ele).toBe($('#unit-3'));
expect(destination.ele).toEqual($('#unit-3'));
expect(destination.attachMethod).toBe('after');
$ele.offset({
top: $('#unit-3').offset().top + 4,
left: $ele.offset().left
});
destination = ContentDragger.findDestination($ele, -1);
expect(destination.ele).toBe($('#unit-3'));
expect(destination.ele).toEqual($('#unit-3'));
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 () {
......@@ -110,7 +110,7 @@ define(["js/utils/drag_and_drop", "common/js/components/views/feedback_notificat
left: $ele.offset().left
});
destination = ContentDragger.findDestination($ele, 1);
expect(destination.ele).toBe($('#subsection-4'));
expect(destination.ele).toEqual($('#subsection-4'));
expect(destination.attachMethod).toBe('after');
});
it("can drag into an empty list", function () {
......@@ -121,7 +121,7 @@ define(["js/utils/drag_and_drop", "common/js/components/views/feedback_notificat
left: $ele.offset().left
});
destination = ContentDragger.findDestination($ele, 1);
expect(destination.ele).toBe($('#subsection-list-3'));
expect(destination.ele).toEqual($('#subsection-list-3'));
expect(destination.attachMethod).toBe('prepend');
});
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
left: $ele.offset().left
});
destination = ContentDragger.findDestination($ele, 1);
expect(destination.ele).toBe($('#subsection-list-2'));
expect(destination.parentList).toBe($('#subsection-2'));
expect(destination.ele).toEqual($('#subsection-list-2'));
expect(destination.parentList).toEqual($('#subsection-2'));
expect(destination.attachMethod).toBe('prepend');
});
});
......@@ -176,7 +176,7 @@ define(["js/utils/drag_and_drop", "common/js/components/views/feedback_notificat
});
describe("onDragMove", 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 () {
var $ele, dragX, dragY;
......@@ -239,7 +239,7 @@ define(["js/utils/drag_and_drop", "common/js/components/views/feedback_notificat
this.reorderSpy = spyOn(ContentDragger, 'handleReorder');
});
afterEach(function () {
this.reorderSpy.reset();
this.reorderSpy.calls.reset();
});
it("calls handleReorder on a successful drag", function () {
ContentDragger.dragState.dropDestination = $('#unit-2');
......@@ -279,7 +279,7 @@ define(["js/utils/drag_and_drop", "common/js/components/views/feedback_notificat
expect($('#subsection-1')).not.toHaveClass('expand-on-drop');
});
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($('#subsection-2').data('ensureChildrenRendered')).not.toHaveBeenCalled();
......@@ -301,8 +301,8 @@ define(["js/utils/drag_and_drop", "common/js/components/views/feedback_notificat
});
describe("AJAX", function () {
beforeEach(function () {
this.savingSpies = spyOnConstructor(Notification, "Mini", ["show", "hide"]);
this.savingSpies.show.andReturn(this.savingSpies);
this.savingSpies = jasmine.stealth.spyOnConstructor(Notification, "Mini", ["show", "hide"]);
this.savingSpies.show.and.returnValue(this.savingSpies);
this.clock = sinon.useFakeTimers();
});
afterEach(function () {
......@@ -327,7 +327,7 @@ define(["js/utils/drag_and_drop", "common/js/components/views/feedback_notificat
expect(this.savingSpies.constructor).toHaveBeenCalled();
expect(this.savingSpies.show).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($('#unit-1')).toHaveClass('was-dropped');
expect(request.requestBody).toEqual('{"children":["fourth-unit-id","first-unit-id"]}');
......
......@@ -39,7 +39,9 @@ function ($, _, IframeBinding) {
//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
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 () {
......
......@@ -30,61 +30,104 @@ function ($, _, Squire) {
var createPromptSpy = function (name) {
var spy = jasmine.createSpyObj(name, ['constructor', 'show', 'hide']);
spy.constructor.andReturn(spy);
spy.show.andReturn(spy);
spy.extend = jasmine.createSpy().andReturn(spy.constructor);
spy.constructor.and.returnValue(spy);
spy.show.and.returnValue(spy);
spy.extend = jasmine.createSpy().and.returnValue(spy.constructor);
return spy;
};
beforeEach(function () {
beforeEach(function (done) {
self = this;
this.addMatchers({
assertValueInView: function(expected) {
var value = this.actual.getValueFromEditor();
return this.env.equals_(value, expected);
jasmine.addMatchers({
assertValueInView: function() {
return {
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) {
var view = this.actual,
value;
view.setValueInEditor(expected);
value = view.getValueFromEditor();
return this.env.equals_(value, expected);
assertCanUpdateView: function () {
return {
compare: function (actual, expected) {
var view = actual,
value,
passed;
view.setValueInEditor(expected);
value = view.getValueFromEditor();
passed = _.isEqual(value, expected);
return {
pass: passed,
message: 'Expected ' + actual + (passed ? '' : ' not') + ' to equal ' + expected
};
}
};
},
assertClear: function (modelValue) {
var env = this.env,
view = this.actual,
model = view.model;
return model.getValue() === null &&
env.equals_(model.getDisplayValue(), modelValue) &&
env.equals_(view.getValueFromEditor(), modelValue);
assertClear: function () {
return {
compare: function (actual, modelValue) {
var view = actual,
model = view.model,
passed;
passed = model.getValue() === null &&
_.isEqual(model.getDisplayValue(), modelValue) &&
_.isEqual(view.getValueFromEditor(), modelValue);
return {
pass: passed
};
}
};
},
assertUpdateModel: function (originalValue, newValue) {
var env = this.env,
view = this.actual,
model = view.model,
expectOriginal;
view.setValueInEditor(newValue);
expectOriginal = env.equals_(model.getValue(), originalValue);
view.updateModel();
return expectOriginal &&
env.equals_(model.getValue(), newValue);
assertUpdateModel: function () {
return {
compare: function (actual, originalValue, newValue) {
var view = actual,
model = view.model,
expectOriginal,
passed;
view.setValueInEditor(newValue);
expectOriginal = _.isEqual(model.getValue(), originalValue);
view.updateModel();
passed = expectOriginal &&
_.isEqual(model.getValue(), newValue);
return {
pass: passed
};
}
};
},
verifyButtons: function (upload, download, index) {
var view = this.actual,
uploadBtn = view.$('.upload-setting'),
downloadBtn = view.$('.download-setting');
upload = upload ? uploadBtn.length : !uploadBtn.length;
download = download ? downloadBtn.length : !downloadBtn.length;
return upload && download;
verifyButtons: function () {
return {
compare: function (actual, upload, download) {
var view = actual,
uploadBtn = view.$('.upload-setting'),
downloadBtn = view.$('.download-setting'),
passed;
upload = upload ? uploadBtn.length : !uploadBtn.length;
download = download ? downloadBtn.length : !downloadBtn.length;
passed = upload && download;
return {
pass: passed
};
}
};
}
});
......@@ -107,22 +150,18 @@ function ($, _, Squire) {
injector.mock('js/views/video/transcripts/metadata_videolist');
injector.mock('js/views/video/translations_editor');
runs(function() {
injector.require([
injector.require([
'js/models/metadata', 'js/views/metadata'
],
function(MetadataModel, MetadataView) {
function (MetadataModel, MetadataView) {
var model = new MetadataModel($.extend(true, {}, modelStub));
self.view = new MetadataView.FileUploader({
model: model,
locator: locator
});
});
});
waitsFor(function() {
return self.view;
}, 'FileUploader was not created', 2000);
done();
});
});
afterEach(function () {
......@@ -150,7 +189,7 @@ function ($, _, Squire) {
expect(this.uploadSpies.constructor).toHaveBeenCalled();
expect(this.uploadSpies.show).toHaveBeenCalled();
options = this.uploadSpies.constructor.mostRecentCall.args[0];
options = this.uploadSpies.constructor.calls.mostRecent().args[0];
options.onSuccess({
'asset': {
'url': 'http://example.org/test_3'
......
......@@ -3,8 +3,7 @@ define(
"jquery", "backbone", "underscore",
"js/views/video/transcripts/utils", "js/views/video/transcripts/editor",
"js/views/metadata", "js/models/metadata", "js/collections/metadata",
"underscore.string", "xmodule", "js/views/video/transcripts/metadata_videolist",
"jasmine-jquery"
"underscore.string", "xmodule", "js/views/video/transcripts/metadata_videolist"
],
function ($, Backbone, _, Utils, Editor, MetadataView, MetadataModel, MetadataCollection, _str) {
describe('Transcripts.Editor', function () {
......@@ -43,6 +42,13 @@ function ($, Backbone, _, Utils, Editor, MetadataView, MetadataModel, MetadataCo
},
transcripts, container;
var waitsForDisplayName = function (collection) {
return jasmine.waitUntil(function () {
var displayNameValue = collection[0].getValue();
return displayNameValue !== '' && displayNameValue !== 'video_id';
});
};
beforeEach(function () {
var tpl = sandbox({
'class': 'wrapper-comp-settings basic_metadata_edit',
......@@ -60,7 +66,6 @@ function ($, Backbone, _, Utils, Editor, MetadataView, MetadataModel, MetadataCo
});
describe('Test initialization', function () {
beforeEach(function () {
spyOn(MetadataView, 'Editor');
......@@ -158,27 +163,23 @@ function ($, Backbone, _, Utils, Editor, MetadataView, MetadataModel, MetadataCo
});
describe('Test Advanced to Basic synchronization', function () {
it('Correct data', function () {
it('Correct data', function (done) {
transcripts.syncBasicTab(metadataCollection, metadataView);
var collection = transcripts.collection.models;
waitsFor(function() {
var displayNameValue = collection[0].getValue();
return (displayNameValue !== "" && displayNameValue != "video_id");
}, "Defaults never loaded", 1000);
runs(function() {
var displayNameValue = collection[0].getValue(),
videoUrlValue = collection[1].getValue();
expect(displayNameValue).toEqual('default');
expect(videoUrlValue).toEqual([
'http://youtu.be/OEoXaMPEzfM',
'default.mp4',
'default.webm'
]);
});
waitsForDisplayName(collection)
.then(function () {
var displayNameValue = collection[0].getValue(),
videoUrlValue = collection[1].getValue();
expect(displayNameValue).toEqual('default');
expect(videoUrlValue).toEqual([
'http://youtu.be/OEoXaMPEzfM',
'default.mp4',
'default.webm'
]);
})
.always(done);
});
it('If metadataCollection is not defined', function () {
......@@ -219,31 +220,26 @@ function ($, Backbone, _, Utils, Editor, MetadataView, MetadataModel, MetadataCo
});
describe('Test Basic to Advanced synchronization', function () {
it('Correct data', function () {
it('Correct data', function (done) {
transcripts.syncAdvancedTab(metadataCollection);
var collection = metadataCollection.models;
waitsFor(function() {
var displayNameValue = collection[0].getValue();
return (displayNameValue !== "" && displayNameValue != "video_id");
}, "Defaults never loaded", 1000);
runs(function() {
var displayNameValue = collection[0].getValue();
var subValue = collection[1].getValue();
var html5SourcesValue = collection[2].getValue();
var youtubeValue = collection[3].getValue();
expect(displayNameValue).toEqual('display value');
expect(subValue).toEqual('default');
expect(html5SourcesValue).toEqual([
'video.mp4',
'video.webm'
]);
expect(youtubeValue).toEqual('12345678901');
});
waitsForDisplayName(collection)
.then(function () {
var displayNameValue = collection[0].getValue();
var subValue = collection[1].getValue();
var html5SourcesValue = collection[2].getValue();
var youtubeValue = collection[3].getValue();
expect(displayNameValue).toEqual('display value');
expect(subValue).toEqual('default');
expect(html5SourcesValue).toEqual([
'video.mp4',
'video.webm'
]);
expect(youtubeValue).toEqual('12345678901');
})
.always(done);
});
it('metadataCollection is not defined', function () {
......@@ -307,8 +303,7 @@ function ($, Backbone, _, Utils, Editor, MetadataView, MetadataModel, MetadataCo
transcripts.syncAdvancedTab(metadataCollection);
transcripts.syncAdvancedTab(metadataCollection);
transcripts.syncAdvancedTab(metadataCollection);
expect(subModel.setValue.calls.length).toEqual(1);
expect(subModel.setValue.calls.count()).toEqual(1);
});
});
......
......@@ -2,7 +2,7 @@ define(
[
"jquery", "underscore",
"js/views/video/transcripts/utils", "js/views/video/transcripts/file_uploader",
"xmodule", "jquery.form", "jasmine-jquery"
"xmodule", "jquery.form"
],
function ($, _, Utils, FileUploader) {
// TODO: fix TNL-559 Intermittent failures of Transcript FileUploader JS tests
......@@ -43,7 +43,7 @@ function ($, _, Utils, FileUploader) {
.append('<div class="transcripts-file-uploader" />')
.append('<a class="setting-upload" href="#">Upload</a>');
spyOn(FileUploader.prototype, 'render').andCallThrough();
spyOn(FileUploader.prototype, 'render').and.callThrough();
view = new FileUploader({
el: $container,
......@@ -61,7 +61,7 @@ function ($, _, Utils, FileUploader) {
describe('Render', function () {
beforeEach(function () {
spyOn(_, 'template').andCallThrough();
spyOn(_, 'template').and.callThrough();
});
it('Template doesn\'t exist', function () {
......@@ -138,7 +138,7 @@ function ($, _, Utils, FileUploader) {
});
it('Valid File Type - error should be hided', function () {
spyOn(view, 'checkExtValidity').andReturn(true);
spyOn(view, 'checkExtValidity').and.returnValue(true);
view.$input.change();
......@@ -148,7 +148,7 @@ function ($, _, Utils, FileUploader) {
});
it('Invalid File Type - error should be shown', function () {
spyOn(view, 'checkExtValidity').andReturn(false);
spyOn(view, 'checkExtValidity').and.returnValue(false);
view.$input.change();
......@@ -189,7 +189,7 @@ function ($, _, Utils, FileUploader) {
it('xhrProgressHandler', function () {
var percent = 26;
spyOn($.fn, 'width').andCallThrough();
spyOn($.fn, 'width').and.callThrough();
view.xhrProgressHandler(null, null, null, percent);
expect(view.$progress.width).toHaveBeenCalledWith(percent + '%');
......@@ -209,7 +209,7 @@ function ($, _, Utils, FileUploader) {
view.xhrCompleteHandler(xhr);
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');
expect(Utils.Storage.set)
.toHaveBeenCalledWith('sub', 'test');
......
......@@ -2,7 +2,7 @@ define(
[
"jquery", "underscore",
"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"
],
function ($, _, Utils, MessageManager, FileUploader, sinon) {
......@@ -67,10 +67,10 @@ function ($, _, Utils, MessageManager, FileUploader, sinon) {
});
// Disabled 2/6/14 after intermittent failure in master
xdescribe('Render', function () {
describe('Render', function () {
beforeEach(function () {
spyOn(_,'template').andCallThrough();
spyOn(_,'template').and.callThrough();
spyOn(fileUploader, 'render');
});
......@@ -101,7 +101,7 @@ function ($, _, Utils, MessageManager, FileUploader, sinon) {
beforeEach(function () {
view.render('found');
spyOn(view, 'hideError');
spyOn($.fn, 'html').andCallThrough();
spyOn($.fn, 'html').and.callThrough();
$error = view.$el.find('.transcripts-error-message');
$buttons = view.$el.find('.wrapper-transcripts-buttons');
});
......@@ -147,10 +147,10 @@ function ($, _, Utils, MessageManager, FileUploader, sinon) {
$.each(handlers, function(key, value) {
it(key, function () {
var eventObj = jasmine.createSpyObj('event', ['preventDefault']);
spyOn($.fn, 'data').andReturn('video_id');
spyOn($.fn, 'data').and.returnValue('video_id');
spyOn(view, 'processCommand');
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) {
beforeEach(function () {
view.render('found');
spyOn(Utils, 'command').andCallThrough();
spyOn(Utils, 'command').and.callThrough();
spyOn(view, 'render');
spyOn(view, 'showError');
......@@ -174,35 +174,19 @@ function ($, _, Utils, MessageManager, FileUploader, sinon) {
sinonXhr.restore();
});
var assertCommand = function (config, expectFunc) {
var flag = false,
defaults = {
var assertCommand = function (config) {
var defaults = {
action: 'replace',
errorMessage: 'errorMessage',
extraParamas: void(0)
};
args = $.extend({}, defaults, config);
var args = $.extend({}, defaults, config);
runs(function() {
view
.processCommand(
args.action,
args.errorMessage,
args.extraParamas
)
.always(function () { flag = true; });
});
waitsFor(function() {
return flag;
}, "Ajax Timeout", 750);
runs(expectFunc);
return view
.processCommand(args.action, args.errorMessage, args.extraParamas);
};
it('Invoke without extraParamas', function () {
it('Invoke without extraParamas', function (done) {
sinonXhr.respondWith([
200,
{ "Content-Type": "application/json"},
......@@ -212,9 +196,8 @@ function ($, _, Utils, MessageManager, FileUploader, sinon) {
})
]);
assertCommand(
{ },
function() {
assertCommand({})
.then(function () {
expect(Utils.command).toHaveBeenCalledWith(
action,
view.component_locator,
......@@ -222,15 +205,14 @@ function ($, _, Utils, MessageManager, FileUploader, sinon) {
void(0)
);
expect(view.showError).not.toHaveBeenCalled();
expect(view.render.mostRecentCall.args[0])
expect(view.render.calls.mostRecent().args[0])
.toEqual('found');
expect(Utils.Storage.set).toHaveBeenCalled();
}
);
})
.always(done);
});
it('Invoke with extraParamas', function () {
it('Invoke with extraParamas', function (done) {
sinonXhr.respondWith([
200,
{ "Content-Type": "application/json"},
......@@ -242,9 +224,8 @@ function ($, _, Utils, MessageManager, FileUploader, sinon) {
view.processCommand(action, errorMessage, extraParamas);
assertCommand(
{ extraParamas : extraParamas },
function () {
assertCommand({extraParamas : extraParamas})
.then(function () {
expect(Utils.command).toHaveBeenCalledWith(
action,
view.component_locator,
......@@ -254,20 +235,16 @@ function ($, _, Utils, MessageManager, FileUploader, sinon) {
}
);
expect(view.showError).not.toHaveBeenCalled();
expect(view.render.mostRecentCall.args[0])
.toEqual('found');
expect(view.render.calls.mostRecent().args[0]).toEqual('found');
expect(Utils.Storage.set).toHaveBeenCalled();
}
);
})
.always(done);
});
it('Fail', function () {
it('Fail', function (done) {
sinonXhr.respondWith([400, {}, '']);
assertCommand(
{ },
function () {
assertCommand({})
.then(function () {
expect(Utils.command).toHaveBeenCalledWith(
action,
view.component_locator,
......@@ -277,8 +254,8 @@ function ($, _, Utils, MessageManager, FileUploader, sinon) {
expect(view.showError).toHaveBeenCalled();
expect(view.render).not.toHaveBeenCalled();
expect(Utils.Storage.set).not.toHaveBeenCalled();
}
);
})
.always(done);
});
});
......
......@@ -2,7 +2,7 @@ define(
[
'jquery', 'underscore',
'js/views/video/transcripts/utils',
'underscore.string', 'xmodule', 'jasmine-jquery'
'underscore.string', 'xmodule'
],
function ($, _, Utils, _str) {
'use strict';
......
......@@ -45,82 +45,133 @@ function ($, _, Squire) {
var createPromptSpy = function (name) {
var spy = jasmine.createSpyObj(name, ['constructor', 'show', 'hide']);
spy.constructor.andReturn(spy);
spy.show.andReturn(spy);
spy.extend = jasmine.createSpy().andReturn(spy.constructor);
spy.constructor.and.returnValue(spy);
spy.show.and.returnValue(spy);
spy.extend = jasmine.createSpy().and.returnValue(spy.constructor);
return spy;
};
beforeEach(function () {
beforeEach(function (done) {
self = this;
this.addMatchers({
assertValueInView: function(expected) {
var value = this.actual.getValueFromEditor();
return this.env.equals_(value, expected);
jasmine.addMatchers({
assertValueInView: function() {
return {
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) {
var view = this.actual,
value;
view.setValueInEditor(expected);
value = view.getValueFromEditor();
return this.env.equals_(value, expected);
assertCanUpdateView: function () {
return {
compare: function (actual, expected) {
var view = actual,
value,
passed;
view.setValueInEditor(expected);
value = view.getValueFromEditor();
passed = _.isEqual(value, expected);
return {
pass: passed,
message: 'Expected ' + actual + (passed ? '' : ' not') + ' to equal ' + expected
};
}
};
},
assertClear: function (modelValue) {
var env = this.env,
view = this.actual,
model = view.model;
return model.getValue() === null &&
env.equals_(model.getDisplayValue(), modelValue) &&
env.equals_(view.getValueFromEditor(), modelValue);
assertClear: function () {
return {
compare: function (actual, modelValue) {
var view = actual,
model = view.model,
passed;
passed = model.getValue() === null &&
_.isEqual(model.getDisplayValue(), modelValue) &&
_.isEqual(view.getValueFromEditor(), modelValue);
return {
pass: passed
};
}
};
},
assertUpdateModel: function (originalValue, newValue) {
var env = this.env,
view = this.actual,
model = view.model,
expectOriginal;
view.setValueInEditor(newValue);
expectOriginal = env.equals_(model.getValue(), originalValue);
view.updateModel();
return expectOriginal &&
env.equals_(model.getValue(), newValue);
assertUpdateModel: function () {
return {
compare: function (actual, originalValue, newValue) {
var view = actual,
model = view.model,
expectOriginal,
passed;
view.setValueInEditor(newValue);
expectOriginal = _.isEqual(model.getValue(), originalValue);
view.updateModel();
passed = expectOriginal &&
_.isEqual(model.getValue(), newValue);
return {
pass: passed
};
}
};
},
verifyKeysUnique: function (initial, expected, testData) {
var env = this.env,
view = this.actual,
item, value;
view.setValueInEditor(initial);
view.updateModel();
view.$el.find('.create-setting').click();
item = view.$el.find('.list-settings-item').last();
item.find('select').val(testData.key);
item.find('input:hidden').val(testData.value);
value = view.getValueFromEditor();
return env.equals_(value, expected);
verifyKeysUnique: function () {
return {
compare: function (actual, initial, expected, testData) {
var view = this.actual,
item,
value,
passed;
view.setValueInEditor(initial);
view.updateModel();
view.$el.find('.create-setting').click();
item = view.$el.find('.list-settings-item').last();
item.find('select').val(testData.key);
item.find('input:hidden').val(testData.value);
value = view.getValueFromEditor();
passed = _.isEqual(value, expected);
return {
pass: passed
};
}
};
},
verifyButtons: function (upload, download, remove, index) {
var view = this.actual,
items = view.$el.find('.list-settings-item'),
item = index ? items.eq(index) : items.last(),
uploadBtn = item.find('.upload-setting'),
downloadBtn = item.find('.download-setting'),
removeBtn = item.find('.remove-setting');
upload = upload ? uploadBtn.length : !uploadBtn.length;
download = download ? downloadBtn.length : !downloadBtn.length;
remove = remove ? removeBtn.length : !removeBtn.length;
return upload && download && remove;
verifyButtons: function () {
return {
compare: function (actual, upload, download, remove, index) {
var view = this.actual,
items = view.$el.find('.list-settings-item'),
item = index ? items.eq(index) : items.last(),
uploadBtn = item.find('.upload-setting'),
downloadBtn = item.find('.download-setting'),
removeBtn = item.find('.remove-setting'),
passed;
upload = upload ? uploadBtn.length : !uploadBtn.length;
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) {
return self.uploadSpies;
});
runs(function() {
injector.require([
injector.require([
'js/models/metadata', 'js/views/video/translations_editor'
],
function(MetadataModel, Translations) {
function (MetadataModel, Translations) {
var model = new MetadataModel($.extend(true, {}, modelStub));
self.view = new Translations({model: model});
});
});
waitsFor(function() {
return self.view;
}, 'VideoTranslations was not created', 1000);
done();
});
});
afterEach(function () {
......@@ -198,7 +245,7 @@ function ($, _, Squire) {
expect(this.uploadSpies.constructor).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'});
expect(this.view).verifyButtons(true, true, true);
......
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) {
"use strict";
var concurrentUploadLimit = 2;
......@@ -16,8 +22,7 @@ define(
uploadButton: this.uploadButton
});
this.view.render();
jasmine.Ajax.useMock();
clearAjaxRequests();
jasmine.Ajax.install();
this.globalAjaxError = jasmine.createSpy();
$(document).ajaxError(this.globalAjaxError);
});
......@@ -25,15 +30,16 @@ define(
// Remove window unload handler triggered by the upload requests
afterEach(function() {
$(window).off("beforeunload");
jasmine.Ajax.uninstall();
});
it("should trigger file selection when either the upload button or the drop zone is clicked", function() {
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.$(".file-drop-area").click();
expect(clickSpy).toHaveBeenCalled();
clickSpy.reset();
clickSpy.calls.reset();
this.uploadButton.click();
expect(clickSpy).toHaveBeenCalled();
});
......@@ -47,17 +53,16 @@ define(
};
var getSentRequests = function() {
return _.filter(
ajaxRequests,
function(request) { return request.readyState > 0; }
);
return jasmine.Ajax.requests.filter(function (request) {
return request.readyState > 0;
});
};
_.each(
[
{desc: "a single file", numFiles: 1},
{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) {
var fileNames = _.map(
......@@ -71,7 +76,7 @@ define(
// security reasons, so we must mock the access mechanism
// that jQuery-File-Upload uses to retrieve it.
var realProp = $.prop;
spyOn($, "prop").andCallFake(function(el, propName) {
spyOn($, "prop").and.callFake(function(el, propName) {
if (arguments.length == 2 && propName == "files") {
return _.map(
fileNames,
......@@ -82,7 +87,7 @@ define(
}
});
this.view.$(".js-file-input").change();
this.request = mostRecentAjaxRequest();
this.request = jasmine.Ajax.requests.mostRecent();
});
it("should trigger the correct request", function() {
......@@ -99,14 +104,14 @@ define(
});
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();
});
describe("and successful server response", function() {
beforeEach(function() {
clearAjaxRequests();
this.request.response({
jasmine.Ajax.requests.reset();
this.request.respondWith({
status: 200,
responseText: JSON.stringify({
files: _.map(
......@@ -141,7 +146,6 @@ define(
});
it("should display upload status and progress", function() {
var spec = this;
expect(this.$uploadElems.length).toEqual(caseInfo.numFiles);
this.$uploadElems.each(function(i, uploadElem) {
var $uploadElem = $(uploadElem);
......@@ -154,7 +158,7 @@ define(
ActiveVideoUpload.STATUS_QUEUED :
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("error");
expect($uploadElem.hasClass("queued")).toEqual(queued);
......@@ -187,12 +191,12 @@ define(
progressValue: 0,
presentClass: "error",
absentClass: "success"
},
}
],
function(subCaseInfo) {
describe("and upload " + subCaseInfo.desc, function() {
beforeEach(function() {
getSentRequests()[0].response({status: subCaseInfo.responseStatus});
getSentRequests()[0].respondWith({status: subCaseInfo.responseStatus});
});
it("should update status and progress", function() {
......@@ -202,7 +206,7 @@ define(
subCaseInfo.statusText
);
expect(
$uploadElem.find(".video-detail-progress").attr("value")
$uploadElem.find(".video-detail-progress").val()
).toEqual(subCaseInfo.progressValue);
expect($uploadElem).toHaveClass(subCaseInfo.presentClass);
expect($uploadElem).not.toHaveClass(subCaseInfo.absentClass);
......
......@@ -16,7 +16,7 @@ define([ "jquery", "common/js/spec_helpers/ajax_helpers", "URI", "js/views/asset
appendSetFixtures(uploadModalTpl);
appendSetFixtures(sandbox({ id: "asset_table_body" }));
spyOn($.fn, "fileupload").andReturn("");
spyOn($.fn, "fileupload").and.returnValue("");
var collection = new AssetCollection();
collection.url = "assets-url";
......@@ -181,7 +181,7 @@ define([ "jquery", "common/js/spec_helpers/ajax_helpers", "URI", "js/views/asset
it('uploads file properly', function () {
var requests = setup.call(this);
expect(assetsView).toBeDefined();
spyOn(assetsView, "addAsset").andCallFake(function () {
spyOn(assetsView, "addAsset").and.callFake(function () {
assetsView.collection.add(mockAssetUploadResponse.asset);
assetsView.pagingView.renderPageItems();
assetsView.pagingView.setPage(0);
......
......@@ -13,8 +13,8 @@ define(["jquery", "underscore", "js/views/baseview", "js/utils/handle_iframe_bin
spyOn(baseViewPrototype, 'initialize');
spyOn(baseViewPrototype, 'beforeRender');
spyOn(baseViewPrototype, 'render').andCallThrough();
spyOn(baseViewPrototype, 'afterRender').andCallThrough();
spyOn(baseViewPrototype, 'render').and.callThrough();
spyOn(baseViewPrototype, 'afterRender').and.callThrough();
});
afterEach(function () {
......
......@@ -125,7 +125,7 @@ define([
ViewHelpers.verifyNotificationShowing(notificationSpy, /Deleting/);
expect($(listItemView)).toExist();
};
var assertCannotDeleteUsed = function (that, toolTipText, warningText){
var assertCannotDeleteUsed = function (that, toolTipText, warningText) {
setUsageInfo(that.model);
that.view.render();
expect(that.view.$(SELECTORS.note)).toHaveAttr(
......@@ -153,36 +153,69 @@ define([
revision: 'course_rev'
});
this.addMatchers({
toContainText: function(text) {
var trimmedText = $.trim(this.actual.text());
if (text && $.isFunction(text.test)) {
return text.test(trimmedText);
} else {
return trimmedText.indexOf(text) !== -1;
}
jasmine.addMatchers({
toContainText: function() {
return {
compare: function (actual, text) {
var trimmedText = $.trim(actual.text()),
passed;
if (text && $.isFunction(text.test)) {
passed = text.test(trimmedText);
} else {
passed = trimmedText.indexOf(text) !== -1;
}
return {
pass: passed
};
}
};
},
toBeCorrectValuesInInputs: function (values) {
var expected = {
name: this.actual.$(SELECTORS.inputName).val(),
description: this.actual
.$(SELECTORS.inputDescription).val()
toBeCorrectValuesInInputs: function () {
return {
compare: function (actual, values) {
var expected = {
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) {
return _.every(values, function (value, key) {
return this.actual.get(key) === value;
}.bind(this));
toBeCorrectValuesInModel: function () {
return {
compare: function (actual, values) {
var passed = _.every(values, function (value, key) {
return actual.get(key) === value;
}.bind(this));
return {
pass: passed
};
}
};
},
toHaveDefaultNames: function (values) {
var actualValues = $.map(this.actual, function (item) {
return $(item).val();
});
return _.isEqual(actualValues, values);
toHaveDefaultNames: function () {
return {
compare: function (actual, values) {
var actualValues = $.map(actual, function (item) {
return $(item).val();
});
var passed = _.isEqual(actualValues, values);
return {
pass: passed
};
}
};
}
});
});
......@@ -389,7 +422,7 @@ define([
groups = this.model.get('groups');
expect(groups.length).toBe(3);
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() {
......@@ -421,7 +454,7 @@ define([
});
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, {
inputName: 'New Configuration',
inputDescription: 'New Description'
......@@ -454,18 +487,23 @@ define([
name: 'New Configuration'
});
// Error message disappear
expect(this.view.$(SELECTORS.errorMessage)).not.toExist();
expect(this.view.$(SELECTORS.errorMessage)).not.toBeInDOM();
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(),
groupFields = this.view.$(SELECTORS.groupFields);
groupInput.focus();
expect(groupFields).toHaveClass('is-focused');
groupInput.blur();
expect(groupFields).not.toHaveClass('is-focused');
jasmine.waitUntil(function() {
return groupFields.hasClass('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 () {
......@@ -957,13 +995,13 @@ define([
expect(this.model).toBeCorrectValuesInModel({
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() {
var requests = AjaxHelpers.requests(this),
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)
});
......
......@@ -12,7 +12,7 @@ function($, LoginFactory, AjaxHelpers, ViewUtils) {
});
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);
expect(submitButton).not.toHaveClass('is-disabled');
submitButton.click();
......
......@@ -31,14 +31,13 @@ define(["jquery", "underscore", "js/views/modals/base_modal", "js/spec_helpers/m
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();
waitsFor(function () {
// This is the implementation of "toBeFocused". However, simply calling that method
// with no wait seems to be flaky.
jasmine.waitUntil(function() {
var modalWindow = ModelHelpers.getModalWindow(modal);
return $(modalWindow)[0] === $(modalWindow)[0].ownerDocument.activeElement;
}, 'Modal Window did not get focus', 5000);
return ($(modalWindow)[0] === $(modalWindow)[0].ownerDocument.activeElement);
}).then(done);
});
it('is removed after hide is called', function () {
......
......@@ -51,7 +51,7 @@ define(['jquery', 'underscore', 'js/spec_helpers/validation_helpers', 'js/views/
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 = [
{
model: {display_name: 'test_attribute1'},
......@@ -64,7 +64,7 @@ define(['jquery', 'underscore', 'js/spec_helpers/validation_helpers', 'js/views/
];
var callback = function() {
return true;
done();
};
// Show Modal and click undo changes
......@@ -72,15 +72,8 @@ define(['jquery', 'underscore', 'js/spec_helpers/validation_helpers', 'js/views/
expect(ValidationHelpers.isShowingModal(modal)).toBeTruthy();
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
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
var pagingContainer;
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 () {
......@@ -546,7 +549,7 @@ define(["jquery", "underscore", "common/js/spec_helpers/ajax_helpers", "URI", "j
mockXBlockView.model.id = 'mock-location';
pagingContainer.refresh(mockXBlockView, true);
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
containerPage.render();
respondWithHtml(html);
AjaxHelpers.expectJsonRequest(requests, 'GET', '/xblock/locator-container');
AjaxHelpers.respondWithJson(requests, options);
AjaxHelpers.respondWithJson(requests, options || {});
};
handleContainerPageRefresh = function(requests) {
......
define(["jquery", "underscore", "underscore.string", "common/js/spec_helpers/ajax_helpers",
"common/js/spec_helpers/template_helpers", "js/spec_helpers/edit_helpers",
"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,
XBlockInfo, XBlockUtils) {
XBlockInfo, XBlockUtils, Course) {
var VisibilityState = XBlockUtils.VisibilityState;
describe("Container Subviews", function() {
......@@ -14,12 +15,26 @@ define(["jquery", "underscore", "underscore.string", "common/js/spec_helpers/aja
mockContainerXBlockHtml = readFixtures('mock/mock-empty-container-xblock.underscore');
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('publish-xblock');
TemplateHelpers.installTemplate('publish-history');
TemplateHelpers.installTemplate('unit-outline');
TemplateHelpers.installTemplate('container-message');
appendSetFixtures(mockContainerPage);
requests = AjaxHelpers.requests(this);
});
afterEach(function() {
delete window.course;
});
defaultXBlockInfo = {
......@@ -39,7 +54,6 @@ define(["jquery", "underscore", "underscore.string", "common/js/spec_helpers/aja
};
createContainerPage = function (test, options) {
requests = AjaxHelpers.requests(test);
model = new XBlockInfo(createXBlockInfo(options), { parse: true });
containerPage = new ContainerPage({
model: model,
......@@ -135,7 +149,7 @@ define(["jquery", "underscore", "underscore.string", "common/js/spec_helpers/aja
// Confirm the discard.
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",
{"publish": "discard_changes"}
......@@ -152,8 +166,8 @@ define(["jquery", "underscore", "underscore.string", "common/js/spec_helpers/aja
};
beforeEach(function() {
promptSpies = spyOnConstructor(Prompt, "Warning", ["show", "hide"]);
promptSpies.show.andReturn(this.promptSpies);
promptSpies = jasmine.stealth.spyOnConstructor(Prompt, "Warning", ["show", "hide"]);
promptSpies.show.and.returnValue(this.promptSpies);
});
it('renders correctly with private content', function () {
......@@ -268,7 +282,7 @@ define(["jquery", "underscore", "underscore.string", "common/js/spec_helpers/aja
var notificationSpy, renderPageSpy, numRequests;
createContainerPage(this);
notificationSpy = EditHelpers.createNotificationSpy();
renderPageSpy = spyOn(containerPage.xblockPublisher, 'renderPage').andCallThrough();
renderPageSpy = spyOn(containerPage.xblockPublisher, 'renderPage').and.callThrough();
sendDiscardChangesToServer();
numRequests = requests.length;
......@@ -287,7 +301,7 @@ define(["jquery", "underscore", "underscore.string", "common/js/spec_helpers/aja
it('does not fetch if discard changes fails', function () {
var renderPageSpy, numRequests;
createContainerPage(this);
renderPageSpy = spyOn(containerPage.xblockPublisher, 'renderPage').andCallThrough();
renderPageSpy = spyOn(containerPage.xblockPublisher, 'renderPage').and.callThrough();
sendDiscardChangesToServer();
......@@ -309,7 +323,7 @@ define(["jquery", "underscore", "underscore.string", "common/js/spec_helpers/aja
// Click cancel to confirmation.
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);
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",
"js/models/xblock_outline_info", "js/utils/date_utils", "js/spec_helpers/edit_helpers",
"common/js/spec_helpers/template_helpers"],
function($, AjaxHelpers, ViewUtils, CourseOutlinePage, XBlockOutlineInfo, DateUtils, EditHelpers, TemplateHelpers) {
"common/js/spec_helpers/template_helpers", 'js/models/course',],
function($, AjaxHelpers, ViewUtils, CourseOutlinePage, XBlockOutlineInfo, DateUtils,
EditHelpers, TemplateHelpers, Course) {
describe("CourseOutlinePage", function() {
var createCourseOutlinePage, displayNameInput, model, outlinePage, requests,
getItemsOfType, getItemHeaders, verifyItemsExpanded, expandItemsAndVerifyState,
collapseItemsAndVerifyState, createMockCourseJSON, createMockSectionJSON, createMockSubsectionJSON,
verifyTypePublishable, mockCourseJSON, mockEmptyCourseJSON, mockSingleSectionCourseJSON,
createMockVerticalJSON, createMockIndexJSON, mockCourseEntranceExamJSON
createMockVerticalJSON, createMockIndexJSON, mockCourseEntranceExamJSON,
mockOutlinePage = readFixtures('mock/mock-course-outline-page.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
};
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.installViewTemplates();
TemplateHelpers.installTemplates([
......@@ -252,6 +262,7 @@ define(["jquery", "common/js/spec_helpers/ajax_helpers", "common/js/components/u
$("#start_date").datepicker( "destroy" );
$("#due_date").datepicker( "destroy" );
$('.ui-datepicker').remove();
delete window.course;
});
describe('Initial display', function() {
......@@ -346,8 +357,8 @@ define(["jquery", "common/js/spec_helpers/ajax_helpers", "common/js/components/u
it('can start reindex of a course', function() {
createCourseOutlinePage(this, mockSingleSectionCourseJSON);
var reindexSpy = spyOn(outlinePage, 'startReIndex').andCallThrough();
var successSpy = spyOn(outlinePage, 'onIndexSuccess').andCallThrough();
var reindexSpy = spyOn(outlinePage, 'startReIndex').and.callThrough();
var successSpy = spyOn(outlinePage, 'onIndexSuccess').and.callThrough();
var reindexButton = outlinePage.$('.button.button-reindex');
var test_url = '/course/5/search_reindex';
reindexButton.attr('href', test_url)
......@@ -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() {
createCourseOutlinePage(this, mockSingleSectionCourseJSON);
var reindexSpy = spyOn(outlinePage, 'startReIndex').andCallThrough();
var errorSpy = spyOn(outlinePage, 'onIndexError').andCallThrough();
var reindexSpy = spyOn(outlinePage, 'startReIndex').and.callThrough();
var errorSpy = spyOn(outlinePage, 'onIndexError').and.callThrough();
var reindexButton = outlinePage.$('.button.button-reindex');
var test_url = '/course/5/search_reindex';
reindexButton.attr('href', test_url)
reindexButton.attr('href', test_url);
reindexButton.trigger('click');
AjaxHelpers.expectJsonRequest(requests, 'GET', test_url);
AjaxHelpers.respondWithError(requests, 500, createMockIndexJSON(false));
......
......@@ -40,9 +40,15 @@ define([
'content-group-editor', 'group-edit', 'list'
]);
this.addMatchers({
jasmine.addMatchers({
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([
});
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();
// We cannot use .toBeFocused due to flakiness.
expect($.fn.focus).toHaveBeenCalled();
......@@ -75,14 +81,14 @@ define([
});
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();
expect($.fn.focus).not.toHaveBeenCalled();
expect(this.view.$(groupConfigItemClassName)).not.toBeExpanded();
});
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();
expect($.fn.focus).not.toHaveBeenCalled();
expect(this.view.$(groupConfigItemClassName)).not.toBeExpanded();
......
......@@ -22,7 +22,7 @@ function ($, AjaxHelpers, ViewHelpers, ManageUsersFactory, ViewUtils) {
describe("read-write access", function() {
var mockHTML = readFixtures('mock/mock-manage-users-lib.underscore');
beforeEach(function () {
beforeEach(function (done) {
ViewHelpers.installMockAnalytics();
setFixtures(mockHTML);
appendSetFixtures($("<script>", { id: "team-member-tpl", type: "text/template"}).text(team_member_fixture));
......@@ -37,9 +37,10 @@ function ($, AjaxHelpers, ViewHelpers, ManageUsersFactory, ViewUtils) {
10000,
true
);
waitsFor(function(){
return $(".ui-loading").length === 0;
}, "Waiting for backbone render to happen", 1000);
jasmine.waitUntil(function() {
return ($(".ui-loading").length === 0);
}).then(done);
});
afterEach(function () {
......
......@@ -47,7 +47,7 @@ define(
it("should render created timestamp correctly", function() {
var fakeDate = "fake formatted date";
spyOn(Date.prototype, "toLocaleString").andCallFake(
spyOn(Date.prototype, "toLocaleString").and.callFake(
function(locales, options) {
expect(locales).toEqual([]);
expect(options.timeZone).toEqual("UTC");
......
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"],
function ($, AjaxHelpers, TemplateHelpers, ViewHelpers, ViewUtils, UnitOutlineView, XBlockInfo) {
"common/js/spec_helpers/view_helpers", "common/js/components/utils/view_utils", "js/models/course",
"js/views/unit_outline", "js/models/xblock_info"],
function ($, AjaxHelpers, TemplateHelpers, ViewHelpers, ViewUtils,
Course, UnitOutlineView, XBlockInfo) {
describe("UnitOutlineView", function() {
var createUnitOutlineView, createMockXBlockInfo,
......@@ -71,6 +73,14 @@ define(["jquery", "common/js/spec_helpers/ajax_helpers", "common/js/spec_helpers
};
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.installViewTemplates();
TemplateHelpers.installTemplate('unit-outline');
......@@ -78,6 +88,7 @@ define(["jquery", "common/js/spec_helpers/ajax_helpers", "common/js/spec_helpers
});
afterEach(function () {
delete window.course;
ViewHelpers.removeMockAnalytics();
});
......
......@@ -91,7 +91,7 @@ define(["jquery", "URI", "common/js/spec_helpers/ajax_helpers", "common/js/compo
var requests = AjaxHelpers.requests(this),
missingJavaScriptUrl = "no_such_file.js",
promise;
spyOn(ViewUtils, 'loadJavaScript').andReturn($.Deferred().reject().promise());
spyOn(ViewUtils, 'loadJavaScript').and.returnValue($.Deferred().reject().promise());
promise = postXBlockRequest(requests, [
["hash5", { mimetype: "application/javascript", kind: "url", data: missingJavaScriptUrl }]
]);
......@@ -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 () {
var notifySpy = spyOn(xblockView, "notifyRuntime").andCallThrough();
var notifySpy = spyOn(xblockView, "notifyRuntime").and.callThrough();
postXBlockRequest(AjaxHelpers.requests(this), []);
xblockView.$el.find(".notification-action-button").click();
......
......@@ -3,9 +3,9 @@
* It is expected to be backed by a Group model.
*/
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';
var ExperimentGroupEditView = BaseView.extend({
tagName: 'li',
......@@ -22,7 +22,6 @@ function(BaseView) {
},
initialize: function() {
this.template = this.loadTemplate('group-edit');
this.listenTo(this.model, 'change', this.render);
},
......@@ -30,7 +29,7 @@ function(BaseView) {
var collection = this.model.collection,
index = collection.indexOf(this.model);
this.$el.html(this.template({
this.$el.html(_.template(groupEditTemplate)({
name: this.model.get('name'),
allocation: this.getAllocation(),
index: index,
......
define(["js/views/baseview", "underscore"], function(BaseView, _) {
define([
"js/views/baseview",
"underscore",
"text!templates/license-selector.underscore"
], function(BaseView, _, licenseSelectorTemplate) {
var defaultLicenseInfo = {
"all-rights-reserved": {
"name": gettext("All Rights Reserved"),
......@@ -55,7 +59,6 @@ define(["js/views/baseview", "underscore"], function(BaseView, _) {
initialize: function(options) {
this.licenseInfo = options.licenseInfo || defaultLicenseInfo;
this.showPreview = !!options.showPreview; // coerce to boolean
this.template = this.loadTemplate("license-selector");
// Rerender when the model changes
this.listenTo(this.model, 'change', this.render);
......@@ -79,7 +82,7 @@ define(["js/views/baseview", "underscore"], function(BaseView, _) {
},
render: function() {
this.$el.html(this.template({
this.$el.html(_.template(licenseSelectorTemplate)({
model: this.model.attributes,
licenseString: this.model.toString() || "",
licenseInfo: this.licenseInfo,
......
......@@ -48,10 +48,9 @@ lib_paths:
- 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/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/libs/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.async.js
- xmodule_js/common_static/js/vendor/CodeMirror/codemirror.js
- xmodule_js/common_static/js/vendor/jQuery-File-Upload/js
- xmodule_js/src/xmodule.js
......
......@@ -45,10 +45,7 @@ lib_paths:
- 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/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.async.js
- xmodule_js/common_static/js/vendor/CodeMirror/codemirror.js
- xmodule_js/common_static/js/vendor/domReady.js
- xmodule_js/common_static/js/vendor/URI.min.js
......
// Common JavaScript tests, using RequireJS.
//
// To run all the tests and print results to the console:
//
// karma start cms/static/karma_cms.conf.js
//
//
// To run the tests for debugging: Debugging can be done in any browser
// but Chrome's developer console debugging experience is best.
//
// karma start cms/static/karma_cms.conf.js --browsers=BROWSER --single-run=false
//
//
// To run the tests with coverage and junit reports:
//
// karma start cms/static/karma_cms.conf.js --browsers=BROWSER --coverage
// --junitreportpath=<xunit_report_path> --coveragereportpath=<report_path>
//
// where `BROWSER` could be Chrome or Firefox.
//
/* jshint node: true */
/*jshint -W079 */
'use strict';
var path = require('path');
var _ = require('underscore');
var configModule = require(path.join(__dirname, '../../common/static/common/js/karma.common.conf.js'));
var libraryFiles = [
{pattern: 'xmodule_js/common_static/coffee/src/ajax_prefix.js', included: false},
{pattern: 'xmodule_js/common_static/js/src/utility.js', included: false},
{pattern: 'xmodule_js/common_static/js/vendor/jquery.min.js', included: false},
{pattern: 'xmodule_js/common_static/js/vendor/jquery-ui.min.js', included: false},
{pattern: 'xmodule_js/common_static/js/vendor/jquery.cookie.js', included: false},
{pattern: 'xmodule_js/common_static/js/vendor/jquery.simulate.js', included: false},
{pattern: 'xmodule_js/common_static/common/js/vendor/underscore.js', included: false},
{pattern: 'xmodule_js/common_static/common/js/vendor/underscore.string.js', included: false},
{pattern: 'xmodule_js/common_static/js/vendor/backbone-min.js', included: false},
{pattern: 'xmodule_js/common_static/js/vendor/backbone-associations-min.js', included: false},
{pattern: 'xmodule_js/common_static/js/vendor/backbone.paginator.min.js', included: false},
{pattern: 'xmodule_js/common_static/js/vendor/backbone-relational.min.js', included: false},
{pattern: 'xmodule_js/common_static/js/vendor/timepicker/jquery.timepicker.js', included: false},
{pattern: 'xmodule_js/common_static/js/vendor/jquery.leanModal.js', included: false},
{pattern: 'xmodule_js/common_static/js/vendor/jquery.ajaxQueue.js', included: false},
{pattern: 'xmodule_js/common_static/js/vendor/jquery.form.js', included: false},
{pattern: 'xmodule_js/common_static/js/vendor/html5-input-polyfills/number-polyfill.js', included: false},
{pattern: 'xmodule_js/common_static/js/vendor/sinon-1.17.0.js', included: false},
{pattern: 'xmodule_js/common_static/js/vendor/Squire.js', included: false},
{pattern: 'xmodule_js/common_static/js/libs/jasmine-stealth.js', included: false},
{pattern: 'xmodule_js/common_static/js/libs/jasmine-waituntil.js', included: false},
{pattern: 'xmodule_js/common_static/js/libs/jasmine-extensions.js', included: true},
{pattern: 'xmodule_js/common_static/js/vendor/jasmine-imagediff.js', included: false},
{pattern: 'xmodule_js/common_static/js/vendor/CodeMirror/codemirror.js', included: false},
{pattern: 'xmodule_js/common_static/js/vendor/jQuery-File-Upload/js/**/*.js', included: false},
{pattern: 'xmodule_js/src/xmodule.js', included: false},
{pattern: 'xmodule_js/common_static/js/test/i18n.js', included: false},
{pattern: 'xmodule_js/common_static/js/vendor/draggabilly.js', included: false},
{pattern: 'xmodule_js/common_static/js/vendor/date.js', included: false},
{pattern: 'xmodule_js/common_static/js/vendor/domReady.js', included: false},
{pattern: 'xmodule_js/common_static/js/vendor/URI.min.js', included: false},
{pattern: 'xmodule_js/common_static/js/vendor/jquery.smooth-scroll.min.js', included: false},
{pattern: 'xmodule_js/common_static/coffee/src/jquery.immediateDescendents.js', included: false},
{pattern: 'xmodule_js/common_static/js/xblock/**/*.js', included: false},
{pattern: 'xmodule_js/common_static/coffee/src/xblock/**/*.js', included: false},
{
pattern: 'xmodule_js/common_static/js/vendor/jQuery-File-Upload/js/jquery.iframe-transport.js',
included: false
},
{pattern: 'xmodule_js/common_static/js/vendor/jQuery-File-Upload/js/jquery.fileupload.js', included: false},
{
pattern: 'xmodule_js/common_static/js/vendor/jQuery-File-Upload/js/jquery.fileupload-process.js',
included: false
},
{
pattern: 'xmodule_js/common_static/js/vendor/jQuery-File-Upload/js/jquery.fileupload-validate.js',
included: false
},
{pattern: 'xmodule_js/common_static/js/vendor/mock-ajax.js', included: false},
{pattern: 'xmodule_js/common_static/js/vendor/requirejs/text.js', included: false},
{pattern: 'edx-ui-toolkit/js/utils/global-loader.js', included: false},
{pattern: 'edx-pattern-library/js/modernizr-custom.js', included: false},
{pattern: 'edx-pattern-library/js/afontgarde.js', included: false},
{pattern: 'edx-pattern-library/js/edx-icons.js', included: false},
{pattern: 'edx-pattern-library/js/**/*.js', included: false},
{pattern: 'edx-ui-toolkit/js/**/*.js', included: false}
];
// Paths to source JavaScript files
var sourceFiles = [
{pattern: 'coffee/src/**/!(*spec).js', included: false},
{pattern: 'js/**/!(*spec).js', included: false},
{pattern: 'common/js/**/!(*spec).js', included: false}
];
// Paths to spec (test) JavaScript files
var specFiles = [
{pattern: 'coffee/spec/**/*spec.js', included: false},
{pattern: 'js/spec/**/*spec.js', included: false},
{pattern: 'js/certificates/spec/**/*spec.js', included: false}
];
// Paths to fixture files
var fixtureFiles = [
{pattern: 'coffee/fixtures/**/*.underscore', included: false},
{pattern: 'templates/**/*.underscore', included: false},
{pattern: 'common/templates/**/*.underscore', included: false}
];
// override fixture path and other config.
var runAndConfigFiles = [
{pattern: path.join(configModule.appRoot, 'common/static/common/js/jasmine.common.conf.js'), included: true},
'coffee/spec/main.js'
];
// do not include tests or libraries
// (these files will be instrumented by Istanbul)
var preprocessors = configModule.getPreprocessorObject(_.flatten([sourceFiles, specFiles]));
module.exports = function (config) {
var commonConfig = configModule.getConfig(config),
files = _.flatten([libraryFiles, sourceFiles, specFiles, fixtureFiles, runAndConfigFiles]),
localConfig;
// add nocache in files if coverage is not set
if (!config.coverage) {
files.forEach(function (f) {
if (_.isObject(f)) {
f.nocache = true;
}
});
}
localConfig = {
files: files,
preprocessors: preprocessors
};
config.set(_.extend(commonConfig, localConfig));
};
// Common JavaScript tests, using RequireJS.
//
// To run all the tests and print results to the console:
//
// karma start cms/static/karma_cms_squire.conf.js
//
//
// To run the tests for debugging: Debugging can be done in any browser
// but Chrome's developer console debugging experience is best.
//
// karma start cms/static/karma_cms_squire.conf.js --browsers=BROWSER --single-run=false
//
//
// To run the tests with coverage and junit reports:
//
// karma start cms/static/karma_cms_squire.conf.js --browsers=BROWSER --coverage
// --junitreportpath=<xunit_report_path> --coveragereportpath=<report_path>
//
// where `BROWSER` could be Chrome or Firefox.
//
/* jshint node: true */
/*jshint -W079 */
'use strict';
var path = require('path');
var _ = require('underscore');
var configModule = require(path.join(__dirname, '../../common/static/common/js/karma.common.conf.js'));
var libraryFiles = [
{pattern: 'xmodule_js/common_static/js/vendor/requirejs/require.js', included: false},
{pattern: 'xmodule_js/common_static/coffee/src/ajax_prefix.js', included: false},
{pattern: 'xmodule_js/common_static/js/src/utility.js', included: false},
{pattern: 'xmodule_js/common_static/js/vendor/jquery.min.js', included: false},
{pattern: 'xmodule_js/common_static/js/vendor/jquery-ui.min.js', included: false},
{pattern: 'xmodule_js/common_static/js/vendor/jquery.cookie.js', included: false},
{pattern: 'xmodule_js/common_static/common/js/vendor/underscore.js', included: false},
{pattern: 'xmodule_js/common_static/common/js/vendor/underscore.string.js', included: false},
{pattern: 'xmodule_js/common_static/js/vendor/backbone-min.js', included: false},
{pattern: 'xmodule_js/common_static/js/vendor/backbone-associations-min.js', included: false},
{pattern: 'xmodule_js/common_static/js/vendor/backbone.paginator.min.js', included: false},
{pattern: 'xmodule_js/common_static/js/vendor/timepicker/jquery.timepicker.js', included: false},
{pattern: 'xmodule_js/common_static/js/vendor/jquery.leanModal.js', included: false},
{pattern: 'xmodule_js/common_static/js/vendor/jquery.form.js', included: false},
{pattern: 'xmodule_js/common_static/js/vendor/html5-input-polyfills/number-polyfill.js', included: false},
{pattern: 'xmodule_js/common_static/js/vendor/sinon-1.17.0.js', included: false},
{pattern: 'xmodule_js/common_static/js/vendor/Squire.js', included: false},
{pattern: 'xmodule_js/common_static/js/vendor/jasmine-imagediff.js', included: false},
{pattern: 'xmodule_js/common_static/js/vendor/CodeMirror/codemirror.js', included: false},
{pattern: 'xmodule_js/common_static/js/vendor/domReady.js', included: false},
{pattern: 'xmodule_js/common_static/js/vendor/URI.min.js', included: false},
{pattern: 'xmodule_js/common_static/js/libs/jasmine-extensions.js', included: true},
{pattern: 'xmodule_js/src/xmodule.js', included: false},
{pattern: 'xmodule_js/common_static/coffee/src/jquery.immediateDescendents.js', included: false},
{pattern: 'xmodule_js/common_static/js/test/i18n.js', included: false},
{pattern: 'xmodule_js/common_static/js/xblock/**/*.js', included: false},
{pattern: 'xmodule_js/common_static/coffee/src/xblock/**/*.js', included: false},
{pattern: 'xmodule_js/common_static/js/vendor/URI.min.js', included: false},
{
pattern: 'xmodule_js/common_static/js/vendor/jQuery-File-Upload/js/jquery.iframe-transport.js',
included: false
},
{pattern: 'xmodule_js/common_static/js/vendor/jQuery-File-Upload/js/jquery.fileupload.js', included: false},
{
pattern: 'xmodule_js/common_static/js/vendor/jQuery-File-Upload/js/jquery.fileupload-process.js',
included: false
},
{
pattern: 'xmodule_js/common_static/js/vendor/jQuery-File-Upload/js/jquery.fileupload-validate.js',
included: false
},
{pattern: 'xmodule_js/common_static/js/vendor/requirejs/text.js', included: false}
];
// Paths to source JavaScript files
var sourceFiles = [
{pattern: 'coffee/src/**/*.js', included: false},
{pattern: 'js/collections/**/*.js', included: false},
{pattern: 'js/models/**/*.js', included: false},
{pattern: 'js/utils/**/*.js', included: false},
{pattern: 'js/views/**/*.js', included: false},
{pattern: 'common/js/**/*.js', included: false}
];
// Paths to spec (test) JavaScript files
var specFiles = [
{pattern: 'coffee/spec/**/*.js', included: false},
{pattern: 'js/spec/**/*.js', included: false}
];
// Paths to fixture files
var fixtureFiles = [
{pattern: 'coffee/fixtures/**/*.*', included: false},
{pattern: 'templates/**/*.*', included: false},
{pattern: 'common/templates/**/*.*', included: false}
];
// override fixture path and other config.
var runAndConfigFiles = [
{pattern: path.join(configModule.appRoot, 'common/static/common/js/jasmine.common.conf.js'), included: true},
'coffee/spec/main_squire.js'
];
// do not include tests or libraries
// (these files will be instrumented by Istanbul)
var preprocessors = configModule.getPreprocessorObject(_.flatten([sourceFiles, specFiles]));
module.exports = function (config) {
var commonConfig = configModule.getConfig(config),
files = _.flatten([libraryFiles, sourceFiles, specFiles, fixtureFiles, runAndConfigFiles]),
localConfig;
// add nocache in files if coverage is not set
if (!config.coverage) {
files.forEach(function (f) {
if (_.isObject(f)) {
f.nocache = true;
}
});
}
localConfig = {
files: files,
preprocessors: preprocessors
};
config.set(_.extend(commonConfig, localConfig));
};
<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-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/">
<section class="editor-with-tabs">
<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">
<script id="metadata-editor-tpl" type="text/template">
<ul class="list-input settings-list">
......
......@@ -4,7 +4,7 @@
<div
id="video_id"
class="video closed"
data-metadata='{"autohideHtml5": "true", "autoplay": "false", "captionDataDir": "", "endTime": "", "generalSpeed": "1.0", "saveStateUrl": "/save_user_state", "savedVideoPosition": "0", "showCaptions": "true", "sources": "[]", "speed": "1.5", "startTime": "", "streams": "0.5:7tqY6eQzVhE,1.0:cogebirgzzM,1.5:abcdefghijkl", "sub": "Z5KLxerq05Y", "transcriptAvailableTranslationsUrl": "/transcript/available_translations", "transcriptLanguage": "en", "transcriptLanguages": {"en": "English", "de": "Deutsch", "zh": "普通话"}, "transcriptTranslationUrl": "/transcript/translation/__lang__", "ytApiUrl": "www.youtube.com/iframe_api", "ytImageUrl": "", "ytTestTimeout": "1500", "ytMetadataUrl": "www.googleapis.com/youtube/v3/videos/"}'
data-metadata='{"autohideHtml5": "true", "autoplay": "false", "captionDataDir": "", "endTime": "", "generalSpeed": "1.0", "saveStateUrl": "/save_user_state", "savedVideoPosition": "0", "showCaptions": "true", "sources": [], "speed": "1.5", "startTime": "", "streams": "0.5:7tqY6eQzVhE,1.0:cogebirgzzM,1.5:abcdefghijkl", "sub": "Z5KLxerq05Y", "transcriptAvailableTranslationsUrl": "/transcript/available_translations", "transcriptLanguage": "en", "transcriptLanguages": {"en": "English", "de": "Deutsch", "zh": "普通话"}, "transcriptTranslationUrl": "/transcript/translation/__lang__", "ytApiUrl": "/base/fixtures/youtube_iframe_api.js", "ytImageUrl": "", "ytTestTimeout": "1500", "ytMetadataUrl": "www.googleapis.com/youtube/v3/videos/"}'
>
<div class="focus_grabber first"></div>
......
......@@ -4,7 +4,7 @@
<div
id="video_id"
class="video closed"
data-metadata='{"autohideHtml5": "true", "autoplay": "false", "captionDataDir": "", "endTime": "", "generalSpeed": "1.0", "saveStateUrl": "/save_user_state", "savedVideoPosition": "0", "showCaptions": "true", "sources": ["xmodule/include/fixtures/test.mp4","xmodule/include/fixtures/test.webm","xmodule/include/fixtures/test.ogv"], "speed": "1.5", "startTime": "", "streams": "", "sub": "Z5KLxerq05Y", "transcriptAvailableTranslationsUrl": "/transcript/available_translations", "transcriptLanguage": "en", "transcriptLanguages": {"en": "English", "de": "Deutsch", "zh": "普通话"}, "transcriptTranslationUrl": "/transcript/translation/__lang__", "ytApiUrl": "www.youtube.com/iframe_api", "ytImageUrl": "", "ytTestTimeout": "1500", "ytMetadataUrl": "www.googleapis.com/youtube/v3/videos/"}'
data-metadata='{"autohideHtml5": "true", "autoplay": "false", "captionDataDir": "", "endTime": "", "generalSpeed": "1.0", "saveStateUrl": "/save_user_state", "savedVideoPosition": "0", "showCaptions": "true", "sources": ["/base/fixtures/test.mp4","/base/fixtures/test.webm","/base/fixtures/test.ogv"], "speed": "1.5", "startTime": "", "streams": "", "sub": "Z5KLxerq05Y", "transcriptAvailableTranslationsUrl": "/transcript/available_translations", "transcriptLanguage": "en", "transcriptLanguages": {"en": "English", "de": "Deutsch", "zh": "普通话"}, "transcriptTranslationUrl": "/transcript/translation/__lang__", "ytApiUrl": "/base/fixtures/youtube_iframe_api.js", "ytImageUrl": "", "ytTestTimeout": "1500", "ytMetadataUrl": "www.googleapis.com/youtube/v3/videos/"}'
>
<div class="focus_grabber first"></div>
......
......@@ -4,7 +4,7 @@
<div
id="video_id"
class="video closed"
data-metadata='{"autohideHtml5": "true", "autoplay": "false", "captionDataDir": "", "endTime": "", "generalSpeed": "1.0", "saveStateUrl": "/save_user_state", "savedVideoPosition": "0", "showCaptions": "true", "sources": ["xmodule/include/fixtures/test.mp4","xmodule/include/fixtures/test.webm","xmodule/include/fixtures/test.ogv"], "speed": "1.5", "startTime": "", "streams": "", "sub": "Z5KLxerq05Y", "transcriptAvailableTranslationsUrl": "/transcript/available_translations", "transcriptLanguage": "en", "transcriptLanguages": {"en": "English", "de": "Deutsch", "zh": "普通话"}, "transcriptTranslationUrl": "/transcript/translation/__lang__", "ytApiUrl": "www.youtube.com/iframe_api", "ytImageUrl": "", "ytTestTimeout": "1500", "ytMetadataUrl": "www.googleapis.com/youtube/v3/videos/", "source": "", "html5_sources": ["http://youtu.be/3_yD_cEKoCk.mp4"]}'
data-metadata='{"autohideHtml5": "true", "autoplay": "false", "captionDataDir": "", "endTime": "", "generalSpeed": "1.0", "saveStateUrl": "/save_user_state", "savedVideoPosition": "0", "showCaptions": "true", "sources": ["/base/fixtures/test.mp4","/base/fixtures/test.webm","/base/fixtures/test.ogv"], "speed": "1.5", "startTime": "", "streams": "", "sub": "Z5KLxerq05Y", "transcriptAvailableTranslationsUrl": "/transcript/available_translations", "transcriptLanguage": "en", "transcriptLanguages": {"en": "English", "de": "Deutsch", "zh": "普通话"}, "transcriptTranslationUrl": "/transcript/translation/__lang__", "ytApiUrl": "/base/fixtures/youtube_iframe_api.js", "ytImageUrl": "", "ytTestTimeout": "1500", "ytMetadataUrl": "www.googleapis.com/youtube/v3/videos/", "source": "", "html5_sources": ["http://youtu.be/3_yD_cEKoCk.mp4"]}'
>
<div class="focus_grabber first"></div>
......
......@@ -4,7 +4,7 @@
<div
id="video_id"
class="video closed"
data-metadata='{"streams":"0.5:7tqY6eQzVhE,1.0:cogebirgzzM,1.5:abcdefghijkl", "showCaptions": false, "saveStateUrl": "/save_user_state", "savedVideoPosition": "0", "speed": "1.5", "startTime": "", "end": "", "transcriptAvailableTranslationsUrl": "/transcript/available_translations", "transcriptLanguage": "en", "transcriptLanguages": {"en": "English", "de": "Deutsch", "zh": "普通话"}, "transcriptTranslationUrl": "/transcript/translation/__lang__", "ytApiUrl": "www.youtube.com/iframe_api", "ytTestTimeout": "1500", "ytMetadataUrl": "www.googleapis.com/youtube/v3/videos/"}'
data-metadata='{"streams":"0.5:7tqY6eQzVhE,1.0:cogebirgzzM,1.5:abcdefghijkl", "showCaptions": false, "saveStateUrl": "/save_user_state", "savedVideoPosition": "0", "speed": "1.5", "startTime": "", "end": "", "transcriptAvailableTranslationsUrl": "/transcript/available_translations", "transcriptLanguage": "en", "transcriptLanguages": {"en": "English", "de": "Deutsch", "zh": "普通话"}, "transcriptTranslationUrl": "/transcript/translation/__lang__", "ytApiUrl": "/base/fixtures/youtube_iframe_api.js", "ytTestTimeout": "1500", "ytMetadataUrl": "www.googleapis.com/youtube/v3/videos/"}'
>
<div class="focus_grabber first"></div>
......
......@@ -4,9 +4,9 @@
<div
id="video_id"
class="video closed"
data-metadata='{"autohideHtml5": "true", "autoplay": "false", "captionDataDir": "", "endTime": "", "generalSpeed": "1.0", "saveStateUrl": "/save_user_state", "savedVideoPosition": "0", "showCaptions": "true", "sources": ["xmodule/include/fixtures/test.mp4","xmodule/include/fixtures/test.webm","xmodule/include/fixtures/test.ogv"], "speed": "1.5", "startTime": "", "streams": "", "sub": "Z5KLxerq05Y", "transcriptAvailableTranslationsUrl": "/transcript/available_translations", "transcriptLanguage": "en", "transcriptLanguages": {"en": "English", "de": "Deutsch", "zh": "普通话"}, "transcriptTranslationUrl": "/transcript/translation/__lang__", "ytApiUrl": "www.youtube.com/iframe_api", "ytImageUrl": "", "ytTestTimeout": "1500", "ytMetadataUrl": "www.googleapis.com/youtube/v3/videos/"}'
data-bumper-metadata='{"transcriptLanguage": "en", "showCaptions": "true", "transcriptLanguages": {"en": "English", "de": "Deutsch", "zh": "普通话"}, "sources": ["xmodule/include/fixtures/test.mp4","xmodule/include/fixtures/test.webm","xmodule/include/fixtures/test.ogv"], "transcriptTranslationUrl": "/transcript/translation/__lang__/?is_bumper=1", "transcriptAvailableTranslationsUrl": "/transcript/available_translations/?is_bumper=1", "streams": "", "saveStateUrl": "/save_user_state"}'
data-poster='{"url": "xmodule/include/fixtures/poster.jpg", "type": "youtube"}'
data-metadata='{"autohideHtml5": "true", "autoplay": "false", "captionDataDir": "", "endTime": "", "generalSpeed": "1.0", "saveStateUrl": "/save_user_state", "savedVideoPosition": "0", "showCaptions": "true", "sources": ["/base/fixtures/test.mp4","/base/fixtures/test.webm","/base/fixtures/test.ogv"], "speed": "1.5", "startTime": "", "streams": "", "sub": "Z5KLxerq05Y", "transcriptAvailableTranslationsUrl": "/transcript/available_translations", "transcriptLanguage": "en", "transcriptLanguages": {"en": "English", "de": "Deutsch", "zh": "普通话"}, "transcriptTranslationUrl": "/transcript/translation/__lang__", "ytApiUrl": "/base/fixtures/youtube_iframe_api.js", "ytImageUrl": "", "ytTestTimeout": "1500", "ytMetadataUrl": "www.googleapis.com/youtube/v3/videos/"}'
data-bumper-metadata='{"transcriptLanguage": "en", "showCaptions": "true", "transcriptLanguages": {"en": "English", "de": "Deutsch", "zh": "普通话"}, "sources": ["/base/fixtures/test.mp4","/base/fixtures/test.webm","/base/fixtures/test.ogv"], "transcriptTranslationUrl": "/transcript/translation/__lang__/?is_bumper=1", "transcriptAvailableTranslationsUrl": "/transcript/available_translations/?is_bumper=1", "streams": "", "saveStateUrl": "/save_user_state"}'
data-poster='{"url": "/base/fixtures/poster.jpg", "type": "youtube"}'
>
<div class="focus_grabber first"></div>
......
......@@ -4,7 +4,7 @@
<div
id="video_id1"
class="video closed"
data-metadata='{"autohideHtml5": "true", "autoplay": "false", "captionDataDir": "", "endTime": "", "generalSpeed": "1.0", "saveStateUrl": "/save_user_state", "savedVideoPosition": "0", "showCaptions": "true", "sources": ["xmodule/include/fixtures/test.mp4","xmodule/include/fixtures/test.webm","xmodule/include/fixtures/test.ogv"], "speed": "1.5", "startTime": "", "streams": "0.5:7tqY6eQzVhE,1.0:cogebirgzzM,1.5:abcdefghijkl", "sub": "", "transcriptAvailableTranslationsUrl": "/transcript/available_translations", "transcriptLanguage": "en", "transcriptLanguages": {"en": "English", "de": "Deutsch", "zh": "普通话"}, "transcriptTranslationUrl": "/transcript/translation/__lang__", "ytApiUrl": "www.youtube.com/iframe_api", "ytImageUrl": "", "ytTestTimeout": "1500", "ytMetadataUrl": "www.googleapis.com/youtube/v3/videos/"}'
data-metadata='{"autohideHtml5": "true", "autoplay": "false", "captionDataDir": "", "endTime": "", "generalSpeed": "1.0", "saveStateUrl": "/save_user_state", "savedVideoPosition": "0", "showCaptions": "true", "sources": ["/base/fixtures/test.mp4","/base/fixtures/test.webm","/base/fixtures/test.ogv"], "speed": "1.5", "startTime": "", "streams": "0.5:7tqY6eQzVhE,1.0:cogebirgzzM,1.5:abcdefghijkl", "sub": "", "transcriptAvailableTranslationsUrl": "/transcript/available_translations", "transcriptLanguage": "en", "transcriptLanguages": {"en": "English", "de": "Deutsch", "zh": "普通话"}, "transcriptTranslationUrl": "/transcript/translation/__lang__", "ytApiUrl": "/base/fixtures/youtube_iframe_api.js", "ytImageUrl": "", "ytTestTimeout": "1500", "ytMetadataUrl": "www.googleapis.com/youtube/v3/videos/"}'
>
<div class="focus_grabber first"></div>
......@@ -38,7 +38,7 @@
<div
id="video_id2"
class="video"
data-metadata='{"autohideHtml5": "true", "autoplay": "false", "captionDataDir": "", "endTime": "", "generalSpeed": "1.0", "saveStateUrl": "/save_user_state", "savedVideoPosition": "0", "showCaptions": "true", "sources": ["xmodule/include/fixtures/test.mp4","xmodule/include/fixtures/test.webm","xmodule/include/fixtures/test.ogv"], "speed": "1.0", "startTime": "", "streams": "0.75:7tqY6eQzVhE,1.0:cogebirgzzM", "sub": "", "transcriptAvailableTranslationsUrl": "/transcript/available_translations", "transcriptLanguage": "en", "transcriptLanguages": {"en": "English", "de": "Deutsch", "zh": "普通话"}, "transcriptTranslationUrl": "/transcript/translation/__lang__", "ytApiUrl": "www.youtube.com/iframe_api", "ytImageUrl": "", "ytTestTimeout": "1500", "ytMetadataUrl": "www.googleapis.com/youtube/v3/videos/"}'
data-metadata='{"autohideHtml5": "true", "autoplay": "false", "captionDataDir": "", "endTime": "", "generalSpeed": "1.0", "saveStateUrl": "/save_user_state", "savedVideoPosition": "0", "showCaptions": "true", "sources": ["/base/fixtures/test.mp4","/base/fixtures/test.webm","/base/fixtures/test.ogv"], "speed": "1.0", "startTime": "", "streams": "0.75:7tqY6eQzVhE,1.0:cogebirgzzM", "sub": "", "transcriptAvailableTranslationsUrl": "/transcript/available_translations", "transcriptLanguage": "en", "transcriptLanguages": {"en": "English", "de": "Deutsch", "zh": "普通话"}, "transcriptTranslationUrl": "/transcript/translation/__lang__", "ytApiUrl": "/base/fixtures/youtube_iframe_api.js", "ytImageUrl": "", "ytTestTimeout": "1500", "ytMetadataUrl": "www.googleapis.com/youtube/v3/videos/"}'
>
<div class="tc-wrapper">
<article class="video-wrapper">
......@@ -68,7 +68,7 @@
<div
id="video_id3"
class="video"
data-metadata='{"autohideHtml5": "true", "autoplay": "false", "captionDataDir": "", "endTime": "", "generalSpeed": "1.0", "saveStateUrl": "/save_user_state", "savedVideoPosition": "0", "showCaptions": "true", "sources": ["xmodule/include/fixtures/test.mp4","xmodule/include/fixtures/test.webm","xmodule/include/fixtures/test.ogv"], "speed": "1.0", "startTime": "", "streams": "0.75:7tqY6eQzVhE,1.0:cogebirgzzM", "sub": "", "transcriptAvailableTranslationsUrl": "/transcript/available_translations", "transcriptLanguage": "en", "transcriptLanguages": {"en": "English", "de": "Deutsch", "zh": "普通话"}, "transcriptTranslationUrl": "/transcript/translation/__lang__", "ytApiUrl": "www.youtube.com/iframe_api", "ytImageUrl": "", "ytTestTimeout": "1500", "ytMetadataUrl": "www.googleapis.com/youtube/v3/videos/"}'
data-metadata='{"autohideHtml5": "true", "autoplay": "false", "captionDataDir": "", "endTime": "", "generalSpeed": "1.0", "saveStateUrl": "/save_user_state", "savedVideoPosition": "0", "showCaptions": "true", "sources": ["/base/fixtures/test.mp4","/base/fixtures/test.webm","/base/fixtures/test.ogv"], "speed": "1.0", "startTime": "", "streams": "0.75:7tqY6eQzVhE,1.0:cogebirgzzM", "sub": "", "transcriptAvailableTranslationsUrl": "/transcript/available_translations", "transcriptLanguage": "en", "transcriptLanguages": {"en": "English", "de": "Deutsch", "zh": "普通话"}, "transcriptTranslationUrl": "/transcript/translation/__lang__", "ytApiUrl": "/base/fixtures/youtube_iframe_api.js", "ytImageUrl": "", "ytTestTimeout": "1500", "ytMetadataUrl": "www.googleapis.com/youtube/v3/videos/"}'
>
<div class="tc-wrapper">
<article class="video-wrapper">
......
......@@ -36,8 +36,8 @@ lib_paths:
- common_static/js/test/i18n.js
- common_static/coffee/src/ajax_prefix.js
- common_static/js/src/logger.js
- common_static/js/vendor/jasmine-jquery.js
- common_static/js/vendor/jasmine-imagediff.js
- common_static/js/libs/jasmine-waituntil.js
- common_static/js/vendor/requirejs/require.js
- RequireJS-namespace-undefine.js
- common_static/js/vendor/jquery.min.js
......
// overwrite the loaded method and manually start the karma after a delay
// Somehow the code initialized in jQuery's onready doesn't get called before karma auto starts
/* jshint node: true */
'use strict';
window.__karma__.loaded = function () {
setTimeout(function () {
window.__karma__.start();
}, 1000);
};
// Xmodule Tests
//
// To run all the tests and print results to the console:
//
// karma start common/lib/xmodule/xmodule/js/karma_xmodule.conf.js
//
//
// To run the tests for debugging: Debugging can be done in any browser
// Chrome's developer console debugging experience is the best though
//
// karma start common/lib/xmodule/xmodule/js/karma-xmodule.conf.js --browsers=BROWSER --single-run=false
//
//
// To run the tests with coverage and junit reports:
//
// karma start common/lib/xmodule/xmodule/js/karma-xmodule.conf.js
// --browsers=BROWSER --coverage --junitreportpath=<xunit_report_path> --coveragereportpath=<report_path>
//
// where `BROWSER` could be Chrome or Firefox.
//
/* jshint node: true */
/*jshint -W079 */
'use strict';
var path = require('path');
var _ = require('underscore');
var configModule = require(path.join(__dirname, 'common_static/common/js/karma.common.conf.js'));
var libraryFiles = [
// override fixture path and other config.
{pattern: path.join(configModule.appRoot, 'common/static/common/js/jasmine.common.conf.js'), included: true},
{pattern: 'common_static/js/vendor/jquery.min.js', included: true},
{pattern: 'common_static/js/test/i18n.js', included: true},
{pattern: 'common_static/coffee/src/ajax_prefix.js', included: true},
{pattern: 'common_static/js/src/logger.js', included: true},
{pattern: 'common_static/js/vendor/jasmine-imagediff.js', included: true},
{pattern: 'common_static/js/libs/jasmine-waituntil.js', included: true},
{pattern: 'common_static/js/libs/jasmine-extensions.js', included: true},
{pattern: 'common_static/js/vendor/requirejs/require.js', included: true},
{pattern: 'RequireJS-namespace-undefine.js', included: true},
{pattern: 'common_static/js/vendor/jquery-ui.min.js', included: true},
{pattern: 'common_static/js/vendor/jquery.ui.draggable.js', included: true},
{pattern: 'common_static/js/vendor/jquery.cookie.js', included: true},
{pattern: 'common_static/js/vendor/json2.js', included: true},
{pattern: 'common_static/common/js/vendor/underscore.js', included: true},
{pattern: 'common_static/js/vendor/backbone-min.js', included: true},
{pattern: 'common_static/js/vendor/jquery.leanModal.js', included: true},
{pattern: 'common_static/js/vendor/CodeMirror/codemirror.js', included: true},
{pattern: 'common_static/js/vendor/tinymce/js/tinymce/jquery.tinymce.min.js', included: true},
{pattern: 'common_static/js/vendor/tinymce/js/tinymce/tinymce.full.min.js', included: true},
{pattern: 'common_static/js/vendor/jquery.timeago.js', included: true},
{pattern: 'common_static/js/vendor/sinon-1.17.0.js', included: true},
{pattern: 'common_static/js/test/add_ajax_prefix.js', included: true},
{pattern: 'common_static/js/src/utility.js', included: true},
{pattern: 'public/js/split_test_staff.js', included: true},
{pattern: 'common_static/js/src/accessibility_tools.js', included: true},
{pattern: 'common_static/js/vendor/moment.min.js', included: true},
{pattern: 'spec/main_requirejs.js', included: true},
{pattern: 'src/word_cloud/d3.min.js', included: true},
{pattern: 'common_static/js/vendor/draggabilly.js', included: false},
{pattern: 'common_static/edx-ui-toolkit/js/utils/global-loader.js', included: true},
{pattern: 'common_static/edx-pattern-library/js/modernizr-custom.js', included: false},
{pattern: 'common_static/edx-pattern-library/js/afontgarde.js', included: false},
{pattern: 'common_static/edx-pattern-library/js/edx-icons.js', included: false}
];
// Paths to source JavaScript files
var sourceFiles = [
{pattern: 'src/xmodule.js', included: true, skipInstrument: true},
{pattern: 'src/**/*.js', included: true}
];
// Paths to spec (test) JavaScript files
var specFiles = [
{pattern: 'spec/helper.js', included: true, skipInstrument: true},
{pattern: 'spec/**/*.js', included: true}
];
// Paths to fixture files
var fixtureFiles = [
{pattern: 'fixtures/*.*', included: false, served: true}
];
var runAndConfigFiles = [
{pattern: 'karma_runner.js', included: true}
];
// do not include tests or libraries
// (these files will be instrumented by Istanbul)
var preprocessors = (function () {
var preprocessFiles = {};
_.flatten([sourceFiles, specFiles]).forEach(function (file) {
var pattern = _.isObject(file) ? file.pattern : file;
if (!file.skipInstrument) {
preprocessFiles[pattern] = ['coverage'];
}
});
return preprocessFiles;
}());
module.exports = function (config) {
var commonConfig = configModule.getConfig(config, false),
files = _.flatten([libraryFiles, sourceFiles, specFiles, fixtureFiles, runAndConfigFiles]),
localConfig;
// add nocache in files if coverage is not set
if (!config.coverage) {
files.forEach(function (f) {
if (_.isObject(f)) {
f.nocache = true;
}
});
}
localConfig = {
files: files,
preprocessors: preprocessors
};
config.set(_.extend(commonConfig, localConfig));
};
......@@ -40,8 +40,8 @@
it('Default container initialized correctly', function () {
initialize(html);
expect(el.find('.shortform')).toContain('.full-top');
expect(el.find('.shortform')).toContain('.full-bottom');
expect(el.find('.shortform')).toContainElement('.full-top');
expect(el.find('.shortform')).toContainElement('.full-bottom');
expect(el.find('.longform')).toBeHidden();
expect(el.find('.full')).toHandle('click');
});
......@@ -49,7 +49,7 @@
it('Custom container initialized correctly', function () {
initialize(html_custom);
expect(el.find('.shortform-custom')).toContain('.full-custom');
expect(el.find('.shortform-custom')).toContainElement('.full-custom');
expect(el.find('.full-custom')).toHaveText('Show shortform-custom');
expect(el.find('.longform')).toBeHidden();
expect(el.find('.full-custom')).toHandle('click');
......
(function () {
'use strict';
var origAjax = $.ajax;
var stubbedYT = {
Player: function () {
......@@ -15,9 +16,9 @@
]
);
Player.getDuration.andReturn(60);
Player.getAvailablePlaybackRates.andReturn([0.50, 1.0, 1.50, 2.0]);
Player.getAvailableQualityLevels.andReturn(
Player.getDuration.and.returnValue(60);
Player.getAvailablePlaybackRates.and.returnValue([0.50, 1.0, 1.50, 2.0]);
Player.getAvailableQualityLevels.and.returnValue(
['highres', 'hd1080', 'hd720', 'large', 'medium', 'small']
);
......@@ -124,11 +125,11 @@
jasmine.stubRequests = function () {
var spy = $.ajax;
if (!($.ajax.isSpy)) {
if (!jasmine.isSpy($.ajax)) {
spy = spyOn($, 'ajax');
}
return spy.andCallFake(function (settings) {
return spy.and.callFake(function (settings) {
var match = settings.url
.match(/googleapis\.com\/.+\/videos\/\?id=(.+)&part=contentDetails/),
status, callCallback;
......@@ -176,46 +177,16 @@
return;
} else if (settings.url === '/save_user_state') {
return {success: true};
} else if(settings.url.match(new RegExp(jasmine.getFixtures().fixturesPath + ".+", 'g'))) {
return origAjax(settings);
} else {
throw 'External request attempted for ' +
settings.url +
', which is not defined.';
$.ajax.and.callThrough();
}
});
};
// Add custom Jasmine matchers.
beforeEach(function () {
this.addMatchers({
toHaveAttrs: function (attrs) {
var element;
if ($.isEmptyObject(attrs)) {
return false;
}
element = this.actual;
return _.every(attrs, function (value, name) {
return element.attr(name) === value;
});
},
toBeInRange: function (min, max) {
return min <= this.actual && this.actual <= max;
},
toBeInArray: function (array) {
return $.inArray(this.actual, array) > -1;
},
toBeFocused: function () {
return $(this.actual)[0] === $(this.actual)[0].ownerDocument.activeElement;
}
});
return this.addMatchers(window.imagediff.jasmine);
});
// Stub jQuery.cookie module.
$.cookie = jasmine.createSpy('jQuery.cookie').andReturn('1.0');
// Stub jQuery.cookie module.
$.cookie = jasmine.createSpy('jQuery.cookie').and.returnValue('1.0');
// # Stub jQuery.qtip module.
$.fn.qtip = jasmine.createSpy('jQuery.qtip');
......@@ -224,7 +195,7 @@
$.fn.scrollTo = jasmine.createSpy('jQuery.scrollTo');
// Stub window.Video.loadYouTubeIFrameAPI()
window.Video.loadYouTubeIFrameAPI = jasmine.createSpy('window.Video.loadYouTubeIFrameAPI').andReturn(
window.Video.loadYouTubeIFrameAPI = jasmine.createSpy('window.Video.loadYouTubeIFrameAPI').and.returnValue(
function (scriptTag) {
var event = document.createEvent('Event');
if (fixture === "video.html") {
......@@ -275,13 +246,13 @@
],
obj = {},
delta = {
add: jasmine.createSpy().andReturn(obj),
substract: jasmine.createSpy().andReturn(obj),
reset: jasmine.createSpy().andReturn(obj)
add: jasmine.createSpy().and.returnValue(obj),
substract: jasmine.createSpy().and.returnValue(obj),
reset: jasmine.createSpy().and.returnValue(obj)
};
$.each(methods, function (index, method) {
obj[method] = jasmine.createSpy(method).andReturn(obj);
obj[method] = jasmine.createSpy(method).and.returnValue(obj);
});
obj.delta = delta;
......
......@@ -10,21 +10,21 @@ describe 'HTMLEditingDescriptor', ->
it 'Returns data from Visual Editor if text has changed', ->
visualEditorStub =
getContent: () -> 'from visual editor'
spyOn(@descriptor, 'getVisualEditor').andCallFake () ->
spyOn(@descriptor, 'getVisualEditor').and.callFake () ->
visualEditorStub
data = @descriptor.save().data
expect(data).toEqual('from visual editor')
it 'Returns data from Raw Editor if text has not changed', ->
visualEditorStub =
getContent: () -> '<p>original visual text</p>'
spyOn(@descriptor, 'getVisualEditor').andCallFake () ->
spyOn(@descriptor, 'getVisualEditor').and.callFake () ->
visualEditorStub
data = @descriptor.save().data
expect(data).toEqual('raw text')
it 'Performs link rewriting for static assets when saving', ->
visualEditorStub =
getContent: () -> 'from visual editor with /c4x/foo/bar/asset/image.jpg'
spyOn(@descriptor, 'getVisualEditor').andCallFake () ->
spyOn(@descriptor, 'getVisualEditor').and.callFake () ->
visualEditorStub
data = @descriptor.save().data
expect(data).toEqual('from visual editor with /static/image.jpg')
......
(function(requirejs) {
requirejs.config({
baseUrl: '/base/',
paths: {
"moment": "xmodule/include/common_static/js/vendor/moment.min",
"modernizr": "xmodule/include/common_static/edx-pattern-library/js/modernizr-custom",
"afontgarde": "xmodule/include/common_static/edx-pattern-library/js/afontgarde",
"edxicons": "xmodule/include/common_static/edx-pattern-library/js/edx-icons",
"draggabilly": "xmodule/include/common_static/js/vendor/draggabilly"
"moment": "common_static/js/vendor/moment.min",
"modernizr": "common_static/edx-pattern-library/js/modernizr-custom",
"afontgarde": "common_static/edx-pattern-library/js/afontgarde",
"edxicons": "common_static/edx-pattern-library/js/edx-icons",
"draggabilly": "common_static/js/vendor/draggabilly"
},
"moment": {
exports: "moment"
......
......@@ -24,7 +24,7 @@ describe 'MarkdownEditingDescriptor', ->
it 'click on advanced editor should work', ->
loadFixtures 'problem-with-markdown.html'
@descriptor = new MarkdownEditingDescriptor($('.problem-editor'))
spyOn(@descriptor, 'confirmConversionToXml').andReturn(true)
spyOn(@descriptor, 'confirmConversionToXml').and.returnValue(true)
expect(@descriptor.confirmConversionToXml).not.toHaveBeenCalled()
e = jasmine.createSpyObj('e', [ 'preventDefault' ])
@descriptor.onShowXMLButton(e)
......
......@@ -14,8 +14,8 @@ describe "TabsEditingDescriptor", ->
TabsEditingDescriptor.Model.addModelUpdate(@html_id, 'Tab 1 Transcripts', @tab_1_modelUpdate)
TabsEditingDescriptor.Model.addOnSwitch(@html_id, 'Tab 1 Transcripts', @tab_1_switch)
spyOn($.fn, 'hide').andCallThrough()
spyOn($.fn, 'show').andCallThrough()
spyOn($.fn, 'hide').and.callThrough()
spyOn($.fn, 'show').and.callThrough()
spyOn(TabsEditingDescriptor.Model, 'initialize')
spyOn(TabsEditingDescriptor.Model, 'updateValue')
......@@ -37,11 +37,11 @@ describe "TabsEditingDescriptor", ->
expect(@tab_1_switch).toHaveBeenCalled()
it "if click on current tab, nothing should happen", ->
spyOn($.fn, 'trigger').andCallThrough()
spyOn($.fn, 'trigger').and.callThrough()
currentTab = @descriptor.$tabs.filter('.' + @isCurrent)
@descriptor.$tabs.eq(0).trigger("click")
expect(@descriptor.$tabs.filter('.' + @isCurrent)).toEqual(currentTab)
expect($.fn.trigger.calls.length).toEqual(1)
expect($.fn.trigger.calls.count()).toEqual(1)
it "onSwitch function call", ->
@descriptor.$tabs.eq(1).trigger("click")
......@@ -82,7 +82,7 @@ describe "TabsEditingDescriptor special save cases", ->
expect(data).toEqual(null)
it "case: no function in model update, but value presented", ->
@tab_0_modelUpdate = jasmine.createSpy('tab_0_modelUpdate').andReturn(1)
@tab_0_modelUpdate = jasmine.createSpy('tab_0_modelUpdate').and.returnValue(1)
TabsEditingDescriptor.Model.addModelUpdate(@html_id, 'Tab 0 Editor', @tab_0_modelUpdate)
@descriptor.$tabs.eq(1).trigger("click")
expect(@tab_0_modelUpdate).toHaveBeenCalled()
......
......@@ -15,82 +15,66 @@ function (AsyncProcess) {
items = getArrayNthLength(1000);
describe('AsyncProcess', function () {
it ('Array is processed successfully', function () {
it ('Array is processed successfully', function (done) {
var processedArray,
expectedArray = getArrayNthLength(1000, 2),
process = function (item) {
return 2 * item;
};
runs(function () {
AsyncProcess.array(items, process).done(function (result) {
processedArray = result;
});
AsyncProcess.array(items, process).done(function (result) {
processedArray = result;
});
waitsFor(function () {
jasmine.waitUntil(function () {
return processedArray;
}, 'Array processing takes too much time', WAIT_TIMEOUT);
runs(function () {
}).then(function () {
expect(processedArray).toEqual(expectedArray);
});
}).always(done);
});
it ('If non-array is passed, error callback is called', function () {
it ('If non-array is passed, error callback is called', function (done) {
var isError,
process = function () {};
runs(function () {
AsyncProcess.array('string', process).fail(function () {
isError = true;
});
AsyncProcess.array('string', process).fail(function () {
isError = true;
});
waitsFor(function () {
jasmine.waitUntil(function () {
return isError;
}, 'Error callback wasn\'t called', WAIT_TIMEOUT);
runs(function () {
}).then(function () {
expect(isError).toBeTruthy();
});
}).always(done);
});
it ('If an empty array is passed, returns initial array', function () {
it ('If an empty array is passed, returns initial array', function (done) {
var processedArray,
process = function () {};
runs(function () {
AsyncProcess.array([], process).done(function (result) {
processedArray = result;
});
AsyncProcess.array([], process).done(function (result) {
processedArray = result;
});
waitsFor(function () {
jasmine.waitUntil(function () {
return processedArray;
}, 'Array processing takes too much time', WAIT_TIMEOUT);
runs(function () {
}).then(function () {
expect(processedArray).toEqual([]);
});
}).always(done);
});
it ('If no process function passed, returns initial array', function () {
it ('If no process function passed, returns initial array', function (done) {
var processedArray;
runs(function () {
AsyncProcess.array(items).done(function (result) {
processedArray = result;
});
AsyncProcess.array(items).done(function (result) {
processedArray = result;
});
waitsFor(function () {
jasmine.waitUntil(function () {
return processedArray;
}, 'Array processing takes too much time', WAIT_TIMEOUT);
runs(function () {
}).then(function () {
expect(processedArray).toEqual(items);
});
}).always(done);
});
});
});
......
......@@ -7,9 +7,7 @@
oldOTBD = window.onTouchBasedDevice;
window.onTouchBasedDevice = jasmine
.createSpy('onTouchBasedDevice')
.andReturn(null);
jasmine.stubRequests();
.and.returnValue(null);
state = jasmine.initializePlayer();
......@@ -20,26 +18,23 @@
$('source').remove();
window.onTouchBasedDevice = oldOTBD;
state.storage.clear();
state.videoPlayer.destroy();
});
it('initialize', function () {
waitsFor(function () {
it('initialize', function (done) {
jasmine.waitUntil(function () {
return state.el.hasClass('is-initialized');
}, 'Player is not initialized.', WAIT_TIMEOUT);
runs(function () {
}).then(function () {
expect('initialize').not.toHaveBeenTriggeredOn('.video');
});
}).always(done);
});
it('ready', function () {
waitsFor(function () {
it('ready', function (done) {
jasmine.waitUntil(function () {
return state.el.hasClass('is-initialized');
}, 'Player is not initialized.', WAIT_TIMEOUT);
runs(function () {
}).then(function () {
expect('ready').not.toHaveBeenTriggeredOn('.video');
});
}).always(done);
});
it('play', function () {
......@@ -86,9 +81,7 @@
oldOTBD = window.onTouchBasedDevice;
window.onTouchBasedDevice = jasmine
.createSpy('onTouchBasedDevice')
.andReturn(null);
jasmine.stubRequests();
.and.returnValue(null);
state = jasmine.initializePlayerYouTube();
});
......@@ -96,6 +89,8 @@
afterEach(function () {
$('source').remove();
window.onTouchBasedDevice = oldOTBD;
state.storage.clear();
state.videoPlayer.destroy();
});
it('qualitychange', function () {
......
......@@ -2,26 +2,27 @@
describe('Video', function () {
var oldOTBD, state;
beforeEach(function () {
jasmine.stubRequests();
});
afterEach(function () {
$('source').remove();
window.VideoState = {};
window.VideoState.id = {};
window.YT = jasmine.YT;
});
describe('constructor', function () {
describe('YT', function () {
beforeEach(function () {
loadFixtures('video.html');
$.cookie.andReturn('0.50');
this.state = jasmine.initializePlayerYouTube('video_html5.html');
$.cookie.and.returnValue('0.50');
});
describe('by default', function () {
beforeEach(function () {
this.state = jasmine.initializePlayerYouTube('video_html5.html');
});
afterEach(function () {
this.state.storage.clear();
this.state.videoPlayer.destroy();
});
......@@ -30,7 +31,7 @@
});
it('set the elements', function () {
expect(this.state.el).toBe('#video_id');
expect(this.state.el).toEqual($('#video_id'));
});
it('parse the videos', function () {
......@@ -55,13 +56,13 @@
var state;
beforeEach(function () {
$.cookie.andReturn('0.75');
$.cookie.and.returnValue('0.75');
state = jasmine.initializePlayer('video_html5.html');
});
afterEach(function () {
state.storage.clear();
state.videoPlayer.destroy();
state = undefined;
});
describe('by default', function () {
......@@ -70,7 +71,7 @@
});
it('set the elements', function () {
expect(state.el).toBe('#video_id');
expect(state.el).toEqual($('#video_id'));
});
it('doesn\'t have `videos` dictionary', function () {
......@@ -101,35 +102,34 @@
});
describe('YouTube API is not loaded', function () {
var state;
beforeEach(function () {
window.YT = undefined;
state = jasmine.initializePlayerYouTube();
})
});
afterEach(function () {
state.storage.clear();
state.videoPlayer.destroy();
});
it('callback, to be called after YouTube API loads, exists and is called', function () {
waitsFor(function () {
return state.youtubeApiAvailable === true;
}, 'YouTube API is loaded', 3000);
it('callback, to be called after YouTube API loads, exists and is called', function (done) {
window.YT = jasmine.YT;
// Call the callback that must be called when YouTube API is
// loaded. By specification.
window.onYouTubeIframeAPIReady();
runs(function () {
jasmine.waitUntil(function () {
return state.youtubeApiAvailable === true;
}).done(function(){
// If YouTube API is not loaded, then the code will should create
// a global callback that will be called by API once it is loaded.
expect(window.onYouTubeIframeAPIReady).not.toBeUndefined();
});
}).always(done);
});
});
describe('checking start and end times', function () {
var state;
var miniTestSuite = [
{
itDescription: 'both times are proper',
......@@ -159,6 +159,7 @@
];
afterEach(function () {
state.storage.clear();
state.videoPlayer.destroy();
});
......
......@@ -82,7 +82,7 @@ function (Initialize) {
'1.50': 'videoId'
},
youtubeId: Initialize.prototype.youtubeId,
isFlashMode: jasmine.createSpy().andReturn(false)
isFlashMode: jasmine.createSpy().and.returnValue(false)
};
});
......@@ -100,7 +100,7 @@ function (Initialize) {
it('returns duration for current video', function () {
var expected;
state.isFlashMode.andReturn(true);
state.isFlashMode.and.returnValue(true);
expected = Initialize.prototype.getDuration.call(state);
expect(expected).toEqual(100);
......@@ -110,7 +110,7 @@ function (Initialize) {
it(msg, function () {
var expected;
state.isFlashMode.andReturn(true);
state.isFlashMode.and.returnValue(true);
state.speed = '2.0';
expected = Initialize.prototype.getDuration.call(state);
......@@ -128,7 +128,7 @@ function (Initialize) {
'1.0': 'cogebirgzzM',
'1.50': 'abcdefghijkl'
},
isFlashMode: jasmine.createSpy().andReturn(false)
isFlashMode: jasmine.createSpy().and.returnValue(false)
};
});
......@@ -148,7 +148,7 @@ function (Initialize) {
it('return the video id for current speed', function () {
var expected;
state.isFlashMode.andReturn(true);
state.isFlashMode.and.returnValue(true);
expected = Initialize.prototype.youtubeId.call(state);
expect(expected).toEqual('abcdefghijkl');
......@@ -279,7 +279,7 @@ function (Initialize) {
describe('isFlashMode', function () {
it('returns `true` if player in `flash` mode', function () {
var state = {
getPlayerMode: jasmine.createSpy().andReturn('flash'),
getPlayerMode: jasmine.createSpy().and.returnValue('flash'),
},
isFlashMode = Initialize.prototype.isFlashMode,
actual = isFlashMode.call(state);
......@@ -289,7 +289,7 @@ function (Initialize) {
it('returns `false` if player is not in `flash` mode', function () {
var state = {
getPlayerMode: jasmine.createSpy().andReturn('html5'),
getPlayerMode: jasmine.createSpy().and.returnValue('html5'),
},
isFlashMode = Initialize.prototype.isFlashMode,
actual = isFlashMode.call(state);
......@@ -301,7 +301,7 @@ function (Initialize) {
describe('isHtml5Mode', function () {
it('returns `true` if player in `html5` mode', function () {
var state = {
getPlayerMode: jasmine.createSpy().andReturn('html5'),
getPlayerMode: jasmine.createSpy().and.returnValue('html5'),
},
isHtml5Mode = Initialize.prototype.isHtml5Mode,
actual = isHtml5Mode.call(state);
......@@ -311,7 +311,7 @@ function (Initialize) {
it('returns `false` if player is not in `html5` mode', function () {
var state = {
getPlayerMode: jasmine.createSpy().andReturn('flash'),
getPlayerMode: jasmine.createSpy().and.returnValue('flash'),
},
isHtml5Mode = Initialize.prototype.isHtml5Mode,
actual = isHtml5Mode.call(state);
......
......@@ -139,7 +139,7 @@ function (Resizer) {
.align()
.alignByHeightOnly();
expect(spiesList[0].calls.length).toEqual(1);
expect(spiesList[0].calls.count()).toEqual(1);
});
it('all callbacks are removed', function () {
......@@ -180,7 +180,7 @@ function (Resizer) {
resizer.callbacks[methodName](arg);
expect(console.error).toHaveBeenCalledWith(errorMessage);
//reset spy
console.log.reset();
console.log.calls.reset();
});
});
......
......@@ -101,7 +101,7 @@
menuList = container.children('ol.a11y-menu-list');
menuItems = menuList.children('li.a11y-menu-item');
menuItemsLinks = menuItems.children('a.a11y-menu-item-link');
spyOn($.fn, 'focus').andCallThrough();
spyOn($.fn, 'focus').and.callThrough();
});
it('open/close the menu on mouseenter/mouseleave', function () {
......@@ -173,7 +173,7 @@
}
// Test if each element has been called twice.
expect($.fn.focus.calls.length)
expect($.fn.focus.calls.count())
.toEqual(2*menuItemsLinks.length+1);
});
......@@ -258,7 +258,7 @@
beforeEach(function () {
state = jasmine.initializePlayer();
state.videoSpeedControl.setSpeed(1.0);
spyOn(state.videoPlayer, 'onSpeedChange').andCallThrough();
spyOn(state.videoPlayer, 'onSpeedChange').and.callThrough();
$('li[data-speed="0.75"] .speed-link').click();
});
......
(function (WAIT_TIMEOUT) {
'use strict';
describe('VideoBumper', function () {
xdescribe('VideoBumper', function () {
var state, oldOTBD, waitForPlaying;
waitForPlaying = function (state) {
waitsFor(function () {
waitForPlaying = function (state, done) {
jasmine.waitUntil(function () {
return state.el.hasClass('is-playing');
}, 'Player is not playing.', WAIT_TIMEOUT);
}).done(done);
};
beforeEach(function () {
oldOTBD = window.onTouchBasedDevice;
window.onTouchBasedDevice = jasmine
.createSpy('onTouchBasedDevice').andReturn(null);
.createSpy('onTouchBasedDevice').and.returnValue(null);
state = jasmine.initializePlayer('video_with_bumper.html');
$('.poster .btn-play').click();
jasmine.Clock.useMock();
jasmine.clock().install();
});
afterEach(function () {
......@@ -28,45 +28,46 @@
state.videoPlayer.destroy();
}
window.onTouchBasedDevice = oldOTBD;
jasmine.clock().uninstall();
});
it('can render the bumper video', function () {
expect($('.is-bumper')).toExist();
});
it('can show the main video on error', function () {
it('can show the main video on error', function (done) {
state.el.trigger('error');
jasmine.Clock.tick(20);
jasmine.clock().tick(20);
expect($('.is-bumper')).not.toExist();
waitForPlaying(state);
waitForPlaying(state, done);
});
it('can show the main video once bumper ends', function () {
it('can show the main video once bumper ends', function (done) {
state.el.trigger('ended');
jasmine.Clock.tick(20);
jasmine.clock().tick(20);
expect($('.is-bumper')).not.toExist();
waitForPlaying(state);
waitForPlaying(state, done);
});
it('can show the main video on skip', function () {
it('can show the main video on skip', function (done) {
state.bumperState.videoBumper.skip();
jasmine.Clock.tick(20);
jasmine.clock().tick(20);
expect($('.is-bumper')).not.toExist();
waitForPlaying(state);
waitForPlaying(state, done);
});
it('can stop the bumper video playing if it is too long', function () {
it('can stop the bumper video playing if it is too long', function (done) {
state.el.trigger('timeupdate', [state.bumperState.videoBumper.maxBumperDuration + 1]);
jasmine.Clock.tick(20);
jasmine.clock().tick(20);
expect($('.is-bumper')).not.toExist();
waitForPlaying(state);
waitForPlaying(state, done);
});
it('can save appropriate states correctly on ended', function () {
var saveState = jasmine.createSpy('saveState');
state.bumperState.videoSaveStatePlugin.saveState = saveState;
state.el.trigger('ended');
jasmine.Clock.tick(20);
jasmine.clock().tick(20);
expect(saveState).toHaveBeenCalledWith(true, {
bumper_last_view_date: true});
});
......@@ -76,7 +77,7 @@
state.bumperState.videoSaveStatePlugin.saveState = saveState;
state.bumperState.videoBumper.skip();
expect(state.storage.getItem('isBumperShown')).toBeTruthy();
jasmine.Clock.tick(20);
jasmine.clock().tick(20);
expect(saveState).toHaveBeenCalledWith(true, {
bumper_last_view_date: true});
});
......@@ -86,7 +87,7 @@
state.bumperState.videoSaveStatePlugin.saveState = saveState;
state.el.trigger('error');
expect(state.storage.getItem('isBumperShown')).toBeTruthy();
jasmine.Clock.tick(20);
jasmine.clock().tick(20);
expect(saveState).toHaveBeenCalledWith(true, {
bumper_last_view_date: true});
});
......@@ -96,7 +97,7 @@
state.bumperState.videoSaveStatePlugin.saveState = saveState;
state.bumperState.videoBumper.skipAndDoNotShowAgain();
expect(state.storage.getItem('isBumperShown')).toBeTruthy();
jasmine.Clock.tick(20);
jasmine.clock().tick(20);
expect(saveState).toHaveBeenCalledWith(true, {
bumper_last_view_date: true, bumper_do_not_show_again: true});
});
......
......@@ -6,7 +6,6 @@
openMenu = function () {
var container = $('.video');
jasmine.Clock.useMock();
container.find('video').trigger('contextmenu');
menu = container.children('.contextmenu');
menuItems = menu.children('.menu-item').not('.submenu-item');
......@@ -23,19 +22,19 @@
openSubmenuMouse = function (menuSubmenuItem) {
menuSubmenuItem.mouseover();
jasmine.Clock.tick(200);
jasmine.clock().tick(200);
expect(menuSubmenuItem).toHaveClass('is-opened');
};
openSubmenuKeyboard = function (menuSubmenuItem, keyCode) {
menuSubmenuItem.focus().trigger(keyPressEvent(keyCode || $.ui.keyCode.RIGHT));
expect(menuSubmenuItem).toHaveClass('is-opened');
expect(menuSubmenuItem.children().first()).toBeFocused();
expect(menuSubmenuItem.children().last().children().first()).toBeFocused();
};
closeSubmenuMouse = function (menuSubmenuItem) {
menuSubmenuItem.mouseleave();
jasmine.Clock.tick(200);
jasmine.clock().tick(200);
expect(menuSubmenuItem).not.toHaveClass('is-opened');
};
......@@ -46,20 +45,20 @@
};
beforeEach(function () {
jasmine.clock().install();
// $.cookie is mocked, make sure we have a state with an unmuted volume.
$.cookie.andReturn('100');
this.addMatchers({
toBeFocused: function () {
$.cookie.and.returnValue('100');
jasmine.addMatchers({
toHaveCorrectLabels: function () {
return {
compare: function (actual) {
return { pass: $(actual)[0] === $(actual)[0].ownerDocument.activeElement };
compare: function (actual, labelsList) {
return {
pass: _.difference(labelsList, _.map(actual, function (item) {
return $(item).text();
})).length === 0
};
}
};
},
toHaveCorrectLabels: function (labelsList) {
return _.difference(labelsList, _.map(this.actual, function (item) {
return $(item).text();
})).length === 0;
}
});
});
......@@ -69,6 +68,7 @@
_.result(state.storage, 'clear');
_.result($('video').data('contextmenu'), 'destroy');
_.result(state.videoPlayer, 'destroy');
jasmine.clock().uninstall();
});
describe('constructor', function () {
......@@ -89,7 +89,7 @@
*/
// Only one context menu per video container
expect(menu).toExist();
expect(menu).toBeInDOM();
expect(menu).toHaveClass('is-opened');
expect(menuItems).toHaveCorrectLabels(['Play', 'Mute', 'Fill browser']);
expect(menuSubmenuItem.children('span')).toHaveText('Speed');
......@@ -141,8 +141,8 @@
menuEvents = ['keydown', 'contextmenu', 'mouseleave', 'mouseover'];
menu.data('menu').destroy();
expect(menu).not.toExist();
expect(overlay).not.toExist();
expect(menu).not.toBeInDOM();
expect(overlay).not.toBeInDOM();
_.each(menuitemEvents, function (eventName) {
expect(menuItems.first()).not.toHandle(eventName);
})
......@@ -177,7 +177,7 @@
it('context menu opens', function () {
expect(menu).toHaveClass('is-opened');
expect(overlay).toExist();
expect(overlay).toBeInDOM();
});
it('mouseover and mouseleave behave as expected', function () {
......@@ -193,25 +193,25 @@
// Left-click outside of open menu, for example on Play button
playButton.click();
expect(menu).not.toHaveClass('is-opened');
expect(overlay).not.toExist();
expect(overlay).not.toBeInDOM();
});
it('mouse right-clicking outside of video will close it', function () {
// Right-click outside of open menu for example on Play button
playButton.trigger('contextmenu');
expect(menu).not.toHaveClass('is-opened');
expect(overlay).not.toExist();
expect(overlay).not.toBeInDOM();
});
it('mouse right-clicking inside video but outside of context menu will not close it', function () {
spyOn(menu.data('menu'), 'pointInContainerBox').andReturn(true);
spyOn(menu.data('menu'), 'pointInContainerBox').and.returnValue(true);
overlay.trigger('contextmenu');
expect(menu).toHaveClass('is-opened');
expect(overlay).toExist();
expect(overlay).toBeInDOM();
});
it('mouse right-clicking inside video but outside of context menu will close submenus', function () {
spyOn(menu.data('menu'), 'pointInContainerBox').andReturn(true);
spyOn(menu.data('menu'), 'pointInContainerBox').and.returnValue(true);
openSubmenuMouse(menuSubmenuItem);
expect(menuSubmenuItem).toHaveClass('is-opened');
overlay.trigger('contextmenu');
......@@ -221,12 +221,12 @@
it('mouse left/right-clicking behaves as expected on play/pause menu item', function () {
var menuItem = menuItems.first();
spyOn(state.videoPlayer, 'isPlaying');
spyOn(state.videoPlayer, 'play').andCallFake(function () {
state.videoPlayer.isPlaying.andReturn(true);
spyOn(state.videoPlayer, 'play').and.callFake(function () {
state.videoPlayer.isPlaying.and.returnValue(true);
state.el.trigger('play');
});
spyOn(state.videoPlayer, 'pause').andCallFake(function () {
state.videoPlayer.isPlaying.andReturn(false);
spyOn(state.videoPlayer, 'pause').and.callFake(function () {
state.videoPlayer.isPlaying.and.returnValue(false);
state.el.trigger('pause');
});
// Left-click on play
......@@ -238,7 +238,7 @@
menuItem.click();
expect(state.videoPlayer.pause).toHaveBeenCalled();
expect(menuItem).toHaveText('Play');
state.videoPlayer.play.reset();
state.videoPlayer.play.calls.reset();
// Right-click on play
menuItem.trigger('contextmenu');
expect(state.videoPlayer.play).toHaveBeenCalled();
......@@ -355,14 +355,14 @@
it('close the menu on ESCAPE keydown', function () {
menu.trigger(keyPressEvent($.ui.keyCode.ESCAPE));
expect(menu).not.toHaveClass('is-opened');
expect(overlay).not.toExist();
expect(overlay).not.toBeInDOM();
});
it('close the submenu on ESCAPE keydown', function () {
openSubmenuKeyboard(menuSubmenuItem);
menuSubmenuItem.trigger(keyPressEvent($.ui.keyCode.ESCAPE));
expect(menuSubmenuItem).not.toHaveClass('is-opened');
expect(overlay).not.toExist();
expect(overlay).not.toBeInDOM();
});
it('close the submenu on LEFT keydown on submenu items', function () {
......@@ -395,9 +395,9 @@
menuItems.eq(0).trigger(keyPressEvent($.ui.keyCode.UP));
expect(menuSubmenuItem).toBeFocused(); // Speed
menuSubmenuItem.trigger(keyPressEvent($.ui.keyCode.UP));
// Check if hidden item can be skipped correctly.
menuItems.eq(2).hide(); // hide Fullscreen item
menuSubmenuItem.trigger(keyPressEvent($.ui.keyCode.UP));
expect(menuItems.eq(1)).toBeFocused(); // Mute
menuItems.eq(1).trigger(keyPressEvent($.ui.keyCode.UP));
expect(menuItems.eq(0)).toBeFocused(); // Play
......
(function (undefined) {
'use strict';
describe('VideoPlayer Events Bumper plugin', function () {
var Logger = window.Logger;
var state, oldOTBD;
beforeEach(function () {
oldOTBD = window.onTouchBasedDevice;
window.onTouchBasedDevice = jasmine
.createSpy('onTouchBasedDevice')
.andReturn(null);
.and.returnValue(null);
jasmine.stubRequests();
state = jasmine.initializePlayer('video_with_bumper.html');
spyOn(Logger, 'log');
$('.poster .btn-play').click();
spyOn(state.bumperState.videoEventsBumperPlugin, 'getCurrentTime').andReturn(10);
spyOn(state.bumperState.videoEventsBumperPlugin, 'getDuration').andReturn(20);
spyOn(state.bumperState.videoEventsBumperPlugin, 'getCurrentTime').and.returnValue(10);
spyOn(state.bumperState.videoEventsBumperPlugin, 'getDuration').and.returnValue(20);
});
afterEach(function () {
......@@ -33,7 +33,7 @@
state.el.trigger('ready');
expect(Logger.log).toHaveBeenCalledWith('edx.video.bumper.loaded', {
host_component_id: 'id',
bumper_id: 'xmodule/include/fixtures/test.mp4',
bumper_id: '/base/fixtures/test.mp4',
code: 'html5',
duration: 20
});
......@@ -43,7 +43,7 @@
state.el.trigger('play');
expect(Logger.log).toHaveBeenCalledWith('edx.video.bumper.played', {
host_component_id: 'id',
bumper_id: 'xmodule/include/fixtures/test.mp4',
bumper_id: '/base/fixtures/test.mp4',
code: 'html5',
currentTime: 10,
duration: 20
......@@ -54,17 +54,17 @@
state.el.trigger('ended');
expect(Logger.log).toHaveBeenCalledWith('edx.video.bumper.stopped', {
host_component_id: 'id',
bumper_id: 'xmodule/include/fixtures/test.mp4',
bumper_id: '/base/fixtures/test.mp4',
code: 'html5',
currentTime: 10,
duration: 20
});
Logger.log.reset();
Logger.log.calls.reset();
state.el.trigger('stop');
expect(Logger.log).toHaveBeenCalledWith('edx.video.bumper.stopped', {
host_component_id: 'id',
bumper_id: 'xmodule/include/fixtures/test.mp4',
bumper_id: '/base/fixtures/test.mp4',
code: 'html5',
currentTime: 10,
duration: 20
......@@ -75,7 +75,7 @@
state.el.trigger('skip', [false]);
expect(Logger.log).toHaveBeenCalledWith('edx.video.bumper.skipped', {
host_component_id: 'id',
bumper_id: 'xmodule/include/fixtures/test.mp4',
bumper_id: '/base/fixtures/test.mp4',
code: 'html5',
currentTime: 10,
duration: 20
......@@ -86,7 +86,7 @@
state.el.trigger('skip', [true]);
expect(Logger.log).toHaveBeenCalledWith('edx.video.bumper.dismissed', {
host_component_id: 'id',
bumper_id: 'xmodule/include/fixtures/test.mp4',
bumper_id: '/base/fixtures/test.mp4',
code: 'html5',
currentTime: 10,
duration: 20
......@@ -97,7 +97,7 @@
state.el.trigger('language_menu:show');
expect(Logger.log).toHaveBeenCalledWith('edx.video.bumper.transcript.menu.shown', {
host_component_id: 'id',
bumper_id: 'xmodule/include/fixtures/test.mp4',
bumper_id: '/base/fixtures/test.mp4',
code: 'html5',
duration: 20
});
......@@ -107,7 +107,7 @@
state.el.trigger('language_menu:hide');
expect(Logger.log).toHaveBeenCalledWith('edx.video.bumper.transcript.menu.hidden', {
host_component_id: 'id',
bumper_id: 'xmodule/include/fixtures/test.mp4',
bumper_id: '/base/fixtures/test.mp4',
code: 'html5',
duration: 20
});
......@@ -117,7 +117,7 @@
state.el.trigger('captions:show');
expect(Logger.log).toHaveBeenCalledWith('edx.video.bumper.transcript.shown', {
host_component_id: 'id',
bumper_id: 'xmodule/include/fixtures/test.mp4',
bumper_id: '/base/fixtures/test.mp4',
code: 'html5',
currentTime: 10,
duration: 20
......@@ -128,7 +128,7 @@
state.el.trigger('captions:hide');
expect(Logger.log).toHaveBeenCalledWith('edx.video.bumper.transcript.hidden', {
host_component_id: 'id',
bumper_id: 'xmodule/include/fixtures/test.mp4',
bumper_id: '/base/fixtures/test.mp4',
code: 'html5',
currentTime: 10,
duration: 20
......@@ -137,7 +137,7 @@
it('can destroy itself', function () {
var plugin = state.bumperState.videoEventsBumperPlugin;
spyOn($.fn, 'off').andCallThrough();
spyOn($.fn, 'off').and.callThrough();
plugin.destroy();
expect(state.bumperState.videoEventsBumperPlugin).toBeUndefined();
expect($.fn.off).toHaveBeenCalledWith({
......
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