Passed
Push — master ( 43c003...f5456e )
by Gaetano
07:42
created

LocalhostTest::testCatchWarnings()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 1 Features 0
Metric Value
cc 2
eloc 5
c 2
b 1
f 0
nc 2
nop 0
dl 0
loc 8
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\Framework\TestResult;
11
12
/**
13
 * Tests which involve interaction between the client and the server.
14
 * They are run against the server found in demo/server.php
15
 */
16
class LocalhostTest extends PhpXmlRpc_PolyfillTestCase
17
{
18
    /** @var xmlrpc_client $client */
19
    protected $client = null;
20
    protected $method = 'http';
21
    protected $timeout = 10;
22
    protected $request_compression = null;
23
    protected $accepted_compression = '';
24
    protected $args = array();
25
26
    protected static $failed_tests = array();
27
28
    protected $testId;
29
    /** @var boolean $collectCodeCoverageInformation */
30
    protected $collectCodeCoverageInformation;
31
    protected $coverageScriptUrl;
32
33
    public static function _fail($message = '')
34
    {
35
        // save in a static var that this particular test has failed
36
        // (but only if not called from subclass objects / multitests)
37
        if (function_exists('debug_backtrace') && strtolower(get_called_class()) == 'localhosttests') {
38
            $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
39
            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...
40
                if (strpos($trace[$i]['function'], 'test') === 0) {
41
                    self::$failed_tests[$trace[$i]['function']] = true;
42
                    break;
43
                }
44
            }
45
        }
46
47
        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

47
        parent::/** @scrutinizer ignore-call */ 
48
                _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...
48
    }
49
50
    /**
51
     * Reimplemented to allow us to collect code coverage info from the target server.
52
     * Code taken from PHPUnit_Extensions_Selenium2TestCase
53
     *
54
     * @param TestResult $result
55
     * @return TestResult
56
     * @throws Exception
57
     */
58
    public function _run(TestResult $result = NULL)
59
    {
60
        $this->testId = get_class($this) . '__' . $this->getName();
61
62
        if ($result === NULL) {
63
            $result = $this->createResult();
64
        }
65
66
        $this->collectCodeCoverageInformation = $result->getCollectCodeCoverageInformation();
67
68
        parent::_run($result);
69
70
        if ($this->collectCodeCoverageInformation) {
71
            $coverage = new PHPUnit_Extensions_SeleniumCommon_RemoteCoverage(
0 ignored issues
show
Bug introduced by
The type PHPUnit_Extensions_SeleniumCommon_RemoteCoverage was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
72
                $this->coverageScriptUrl,
73
                $this->testId
74
            );
75
            $result->getCodeCoverage()->append(
76
                $coverage->get(), $this
77
            );
78
        }
79
80
        // do not call this before to give the time to the Listeners to run
81
        //$this->getStrategy()->endOfTest($this->session);
82
83
        return $result;
84
    }
85
86
    public function set_up()
