ServerTest::testWrappedClass()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 18
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 10
c 0
b 0
f 0
nc 3
nop 0
dl 0
loc 18
rs 9.9332
1
<?php
2
3
include_once __DIR__ . '/../lib/xmlrpc_wrappers.inc';
4
5
include_once __DIR__ . '/ServerAwareTestCase.php';
6
7
/**
8
 * Tests which involve interaction with the server - carried out via the client.
9
 * They are run against the server found in demo/server.php.
10
 * Includes testing of (some of) the Wrapper class
11
 */
12
class ServerTest extends PhpXmlRpc_ServerAwareTestCase
13
{
14
    /** @var xmlrpc_client $client */
15
    protected $client = null;
16
    protected $method = 'http';
17
    protected $timeout = 10;
18
    protected $request_compression = null;
19
    protected $accepted_compression = '';
20
21
    protected static $failed_tests = array();
22
    protected static $originalInternalEncoding;
23
24
    /**
25
     * @todo instead of overriding fail via _fail, implement Yoast\PHPUnitPolyfills\TestListeners\TestListenerDefaultImplementation
26
     */
27
    public static function _fail($message = '')
28
    {
29
        // save in a static var that this particular test has failed
30
        // (but only if not called from subclass objects / multitests)
31
        if (function_exists('debug_backtrace') && strtolower(get_called_class()) == 'servertest') {
32
            $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
33
            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...
34
                if (strpos($trace[$i]['function'], 'test') === 0) {
35
                    self::$failed_tests[$trace[$i]['function']] = true;
36
                    break;
37
                }
38
            }
39
        }
40
41
        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

41
        parent::/** @scrutinizer ignore-call */ 
42
                _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...
42
    }
43
44
    public static function set_up_before_class()
45
    {
46
        parent::set_up_before_class();
47
48
        self::$originalInternalEncoding = \PhpXmlRpc\PhpXmlRpc::$xmlrpc_internalencoding;
49
    }
50
51
    public function set_up()
52
    {
53
        parent::set_up();
54
55
        $this->timeout = 10;
56
57
        $this->client = $this->getClient();
58
        $this->client->request_compression = $this->request_compression;
0 ignored issues
show
Bug Best Practice introduced by
The property $request_compression is declared protected in PhpXmlRpc\Client. Since you implement __set, consider adding a @property or @property-write.
Loading history...
59
        $this->client->accepted_compression = $this->accepted_compression;
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->accepted_compression of type string is incompatible with the declared type array of property $accepted_compression.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
Bug Best Practice introduced by
The property $accepted_compression is declared protected in PhpXmlRpc\Client. Since you implement __set, consider adding a @property or @property-write.
Loading history...
60
    }
61
62
    public function tear_down()
63
    {
64
        \PhpXmlRpc\PhpXmlRpc::$xmlrpc_internalencoding = self::$originalInternalEncoding;
65
66
        parent::tear_down();
67
    }
68
69
    /**
70
     * @param PhpXmlRpc\Request|array $msg
71
     * @param int|int[] $errorCode expected error codes
72
     * @param bool $returnResponse
73
     * @return mixed|\PhpXmlRpc\Response|\PhpXmlRpc\Response[]|\PhpXmlRpc\Value|string|null
74
     * @todo allo callers to disable checking of faultCode
75
     */
76
    protected function send($msg, $errorCode = 0, $returnResponse = false)
77
    {
78
        $r = $this->client->send($msg, $this->timeout, $this->method);
79
        // for multicall, return directly array of responses
80
        if (is_array($r)) {
81
            return $r;
82
        }
83
        $this->validateResponse($r);
84
        if (is_array($errorCode)) {
85
            $this->assertContains($r->faultCode(), $errorCode, 'Error ' . $r->faultCode() . ' connecting to server: ' . $r->faultString());
86
        } else {
87
            $this->assertEquals($errorCode, $r->faultCode(), 'Error ' . $r->faultCode() . ' connecting to server: ' . $r->faultString());
88
        }
89
        if (!$r->faultCode()) {
90
            if ($returnResponse) {
91
                return $r;
92
            } else {
93
                return $r->value();
94
            }
95
        } else {
96
            return null;
97
        }
98
    }
99
100
    protected function validateResponse($r)
101
    {
102
        // to be implemented in subclasses
103
    }
104
105
    /**
106
     * Adds (and replaces) query params to the url currently used by the client
107
     * @param array $data
108
     */
109
    protected function addQueryParams($data)
