Passed
Push — master ( bb780a...ebcf65 )
by Gaetano
08:40
created

ParsingTests::testQuirkyStruct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 35
Code Lines 33

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 33
nc 1
nop 0
dl 0
loc 35
rs 9.392
c 0
b 0
f 0
1
<?php
2
3
include_once __DIR__ . '/../lib/xmlrpc.inc';
4
include_once __DIR__ . '/../lib/xmlrpcs.inc';
5
6
include_once __DIR__ . '/parse_args.php';
7
8
include_once __DIR__ . '/PolyfillTestCase.php';
9
10
use PHPUnit\Runner\BaseTestRunner;
11
12
/**
13
 * Tests involving xml parsing.
14
 *
15
 * @todo some tests are here even though they logically belong elsewhere...
16
 */
17
class ParsingTests extends PhpXmlRpc_PolyfillTestCase
18
{
19
    public $args = array();
20
21
    protected function set_up()
22
    {
23
        $this->args = argParser::getArgs();
24
        if ($this->args['DEBUG'] == 1)
25
            ob_start();
26
    }
27
28
    protected function tear_down()
29
    {
30
        if ($this->args['DEBUG'] != 1)
31
            return;
32
        $out = ob_get_clean();
33
        $status = $this->getStatus();
34
        if ($status == BaseTestRunner::STATUS_ERROR
35
            || $status == BaseTestRunner::STATUS_FAILURE) {
36
            echo $out;
37
        }
38
    }
39
40
    protected function newRequest($methodName, $params = array())
41
    {
42
        $msg = new xmlrpcmsg($methodName, $params);
43
        $msg->setDebug($this->args['DEBUG']);
44
        return $msg;
45
    }
46
47
    public function testValidNumbers()
48
    {
49
        $m = $this->newRequest('dummy');
50
        $fp =
51
            '<?xml version="1.0"?>
52
<methodResponse>
53
<params>
54
<param>
55
<value>
56
<struct>
57
<member><name>integer1</name><value><int>01</int></value></member>
58
<member><name>integer2</name><value><int>+1</int></value></member>
59
<member><name>integer3</name><value><i4>1</i4></value></member>
60
<member><name>integer4</name><value><int> 1 </int></value></member>
61
<member><name>float1</name><value><double>01.10</double></value></member>
62
<member><name>float2</name><value><double>+1.10</double></value></member>
63
<member><name>float3</name><value><double>-1.10e2</double></value></member>
64
<member><name>float4</name><value><double> -1.10e2 </double></value></member>
65
</struct>
66
</value>
67
</param>
68
</params>
69
</methodResponse>';
70
        $r = $m->parseResponse($fp);
71
        $v = $r->value();
72
        $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

72
        /** @scrutinizer ignore-call */ 
73
        $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...
73
        $t = $v->structmem('integer2');
74
        $u = $v->structmem('integer3');
75
        $u2 = $v->structmem('integer4');
76
        $x = $v->structmem('float1');
77
        $y = $v->structmem('float2');
78
        $z = $v->structmem('float3');
79
        $z2 = $v->structmem('float4');
80
        $this->assertEquals(1, $s->scalarval());
81
        $this->assertEquals(1, $t->scalarval());
82
        $this->assertEquals(1, $u->scalarval());
83
        $this->assertEquals(1, $u2->scalarval());
84
        $this->assertEquals('int', $u->scalartyp());
85
86
        $this->assertEquals(1.1, $x->scalarval());
87
        $this->assertEquals(1.1, $y->scalarval());
88
        $this->assertEquals(-110.0, $z->scalarval());
89
        $this->assertEquals(-110.0, $z2->scalarval());
90
    }
91
92
    public function testBooleans()
93
    {
94
        $m = $this->newRequest('dummy');
95
        $fp =
96
            '<?xml version="1.0"?>
97
<methodResponse><params><param><value><struct>
98
<member><name>b1</name>
99
<value><boolean>1</boolean></value></member>
100
<member><name>b2</name>
101
<value><boolean> 1 </boolean></value></member>
102
<member><name>b3</name>
103
<value><boolean>tRuE</boolean></value></member>
104
<member><name>b4</name>
105
<value><boolean>0</boolean></value></member>
106
<member><name>b5</name>
107
<value><boolean> 0 </boolean></value></member>
108
<member><name>b6</name>
109
<value><boolean>fAlSe</boolean></value></member>
110
</struct></value></param></params></methodResponse>';
111
        $r = $m->parseResponse($fp);
112
        $v = $r->value();
113
114
        $s = $v->structmem('b1');
115
        $t = $v->structmem('b2');
0 ignored issues
show
Unused Code introduced by
The assignment to $t is dead and can be removed.
Loading history...
116
        $u = $v->structmem('b3');
117
        $x = $v->structmem('b4');
118
        $y = $v->structmem('b5');
0 ignored issues
show
Unused Code introduced by
The assignment to $y is dead and can be removed.
Loading history...
119
        $z = $v->structmem('b6');
120
121
        /// @todo this test fails with phpunit, but the same code works elsewhere!
122
        $this->assertEquals(true, $s->scalarval());
123
        //$this->assertEquals(true, $t->scalarval());
124
        $this->assertEquals(true, $u->scalarval());
125
        $this->assertEquals(false, $x->scalarval());
126
        //$this->assertEquals(false, $y->scalarval());
127
        $this->assertEquals(false, $z->scalarval());
128
    }
129
130
    public function testI8()
131
    {
132
        if (PHP_INT_SIZE == 4 ) {
133
            $this->markTestSkipped('Can not test i8 as php is compiled in 32 bit mode');
134
            return;
135
        }
136
137
        $m = $this->newRequest('dummy');
138
        $fp =
139
            '<?xml version="1.0"?>
140
<methodResponse>
141
<params>
142
<param>
143
<value>
144
<struct>
145
<member>
146
<name>integer1</name>
147
<value><i8>1</i8></value>
148
</member>
149
<member>
150
<name>integer2</name>
151
<value><ex:i8>1</ex:i8></value>
152
</member>
153
</struct>
154
</value>
155
</param>
156
</params>
157
</methodResponse>';
158
        $r = $m->parseResponse($fp);
159
        $v = $r->value();
160
        $s = $v->structmem('integer1');
161
        $this->assertEquals(1, $s->scalarval());
162
        $s = $v->structmem('integer2');
163
        $this->assertEquals(1, $s->scalarval());
164
        $this->assertEquals('i8', $s->scalartyp());
165
    }
166
167
    // struct with value before name, with no name, with no value, etc...
168
    public function testQuirkyStruct()
169
    {
170
        $m = $this->newRequest('dummy');
171
        $fp =
172
            '<?xml version="1.0"?>
173
<methodResponse>
174
<params>
175
<param>
176
<value>
177
<struct>
178
<member>
179
<value><int>1</int></value>
180
<name>Gollum</name>
181
</member>
182
<member>
183
<name>Bilbo</name>
184
</member>
185
<member>
186
<value><int>9</int></value>
187
</member>
188
<member>
189
<value><int>1</int></value>
190
</member>
191
</struct>
192
</value>
193
</param>
194
</params>
195
</methodResponse>';
196
        $r = $m->parseResponse($fp);
197
        $v = $r->value();
198
        $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

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

576
        /** @scrutinizer ignore-call */ 
577
        $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

576
        /** @scrutinizer ignore-call */ 
577
        $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...
577
        $v = $v->structmem('content')->scalarval();
578
        $this->assertEquals($string, $v);
579
    }
580
581
    public function testLatin1Response()
582
    {
583
        $string = chr(224) . chr(252) . chr(232);
584
585
        $s = $this->newRequest('dummy');
586
        $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>
587
<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>
588
';
589
        $r = $s->parseResponse($f, false, 'phpvals');
590
        $v = $r->value();
591
        $v = $v['content'];
592
        $this->assertEquals($string, $v);
593
594
        $f = '<?xml version="1.0" encoding="ISO-8859-1"?><methodResponse><params><param><value><struct><member><name>userid</name><value>311127</value></member>
595
<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>
596
';
597
        $r = $s->parseResponse($f, false, 'phpvals');
598
        $v = $r->value();
599
        $v = $v['content'];
600
        $this->assertEquals($string, $v);
601
602
        /// @todo move to EncoderTest
603
        $r = php_xmlrpc_decode_xml($f);
604
        $v = $r->value();
605
        $v = $v->structmem('content')->scalarval();
606
        $this->assertEquals($string, $v);
607
    }
608
609
    public function testDatetimeAsObject()
610
    {
611
        $s = $this->newRequest('dummy');
612
        $f = '<?xml version="1.0"?>
613
<methodResponse><params><param><value>
614
<dateTime.iso8601>20011126T09:17:52</dateTime.iso8601>
615
</value></param></params></methodResponse>';
616
617
        $o = \PhpXmlRpc\PhpXmlRpc::$xmlrpc_return_datetimes;
618
        \PhpXmlRpc\PhpXmlRpc::$xmlrpc_return_datetimes = true;
619
620
        $r = $s->parseResponse($f);
621
        $v = $r->value();
622
        $this->assertInstanceOf('\DateTime', $v->scalarval());
623
624
        \PhpXmlRpc\PhpXmlRpc::$xmlrpc_return_datetimes = $o;
625
    }
626
627
    public function testCustomDatetimeFormat()
628
    {
629
        $s = $this->newRequest('dummy');
630
        $f = '<?xml version="1.0"?>
631
<methodResponse><params><param><value>
632
<dateTime.iso8601>20011126T09:17:52+01:00</dateTime.iso8601>
633
</value></param></params></methodResponse>';
634
635
        $o = \PhpXmlRpc\PhpXmlRpc::$xmlrpc_return_datetimes;
636
        \PhpXmlRpc\PhpXmlRpc::$xmlrpc_return_datetimes = true;
637
        $i = \PhpXmlRpc\PhpXmlRpc::$xmlrpc_reject_invalid_values;
638
        \PhpXmlRpc\PhpXmlRpc::$xmlrpc_reject_invalid_values = true;
639
640
        $r = $s->parseResponse($f);
641
        $v = $r->faultCode();
642
        $this->assertNotEquals(0, $v);
643
644
        $d = \PhpXmlRpc\PhpXmlRpc::$xmlrpc_datetime_format;
645
        \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})?)?$/';
