Completed
Push — api ( cecea0...116a36 )
by Kamil
29:57 queued 30s
created

theExchangeRateWithRatioBetweenAndShouldAppearInTheStore()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 15
c 0
b 0
f 0
rs 9.7666
cc 1
nc 1
nop 3
1
<?php
2
3
/*
4
 * This file is part of the Sylius package.
5
 *
6
 * (c) Paweł Jędrzejewski
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Sylius\Behat\Context\Api\Admin;
13
14
use Behat\Behat\Context\Context;
15
use Sylius\Behat\Client\ApiClientInterface;
16
use Sylius\Behat\Service\SharedStorageInterface;
17
use Sylius\Component\Currency\Model\CurrencyInterface;
18
use Sylius\Component\Currency\Model\ExchangeRateInterface;
19
use Webmozart\Assert\Assert;
20
21
final class ManagingExchangeRatesContext implements Context
22
{
23
    /** @var ApiClientInterface */
24
    private $client;
25
26
    /** @var SharedStorageInterface */
27
    private $sharedStorage;
28
29
    public function __construct(
30
        ApiClientInterface $client,
31
        SharedStorageInterface $sharedStorage
32
    ) {
33
        $this->client = $client;
34
        $this->sharedStorage = $sharedStorage;
35
    }
36
37
    /**
38
     * @When I want to add a new exchange rate
39
     */
40
    public function iWantToAddNewExchangeRate(): void
41
    {
42
        $this->client->buildCreateRequest('exchange_rates');
43
    }
44
45
    /**
46
     * @When /^I want to edit (this exchange rate)$/
47
     * @Given /^I am editing (this exchange rate)$/
48
     */
49
    public function iWantToEditThisExchangeRate(ExchangeRateInterface $exchangeRate): void
50
    {
51
        $this->client->buildUpdateRequest('exchange_rates', $exchangeRate->getId());
52
53
        $this->sharedStorage->set('exchange_rate_id', $exchangeRate->getId());
54
    }
55
56
    /**
57
     * @Given I am browsing exchange rates of the store
58
     * @When I browse exchange rates
59
     * @When I browse exchange rates of the store
60
     */
61
    public function iBrowseExchangeRatesOfTheStore(): void
62
    {
63
        $this->client->index('exchange_rates');
64
    }
65
66
    /**
67
     * @When I specify its ratio as :ratio
68
     * @When I don't specify its ratio
69
     */
70
    public function iSpecifyItsRatioAs(?string $ratio = null): void
71
    {
72
        if ($ratio !== null) {
73
            $this->client->addRequestData('ratio', $ratio);
74
        }
75
    }
76
77
    /**
78
     * @When I choose :currencyCode as the source currency
79
     */
80
    public function iChooseAsTheSourceCurrency(string $currencyCode): void
81
    {
82
        $this->client->addRequestData('sourceCurrency', '/new-api/currencies/' . $currencyCode);
83
    }
84
85
    /**
86
     * @When I choose :currencyCode as the target currency
87
     */
88
    public function iChooseAsTheTargetCurrency(string $currencyCode): void
89
    {
90
        $this->client->addRequestData('targetCurrency', '/new-api/currencies/' . $currencyCode);
91
    }
92
93
    /**
94
     * @When I (try to) add it
95
     */
96
    public function iAddIt(): void
97
    {
98
        $this->client->create();
99
    }
100
101
    /**
102
     * @When I change ratio to :ratio
103
     */
104
    public function iChangeRatioTo(string $ratio): void
105
    {
106
        $this->client->updateRequestData(['ratio' => $ratio]);
107
    }
108
109
    /**
110
     * @When I save my changes
111
     */
112
    public function iSaveMyChanges(): void
113
    {
114
        $this->client->update();
115
    }
116
117
    /**
118
     * @When /^I delete the (exchange rate between "[^"]+" and "[^"]+")$/
119
     */
120
    public function iDeleteTheExchangeRateBetweenAnd(ExchangeRateInterface $exchangeRate) : void
121
    {
122
        $this->client->delete('exchange_rates', $exchangeRate->getId());
123
    }
