Skip to content

Commit 3c404e1

Browse files
authored
Merge pull request #53 from canjs/52-beforeSend-updates
52 before send updates
2 parents d5241b0 + 71d8323 commit 3c404e1

File tree

2 files changed

+160
-33
lines changed

2 files changed

+160
-33
lines changed

can-ajax-test.js

Lines changed: 143 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -285,20 +285,20 @@ if(typeof XDomainRequest === 'undefined') {
285285
QUnit.test("cross domain post request should change data to form data (#90)", function (assert) {
286286
var done = assert.async();
287287
var headers = {},
288-
restore = makeFixture(function () {
289-
this.open = function (type, url) {};
290-
291-
this.send = function () {
292-
this.readyState = 4;
293-
this.status = 204;
294-
this.responseText = '';
295-
this.onreadystatechange();
296-
};
297-
298-
this.setRequestHeader = function (header, value) {
299-
headers[header] = value;
300-
};
301-
});
288+
restore = makeFixture(function () {
289+
this.open = function (type, url) {};
290+
291+
this.send = function () {
292+
this.readyState = 4;
293+
this.status = 204;
294+
this.responseText = '';
295+
this.onreadystatechange();
296+
};
297+
298+
this.setRequestHeader = function (header, value) {
299+
headers[header] = value;
300+
};
301+
});
302302
ajax({
303303
type: "POST",
304304
url: "https://httpbin.org/post",
@@ -569,23 +569,71 @@ QUnit.test("It doesn't stringify FormData", function(assert) {
569569
});
570570
});
571571

572-
QUnit.test("beforsend", function (assert) {
572+
QUnit.test("abort", function (assert) {
573+
var done = assert.async();
574+
var restore = makeFixture(function () {
575+
var aborted = false;
576+
this.open = function (type, url) {};
577+
this.setRequestHeader = function (header, value) {};
578+
this.send = function () {};
579+
this.abort = function() {
580+
assert.ok(true, 'called the underlying XHR.abort');
581+
done();
582+
};
583+
});
584+
585+
var request = ajax({
586+
url: "/foo"
587+
});
588+
589+
request.abort();
590+
});
591+
592+
QUnit.test("abort prevents sending if beforeSend is not finished", function (assert) {
593+
var done = assert.async();
594+
var restore = makeFixture(function () {
595+
var aborted = false;
596+
this.open = function (type, url) {};
597+
this.setRequestHeader = function (header, value) {};
598+
this.abort = function() {
599+
assert.ok(true, 'XHR abort was called');
600+
};
601+
this.send = function () {
602+
assert.notOk(true, 'should not have been called');
603+
};
604+
});
605+
606+
var request = ajax({
607+
url: "/foo",
608+
beforeSend: function (xhr){
609+
return new Promise(resolve => {
610+
setTimeout(resolve, 1);
611+
});
612+
}
613+
});
614+
615+
request.abort();
616+
617+
setTimeout(done, 10);
618+
});
619+
620+
QUnit.test("beforeSend", function (assert) {
573621
var done = assert.async();
574622
var headers = {},
575-
restore = makeFixture(function () {
576-
this.open = function (type, url) {};
623+
restore = makeFixture(function () {
624+
this.open = function (type, url) {};
577625

578-
this.send = function () {
579-
this.readyState = 4;
580-
this.status = 204;
581-
this.responseText = '';
582-
this.onreadystatechange();
583-
};
626+
this.send = function () {
627+
this.readyState = 4;
628+
this.status = 204;
629+
this.responseText = '';
630+
this.onreadystatechange();
631+
};
584632

585-
this.setRequestHeader = function (header, value) {
586-
headers[header] = value;
587-
};
588-
});
633+
this.setRequestHeader = function (header, value) {
634+
headers[header] = value;
635+
};
636+
});
589637

590638
ajax({
591639
type: "post",
@@ -594,11 +642,15 @@ QUnit.test("beforsend", function (assert) {
594642
id: "qux"
595643
},
596644
dataType: "json",
645+
xhrFields: {
646+
'CustomHeader': 'CustomValue'
647+
},
597648
beforeSend: function (xhr){
649+
assert.ok(xhr.hasOwnProperty('CustomHeader'), "xhrField header set");
598650
xhr.setRequestHeader("Authorization", "Bearer 123");
599651
}
600652
}).then(function (value) {
601-
assert.ok(headers.hasOwnProperty('Authorization'), "custom header set");
653+
assert.ok(headers.hasOwnProperty('Authorization'), "authorization header set");
602654
}, function (reason) {
603655
assert.notOk(reason, "request failed with reason = ", reason);
604656
}).then(function () {
@@ -607,3 +659,66 @@ QUnit.test("beforsend", function (assert) {
607659
done();
608660
});
609661
});
662+
663+
QUnit.test("beforeSend async", function (assert) {
664+
var done = assert.async();
665+
var headers = {};
666+
var restore = makeFixture(function () {
667+
this.open = function (type, url) {};
668+
669+
this.send = function () {
670+
this.readyState = 4;
671+
this.status = 204;
672+
this.responseText = '';
673+
this.onreadystatechange();
674+
};
675+
676+
this.setRequestHeader = function (header, value) {
677+
headers[header] = value;
678+
};
679+
});
680+
681+
ajax({
682+
url: "/foo",
683+
beforeSend: function (xhr){
684+
return new Promise(resolve => {
685+
setTimeout(() => {
686+
xhr.setRequestHeader("Authorization", "Bearer 123");
687+
resolve();
688+
}, 1);
689+
});
690+
}
691+
}).then(function (value) {
692+
assert.ok(headers.hasOwnProperty('Authorization'), "authorization header set");
693+
}, function (reason) {
694+
assert.notOk(reason, "request failed with reason = ", reason);
695+
}).then(done);
696+
});
697+
698+
QUnit.test("beforeSend rejects the ajax promise on failure", function (assert) {
699+
var done = assert.async();
700+
var error = new Error();
701+
var restore = makeFixture(function () {
702+
this.open = function (type, url) {};
703+
this.send = function () {
704+
assert.notOk(true, 'Should not be called');
705+
};
706+
this.setRequestHeader = function (header, value) {};
707+
});
708+
709+
ajax({
710+
url: "/foo",
711+
beforeSend: function (xhr){
712+
return new Promise((resolve, reject) => {
713+
setTimeout(() => {
714+
reject(error);
715+
}, 1);
716+
});
717+
}
718+
}).then(function (value) {
719+
assert.notOk(true, "request should have rejected");
720+
}, function (reason) {
721+
assert.ok(true, "request rejected");
722+
assert.equal(reason, error, "error is what we expect");
723+
}).then(done);
724+
});

can-ajax.js

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -137,8 +137,10 @@ function ajax(o) {
137137
deferred.reject = reject;
138138
});
139139
var requestUrl;
140+
var isAborted = false;
140141

141142
promise.abort = function () {
143+
isAborted = true;
142144
xhr.abort();
143145
};
144146

@@ -244,17 +246,27 @@ function ajax(o) {
244246
xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
245247
}
246248

247-
if(o.beforeSend){
248-
o.beforeSend.call( o, xhr, o );
249-
}
250-
251249
if (o.xhrFields) {
252250
for (var f in o.xhrFields) {
253251
xhr[f] = o.xhrFields[f];
254252
}
255253
}
256254

257-
xhr.send(data);
255+
function send () {
256+
if(!isAborted) {
257+
xhr.send(data);
258+
}
259+
}
260+
261+
if(o.beforeSend){
262+
const result = o.beforeSend.call( o, xhr, o );
263+
if(canReflect.isPromise(result)) {
264+
result.then(send).catch(deferred.reject);
265+
return promise;
266+
}
267+
}
268+
269+
send();
258270
return promise;
259271
}
260272

0 commit comments

Comments
 (0)