Passed
Push — master ( 8ff19d...02b7f4 )
by Gaetano
05:49
created

ParsingTest::testNewlines()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 13
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 6
nc 1
nop 0
dl 0
loc 13
rs 10
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 ParsingTest extends PhpXmlRpc_PolyfillTestCase
18
{
19
    public $args = array();
20
21
    protected function set_up()
22
    {
23
        $this->args = argParser::getArgs();
24
        // hide parsing errors unless in debug mode
25
        if ($this->args['DEBUG'] < 1)
26
            ob_start();
27
    }
28
29
    protected function tear_down()
30
    {
31
        if ($this->args['DEBUG'] >= 1)
32
            return;
33
        $out = ob_get_clean();
34
        $status = $this->getStatus();
35
        if ($status == BaseTestRunner::STATUS_ERROR
36
            || $status == BaseTestRunner::STATUS_FAILURE) {
37
            echo $out;
38
        }
39
    }
40
41
    protected function newRequest($methodName, $params = array())
42
    {
43
        $msg = new xmlrpcmsg($methodName, $params);
44
        $msg->setDebug($this->args['DEBUG']);
45
        return $msg;
46
    }
47
48
    public function testValidNumbers()
49
    {
50
        $m = $this->newRequest('dummy');
51
        $fp =
52
            '<?xml version="1.0"?>
53
<methodResponse>
54
<params>
55
<param>
56
<value>
57
<struct>
58
<member><name>integer1</name><value><int>01</int></value></member>
59
<member><name>integer2</name><value><int>+1</int></value></member>
60
<member><name>integer3</name><value><i4>1</i4></value></member>
61
<member><name>integer4</name><value><int> 1 </int></value></member>
62
<member><name>float1</name><value><double>01.10</double></value></member>
63
<member><name>float2</name><value><double>+1.10</double></value></member>
64
<member><name>float3</name><value><double>-1.10e2</double></value></member>
65
<member><name>float4</name><value><double> -1.10e2 </double></value></member>
66
</struct>
67
</value>
68
</param>
69
</params>
70
</methodResponse>';
71
        $r = $m->parseResponse($fp);
72
        $v = $r->value();
73
        $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

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

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

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

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