110
    {
111
        $query = parse_url($this->client->path, PHP_URL_QUERY);
112
        parse_str($query, $vars);
113
        $query = http_build_query(array_merge($vars, $data));
114
        $this->client->path = parse_url($this->client->path, PHP_URL_PATH) . '?' . $query;
115
    }
116
117
    public function testString()
118
    {
119
        $sendString = "here are 3 \"entities\": < > & " .
120
            "and here's a dollar sign: \$pretendvarname and a backslash too: " . chr(92) .
121
            " - isn't that great? \\\"hackery\\\" at it's best " .
122
            " also don't want to miss out on \$item[0]. " .
123
            "The real weird stuff follows: CRLF here" . chr(13) . chr(10) .
124
            "a simple CR here" . chr(13) .
125
            "a simple LF here" . chr(10) .
126
            "and then LFCR" . chr(10) . chr(13) .
127
            "last but not least weird names: G" . chr(252) . "nter, El" . chr(232) . "ne, and an xml comment closing tag: -->";
128
        $m = new xmlrpcmsg('examples.stringecho', array(
129
            new xmlrpcval($sendString, 'string'),
130
        ));
131
        $v = $this->send($m);
132
        if ($v) {
133
            // when sending/receiving non-US-ASCII encoded strings, XML says cr-lf can be normalized.
134
            // so we relax our tests...
135
            $l1 = strlen($sendString);
136
            $l2 = strlen($v->scalarval());
0 ignored issues
show
Bug introduced by
The method scalarval() does not exist on PhpXmlRpc\Response. ( Ignorable by Annotation )

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

136
            $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...
137
            if ($l1 == $l2) {
138
                $this->assertEquals($sendString, $v->scalarval());
139
            } else {
140
                $this->assertEquals(str_replace(array("\r\n", "\r"), array("\n", "\n"), $sendString), $v->scalarval());
141
            }
142
        }
143
    }
144
145
    public function testLatin1String()
146
    {
147
        $sendString =
148
            "last but not least weird names: G" . chr(252) . "nter, El" . chr(232) . "ne";
149
        $x = '<?xml version="1.0" encoding="ISO-8859-1"?><methodCall><methodName>examples.stringecho</methodName><params><param><value>'.
150
            $sendString.
151
            '</value></param></params></methodCall>';
152
        $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

152
        $v = $this->send(/** @scrutinizer ignore-type */ $x);
Loading history...
153
        if ($v) {
154
            $this->assertEquals($sendString, $v->scalarval());
155
        }
156
    }
157
158
    public function testExoticCharsetsRequests()
159
    {
160
        // note that we should disable this call also when mbstring is missing server-side
161
        if (!function_exists('mb_convert_encoding')) {
162
            $this->markTestSkipped('Miss mbstring extension to test exotic charsets');
163
            return;
164
        }
165
        $sendString = 'κόσμε'; // Greek word 'kosme'
166
        $str = '<?xml version="1.0" encoding="_ENC_"?>
167
<methodCall>
168
    <methodName>examples.stringecho</methodName>
169
    <params>
170
        <param>
171
        <value><string>'.$sendString.'</string></value>
172
        </param>
173
    </params>
174
</methodCall>';
175
176
        PhpXmlRpc\PhpXmlRpc::$xmlrpc_internalencoding = 'UTF-8';
177
        // This test is known to fail with old mbstring versions, at least the ones we get with php 5.4, 5.5 as present
178
        // in the CI test vms
179
        if (version_compare(PHP_VERSION, '5.6.0', '>=')) {
180
            // we have to set the encoding declaration either in the http header or xml prolog, as mb_detect_encoding
181
            // (used on the server side) will fail recognizing these 2 charsets
182
            $v = $this->send(mb_convert_encoding(str_replace('_ENC_', 'UCS-4', $str), 'UCS-4', 'UTF-8'));
0 ignored issues
show
Bug introduced by
It seems like mb_convert_encoding(str_...str), 'UCS-4', 'UTF-8') can also be of type string; however, parameter $msg of ServerTest::send() does only seem to accept PhpXmlRpc\Request|array, maybe add an additional type check? ( Ignorable by Annotation )

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

182
            $v = $this->send(/** @scrutinizer ignore-type */ mb_convert_encoding(str_replace('_ENC_', 'UCS-4', $str), 'UCS-4', 'UTF-8'));
Loading history...
183
            $this->assertEquals($sendString, $v->scalarval());
184
        }
185
        $v = $this->send(mb_convert_encoding(str_replace('_ENC_', 'UTF-16', $str), 'UTF-16', 'UTF-8'));
