Passed
Push — master ( 02b7f4...c1cbf5 )
by Gaetano
07:18
created

ParsingTest::tear_down()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 9
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 7
nc 3
nop 0
dl 0
loc 9
rs 10
c 0
b 0
f 0
1
<?php
2
3
include_once __DIR__ . '/LogAwareTestCase.php';
4
5
/**
6
 * Tests involving xml parsing.
7
 *
8
 * @todo some tests are here even though they logically belong elsewhere...
9
 */
10
class ParsingTest extends PhpXmlRpc_LogAwareTestCase
11
{
12
    protected function newRequest($methodName, $params = array())
13
    {
14
        $msg = new xmlrpcmsg($methodName, $params);
15
        $msg->setDebug($this->args['DEBUG']);
16
        return $msg;
17
    }
18
19
    public function testValidNumbers()
20
    {
21
        $m = $this->newRequest('dummy');
22
        $fp =
23
            '<?xml version="1.0"?>
24
<methodResponse>
25
<params>
26
<param>
27
<value>
28
<struct>
29
<member><name>integer1</name><value><int>01</int></value></member>
30
<member><name>integer2</name><value><int>+1</int></value></member>
31
<member><name>integer3</name><value><i4>1</i4></value></member>
32
<member><name>integer4</name><value><int> 1 </int></value></member>
33
<member><name>float1</name><value><double>01.10</double></value></member>
34
<member><name>float2</name><value><double>+1.10</double></value></member>
35
<member><name>float3</name><value><double>-1.10e2</double></value></member>
36
<member><name>float4</name><value><double> -1.10e2 </double></value></member>
37
</struct>
38
</value>
39
</param>
40
</params>
41
</methodResponse>';
42
        $r = $m->parseResponse($fp);
43
        $v = $r->value();
44
        $s = $v->structmem('integer1');
0 ignored issues
show
Bug introduced by
The method structmem() does not exist on integer. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

44
        /** @scrutinizer ignore-call */ 
45
        $s = $v->structmem('integer1');

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
45
        $t = $v->structmem('integer2');
46
        $u = $v->structmem('integer3');
47
        $u2 = $v->structmem('integer4');
48
        $x = $v->structmem('float1');
49
        $y = $v->structmem('float2');
50
        $z = $v->structmem('float3');
51
        $z2 = $v->structmem('float4');
52
        $this->assertEquals(1, $s->scalarval());
53
        $this->assertEquals(1, $t->scalarval());
54
        $this->assertEquals(1, $u->scalarval());
55
        $this->assertEquals(1, $u2->scalarval());
56
        $this->assertEquals('int', $u->scalartyp());
57
58
        $this->assertEquals(1.1, $x->scalarval());
59
        $this->assertEquals(1.1, $y->scalarval());
60
        $this->assertEquals(-110.0, $z->scalarval());
61
        $this->assertEquals(-110.0, $z2->scalarval());
62
    }
63
64
    public function testBooleans()
65
    {
66
        $m = $this->newRequest('dummy');
67
        $fp =
68
            '<?xml version="1.0"?>
69
<methodResponse><params><param><value><struct>
70
<member><name>b1</name>
71
<value><boolean>1</boolean></value></member>
72
<member><name>b2</name>
73
<value><boolean> 1 </boolean></value></member>
74
<member><name>b3</name>
75
<value><boolean>tRuE</boolean></value></member>
76
<member><name>b4</name>
77
<value><boolean>0</boolean></value></member>
78
<member><name>b5</name>
79
<value><boolean> 0 </boolean></value></member>
80
<member><name>b6</name>
81
<value><boolean>fAlSe</boolean></value></member>
82
</struct></value></param></params></methodResponse>';
83
        $r = $m->parseResponse($fp);
84
        $v = $r->value();
85
86
        $s = $v->structmem('b1');
87
        $t = $v->structmem('b2');
0 ignored issues
show
Unused Code introduced by
The assignment to $t is dead and can be removed.
Loading history...
88
        $u = $v->structmem('b3');
89
        $x = $v->structmem('b4');
90
        $y = $v->structmem('b5');
0 ignored issues
show
Unused Code introduced by
The assignment to $y is dead and can be removed.
Loading history...
91
        $z = $v->structmem('b6');
92
93
        /// @todo this test fails with phpunit, but the same code works elsewhere! It makes string-int casting stricter??
94
        $this->assertEquals(true, $s->scalarval());
95
        //$this->assertEquals(true, $t->scalarval());
96
        $this->assertEquals(true, $u->scalarval());
97
        $this->assertEquals(false, $x->scalarval());
98
        //$this->assertEquals(false, $y->scalarval());
99
        $this->assertEquals(false, $z->scalarval());
100
    }
101
102
    public function testI8()
103
    {
104
        if (PHP_INT_SIZE == 4 ) {
105
            $this->markTestSkipped('Can not test i8 as php is compiled in 32 bit mode');
106
            return;
107
        }
108
109
        $m = $this->newRequest('dummy');
110
        $fp =
111
            '<?xml version="1.0"?>
112
<methodResponse>
113
<params>
114
<param>
115
<value>
116
<struct>
117
<member>
118
<name>integer1</name>
119
<value><i8>1</i8></value>
120
</member>
121
<member>
122
<name>integer2</name>
123
<value><ex:i8>1</ex:i8></value>
124
</member>
125
</struct>
126
</value>
127
</param>
128
</params>
129
</methodResponse>';
130
        $r = $m->parseResponse($fp);
131
        $v = $r->value();
132
        $s = $v->structmem('integer1');
133
        $this->assertEquals(1, $s->scalarval());
134
        $s = $v->structmem('integer2');
135
        $this->assertEquals(1, $s->scalarval());
136
        $this->assertEquals('i8', $s->scalartyp());
137
    }
138
139
    // struct with value before name, with no name, with no value, etc...
140
    public function testQuirkyStruct()
141
    {
142
        $m = $this->newRequest('dummy');
143
        $fp =
144
            '<?xml version="1.0"?>
145
<methodResponse>
146
<params>
147
<param>
148
<value>
149
<struct>
150
<member>
151
<value><int>1</int></value>
152
<name>Gollum</name>
153
</member>
154
<member>
155
<name>Bilbo</name>
156
</member>
157
<member>
158
<value><int>9</int></value>
159
</member>
160
<member>
161
<value><int>1</int></value>
162
</member>
163
</struct>
164
</value>
165
</param>
166
</params>
167
</methodResponse>';
168
        $r = $m->parseResponse($fp);
169
        $v = $r->value();
170
        $this->assertEquals(2, count($v));
0 ignored issues
show
Bug introduced by
$v of type integer is incompatible with the type Countable|array expected by parameter $value of count(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

170
        $this->assertEquals(2, count(/** @scrutinizer ignore-type */ $v));
Loading history...
171
        $s = $v['Gollum'];
172
        $this->assertEquals(1, $s->scalarval());
173
        $s = $v[''];
174
        $this->assertEquals(1, $s->scalarval());
175
    }
176
177
    public function testUnicodeInMemberName()
178
    {
179
        $str = "G" . chr(252) . "nter, El" . chr(232) . "ne";
180
        $v = array($str => new xmlrpcval(1));
181
        $r = new xmlrpcresp(new xmlrpcval($v, 'struct'));
182
        $r = $r->serialize();
183
        $m = $this->newRequest('dummy');
184
        $r = $m->parseResponse($r);
185
        $v = $r->value();
186
        $this->assertEquals(true, $v->structmemexists($str));
187
    }
188
189
    public function testUnicodeInErrorString()
190
    {
191
        // the warning suppression is due to utf8_decode being deprecated in php 8.2
192
        $response = @utf8_encode(
193
            '<?xml version="1.0"?>
194
<!-- covers what happens when lib receives UTF8 chars in response text and comments -->
195
<!-- ' . chr(224) . chr(252) . chr(232) . '&#224;&#252;&#232; -->
196
<methodResponse>
197
<fault>
198
<value>
199
<struct>
200
<member>
201
<name>faultCode</name>
202
<value><int>888</int></value>
203
</member>
204
<member>
205
<name>faultString</name>
206
<value><string>' . chr(224) . chr(252) . chr(232) . '&#224;&#252;&#232;</string></value>
207
</member>
208
</struct>
209
</value>
210
</fault>
211
</methodResponse>');
212
        $m = $this->newRequest('dummy');
213
        $r = $m->parseResponse($response);
214
        $v = $r->faultString();
215
        $this->assertEquals(chr(224) . chr(252) . chr(232) . chr(224) . chr(252) . chr(232), $v);
216
    }
217
218
    public function testBrokenRequests()
219
    {
220
        $s = new xmlrpc_server();
221
        // omitting the 'params' tag: not tolerated by the lib anymore
222
        $f = '<?xml version="1.0"?>
223
<methodCall>
224
<methodName>system.methodHelp</methodName>
225
<param>
226
<value><string>system.methodHelp</string></value>
227
</param>
228
</methodCall>';
229
        $r = $s->parserequest($f);
230
        $this->assertEquals(15, $r->faultCode());
231
        // omitting a 'param' tag
232
        $f = '<?xml version="1.0"?>
233
<methodCall>
234
<methodName>system.methodHelp</methodName>
235
<params>
236
<value><string>system.methodHelp</string></value>
237
</params>
238
</methodCall>';
239
        $r = $s->parserequest($f);
240
        $this->assertEquals(15, $r->faultCode());
241
        // omitting a 'value' tag
242
        $f = '<?xml version="1.0"?>
243
<methodCall>
244
<methodName>system.methodHelp</methodName>
245
<params>
246
<param><string>system.methodHelp</string></param>
247
</params>
248
</methodCall>';
249
        $r = $s->parserequest($f);
250
        $this->assertEquals(15, $r->faultCode());
251
    }
252
253
    public function testBrokenResponses()
254
    {
255
        $m = $this->newRequest('dummy');
256
        // omitting the 'params' tag: no more tolerated by the lib...
257
        $f = '<?xml version="1.0"?>
258
<methodResponse>
259
<param>
260
<value><string>system.methodHelp</string></value>
261
</param>
262
</methodResponse>';
263
        $r = $m->parseResponse($f);
264
        $this->assertEquals(2, $r->faultCode());
265
        // omitting the 'param' tag: no more tolerated by the lib...
266
        $f = '<?xml version="1.0"?>
267
<methodResponse>
268
<params>
269
<value><string>system.methodHelp</string></value>
270
</params>
271
</methodResponse>';
272
        $r = $m->parseResponse($f);
273
        $this->assertEquals(2, $r->faultCode());
274
        // omitting a 'value' tag: KO
275
        $f = '<?xml version="1.0"?>
276
<methodResponse>
277
<params>
278
<param><string>system.methodHelp</string></param>
279
</params>
280
</methodResponse>';
281
        $r = $m->parseResponse($f);
282
        $this->assertEquals(2, $r->faultCode());
283
    }
284
285
    public function testBuggyHttp()
286
    {
287
        $s = $this->newRequest('dummy');
288
        $f = 'HTTP/1.1 100 Welcome to the jungle
289
290
HTTP/1.0 200 OK
291
X-Content-Marx-Brothers: Harpo
292
        Chico and Groucho
293
Content-Length: who knows?
294
295
296
297
<?xml version="1.0"?>
298
<!-- First of all, let\'s check out if the lib properly handles a commented </methodResponse> tag... -->
299
<methodResponse><params><param><value><struct><member><name>userid</name><value>311127</value></member>
300
<member><name>dateCreated</name><value><dateTime.iso8601>20011126T09:17:52</dateTime.iso8601></value></member><member><name>content</name><value>hello world. 2 newlines follow
301
302
303
and there they were.</value></member><member><name>postid</name><value>7414222</value></member></struct></value></param></params></methodResponse>
304
<script type="text\javascript">document.write(\'Hello, my name is added nag, I\\\'m happy to serve your content for free\');</script>
305
 ';
306
        $r = $s->parseResponse($f);
307
        $v = $r->value();
308
        $s = $v->structmem('content');
309
        $this->assertEquals("hello world. 2 newlines follow\n\n\nand there they were.", $s->scalarval());
310
    }
311
312
    public function testStringBug()
313
    {
314
        $s = $this->newRequest('dummy');
315
        $f = '<?xml version="1.0"?>
316
<!-- found by [email protected], amongst others covers what happens when there\'s character data after </string>
317
 and before </value> -->
318
<methodResponse>
319
<params>
320
<param>
321
<value>
322
<struct>
323
<member>
324
<name>success</name>
325
<value>
326
<boolean>1</boolean>
327
</value>
328
</member>
329
<member>
330
<name>sessionID</name>
331
<value>
332
<string>S300510007I</string>
333
</value>
334
</member>
335
</struct>
336
</value>
337
</param>
338
</params>
339
</methodResponse> ';
340
        $r = $s->parseResponse($f);
341
        $v = $r->value();
342
        $s = $v->structmem('sessionID');
343
        $this->assertEquals('S300510007I', $s->scalarval());
344
    }
345
346
    public function testBase64()
347
    {
348
        $s = $this->newRequest('dummy');
349
        $f = '<?xml version="1.0"?><methodResponse><params><param><value><base64>
350
aGk=
351
</base64></value></param></params></methodResponse> ';
352
        $r = $s->parseResponse($f);
353
        $v = $r->value();
354
        $this->assertEquals('hi', $v->scalarval());
355
    }
356
357
    public function testInvalidValues()
358
    {
359
        $s = $this->newRequest('dummy');
360
        $f = '<?xml version="1.0"?><methodResponse><params><param><value><struct>
361
<member>
362
<name>bool</name>
363
<value><boolean>
364
yes
365
</boolean></value>
366
</member>
367
<member>
368
<name>double</name>
369
<value><double>
370
1.01
371
</double></value>
372
</member>
373
<member>
374
<name>int</name>
375
<value><int>
376
1
377
</int></value>
378
</member>
379
<member>
380
<name>date</name>
381
<value><dateTime.iso8601>
382
20011126T09:17:52
383
</dateTime.iso8601></value>
384
</member>
385
<member>
386
<name>base64</name>
387
<value><base64>
388
!
389
</base64></value>
390
</member>
391
</struct></value></param></params></methodResponse> ';
392
        $r = $s->parseResponse($f);
393
        $v = $r->value();
394
        // NB: this is the status-quo of the xml parser, rather than something we want the library to always be returning...
395
        $this->assertEquals(false, $v['bool']->scalarval());
396
        $this->assertEquals("ERROR_NON_NUMERIC_FOUND", $v['double']->scalarval());
397
        $this->assertEquals("ERROR_NON_NUMERIC_FOUND", $v['int']->scalarval());
398
        $this->assertEquals("\n20011126T09:17:52\n", $v['date']->scalarval());
399
        $this->assertEquals("", $v['base64']->scalarval());
400
    }
401
402
    public function testInvalidValuesStrictMode()
403
    {
404
        $s = $this->newRequest('dummy');
405
406
        $values = array(
407
            '<boolean>x</boolean>',
408
            '<double>x</double>',
409
            '<double>1..</double>',
410
            '<double>..1</double>',
411
            '<double>1.0.1</double>',
412
            '<int>x</int>',
413
            '<int>1.0</int>',
414
            '<dateTime.iso8601> 20011126T09:17:52</dateTime.iso8601>',
415
            '<dateTime.iso8601>20011126T09:17:52 </dateTime.iso8601>',
416
            '<base64>!</base64>'
417
        );
418
419
        $i = \PhpXmlRpc\PhpXmlRpc::$xmlrpc_reject_invalid_values;
420
        \PhpXmlRpc\PhpXmlRpc::$xmlrpc_reject_invalid_values = true;
421
422
        foreach($values as $value) {
423
            $f = '<?xml version="1.0"?><methodResponse><params><param><value>' . $value . '</value></param></params></methodResponse> ';
424
            $r = $s->parseResponse($f);
425
            $v = $r->faultCode();
426
            $this->assertEquals(2, $v, "Testing $value");
427
        }
428
429
        \PhpXmlRpc\PhpXmlRpc::$xmlrpc_reject_invalid_values = $i;
430
    }
431
432
    public function testNewlines()
433
    {
434
        $s = $this->newRequest('dummy');
435
        $f = '<?xml version="1.0"?><methodResponse><params><param><value><struct><member><name>userid</name><value>311127</value></member>
436
<member><name>dateCreated</name><value><dateTime.iso8601>20011126T09:17:52</dateTime.iso8601></value></member><member><name>content</name><value>hello world. 2 newlines follow
437
438
439
and there they were.</value></member><member><name>postid</name><value>7414222</value></member></struct></value></param></params></methodResponse>
440
';
441
        $r = $s->parseResponse($f);
442
        $v = $r->value();
443
        $s = $v->structmem('content');
444
        $this->assertEquals("hello world. 2 newlines follow\n\n\nand there they were.", $s->scalarval());
445
    }
446
447
    public function testDoubleDataInArrayTag()
448
    {
449
        $s = $this->newRequest('dummy');
450
        $f = '<?xml version="1.0"?><methodResponse><params><param><value><array>
451
<data></data>
452
<data></data>
453
</array></value></param></params></methodResponse>
454
';
455
        $r = $s->parseResponse($f);
456
        $v = $r->faultCode();
457
        $this->assertEquals(2, $v);
458
        $f = '<?xml version="1.0"?><methodResponse><params><param><value><array>
459
<data><value>Hello world</value></data>
460
<data></data>
461
</array></value></param></params></methodResponse>
462
';
463
        $r = $s->parseResponse($f);
464
        $v = $r->faultCode();
465
        $this->assertEquals(2, $v);
466
    }
467
468
    public function testDoubleStuffInValueTag()
469
    {
470
        $s = $this->newRequest('dummy');
471
        $f = '<?xml version="1.0"?><methodResponse><params><param><value>
472
<string>hello world</string>
473
<array><data></data></array>
474
</value></param></params></methodResponse>
475
';
476
        $r = $s->parseResponse($f);
477
        $v = $r->faultCode();
478
        $this->assertEquals(2, $v);
479
        $f = '<?xml version="1.0"?><methodResponse><params><param><value>
480
<string>hello</string>
481
<string>world</string>
482
</value></param></params></methodResponse>
483
';
484
        $r = $s->parseResponse($f);
485
        $v = $r->faultCode();
486
        $this->assertEquals(2, $v);
487
        $f = '<?xml version="1.0"?><methodResponse><params><param><value>
488
<string>hello</string>
489
<struct><member><name>hello><value>world</value></member></struct>
490
</value></param></params></methodResponse>
491
';
492
        $r = $s->parseResponse($f);
493
        $v = $r->faultCode();
494
        $this->assertEquals(2, $v);
495
    }
496
497
    public function testAutoDecodeResponse()
498
    {
499
        $s = $this->newRequest('dummy');
500
        $f = '<?xml version="1.0"?><methodResponse><params><param><value><struct><member><name>userid</name><value>311127</value></member>
501
<member><name>dateCreated</name><value><dateTime.iso8601>20011126T09:17:52</dateTime.iso8601></value></member><member><name>content</name><value>hello world. 3 newlines follow
502
503
504
and there they were.</value></member><member><name>postid</name><value>7414222</value></member></struct></value></param></params></methodResponse>
505
';
506
        $r = $s->parseResponse($f, true, 'phpvals');
507
        $v = $r->value();
508
        $s = $v['content'];
509
        $this->assertEquals("hello world. 3 newlines follow\n\n\nand there they were.", $s);
510
    }
511
512
    public function testNoDecodeResponse()
513
    {
514
        $s = $this->newRequest('dummy');
515
        $f = '<?xml version="1.0"?><methodResponse><params><param><value><struct><member><name>userid</name><value>311127</value></member>
516
<member><name>dateCreated</name><value><dateTime.iso8601>20011126T09:17:52</dateTime.iso8601></value></member><member><name>content</name><value>hello world. 3 newlines follow
517
518
519
and there they were.</value></member><member><name>postid</name><value>7414222</value></member></struct></value></param></params></methodResponse>';
520
        $r = $s->parseResponse($f, true, 'xml');
521
        $v = $r->value();
522
        $this->assertEquals($f, $v);
523
    }
524
525
    public function testUTF8Response()
526
    {
527
        $string = chr(224) . chr(252) . chr(232);
528
529
        $s = $this->newRequest('dummy');
530
        $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>
531
<member><name>dateCreated</name><value><dateTime.iso8601>20011126T09:17:52</dateTime.iso8601></value></member><member><name>content</name><value>' . @utf8_encode($string) . '</value></member><member><name>postid</name><value>7414222</value></member></struct></value></param></params></methodResponse>
532
';
533
        $r = $s->parseResponse($f, false, 'phpvals');
534
        $v = $r->value();
535
        $v = $v['content'];
536
        $this->assertEquals($string, $v);
537
538
        $f = '<?xml version="1.0" encoding="UTF-8"?><methodResponse><params><param><value><struct><member><name>userid</name><value>311127</value></member>
539
<member><name>dateCreated</name><value><dateTime.iso8601>20011126T09:17:52</dateTime.iso8601></value></member><member><name>content</name><value>' . @utf8_encode($string) . '</value></member><member><name>postid</name><value>7414222</value></member></struct></value></param></params></methodResponse>
540
';
541
        $r = $s->parseResponse($f, false, 'phpvals');
542
        $v = $r->value();
543
        $v = $v['content'];
544
        $this->assertEquals($string, $v);
545
546
        /// @todo move to EncoderTest
547
        $r = php_xmlrpc_decode_xml($f);
548
        $v = $r->value();
0 ignored issues
show
Bug introduced by
The method value() does not exist on PhpXmlRpc\Request. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

548
        /** @scrutinizer ignore-call */ 
549
        $v = $r->value();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
Bug introduced by
The method value() does not exist on PhpXmlRpc\Value. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

548
        /** @scrutinizer ignore-call */ 
549
        $v = $r->value();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
549
        $v = $v->structmem('content')->scalarval();
550
        $this->assertEquals($string, $v);
551
    }
552
553
    public function testLatin1Response()
554
    {
555
        $string = chr(224) . chr(252) . chr(232);
556
557
        $s = $this->newRequest('dummy');
558
        $f = "HTTP/1.1 200 OK\r\nContent-type: text/xml; charset=ISO-8859-1\r\n\r\n" . '<?xml version="1.0"?><methodResponse><params><param><value><struct><member><name>userid</name><value>311127</value></member>
559
<member><name>dateCreated</name><value><dateTime.iso8601>20011126T09:17:52</dateTime.iso8601></value></member><member><name>content</name><value>' . $string . '</value></member><member><name>postid</name><value>7414222</value></member></struct></value></param></params></methodResponse>
560
';
561
        $r = $s->parseResponse($f, false, 'phpvals');
562
        $v = $r->value();
563
        $v = $v['content'];
564
        $this->assertEquals($string, $v);
565
566
        $f = '<?xml version="1.0" encoding="ISO-8859-1"?><methodResponse><params><param><value><struct><member><name>userid</name><value>311127</value></member>
567
<member><name>dateCreated</name><value><dateTime.iso8601>20011126T09:17:52</dateTime.iso8601></value></member><member><name>content</name><value>' . $string . '</value></member><member><name>postid</name><value>7414222</value></member></struct></value></param></params></methodResponse>
568
';
569
        $r = $s->parseResponse($f, false, 'phpvals');
570
        $v = $r->value();
571
        $v = $v['content'];
572
        $this->assertEquals($string, $v);
573
574
        /// @todo move to EncoderTest
575
        $r = php_xmlrpc_decode_xml($f);
576
        $v = $r->value();
577
        $v = $v->structmem('content')->scalarval();
578
        $this->assertEquals($string, $v);
579
    }
580
581
    public function testDatetimeAsObject()
582
    {
583
        $s = $this->newRequest('dummy');
584
        $f = '<?xml version="1.0"?>
585
<methodResponse><params><param><value>
586
<dateTime.iso8601>20011126T09:17:52</dateTime.iso8601>
587
</value></param></params></methodResponse>';
588
589
        $o = \PhpXmlRpc\PhpXmlRpc::$xmlrpc_return_datetimes;
590
        \PhpXmlRpc\PhpXmlRpc::$xmlrpc_return_datetimes = true;
591
592
        $r = $s->parseResponse($f);
593
        $v = $r->value();
594
        $this->assertInstanceOf('\DateTime', $v->scalarval());
595
596
        \PhpXmlRpc\PhpXmlRpc::$xmlrpc_return_datetimes = $o;
597
    }
598
599
    public function testCustomDatetimeFormat()
600
    {
601
        $s = $this->newRequest('dummy');
602
        $f = '<?xml version="1.0"?>
603
<methodResponse><params><param><value>
604
<dateTime.iso8601>20011126T09:17:52+01:00</dateTime.iso8601>
605
</value></param></params></methodResponse>';
606
607
        $o = \PhpXmlRpc\PhpXmlRpc::$xmlrpc_return_datetimes;
608
        \PhpXmlRpc\PhpXmlRpc::$xmlrpc_return_datetimes = true;
609
        $i = \PhpXmlRpc\PhpXmlRpc::$xmlrpc_reject_invalid_values;
610
        \PhpXmlRpc\PhpXmlRpc::$xmlrpc_reject_invalid_values = true;
611
612
        $r = $s->parseResponse($f);
613
        $v = $r->faultCode();
614
        $this->assertNotEquals(0, $v);
615
616
        $d = \PhpXmlRpc\PhpXmlRpc::$xmlrpc_datetime_format;
617
        \PhpXmlRpc\PhpXmlRpc::$xmlrpc_datetime_format = '/^([0-9]{4})(0[1-9]|1[012])(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-4]):([0-5][0-9]):([0-5][0-9]|60)(Z|[+-][0-9]{2}(:?[0-9]{2})?)?$/';
618
619
        $r = $s->parseResponse($f);
620
        $v = $r->value();
621
        $this->assertInstanceOf('\DateTime', $v->scalarval());
622
623
        \PhpXmlRpc\PhpXmlRpc::$xmlrpc_return_datetimes = $o;
624
        \PhpXmlRpc\PhpXmlRpc::$xmlrpc_reject_invalid_values = $i;
625
        \PhpXmlRpc\PhpXmlRpc::$xmlrpc_datetime_format = $d;
626
    }
627
628
    /// @todo can we change this test to purely using the Value class ?
629
    /// @todo move test to its own class
630
    public function testNilSupport()
631
    {
632
        // default case: we do not accept nil values received
633
        $v = new xmlrpcval('hello', 'null');
634
        $r = new xmlrpcresp($v);
635
        $s = $r->serialize();
636
        $m = $this->newRequest('dummy');
637
        $r = $m->parseresponse($s);
638
        $this->assertequals(2, $r->faultCode());
639
        // enable reception of nil values
640
        $GLOBALS['xmlrpc_null_extension'] = true;
641
        \PhpXmlRpc\PhpXmlRpc::importGlobals();
642
        $r = $m->parseresponse($s);
643
        $v = $r->value();
644
        $this->assertequals('null', $v->scalartyp());
645
        // test with the apache version: EX:NIL
646
        $GLOBALS['xmlrpc_null_apache_encoding'] = true;
647
        \PhpXmlRpc\PhpXmlRpc::importGlobals();
648
        // serialization
649
        $v = new xmlrpcval('hello', 'null');
650
        $s = $v->serialize();
651
        $this->assertequals(1, preg_match('#<value><ex:nil/></value>#', $s));
652
        // deserialization
653
        $r = new xmlrpcresp($v);
654
        $s = $r->serialize();
655
        $r = $m->parseresponse($s);
656
        $v = $r->value();
657
        $this->assertequals('null', $v->scalartyp());
658
        $GLOBALS['xmlrpc_null_extension'] = false;
659
        \PhpXmlRpc\PhpXmlRpc::importGlobals();
660
        $r = $m->parseresponse($s);
661
        $this->assertequals(2, $r->faultCode());
662
    }
663
}
664