Passed
Push — master ( 0c0b5a...7953de )
by Gaetano
05:21
created

ServerTest::testUtf8Method()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 7
c 0
b 0
f 0
nc 2
nop 0
dl 0
loc 11
rs 10
1
<?php
2
3
include_once __DIR__ . '/../lib/xmlrpc.inc';
4
include_once __DIR__ . '/../lib/xmlrpc_wrappers.inc';
5
6
include_once __DIR__ . '/parse_args.php';
7
8
include_once __DIR__ . '/PolyfillTestCase.php';
9
10
use PHPUnit\Extensions\SeleniumCommon\RemoteCoverage;
11
use PHPUnit\Framework\TestResult;
12
use PHPUnit\Runner\BaseTestRunner;
13
14
/**
15
 * Tests which involve interaction between the client and the server.
16
 * They are run against the server found in demo/server.php.
17
 * Includes testing of (some of) the Wrapper class
18
 */
19
class ServerTest extends PhpXmlRpc_PolyfillTestCase
20
{
21
    /** @var xmlrpc_client $client */
22
    protected $client = null;
23
    protected $method = 'http';
24
    protected $timeout = 10;
25
    protected $request_compression = null;
26
    protected $accepted_compression = '';
27
    protected $args = array();
28
29
    protected static $failed_tests = array();
30
31
    protected $testId;
32
    /** @var boolean $collectCodeCoverageInformation */
33
    protected $collectCodeCoverageInformation;
34
    protected $coverageScriptUrl;
35
36
    /**
37
     * @todo instead of overriding fail via _fail, implement Yoast\PHPUnitPolyfills\TestListeners\TestListenerDefaultImplementation
38
     */
39
    public static function _fail($message = '')
40
    {
41
        // save in a static var that this particular test has failed
42
        // (but only if not called from subclass objects / multitests)
43
        if (function_exists('debug_backtrace') && strtolower(get_called_class()) == 'localhosttests') {
44
            $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
45
            for ($i = 0; $i < count($trace); $i++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
46
                if (strpos($trace[$i]['function'], 'test') === 0) {
47
                    self::$failed_tests[$trace[$i]['function']] = true;
48
                    break;
49
                }
50
            }
51
        }
52
53
        parent::_fail($message);
0 ignored issues
show
Unused Code introduced by
The call to PhpXmlRpc_PolyfillTestCase::_fail() has too many arguments starting with $message. ( Ignorable by Annotation )

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

53
        parent::/** @scrutinizer ignore-call */ 
54
                _fail($message);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
54
    }
55
56
    /**
57
     * Reimplemented to allow us to collect code coverage info from the target server.
58
     * Code taken from PHPUnit_Extensions_Selenium2TestCase
59
     *
60
     * @param TestResult $result
61
     * @return TestResult
62
     * @throws Exception
63
     *
64
     * @todo instead of overriding run via _run, try to achieve this by implementing Yoast\PHPUnitPolyfills\TestListeners\TestListenerDefaultImplementation
65
     */
66
    public function _run($result = NULL)
67
    {
68
        $this->testId = get_class($this) . '__' . $this->getName();
69
70
        if ($result === NULL) {
71
            $result = $this->createResult();
72
        }
73
74
        $this->collectCodeCoverageInformation = $result->getCollectCodeCoverageInformation();
75
76
        parent::_run($result);
77
78
        if ($this->collectCodeCoverageInformation) {
79
            $coverage = new RemoteCoverage(
80
                $this->coverageScriptUrl,
81
                $this->testId
82
            );
83
            $result->getCodeCoverage()->append(
84
                $coverage->get(), $this
85
            );
86
        }
87
88
        // do not call this before to give the time to the Listeners to run
89
        //$this->getStrategy()->endOfTest($this->session);
90
91
        return $result;
92
    }
93
94
    public function set_up()
95
    {
96
        $this->args = argParser::getArgs();
97
98
        $server = explode(':', $this->args['HTTPSERVER']);
99
        if (count($server) > 1) {
100
            $this->client = new xmlrpc_client($this->args['HTTPURI'], $server[0], $server[1]);
0 ignored issues
show
Bug introduced by
$server[1] of type string is incompatible with the type integer expected by parameter $port of xmlrpc_client::__construct(). ( Ignorable by Annotation )

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

100
            $this->client = new xmlrpc_client($this->args['HTTPURI'], $server[0], /** @scrutinizer ignore-type */ $server[1]);
Loading history...
101
        } else {
102
            $this->client = new xmlrpc_client($this->args['HTTPURI'], $this->args['HTTPSERVER']);
103
        }
104
105
        $this->client->setDebug($this->args['DEBUG']);
106
        $this->client->request_compression = $this->request_compression;
107
        $this->client->accepted_compression = $this->accepted_compression;
108
109
        $this->coverageScriptUrl = 'http://' . $this->args['HTTPSERVER'] . '/' . str_replace( '/demo/server/server.php', 'tests/phpunit_coverage.php', $this->args['HTTPURI'] );
110
111
        if ($this->args['DEBUG'] == 1)
112
            ob_start();
113
    }
114
115
    protected function tear_down()
116
    {
117
        if ($this->args['DEBUG'] != 1)
118
            return;
119
        $out = ob_get_clean();
120
        $status = $this->getStatus();
121
        if ($status == BaseTestRunner::STATUS_ERROR
122
            || $status == BaseTestRunner::STATUS_FAILURE) {
123
            echo $out;
124
        }
125
    }
126
127
    /**
128
     * @param PhpXmlRpc\Request|array $msg
129
     * @param int|array $errorCode expected error codes
130
     * @param bool $returnResponse
131
     * @return mixed|\PhpXmlRpc\Response|\PhpXmlRpc\Response[]|\PhpXmlRpc\Value|string|null
132
     */
133
    protected function send($msg, $errorCode = 0, $returnResponse = false)
134
    {
135
        if ($this->collectCodeCoverageInformation) {
136
            $this->client->setCookie('PHPUNIT_SELENIUM_TEST_ID', $this->testId);
137
        }
138
139
        $r = $this->client->send($msg, $this->timeout, $this->method);
140
        // for multicall, return directly array of responses
141
        if (is_array($r)) {
142
            return $r;
143
        }
144
        $this->validateResponse($r);
145
        if (is_array($errorCode)) {
146
            $this->assertContains($r->faultCode(), $errorCode, 'Error ' . $r->faultCode() . ' connecting to server: ' . $r->faultString());
147
        } else {
148
            $this->assertEquals($errorCode, $r->faultCode(), 'Error ' . $r->faultCode() . ' connecting to server: ' . $r->faultString());
149
        }
150
        if (!$r->faultCode()) {
151
            if ($returnResponse) {
152
                return $r;
153
            } else {
154
                return $r->value();
155
            }
156
        } else {
157
            return null;
158
        }
159
    }
160
161
    protected function validateResponse($r)
162
    {
163
        // to be implemented in subclasses
164
    }
165
166
    /**
167
     * Adds (and replaces) query params to the url currently used by the client
168
     * @param array $data
169
     */
170
    protected function addQueryParams($data)
171
    {
172
        $query = parse_url($this->client->path, PHP_URL_QUERY);
173
        parse_str($query, $vars);
174
        $query = http_build_query(array_merge($vars, $data));
175
        $this->client->path = parse_url($this->client->path, PHP_URL_PATH) . '?' . $query;
176
    }
177
178
    public function testString()
179
    {
180
        $sendString = "here are 3 \"entities\": < > & " .
181
            "and here's a dollar sign: \$pretendvarname and a backslash too: " . chr(92) .
182
            " - isn't that great? \\\"hackery\\\" at it's best " .
183
            " also don't want to miss out on \$item[0]. " .
184
            "The real weird stuff follows: CRLF here" . chr(13) . chr(10) .
185
            "a simple CR here" . chr(13) .
186
            "a simple LF here" . chr(10) .
187
            "and then LFCR" . chr(10) . chr(13) .
188
            "last but not least weird names: G" . chr(252) . "nter, El" . chr(232) . "ne, and an xml comment closing tag: -->";
189
        $m = new xmlrpcmsg('examples.stringecho', array(
190
            new xmlrpcval($sendString, 'string'),
191
        ));
192
        $v = $this->send($m);
193
        if ($v) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $v of type integer|null is loosely compared to true; this is ambiguous if the integer can be 0. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
194
            // when sending/receiving non-US-ASCII encoded strings, XML says cr-lf can be normalized.
195
            // so we relax our tests...
196
            $l1 = strlen($sendString);
197
            $l2 = strlen($v->scalarval());
0 ignored issues
show
Bug introduced by
The method scalarval() 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

197
            $l2 = strlen($v->/** @scrutinizer ignore-call */ scalarval());

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...
198
            if ($l1 == $l2) {
199
                $this->assertEquals($sendString, $v->scalarval());
200
            } else {
201
                $this->assertEquals(str_replace(array("\r\n", "\r"), array("\n", "\n"), $sendString), $v->scalarval());
202
            }
203
        }
204
    }
