Passed
Push — master ( 5787f8...cad2d5 )
by Gaetano
08:38
created

ServerTest::testGetCookies()   B

Complexity

Conditions 9
Paths 21

Size

Total Lines 41
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 9
eloc 24
c 0
b 0
f 0
nc 21
nop 0
dl 0
loc 41
rs 8.0555
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
        if (is_array($errorCode)) {
145
            $this->assertContains($r->faultCode(), $errorCode, 'Error ' . $r->faultCode() . ' connecting to server: ' . $r->faultString());
146
        } else {
147
            $this->assertEquals($errorCode, $r->faultCode(), 'Error ' . $r->faultCode() . ' connecting to server: ' . $r->faultString());
148
        }
149
        if (!$r->faultCode()) {
150
            if ($returnResponse) {
151
                return $r;
152
            } else {
153
                return $r->value();
154
            }
155
        } else {
156
            return null;
157
        }
158
    }
159
160
    /**
161
     * Adds (and replaces) query params to the url currently used by the client
162
     * @param array $data
163
     */
164
    protected function addQueryParams($data)
165
    {
166
        $query = parse_url($this->client->path, PHP_URL_QUERY);
167
        parse_str($query, $vars);
168
        $query = http_build_query(array_merge($vars, $data));
169
        $this->client->path = parse_url($this->client->path, PHP_URL_PATH) . '?' . $query;
170
    }
171
172
    public function testString()
173
    {
174
        $sendString = "here are 3 \"entities\": < > & " .
175
            "and here's a dollar sign: \$pretendvarname and a backslash too: " . chr(92) .
176
            " - isn't that great? \\\"hackery\\\" at it's best " .
177
            " also don't want to miss out on \$item[0]. " .
178
            "The real weird stuff follows: CRLF here" . chr(13) . chr(10) .
179
            "a simple CR here" . chr(13) .
180
            "a simple LF here" . chr(10) .
181
            "and then LFCR" . chr(10) . chr(13) .
182
            "last but not least weird names: G" . chr(252) . "nter, El" . chr(232) . "ne, and an xml comment closing tag: -->";
183
        $m = new xmlrpcmsg('examples.stringecho', array(
184
            new xmlrpcval($sendString, 'string'),
185
        ));
186
        $v = $this->send($m);
187
        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...
188
            // when sending/receiving non-US-ASCII encoded strings, XML says cr-lf can be normalized.
189
            // so we relax our tests...
190
            $l1 = strlen($sendString);
191
            $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

191
            $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...
192
            if ($l1 == $l2) {
193
                $this->assertEquals($sendString, $v->scalarval());
194
            } else {
195
                $this->assertEquals(str_replace(array("\r\n", "\r"), array("\n", "\n"), $sendString), $v->scalarval());
196
            }
197
        }
198
    }
199
200
    public function testLatin1String()
201
    {
202
        $sendString =
203
            "last but not least weird names: G" . chr(252) . "nter, El" . chr(232) . "ne";
204
        $x = '<?xml version="1.0" encoding="ISO-8859-1"?><methodCall><methodName>examples.stringecho</methodName><params><param><value>'.
205
            $sendString.
206
            '</value></param></params></methodCall>';
207
        $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

207
        $v = $this->send(/** @scrutinizer ignore-type */ $x);
Loading history...
208
        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...
209
            $this->assertEquals($sendString, $v->scalarval());
210
        }
211
    }
212
213
    public function testExoticCharsetsRequests()
214
    {
215
        // note that we should disable this call also when mbstring is missing server-side
216
        if (!function_exists('mb_convert_encoding')) {
217
            $this->markTestSkipped('Miss mbstring extension to test exotic charsets');
218
            return;
219
        }
220
        $sendString = 'κόσμε'; // Greek word 'kosme'. NB: NOT a valid ISO8859 string!
221
        $str = '<?xml version="1.0" encoding="_ENC_"?>
222
<methodCall>
223
    <methodName>examples.stringecho</methodName>
224
    <params>
225
        <param>
226
        <value><string>'.$sendString.'</string></value>
227
        </param>
228
    </params>
229
</methodCall>';
230
231
        PhpXmlRpc\PhpXmlRpc::$xmlrpc_internalencoding = 'UTF-8';
232
        // we have to set the encoding declaration either in the http header or xml prolog, as mb_detect_encoding
233
        // (used on the server side) will fail recognizing these 2 charsets
234
        $v = $this->send(mb_convert_encoding(str_replace('_ENC_', 'UCS-4', $str), 'UCS-4', 'UTF-8'));
0 ignored issues
show
Bug introduced by
mb_convert_encoding(str_...str), 'UCS-4', 'UTF-8') 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

