Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Workaround for "xhr.restore" failures. #1951

Merged
merged 2 commits into from
Dec 17, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions cms/static/coffee/spec/main.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,10 @@ requirejs.config({

"mathjax": "//edx-static.s3.amazonaws.com/mathjax-MathJax-727332c/MathJax.js?config=TeX-MML-AM_HTMLorMML-full&delayStartupUntil=configured",
"youtube": "//www.youtube.com/player_api?noext",
"tender": "//edxedge.tenderapp.com/tender_widget"
"tender": "//edxedge.tenderapp.com/tender_widget",

"coffee/src/ajax_prefix": "xmodule_js/common_static/coffee/src/ajax_prefix"
"coffee/src/ajax_prefix": "xmodule_js/common_static/coffee/src/ajax_prefix",
"js/spec/test_utils": "js/spec/test_utils",
}
shim: {
"gettext": {
Expand Down
24 changes: 12 additions & 12 deletions cms/static/coffee/spec/main_spec.coffee
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
require ["jquery", "backbone", "coffee/src/main", "sinon", "jasmine-stealth", "jquery.cookie"],
($, Backbone, main, sinon) ->
require ["jquery", "backbone", "coffee/src/main", "js/spec/create_sinon", "jasmine-stealth", "jquery.cookie"],
($, Backbone, main, create_sinon) ->
describe "CMS", ->
it "should initialize URL", ->
expect(window.CMS.URL).toBeDefined()
Expand All @@ -26,30 +26,30 @@ require ["jquery", "backbone", "coffee/src/main", "sinon", "jasmine-stealth", "j
beforeEach ->
setFixtures($("<script>", {id: "system-feedback-tpl", type: "text/template"}).text(tpl))
appendSetFixtures(sandbox({id: "page-notification"}))
@requests = requests = []
@xhr = sinon.useFakeXMLHttpRequest()
@xhr.onCreate = (xhr) -> requests.push(xhr)

afterEach ->
@xhr.restore()

it "successful AJAX request does not pop an error notification", ->
server = create_sinon['server'](200, this)

expect($("#page-notification")).toBeEmpty()
$.ajax("/test")
expect($("#page-notification")).toBeEmpty()
@requests[0].respond(200)
server.respond()
expect($("#page-notification")).toBeEmpty()

it "AJAX request with error should pop an error notification", ->
server = create_sinon['server'](500, this)

$.ajax("/test")
@requests[0].respond(500)
server.respond()
expect($("#page-notification")).not.toBeEmpty()
expect($("#page-notification")).toContain('div.wrapper-notification-error')

it "can override AJAX request with error so it does not pop an error notification", ->
server = create_sinon['server'](500, this)

$.ajax
url: "/test"
notifyOnError: false
@requests[0].respond(500)
expect($("#page-notification")).toBeEmpty()

server.respond()
expect($("#page-notification")).toBeEmpty()
16 changes: 7 additions & 9 deletions cms/static/coffee/spec/models/section_spec.coffee
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
define ["js/models/section", "sinon", "js/utils/module"], (Section, sinon, ModuleUtils) ->
define ["js/models/section", "js/spec/create_sinon", "js/utils/module"], (Section, create_sinon, ModuleUtils) ->
describe "Section", ->
describe "basic", ->
beforeEach ->
Expand Down Expand Up @@ -32,21 +32,19 @@ define ["js/models/section", "sinon", "js/utils/module"], (Section, sinon, Modul
id: 42
name: "Life, the Universe, and Everything"
})
@requests = requests = []
@xhr = sinon.useFakeXMLHttpRequest()
@xhr.onCreate = (xhr) -> requests.push(xhr)

afterEach ->
@xhr.restore()

it "show/hide a notification when it saves to the server", ->
server = create_sinon['server'](200, this)

@model.save()
expect(Section.prototype.showNotification).toHaveBeenCalled()
@requests[0].respond(200)
server.respond()
expect(Section.prototype.hideNotification).toHaveBeenCalled()

it "don't hide notification when saving fails", ->
# this is handled by the global AJAX error handler
server = create_sinon['server'](500, this)

@model.save()
@requests[0].respond(500)
server.respond()
expect(Section.prototype.hideNotification).not.toHaveBeenCalled()
43 changes: 22 additions & 21 deletions cms/static/coffee/spec/views/assets_spec.coffee
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
define ["jasmine", "sinon", "squire"],
(jasmine, sinon, Squire) ->
define ["jasmine", "js/spec/create_sinon", "squire"],
(jasmine, create_sinon, Squire) ->

feedbackTpl = readFixtures('system-feedback.underscore')
assetTpl = readFixtures('asset.underscore')
Expand Down Expand Up @@ -68,63 +68,63 @@ define ["jasmine", "sinon", "squire"],
expect(@collection).toContain(@model)

describe "AJAX", ->
beforeEach ->
@requests = requests = []
@xhr = sinon.useFakeXMLHttpRequest()
@xhr.onCreate = (xhr) -> requests.push(xhr)

afterEach ->
@xhr.restore()

it "should destroy itself on confirmation", ->
requests = create_sinon["requests"](this)

@view.render().$(".remove-asset-button").click()
ctorOptions = @promptSpies.constructor.mostRecentCall.args[0]
# run the primary function to indicate confirmation
ctorOptions.actions.primary.click(@promptSpies)
# AJAX request has been sent, but not yet returned
expect(@model.destroy).toHaveBeenCalled()
expect(@requests.length).toEqual(1)
expect(requests.length).toEqual(1)
expect(@confirmationSpies.constructor).not.toHaveBeenCalled()
expect(@collection.contains(@model)).toBeTruthy()
# return a success response
@requests[0].respond(200)
requests[0].respond(200)
expect(@confirmationSpies.constructor).toHaveBeenCalled()
expect(@confirmationSpies.show).toHaveBeenCalled()
savingOptions = @confirmationSpies.constructor.mostRecentCall.args[0]
expect(savingOptions.title).toMatch("Your file has been deleted.")
expect(@collection.contains(@model)).toBeFalsy()

it "should not destroy itself if server errors", ->
requests = create_sinon["requests"](this)

@view.render().$(".remove-asset-button").click()
ctorOptions = @promptSpies.constructor.mostRecentCall.args[0]
# run the primary function to indicate confirmation
ctorOptions.actions.primary.click(@promptSpies)
# AJAX request has been sent, but not yet returned
expect(@model.destroy).toHaveBeenCalled()
# return an error response
@requests[0].respond(404)
requests[0].respond(404)
expect(@confirmationSpies.constructor).not.toHaveBeenCalled()
expect(@collection.contains(@model)).toBeTruthy()

it "should lock the asset on confirmation", ->
requests = create_sinon["requests"](this)

@view.render().$(".lock-checkbox").click()
# AJAX request has been sent, but not yet returned
expect(@model.save).toHaveBeenCalled()
expect(@requests.length).toEqual(1)
expect(requests.length).toEqual(1)
expect(@savingSpies.constructor).toHaveBeenCalled()
expect(@savingSpies.show).toHaveBeenCalled()
savingOptions = @savingSpies.constructor.mostRecentCall.args[0]
expect(savingOptions.title).toMatch("Saving...")
expect(@model.get("locked")).toBeFalsy()
# return a success response
@requests[0].respond(200)
requests[0].respond(200)
expect(@savingSpies.hide).toHaveBeenCalled()
expect(@model.get("locked")).toBeTruthy()

it "should not lock the asset if server errors", ->
requests = create_sinon["requests"](this)

@view.render().$(".lock-checkbox").click()
# return an error response
@requests[0].respond(404)
requests[0].respond(404)
# Don't call hide because that closes the notification showing the server error.
expect(@savingSpies.hide).not.toHaveBeenCalled()
expect(@model.get("locked")).toBeFalsy()
Expand Down Expand Up @@ -172,9 +172,6 @@ define ["jasmine", "sinon", "squire"],
waitsFor (=> @view), "AssetView was not created", 1000

$.ajax()
@requests = requests = []
@xhr = sinon.useFakeXMLHttpRequest()
@xhr.onCreate = (xhr) -> requests.push(xhr)

afterEach ->
delete window.analytics
Expand All @@ -190,18 +187,22 @@ define ["jasmine", "sinon", "squire"],
expect(@view.$el).toContainText("test asset 2")

it "should remove the deleted asset from the view", ->
requests = create_sinon["requests"](this)

# Delete the 2nd asset with success from server.
@view.render().$(".remove-asset-button")[1].click()
@promptSpies.constructor.mostRecentCall.args[0].actions.primary.click(@promptSpies)
req.respond(200) for req in @requests
req.respond(200) for req in requests
expect(@view.$el).toContainText("test asset 1")
expect(@view.$el).not.toContainText("test asset 2")

it "does not remove asset if deletion failed", ->
requests = create_sinon["requests"](this)

# Delete the 2nd asset, but mimic a failure from the server.
@view.render().$(".remove-asset-button")[1].click()
@promptSpies.constructor.mostRecentCall.args[0].actions.primary.click(@promptSpies)
req.respond(404) for req in @requests
req.respond(404) for req in requests
expect(@view.$el).toContainText("test asset 1")
expect(@view.$el).toContainText("test asset 2")

Expand Down
Loading