205
206
    public function testLatin1String()
207
    {
208
        $sendString =
209
            "last but not least weird names: G" . chr(252) . "nter, El" . chr(232) . "ne";
210
        $x = '<?xml version="1.0" encoding="ISO-8859-1"?><methodCall><methodName>examples.stringecho</methodName><params><param><value>'.
211
            $sendString.
212
            '</value></param></params></methodCall>';
213
        $v = $this->send($x);
0 ignored issues
show
Bug introduced by
$x of type string is incompatible with the type PhpXmlRpc\Request|array expected by parameter $msg of ServerTest::send(). ( Ignorable by Annotation )

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

213
        $v = $this->send(/** @scrutinizer ignore-type */ $x);
Loading history...
214
        if ($v) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $v of type integer|null is loosely compared to true; this is ambiguous if the integer can be 0. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
215
            $this->assertEquals($sendString, $v->scalarval());
216
        }
217
    }
218
219
    public function testExoticCharsetsRequests()
220
    {
221
        // note that we should disable this call also when mbstring is missing server-side
222
        if (!function_exists('mb_convert_encoding')) {
223
            $this->markTestSkipped('Miss mbstring extension to test exotic charsets');
224
            return;
225
        }
226
        $sendString = 'κόσμε'; // Greek word 'kosme'. NB: NOT a valid ISO8859 string!
227
        $str = '<?xml version="1.0" encoding="_ENC_"?>
228
<methodCall>
229
    <methodName>examples.stringecho</methodName>
230
    <params>
231
        <param>
232
        <value><string>'.$sendString.'</string></value>
233
        </param>
234
    </params>
235
</methodCall>';
236
237
        PhpXmlRpc\PhpXmlRpc::$xmlrpc_internalencoding = 'UTF-8';
238
        // we have to set the encoding declaration either in the http header or xml prolog, as mb_detect_encoding
239
        // (used on the server side) will fail recognizing these 2 charsets
240
        $v = $this->send(mb_convert_encoding(str_replace('_ENC_', 'UCS-4', $str), 'UCS-4', 'UTF-8'));
0 ignored issues
show
Bug introduced by
It seems like mb_convert_encoding(str_...str), 'UCS-4', 'UTF-8') can also be of type string; however, parameter $msg of ServerTest::send() does only seem to accept PhpXmlRpc\Request|array, maybe add an additional type check? ( Ignorable by Annotation )

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

240
        $v = $this->send(/** @scrutinizer ignore-type */ mb_convert_encoding(str_replace('_ENC_', 'UCS-4', $str), 'UCS-4', 'UTF-8'));
Loading history...
241
        $this->assertEquals($sendString, $v->scalarval());
242
        $v = $this->send(mb_convert_encoding(str_replace('_ENC_', 'UTF-16', $str), 'UTF-16', 'UTF-8'));
243
        $this->assertEquals($sendString, $v->scalarval());
244
        PhpXmlRpc\PhpXmlRpc::$xmlrpc_internalencoding = 'ISO-8859-1';
245
    }
246
247
    public function testExoticCharsetsRequests2()
