Test Failed
Pull Request — master (#11)
by Pavel
07:46
created

JsonRpcControllerTest::createJsonRequest()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 2
1
<?php
2
3
namespace Bankiru\Api\JsonRpc\Tests;
4
5
use Bankiru\Api\JsonRpc\Controller\JsonRpcController;
6
use Bankiru\Api\JsonRpc\Http\JsonRpcHttpResponse;
7
use Bankiru\Api\JsonRpc\Specification\JsonRpcResponse;
8
use Bankiru\Api\Rpc\Event\FilterControllerEvent;
9
use Bankiru\Api\Rpc\Event\FilterResponseEvent;
10
use Bankiru\Api\Rpc\Event\FinishRequestEvent;
11
use Bankiru\Api\Rpc\Event\GetExceptionResponseEvent;
12
use Bankiru\Api\Rpc\Event\GetResponseEvent;
13
use Bankiru\Api\Rpc\Routing\ControllerResolver\ControllerResolverInterface;
14
use Bankiru\Api\Rpc\RpcEvents;
15
use PHPUnit\Framework\TestCase;
16
use Prophecy\Argument;
17
use ScayTrase\Api\JsonRpc\JsonRpcError;
18
use ScayTrase\Api\JsonRpc\JsonRpcRequestInterface;
19
use ScayTrase\Api\Rpc\RpcRequestInterface;
20
use Symfony\Component\DependencyInjection\ContainerInterface;
21
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
22
use Symfony\Component\HttpFoundation\Request;
23
use Symfony\Component\HttpKernel\KernelInterface;
24
25
final class JsonRpcControllerTest extends TestCase
26
{
27
    public function getInvalidJsonRequests()
28
    {
29
        return [
30
            'empty'        => [null],
31
            'string'       => ['test'],
32
            'invalid_json' => [substr(json_encode(['test']), 2)],
33
        ];
34
    }
35
36
    /**
37
     * @dataProvider getInvalidJsonRequests
38
     * @expectedException \Symfony\Component\HttpKernel\Exception\BadRequestHttpException
39
     *
40
     * @param $content
41
     */
42
    public function testInvalidJsonHandling($content)
43
    {
44
        $controller = $this->createController();
45
46
        $request = $this->createJsonRequest('/', $content);
47
        $controller->jsonRpcAction($request);
48
    }
49
50
    public function getInvalidJsonRpcRequests()
51
    {
52
        return [
53
            'invalid version' => [['jsonrpc' => '1.0']],
54
            'no method'       => [['jsonrpc' => '2.0']],
55
            'no version'      => [['method' => 'test']],
56
        ];
57
    }
58
59
    /**
60
     * @dataProvider getInvalidJsonRpcRequests
61
     * @expectedException \Bankiru\Api\JsonRpc\Exception\InvalidRequestException
62
     *
63
     * @param $content
64
     */
65
    public function testInvalidJsonRpcHandling($content)
66
    {
67
        $controller = $this->createController();
68
69
        $request = $this->createJsonRequest('/', $content);
70
        $controller->jsonRpcAction($request);
71
    }
72
73
    public function getValidResponseAndRequests()
74
    {
75
        return [
76
            'empty batch' => [[], '[]'],
77
            'single'      => [
78
                [
79
                    'jsonrpc' => '2.0',
80
                    'id'      => 'test',
81
                    'method'  => 'test',
82
                ],
83
                '{"jsonrpc":"2.0","id":"test","result":{"success":true}}',
84
            ],
85
            'batch'       => [
86
                [
87
                    [
88
                        'jsonrpc' => '2.0',
89
                        'id'      => 'test',
90
                        'method'  => 'test',
91
                    ],
92
                ],
93
                '[{"jsonrpc":"2.0","id":"test","result":{"success":true}}]',
94
            ],
95
        ];
96
    }
97
98
    /**
99
     * @dataProvider getValidResponseAndRequests
100
     *
101
     * @param array  $content
102
     * @param string $responseBody
103
     */
104
    public function testValidRequestHandling($content, $responseBody)
105
    {
106
        $controller = $this->createController();
107
        $request    = $this->createJsonRequest(
108
            '/',
109
            $content
110
        );
111
        $response   = $controller->jsonRpcAction($request);
112
113
        self::assertInstanceOf(JsonRpcHttpResponse::class, $response);
114
        self::assertTrue($response->isSuccessful());
115
        self::assertEquals($responseBody, $response->getContent());
116
    }
117
118
    public function testExceptionHandling()
119
    {
120
        $controller = $this->createController();
121
        $request    = $this->createJsonRequest(
122
            '/',
123
            [
124
                'jsonrpc' => '2.0',
125
                'id'      => 'test',
126
                'method'  => 'exception',
127
            ]
128
        );
129
        $response   = $controller->jsonRpcAction($request);
130
131
        self::assertTrue($response->isSuccessful());
132
        self::assertEquals(
133
            '{"jsonrpc":"2.0","id":"test","error":{"code":-32603,"message":"Failure!","data":null}}',
134
            $response->getContent()
135
        );
136
    }
137
138
    public function testExceptionHandlingAmongBatchRequest()
139
    {
140
        $controller = $this->createController();
141
        $request    = $this->createJsonRequest(
142
            '/',
143
            [
144
                [
145
                    'jsonrpc' => '2.0',
146
                    'id'      => 'test1',
147
                    'method'  => 'test',
148
                ],
149
                [
150
                    'jsonrpc' => '2.0',
151
                    'id'      => 'test2',
152
                    'method'  => 'exception',
153
                ],
154
            ]
155
        );
156
        $response   = $controller->jsonRpcAction($request);
157
158
        self::assertTrue($response->isSuccessful());
159
        self::assertEquals(
160
            '[{"jsonrpc":"2.0","id":"test1","result":{"success":true}},{"jsonrpc":"2.0","id":"test2","error":{"code":-32603,"message":"Failure!","data":null}}]',
161
            $response->getContent()
162
        );
163
    }
164
165
    /**
166
     * @param string $uri
167
     * @param mixed  $content
168
     *
169
     * @return Request
170
     */
171
    private function createJsonRequest($uri, $content)
172
    {
173
        return Request::create($uri, 'POST', [], [], [], [], json_encode($content));
174
    }
175
176
    private function getContainerMock()
177
    {
178
        $mock     = $this->prophesize(ContainerInterface::class);
179
        $kernel   = $this->prophesize(KernelInterface::class);
180
        $resolver = $this->prophesize(ControllerResolverInterface::class);
181
        $resolver->getController(Argument::type(RpcRequestInterface::class))->willReturn(
182
            function (JsonRpcRequestInterface $request) {
183
                if ($request->getMethod() === 'exception') {
184
                    throw new \LogicException('Failure!');
185
                }
186
187
                return new JsonRpcResponse($request->getId(), (object)['success' => true]);
188
            }
189
        );
190
        $resolver->getArguments(Argument::type(RpcRequestInterface::class), Argument::any())->will(
191
            function (array $args) {
192
                return [
193
                    $args[0],
194
                ];
195
            }
196
        );
197
198
        $evm = $this->prophesize(EventDispatcherInterface::class);
199
        $evm->dispatch(Argument::exact(RpcEvents::EXCEPTION), Argument::type(GetExceptionResponseEvent::class))
200
            ->will(
201
                function ($args) {
202
                    /** @var GetExceptionResponseEvent $event */
203
                    $event = $args[1];
204
205
                    /** @var JsonRpcRequestInterface $request */
206
                    $request = $event->getRequest();
207
208
                    $event->setResponse(
209
                        new JsonRpcResponse(
210
                            $request->getId(),
211
                            null, new JsonRpcError(
212
                                JsonRpcError::INTERNAL_ERROR,
213
                                $event->getException()->getMessage()
214
                            )
215
                        )
216
                    );
217
                }
218
            );
219
        $evm->dispatch(Argument::exact(RpcEvents::FINISH_REQUEST), Argument::type(FinishRequestEvent::class))
220
            ->willReturn(null);
221
        $evm->dispatch(Argument::exact(RpcEvents::CONTROLLER), Argument::type(FilterControllerEvent::class))
222
            ->willReturn(null);
223
        $evm->dispatch(Argument::exact(RpcEvents::REQUEST), Argument::type(GetResponseEvent::class))->willReturn(null);
224
        $evm->dispatch(Argument::exact(RpcEvents::RESPONSE), Argument::type(FilterResponseEvent::class))
225
            ->willReturn(null);
226
227
        $mock->get(Argument::exact('jsonrpc_server.controller_resolver'))->willReturn($resolver->reveal());
228
        $mock->get(Argument::exact('event_dispatcher'))->willReturn($evm->reveal());
229
        $mock->get(Argument::exact('kernel'))->willReturn($kernel->reveal());
230
231
        return $mock->reveal();
232
    }
233
234
    private function createController()
235
    {
236
        $controller = new JsonRpcController();
237
        $controller->setContainer($this->getContainerMock());
238
239
        return $controller;
240
    }
241
}
242