Skip to content

Commit

Permalink
[Account][API] Edititng customer profile with validation
Browse files Browse the repository at this point in the history
  • Loading branch information
AdamKasp committed Sep 23, 2020
1 parent 34c4668 commit 5109de8
Show file tree
Hide file tree
Showing 10 changed files with 279 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,39 +10,39 @@ Feature: Customer profile validation
And there is a customer "Francis Underwood" identified by an email "francis@underwood.com" and a password "whitehouse"
And I am logged in as "francis@underwood.com"

@ui
@ui @api
Scenario: Trying to remove my first name
When I want to modify my profile
And I remove the first name
And I try to save my changes
Then I should be notified that the first name is required
And my name should still be "Francis Underwood"

@ui
@ui @api
Scenario: Trying to remove my last name
When I want to modify my profile
And I remove the last name
And I try to save my changes
Then I should be notified that the last name is required
And my name should still be "Francis Underwood"

@ui
@ui @api
Scenario: Trying to remove my email
When I want to modify my profile
And I remove the customer email
And I try to save my changes
Then I should be notified that the email is required
And my email should still be "francis@underwood.com"

@ui
@ui @api
Scenario: Trying to change my email to an existing value
When I want to modify my profile
And I specify the customer email as "claire@underwood.com"
And I try to save my changes
Then I should be notified that the email is already used
And my email should still be "francis@underwood.com"

@ui
@ui @api
Scenario: Trying to change my email to an invalid value
When I want to modify my profile
And I specify the customer email as "francisunderwood"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Feature: Editing a customer profile
And there is a customer "Francis Underwood" identified by an email "francis@underwood.com" and a password "whitehouse"
And I am logged in as "francis@underwood.com"

@ui
@ui @api
Scenario: Changing my first name and last name
When I want to modify my profile
And I specify the first name as "Will"
Expand All @@ -18,7 +18,7 @@ Feature: Editing a customer profile
Then I should be notified that it has been successfully edited
And my name should be "Will Conway"

@ui
@ui @api
Scenario: Changing my email
When I want to modify my profile
And I specify the customer email as "frank@underwood.com"
Expand Down
195 changes: 195 additions & 0 deletions src/Sylius/Behat/Context/Api/Shop/AccountContext.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
<?php

/*
* This file is part of the Sylius package.
*
* (c) Paweł Jędrzejewski
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace Sylius\Behat\Context\Api\Shop;

use Behat\Behat\Context\Context;
use Sylius\Behat\Client\ApiClientInterface;
use Sylius\Behat\Client\ResponseCheckerInterface;
use Sylius\Behat\Service\SharedStorageInterface;
use Sylius\Component\Core\Model\ShopUserInterface;
use Symfony\Component\HttpFoundation\Response;
use Webmozart\Assert\Assert;

final class AccountContext implements Context
{
/** @var ApiClientInterface */
private $accountClient;

/** @var SharedStorageInterface */
private $sharedStorage;

/** @var ResponseCheckerInterface */
private $responseChecker;

public function __construct(
ApiClientInterface $accountClient,
SharedStorageInterface $sharedStorage,
ResponseCheckerInterface $responseChecker
) {
$this->accountClient = $accountClient;
$this->sharedStorage = $sharedStorage;
$this->responseChecker = $responseChecker;
}

/**
* @When I want to modify my profile
*/
public function iWantToModifyMyProfile(): void
{
/** @var ShopUserInterface $shopUser */
$shopUser = $this->sharedStorage->get('user');
$customer = $shopUser->getCustomer();

$this->accountClient->buildUpdateRequest((string) $customer->getId());
}

/**
* @When I specify the first name as :firstName
* @When I remove the first name
*/
public function iSpecifyTheFirstName(string $firstName = ''): void
{
$this->accountClient->addRequestData('firstName', $firstName);
}

/**
* @When I specify the last name as :lastName
* @When I remove the last name
*/
public function iSpecifyTheLastName(string $lastName = ''): void
{
$this->accountClient->addRequestData('lastName', $lastName);
}

/**
* @When I specify the customer email as :email
* @When I remove the customer email
*/
public function iSpecifyCustomerTheEmail(string $email = ''): void
{
$this->accountClient->addRequestData('email', $email);
}

/**
* @When I save my changes
* @When I try to save my changes
*/
public function iSaveMyChanges(): void
{
$this->accountClient->update();
}

/**
* @Then I should be notified that it has been successfully edited
*/
public function iShouldBeNotifiedThatItHasBeenSuccessfullyEdited(): void
{
Assert::true($this->responseChecker->isUpdateSuccessful($this->accountClient->getLastResponse()));
}

/**
* @Then my email should be :email
* @Then my email should still be :email
*/
public function myEmailShouldBe(string $email): void
{
/** @var ShopUserInterface $shopUser */
$shopUser = $this->sharedStorage->get('user');

$response = $this->accountClient->show((string) $shopUser->getCustomer()->getId());

Assert::true($this->responseChecker->hasValue($response, 'email', $email));
}

/**
* @Then my name should be :name
* @Then my name should still be :name
*/
public function myNameShouldBe(string $name): void
{
/** @var ShopUserInterface $shopUser */
$shopUser = $this->sharedStorage->get('user');

$response = $this->accountClient->show((string) $shopUser->getCustomer()->getId());

Assert::true($this->responseChecker->hasValue($response, 'fullName', $name));
}

/**
* @Then I should be notified that the first name is required
*/
public function iShouldBeNotifiedThatFirstNameIsRequired(): void
{
$this->isViolationWithMessageInResponse(
$this->accountClient->getLastResponse(),
'First name must be at least 2 characters long.'
);
}

