* xmlrpcs.inc, xmlrpcs.inc: remove code that was left for compatibility with php...
[plcapi.git] / test / testsuite.php
1 <?php
2         /* $Id$ */
3
4         include(getcwd().'/parse_args.php');
5
6         require_once('xmlrpc.inc');
7         require_once('xmlrpcs.inc');
8         require_once('xmlrpc_wrappers.inc');
9
10         require_once 'phpunit.php';
11         //require_once 'PHPUnit/TestDecorator.php';
12
13         // let testuite run for the needed time
14         if ((int)ini_get('max_execution_time') < 180)
15                 ini_set('max_execution_time', 180);
16
17         ini_set('max_execution_time', 180);
18
19         $suite = new PHPUnit_TestSuite();
20
21         // array with list of failed tests
22         $failed_tests = array();
23
24         class LocalhostTests extends PHPUnit_TestCase
25         {
26                 var $client = null;
27                 var $method = 'http';
28                 var $timeout = 10;
29                 var $request_compression = null;
30                 var $accepted_compression = '';
31
32                 function fail($message = '')
33                 {
34                         PHPUnit_TestCase::fail($message);
35                         // save in global var that this particular test has failed
36                         // (but only if not called from subclass objects / multitests)
37                         if (function_exists('debug_backtrace') && strtolower(get_class($this)) == 'localhosttests')
38                         {
39                                 global $failed_tests;
40                                 $trace = debug_backtrace();
41                                 for ($i = 0; $i < count($trace); $i++)
42                                 {
43                                         if (strpos($trace[$i]['function'], 'test') === 0)
44                                         {
45                                                 $failed_tests[$trace[$i]['function']] = true;
46                                                 break;
47                                         }
48                                 }
49                         }
50                 }
51
52                 function setUp()
53                 {
54                         global $DEBUG, $LOCALSERVER, $URI;
55                         $server = explode(':', $LOCALSERVER);
56                         if(count($server) > 1)
57                         {
58                                 $this->client=new xmlrpc_client($URI, $server[0], $server[1]);
59                         }
60                         else
61                         {
62                                 $this->client=new xmlrpc_client($URI, $LOCALSERVER);
63                         }
64                         if($DEBUG)
65                         {
66                                 $this->client->setDebug($DEBUG);
67                         }
68                         $this->client->request_compression = $this->request_compression;
69                         $this->client->accepted_compression = $this->accepted_compression;
70                 }
71
72                 function send($msg, $errrorcode=0, $return_response=false)
73                 {
74                         $r = $this->client->send($msg, $this->timeout, $this->method);
75                         // for multicall, return directly array of responses
76                         if(is_array($r))
77                         {
78                                 return $r;
79                         }
80                         $this->assertEquals($r->faultCode(), $errrorcode, 'Error '.$r->faultCode().' connecting to server: '.$r->faultString());
81                         if(!$r->faultCode())
82                         {
83                                 if($return_response)
84                                         return $r;
85                                 else
86                                         return $r->value();
87                         }
88                         else
89                         {
90                                 return null;
91                         }
92                 }
93
94                 function testString()
95                 {
96                         $sendstring="here are 3 \"entities\": < > &" .
97                                 "and here's a dollar sign: \$pretendvarname and a backslash too: " . chr(92) .
98                                 " - isn't that great? \\\"hackery\\\" at it's best " .
99                                 " also don't want to miss out on \$item[0]. ".
100                                 "The real weird stuff follows: CRLF here".chr(13).chr(10).
101                                 "a simple CR here".chr(13).
102                                 "a simple LF here".chr(10).
103                                 "and then LFCR".chr(10).chr(13).
104                                 "last but not least weird names: Günter, Elène, and an xml comment closing tag: -->";
105                         $f=new xmlrpcmsg('examples.stringecho', array(
106                                 new xmlrpcval($sendstring, 'string')
107                         ));
108                         $v=$this->send($f);
109                         if($v)
110                         {
111                                 // when sending/receiving non-US-ASCII encoded strings, XML says cr-lf can be normalized.
112                                 // so we relax our tests...
113                                 $l1 = strlen($sendstring);
114                                 $l2 = strlen($v->scalarval());
115                                 if ($l1 == $l2)
116                                         $this->assertEquals($sendstring, $v->scalarval());
117                                 else
118                                         $this->assertEquals(str_replace(array("\r\n", "\r"), array("\n", "\n"), $sendstring), $v->scalarval());
119                         }
120                 }
121
122                 function testAddingDoubles()
123                 {
124                         // note that rounding errors mean i
125                         // keep precision to sensible levels here ;-)
126                         $a=12.13; $b=-23.98;
127                         $f=new xmlrpcmsg('examples.addtwodouble',array(
128                                 new xmlrpcval($a, 'double'),
129                                 new xmlrpcval($b, 'double')
130                         ));
131                         $v=$this->send($f);
132                         if($v)
133                         {
134                                 $this->assertEquals($a+$b,$v->scalarval());
135                         }
136                 }
137
138                 function testAdding()
139                 {
140                         $f=new xmlrpcmsg('examples.addtwo',array(
141                                 new xmlrpcval(12, 'int'),
142                                 new xmlrpcval(-23, 'int')
143                         ));
144                         $v=$this->send($f);
145                         if($v)
146                         {
147                                 $this->assertEquals(12-23, $v->scalarval());
148                         }
149                 }
150
151                 function testInvalidNumber()
152                 {
153                         $f=new xmlrpcmsg('examples.addtwo',array(
154                                 new xmlrpcval('fred', 'int'),
155                                 new xmlrpcval("\"; exec('ls')", 'int')
156                         ));
157                         $v=$this->send($f);
158                         /// @todo a fault condition should be generated here
159                         /// by the server, which we pick up on
160                         if($v)
161                         {
162                                 $this->assertEquals(0, $v->scalarval());
163                         }
164                 }
165
166                 function testBoolean()
167                 {
168                         $f=new xmlrpcmsg('examples.invertBooleans', array(
169                                 new xmlrpcval(array(
170                                         new xmlrpcval(true, 'boolean'),
171                                         new xmlrpcval(false, 'boolean'),
172                                         new xmlrpcval(1, 'boolean'),
173                                         new xmlrpcval(0, 'boolean'),
174                                         //new xmlrpcval('true', 'boolean'),
175                                         //new xmlrpcval('false', 'boolean')
176                                 ),
177                                 'array'
178                         )));
179                         $answer='0101';
180                         $v=$this->send($f);
181                         if($v)
182                         {
183                                 $sz=$v->arraysize();
184                                 $got='';
185                                 for($i=0; $i<$sz; $i++)
186                                 {
187                                         $b=$v->arraymem($i);
188                                         if($b->scalarval())
189                                         {
190                                                 $got.='1';
191                                         }
192                                         else
193                                         {
194                                                 $got.='0';
195                                         }
196                                 }
197                                 $this->assertEquals($answer, $got);
198                         }
199                 }
200
201                 function testBase64()
202                 {
203                         $sendstring='Mary had a little lamb,
204 Whose fleece was white as snow,
205 And everywhere that Mary went
206 the lamb was sure to go.
207
208 Mary had a little lamb
209 She tied it to a pylon
210 Ten thousand volts went down its back
211 And turned it into nylon';
212                         $f=new xmlrpcmsg('examples.decode64',array(
213                                 new xmlrpcval($sendstring, 'base64')
214                         ));
215                         $v=$this->send($f);
216                         if($v)
217                         {
218                                 if (strlen($sendstring) == strlen($v->scalarval()))
219                                         $this->assertEquals($sendstring, $v->scalarval());
220                                 else
221                                         $this->assertEquals(str_replace(array("\r\n", "\r"), array("\n", "\n"), $sendstring), $v->scalarval());
222                         }
223                 }
224
225         function testDateTime()
226         {
227             $time = time();
228             $t1 = new xmlrpcval($time, 'dateTime.iso8601');
229             $t2 = new xmlrpcval(iso8601_encode($time), 'dateTime.iso8601');
230             $this->assertEquals($t1->serialize(), $t2->serialize());
231             if (class_exists('DateTime'))
232             {
233                 $datetime = new DateTime();
234                 $t3 = new xmlrpcval($datetime->setTimestamp($time), 'dateTime.iso8601');
235                 $this->assertEquals($t1->serialize(), $t3->serialize());
236             }
237         }
238
239                 function testCountEntities()
240                 {
241                         $sendstring = "h'fd>onc>>l>>rw&bpu>q>e<v&gxs<ytjzkami<";
242                         $f = new xmlrpcmsg('validator1.countTheEntities',array(
243                                 new xmlrpcval($sendstring, 'string')
244                         ));
245                         $v = $this->send($f);
246                         if($v)
247                         {
248                                 $got = '';
249                                 $expected = '37210';
250                                 $expect_array = array('ctLeftAngleBrackets','ctRightAngleBrackets','ctAmpersands','ctApostrophes','ctQuotes');
251                                 while(list(,$val) = each($expect_array))
252                                 {
253                                         $b = $v->structmem($val);
254                                         $got .= $b->me['int'];
255                                 }
256                                 $this->assertEquals($expected, $got);
257                         }
258                 }
259
260                 function _multicall_msg($method, $params)
261                 {
262                         $struct['methodName'] = new xmlrpcval($method, 'string');
263                         $struct['params'] = new xmlrpcval($params, 'array');
264                         return new xmlrpcval($struct, 'struct');
265                 }
266
267                 function testServerMulticall()
268                 {
269                         // We manually construct a system.multicall() call to ensure
270                         // that the server supports it.
271
272                         // NB: This test will NOT pass if server does not support system.multicall.
273
274                         // Based on http://xmlrpc-c.sourceforge.net/hacks/test_multicall.py
275                         $good1 = $this->_multicall_msg(
276                                 'system.methodHelp',
277                                 array(php_xmlrpc_encode('system.listMethods')));
278                         $bad = $this->_multicall_msg(
279                                 'test.nosuch',
280                                 array(php_xmlrpc_encode(1), php_xmlrpc_encode(2)));
281                         $recursive = $this->_multicall_msg(
282                                 'system.multicall',
283                                 array(new xmlrpcval(array(), 'array')));
284                         $good2 = $this->_multicall_msg(
285                                 'system.methodSignature',
286                                 array(php_xmlrpc_encode('system.listMethods')));
287                         $arg = new xmlrpcval(
288                                 array($good1, $bad, $recursive, $good2),
289                                 'array'
290                         );
291
292                         $f = new xmlrpcmsg('system.multicall', array($arg));
293                         $v = $this->send($f);
294                         if($v)
295                         {
296                                 //$this->assertTrue($r->faultCode() == 0, "fault from system.multicall");
297                                 $this->assertTrue($v->arraysize() == 4, "bad number of return values");
298
299                                 $r1 = $v->arraymem(0);
300                                 $this->assertTrue(
301                                         $r1->kindOf() == 'array' && $r1->arraysize() == 1,
302                                         "did not get array of size 1 from good1"
303                                 );
304
305                                 $r2 = $v->arraymem(1);
306                                 $this->assertTrue(
307                                         $r2->kindOf() == 'struct',
308                                         "no fault from bad"
309                                 );
310
311                                 $r3 = $v->arraymem(2);
312                                 $this->assertTrue(
313                                         $r3->kindOf() == 'struct',
314                                         "recursive system.multicall did not fail"
315                                 );
316
317                                 $r4 = $v->arraymem(3);
318                                 $this->assertTrue(
319                                         $r4->kindOf() == 'array' && $r4->arraysize() == 1,
320                                         "did not get array of size 1 from good2"
321                                 );
322                         }
323                 }
324
325                 function testClientMulticall1()
326                 {
327                         // NB: This test will NOT pass if server does not support system.multicall.
328
329                         $this->client->no_multicall = false;
330
331                         $good1 = new xmlrpcmsg('system.methodHelp',
332                                 array(php_xmlrpc_encode('system.listMethods')));
333                         $bad = new xmlrpcmsg('test.nosuch',
334                                 array(php_xmlrpc_encode(1), php_xmlrpc_encode(2)));
335                         $recursive = new xmlrpcmsg('system.multicall',
336                                 array(new xmlrpcval(array(), 'array')));
337                         $good2 = new xmlrpcmsg('system.methodSignature',
338                                 array(php_xmlrpc_encode('system.listMethods'))
339                         );
340
341                         $r = $this->send(array($good1, $bad, $recursive, $good2));
342                         if($r)
343                         {
344                                 $this->assertTrue(count($r) == 4, "wrong number of return values");
345                         }
346
347                         $this->assertTrue($r[0]->faultCode() == 0, "fault from good1");
348                         if(!$r[0]->faultCode())
349                         {
350                                 $val = $r[0]->value();
351                                 $this->assertTrue(
352                                         $val->kindOf() == 'scalar' && $val->scalartyp() == 'string',
353                                         "good1 did not return string"
354                                 );
355                         }
356                         $this->assertTrue($r[1]->faultCode() != 0, "no fault from bad");
357                         $this->assertTrue($r[2]->faultCode() != 0, "no fault from recursive system.multicall");
358                         $this->assertTrue($r[3]->faultCode() == 0, "fault from good2");
359                         if(!$r[3]->faultCode())
360                         {
361                                 $val = $r[3]->value();
362                                 $this->assertTrue($val->kindOf() == 'array', "good2 did not return array");
363                         }
364                         // This is the only assert in this test which should fail
365                         // if the test server does not support system.multicall.
366                         $this->assertTrue($this->client->no_multicall == false,
367                                 "server does not support system.multicall"
368                         );
369                 }
370
371                 function testClientMulticall2()
372                 {
373                         // NB: This test will NOT pass if server does not support system.multicall.
374
375                         $this->client->no_multicall = true;
376
377                         $good1 = new xmlrpcmsg('system.methodHelp',
378                                 array(php_xmlrpc_encode('system.listMethods')));
379                         $bad = new xmlrpcmsg('test.nosuch',
380                                 array(php_xmlrpc_encode(1), php_xmlrpc_encode(2)));
381                         $recursive = new xmlrpcmsg('system.multicall',
382                                 array(new xmlrpcval(array(), 'array')));
383                         $good2 = new xmlrpcmsg('system.methodSignature',
384                                 array(php_xmlrpc_encode('system.listMethods'))
385                         );
386
387                         $r = $this->send(array($good1, $bad, $recursive, $good2));
388                         if($r)
389                         {
390                                 $this->assertTrue(count($r) == 4, "wrong number of return values");
391                         }
392
393                         $this->assertTrue($r[0]->faultCode() == 0, "fault from good1");
394                         if(!$r[0]->faultCode())
395                         {
396                                 $val = $r[0]->value();
397                                 $this->assertTrue(
398                                         $val->kindOf() == 'scalar' && $val->scalartyp() == 'string',
399                                         "good1 did not return string");
400                         }
401                         $this->assertTrue($r[1]->faultCode() != 0, "no fault from bad");
402                         $this->assertTrue($r[2]->faultCode() == 0, "fault from (non recursive) system.multicall");
403                         $this->assertTrue($r[3]->faultCode() == 0, "fault from good2");
404                         if(!$r[3]->faultCode())
405                         {
406                                 $val = $r[3]->value();
407                                 $this->assertTrue($val->kindOf() == 'array', "good2 did not return array");
408                         }
409                 }
410
411                 function testClientMulticall3()
412                 {
413                         // NB: This test will NOT pass if server does not support system.multicall.
414
415                         $this->client->return_type = 'phpvals';
416                         $this->client->no_multicall = false;
417
418                         $good1 = new xmlrpcmsg('system.methodHelp',
419                                 array(php_xmlrpc_encode('system.listMethods')));
420                         $bad = new xmlrpcmsg('test.nosuch',
421                                 array(php_xmlrpc_encode(1), php_xmlrpc_encode(2)));
422                         $recursive = new xmlrpcmsg('system.multicall',
423                                 array(new xmlrpcval(array(), 'array')));
424                         $good2 = new xmlrpcmsg('system.methodSignature',
425                                 array(php_xmlrpc_encode('system.listMethods'))
426                         );
427
428                         $r = $this->send(array($good1, $bad, $recursive, $good2));
429                         if($r)
430                         {
431                                 $this->assertTrue(count($r) == 4, "wrong number of return values");
432                         }
433                         $this->assertTrue($r[0]->faultCode() == 0, "fault from good1");
434                         if(!$r[0]->faultCode())
435                         {
436                                 $val = $r[0]->value();
437                                 $this->assertTrue(
438                                         is_string($val) , "good1 did not return string");
439                         }
440                         $this->assertTrue($r[1]->faultCode() != 0, "no fault from bad");
441                         $this->assertTrue($r[2]->faultCode() != 0, "no fault from recursive system.multicall");
442                         $this->assertTrue($r[3]->faultCode() == 0, "fault from good2");
443                         if(!$r[3]->faultCode())
444                         {
445                                 $val = $r[3]->value();
446                                 $this->assertTrue(is_array($val), "good2 did not return array");
447                         }
448                         $this->client->return_type = 'xmlrpcvals';
449                 }
450
451                 function testCatchWarnings()
452                 {
453                         $f = new xmlrpcmsg('examples.generatePHPWarning', array(
454                                 new xmlrpcval('whatever', 'string')
455                         ));
456                         $v = $this->send($f);
457                         if($v)
458                         {
459                                 $this->assertEquals($v->scalarval(), true);
460                         }
461                 }
462
463             function testCatchExceptions()
464             {
465                 global $URI;
466                 $f = new xmlrpcmsg('examples.raiseException', array(
467                         new xmlrpcval('whatever', 'string')
468                 ));
469                 $v = $this->send($f, $GLOBALS['xmlrpcerr']['server_error']);
470                 $this->client->path = $URI.'?EXCEPTION_HANDLING=1';
471                 $v = $this->send($f, 1);
472                 $this->client->path = $URI.'?EXCEPTION_HANDLING=2';
473                 $v = $this->send($f, $GLOBALS['xmlrpcerr']['invalid_return']);
474             }
475
476                 function testZeroParams()
477                 {
478                         $f = new xmlrpcmsg('system.listMethods');
479                         $v = $this->send($f);
480                 }
481
482                 function testCodeInjectionServerSide()
483                 {
484                         $f = new xmlrpcmsg('system.MethodHelp');
485                         $f->payload = "<?xml version=\"1.0\"?><methodCall><methodName>validator1.echoStructTest</methodName><params><param><value><struct><member><name>','')); echo('gotcha!'); die(); //</name></member></struct></value></param></params></methodCall>";
486                         $v = $this->send($f);
487                         //$v = $r->faultCode();
488                         if ($v)
489                         {
490                                 $this->assertEquals(0, $v->structsize());
491                         }
492                 }
493
494                 function testAutoRegisteredFunction()
495                 {
496                         $f=new xmlrpcmsg('examples.php.getStateName',array(
497                                 new xmlrpcval(23, 'int')
498                         ));
499                         $v=$this->send($f);
500                         if($v)
501                         {
502                                 $this->assertEquals('Michigan', $v->scalarval());
503                         }
504                         else
505                         {
506                                 $this->fail('Note: server can only auto register functions if running with PHP 5.0.3 and up');
507                         }
508                 }
509
510                 function testAutoRegisteredClass()
511                 {
512                         $f=new xmlrpcmsg('examples.php2.getStateName',array(
513                                 new xmlrpcval(23, 'int')
514                         ));
515                         $v=$this->send($f);
516                         if($v)
517                         {
518                                 $this->assertEquals('Michigan', $v->scalarval());
519                         $f=new xmlrpcmsg('examples.php3.getStateName',array(
520                                 new xmlrpcval(23, 'int')
521                         ));
522                         $v=$this->send($f);
523                         if($v)
524                         {
525                                 $this->assertEquals('Michigan', $v->scalarval());
526                         }
527                 }
528                         else
529                         {
530                                 $this->fail('Note: server can only auto register class methods if running with PHP 5.0.3 and up');
531                         }
532                 }
533
534                 function testAutoRegisteredMethod()
535                 {
536                         $func=wrap_xmlrpc_method($this->client, 'examples.getStateName');
537                         if($func == '')
538                         {
539                                 $this->fail('Registration of examples.getStateName failed');
540                         }
541                         else
542                         {
543                                 $v=$func(23);
544                                 $this->assertEquals('Michigan', $v);
545                         }
546                 }
547
548                 function testGetCookies()
549                 {
550                         // let server set to us some cookies we tell it
551                         $cookies = array(
552                                 //'c1' => array(),
553                                 'c2' => array('value' => 'c2'),
554                                 'c3' => array('value' => 'c3', 'expires' => time()+60*60*24*30),
555                                 'c4' => array('value' => 'c4', 'expires' => time()+60*60*24*30, 'path' => '/'),
556                                 'c5' => array('value' => 'c5', 'expires' => time()+60*60*24*30, 'path' => '/', 'domain' => 'localhost'),
557                         );
558                         $cookiesval = php_xmlrpc_encode($cookies);
559                         $f=new xmlrpcmsg('examples.setcookies',array($cookiesval));
560                         $r=$this->send($f, 0, true);
561                         if($r)
562                         {
563                                 $v = $r->value();
564                                 $this->assertEquals(1, $v->scalarval());
565                                 // now check if we decoded the cookies as we had set them
566                                 $rcookies = $r->cookies();
567                                 foreach($cookies as $c => $v)
568                                 // format for date string in cookies: 'Mon, 31 Oct 2005 13:50:56 GMT'
569                                 // but PHP versions differ on that, some use 'Mon, 31-Oct-2005 13:50:56 GMT'...
570                                         if(isset($v['expires']))
571                                         {
572                                                 if (isset($rcookies[$c]['expires']) && strpos($rcookies[$c]['expires'], '-'))
573                                                 {
574                                                         $cookies[$c]['expires'] = gmdate('D, d\-M\-Y H:i:s \G\M\T' ,$cookies[$c]['expires']);
575                                                 }
576                                                 else
577                                                 {
578                                                         $cookies[$c]['expires'] = gmdate('D, d M Y H:i:s \G\M\T' ,$cookies[$c]['expires']);
579                                                 }
580                                         }
581                                 $this->assertEquals($cookies, $rcookies);
582                         }
583                 }
584
585                 function testSetCookies()
586                 {
587                         // let server set to us some cookies we tell it
588                         $cookies = array(
589                                 'c0' => null,
590                                 'c1' => 1,
591                                 'c2' => '2 3',
592                                 'c3' => '!@#$%^&*()_+|}{":?><,./\';[]\\=-'
593                         );
594                         $f=new xmlrpcmsg('examples.getcookies',array());
595                         foreach ($cookies as $cookie => $val)
596                         {
597                                 $this->client->setCookie($cookie, $val);
598                                 $cookies[$cookie] = (string) $cookies[$cookie];
599                         }
600                         $r = $this->client->send($f, $this->timeout, $this->method);
601                         $this->assertEquals($r->faultCode(), 0, 'Error '.$r->faultCode().' connecting to server: '.$r->faultString());
602                         if(!$r->faultCode())
603                         {
604                                 $v = $r->value();
605                                 $v = php_xmlrpc_decode($v);
606                                 // on IIS and Apache getallheaders returns something slightly different...
607                                 $this->assertEquals($v, $cookies);
608                         }
609                 }
610
611                 function testSendTwiceSameMsg()
612                 {
613                         $f=new xmlrpcmsg('examples.stringecho', array(
614                                 new xmlrpcval('hello world', 'string')
615                         ));
616                         $v1 = $this->send($f);
617                         $v2 = $this->send($f);
618                         //$v = $r->faultCode();
619                         if ($v1 && $v2)
620                         {
621                                 $this->assertEquals($v2, $v1);
622                         }
623                 }
624         }
625
626         class LocalHostMultiTests extends LocalhostTests
627         {
628                 function _runtests()
629                 {
630                         global $failed_tests;
631                         foreach(get_class_methods('LocalhostTests') as $meth)
632                         {
633                                 if(strpos($meth, 'test') === 0 && $meth != 'testHttps' && $meth != 'testCatchExceptions')
634                                 {
635                                         if (!isset($failed_tests[$meth]))
636                                                 $this->$meth();
637                                 }
638                                 if ($this->_failed)
639                                 {
640                                         break;
641                                 }
642                         }
643                 }
644
645                 function testDeflate()
646                 {
647                         if(!function_exists('gzdeflate'))
648                         {
649                                 $this->fail('Zlib missing: cannot test deflate functionality');
650                                 return;
651                         }
652                         $this->client->accepted_compression = array('deflate');
653                         $this->client->request_compression = 'deflate';
654                         $this->_runtests();
655                 }
656
657                 function testGzip()
658                 {
659                         if(!function_exists('gzdeflate'))
660                         {
661                                 $this->fail('Zlib missing: cannot test gzip functionality');
662                                 return;
663                         }
664                         $this->client->accepted_compression = array('gzip');
665                         $this->client->request_compression = 'gzip';
666                         $this->_runtests();
667                 }
668
669                 function testKeepAlives()
670                 {
671                         if(!function_exists('curl_init'))
672                         {
673                                 $this->fail('CURL missing: cannot test http 1.1');
674                                 return;
675                         }
676                         $this->method = 'http11';
677                         $this->client->keepalive = true;
678                         $this->_runtests();
679                 }
680
681                 function testProxy()
682                 {
683                         global $PROXYSERVER, $PROXYPORT;
684             if ($PROXYSERVER)
685             {
686                                 $this->client->setProxy($PROXYSERVER, $PROXYPORT);
687                                 $this->_runtests();
688             }
689             else
690                 $this->fail('PROXY definition missing: cannot test proxy');
691                 }
692
693                 function testHttp11()
694                 {
695                         if(!function_exists('curl_init'))
696                         {
697                                 $this->fail('CURL missing: cannot test http 1.1');
698                                 return;
699                         }
700                         $this->method = 'http11'; // not an error the double assignment!
701                         $this->client->method = 'http11';
702                         //$this->client->verifyhost = 0;
703                         //$this->client->verifypeer = 0;
704                         $this->client->keepalive = false;
705                         $this->_runtests();
706                 }
707
708                 function testHttp11Gzip()
709                 {
710                         if(!function_exists('curl_init'))
711                         {
712                                 $this->fail('CURL missing: cannot test http 1.1');
713                                 return;
714                         }
715                         $this->method = 'http11'; // not an error the double assignment!
716                         $this->client->method = 'http11';
717                         $this->client->keepalive = false;
718                         $this->client->accepted_compression = array('gzip');
719                         $this->client->request_compression = 'gzip';
720                         $this->_runtests();
721                 }
722
723                 function testHttp11Deflate()
724                 {
725                         if(!function_exists('curl_init'))
726                         {
727                                 $this->fail('CURL missing: cannot test http 1.1');
728                                 return;
729                         }
730                         $this->method = 'http11'; // not an error the double assignment!
731                         $this->client->method = 'http11';
732                         $this->client->keepalive = false;
733                         $this->client->accepted_compression = array('deflate');
734                         $this->client->request_compression = 'deflate';
735                         $this->_runtests();
736                 }
737
738                 function testHttp11Proxy()
739                 {
740                         global $PROXYSERVER, $PROXYPORT;
741                         if(!function_exists('curl_init'))
742                         {
743                                 $this->fail('CURL missing: cannot test http 1.1 w. proxy');
744                                 return;
745                         }
746             else if ($PROXYSERVER == '')
747             {
748                 $this->fail('PROXY definition missing: cannot test proxy w. http 1.1');
749                 return;
750             }
751                         $this->method = 'http11'; // not an error the double assignment!
752                         $this->client->method = 'http11';
753             $this->client->setProxy($PROXYSERVER, $PROXYPORT);
754                         //$this->client->verifyhost = 0;
755                         //$this->client->verifypeer = 0;
756                         $this->client->keepalive = false;
757                         $this->_runtests();
758                 }
759
760                 function testHttps()
761                 {
762                         global $HTTPSSERVER, $HTTPSURI;
763                         if(!function_exists('curl_init'))
764                         {
765                                 $this->fail('CURL missing: cannot test https functionality');
766                                 return;
767                         }
768                         $this->client->server = $HTTPSSERVER;
769                         $this->method = 'https';
770                         $this->client->method = 'https';
771                         $this->client->path = $HTTPSURI;
772                         $this->_runtests();
773                 }
774
775                 function testHttpsProxy()
776                 {
777                         global $HTTPSSERVER, $HTTPSURI, $PROXYSERVER, $PROXYPORT;;
778                         if(!function_exists('curl_init'))
779                         {
780                                 $this->fail('CURL missing: cannot test https functionality');
781                                 return;
782                         }
783             else if ($PROXYSERVER == '')
784             {
785                 $this->fail('PROXY definition missing: cannot test proxy w. http 1.1');
786                 return;
787             }
788                         $this->client->server = $HTTPSSERVER;
789                         $this->method = 'https';
790                         $this->client->method = 'https';
791             $this->client->setProxy($PROXYSERVER, $PROXYPORT);
792                         $this->client->path = $HTTPSURI;
793                         $this->_runtests();
794                 }
795
796                 function testUTF8Responses()
797                 {
798                         global $URI;
799                         //$this->client->path = strpos($URI, '?') === null ? $URI.'?RESPONSE_ENCODING=UTF-8' : $URI.'&RESPONSE_ENCODING=UTF-8';
800                         $this->client->path = $URI.'?RESPONSE_ENCODING=UTF-8';
801                         $this->_runtests();
802                 }
803
804                 function testUTF8Requests()
805                 {
806                         $this->client->request_charset_encoding = 'UTF-8';
807                         $this->_runtests();
808                 }
809
810                 function testISOResponses()
811                 {
812                         global $URI;
813                         //$this->client->path = strpos($URI, '?') === null ? $URI.'?RESPONSE_ENCODING=UTF-8' : $URI.'&RESPONSE_ENCODING=UTF-8';
814                         $this->client->path = $URI.'?RESPONSE_ENCODING=ISO-8859-1';
815                         $this->_runtests();
816                 }
817
818                 function testISORequests()
819                 {
820                         $this->client->request_charset_encoding = 'ISO-8859-1';
821                         $this->_runtests();
822                 }
823         }
824
825         class ParsingBugsTests extends PHPUnit_TestCase
826         {
827                 function testMinusOneString()
828                 {
829                         $v=new xmlrpcval('-1');
830                         $u=new xmlrpcval('-1', 'string');
831                         $this->assertEquals($u->scalarval(), $v->scalarval());
832                 }
833
834                 function testUnicodeInMemberName(){
835                         $v = array('Günter, Elène' => new xmlrpcval(1));
836                         $r = new xmlrpcresp(new xmlrpcval($v, 'struct'));
837                         $r = $r->serialize();
838                         $m = new xmlrpcmsg('dummy');
839                         $r = $m->parseResponse($r);
840                         $v = $r->value();
841                         $this->assertEquals($v->structmemexists('Günter, Elène'), true);
842                 }
843
844                 function testUnicodeInErrorString()
845                 {
846                         $response = utf8_encode(
847 '<?xml version="1.0"?>
848 <!-- $Id -->
849 <!-- found by G. giunta, covers what happens when lib receives
850   UTF8 chars in reponse text and comments -->
851 <!-- àüè&#224;&#252;&#232; -->
852 <methodResponse>
853 <fault>
854 <value>
855 <struct>
856 <member>
857 <name>faultCode</name>
858 <value><int>888</int></value>
859 </member>
860 <member>
861 <name>faultString</name>
862 <value><string>àüè&#224;&#252;&#232;</string></value>
863 </member>
864 </struct>
865 </value>
866 </fault>
867 </methodResponse>');
868                         $m=new xmlrpcmsg('dummy');
869                         $r=$m->parseResponse($response);
870                         $v=$r->faultString();
871                         $this->assertEquals('àüèàüè', $v);
872                 }
873
874                 function testValidNumbers()
875                 {
876                         $m=new xmlrpcmsg('dummy');
877                         $fp=
878 '<?xml version="1.0"?>
879 <methodResponse>
880 <params>
881 <param>
882 <value>
883 <struct>
884 <member>
885 <name>integer1</name>
886 <value><int>01</int></value>
887 </member>
888 <member>
889 <name>float1</name>
890 <value><double>01.10</double></value>
891 </member>
892 <member>
893 <name>integer2</name>
894 <value><int>+1</int></value>
895 </member>
896 <member>
897 <name>float2</name>
898 <value><double>+1.10</double></value>
899 </member>
900 <member>
901 <name>float3</name>
902 <value><double>-1.10e2</double></value>
903 </member>
904 </struct>
905 </value>
906 </param>
907 </params>
908 </methodResponse>';
909                         $r=$m->parseResponse($fp);
910                         $v=$r->value();
911                         $s=$v->structmem('integer1');
912                         $t=$v->structmem('float1');
913                         $u=$v->structmem('integer2');
914                         $w=$v->structmem('float2');
915                         $x=$v->structmem('float3');
916                         $this->assertEquals(1, $s->scalarval());
917                         $this->assertEquals(1.1, $t->scalarval());
918                         $this->assertEquals(1, $u->scalarval());
919                         $this->assertEquals(1.1, $w->scalarval());
920                         $this->assertEquals(-110.0, $x->scalarval());
921                 }
922
923                 function testAddScalarToStruct()
924                 {
925                         $v=new xmlrpcval(array('a' => 'b'), 'struct');
926                         // use @ operator in case error_log gets on screen
927                         $r= @$v->addscalar('c');
928                         $this->assertEquals(0, $r);
929                 }
930
931                 function testAddStructToStruct()
932                 {
933                         $v=new xmlrpcval(array('a' => new xmlrpcval('b')), 'struct');
934                         $r=$v->addstruct(array('b' => new xmlrpcval('c')));
935                         $this->assertEquals(2, $v->structsize());
936                         $this->assertEquals(1, $r);
937                         $r=$v->addstruct(array('b' => new xmlrpcval('b')));
938                         $this->assertEquals(2, $v->structsize());
939                 }
940
941                 function testAddArrayToArray()
942                 {
943                         $v=new xmlrpcval(array(new xmlrpcval('a'), new xmlrpcval('b')), 'array');
944                         $r=$v->addarray(array(new xmlrpcval('b'), new xmlrpcval('c')));
945                         $this->assertEquals(4, $v->arraysize());
946                         $this->assertEquals(1, $r);
947                 }
948
949                 function testEncodeArray()
950                 {
951                         $r=range(1, 100);
952                         $v = php_xmlrpc_encode($r);
953                         $this->assertEquals('array', $v->kindof());
954                 }
955
956                 function testEncodeRecursive()
957                 {
958                         $v = php_xmlrpc_encode(php_xmlrpc_encode('a simple string'));
959                         $this->assertEquals('scalar', $v->kindof());
960                 }
961
962                 function testBrokenRequests()
963                 {
964                         $s = new xmlrpc_server();
965 // omitting the 'params' tag: not tolerated by the lib anymore
966 $f = '<?xml version="1.0"?>
967 <methodCall>
968 <methodName>system.methodHelp</methodName>
969 <param>
970 <value><string>system.methodHelp</string></value>
971 </param>
972 </methodCall>';
973                         $r = $s->parserequest($f);
974                         $this->assertEquals(15, $r->faultCode());
975 // omitting a 'param' tag
976 $f = '<?xml version="1.0"?>
977 <methodCall>
978 <methodName>system.methodHelp</methodName>
979 <params>
980 <value><string>system.methodHelp</string></value>
981 </params>
982 </methodCall>';
983                         $r = $s->parserequest($f);
984                         $this->assertEquals(15, $r->faultCode());
985 // omitting a 'value' tag
986 $f = '<?xml version="1.0"?>
987 <methodCall>
988 <methodName>system.methodHelp</methodName>
989 <params>
990 <param><string>system.methodHelp</string></param>
991 </params>
992 </methodCall>';
993                         $r = $s->parserequest($f);
994                         $this->assertEquals(15, $r->faultCode());
995                 }
996
997                 function testBrokenResponses()
998                 {
999                         $m=new xmlrpcmsg('dummy');
1000                         //$m->debug = 1;
1001 // omitting the 'params' tag: no more tolerated by the lib...
1002 $f = '<?xml version="1.0"?>
1003 <methodResponse>
1004 <param>
1005 <value><string>system.methodHelp</string></value>
1006 </param>
1007 </methodResponse>';
1008                         $r = $m->parseResponse($f);
1009                         $this->assertEquals(2, $r->faultCode());
1010 // omitting the 'param' tag: no more tolerated by the lib...
1011 $f = '<?xml version="1.0"?>
1012 <methodResponse>
1013 <params>
1014 <value><string>system.methodHelp</string></value>
1015 </params>
1016 </methodResponse>';
1017                         $r = $m->parseResponse($f);
1018                         $this->assertEquals(2, $r->faultCode());
1019 // omitting a 'value' tag: KO
1020 $f = '<?xml version="1.0"?>
1021 <methodResponse>
1022 <params>
1023 <param><string>system.methodHelp</string></param>
1024 </params>
1025 </methodResponse>';
1026                         $r = $m->parseResponse($f);
1027                         $this->assertEquals(2, $r->faultCode());
1028                 }
1029
1030                 function testBuggyHttp()
1031                 {
1032                         $s = new xmlrpcmsg('dummy');
1033 $f = 'HTTP/1.1 100 Welcome to the jungle
1034
1035 HTTP/1.0 200 OK
1036 X-Content-Marx-Brothers: Harpo
1037                         Chico and Groucho
1038 Content-Length: who knows?
1039
1040
1041
1042 <?xml version="1.0"?>
1043 <!-- First of all, let\'s check out if the lib properly handles a commented </methodResponse> tag... -->
1044 <methodResponse><params><param><value><struct><member><name>userid</name><value>311127</value></member>
1045 <member><name>dateCreated</name><value><dateTime.iso8601>20011126T09:17:52</dateTime.iso8601></value></member><member><name>content</name><value>hello world. 2 newlines follow
1046
1047
1048 and there they were.</value></member><member><name>postid</name><value>7414222</value></member></struct></value></param></params></methodResponse>
1049 <script type="text\javascript">document.write(\'Hello, my name is added nag, I\\\'m happy to serve your content for free\');</script>
1050  ';
1051                         $r = $s->parseResponse($f);
1052                         $v = $r->value();
1053                         $s = $v->structmem('content');
1054                         $this->assertEquals("hello world. 2 newlines follow\n\n\nand there they were.", $s->scalarval());
1055                 }
1056
1057                 function testStringBug()
1058                 {
1059                         $s = new xmlrpcmsg('dummy');
1060 $f = '<?xml version="1.0"?>
1061 <!-- $Id -->
1062 <!-- found by 2z69xks7bpy001@sneakemail.com, amongst others
1063  covers what happens when there\'s character data after </string>
1064  and before </value> -->
1065 <methodResponse>
1066 <params>
1067 <param>
1068 <value>
1069 <struct>
1070 <member>
1071 <name>success</name>
1072 <value>
1073 <boolean>1</boolean>
1074 </value>
1075 </member>
1076 <member>
1077 <name>sessionID</name>
1078 <value>
1079 <string>S300510007I</string>
1080 </value>
1081 </member>
1082 </struct>
1083 </value>
1084 </param>
1085 </params>
1086 </methodResponse> ';
1087                         $r = $s->parseResponse($f);
1088                         $v = $r->value();
1089                         $s = $v->structmem('sessionID');
1090                         $this->assertEquals('S300510007I', $s->scalarval());
1091                 }
1092
1093                 function testWhiteSpace()
1094                 {
1095                         $s = new xmlrpcmsg('dummy');
1096 $f = '<?xml version="1.0"?><methodResponse><params><param><value><struct><member><name>userid</name><value>311127</value></member>
1097 <member><name>dateCreated</name><value><dateTime.iso8601>20011126T09:17:52</dateTime.iso8601></value></member><member><name>content</name><value>hello world. 2 newlines follow
1098
1099
1100 and there they were.</value></member><member><name>postid</name><value>7414222</value></member></struct></value></param></params></methodResponse>
1101 ';
1102                         $r = $s->parseResponse($f);
1103                         $v = $r->value();
1104                         $s = $v->structmem('content');
1105                         $this->assertEquals("hello world. 2 newlines follow\n\n\nand there they were.", $s->scalarval());
1106                 }
1107
1108                 function testDoubleDataInArrayTag()
1109                 {
1110                         $s = new xmlrpcmsg('dummy');
1111 $f = '<?xml version="1.0"?><methodResponse><params><param><value><array>
1112 <data></data>
1113 <data></data>
1114 </array></value></param></params></methodResponse>
1115 ';
1116                         $r = $s->parseResponse($f);
1117                         $v = $r->faultCode();
1118                         $this->assertEquals(2, $v);
1119 $f = '<?xml version="1.0"?><methodResponse><params><param><value><array>
1120 <data><value>Hello world</value></data>
1121 <data></data>
1122 </array></value></param></params></methodResponse>
1123 ';
1124                         $r = $s->parseResponse($f);
1125                         $v = $r->faultCode();
1126                         $this->assertEquals(2, $v);
1127                 }
1128
1129                 function testDoubleStuffInValueTag()
1130                 {
1131                         $s = new xmlrpcmsg('dummy');
1132 $f = '<?xml version="1.0"?><methodResponse><params><param><value>
1133 <string>hello world</string>
1134 <array><data></data></array>
1135 </value></param></params></methodResponse>
1136 ';
1137                         $r = $s->parseResponse($f);
1138                         $v = $r->faultCode();
1139                         $this->assertEquals(2, $v);
1140 $f = '<?xml version="1.0"?><methodResponse><params><param><value>
1141 <string>hello</string>
1142 <string>world</string>
1143 </value></param></params></methodResponse>
1144 ';
1145                         $r = $s->parseResponse($f);
1146                         $v = $r->faultCode();
1147                         $this->assertEquals(2, $v);
1148 $f = '<?xml version="1.0"?><methodResponse><params><param><value>
1149 <string>hello</string>
1150 <struct><member><name>hello><value>world</value></member></struct>
1151 </value></param></params></methodResponse>
1152 ';
1153                         $r = $s->parseResponse($f);
1154                         $v = $r->faultCode();
1155                         $this->assertEquals(2, $v);
1156                 }
1157
1158                 function testAutodecodeResponse()
1159                 {
1160                         $s = new xmlrpcmsg('dummy');
1161 $f = '<?xml version="1.0"?><methodResponse><params><param><value><struct><member><name>userid</name><value>311127</value></member>
1162 <member><name>dateCreated</name><value><dateTime.iso8601>20011126T09:17:52</dateTime.iso8601></value></member><member><name>content</name><value>hello world. 2 newlines follow
1163
1164
1165 and there they were.</value></member><member><name>postid</name><value>7414222</value></member></struct></value></param></params></methodResponse>
1166 ';
1167                         $r = $s->parseResponse($f, true, 'phpvals');
1168                         $v = $r->value();
1169                         $s = $v['content'];
1170                         $this->assertEquals("hello world. 2 newlines follow\n\n\nand there they were.", $s);
1171                 }
1172
1173                 function testNoDecodeResponse()
1174                 {
1175                         $s = new xmlrpcmsg('dummy');
1176 $f = '<?xml version="1.0"?><methodResponse><params><param><value><struct><member><name>userid</name><value>311127</value></member>
1177 <member><name>dateCreated</name><value><dateTime.iso8601>20011126T09:17:52</dateTime.iso8601></value></member><member><name>content</name><value>hello world. 2 newlines follow
1178
1179
1180 and there they were.</value></member><member><name>postid</name><value>7414222</value></member></struct></value></param></params></methodResponse>';
1181                         $r = $s->parseResponse($f, true, 'xml');
1182                         $v = $r->value();
1183                         $this->assertEquals($f, $v);
1184                 }
1185
1186                 function testAutoCoDec()
1187                 {
1188                         $data1 = array(1, 1.0, 'hello world', true, '20051021T23:43:00', -1, 11.0, '~!@#$%^&*()_+|', false, '20051021T23:43:00');
1189                         $data2 = array('zero' => $data1, 'one' => $data1, 'two' => $data1, 'three' => $data1, 'four' => $data1, 'five' => $data1, 'six' => $data1, 'seven' => $data1, 'eight' => $data1, 'nine' => $data1);
1190                         $data = array($data2, $data2, $data2, $data2, $data2, $data2, $data2, $data2, $data2, $data2);
1191                         //$keys = array('zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine');
1192                         $v1 = php_xmlrpc_encode($data, array('auto_dates'));
1193                         $v2 = php_xmlrpc_decode_xml($v1->serialize());
1194                         $this->assertEquals($v1, $v2);
1195                         $r1 = new xmlrpcresp($v1);
1196                         $r2 = php_xmlrpc_decode_xml($r1->serialize());
1197                         $r2->serialize(); // needed to set internal member payload
1198                         $this->assertEquals($r1, $r2);
1199                         $m1 = new xmlrpcmsg('hello dolly', array($v1));
1200                         $m2 = php_xmlrpc_decode_xml($m1->serialize());
1201                         $m2->serialize(); // needed to set internal member payload
1202                         $this->assertEquals($m1, $m2);
1203                 }
1204
1205                 function testUTF8Request()
1206                 {
1207                         $sendstring='κόσμε'; // Greek word 'kosme'. NB: NOT a valid ISO8859 string!
1208                         $GLOBALS['xmlrpc_internalencoding'] = 'UTF-8';
1209                         $f = new xmlrpcval($sendstring, 'string');
1210                         $v=$f->serialize();
1211                         $this->assertEquals("<value><string>&#954;&#8057;&#963;&#956;&#949;</string></value>\n", $v);
1212                         $GLOBALS['xmlrpc_internalencoding'] = 'ISO-8859-1';
1213                 }
1214
1215                 function testUTF8Response()
1216                 {
1217                         $s = new xmlrpcmsg('dummy');
1218 $f = "HTTP/1.1 200 OK\r\nContent-type: text/xml; charset=UTF-8\r\n\r\n".'<?xml version="1.0"?><methodResponse><params><param><value><struct><member><name>userid</name><value>311127</value></member>
1219 <member><name>dateCreated</name><value><dateTime.iso8601>20011126T09:17:52</dateTime.iso8601></value></member><member><name>content</name><value>'.utf8_encode('àüèàüè').'</value></member><member><name>postid</name><value>7414222</value></member></struct></value></param></params></methodResponse>
1220 ';
1221                         $r = $s->parseResponse($f, false, 'phpvals');
1222                         $v = $r->value();
1223                         $v = $v['content'];
1224                         $this->assertEquals("àüèàüè", $v);
1225 $f = '<?xml version="1.0" encoding="utf-8"?><methodResponse><params><param><value><struct><member><name>userid</name><value>311127</value></member>
1226 <member><name>dateCreated</name><value><dateTime.iso8601>20011126T09:17:52</dateTime.iso8601></value></member><member><name>content</name><value>'.utf8_encode('àüèàüè').'</value></member><member><name>postid</name><value>7414222</value></member></struct></value></param></params></methodResponse>
1227 ';
1228                         $r = $s->parseResponse($f, false, 'phpvals');
1229                         $v = $r->value();
1230                         $v = $v['content'];
1231                         $this->assertEquals("àüèàüè", $v);
1232                 }
1233
1234                 function testUTF8IntString()
1235                 {
1236                         $v=new xmlrpcval(100, 'int');
1237                         $s=$v->serialize('UTF-8');
1238                         $this->assertequals("<value><int>100</int></value>\n", $s);
1239                 }
1240
1241                 function testStringInt()
1242                 {
1243                         $v=new xmlrpcval('hello world', 'int');
1244                         $s=$v->serialize();
1245                         $this->assertequals("<value><int>0</int></value>\n", $s);
1246                 }
1247
1248                 function testStructMemExists()
1249                 {
1250                         $v=php_xmlrpc_encode(array('hello' => 'world'));
1251                         $b=$v->structmemexists('hello');
1252                         $this->assertequals(true, $b);
1253                         $b=$v->structmemexists('world');
1254                         $this->assertequals(false, $b);
1255                 }
1256
1257                 function testNilvalue()
1258                 {
1259                         // default case: we do not accept nil values received
1260                         $v = new xmlrpcval('hello', 'null');
1261                         $r = new xmlrpcresp($v);
1262                         $s = $r->serialize();
1263                         $m = new xmlrpcmsg('dummy');
1264                         $r = $m->parseresponse($s);
1265                         $this->assertequals(2, $r->faultCode());
1266                         // enable reception of nil values
1267                         $GLOBALS['xmlrpc_null_extension'] = true;
1268                         $r = $m->parseresponse($s);
1269                         $v = $r->value();
1270                         $this->assertequals('null', $v->scalartyp());
1271                     // test with the apache version: EX:NIL
1272                     $GLOBALS['xmlrpc_null_apache_encoding'] = true;
1273                     // serialization
1274                     $v = new xmlrpcval('hello', 'null');
1275                     $s = $v->serialize();
1276                     $this->assertequals(1, preg_match( '#<value><ex:nil/></value>#', $s ));
1277                     // deserialization
1278             $r = new xmlrpcresp($v);
1279             $s = $r->serialize();
1280             $r = $m->parseresponse($s);
1281             $v = $r->value();
1282             $this->assertequals('null', $v->scalartyp());
1283                     $GLOBALS['xmlrpc_null_extension'] = false;
1284                     $r = $m->parseresponse($s);
1285                     $this->assertequals(2, $r->faultCode());
1286                 }
1287
1288                 function TestLocale()
1289         {
1290             $locale = setlocale(LC_NUMERIC,0);
1291             if ( setlocale(LC_NUMERIC,'deu', 'de_DE@euro', 'de_DE', 'de', 'ge') !== false )
1292             {
1293                         $v = new xmlrpcval(1.1,'double');
1294                         $r = $v->serialize();
1295                         $this->assertequals(false, strpos($r,','));
1296                         $this->assertequals(1, strpos($v->scalarval(),','));
1297                         setlocale(LC_NUMERIC,$locale);
1298                 }
1299                 }
1300         }
1301
1302         class InvalidHostTests extends PHPUnit_TestCase
1303         {
1304                 var $client = null;
1305
1306                 function setUp()
1307                 {
1308                         global $DEBUG,$LOCALSERVER;
1309                         $this->client=new xmlrpc_client('/NOTEXIST.php', $LOCALSERVER, 80);
1310                         if($DEBUG)
1311                         {
1312                                 $this->client->setDebug($DEBUG);
1313                         }
1314                 }
1315
1316                 function test404()
1317                 {
1318                         $f = new xmlrpcmsg('examples.echo',array(
1319                                 new xmlrpcval('hello', 'string')
1320                         ));
1321                         $r = $this->client->send($f, 5);
1322                         $this->assertEquals(5, $r->faultCode());
1323                 }
1324
1325                 function testSrvNotFound()
1326                 {
1327                         $f = new xmlrpcmsg('examples.echo',array(
1328                                 new xmlrpcval('hello', 'string')
1329                         ));
1330                         $this->client->server .= 'XXX';
1331                         $r = $this->client->send($f, 5);
1332                         $this->assertEquals(5, $r->faultCode());
1333                 }
1334
1335                 function testCurlKAErr()
1336                 {
1337                         global $LOCALSERVER, $URI;
1338                         if(!function_exists('curl_init'))
1339                         {
1340                                 $this->fail('CURL missing: cannot test curl keepalive errors');
1341                                 return;
1342                         }
1343                         $f = new xmlrpcmsg('examples.stringecho',array(
1344                                 new xmlrpcval('hello', 'string')
1345                         ));
1346                         // test 2 calls w. keepalive: 1st time connection ko, second time ok
1347                         $this->client->server .= 'XXX';
1348                         $this->client->keepalive = true;
1349                         $r = $this->client->send($f, 5, 'http11');
1350                         $this->assertEquals(8, $r->faultCode());
1351
1352                         // now test a successful connection
1353                         $server = explode(':', $LOCALSERVER);
1354                         if(count($server) > 1)
1355                         {
1356                                 $this->client->port = $server[1];
1357                         }
1358                         $this->client->server = $server[0];
1359                         $this->client->path = $URI;
1360
1361                         $r = $this->client->send($f, 5, 'http11');
1362                         $ro = $r->value();
1363                         $this->assertEquals('hello', $ro->scalarVal());
1364                 }
1365         }
1366
1367
1368         $suite->addTest(new LocalhostTests('testString'));
1369         $suite->addTest(new LocalhostTests('testAdding'));
1370         $suite->addTest(new LocalhostTests('testAddingDoubles'));
1371         $suite->addTest(new LocalhostTests('testInvalidNumber'));
1372         $suite->addTest(new LocalhostTests('testBoolean'));
1373         $suite->addTest(new LocalhostTests('testCountEntities'));
1374         $suite->addTest(new LocalhostTests('testBase64'));
1375         $suite->addTest(new LocalhostTests('testDateTime'));
1376         $suite->addTest(new LocalhostTests('testServerMulticall'));
1377         $suite->addTest(new LocalhostTests('testClientMulticall1'));
1378         $suite->addTest(new LocalhostTests('testClientMulticall2'));
1379         $suite->addTest(new LocalhostTests('testClientMulticall3'));
1380         $suite->addTest(new LocalhostTests('testCatchWarnings'));
1381         $suite->addTest(new LocalhostTests('testCatchExceptions'));
1382         $suite->addTest(new LocalhostTests('testZeroParams'));
1383         $suite->addTest(new LocalhostTests('testCodeInjectionServerSide'));
1384         $suite->addTest(new LocalhostTests('testAutoRegisteredFunction'));
1385         $suite->addTest(new LocalhostTests('testAutoRegisteredMethod'));
1386         $suite->addTest(new LocalhostTests('testSetCookies'));
1387         $suite->addTest(new LocalhostTests('testGetCookies'));
1388         $suite->addTest(new LocalhostTests('testSendTwiceSameMsg'));
1389
1390         $suite->addTest(new LocalhostMultiTests('testUTF8Requests'));
1391         $suite->addTest(new LocalhostMultiTests('testUTF8Responses'));
1392         $suite->addTest(new LocalhostMultiTests('testISORequests'));
1393         $suite->addTest(new LocalhostMultiTests('testISOResponses'));
1394         $suite->addTest(new LocalhostMultiTests('testGzip'));
1395         $suite->addTest(new LocalhostMultiTests('testDeflate'));
1396         $suite->addTest(new LocalhostMultiTests('testProxy'));
1397         $suite->addTest(new LocalhostMultiTests('testHttp11'));
1398         $suite->addTest(new LocalhostMultiTests('testHttp11Gzip'));
1399         $suite->addTest(new LocalhostMultiTests('testHttp11Deflate'));
1400         $suite->addTest(new LocalhostMultiTests('testKeepAlives'));
1401         $suite->addTest(new LocalhostMultiTests('testHttp11Proxy'));
1402         $suite->addTest(new LocalhostMultiTests('testHttps'));
1403         $suite->addTest(new LocalhostMultiTests('testHttpsProxy'));
1404
1405         $suite->addTest(new InvalidHostTests('test404'));
1406         //$suite->addTest(new InvalidHostTests('testSrvNotFound'));
1407         $suite->addTest(new InvalidHostTests('testCurlKAErr'));
1408
1409         $suite->addTest(new ParsingBugsTests('testMinusOneString'));
1410         $suite->addTest(new ParsingBugsTests('testUnicodeInMemberName'));
1411         $suite->addTest(new ParsingBugsTests('testUnicodeInErrorString'));
1412         $suite->addTest(new ParsingBugsTests('testValidNumbers'));
1413         $suite->addTest(new ParsingBugsTests('testAddScalarToStruct'));
1414         $suite->addTest(new ParsingBugsTests('testAddStructToStruct'));
1415         $suite->addTest(new ParsingBugsTests('testAddArrayToArray'));
1416         $suite->addTest(new ParsingBugsTests('testEncodeArray'));
1417         $suite->addTest(new ParsingBugsTests('testEncodeRecursive'));
1418         $suite->addTest(new ParsingBugsTests('testBrokenrequests'));
1419         $suite->addTest(new ParsingBugsTests('testBrokenresponses'));
1420         $suite->addTest(new ParsingBugsTests('testBuggyHttp'));
1421         $suite->addTest(new ParsingBugsTests('testStringBug'));
1422         $suite->addTest(new ParsingBugsTests('testWhiteSpace'));
1423         $suite->addTest(new ParsingBugsTests('testAutodecodeResponse'));
1424         $suite->addTest(new ParsingBugsTests('testNoDecodeResponse'));
1425         $suite->addTest(new ParsingBugsTests('testAutoCoDec'));
1426         $suite->addTest(new ParsingBugsTests('testUTF8Response'));
1427         $suite->addTest(new ParsingBugsTests('testUTF8Request'));
1428         $suite->addTest(new ParsingBugsTests('testUTF8IntString'));
1429         $suite->addTest(new ParsingBugsTests('testStringInt'));
1430         $suite->addTest(new ParsingBugsTests('testStructMemExists'));
1431         $suite->addTest(new ParsingBugsTests('testDoubleDataInArrayTag'));
1432         $suite->addTest(new ParsingBugsTests('testDoubleStuffInValueTag'));
1433         $suite->addTest(new ParsingBugsTests('testNilValue'));
1434         $suite->addTest(new ParsingBugsTests('testLocale'));
1435
1436         $title = 'XML-RPC Unit Tests';
1437
1438         if(isset($only))
1439         {
1440                 $suite = new PHPUnit_TestSuite($only);
1441         }
1442
1443         if(isset($_SERVER['REQUEST_METHOD']))
1444         {
1445                 echo "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\" lang=\"en\" xml:lang=\"en\">\n<head>\n<title>$title</title>\n</head>\n<body>\n<h1>$title</h1>\n";
1446         }
1447         else
1448         {
1449                 echo "$title\n\n";
1450         }
1451
1452         if(isset($_SERVER['REQUEST_METHOD']))
1453         {
1454                 echo "<h3>Using lib version: $xmlrpcVersion on PHP version: ".phpversion()."</h3>\n";
1455                 echo '<h3>Running '.$suite->testCount().' tests (some of which are multiple) against servers: http://'.htmlspecialchars($LOCALSERVER.$URI).' and https://'.htmlspecialchars($HTTPSSERVER.$HTTPSURI)."\n ...</h3>\n";
1456                 flush();
1457             @ob_flush();
1458         }
1459         else
1460         {
1461                 echo "Using lib version: $xmlrpcVersion on PHP version: ".phpversion()."\n";
1462                 echo 'Running '.$suite->testCount().' tests (some of which are multiple) against servers: http://'.$LOCALSERVER.$URI.' and https://'.$HTTPSSERVER.$HTTPSURI."\n\n";
1463         }
1464
1465         // do some basic timing measurement
1466         list($micro, $sec) = explode(' ', microtime());
1467         $start_time = $sec + $micro;
1468
1469         $PHPUnit = new PHPUnit;
1470         $result = $PHPUnit->run($suite, ($DEBUG == 0 ? '.' : '<hr/>'));
1471
1472         list($micro, $sec) = explode(' ', microtime());
1473         $end_time = $sec + $micro;
1474
1475         if(!isset($_SERVER['REQUEST_METHOD']))
1476         {
1477                 echo $result->toString()."\n";
1478         }
1479
1480         if(isset($_SERVER['REQUEST_METHOD']))
1481         {
1482                 echo '<h3>'.$result->failureCount()." test failures</h3>\n";
1483                 printf("Time spent: %.2f secs<br/>\n", $end_time - $start_time);
1484         }
1485         else
1486         {
1487                 echo $result->failureCount()." test failures\n";
1488                 printf("Time spent: %.2f secs\n", $end_time - $start_time);
1489         }
1490
1491         if($result->failureCount() && !$DEBUG)
1492         {
1493                 $target = strpos($_SERVER['PHP_SELF'], '?') ? $_SERVER['PHP_SELF'].'&amp;DEBUG=1' : $_SERVER['PHP_SELF'].'?DEBUG=1';
1494                 $t2 = strpos($_SERVER['PHP_SELF'], '?') ? $_SERVER['PHP_SELF'].'&amp;DEBUG=2' : $_SERVER['PHP_SELF'].'?DEBUG=2';
1495                 if(isset($_SERVER['REQUEST_METHOD']))
1496                 {
1497                         echo '<p>Run testsuite with <a href="'.$target.'">DEBUG=1</a> to have more detail about tests results. Or with <a href="'.$t2.'">DEBUG=2</a> for even more.</p>'."\n";
1498                 }
1499                 else
1500                 {
1501                         echo "Run testsuite with DEBUG=1 (or 2) to have more detail about tests results\n";
1502                 }
1503         }
1504
1505         if(isset($_SERVER['REQUEST_METHOD']))
1506         {
1507 ?>
1508 <a href="#" onclick="if (document.getElementById('opts').style.display == 'block') document.getElementById('opts').style.display = 'none'; else document.getElementById('opts').style.display = 'block';">More options...</a>
1509 <div id="opts" style="display: none;">
1510 <form method="GET" style="border: 1px solid silver; margin: 5px; padding: 5px; font-family: monospace;">
1511 HTTP Server:&nbsp;&nbsp;<input name="LOCALSERVER" size="30" value="<?php echo htmlspecialchars($LOCALSERVER); ?>"/> Path: <input name="URI"  size="30" value="<?php echo htmlspecialchars($URI); ?>"/><br/>
1512 HTTPS Server: <input name="HTTPSSERVER" size="30" value="<?php echo htmlspecialchars($HTTPSSERVER); ?>"/> Path: <input name="HTTPSURI"  size="30" value="<?php echo htmlspecialchars($HTTPSURI); ?>"/><br/>
1513 Proxy Server: <input name="PROXY" size="30" value="<?php echo isset($PROXY) ? htmlspecialchars($PROXY) : ''; ?>"/> <input type="submit" value="Run Testsuite"/>
1514 </form>
1515 </div>
1516 <?php
1517                 echo $result->toHTML()."\n</body>\n</html>\n";
1518         }
1519 ?>