186
        $this->assertEquals($sendString, $v->scalarval());
187
        //PhpXmlRpc\PhpXmlRpc::$xmlrpc_internalencoding = 'ISO-8859-1';
188
    }
189
190
    public function testExoticCharsetsRequests2()
191
    {
192
        // note that we should disable this call also when mbstring is missing server-side
193
        if (!function_exists('mb_convert_encoding')) {
194
            $this->markTestSkipped('Miss mbstring extension to test exotic charsets');
195
            return;
196
        }
197
        $sendString = '安室奈美恵'; // Japanese name "Namie Amuro"
198
        $str = '<?xml version="1.0"?>
199
<methodCall>
200
    <methodName>examples.stringecho</methodName>
201
    <params>
202
        <param>
203
        <value><string>'.$sendString.'</string></value>
204
        </param>
205
    </params>
206
</methodCall>';
207
208
        PhpXmlRpc\PhpXmlRpc::$xmlrpc_internalencoding = 'UTF-8';
209
        // no encoding declaration either in the http header or xml prolog, let mb_detect_encoding
210
        // (used on the server side) sort it out
211
        $this->addQueryParams(array('DETECT_ENCODINGS' => array('EUC-JP', 'UTF-8')));
212
        $v = $this->send(mb_convert_encoding($str, 'EUC-JP', 'UTF-8'));
0 ignored issues
show
Bug introduced by
It seems like mb_convert_encoding($str, 'EUC-JP', 'UTF-8') can also be of type string; however, parameter $msg of ServerTest::send() does only seem to accept PhpXmlRpc\Request|array, maybe add an additional type check? ( Ignorable by Annotation )

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

212
        $v = $this->send(/** @scrutinizer ignore-type */ mb_convert_encoding($str, 'EUC-JP', 'UTF-8'));
Loading history...
213
        //PhpXmlRpc\PhpXmlRpc::$xmlrpc_internalencoding = 'ISO-8859-1';
214
        $this->assertEquals($sendString, $v->scalarval());
215
    }
216
217
    public function testExoticCharsetsRequests3()
218
    {
219
        // note that we should disable this call also when mbstring is missing server-side
220
        if (!function_exists('mb_convert_encoding')) {
221
            $this->markTestSkipped('Miss mbstring extension to test exotic charsets');
222
            return;
223
        }
224
        // the warning suppression is due to utf8_decode being deprecated in php 8.2
225
        $sendString = @utf8_decode('élève');
226
        $str = '<?xml version="1.0"?>
227
<methodCall>
228
    <methodName>examples.stringecho</methodName>
229
    <params>
230
        <param>
231
        <value><string>'.$sendString.'</string></value>
232
        </param>
233
    </params>
234
</methodCall>';
235
236
        // no encoding declaration either in the http header or xml prolog, let mb_detect_encoding
237
        // (used on the server side) sort it out
238
        $this->addQueryParams(array('DETECT_ENCODINGS' => array('ISO-8859-1', 'UTF-8')));
239
        $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

239
        $v = $this->send(/** @scrutinizer ignore-type */ $str);
Loading history...
240
        $this->assertEquals($sendString, $v->scalarval());
241
    }
242
243
    /*public function testLatin1Method()
244
    {
245
        $f = new xmlrpcmsg("tests.iso88591methodname." . chr(224) . chr(252) . chr(232), array(
246
            new xmlrpcval('hello')
247
        ));
248
        $v = $this->send($f);
249
        if ($v) {
250
            $this->assertEquals('hello', $v->scalarval());
251
        }
252
    }*/
253
254
    public function testUtf8Method()
255
    {
256
        PhpXmlRpc\PhpXmlRpc::$xmlrpc_internalencoding = 'UTF-8';
257
        $m = new xmlrpcmsg("tests.utf8methodname." . 'κόσμε', array(
258
            new xmlrpcval('hello')
259
        ));
260
        $v = $this->send($m);
261
        //PhpXmlRpc\PhpXmlRpc::$xmlrpc_internalencoding = 'ISO-8859-1';
262
        if ($v) {
263
            $this->assertEquals('hello', $v->scalarval());
264
        }
265
    }
266
267
    public function testAddingDoubles()
268
    {
269
        // note that rounding errors mean we keep precision to sensible levels here ;-)
270
        $a = 12.13;
271
        $b = -23.98;
272
        $m = new xmlrpcmsg('examples.addtwodouble', array(
273
            new xmlrpcval($a, 'double'),
274
            new xmlrpcval($b, 'double'),
275
        ));
276
        $v = $this->send($m);
277
        if ($v) {
278
            $this->assertEquals($a + $b, $v->scalarval());
279
        }
280
    }
