228 lines
11 KiB
CoffeeScript
228 lines
11 KiB
CoffeeScript
define ["jasmine", "sinon", "squire"],
|
|
(jasmine, sinon, Squire) ->
|
|
|
|
feedbackTpl = readFixtures('system-feedback.underscore')
|
|
assetTpl = readFixtures('asset.underscore')
|
|
|
|
describe "Asset view", ->
|
|
beforeEach ->
|
|
setFixtures($("<script>", {id: "asset-tpl", type: "text/template"}).text(assetTpl))
|
|
appendSetFixtures($("<script>", {id: "system-feedback-tpl", type: "text/template"}).text(feedbackTpl))
|
|
appendSetFixtures(sandbox({id: "page-prompt"}))
|
|
|
|
@promptSpies = jasmine.createSpyObj('Prompt.Warning', ["constructor", "show", "hide"])
|
|
@promptSpies.constructor.andReturn(@promptSpies)
|
|
@promptSpies.show.andReturn(@promptSpies)
|
|
|
|
@confirmationSpies = jasmine.createSpyObj('Notification.Confirmation', ["constructor", "show"])
|
|
@confirmationSpies.constructor.andReturn(@confirmationSpies)
|
|
@confirmationSpies.show.andReturn(@confirmationSpies)
|
|
|
|
@savingSpies = jasmine.createSpyObj('Notification.Mini', ["constructor", "show", "hide"])
|
|
@savingSpies.constructor.andReturn(@savingSpies)
|
|
@savingSpies.show.andReturn(@savingSpies)
|
|
|
|
@injector = new Squire()
|
|
@injector.mock("js/views/feedback_prompt", {
|
|
"Warning": @promptSpies.constructor
|
|
})
|
|
@injector.mock("js/views/feedback_notification", {
|
|
"Confirmation": @confirmationSpies.constructor,
|
|
"Mini": @savingSpies.constructor
|
|
})
|
|
runs =>
|
|
@injector.require ["js/models/asset", "js/collections/asset", "js/views/asset"],
|
|
(AssetModel, AssetCollection, AssetView) =>
|
|
@model = new AssetModel
|
|
display_name: "test asset"
|
|
url: 'actual_asset_url'
|
|
portable_url: 'portable_url'
|
|
date_added: 'date'
|
|
thumbnail: null
|
|
id: 'id'
|
|
spyOn(@model, "destroy").andCallThrough()
|
|
spyOn(@model, "save").andCallThrough()
|
|
|
|
@collection = new AssetCollection([@model])
|
|
@collection.url = "update-asset-url"
|
|
@view = new AssetView({model: @model})
|
|
|
|
waitsFor (=> @view), "AssetView was not created", 1000
|
|
|
|
afterEach ->
|
|
@injector.clean()
|
|
@injector.remove()
|
|
|
|
describe "Basic", ->
|
|
it "should render properly", ->
|
|
@view.render()
|
|
expect(@view.$el).toContainText("test asset")
|
|
|
|
it "should pop a delete confirmation when the delete button is clicked", ->
|
|
@view.render().$(".remove-asset-button").click()
|
|
expect(@promptSpies.constructor).toHaveBeenCalled()
|
|
ctorOptions = @promptSpies.constructor.mostRecentCall.args[0]
|
|
expect(ctorOptions.title).toMatch('Delete File Confirmation')
|
|
# hasn't actually been removed
|
|
expect(@model.destroy).not.toHaveBeenCalled()
|
|
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", ->
|
|
@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(@confirmationSpies.constructor).not.toHaveBeenCalled()
|
|
expect(@collection.contains(@model)).toBeTruthy()
|
|
# return a success response
|
|
@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", ->
|
|
@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)
|
|
expect(@confirmationSpies.constructor).not.toHaveBeenCalled()
|
|
expect(@collection.contains(@model)).toBeTruthy()
|
|
|
|
it "should lock the asset on confirmation", ->
|
|
@view.render().$(".lock-checkbox").click()
|
|
# AJAX request has been sent, but not yet returned
|
|
expect(@model.save).toHaveBeenCalled()
|
|
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)
|
|
expect(@savingSpies.hide).toHaveBeenCalled()
|
|
expect(@model.get("locked")).toBeTruthy()
|
|
|
|
it "should not lock the asset if server errors", ->
|
|
@view.render().$(".lock-checkbox").click()
|
|
# return an error response
|
|
@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()
|
|
|
|
describe "Assets view", ->
|
|
beforeEach ->
|
|
setFixtures($("<script>", {id: "asset-tpl", type: "text/template"}).text(assetTpl))
|
|
window.analytics = jasmine.createSpyObj('analytics', ['track'])
|
|
window.course_location_analytics = jasmine.createSpy()
|
|
appendSetFixtures(sandbox({id: "asset_table_body"}))
|
|
|
|
@promptSpies = jasmine.createSpyObj('Prompt.Warning', ["constructor", "show", "hide"])
|
|
@promptSpies.constructor.andReturn(@promptSpies)
|
|
@promptSpies.show.andReturn(@promptSpies)
|
|
|
|
@injector = new Squire()
|
|
@injector.mock("js/views/feedback_prompt", {
|
|
"Warning": @promptSpies.constructor
|
|
})
|
|
|
|
runs =>
|
|
@injector.require ["js/models/asset", "js/collections/asset", "js/views/assets"],
|
|
(AssetModel, AssetCollection, AssetsView) =>
|
|
@AssetModel = AssetModel
|
|
@collection = new AssetCollection [
|
|
display_name: "test asset 1"
|
|
url: 'actual_asset_url_1'
|
|
portable_url: 'portable_url_1'
|
|
date_added: 'date_1'
|
|
thumbnail: null
|
|
id: 'id_1'
|
|
,
|
|
display_name: "test asset 2"
|
|
url: 'actual_asset_url_2'
|
|
portable_url: 'portable_url_2'
|
|
date_added: 'date_2'
|
|
thumbnail: null
|
|
id: 'id_2'
|
|
]
|
|
@collection.url = "update-asset-url"
|
|
@view = new AssetsView
|
|
collection: @collection
|
|
el: $('#asset_table_body')
|
|
|
|
waitsFor (=> @view), "AssetView was not created", 1000
|
|
|
|
$.ajax()
|
|
@requests = requests = []
|
|
@xhr = sinon.useFakeXMLHttpRequest()
|
|
@xhr.onCreate = (xhr) -> requests.push(xhr)
|
|
|
|
afterEach ->
|
|
delete window.analytics
|
|
delete window.course_location_analytics
|
|
|
|
@injector.clean()
|
|
@injector.remove()
|
|
|
|
describe "Basic", ->
|
|
it "should render both assets", ->
|
|
@view.render()
|
|
expect(@view.$el).toContainText("test asset 1")
|
|
expect(@view.$el).toContainText("test asset 2")
|
|
|
|
it "should remove the deleted asset from the view", ->
|
|
# 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
|
|
expect(@view.$el).toContainText("test asset 1")
|
|
expect(@view.$el).not.toContainText("test asset 2")
|
|
|
|
it "does not remove asset if deletion failed", ->
|
|
# 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
|
|
expect(@view.$el).toContainText("test asset 1")
|
|
expect(@view.$el).toContainText("test asset 2")
|
|
|
|
it "adds an asset if asset does not already exist", ->
|
|
@view.render()
|
|
model = new @AssetModel
|
|
display_name: "new asset"
|
|
url: 'new_actual_asset_url'
|
|
portable_url: 'portable_url'
|
|
date_added: 'date'
|
|
thumbnail: null
|
|
id: 'idx'
|
|
@view.addAsset(model)
|
|
expect(@view.$el).toContainText("new asset")
|
|
expect(@collection.models.indexOf(model)).toBe(0)
|
|
expect(@collection.models.length).toBe(3)
|
|
|
|
it "does not add an asset if asset already exists", ->
|
|
@view.render()
|
|
spyOn(@collection, "add").andCallThrough()
|
|
model = @collection.models[1]
|
|
@view.addAsset(model)
|
|
expect(@collection.add).not.toHaveBeenCalled()
|