248
    {
249
        // note that we should disable this call also when mbstring is missing server-side
250
        if (!function_exists('mb_convert_encoding')) {
251
            $this->markTestSkipped('Miss mbstring extension to test exotic charsets');
252
            return;
253
        }
254
        $sendString = '安室奈美恵'; // No idea what this means :-) NB: NOT a valid ISO8859 string!
255
        $str = '<?xml version="1.0"?>
256
<methodCall>
257
    <methodName>examples.stringecho</methodName>
258
    <params>
259
        <param>
260
        <value><string>'.$sendString.'</string></value>
261
        </param>
262
    </params>
263
</methodCall>';
264
265
        PhpXmlRpc\PhpXmlRpc::$xmlrpc_internalencoding = 'UTF-8';
266
        // no encoding declaration either in the http header or xml prolog, let mb_detect_encoding
267
        // (used on the server side) sort it out
268
        $this->addQueryParams(array('DETECT_ENCODINGS' => array('EUC-JP', 'UTF-8')));
269
        $v = $this->send(mb_convert_encoding($str, 'EUC-JP', 'UTF-8'));
0 ignored issues
show
Bug introduced by
It seems like mb_convert_encoding($str, 'EUC-JP', 'UTF-8') can also be of type string; however, parameter $msg of ServerTest::send() does only seem to accept PhpXmlRpc\Request|array, maybe add an additional type check? ( Ignorable by Annotation )

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

269
        $v = $this->send(/** @scrutinizer ignore-type */ mb_convert_encoding($str, 'EUC-JP', 'UTF-8'));
Loading history...
270
        $this->assertEquals($sendString, $v->scalarval());
271
        PhpXmlRpc\PhpXmlRpc::$xmlrpc_internalencoding = 'ISO-8859-1';
272
    }
273
274
    public function testExoticCharsetsRequests3()
275
    {
276
        // note that we should disable this call also when mbstring is missing server-side
277
        if (!function_exists('mb_convert_encoding')) {
278
            $this->markTestSkipped('Miss mbstring extension to test exotic charsets');
279
            return;
280
        }
281
        $sendString = utf8_decode('élève');
282
        $str = '<?xml version="1.0"?>
283
<methodCall>
284
    <methodName>examples.stringecho</methodName>
285
    <params>
286
        <param>
287
        <value><string>'.$sendString.'</string></value>
288
        </param>
289
    </params>
290
</methodCall>';
291
292
        // no encoding declaration either in the http header or xml prolog, let mb_detect_encoding
293
        // (used on the server side) sort it out
294
        $this->addQueryParams(array('DETECT_ENCODINGS' => array('ISO-8859-1', 'UTF-8')));
295
        $v = $this->send($str);
0 ignored issues
show
Bug introduced by
$str of type string is incompatible with the type PhpXmlRpc\Request|array expected by parameter $msg of ServerTest::send(). ( Ignorable by Annotation )

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

295
        $v = $this->send(/** @scrutinizer ignore-type */ $str);
Loading history...
296
        $this->assertEquals($sendString, $v->scalarval());
297
    }
298
299
    /*public function testLatin1Method()
300
    {
301
        $f = new xmlrpcmsg("tests.iso88591methodname." . chr(224) . chr(252) . chr(232), array(
302
            new xmlrpcval('hello')
303
        ));
304
        $v = $this->send($f);
305
        if ($v) {
306
            $this->assertEquals('hello', $v->scalarval());
307
        }
308
    }*/
309
310
    public function testUtf8Method()
311
    {
312
        PhpXmlRpc\PhpXmlRpc::$xmlrpc_internalencoding = 'UTF-8';
313
        $m = new xmlrpcmsg("tests.utf8methodname." . 'κόσμε', array(
314
            new xmlrpcval('hello')
315
        ));
316
        $v = $this->send($m);
317
        if ($v) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $v of type integer|null is loosely compared to true; this is ambiguous if the integer can be 0. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
318
            $this->assertEquals('hello', $v->scalarval());
319
        }
320
        PhpXmlRpc\PhpXmlRpc::$xmlrpc_internalencoding = 'ISO-8859-1';
321
    }
322
323
    public function testAddingDoubles()
324
    {
325
        // note that rounding errors mean we
326
        // keep precision to sensible levels here ;-)
327
        $a = 12.13;
328
        $b = -23.98;
329
        $m = new xmlrpcmsg('examples.addtwodouble', array(
330
            new xmlrpcval($a, 'double'),
331
            new xmlrpcval($b, 'double'),
332
        ));
333
        $v = $this->send($m);
334
        if ($v) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $v of type integer|null is loosely compared to true; this is ambiguous if the integer can be 0. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
335
            $this->assertEquals($a + $b, $v->scalarval());
336
        }
337
    }
338
339
    public function testAdding()
340
    {
341
        $m = new xmlrpcmsg('examples.addtwo', array(
342
            new xmlrpcval(12, 'int'),
343
            new xmlrpcval(-23, 'int'),
344
        ));
345
        $v = $this->send($m);
346
        if ($v) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $v of type integer|null is loosely compared to true; this is ambiguous if the integer can be 0. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
347
            $this->assertEquals(12 - 23, $v->scalarval());
348
        }
349
    }
350
351
    public function testInvalidNumber()
352
    {
353
        $m = new xmlrpcmsg('examples.addtwo', array(
354
            new xmlrpcval('fred', 'int'),
355
            new xmlrpcval("\"; exec('ls')", 'int'),
356
        ));
357
        $v = $this->send($m);
358
        /// @todo a fault condition should be generated here
359
        /// by the server, which we pick up on
360
        if ($v) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $v of type integer|null is loosely compared to true; this is ambiguous if the integer can be 0. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
361
            $this->assertEquals(0, $v->scalarval());
362
        }
363
    }
364
365
    public function testBoolean()
