Passed
Pull Request — master (#2)
by thomas
02:16
created

Client::processResponse()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 5
ccs 4
cts 4
cp 1
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 3
nc 1
nop 2
crap 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace BitWasp\Trezor\Bridge;
6
7
use BitWasp\Trezor\Bridge\Exception\InvalidMessageException;
8
use BitWasp\Trezor\Bridge\Exception\SchemaValidationException;
9
use BitWasp\Trezor\Bridge\Message\Device;
10
use BitWasp\Trezor\Bridge\Message\ListDevicesResponse;
11
use BitWasp\Trezor\Bridge\Message\VersionResponse;
12
use BitWasp\Trezor\Bridge\Schema\ValidatorFactory;
13
use BitWasp\Trezor\Bridge\Http\HttpClient;
14
use BitWasp\Trezor\Device\Message;
15
use Psr\Http\Message\ResponseInterface;
16
17
class Client
18
{
19
    /**
20
     * @var HttpClient
21
     */
22
    private $client;
23
24
    /**
25
     * @var ValidatorFactory
26
     */
27
    private $validation;
28
29
    /**
30
     * TrezorClient constructor.
31
     * @param HttpClient $client
32
     */
33 5
    public function __construct(HttpClient $client)
34
    {
35 5
        $this->client = $client;
36 5
        $this->validation = new ValidatorFactory();
37 5
    }
38
39
    /**
40
     * @param string $uri
41
     * @return Client
42
     */
43
    public static function fromUri(string $uri)
44
    {
45
        return new self(HttpClient::forUri($uri));
46
    }
47
48
    /**
49
     * @param \Psr\Http\Message\StreamInterface $body
50
     * @return mixed
51
     */
52 5
    protected function parseResponse(\Psr\Http\Message\StreamInterface $body)
53
    {
54 5
        $data = json_decode($body->getContents());
55 5
        if (json_last_error() !== JSON_ERROR_NONE) {
56 1
            throw new InvalidMessageException("Invalid JSON received in response");
57
        }
58 4
        return $data;
59
    }
60
61
    /**
62
     * @param \stdClass $data
63
     * @param \stdClass $schema
64
     */
65 4
    protected function validateSchema($data, \stdClass $schema)
66
    {
67 4
        $validator = new \JsonSchema\Validator;
68 4
        $validator->coerce($data, $schema);
69 4
        if ($validator->isValid()) {
70 2
            return;
71
        }
72
73 2
        throw new SchemaValidationException($validator->getErrors());
74
    }
75
76
    /**
77
     * @param ResponseInterface $response - Response message
78
     * @param \stdClass $schema - JSON schema to validate against
79
     * @return mixed
80
     */
81 5
    protected function processResponse(ResponseInterface $response, \stdClass $schema)
82
    {
83 5
        $result = $this->parseResponse($response->getBody());
84 4
        $this->validateSchema($result, $schema);
85 2
        return $result;
86
    }
87
88
    /**
89
     * @return VersionResponse
90
     */
91 3
    public function bridgeVersion(): VersionResponse
92
    {
93 3
        $result = $this->processResponse(
94 3
            $this->client->bridgeVersion(),
95 3
            $this->validation->versionResponse()
96
        );
97
98 1
        return new VersionResponse($result);
99
    }
100
101
    /**
102
     * @return ListDevicesResponse
103
     */
104 2
    public function listDevices(): ListDevicesResponse
105
    {
106 2
        $result = $this->processResponse(
107 2
            $this->client->listDevices(),
108 2
            $this->validation->listDevicesResponse()
109
        );
110
111 1
        $devices = [];
112 1
        foreach ($result as $device) {
113 1
            $devices[] = new Device($device);
114
        }
115
116 1
        return new ListDevicesResponse($devices);
117
    }
118
119
    public function listen(Device ...$devices)
120
    {
121
        return $this->parseResponse($this->client->listen(...$devices)->getBody());
122
    }
123
124
    /**
125
     * @param Device $device
126
     * @return Session
127
     */
128
    public function acquire(Device $device): Session
129
    {
130
        $result = $this->processResponse(
131
            $this->client->acquire($device),
132
            $this->validation->acquireResponse()
133
        );
134
135
        return new Session($this, $device, $result->session);
136
    }
137
138
    public function release(string $sessionId): bool
139
    {
140
        $this->processResponse(
141
            $this->client->release($sessionId),
142
            $this->validation->releaseResponse()
143
        );
144
145
        return true;
146
    }
147
148
    public function call(string $sessionId, Message $message): Message
149
    {
150
        return $this->client->call($sessionId, $message);
151
    }
152
}
153