Fixes #5955. Option crossDomain now forces ajax to consider a request as cross-domain...
[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         jQuery('#foo').ajaxStart(function(){
18                 ok( true, "ajaxStart" );
19         }).ajaxStop(function(){
20                 ok( true, "ajaxStop" );
21                 start();
22         }).ajaxSend(function(){
23                 ok( true, "ajaxSend" );
24         }).ajaxComplete(function(){
25                 ok( true, "ajaxComplete" );
26         }).ajaxError(function(){
27                 ok( false, "ajaxError" );
28         }).ajaxSuccess(function(){
29                 ok( true, "ajaxSuccess" );
30         });
31
32         jQuery.ajax({
33                 url: url("data/name.html"),
34                 beforeSend: function(){ ok(true, "beforeSend"); },
35                 success: function(){ ok(true, "success"); },
36                 error: function(){ ok(false, "error"); },
37                 complete: function(){ ok(true, "complete"); }
38         });
39 });
40
41 test("jQuery.ajax() - success callbacks - (url, options) syntax", function() {
42         expect( 8 );
43
44         jQuery.ajaxSetup({ timeout: 0 });
45
46         stop();
47
48         setTimeout(function(){
49                 jQuery('#foo').ajaxStart(function(){
50                         ok( true, "ajaxStart" );
51                 }).ajaxStop(function(){
52                         ok( true, "ajaxStop" );
53                         start();
54                 }).ajaxSend(function(){
55                         ok( true, "ajaxSend" );
56                 }).ajaxComplete(function(){
57                         ok( true, "ajaxComplete" );
58                 }).ajaxError(function(){
59                         ok( false, "ajaxError" );
60                 }).ajaxSuccess(function(){
61                         ok( true, "ajaxSuccess" );
62                 });
63
64                 jQuery.ajax( url("data/name.html") , {
65                         beforeSend: function(){ ok(true, "beforeSend"); },
66                         success: function(){ ok(true, "success"); },
67                         error: function(){ ok(false, "error"); },
68                         complete: function(){ ok(true, "complete"); }
69                 });
70         }, 13);
71 });
72
73 test("jQuery.ajax() - success callbacks (late binding)", function() {
74         expect( 8 );
75
76         jQuery.ajaxSetup({ timeout: 0 });
77
78         stop();
79
80         setTimeout(function(){
81                 jQuery('#foo').ajaxStart(function(){
82                         ok( true, "ajaxStart" );
83                 }).ajaxStop(function(){
84                         ok( true, "ajaxStop" );
85                         start();
86                 }).ajaxSend(function(){
87                         ok( true, "ajaxSend" );
88                 }).ajaxComplete(function(){
89                         ok( true, "ajaxComplete" );
90                 }).ajaxError(function(){
91                         ok( false, "ajaxError" );
92                 }).ajaxSuccess(function(){
93                         ok( true, "ajaxSuccess" );
94                 });
95
96                 jQuery.ajax({
97                         url: url("data/name.html"),
98                         beforeSend: function(){ ok(true, "beforeSend"); }
99                 })
100                         .complete(function(){ ok(true, "complete"); })
101                         .success(function(){ ok(true, "success"); })
102                         .error(function(){ ok(false, "error"); });
103         }, 13);
104 });
105
106 test("jQuery.ajax() - success callbacks (oncomplete binding)", function() {
107         expect( 8 );
108
109         jQuery.ajaxSetup({ timeout: 0 });
110
111         stop();
112
113         setTimeout(function(){
114                 jQuery('#foo').ajaxStart(function(){
115                         ok( true, "ajaxStart" );
116                 }).ajaxStop(function(){
117                         ok( true, "ajaxStop" );
118                 }).ajaxSend(function(){
119                         ok( true, "ajaxSend" );
120                 }).ajaxComplete(function(){
121                         ok( true, "ajaxComplete" );
122                 }).ajaxError(function(){
123                         ok( false, "ajaxError" );
124                 }).ajaxSuccess(function(){
125                         ok( true, "ajaxSuccess" );
126                 });
127
128                 jQuery.ajax({
129                         url: url("data/name.html"),
130                         beforeSend: function(){ ok(true, "beforeSend"); },
131                         complete: function(xhr) {
132                                 xhr
133                                 .complete(function(){ ok(true, "complete"); })
134                                 .success(function(){ ok(true, "success"); })
135                                 .error(function(){ ok(false, "error"); })
136                                 .complete(function(){ start(); });
137                         }
138                 });
139         }, 13);
140 });
141
142 test("jQuery.ajax() - success callbacks (very late binding)", function() {
143         expect( 8 );
144
145         jQuery.ajaxSetup({ timeout: 0 });
146
147         stop();
148
149         setTimeout(function(){
150                 jQuery('#foo').ajaxStart(function(){
151                         ok( true, "ajaxStart" );
152                 }).ajaxStop(function(){
153                         ok( true, "ajaxStop" );
154                 }).ajaxSend(function(){
155                         ok( true, "ajaxSend" );
156                 }).ajaxComplete(function(){
157                         ok( true, "ajaxComplete" );
158                 }).ajaxError(function(){
159                         ok( false, "ajaxError" );
160                 }).ajaxSuccess(function(){
161                         ok( true, "ajaxSuccess" );
162                 });
163
164                 jQuery.ajax({
165                         url: url("data/name.html"),
166                         beforeSend: function(){ ok(true, "beforeSend"); },
167                         complete: function(xhr) {
168                                 setTimeout (function() {
169                                         xhr
170                                         .complete(function(){ ok(true, "complete"); })
171                                         .success(function(){ ok(true, "success"); })
172                                         .error(function(){ ok(false, "error"); })
173                                         .complete(function(){ start(); });
174                                 },100);
175                         }
176                 });
177         }, 13);
178 });
179
180 test("jQuery.ajax() - success callbacks (order)", function() {
181         expect( 1 );
182
183         jQuery.ajaxSetup({ timeout: 0 });
184
185         stop();
186
187         var testString = "";
188
189         setTimeout(function(){
190                 jQuery.ajax({
191                         url: url("data/name.html"),
192                         success: function( _1 , _2 , xhr ) {
193                                 xhr.success(function() {
194                                         xhr.success(function() {
195                                                 testString += "E";
196                                         });
197                                         testString += "D";
198                                 });
199                                 testString += "A";
200                         },
201                         complete: function() {
202                                 strictEqual(testString, "ABCDE", "Proper order");
203                                 start();
204                         }
205                 }).success(function() {
206                         testString += "B";
207                 }).success(function() {
208                         testString += "C";
209                 });
210         }, 13);
211 });
212
213 test("jQuery.ajax() - error callbacks", function() {
214         expect( 8 );
215         stop();
216
217         jQuery('#foo').ajaxStart(function(){
218                 ok( true, "ajaxStart" );
219         }).ajaxStop(function(){
220                 ok( true, "ajaxStop" );
221                 start();
222         }).ajaxSend(function(){
223                 ok( true, "ajaxSend" );
224         }).ajaxComplete(function(){
225                 ok( true, "ajaxComplete" );
226         }).ajaxError(function(){
227                 ok( true, "ajaxError" );
228         }).ajaxSuccess(function(){
229                 ok( false, "ajaxSuccess" );
230         });
231
232         jQuery.ajaxSetup({ timeout: 500 });
233
234         jQuery.ajax({
235                 url: url("data/name.php?wait=5"),
236                 beforeSend: function(){ ok(true, "beforeSend"); },
237                 success: function(){ ok(false, "success"); },
238                 error: function(){ ok(true, "error"); },
239                 complete: function(){ ok(true, "complete"); }
240         });
241 });
242
243 test("jQuery.ajax() - responseText on error", function() {
244
245         expect( 1 );
246
247         stop();
248
249         jQuery.ajax({
250                 url: url("data/errorWithText.php"),
251                 error: function(xhr) {
252                         strictEqual( xhr.responseText , "plain text message" , "Test jXHR.responseText is filled for HTTP errors" );
253                 },
254                 complete: function() {
255                         start();
256                 }
257         });
258 });
259
260 test(".ajax() - retry with jQuery.ajax( this )", function() {
261
262         expect( 1 );
263
264         stop();
265
266         var firstTime = 1;
267
268         jQuery.ajax({
269                 url: url("data/errorWithText.php"),
270                 error: function() {
271                         if ( firstTime ) {
272                                 firstTime = 0;
273                                 jQuery.ajax( this );
274                         } else {
275                                 ok( true , "Test retrying with jQuery.ajax(this) works" );
276                                 start();
277                         }
278                 }
279         })
280
281 });
282
283 test(".ajax() - headers" , function() {
284
285         expect( 2 );
286
287         stop();
288
289         var requestHeaders = {
290                 siMPle: "value",
291                 "SometHing-elsE": "other value",
292                 OthEr: "something else"
293                 },
294                 list = [],
295                 i;
296
297         for( i in requestHeaders ) {
298                 list.push( i );
299         }
300
301         jQuery.ajax(url("data/headers.php?keys="+list.join( "_" ) ), {
302                 headers: requestHeaders,
303                 success: function( data , _ , xhr ) {
304                         var tmp = [];
305                         for ( i in requestHeaders ) {
306                                 tmp.push( i , ": " , requestHeaders[ i ] , "\n" );
307                         }
308                         tmp = tmp.join( "" );
309
310                         equals( data , tmp , "Headers were sent" );
311                         equals( xhr.getResponseHeader( "Sample-Header" ) , "Hello World" , "Sample header received" );
312                         start();
313                 },
314                 error: function(){ ok(false, "error"); }
315         });
316
317 });
318
319 test(".ajax() - contentType" , function() {
320
321         expect( 2 );
322
323         stop();
324
325         var count = 2;
326
327         function restart() {
328                 if ( ! --count ) {
329                         start();
330                 }
331         }
332
333         jQuery.ajax(url("data/headers.php?keys=content-type" ), {
334                 contentType: "test",
335                 success: function( data ) {
336                         strictEqual( data , "content-type: test\n" , "Test content-type is sent when options.contentType is set" );
337                 },
338                 complete: function() {
339                         restart();
340                 }
341         });
342
343         jQuery.ajax(url("data/headers.php?keys=content-type" ), {
344                 contentType: false,
345                 success: function( data ) {
346                         strictEqual( data , "content-type: \n" , "Test content-type is not sent when options.contentType===false" );
347                 },
348                 complete: function() {
349                         restart();
350                 }
351         });
352
353 });
354
355 test(".ajax() - hash", function() {
356         expect(3);
357
358         jQuery.ajax({
359                 url: "data/name.html#foo",
360                 beforeSend: function( xhr, settings ) {
361                         equals(settings.url, "data/name.html", "Make sure that the URL is trimmed.");
362                         return false;
363                 }
364         });
365
366         jQuery.ajax({
367                 url: "data/name.html?abc#foo",
368                 beforeSend: function( xhr, settings ) {
369                 equals(settings.url, "data/name.html?abc", "Make sure that the URL is trimmed.");
370                         return false;
371                 }
372         });
373
374         jQuery.ajax({
375                 url: "data/name.html?abc#foo",
376                 data: { "test": 123 },
377                 beforeSend: function( xhr, settings ) {
378                         equals(settings.url, "data/name.html?abc&test=123", "Make sure that the URL is trimmed.");
379                         return false;
380                 }
381         });
382 });
383
384 test("jQuery ajax - cross-domain detection", function() {
385
386         expect( 4 );
387
388         var loc = document.location,
389                 otherPort = loc.port === 666 ? 667 : 666,
390                 otherProtocol = loc.protocol === "http:" ? "https:" : "http:",
391                 protocolFlag,
392                 hostFlag,
393                 portFlag,
394                 forcedFlag;
395
396         if ( jQuery.ajax({
397                 url: otherProtocol + "//" + loc.host,
398                 beforeSend: function( _ , s ) {
399                         protocolFlag = 1;
400                         ok( s.crossDomain , "Test different protocols are detected as cross-domain" );
401                         return false;
402                 }
403         }) === false ) {
404                 if ( ! protocolFlag ) {
405                         ok( ! jQuery.support.cors , "Test different protocols are detected as cross-domain (no transport)" );
406                 }
407         }
408
409         if ( jQuery.ajax({
410                 url: loc.protocol + '//somewebsitethatdoesnotexist-656329477541.com:' + ( loc.port || 80 ),
411                 beforeSend: function( _ , s ) {
412                         hostFlag = 1;
413                         ok( s.crossDomain , "Test different hostnames are detected as cross-domain" );
414                         return false;
415                 }
416         }) === false ) {
417                 if ( ! hostFlag ) {
418                         ok( ! jQuery.support.cors , "Test different hostnames are detected as cross-domain (no transport)" );
419                 }
420         }
421
422         if ( jQuery.ajax({
423                 url: loc.protocol + "//" + loc.hostname + ":" + otherPort,
424                 beforeSend: function( _ , s ) {
425                         portFlag = 1;
426                         ok( s.crossDomain , "Test different ports are detected as cross-domain" );
427                         return false;
428                 }
429         }) === false ) {
430                 if ( ! portFlag ) {
431                         ok( ! jQuery.support.cors , "Test different ports are detected as cross-domain (no transport)" );
432                 }
433         }
434
435         if ( jQuery.ajax({
436                 url: loc.protocol + "//" + loc.host,
437                 crossDomain: true,
438                 beforeSend: function( _ , s ) {
439                         forcedFlag = 1;
440                         ok( s.crossDomain , "Test forced crossDomain is detected as cross-domain" );
441                         return false;
442                 }
443         }) === false ) {
444                 if ( ! forcedFlag ) {
445                         ok( ! jQuery.support.cors , "Test forced crossDomain is detected as cross-domain (no transport)" );
446                 }
447         }
448
449 });
450
451 test(".ajax() - 304", function() {
452         expect( 1 );
453         stop();
454
455         jQuery.ajax({
456                 url: url("data/notmodified.php"),
457                 success: function(){ ok(true, "304 ok"); },
458                 // Do this because opera simply refuses to implement 304 handling :(
459                 // A feature-driven way of detecting this would be appreciated
460                 // See: http://gist.github.com/599419
461                 error: function(){ ok(jQuery.browser.opera, "304 not ok "); },
462                 complete: function(xhr){ start(); }
463         });
464 });
465
466 test(".load()) - 404 error callbacks", function() {
467         expect( 6 );
468         stop();
469
470         jQuery('#foo').ajaxStart(function(){
471                 ok( true, "ajaxStart" );
472         }).ajaxStop(function(){
473                 ok( true, "ajaxStop" );
474                 start();
475         }).ajaxSend(function(){
476                 ok( true, "ajaxSend" );
477         }).ajaxComplete(function(){
478                 ok( true, "ajaxComplete" );
479         }).ajaxError(function(){
480                 ok( true, "ajaxError" );
481         }).ajaxSuccess(function(){
482                 ok( false, "ajaxSuccess" );
483         });
484
485         jQuery("<div/>").load("data/404.html", function(){
486                 ok(true, "complete");
487         });
488 });
489
490 test("jQuery.ajax() - abort", function() {
491         expect( 8 );
492         stop();
493
494         jQuery('#foo').ajaxStart(function(){
495                 ok( true, "ajaxStart" );
496         }).ajaxStop(function(){
497                 ok( true, "ajaxStop" );
498                 start();
499         }).ajaxSend(function(){
500                 ok( true, "ajaxSend" );
501         }).ajaxComplete(function(){
502                 ok( true, "ajaxComplete" );
503         });
504
505         var xhr = jQuery.ajax({
506                 url: url("data/name.php?wait=5"),
507                 beforeSend: function(){ ok(true, "beforeSend"); },
508                 complete: function(){ ok(true, "complete"); }
509         });
510
511         equals( xhr.readyState, 1, "XHR readyState indicates successful dispatch" );
512
513         xhr.abort();
514         equals( xhr.readyState, 0, "XHR readyState indicates successful abortion" );
515 });
516
517 test("Ajax events with context", function() {
518         expect(14);
519
520         stop();
521         var context = document.createElement("div");
522
523         function event(e){
524                 equals( this, context, e.type );
525         }
526
527         function callback(msg){
528                 return function(){
529                         equals( this, context, "context is preserved on callback " + msg );
530                 };
531         }
532
533         function nocallback(msg){
534                 return function(){
535                         equals( typeof this.url, "string", "context is settings on callback " + msg );
536                 };
537         }
538
539         jQuery('#foo').add(context)
540                         .ajaxSend(event)
541                         .ajaxComplete(event)
542                         .ajaxError(event)
543                         .ajaxSuccess(event);
544
545         jQuery.ajax({
546                 url: url("data/name.html"),
547                 beforeSend: callback("beforeSend"),
548                 success: callback("success"),
549                 error: callback("error"),
550                 complete:function(){
551                         callback("complete").call(this);
552
553                         jQuery.ajax({
554                                 url: url("data/404.html"),
555                                 context: context,
556                                 beforeSend: callback("beforeSend"),
557                                 error: callback("error"),
558                                 complete: function(){
559                                         callback("complete").call(this);
560
561                                         jQuery('#foo').add(context).unbind();
562
563                                         jQuery.ajax({
564                                                 url: url("data/404.html"),
565                                                 beforeSend: nocallback("beforeSend"),
566                                                 error: nocallback("error"),
567                                                 complete: function(){
568                                                         nocallback("complete").call(this);
569                                                         start();
570                                                 }
571                                         });
572                                 }
573                         });
574                 },
575                 context:context
576         });
577 });
578
579 test("jQuery.ajax context modification", function() {
580         expect(1);
581
582         stop();
583
584         var obj = {};
585
586         jQuery.ajax({
587                 url: url("data/name.html"),
588                 context: obj,
589                 beforeSend: function(){
590                         this.test = "foo";
591                 },
592                 complete: function() {
593                         start();
594                 }
595         });
596
597         equals( obj.test, "foo", "Make sure the original object is maintained." );
598 });
599
600 test("jQuery.ajax() - disabled globals", function() {
601         expect( 3 );
602         stop();
603
604         jQuery('#foo').ajaxStart(function(){
605                 ok( false, "ajaxStart" );
606         }).ajaxStop(function(){
607                 ok( false, "ajaxStop" );
608         }).ajaxSend(function(){
609                 ok( false, "ajaxSend" );
610         }).ajaxComplete(function(){
611                 ok( false, "ajaxComplete" );
612         }).ajaxError(function(){
613                 ok( false, "ajaxError" );
614         }).ajaxSuccess(function(){
615                 ok( false, "ajaxSuccess" );
616         });
617
618         jQuery.ajax({
619                 global: false,
620                 url: url("data/name.html"),
621                 beforeSend: function(){ ok(true, "beforeSend"); },
622                 success: function(){ ok(true, "success"); },
623                 error: function(){ ok(false, "error"); },
624                 complete: function(){
625                   ok(true, "complete");
626                   setTimeout(function(){ start(); }, 13);
627                 }
628         });
629 });
630
631 test("jQuery.ajax - xml: non-namespace elements inside namespaced elements", function() {
632         expect(3);
633         stop();
634         jQuery.ajax({
635           url: url("data/with_fries.xml"),
636           dataType: "xml",
637           success: function(resp) {
638                 equals( jQuery("properties", resp).length, 1, 'properties in responseXML' );
639                 equals( jQuery("jsconf", resp).length, 1, 'jsconf in responseXML' );
640                 equals( jQuery("thing", resp).length, 2, 'things in responseXML' );
641                 start();
642           }
643         });
644 });
645
646 test("jQuery.ajax - xml: non-namespace elements inside namespaced elements (over JSONP)", function() {
647         expect(3);
648         stop();
649         jQuery.ajax({
650           url: url("data/with_fries_over_jsonp.php"),
651           dataType: "jsonp xml",
652           success: function(resp) {
653                 equals( jQuery("properties", resp).length, 1, 'properties in responseXML' );
654                 equals( jQuery("jsconf", resp).length, 1, 'jsconf in responseXML' );
655                 equals( jQuery("thing", resp).length, 2, 'things in responseXML' );
656                 start();
657           },
658           error: function(_1,_2,error) {
659                 ok( false, error );
660                 start();
661           }
662         });
663 });
664
665 test("jQuery.ajax - HEAD requests", function() {
666         expect(2);
667
668         stop();
669         jQuery.ajax({
670                 url: url("data/name.html"),
671                 type: "HEAD",
672                 success: function(data, status, xhr){
673                         var h = xhr.getAllResponseHeaders();
674                         ok( /Date/i.test(h), 'No Date in HEAD response' );
675
676                         jQuery.ajax({
677                                 url: url("data/name.html"),
678                                 data: { whip_it: "good" },
679                                 type: "HEAD",
680                                 success: function(data, status, xhr){
681                                         var h = xhr.getAllResponseHeaders();
682                                         ok( /Date/i.test(h), 'No Date in HEAD response with data' );
683                                         start();
684                                 }
685                         });
686                 }
687         });
688
689 });
690
691 test("jQuery.ajax - beforeSend", function() {
692         expect(1);
693         stop();
694
695         var check = false;
696
697         jQuery.ajaxSetup({ timeout: 0 });
698
699         jQuery.ajax({
700                 url: url("data/name.html"),
701                 beforeSend: function(xml) {
702                         check = true;
703                 },
704                 success: function(data) {
705                         ok( check, "check beforeSend was executed" );
706                         start();
707                 }
708         });
709 });
710
711 test("jQuery.ajax - beforeSend, cancel request (#2688)", function() {
712         expect(2);
713         var request = jQuery.ajax({
714                 url: url("data/name.html"),
715                 beforeSend: function() {
716                         ok( true, "beforeSend got called, canceling" );
717                         return false;
718                 },
719                 success: function() {
720                         ok( false, "request didn't get canceled" );
721                 },
722                 complete: function() {
723                         ok( false, "request didn't get canceled" );
724                 },
725                 error: function() {
726                         ok( false, "request didn't get canceled" );
727                 }
728         });
729         ok( request === false, "canceled request must return false instead of XMLHttpRequest instance" );
730 });
731
732 test("jQuery.ajax - beforeSend, cancel request manually", function() {
733         expect(2);
734         var request = jQuery.ajax({
735                 url: url("data/name.html"),
736                 beforeSend: function(xhr) {
737                         ok( true, "beforeSend got called, canceling" );
738                         xhr.abort();
739                 },
740                 success: function() {
741                         ok( false, "request didn't get canceled" );
742                 },
743                 complete: function() {
744                         ok( false, "request didn't get canceled" );
745                 },
746                 error: function() {
747                         ok( false, "request didn't get canceled" );
748                 }
749         });
750         ok( request === false, "canceled request must return false instead of XMLHttpRequest instance" );
751 });
752
753 window.foobar = null;
754 window.testFoo = undefined;
755
756 test("jQuery.ajax - dataType html", function() {
757         expect(5);
758         stop();
759
760         var verifyEvaluation = function() {
761                 equals( testFoo, "foo", 'Check if script was evaluated for datatype html' );
762                 equals( foobar, "bar", 'Check if script src was evaluated for datatype html' );
763
764                 start();
765         };
766
767         jQuery.ajax({
768           dataType: "html",
769           url: url("data/test.html"),
770           success: function(data) {
771                 jQuery("#ap").html(data);
772                 ok( data.match(/^html text/), 'Check content for datatype html' );
773                 setTimeout(verifyEvaluation, 600);
774           }
775         });
776 });
777
778 test("serialize()", function() {
779         expect(5);
780
781         // Add html5 elements only for serialize because selector can't yet find them on non-html5 browsers
782         jQuery("#search").after(
783                 '<input type="email" id="html5email" name="email" value="dave@jquery.com" />'+
784                 '<input type="number" id="html5number" name="number" value="43" />'
785         );
786
787         equals( jQuery('#form').serialize(),
788                 "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&select5=3",
789                 'Check form serialization as query string');
790
791         equals( jQuery('#form :input').serialize(),
792                 "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&select5=3",
793                 'Check input serialization as query string');
794
795         equals( jQuery('#testForm').serialize(),
796                 'T3=%3F%0D%0AZ&H1=x&H2=&PWD=&T1=&T2=YES&My+Name=me&S1=abc&S3=YES&S4=',
797                 'Check form serialization as query string');
798
799         equals( jQuery('#testForm :input').serialize(),
800                 'T3=%3F%0D%0AZ&H1=x&H2=&PWD=&T1=&T2=YES&My+Name=me&S1=abc&S3=YES&S4=',
801                 'Check input serialization as query string');
802
803         equals( jQuery('#form, #testForm').serialize(),
804                 "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&select5=3&T3=%3F%0D%0AZ&H1=x&H2=&PWD=&T1=&T2=YES&My+Name=me&S1=abc&S3=YES&S4=",
805                 'Multiple form serialization as query string');
806
807   /* Temporarily disabled. Opera 10 has problems with form serialization.
808         equals( jQuery('#form, #testForm :input').serialize(),
809                 "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%0D%0AZ&H1=x&H2=&PWD=&T1=&T2=YES&My+Name=me&S1=abc&S3=YES&S4=",
810                 'Mixed form/input serialization as query string');
811         */
812         jQuery("#html5email, #html5number").remove();
813 });
814
815 test("jQuery.param()", function() {
816         expect(22);
817
818         equals( !jQuery.ajaxSettings.traditional, true, "traditional flag, falsy by default" );
819
820         var params = {foo:"bar", baz:42, quux:"All your base are belong to us"};
821         equals( jQuery.param(params), "foo=bar&baz=42&quux=All+your+base+are+belong+to+us", "simple" );
822
823         params = {someName: [1, 2, 3], regularThing: "blah" };
824         equals( jQuery.param(params), "someName%5B%5D=1&someName%5B%5D=2&someName%5B%5D=3&regularThing=blah", "with array" );
825
826         params = {foo: ['a', 'b', 'c']};
827         equals( jQuery.param(params), "foo%5B%5D=a&foo%5B%5D=b&foo%5B%5D=c", "with array of strings" );
828
829         params = {foo: ["baz", 42, "All your base are belong to us"] };
830         equals( jQuery.param(params), "foo%5B%5D=baz&foo%5B%5D=42&foo%5B%5D=All+your+base+are+belong+to+us", "more array" );
831
832         params = {foo: { bar: 'baz', beep: 42, quux: 'All your base are belong to us' } };
833         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" );
834
835         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?" };
836         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" );
837
838         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 ] };
839         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" );
840
841         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?" };
842         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" );
843
844         equals( decodeURIComponent( jQuery.param({ a: [1,2,3], 'b[]': [4,5,6], 'c[d]': [7,8,9], e: { f: [10], g: [11,12], h: 13 } }) ), "a[]=1&a[]=2&a[]=3&b[]=4&b[]=5&b[]=6&c[d][]=7&c[d][]=8&c[d][]=9&e[f][]=10&e[g][]=11&e[g][]=12&e[h]=13", "Make sure params are not double-encoded." );
845
846         // Make sure empty arrays and objects are handled #6481
847         equals( jQuery.param({"foo": {"bar": []} }), "foo%5Bbar%5D=", "Empty array param" );
848         equals( jQuery.param({"foo": {"bar": [], foo: 1} }), "foo%5Bbar%5D=&foo%5Bfoo%5D=1", "Empty array param" );
849         equals( jQuery.param({"foo": {"bar": {}} }), "foo%5Bbar%5D=", "Empty object param" );
850
851         jQuery.ajaxSetup({ traditional: true });
852
853         var params = {foo:"bar", baz:42, quux:"All your base are belong to us"};
854         equals( jQuery.param(params), "foo=bar&baz=42&quux=All+your+base+are+belong+to+us", "simple" );
855
856         params = {someName: [1, 2, 3], regularThing: "blah" };
857         equals( jQuery.param(params), "someName=1&someName=2&someName=3&regularThing=blah", "with array" );
858
859         params = {foo: ['a', 'b', 'c']};
860         equals( jQuery.param(params), "foo=a&foo=b&foo=c", "with array of strings" );
861
862         params = {"foo[]":["baz", 42, "All your base are belong to us"]};
863         equals( jQuery.param(params), "foo%5B%5D=baz&foo%5B%5D=42&foo%5B%5D=All+your+base+are+belong+to+us", "more array" );
864
865         params = {"foo[bar]":"baz", "foo[beep]":42, "foo[quux]":"All your base are belong to us"};
866         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" );
867
868         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?" };
869         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" );
870
871         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 ] };
872         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)" );
873
874         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?" };
875         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" );
876
877         params = { param1: null };
878         equals( jQuery.param(params,false), "param1=null", "Make sure that null params aren't traversed." );
879 });
880
881 test("synchronous request", function() {
882         expect(1);
883         ok( /^{ "data"/.test( jQuery.ajax({url: url("data/json_obj.js"), dataType: "text", async: false}).responseText ), "check returned text" );
884 });
885
886 test("synchronous request with callbacks", function() {
887         expect(2);
888         var result;
889         jQuery.ajax({url: url("data/json_obj.js"), async: false, dataType: "text", success: function(data) { ok(true, "sucess callback executed"); result = data; } });
890         ok( /^{ "data"/.test( result ), "check returned text" );
891 });
892
893 test("pass-through request object", function() {
894         expect(8);
895         stop();
896
897         var target = "data/name.html";
898         var successCount = 0;
899         var errorCount = 0;
900         var errorEx = "";
901         var success = function() {
902                 successCount++;
903         };
904         jQuery("#foo").ajaxError(function (e, xml, s, ex) {
905                 errorCount++;
906                 errorEx += ": " + xml.status;
907         });
908         jQuery("#foo").one('ajaxStop', function () {
909                 equals(successCount, 5, "Check all ajax calls successful");
910                 equals(errorCount, 0, "Check no ajax errors (status" + errorEx + ")");
911                 jQuery("#foo").unbind('ajaxError');
912
913                 start();
914         });
915
916         ok( jQuery.get(url(target), success), "get" );
917         ok( jQuery.post(url(target), success), "post" );
918         ok( jQuery.getScript(url("data/test.js"), success), "script" );
919         ok( jQuery.getJSON(url("data/json_obj.js"), success), "json" );
920         ok( jQuery.ajax({url: url(target), success: success}), "generic" );
921 });
922
923 test("ajax cache", function () {
924         expect(18);
925
926         stop();
927
928         var count = 0;
929
930         jQuery("#firstp").bind("ajaxSuccess", function (e, xml, s) {
931                 var re = /_=(.*?)(&|$)/g;
932                 var oldOne = null;
933                 for (var i = 0; i < 6; i++) {
934                         var ret = re.exec(s.url);
935                         if (!ret) {
936                                 break;
937                         }
938                         oldOne = ret[1];
939                 }
940                 equals(i, 1, "Test to make sure only one 'no-cache' parameter is there");
941                 ok(oldOne != "tobereplaced555", "Test to be sure parameter (if it was there) was replaced");
942                 if(++count == 6)
943                         start();
944         });
945
946         ok( jQuery.ajax({url: "data/text.php", cache:false}), "test with no parameters" );
947         ok( jQuery.ajax({url: "data/text.php?pizza=true", cache:false}), "test with 1 parameter" );
948         ok( jQuery.ajax({url: "data/text.php?_=tobereplaced555", cache:false}), "test with _= parameter" );
949         ok( jQuery.ajax({url: "data/text.php?pizza=true&_=tobereplaced555", cache:false}), "test with 1 parameter plus _= one" );
950         ok( jQuery.ajax({url: "data/text.php?_=tobereplaced555&tv=false", cache:false}), "test with 1 parameter plus _= one before it" );
951         ok( jQuery.ajax({url: "data/text.php?name=David&_=tobereplaced555&washere=true", cache:false}), "test with 2 parameters surrounding _= one" );
952 });
953
954 /*
955  * Test disabled.
956  * The assertions expect that the passed-in object will be modified,
957  * which shouldn't be the case. Fixes #5439.
958 test("global ajaxSettings", function() {
959         expect(2);
960
961         var tmp = jQuery.extend({}, jQuery.ajaxSettings);
962         var orig = { url: "data/with_fries.xml" };
963         var t;
964
965         jQuery.ajaxSetup({ data: {foo: 'bar', bar: 'BAR'} });
966
967         t = jQuery.extend({}, orig);
968         t.data = {};
969         jQuery.ajax(t);
970         ok( t.url.indexOf('foo') > -1 && t.url.indexOf('bar') > -1, "Check extending {}" );
971
972         t = jQuery.extend({}, orig);
973         t.data = { zoo: 'a', ping: 'b' };
974         jQuery.ajax(t);
975         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' }" );
976
977         jQuery.ajaxSettings = tmp;
978 });
979 */
980
981 test("load(String)", function() {
982         expect(1);
983         stop(); // check if load can be called with only url
984         jQuery('#first').load("data/name.html", start);
985 });
986
987 test("load('url selector')", function() {
988         expect(1);
989         stop(); // check if load can be called with only url
990         jQuery('#first').load("data/test3.html div.user", function(){
991                 equals( jQuery(this).children("div").length, 2, "Verify that specific elements were injected" );
992                 start();
993         });
994 });
995
996 test("load(String, Function) with ajaxSetup on dataType json, see #2046", function() {
997         expect(1);
998         stop();
999         jQuery.ajaxSetup({ dataType: "json" });
1000         jQuery("#first").ajaxComplete(function (e, xml, s) {
1001                 equals( s.dataType, "html", "Verify the load() dataType was html" );
1002                 jQuery("#first").unbind("ajaxComplete");
1003                 jQuery.ajaxSetup({ dataType: "" });
1004                 start();
1005         });
1006         jQuery('#first').load("data/test3.html");
1007 });
1008
1009 test("load(String, Function) - simple: inject text into DOM", function() {
1010         expect(2);
1011         stop();
1012         jQuery('#first').load(url("data/name.html"), function() {
1013                 ok( /^ERROR/.test(jQuery('#first').text()), 'Check if content was injected into the DOM' );
1014                 start();
1015         });
1016 });
1017
1018 test("load(String, Function) - check scripts", function() {
1019         expect(7);
1020         stop();
1021
1022         var verifyEvaluation = function() {
1023                 equals( foobar, "bar", 'Check if script src was evaluated after load' );
1024                 equals( jQuery('#ap').html(), 'bar', 'Check if script evaluation has modified DOM');
1025
1026                 start();
1027         };
1028         jQuery('#first').load(url('data/test.html'), function() {
1029                 ok( jQuery('#first').html().match(/^html text/), 'Check content after loading html' );
1030                 equals( jQuery('#foo').html(), 'foo', 'Check if script evaluation has modified DOM');
1031                 equals( testFoo, "foo", 'Check if script was evaluated after load' );
1032                 setTimeout(verifyEvaluation, 600);
1033         });
1034 });
1035
1036 test("load(String, Function) - check file with only a script tag", function() {
1037         expect(3);
1038         stop();
1039
1040         jQuery('#first').load(url('data/test2.html'), function() {
1041                 equals( jQuery('#foo').html(), 'foo', 'Check if script evaluation has modified DOM');
1042                 equals( testFoo, "foo", 'Check if script was evaluated after load' );
1043
1044                 start();
1045         });
1046 });
1047
1048 test("load(String, Object, Function)", function() {
1049         expect(2);
1050         stop();
1051
1052         jQuery('<div />').load(url('data/params_html.php'), { foo:3, bar:'ok' }, function() {
1053                 var $post = jQuery(this).find('#post');
1054                 equals( $post.find('#foo').text(), '3', 'Check if a hash of data is passed correctly');
1055                 equals( $post.find('#bar').text(), 'ok', 'Check if a hash of data is passed correctly');
1056                 start();
1057         });
1058 });
1059
1060 test("load(String, String, Function)", function() {
1061         expect(2);
1062         stop();
1063
1064         jQuery('<div />').load(url('data/params_html.php'), 'foo=3&bar=ok', function() {
1065                 var $get = jQuery(this).find('#get');
1066                 equals( $get.find('#foo').text(), '3', 'Check if a string of data is passed correctly');
1067                 equals( $get.find('#bar').text(), 'ok', 'Check if a      of data is passed correctly');
1068                 start();
1069         });
1070 });
1071
1072 test("jQuery.get(String, Hash, Function) - parse xml and use text() on nodes", function() {
1073         expect(2);
1074         stop();
1075         jQuery.get(url('data/dashboard.xml'), function(xml) {
1076                 var content = [];
1077                 jQuery('tab', xml).each(function() {
1078                         content.push(jQuery(this).text());
1079                 });
1080                 equals( content[0], 'blabla', 'Check first tab');
1081                 equals( content[1], 'blublu', 'Check second tab');
1082                 start();
1083         });
1084 });
1085
1086 test("jQuery.getScript(String, Function) - with callback", function() {
1087         expect(2);
1088         stop();
1089         jQuery.getScript(url("data/test.js"), function() {
1090                 equals( foobar, "bar", 'Check if script was evaluated' );
1091                 setTimeout(start, 100);
1092         });
1093 });
1094
1095 test("jQuery.getScript(String, Function) - no callback", function() {
1096         expect(1);
1097         stop();
1098         jQuery.getScript(url("data/test.js"), function(){
1099                 start();
1100         });
1101 });
1102
1103 test("jQuery.ajax() - JSONP, Local", function() {
1104         expect(9);
1105
1106         var count = 0;
1107         function plus(){ if ( ++count == 9 ) start(); }
1108
1109         stop();
1110
1111         jQuery.ajax({
1112                 url: "data/jsonp.php",
1113                 dataType: "jsonp",
1114                 success: function(data){
1115                         ok( data.data, "JSON results returned (GET, no callback)" );
1116                         plus();
1117                 },
1118                 error: function(data){
1119                         ok( false, "Ajax error JSON (GET, no callback)" );
1120                         plus();
1121                 }
1122         });
1123
1124         jQuery.ajax({
1125                 url: "data/jsonp.php?callback=?",
1126                 dataType: "jsonp",
1127                 success: function(data){
1128                         ok( data.data, "JSON results returned (GET, url callback)" );
1129                         plus();
1130                 },
1131                 error: function(data){
1132                         ok( false, "Ajax error JSON (GET, url callback)" );
1133                         plus();
1134                 }
1135         });
1136
1137         jQuery.ajax({
1138                 url: "data/jsonp.php",
1139                 dataType: "jsonp",
1140                 data: "callback=?",
1141                 success: function(data){
1142                         ok( data.data, "JSON results returned (GET, data callback)" );
1143                         plus();
1144                 },
1145                 error: function(data){
1146                         ok( false, "Ajax error JSON (GET, data callback)" );
1147                         plus();
1148                 }
1149         });
1150
1151         jQuery.ajax({
1152                 url: "data/jsonp.php",
1153                 dataType: "jsonp",
1154                 jsonp: "callback",
1155                 success: function(data){
1156                         ok( data.data, "JSON results returned (GET, data obj callback)" );
1157                         plus();
1158                 },
1159                 error: function(data){
1160                         ok( false, "Ajax error JSON (GET, data obj callback)" );
1161                         plus();
1162                 }
1163         });
1164
1165         jQuery.ajax({
1166                 url: "data/jsonp.php",
1167                 dataType: "jsonp",
1168                 jsonpCallback: "jsonpResults",
1169                 success: function(data){
1170                         ok( data.data, "JSON results returned (GET, custom callback name)" );
1171                         plus();
1172                 },
1173                 error: function(data){
1174                         ok( false, "Ajax error JSON (GET, custom callback name)" );
1175                         plus();
1176                 }
1177         });
1178
1179         jQuery.ajax({
1180                 type: "POST",
1181                 url: "data/jsonp.php",
1182                 dataType: "jsonp",
1183                 success: function(data){
1184                         ok( data.data, "JSON results returned (POST, no callback)" );
1185                         plus();
1186                 },
1187                 error: function(data){
1188                         ok( false, "Ajax error JSON (GET, data obj callback)" );
1189                         plus();
1190                 }
1191         });
1192
1193         jQuery.ajax({
1194                 type: "POST",
1195                 url: "data/jsonp.php",
1196                 data: "callback=?",
1197                 dataType: "jsonp",
1198                 success: function(data){
1199                         ok( data.data, "JSON results returned (POST, data callback)" );
1200                         plus();
1201                 },
1202                 error: function(data){
1203                         ok( false, "Ajax error JSON (POST, data callback)" );
1204                         plus();
1205                 }
1206         });
1207
1208         jQuery.ajax({
1209                 type: "POST",
1210                 url: "data/jsonp.php",
1211                 jsonp: "callback",
1212                 dataType: "jsonp",
1213                 success: function(data){
1214                         ok( data.data, "JSON results returned (POST, data obj callback)" );
1215                         plus();
1216                 },
1217                 error: function(data){
1218                         ok( false, "Ajax error JSON (POST, data obj callback)" );
1219                         plus();
1220                 }
1221         });
1222
1223         //#7578
1224         jQuery.ajax({
1225                 url: "data/jsonp.php",
1226                 dataType: "jsonp",
1227                 beforeSend: function(){
1228                         strictEqual( this.cache, false, "cache must be false on JSON request" );
1229                         plus();
1230                         return false;
1231                 }
1232         });
1233 });
1234
1235 test("jQuery.ajax() - JSONP - Custom JSONP Callback", function() {
1236         expect(1);
1237         stop();
1238
1239         window.jsonpResults = function(data) {
1240                 ok( data.data, "JSON results returned (GET, custom callback function)" );
1241                 window.jsonpResults = undefined;
1242                 start();
1243         };
1244
1245         jQuery.ajax({
1246                 url: "data/jsonp.php",
1247                 dataType: "jsonp",
1248                 jsonpCallback: "jsonpResults"
1249         });
1250 });
1251
1252 test("jQuery.ajax() - JSONP, Remote", function() {
1253         expect(4);
1254
1255         var count = 0;
1256         function plus(){ if ( ++count == 4 ) start(); }
1257
1258         var base = window.location.href.replace(/[^\/]*$/, "");
1259
1260         stop();
1261
1262         jQuery.ajax({
1263                 url: base + "data/jsonp.php",
1264                 dataType: "jsonp",
1265                 success: function(data){
1266                         ok( data.data, "JSON results returned (GET, no callback)" );
1267                         plus();
1268                 },
1269                 error: function(data){
1270                         ok( false, "Ajax error JSON (GET, no callback)" );
1271                         plus();
1272                 }
1273         });
1274
1275         jQuery.ajax({
1276                 url: base + "data/jsonp.php?callback=?",
1277                 dataType: "jsonp",
1278                 success: function(data){
1279                         ok( data.data, "JSON results returned (GET, url callback)" );
1280                         plus();
1281                 },
1282                 error: function(data){
1283                         ok( false, "Ajax error JSON (GET, url callback)" );
1284                         plus();
1285                 }
1286         });
1287
1288         jQuery.ajax({
1289                 url: base + "data/jsonp.php",
1290                 dataType: "jsonp",
1291                 data: "callback=?",
1292                 success: function(data){
1293                         ok( data.data, "JSON results returned (GET, data callback)" );
1294                         plus();
1295                 },
1296                 error: function(data){
1297                         ok( false, "Ajax error JSON (GET, data callback)" );
1298                         plus();
1299                 }
1300         });
1301
1302         jQuery.ajax({
1303                 url: base + "data/jsonp.php",
1304                 dataType: "jsonp",
1305                 jsonp: "callback",
1306                 success: function(data){
1307                         ok( data.data, "JSON results returned (GET, data obj callback)" );
1308                         plus();
1309                 },
1310                 error: function(data){
1311                         ok( false, "Ajax error JSON (GET, data obj callback)" );
1312                         plus();
1313                 }
1314         });
1315 });
1316
1317 test("jQuery.ajax() - script, Remote", function() {
1318         expect(2);
1319
1320         var base = window.location.href.replace(/[^\/]*$/, "");
1321
1322         stop();
1323
1324         jQuery.ajax({
1325                 url: base + "data/test.js",
1326                 dataType: "script",
1327                 success: function(data){
1328                         ok( foobar, "Script results returned (GET, no callback)" );
1329                         start();
1330                 }
1331         });
1332 });
1333
1334 test("jQuery.ajax() - script, Remote with POST", function() {
1335         expect(3);
1336
1337         var base = window.location.href.replace(/[^\/]*$/, "");
1338
1339         stop();
1340
1341         jQuery.ajax({
1342                 url: base + "data/test.js",
1343                 type: "POST",
1344                 dataType: "script",
1345                 success: function(data, status){
1346                         ok( foobar, "Script results returned (POST, no callback)" );
1347                         equals( status, "success", "Script results returned (POST, no callback)" );
1348                         start();
1349                 },
1350                 error: function(xhr) {
1351                         ok( false, "ajax error, status code: " + xhr.status );
1352                         start();
1353                 }
1354         });
1355 });
1356
1357 test("jQuery.ajax() - script, Remote with scheme-less URL", function() {
1358         expect(2);
1359
1360         var base = window.location.href.replace(/[^\/]*$/, "");
1361         base = base.replace(/^.*?\/\//, "//");
1362
1363         stop();
1364
1365         jQuery.ajax({
1366                 url: base + "data/test.js",
1367                 dataType: "script",
1368                 success: function(data){
1369                         ok( foobar, "Script results returned (GET, no callback)" );
1370                         start();
1371                 }
1372         });
1373 });
1374
1375 test("jQuery.ajax() - malformed JSON", function() {
1376         expect(2);
1377
1378         stop();
1379
1380         jQuery.ajax({
1381                 url: "data/badjson.js",
1382                 dataType: "json",
1383                 success: function(){
1384                         ok( false, "Success." );
1385                         start();
1386                 },
1387                 error: function(xhr, msg, detailedMsg) {
1388                         equals( "parsererror", msg, "A parse error occurred." );
1389                         ok( /^Invalid JSON/.test(detailedMsg), "Detailed parsererror message provided" );
1390                         start();
1391                 }
1392         });
1393 });
1394
1395 test("jQuery.ajax() - script by content-type", function() {
1396         expect(1);
1397
1398         stop();
1399
1400         jQuery.ajax({
1401                 url: "data/script.php",
1402                 data: { header: "script" },
1403                 success: function() {
1404                         start();
1405                 }
1406         });
1407 });
1408
1409 test("jQuery.ajax() - json by content-type", function() {
1410         expect(5);
1411
1412         stop();
1413
1414         jQuery.ajax({
1415                 url: "data/json.php",
1416                 data: { header: "json", json: "array" },
1417                 success: function( json ) {
1418                         ok( json.length >= 2, "Check length");
1419                         equals( json[0].name, 'John', 'Check JSON: first, name' );
1420                         equals( json[0].age, 21, 'Check JSON: first, age' );
1421                         equals( json[1].name, 'Peter', 'Check JSON: second, name' );
1422                         equals( json[1].age, 25, 'Check JSON: second, age' );
1423                         start();
1424                 }
1425         });
1426 });
1427
1428 test("jQuery.ajax() - json by content-type disabled with options", function() {
1429         expect(6);
1430
1431         stop();
1432
1433         jQuery.ajax({
1434                 url: url("data/json.php"),
1435                 data: { header: "json", json: "array" },
1436                 contents: {
1437                         json: false
1438                 },
1439                 success: function( text ) {
1440                         equals( typeof text , "string" , "json wasn't auto-determined" );
1441                         var json = jQuery.parseJSON( text );
1442                         ok( json.length >= 2, "Check length");
1443                         equals( json[0].name, 'John', 'Check JSON: first, name' );
1444                         equals( json[0].age, 21, 'Check JSON: first, age' );
1445                         equals( json[1].name, 'Peter', 'Check JSON: second, name' );
1446                         equals( json[1].age, 25, 'Check JSON: second, age' );
1447                         start();
1448                 }
1449         });
1450 });
1451
1452 test("jQuery.getJSON(String, Hash, Function) - JSON array", function() {
1453         expect(5);
1454         stop();
1455         jQuery.getJSON(url("data/json.php"), {json: "array"}, function(json) {
1456           ok( json.length >= 2, "Check length");
1457           equals( json[0].name, 'John', 'Check JSON: first, name' );
1458           equals( json[0].age, 21, 'Check JSON: first, age' );
1459           equals( json[1].name, 'Peter', 'Check JSON: second, name' );
1460           equals( json[1].age, 25, 'Check JSON: second, age' );
1461           start();
1462         });
1463 });
1464
1465 test("jQuery.getJSON(String, Function) - JSON object", function() {
1466         expect(2);
1467         stop();
1468         jQuery.getJSON(url("data/json.php"), function(json) {
1469           if (json && json.data) {
1470                   equals( json.data.lang, 'en', 'Check JSON: lang' );
1471                   equals( json.data.length, 25, 'Check JSON: length' );
1472           }
1473           start();
1474         });
1475 });
1476
1477 test("jQuery.getJSON - Using Native JSON", function() {
1478         expect(2);
1479
1480         var old = window.JSON;
1481         JSON = {
1482                 parse: function(str){
1483                         ok( true, "Verifying that parse method was run" );
1484                         return true;
1485                 }
1486         };
1487
1488         stop();
1489         jQuery.getJSON(url("data/json.php"), function(json) {
1490                 window.JSON = old;
1491                 equals( json, true, "Verifying return value" );
1492                 start();
1493         });
1494 });
1495
1496 test("jQuery.getJSON(String, Function) - JSON object with absolute url to local content", function() {
1497         expect(2);
1498
1499         var base = window.location.href.replace(/[^\/]*$/, "");
1500
1501         stop();
1502         jQuery.getJSON(url(base + "data/json.php"), function(json) {
1503           equals( json.data.lang, 'en', 'Check JSON: lang' );
1504           equals( json.data.length, 25, 'Check JSON: length' );
1505           start();
1506         });
1507 });
1508
1509 test("jQuery.post - data", function() {
1510         expect(2);
1511         stop();
1512
1513         jQuery.post(url("data/name.php"), {xml: "5-2", length: 3}, function(xml){
1514                 jQuery('math', xml).each(function() {
1515                         equals( jQuery('calculation', this).text(), '5-2', 'Check for XML' );
1516                         equals( jQuery('result', this).text(), '3', 'Check for XML' );
1517                 });
1518                 start();
1519         });
1520 });
1521
1522 test("jQuery.post(String, Hash, Function) - simple with xml", function() {
1523         expect(4);
1524         stop();
1525         var done = 0;
1526
1527         jQuery.post(url("data/name.php"), {xml: "5-2"}, function(xml){
1528           jQuery('math', xml).each(function() {
1529                         equals( jQuery('calculation', this).text(), '5-2', 'Check for XML' );
1530                         equals( jQuery('result', this).text(), '3', 'Check for XML' );
1531                  });
1532           if ( ++done === 2 ) start();
1533         });
1534
1535         jQuery.post(url("data/name.php?xml=5-2"), {}, function(xml){
1536           jQuery('math', xml).each(function() {
1537                         equals( jQuery('calculation', this).text(), '5-2', 'Check for XML' );
1538                         equals( jQuery('result', this).text(), '3', 'Check for XML' );
1539                  });
1540           if ( ++done === 2 ) start();
1541         });
1542 });
1543
1544 test("jQuery.ajaxSetup({timeout: Number}) - with global timeout", function() {
1545         stop();
1546
1547         var passed = 0;
1548
1549         jQuery.ajaxSetup({timeout: 1000});
1550
1551         var pass = function() {
1552                 passed++;
1553                 if ( passed == 2 ) {
1554                         ok( true, 'Check local and global callbacks after timeout' );
1555                         jQuery('#main').unbind("ajaxError");
1556                         start();
1557                 }
1558         };
1559
1560         var fail = function(a,b,c) {
1561                 ok( false, 'Check for timeout failed ' + a + ' ' + b );
1562                 start();
1563         };
1564
1565         jQuery('#main').ajaxError(pass);
1566
1567         jQuery.ajax({
1568           type: "GET",
1569           url: url("data/name.php?wait=5"),
1570           error: pass,
1571           success: fail
1572         });
1573
1574         // reset timeout
1575         jQuery.ajaxSetup({timeout: 0});
1576 });
1577
1578 test("jQuery.ajaxSetup({timeout: Number}) with localtimeout", function() {
1579         stop();
1580         jQuery.ajaxSetup({timeout: 50});
1581
1582         jQuery.ajax({
1583           type: "GET",
1584           timeout: 15000,
1585           url: url("data/name.php?wait=1"),
1586           error: function() {
1587                    ok( false, 'Check for local timeout failed' );
1588                    start();
1589           },
1590           success: function() {
1591                 ok( true, 'Check for local timeout' );
1592                 start();
1593           }
1594         });
1595
1596         // reset timeout
1597         jQuery.ajaxSetup({timeout: 0});
1598 });
1599
1600 test("jQuery.ajax - simple get", function() {
1601         expect(1);
1602         stop();
1603         jQuery.ajax({
1604           type: "GET",
1605           url: url("data/name.php?name=foo"),
1606           success: function(msg){
1607                 equals( msg, 'bar', 'Check for GET' );
1608                 start();
1609           }
1610         });
1611 });
1612
1613 test("jQuery.ajax - simple post", function() {
1614         expect(1);
1615         stop();
1616         jQuery.ajax({
1617           type: "POST",
1618           url: url("data/name.php"),
1619           data: "name=peter",
1620           success: function(msg){
1621                 equals( msg, 'pan', 'Check for POST' );
1622                 start();
1623           }
1624         });
1625 });
1626
1627 test("ajaxSetup()", function() {
1628         expect(1);
1629         stop();
1630         jQuery.ajaxSetup({
1631                 url: url("data/name.php?name=foo"),
1632                 success: function(msg){
1633                         equals( msg, 'bar', 'Check for GET' );
1634                         start();
1635                 }
1636         });
1637         jQuery.ajax();
1638 });
1639
1640 /*
1641 test("custom timeout does not set error message when timeout occurs, see #970", function() {
1642         stop();
1643         jQuery.ajax({
1644                 url: "data/name.php?wait=1",
1645                 timeout: 500,
1646                 error: function(request, status) {
1647                         ok( status != null, "status shouldn't be null in error handler" );
1648                         equals( "timeout", status );
1649                         start();
1650                 }
1651         });
1652 });
1653 */
1654
1655 test("data option: evaluate function values (#2806)", function() {
1656         stop();
1657         jQuery.ajax({
1658                 url: "data/echoQuery.php",
1659                 data: {
1660                         key: function() {
1661                                 return "value";
1662                         }
1663                 },
1664                 success: function(result) {
1665                         equals( result, "key=value" );
1666                         start();
1667                 }
1668         });
1669 });
1670
1671 test("data option: empty bodies for non-GET requests", function() {
1672         stop();
1673         jQuery.ajax({
1674                 url: "data/echoData.php",
1675                 data: undefined,
1676                 type: "post",
1677                 success: function(result) {
1678                         equals( result, "" );
1679                         start();
1680                 }
1681         });
1682 });
1683
1684 test("jQuery.ajax - If-Modified-Since support", function() {
1685         expect( 3 );
1686
1687         stop();
1688
1689         var url = "data/if_modified_since.php?ts=" + new Date();
1690
1691         jQuery.ajax({
1692                 url: url,
1693                 ifModified: true,
1694                 success: function(data, status) {
1695                         equals(status, "success");
1696
1697                         jQuery.ajax({
1698                                 url: url,
1699                                 ifModified: true,
1700                                 success: function(data, status) {
1701                                         if ( data === "FAIL" ) {
1702                                                 ok(true, "Opera is incapable of doing .setRequestHeader('If-Modified-Since').");
1703                                                 ok(true, "Opera is incapable of doing .setRequestHeader('If-Modified-Since').");
1704                                         } else {
1705                                                 equals(status, "notmodified");
1706                                                 ok(data == null, "response body should be empty");
1707                                         }
1708                                         start();
1709                         },
1710                                 error: function() {
1711                                         // Do this because opera simply refuses to implement 304 handling :(
1712                                         // A feature-driven way of detecting this would be appreciated
1713                                         // See: http://gist.github.com/599419
1714                                         ok(jQuery.browser.opera, "error");
1715                                         ok(jQuery.browser.opera, "error");
1716                                         start();
1717                         }
1718                         });
1719                 },
1720                 error: function() {
1721                         equals(false, "error");
1722                         // Do this because opera simply refuses to implement 304 handling :(
1723                         // A feature-driven way of detecting this would be appreciated
1724                         // See: http://gist.github.com/599419
1725                         ok(jQuery.browser.opera, "error");
1726                         start();
1727                 }
1728         });
1729 });
1730
1731 test("jQuery.ajax - Etag support", function() {
1732         expect( 3 );
1733
1734         stop();
1735
1736         var url = "data/etag.php?ts=" + new Date();
1737
1738         jQuery.ajax({
1739                 url: url,
1740                 ifModified: true,
1741                 success: function(data, status) {
1742                         equals(status, "success");
1743
1744                         jQuery.ajax({
1745                                 url: url,
1746                                 ifModified: true,
1747                                 success: function(data, status) {
1748                                         if ( data === "FAIL" ) {
1749                                                 ok(true, "Opera is incapable of doing .setRequestHeader('If-None-Match').");
1750                                                 ok(true, "Opera is incapable of doing .setRequestHeader('If-None-Match').");
1751                                         } else {
1752                                                 equals(status, "notmodified");
1753                                                 ok(data == null, "response body should be empty");
1754                                         }
1755                                         start();
1756                         },
1757                         error: function() {
1758                                         // Do this because opera simply refuses to implement 304 handling :(
1759                                         // A feature-driven way of detecting this would be appreciated
1760                                         // See: http://gist.github.com/599419
1761                                         ok(jQuery.browser.opera, "error");
1762                                         ok(jQuery.browser.opera, "error");
1763                                         start();
1764                                 }
1765                         });
1766                 },
1767                 error: function() {
1768                         // Do this because opera simply refuses to implement 304 handling :(
1769                         // A feature-driven way of detecting this would be appreciated
1770                         // See: http://gist.github.com/599419
1771                         ok(jQuery.browser.opera, "error");
1772                         start();
1773                 }
1774         });
1775 });
1776
1777 test("jQuery ajax - failing cross-domain", function() {
1778
1779         expect( 2 );
1780
1781         stop();
1782
1783         var i = 2;
1784
1785         if ( jQuery.ajax({
1786                 url: 'http://somewebsitethatdoesnotexist-67864863574657654.com',
1787                 success: function(){ ok( false , "success" ); },
1788                 error: function(xhr,_,e){ ok( true , "file not found: " + xhr.status + " => " + e ); },
1789                 complete: function() { if ( ! --i ) start(); }
1790         }) === false ) {
1791                 ok( true , "no transport" );
1792                 if ( ! --i ) start();
1793         }
1794
1795         if ( jQuery.ajax({
1796                 url: 'http://www.google.com',
1797                 success: function(){ ok( false , "success" ); },
1798                 error: function(xhr,_,e){ ok( true , "access denied: " + xhr.status + " => " + e ); },
1799                 complete: function() { if ( ! --i ) start(); }
1800         }) === false ) {
1801                 ok( true , "no transport" );
1802                 if ( ! --i ) start();
1803         }
1804
1805 });
1806
1807 test("jQuery ajax - atom+xml", function() {
1808
1809         stop();
1810
1811         jQuery.ajax({
1812                 url: url( 'data/atom+xml.php' ),
1813                 success: function(){ ok( true , "success" ); },
1814                 error: function(){ ok( false , "error" ); },
1815                 complete: function() { start(); }
1816         });
1817
1818 });
1819
1820 test("jQuery.ajax - active counter", function() {
1821     ok( jQuery.active == 0, "ajax active counter should be zero: " + jQuery.active );
1822 });
1823
1824 test( "jQuery.ajax - Location object as url (#7531)", 1, function () {
1825         var success = false;
1826         try {
1827                 var xhr = jQuery.ajax({ url: window.location });
1828                 success = true;
1829                 xhr.abort();
1830         } catch (e) {}
1831
1832         ok( success, "document.location did not generate exception" );
1833 });
1834
1835 }
1836
1837 //}