281
282
    public function testAdding()
283
    {
284
        $m = new xmlrpcmsg('examples.addtwo', array(
285
            new xmlrpcval(12, 'int'),
286
            new xmlrpcval(-23, 'int'),
287
        ));
288
        $v = $this->send($m);
289
        if ($v) {
290
            $this->assertEquals(12 - 23, $v->scalarval());
291
        }
292
    }
293
294
    public function testInvalidNumber()
295
    {
296
        $m = new xmlrpcmsg('examples.addtwo', array(
297
            new xmlrpcval('fred', 'int'),
298
            new xmlrpcval("\"; exec('ls')", 'int'),
299
        ));
300
        $v = $this->send($m);
301
        /// @todo a specific fault should be generated here by the server, which we can check
302
        if ($v) {
303
            $this->assertEquals(0, $v->scalarval());
304
        }
305
    }
306
307
    public function testUnknownMethod()
308
    {
309
        $m = new xmlrpcmsg('examples.a_very_unlikely.method', array());
310
        $this->send($m, \PhpXmlRpc\PhpXmlRpc::$xmlrpcerr['unknown_method']);
311
    }
312
313
    public function testBoolean()
314
    {
315
        $m = new xmlrpcmsg('examples.invertBooleans', array(
316
            new xmlrpcval(array(
317
                new xmlrpcval(true, 'boolean'),
318
                new xmlrpcval(false, 'boolean'),
319
                new xmlrpcval(1, 'boolean'),
320
                new xmlrpcval(0, 'boolean')
321
            ),
322
                'array'
323
            ),));
324
        $answer = '0101';
325
        $v = $this->send($m);
326
        if ($v) {
327
            $sz = $v->arraysize();
0 ignored issues
show
Deprecated Code introduced by
The function PhpXmlRpc\Value::arraySize() has been deprecated: use count() instead ( Ignorable by Annotation )

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

327
            $sz = /** @scrutinizer ignore-deprecated */ $v->arraysize();

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
Bug introduced by
The method arraysize() does not exist on PhpXmlRpc\Response. ( Ignorable by Annotation )

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

327
            /** @scrutinizer ignore-call */ 
328
            $sz = $v->arraysize();

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...
328
            $got = '';
329
            for ($i = 0; $i < $sz; $i++) {
330
                $b = $v->arraymem($i);
0 ignored issues
show
Bug introduced by
The method arraymem() does not exist on PhpXmlRpc\Response. ( Ignorable by Annotation )

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

330
                /** @scrutinizer ignore-call */ 
331
                $b = $v->arraymem($i);

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...
Deprecated Code introduced by
The function PhpXmlRpc\Value::arrayMem() has been deprecated: use array access, e.g. $val[$key] ( Ignorable by Annotation )

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

330
                $b = /** @scrutinizer ignore-deprecated */ $v->arraymem($i);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
331
                if ($b->scalarval()) {
332
                    $got .= '1';
333
                } else {
334
                    $got .= '0';
335
                }
336
            }
337
            $this->assertEquals($answer, $got);
338
        }
339
    }
340
341
    public function testBase64()
342
    {
343
        $sendString = 'Mary had a little lamb,
344
Whose fleece was white as snow,
345
And everywhere that Mary went
346
the lamb was sure to go.
347
348
Mary had a little lamb
349
She tied it to a pylon
350
Ten thousand volts went down its back
351
And turned it into nylon';
352
        $m = new xmlrpcmsg('examples.decode64', array(
353
            new xmlrpcval($sendString, 'base64'),
354
        ));
355
        $v = $this->send($m);
356
        if ($v) {
357
            if (strlen($sendString) == strlen($v->scalarval())) {
358
                $this->assertEquals($sendString, $v->scalarval());
359
            } else {
360
                $this->assertEquals(str_replace(array("\r\n", "\r"), array("\n", "\n"), $sendString), $v->scalarval());
361
            }
362
        }
363
    }
364
365
    public function testCountEntities()