234
        $v = $this->send(/** @scrutinizer ignore-type */ mb_convert_encoding(str_replace('_ENC_', 'UCS-4', $str), 'UCS-4', 'UTF-8'));
Loading history...
235
        $this->assertEquals($sendString, $v->scalarval());
236
        $v = $this->send(mb_convert_encoding(str_replace('_ENC_', 'UTF-16', $str), 'UTF-16', 'UTF-8'));
237
        $this->assertEquals($sendString, $v->scalarval());
238
        PhpXmlRpc\PhpXmlRpc::$xmlrpc_internalencoding = 'ISO-8859-1';
239
    }
240
241
    public function testExoticCharsetsRequests2()
242
    {
243
        // note that we should disable this call also when mbstring is missing server-side
244
        if (!function_exists('mb_convert_encoding')) {
245
            $this->markTestSkipped('Miss mbstring extension to test exotic charsets');
246
            return;
247
        }
248
        $sendString = '安室奈美恵'; // No idea what this means :-) NB: NOT a valid ISO8859 string!
249
        $str = '<?xml version="1.0"?>
250
<methodCall>
251
    <methodName>examples.stringecho</methodName>
252
    <params>
253
        <param>
254
        <value><string>'.$sendString.'</string></value>
255
        </param>
256
    </params>
257
</methodCall>';
258
259
        PhpXmlRpc\PhpXmlRpc::$xmlrpc_internalencoding = 'UTF-8';
260
        // no encoding declaration either in the http header or xml prolog, let mb_detect_encoding
261
        // (used on the server side) sort it out
262
        $this->addQueryParams(array('DETECT_ENCODINGS' => array('EUC-JP', 'UTF-8')));
263
        $v = $this->send(mb_convert_encoding($str, 'EUC-JP', 'UTF-8'));
0 ignored issues
show
Bug introduced by
mb_convert_encoding($str, 'EUC-JP', 'UTF-8') 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

263
        $v = $this->send(/** @scrutinizer ignore-type */ mb_convert_encoding($str, 'EUC-JP', 'UTF-8'));
Loading history...
264
        $this->assertEquals($sendString, $v->scalarval());
265
        PhpXmlRpc\PhpXmlRpc::$xmlrpc_internalencoding = 'ISO-8859-1';
266
    }
267
268
    public function testExoticCharsetsRequests3()
269
    {
270
        // note that we should disable this call also when mbstring is missing server-side
271
        if (!function_exists('mb_convert_encoding')) {
272
            $this->markTestSkipped('Miss mbstring extension to test exotic charsets');
273
            return;
274
        }
275
        $sendString = utf8_decode('élève');
276
        $str = '<?xml version="1.0"?>
277
<methodCall>
278
    <methodName>examples.stringecho</methodName>
279
    <params>
280
        <param>
281
        <value><string>'.$sendString.'</string></value>
282
        </param>
283
    </params>
284
</methodCall>';
285
286
        // no encoding declaration either in the http header or xml prolog, let mb_detect_encoding
287
        // (used on the server side) sort it out
288
        $this->addQueryParams(array('DETECT_ENCODINGS' => array('ISO-8859-1', 'UTF-8')));
289
        $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

289
        $v = $this->send(/** @scrutinizer ignore-type */ $str);
Loading history...
290
        $this->assertEquals($sendString, $v->scalarval());
291
    }
292
293
    /*public function testLatin1Method()
294
    {
295
        $f = new xmlrpcmsg("tests.iso88591methodname." . chr(224) . chr(252) . chr(232), array(
296
            new xmlrpcval('hello')
297
        ));
298
        $v = $this->send($f);
299
        if ($v) {
300
            $this->assertEquals('hello', $v->scalarval());
301
        }
302
    }*/
303
304
    public function testUtf8Method()