366
    {
367
        $m = new xmlrpcmsg('examples.invertBooleans', array(
368
            new xmlrpcval(array(
369
                new xmlrpcval(true, 'boolean'),
370
                new xmlrpcval(false, 'boolean'),
371
                new xmlrpcval(1, 'boolean'),
372
                new xmlrpcval(0, 'boolean')
373
            ),
374
                'array'
375
            ),));
376
        $answer = '0101';
377
        $v = $this->send($m);
378
        if ($v) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $v of type integer|null is loosely compared to true; this is ambiguous if the integer can be 0. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
379
            $sz = $v->arraysize();
380
            $got = '';
381
            for ($i = 0; $i < $sz; $i++) {
382
                $b = $v->arraymem($i);
383
                if ($b->scalarval()) {
384
                    $got .= '1';
385
                } else {
386
                    $got .= '0';
387
                }
388
            }
389
            $this->assertEquals($answer, $got);
390
        }
391
    }
392
393
    public function testBase64()
394
    {
395
        $sendString = 'Mary had a little lamb,
396
Whose fleece was white as snow,
397
And everywhere that Mary went
398
the lamb was sure to go.
399
400
Mary had a little lamb
401
She tied it to a pylon
402
Ten thousand volts went down its back
403
And turned it into nylon';
404
        $m = new xmlrpcmsg('examples.decode64', array(
405
            new xmlrpcval($sendString, 'base64'),
406
        ));
407
        $v = $this->send($m);
408
        if ($v) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $v of type integer|null is loosely compared to true; this is ambiguous if the integer can be 0. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
409
            if (strlen($sendString) == strlen($v->scalarval())) {
410
                $this->assertEquals($sendString, $v->scalarval());
411
            } else {
412
                $this->assertEquals(str_replace(array("\r\n", "\r"), array("\n", "\n"), $sendString), $v->scalarval());
413
            }
414
        }
415
    }
416
417
    public function testDateTime()
418
    {
419
        $time = time();
420
        $t1 = new xmlrpcval($time, 'dateTime.iso8601');
421
        $t2 = new xmlrpcval(iso8601_encode($time), 'dateTime.iso8601');
422
        $this->assertEquals($t1->serialize(), $t2->serialize());
423
        if (class_exists('DateTime')) {
424
            $datetime = new DateTime();
425
            // skip this test for php 5.2. It is a bit harder there to build a DateTime from unix timestamp with proper TZ info
426
            if (is_callable(array($datetime, 'setTimestamp'))) {
427
                $t3 = new xmlrpcval($datetime->setTimestamp($time), 'dateTime.iso8601');
428
                $this->assertEquals($t1->serialize(), $t3->serialize());
429
            }
430
        }
431
    }
432
433
    public function testCountEntities()
434
    {
435
        $sendString = "h'fd>onc>>l>>rw&bpu>q>e<v&gxs<ytjzkami<";
436
        $m = new xmlrpcmsg('validator1.countTheEntities', array(
437
            new xmlrpcval($sendString, 'string'),
438
        ));
439
        $v = $this->send($m);
440
        if ($v) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $v of type integer|null is loosely compared to true; this is ambiguous if the integer can be 0. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
441
            $got = '';
442
            $expected = '37210';
443
            $expect_array = array('ctLeftAngleBrackets', 'ctRightAngleBrackets', 'ctAmpersands', 'ctApostrophes', 'ctQuotes');
444
            foreach($expect_array as $val) {
445
                $b = $v->structmem($val);
446
                $got .= $b->me['int'];
447
            }
448
            $this->assertEquals($expected, $got);
449
        }
450
    }
451
452
    public function _multicall_msg($method, $params)
453
    {
454
        $struct['methodName'] = new xmlrpcval($method, 'string');
0 ignored issues
show
Comprehensibility Best Practice introduced by
$struct was never initialized. Although not strictly required by PHP, it is generally a good practice to add $struct = array(); before regardless.
Loading history...
455
        $struct['params'] = new xmlrpcval($params, 'array');
456
457
        return new xmlrpcval($struct, 'struct');
458
    }
459
460
    public function testServerMulticall()
461
    {
462
        // We manually construct a system.multicall() call to ensure
463
        // that the server supports it.
464
465
        // NB: This test will NOT pass if server does not support system.multicall.
466
467
        // Based on http://xmlrpc-c.sourceforge.net/hacks/test_multicall.py
468
        $good1 = $this->_multicall_msg(
469
            'system.methodHelp',
470
            array(php_xmlrpc_encode('system.listMethods')));
471
        $bad = $this->_multicall_msg(
472
            'test.nosuch',
473
            array(php_xmlrpc_encode(1), php_xmlrpc_encode(2)));
474
        $recursive = $this->_multicall_msg(
475
            'system.multicall',
476
            array(new xmlrpcval(array(), 'array')));
477
        $good2 = $this->_multicall_msg(
478
            'system.methodSignature',
479
            array(php_xmlrpc_encode('system.listMethods')));
480
        $arg = new xmlrpcval(
481
            array($good1, $bad, $recursive, $good2),
482
            'array'
483
        );
484
485
        $m = new xmlrpcmsg('system.multicall', array($arg));
486
        $v = $this->send($m);
487
        if ($v) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $v of type integer|null is loosely compared to true; this is ambiguous if the integer can be 0. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
488
            //$this->assertTrue($r->faultCode() == 0, "fault from system.multicall");
489
            $this->assertTrue($v->arraysize() == 4, "bad number of return values");
490
491
            $r1 = $v->arraymem(0);
492
            $this->assertTrue(
493
                $r1->kindOf() == 'array' && $r1->arraysize() == 1,
494
                "did not get array of size 1 from good1"
495
            );
496
497
            $r2 = $v->arraymem(1);
498
            $this->assertTrue(
499
                $r2->kindOf() == 'struct',
500
                "no fault from bad"
501
            );
502
503
            $r3 = $v->arraymem(2);
504
            $this->assertTrue(
505
                $r3->kindOf() == 'struct',
506
                "recursive system.multicall did not fail"
507
            );
508
509
            $r4 = $v->arraymem(3);
510
            $this->assertTrue(
511
                $r4->kindOf() == 'array' && $r4->arraysize() == 1,
512
                "did not get array of size 1 from good2"
513
            );
514
        }
515
    }
516
517
    public function testClientMulticall1()