366
    {
367
        $sendString = "h'fd>onc>>l>>rw&bpu>q>e<v&gxs<ytjzkami<";
368
        $m = new xmlrpcmsg('validator1.countTheEntities', array(
369
            new xmlrpcval($sendString, 'string'),
370
        ));
371
        $v = $this->send($m);
372
        if ($v) {
373
            $got = '';
374
            $expected = '37210';
375
            $expect_array = array('ctLeftAngleBrackets', 'ctRightAngleBrackets', 'ctAmpersands', 'ctApostrophes', 'ctQuotes');
376
            foreach($expect_array as $val) {
377
                $b = $v->structmem($val);
0 ignored issues
show
Bug introduced by
The method structmem() does not exist on PhpXmlRpc\Response. ( Ignorable by Annotation )

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

377
                /** @scrutinizer ignore-call */ 
378
                $b = $v->structmem($val);

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...
Deprecated Code introduced by
The function PhpXmlRpc\Value::structMem() has been deprecated: use array access, e.g. $val[$key] ( Ignorable by Annotation )

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

377
                $b = /** @scrutinizer ignore-deprecated */ $v->structmem($val);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
378
                $got .= $b->scalarVal();
379
            }
380
            $this->assertEquals($expected, $got);
381
        }
382
    }
383
384
    protected function _multicall_msg($method, $params)
385
    {
386
        $struct = array();
387
        $struct['methodName'] = new xmlrpcval($method, 'string');
388
        $struct['params'] = new xmlrpcval($params, 'array');
389
390
        return new xmlrpcval($struct, 'struct');
391
    }
392
393
    public function testServerMulticall()
394
    {
395
        // We manually construct a system.multicall() call to ensure
396
        // that the server supports it.
397
398
        // NB: This test will NOT pass if server does not support system.multicall.
399
400
        // Based on http://xmlrpc-c.sourceforge.net/hacks/test_multicall.py
401
        $good1 = $this->_multicall_msg(
402
            'system.methodHelp',
403
            array(php_xmlrpc_encode('system.listMethods')));
404
        $bad = $this->_multicall_msg(
405
            'test.nosuch',
406
            array(php_xmlrpc_encode(1), php_xmlrpc_encode(2)));
407
        $recursive = $this->_multicall_msg(
408
            'system.multicall',
409
            array(new xmlrpcval(array(), 'array')));
410
        $good2 = $this->_multicall_msg(
411
            'system.methodSignature',
412
            array(php_xmlrpc_encode('system.listMethods')));
413
        $arg = new xmlrpcval(
414
            array($good1, $bad, $recursive, $good2),
415
            'array'
416
        );
417
418
        $m = new xmlrpcmsg('system.multicall', array($arg));
419
        $v = $this->send($m);
420
        if ($v) {
421
            //$this->assertEquals(0, $r->faultCode(), "fault from system.multicall");
422
            $this->assertEquals(4, $v->arraysize(), "bad number of return values");
0 ignored issues
show
Deprecated Code introduced by
The function PhpXmlRpc\Value::arraySize() has been deprecated: use count() instead ( Ignorable by Annotation )

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

422
            $this->assertEquals(4, /** @scrutinizer ignore-deprecated */ $v->arraysize(), "bad number of return values");

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
423
424
            $r1 = $v->arraymem(0);
0 ignored issues
show
Deprecated Code introduced by
The function PhpXmlRpc\Value::arrayMem() has been deprecated: use array access, e.g. $val[$key] ( Ignorable by Annotation )

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

424
            $r1 = /** @scrutinizer ignore-deprecated */ $v->arraymem(0);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
425
            $this->assertTrue(
426
                $r1->kindOf() == 'array' && $r1->arraysize() == 1,
0 ignored issues
show
Deprecated Code introduced by
The function PhpXmlRpc\Value::arraySize() has been deprecated: use count() instead ( Ignorable by Annotation )

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

426
                $r1->kindOf() == 'array' && /** @scrutinizer ignore-deprecated */ $r1->arraysize() == 1,

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
427
                "did not get array of size 1 from good1"
428
            );
429
430
            $r2 = $v->arraymem(1);
0 ignored issues
show
Deprecated Code introduced by
The function PhpXmlRpc\Value::arrayMem() has been deprecated: use array access, e.g. $val[$key] ( Ignorable by Annotation )

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

430
            $r2 = /** @scrutinizer ignore-deprecated */ $v->arraymem(1);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
431
            $this->assertEquals('struct', $r2->kindOf(), "no fault from bad");
432
433
            $r3 = $v->arraymem(2);
0 ignored issues
show
Deprecated Code introduced by
The function PhpXmlRpc\Value::arrayMem() has been deprecated: use array access, e.g. $val[$key] ( Ignorable by Annotation )

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

433
            $r3 = /** @scrutinizer ignore-deprecated */ $v->arraymem(2);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
434
            $this->assertEquals('struct', $r3->kindOf(), "recursive system.multicall did not fail");
435
436
            $r4 = $v->arraymem(3);
0 ignored issues
show
Deprecated Code introduced by
The function PhpXmlRpc\Value::arrayMem() has been deprecated: use array access, e.g. $val[$key] ( Ignorable by Annotation )

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

436
            $r4 = /** @scrutinizer ignore-deprecated */ $v->arraymem(3);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
437
            $this->assertTrue(
438
                $r4->kindOf() == 'array' && $r4->arraysize() == 1,
0 ignored issues
show
Deprecated Code introduced by
The function PhpXmlRpc\Value::arraySize() has been deprecated: use count() instead ( Ignorable by Annotation )

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

438
                $r4->kindOf() == 'array' && /** @scrutinizer ignore-deprecated */ $r4->arraysize() == 1,

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
439
                "did not get array of size 1 from good2"
440
            );
441
        }
442
    }
