summaryrefslogtreecommitdiff
path: root/misc/openlayers/tests/Request.html
diff options
context:
space:
mode:
Diffstat (limited to 'misc/openlayers/tests/Request.html')
-rw-r--r--misc/openlayers/tests/Request.html524
1 files changed, 524 insertions, 0 deletions
diff --git a/misc/openlayers/tests/Request.html b/misc/openlayers/tests/Request.html
new file mode 100644
index 0000000..cd679c6
--- /dev/null
+++ b/misc/openlayers/tests/Request.html
@@ -0,0 +1,524 @@
+<html>
+<head>
+ <script src="OLLoader.js"></script>
+ <script type="text/javascript">
+ function setup() {
+ window._xhr = OpenLayers.Request.XMLHttpRequest;
+ var anon = new Function();
+ OpenLayers.Request.XMLHttpRequest = function() {};
+ OpenLayers.Request.XMLHttpRequest.prototype = {
+ open: anon,
+ setRequestHeader: anon,
+ send: anon
+ };
+ OpenLayers.Request.XMLHttpRequest.DONE = 4;
+ }
+ function teardown() {
+ OpenLayers.Request.XMLHttpRequest = window._xhr;
+ }
+
+ function test_defaultHeaders(t) {
+ setup();
+ t.plan(2);
+ var config = {
+ headers: {
+ x: 'y'
+ }
+ };
+ OpenLayers.Request.DEFAULT_CONFIG.headers = {
+ foo: 'bar'
+ };
+ var proto = OpenLayers.Request.XMLHttpRequest.prototype;
+ var issue = OpenLayers.Function.bind(OpenLayers.Request.issue,
+ OpenLayers.Request);
+
+ var headers = {};
+ var _setRequestHeader = proto.setRequestHeader;
+ proto.setRequestHeader = function(key, value) {
+ headers[key] = value;
+ };
+ request = issue(config);
+ t.eq(headers.foo, 'bar', "Header from DEFAULT_CONFIG set correctly");
+ t.eq(headers.x, 'y', "Header from config set correctly");
+ proto.setRequestHeader = _setRequestHeader;
+ OpenLayers.Request.DEFAULT_CONFIG.headers = {};
+ teardown();
+ }
+
+ function test_issue(t) {
+ setup();
+
+ t.plan(25);
+ var request, config;
+ var proto = OpenLayers.Request.XMLHttpRequest.prototype;
+ var issue = OpenLayers.Function.bind(OpenLayers.Request.issue,
+ OpenLayers.Request);
+
+ // test that issue returns a new XMLHttpRequest - 1 test
+ request = issue();
+ t.ok(request instanceof OpenLayers.Request.XMLHttpRequest,
+ "returns an XMLHttpRequest instance");
+
+ // test that issue calls xhr.open with correct args from config - 5 tests
+ var _open = proto.open;
+ config = {
+ method: "foo",
+ url: "http://nowhere",
+ async: "bar",
+ user: "uncle",
+ password: "sam"
+ };
+ proto.open = function(method, url, async, user, password) {
+ t.eq(method, config.method, "open called with correct method");
+ t.eq(url, config.url, "open called with correct url");
+ t.eq(async, config.async, "open called with correct async");
+ t.eq(user, config.user, "open called with correct user");
+ t.eq(password, config.password, "open called with correct password");
+ };
+ request = issue(config);
+
+ // test that params are serialized as query string - 1 test
+ config = {
+ method: "GET",
+ url: "http://example.com/",
+ params: {"foo": "bar"}
+ };
+ proto.open = function(method, url, async, user, password) {
+ t.eq(url, config.url + "?foo=bar", "params serialized as query string");
+ };
+ request = issue(config);
+
+ // test that empty params object doesn't produce query string - 1 test
+ config = {
+ method: "GET",
+ url: "http://example.com/",
+ params: {}
+ };
+ proto.open = function(method, url, async, user, password) {
+ t.eq(url, config.url, "empty params doesn't produce query string");
+ }
+ request = issue(config);
+
+ // test that query string doesn't get two ? separators
+ config = {
+ method: "GET",
+ url: "http://example.com/?existing=query",
+ params: {"foo": "bar"}
+ };
+ proto.open = function(method, url, async, user, password) {
+ t.eq(url, config.url + "&foo=bar", "existing query string gets extended with &");
+ }
+ request = issue(config);
+
+ // test that query string doesn't get ? followed by &
+ config = {
+ method: "GET",
+ url: "http://example.com/service?",
+ params: {"foo": "bar"}
+ };
+ proto.open = function(method, url, async, user, password) {
+ t.eq(url, config.url + "foo=bar", "existing query string ending with ? gets extended without &");
+ }
+ request = issue(config);
+
+ // reset open method
+ proto.open = _open;
+
+ // test that headers are correctly set - 6 tests
+ var _setRequestHeader = proto.setRequestHeader;
+ config = {
+ headers: {
+ foo: "bar",
+ chicken: "soup",
+ // This checks whether the autoadded 'X-Requested-With'-header
+ // can be overridden, even though the given key here is spelled
+ // in lowercase.
+ 'x-requested-with': 'humpty'
+ }
+ };
+ // we also track how often setRequestHeader is being called, it should
+ // be called once for every header, even with the above defined
+ // custom 'x-requested-with' header which we usually autoadd.
+ // If the numbers match, we make sure to not send duplicate headers like
+ // x-requested-with: humpty AND
+ // X-Requested-With: XMLHttpRequest
+ var actualSetHeaderCnt = 0;
+ var expectedSetHeaderCnt = 3; // and not four!
+ proto.setRequestHeader = function(key, value) {
+ actualSetHeaderCnt++;
+ t.ok(key in config.headers, "setRequestHeader called with key: " + key);
+ t.eq(value, config.headers[key], "setRequestHeader called with correct value: " + value);
+ };
+ request = issue(config);
+
+ t.eq(actualSetHeaderCnt, expectedSetHeaderCnt, 'A custom "x-requested-with" header overrides the default "X-Requested-With" header.');
+
+ proto.setRequestHeader = _setRequestHeader;
+
+ // test that callback is called (no scope) - 1 test
+ var unbound = function(request) {
+ t.ok(request instanceof OpenLayers.Request.XMLHttpRequest,
+ "unbound callback called with xhr instance");
+ }
+ config = {
+ callback: unbound
+ };
+ request = issue(config);
+ request.readyState = OpenLayers.Request.XMLHttpRequest.DONE;
+ request.onreadystatechange();
+
+ // test that callback is called (with scope) - 2 tests
+ var obj = {};
+ var bound = function(request) {
+ t.ok(this === obj, "bound callback has correct scope");
+ t.ok(request instanceof OpenLayers.Request.XMLHttpRequest,
+ "bound callback called with xhr instance");
+ }
+ config = {
+ callback: bound,
+ scope: obj
+ };
+ request = issue(config);
+ request.readyState = 4;
+ request.onreadystatechange();
+
+ // test that optional success callback is only called with 200s and
+ // failure is only called with non-200s
+ var _send = proto.send;
+ proto.send = function() {};
+
+ config = {
+ success: function(req) {
+ t.ok(!req.status || (req.status >= 200 && req.status < 300),
+ "success callback called with " + req.status + " status");
+ },
+ failure: function(req) {
+ t.ok(req.status && (req.status < 200 || req.status >= 300),
+ "failure callback called with " + req.status + " status");
+ }
+ };
+ request = issue(config);
+ request.readyState = 4;
+
+ // mock up status 200 (1 test)
+ request.status = 200;
+ request.onreadystatechange();
+
+ // mock up status 299 (1 test)
+ request.status = 299;
+ request.onreadystatechange();
+
+ // mock up status 100 (1 test)
+ request.status = 100;
+ request.onreadystatechange();
+
+ // mock up status 300 (1 test)
+ request.status = 300;
+ request.onreadystatechange();
+
+ // mock up a status null (1 test)
+ request.status = null;
+ request.onreadystatechange();
+
+ proto.send = _send;
+
+ teardown();
+ }
+
+ function test_delayed_send(t) {
+ t.plan(1);
+ var proto = OpenLayers.Request.XMLHttpRequest.prototype;
+ var _send = proto.send;
+
+ // test that send is called with data - 1 test
+ var config = {
+ method: "PUT",
+ data: "bling"
+ };
+ var got = {};
+ proto.send = function(data) {
+ got.data = data;
+ }
+ OpenLayers.Request.issue(config);
+
+ t.delay_call(1, function() {
+ t.eq(got.data, config.data, "proper data sent");
+ proto.send = _send;
+ });
+
+ }
+
+ function test_GET(t) {
+ t.plan(1);
+ var _issue = OpenLayers.Request.issue;
+ OpenLayers.Request.issue = function(config) {
+ t.eq(config.method, "GET", "calls issue with correct method");
+ }
+ OpenLayers.Request.GET();
+ OpenLayers.Request.issue = _issue;
+ }
+ function test_POST(t) {
+ t.plan(1);
+ var _issue = OpenLayers.Request.issue;
+ OpenLayers.Request.issue = function(config) {
+ t.eq(config.method, "POST", "calls issue with correct method");
+ }
+ OpenLayers.Request.POST();
+ OpenLayers.Request.issue = _issue;
+ }
+ function test_PUT(t) {
+ t.plan(1);
+ var _issue = OpenLayers.Request.issue;
+ OpenLayers.Request.issue = function(config) {
+ t.eq(config.method, "PUT", "calls issue with correct method");
+ }
+ OpenLayers.Request.PUT();
+ OpenLayers.Request.issue = _issue;
+ }
+ function test_DELETE(t) {
+ t.plan(1);
+ var _issue = OpenLayers.Request.issue;
+ OpenLayers.Request.issue = function(config) {
+ t.eq(config.method, "DELETE", "calls issue with correct method");
+ }
+ OpenLayers.Request.DELETE();
+ OpenLayers.Request.issue = _issue;
+ }
+ function test_HEAD(t) {
+ t.plan(1);
+ var _issue = OpenLayers.Request.issue;
+ OpenLayers.Request.issue = function(config) {
+ t.eq(config.method, "HEAD", "calls issue with correct method");
+ }
+ OpenLayers.Request.HEAD();
+ OpenLayers.Request.issue = _issue;
+ }
+ function test_OPTIONS(t) {
+ t.plan(1);
+ var _issue = OpenLayers.Request.issue;
+ OpenLayers.Request.issue = function(config) {
+ t.eq(config.method, "OPTIONS", "calls issue with correct method");
+ }
+ OpenLayers.Request.OPTIONS();
+ OpenLayers.Request.issue = _issue;
+ }
+
+ function test_events_success(t) {
+
+ t.plan(5);
+
+ var events = [];
+ function listener(event) {
+ events.push(event);
+ }
+
+ // set up event listeners
+ OpenLayers.Request.events.on({
+ complete: listener,
+ success: listener,
+ failure: listener
+ });
+
+ // issue a request that succeeds
+ OpenLayers.Request.GET({
+ url: ".", params: {bar: "baz"}, async: false
+ });
+ t.eq(events.length, 2, "two events logged");
+ t.eq(events[0].type, "complete", "first event is complete");
+ t.eq(events[1].type, "success", "second event is success");
+ t.ok(events[1].config, "success listener sent config");
+ t.eq(events[1].requestUrl, ".?bar=baz", "success listener sent config.url");
+
+ // remove event listeners
+ OpenLayers.Request.events.un({
+ complete: listener,
+ success: listener,
+ failure: listener
+ });
+
+ }
+
+ function test_events_failure(t) {
+
+ t.plan(5);
+
+ var events = [];
+ function listener(event) {
+ events.push(event);
+ }
+
+ // set up event listeners
+ OpenLayers.Request.events.on({
+ complete: listener,
+ success: listener,
+ failure: listener
+ });
+
+ // issue a request that succeeds
+ OpenLayers.Request.GET({
+ url: "foo", params: {bar: "baz"}, async: false
+ });
+ t.eq(events.length, 2, "two events logged");
+ t.eq(events[0].type, "complete", "first event is complete");
+ t.eq(events[1].type, "failure", "second event is failure");
+ t.ok(events[1].config, "failure listener sent config");
+ t.eq(events[1].requestUrl, "foo?bar=baz", "failure listener sent requestUrl");
+
+ // remove event listeners
+ OpenLayers.Request.events.un({
+ complete: listener,
+ success: listener,
+ failure: listener
+ });
+
+ }
+
+ function test_ProxyHost(t) {
+ t.plan(5);
+
+ /*
+ * Setup
+ */
+
+ setup();
+
+ var expectedURL;
+
+ var _ProxyHost = OpenLayers.ProxyHost;
+
+ var proto = OpenLayers.Request.XMLHttpRequest.prototype;
+ var _open = proto.open;
+ var log = [];
+ var port;
+ proto.open = function(method, url, async, user, password) {
+ log.push(url);
+ };
+
+ /*
+ * Test
+ */
+
+ // 2 tests
+ log = [];
+ OpenLayers.ProxyHost = "http://fooproxy/?url=";
+ expectedURL = "http://fooproxy/?url=http%3A%2F%2Fbar%3Fk1%3Dv1%26k2%3Dv2";
+ OpenLayers.Request.GET({url: "http://bar?k1=v1&k2=v2"});
+ t.eq(log.length, 1, "[1] XHR.open called once");
+ t.eq(log[0], expectedURL, "[1] the URL used for XHR is correct (" + log[0] + ")");
+
+ // 1 test
+ log = [];
+ OpenLayers.ProxyHost = "http://fooproxy/?url=";
+ port = window.location.port ? ':'+window.location.port : '';
+ expectedURL = window.location.protocol+"//"+window.location.hostname+port+"/service";
+ OpenLayers.Request.GET({url: expectedURL});
+ t.eq(log[0], expectedURL, "[2] proxy is not used when requesting the same server");
+
+ // 2 tests
+ log = [];
+ OpenLayers.ProxyHost = function(url) {
+ var p = OpenLayers.Util.getParameters(url);
+ var p = OpenLayers.Util.getParameterString(p);
+ return "http://barproxy/?" + p;
+ };
+ expectedURL = "http://barproxy/?k1=v1&k2=v2";
+ OpenLayers.Request.GET({url: "http://bar?k1=v1&k2=v2"});
+ t.eq(log.length, 1, "[3] XHR.open called once");
+ t.eq(log[0], expectedURL, "[3] the URL used for XHR is correct (" + log[0] + ")");
+
+ /*
+ * Teardown
+ */
+
+ OpenLayers.Request.XMLHttpRequest.prototype.open = _open;
+ OpenLayers.ProxyHost = _ProxyHost;
+ teardown();
+ }
+
+ function test_abort(t) {
+
+ t.plan(0);
+
+ var sendCalled;
+
+ // set up
+
+ var _open = OpenLayers.Request.XMLHttpRequest.prototype.open;
+ OpenLayers.Request.XMLHttpRequest.prototype.open = function() {
+ this.readyState = OpenLayers.Request.XMLHttpRequest.OPENED;
+ };
+
+ var _setRequestHeader = OpenLayers.Request.XMLHttpRequest.prototype.setRequestHeader;
+ OpenLayers.Request.XMLHttpRequest.prototype.setRequestHeader = function() {};
+
+ var _send = OpenLayers.Request.XMLHttpRequest.prototype.send;
+ OpenLayers.Request.XMLHttpRequest.prototype.send = function() {
+ sendCalled = true;
+ };
+
+ // test
+
+ sendCalled = false;
+ OpenLayers.Request.issue().abort();
+
+ t.delay_call(0.5, function() {
+ if (sendCalled) {
+ t.fail("Send should not be called because request is aborted");
+ }
+
+ // tear down
+ OpenLayers.Request.XMLHttpRequest.prototype.open = _open;
+ OpenLayers.Request.XMLHttpRequest.prototype.setRequestHeader = _setRequestHeader;
+ OpenLayers.Request.XMLHttpRequest.prototype.send = _send;
+ });
+ }
+
+ function test_abort2(t) {
+ t.plan(0);
+ var fail = false;
+ OpenLayers.Request.XMLHttpRequest.onsend = function(args) {
+ fail = true;
+ }
+ t.delay_call(0.5, function() {
+ if (fail === true) {
+ t.fail("Send should not be called because request is aborted");
+ }
+ OpenLayers.Request.XMLHttpRequest.onsend = null;
+ });
+ var req = OpenLayers.Request.GET();
+ req.abort();
+ }
+
+ function test_XRequestedWithHeaderAutoadded(t) {
+ t.plan( 2 );
+
+ var headerSet = false;
+ var headerGot = '';
+ var headerExpected = 'XMLHttpRequest';
+
+ // save to be able to restore later
+ var _setRequestHeader = OpenLayers.Request.XMLHttpRequest.prototype.setRequestHeader;
+
+ OpenLayers.Request.XMLHttpRequest.prototype.setRequestHeader = function(field, value) {
+ if (field === 'X-Requested-With') {
+ headerSet = true;
+ headerGot = value;
+ }
+ };
+
+ var req = OpenLayers.Request.issue({
+ url: location.href,
+ async: false
+ });
+
+ t.ok( headerSet, 'We call the method "setRequestHeader" to set a "X-Requested-With"-header' );
+ t.eq( headerGot, headerExpected, 'The "X-Requested-With"-header is set to "' + headerExpected + '" as expected.' );
+
+ // restore old setRequestHeader
+ OpenLayers.Request.XMLHttpRequest.prototype.setRequestHeader = _setRequestHeader;
+ }
+ </script>
+</head>
+<body>
+</body>
+</html>