124
125
    /**
126
     * @When I choose :currency as a currency filter
127
     */
128
    public function iChooseCurrencyAsACurrencyFilter(CurrencyInterface $currency): void
129
    {
130
        $this->client->buildFilter(['currencyCode' => $currency->getCode()]);
131
    }
132
133
    /**
134
     * @When I filter
135
     */
136
    public function iFilter(): void
137
    {
138
        $this->client->filter('exchange_rates');
139
    }
140
141
    /**
142
     * @Then I should see :count exchange rates on the list
143
     */
144
    public function iShouldSeeExchangeRatesOnTheList(int $count): void
145
    {
146
        Assert::count($this->client->getCollectionItems(), $count);
147
    }
148
149
    /**
150
     * @Then I should see a single exchange rate in the list
151
     * @Then I should( still) see one exchange rate on the list
152
     */
153
    public function iShouldSeeASingleExchangeRateInTheList(): void
154
    {
155
        $this->client->index('exchange_rates');
156
        Assert::count($this->client->getCollectionItems(), 1);
157
    }
158
159
    /**
160
     * @Then the exchange rate with ratio :ratio between :sourceCurrency and :targetCurrency should appear in the store
161
     */
162
    public function theExchangeRateWithRatioBetweenAndShouldAppearInTheStore(
163
        float $ratio,
164
        CurrencyInterface $sourceCurrency,
165
        CurrencyInterface $targetCurrency
166
    ): void {
167
        Assert::true(
168
            $this->responseHasExchangeRate($ratio, $sourceCurrency, $targetCurrency),
169
            sprintf(
170
                'Exchange rate with ratio %s between %s and %s does not exist',
171
                $ratio,
172
                $sourceCurrency->getName(),
173
                $targetCurrency->getName()
174
            )
175
        );
176
    }
177
178
    /**
179
     * @Then I should see the exchange rate between :sourceCurrency and :targetCurrency in the list
180
     * @Then I should (also) see an exchange rate between :sourceCurrency and :targetCurrency on the list
181
     */
182
    public function iShouldSeeTheExchangeRateBetweenAndInTheList(
183
        CurrencyInterface $sourceCurrency,
184
        CurrencyInterface $targetCurrency
185
    ): void {
186
        Assert::notNull(
187
            $this->getExchangeRateFromResponse($sourceCurrency, $targetCurrency),
188
            sprintf('Exchange rate for %s and %s currencies does not exist', $sourceCurrency, $targetCurrency)
189
        );
190
    }
191
192
    /**
193
     * @Then it should have a ratio of :ratio
194
     */
195
    public function itShouldHaveARatioOf(float $ratio): void
196
    {
197
        $this->client->index('exchange_rates');
198
199
        Assert::true(
200
            $this->client->hasItemWithValue('ratio', $ratio),
201
            sprintf('ExchangeRate with ratio %s does not exist', $ratio)
202
        );
203
    }
204
205
    /**
206
     * @Then /^(this exchange rate) should no longer be on the list$/
207
     */
208
    public function thisExchangeRateShouldNoLongerBeOnTheList(ExchangeRateInterface $exchangeRate): void
209
    {
210
        Assert::false(
211
            $this->responseHasExchangeRate(
212
                $exchangeRate->getRatio(),
213
                $exchangeRate->getSourceCurrency(),
214
                $exchangeRate->getTargetCurrency()
215
            ),
216
            sprintf(
217
                'Exchange rate with ratio %s between %s and %s still exists, but it should not.',
218
                $exchangeRate->getRatio(),
219
                $exchangeRate->getSourceCurrency()->getName(),
220
                $exchangeRate->getTargetCurrency()->getName()
221
            )
222
        );
223
    }
224
225
    /**
226
     * @Then the exchange rate between :sourceCurrency and :targetCurrency should not be added
227
     */
228
    public function theExchangeRateBetweenAndShouldNotBeAdded(
229
        CurrencyInterface $sourceCurrency,
230
        CurrencyInterface $targetCurrency
231
    ): void {
232
        $this->client->index('exchange_rates');
233
234
        Assert::null($this->getExchangeRateFromResponse($sourceCurrency, $targetCurrency));
235
    }
