Completed
Push — master ( b4619a...ab6ee6 )
by Kamil
12:06 queued 06:35
created

iShouldBeNotifiedThatItHasBeenSuccessfullyCreated()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 7
c 0
b 0
f 0
rs 10
cc 1
nc 1
nop 0
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
declare(strict_types=1);
13
14
namespace Sylius\Behat\Context\Api\Admin;
15
16
use ApiPlatform\Core\Api\IriConverterInterface;
17
use Behat\Behat\Context\Context;
18
use Sylius\Behat\Client\ApiClientInterface;
19
use Sylius\Behat\Client\ResponseCheckerInterface;
20
use Sylius\Behat\Service\SharedStorageInterface;
21
use Sylius\Component\Addressing\Model\CountryInterface;
22
use Sylius\Component\Addressing\Model\Province;
23
use Sylius\Component\Addressing\Model\ProvinceInterface;
24
use Symfony\Component\Intl\Countries;
25
use Webmozart\Assert\Assert;
26
27
final class ManagingCountriesContext implements Context
28
{
29
    /** @var ApiClientInterface */
30
    private $client;
31
32
    /** @var ResponseCheckerInterface */
33
    private $responseChecker;
34
35
    /** @var SharedStorageInterface */
36
    private $sharedStorage;
37
38
    /** @var IriConverterInterface */
39
    private $iriConverter;
40
41
    public function __construct(
42
        ApiClientInterface $client,
43
        ResponseCheckerInterface $responseChecker,
44
        SharedStorageInterface $sharedStorage,
45
        IriConverterInterface $iriConverter
46
    ) {
47
        $this->client = $client;
48
        $this->responseChecker = $responseChecker;
49
        $this->sharedStorage = $sharedStorage;
50
        $this->iriConverter = $iriConverter;
51
    }
52
53
    /**
54
     * @When I want to add a new country
55
     */
56
    public function iWantToAddANewCountry(): void
57
    {
58
        $this->client->buildCreateRequest();
59
    }
60
61
    /**
62
     * @When I choose :countryName
63
     */
64
    public function iChoose(string $countryName): void
65
    {
66
        $this->client->addRequestData('code', $this->getCountryCodeByName($countryName));
67
    }
68
69
    /**
70
     * @When I add it
71
     */
72
    public function iAddIt(): void
73
    {
74
        $this->client->create();
75
    }
76
77
    /**
78
     * @When /^I want to edit (this country)$/
79
     * @When /^I want to create a new province in (country "([^"]+)")$/
80
     */
81
    public function iWantToEditThisCountry(CountryInterface $country): void
82
    {
83
        $this->client->buildUpdateRequest($country->getCode());
84
    }
85
86
    /**
87
     * @When I enable it
88
     */
89
    public function iEnableIt(): void
90
    {
91
        $this->client->addRequestData('enabled', true);
0 ignored issues
show
Documentation introduced by
true is of type boolean, but the function expects a string|integer|array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
92
    }
93
94
    /**
95
     * @When I disable it
96
     */
97
    public function iDisableIt(): void
98
    {
99
        $this->client->addRequestData('enabled', false);
0 ignored issues
show
Documentation introduced by
false is of type boolean, but the function expects a string|integer|array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
100
    }
101
102
    /**
103
     * @When I save my changes
104
     * @When I try to save changes
105
     */
106
    public function iSaveMyChanges(): void
107
    {
108
        $this->client->update();
109
    }
110
111
    /**
112
     * @When I name the province :provinceName
113
     */
114
    public function iNameTheProvince(string $provinceName): void
115
    {
116
        $this->client->addSubResourceData(
117
            'provinces',
118
            ['name' => $provinceName]
119
        );
120
    }
121
122
    /**
123
     * @When I specify the province code as :provinceCode
124
     */
125
    public function iSpecifyTheProvinceCodeAs(string $provinceCode): void
126
    {
127
        $this->client->addSubResourceData(
128
            'provinces',
129
            ['code' => $provinceCode]
130
        );
131
    }
132
133
    /**
134
     * @When I add the :provinceName province with :provinceCode code
135
     */
136
    public function iAddTheProvinceWithCode(string $provinceName, string $provinceCode): void
137
    {
138
        $this->client->addSubResourceData(
139
            'provinces',
140
            ['code' => $provinceCode, 'name' => $provinceName]
141
        );
142
    }
143
144
    /**
145
     * @When I add the :name province with :code code and :abbreviation abbreviation
146
     */
147
    public function iAddTheProvinceWithCodeAndAbbreviation(string $name, string $code, string $abbreviation): void
148
    {
149
        $this->client->addSubResourceData(
150
            'provinces',
151
            ['code' => $code, 'name' => $name, 'abbreviation' => $abbreviation]
152
        );
153
    }
154
155
    /**
156
     * @When /^I delete the ("[^"]+" province) of (this country)$/
157
     */
158
    public function iDeleteTheProvinceOfThisCountry(ProvinceInterface $province, CountryInterface $country): void
159
    {
160
        $iri = $this->iriConverter->getItemIriFromResourceClass(Province::class, ['code' => $province->getCode()]);
161
162
        $provinces = $this->responseChecker->getValue($this->client->show($country->getCode()), 'provinces');
163
        foreach ($provinces as $countryProvince) {
164
            if ($iri === $countryProvince) {
165
                $this->client->removeSubResource('provinces', $countryProvince);
166
            }
167
        }
168
    }
169
170
    /**
171
     * @When I do not specify the province code
172
     * @When I do not name the province
173
     */
174
    public function iDoNotSpecifyTheProvinceCode(): void
175
    {
176
        // Intentionally left blank
177
    }
178
179
    /**
180
     * @Then I should be notified that it has been successfully created
181
     */
182
    public function iShouldBeNotifiedThatItHasBeenSuccessfullyCreated(): void
183
    {
184
        Assert::true(
185
            $this->responseChecker->isCreationSuccessful($this->client->getLastResponse()),
186
            'Country could not be created'
187
        );
188
    }
189
190
    /**
191
     * @Then the country :country should appear in the store
192
     */
193
    public function theCountryShouldAppearInTheStore(CountryInterface $country): void
194
    {
195
        Assert::true(
196
            $this->responseChecker->hasItemWithValue($this->client->index(), 'code', $country->getCode()),
197
            sprintf('There is no country with name "%s"', $country->getName())
198
        );
199
    }
200
201
    /**
202
     * @Then the country :country should have the :province province
203
     * @Then /^(this country) should have the ("[^"]*" province)$/
204
     */
205
    public function theCountryShouldHaveTheProvince(CountryInterface $country, ProvinceInterface $province): void
206
    {
207
        Assert::true($this->responseChecker->hasItemWithValue(
208
            $this->client->subResourceIndex('provinces', $country->getCode()),
209
            'code',
210
            $province->getCode()
211
        ));
212
    }
213
214
    /**
215
     * @Then the province should still be named :province in this country
216
     */
217
    public function theProvinceShouldStillBeNamedInThisCountry(ProvinceInterface $province): void
218
    {
219
        /** @var CountryInterface $country */
220
        $country = $this->sharedStorage->get('country');
221
        Assert::true($this->responseChecker->hasItemWithValue(
222
            $this->client->subResourceIndex('provinces', $country->getCode()),
223
            'code',
224
            $province->getCode()
225
        ));
226
    }
227
228
    /**
229
     * @Then I should not be able to choose :countryName
230
     */
231
    public function iShouldNotBeAbleToChoose(string $countryName): void
232
    {
233
        $this->client->addRequestData('code', $this->getCountryCodeByName($countryName));
234
        $response = $this->client->create();
235
        Assert::false(
236
            $this->responseChecker->isCreationSuccessful($response),
237
            'Country has been created successfully, but it should not'
238
        );
239
        Assert::same($this->responseChecker->getError($response), 'code: Country ISO code must be unique.');
240
    }
241
242
    /**
243
     * @Then I should be notified that it has been successfully edited
244
     */
245
    public function iShouldBeNotifiedThatItHasBeenSuccessfullyEdited(): void
246
    {
247
        Assert::true(
248
            $this->responseChecker->isUpdateSuccessful($this->client->getLastResponse()),
249
            'Country could not be edited'
250
        );
251
    }
252
253
    /**
254
     * @Then /^(this country) should be (enabled|disabled)$/
255
     */
256
    public function thisCountryShouldBeDisabled(CountryInterface $country, string $enabled): void
257
    {
258
        Assert::true(
259
            $this->responseChecker->hasValue(
260
                $this->client->show($country->getCode()),
261
                'enabled',
262
                $enabled === 'enabled' ? true : false
0 ignored issues
show
Documentation introduced by
$enabled === 'enabled' ? true : false is of type boolean, but the function expects a string|integer.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
263
            ),
264
            'Country is not disabled'
265
        );
266
    }
267
268
    /**
269
     * @Then I should not be able to edit its code
270
     */
271
    public function theCodeFieldShouldBeDisabled(): void
272
    {
273
        $this->client->updateRequestData(['code' => 'NEW_CODE']);
274
275
        Assert::false($this->responseChecker->hasValue($this->client->update(), 'code', 'NEW_CODE'));
276
    }
277
278
    /**
279
     * @Then /^province with code ("[^"]*") should not be added in (this country)$/
280
     */
281
    public function provinceWithCodeShouldNotBeAddedInThisCountry(string $provinceCode, CountryInterface $country): void
282
    {
283
        /** @var ProvinceInterface $province */
284
        foreach ($this->getProvincesOfCountry($country) as $province) {
285
            Assert::false(
286
                $province->getCode() === $provinceCode,
287
                sprintf('The country "%s" should not have the "%s" province', $country->getName(), $province->getName())
288
            );
289
        }
290
    }
291
292
    /**
293
     * @Then this country should not have the :provinceName province
294
     * @Then province with name :provinceName should not be added in this country
295
     */
296
    public function thisCountryShouldNotHaveTheProvince(string $provinceName): void
297
    {
298
        /** @var CountryInterface $country */
299
        $country = $this->sharedStorage->get('country');
300
        /** @var ProvinceInterface $province */
301
        foreach ($this->getProvincesOfCountry($country) as $province) {
302
            Assert::false(
303
                $province->getName() === $provinceName,
304
                sprintf('The country "%s" should not have the "%s" province', $country->getName(), $province->getName())
305
            );
306
        }
307
    }
308
309
    /**
310
     * @Then I should be notified that province code must be unique
311
     */
312
    public function iShouldBeNotifiedThatProvinceCodeMustBeUnique(): void
313
    {
314
        Assert::same(
315
            $this->responseChecker->getError($this->client->getLastResponse()),
316
            'provinces[1].code: Province code must be unique.'
317
        );
318
    }
319
320
    /**
321
     * @Then I should be notified that :field is required
322
     */
323
    public function iShouldBeNotifiedThatFieldIsRequired(string $field): void
324
    {
325
        Assert::contains(
326
            $this->responseChecker->getError($this->client->getLastResponse()),
327
            \sprintf('Please enter province %s.', $field)
328
        );
329
    }
330
331
    private function getCountryCodeByName(string $countryName): string
332
    {
333
        $countryList = array_flip(Countries::getNames());
334
        Assert::keyExists(
335
            $countryList,
336
            $countryName,
337
            sprintf('The country with name "%s" not found', $countryName)
338
        );
339
340
        return $countryList[$countryName];
341
    }
342
343
    private function getProvincesOfCountry(CountryInterface $country): iterable
344
    {
345
        $response = $this->client->show($country->getCode());
346
        $countryFromResponse = $this->responseChecker->getResponseContent($response);
347
348
        foreach ($countryFromResponse['provinces'] as $provinceFromResponse) {
349
            yield $this->iriConverter->getItemFromIri($provinceFromResponse);
350
        }
351
    }
352
}
353