Passed
Branch issue-4 (9d1220)
by Andrejs
02:08
created

Juggler   A

Complexity

Total Complexity 24

Size/Duplication

Total Lines 238
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 4

Test Coverage

Coverage 80.33%

Importance

Changes 0
Metric Value
dl 0
loc 238
ccs 49
cts 61
cp 0.8033
rs 10
c 0
b 0
f 0
wmc 24
lcom 2
cbo 4

18 Methods

Rating   Name   Duplication   Size   Complexity  
A setUrl() 0 4 1
A getUrl() 0 4 1
A getHost() 0 4 1
A getPort() 0 4 1
A createImposterFromFile() 0 4 1
A postImposterFromFile() 0 4 1
A postImposterContract() 0 6 1
A getHttpImposter() 0 4 1
A getImposter() 0 4 1
A getImposterContract() 0 6 1
A replaceImposter() 0 5 1
A deleteImposter() 0 7 2
A deleteImposters() 0 4 1
A removeProxies() 0 5 1
A saveContract() 0 5 2
A __construct() 0 9 2
A postImposter() 0 9 2
A composeQueryString() 0 7 3
1
<?php
2
3
namespace Meare\Juggler;
4
5
6
use Meare\Juggler\Exception\Mountebank\MountebankException;
7
use Meare\Juggler\HttpClient\GuzzleClient;
8
use Meare\Juggler\HttpClient\IHttpClient;
9
use Meare\Juggler\Imposter\Builder\AbstractImposterBuilder;
10
use Meare\Juggler\Imposter\HttpImposter;
11
use Meare\Juggler\Imposter\Imposter;
12
13
class Juggler
14
{
15
    const PARAM_REPLAYABLE = 'replayable';
16
    const PARAM_REMOVE_PROXIES = 'remove_proxies';
17
    const DEFAULT_PORT = 2525;
18
19
    /**
20
     * @var IHttpClient
21
     */
22
    private $httpClient;
23
24
    /**
25
     * @var AbstractImposterBuilder
26
     */
27
    private $abstractImposterBuilder;
28
29
    /**
30
     * @var string
31
     */
32
    private $host;
33
34
    /**
35
     * @var int
36
     */
37
    private $port;
38
39
    /**
40
     * Full URL to Juggler client
41
     *
42
     * @var string
43
     */
44
    private $url;
45
46
    /**
47
     * @param string      $host
48
     * @param int         $port
49
     * @param IHttpClient $httpClient
50
     */
51 8
    public function __construct($host, $port = self::DEFAULT_PORT, IHttpClient $httpClient = null)
52
    {
53 8
        $this->host = $host;
54 8
        $this->port = $port;
55 8
        $this->setUrl($host, $port);
56 8
        $this->httpClient = isset($httpClient) ? $httpClient : GuzzleClient::create();
57 8
        $this->httpClient->setHost($this->getUrl());
58 8
        $this->abstractImposterBuilder = new AbstractImposterBuilder;
59 8
    }
60
61
    /**
62
     * @param string $host
63
     * @param int    $port
64
     */
65 8
    private function setUrl($host, $port)
66
    {
67 8
        $this->url = 'http://' . $host . ':' . $port;
68 8
    }
69
70
    /**
71
     * @return string
72
     */
73 8
    public function getUrl()
74
    {
75 8
        return $this->url;
76
    }
77
78
    /**
79
     * @return string
80
     */
81 1
    public function getHost()
82
    {
83 1
        return $this->host;
84
    }
85
86
    /**
87
     * @return int
88
     */
89 1
    public function getPort()
90
    {
91 1
        return $this->port;
92
    }
93
94
    /**
95
     * @param string $path
96
     * @return Imposter
97
     */
98 1
    public function createImposterFromFile($path)
99
    {
100 1
        return $this->abstractImposterBuilder->build(file_get_contents($path));
101
    }
102
103
    /**
104
     * @param string $path
105
     * @throws MountebankException
106
     * @throws \RuntimeException if file does not exist
107
     * @return int Imposter port
108
     */
109
    public function postImposterFromFile($path)
110
    {
111
        return $this->postImposterContract(file_get_contents($path));
112
    }
113
114
    /**
115
     * @param string $contract
116
     * @throws MountebankException
117
     * @return int Imposter port
118
     */
119 1
    public function postImposterContract($contract)
120
    {
121 1
        $received_contract = $this->httpClient->post('/imposters', $contract);
122
123 1
        return (int)\GuzzleHttp\json_decode($received_contract, true)['port'];
124
    }
125
126
    /**
127
     * @param int  $port
128
     * @param bool $replayable
129
     * @param bool $remove_proxies
130
     * @return HttpImposter
131
     */
132
    public function getHttpImposter($port, $replayable = false, $remove_proxies = false)
133
    {
134
        return $this->getImposter($port, $replayable, $remove_proxies);
135
    }
136
137
    /**
138
     * Retrieves contract and builds Imposter
139
     *
140
     * @param int  $port
141
     * @param bool $replayable
142
     * @param bool $remove_proxies
143
     * @throws MountebankException
144
     * @return Imposter
145
     */
146 1
    public function getImposter($port, $replayable = false, $remove_proxies = false)
147
    {
148 1
        return $this->abstractImposterBuilder->build($this->getImposterContract($port, $replayable, $remove_proxies));
149
    }
150
151
    /**
152
     * @param int  $port
153
     * @param bool $replayable
154
     * @param bool $remove_proxies
155
     * @throws MountebankException
156
     * @return string
157
     */
158 1
    public function getImposterContract($port, $replayable = false, $remove_proxies = false)
159
    {
160 1
        $query = $this->composeQueryString($replayable, $remove_proxies);
161
162 1
        return $this->httpClient->get("/imposters/$port?$query");
163
    }
164
165
    /**
166
     * @param Imposter $imposter
167
     */
168
    public function replaceImposter(Imposter $imposter)
169
    {
170
        $this->deleteImposter($imposter);
171
        $this->postImposter($imposter);
172
    }
173
174
    /**
175
     * @param int|Imposter $imposter Port or Imposter instance
176
     * @param bool         $replayable
177
     * @param bool         $remove_proxies
178
     *
179
     * @return string Imposter contract
180
     * @throws MountebankException
181
     */
182 3
    public function deleteImposter($imposter, $replayable = false, $remove_proxies = false)
183
    {
184 3
        $query = $this->composeQueryString($replayable, $remove_proxies);
185 3
        $port = $imposter instanceof Imposter ? $imposter->getPort() : $imposter;
186
187 3
        return $this->httpClient->delete("/imposters/$port?$query");
188
    }
189
190
    /**
191
     * @param Imposter $imposter
192
     * @throws MountebankException
193
     * @return int Imposter port
194
     */
195 1
    public function postImposter(Imposter $imposter)
196
    {
197 1
        $port = $this->postImposterContract(json_encode($imposter));
198 1
        if (!$imposter->hasPort()) {
199 1
            $imposter->setPort($port);
200 1
        }
201
202 1
        return $port;
203
    }
204
205
    /**
206
     * @throws MountebankException
207
     */
208 1
    public function deleteImposters()
209
    {
210 1
        $this->httpClient->delete("/imposters");
211 1
    }
212
213
    /**
214
     * @param int $port
215
     * @throws MountebankException
216
     */
217 1
    public function removeProxies($port)
218
    {
219 1
        $query = $this->composeQueryString(false, true);
220 1
        $this->httpClient->get("/imposters/$port?$query");
221 1
    }
222
223
    /**
224
     * Retrieves imposter contract and saves to a local filesystem
225
     *
226
     * @param int|Imposter $imposter
227
     * @param string       $path
228
     */
229
    public function saveContract($imposter, $path)
230
    {
231
        $port = $imposter instanceof Imposter ? $imposter->getPort() : $imposter;
232
        file_put_contents($path, $this->getImposterContract($port));
233
    }
234
235
    /**
236
     * mountebank API only supports string 'true' as boolean param value
237
     *
238
     * @param bool $replayable
239
     * @param bool $remove_proxies
240
     *
241
     * @return string
242
     */
243 5
    private function composeQueryString($replayable, $remove_proxies)
244
    {
245 5
        return http_build_query(array_filter([
246 5
            self::PARAM_REPLAYABLE     => $replayable ? 'true' : null,
247 5
            self::PARAM_REMOVE_PROXIES => $remove_proxies ? 'true' : null,
248 5
        ]));
249
    }
250
}
251