Skip to content

Commit 9adad92

Browse files
committed
fixup! fixup! fix: refactor assets, settings/main, pages/index specs to not call AjaxHelpers inside it()
1 parent 0f188a3 commit 9adad92

1 file changed

Lines changed: 31 additions & 9 deletions

File tree

cms/static/js/spec/views/assets_spec.js

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,36 @@ function($, sinon, AjaxHelpers, URI, AssetsView, AssetCollection, ViewHelpers) {
1111
uploadModalTpl = readFixtures('asset-upload-modal.underscore');
1212

1313
beforeEach(function() {
14+
// Fake XHR must be installed BEFORE new AssetsView() for two reasons:
15+
//
16+
// 1. AssetsView.initialize() calls createPagingView() which immediately calls
17+
// pagingView.setPage(1), firing an AJAX request. If real XHR is active at that
18+
// point, the request goes to Karma's server which returns 404. Jasmine 2.x
19+
// schedules beforeEach and it() with setTimeout(0) between them, giving the
20+
// browser event loop a window to process pending async work. The Karma 404
21+
// response fires during that window, triggering AssetsView's error callback
22+
// -> getTableBody() -> DOM creation -> .upload-button becomes visible. Tests
23+
// that check this button is hidden (in loading state) then fail.
24+
//
25+
// 2. This test suite tests the loading -> loaded state transition. Several tests
26+
// call setup() inside it(), which calls setPage(1) and responds to it, driving
27+
// the view from "loading" to "loaded". That precondition requires the view to
28+
// still be in "loading" state at the start of it(). Responding to the init
29+
// request in beforeEach (to avoid the dangling request) would put the view
30+
// into "loaded" state too early and break those assertions.
31+
//
32+
// With sinon installed first, the init setPage(1) is captured as requests[0] —
33+
// a frozen pending fake request that never gets a response unless explicitly told
34+
// to. No response means no callbacks, no DOM mutation, view stays in "loading"
35+
// state. We advance currentIndex to 1 so AjaxHelpers treats that request as
36+
// already consumed; test-driven setPage() calls start at index 1. The pending
37+
// requests[0] is abandoned when xhrFactory.restore() runs in afterEach.
38+
xhrFactory = sinon.useFakeXMLHttpRequest();
39+
requests = [];
40+
requests.currentIndex = 0;
41+
requests.restore = function() { xhrFactory.restore(); };
42+
xhrFactory.onCreate = function(req) { requests.push(req); };
43+
1444
setFixtures($('<script>', {id: 'asset-library-tpl', type: 'text/template'}).text(assetLibraryTpl));
1545
appendSetFixtures($('<script>', {id: 'asset-tpl', type: 'text/template'}).text(assetTpl));
1646
appendSetFixtures(uploadModalTpl);
@@ -30,15 +60,7 @@ function($, sinon, AjaxHelpers, URI, AssetsView, AssetCollection, ViewHelpers) {
3060
collection: collection,
3161
el: $('#asset_table_body')
3262
});
33-
34-
// Install fake XHR after creating assetsView so that the initial setPage(1)
35-
// fired by createPagingView() during initialize() is not captured. Tests that
36-
// need a specific page state drive it themselves via setPage() + respond.
37-
xhrFactory = sinon.useFakeXMLHttpRequest();
38-
requests = [];
39-
requests.currentIndex = 0;
40-
requests.restore = function() { xhrFactory.restore(); };
41-
xhrFactory.onCreate = function(req) { requests.push(req); };
63+
requests.currentIndex = 1;
4264
});
4365

4466
afterEach(function() {

0 commit comments

Comments
 (0)