443
444
    public function testClientMulticall1()
445
    {
446
        // NB: This test will NOT pass if server does not support system.multicall.
447
448
        $noMultiCall = $this->client->no_multicall;
0 ignored issues
show
Bug Best Practice introduced by
The property $no_multicall is declared protected in PhpXmlRpc\Client. Since you implement __get, consider adding a @property or @property-read.
Loading history...
449
        $this->client->no_multicall = false;
450
451
        $good1 = new xmlrpcmsg('system.methodHelp',
452
            array(php_xmlrpc_encode('system.listMethods')));
453
        $bad = new xmlrpcmsg('test.nosuch',
454
            array(php_xmlrpc_encode(1), php_xmlrpc_encode(2)));
455
        $recursive = new xmlrpcmsg('system.multicall',
456
            array(new xmlrpcval(array(), 'array')));
457
        $good2 = new xmlrpcmsg('system.methodSignature',
458
            array(php_xmlrpc_encode('system.listMethods'))
459
        );
460
461
        $r = $this->send(array($good1, $bad, $recursive, $good2));
462
        if ($r) {
463
            $this->assertEquals(4, count($r), "wrong number of return values");
464
        }
465
466
        $this->assertEquals(0, $r[0]->faultCode(), "fault from good1");
467
        if (!$r[0]->faultCode()) {
468
            $val = $r[0]->value();
469
            $this->assertTrue(
470
                $val->kindOf() == 'scalar' && $val->scalartyp() == 'string',
471
                "good1 did not return string"
472
            );
473
        }
474
        $this->assertNotEquals(0, $r[1]->faultCode(), "no fault from bad");
475
        $this->assertNotEquals(0, $r[2]->faultCode(), "no fault from recursive system.multicall");
476
        $this->assertEquals(0, $r[3]->faultCode(), "fault from good2");
477
        if (!$r[3]->faultCode()) {
478
            $val = $r[3]->value();
479
            $this->assertEquals('array', $val->kindOf(), "good2 did not return array");
480
        }
481
        // This is the only assert in this test which should fail
482
        // if the test server does not support system.multicall.
483
        $this->assertEquals(false, $this->client->no_multicall, "server does not support system.multicall");
484
485
        $this->client->no_multicall = $noMultiCall;
486
    }
487
488
    public function testClientMulticall2()
489
    {
490
        // NB: This test will NOT pass if server does not support system.multicall.
491
492
        $noMultiCall = $this->client->no_multicall;
0 ignored issues
show
Bug Best Practice introduced by
The property $no_multicall is declared protected in PhpXmlRpc\Client. Since you implement __get, consider adding a @property or @property-read.
Loading history...
493
        $this->client->no_multicall = true;
494
495
        $good1 = new xmlrpcmsg('system.methodHelp',
496
            array(php_xmlrpc_encode('system.listMethods')));
497
        $bad = new xmlrpcmsg('test.nosuch',
498
            array(php_xmlrpc_encode(1), php_xmlrpc_encode(2)));
499
        $recursive = new xmlrpcmsg('system.multicall',
500
            array(new xmlrpcval(array(), 'array')));
501
        $good2 = new xmlrpcmsg('system.methodSignature',
502
            array(php_xmlrpc_encode('system.listMethods'))
503
        );
504
505
        $r = $this->send(array($good1, $bad, $recursive, $good2));
506
        if ($r) {
507
            $this->assertEquals(4, count($r), "wrong number of return values");
508
        }
509
510
        $this->assertEquals(0, $r[0]->faultCode(), "fault from good1");
511
        if (!$r[0]->faultCode()) {
512
            $val = $r[0]->value();
513
            $this->assertTrue(
514
                $val->kindOf() == 'scalar' && $val->scalartyp() == 'string',
515
                "good1 did not return string");
516
        }
517
        $this->assertNotEquals(0, $r[1]->faultCode(), "no fault from bad");
518
        $this->assertEquals(0, $r[2]->faultCode(), "fault from (non recursive) system.multicall");
519
        $this->assertEquals(0, $r[3]->faultCode(), "fault from good2");
520
        if (!$r[3]->faultCode()) {
521
            $val = $r[3]->value();
522
            $this->assertEquals('array', $val->kindOf(), "good2 did not return array");
523
        }
524
525
        $this->client->no_multicall = $noMultiCall;
526
    }
