Thu, 22 Jan 2015 13:21:57 +0100
Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6
1 <!DOCTYPE HTML>
2 <html>
3 <head>
4 <title>Test for XMLHttpRequest</title>
5 <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
6 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
7 </head>
8 <body onload="gen.next();">
9 <p id="display"></p>
10 <div id="content" style="display: none">
12 </div>
13 <pre id="test">
14 <script class="testbody" type="application/javascript;version=1.7">
15 "use strict";
16 SimpleTest.waitForExplicitFinish();
18 var gen = runTests();
19 function continueTest() { gen.next(); }
21 function runTests() {
23 var path = "/tests/content/base/test/";
25 var passFiles = [['file_XHR_pass1.xml', 'GET', 200, 'text/xml'],
26 ['file_XHR_pass2.txt', 'GET', 200, 'text/plain'],
27 ['file_XHR_pass3.txt', 'GET', 200, 'text/plain'],
28 ['data:text/xml,%3Cres%3Ehello%3C/res%3E%0A', 'GET', 0, 'text/xml'],
29 ['data:text/plain,hello%20pass%0A', 'GET', 0, 'text/plain'],
30 ['data:,foo', 'GET', 0, 'text/plain;charset=US-ASCII', 'foo'],
31 ['data:text/plain;base64,Zm9v', 'GET', 0, 'text/plain', 'foo'],
32 ['data:text/plain,foo#bar', 'GET', 0, 'text/plain', 'foo'],
33 ['data:text/plain,foo%23bar', 'GET', 0, 'text/plain', 'foo#bar'],
34 ];
36 var failFiles = [['//example.com' + path + 'file_XHR_pass1.xml', 'GET'],
37 ['ftp://localhost' + path + 'file_XHR_pass1.xml', 'GET'],
38 ['file_XHR_fail1.txt', 'GET'],
39 ];
41 for (i = 0; i < passFiles.length; ++i) {
42 xhr = new XMLHttpRequest();
43 is(xhr.getResponseHeader("Content-Type"), null, "should be null");
44 is(xhr.getAllResponseHeaders(), "", "should be empty string");
45 is(xhr.responseType, "", "wrong initial responseType");
46 xhr.open(passFiles[i][1], passFiles[i][0], false);
47 xhr.send(null);
48 is(xhr.status, passFiles[i][2], "wrong status");
49 is(xhr.getResponseHeader("Content-Type"), passFiles[i][3], "wrong content type");
50 var headers = xhr.getAllResponseHeaders();
51 ok(/(?:^|\n)Content-Type:\s*([^\r\n]*)\r\n/i.test(headers) &&
52 RegExp.$1 === passFiles[i][3], "wrong response headers");
53 if (xhr.responseXML) {
54 is((new XMLSerializer()).serializeToString(xhr.responseXML.documentElement),
55 passFiles[i][4] || "<res>hello</res>", "wrong responseXML");
56 is(xhr.response, passFiles[i][4] || "<res>hello</res>\n", "wrong response");
57 }
58 else {
59 is(xhr.responseText, passFiles[i][4] || "hello pass\n", "wrong responseText");
60 is(xhr.response, passFiles[i][4] || "hello pass\n", "wrong response");
61 }
62 }
64 for (i = 0; i < failFiles.length; ++i) {
65 xhr = new XMLHttpRequest();
66 var didthrow = false;
67 try {
68 xhr.open(failFiles[i][1], failFiles[i][0], false);
69 xhr.send(null);
70 }
71 catch (e) {
72 didthrow = true;
73 }
74 if (!didthrow) {
75 is(xhr.status, 301, "wrong status");
76 is(xhr.responseText, "redirect file\n", "wrong response");
77 }
78 else {
79 ok(1, "should have thrown or given incorrect result");
80 }
81 }
83 function checkResponseTextAccessThrows(xhr) {
84 var didthrow = false;
85 try { xhr.responseText } catch (e) { didthrow = true; }
86 ok(didthrow, "should have thrown when accessing responseText");
87 }
88 function checkResponseXMLAccessThrows(xhr) {
89 var didthrow = false;
90 try { xhr.responseXML } catch (e) { didthrow = true; }
91 ok(didthrow, "should have thrown when accessing responseXML");
92 }
93 function checkSetResponseTypeThrows(xhr, type) {
94 var didthrow = false;
95 try { xhr.responseType = type; } catch (e) { didthrow = true; }
96 ok(didthrow, "should have thrown when setting responseType");
97 }
98 function checkOpenThrows(xhr, method, url, async) {
99 var didthrow = false;
100 try { xhr.open(method, url, async); } catch (e) { didthrow = true; }
101 ok(didthrow, "should have thrown when open is called");
102 }
104 // test response (sync, responseType is not changeable)
105 xhr = new XMLHttpRequest();
106 xhr.open("GET", 'file_XHR_pass2.txt', false);
107 checkSetResponseTypeThrows(xhr, "");
108 checkSetResponseTypeThrows(xhr, "text");
109 checkSetResponseTypeThrows(xhr, "document");
110 checkSetResponseTypeThrows(xhr, "arraybuffer");
111 checkSetResponseTypeThrows(xhr, "blob");
112 checkSetResponseTypeThrows(xhr, "json");
113 checkSetResponseTypeThrows(xhr, "moz-chunked-text");
114 checkSetResponseTypeThrows(xhr, "moz-chunked-arraybuffer");
115 xhr.send(null);
116 checkSetResponseTypeThrows(xhr, "document");
117 is(xhr.status, 200, "wrong status");
118 is(xhr.response, "hello pass\n", "wrong response");
120 // test response (responseType='document')
121 xhr = new XMLHttpRequest();
122 xhr.open("GET", 'file_XHR_pass1.xml');
123 xhr.responseType = 'document';
124 xhr.onloadend = continueTest;
125 xhr.send(null);
126 yield undefined;
127 checkSetResponseTypeThrows(xhr, "document");
128 is(xhr.status, 200, "wrong status");
129 checkResponseTextAccessThrows(xhr);
130 is((new XMLSerializer()).serializeToString(xhr.response.documentElement),
131 "<res>hello</res>",
132 "wrong response");
134 // test response (responseType='text')
135 xhr = new XMLHttpRequest();
136 xhr.open("GET", 'file_XHR_pass2.txt');
137 xhr.responseType = 'text';
138 xhr.onloadend = continueTest;
139 xhr.send(null);
140 yield undefined;
141 is(xhr.status, 200, "wrong status");
142 checkResponseXMLAccessThrows(xhr);
143 is(xhr.response, "hello pass\n", "wrong response");
145 // test response (responseType='arraybuffer')
146 function arraybuffer_equals_to(ab, s) {
147 is(ab.byteLength, s.length, "wrong arraybuffer byteLength");
149 var u8v = new Uint8Array(ab);
150 is(String.fromCharCode.apply(String, u8v), s, "wrong values");
151 }
153 // with a simple text file
154 xhr = new XMLHttpRequest();
155 xhr.open("GET", 'file_XHR_pass2.txt');
156 xhr.responseType = 'arraybuffer';
157 xhr.onloadend = continueTest;
158 xhr.send(null);
159 yield undefined;
160 is(xhr.status, 200, "wrong status");
161 checkResponseTextAccessThrows(xhr);
162 checkResponseXMLAccessThrows(xhr);
163 var ab = xhr.response;
164 ok(ab != null, "should have a non-null arraybuffer");
165 arraybuffer_equals_to(ab, "hello pass\n");
167 // test reusing the same XHR (Bug 680816)
168 xhr.open("GET", 'file_XHR_binary1.bin');
169 xhr.responseType = 'arraybuffer';
170 xhr.onloadend = continueTest;
171 xhr.send(null);
172 yield undefined;
173 is(xhr.status, 200, "wrong status");
174 var ab2 = xhr.response;
175 ok(ab2 != null, "should have a non-null arraybuffer");
176 ok(ab2 != ab, "arraybuffer on XHR reuse should be distinct");
177 arraybuffer_equals_to(ab, "hello pass\n");
178 arraybuffer_equals_to(ab2, "\xaa\xee\0\x03\xff\xff\xff\xff\xbb\xbb\xbb\xbb");
180 // with a binary file
181 xhr = new XMLHttpRequest();
182 xhr.open("GET", 'file_XHR_binary1.bin');
183 xhr.responseType = 'arraybuffer';
184 xhr.onloadend = continueTest;
185 xhr.send(null);
186 yield undefined;
187 is(xhr.status, 200, "wrong status");
188 checkResponseTextAccessThrows(xhr);
189 checkResponseXMLAccessThrows(xhr);
190 ab = xhr.response;
191 ok(ab != null, "should have a non-null arraybuffer");
192 arraybuffer_equals_to(ab, "\xaa\xee\0\x03\xff\xff\xff\xff\xbb\xbb\xbb\xbb");
193 is(xhr.response, xhr.response, "returns the same ArrayBuffer");
195 // test response (responseType='json')
196 var xhr = new XMLHttpRequest();
197 xhr.open("POST", 'responseIdentical.sjs');
198 xhr.responseType = 'json';
199 var jsonObjStr = JSON.stringify({title: "aBook", author: "john"});
200 xhr.onloadend = continueTest;
201 xhr.send(jsonObjStr);
202 yield undefined;
203 is(xhr.status, 200, "wrong status");
204 checkResponseTextAccessThrows(xhr);
205 checkResponseXMLAccessThrows(xhr);
206 is(JSON.stringify(xhr.response), jsonObjStr, "correct result");
207 is(xhr.response, xhr.response, "returning the same object on each access");
209 // with invalid json
210 var xhr = new XMLHttpRequest();
211 xhr.open("POST", 'responseIdentical.sjs');
212 xhr.responseType = 'json';
213 xhr.onloadend = continueTest;
214 xhr.send("{");
215 yield undefined;
216 is(xhr.status, 200, "wrong status");
217 checkResponseTextAccessThrows(xhr);
218 checkResponseXMLAccessThrows(xhr);
219 is(xhr.response, null, "Bad JSON should result in null response.");
220 is(xhr.response, null, "Bad JSON should result in null response even 2nd time.");
222 // Test status/statusText in all readyStates
223 xhr = new XMLHttpRequest();
224 function checkXHRStatus() {
225 if (xhr.readyState == xhr.UNSENT || xhr.readyState == xhr.OPENED) {
226 is(xhr.status, 0, "should be 0 before getting data");
227 is(xhr.statusText, "", "should be empty before getting data");
228 }
229 else {
230 is(xhr.status, 200, "should be 200 when we have data");
231 is(xhr.statusText, "OK", "should be OK when we have data");
232 }
233 }
234 checkXHRStatus();
235 xhr.open("GET", 'file_XHR_binary1.bin');
236 checkXHRStatus();
237 xhr.responseType = 'arraybuffer';
238 xhr.send(null);
239 xhr.onreadystatechange = continueTest;
240 while (xhr.readyState != 4) {
241 checkXHRStatus();
242 yield undefined;
243 }
244 checkXHRStatus();
246 // test response (responseType='blob')
247 var responseTypes = ['blob', 'moz-blob'];
248 for (var i = 0; i < responseTypes.length; i++) {
249 var t = responseTypes[i];
250 // with a simple text file
251 xhr = new XMLHttpRequest();
252 xhr.open("GET", 'file_XHR_pass2.txt');
253 xhr.responseType = t;
254 xhr.onloadend = continueTest;
255 xhr.send(null);
256 yield undefined;
257 is(xhr.status, 200, "wrong status");
258 checkResponseTextAccessThrows(xhr);
259 checkResponseXMLAccessThrows(xhr);
260 var b = xhr.response;
261 ok(b, "should have a non-null blob");
262 ok(b instanceof Blob, "should be a Blob");
263 ok(!(b instanceof File), "should not be a File");
264 is(b.size, "hello pass\n".length, "wrong blob size");
266 var fr = new FileReader();
267 fr.onload = continueTest;
268 fr.readAsBinaryString(b);
269 yield undefined;
270 ok(fr.result, "hello pass\n", "wrong values");
272 // with a binary file
273 xhr = new XMLHttpRequest();
274 xhr.open("GET", 'file_XHR_binary1.bin', true);
275 xhr.send(null);
276 xhr.onreadystatechange = continueTest;
277 while(xhr.readyState != 2)
278 yield undefined;
280 is(xhr.status, 200, "wrong status");
281 xhr.responseType = t;
283 while(xhr.readyState != 4)
284 yield undefined;
286 xhr.onreadystatechange = null;
288 b = xhr.response;
289 ok(b != null, "should have a non-null blob");
290 is(b.size, 12, "wrong blob size");
292 fr = new FileReader();
293 fr.readAsBinaryString(b);
294 xhr = null; // kill the XHR object
295 b = null;
296 SpecialPowers.gc();
297 fr.onload = continueTest;
298 yield undefined;
299 is(fr.result, "\xaa\xee\0\x03\xff\xff\xff\xff\xbb\xbb\xbb\xbb", "wrong values");
301 // with a larger binary file
302 xhr = new XMLHttpRequest();
303 xhr.open("GET", 'file_XHR_binary2.bin', true);
304 xhr.responseType = t;
305 xhr.send(null);
306 xhr.onreadystatechange = continueTest;
308 while (xhr.readyState != 4)
309 yield undefined;
311 xhr.onreadystatechange = null;
313 var b = xhr.response;
314 ok(b != null, "should have a non-null blob");
315 is(b.size, 65536, "wrong blob size");
317 fr = new FileReader();
318 fr.readAsArrayBuffer(b);
319 fr.onload = continueTest;
320 xhr = null; // kill the XHR object
321 b = null;
322 SpecialPowers.gc();
323 yield undefined;
325 var u8 = new Uint8Array(fr.result);
326 for (var i = 0; i < 65536; i++) {
327 if (u8[i] !== (i & 255)) {
328 break;
329 }
330 }
331 is(i, 65536, "wrong value at offset " + i);
332 }
334 var client = new XMLHttpRequest();
335 client.open("GET", "file_XHR_pass1.xml", true);
336 client.send();
337 client.onreadystatechange = function() {
338 if(client.readyState == 4) {
339 try {
340 is(client.responseXML, null, "responseXML should be null.");
341 is(client.responseText, "", "responseText should be empty string.");
342 is(client.response, "", "response should be empty string.");
343 is(client.status, 0, "status should be 0.");
344 is(client.statusText, "", "statusText should be empty string.");
345 is(client.getAllResponseHeaders(), "",
346 "getAllResponseHeaders() should return empty string.");
347 } catch(ex) {
348 ok(false, "Shouldn't throw! [" + ex + "]");
349 }
350 }
351 }
352 client.abort();
354 SimpleTest.finish();
355 yield undefined;
357 } /* runTests */
358 </script>
359 </pre>
360 </body>
361 </html>