305
    {
306
        PhpXmlRpc\PhpXmlRpc::$xmlrpc_internalencoding = 'UTF-8';
307
        $m = new xmlrpcmsg("tests.utf8methodname." . 'κόσμε', array(
308
            new xmlrpcval('hello')
309
        ));
310
        $v = $this->send($m);
311
        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...
312
            $this->assertEquals('hello', $v->scalarval());
313
        }
314
        PhpXmlRpc\PhpXmlRpc::$xmlrpc_internalencoding = 'ISO-8859-1';
315
    }
316
317
    public function testAddingDoubles()
318
    {
319
        // note that rounding errors mean we
320
        // keep precision to sensible levels here ;-)
321
        $a = 12.13;
322
        $b = -23.98;
323
        $m = new xmlrpcmsg('examples.addtwodouble', array(
324
            new xmlrpcval($a, 'double'),
325
            new xmlrpcval($b, 'double'),
326
        ));
327
        $v = $this->send($m);
328
        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...
329
            $this->assertEquals($a + $b, $v->scalarval());
330
        }
331
    }
332
333
    public function testAdding()
334
    {
335
        $m = new xmlrpcmsg('examples.addtwo', array(
336
            new xmlrpcval(12, 'int'),
337
            new xmlrpcval(-23, 'int'),
338
        ));
339
        $v = $this->send($m);
340
        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...
341
            $this->assertEquals(12 - 23, $v->scalarval());
342
        }
343
    }
344
345
    public function testInvalidNumber()
346
    {
347
        $m = new xmlrpcmsg('examples.addtwo', array(
348
            new xmlrpcval('fred', 'int'),
349
            new xmlrpcval("\"; exec('ls')", 'int'),
350
        ));
351
        $v = $this->send($m);
352
        /// @todo a fault condition should be generated here
353
        /// by the server, which we pick up on
354
        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...
355
            $this->assertEquals(0, $v->scalarval());
356
        }
357
    }
358
359
    public function testBoolean()
360
    {
361
        $m = new xmlrpcmsg('examples.invertBooleans', array(
362
            new xmlrpcval(array(
363
                new xmlrpcval(true, 'boolean'),
364
                new xmlrpcval(false, 'boolean'),
365
                new xmlrpcval(1, 'boolean'),
366
                new xmlrpcval(0, 'boolean')
367
            ),
368
                'array'
369
            ),));
370
        $answer = '0101';
371
        $v = $this->send($m);
372
        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...
373
            $sz = $v->arraysize();
374
            $got = '';
375
            for ($i = 0; $i < $sz; $i++) {
376
                $b = $v->arraymem($i);
377
                if ($b->scalarval()) {
378
                    $got .= '1';
379
                } else {
380
                    $got .= '0';
381
                }
382
            }
383
            $this->assertEquals($answer, $got);
384
        }
385
    }
386
387
    public function testBase64()
388
    {
389
        $sendString = 'Mary had a little lamb,
390
Whose fleece was white as snow,
391
And everywhere that Mary went
392
the lamb was sure to go.
393
394
Mary had a little lamb
395
She tied it to a pylon
396
Ten thousand volts went down its back
397
And turned it into nylon';
398
        $m = new xmlrpcmsg('examples.decode64', array(
399
            new xmlrpcval($sendString, 'base64'),
400
        ));
401
        $v = $this->send($m);
402
        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...
403
            if (strlen($sendString) == strlen($v->scalarval())) {
404
                $this->assertEquals($sendString, $v->scalarval());
405
            } else {
406
                $this->assertEquals(str_replace(array("\r\n", "\r"), array("\n", "\n"), $sendString), $v->scalarval());
407
            }
408
        }
409
    }
410
411
    public function testDateTime()
412
    {
413
        $time = time();
414
        $t1 = new xmlrpcval($time, 'dateTime.iso8601');
415
        $t2 = new xmlrpcval(iso8601_encode($time), 'dateTime.iso8601');
416
        $this->assertEquals($t1->serialize(), $t2->serialize());
417
        if (class_exists('DateTime')) {
418
            $datetime = new DateTime();
419
            // skip this test for php 5.2. It is a bit harder there to build a DateTime from unix timestamp with proper TZ info
420
            if (is_callable(array($datetime, 'setTimestamp'))) {
421
                $t3 = new xmlrpcval($datetime->setTimestamp($time), 'dateTime.iso8601');
422
                $this->assertEquals($t1->serialize(), $t3->serialize());
423
            }
424
        }
425
    }