518
    {
519
        // NB: This test will NOT pass if server does not support system.multicall.
520
521
        $noMultiCall = $this->client->no_multicall;
522
        $this->client->no_multicall = false;
523
524
        $good1 = new xmlrpcmsg('system.methodHelp',
525
            array(php_xmlrpc_encode('system.listMethods')));
526
        $bad = new xmlrpcmsg('test.nosuch',
527
            array(php_xmlrpc_encode(1), php_xmlrpc_encode(2)));
528
        $recursive = new xmlrpcmsg('system.multicall',
529
            array(new xmlrpcval(array(), 'array')));
530
        $good2 = new xmlrpcmsg('system.methodSignature',
531
            array(php_xmlrpc_encode('system.listMethods'))
532
        );
533
534
        $r = $this->send(array($good1, $bad, $recursive, $good2));
535
        if ($r) {
536
            $this->assertTrue(count($r) == 4, "wrong number of return values");
0 ignored issues
show
Bug introduced by
It seems like $r can also be of type integer; however, parameter $value of count() does only seem to accept Countable|array, maybe add an additional type check? ( Ignorable by Annotation )

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

536
            $this->assertTrue(count(/** @scrutinizer ignore-type */ $r) == 4, "wrong number of return values");
Loading history...
537
        }
538
539
        $this->assertTrue($r[0]->faultCode() == 0, "fault from good1");
540
        if (!$r[0]->faultCode()) {
541
            $val = $r[0]->value();
542
            $this->assertTrue(
543
                $val->kindOf() == 'scalar' && $val->scalartyp() == 'string',
544
                "good1 did not return string"
545
            );
546
        }
547
        $this->assertTrue($r[1]->faultCode() != 0, "no fault from bad");
548
        $this->assertTrue($r[2]->faultCode() != 0, "no fault from recursive system.multicall");
549
        $this->assertTrue($r[3]->faultCode() == 0, "fault from good2");
550
        if (!$r[3]->faultCode()) {
551
            $val = $r[3]->value();
552
            $this->assertTrue($val->kindOf() == 'array', "good2 did not return array");
553
        }
554
        // This is the only assert in this test which should fail
555
        // if the test server does not support system.multicall.
556
        $this->assertTrue($this->client->no_multicall == false,
557
            "server does not support system.multicall"
558
        );
559
560
        $this->client->no_multicall = $noMultiCall;
561
    }
562
563
    public function testClientMulticall2()
564
    {
565
        // NB: This test will NOT pass if server does not support system.multicall.
566
567
        $noMultiCall = $this->client->no_multicall;
568
        $this->client->no_multicall = true;
569
570
        $good1 = new xmlrpcmsg('system.methodHelp',
571
            array(php_xmlrpc_encode('system.listMethods')));
572
        $bad = new xmlrpcmsg('test.nosuch',
573
            array(php_xmlrpc_encode(1), php_xmlrpc_encode(2)));
574
        $recursive = new xmlrpcmsg('system.multicall',
575
            array(new xmlrpcval(array(), 'array')));
576
        $good2 = new xmlrpcmsg('system.methodSignature',
577
            array(php_xmlrpc_encode('system.listMethods'))
578
        );
579
580
        $r = $this->send(array($good1, $bad, $recursive, $good2));
581
        if ($r) {
582
            $this->assertTrue(count($r) == 4, "wrong number of return values");
0 ignored issues
show
Bug introduced by
It seems like $r can also be of type integer; however, parameter $value of count() does only seem to accept Countable|array, maybe add an additional type check? ( Ignorable by Annotation )

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

582
            $this->assertTrue(count(/** @scrutinizer ignore-type */ $r) == 4, "wrong number of return values");
Loading history...
583
        }
584
585
        $this->assertTrue($r[0]->faultCode() == 0, "fault from good1");
586
        if (!$r[0]->faultCode()) {
587
            $val = $r[0]->value();
588
            $this->assertTrue(
589
                $val->kindOf() == 'scalar' && $val->scalartyp() == 'string',
590
                "good1 did not return string");
591
        }
592
        $this->assertTrue($r[1]->faultCode() != 0, "no fault from bad");
593
        $this->assertTrue($r[2]->faultCode() == 0, "fault from (non recursive) system.multicall");
594
        $this->assertTrue($r[3]->faultCode() == 0, "fault from good2");
595
        if (!$r[3]->faultCode()) {
596
            $val = $r[3]->value();
597
            $this->assertTrue($val->kindOf() == 'array', "good2 did not return array");
598
        }
599
600
        $this->client->no_multicall = $noMultiCall;
601
    }
602
603
    public function testClientMulticall3()
604
    {
605
        // NB: This test will NOT pass if server does not support system.multicall.
606
607
        $noMultiCall = $this->client->no_multicall;
608
        $returnType = $this->client->return_type;
609
610
        $this->client->return_type = 'phpvals';
611
        $this->client->no_multicall = false;
612
613
        $good1 = new xmlrpcmsg('system.methodHelp',
614
            array(php_xmlrpc_encode('system.listMethods')));
615
        $bad = new xmlrpcmsg('test.nosuch',
616
            array(php_xmlrpc_encode(1), php_xmlrpc_encode(2)));
617
        $recursive = new xmlrpcmsg('system.multicall',
618
            array(new xmlrpcval(array(), 'array')));
619
        $good2 = new xmlrpcmsg('system.methodSignature',
620
            array(php_xmlrpc_encode('system.listMethods'))
621
        );
622
623
        $r = $this->send(array($good1, $bad, $recursive, $good2));
624
        if ($r) {
625
            $this->assertTrue(count($r) == 4, "wrong number of return values");
0 ignored issues
show
Bug introduced by
It seems like $r can also be of type integer; however, parameter $value of count() does only seem to accept Countable|array, maybe add an additional type check? ( Ignorable by Annotation )

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

625
            $this->assertTrue(count(/** @scrutinizer ignore-type */ $r) == 4, "wrong number of return values");
Loading history...
626
        }
627
        $this->assertTrue($r[0]->faultCode() == 0, "fault from good1");
628
        if (!$r[0]->faultCode()) {
629
            $val = $r[0]->value();
630
            $this->assertTrue(
631
                is_string($val), "good1 did not return string");
632
        }
633
        $this->assertTrue($r[1]->faultCode() != 0, "no fault from bad");
634
        $this->assertTrue($r[2]->faultCode() != 0, "no fault from recursive system.multicall");
635
        $this->assertTrue($r[3]->faultCode() == 0, "fault from good2");
636
        if (!$r[3]->faultCode()) {
637
            $val = $r[3]->value();
638
            $this->assertTrue(is_array($val), "good2 did not return array");
639
        }
640
641
        $this->client->return_type = $returnType;
642
        $this->client->no_multicall = $noMultiCall;
643
    }
