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