527
528
    public function testClientMulticall3()
529
    {
530
        // NB: This test will NOT pass if server does not support system.multicall.
531
532
        $noMultiCall = $this->client->no_multicall;
0 ignored issues
show
Bug Best Practice introduced by
The property $no_multicall is declared protected in PhpXmlRpc\Client. Since you implement __get, consider adding a @property or @property-read.
Loading history...
533
        $returnType = $this->client->return_type;
0 ignored issues
show
Bug Best Practice introduced by
The property $return_type is declared protected in PhpXmlRpc\Client. Since you implement __get, consider adding a @property or @property-read.
Loading history...
534
535
        $this->client->return_type = 'phpvals';
536
        $this->client->no_multicall = false;
537
538
        $good1 = new xmlrpcmsg('system.methodHelp',
539
            array(php_xmlrpc_encode('system.listMethods')));
540
        $bad = new xmlrpcmsg('test.nosuch',
541
            array(php_xmlrpc_encode(1), php_xmlrpc_encode(2)));
542
        $recursive = new xmlrpcmsg('system.multicall',
543
            array(new xmlrpcval(array(), 'array')));
544
        $good2 = new xmlrpcmsg('system.methodSignature',
545
            array(php_xmlrpc_encode('system.listMethods'))
546
        );
547
548
        $r = $this->send(array($good1, $bad, $recursive, $good2));
549
        if ($r) {
550
            $this->assertEquals(4, count($r), "wrong number of return values");
551
        }
552
        $this->assertEquals(0, $r[0]->faultCode(), "fault from good1");
553
        if (!$r[0]->faultCode()) {
554
            $val = $r[0]->value();
555
            $this->assertIsString($val, "good1 did not return string");
556
        }
557
        $this->assertNotEquals(0, $r[1]->faultCode(), "no fault from bad");
558
        $this->assertNotEquals(0, $r[2]->faultCode(), "no fault from recursive system.multicall");
559
        $this->assertEquals(0, $r[3]->faultCode(), "fault from good2");
560
        if (!$r[3]->faultCode()) {
561
            $val = $r[3]->value();
562
            $this->assertIsArray($val, "good2 did not return array");
563
        }
564
565
        $this->client->return_type = $returnType;
566
        $this->client->no_multicall = $noMultiCall;
567
    }
568
569
    public function testClientMulticall4()
570
    {
571
        // NB: This test will NOT pass if server does not support system.multicall.
572
573
        $noMultiCall = $this->client->no_multicall;
0 ignored issues
show
Bug Best Practice introduced by
The property $no_multicall is declared protected in PhpXmlRpc\Client. Since you implement __get, consider adding a @property or @property-read.
Loading history...
574
        $returnType = $this->client->return_type;
0 ignored issues
show
Bug Best Practice introduced by
The property $return_type is declared protected in PhpXmlRpc\Client. Since you implement __get, consider adding a @property or @property-read.
Loading history...
575
576
        $this->client->return_type = 'xml';
577
        $this->client->no_multicall = false;
578
579
        $good1 = new xmlrpcmsg('system.methodHelp',
580
            array(php_xmlrpc_encode('system.listMethods')));
581
        $good2 = new xmlrpcmsg('system.methodSignature',
582
            array(php_xmlrpc_encode('system.listMethods'))
583
        );
584
585
        $r = $this->send(array($good1, $good2));
586
        if ($r) {
587
            $this->assertEquals(2, count($r), "wrong number of return values");
588
        }
589
        $this->assertEquals(0, $r[0]->faultCode(), "fault from good1");
590
        $this->assertEquals(0, $r[1]->faultCode(), "fault from good2");
591
592
        $hr = $r[0]->httpResponse();
593
        $this->assertEquals(200, $hr['status_code'], "http response of multicall has no status code");
594
        $this->assertEquals($r[0]->httpResponse(), $r[1]->httpResponse(), "http response of multicall items differs");
595
596
        $this->client->return_type = $returnType;
597
        $this->client->no_multicall = $noMultiCall;
598
    }
