Passed
Push — master ( 18eded...8ccda3 )
by Gaetano
12:44
created

ServerTest::tear_down()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

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

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

149
        $v = $this->send(/** @scrutinizer ignore-type */ $x);
Loading history...
150
        if ($v) {
151
            $this->assertEquals($sendString, $v->scalarval());
152
        }
153
    }
154
155
    public function testExoticCharsetsRequests()
156
    {
157
        // note that we should disable this call also when mbstring is missing server-side
158
        if (!function_exists('mb_convert_encoding')) {
159
            $this->markTestSkipped('Miss mbstring extension to test exotic charsets');
160
            return;
161
        }
162
        $sendString = 'κόσμε'; // Greek word 'kosme'
163
        $str = '<?xml version="1.0" encoding="_ENC_"?>
164
<methodCall>
165
    <methodName>examples.stringecho</methodName>
166
    <params>
167
        <param>
168
        <value><string>'.$sendString.'</string></value>
169
        </param>
170
    </params>
171
</methodCall>';
172
173
        PhpXmlRpc\PhpXmlRpc::$xmlrpc_internalencoding = 'UTF-8';
174
        // This test is known to fail with old mbstring versions, at least the ones we get with php 5.4, 5.5 as present
175
        // in the CI test vms
176
        if (version_compare(PHP_VERSION, '5.6.0', '>=')) {
177
            // we have to set the encoding declaration either in the http header or xml prolog, as mb_detect_encoding
178
            // (used on the server side) will fail recognizing these 2 charsets
179
            $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

179
            $v = $this->send(/** @scrutinizer ignore-type */ mb_convert_encoding(str_replace('_ENC_', 'UCS-4', $str), 'UCS-4', 'UTF-8'));
Loading history...
180
            $this->assertEquals($sendString, $v->scalarval());
181
        }
182
        $v = $this->send(mb_convert_encoding(str_replace('_ENC_', 'UTF-16', $str), 'UTF-16', 'UTF-8'));
183
        $this->assertEquals($sendString, $v->scalarval());
184
        //PhpXmlRpc\PhpXmlRpc::$xmlrpc_internalencoding = 'ISO-8859-1';
185
    }
186
187
    public function testExoticCharsetsRequests2()
188
    {
189
        // note that we should disable this call also when mbstring is missing server-side
190
        if (!function_exists('mb_convert_encoding')) {
191
            $this->markTestSkipped('Miss mbstring extension to test exotic charsets');
192
            return;
193
        }
194
        $sendString = '安室奈美恵'; // Japanese name "Namie Amuro"
195
        $str = '<?xml version="1.0"?>
196
<methodCall>
197
    <methodName>examples.stringecho</methodName>
198
    <params>
199
        <param>
200
        <value><string>'.$sendString.'</string></value>
201
        </param>
202
    </params>
203
</methodCall>';
204
205
        PhpXmlRpc\PhpXmlRpc::$xmlrpc_internalencoding = 'UTF-8';
206
        // no encoding declaration either in the http header or xml prolog, let mb_detect_encoding
207
        // (used on the server side) sort it out
208
        $this->addQueryParams(array('DETECT_ENCODINGS' => array('EUC-JP', 'UTF-8')));
209
        $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

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

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

324
            /** @scrutinizer ignore-call */ 
325
            $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...
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

324
            $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...
325
            $got = '';
326
            for ($i = 0; $i < $sz; $i++) {
327
                $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

327
                /** @scrutinizer ignore-call */ 
328
                $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

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

374
                $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...
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

374
                /** @scrutinizer ignore-call */ 
375
                $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...
375
                $got .= $b->scalarVal();
376
            }
377
            $this->assertEquals($expected, $got);
378
        }
379
    }
380
381
    protected function _multicall_msg($method, $params)
382
    {
383
        $struct = array();
384
        $struct['methodName'] = new xmlrpcval($method, 'string');
385
        $struct['params'] = new xmlrpcval($params, 'array');
386
387
        return new xmlrpcval($struct, 'struct');
388
    }
389
390
    public function testServerMulticall()
391
    {
392
        // We manually construct a system.multicall() call to ensure
393
        // that the server supports it.
394
395
        // NB: This test will NOT pass if server does not support system.multicall.
396
397
        // Based on http://xmlrpc-c.sourceforge.net/hacks/test_multicall.py
398
        $good1 = $this->_multicall_msg(
399
            'system.methodHelp',
400
            array(php_xmlrpc_encode('system.listMethods')));
401
        $bad = $this->_multicall_msg(
402
            'test.nosuch',
403
            array(php_xmlrpc_encode(1), php_xmlrpc_encode(2)));
404
        $recursive = $this->_multicall_msg(
405
            'system.multicall',
406
            array(new xmlrpcval(array(), 'array')));
407
        $good2 = $this->_multicall_msg(
408
            'system.methodSignature',
409
            array(php_xmlrpc_encode('system.listMethods')));
410
        $arg = new xmlrpcval(
411
            array($good1, $bad, $recursive, $good2),
412
            'array'
413
        );
414
415
        $m = new xmlrpcmsg('system.multicall', array($arg));
416
        $v = $this->send($m);
417
        if ($v) {
418
            //$this->assertEquals(0, $r->faultCode(), "fault from system.multicall");
419
            $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

419
            $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...
420
421
            $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

421
            $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...
422
            $this->assertTrue(
423
                $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

423
                $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...
424
                "did not get array of size 1 from good1"
425
            );
426
427
            $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

427
            $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...
428
            $this->assertEquals('struct', $r2->kindOf(), "no fault from bad");
429
430
            $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

430
            $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...
431
            $this->assertEquals('struct', $r3->kindOf(), "recursive system.multicall did not fail");
432
433
            $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

433
            $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...
434
            $this->assertTrue(
435
                $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

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

685
            $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

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