87
    {
88
        $this->args = argParser::getArgs();
89
90
        $server = explode(':', $this->args['LOCALSERVER']);
91
        if (count($server) > 1) {
92
            $this->client = new xmlrpc_client($this->args['URI'], $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

92
            $this->client = new xmlrpc_client($this->args['URI'], $server[0], /** @scrutinizer ignore-type */ $server[1]);
Loading history...
93
        } else {
94
            $this->client = new xmlrpc_client($this->args['URI'], $this->args['LOCALSERVER']);
95
        }
96
97
        $this->client->setDebug($this->args['DEBUG']);
98
        $this->client->request_compression = $this->request_compression;
99
        $this->client->accepted_compression = $this->accepted_compression;
100
101
        $this->coverageScriptUrl = 'http://' . $this->args['LOCALSERVER'] . '/' . str_replace( '/demo/server/server.php', 'tests/phpunit_coverage.php', $this->args['URI'] );
102
103
        if ($this->args['DEBUG'] == 1)
104
            ob_start();
105
    }
106
107
    protected function tear_down()
108
    {
109
        if ($this->args['DEBUG'] != 1)
110
            return;
111
        $out = ob_get_clean();
112
        $status = $this->getStatus();
113
        if ($status == PHPUnit_Runner_BaseTestRunner::STATUS_ERROR
0 ignored issues
show
Bug introduced by
The type PHPUnit_Runner_BaseTestRunner was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
114
            || $status == PHPUnit_Runner_BaseTestRunner::STATUS_FAILURE) {
115
            echo $out;
116
        }
117
    }
118
119
    /**
120
     * @param PhpXmlRpc\Request|array $msg
121
     * @param int|array $errorCode
122
     * @param bool $returnResponse
123
     * @return mixed|\PhpXmlRpc\Response|\PhpXmlRpc\Response[]|\PhpXmlRpc\Value|string|null
124
     */
125
    protected function send($msg, $errorCode = 0, $returnResponse = false)
126
    {
127
        if ($this->collectCodeCoverageInformation) {
128
            $this->client->setCookie('PHPUNIT_SELENIUM_TEST_ID', $this->testId);
129
        }
130
131
        $r = $this->client->send($msg, $this->timeout, $this->method);
132
        // for multicall, return directly array of responses
133
        if (is_array($r)) {
134
            return $r;
135
        }
136
        if (is_array($errorCode)) {
137
            $this->assertContains($r->faultCode(), $errorCode, 'Error ' . $r->faultCode() . ' connecting to server: ' . $r->faultString());
138
        } else {
139
            $this->assertEquals($errorCode, $r->faultCode(), 'Error ' . $r->faultCode() . ' connecting to server: ' . $r->faultString());
140
        }
141
        if (!$r->faultCode()) {
142
            if ($returnResponse) {
143
                return $r;
144
            } else {
145
                return $r->value();
146
            }
147
        } else {
148
            return null;
149
        }
150
    }
151
152
    /**
153
     * Adds (and replaces) query params to the url currently used by the client
154
     * @param array $data
155
     */
156
    protected function addQueryParams($data)
157
    {
158
        $query = parse_url($this->client->path, PHP_URL_QUERY);
159
        parse_str($query, $vars);
160
        $query = http_build_query(array_merge($vars, $data));
161
        $this->client->path = parse_url($this->client->path, PHP_URL_PATH) . '?' . $query;
162
    }
163
164
    public function testString()
165
    {
166
        $sendString = "here are 3 \"entities\": < > & " .
167
            "and here's a dollar sign: \$pretendvarname and a backslash too: " . chr(92) .
168
            " - isn't that great? \\\"hackery\\\" at it's best " .
169
            " also don't want to miss out on \$item[0]. " .
170
            "The real weird stuff follows: CRLF here" . chr(13) . chr(10) .
171
            "a simple CR here" . chr(13) .
172
            "a simple LF here" . chr(10) .
173
            "and then LFCR" . chr(10) . chr(13) .
174
            "last but not least weird names: G" . chr(252) . "nter, El" . chr(232) . "ne, and an xml comment closing tag: -->";
175
        $m = new xmlrpcmsg('examples.stringecho', array(
176
            new xmlrpcval($sendString, 'string'),
177
        ));
178
        $v = $this->send($m);
179
        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...
180
            // when sending/receiving non-US-ASCII encoded strings, XML says cr-lf can be normalized.
181
            // so we relax our tests...
182
            $l1 = strlen($sendString);
183
            $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

183
            $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...
184
            if ($l1 == $l2) {
185
                $this->assertEquals($sendString, $v->scalarval());
186
            } else {
187
                $this->assertEquals(str_replace(array("\r\n", "\r"), array("\n", "\n"), $sendString), $v->scalarval());
188
            }
189
        }
190
    }
191
192
    public function testLatin1String()
193
    {
194
        $sendString =
195
            "last but not least weird names: G" . chr(252) . "nter, El" . chr(232) . "ne";
196
        $x = '<?xml version="1.0" encoding="ISO-8859-1"?><methodCall><methodName>examples.stringecho</methodName><params><param><value>'.
197
            $sendString.
198
            '</value></param></params></methodCall>';
199
        $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 LocalhostTest::send(). ( Ignorable by Annotation )

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

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

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

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

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

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

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

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

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

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

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

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