Make sure that we don't try to double-encode params using the traditional style....
[jquery.git] / test / unit / ajax.js
1 module("ajax");
2
3 // Safari 3 randomly crashes when running these tests,
4 // but only in the full suite - you can run just the Ajax
5 // tests and they'll pass
6 //if ( !jQuery.browser.safari ) {
7
8 if ( !isLocal ) {
9
10 test("jQuery.ajax() - success callbacks", function() {
11         expect( 8 );
12
13         jQuery.ajaxSetup({ timeout: 0 });
14
15         stop();
16
17         setTimeout(function(){
18                 jQuery('#foo').ajaxStart(function(){
19                         ok( true, "ajaxStart" );
20                 }).ajaxStop(function(){
21                         ok( true, "ajaxStop" );
22                         start();
23                 }).ajaxSend(function(){
24                         ok( true, "ajaxSend" );
25                 }).ajaxComplete(function(){
26                         ok( true, "ajaxComplete" );
27                 }).ajaxError(function(){
28                         ok( false, "ajaxError" );
29                 }).ajaxSuccess(function(){
30                         ok( true, "ajaxSuccess" );
31                 });
32
33                 jQuery.ajax({
34                         url: url("data/name.html"),
35                         beforeSend: function(){ ok(true, "beforeSend"); },
36                         success: function(){ ok(true, "success"); },
37                         error: function(){ ok(false, "error"); },
38                         complete: function(){ ok(true, "complete"); }
39                 });
40         }, 13);
41 });
42
43 test("jQuery.ajax() - error callbacks", function() {
44         expect( 8 );
45         stop();
46
47         jQuery('#foo').ajaxStart(function(){
48                 ok( true, "ajaxStart" );
49         }).ajaxStop(function(){
50                 ok( true, "ajaxStop" );
51                 start();
52         }).ajaxSend(function(){
53                 ok( true, "ajaxSend" );
54         }).ajaxComplete(function(){
55                 ok( true, "ajaxComplete" );
56         }).ajaxError(function(){
57                 ok( true, "ajaxError" );
58         }).ajaxSuccess(function(){
59                 ok( false, "ajaxSuccess" );
60         });
61
62         jQuery.ajaxSetup({ timeout: 500 });
63
64         jQuery.ajax({
65                 url: url("data/name.php?wait=5"),
66                 beforeSend: function(){ ok(true, "beforeSend"); },
67                 success: function(){ ok(false, "success"); },
68                 error: function(){ ok(true, "error"); },
69                 complete: function(){ ok(true, "complete"); }
70         });
71 });
72
73 test(".load()) - 404 error callbacks", function() {
74         expect( 6 );
75         stop();
76
77         jQuery('#foo').ajaxStart(function(){
78                 ok( true, "ajaxStart" );
79         }).ajaxStop(function(){
80                 ok( true, "ajaxStop" );
81                 start();
82         }).ajaxSend(function(){
83                 ok( true, "ajaxSend" );
84         }).ajaxComplete(function(){
85                 ok( true, "ajaxComplete" );
86         }).ajaxError(function(){
87                 ok( true, "ajaxError" );
88         }).ajaxSuccess(function(){
89                 ok( false, "ajaxSuccess" );
90         });
91
92         jQuery("<div/>").load("data/404.html", function(){
93                 ok(true, "complete");
94         });
95 });
96
97 test("jQuery.ajax() - abort", function() {
98         expect( 6 );
99         stop();
100
101         jQuery('#foo').ajaxStart(function(){
102                 ok( true, "ajaxStart" );
103         }).ajaxStop(function(){
104                 ok( true, "ajaxStop" );
105                 start();
106         }).ajaxSend(function(){
107                 ok( true, "ajaxSend" );
108         }).ajaxComplete(function(){
109                 ok( true, "ajaxComplete" );
110         });
111
112         var xhr = jQuery.ajax({
113                 url: url("data/name.php?wait=5"),
114                 beforeSend: function(){ ok(true, "beforeSend"); },
115                 complete: function(){ ok(true, "complete"); }
116         });
117
118         xhr.abort();
119 });
120
121 test("Ajax events with context", function() {
122         expect(14);
123         
124         stop();
125         var context = document.createElement("div");
126         
127         function event(e){
128                 equals( this, context, e.type );
129         }
130
131         function callback(msg){
132                 return function(){
133                         equals( this, context, "context is preserved on callback " + msg );
134                 };
135         }
136
137         function nocallback(msg){
138                 return function(){
139                         equals( typeof this.url, "string", "context is settings on callback " + msg );
140                 };
141         }
142         
143         jQuery('#foo').add(context)
144                         .ajaxSend(event)
145                         .ajaxComplete(event)
146                         .ajaxError(event)
147                         .ajaxSuccess(event);
148
149         jQuery.ajax({
150                 url: url("data/name.html"),
151                 beforeSend: callback("beforeSend"),
152                 success: callback("success"),
153                 error: callback("error"),
154                 complete:function(){
155                         callback("complete").call(this);
156
157                         jQuery.ajax({
158                                 url: url("data/404.html"),
159                                 context: context,
160                                 beforeSend: callback("beforeSend"),
161                                 error: callback("error"),
162                                 complete: function(){
163                                         callback("complete").call(this);
164
165                                         jQuery('#foo').add(context).unbind();
166
167                                         jQuery.ajax({
168                                                 url: url("data/404.html"),
169                                                 beforeSend: nocallback("beforeSend"),
170                                                 error: nocallback("error"),
171                                                 complete: function(){
172                                                         nocallback("complete").call(this);
173                                                         start();
174                                                 }
175                                         });
176                                 }
177                         });
178                 },
179                 context:context
180         });
181 });
182
183 test("jQuery.ajax context modification", function() {
184         expect(1);
185
186         stop();
187
188         var obj = {}
189
190         jQuery.ajax({
191                 url: url("data/name.html"),
192                 context: obj,
193                 beforeSend: function(){
194                         this.test = "foo";
195                 },
196                 complete: function() {
197                         start();
198                 }
199         });
200
201         equals( obj.test, "foo", "Make sure the original object is maintained." );
202 });
203
204 test("jQuery.ajax() - disabled globals", function() {
205         expect( 3 );
206         stop();
207
208         jQuery('#foo').ajaxStart(function(){
209                 ok( false, "ajaxStart" );
210         }).ajaxStop(function(){
211                 ok( false, "ajaxStop" );
212         }).ajaxSend(function(){
213                 ok( false, "ajaxSend" );
214         }).ajaxComplete(function(){
215                 ok( false, "ajaxComplete" );
216         }).ajaxError(function(){
217                 ok( false, "ajaxError" );
218         }).ajaxSuccess(function(){
219                 ok( false, "ajaxSuccess" );
220         });
221
222         jQuery.ajax({
223                 global: false,
224                 url: url("data/name.html"),
225                 beforeSend: function(){ ok(true, "beforeSend"); },
226                 success: function(){ ok(true, "success"); },
227                 error: function(){ ok(false, "error"); },
228                 complete: function(){
229                   ok(true, "complete");
230                   setTimeout(function(){ start(); }, 13);
231                 }
232         });
233 });
234
235 test("jQuery.ajax - xml: non-namespace elements inside namespaced elements", function() {
236         expect(3);
237         stop();
238         jQuery.ajax({
239           url: url("data/with_fries.xml"),
240           dataType: "xml",
241           success: function(resp) {
242                 equals( jQuery("properties", resp).length, 1, 'properties in responseXML' );
243                 equals( jQuery("jsconf", resp).length, 1, 'jsconf in responseXML' );
244                 equals( jQuery("thing", resp).length, 2, 'things in responseXML' );
245                 start();
246           }
247         });
248 });
249
250 test("jQuery.ajax - beforeSend", function() {
251         expect(1);
252         stop();
253
254         var check = false;
255
256         jQuery.ajaxSetup({ timeout: 0 });
257
258         jQuery.ajax({
259                 url: url("data/name.html"),
260                 beforeSend: function(xml) {
261                         check = true;
262                 },
263                 success: function(data) {
264                         ok( check, "check beforeSend was executed" );
265                         start();
266                 }
267         });
268 });
269
270 test("jQuery.ajax - beforeSend, cancel request (#2688)", function() {
271         expect(2);
272         var request = jQuery.ajax({
273                 url: url("data/name.html"),
274                 beforeSend: function() {
275                         ok( true, "beforeSend got called, canceling" );
276                         return false;
277                 },
278                 success: function() {
279                         ok( false, "request didn't get canceled" );
280                 },
281                 complete: function() {
282                         ok( false, "request didn't get canceled" );
283                 },
284                 error: function() {
285                         ok( false, "request didn't get canceled" );
286                 }
287         });
288         ok( request === false, "canceled request must return false instead of XMLHttpRequest instance" );
289 });
290
291 window.foobar = null;
292 window.testFoo = undefined;
293
294 test("jQuery.ajax - dataType html", function() {
295         expect(5);
296         stop();
297
298         var verifyEvaluation = function() {
299                 equals( testFoo, "foo", 'Check if script was evaluated for datatype html' );
300                 equals( foobar, "bar", 'Check if script src was evaluated for datatype html' );
301
302                 start();
303         };
304
305         jQuery.ajax({
306           dataType: "html",
307           url: url("data/test.html"),
308           success: function(data) {
309                 jQuery("#ap").html(data);
310                 ok( data.match(/^html text/), 'Check content for datatype html' );
311                 setTimeout(verifyEvaluation, 600);
312           }
313         });
314 });
315
316 test("serialize()", function() {
317         expect(5);
318
319         // Add html5 elements only for serialize because selector can't yet find them on non-html5 browsers
320         jQuery("#search").after(
321                 '<input type="email" id="html5email" name="email" value="dave@jquery.com" />'+
322                 '<input type="number" id="html5number" name="number" value="43" />'
323         );
324
325         equals( jQuery('#form').serialize(),
326                 "action=Test&radio2=on&check=on&hidden=&foo%5Bbar%5D=&name=name&search=search&email=dave%40jquery.com&number=43&select1=&select2=3&select3=1&select3=2",
327                 'Check form serialization as query string');
328
329         equals( jQuery('#form :input').serialize(),
330                 "action=Test&radio2=on&check=on&hidden=&foo%5Bbar%5D=&name=name&search=search&email=dave%40jquery.com&number=43&select1=&select2=3&select3=1&select3=2",
331                 'Check input serialization as query string');
332
333         equals( jQuery('#testForm').serialize(),
334                 'T3=%3F%0AZ&H1=x&H2=&PWD=&T1=&T2=YES&My+Name=me&S1=abc&S3=YES&S4=',
335                 'Check form serialization as query string');
336
337         equals( jQuery('#testForm :input').serialize(),
338                 'T3=%3F%0AZ&H1=x&H2=&PWD=&T1=&T2=YES&My+Name=me&S1=abc&S3=YES&S4=',
339                 'Check input serialization as query string');
340
341         equals( jQuery('#form, #testForm').serialize(),
342                 "action=Test&radio2=on&check=on&hidden=&foo%5Bbar%5D=&name=name&search=search&email=dave%40jquery.com&number=43&select1=&select2=3&select3=1&select3=2&T3=%3F%0AZ&H1=x&H2=&PWD=&T1=&T2=YES&My+Name=me&S1=abc&S3=YES&S4=",
343                 'Multiple form serialization as query string');
344
345   /* Temporarily disabled. Opera 10 has problems with form serialization.
346         equals( jQuery('#form, #testForm :input').serialize(),
347                 "action=Test&radio2=on&check=on&hidden=&foo%5Bbar%5D=&name=name&search=search&email=dave%40jquery.com&number=43&select1=&select2=3&select3=1&select3=2&T3=%3F%0AZ&H1=x&H2=&PWD=&T1=&T2=YES&My+Name=me&S1=abc&S3=YES&S4=",
348                 'Mixed form/input serialization as query string');
349         */
350         jQuery("#html5email, #html5number").remove();
351 });
352
353 test("jQuery.param()", function() {
354         expect(19);
355         
356         equals( !jQuery.ajaxSettings.traditional, true, "traditional flag, falsy by default" );
357   
358         var params = {foo:"bar", baz:42, quux:"All your base are belong to us"};
359         equals( jQuery.param(params), "foo=bar&baz=42&quux=All+your+base+are+belong+to+us", "simple" );
360
361         params = {someName: [1, 2, 3], regularThing: "blah" };
362         equals( jQuery.param(params), "someName%5B%5D=1&someName%5B%5D=2&someName%5B%5D=3&regularThing=blah", "with array" );
363
364         params = {foo: ['a', 'b', 'c']};
365         equals( jQuery.param(params), "foo%5B%5D=a&foo%5B%5D=b&foo%5B%5D=c", "with array of strings" );
366
367         params = {foo: ["baz", 42, "All your base are belong to us"] };
368         equals( jQuery.param(params), "foo%5B%5D=baz&foo%5B%5D=42&foo%5B%5D=All+your+base+are+belong+to+us", "more array" );
369
370         params = {foo: { bar: 'baz', beep: 42, quux: 'All your base are belong to us' } };
371         equals( jQuery.param(params), "foo%5Bbar%5D=baz&foo%5Bbeep%5D=42&foo%5Bquux%5D=All+your+base+are+belong+to+us", "even more arrays" );
372         
373         params = { a:[1,2], b:{ c:3, d:[4,5], e:{ x:[6], y:7, z:[8,9] }, f:true, g:false, h:undefined }, i:[10,11], j:true, k:false, l:[undefined,0], m:"cowboy hat?" };
374         equals( decodeURIComponent( jQuery.param(params) ), "a[]=1&a[]=2&b[c]=3&b[d][]=4&b[d][]=5&b[e][x][]=6&b[e][y]=7&b[e][z][]=8&b[e][z][]=9&b[f]=true&b[g]=false&b[h]=undefined&i[]=10&i[]=11&j=true&k=false&l[]=undefined&l[]=0&m=cowboy+hat?", "huge structure" );
375         
376         params = { a: [ 0, [ 1, 2 ], [ 3, [ 4, 5 ], [ 6 ] ], { b: [ 7, [ 8, 9 ], [ { c: 10, d: 11 } ], [ [ 12 ] ], [ [ [ 13 ] ] ], { e: { f: { g: [ 14, [ 15 ] ] } } }, 16 ] }, 17 ] };
377         equals( decodeURIComponent( jQuery.param(params) ), "a[]=0&a[1][]=1&a[1][]=2&a[2][]=3&a[2][1][]=4&a[2][1][]=5&a[2][2][]=6&a[3][b][]=7&a[3][b][1][]=8&a[3][b][1][]=9&a[3][b][2][0][c]=10&a[3][b][2][0][d]=11&a[3][b][3][0][]=12&a[3][b][4][0][0][]=13&a[3][b][5][e][f][g][]=14&a[3][b][5][e][f][g][1][]=15&a[3][b][]=16&a[]=17", "nested arrays" );
378         
379         params = { a:[1,2], b:{ c:3, d:[4,5], e:{ x:[6], y:7, z:[8,9] }, f:true, g:false, h:undefined }, i:[10,11], j:true, k:false, l:[undefined,0], m:"cowboy hat?" };
380         equals( jQuery.param(params,true), "a=1&a=2&b=%5Bobject+Object%5D&i=10&i=11&j=true&k=false&l=undefined&l=0&m=cowboy+hat%3F", "huge structure, forced traditional" );
381
382         equals( decodeURIComponent( jQuery.param({ "test[]": [0, 1, 2] }) ), "test[]=0&test[]=1&test[]=2", "Make sure params are double-encoded." );
383         
384         jQuery.ajaxSetup({ traditional: true });
385         
386         var params = {foo:"bar", baz:42, quux:"All your base are belong to us"};
387         equals( jQuery.param(params), "foo=bar&baz=42&quux=All+your+base+are+belong+to+us", "simple" );
388
389         params = {someName: [1, 2, 3], regularThing: "blah" };
390         equals( jQuery.param(params), "someName=1&someName=2&someName=3&regularThing=blah", "with array" );
391
392         params = {foo: ['a', 'b', 'c']};
393         equals( jQuery.param(params), "foo=a&foo=b&foo=c", "with array of strings" );
394
395         params = {"foo[]":["baz", 42, "All your base are belong to us"]};
396         equals( jQuery.param(params), "foo%5B%5D=baz&foo%5B%5D=42&foo%5B%5D=All+your+base+are+belong+to+us", "more array" );
397
398         params = {"foo[bar]":"baz", "foo[beep]":42, "foo[quux]":"All your base are belong to us"};
399         equals( jQuery.param(params), "foo%5Bbar%5D=baz&foo%5Bbeep%5D=42&foo%5Bquux%5D=All+your+base+are+belong+to+us", "even more arrays" );
400         
401         params = { a:[1,2], b:{ c:3, d:[4,5], e:{ x:[6], y:7, z:[8,9] }, f:true, g:false, h:undefined }, i:[10,11], j:true, k:false, l:[undefined,0], m:"cowboy hat?" };
402         equals( jQuery.param(params), "a=1&a=2&b=%5Bobject+Object%5D&i=10&i=11&j=true&k=false&l=undefined&l=0&m=cowboy+hat%3F", "huge structure" );
403         
404         params = { a: [ 0, [ 1, 2 ], [ 3, [ 4, 5 ], [ 6 ] ], { b: [ 7, [ 8, 9 ], [ { c: 10, d: 11 } ], [ [ 12 ] ], [ [ [ 13 ] ] ], { e: { f: { g: [ 14, [ 15 ] ] } } }, 16 ] }, 17 ] };
405         equals( jQuery.param(params), "a=0&a=1%2C2&a=3%2C4%2C5%2C6&a=%5Bobject+Object%5D&a=17", "nested arrays (not possible when jQuery.param.traditional == true)" );
406         
407         params = { a:[1,2], b:{ c:3, d:[4,5], e:{ x:[6], y:7, z:[8,9] }, f:true, g:false, h:undefined }, i:[10,11], j:true, k:false, l:[undefined,0], m:"cowboy hat?" };
408         equals( decodeURIComponent( jQuery.param(params,false) ), "a[]=1&a[]=2&b[c]=3&b[d][]=4&b[d][]=5&b[e][x][]=6&b[e][y]=7&b[e][z][]=8&b[e][z][]=9&b[f]=true&b[g]=false&b[h]=undefined&i[]=10&i[]=11&j=true&k=false&l[]=undefined&l[]=0&m=cowboy+hat?", "huge structure, forced not traditional" );
409         
410         params = { param1: null };
411         equals( jQuery.param(params,false), "param1=null", "Make sure that null params aren't traversed." );
412 });
413
414 test("synchronous request", function() {
415         expect(1);
416         ok( /^{ "data"/.test( jQuery.ajax({url: url("data/json_obj.js"), dataType: "text", async: false}).responseText ), "check returned text" );
417 });
418
419 test("synchronous request with callbacks", function() {
420         expect(2);
421         var result;
422         jQuery.ajax({url: url("data/json_obj.js"), async: false, dataType: "text", success: function(data) { ok(true, "sucess callback executed"); result = data; } });
423         ok( /^{ "data"/.test( result ), "check returned text" );
424 });
425
426 test("pass-through request object", function() {
427         expect(8);
428         stop();
429
430         var target = "data/name.html";
431         var successCount = 0;
432         var errorCount = 0;
433         var errorEx = "";
434         var success = function() {
435                 successCount++;
436         };
437         jQuery("#foo").ajaxError(function (e, xml, s, ex) {
438                 errorCount++;
439                 errorEx += ": " + xml.status;
440         });
441         jQuery("#foo").one('ajaxStop', function () {
442                 equals(successCount, 5, "Check all ajax calls successful");
443                 equals(errorCount, 0, "Check no ajax errors (status" + errorEx + ")");
444                 jQuery("#foo").unbind('ajaxError');
445
446                 start();
447         });
448
449         ok( jQuery.get(url(target), success), "get" );
450         ok( jQuery.post(url(target), success), "post" );
451         ok( jQuery.getScript(url("data/test.js"), success), "script" );
452         ok( jQuery.getJSON(url("data/json_obj.js"), success), "json" );
453         ok( jQuery.ajax({url: url(target), success: success}), "generic" );
454 });
455
456 test("ajax cache", function () {
457         expect(18);
458         
459         stop();
460
461         var count = 0;
462
463         jQuery("#firstp").bind("ajaxSuccess", function (e, xml, s) {
464                 var re = /_=(.*?)(&|$)/g;
465                 var oldOne = null;
466                 for (var i = 0; i < 6; i++) {
467                         var ret = re.exec(s.url);
468                         if (!ret) {
469                                 break;
470                         }
471                         oldOne = ret[1];
472                 }
473                 equals(i, 1, "Test to make sure only one 'no-cache' parameter is there");
474                 ok(oldOne != "tobereplaced555", "Test to be sure parameter (if it was there) was replaced");
475                 if(++count == 6)
476                         start();
477         });
478
479         ok( jQuery.ajax({url: "data/text.php", cache:false}), "test with no parameters" );
480         ok( jQuery.ajax({url: "data/text.php?pizza=true", cache:false}), "test with 1 parameter" );
481         ok( jQuery.ajax({url: "data/text.php?_=tobereplaced555", cache:false}), "test with _= parameter" );
482         ok( jQuery.ajax({url: "data/text.php?pizza=true&_=tobereplaced555", cache:false}), "test with 1 parameter plus _= one" );
483         ok( jQuery.ajax({url: "data/text.php?_=tobereplaced555&tv=false", cache:false}), "test with 1 parameter plus _= one before it" );
484         ok( jQuery.ajax({url: "data/text.php?name=David&_=tobereplaced555&washere=true", cache:false}), "test with 2 parameters surrounding _= one" );
485 });
486
487 /*
488  * Test disabled.
489  * The assertions expect that the passed-in object will be modified,
490  * which shouldn't be the case. Fixes #5439.
491 test("global ajaxSettings", function() {
492         expect(2);
493
494         var tmp = jQuery.extend({}, jQuery.ajaxSettings);
495         var orig = { url: "data/with_fries.xml" };
496         var t;
497
498         jQuery.ajaxSetup({ data: {foo: 'bar', bar: 'BAR'} });
499
500         t = jQuery.extend({}, orig);
501         t.data = {};
502         jQuery.ajax(t);
503         ok( t.url.indexOf('foo') > -1 && t.url.indexOf('bar') > -1, "Check extending {}" );
504
505         t = jQuery.extend({}, orig);
506         t.data = { zoo: 'a', ping: 'b' };
507         jQuery.ajax(t);
508         ok( t.url.indexOf('ping') > -1 && t.url.indexOf('zoo') > -1 && t.url.indexOf('foo') > -1 && t.url.indexOf('bar') > -1, "Check extending { zoo: 'a', ping: 'b' }" );
509
510         jQuery.ajaxSettings = tmp;
511 });
512 */
513
514 test("load(String)", function() {
515         expect(1);
516         stop(); // check if load can be called with only url
517         jQuery('#first').load("data/name.html", start);
518 });
519
520 test("load('url selector')", function() {
521         expect(1);
522         stop(); // check if load can be called with only url
523         jQuery('#first').load("data/test3.html div.user", function(){
524                 equals( jQuery(this).children("div").length, 2, "Verify that specific elements were injected" );
525                 start();
526         });
527 });
528
529 test("load(String, Function) with ajaxSetup on dataType json, see #2046", function() {
530         expect(1);
531         stop();
532         jQuery.ajaxSetup({ dataType: "json" });
533         jQuery("#first").ajaxComplete(function (e, xml, s) {
534                 equals( s.dataType, "html", "Verify the load() dataType was html" );
535                 jQuery("#first").unbind("ajaxComplete");
536                 jQuery.ajaxSetup({ dataType: "" });
537                 start();
538         });
539         jQuery('#first').load("data/test3.html");
540 });
541
542 test("load(String, Function) - simple: inject text into DOM", function() {
543         expect(2);
544         stop();
545         jQuery('#first').load(url("data/name.html"), function() {
546                 ok( /^ERROR/.test(jQuery('#first').text()), 'Check if content was injected into the DOM' );
547                 start();
548         });
549 });
550
551 test("load(String, Function) - check scripts", function() {
552         expect(7);
553         stop();
554
555         var verifyEvaluation = function() {
556                 equals( foobar, "bar", 'Check if script src was evaluated after load' );
557                 equals( jQuery('#ap').html(), 'bar', 'Check if script evaluation has modified DOM');
558
559                 start();
560         };
561         jQuery('#first').load(url('data/test.html'), function() {
562                 ok( jQuery('#first').html().match(/^html text/), 'Check content after loading html' );
563                 equals( jQuery('#foo').html(), 'foo', 'Check if script evaluation has modified DOM');
564                 equals( testFoo, "foo", 'Check if script was evaluated after load' );
565                 setTimeout(verifyEvaluation, 600);
566         });
567 });
568
569 test("load(String, Function) - check file with only a script tag", function() {
570         expect(3);
571         stop();
572
573         jQuery('#first').load(url('data/test2.html'), function() {
574                 equals( jQuery('#foo').html(), 'foo', 'Check if script evaluation has modified DOM');
575                 equals( testFoo, "foo", 'Check if script was evaluated after load' );
576
577                 start();
578         });
579 });
580
581 test("load(String, Object, Function)", function() {
582         expect(2);
583         stop();
584
585         jQuery('<div />').load(url('data/params_html.php'), { foo:3, bar:'ok' }, function() {
586                 var $post = jQuery(this).find('#post');
587                 equals( $post.find('#foo').text(), '3', 'Check if a hash of data is passed correctly');
588                 equals( $post.find('#bar').text(), 'ok', 'Check if a hash of data is passed correctly');
589                 start();
590         });
591 });
592
593 test("load(String, String, Function)", function() {
594         expect(2);
595         stop();
596
597         jQuery('<div />').load(url('data/params_html.php'), 'foo=3&bar=ok', function() {
598                 var $get = jQuery(this).find('#get');
599                 equals( $get.find('#foo').text(), '3', 'Check if a string of data is passed correctly');
600                 equals( $get.find('#bar').text(), 'ok', 'Check if a      of data is passed correctly');
601                 start();
602         });
603 });
604
605 test("jQuery.get(String, Hash, Function) - parse xml and use text() on nodes", function() {
606         expect(2);
607         stop();
608         jQuery.get(url('data/dashboard.xml'), function(xml) {
609                 var content = [];
610                 jQuery('tab', xml).each(function() {
611                         content.push(jQuery(this).text());
612                 });
613                 equals( content[0], 'blabla', 'Check first tab');
614                 equals( content[1], 'blublu', 'Check second tab');
615                 start();
616         });
617 });
618
619 test("jQuery.getScript(String, Function) - with callback", function() {
620         expect(2);
621         stop();
622         jQuery.getScript(url("data/test.js"), function() {
623                 equals( foobar, "bar", 'Check if script was evaluated' );
624                 setTimeout(start, 100);
625         });
626 });
627
628 test("jQuery.getScript(String, Function) - no callback", function() {
629         expect(1);
630         stop();
631         jQuery.getScript(url("data/test.js"), function(){
632                 start();
633         });
634 });
635
636 test("jQuery.ajax() - JSONP, Local", function() {
637         expect(8);
638
639         var count = 0;
640         function plus(){ if ( ++count == 8 ) start(); }
641
642         stop();
643
644         jQuery.ajax({
645                 url: "data/jsonp.php",
646                 dataType: "jsonp",
647                 success: function(data){
648                         ok( data.data, "JSON results returned (GET, no callback)" );
649                         plus();
650                 },
651                 error: function(data){
652                         ok( false, "Ajax error JSON (GET, no callback)" );
653                         plus();
654                 }
655         });
656
657         jQuery.ajax({
658                 url: "data/jsonp.php?callback=?",
659                 dataType: "jsonp",
660                 success: function(data){
661                         ok( data.data, "JSON results returned (GET, url callback)" );
662                         plus();
663                 },
664                 error: function(data){
665                         ok( false, "Ajax error JSON (GET, url callback)" );
666                         plus();
667                 }
668         });
669
670         jQuery.ajax({
671                 url: "data/jsonp.php",
672                 dataType: "jsonp",
673                 data: "callback=?",
674                 success: function(data){
675                         ok( data.data, "JSON results returned (GET, data callback)" );
676                         plus();
677                 },
678                 error: function(data){
679                         ok( false, "Ajax error JSON (GET, data callback)" );
680                         plus();
681                 }
682         });
683
684         jQuery.ajax({
685                 url: "data/jsonp.php",
686                 dataType: "jsonp",
687                 jsonp: "callback",
688                 success: function(data){
689                         ok( data.data, "JSON results returned (GET, data obj callback)" );
690                         plus();
691                 },
692                 error: function(data){
693                         ok( false, "Ajax error JSON (GET, data obj callback)" );
694                         plus();
695                 }
696         });
697
698         jQuery.ajax({
699                 url: "data/jsonp.php",
700                 dataType: "jsonp",
701                 jsonpCallback: "jsonpResults",
702                 success: function(data){
703                         ok( data.data, "JSON results returned (GET, custom callback name)" );
704                         plus();
705                 },
706                 error: function(data){
707                         ok( false, "Ajax error JSON (GET, custom callback name)" );
708                         plus();
709                 }
710         });
711
712         jQuery.ajax({
713                 type: "POST",
714                 url: "data/jsonp.php",
715                 dataType: "jsonp",
716                 success: function(data){
717                         ok( data.data, "JSON results returned (POST, no callback)" );
718                         plus();
719                 },
720                 error: function(data){
721                         ok( false, "Ajax error JSON (GET, data obj callback)" );
722                         plus();
723                 }
724         });
725
726         jQuery.ajax({
727                 type: "POST",
728                 url: "data/jsonp.php",
729                 data: "callback=?",
730                 dataType: "jsonp",
731                 success: function(data){
732                         ok( data.data, "JSON results returned (POST, data callback)" );
733                         plus();
734                 },
735                 error: function(data){
736                         ok( false, "Ajax error JSON (POST, data callback)" );
737                         plus();
738                 }
739         });
740
741         jQuery.ajax({
742                 type: "POST",
743                 url: "data/jsonp.php",
744                 jsonp: "callback",
745                 dataType: "jsonp",
746                 success: function(data){
747                         ok( data.data, "JSON results returned (POST, data obj callback)" );
748                         plus();
749                 },
750                 error: function(data){
751                         ok( false, "Ajax error JSON (POST, data obj callback)" );
752                         plus();
753                 }
754         });
755 });
756
757 test("JSONP - Custom JSONP Callback", function() {
758         expect(1);
759         stop();
760
761         window.jsonpResults = function(data) {
762                 ok( data.data, "JSON results returned (GET, custom callback function)" );
763                 start();
764         };
765
766         jQuery.ajax({
767                 url: "data/jsonp.php",
768                 dataType: "jsonp",
769                 jsonpCallback: "jsonpResults"
770         });
771 });
772
773 test("jQuery.ajax() - JSONP, Remote", function() {
774         expect(4);
775
776         var count = 0;
777         function plus(){ if ( ++count == 4 ) start(); }
778
779         var base = window.location.href.replace(/\?.*$/, "");
780
781         stop();
782
783         jQuery.ajax({
784                 url: base + "data/jsonp.php",
785                 dataType: "jsonp",
786                 success: function(data){
787                         ok( data.data, "JSON results returned (GET, no callback)" );
788                         plus();
789                 },
790                 error: function(data){
791                         ok( false, "Ajax error JSON (GET, no callback)" );
792                         plus();
793                 }
794         });
795
796         jQuery.ajax({
797                 url: base + "data/jsonp.php?callback=?",
798                 dataType: "jsonp",
799                 success: function(data){
800                         ok( data.data, "JSON results returned (GET, url callback)" );
801                         plus();
802                 },
803                 error: function(data){
804                         ok( false, "Ajax error JSON (GET, url callback)" );
805                         plus();
806                 }
807         });
808
809         jQuery.ajax({
810                 url: base + "data/jsonp.php",
811                 dataType: "jsonp",
812                 data: "callback=?",
813                 success: function(data){
814                         ok( data.data, "JSON results returned (GET, data callback)" );
815                         plus();
816                 },
817                 error: function(data){
818                         ok( false, "Ajax error JSON (GET, data callback)" );
819                         plus();
820                 }
821         });
822
823         jQuery.ajax({
824                 url: base + "data/jsonp.php",
825                 dataType: "jsonp",
826                 jsonp: "callback",
827                 success: function(data){
828                         ok( data.data, "JSON results returned (GET, data obj callback)" );
829                         plus();
830                 },
831                 error: function(data){
832                         ok( false, "Ajax error JSON (GET, data obj callback)" );
833                         plus();
834                 }
835         });
836 });
837
838 test("jQuery.ajax() - script, Remote", function() {
839         expect(2);
840
841         var base = window.location.href.replace(/\?.*$/, "");
842
843         stop();
844
845         jQuery.ajax({
846                 url: base + "data/test.js",
847                 dataType: "script",
848                 success: function(data){
849                         ok( foobar, "Script results returned (GET, no callback)" );
850                         start();
851                 }
852         });
853 });
854
855 test("jQuery.ajax() - script, Remote with POST", function() {
856         expect(3);
857
858         var base = window.location.href.replace(/\?.*$/, "");
859
860         stop();
861
862         jQuery.ajax({
863                 url: base + "data/test.js",
864                 type: "POST",
865                 dataType: "script",
866                 success: function(data, status){
867                         ok( foobar, "Script results returned (POST, no callback)" );
868                         equals( status, "success", "Script results returned (POST, no callback)" );
869                         start();
870                 },
871                 error: function(xhr) {
872                         ok( false, "ajax error, status code: " + xhr.status );
873                         start();
874                 }
875         });
876 });
877
878 test("jQuery.ajax() - script, Remote with scheme-less URL", function() {
879         expect(2);
880
881         var base = window.location.href.replace(/\?.*$/, "");
882         base = base.replace(/^.*?\/\//, "//");
883
884         stop();
885
886         jQuery.ajax({
887                 url: base + "data/test.js",
888                 dataType: "script",
889                 success: function(data){
890                         ok( foobar, "Script results returned (GET, no callback)" );
891                         start();
892                 }
893         });
894 });
895
896 test("jQuery.ajax() - malformed JSON", function() {
897         expect(2);
898
899         stop();
900
901         jQuery.ajax({
902                 url: "data/badjson.js",
903                 dataType: "json",
904                 success: function(){
905                         ok( false, "Success." );
906                         start();
907                 },
908                 error: function(xhr, msg, detailedMsg) {
909                         equals( "parsererror", msg, "A parse error occurred." );
910                         ok( /^Invalid JSON/.test(detailedMsg), "Detailed parsererror message provided" );
911                         start();
912                 }
913         });
914 });
915
916 test("jQuery.ajax() - script by content-type", function() {
917         expect(1);
918
919         stop();
920
921         jQuery.ajax({
922                 url: "data/script.php",
923                 data: { header: "script" },
924                 success: function() {
925                         start();
926                 }
927         });
928 });
929
930 test("jQuery.ajax() - json by content-type", function() {
931         expect(5);
932
933         stop();
934
935         jQuery.ajax({
936                 url: "data/json.php",
937                 data: { header: "json", json: "array" },
938                 success: function( json ) {
939                         ok( json.length >= 2, "Check length");
940                         equals( json[0].name, 'John', 'Check JSON: first, name' );
941                         equals( json[0].age, 21, 'Check JSON: first, age' );
942                         equals( json[1].name, 'Peter', 'Check JSON: second, name' );
943                         equals( json[1].age, 25, 'Check JSON: second, age' );
944                         start();
945                 }
946         });
947 });
948
949 test("jQuery.getJSON(String, Hash, Function) - JSON array", function() {
950         expect(5);
951         stop();
952         jQuery.getJSON(url("data/json.php"), {json: "array"}, function(json) {
953           ok( json.length >= 2, "Check length");
954           equals( json[0].name, 'John', 'Check JSON: first, name' );
955           equals( json[0].age, 21, 'Check JSON: first, age' );
956           equals( json[1].name, 'Peter', 'Check JSON: second, name' );
957           equals( json[1].age, 25, 'Check JSON: second, age' );
958           start();
959         });
960 });
961
962 test("jQuery.getJSON(String, Function) - JSON object", function() {
963         expect(2);
964         stop();
965         jQuery.getJSON(url("data/json.php"), function(json) {
966           if (json && json.data) {
967                   equals( json.data.lang, 'en', 'Check JSON: lang' );
968                   equals( json.data.length, 25, 'Check JSON: length' );
969           }
970           start();
971         });
972 });
973
974 test("jQuery.getJSON - Using Native JSON", function() {
975         expect(2);
976         
977         var old = window.JSON;
978         JSON = {
979                 parse: function(str){
980                         ok( true, "Verifying that parse method was run" );
981                         return true;
982                 }
983         };
984
985         stop();
986         jQuery.getJSON(url("data/json.php"), function(json) {
987                 window.JSON = old;
988                 equals( json, true, "Verifying return value" );
989                 start();
990         });
991 });
992
993 test("jQuery.getJSON(String, Function) - JSON object with absolute url to local content", function() {
994         expect(2);
995
996         var base = window.location.href.replace(/\?.*$/, "");
997
998         stop();
999         jQuery.getJSON(url(base + "data/json.php"), function(json) {
1000           equals( json.data.lang, 'en', 'Check JSON: lang' );
1001           equals( json.data.length, 25, 'Check JSON: length' );
1002           start();
1003         });
1004 });
1005
1006 test("jQuery.post - data", function() {
1007         expect(2);
1008         stop();
1009
1010         jQuery.post(url("data/name.php"), {xml: "5-2", length: 3}, function(xml){
1011                 jQuery('math', xml).each(function() {
1012                         equals( jQuery('calculation', this).text(), '5-2', 'Check for XML' );
1013                         equals( jQuery('result', this).text(), '3', 'Check for XML' );
1014                 });
1015                 start();
1016         });
1017 });
1018
1019 test("jQuery.post(String, Hash, Function) - simple with xml", function() {
1020         expect(4);
1021         stop();
1022         var done = 0;
1023
1024         jQuery.post(url("data/name.php"), {xml: "5-2"}, function(xml){
1025           jQuery('math', xml).each(function() {
1026                         equals( jQuery('calculation', this).text(), '5-2', 'Check for XML' );
1027                         equals( jQuery('result', this).text(), '3', 'Check for XML' );
1028                  });
1029           if ( ++done === 2 ) start();
1030         });
1031
1032         jQuery.post(url("data/name.php?xml=5-2"), {}, function(xml){
1033           jQuery('math', xml).each(function() {
1034                         equals( jQuery('calculation', this).text(), '5-2', 'Check for XML' );
1035                         equals( jQuery('result', this).text(), '3', 'Check for XML' );
1036                  });
1037           if ( ++done === 2 ) start();
1038         });
1039 });
1040
1041 test("jQuery.ajaxSetup({timeout: Number}) - with global timeout", function() {
1042         stop();
1043
1044         var passed = 0;
1045
1046         jQuery.ajaxSetup({timeout: 1000});
1047
1048         var pass = function() {
1049                 passed++;
1050                 if ( passed == 2 ) {
1051                         ok( true, 'Check local and global callbacks after timeout' );
1052                         jQuery('#main').unbind("ajaxError");
1053                         start();
1054                 }
1055         };
1056
1057         var fail = function(a,b,c) {
1058                 ok( false, 'Check for timeout failed ' + a + ' ' + b );
1059                 start();
1060         };
1061
1062         jQuery('#main').ajaxError(pass);
1063
1064         jQuery.ajax({
1065           type: "GET",
1066           url: url("data/name.php?wait=5"),
1067           error: pass,
1068           success: fail
1069         });
1070
1071         // reset timeout
1072         jQuery.ajaxSetup({timeout: 0});
1073 });
1074
1075 test("jQuery.ajaxSetup({timeout: Number}) with localtimeout", function() {
1076         stop();
1077         jQuery.ajaxSetup({timeout: 50});
1078
1079         jQuery.ajax({
1080           type: "GET",
1081           timeout: 15000,
1082           url: url("data/name.php?wait=1"),
1083           error: function() {
1084                    ok( false, 'Check for local timeout failed' );
1085                    start();
1086           },
1087           success: function() {
1088                 ok( true, 'Check for local timeout' );
1089                 start();
1090           }
1091         });
1092
1093         // reset timeout
1094         jQuery.ajaxSetup({timeout: 0});
1095 });
1096
1097 test("jQuery.ajax - simple get", function() {
1098         expect(1);
1099         stop();
1100         jQuery.ajax({
1101           type: "GET",
1102           url: url("data/name.php?name=foo"),
1103           success: function(msg){
1104                 equals( msg, 'bar', 'Check for GET' );
1105                 start();
1106           }
1107         });
1108 });
1109
1110 test("jQuery.ajax - simple post", function() {
1111         expect(1);
1112         stop();
1113         jQuery.ajax({
1114           type: "POST",
1115           url: url("data/name.php"),
1116           data: "name=peter",
1117           success: function(msg){
1118                 equals( msg, 'pan', 'Check for POST' );
1119                 start();
1120           }
1121         });
1122 });
1123
1124 test("ajaxSetup()", function() {
1125         expect(1);
1126         stop();
1127         jQuery.ajaxSetup({
1128                 url: url("data/name.php?name=foo"),
1129                 success: function(msg){
1130                         equals( msg, 'bar', 'Check for GET' );
1131                         start();
1132                 }
1133         });
1134         jQuery.ajax();
1135 });
1136
1137 /*
1138 test("custom timeout does not set error message when timeout occurs, see #970", function() {
1139         stop();
1140         jQuery.ajax({
1141                 url: "data/name.php?wait=1",
1142                 timeout: 500,
1143                 error: function(request, status) {
1144                         ok( status != null, "status shouldn't be null in error handler" );
1145                         equals( "timeout", status );
1146                         start();
1147                 }
1148         });
1149 });
1150 */
1151
1152 test("data option: evaluate function values (#2806)", function() {
1153         stop();
1154         jQuery.ajax({
1155                 url: "data/echoQuery.php",
1156                 data: {
1157                         key: function() {
1158                                 return "value";
1159                         }
1160                 },
1161                 success: function(result) {
1162                         equals( result, "key=value" );
1163                         start();
1164                 }
1165         })
1166 });
1167
1168 test("jQuery.ajax - If-Modified-Since support", function() {
1169         expect( 3 );
1170
1171         stop();
1172
1173         var url = "data/if_modified_since.php?ts=" + new Date();
1174
1175         jQuery.ajax({
1176                 url: url,
1177                 ifModified: true,
1178                 success: function(data, status) { 
1179                         equals(status, "success");
1180                         
1181                         jQuery.ajax({
1182                                 url: url,
1183                                 ifModified: true,
1184                                 success: function(data, status) { 
1185                                         if ( data === "FAIL" ) {
1186                                                 ok(true, "Opera is incapable of doing .setRequestHeader('If-Modified-Since').");
1187                                                 ok(true, "Opera is incapable of doing .setRequestHeader('If-Modified-Since').");
1188                                         } else {
1189                                                 equals(status, "notmodified");
1190                                                 ok(data == null, "response body should be empty")
1191                                         }
1192                                         start();
1193                                 }
1194                         });
1195                 }
1196         });
1197 });
1198
1199 test("jQuery.ajax - Etag support", function() {
1200         expect( 3 );
1201
1202         stop();
1203
1204         var url = "data/etag.php?ts=" + new Date();
1205
1206         jQuery.ajax({
1207                 url: url,
1208                 ifModified: true,
1209                 success: function(data, status) { 
1210                         equals(status, "success");
1211                         
1212                         jQuery.ajax({
1213                                 url: url,
1214                                 ifModified: true,
1215                                 success: function(data, status) { 
1216                                         if ( data === "FAIL" ) {
1217                                                 ok(true, "Opera is incapable of doing .setRequestHeader('If-None-Match').");
1218                                                 ok(true, "Opera is incapable of doing .setRequestHeader('If-None-Match').");
1219                                         } else {
1220                                                 equals(status, "notmodified");
1221                                                 ok(data == null, "response body should be empty")
1222                                         }
1223                                         start();
1224                                 }
1225                         });
1226                 }
1227         });
1228 });
1229
1230 }
1231
1232 //}