/**
* @Then I should be notified that the last name is required
*/
public function iShouldBeNotifiedThatLastNameIsRequired(): void
{
$this->isViolationWithMessageInResponse(
$this->accountClient->getLastResponse(),
'Last name must be at least 2 characters long.'
);
}

/**
* @Then I should be notified that the email is required
*/
public function iShouldBeNotifiedThatEmailIsRequired(): void
{
$this->isViolationWithMessageInResponse(
$this->accountClient->getLastResponse(),
'Please enter your email.'
);
}

/**
* @Then I should be notified that the email is already used
*/
public function iShouldBeNotifiedThatTheEmailIsAlreadyUsed(): void
{
$this->isViolationWithMessageInResponse(
$this->accountClient->getLastResponse(),
'This email is already used.'
);
}

/**
* @Then I should be notified that the email is invalid
*/
public function iShouldBeNotifiedThatElementIsInvalid(): void
{
$this->isViolationWithMessageInResponse(
$this->accountClient->getLastResponse(),
'This email is invalid.'
);
}

private function isViolationWithMessageInResponse(Response $response, string $message): bool
{
$violations = $this->responseChecker->getResponseContent($response)['violations'];
foreach ($violations as $violation) {
if ($violation['message'] === $message) {
return true;
}
}

return false;
}
}
6 changes: 4 additions & 2 deletions src/Sylius/Behat/Context/Setup/ShopSecurityContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,19 +49,21 @@ public function __construct(
/**
* @Given I am logged in as :email
*/
public function iAmLoggedInAs($email)
public function iAmLoggedInAs(string $email): void
{
$user = $this->userRepository->findOneByEmail($email);
Assert::notNull($user);

$this->securityService->logIn($user);

$this->sharedStorage->set('user', $user);
}

/**
* @Given I am a logged in customer
* @Given the customer logged in
*/
public function iAmLoggedInCustomer()
public function iAmLoggedInCustomer(): void
{
$user = $this->userFactory->create(['email' => 'sylius@example.com', 'password' => 'sylius', 'enabled' => true]);
$this->userRepository->add($user);
Expand Down
5 changes: 5 additions & 0 deletions src/Sylius/Behat/Resources/config/services/api.xml
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,11 @@
<argument>admin</argument>
</service>

<service id="sylius.behat.api_platform_client.shop.account" class="Sylius\Behat\Client\ApiPlatformClient" parent="sylius.behat.api_platform_client">
<argument>customers</argument>
<argument>shop</argument>
</service>

<service id="Sylius\Behat\Client\ResponseCheckerInterface" class="Sylius\Behat\Client\ResponseChecker">
<argument type="service" id="test.client" />
</service>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,5 +70,11 @@
<argument type="service" id="sylius.admin_to_shop_iri_converter" />
<argument type="service" id="sylius.behat.shared_storage" />
</service>

<service id="sylius.behat.context.api.shop.account" class="Sylius\Behat\Context\Api\Shop\AccountContext">
<argument type="service" id="sylius.behat.api_platform_client.shop.account" />
<argument type="service" id="sylius.behat.shared_storage" />
<argument type="service" id="Sylius\Behat\Client\ResponseCheckerInterface" />
</service>
</services>
</container>
1 change: 1 addition & 0 deletions src/Sylius/Behat/Resources/config/suites.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
# (c) Paweł Jędrzejewski

imports:
- suites/api/account/customer.yml
- suites/api/account/customer_registration.yml
- suites/api/account/login.yml
- suites/api/addressing/managing_countries.yml
Expand Down
23 changes: 23 additions & 0 deletions src/Sylius/Behat/Resources/config/suites/api/account/customer.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# This file is part of the Sylius package.
# (c) Paweł Jędrzejewski

default:
suites:
api_customer_account:
contexts:
- sylius.behat.context.hook.doctrine_orm

- sylius.behat.context.transform.country
- sylius.behat.context.transform.customer
- sylius.behat.context.transform.user

- sylius.behat.context.setup.currency
- sylius.behat.context.setup.customer
- sylius.behat.context.setup.shop_security
- sylius.behat.context.setup.user
- sylius.behat.context.setup.channel

- sylius.behat.context.api.shop.account

filters:
tags: "@customer_account && @api"
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@
xsi:schemaLocation="https://api-platform.com/schema/metadata https://api-platform.com/schema/metadata/metadata-2.0.xsd"
>
<resource class="%sylius.model.customer.class%" shortName="Customer">
<attribute name="route_prefix">admin</attribute>

<attribute name="validation_groups">sylius</attribute>

<attribute name="normalization_context">
<attribute name="groups">
Expand All @@ -29,13 +30,33 @@
<itemOperations>
<itemOperation name="admin_get">
<attribute name="method">GET</attribute>
<attribute name="path">/admin/customers/{id}</attribute>
<attribute name="groups">
<attribute>customer:read</attribute>
</attribute>
</itemOperation>

<itemOperation name="shop_get">
<attribute name="method">GET</attribute>
<attribute name="path">/shop/customers/{id}</attribute>
<attribute name="groups">
<attribute>customer:read</attribute>
</attribute>
</itemOperation>

<itemOperation name="shop_put">
<attribute name="method">PUT</attribute>
<attribute name="path">/shop/customers/{id}</attribute>
<attribute name="denormalization_context">
<attribute name="groups">customer:update</attribute>
</attribute>
</itemOperation>
</itemOperations>

<property name="id" identifier="true" writable="false" />
<property name="email" writable="false" />
<property name="email" writable="true" />
<property name="firstName" writable="true" />
<property name="lastName" writable="true" />
<property name="fullName" writable="false" />
</resource>
</resources>

0 comments on commit 5109de8

Please sign in to comment.