ServerTest   F
last analyzed

Complexity

Total Complexity 116

Size/Duplication

Total Lines 1010
Duplicated Lines 0 %

Importance

Changes 2
Bugs 1 Features 0
Metric Value
eloc 529
c 2
b 1
f 0
dl 0
loc 1010
rs 2
wmc 116

49 Methods

Rating   Name   Duplication   Size   Complexity  
A _fail() 0 15 5
A _multicall_msg() 0 7 1
A validateResponse() 0 2 1
A addQueryParams() 0 6 1
A testUnknownMethod() 0 4 1
A testInvalidNumber() 0 10 2
A testServerMulticall() 0 47 4
A testAddingDoubles() 0 12 2
A send() 0 21 5
A testClientMulticall2() 0 38 5
A testExoticCharsetsRequests() 0 30 3
A testExoticCharsetsRequests2() 0 25 2
A testClientMulticall3() 0 39 4
A testCountEntities() 0 16 3
A testString() 0 24 3
A testLatin1String() 0 10 2
A testExoticCharsetsRequests3() 0 24 2
A testBase64() 0 20 3
A testBoolean() 0 25 4
A testAdding() 0 9 2
A set_up() 0 19 3
A testUtf8Method() 0 10 2
A testClientMulticall1() 0 42 5
A testClientMulticall4() 0 29 2
A testCatchErrors() 0 17 2
A testNullParams() 0 22 3
A testWrappedMethod() 0 13 2
A testServerWrappedClosure() 0 7 1
A testZeroParams() 0 4 1
A testWrapInexistentUrl() 0 6 1
A testServerWrappedClassWithNamespace() 0 7 1
A testWrappedMethodAsSource() 0 15 2
A testSetCookies() 0 30 5
A testTransferOfObjectViaWrapping() 0 12 2
A testWrappedClass() 0 18 3
B testGetCookies() 0 41 9
A testCatchExceptions() 0 19 1
A testServerWrappedObjectMethodsAsSource() 0 19 1
A testWrapInexistentMethod() 0 5 1
A testServerWrappedFunctionAsSource() 0 13 1
A testServerWrappedFunction() 0 21 1
A testCatchWarnings() 0 9 2
A testNegativeDebug() 0 17 1
A testServerComments() 0 7 1
A testSendTwiceSameMsg() 0 9 3
A testServerWrappedObjectMethods() 0 37 1
A testCodeInjectionServerSide() 0 7 2
A testServerClosure() 0 7 1
A testServerWrappedClass() 0 7 1

How to fix   Complexity   

Complex Class

Complex classes like ServerTest often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use ServerTest, and based on these observations, apply Extract Interface, too.

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
23
    /**
24
     * @todo instead of overriding fail via _fail, implement Yoast\PHPUnitPolyfills\TestListeners\TestListenerDefaultImplementation
25
     */
26
    public static function _fail($message = '')
27
    {
28
        // save in a static var that this particular test has failed
29
        // (but only if not called from subclass objects / multitests)
30
        if (function_exists('debug_backtrace') && strtolower(get_called_class()) == 'localhosttests') {
31
            $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
32
            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...
33
                if (strpos($trace[$i]['function'], 'test') === 0) {
34
                    self::$failed_tests[$trace[$i]['function']] = true;
35
                    break;
36
                }
37
            }
38
        }
39
40
        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

40
        parent::/** @scrutinizer ignore-call */ 
41
                _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...
41
    }
42
43
    public function set_up()
44
    {
45
        parent::set_up();
46
47
        $server = explode(':', $this->args['HTTPSERVER']);
48
        if (count($server) > 1) {
49
            $this->client = new xmlrpc_client($this->args['HTTPURI'], $server[0], $server[1]);
0 ignored issues
show
Bug introduced by
$server[1] of type string is incompatible with the type integer expected by parameter $port of xmlrpc_client::__construct(). ( Ignorable by Annotation )

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

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

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

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

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

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

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

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

322
            /** @scrutinizer ignore-call */ 
323
            $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...
323
            $got = '';
324
            for ($i = 0; $i < $sz; $i++) {
325
                $b = $v->arraymem($i);
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

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

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

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

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

417
            $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...
418
419
            $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

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

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

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

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

431
            $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...
432
            $this->assertTrue(
433
                $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

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

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

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