426
427
    public function testCountEntities()
428
    {
429
        $sendString = "h'fd>onc>>l>>rw&bpu>q>e<v&gxs<ytjzkami<";
430
        $m = new xmlrpcmsg('validator1.countTheEntities', array(
431
            new xmlrpcval($sendString, 'string'),
432
        ));
433
        $v = $this->send($m);
434
        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...
435
            $got = '';
436
            $expected = '37210';
437
            $expect_array = array('ctLeftAngleBrackets', 'ctRightAngleBrackets', 'ctAmpersands', 'ctApostrophes', 'ctQuotes');
438
            foreach($expect_array as $val) {
439
                $b = $v->structmem($val);
440
                $got .= $b->me['int'];
441
            }
442
            $this->assertEquals($expected, $got);
443
        }
444
    }
445
446
    public function _multicall_msg($method, $params)
447
    {
448
        $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...
449
        $struct['params'] = new xmlrpcval($params, 'array');
450
451
        return new xmlrpcval($struct, 'struct');
452
    }
453
454
    public function testServerMulticall()
455
    {
456
        // We manually construct a system.multicall() call to ensure
457
        // that the server supports it.
458
459
        // NB: This test will NOT pass if server does not support system.multicall.
460
461
        // Based on http://xmlrpc-c.sourceforge.net/hacks/test_multicall.py
462
        $good1 = $this->_multicall_msg(
463
            'system.methodHelp',
464
            array(php_xmlrpc_encode('system.listMethods')));
465
        $bad = $this->_multicall_msg(
466
            'test.nosuch',
467
            array(php_xmlrpc_encode(1), php_xmlrpc_encode(2)));
468
        $recursive = $this->_multicall_msg(
469
            'system.multicall',
470
            array(new xmlrpcval(array(), 'array')));
471
        $good2 = $this->_multicall_msg(
472
            'system.methodSignature',
473
            array(php_xmlrpc_encode('system.listMethods')));
474
        $arg = new xmlrpcval(
475
            array($good1, $bad, $recursive, $good2),
476
            'array'
477
        );
478
479
        $m = new xmlrpcmsg('system.multicall', array($arg));
480
        $v = $this->send($m);
481
        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...
482
            //$this->assertTrue($r->faultCode() == 0, "fault from system.multicall");
483
            $this->assertTrue($v->arraysize() == 4, "bad number of return values");
484
485
            $r1 = $v->arraymem(0);
486
            $this->assertTrue(
487
                $r1->kindOf() == 'array' && $r1->arraysize() == 1,
488
                "did not get array of size 1 from good1"
489
            );
490
491
            $r2 = $v->arraymem(1);
492
            $this->assertTrue(
493
                $r2->kindOf() == 'struct',
494
                "no fault from bad"
495
            );
496
497
            $r3 = $v->arraymem(2);
498
            $this->assertTrue(
499
                $r3->kindOf() == 'struct',
500
                "recursive system.multicall did not fail"
501
            );
502
503
            $r4 = $v->arraymem(3);
504
            $this->assertTrue(
505
                $r4->kindOf() == 'array' && $r4->arraysize() == 1,
506
                "did not get array of size 1 from good2"
507
            );
508
        }
509
    }
510
511
    public function testClientMulticall1()