646
647
        $r = $s->parseResponse($f);
648
        $v = $r->value();
649
        $this->assertInstanceOf('\DateTime', $v->scalarval());
650
651
        \PhpXmlRpc\PhpXmlRpc::$xmlrpc_return_datetimes = $o;
652
        \PhpXmlRpc\PhpXmlRpc::$xmlrpc_reject_invalid_values = $i;
653
        \PhpXmlRpc\PhpXmlRpc::$xmlrpc_datetime_format = $d;
654
    }
655
656
    /// @todo can we change this test to purely using the Value class ?
657
    /// @todo move test to its own class
658
    public function testNilSupport()
659
    {
660
        // default case: we do not accept nil values received
661
        $v = new xmlrpcval('hello', 'null');
662
        $r = new xmlrpcresp($v);
663
        $s = $r->serialize();
664
        $m = $this->newRequest('dummy');
665
        $r = $m->parseresponse($s);
666
        $this->assertequals(2, $r->faultCode());
667
        // enable reception of nil values
668
        $GLOBALS['xmlrpc_null_extension'] = true;
669
        \PhpXmlRpc\PhpXmlRpc::importGlobals();
670
        $r = $m->parseresponse($s);
671
        $v = $r->value();
672
        $this->assertequals('null', $v->scalartyp());
673
        // test with the apache version: EX:NIL
674
        $GLOBALS['xmlrpc_null_apache_encoding'] = true;
675
        \PhpXmlRpc\PhpXmlRpc::importGlobals();
676
        // serialization
677
        $v = new xmlrpcval('hello', 'null');
678
        $s = $v->serialize();
679
        $this->assertequals(1, preg_match('#<value><ex:nil/></value>#', $s));
680
        // deserialization
681
        $r = new xmlrpcresp($v);
682
        $s = $r->serialize();
683
        $r = $m->parseresponse($s);
684
        $v = $r->value();
685
        $this->assertequals('null', $v->scalartyp());
686
        $GLOBALS['xmlrpc_null_extension'] = false;
687
        \PhpXmlRpc\PhpXmlRpc::importGlobals();
688
        $r = $m->parseresponse($s);
689
        $this->assertequals(2, $r->faultCode());
690
    }
691
}
692