Completed
Pull Request — master (#15)
by Pavel
05:22
created

JsonRpcClientTest   C

Complexity

Total Complexity 10

Size/Duplication

Total Lines 177
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 20

Test Coverage

Coverage 91.45%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
dl 0
loc 177
c 1
b 0
f 0
wmc 10
lcom 1
cbo 20
ccs 107
cts 117
cp 0.9145
rs 6.4705

9 Methods

Rating   Name   Duplication   Size   Complexity  
A paramsProvider() 0 10 1
A testSingleRequestFormatting() 0 5 1
B getProphetClient() 0 36 2
A testBatchRequestFormatting() 0 5 1
A testSingleSuccessfulRequest() 0 16 1
A testSingleFailedRequest() 0 17 1
A testSingleNotification() 0 13 1
B testMultipleMixedRequests() 0 42 1
A testFailedCall() 0 8 1
1
<?php
2
3
namespace ScayTrase\Api\JsonRpc\Tests;
4
5
use GuzzleHttp\Client;
6
use GuzzleHttp\ClientInterface;
7
use GuzzleHttp\Exception\ConnectException;
8
use GuzzleHttp\HandlerStack;
9
use GuzzleHttp\Promise\Promise;
10
use GuzzleHttp\Psr7\Request;
11
use GuzzleHttp\Psr7\Response;
12
use GuzzleHttp\Psr7\Uri;
13
use Prophecy\Argument;
14
use Psr\Http\Message\RequestInterface;
15
use ScayTrase\Api\JsonRpc\JsonRpcClient;
16
use ScayTrase\Api\JsonRpc\JsonRpcError;
17
use ScayTrase\Api\JsonRpc\JsonRpcErrorInterface;
18
use ScayTrase\Api\JsonRpc\JsonRpcNotification;
19
use ScayTrase\Api\JsonRpc\JsonRpcRequest;
20
use ScayTrase\Api\JsonRpc\JsonRpcResponseInterface;
21
use ScayTrase\Api\Rpc\RpcErrorInterface;
22
23
class JsonRpcClientTest extends AbstractJsonRpcClientTest
24
{
25
    public function paramsProvider()
26
    {
27
        return [
28
            'Null' => [null],
29
            'Empty array' => [[]],
30
            'Scalar' => [5], // This really shoud be an exception
31
            'Named Params' => [(object)['test' => 'test']],
32
            'Positional params' => [['test']],
33
        ];
34
    }
35
36
    /**
37
     * @dataProvider paramsProvider
38
     * @param $params
39
     */
40 5
    public function testSingleRequestFormatting($params)
41
    {
42 5
        $client = $this->getProphetClient($params, false);
43 5
        $client->invoke(new JsonRpcRequest('test', $params, 'test'));
44 5
    }
45
46
    /**
47
     * @param mixed $params
48
     * @param bool $isArray
49
     * @return JsonRpcClient
50
     */
51 10
    private function getProphetClient($params, $isArray)
52 1
    {
53 10
        $guzzle = $this->prophesize(ClientInterface::class);
54 10
        $self = $this;
55 10
        $guzzle->sendAsync(Argument::type(RequestInterface::class))->will(
56
            function ($args) use ($self, $params, $isArray) {
57
                /** @var RequestInterface $request */
58 10
                $request = $args[0];
59 10
                $content = $request->getBody()->getContents();
60 10
                $data = json_decode($content);
61 10
                if ($isArray) {
62 5
                    $self::assertTrue(is_array($data));
63 5
                    $self::assertNotEmpty($data);
64 5
                    $data = array_shift($data);
65 5
                }
66 10
                $self::assertEquals(JSON_ERROR_NONE, json_last_error());
67 10
                $self::assertObjectHasAttribute('id', $data);
68 10
                $self::assertObjectHasAttribute('method', $data);
69 10
                $self::assertObjectHasAttribute('params', $data);
70 10
                $self::assertObjectHasAttribute('jsonrpc', $data);
71 10
                $self::assertEquals('test', $data->id);
72 10
                $self::assertEquals('2.0', $data->jsonrpc);
73 10
                $self::assertEquals('test', $data->method);
74 10
                $self::assertEquals($params, $data->params);
75
76 10
                return new Promise(
77
                    function () {
78 10
                    },
79
                    function () {
80
                    }
81 10
                );
82
            }
83 10
        );
84
85 10
        return new JsonRpcClient($guzzle->reveal(), new Uri('http://localhost/'));
86 1
    }
87
88
    /**
89
     * @dataProvider paramsProvider
90
     * @param $params
91
     */
92 5
    public function testBatchRequestFormatting($params)
93
    {
94 5
        $client = $this->getProphetClient($params, true);
95 5
        $client->invoke([new JsonRpcRequest('test', $params, 'test')]);
96 5
    }
97
98 1
    public function testSingleSuccessfulRequest()
99
    {
100 1
        $client = new JsonRpcClient($this->getClient(), new Uri('http://localhost/'));
101
102 1
        $request = $this->createRequestForSingleInvocation('/test', ['parameter' => 'test'], ['foo' => 'bar']);
103 1
        $collection = $client->invoke([$request]);
104
105
        /** @var JsonRpcResponseInterface $response */
106 1
        $response = $collection->getResponse($request);
107 1
        self::assertTrue($response->isSuccessful());
108 1
        self::assertNotNull($response->getBody());
109 1
        self::assertEquals($client::VERSION, $response->getVersion());
110 1
        self::assertNull($response->getError());
111 1
        self::assertObjectHasAttribute('foo', $response->getBody());
112 1
        self::assertEquals('bar', $response->getBody()->foo);
113 1
    }
114
115 2
    public function testSingleFailedRequest()
116
    {
117 2
        $client = new JsonRpcClient($this->getClient(), new Uri('http://localhost/'));
118
119 1
        $request = $this->createRequestForSingleInvocation('/test', ['parameter' => 'test'], new JsonRpcError(JsonRpcErrorInterface::INTERNAL_ERROR, 'Test error'));
120 1
        $collection = $client->invoke([$request]);
121
122
        /** @var JsonRpcResponseInterface $response */
123 1
        $response = $collection->getResponse($request);
124 1
        self::assertFalse($response->isSuccessful());
125 1
        self::assertNull($response->getBody());
126 1
        self::assertNotNull($response->getError());
127 1
        self::assertEquals($client::VERSION, $response->getVersion());
128 1
        self::assertInstanceOf(RpcErrorInterface::class, $response->getError());
129 1
        self::assertEquals(JsonRpcErrorInterface::INTERNAL_ERROR, $response->getError()->getCode());
130 1
        self::assertEquals('Test error', $response->getError()->getMessage());
131 1
    }
132
133 1
    public function testSingleNotification()
134
    {
135 1
        $client = new JsonRpcClient($this->getClient(), new Uri('http://localhost/'));
136
137 1
        $notification = $this->createNotificationForSingleInvocation('/test-notify', ['parameter' => 'test']);
138 1
        $collection = $client->invoke([$notification]);
139
140 1
        $response = $collection->getResponse($notification);
141 1
        self::assertTrue($response->isSuccessful());
142 1
        self::assertNull($response->getBody());
143 1
        self::assertNull($response->getError());
144 1
        self::assertEquals($client::VERSION, $response->getVersion());
145 1
    }
146
147 1
    public function testMultipleMixedRequests()
148 1
    {
149 1
        $handler = HandlerStack::create($this->getQueue());
150 1
        $this->client = new Client(['handler' => $handler]);
151
152 1
        $client = new JsonRpcClient($this->getClient(), new Uri('http://localhost/'));
153
154 1
        $request = new JsonRpcRequest('/test-request', [], $this->getRandomHash());
155 1
        $notification = new JsonRpcNotification('/test-notify', []);
156 1
        $error = new JsonRpcRequest('/test-error', [], $this->getRandomHash());
157
158 1
        $this->getQueue()->append(new Response(200, [], json_encode(
159
            [
160 1
                ['jsonrpc' => '2.0', 'id' => $request->getId(), 'result' => ['success' => true]],
161 1
                ['jsonrpc' => '2.0', 'id' => $error->getId(), 'error' => ['code' => JsonRpcErrorInterface::INTERNAL_ERROR, 'message' => 'Test error']],
162
            ]
163 1
        )));
164
165 1
        $calls = [$request, $notification, $error];
166 1
        $collection = $client->invoke($calls);
167
168 1
        $rResponse = $collection->getResponse($request);
169 1
        $nResponse = $collection->getResponse($notification);
170 1
        $eResponse = $collection->getResponse($error);
171
172 1
        self::assertNotNull($rResponse);
173 1
        self::assertInstanceOf(JsonRpcResponseInterface::class, $rResponse);
174 1
        self::assertTrue($rResponse->isSuccessful());
175 1
        self::assertObjectHasAttribute('success', $rResponse->getBody());
176 1
        self::assertTrue($rResponse->getBody()->success);
177
178 1
        self::assertNotNull($nResponse);
179 1
        self::assertInstanceOf(JsonRpcResponseInterface::class, $nResponse);
180 1
        self::assertTrue($nResponse->isSuccessful());
181
182 1
        self::assertNotNull($eResponse);
183 1
        self::assertInstanceOf(JsonRpcResponseInterface::class, $eResponse);
184 1
        self::assertFalse($eResponse->isSuccessful());
185 1
        self::assertInstanceOf(JsonRpcErrorInterface::class, $eResponse->getError());
186 1
        self::assertEquals('Test error', $eResponse->getError()->getMessage());
187 1
        self::assertEquals(JsonRpcErrorInterface::INTERNAL_ERROR, $eResponse->getError()->getCode());
188 1
    }
189
190
    /** @expectedException \GuzzleHttp\Exception\GuzzleException */
191 1
    public function testFailedCall()
192
    {
193 1
        $client = new JsonRpcClient($this->getClient(), new Uri('http://localhost/'));
194
195 1
        $request = $this->createRequestForSingleInvocation('/test-notify', ['parameter' => 'test'], new ConnectException('Connection failed', new Request('POST', 'test')));
196
197 1
        $client->invoke([$request])->getResponse($request);
198
    }
199
}
200