599
600
    public function testCatchWarnings()
601
    {
602
        $m = new xmlrpcmsg('tests.generatePHPWarning', array(
603
            new xmlrpcval('whatever', 'string'),
604
        ));
605
        $this->addQueryParams(array('FORCE_DEBUG' => 0));
606
        $v = $this->send($m);
607
        if ($v) {
608
            $this->assertEquals(true, $v->scalarval());
609
        }
610
    }
611
612
    public function testCatchExceptions()
613
    {
614
        // this tests for the server to catch exceptions with error code 0
615
        $m = new xmlrpcmsg('tests.raiseException', array(
616
            new xmlrpcval(0, 'int'),
617
        ));
618
        $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...
619
620
        // these test for the different server exception catching modes
621
        $m = new xmlrpcmsg('tests.raiseException', array(
622
            new xmlrpcval(3, 'int'),
623
        ));
624
        $v = $this->send($m, $GLOBALS['xmlrpcerr']['server_error']);
625
        $this->addQueryParams(array('EXCEPTION_HANDLING' => 1));
626
        $v = $this->send($m, 3); // the error code of the expected exception
627
        $this->addQueryParams(array('EXCEPTION_HANDLING' => 2));
628
        // depending on whether display_errors is ON or OFF on the server, we will get back a different error here,
629
        // as php will generate an http status code of either 200 or 500...
630
        $v = $this->send($m, array($GLOBALS['xmlrpcerr']['invalid_return'], $GLOBALS['xmlrpcerr']['http_error']));
631
    }
632
633
    public function testCatchErrors()
634
    {
635
        if (version_compare(PHP_VERSION, '7.0.0', '<'))
636
        {
637
            $this->markTestSkipped('Cannot test php Error on php < 7.0');
638
            return;
639
        }
640
641
        // these test for the different server error catching modes
642
        $m = new xmlrpcmsg('tests.raiseError');
643
        $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...
644
        $this->addQueryParams(array('EXCEPTION_HANDLING' => 1));
645
        $v = $this->send($m, 1); // the error code of the expected exception
646
        $this->addQueryParams(array('EXCEPTION_HANDLING' => 2));
647
        // depending on whether display_errors is ON or OFF on the server, we will get back a different error here,
648
        // as php will generate an http status code of either 200 or 500...
649
        $v = $this->send($m, array($GLOBALS['xmlrpcerr']['invalid_return'], $GLOBALS['xmlrpcerr']['http_error']));
650
    }
651
652
    public function testZeroParams()
653
    {
654
        $m = new xmlrpcmsg('system.listMethods');
655
        $v = $this->send($m);
0 ignored issues
show
Unused Code introduced by
The assignment to $v is dead and can be removed.
Loading history...
656
    }
657
658
    public function testNullParams()
659
    {
660
        $m = new xmlrpcmsg('tests.getStateName.12', array(
661
            new xmlrpcval('whatever', 'null'),
662
            new xmlrpcval(23, 'int'),
663
        ));
664
        $v = $this->send($m);
665
        if ($v) {
666
            $this->assertEquals('Michigan', $v->scalarval());
667
        }
668
        $m = new xmlrpcmsg('tests.getStateName.12', array(
669
            new xmlrpcval(23, 'int'),
670
            new xmlrpcval('whatever', 'null'),
671
        ));
672
        $v = $this->send($m);
673
        if ($v) {
674
            $this->assertEquals('Michigan', $v->scalarval());
675
        }
676
        $m = new xmlrpcmsg('tests.getStateName.12', array(
677
            new xmlrpcval(23, 'int')
678
        ));
679
        $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...
680
    }
681
682
    public function testCodeInjectionServerSide()
683
    {
684
        $m = new xmlrpcmsg('system.MethodHelp');
685
        $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>";
686
        $v = $this->send($m);
687
        if ($v) {
688
            $this->assertEquals(0, $v->structsize());
0 ignored issues
show
Deprecated Code introduced by
The function PhpXmlRpc\Value::structSize() has been deprecated: use count() instead ( Ignorable by Annotation )

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

688
            $this->assertEquals(0, /** @scrutinizer ignore-deprecated */ $v->structsize());

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
Bug introduced by
The method structsize() does not exist on PhpXmlRpc\Response. ( Ignorable by Annotation )

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

688
            $this->assertEquals(0, $v->/** @scrutinizer ignore-call */ structsize());

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