Test Setup Failed
Pull Request — master (#2)
by Pol
13:44
created

RandomOrgAPI::validateResponse()   C

Complexity

Conditions 7
Paths 7

Size

Total Lines 40
Code Lines 27

Duplication

Lines 8
Ratio 20 %

Code Coverage

Tests 10
CRAP Score 7

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 8
loc 40
ccs 10
cts 10
cp 1
rs 6.7272
cc 7
eloc 27
nc 7
nop 1
crap 7
1
<?php
2
3
namespace drupol\Yaroc;
4
5
use drupol\Yaroc\Plugin\MethodPluginInterface;
6
use Http\Client\HttpClient;
7
use Psr\Http\Message\ResponseInterface;
8
9
/**
10
 * Class RandomOrgAPI.
11
 */
12
class RandomOrgAPI implements RandomOrgAPIInterface
13
{
14
    /**
15
     * The default Random.org endpoint template.
16
     *
17
     * @var string;
18
     */
19
    private $endpoint = 'https://api.random.org/json-rpc/1/invoke';
20
21
    /**
22
     * The configuration.
23
     *
24
     * @var array
25
     */
26
    private $configuration;
27
28
    /**
29
     * The HTTP client.
30
     *
31
     * @var \Http\Client\HttpClient
32
     */
33
    private $httpClient;
34
35
    /**
36
     * RandomOrgAPI constructor.
37
     *
38
     * @param array $configuration
39
     */
40
    public function __construct(array $configuration = [])
41
    {
42
        $this->configuration = $configuration;
43
    }
44
45
    /**
46
     * {@inheritdoc}
47
     */
48
    public function withApiKey(string $apikey)
49
    {
50
        $clone = clone $this;
51
52
        return $clone->setApiKey($apikey);
53
    }
54
55
    /**
56
     * {@inheritdoc}
57
     */
58
    public function withEndPoint(string $endpoint)
59
    {
60
        $clone = clone $this;
61
62
        return $clone->setEndPoint($endpoint);
63
    }
64
65
    /**
66
     * {@inheritdoc}
67
     */
68
    public function withHttpClient(HttpClient $client)
69
    {
70
        $clone = clone $this;
71
72
        return $clone->setHttpClient($client);
73 16
    }
74 16
75 16
    /**
76 16
     * {@inheritdoc}
77 16
     */
78
    public function getEndPoint()
79
    {
80
        return $this->endpoint;
81
    }
82
83
    /**
84
     * {@inheritdoc}
85
     */
86
    public function getApiKey()
87 16
    {
88 16
        $configuration = $this->getConfiguration();
89
90 16
        $configuration += ['apiKey' => ''];
91
92
        return $configuration['apiKey'];
93
    }
94
95
    /**
96
     * {@inheritdoc}
97
     */
98
    public function call(MethodPluginInterface $methodPlugin)
99 13
    {
100 13
        return $this->validateResponse($methodPlugin
101
            ->withEndPoint($this->getEndPoint())
102
            ->withApiKey($this->getApiKey())->call());
103
    }
104
105
    /**
106
     * {@inheritdoc}
107
     */
108
    public function get(MethodPluginInterface $methodPlugin)
109
    {
110
        return json_decode(
111 16
            (string) $this
0 ignored issues
show
Bug introduced by
The method getBody does only exist in Psr\Http\Message\ResponseInterface, but not in Exception.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
112 16
                ->call($methodPlugin)
113 16
                ->getBody()
114
                ->getContents(),
115 16
            true
116
        );
117
    }
118
119
    /**
120
     * {@inheritdoc}
121
     */
122
    public function getData(MethodPluginInterface $methodPlugin)
123 16
    {
124 16
        $data = $this->get($methodPlugin);
125
126
        if (!isset($data['result'])) {
127
            return false;
128
        }
129
130
        if (isset($data['result']['random']) && isset($data['result']['random']['data'])) {
131
            return $data['result']['random']['data'];
132
        }
133
134
        return false;
135 2
    }
136 2
137 2
    /**
138
     * {@inheritdoc}
139 2
     */
140
    public function getConfiguration()
141
    {
142
        return $this->configuration;
143
    }
144
145
    /**
146
     * {@inheritdoc}
147 17
     */
148 17
    public function getHttpClient()
149
    {
150
        return $this->httpClient;
151
    }
152
153
    /**
154
     * @param string $apikey
155
     *
156
     * @return $this
157
     */
158
    private function setApiKey(string $apikey)
159
    {
160
        $configuration = $this->getConfiguration();
161
        $configuration['apiKey'] = $apikey;
162
163 16
        return $this->setConfiguration($configuration);
164
    }
165 16
166 16
    /**
167
     * @param string $endpoint
168
     *
169 16
     * @return $this
170 16
     */
171
    private function setEndPoint(string $endpoint)
172
    {
173
        $this->endpoint = $endpoint;
174 16
175 16
        return $this;
176 16
    }
177
178 16
    /**
179
     * Validate the response.
180
     *
181
     * @param \Psr\Http\Message\ResponseInterface $response
182
     *
183
     * @return \Exception|ResponseInterface
184
     */
185
    private function validateResponse(ResponseInterface $response)
186 16
    {
187 16
        if (200 == $response->getStatusCode()) {
188
            $body = json_decode((string) $response->getBody()->getContents(), true);
189
190
            if (isset($body['error']['code'])) {
191
                switch ($body['error']['code']) {
192 View Code Duplication
                    case -32600:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
193
                        throw new \InvalidArgumentException(
194
                            'Invalid Request: ' . $body['error']['message'],
195
                            $body['error']['code']
196
                        );
197
                    case -32601:
198 13
                        throw new \BadFunctionCallException(
199 13
                            'Procedure not found: ' . $body['error']['message'],
200
                            $body['error']['code']
201 13
                        );
202 View Code Duplication
                    case -32602:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
203
                        throw new \InvalidArgumentException(
204
                            'Invalid arguments: ' . $body['error']['message'],
205
                            $body['error']['code']
206
                        );
207 View Code Duplication
                    case -32603:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
208
                        throw new \RuntimeException(
209 12
                            'Internal Error: ' . $body['error']['message'],
210 12
                            $body['error']['code']
211
                        );
212 View Code Duplication
                    default:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
213
                        throw new \RuntimeException(
214
                            'Invalid request/response: ' . $body['error']['message'],
215
                            $body['error']['code']
216
                        );
217
                }
218
            }
219
        }
220
221 16
        $response->getBody()->rewind();
222 16
223
        return $response;
224 16
    }
225
226
    /**
227
     * @param $configuration
228
     *
229
     * @return $this
230
     */
231
    private function setConfiguration($configuration)
232 13
    {
233 13
        $this->configuration = $configuration;
234
235
        return $this;
236
    }
237
238
    /**
239
     * Set the HTTP client.
240
     *
241
     * @param \Http\Client\HttpClient $client
242
     *
243 13
     * @return \drupol\Yaroc\RandomOrgAPI
244 13
     */
245
    private function setHttpClient(HttpClient $client)
246 13
    {
247
        $this->httpClient = $client;
248
249
        return $this;
250
    }
251
}
252