Completed
Push — master ( ab6ee6...8da333 )
by Kamil
32:30 queued 09:03
created

ManagingZonesContext::itsScopeShouldBe()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 7
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
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\ProvinceInterface;
23
use Sylius\Component\Addressing\Model\ZoneInterface;
24
use Sylius\Component\Addressing\Model\ZoneMember;
25
use Sylius\Component\Addressing\Model\ZoneMemberInterface;
26
use Webmozart\Assert\Assert;
27
28
final class ManagingZonesContext implements Context
29
{
30
    /** @var ApiClientInterface */
31
    private $client;
32
33
    /** @var ResponseCheckerInterface */
34
    private $responseChecker;
35
36
    /** @var SharedStorageInterface */
37
    private $sharedStorage;
38
39
    /** @var IriConverterInterface */
40
    private $iriConverter;
41
42
    public function __construct(
43
        ApiClientInterface $client,
44
        ResponseCheckerInterface $responseChecker,
45
        SharedStorageInterface $sharedStorage,
46
        IriConverterInterface $iriConverter
47
    ) {
48
        $this->client = $client;
49
        $this->responseChecker = $responseChecker;
50
        $this->sharedStorage = $sharedStorage;
51
        $this->iriConverter = $iriConverter;
52
    }
53
54
    /**
55
     * @When I want to create a new zone consisting of :memberType
56
     */
57
    public function iWantToCreateANewZoneConsistingOfCountry(string $memberType): void
58
    {
59
        $this->client->buildCreateRequest();
60
        $this->client->addRequestData('type', $memberType);
61
    }
62
63
    /**
64
     * @When I name it :name
65
     * @When I rename it to :name
66
     */
67
    public function iNameIt(string $name): void
68
    {
69
        $this->client->addRequestData('name', $name);
70
    }
71
72
    /**
73
     * @When I specify its code as :code
74
     */
75
    public function iSpecifyItsCodeAs(string $code): void
76
    {
77
        $this->client->addRequestData('code', $code);
78
    }
79
80
    /**
81
     * @When I do not specify its :type
82
     * @When I do not add a country member
83
     */
84
    public function iDoNotSpecifyItsField(): void
85
    {
86
        // Intentionally left blank
87
    }
88
89
    /**
90
     * @When I add a country :country
91
     */
92
    public function iAddACountry(CountryInterface $country): void
93
    {
94
        $this->client->addSubResourceData('members', [
95
            'code' => $country->getCode(),
96
        ]);
97
    }
98
99
    /**
100
     * @When I add a province :province
101
     */
102
    public function iAddAProvince(ProvinceInterface $province): void
103
    {
104
        $this->client->addSubResourceData('members', [
105
            'code' => $province->getCode(),
106
        ]);
107
    }
108
109
    /**
110
     * @When I add a zone :zone
111
     */
112
    public function iAddAZone(ZoneInterface $zone): void
113
    {
114
        $this->client->addSubResourceData('members', [
115
            'code' => $zone->getCode(),
116
        ]);
117
    }
118
119
    /**
120
     * @When I select its scope as :scope
121
     */
122
    public function iSelectItsScopeAs(string $scope): void
123
    {
124
        $this->client->addRequestData('scope', $scope);
125
    }
126
127
    /**
128
     * @When I add it
129
     * @When I try to add it
130
     */
131
    public function iAddIt(): void
132
    {
133
        $this->client->create();
134
    }
135
136
    /**
137
     * @When I want to see all zones in store
138
     * @When I browse zones
139
     */
140
    public function iWantToSeeAllZonesInStore(): void
141
    {
142
        $this->client->index();
143
    }
144
145
    /**
146
     * @When I delete zone named :zone
147
     */
148
    public function iDeleteZoneNamed(ZoneInterface $zone): void
149
    {
150
        $this->client->delete($zone->getCode());
151
    }
152
153
    /**
154
     * @When I check the :zone zone
155
     * @When I check also the :zone zone
156
     */
157
    public function iCheckTheZone(ZoneInterface $zone): void
158
    {
159
        $ZoneToDelete = [];
0 ignored issues
show
Coding Style introduced by
$ZoneToDelete does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

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...
160
        if ($this->sharedStorage->has('zone_to_delete')) {
161
            $ZoneToDelete = $this->sharedStorage->get('zone_to_delete');
0 ignored issues
show
Coding Style introduced by
$ZoneToDelete does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

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...
162
        }
163
        $ZoneToDelete[] = $zone->getCode();
0 ignored issues
show
Coding Style introduced by
$ZoneToDelete does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

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...
164
        $this->sharedStorage->set('zone_to_delete', $ZoneToDelete);
0 ignored issues
show
Coding Style introduced by
$ZoneToDelete does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

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...
165
    }
166
167
    /**
168
     * @When I delete them
169
     */
170
    public function iDeleteThem(): void
171
    {
172
        foreach ($this->sharedStorage->get('zone_to_delete') as $code) {
173
            $this->client->delete($code);
174
        }
175
    }
176
177
    /**
178
     * @When I want to modify the zone named :zone
179
     */
180
    public function iWantToModifyTheZoneNamed(ZoneInterface $zone): void
181
    {
182
        $this->client->buildUpdateRequest($zone->getCode());
183
    }
184
185
    /**
186
     * @When I remove the :country country member
187
     */
188
    public function iRemoveTheCountryMember(CountryInterface $country): void
189
    {
190
        $this->removeZoneMember($country);
191
    }
192
193
    /**
194
     * @When I remove the :province province member
195
     */
196
    public function iRemoveTheProvinceMember(ProvinceInterface $province): void
197
    {
198
        $this->removeZoneMember($province);
199
    }
200
201
    /**
202
     * @When I remove the :zone zone member
203
     */
204
    public function iRemoveTheZoneMember(ZoneInterface $zone): void
205
    {
206
        $this->removeZoneMember($zone);
207
    }
208
209
    /**
210
     * @When I save my changes
211
     */
212
    public function iSaveMyChanges(): void
213
    {
214
        $this->client->update();
215
    }
216
217
    /**
218
     * @Then the zone named :zone with the :country country member should appear in the registry
219
     */
220
    public function theZoneNamedWithTheCountryMemberShouldAppearInTheRegistry(
221
        ZoneInterface $zone,
222
        CountryInterface $country
223
    ): void {
224
        Assert::true($this->responseChecker->hasItemWithValue(
225
            $this->client->subResourceIndex('members', $zone->getCode()),
226
            'code',
227
            $country->getCode()
228
        ));
229
    }
230
231
    /**
232
     * @Then I should not be able to edit its code
233
     */
234
    public function iShouldNotBeAbleToEditItsCode(): void
235
    {
236
        $this->client->addRequestData('code', 'NEW_CODE');
237
238
        Assert::false(
239
            $this->responseChecker->hasValue($this->client->update(), 'code', 'NEW_CODE'),
240
            'The code field with value NEW_CODE exists'
241
        );
242
    }
243
244
    /**
245
     * @Then I can not add a zone :zone
246
     */
247
    public function iCanNotAddAZone(ZoneInterface $zone): void
248
    {
249
        $this->client->addSubResourceData('members', [
250
            'code' => $zone->getCode(),
251
        ]);
252
253
        Assert::contains(
254
            $this->responseChecker->getError($this->client->update()),
255
            'members: Zone member cannot be the same as a zone.'
256
        );
257
    }
258
259
    /**
260
     * @Then the zone named :zone with the :province province member should appear in the registry
261
     */
262
    public function theZoneNamedWithTheProvinceMemberShouldAppearInTheRegistry(
263
        ZoneInterface $zone,
264
        ProvinceInterface $province
265
    ): void {
266
        Assert::true($this->responseChecker->hasItemWithValue(
267
            $this->client->subResourceIndex('members', $zone->getCode()),
268
            'code',
269
            $province->getCode()
270
        ));
271
    }
272
273
    /**
274
     * @Then the zone named :zone with the :otherZone zone member should appear in the registry
275
     */
276
    public function theZoneNamedWithTheZoneMemberShouldAppearInTheRegistry(
277
        ZoneInterface $zone,
278
        ZoneInterface $otherZone
279
    ): void {
280
        Assert::true($this->responseChecker->hasItemWithValue(
281
            $this->client->subResourceIndex('members', $zone->getCode()),
282
            'code',
283
            $otherZone->getCode()
284
        ));
285
    }
286
287
    /**
288
     * @Then its scope should be :scope
289
     */
290
    public function itsScopeShouldBe(string $scope): void
291
    {
292
        Assert::true(
293
            $this->responseChecker->hasValue($this->client->show('EU'), 'scope', $scope),
294
            sprintf('Its Zone does not have %s scope', $scope)
295
        );
296
    }
297
298
    /**
299
     * @Then I should see :count zones in the list
300
     * @Then I should see a single zone in the list
301
     */
302
    public function iShouldSeeZonesInTheList(int $count = 1): void
303
    {
304
        Assert::same($this->responseChecker->countCollectionItems($this->client->index()), $count);
305
    }
306
307
    /**
308
     * @Then I should see the zone named :name in the list
309
     * @Then I should still see the zone named :name in the list
310
     */
311
    public function iShouldSeeTheZoneNamedInTheList(string $name): void
312
    {
313
        Assert::true(
314
            $this->responseChecker->hasItemWithValue($this->client->index(), 'name', $name),
315
            sprintf('There is no zone with name "%s"', $name)
316
        );
317
    }
318
319
    /**
320
     * @Then there should still be only one zone with code :code
321
     */
322
    public function thereShouldStillBeOnlyOneZoneWithCode(string $code): void
323
    {
324
        Assert::count(
325
            $this->responseChecker->getCollectionItemsWithValue($this->client->index(), 'code', $code),
326
            1,
327
            sprintf('There should be only one zone with code "%s"', $code)
328
        );
329
    }
330
331
    /**
332
     * @Then the zone named :name should no longer exist in the registry
333
     */
334
    public function theZoneNamedShouldNoLongerExistInTheRegistry(string $name): void
335
    {
336
        Assert::false(
337
            $this->responseChecker->hasItemWithValue($this->client->index(), 'name', $name),
338
            sprintf('Zone with name %s exists', $name)
339
        );
340
    }
341
342
    /**
343
     * @Then /^zone with (code|name) "([^"]*)" should not be added$/
344
     */
345
    public function zoneShouldNotBeAdded(string $field, string $value): void
346
    {
347
        Assert::false(
348
            $this->responseChecker->hasItemWithValue($this->client->index(), $field, $value),
349
            sprintf('Zone with %s %s exists', $field, $value)
350
        );
351
    }
352
353
    /**
354
     * @Then /^(this zone) should have only (the "([^"]*)" (?:country|province|zone) member)$/
355
     */
356
    public function thisZoneShouldHaveOnlyTheProvinceMember(ZoneInterface $zone, ZoneMemberInterface $zoneMember): void
357
    {
358
        Assert::true($this->responseChecker->hasItemWithValue(
359
            $this->client->subResourceIndex('members', $zone->getCode()),
360
            'code',
361
            $zoneMember->getCode()
362
        ));
363
364
        Assert::same(
365
            $this->responseChecker->countCollectionItems($this->client->subResourceIndex('members', $zone->getCode())),
366
            1
367
        );
368
    }
369
370
    /**
371
     * @Then /^(this zone) name should be "([^"]*)"$/
372
     */
373
    public function thisZoneNameShouldBe(ZoneInterface $zone, string $name): void
374
    {
375
        Assert::true(
376
            $this->responseChecker->hasValue($this->client->show($zone->getCode()), 'name', $name),
377
            sprintf('Its Zone does not have name %s.', $name)
378
        );
379
    }
380
381
    /**
382
     * @Then I should be notified that it has been successfully created
383
     */
384
    public function iShouldBeNotifiedThatItHasBeenSuccessfullyCreated(): void
385
    {
386
        Assert::true(
387
            $this->responseChecker->isCreationSuccessful($this->client->getLastResponse()),
388
            'Zone could not be created'
389
        );
390
    }
391
392
    /**
393
     * @Then I should be notified that it has been successfully edited
394
     */
395
    public function iShouldBeNotifiedThatItHasBeenSuccessfullyEdited(): void
396
    {
397
        Assert::true(
398
            $this->responseChecker->isUpdateSuccessful($this->client->getLastResponse()),
399
            'Zone could not be edited'
400
        );
401
    }
402
403
    /**
404
     * @Then I should be notified that it has been successfully deleted
405
     * @Then I should be notified that they have been successfully deleted
406
     */
407
    public function iShouldBeNotifiedThatItHasBeenSuccessfullyDeleted(): void
408
    {
409
        Assert::true($this->responseChecker->isDeletionSuccessful(
410
            $this->client->getLastResponse()),
411
            'Zone could not be deleted'
412
        );
413
    }
414
415
    /**
416
     * @Then I should be notified that this zone cannot be deleted
417
     */
418
    public function iShouldBeNotifiedThatThisZoneCannotBeDeleted(): void
419
    {
420
        Assert::false(
421
            $this->responseChecker->isDeletionSuccessful($this->client->getLastResponse()),
422
            'Zone can be deleted, but it should not'
423
        );
424
    }
425
426
    /**
427
     * @Then I should be notified that zone with this code already exists
428
     */
429
    public function iShouldBeNotifiedThatZoneWithThisCodeAlreadyExists(): void
430
    {
431
        Assert::contains(
432
            $this->responseChecker->getError($this->client->getLastResponse()),
433
            'code: Zone code must be unique.'
434
        );
435
    }
436
437
    /**
438
     * @Then /^I should be notified that (code|name) is required$/
439
     */
440
    public function iShouldBeNotifiedThatIsRequired(string $element): void
441
    {
442
        Assert::contains(
443
            $this->responseChecker->getError($this->client->getLastResponse()),
444
            sprintf('Please enter zone %s.', $element)
445
        );
446
    }
447
448
    /**
449
     * @Then I should be notified that at least one zone member is required
450
     */
451
    public function iShouldBeNotifiedThatAtLeastOneZoneMemberIsRequired(): void
452
    {
453
        Assert::contains(
454
            $this->responseChecker->getError($this->client->getLastResponse()),
455
            'members: Please add at least 1 zone member.'
456
        );
457
    }
458
459
    /**
460
     * @param CountryInterface|ZoneInterface|ProvinceInterface $objectToRemove
461
     */
462
    private function removeZoneMember($objectToRemove): void
463
    {
464
        $iri = $this->iriConverter->getItemIriFromResourceClass(ZoneMember::class, ['code' => $objectToRemove->getCode()]);
465
466
        $this->client->removeSubResource('members', $iri);
467
    }
468
}
469