236
237
    /**
238
     * @Then /^(this exchange rate) should have a ratio of ([0-9\.]+)$/
239
     */
240
    public function thisExchangeRateShouldHaveARatioOf(ExchangeRateInterface $exchangeRate, float $ratio): void
241
    {
242
        $exchangeRate = $this->getExchangeRateFromResponse(
243
            $exchangeRate->getSourceCurrency(),
244
            $exchangeRate->getTargetCurrency()
245
        );
246
247
        Assert::same($exchangeRate['ratio'], $ratio);
248
    }
249
250
    /**
251
     * @Then I should not be able to edit its source currency
252
     */
253
    public function iShouldNotBeAbleToEditItsSourceCurrency(): void
254
    {
255
        $this->assertIfNotBeAbleToEditItCurrency('sourceCurrency');
256
    }
257
258
    /**
259
     * @Then I should not be able to edit its target currency
260
     */
261
    public function iShouldNotBeAbleToEditItsTargetCurrency(): void
262
    {
263
        $this->assertIfNotBeAbleToEditItCurrency('targetCurrency');
264
    }
265
266
    /**
267
     * @Then I should be notified that :element is required
268
     */
269
    public function iShouldBeNotifiedThatIsRequired(string $element): void
270
    {
271
        Assert::contains($this->client->getError(), sprintf('%s: Please enter exchange rate %s.', $element, $element));
272
    }
273
274
    /**
275
     * @Then I should be notified that the ratio must be greater than zero
276
     */
277
    public function iShouldBeNotifiedThatRatioMustBeGreaterThanZero(): void
278
    {
279
        Assert::contains($this->client->getError(), 'The ratio must be greater than 0.');
280
    }
281
282
    /**
283
     * @Then I should be notified that source and target currencies must differ
284
     */
285
    public function iShouldBeNotifiedThatSourceAndTargetCurrenciesMustDiffer(): void
286
    {
287
        Assert::contains($this->client->getError(), 'The source and target currencies must differ.');
288
    }
289
290
    /**
291
     * @Then I should be notified that the currency pair must be unique
292
     */
293
    public function iShouldBeNotifiedThatTheCurrencyPairMustBeUnique(): void
294
    {
295
        Assert::contains($this->client->getError(), 'The currency pair must be unique.');
296
    }
297
298
    private function assertIfNotBeAbleToEditItCurrency(string $currencyType): void
299
    {
300
        $this->client->buildUpdateRequest('exchange_rates', $this->sharedStorage->get('exchange_rate_id'));
301
302
        $this->client->addRequestData($currencyType, '/new-api/currencies/EUR');
303
        $this->client->update();
304
305
        $this->client->index('exchange_rates');
306
        Assert::false(
307
            $this->client->hasItemOnPositionWithValue(0, $currencyType, '/new-api/currencies/EUR'),
308
            sprintf('It was possible to change %s', $currencyType)
309
        );
310
    }
311
312
    private function getExchangeRateFromResponse(
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
313
        CurrencyInterface $sourceCurrency,
314
        CurrencyInterface $targetCurrency
315
    ): ?array {
316
        $this->client->index('exchange_rates');
317
318
        /** @var array $item */
319
        foreach ($this->client->getCollectionItems() as $item)
320
        {
321
            if (
322
                $item['sourceCurrency'] === '/new-api/currencies/' . $sourceCurrency->getCode() &&
323
                $item['targetCurrency'] === '/new-api/currencies/' . $targetCurrency->getCode()
324
            ) {
325
                return $item;
326
            }
327
        }
328
329
        return null;
330
    }
331
332
    private function responseHasExchangeRate(
0 ignored issues
show
Coding Style introduced by
function responseHasExchangeRate() does not seem to conform to the naming convention (^(?:is|has|should|may|supports)).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
333
        float $ratio,
334
        CurrencyInterface $sourceCurrency,
335
        CurrencyInterface $targetCurrency
336
    ): bool {
337
        return $this->getExchangeRateFromResponse($sourceCurrency, $targetCurrency)['ratio'] === $ratio;
338
    }
339
}
340