512
    {
513
        // NB: This test will NOT pass if server does not support system.multicall.
514
515
        $noMultiCall = $this->client->no_multicall;
516
        $this->client->no_multicall = false;
517
518
        $good1 = new xmlrpcmsg('system.methodHelp',
519
            array(php_xmlrpc_encode('system.listMethods')));
520
        $bad = new xmlrpcmsg('test.nosuch',
521
            array(php_xmlrpc_encode(1), php_xmlrpc_encode(2)));
522
        $recursive = new xmlrpcmsg('system.multicall',
523
            array(new xmlrpcval(array(), 'array')));
524
        $good2 = new xmlrpcmsg('system.methodSignature',
525
            array(php_xmlrpc_encode('system.listMethods'))
526
        );
527
528
        $r = $this->send(array($good1, $bad, $recursive, $good2));
529
        if ($r) {
530
            $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 $var 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

530
            $this->assertTrue(count(/** @scrutinizer ignore-type */ $r) == 4, "wrong number of return values");
Loading history...
531
        }
532
533
        $this->assertTrue($r[0]->faultCode() == 0, "fault from good1");
534
        if (!$r[0]->faultCode()) {
535
            $val = $r[0]->value();
536
            $this->assertTrue(
537
                $val->kindOf() == 'scalar' && $val->scalartyp() == 'string',
538
                "good1 did not return string"
539
            );
540
        }
541
        $this->assertTrue($r[1]->faultCode() != 0, "no fault from bad");
542
        $this->assertTrue($r[2]->faultCode() != 0, "no fault from recursive system.multicall");
543
        $this->assertTrue($r[3]->faultCode() == 0, "fault from good2");
544
        if (!$r[3]->faultCode()) {
545
            $val = $r[3]->value();
546
            $this->assertTrue($val->kindOf() == 'array', "good2 did not return array");
547
        }
548
        // This is the only assert in this test which should fail
549
        // if the test server does not support system.multicall.
550
        $this->assertTrue($this->client->no_multicall == false,
551
            "server does not support system.multicall"
552
        );
553
554
        $this->client->no_multicall = $noMultiCall;
555
    }
556
557
    public function testClientMulticall2()
558
    {
559
        // NB: This test will NOT pass if server does not support system.multicall.
560
561
        $noMultiCall = $this->client->no_multicall;
562
        $this->client->no_multicall = true;
563
564
        $good1 = new xmlrpcmsg('system.methodHelp',
565
            array(php_xmlrpc_encode('system.listMethods')));
566
        $bad = new xmlrpcmsg('test.nosuch',
567
            array(php_xmlrpc_encode(1), php_xmlrpc_encode(2)));
568
        $recursive = new xmlrpcmsg('system.multicall',
569
            array(new xmlrpcval(array(), 'array')));
570
        $good2 = new xmlrpcmsg('system.methodSignature',
571
            array(php_xmlrpc_encode('system.listMethods'))
572
        );
573
574
        $r = $this->send(array($good1, $bad, $recursive, $good2));
575
        if ($r) {
576
            $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 $var 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

576
            $this->assertTrue(count(/** @scrutinizer ignore-type */ $r) == 4, "wrong number of return values");
Loading history...
577
        }
578
579
        $this->assertTrue($r[0]->faultCode() == 0, "fault from good1");
580
        if (!$r[0]->faultCode()) {
581
            $val = $r[0]->value();
582
            $this->assertTrue(
583
                $val->kindOf() == 'scalar' && $val->scalartyp() == 'string',
584
                "good1 did not return string");
585
        }
586
        $this->assertTrue($r[1]->faultCode() != 0, "no fault from bad");
587
        $this->assertTrue($r[2]->faultCode() == 0, "fault from (non recursive) system.multicall");
588
        $this->assertTrue($r[3]->faultCode() == 0, "fault from good2");
589
        if (!$r[3]->faultCode()) {
590
            $val = $r[3]->value();
591
            $this->assertTrue($val->kindOf() == 'array', "good2 did not return array");
592
        }
593
594
        $this->client->no_multicall = $noMultiCall;
595
    }
596
597
    public function testClientMulticall3()
598
    {
599
        // NB: This test will NOT pass if server does not support system.multicall.
600
601
        $noMultiCall = $this->client->no_multicall;
602
        $returnType = $this->client->return_type;
603
604
        $this->client->return_type = 'phpvals';
605
        $this->client->no_multicall = false;
606
607
        $good1 = new xmlrpcmsg('system.methodHelp',
608
            array(php_xmlrpc_encode('system.listMethods')));
609
        $bad = new xmlrpcmsg('test.nosuch',
610
            array(php_xmlrpc_encode(1), php_xmlrpc_encode(2)));
611
        $recursive = new xmlrpcmsg('system.multicall',
612
            array(new xmlrpcval(array(), 'array')));
613
        $good2 = new xmlrpcmsg('system.methodSignature',
614
            array(php_xmlrpc_encode('system.listMethods'))
615
        );
616
617
        $r = $this->send(array($good1, $bad, $recursive, $good2));
618
        if ($r) {
619
            $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 $var 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

619
            $this->assertTrue(count(/** @scrutinizer ignore-type */ $r) == 4, "wrong number of return values");
Loading history...
620
        }
621
        $this->assertTrue($r[0]->faultCode() == 0, "fault from good1");
622
        if (!$r[0]->faultCode()) {
623
            $val = $r[0]->value();
624
            $this->assertTrue(
625
                is_string($val), "good1 did not return string");
626
        }
627
        $this->assertTrue($r[1]->faultCode() != 0, "no fault from bad");
628
        $this->assertTrue($r[2]->faultCode() != 0, "no fault from recursive system.multicall");
629
        $this->assertTrue($r[3]->faultCode() == 0, "fault from good2");
630
        if (!$r[3]->faultCode()) {
631
            $val = $r[3]->value();
632
            $this->assertTrue(is_array($val), "good2 did not return array");
633
        }
634
635
        $this->client->return_type = $returnType;
636
        $this->client->no_multicall = $noMultiCall;
637
    }