644
645
    public function testCatchWarnings()
646
    {
647
        $m = new xmlrpcmsg('tests.generatePHPWarning', array(
648
            new xmlrpcval('whatever', 'string'),
649
        ));
650
        $v = $this->send($m);
651
        if ($v) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $v of type integer|null is loosely compared to true; this is ambiguous if the integer can be 0. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
652
            $this->assertEquals(true, $v->scalarval());
653
        }
654
    }
655
656
    public function testCatchExceptions()
657
    {
658
        $m = new xmlrpcmsg('tests.raiseException', array(
659
            new xmlrpcval('whatever', 'string'),
660
        ));
661
        $v = $this->send($m, $GLOBALS['xmlrpcerr']['server_error']);
0 ignored issues
show
Unused Code introduced by
The assignment to $v is dead and can be removed.
Loading history...
662
        $this->addQueryParams(array('EXCEPTION_HANDLING' => 1));
663
        $v = $this->send($m, 1); // the error code of the expected exception
664
        $this->addQueryParams(array('EXCEPTION_HANDLING' => 2));
665
        // depending on whether display_errors is ON or OFF on the server, we will get back a different error here,
666
        // as php will generate an http status code of either 200 or 500...
667
        $v = $this->send($m, array($GLOBALS['xmlrpcerr']['invalid_return'], $GLOBALS['xmlrpcerr']['http_error']));
668
    }
669
670
    public function testZeroParams()
671
    {
672
        $m = new xmlrpcmsg('system.listMethods');
673
        $v = $this->send($m);
0 ignored issues
show
Unused Code introduced by
The assignment to $v is dead and can be removed.
Loading history...
674
    }
675
676
    public function testNullParams()
677
    {
678
        $m = new xmlrpcmsg('tests.getStateName.12', array(
679
            new xmlrpcval('whatever', 'null'),
680
            new xmlrpcval(23, 'int'),
681
        ));
682
        $v = $this->send($m);
683
        if ($v) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $v of type integer|null is loosely compared to true; this is ambiguous if the integer can be 0. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
684
            $this->assertEquals('Michigan', $v->scalarval());
685
        }
686
        $m = new xmlrpcmsg('tests.getStateName.12', array(
687
            new xmlrpcval(23, 'int'),
688
            new xmlrpcval('whatever', 'null'),
689
        ));
690
        $v = $this->send($m);
691
        if ($v) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $v of type integer|null is loosely compared to true; this is ambiguous if the integer can be 0. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
692
            $this->assertEquals('Michigan', $v->scalarval());
693
        }
694
        $m = new xmlrpcmsg('tests.getStateName.12', array(
695
            new xmlrpcval(23, 'int')
696
        ));
697
        $v = $this->send($m, array($GLOBALS['xmlrpcerr']['incorrect_params']));
0 ignored issues
show
Unused Code introduced by
The assignment to $v is dead and can be removed.
Loading history...
698
    }
699
700
    public function testCodeInjectionServerSide()
701
    {
702
        $m = new xmlrpcmsg('system.MethodHelp');
703
        $m->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>";
704
        $v = $this->send($m);
705
        if ($v) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $v of type integer|null is loosely compared to true; this is ambiguous if the integer can be 0. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
706
            $this->assertEquals(0, $v->structsize());
707
        }
708
    }
709
710
    public function testServerWrappedFunction()
711
    {
712
        $m = new xmlrpcmsg('tests.getStateName.2', array(
713
            new xmlrpcval(23, 'int'),
714
        ));
715
        $v = $this->send($m);
716
        $this->assertEquals('Michigan', $v->scalarval());
717
718
        // this generates an exception in the function which was wrapped, which is by default wrapped in a known error response
719
        $m = new xmlrpcmsg('tests.getStateName.2', array(
720
            new xmlrpcval(0, 'int'),
721
        ));
722
        $v = $this->send($m, $GLOBALS['xmlrpcerr']['server_error']);
0 ignored issues
show
Unused Code introduced by
The assignment to $v is dead and can be removed.
Loading history...
723
724
        // check if the generated function dispatch map is fine, by checking if the server registered it
725
        $m = new xmlrpcmsg('system.methodSignature', array(
726
            new xmlrpcval('tests.getStateName.2'),
727
        ));
728
        $v = $this->send($m);
729
        $encoder = new \PhpXmlRpc\Encoder();
730
        $this->assertEquals(array(array('string', 'int')), $encoder->decode($v));
0 ignored issues
show
Bug introduced by
It seems like $v can also be of type integer; however, parameter $xmlrpcVal of PhpXmlRpc\Encoder::decode() does only seem to accept PhpXmlRpc\Request|PhpXmlRpc\Value, maybe add an additional type check? ( Ignorable by Annotation )

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

730
        $this->assertEquals(array(array('string', 'int')), $encoder->decode(/** @scrutinizer ignore-type */ $v));
Loading history...
731
    }
732
733
    public function testServerWrappedFunctionAsSource()
734
    {
735
        $m = new xmlrpcmsg('tests.getStateName.6', array(
736
            new xmlrpcval(23, 'int'),
737
        ));
738
        $v = $this->send($m);
739
        $this->assertEquals('Michigan', $v->scalarval());
740
741
        // this generates an exception in the function which was wrapped, which is by default wrapped in a known error response
742
        $m = new xmlrpcmsg('tests.getStateName.6', array(
743
            new xmlrpcval(0, 'int'),
744
        ));
745
        $v = $this->send($m, $GLOBALS['xmlrpcerr']['server_error']);
0 ignored issues
show
Unused Code introduced by
The assignment to $v is dead and can be removed.
Loading history...
746
    }
