Passed
Push — master ( 17c573...816792 )
by Andrejs
02:29
created

Juggler::deleteImposterIfExists()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 5
nc 2
nop 3
dl 0
loc 8
rs 9.4285
c 0
b 0
f 0
ccs 4
cts 4
cp 1
crap 2
1
<?php
2
3
namespace Meare\Juggler;
4
5
6
use Meare\Juggler\Exception\Mountebank\MountebankException;
7
use Meare\Juggler\Exception\Mountebank\NoSuchResourceException;
8
use Meare\Juggler\HttpClient\GuzzleClient;
9
use Meare\Juggler\HttpClient\IHttpClient;
10
use Meare\Juggler\Imposter\Builder\AbstractImposterBuilder;
11
use Meare\Juggler\Imposter\HttpImposter;
12
use Meare\Juggler\Imposter\Imposter;
13
14
class Juggler
15
{
16
    const PARAM_REPLAYABLE = 'replayable';
17
    const PARAM_REMOVE_PROXIES = 'remove_proxies';
18
    const DEFAULT_PORT = 2525;
19
20
    /**
21
     * @var IHttpClient
22
     */
23
    private $httpClient;
24
25
    /**
26
     * @var AbstractImposterBuilder
27
     */
28
    private $abstractImposterBuilder;
29
30
    /**
31
     * @var string
32
     */
33
    private $host;
34
35
    /**
36
     * @var int
37
     */
38
    private $port;
39
40
    /**
41
     * Full URL to Juggler client
42
     *
43
     * @var string
44
     */
45
    private $url;
46
47
    /**
48
     * @param string      $host
49
     * @param int         $port
50
     * @param IHttpClient $httpClient
51
     */
52 10
    public function __construct(string $host, int $port = self::DEFAULT_PORT, IHttpClient $httpClient = null)
53
    {
54 10
        $this->host = $host;
55 10
        $this->port = $port;
56 10
        $this->setUrl($host, $port);
57 10
        $this->httpClient = $httpClient ?? GuzzleClient::create();
0 ignored issues
show
Documentation Bug introduced by
It seems like $httpClient ?? \Meare\Ju...\GuzzleClient::create() can also be of type object<self>. However, the property $httpClient is declared as type object<Meare\Juggler\HttpClient\IHttpClient>. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
58 10
        $this->httpClient->setHost($this->getUrl());
59 10
        $this->abstractImposterBuilder = new AbstractImposterBuilder;
60 10
    }
61
62
    /**
63
     * @param string $host
64
     * @param int    $port
65
     */
66 10
    private function setUrl(string $host, int $port)
67
    {
68 10
        $this->url = 'http://' . $host . ':' . $port;
69 10
    }
70
71
    /**
72
     * @return string
73
     */
74 10
    public function getUrl() : string
75
    {
76 10
        return $this->url;
77
    }
78
79
    /**
80
     * @return string
81
     */
82 1
    public function getHost() : string
83
    {
84 1
        return $this->host;
85
    }
86
87
    /**
88
     * @return int
89
     */
90 1
    public function getPort() : int
91
    {
92 1
        return $this->port;
93
    }
94
95
    /**
96
     * @param string $path
97
     * @return Imposter
98
     */
99 1
    public function createImposterFromFile(string $path) : Imposter
100
    {
101 1
        return $this->abstractImposterBuilder->build(file_get_contents($path));
102
    }
103
104
    /**
105
     * @param string $path
106
     * @throws MountebankException
107
     * @throws \RuntimeException if file does not exist
108
     * @return int Imposter port
109
     */
110
    public function postImposterFromFile(string $path)
111
    {
112
        return $this->postImposterContract(file_get_contents($path));
113
    }
114
115
    /**
116
     * @param string $contract
117
     * @throws MountebankException
118
     * @return int Imposter port
119
     */
120 1
    public function postImposterContract(string $contract)
121
    {
122 1
        $received_contract = $this->httpClient->post('/imposters', $contract);
123
124 1
        return (int)\GuzzleHttp\json_decode($received_contract, true)['port'];
125
    }
126
127
    /**
128
     * @param int  $port
129
     * @param bool $replayable
130
     * @param bool $remove_proxies
131
     * @return HttpImposter
132
     */
133
    public function getHttpImposter(int $port, bool $replayable = false, bool $remove_proxies = false) : HttpImposter
134
    {
135
        return $this->getImposter($port, $replayable, $remove_proxies);
136
    }
137
138
    /**
139
     * Retrieves contract and builds Imposter
140
     *
141
     * @param int  $port
142
     * @param bool $replayable
143
     * @param bool $remove_proxies
144
     * @throws MountebankException
145
     * @return Imposter
146
     */
147 1
    public function getImposter(int $port, bool $replayable = false, bool $remove_proxies = false) : Imposter
148
    {
149 1
        return $this->abstractImposterBuilder->build($this->getImposterContract($port, $replayable, $remove_proxies));
150
    }
151
152
    /**
153
     * @param int  $port
154
     * @param bool $replayable
155
     * @param bool $remove_proxies
156
     * @throws MountebankException
157
     * @return string
158
     */
159 1
    public function getImposterContract(int $port, bool $replayable = false, bool $remove_proxies = false) : string
160
    {
161 1
        $query = $this->composeQueryString($replayable, $remove_proxies);
162
163 1
        return $this->httpClient->get("/imposters/$port?$query");
164
    }
165
166
    /**
167
     * @param Imposter $imposter
168
     * @return int Imposter port
169
     */
170
    public function replaceImposter(Imposter $imposter)
171
    {
172
        $this->deleteImposter($imposter);
173
        return $this->postImposter($imposter);
174
    }
175
176
    /**
177
     * @param int|Imposter $imposter Port or Imposter instance
178
     * @param bool         $replayable
179
     * @param bool         $remove_proxies
180
     *
181
     * @return string Imposter contract
182
     * @throws MountebankException
183
     */
184 5
    public function deleteImposter($imposter, bool $replayable = false, bool $remove_proxies = false)
185
    {
186 5
        $query = $this->composeQueryString($replayable, $remove_proxies);
187 5
        $port = $imposter instanceof Imposter ? $imposter->getPort() : $imposter;
188
189 5
        return $this->httpClient->delete("/imposters/$port?$query");
190
    }
191
192
    /**
193
     * @param int|Imposter $imposter
194
     * @param bool         $replayable
195
     * @param bool         $remove_proxies
196
     * @return string|null Imposter contract or null if there was no requested imposter
197
     */
198 2
    public function deleteImposterIfExists($imposter, bool $replayable = false, bool $remove_proxies = false)
199
    {
200
        try {
201 2
            return $this->deleteImposter($imposter, $replayable, $remove_proxies);
202 1
        } catch (NoSuchResourceException $e) {
203 1
            return null;
204
        }
205
    }
206
207
    /**
208
     * @param Imposter $imposter
209
     * @throws MountebankException
210
     * @return int Imposter port
211
     */
212 1
    public function postImposter(Imposter $imposter) : int
213
    {
214 1
        $port = $this->postImposterContract(json_encode($imposter));
215 1
        if (!$imposter->hasPort()) {
216 1
            $imposter->setPort($port);
217
        }
218
219 1
        return $port;
220
    }
221
222
    /**
223
     * @throws MountebankException
224
     */
225 1
    public function deleteImposters()
226
    {
227 1
        $this->httpClient->delete("/imposters");
228 1
    }
229
230
    /**
231
     * @param int $port
232
     * @throws MountebankException
233
     */
234 1
    public function removeProxies(int $port)
235
    {
236 1
        $query = $this->composeQueryString(false, true);
237 1
        $this->httpClient->get("/imposters/$port?$query");
238 1
    }
239
240
    /**
241
     * Retrieves imposter contract and saves to a local filesystem
242
     *
243
     * @param int|Imposter $imposter
244
     * @param string       $path
245
     */
246
    public function saveContract($imposter, string $path)
247
    {
248
        $port = $imposter instanceof Imposter ? $imposter->getPort() : $imposter;
249
        file_put_contents($path, $this->getImposterContract($port));
250
    }
251
252
    /**
253
     * mountebank API only supports string 'true' as boolean param value
254
     *
255
     * @param bool $replayable
256
     * @param bool $remove_proxies
257
     *
258
     * @return string
259
     */
260 7
    private function composeQueryString(bool $replayable, bool $remove_proxies) : string
261
    {
262 7
        return http_build_query(array_filter([
263 7
            self::PARAM_REPLAYABLE     => $replayable ? 'true' : null,
264 7
            self::PARAM_REMOVE_PROXIES => $remove_proxies ? 'true' : null,
265
        ]));
266
    }
267
}
268