UNPKG

@qooxdoo/framework

Version:

The JS Framework for Coders

578 lines (421 loc) 13.8 kB
/* ************************************************************************ qooxdoo - the new era of web development http://qooxdoo.org Copyright: 2004-2011 1&1 Internet AG, Germany, http://www.1und1.de License: MIT: https://opensource.org/licenses/MIT See the LICENSE file in the project's top-level directory for details. Authors: * Tristan Koch (tristankoch) ************************************************************************ */ /* ************************************************************************ ************************************************************************ */ /** * @ignore(Klass) * @asset(qx/test/xmlhttp/*) */ /** * Tests asserting shared behavior of io.request.* classes. Also provides * common helpers. * * It should be noted that tests defined here fake an ideal transport. The * transport itself is tested elsewhere (see {@link qx.test.bom.request}). */ qx.Mixin.define("qx.test.io.request.MRequest", { members : { setUpKlass: function() { qx.Class.define("Klass", { extend : qx.core.Object, properties : { affe: { init: true } } }); }, // // General // "test: dispose transport on destruct": function() { this.req.dispose(); this.wait(100, function() { this.assertCalled(this.transport.dispose); }, this); }, "test: getTransport()": function() { this.assertEquals(this.transport, this.req.getTransport()); }, // // Send // "test: send() GET": function() { this.req.send(); this.assertCalledWith(this.transport.open, "GET", "url"); this.assertCalled(this.transport.send); }, "test: drop fragment from URL": function() { this.req.setUrl("example.com#fragment"); this.req.send(); this.assertCalledWith(this.transport.open, "GET", "example.com"); }, // // Abort // "test: abort request": function() { this.req.abort(); this.assertCalled(this.transport.abort); }, // // Data // "test: not send data with GET request": function() { this.req.setRequestData("str"); this.req.send(); this.assertCalledWith(this.transport.send, undefined); }, "test: append string data to URL with GET request": function() { this.req.setRequestData("str"); this.req.send(); this.assertCalledWith(this.transport.open, "GET", "url?str"); }, "test: append obj data to URL with GET request": function() { this.req.setRequestData({affe: true}); this.req.send(); this.assertCalledWith(this.transport.open, "GET", "url?affe=true"); }, "test: append qooxdoo obj data to URL with GET request": function() { this.setUpKlass(); var obj = new Klass(); this.req.setRequestData(obj); this.req.send(); this.assertCalledWith(this.transport.open, "GET", "url?affe=true"); obj.dispose(); }, "test: append FormData to URL with POST request": function() { if (!window.FormData) { this.skip("FormData API not supported"); } if (!this.req.setMethod) { this.skip("POST requests not supported by this transport"); } var formData = new FormData(); formData.append("foo", "bar"); formData.append("baz", "qux"); this.req.setMethod("POST"); this.req.setRequestData(formData); this.req.send(); this.assertCalledWith(this.transport.send, formData); }, // // Header and Params // "test: set request header": function() { this.req.setRequestHeader("key", "value"); this.req.send(); this.assertCalledWith(this.transport.setRequestHeader, "key", "value"); }, "test: set request header does not append": function() { var stub = this.transport.setRequestHeader.withArgs("key", "value"); this.req.setRequestHeader("key", "value"); this.req.setRequestHeader("key", "value"); this.req.send(); this.assertCalledOnce(stub.withArgs("key", "value")); }, "test: get request header": function() { this.req.setRequestHeader("key", "value"); this.assertEquals("value", this.req.getRequestHeader("key")); }, "test: remove request header": function() { var stub; this.req.setRequestHeader("key", "value"); this.req.removeRequestHeader("key"); stub = this.transport.setRequestHeader.withArgs("key", "value"); this.req.send(); this.assertNotCalled(stub); }, "test: get all request headers": function() { this.req.setRequestHeader("key", "value"); this.req.setRequestHeader("otherkey", "value"); this.assertEquals("value", this.req._getAllRequestHeaders()["key"]); this.assertEquals("value", this.req._getAllRequestHeaders()["otherkey"]); }, "test: get all request headers includes configuration dependent headers": function() { this.req.setRequestHeader("key", "value"); this.req._getConfiguredRequestHeaders = function() { return {"otherkey": "value"}; }; this.assertEquals("value", this.req._getAllRequestHeaders()["key"]); this.assertEquals("value", this.req._getAllRequestHeaders()["otherkey"]); }, "test: not append cache parameter to URL": function() { this.req.send(); var msg = "nocache parameter must not be set"; this.assertFalse(/\?nocache/.test(this.transport.open.args[0][1]), msg); }, "test: append nocache parameter to URL": function() { this.req.setCache(false); this.req.send(); var msg = "nocache parameter must be set to number"; this.assertTrue(/\?nocache=\d{13,}/.test(this.transport.open.args[0][1]), msg); }, // // Events // "test: fire readyStateChange": function() { var req = this.req, readystatechange = this.spy(); req.addListener("readyStateChange", readystatechange); this.respond(); this.assertCalledOnce(readystatechange); }, "test: fire success": function() { var req = this.req, success = this.spy(); req.addListener("success", success); this.respond(); this.assertCalledOnce(success); }, "test: not fire success on erroneous status": function() { var req = this.req, success = this.spy(); req.addListener("success", success); this.respond(500); this.assertNotCalled(success); }, "test: fire load": function() { var req = this.req, load = this.spy(); req.addListener("load", load); this.respond(); this.assertCalledOnce(load); }, "test: fire loadEnd": function() { var req = this.req, loadEnd = this.spy(); req.addListener("loadEnd", loadEnd); this.respond(); this.assertCalledOnce(loadEnd); }, "test: fire abort": function() { var req = this.req, abort = this.spy(); req.addListener("abort", abort); this.transport.onabort(); this.assertCalledOnce(abort); }, "test: fire timeout": function() { var req = this.req, transport = this.transport, timeout = this.spy(); req.setTimeout(100); req.send(); req.addListener("timeout", timeout); transport.ontimeout(); this.assertEquals(100, transport.timeout); this.assertCalledOnce(timeout); }, "test: fire error": function() { var req = this.req, error = this.spy(); req.addListener("error", error); this.respondError(); this.assertCalledOnce(error); }, "test: fire statusError": function() { var req = this.req, statusError = this.spy(); req.addListener("statusError", statusError); this.respond(500); this.assertCalledOnce(statusError); }, "test: fire fail on erroneous status": function() { var req = this.req, fail = this.spy(); req.addListener("fail", fail); this.respond(500); this.assertCalledOnce(fail); }, "test: fire fail on network error": function() { var req = this.req, fail = this.spy(); req.addListener("fail", fail); this.respondError(); this.assertCalledOnce(fail); }, "test: fire fail on timeout": function() { var req = this.req, fail = this.spy(); req.addListener("fail", fail); this.timeout(); this.assertCalledOnce(fail); }, "test: fire changePhase": function() { var req = this.req, that = this; this.assertEventFired(req, "changePhase", function() { that.respond(); }, function(evt) { that.assertMatch(evt.getData(), "load|success"); }); }, // // Phase // "test: phase is unsent": function() { this.assertEquals("unsent", this.req.getPhase()); }, "test: phase was open before send": function() { var req = this.req, phases = []; req.addListener("changePhase", function() { phases.push(req.getPhase()); }); req.setUrl("/url"); req.send(); this.assertArrayEquals(["opened", "sent"], phases); }, "test: phase is sent": function() { var req = this.req; req.setUrl("/url"); req.send(); this.assertEquals("sent", req.getPhase()); }, "test: phase is loading": function() { var req = this.req, transport = this.transport; transport.readyState = 3; transport.onreadystatechange(); this.assertEquals("loading", req.getPhase()); }, "test: phase is load intermediately": function() { var req = this.req, transport = this.transport, phases = []; req.addListener("changePhase", function() { phases.push(req.getPhase()); }); transport.readyState = 4; transport.onreadystatechange(); // phases = ["load", "statusError"] this.assertEquals("load", phases[0]); }, "test: phase is success": function() { var req = this.req; this.respond(); this.assertEquals("success", req.getPhase()); }, // Error handling "test: phase is statusError": function() { var req = this.req; this.respond(500); this.assertEquals("statusError", req.getPhase()); }, "test: phase is abort": function() { var req = this.req, transport = this.transport; req.abort(); transport.onabort(); // Transport switches to readyState DONE on abort transport.readyState = 4; transport.onreadystatechange(); this.assertEquals("abort", req.getPhase()); }, "test: phase is abort when from cache": function() { var req = this.req, transport = this.transport; req.abort(); transport.onabort(); // Synchronously served from cached transport.status = 304; // Transport switches to readyState DONE on abort transport.readyState = 4; transport.onreadystatechange(); this.assertEquals("abort", req.getPhase()); }, "test: phase is abort on readyState DONE when aborted before": function() { var req = this.req, transport = this.transport; req.addListener("readyStateChange", function() { if (req.getReadyState() == 4) { this.assertEquals("abort", req.getPhase()); } }, this); req.send(); req.abort(); // Transport switches to readyState DONE on abort transport.readyState = 4; transport.onreadystatechange(); transport.onabort(); }, "test: phase is abort on readyState DONE when aborting loading": function() { var req = this.req, transport = this.transport; req.addListener("readyStateChange", function() { if (req.getReadyState() == 4) { this.assertEquals("abort", req.getPhase()); } }, this); req.send(); // Loading transport.readyState = 3; transport.onreadystatechange(); // Abort loading req.abort(); // Transport switches to readyState DONE on abort transport.readyState = 4; transport.onreadystatechange(); transport.onabort(); }, "test: phase is abort on loadEnd when aborted before": function() { var req = this.req, transport = this.transport; req.addListener("loadEnd", function() { this.assertEquals("abort", req.getPhase()); }, this); req.send(); req.abort(); // Transport fires "onloadend" on abort transport.readyState = 4; transport.onloadend(); transport.onabort(); }, "test: phase is timeout": function() { var req = this.req; this.timeout(); this.assertEquals("timeout", req.getPhase()); }, getFakeReq: function() { return this.getRequests().slice(-1)[0]; }, noCache: function(url) { return qx.util.Uri.appendParamsToUrl(url, "nocache=" + (new Date).valueOf()); }, respond: function(status, error) { var transport = this.transport; transport.status = typeof status === "undefined" ? 200 : status; transport.readyState = 4; transport.onreadystatechange(); (function() { if (error === "timeout") { transport.ontimeout(); return; } if (error === "network") { transport.onerror(); return; } transport.onload(); })(); transport.onloadend(); }, respondError: function() { this.respond(0, "network"); }, timeout: function() { this.respond(0, "timeout"); } } });