747
748
    public function testServerWrappedObjectMethods()
749
    {
750
        $m = new xmlrpcmsg('tests.getStateName.3', array(
751
            new xmlrpcval(23, 'int'),
752
        ));
753
        $v = $this->send($m);
754
        $this->assertEquals('Michigan', $v->scalarval());
755
756
        $m = new xmlrpcmsg('tests.getStateName.4', array(
757
            new xmlrpcval(23, 'int'),
758
        ));
759
        $v = $this->send($m);
760
        $this->assertEquals('Michigan', $v->scalarval());
761
762
        $m = new xmlrpcmsg('tests.getStateName.5', array(
763
            new xmlrpcval(23, 'int'),
764
        ));
765
        $v = $this->send($m);
766
        $this->assertEquals('Michigan', $v->scalarval());
767
768
        $m = new xmlrpcmsg('tests.getStateName.7', array(
769
            new xmlrpcval(23, 'int'),
770
        ));
771
        $v = $this->send($m);
772
        $this->assertEquals('Michigan', $v->scalarval());
773
774
        $m = new xmlrpcmsg('tests.getStateName.8', array(
775
            new xmlrpcval(23, 'int'),
776
        ));
777
        $v = $this->send($m);
778
        $this->assertEquals('Michigan', $v->scalarval());
779
780
        $m = new xmlrpcmsg('tests.getStateName.9', array(
781
            new xmlrpcval(23, 'int'),
782
        ));
783
        $v = $this->send($m);
784
        $this->assertEquals('Michigan', $v->scalarval());
785
    }
786
787
    public function testServerWrappedObjectMethodsAsSource()
788
    {
789
        $m = new xmlrpcmsg('tests.getStateName.7', array(
790
            new xmlrpcval(23, 'int'),
791
        ));
792
        $v = $this->send($m);
793
        $this->assertEquals('Michigan', $v->scalarval());
794
795
        $m = new xmlrpcmsg('tests.getStateName.8', array(
796
            new xmlrpcval(23, 'int'),
797
        ));
798
        $v = $this->send($m);
799
        $this->assertEquals('Michigan', $v->scalarval());
800
801
        $m = new xmlrpcmsg('tests.getStateName.9', array(
802
            new xmlrpcval(23, 'int'),
803
        ));
804
        $v = $this->send($m);
805
        $this->assertEquals('Michigan', $v->scalarval());
806
    }
807
808
    public function testServerClosure()
809
    {
810
        $m = new xmlrpcmsg('tests.getStateName.10', array(
811
            new xmlrpcval(23, 'int'),
812
        ));
813
        $v = $this->send($m);
814
        $this->assertEquals('Michigan', $v->scalarval());
815
    }
816
817
    public function testServerWrappedClosure()
818
    {
819
        $m = new xmlrpcmsg('tests.getStateName.11', array(
820
            new xmlrpcval(23, 'int'),
821
        ));
822
        $v = $this->send($m);
823
        $this->assertEquals('Michigan', $v->scalarval());
824
    }
825
826
    public function testServerWrappedClass()
827
    {
828
        $m = new xmlrpcmsg('tests.xmlrpcServerMethodsContainer.findState', array(
829
            new xmlrpcval(23, 'int'),
830
        ));
831
        $v = $this->send($m);
832
        $this->assertEquals('Michigan', $v->scalarval());
833
    }
834
835
    public function testServerWrappedClassWithNamespace()
836
    {
837
        $m = new xmlrpcmsg('namespacetest.findState', array(
838
            new xmlrpcval(23, 'int'),
839
        ));
840
        $v = $this->send($m);
841
        $this->assertEquals('Michigan', $v->scalarval());
842
    }
843
844
    public function testWrapInexistentMethod()
845
    {
846
        // make a 'deep client copy' as the original one might have many properties set
847
        $func = wrap_xmlrpc_method($this->client, 'examples.getStateName.notexisting', array('simple_client_copy' => 0));
848
        $this->assertEquals(false, $func);
849
    }
850
851
    public function testWrapInexistentUrl()
852
    {
853
        $this->client->path = '/notexisting';
854
        // make a 'deep client copy' as the original one might have many properties set
855
        $func = wrap_xmlrpc_method($this->client, 'examples.getStateName', array('simple_client_copy' => 0));
856
        $this->assertEquals(false, $func);
857
    }
858
859
    public function testWrappedMethod()
860
    {
861
        // make a 'deep client copy' as the original one might have many properties set
862
        $func = wrap_xmlrpc_method($this->client, 'examples.getStateName', array('simple_client_copy' => 0));
863
        if ($func == false) {
864
            $this->fail('Registration of examples.getStateName failed');
865
        } else {
866
            $v = $func(23);
867
            // work around bug in current (or old?) version of phpunit when reporting the error
868
            /*if (is_object($v)) {
869
                $v = var_export($v, true);
870
            }*/
871
            $this->assertEquals('Michigan', $v);
872
        }
873
    }
874
875
    public function testWrappedMethodAsSource()
876
    {
877
        // make a 'deep client copy' as the original one might have many properties set
878
        $func = wrap_xmlrpc_method($this->client, 'examples.getStateName', array('simple_client_copy' => 0, 'return_source' => true));
879
        if ($func == false) {
880
            $this->fail('Registration of examples.getStateName failed');
881
        } else {
882
            eval($func['source']);
0 ignored issues
show
introduced by
The use of eval() is discouraged.
Loading history...
883
            $func = $func['function'];
884
            $v = $func(23);
885
            // work around bug in current (or old?) version of phpunit when reporting the error
886
            /*if (is_object($v)) {
887
                $v = var_export($v, true);
888
            }*/
889
            $this->assertEquals('Michigan', $v);
890
        }
891
    }
892
893
    public function testWrappedClass()
