Commit b2a0b2f7 by Andy Armstrong

Improve response handling in AjaxHelpers

I've changed the logic so that AjaxHelpers keeps
track of which requests have not yet had mock
responses sent. This ensures that every response
is handled before moving on to the next one,
rather than always handling the last request.
My intention is that this won't allow bugs to creep
in where a request isn't fired and instead the test
responds to an old request. It also should ensure
that extra events aren't accidentally fired.
parent 7280a587
...@@ -290,6 +290,7 @@ define ["jquery", "jasmine", "common/js/spec_helpers/ajax_helpers", "squire"], ...@@ -290,6 +290,7 @@ define ["jquery", "jasmine", "common/js/spec_helpers/ajax_helpers", "squire"],
it "should remove the deleted asset from the view", -> it "should remove the deleted asset from the view", ->
{view: @view, requests: requests} = @createAssetsView(this) {view: @view, requests: requests} = @createAssetsView(this)
AjaxHelpers.respondWithJson(requests, @mockAssetsResponse)
setup.call(this, requests) setup.call(this, requests)
# Delete the 2nd asset with success from server. # Delete the 2nd asset with success from server.
@view.$(".remove-asset-button")[1].click() @view.$(".remove-asset-button")[1].click()
......
...@@ -309,7 +309,7 @@ define(["js/utils/drag_and_drop", "common/js/components/views/feedback_notificat ...@@ -309,7 +309,7 @@ define(["js/utils/drag_and_drop", "common/js/components/views/feedback_notificat
this.clock.restore(); this.clock.restore();
}); });
it("should send an update on reorder from one parent to another", function () { it("should send an update on reorder from one parent to another", function () {
var requests, savingOptions; var requests, request, savingOptions;
requests = AjaxHelpers["requests"](this); requests = AjaxHelpers["requests"](this);
ContentDragger.dragState.dropDestination = $('#unit-4'); ContentDragger.dragState.dropDestination = $('#unit-4');
ContentDragger.dragState.attachMethod = "after"; ContentDragger.dragState.attachMethod = "after";
...@@ -323,15 +323,15 @@ define(["js/utils/drag_and_drop", "common/js/components/views/feedback_notificat ...@@ -323,15 +323,15 @@ define(["js/utils/drag_and_drop", "common/js/components/views/feedback_notificat
}, null, { }, null, {
clientX: $('#unit-1').offset().left clientX: $('#unit-1').offset().left
}); });
expect(requests.length).toEqual(1); request = AjaxHelpers.currentRequest(requests);
expect(this.savingSpies.constructor).toHaveBeenCalled(); expect(this.savingSpies.constructor).toHaveBeenCalled();
expect(this.savingSpies.show).toHaveBeenCalled(); expect(this.savingSpies.show).toHaveBeenCalled();
expect(this.savingSpies.hide).not.toHaveBeenCalled(); expect(this.savingSpies.hide).not.toHaveBeenCalled();
savingOptions = this.savingSpies.constructor.mostRecentCall.args[0]; savingOptions = this.savingSpies.constructor.mostRecentCall.args[0];
expect(savingOptions.title).toMatch(/Saving/); expect(savingOptions.title).toMatch(/Saving/);
expect($('#unit-1')).toHaveClass('was-dropped'); expect($('#unit-1')).toHaveClass('was-dropped');
expect(requests[0].requestBody).toEqual('{"children":["fourth-unit-id","first-unit-id"]}'); expect(request.requestBody).toEqual('{"children":["fourth-unit-id","first-unit-id"]}');
requests[0].respond(200); request.respond(200);
expect(this.savingSpies.hide).toHaveBeenCalled(); expect(this.savingSpies.hide).toHaveBeenCalled();
this.clock.tick(1001); this.clock.tick(1001);
expect($('#unit-1')).not.toHaveClass('was-dropped'); expect($('#unit-1')).not.toHaveClass('was-dropped');
...@@ -341,7 +341,8 @@ define(["js/utils/drag_and_drop", "common/js/components/views/feedback_notificat ...@@ -341,7 +341,8 @@ define(["js/utils/drag_and_drop", "common/js/components/views/feedback_notificat
expect($('#subsection-2').data('refresh')).toHaveBeenCalled(); expect($('#subsection-2').data('refresh')).toHaveBeenCalled();
}); });
it("should send an update on reorder within the same parent", function () { it("should send an update on reorder within the same parent", function () {
var requests = AjaxHelpers["requests"](this); var requests = AjaxHelpers["requests"](this),
request;
ContentDragger.dragState.dropDestination = $('#unit-2'); ContentDragger.dragState.dropDestination = $('#unit-2');
ContentDragger.dragState.attachMethod = "after"; ContentDragger.dragState.attachMethod = "after";
ContentDragger.dragState.parentList = $('#subsection-1'); ContentDragger.dragState.parentList = $('#subsection-1');
...@@ -354,12 +355,12 @@ define(["js/utils/drag_and_drop", "common/js/components/views/feedback_notificat ...@@ -354,12 +355,12 @@ define(["js/utils/drag_and_drop", "common/js/components/views/feedback_notificat
}, null, { }, null, {
clientX: $('#unit-1').offset().left clientX: $('#unit-1').offset().left
}); });
expect(requests.length).toEqual(1); request = AjaxHelpers.currentRequest(requests);
expect($('#unit-1')).toHaveClass('was-dropped'); expect($('#unit-1')).toHaveClass('was-dropped');
expect(requests[0].requestBody).toEqual( expect(request.requestBody).toEqual(
'{"children":["second-unit-id","first-unit-id","third-unit-id"]}' '{"children":["second-unit-id","first-unit-id","third-unit-id"]}'
); );
requests[0].respond(200); request.respond(200);
this.clock.tick(1001); this.clock.tick(1001);
expect($('#unit-1')).not.toHaveClass('was-dropped'); expect($('#unit-1')).not.toHaveClass('was-dropped');
// parent // parent
......
...@@ -119,13 +119,12 @@ define([ "jquery", "common/js/spec_helpers/ajax_helpers", "URI", "js/views/asset ...@@ -119,13 +119,12 @@ define([ "jquery", "common/js/spec_helpers/ajax_helpers", "URI", "js/views/asset
}; };
var respondWithMockAssets = function(requests) { var respondWithMockAssets = function(requests) {
var requestIndex = requests.length - 1; var request = AjaxHelpers.currentRequest(requests);
var request = requests[requestIndex];
var url = new URI(request.url); var url = new URI(request.url);
var queryParameters = url.query(true); // Returns an object with each query parameter stored as a value var queryParameters = url.query(true); // Returns an object with each query parameter stored as a value
var asset_type = queryParameters.asset_type; var asset_type = queryParameters.asset_type;
var response = asset_type !== '' ? mockExampleFilteredAssetsResponse : mockExampleAssetsResponse; var response = asset_type !== '' ? mockExampleFilteredAssetsResponse : mockExampleAssetsResponse;
AjaxHelpers.respondWithJson(requests, response, requestIndex); AjaxHelpers.respondWithJson(requests, response);
}; };
var event = {}; var event = {};
......
...@@ -7,7 +7,7 @@ define([ "jquery", "common/js/spec_helpers/ajax_helpers", "js/spec_helpers/edit_ ...@@ -7,7 +7,7 @@ define([ "jquery", "common/js/spec_helpers/ajax_helpers", "js/spec_helpers/edit_
describe("Supports reordering components", function () { describe("Supports reordering components", function () {
var model, containerView, mockContainerHTML, respondWithMockXBlockFragment, init, getComponent, var model, containerView, mockContainerHTML, init, getComponent,
getDragHandle, dragComponentVertically, dragComponentAbove, getDragHandle, dragComponentVertically, dragComponentAbove,
verifyRequest, verifyNumReorderCalls, respondToRequest, notificationSpy, verifyRequest, verifyNumReorderCalls, respondToRequest, notificationSpy,
...@@ -28,11 +28,6 @@ define([ "jquery", "common/js/spec_helpers/ajax_helpers", "js/spec_helpers/edit_ ...@@ -28,11 +28,6 @@ define([ "jquery", "common/js/spec_helpers/ajax_helpers", "js/spec_helpers/edit_
mockContainerHTML = readFixtures('mock/mock-container-xblock.underscore'); mockContainerHTML = readFixtures('mock/mock-container-xblock.underscore');
respondWithMockXBlockFragment = function (requests, response) {
var requestIndex = requests.length - 1;
AjaxHelpers.respondWithJson(requests, response, requestIndex);
};
beforeEach(function () { beforeEach(function () {
EditHelpers.installMockXBlock(); EditHelpers.installMockXBlock();
EditHelpers.installViewTemplates(); EditHelpers.installViewTemplates();
...@@ -60,7 +55,7 @@ define([ "jquery", "common/js/spec_helpers/ajax_helpers", "js/spec_helpers/edit_ ...@@ -60,7 +55,7 @@ define([ "jquery", "common/js/spec_helpers/ajax_helpers", "js/spec_helpers/edit_
var requests = AjaxHelpers.requests(caller); var requests = AjaxHelpers.requests(caller);
containerView.render(); containerView.render();
respondWithMockXBlockFragment(requests, { AjaxHelpers.respondWithJson(requests, {
html: mockContainerHTML, html: mockContainerHTML,
"resources": [] "resources": []
}); });
......
...@@ -443,19 +443,19 @@ define([ ...@@ -443,19 +443,19 @@ define([
'Group Configuration name is required' 'Group Configuration name is required'
); );
// No request // No request
expect(requests.length).toBe(0); AjaxHelpers.expectNoRequests(requests);
// Set correct value // Set correct value
setValuesToInputs(this.view, { inputName: 'New Configuration' }); setValuesToInputs(this.view, { inputName: 'New Configuration' });
// Try to save // Try to save
this.view.$('form').submit(); this.view.$('form').submit();
requests[0].respond(200); AjaxHelpers.respondWithJson(requests, {});
// Model is updated // Model is updated
expect(this.model).toBeCorrectValuesInModel({ expect(this.model).toBeCorrectValuesInModel({
name: 'New Configuration' name: 'New Configuration'
}); });
// Error message disappear // Error message disappear
expect(this.view.$(SELECTORS.errorMessage)).not.toExist(); expect(this.view.$(SELECTORS.errorMessage)).not.toExist();
expect(requests.length).toBe(1); AjaxHelpers.expectNoRequests(requests);
}); });
it('should have appropriate class names on focus/blur', function () { it('should have appropriate class names on focus/blur', function () {
...@@ -733,9 +733,9 @@ define([ ...@@ -733,9 +733,9 @@ define([
}; };
respondToSave = function(requests, view) { respondToSave = function(requests, view) {
expect(requests.length).toBe(1); var request = AjaxHelpers.currentRequest(requests);
expect(requests[0].method).toBe('POST'); expect(request.method).toBe('POST');
expect(requests[0].url).toBe('/mock_url/0'); expect(request.url).toBe('/mock_url/0');
AjaxHelpers.respondWithJson(requests, { AjaxHelpers.respondWithJson(requests, {
name: 'Content Group Configuration', name: 'Content Group Configuration',
groups: view.collection.map(function(groupModel, index) { groups: view.collection.map(function(groupModel, index) {
...@@ -803,7 +803,7 @@ define([ ...@@ -803,7 +803,7 @@ define([
newGroupName = 'New Group Name', newGroupName = 'New Group Name',
view = renderView(); view = renderView();
editNewGroup(view, {newName: newGroupName, cancel: true}); editNewGroup(view, {newName: newGroupName, cancel: true});
expect(requests.length).toBe(0); AjaxHelpers.expectNoRequests(requests);
verifyEditingGroup(view, false); verifyEditingGroup(view, false);
expect(view.$()).not.toContainText(newGroupName); expect(view.$()).not.toContainText(newGroupName);
}); });
...@@ -814,7 +814,7 @@ define([ ...@@ -814,7 +814,7 @@ define([
view = renderView([originalGroupName]); view = renderView([originalGroupName]);
editExistingGroup(view, {newName: 'New Group Name', cancel: true}); editExistingGroup(view, {newName: 'New Group Name', cancel: true});
verifyEditingGroup(view, false); verifyEditingGroup(view, false);
expect(requests.length).toBe(0); AjaxHelpers.expectNoRequests(requests);
expect(view.collection.at(0).get('name')).toBe(originalGroupName); expect(view.collection.at(0).get('name')).toBe(originalGroupName);
}); });
...@@ -823,7 +823,7 @@ define([ ...@@ -823,7 +823,7 @@ define([
newGroupName = 'New Group Name', newGroupName = 'New Group Name',
view = renderView(); view = renderView();
editNewGroup(view, {newName: '', save: true}); editNewGroup(view, {newName: '', save: true});
expect(requests.length).toBe(0); AjaxHelpers.expectNoRequests(requests);
correctValidationError(view, requests, newGroupName); correctValidationError(view, requests, newGroupName);
}); });
...@@ -832,7 +832,7 @@ define([ ...@@ -832,7 +832,7 @@ define([
oldGroupName = 'Old Group Name', oldGroupName = 'Old Group Name',
view = renderView([oldGroupName]); view = renderView([oldGroupName]);
editExistingGroup(view, {newName: '', save: true}); editExistingGroup(view, {newName: '', save: true});
expect(requests.length).toBe(0); AjaxHelpers.expectNoRequests(requests);
correctValidationError(view, requests, oldGroupName); correctValidationError(view, requests, oldGroupName);
}); });
......
...@@ -54,15 +54,14 @@ define(["jquery", "underscore", "common/js/spec_helpers/ajax_helpers", "URI", "j ...@@ -54,15 +54,14 @@ define(["jquery", "underscore", "common/js/spec_helpers/ajax_helpers", "URI", "j
}); });
var respondWithMockPage = function(requests, mockPage) { var respondWithMockPage = function(requests, mockPage) {
var requestIndex = requests.length - 1; var request = AjaxHelpers.currentRequest(requests);
if (typeof mockPage == 'undefined') { if (typeof mockPage == 'undefined') {
var request = requests[requestIndex];
var url = new URI(request.url); var url = new URI(request.url);
var queryParameters = url.query(true); // Returns an object with each query parameter stored as a value var queryParameters = url.query(true); // Returns an object with each query parameter stored as a value
var page = queryParameters.page_number; var page = queryParameters.page_number;
mockPage = page === "0" ? mockFirstPage : mockSecondPage; mockPage = page === "0" ? mockFirstPage : mockSecondPage;
} }
AjaxHelpers.respondWithJson(requests, mockPage, requestIndex); AjaxHelpers.respondWithJson(requests, mockPage);
}; };
var MockPagingView = PagedContainer.extend({ var MockPagingView = PagedContainer.extend({
...@@ -140,7 +139,7 @@ define(["jquery", "underscore", "common/js/spec_helpers/ajax_helpers", "URI", "j ...@@ -140,7 +139,7 @@ define(["jquery", "underscore", "common/js/spec_helpers/ajax_helpers", "URI", "j
pagingContainer.setPage(1); pagingContainer.setPage(1);
respondWithMockPage(requests); respondWithMockPage(requests);
pagingContainer.nextPage(); pagingContainer.nextPage();
expect(requests.length).toBe(1); AjaxHelpers.expectNoRequests(requests);
}); });
}); });
...@@ -159,7 +158,7 @@ define(["jquery", "underscore", "common/js/spec_helpers/ajax_helpers", "URI", "j ...@@ -159,7 +158,7 @@ define(["jquery", "underscore", "common/js/spec_helpers/ajax_helpers", "URI", "j
pagingContainer.setPage(0); pagingContainer.setPage(0);
respondWithMockPage(requests); respondWithMockPage(requests);
pagingContainer.previousPage(); pagingContainer.previousPage();
expect(requests.length).toBe(1); AjaxHelpers.expectNoRequests(requests);
}); });
it('does not move back after a server error', function () { it('does not move back after a server error', function () {
......
...@@ -2,22 +2,23 @@ define(["jquery", "underscore", "underscore.string", "common/js/spec_helpers/aja ...@@ -2,22 +2,23 @@ define(["jquery", "underscore", "underscore.string", "common/js/spec_helpers/aja
"common/js/spec_helpers/template_helpers", "js/spec_helpers/edit_helpers", "common/js/spec_helpers/template_helpers", "js/spec_helpers/edit_helpers",
"js/views/pages/container", "js/views/pages/paged_container", "js/models/xblock_info", "jquery.simulate"], "js/views/pages/container", "js/views/pages/paged_container", "js/models/xblock_info", "jquery.simulate"],
function ($, _, str, AjaxHelpers, TemplateHelpers, EditHelpers, ContainerPage, PagedContainerPage, XBlockInfo) { function ($, _, str, AjaxHelpers, TemplateHelpers, EditHelpers, ContainerPage, PagedContainerPage, XBlockInfo) {
'use strict';
function parameterized_suite(label, global_page_options, fixtures) { function parameterized_suite(label, globalPageOptions) {
describe(label + " ContainerPage", function () { describe(label + " ContainerPage", function () {
var lastRequest, getContainerPage, renderContainerPage, expectComponents, respondWithHtml, var getContainerPage, renderContainerPage, handleContainerPageRefresh, expectComponents,
model, containerPage, requests, initialDisplayName, respondWithHtml, model, containerPage, requests, initialDisplayName,
mockContainerPage = readFixtures('mock/mock-container-page.underscore'), mockContainerPage = readFixtures('mock/mock-container-page.underscore'),
mockContainerXBlockHtml = readFixtures(fixtures.initial), mockContainerXBlockHtml = readFixtures(globalPageOptions.initial),
mockXBlockHtml = readFixtures(fixtures.add_response), mockXBlockHtml = readFixtures(globalPageOptions.addResponse),
mockBadContainerXBlockHtml = readFixtures('mock/mock-bad-javascript-container-xblock.underscore'), mockBadContainerXBlockHtml = readFixtures('mock/mock-bad-javascript-container-xblock.underscore'),
mockBadXBlockContainerXBlockHtml = readFixtures('mock/mock-bad-xblock-container-xblock.underscore'), mockBadXBlockContainerXBlockHtml = readFixtures('mock/mock-bad-xblock-container-xblock.underscore'),
mockUpdatedContainerXBlockHtml = readFixtures('mock/mock-updated-container-xblock.underscore'), mockUpdatedContainerXBlockHtml = readFixtures('mock/mock-updated-container-xblock.underscore'),
mockXBlockEditorHtml = readFixtures('mock/mock-xblock-editor.underscore'), mockXBlockEditorHtml = readFixtures('mock/mock-xblock-editor.underscore'),
mockXBlockVisibilityEditorHtml = readFixtures('mock/mock-xblock-visibility-editor.underscore'), mockXBlockVisibilityEditorHtml = readFixtures('mock/mock-xblock-visibility-editor.underscore'),
PageClass = fixtures.page, PageClass = globalPageOptions.page,
pagedSpecificTests = fixtures.paged_specific_tests, pagedSpecificTests = globalPageOptions.pagedSpecificTests,
hasVisibilityEditor = fixtures.has_visibility_editor; hasVisibilityEditor = globalPageOptions.hasVisibilityEditor;
beforeEach(function () { beforeEach(function () {
var newDisplayName = 'New Display Name'; var newDisplayName = 'New Display Name';
...@@ -47,16 +48,10 @@ define(["jquery", "underscore", "underscore.string", "common/js/spec_helpers/aja ...@@ -47,16 +48,10 @@ define(["jquery", "underscore", "underscore.string", "common/js/spec_helpers/aja
EditHelpers.uninstallMockXBlock(); EditHelpers.uninstallMockXBlock();
}); });
lastRequest = function () {
return requests[requests.length - 1];
};
respondWithHtml = function (html) { respondWithHtml = function (html) {
var requestIndex = requests.length - 1;
AjaxHelpers.respondWithJson( AjaxHelpers.respondWithJson(
requests, requests,
{ html: html, "resources": [] }, { html: html, "resources": [] }
requestIndex
); );
}; };
...@@ -66,7 +61,7 @@ define(["jquery", "underscore", "underscore.string", "common/js/spec_helpers/aja ...@@ -66,7 +61,7 @@ define(["jquery", "underscore", "underscore.string", "common/js/spec_helpers/aja
templates: EditHelpers.mockComponentTemplates, templates: EditHelpers.mockComponentTemplates,
el: $('#content') el: $('#content')
}; };
return new PageClass(_.extend(options || {}, global_page_options, default_options)); return new PageClass(_.extend(options || {}, globalPageOptions, default_options));
}; };
renderContainerPage = function (test, html, options) { renderContainerPage = function (test, html, options) {
...@@ -74,6 +69,18 @@ define(["jquery", "underscore", "underscore.string", "common/js/spec_helpers/aja ...@@ -74,6 +69,18 @@ define(["jquery", "underscore", "underscore.string", "common/js/spec_helpers/aja
containerPage = getContainerPage(options); containerPage = getContainerPage(options);
containerPage.render(); containerPage.render();
respondWithHtml(html); respondWithHtml(html);
AjaxHelpers.expectJsonRequest(requests, 'GET', '/xblock/locator-container');
AjaxHelpers.respondWithJson(requests, options);
};
handleContainerPageRefresh = function(requests) {
var request = AjaxHelpers.currentRequest(requests);
expect(str.startsWith(request.url,
'/xblock/locator-container/container_preview')).toBeTruthy();
AjaxHelpers.respondWithJson(requests, {
html: mockUpdatedContainerXBlockHtml,
resources: []
});
}; };
expectComponents = function (container, locators) { expectComponents = function (container, locators) {
...@@ -136,7 +143,7 @@ define(["jquery", "underscore", "underscore.string", "common/js/spec_helpers/aja ...@@ -136,7 +143,7 @@ define(["jquery", "underscore", "underscore.string", "common/js/spec_helpers/aja
}; };
it('can edit itself', function () { it('can edit itself', function () {
var editButtons, displayNameElement; var editButtons, displayNameElement, request;
renderContainerPage(this, mockContainerXBlockHtml); renderContainerPage(this, mockContainerXBlockHtml);
displayNameElement = containerPage.$('.page-header-title'); displayNameElement = containerPage.$('.page-header-title');
...@@ -145,7 +152,8 @@ define(["jquery", "underscore", "underscore.string", "common/js/spec_helpers/aja ...@@ -145,7 +152,8 @@ define(["jquery", "underscore", "underscore.string", "common/js/spec_helpers/aja
editButtons.first().click(); editButtons.first().click();
// Expect a request to be made to show the studio view for the container // Expect a request to be made to show the studio view for the container
expect(str.startsWith(lastRequest().url, '/xblock/locator-container/studio_view')).toBeTruthy(); request = AjaxHelpers.currentRequest(requests);
expect(str.startsWith(request.url, '/xblock/locator-container/studio_view')).toBeTruthy();
AjaxHelpers.respondWithJson(requests, { AjaxHelpers.respondWithJson(requests, {
html: mockContainerXBlockHtml, html: mockContainerXBlockHtml,
resources: [] resources: []
...@@ -161,12 +169,7 @@ define(["jquery", "underscore", "underscore.string", "common/js/spec_helpers/aja ...@@ -161,12 +169,7 @@ define(["jquery", "underscore", "underscore.string", "common/js/spec_helpers/aja
expect(EditHelpers.isShowingModal()).toBeFalsy(); expect(EditHelpers.isShowingModal()).toBeFalsy();
// Expect the last request be to refresh the container page // Expect the last request be to refresh the container page
expect(str.startsWith(lastRequest().url, handleContainerPageRefresh(requests);
'/xblock/locator-container/container_preview')).toBeTruthy();
AjaxHelpers.respondWithJson(requests, {
html: mockUpdatedContainerXBlockHtml,
resources: []
});
// Respond to the subsequent xblock info fetch request. // Respond to the subsequent xblock info fetch request.
AjaxHelpers.respondWithJson(requests, {"display_name": updatedDisplayName}); AjaxHelpers.respondWithJson(requests, {"display_name": updatedDisplayName});
...@@ -196,14 +199,15 @@ define(["jquery", "underscore", "underscore.string", "common/js/spec_helpers/aja ...@@ -196,14 +199,15 @@ define(["jquery", "underscore", "underscore.string", "common/js/spec_helpers/aja
}); });
it('can show an edit modal for a child xblock', function () { it('can show an edit modal for a child xblock', function () {
var editButtons; var editButtons, request;
renderContainerPage(this, mockContainerXBlockHtml); renderContainerPage(this, mockContainerXBlockHtml);
editButtons = containerPage.$('.wrapper-xblock .edit-button'); editButtons = containerPage.$('.wrapper-xblock .edit-button');
// The container should have rendered six mock xblocks // The container should have rendered six mock xblocks
expect(editButtons.length).toBe(6); expect(editButtons.length).toBe(6);
editButtons[0].click(); editButtons[0].click();
// Make sure that the correct xblock is requested to be edited // Make sure that the correct xblock is requested to be edited
expect(str.startsWith(lastRequest().url, '/xblock/locator-component-A1/studio_view')).toBeTruthy(); request = AjaxHelpers.currentRequest(requests);
expect(str.startsWith(request.url, '/xblock/locator-component-A1/studio_view')).toBeTruthy();
AjaxHelpers.respondWithJson(requests, { AjaxHelpers.respondWithJson(requests, {
html: mockXBlockEditorHtml, html: mockXBlockEditorHtml,
resources: [] resources: []
...@@ -224,13 +228,14 @@ define(["jquery", "underscore", "underscore.string", "common/js/spec_helpers/aja ...@@ -224,13 +228,14 @@ define(["jquery", "underscore", "underscore.string", "common/js/spec_helpers/aja
}); });
it('can show a visibility modal for a child xblock if supported for the page', function() { it('can show a visibility modal for a child xblock if supported for the page', function() {
var visibilityButtons; var visibilityButtons, request;
renderContainerPage(this, mockContainerXBlockHtml); renderContainerPage(this, mockContainerXBlockHtml);
visibilityButtons = containerPage.$('.wrapper-xblock .visibility-button'); visibilityButtons = containerPage.$('.wrapper-xblock .visibility-button');
if (hasVisibilityEditor) { if (hasVisibilityEditor) {
expect(visibilityButtons.length).toBe(6); expect(visibilityButtons.length).toBe(6);
visibilityButtons[0].click(); visibilityButtons[0].click();
expect(str.startsWith(lastRequest().url, '/xblock/locator-component-A1/visibility_view')) request = AjaxHelpers.currentRequest(requests);
expect(str.startsWith(request.url, '/xblock/locator-component-A1/visibility_view'))
.toBeTruthy(); .toBeTruthy();
AjaxHelpers.respondWithJson(requests, { AjaxHelpers.respondWithJson(requests, {
html: mockXBlockVisibilityEditorHtml, html: mockXBlockVisibilityEditorHtml,
...@@ -297,7 +302,7 @@ define(["jquery", "underscore", "underscore.string", "common/js/spec_helpers/aja ...@@ -297,7 +302,7 @@ define(["jquery", "underscore", "underscore.string", "common/js/spec_helpers/aja
}); });
describe("xblock operations", function () { describe("xblock operations", function () {
var getGroupElement, paginated, getDeleteOffset, var getGroupElement,
NUM_COMPONENTS_PER_GROUP = 3, GROUP_TO_TEST = "A", NUM_COMPONENTS_PER_GROUP = 3, GROUP_TO_TEST = "A",
allComponentsInGroup = _.map( allComponentsInGroup = _.map(
_.range(NUM_COMPONENTS_PER_GROUP), _.range(NUM_COMPONENTS_PER_GROUP),
...@@ -306,11 +311,6 @@ define(["jquery", "underscore", "underscore.string", "common/js/spec_helpers/aja ...@@ -306,11 +311,6 @@ define(["jquery", "underscore", "underscore.string", "common/js/spec_helpers/aja
} }
); );
getDeleteOffset = function () {
// Paginated containers will make an additional AJAX request.
return pagedSpecificTests ? 3 : 2;
};
getGroupElement = function () { getGroupElement = function () {
return containerPage.$("[data-locator='locator-group-" + GROUP_TO_TEST + "']"); return containerPage.$("[data-locator='locator-group-" + GROUP_TO_TEST + "']");
}; };
...@@ -337,28 +337,35 @@ define(["jquery", "underscore", "underscore.string", "common/js/spec_helpers/aja ...@@ -337,28 +337,35 @@ define(["jquery", "underscore", "underscore.string", "common/js/spec_helpers/aja
EditHelpers.confirmPrompt(promptSpy, clickNo); EditHelpers.confirmPrompt(promptSpy, clickNo);
}; };
deleteComponent = function (componentIndex, requestOffset) { deleteComponent = function (componentIndex) {
clickDelete(componentIndex); clickDelete(componentIndex);
AjaxHelpers.respondWithJson(requests, {});
// first request to delete the component
AjaxHelpers.expectJsonRequest(requests, 'DELETE', AjaxHelpers.expectJsonRequest(requests, 'DELETE',
'/xblock/locator-component-' + GROUP_TO_TEST + (componentIndex + 1), '/xblock/locator-component-' + GROUP_TO_TEST + (componentIndex + 1),
null, requests.length - requestOffset); null);
AjaxHelpers.respondWithNoContent(requests);
// then handle the request to refresh the preview
if (globalPageOptions.requiresPageRefresh) {
handleContainerPageRefresh(requests);
}
// final request to refresh the xblock info // final request to refresh the xblock info
AjaxHelpers.expectJsonRequest(requests, 'GET', '/xblock/locator-container'); AjaxHelpers.expectJsonRequest(requests, 'GET', '/xblock/locator-container');
AjaxHelpers.respondWithJson(requests, {});
}; };
deleteComponentWithSuccess = function (componentIndex) { deleteComponentWithSuccess = function (componentIndex) {
var deleteOffset; deleteComponent(componentIndex);
deleteOffset = getDeleteOffset(); // verify the new list of components within the group (unless reloading)
deleteComponent(componentIndex, deleteOffset); if (!globalPageOptions.requiresPageRefresh) {
expectComponents(
// verify the new list of components within the group getGroupElement(),
expectComponents( _.without(allComponentsInGroup, allComponentsInGroup[componentIndex])
getGroupElement(), );
_.without(allComponentsInGroup, allComponentsInGroup[componentIndex]) }
);
}; };
it("can delete the first xblock", function () { it("can delete the first xblock", function () {
...@@ -377,24 +384,25 @@ define(["jquery", "underscore", "underscore.string", "common/js/spec_helpers/aja ...@@ -377,24 +384,25 @@ define(["jquery", "underscore", "underscore.string", "common/js/spec_helpers/aja
}); });
it("can delete an xblock with broken JavaScript", function () { it("can delete an xblock with broken JavaScript", function () {
var deleteOffset = getDeleteOffset();
renderContainerPage(this, mockBadContainerXBlockHtml); renderContainerPage(this, mockBadContainerXBlockHtml);
containerPage.$('.delete-button').first().click(); containerPage.$('.delete-button').first().click();
EditHelpers.confirmPrompt(promptSpy); EditHelpers.confirmPrompt(promptSpy);
AjaxHelpers.respondWithJson(requests, {});
// expect the second to last request to be a delete of the xblock // expect the second to last request to be a delete of the xblock
AjaxHelpers.expectJsonRequest(requests, 'DELETE', '/xblock/locator-broken-javascript', AjaxHelpers.expectJsonRequest(requests, 'DELETE', '/xblock/locator-broken-javascript');
null, requests.length - deleteOffset); AjaxHelpers.respondWithNoContent(requests);
// handle the refresh request for pages that require a full refresh on delete
if (globalPageOptions.requiresPageRefresh) {
handleContainerPageRefresh(requests);
}
// expect the last request to be a fetch of the xblock info for the parent container // expect the last request to be a fetch of the xblock info for the parent container
AjaxHelpers.expectJsonRequest(requests, 'GET', '/xblock/locator-container'); AjaxHelpers.expectJsonRequest(requests, 'GET', '/xblock/locator-container');
}); });
it('does not delete when clicking No in prompt', function () { it('does not delete when clicking No in prompt', function () {
var numRequests;
renderContainerPage(this, mockContainerXBlockHtml); renderContainerPage(this, mockContainerXBlockHtml);
numRequests = requests.length;
// click delete on the first component but press no // click delete on the first component but press no
clickDelete(0, true); clickDelete(0, true);
...@@ -403,7 +411,7 @@ define(["jquery", "underscore", "underscore.string", "common/js/spec_helpers/aja ...@@ -403,7 +411,7 @@ define(["jquery", "underscore", "underscore.string", "common/js/spec_helpers/aja
expectComponents(getGroupElement(), allComponentsInGroup); expectComponents(getGroupElement(), allComponentsInGroup);
// no requests should have been sent to the server // no requests should have been sent to the server
expect(requests.length).toBe(numRequests); AjaxHelpers.expectNoRequests(requests);
}); });
it('shows a notification during the delete operation', function () { it('shows a notification during the delete operation', function () {
...@@ -526,13 +534,13 @@ define(["jquery", "underscore", "underscore.string", "common/js/spec_helpers/aja ...@@ -526,13 +534,13 @@ define(["jquery", "underscore", "underscore.string", "common/js/spec_helpers/aja
expect(getButtonText(containerPage)).toBe(""); expect(getButtonText(containerPage)).toBe("");
}); });
function updatePreviewButtonTest(show_previews, expected_text) { var updatePreviewButtonTest = function(show_previews, expected_text) {
it('can set preview button to "' + expected_text + '"', function () { it('can set preview button to "' + expected_text + '"', function () {
containerPage = getContainerPage(); containerPage = getContainerPage();
containerPage.updatePreviewButton(show_previews); containerPage.updatePreviewButton(show_previews);
expect(getButtonText(containerPage)).toBe(expected_text); expect(getButtonText(containerPage)).toBe(expected_text);
}); });
} };
updatePreviewButtonTest(true, 'Hide Previews'); updatePreviewButtonTest(true, 'Hide Previews');
updatePreviewButtonTest(false, 'Show Previews'); updatePreviewButtonTest(false, 'Show Previews');
...@@ -603,13 +611,11 @@ define(["jquery", "underscore", "underscore.string", "common/js/spec_helpers/aja ...@@ -603,13 +611,11 @@ define(["jquery", "underscore", "underscore.string", "common/js/spec_helpers/aja
}); });
it('does not insert component upon failure', function () { it('does not insert component upon failure', function () {
var requestCount;
renderContainerPage(this, mockContainerXBlockHtml); renderContainerPage(this, mockContainerXBlockHtml);
clickNewComponent(0); clickNewComponent(0);
requestCount = requests.length;
AjaxHelpers.respondWithError(requests); AjaxHelpers.respondWithError(requests);
// No new requests should be made to refresh the view // No new requests should be made to refresh the view
expect(requests.length).toBe(requestCount); AjaxHelpers.expectNoRequests(requests);
expectComponents(getGroupElement(), allComponentsInGroup); expectComponents(getGroupElement(), allComponentsInGroup);
}); });
...@@ -649,31 +655,31 @@ define(["jquery", "underscore", "underscore.string", "common/js/spec_helpers/aja ...@@ -649,31 +655,31 @@ define(["jquery", "underscore", "underscore.string", "common/js/spec_helpers/aja
}); });
}); });
}); });
}); });
} }
// Create a suite for a non-paged container that includes 'edit visibility' buttons // Create a suite for a non-paged container that includes 'edit visibility' buttons
parameterized_suite("Non paged", parameterized_suite("Non paged",
{ },
{ {
page: ContainerPage, page: ContainerPage,
requiresPageRefresh: false,
initial: 'mock/mock-container-xblock.underscore', initial: 'mock/mock-container-xblock.underscore',
add_response: 'mock/mock-xblock.underscore', addResponse: 'mock/mock-xblock.underscore',
has_visibility_editor: true, hasVisibilityEditor: true,
paged_specific_tests: false pagedSpecificTests: false
} }
); );
// Create a suite for a paged container that does not include 'edit visibility' buttons // Create a suite for a paged container that does not include 'edit visibility' buttons
parameterized_suite("Paged", parameterized_suite("Paged",
{ page_size: 42 },
{ {
page: PagedContainerPage, page: PagedContainerPage,
page_size: 42,
requiresPageRefresh: true,
initial: 'mock/mock-container-paged-xblock.underscore', initial: 'mock/mock-container-paged-xblock.underscore',
add_response: 'mock/mock-xblock-paged.underscore', addResponse: 'mock/mock-xblock-paged.underscore',
has_visibility_editor: false, hasVisibilityEditor: false,
paged_specific_tests: true pagedSpecificTests: true
} }
); );
}); });
...@@ -8,7 +8,7 @@ define(["jquery", "underscore", "underscore.string", "common/js/spec_helpers/aja ...@@ -8,7 +8,7 @@ define(["jquery", "underscore", "underscore.string", "common/js/spec_helpers/aja
describe("Container Subviews", function() { describe("Container Subviews", function() {
var model, containerPage, requests, createContainerPage, renderContainerPage, var model, containerPage, requests, createContainerPage, renderContainerPage,
respondWithHtml, respondWithJson, fetch, respondWithHtml, fetch,
disabledCss = "is-disabled", defaultXBlockInfo, createXBlockInfo, disabledCss = "is-disabled", defaultXBlockInfo, createXBlockInfo,
mockContainerPage = readFixtures('mock/mock-container-page.underscore'), mockContainerPage = readFixtures('mock/mock-container-page.underscore'),
mockContainerXBlockHtml = readFixtures('mock/mock-empty-container-xblock.underscore'); mockContainerXBlockHtml = readFixtures('mock/mock-empty-container-xblock.underscore');
...@@ -52,30 +52,23 @@ define(["jquery", "underscore", "underscore.string", "common/js/spec_helpers/aja ...@@ -52,30 +52,23 @@ define(["jquery", "underscore", "underscore.string", "common/js/spec_helpers/aja
renderContainerPage = function (test, html, options) { renderContainerPage = function (test, html, options) {
createContainerPage(test, options); createContainerPage(test, options);
containerPage.render(); containerPage.render();
respondWithHtml(html); respondWithHtml(html, options);
}; };
respondWithHtml = function(html) { respondWithHtml = function(html, options) {
var requestIndex = requests.length - 1;
AjaxHelpers.respondWithJson( AjaxHelpers.respondWithJson(
requests, requests,
{ html: html, "resources": [] }, { html: html, "resources": [] }
requestIndex
);
};
respondWithJson = function(json, requestIndex) {
AjaxHelpers.respondWithJson(
requests,
json,
requestIndex
); );
AjaxHelpers.expectJsonRequest(requests, 'GET', '/xblock/locator-container');
AjaxHelpers.respondWithJson(requests, createXBlockInfo(options));
}; };
fetch = function (json) { fetch = function (json) {
json = createXBlockInfo(json); json = createXBlockInfo(json);
model.fetch(); model.fetch();
respondWithJson(json); AjaxHelpers.expectJsonRequest(requests, 'GET', '/xblock/locator-container');
AjaxHelpers.respondWithJson(requests, json);
}; };
describe("ViewLiveButtonController", function () { describe("ViewLiveButtonController", function () {
...@@ -236,14 +229,17 @@ define(["jquery", "underscore", "underscore.string", "common/js/spec_helpers/aja ...@@ -236,14 +229,17 @@ define(["jquery", "underscore", "underscore.string", "common/js/spec_helpers/aja
); );
// Response to publish call // Response to publish call
respondWithJson({"id": "locator-container", "data": null, "metadata":{}}); AjaxHelpers.respondWithJson(requests, {"id": "locator-container", "data": null, "metadata":{}});
EditHelpers.verifyNotificationHidden(notificationSpy); EditHelpers.verifyNotificationHidden(notificationSpy);
AjaxHelpers.expectJsonRequest(requests, "GET", "/xblock/locator-container"); AjaxHelpers.expectJsonRequest(requests, "GET", "/xblock/locator-container");
// Response to fetch // Response to fetch
respondWithJson(createXBlockInfo({ AjaxHelpers.respondWithJson(
published: true, has_changes: false, visibility_state: VisibilityState.ready requests,
})); createXBlockInfo({
published: true, has_changes: false, visibility_state: VisibilityState.ready
})
);
// Verify updates displayed // Verify updates displayed
expect(containerPage.$(bitPublishingCss)).toHaveClass(readyClass); expect(containerPage.$(bitPublishingCss)).toHaveClass(readyClass);
...@@ -258,11 +254,9 @@ define(["jquery", "underscore", "underscore.string", "common/js/spec_helpers/aja ...@@ -258,11 +254,9 @@ define(["jquery", "underscore", "underscore.string", "common/js/spec_helpers/aja
// Click publish // Click publish
containerPage.$(publishButtonCss).click(); containerPage.$(publishButtonCss).click();
var numRequests = requests.length;
// Respond with failure // Respond with failure
AjaxHelpers.respondWithError(requests); AjaxHelpers.respondWithError(requests);
AjaxHelpers.expectNoRequests(requests);
expect(requests.length).toEqual(numRequests);
// Verify still in draft (unscheduled) state. // Verify still in draft (unscheduled) state.
verifyPublishingBitUnscheduled(); verifyPublishingBitUnscheduled();
...@@ -280,7 +274,7 @@ define(["jquery", "underscore", "underscore.string", "common/js/spec_helpers/aja ...@@ -280,7 +274,7 @@ define(["jquery", "underscore", "underscore.string", "common/js/spec_helpers/aja
numRequests = requests.length; numRequests = requests.length;
// Respond with success. // Respond with success.
respondWithJson({"id": "locator-container"}); AjaxHelpers.respondWithJson(requests, {"id": "locator-container"});
EditHelpers.verifyNotificationHidden(notificationSpy); EditHelpers.verifyNotificationHidden(notificationSpy);
// Verify other requests are sent to the server to update page state. // Verify other requests are sent to the server to update page state.
...@@ -296,12 +290,10 @@ define(["jquery", "underscore", "underscore.string", "common/js/spec_helpers/aja ...@@ -296,12 +290,10 @@ define(["jquery", "underscore", "underscore.string", "common/js/spec_helpers/aja
renderPageSpy = spyOn(containerPage.xblockPublisher, 'renderPage').andCallThrough(); renderPageSpy = spyOn(containerPage.xblockPublisher, 'renderPage').andCallThrough();
sendDiscardChangesToServer(); sendDiscardChangesToServer();
numRequests = requests.length;
// Respond with failure // Respond with failure
AjaxHelpers.respondWithError(requests); AjaxHelpers.respondWithError(requests);
AjaxHelpers.expectNoRequests(requests);
expect(requests.length).toEqual(numRequests);
expect(containerPage.$(discardChangesButtonCss)).not.toHaveClass('is-disabled'); expect(containerPage.$(discardChangesButtonCss)).not.toHaveClass('is-disabled');
expect(containerPage.model.get("publish")).toBeNull(); expect(containerPage.model.get("publish")).toBeNull();
expect(renderPageSpy).not.toHaveBeenCalled(); expect(renderPageSpy).not.toHaveBeenCalled();
...@@ -310,7 +302,6 @@ define(["jquery", "underscore", "underscore.string", "common/js/spec_helpers/aja ...@@ -310,7 +302,6 @@ define(["jquery", "underscore", "underscore.string", "common/js/spec_helpers/aja
it('does not discard changes on cancel', function () { it('does not discard changes on cancel', function () {
renderContainerPage(this, mockContainerXBlockHtml); renderContainerPage(this, mockContainerXBlockHtml);
fetch({published: true, has_changes: true, visibility_state: VisibilityState.needsAttention}); fetch({published: true, has_changes: true, visibility_state: VisibilityState.needsAttention});
var numRequests = requests.length;
// Click discard changes // Click discard changes
expect(containerPage.$(discardChangesButtonCss)).not.toHaveClass('is-disabled'); expect(containerPage.$(discardChangesButtonCss)).not.toHaveClass('is-disabled');
...@@ -319,8 +310,7 @@ define(["jquery", "underscore", "underscore.string", "common/js/spec_helpers/aja ...@@ -319,8 +310,7 @@ define(["jquery", "underscore", "underscore.string", "common/js/spec_helpers/aja
// Click cancel to confirmation. // Click cancel to confirmation.
expect(promptSpies.constructor).toHaveBeenCalled(); expect(promptSpies.constructor).toHaveBeenCalled();
promptSpies.constructor.mostRecentCall.args[0].actions.secondary.click(promptSpies); promptSpies.constructor.mostRecentCall.args[0].actions.secondary.click(promptSpies);
AjaxHelpers.expectNoRequests(requests);
expect(requests.length).toEqual(numRequests);
expect(containerPage.$(discardChangesButtonCss)).not.toHaveClass('is-disabled'); expect(containerPage.$(discardChangesButtonCss)).not.toHaveClass('is-disabled');
}); });
...@@ -534,28 +524,24 @@ define(["jquery", "underscore", "underscore.string", "common/js/spec_helpers/aja ...@@ -534,28 +524,24 @@ define(["jquery", "underscore", "underscore.string", "common/js/spec_helpers/aja
}); });
it("does not refresh if removing staff only is canceled", function() { it("does not refresh if removing staff only is canceled", function() {
var requestCount;
promptSpy = EditHelpers.createPromptSpy(); promptSpy = EditHelpers.createPromptSpy();
renderContainerPage(this, mockContainerXBlockHtml, { renderContainerPage(this, mockContainerXBlockHtml, {
visibility_state: VisibilityState.staffOnly, visibility_state: VisibilityState.staffOnly,
has_explicit_staff_lock: true, has_explicit_staff_lock: true,
ancestor_has_staff_lock: false ancestor_has_staff_lock: false
}); });
requestCount = requests.length;
containerPage.$('.action-staff-lock').click(); containerPage.$('.action-staff-lock').click();
EditHelpers.confirmPrompt(promptSpy, true); // Click 'No' to cancel EditHelpers.confirmPrompt(promptSpy, true); // Click 'No' to cancel
expect(requests.length).toBe(requestCount); AjaxHelpers.expectNoRequests(requests);
verifyExplicitStaffOnly(true); verifyExplicitStaffOnly(true);
verifyStaffOnly(true); verifyStaffOnly(true);
}); });
it("does not refresh when failing to set staff only", function() { it("does not refresh when failing to set staff only", function() {
var requestCount;
renderContainerPage(this, mockContainerXBlockHtml); renderContainerPage(this, mockContainerXBlockHtml);
containerPage.$('.lock-checkbox').click(); containerPage.$('.action-staff-lock').click();
requestCount = requests.length;
AjaxHelpers.respondWithError(requests); AjaxHelpers.respondWithError(requests);
expect(requests.length).toBe(requestCount); AjaxHelpers.expectNoRequests(requests);
verifyStaffOnly(false); verifyStaffOnly(false);
}); });
}); });
......
...@@ -401,9 +401,8 @@ define(["jquery", "common/js/spec_helpers/ajax_helpers", "common/js/components/u ...@@ -401,9 +401,8 @@ define(["jquery", "common/js/spec_helpers/ajax_helpers", "common/js/components/u
'display_name': 'Section', 'display_name': 'Section',
'parent_locator': 'mock-course' 'parent_locator': 'mock-course'
}); });
requestCount = requests.length;
AjaxHelpers.respondWithError(requests); AjaxHelpers.respondWithError(requests);
expect(requests.length).toBe(requestCount); // No additional requests should be made AjaxHelpers.expectNoRequests(requests);
expect(outlinePage.$('.no-content')).not.toHaveClass('is-hidden'); expect(outlinePage.$('.no-content')).not.toHaveClass('is-hidden');
expect(outlinePage.$('.no-content .button-new')).toExist(); expect(outlinePage.$('.no-content .button-new')).toExist();
}); });
...@@ -424,10 +423,9 @@ define(["jquery", "common/js/spec_helpers/ajax_helpers", "common/js/components/u ...@@ -424,10 +423,9 @@ define(["jquery", "common/js/spec_helpers/ajax_helpers", "common/js/components/u
])); ]));
getItemHeaders('section').find('.delete-button').first().click(); getItemHeaders('section').find('.delete-button').first().click();
EditHelpers.confirmPrompt(promptSpy); EditHelpers.confirmPrompt(promptSpy);
requestCount = requests.length;
AjaxHelpers.expectJsonRequest(requests, 'DELETE', '/xblock/mock-section'); AjaxHelpers.expectJsonRequest(requests, 'DELETE', '/xblock/mock-section');
AjaxHelpers.respondWithJson(requests, {}); AjaxHelpers.respondWithJson(requests, {});
expect(requests.length).toBe(requestCount); // No fetch should be performed AjaxHelpers.expectNoRequests(requests); // No fetch should be performed
expect(outlinePage.$('[data-locator="mock-section"]')).not.toExist(); expect(outlinePage.$('[data-locator="mock-section"]')).not.toExist();
expect(outlinePage.$('[data-locator="mock-section-2"]')).toExist(); expect(outlinePage.$('[data-locator="mock-section-2"]')).toExist();
}); });
...@@ -452,9 +450,8 @@ define(["jquery", "common/js/spec_helpers/ajax_helpers", "common/js/components/u ...@@ -452,9 +450,8 @@ define(["jquery", "common/js/spec_helpers/ajax_helpers", "common/js/components/u
getItemHeaders('section').find('.delete-button').click(); getItemHeaders('section').find('.delete-button').click();
EditHelpers.confirmPrompt(promptSpy); EditHelpers.confirmPrompt(promptSpy);
AjaxHelpers.expectJsonRequest(requests, 'DELETE', '/xblock/mock-section'); AjaxHelpers.expectJsonRequest(requests, 'DELETE', '/xblock/mock-section');
requestCount = requests.length;
AjaxHelpers.respondWithError(requests); AjaxHelpers.respondWithError(requests);
expect(requests.length).toBe(requestCount); // No additional requests should be made AjaxHelpers.expectNoRequests(requests);
expect(outlinePage.$('.list-sections li.outline-section').data('locator')).toEqual('mock-section'); expect(outlinePage.$('.list-sections li.outline-section').data('locator')).toEqual('mock-section');
}); });
...@@ -534,10 +531,8 @@ define(["jquery", "common/js/spec_helpers/ajax_helpers", "common/js/components/u ...@@ -534,10 +531,8 @@ define(["jquery", "common/js/spec_helpers/ajax_helpers", "common/js/components/u
]) ])
]); ]);
AjaxHelpers.expectJsonRequest(requests, 'GET', '/xblock/outline/mock-section'); AjaxHelpers.expectJsonRequest(requests, 'GET', '/xblock/outline/mock-section');
expect(requests.length).toBe(2);
// This is the response for the subsequent fetch operation for the section.
AjaxHelpers.respondWithJson(requests, mockResponseSectionJSON); AjaxHelpers.respondWithJson(requests, mockResponseSectionJSON);
AjaxHelpers.expectNoRequests(requests);
expect($(".outline-section .status-release-value")).toContainText("Jan 02, 2015 at 00:00 UTC"); expect($(".outline-section .status-release-value")).toContainText("Jan 02, 2015 at 00:00 UTC");
}); });
...@@ -713,13 +708,11 @@ define(["jquery", "common/js/spec_helpers/ajax_helpers", "common/js/components/u ...@@ -713,13 +708,11 @@ define(["jquery", "common/js/spec_helpers/ajax_helpers", "common/js/components/u
} }
}); });
expect(requests[0].requestHeaders['X-HTTP-Method-Override']).toBe('PATCH'); expect(requests[0].requestHeaders['X-HTTP-Method-Override']).toBe('PATCH');
// This is the response for the change operation.
AjaxHelpers.respondWithJson(requests, {}); AjaxHelpers.respondWithJson(requests, {});
AjaxHelpers.expectJsonRequest(requests, 'GET', '/xblock/outline/mock-section'); AjaxHelpers.expectJsonRequest(requests, 'GET', '/xblock/outline/mock-section');
expect(requests.length).toBe(2);
// This is the response for the subsequent fetch operation for the section.
AjaxHelpers.respondWithJson(requests, mockServerValuesJson); AjaxHelpers.respondWithJson(requests, mockServerValuesJson);
AjaxHelpers.expectNoRequests(requests);
expect($(".outline-subsection .status-release-value")).toContainText( expect($(".outline-subsection .status-release-value")).toContainText(
"Jul 09, 2014 at 00:00 UTC" "Jul 09, 2014 at 00:00 UTC"
......
...@@ -193,7 +193,7 @@ define(["jquery", "common/js/spec_helpers/ajax_helpers", "common/js/spec_helpers ...@@ -193,7 +193,7 @@ define(["jquery", "common/js/spec_helpers/ajax_helpers", "common/js/spec_helpers
var requests = AjaxHelpers.requests(this); var requests = AjaxHelpers.requests(this);
fillInFields('DemoX', 'DM101', '', 'Demo course'); fillInFields('DemoX', 'DM101', '', 'Demo course');
$(selectors.save).click(); $(selectors.save).click();
expect(requests.length).toBe(0); AjaxHelpers.expectNoRequests(requests);
}); });
it("can be canceled", function () { it("can be canceled", function () {
......
...@@ -88,7 +88,6 @@ define(["jquery", "common/js/spec_helpers/ajax_helpers", "common/js/spec_helpers ...@@ -88,7 +88,6 @@ define(["jquery", "common/js/spec_helpers/ajax_helpers", "common/js/spec_helpers
it("displays an error when a required field is blank", function () { it("displays an error when a required field is blank", function () {
var requests = AjaxHelpers.requests(this); var requests = AjaxHelpers.requests(this);
var requests_count = requests.length;
$('.new-library-button').click(); $('.new-library-button').click();
var values = ['DemoX', 'DM101', 'Demo library']; var values = ['DemoX', 'DM101', 'Demo library'];
// Try making each of these three values empty one at a time and ensure the form won't submit: // Try making each of these three values empty one at a time and ensure the form won't submit:
...@@ -100,7 +99,7 @@ define(["jquery", "common/js/spec_helpers/ajax_helpers", "common/js/spec_helpers ...@@ -100,7 +99,7 @@ define(["jquery", "common/js/spec_helpers/ajax_helpers", "common/js/spec_helpers
expect($('.new-library-save')).toHaveClass('is-disabled'); expect($('.new-library-save')).toHaveClass('is-disabled');
expect($('.new-library-save')).toHaveAttr('aria-disabled', 'true'); expect($('.new-library-save')).toHaveAttr('aria-disabled', 'true');
$('.new-library-save').click(); $('.new-library-save').click();
expect(requests.length).toEqual(requests_count); // Expect no new requests AjaxHelpers.expectNoRequests(requests);
} }
}); });
......
...@@ -84,7 +84,7 @@ function ($, AjaxHelpers, ViewHelpers, ManageUsersFactory, ViewUtils) { ...@@ -84,7 +84,7 @@ function ($, AjaxHelpers, ViewHelpers, ManageUsersFactory, ViewUtils) {
$('.form-create.create-user .action-primary').click(); $('.form-create.create-user .action-primary').click();
expect($(errorPromptSelector).length).toEqual(1); expect($(errorPromptSelector).length).toEqual(1);
expect($(errorPromptSelector)).toContainText('You must enter a valid email address'); expect($(errorPromptSelector)).toContainText('You must enter a valid email address');
expect(requests.length).toEqual(0); AjaxHelpers.expectNoRequests(requests);
}); });
it("displays an error when the user has already been added", function () { it("displays an error when the user has already been added", function () {
...@@ -94,7 +94,7 @@ function ($, AjaxHelpers, ViewHelpers, ManageUsersFactory, ViewUtils) { ...@@ -94,7 +94,7 @@ function ($, AjaxHelpers, ViewHelpers, ManageUsersFactory, ViewUtils) {
$('.user-email-input').val('honor@example.com'); $('.user-email-input').val('honor@example.com');
$('.form-create.create-user .action-primary').click(); $('.form-create.create-user .action-primary').click();
ViewHelpers.verifyPromptShowing(promptSpy, 'Already a library team member'); ViewHelpers.verifyPromptShowing(promptSpy, 'Already a library team member');
expect(requests.length).toEqual(0); AjaxHelpers.expectNoRequests(requests);
}); });
......
...@@ -51,13 +51,12 @@ define([ ...@@ -51,13 +51,12 @@ define([
}; };
var respondWithMockItems = function(requests) { var respondWithMockItems = function(requests) {
var requestIndex = requests.length - 1; var request = AjaxHelpers.currentRequest(requests);
var request = requests[requestIndex];
var url = new URI(request.url); var url = new URI(request.url);
var queryParameters = url.query(true); // Returns an object with each query parameter stored as a value var queryParameters = url.query(true); // Returns an object with each query parameter stored as a value
var page = queryParameters.page; var page = queryParameters.page;
var response = page === "0" ? mockFirstPage : mockSecondPage; var response = page === "0" ? mockFirstPage : mockSecondPage;
AjaxHelpers.respondWithJson(requests, response, requestIndex); AjaxHelpers.respondWithJson(requests, response);
}; };
var MockPagingView = PagingView.extend({ var MockPagingView = PagingView.extend({
...@@ -124,7 +123,7 @@ define([ ...@@ -124,7 +123,7 @@ define([
pagingView.setPage(2); pagingView.setPage(2);
respondWithMockItems(requests); respondWithMockItems(requests);
pagingView.nextPage(); pagingView.nextPage();
expect(requests.length).toBe(1); AjaxHelpers.expectNoRequests(requests);
}); });
}); });
...@@ -144,7 +143,7 @@ define([ ...@@ -144,7 +143,7 @@ define([
pagingView.setPage(1); pagingView.setPage(1);
respondWithMockItems(requests); respondWithMockItems(requests);
pagingView.previousPage(); pagingView.previousPage();
expect(requests.length).toBe(1); AjaxHelpers.expectNoRequests(requests);
}); });
it('does not move back after a server error', function () { it('does not move back after a server error', function () {
......
...@@ -86,7 +86,7 @@ define([ "jquery", "underscore", "common/js/spec_helpers/ajax_helpers", "js/spec ...@@ -86,7 +86,7 @@ define([ "jquery", "underscore", "common/js/spec_helpers/ajax_helpers", "js/spec
// Give the mock xblock a save method... // Give the mock xblock a save method...
editor.xblock.save = window.MockDescriptor.save; editor.xblock.save = window.MockDescriptor.save;
editor.model.save(editor.getXBlockFieldData()); editor.model.save(editor.getXBlockFieldData());
request = requests[requests.length - 1]; request = AjaxHelpers.currentRequest(requests);
response = JSON.parse(request.requestBody); response = JSON.parse(request.requestBody);
expect(response.metadata.display_name).toBe(testDisplayName); expect(response.metadata.display_name).toBe(testDisplayName);
expect(response.metadata.custom_field).toBe('Custom Value'); expect(response.metadata.custom_field).toBe('Custom Value');
......
...@@ -3,7 +3,7 @@ define([ "jquery", "common/js/spec_helpers/ajax_helpers", "URI", "js/views/xbloc ...@@ -3,7 +3,7 @@ define([ "jquery", "common/js/spec_helpers/ajax_helpers", "URI", "js/views/xbloc
function ($, AjaxHelpers, URI, XBlockView, XBlockInfo) { function ($, AjaxHelpers, URI, XBlockView, XBlockInfo) {
describe("XBlockView", function() { describe("XBlockView", function() {
var model, xblockView, mockXBlockHtml, respondWithMockXBlockFragment; var model, xblockView, mockXBlockHtml;
beforeEach(function () { beforeEach(function () {
model = new XBlockInfo({ model = new XBlockInfo({
...@@ -18,15 +18,10 @@ define([ "jquery", "common/js/spec_helpers/ajax_helpers", "URI", "js/views/xbloc ...@@ -18,15 +18,10 @@ define([ "jquery", "common/js/spec_helpers/ajax_helpers", "URI", "js/views/xbloc
mockXBlockHtml = readFixtures('mock/mock-xblock.underscore'); mockXBlockHtml = readFixtures('mock/mock-xblock.underscore');
respondWithMockXBlockFragment = function(requests, response) {
var requestIndex = requests.length - 1;
AjaxHelpers.respondWithJson(requests, response, requestIndex);
};
it('can render a nested xblock', function() { it('can render a nested xblock', function() {
var requests = AjaxHelpers.requests(this); var requests = AjaxHelpers.requests(this);
xblockView.render(); xblockView.render();
respondWithMockXBlockFragment(requests, { AjaxHelpers.respondWithJson(requests, {
html: mockXBlockHtml, html: mockXBlockHtml,
resources: [] resources: []
}); });
...@@ -48,7 +43,7 @@ define([ "jquery", "common/js/spec_helpers/ajax_helpers", "URI", "js/views/xbloc ...@@ -48,7 +43,7 @@ define([ "jquery", "common/js/spec_helpers/ajax_helpers", "URI", "js/views/xbloc
}); });
// Note: this mock response will call the AJAX success function synchronously // Note: this mock response will call the AJAX success function synchronously
// so the promise variable defined above will be available. // so the promise variable defined above will be available.
respondWithMockXBlockFragment(requests, { AjaxHelpers.respondWithJson(requests, {
html: mockXBlockHtml, html: mockXBlockHtml,
resources: resources resources: resources
}); });
......
...@@ -52,7 +52,6 @@ define(["jquery", "common/js/spec_helpers/ajax_helpers", "common/js/spec_helpers ...@@ -52,7 +52,6 @@ define(["jquery", "common/js/spec_helpers/ajax_helpers", "common/js/spec_helpers
expectEditCanceled = function (test, fieldEditorView, options) { expectEditCanceled = function (test, fieldEditorView, options) {
var requests, initialRequests, displayNameInput; var requests, initialRequests, displayNameInput;
requests = AjaxHelpers.requests(test); requests = AjaxHelpers.requests(test);
initialRequests = requests.length;
displayNameInput = EditHelpers.inlineEdit(fieldEditorView.$el, options.newTitle); displayNameInput = EditHelpers.inlineEdit(fieldEditorView.$el, options.newTitle);
if (options.pressEscape) { if (options.pressEscape) {
displayNameInput.simulate("keydown", { keyCode: $.simulate.keyCode.ESCAPE }); displayNameInput.simulate("keydown", { keyCode: $.simulate.keyCode.ESCAPE });
...@@ -63,7 +62,7 @@ define(["jquery", "common/js/spec_helpers/ajax_helpers", "common/js/spec_helpers ...@@ -63,7 +62,7 @@ define(["jquery", "common/js/spec_helpers/ajax_helpers", "common/js/spec_helpers
displayNameInput.change(); displayNameInput.change();
} }
// No requests should be made when the edit is cancelled client-side // No requests should be made when the edit is cancelled client-side
expect(initialRequests).toBe(requests.length); AjaxHelpers.expectNoRequests(requests);
EditHelpers.verifyInlineEditChange(fieldEditorView.$el, initialDisplayName); EditHelpers.verifyInlineEditChange(fieldEditorView.$el, initialDisplayName);
expect(fieldEditorView.model.get('display_name')).toBe(initialDisplayName); expect(fieldEditorView.model.get('display_name')).toBe(initialDisplayName);
}; };
...@@ -85,14 +84,13 @@ define(["jquery", "common/js/spec_helpers/ajax_helpers", "common/js/spec_helpers ...@@ -85,14 +84,13 @@ define(["jquery", "common/js/spec_helpers/ajax_helpers", "common/js/spec_helpers
it('does not change the title when a display name update fails', function () { it('does not change the title when a display name update fails', function () {
var requests, fieldEditorView, initialRequests; var requests, fieldEditorView, initialRequests;
requests = AjaxHelpers.requests(this); requests = AjaxHelpers.requests(this);
initialRequests = requests.length;
fieldEditorView = getFieldEditorView().render(); fieldEditorView = getFieldEditorView().render();
EditHelpers.inlineEdit(fieldEditorView.$el, updatedDisplayName); EditHelpers.inlineEdit(fieldEditorView.$el, updatedDisplayName);
fieldEditorView.$('button[name=submit]').click(); fieldEditorView.$('button[name=submit]').click();
expectPostedNewDisplayName(requests, updatedDisplayName); expectPostedNewDisplayName(requests, updatedDisplayName);
AjaxHelpers.respondWithError(requests); AjaxHelpers.respondWithError(requests);
// No fetch operation should occur. // No fetch operation should occur.
expect(initialRequests + 1).toBe(requests.length); AjaxHelpers.expectNoRequests(requests);
EditHelpers.verifyInlineEditChange(fieldEditorView.$el, initialDisplayName, updatedDisplayName); EditHelpers.verifyInlineEditChange(fieldEditorView.$el, initialDisplayName, updatedDisplayName);
}); });
......
...@@ -98,7 +98,7 @@ define(["jquery", "underscore", "common/js/spec_helpers/ajax_helpers", "common/j ...@@ -98,7 +98,7 @@ define(["jquery", "underscore", "common/js/spec_helpers/ajax_helpers", "common/j
}; };
verifyXBlockRequest = function (requests, expectedJson) { verifyXBlockRequest = function (requests, expectedJson) {
var request = requests[requests.length - 1], var request = AjaxHelpers.currentRequest(requests),
actualJson = JSON.parse(request.requestBody); actualJson = JSON.parse(request.requestBody);
expect(request.url).toEqual("/xblock/"); expect(request.url).toEqual("/xblock/");
expect(request.method).toEqual("POST"); expect(request.method).toEqual("POST");
......
...@@ -109,9 +109,8 @@ define([ ...@@ -109,9 +109,8 @@ define([
expectHeader('Showing 1-5 out of 6 total'); expectHeader('Showing 1-5 out of 6 total');
expectItems(initialItems); expectItems(initialItems);
expectFooter({currentPage: 1, totalPages: 2, isHidden: false}); expectFooter({currentPage: 1, totalPages: 2, isHidden: false});
expect(requests.length).toBe(0); AjaxHelpers.expectNoRequests(requests);
testView.$(nextPageButtonCss).click(); testView.$(nextPageButtonCss).click();
expect(requests.length).toBe(1);
AjaxHelpers.respondWithJson(requests, { AjaxHelpers.respondWithJson(requests, {
"count": 6, "count": 6,
"num_pages": 2, "num_pages": 2,
......
...@@ -15,7 +15,8 @@ define(['jquery', ...@@ -15,7 +15,8 @@ define(['jquery',
isZeroIndexed: false, isZeroIndexed: false,
count: 43, count: 43,
respond: function (requests) { respond: function (requests) {
var params = (new URI(requests[requests.length - 1].url)).query(true), var request = AjaxHelpers.currentRequest(requests),
params = (new URI(request.url)).query(true),
page = parseInt(params['page'], 10), page = parseInt(params['page'], 10),
page_size = parseInt(params['page_size'], 10), page_size = parseInt(params['page_size'], 10),
page_count = Math.ceil(this.count / page_size); page_count = Math.ceil(this.count / page_size);
...@@ -23,7 +24,7 @@ define(['jquery', ...@@ -23,7 +24,7 @@ define(['jquery',
// Make zeroPage consistently start at zero for ease of calculation // Make zeroPage consistently start at zero for ease of calculation
var zeroPage = page - (this.isZeroIndexed ? 0 : 1); var zeroPage = page - (this.isZeroIndexed ? 0 : 1);
if (zeroPage < 0 || zeroPage > page_count) { if (zeroPage < 0 || zeroPage > page_count) {
AjaxHelpers.respondWithError(requests, 404, {}, requests.length - 1); AjaxHelpers.respondWithError(requests, 404);
} else { } else {
AjaxHelpers.respondWithJson(requests, { AjaxHelpers.respondWithJson(requests, {
'count': this.count, 'count': this.count,
...@@ -31,12 +32,13 @@ define(['jquery', ...@@ -31,12 +32,13 @@ define(['jquery',
'num_pages': page_count, 'num_pages': page_count,
'start': zeroPage * page_size, 'start': zeroPage * page_size,
'results': [] 'results': []
}, requests.length - 1); });
} }
} }
}; };
var assertQueryParams = function (requests, params) { var assertQueryParams = function (requests, params) {
var urlParams = (new URI(requests[requests.length - 1].url)).query(true); var request = AjaxHelpers.currentRequest(requests),
urlParams = (new URI(request.url)).query(true);
_.each(params, function (value, key) { _.each(params, function (value, key) {
expect(urlParams[key]).toBe(value); expect(urlParams[key]).toBe(value);
}); });
...@@ -153,7 +155,7 @@ define(['jquery', ...@@ -153,7 +155,7 @@ define(['jquery',
expect(collection.getPage()).toBe(2); expect(collection.getPage()).toBe(2);
server.respond(requests); server.respond(requests);
collection.setPage(3); collection.setPage(3);
AjaxHelpers.respondWithError(requests, 500, {}, requests.length - 1); AjaxHelpers.respondWithError(requests, 500);
expect(errorTriggered).toBe(true); expect(errorTriggered).toBe(true);
expect(collection.getPage()).toBe(2); expect(collection.getPage()).toBe(2);
}); });
......
define(['sinon', 'underscore', 'URI'], function(sinon, _, URI) { define(['sinon', 'underscore', 'URI'], function(sinon, _, URI) {
'use strict'; 'use strict';
var fakeServer, fakeRequests, expectRequest, expectJsonRequest, expectPostRequest, expectRequestURL, var XML_HTTP_READY_STATES, fakeServer, fakeRequests, currentRequest, expectRequest, expectNoRequests,
expectJsonRequest, expectPostRequest, expectRequestURL, skipResetRequest,
respondWithJson, respondWithError, respondWithTextError, respondWithNoContent; respondWithJson, respondWithError, respondWithTextError, respondWithNoContent;
XML_HTTP_READY_STATES = {
UNSENT: 0,
OPENED: 1,
LOADING: 3,
DONE: 4
};
/* These utility methods are used by Jasmine tests to create a mock server or /* These utility methods are used by Jasmine tests to create a mock server or
* get reference to mock requests. In either case, the cleanup (restore) is done with * get reference to mock requests. In either case, the cleanup (restore) is done with
* an after function. * an after function.
...@@ -37,6 +45,7 @@ define(['sinon', 'underscore', 'URI'], function(sinon, _, URI) { ...@@ -37,6 +45,7 @@ define(['sinon', 'underscore', 'URI'], function(sinon, _, URI) {
fakeRequests = function (that) { fakeRequests = function (that) {
var requests = [], var requests = [],
xhr = sinon.useFakeXMLHttpRequest(); xhr = sinon.useFakeXMLHttpRequest();
requests.currentIndex = 0;
xhr.onCreate = function(request) { xhr.onCreate = function(request) {
requests.push(request); requests.push(request);
}; };
...@@ -44,27 +53,38 @@ define(['sinon', 'underscore', 'URI'], function(sinon, _, URI) { ...@@ -44,27 +53,38 @@ define(['sinon', 'underscore', 'URI'], function(sinon, _, URI) {
that.after(function() { that.after(function() {
xhr.restore(); xhr.restore();
}); });
return requests; return requests;
}; };
expectRequest = function(requests, method, url, body, requestIndex) { /**
var request; * Returns the request that has not yet been responded to. If no such request
if (_.isUndefined(requestIndex)) { * is available then the current test will fail.
requestIndex = requests.length - 1; * @param requests The Sinon requests list.
} * @returns {*} The current request.
request = requests[requestIndex]; */
currentRequest = function(requests) {
expect(requests.length).toBeGreaterThan(requests.currentIndex);
return requests[requests.currentIndex];
};
expectRequest = function(requests, method, url, body) {
var request = currentRequest(requests);
expect(request.readyState).toEqual(XML_HTTP_READY_STATES.OPENED);
expect(request.url).toEqual(url); expect(request.url).toEqual(url);
expect(request.method).toEqual(method); expect(request.method).toEqual(method);
expect(request.requestBody).toEqual(body); expect(request.requestBody).toEqual(body);
}; };
expectJsonRequest = function(requests, method, url, jsonRequest, requestIndex) { /**
var request; * Verifies the there are no unconsumed requests.
if (_.isUndefined(requestIndex)) { */
requestIndex = requests.length - 1; expectNoRequests = function(requests) {
} expect(requests.length).toEqual(requests.currentIndex);
request = requests[requestIndex]; };
expectJsonRequest = function(requests, method, url, jsonRequest) {
var request = currentRequest(requests);
expect(request.readyState).toEqual(XML_HTTP_READY_STATES.OPENED);
expect(request.url).toEqual(url); expect(request.url).toEqual(url);
expect(request.method).toEqual(method); expect(request.method).toEqual(method);
expect(JSON.parse(request.requestBody)).toEqual(jsonRequest); expect(JSON.parse(request.requestBody)).toEqual(jsonRequest);
...@@ -75,14 +95,10 @@ define(['sinon', 'underscore', 'URI'], function(sinon, _, URI) { ...@@ -75,14 +95,10 @@ define(['sinon', 'underscore', 'URI'], function(sinon, _, URI) {
* @param requests The collected requests * @param requests The collected requests
* @param expectedUrl The expected URL excluding the parameters * @param expectedUrl The expected URL excluding the parameters
* @param expectedParameters An object representing the URL parameters * @param expectedParameters An object representing the URL parameters
* @param requestIndex An optional index for the request (by default, the last request is used)
*/ */
expectRequestURL = function(requests, expectedUrl, expectedParameters, requestIndex) { expectRequestURL = function(requests, expectedUrl, expectedParameters) {
var request, parameters; var request = currentRequest(requests),
if (_.isUndefined(requestIndex)) { parameters;
requestIndex = requests.length - 1;
}
request = requests[requestIndex];
expect(new URI(request.url).path()).toEqual(expectedUrl); expect(new URI(request.url).path()).toEqual(expectedUrl);
parameters = new URI(request.url).query(true); parameters = new URI(request.url).query(true);
delete parameters._; // Ignore the cache-busting argument delete parameters._; // Ignore the cache-busting argument
...@@ -92,73 +108,82 @@ define(['sinon', 'underscore', 'URI'], function(sinon, _, URI) { ...@@ -92,73 +108,82 @@ define(['sinon', 'underscore', 'URI'], function(sinon, _, URI) {
/** /**
* Intended for use with POST requests using application/x-www-form-urlencoded. * Intended for use with POST requests using application/x-www-form-urlencoded.
*/ */
expectPostRequest = function(requests, url, body, requestIndex) { expectPostRequest = function(requests, url, body) {
var request; var request = currentRequest(requests);
if (_.isUndefined(requestIndex)) { expect(request.readyState).toEqual(XML_HTTP_READY_STATES.OPENED);
requestIndex = requests.length - 1;
}
request = requests[requestIndex];
expect(request.url).toEqual(url); expect(request.url).toEqual(url);
expect(request.method).toEqual("POST"); expect(request.method).toEqual("POST");
expect(_.difference(request.requestBody.split('&'), body.split('&'))).toEqual([]); expect(_.difference(request.requestBody.split('&'), body.split('&'))).toEqual([]);
}; };
respondWithJson = function(requests, jsonResponse, requestIndex) { /**
if (_.isUndefined(requestIndex)) { * Verify that the request was reset, and then skip it.
requestIndex = requests.length - 1; */
} skipResetRequest = function(requests) {
requests[requestIndex].respond(200, var request = currentRequest(requests);
expect(request.readyState).toEqual(XML_HTTP_READY_STATES.UNSENT);
requests.currentIndex++;
};
respondWithJson = function(requests, jsonResponse) {
var request = currentRequest(requests);
request.respond(200,
{ 'Content-Type': 'application/json' }, { 'Content-Type': 'application/json' },
JSON.stringify(jsonResponse)); JSON.stringify(jsonResponse));
requests.currentIndex++;
}; };
respondWithError = function(requests, statusCode, jsonResponse, requestIndex) { respondWithError = function(requests, statusCode, jsonResponse) {
if (_.isUndefined(requestIndex)) { var request = currentRequest(requests);
requestIndex = requests.length - 1;
}
if (_.isUndefined(statusCode)) { if (_.isUndefined(statusCode)) {
statusCode = 500; statusCode = 500;
} }
if (_.isUndefined(jsonResponse)) { if (_.isUndefined(jsonResponse)) {
jsonResponse = {}; jsonResponse = {};
} }
requests[requestIndex].respond(statusCode, request.respond(
statusCode,
{ 'Content-Type': 'application/json' }, { 'Content-Type': 'application/json' },
JSON.stringify(jsonResponse) JSON.stringify(jsonResponse)
); );
requests.currentIndex++;
}; };
respondWithTextError = function(requests, statusCode, textResponse, requestIndex) { respondWithTextError = function(requests, statusCode, textResponse) {
if (_.isUndefined(requestIndex)) { var request = currentRequest(requests);
requestIndex = requests.length - 1;
}
if (_.isUndefined(statusCode)) { if (_.isUndefined(statusCode)) {
statusCode = 500; statusCode = 500;
} }
if (_.isUndefined(textResponse)) { if (_.isUndefined(textResponse)) {
textResponse = ""; textResponse = "";
} }
requests[requestIndex].respond(statusCode, request.respond(
statusCode,
{ 'Content-Type': 'text/plain' }, { 'Content-Type': 'text/plain' },
textResponse textResponse
); );
requests.currentIndex++;
}; };
respondWithNoContent = function(requests, requestIndex) { respondWithNoContent = function(requests) {
if (_.isUndefined(requestIndex)) { var request = currentRequest(requests);
requestIndex = requests.length - 1; request.respond(
} 204,
requests[requestIndex].respond(204, { 'Content-Type': 'application/json' }
{ 'Content-Type': 'application/json' }); );
requests.currentIndex++;
}; };
return { return {
server: fakeServer, server: fakeServer,
requests: fakeRequests, requests: fakeRequests,
currentRequest: currentRequest,
expectRequest: expectRequest, expectRequest: expectRequest,
expectNoRequests: expectNoRequests,
expectJsonRequest: expectJsonRequest, expectJsonRequest: expectJsonRequest,
expectPostRequest: expectPostRequest, expectPostRequest: expectPostRequest,
expectRequestURL: expectRequestURL, expectRequestURL: expectRequestURL,
skipResetRequest: skipResetRequest,
respondWithJson: respondWithJson, respondWithJson: respondWithJson,
respondWithError: respondWithError, respondWithError: respondWithError,
respondWithTextError: respondWithTextError, respondWithTextError: respondWithTextError,
......
...@@ -10,11 +10,12 @@ define(['backbone', 'URI', 'underscore', 'common/js/spec_helpers/ajax_helpers', ...@@ -10,11 +10,12 @@ define(['backbone', 'URI', 'underscore', 'common/js/spec_helpers/ajax_helpers',
var testRequestParam = function (self, param, value) { var testRequestParam = function (self, param, value) {
var requests = AjaxHelpers.requests(self), var requests = AjaxHelpers.requests(self),
request,
url, url,
params; params;
topicCollection.fetch(); topicCollection.fetch();
expect(requests.length).toBe(1); request = AjaxHelpers.currentRequest(requests);
url = new URI(requests[0].url); url = new URI(request.url);
params = url.query(true); params = url.query(true);
expect(params[param]).toBe(value); expect(params[param]).toBe(value);
}; };
......
...@@ -138,7 +138,7 @@ define([ ...@@ -138,7 +138,7 @@ define([
verifyTeamMembersView(view); verifyTeamMembersView(view);
deleteTeamMemember(view, false); deleteTeamMemember(view, false);
expect(requests.length).toBe(0); AjaxHelpers.expectNoRequests(requests);
expect(view.teamEvents.trigger).not.toHaveBeenCalled(); expect(view.teamEvents.trigger).not.toHaveBeenCalled();
verifyTeamMembersView(view); verifyTeamMembersView(view);
}); });
......
...@@ -55,7 +55,8 @@ define([ ...@@ -55,7 +55,8 @@ define([
} }
}); });
expect(requests.length).toBe(0); AjaxHelpers.expectNoRequests(requests);
}, },
editTeamID = 'av', editTeamID = 'av',
teamAction; teamAction;
......
...@@ -72,7 +72,7 @@ define([ ...@@ -72,7 +72,7 @@ define([
it('can cancel team deletion', function () { it('can cancel team deletion', function () {
var requests = AjaxHelpers.requests(this); var requests = AjaxHelpers.requests(this);
deleteTeam(view, false); deleteTeam(view, false);
expect(requests.length).toBe(0); AjaxHelpers.expectNoRequests(requests);
expect(Backbone.history.navigate).not.toHaveBeenCalled(); expect(Backbone.history.navigate).not.toHaveBeenCalled();
}); });
......
...@@ -168,7 +168,7 @@ define([ ...@@ -168,7 +168,7 @@ define([
expect(view.$('.join-team-message').text().trim()).toBe(view.teamFullMessage); expect(view.$('.join-team-message').text().trim()).toBe(view.teamFullMessage);
// there should be no request made // there should be no request made
expect(requests.length).toBe(0); AjaxHelpers.expectNoRequests(requests);
}); });
it('shows correct error message if user fails to join team', function () { it('shows correct error message if user fails to join team', function () {
......
...@@ -85,10 +85,9 @@ define([ ...@@ -85,10 +85,9 @@ define([
AjaxHelpers.expectJsonRequest(requests, 'GET', '/api/team/v0/teams/test-team'); AjaxHelpers.expectJsonRequest(requests, 'GET', '/api/team/v0/teams/test-team');
AjaxHelpers.respondWithJson(requests, createTeamModelData({country: 'US', language: 'en'})); AjaxHelpers.respondWithJson(requests, createTeamModelData({country: 'US', language: 'en'}));
} else { } else {
var requestCount = requests.length;
// click on Cancel button on dialog // click on Cancel button on dialog
$('.prompt.warning .action-secondary').click(); $('.prompt.warning .action-secondary').click();
expect(requests.length).toBe(requestCount); AjaxHelpers.expectNoRequests(requests);
} }
}; };
......
...@@ -174,7 +174,7 @@ define([ ...@@ -174,7 +174,7 @@ define([
userInfo: TeamSpecHelpers.createMockUserInfo({staff: true}) userInfo: TeamSpecHelpers.createMockUserInfo({staff: true})
}); });
teamsTabView.router.navigate(url, {trigger: true}); teamsTabView.router.navigate(url, {trigger: true});
if (requests.length) { if (AjaxHelpers.currentRequest(requests)) {
AjaxHelpers.respondWithJson(requests, {}); AjaxHelpers.respondWithJson(requests, {});
} }
expect(Logger.log).toHaveBeenCalledWith('edx.team.page_viewed', expectedEvent); expect(Logger.log).toHaveBeenCalledWith('edx.team.page_viewed', expectedEvent);
...@@ -229,24 +229,22 @@ define([ ...@@ -229,24 +229,22 @@ define([
text_search: 'foo' text_search: 'foo'
}); });
AjaxHelpers.respondWithJson(requests, TeamSpecHelpers.createMockTeamsResponse({results: []})); AjaxHelpers.respondWithJson(requests, TeamSpecHelpers.createMockTeamsResponse({results: []}));
// Expect exactly one search request to be fired
AjaxHelpers.expectNoRequests(requests);
}; };
it('can search teams', function () { it('can search teams', function () {
var teamsTabView = createTeamsTabView(this), var teamsTabView = createTeamsTabView(this);
requestCountBeforeSearch;
teamsTabView.browseTopic(TeamSpecHelpers.testTopicID); teamsTabView.browseTopic(TeamSpecHelpers.testTopicID);
verifyTeamsRequest({ verifyTeamsRequest({
order_by: 'last_activity_at', order_by: 'last_activity_at',
text_search: '' text_search: ''
}); });
AjaxHelpers.respondWithJson(requests, {}); AjaxHelpers.respondWithJson(requests, {});
requestCountBeforeSearch = requests.length;
performSearch(requests, teamsTabView); performSearch(requests, teamsTabView);
expect(teamsTabView.$('.page-title').text()).toBe('Team Search'); expect(teamsTabView.$('.page-title').text()).toBe('Team Search');
expect(teamsTabView.$('.page-description').text()).toBe('Showing results for "foo"'); expect(teamsTabView.$('.page-description').text()).toBe('Showing results for "foo"');
// Expect exactly one search request to be fired
expect(requests.length).toBe(requestCountBeforeSearch + 1);
}); });
it('can clear a search', function () { it('can clear a search', function () {
......
...@@ -130,6 +130,9 @@ define([ ...@@ -130,6 +130,9 @@ define([
window.scroll(0, $(document).height()); window.scroll(0, $(document).height());
$(window).trigger('scroll'); $(window).trigger('scroll');
jasmine.Clock.tick(500); jasmine.Clock.tick(500);
// TODO: determine why the search API is invoked twice
AjaxHelpers.respondWithJson(requests, JSON_RESPONSE);
AjaxHelpers.respondWithJson(requests, JSON_RESPONSE); AjaxHelpers.respondWithJson(requests, JSON_RESPONSE);
expect($('.courses-listing article').length).toEqual(2); expect($('.courses-listing article').length).toEqual(2);
}); });
......
...@@ -70,6 +70,16 @@ define([ ...@@ -70,6 +70,16 @@ define([
expect(this.toggleMessage).toContainText('Notes visible'); expect(this.toggleMessage).toContainText('Notes visible');
expect(Annotator._instances).toHaveLength(2); expect(Annotator._instances).toHaveLength(2);
// TODO: why is the same search request made twice?
AjaxHelpers.expectJsonRequest(requests, 'GET',
'/test_endpoint/search/?user=a+user&usage_id=an+usage&course_id=a+course'
);
AjaxHelpers.respondWithJson(requests, {});
AjaxHelpers.expectJsonRequest(requests, 'GET',
'/test_endpoint/search/?user=a+user&usage_id=an+usage&course_id=a+course'
);
AjaxHelpers.respondWithJson(requests, {});
AjaxHelpers.expectJsonRequest(requests, 'PUT', '/test_url', { AjaxHelpers.expectJsonRequest(requests, 'PUT', '/test_url', {
'visibility': true 'visibility': true
}); });
...@@ -90,6 +100,17 @@ define([ ...@@ -90,6 +100,17 @@ define([
expect(errorContainer).toHaveClass('annotator-notice-error'); expect(errorContainer).toHaveClass('annotator-notice-error');
this.button.click(); this.button.click();
// TODO: why is the same search request made twice?
AjaxHelpers.expectJsonRequest(requests, 'GET',
'/test_endpoint/search/?user=a+user&usage_id=an+usage&course_id=a+course'
);
AjaxHelpers.respondWithJson(requests, {});
AjaxHelpers.expectJsonRequest(requests, 'GET',
'/test_endpoint/search/?user=a+user&usage_id=an+usage&course_id=a+course'
);
AjaxHelpers.respondWithJson(requests, {});
AjaxHelpers.respondWithJson(requests, {}); AjaxHelpers.respondWithJson(requests, {});
expect(errorContainer).not.toHaveClass('annotator-notice-show'); expect(errorContainer).not.toHaveClass('annotator-notice-show');
}); });
......
...@@ -9,30 +9,30 @@ define([ ...@@ -9,30 +9,30 @@ define([
'use strict'; 'use strict';
describe('EdxNotes SearchResultsView', function() { describe('EdxNotes SearchResultsView', function() {
var notes = [ var notes = [
{ {
created: 'December 11, 2014 at 11:12AM', created: 'December 11, 2014 at 11:12AM',
updated: 'December 11, 2014 at 11:12AM', updated: 'December 11, 2014 at 11:12AM',
text: 'Third added model', text: 'Third added model',
quote: 'Should be listed first' quote: 'Should be listed first'
}, },
{ {
created: 'December 11, 2014 at 11:11AM', created: 'December 11, 2014 at 11:11AM',
updated: 'December 11, 2014 at 11:11AM', updated: 'December 11, 2014 at 11:11AM',
text: 'Second added model', text: 'Second added model',
quote: 'Should be listed second' quote: 'Should be listed second'
},
{
created: 'December 11, 2014 at 11:10AM',
updated: 'December 11, 2014 at 11:10AM',
text: 'First added model',
quote: 'Should be listed third'
}
],
responseJson = {
total: 3,
rows: notes
}, },
{ getView, submitForm, respondToSearch;
created: 'December 11, 2014 at 11:10AM',
updated: 'December 11, 2014 at 11:10AM',
text: 'First added model',
quote: 'Should be listed third'
}
],
responseJson = {
total: 3,
rows: notes
},
getView, submitForm;
getView = function (tabsCollection, options) { getView = function (tabsCollection, options) {
options = _.defaults(options || {}, { options = _.defaults(options || {}, {
...@@ -50,6 +50,14 @@ define([ ...@@ -50,6 +50,14 @@ define([
searchBox.$('.search-notes-submit').click(); searchBox.$('.search-notes-submit').click();
}; };
respondToSearch = function(requests, responseJson) {
// First respond to the analytics event
AjaxHelpers.respondWithNoContent(requests);
// Now process the search request
AjaxHelpers.respondWithJson(requests, responseJson);
};
beforeEach(function () { beforeEach(function () {
customMatchers(this); customMatchers(this);
loadFixtures('js/fixtures/edxnotes/edxnotes.html'); loadFixtures('js/fixtures/edxnotes/edxnotes.html');
...@@ -71,7 +79,7 @@ define([ ...@@ -71,7 +79,7 @@ define([
requests = AjaxHelpers.requests(this); requests = AjaxHelpers.requests(this);
submitForm(view.searchBox, 'second'); submitForm(view.searchBox, 'second');
AjaxHelpers.respondWithJson(requests, responseJson); respondToSearch(requests, responseJson);
expect(this.tabsCollection).toHaveLength(1); expect(this.tabsCollection).toHaveLength(1);
expect(this.tabsCollection.at(0).toJSON()).toEqual({ expect(this.tabsCollection.at(0).toJSON()).toEqual({
...@@ -100,7 +108,7 @@ define([ ...@@ -100,7 +108,7 @@ define([
expect(this.tabsCollection).toHaveLength(1); expect(this.tabsCollection).toHaveLength(1);
expect(view.searchResults).toBeNull(); expect(view.searchResults).toBeNull();
expect(view.$('.tab-panel')).not.toExist(); expect(view.$('.tab-panel')).not.toExist();
AjaxHelpers.respondWithJson(requests, responseJson); respondToSearch(requests, responseJson);
expect(view.$('.ui-loading')).toHaveClass('is-hidden'); expect(view.$('.ui-loading')).toHaveClass('is-hidden');
}); });
...@@ -109,7 +117,7 @@ define([ ...@@ -109,7 +117,7 @@ define([
requests = AjaxHelpers.requests(this); requests = AjaxHelpers.requests(this);
submitForm(view.searchBox, 'some text'); submitForm(view.searchBox, 'some text');
AjaxHelpers.respondWithJson(requests, { respondToSearch(requests, {
total: 0, total: 0,
rows: [] rows: []
}); });
...@@ -147,7 +155,7 @@ define([ ...@@ -147,7 +155,7 @@ define([
requests = AjaxHelpers.requests(this); requests = AjaxHelpers.requests(this);
submitForm(view.searchBox, 'test_query'); submitForm(view.searchBox, 'test_query');
AjaxHelpers.respondWithJson(requests, responseJson); respondToSearch(requests, responseJson);
expect(view.searchResults).toBeDefined(); expect(view.searchResults).toBeDefined();
this.tabsCollection.at(0).destroy(); this.tabsCollection.at(0).destroy();
expect(view.searchResults).toBeNull(); expect(view.searchResults).toBeNull();
...@@ -158,6 +166,11 @@ define([ ...@@ -158,6 +166,11 @@ define([
requests = AjaxHelpers.requests(this); requests = AjaxHelpers.requests(this);
submitForm(view.searchBox, 'test error'); submitForm(view.searchBox, 'test error');
// First respond to the analytics event
AjaxHelpers.respondWithNoContent(requests);
// Now respond to the search with a 500 error
AjaxHelpers.respondWithError(requests, 500, {error: 'test error message'}); AjaxHelpers.respondWithError(requests, 500, {error: 'test error message'});
expect(view.$('.wrapper-msg')).not.toHaveClass('is-hidden'); expect(view.$('.wrapper-msg')).not.toHaveClass('is-hidden');
...@@ -182,12 +195,12 @@ define([ ...@@ -182,12 +195,12 @@ define([
}]; }];
submitForm(view.searchBox, 'test_query'); submitForm(view.searchBox, 'test_query');
AjaxHelpers.respondWithJson(requests, responseJson); respondToSearch(requests, responseJson);
expect(view.$('.note')).toHaveLength(3); expect(view.$('.note')).toHaveLength(3);
submitForm(view.searchBox, 'new_test_query'); submitForm(view.searchBox, 'new_test_query');
AjaxHelpers.respondWithJson(requests, { respondToSearch(requests, {
total: 1, total: 1,
rows: newNotes rows: newNotes
}); });
......
...@@ -247,8 +247,7 @@ define(['backbone', 'jquery', 'common/js/spec_helpers/ajax_helpers', 'common/js/ ...@@ -247,8 +247,7 @@ define(['backbone', 'jquery', 'common/js/spec_helpers/ajax_helpers', 'common/js/
}; };
saveFormAndExpectErrors = function(action, errors) { saveFormAndExpectErrors = function(action, errors) {
var requestCount = requests.length, var form, expectedTitle;
form, expectedTitle;
if (action === 'add') { if (action === 'add') {
expectedTitle = 'The cohort cannot be added'; expectedTitle = 'The cohort cannot be added';
form = getAddModal(); form = getAddModal();
...@@ -257,7 +256,7 @@ define(['backbone', 'jquery', 'common/js/spec_helpers/ajax_helpers', 'common/js/ ...@@ -257,7 +256,7 @@ define(['backbone', 'jquery', 'common/js/spec_helpers/ajax_helpers', 'common/js/
form = cohortsView.$('.cohort-management-settings-form'); form = cohortsView.$('.cohort-management-settings-form');
} }
form.find('.action-save').click(); form.find('.action-save').click();
expect(requests.length).toBe(requestCount); AjaxHelpers.expectNoRequests(requests);
verifyDetailedMessage(expectedTitle, 'error', errors); verifyDetailedMessage(expectedTitle, 'error', errors);
}; };
...@@ -360,6 +359,9 @@ define(['backbone', 'jquery', 'common/js/spec_helpers/ajax_helpers', 'common/js/ ...@@ -360,6 +359,9 @@ define(['backbone', 'jquery', 'common/js/spec_helpers/ajax_helpers', 'common/js/
cohortsView.$(fileUploadForm).fileupload('add', {files: [{name: 'upload_file.txt'}]}); cohortsView.$(fileUploadForm).fileupload('add', {files: [{name: 'upload_file.txt'}]});
cohortsView.$('.submit-file-button').click(); cohortsView.$('.submit-file-button').click();
// Respond to the event request
AjaxHelpers.respondWithNoContent(requests);
// No file will actually be uploaded because "uploaded_file.txt" doesn't actually exist. // No file will actually be uploaded because "uploaded_file.txt" doesn't actually exist.
AjaxHelpers.expectRequest(requests, 'POST', MOCK_UPLOAD_COHORTS_CSV_URL, new FormData()); AjaxHelpers.expectRequest(requests, 'POST', MOCK_UPLOAD_COHORTS_CSV_URL, new FormData());
AjaxHelpers.respondWithJson(requests, {}); AjaxHelpers.respondWithJson(requests, {});
...@@ -706,7 +708,7 @@ define(['backbone', 'jquery', 'common/js/spec_helpers/ajax_helpers', 'common/js/ ...@@ -706,7 +708,7 @@ define(['backbone', 'jquery', 'common/js/spec_helpers/ajax_helpers', 'common/js/
it('shows an error when adding with no students specified', function() { it('shows an error when adding with no students specified', function() {
createCohortsView(this, {selectCohort: 1}); createCohortsView(this, {selectCohort: 1});
addStudents(' '); addStudents(' ');
expect(requests.length).toBe(0); AjaxHelpers.expectNoRequests(requests);
verifyMessage('Enter a username or email.', 'error'); verifyMessage('Enter a username or email.', 'error');
expect(getStudentInput().val()).toBe(''); expect(getStudentInput().val()).toBe('');
}); });
......
...@@ -162,16 +162,18 @@ define([ ...@@ -162,16 +162,18 @@ define([
this.collection.performSearch('old search'); this.collection.performSearch('old search');
this.collection.performSearch('new search'); this.collection.performSearch('new search');
AjaxHelpers.skipResetRequest(requests);
AjaxHelpers.respondWithJson(requests, response); AjaxHelpers.respondWithJson(requests, response);
expect(this.onSearch.calls.length).toEqual(1); expect(this.onSearch.calls.length).toEqual(1);
this.collection.performSearch('old search'); this.collection.performSearch('old search');
this.collection.cancelSearch(); this.collection.cancelSearch();
AjaxHelpers.respondWithJson(requests, response); AjaxHelpers.skipResetRequest(requests);
expect(this.onSearch.calls.length).toEqual(1); expect(this.onSearch.calls.length).toEqual(1);
this.collection.loadNextPage(); this.collection.loadNextPage();
this.collection.loadNextPage(); this.collection.loadNextPage();
AjaxHelpers.skipResetRequest(requests);
AjaxHelpers.respondWithJson(requests, response); AjaxHelpers.respondWithJson(requests, response);
expect(this.onNext.calls.length).toEqual(1); expect(this.onNext.calls.length).toEqual(1);
}); });
......
...@@ -139,6 +139,7 @@ define(['backbone', 'jquery', 'underscore', 'common/js/spec_helpers/ajax_helpers ...@@ -139,6 +139,7 @@ define(['backbone', 'jquery', 'underscore', 'common/js/spec_helpers/ajax_helpers
AjaxHelpers.respondWithJson(requests, Helpers.createAccountSettingsData()); AjaxHelpers.respondWithJson(requests, Helpers.createAccountSettingsData());
AjaxHelpers.respondWithJson(requests, Helpers.createUserPreferencesData()); AjaxHelpers.respondWithJson(requests, Helpers.createUserPreferencesData());
AjaxHelpers.respondWithJson(requests, {}); // Page viewed analytics event
var sectionsData = accountSettingsView.options.sectionsData; var sectionsData = accountSettingsView.options.sectionsData;
......
...@@ -42,16 +42,13 @@ define(['backbone', 'jquery', 'underscore', 'common/js/spec_helpers/ajax_helpers ...@@ -42,16 +42,13 @@ define(['backbone', 'jquery', 'underscore', 'common/js/spec_helpers/ajax_helpers
}); });
}; };
it("renders the full profile after data is successfully fetched", function() { it("renders the full profile for a user", function() {
requests = AjaxHelpers.requests(this); requests = AjaxHelpers.requests(this);
var context = createProfilePage(true), var context = createProfilePage(true),
learnerProfileView = context.learnerProfileView; learnerProfileView = context.learnerProfileView;
AjaxHelpers.respondWithJson(requests, Helpers.createAccountSettingsData());
AjaxHelpers.respondWithJson(requests, Helpers.createUserPreferencesData());
// sets the profile for full view. // sets the profile for full view.
context.accountPreferencesModel.set({account_privacy: 'all_users'}); context.accountPreferencesModel.set({account_privacy: 'all_users'});
LearnerProfileHelpers.expectProfileSectionsAndFieldsToBeRendered(learnerProfileView, false); LearnerProfileHelpers.expectProfileSectionsAndFieldsToBeRendered(learnerProfileView, false);
......
...@@ -110,6 +110,9 @@ define(['backbone', 'jquery', 'underscore', 'common/js/spec_helpers/ajax_helpers ...@@ -110,6 +110,9 @@ define(['backbone', 'jquery', 'underscore', 'common/js/spec_helpers/ajax_helpers
// Verify image upload progress message // Verify image upload progress message
verifyImageUploadButtonMessage(imageView, true); verifyImageUploadButtonMessage(imageView, true);
// Respond to the analytics event
AjaxHelpers.respondWithJson(requests, {});
// Verify if POST request received for image upload // Verify if POST request received for image upload
AjaxHelpers.expectRequest(requests, 'POST', Helpers.IMAGE_UPLOAD_API_URL, new FormData()); AjaxHelpers.expectRequest(requests, 'POST', Helpers.IMAGE_UPLOAD_API_URL, new FormData());
...@@ -278,6 +281,9 @@ define(['backbone', 'jquery', 'underscore', 'common/js/spec_helpers/ajax_helpers ...@@ -278,6 +281,9 @@ define(['backbone', 'jquery', 'underscore', 'common/js/spec_helpers/ajax_helpers
// Verify image upload progress message // Verify image upload progress message
verifyImageUploadButtonMessage(imageView, true); verifyImageUploadButtonMessage(imageView, true);
// Respond to the analytics event
AjaxHelpers.respondWithJson(requests, {});
// Verify if POST request received for image upload // Verify if POST request received for image upload
AjaxHelpers.expectRequest(requests, 'POST', Helpers.IMAGE_UPLOAD_API_URL, new FormData()); AjaxHelpers.expectRequest(requests, 'POST', Helpers.IMAGE_UPLOAD_API_URL, new FormData());
......
...@@ -83,7 +83,7 @@ define([ ...@@ -83,7 +83,7 @@ define([
// TODO put fixture responses in the right place // TODO put fixture responses in the right place
AjaxHelpers.respondWithJson( requests, {payment_page_url: 'http://payment-page-url/', payment_form_data: {foo: 'bar'}} ); AjaxHelpers.respondWithJson( requests, {payment_page_url: 'http://payment-page-url/', payment_form_data: {foo: 'bar'}} );
} else { } else {
AjaxHelpers.respondWithTextError( requests, 400, SERVER_ERROR_MSG ); AjaxHelpers.respondWithTextError( requests, 400, SERVER_ERROR_MSG);
} }
}; };
...@@ -102,7 +102,8 @@ define([ ...@@ -102,7 +102,8 @@ define([
var $el = $( '.payment-button' ); var $el = $( '.payment-button' );
expect($el.length).toEqual(_.size(buttons)); expect($el.length).toEqual(_.size(buttons));
_.each(buttons, function( expectedText, expectedId ) { _.each(buttons, function( expectedText, expectedId ) {
var buttonEl = $( '#' + expectedId ); var buttonEl = $( '#' + expectedId),
request;
buttonEl.removeAttr('disabled'); buttonEl.removeAttr('disabled');
expect( buttonEl.length ).toEqual( 1 ); expect( buttonEl.length ).toEqual( 1 );
...@@ -112,7 +113,9 @@ define([ ...@@ -112,7 +113,9 @@ define([
buttonEl[0].click(); buttonEl[0].click();
expect( buttonEl[0] ).toHaveClass( 'is-selected' ); expect( buttonEl[0] ).toHaveClass( 'is-selected' );
expectPaymentButtonEnabled( false ); expectPaymentButtonEnabled( false );
expect(requests[requests.length - 1].requestBody.split('&')).toContain('processor=' + expectedId); request = AjaxHelpers.currentRequest(requests);
expect(request.requestBody.split('&')).toContain('processor=' + expectedId);
AjaxHelpers.respondWithJson(requests, {});
}); });
}; };
......
...@@ -154,7 +154,7 @@ define(['backbone', 'jquery', 'underscore', 'common/js/spec_helpers/ajax_helpers ...@@ -154,7 +154,7 @@ define(['backbone', 'jquery', 'underscore', 'common/js/spec_helpers/ajax_helpers
view.$(valueInputSelector).val(fieldData.validValue).change(); view.$(valueInputSelector).val(fieldData.validValue).change();
expect(view.fieldValue()).toBe(fieldData.validValue); expect(view.fieldValue()).toBe(fieldData.validValue);
expectMessageContains(view, view.helpMessage); expectMessageContains(view, view.helpMessage);
expect(requests.length).toBe(0); AjaxHelpers.expectNoRequests(requests);
}; };
var verifyEditableField = function (view, data, requests) { var verifyEditableField = function (view, data, requests) {
......
...@@ -54,6 +54,9 @@ define(['backbone', 'jquery', 'js/views/file_uploader', 'common/js/spec_helpers/ ...@@ -54,6 +54,9 @@ define(['backbone', 'jquery', 'js/views/file_uploader', 'common/js/spec_helpers/
verifySubmitButtonEnabled(true); verifySubmitButtonEnabled(true);
fileUploaderView.$('.submit-file-button').click(); fileUploaderView.$('.submit-file-button').click();
// Respond to the analytics event first
AjaxHelpers.respondWithJson(requests, {});
// No file will actually be uploaded because "uploaded_file.txt" doesn't actually exist. // No file will actually be uploaded because "uploaded_file.txt" doesn't actually exist.
AjaxHelpers.expectRequest(requests, 'POST', url, new FormData()); AjaxHelpers.expectRequest(requests, 'POST', url, new FormData());
return requests; return requests;
......
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