638
639
    public function testCatchWarnings()
640
    {
641
        $m = new xmlrpcmsg('tests.generatePHPWarning', array(
642
            new xmlrpcval('whatever', 'string'),
643
        ));
644
        $v = $this->send($m);
645
        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...
646
            $this->assertEquals(true, $v->scalarval());
647
        }
648
    }
649
650
    public function testCatchExceptions()
651
    {
652
        $m = new xmlrpcmsg('tests.raiseException', array(
653
            new xmlrpcval('whatever', 'string'),
654
        ));
655
        $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...
656
        $this->addQueryParams(array('EXCEPTION_HANDLING' => 1));
657
        $v = $this->send($m, 1); // the error code of the expected exception
658
        $this->addQueryParams(array('EXCEPTION_HANDLING' => 2));
659
        // depending on whether display_errors is ON or OFF on the server, we will get back a different error here,
660
        // as php will generate an http status code of either 200 or 500...
661
        $v = $this->send($m, array($GLOBALS['xmlrpcerr']['invalid_return'], $GLOBALS['xmlrpcerr']['http_error']));
662
    }
663
664
    public function testZeroParams()
665
    {
666
        $m = new xmlrpcmsg('system.listMethods');
667
        $v = $this->send($m);
0 ignored issues
show
Unused Code introduced by
The assignment to $v is dead and can be removed.
Loading history...
668
    }
669
670
    public function testNullParams()
671
    {
672
        $m = new xmlrpcmsg('tests.getStateName.12', array(
673
            new xmlrpcval('whatever', 'null'),
674
            new xmlrpcval(23, 'int'),
675
        ));
676
        $v = $this->send($m);
677
        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...
678
            $this->assertEquals('Michigan', $v->scalarval());
679
        }
680
        $m = new xmlrpcmsg('tests.getStateName.12', array(
681
            new xmlrpcval(23, 'int'),
682
            new xmlrpcval('whatever', 'null'),
683
        ));
684
        $v = $this->send($m);
685
        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...
686
            $this->assertEquals('Michigan', $v->scalarval());
687
        }
688
        $m = new xmlrpcmsg('tests.getStateName.12', array(
689
            new xmlrpcval(23, 'int')
690
        ));
691
        $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...
692
    }
693
694
    public function testCodeInjectionServerSide()
695
    {
696
        $m = new xmlrpcmsg('system.MethodHelp');
697
        $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>";
698
        $v = $this->send($m);
699
        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...
700
            $this->assertEquals(0, $v->structsize());
701
        }
702
    }
703
704
    public function testServerWrappedFunction()
705
    {
706
        $m = new xmlrpcmsg('tests.getStateName.2', array(
707
            new xmlrpcval(23, 'int'),
708
        ));
709
        $v = $this->send($m);
710
        $this->assertEquals('Michigan', $v->scalarval());
711
712
        // this generates an exception in the function which was wrapped, which is by default wrapped in a known error response
713
        $m = new xmlrpcmsg('tests.getStateName.2', array(
714
            new xmlrpcval(0, 'int'),
715
        ));
716
        $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...
717
718
        // check if the generated function dispatch map is fine, by checking if the server registered it
719
        $m = new xmlrpcmsg('system.methodSignature', array(
720
            new xmlrpcval('tests.getStateName.2'),
721
        ));
722
        $v = $this->send($m);
723
        $encoder = new \PhpXmlRpc\Encoder();
724
        $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

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