894
    {
895
        // make a 'deep client copy' as the original one might have many properties set
896
        // also for speed only wrap one method of the whole server
897
        $class = wrap_xmlrpc_server($this->client, array('simple_client_copy' => 0, 'method_filter' => '/examples\.getStateName/' ));
898
        if ($class == '') {
899
            $this->fail('Registration of remote server failed');
900
        } else {
901
            $obj = new $class();
902
            if (!is_callable(array($obj, 'examples_getStateName'))) {
903
                $this->fail('Registration of remote server failed to import method "examples_getStateName"');
904
            } else {
905
                $v = $obj->examples_getStateName(23);
906
                // work around bug in current (or old?) version of phpunit when reporting the error
907
                /*if (is_object($v)) {
908
                    $v = var_export($v, true);
909
                }*/
910
                $this->assertEquals('Michigan', $v);
911
            }
912
        }
913
    }
914
915
    public function testTransferOfObjectViaWrapping()
916
    {
917
        // make a 'deep client copy' as the original one might have many properties set
918
        $func = wrap_xmlrpc_method($this->client, 'tests.returnPhpObject', array('simple_client_copy' => 0,
919
            'decode_php_objs' => true));
920
        if ($func == false) {
921
            $this->fail('Registration of tests.returnPhpObject failed');
922
        } else {
923
            $v = $func();
924
            $obj = new stdClass();
925
            $obj->hello = 'world';
926
            $this->assertEquals($obj, $v);
927
        }
928
    }
929
930
    public function testGetCookies()
931
    {
932
        // let server set to us some cookies we tell it
933
        $cookies = array(
934
            //'c1' => array(),
935
            'c2' => array('value' => 'c2'),
936
            'c3' => array('value' => 'c3', 'expires' => time() + 60 * 60 * 24 * 30),
937
            'c4' => array('value' => 'c4', 'expires' => time() + 60 * 60 * 24 * 30, 'path' => '/'),
938
            'c5' => array('value' => 'c5', 'expires' => time() + 60 * 60 * 24 * 30, 'path' => '/', 'domain' => 'localhost'),
939
        );
940
        $cookiesval = php_xmlrpc_encode($cookies);
941
        $m = new xmlrpcmsg('examples.setcookies', array($cookiesval));
942
        $r = $this->send($m, 0, true);
943
        if ($r) {
944
            $v = $r->value();
945
            $this->assertEquals(1, $v->scalarval());
946
            // now check if we decoded the cookies as we had set them
947
            $rcookies = $r->cookies();
948
            // remove extra cookies which might have been set by proxies
949
            foreach ($rcookies as $c => $v) {
950
                if (!in_array($c, array('c2', 'c3', 'c4', 'c5'))) {
951
                    unset($rcookies[$c]);
952
                }
953
                // Seems like we get this when using php-fpm and php 5.5+ ...
954
                if (isset($rcookies[$c]['Max-Age'])) {
955
                    unset($rcookies[$c]['Max-Age']);
956
                }
957
            }
958
            foreach ($cookies as $c => $v) {
959
                // format for date string in cookies: 'Mon, 31 Oct 2005 13:50:56 GMT'
960
                // but PHP versions differ on that, some use 'Mon, 31-Oct-2005 13:50:56 GMT'...
961
                if (isset($v['expires'])) {
962
                    if (isset($rcookies[$c]['expires']) && strpos($rcookies[$c]['expires'], '-')) {
963
                        $cookies[$c]['expires'] = gmdate('D, d\-M\-Y H:i:s \G\M\T', $cookies[$c]['expires']);
964
                    } else {
965
                        $cookies[$c]['expires'] = gmdate('D, d M Y H:i:s \G\M\T', $cookies[$c]['expires']);
966
                    }
967
                }
968
            }
969
970
            $this->assertEquals($cookies, $rcookies);
971
        }
972
    }
973
974
    public function testSetCookies()
975
    {
976
        // let server set to us some cookies we tell it
977
        $cookies = array(
978
            'c0' => null,
979
            'c1' => 1,
980
            'c2' => '2 3',
981
            'c3' => '!@#$%^&*()_+|}{":?><,./\';[]\\=-',
982
        );
983
        $m = new xmlrpcmsg('examples.getcookies', array());
984
        foreach ($cookies as $cookie => $val) {
985
            $this->client->setCookie($cookie, $val);
986
            $cookies[$cookie] = (string)$cookies[$cookie];
987
        }
988
        $r = $this->client->send($m, $this->timeout, $this->method);
989
        $this->assertEquals(0, $r->faultCode(), 'Error ' . $r->faultCode() . ' connecting to server: ' . $r->faultString());
990
        if (!$r->faultCode()) {
991
            $v = $r->value();
992
            $v = php_xmlrpc_decode($v);
993
994
            // take care for the extra cookie used for coverage collection
995
            if (isset($v['PHPUNIT_SELENIUM_TEST_ID'])) {
996
                unset($v['PHPUNIT_SELENIUM_TEST_ID']);
997
            }
998
999
            // on IIS and Apache getallheaders returns something slightly different...
1000
            $this->assertEquals($cookies, $v);
1001
        }
1002
    }
1003
1004
    public function testServerComments()
1005
    {
1006
        $m = new xmlrpcmsg('tests.xmlrpcServerMethodsContainer.debugMessageGenerator', array(
1007
            new xmlrpcval('hello world', 'string'),
1008
        ));
1009
        $r = $this->send($m, 0, true);
1010
        $this->assertStringContainsString('hello world', $r->raw_data);
1011
    }
1012
1013
    public function testSendTwiceSameMsg()
1014
    {
1015
        $m = new xmlrpcmsg('examples.stringecho', array(
1016
            new xmlrpcval('hello world', 'string'),
1017
        ));
1018
        $v1 = $this->send($m);
1019
        $v2 = $this->send($m);
1020
        if ($v1 && $v2) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $v1 of type integer|null is loosely compared to true; this is ambiguous if the integer can be 0. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
Bug Best Practice introduced by
The expression $v2 of type integer|null is loosely compared to true; this is ambiguous if the integer can be 0. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
1021
            $this->assertEquals($v1, $v2);
1022
        }
1023
    }
1024
}
1025