diff --git a/app/code/Magento/CustomerGraphQl/Model/Customer/Address/CreateCustomerAddress.php b/app/code/Magento/CustomerGraphQl/Model/Customer/Address/CreateCustomerAddress.php index 9637b3e555b8b..37230df202a6f 100644 --- a/app/code/Magento/CustomerGraphQl/Model/Customer/Address/CreateCustomerAddress.php +++ b/app/code/Magento/CustomerGraphQl/Model/Customer/Address/CreateCustomerAddress.php @@ -10,9 +10,10 @@ use Magento\Customer\Api\AddressRepositoryInterface; use Magento\Customer\Api\Data\AddressInterface; use Magento\Customer\Api\Data\AddressInterfaceFactory; +use Magento\Directory\Helper\Data as DirectoryData; +use Magento\Framework\Api\DataObjectHelper; use Magento\Framework\Exception\LocalizedException; use Magento\Framework\GraphQl\Exception\GraphQlInputException; -use Magento\Framework\Api\DataObjectHelper; /** * Create customer address @@ -38,23 +39,30 @@ class CreateCustomerAddress * @var DataObjectHelper */ private $dataObjectHelper; + /** + * @var DirectoryData + */ + private $directoryData; /** * @param GetAllowedAddressAttributes $getAllowedAddressAttributes * @param AddressInterfaceFactory $addressFactory * @param AddressRepositoryInterface $addressRepository * @param DataObjectHelper $dataObjectHelper + * @param DirectoryData $directoryData */ public function __construct( GetAllowedAddressAttributes $getAllowedAddressAttributes, AddressInterfaceFactory $addressFactory, AddressRepositoryInterface $addressRepository, - DataObjectHelper $dataObjectHelper + DataObjectHelper $dataObjectHelper, + DirectoryData $directoryData ) { $this->getAllowedAddressAttributes = $getAllowedAddressAttributes; $this->addressFactory = $addressFactory; $this->addressRepository = $addressRepository; $this->dataObjectHelper = $dataObjectHelper; + $this->directoryData = $directoryData; } /** @@ -102,6 +110,13 @@ public function validateData(array $addressData): void $attributes = $this->getAllowedAddressAttributes->execute(); $errorInput = []; + //Add error for empty postcode with country with no optional ZIP + if (!$this->directoryData->isZipCodeOptional($addressData['country_id']) + && (!isset($addressData['postcode']) || empty($addressData['postcode'])) + ) { + $errorInput[] = 'postcode'; + } + foreach ($attributes as $attributeName => $attributeInfo) { if ($attributeInfo->getIsRequired() && (!isset($addressData[$attributeName]) || empty($addressData[$attributeName])) diff --git a/app/code/Magento/CustomerGraphQl/Model/Resolver/DeleteCustomerAddress.php b/app/code/Magento/CustomerGraphQl/Model/Resolver/DeleteCustomerAddress.php index da588b98b5dbc..c26b3710ef561 100644 --- a/app/code/Magento/CustomerGraphQl/Model/Resolver/DeleteCustomerAddress.php +++ b/app/code/Magento/CustomerGraphQl/Model/Resolver/DeleteCustomerAddress.php @@ -58,10 +58,6 @@ public function resolve( throw new GraphQlAuthorizationException(__('The current customer isn\'t authorized.')); } - if (empty($args['id'])) { - throw new GraphQlInputException(__('Address "id" value should be specified')); - } - $address = $this->getCustomerAddress->execute((int)$args['id'], $context->getUserId()); $this->deleteCustomerAddress->execute($address); return true; diff --git a/app/code/Magento/CustomerGraphQl/composer.json b/app/code/Magento/CustomerGraphQl/composer.json index 911624da8fe57..70a98f728b696 100644 --- a/app/code/Magento/CustomerGraphQl/composer.json +++ b/app/code/Magento/CustomerGraphQl/composer.json @@ -4,7 +4,6 @@ "type": "magento2-module", "require": { "php": "~7.1.3||~7.2.0||~7.3.0", - "magento/module-customer": "*", "magento/module-authorization": "*", "magento/module-customer": "*", "magento/module-eav": "*", @@ -12,7 +11,8 @@ "magento/module-newsletter": "*", "magento/module-integration": "*", "magento/module-store": "*", - "magento/framework": "*" + "magento/framework": "*", + "magento/module-directory": "*" }, "license": [ "OSL-3.0", diff --git a/app/code/Magento/QuoteGraphQl/Model/Cart/AddProductsToCart.php b/app/code/Magento/QuoteGraphQl/Model/Cart/AddProductsToCart.php index 005cf3a10ca80..91c77a1a3ecc5 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Cart/AddProductsToCart.php +++ b/app/code/Magento/QuoteGraphQl/Model/Cart/AddProductsToCart.php @@ -8,7 +8,7 @@ namespace Magento\QuoteGraphQl\Model\Cart; use Magento\Framework\GraphQl\Exception\GraphQlInputException; -use Magento\Framework\Message\AbstractMessage; +use Magento\Framework\Message\MessageInterface; use Magento\Quote\Api\CartRepositoryInterface; use Magento\Quote\Model\Quote; @@ -55,29 +55,15 @@ public function execute(Quote $cart, array $cartItems): void } if ($cart->getData('has_error')) { - throw new GraphQlInputException( - __('Shopping cart error: %message', ['message' => $this->getCartErrors($cart)]) - ); + $e = new GraphQlInputException(__('Shopping cart errors')); + $errors = $cart->getErrors(); + foreach ($errors as $error) { + /** @var MessageInterface $error */ + $e->addError(new GraphQlInputException(__($error->getText()))); + } + throw $e; } $this->cartRepository->save($cart); } - - /** - * Collecting cart errors - * - * @param Quote $cart - * @return string - */ - private function getCartErrors(Quote $cart): string - { - $errorMessages = []; - - /** @var AbstractMessage $error */ - foreach ($cart->getErrors() as $error) { - $errorMessages[] = $error->getText(); - } - - return implode(PHP_EOL, $errorMessages); - } } diff --git a/app/code/Magento/QuoteGraphQl/Model/Cart/AddSimpleProductToCart.php b/app/code/Magento/QuoteGraphQl/Model/Cart/AddSimpleProductToCart.php index 11719db2d1b8f..83c1d03f132db 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Cart/AddSimpleProductToCart.php +++ b/app/code/Magento/QuoteGraphQl/Model/Cart/AddSimpleProductToCart.php @@ -72,7 +72,12 @@ public function execute(Quote $cart, array $cartItemData): void } if (is_string($result)) { - throw new GraphQlInputException(__($result)); + $e = new GraphQlInputException(__('Cannot add product to cart')); + $errors = array_unique(explode("\n", $result)); + foreach ($errors as $error) { + $e->addError(new GraphQlInputException(__($error))); + } + throw $e; } } diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/ChangeCustomerPasswordTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/ChangeCustomerPasswordTest.php index f36200c8e9218..bf01ad4b37218 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/ChangeCustomerPasswordTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/ChangeCustomerPasswordTest.php @@ -48,7 +48,7 @@ class ChangeCustomerPasswordTest extends GraphQlAbstract */ private $customerRepository; - protected function setUp() + protected function setUp(): void { $this->customerTokenService = Bootstrap::getObjectManager()->get(CustomerTokenServiceInterface::class); $this->accountManagement = Bootstrap::getObjectManager()->get(AccountManagementInterface::class); diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/CreateCustomerAddressTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/CreateCustomerAddressTest.php index 408a254f65f2e..81300e967f6a2 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/CreateCustomerAddressTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/CreateCustomerAddressTest.php @@ -29,7 +29,7 @@ class CreateCustomerAddressTest extends GraphQlAbstract */ private $addressRepository; - protected function setUp() + protected function setUp(): void { parent::setUp(); @@ -358,6 +358,67 @@ public function testCreateCustomerAddressWithRedundantStreetLine() $this->graphQlMutation($mutation, [], '', $this->getCustomerAuthHeaders($userName, $password)); } + /** + * @magentoApiDataFixture Magento/Customer/_files/customer_without_addresses.php + * @magentoConfigFixture default_store general/country/optional_zip_countries UA + * + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) + */ + public function testCreateCustomerAddressWithOptionalZipCode() + { + $newAddress = [ + 'country_code' => 'UA', + 'street' => ['Line 1 Street', 'Line 2'], + 'company' => 'Company name', + 'telephone' => '123456789', + 'fax' => '123123123', + 'city' => 'City Name', + 'firstname' => 'Adam', + 'lastname' => 'Phillis', + 'middlename' => 'A', + 'prefix' => 'Mr.', + 'suffix' => 'Jr.', + 'vat_id' => '1', + 'default_shipping' => true, + 'default_billing' => false + ]; + + $mutation + = <<graphQlMutation( + $mutation, + [], + '', + $this->getCustomerAuthHeaders($userName, $password) + ); + $this->assertNotEmpty($response['createCustomerAddress']['id']); + } + /** * Create new address with invalid input * diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/CreateCustomerTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/CreateCustomerTest.php index 618fe289ad566..a6455a9728fec 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/CreateCustomerTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/CreateCustomerTest.php @@ -13,7 +13,7 @@ use Magento\TestFramework\TestCase\GraphQlAbstract; /** - * Test for create customer functionallity + * Test for create customer functionality */ class CreateCustomerTest extends GraphQlAbstract { @@ -27,7 +27,7 @@ class CreateCustomerTest extends GraphQlAbstract */ private $customerRepository; - protected function setUp() + protected function setUp(): void { parent::setUp(); @@ -308,7 +308,40 @@ public function testCreateCustomerSubscribed() $this->assertEquals(false, $response['createCustomer']['customer']['is_subscribed']); } - public function tearDown() + /** + * @magentoApiDataFixture Magento/Customer/_files/customer.php + * @expectedException \Exception + * @expectedExceptionMessage A customer with the same email address already exists in an associated website. + */ + public function testCreateCustomerIfCustomerWithProvidedEmailAlreadyExists() + { + $existedEmail = 'customer@example.com'; + $password = 'test123#'; + $firstname = 'John'; + $lastname = 'Smith'; + + $query = <<graphQlMutation($query); + } + + public function tearDown(): void { $newEmail = 'new_customer@example.com'; try { diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/DeleteCustomerAddressTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/DeleteCustomerAddressTest.php index 443b9d7ec53e5..31065f3f6f98b 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/DeleteCustomerAddressTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/DeleteCustomerAddressTest.php @@ -39,7 +39,7 @@ class DeleteCustomerAddressTest extends GraphQlAbstract */ private $lockCustomer; - protected function setUp() + protected function setUp(): void { parent::setUp(); diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/GetAddressesTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/GetAddressesTest.php index c1573d7dbd8af..ed360919d8320 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/GetAddressesTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/GetAddressesTest.php @@ -31,7 +31,7 @@ class GetAddressesTest extends GraphQlAbstract */ private $lockCustomer; - protected function setUp() + protected function setUp(): void { parent::setUp(); diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/GetCustomerTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/GetCustomerTest.php index 56e950c45fae0..c645d8953981a 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/GetCustomerTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/GetCustomerTest.php @@ -36,7 +36,7 @@ class GetCustomerTest extends GraphQlAbstract */ private $customerRepository; - protected function setUp() + protected function setUp(): void { parent::setUp(); diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/SubscriptionStatusTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/SubscriptionStatusTest.php index bbb7e245c91fd..4cba8323793dc 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/SubscriptionStatusTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/SubscriptionStatusTest.php @@ -29,7 +29,7 @@ class SubscriptionStatusTest extends GraphQlAbstract */ private $subscriberFactory; - protected function setUp() + protected function setUp(): void { parent::setUp(); @@ -162,7 +162,7 @@ private function getHeaderMap(string $email, string $password): array return ['Authorization' => 'Bearer ' . $customerToken]; } - protected function tearDown() + protected function tearDown(): void { parent::tearDown(); diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/UpdateCustomerAddressTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/UpdateCustomerAddressTest.php index 60f1f2d64df90..da67900994940 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/UpdateCustomerAddressTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/UpdateCustomerAddressTest.php @@ -40,7 +40,7 @@ class UpdateCustomerAddressTest extends GraphQlAbstract */ private $lockCustomer; - protected function setUp() + protected function setUp(): void { parent::setUp(); diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/UpdateCustomerTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/UpdateCustomerTest.php index d1c6638e8d5ff..7121f12bc2a42 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/UpdateCustomerTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/UpdateCustomerTest.php @@ -33,7 +33,7 @@ class UpdateCustomerTest extends GraphQlAbstract */ private $lockCustomer; - protected function setUp() + protected function setUp(): void { parent::setUp(); diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/AddSimpleProductToCartTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/AddSimpleProductToCartTest.php index cd9b48bccaf22..0c676d86a33da 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/AddSimpleProductToCartTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/AddSimpleProductToCartTest.php @@ -29,7 +29,7 @@ class AddSimpleProductToCartTest extends GraphQlAbstract */ private $getMaskedQuoteIdByReservedOrderId; - protected function setUp() + protected function setUp(): void { $objectManager = Bootstrap::getObjectManager(); $this->customerTokenService = $objectManager->get(CustomerTokenServiceInterface::class); diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/GetCustomerCartTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/GetCustomerCartTest.php index a52938c13e5c0..8100bce4ac718 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/GetCustomerCartTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/GetCustomerCartTest.php @@ -90,10 +90,8 @@ public function testGetLoggedInCustomerCartWithoutMaskedQuoteId() */ public function testGetNewCustomerCart() { - $customerToken = $this->generateCustomerToken(); $customerCartQuery = $this->getCustomerCartQuery(); - $headers = ['Authorization' => 'Bearer ' . $customerToken]; - $response = $this->graphQlQuery($customerCartQuery, [], '', $headers); + $response = $this->graphQlQuery($customerCartQuery, [], '', $this->getHeaderMap()); $this->assertArrayHasKey('customerCart', $response); $this->assertArrayHasKey('id', $response['customerCart']); $this->assertNotNull($response['customerCart']['id']); @@ -118,12 +116,13 @@ public function testGetCustomerCartWithNoCustomerToken() * Query for customer cart after customer token is revoked * * @magentoApiDataFixture Magento/Customer/_files/customer.php + * @expectedException \Exception + * @expectedExceptionMessage The request is allowed for logged in customer */ public function testGetCustomerCartAfterTokenRevoked() { - $customerToken = $this->generateCustomerToken(); - $headers = ['Authorization' => 'Bearer ' . $customerToken]; $customerCartQuery = $this->getCustomerCartQuery(); + $headers = $this->getHeaderMap(); $response = $this->graphQlMutation($customerCartQuery, [], '', $headers); $this->assertArrayHasKey('customerCart', $response); $this->assertArrayHasKey('id', $response['customerCart']); @@ -131,9 +130,6 @@ public function testGetCustomerCartAfterTokenRevoked() $this->assertNotEmpty($response['customerCart']['id']); $this->revokeCustomerToken(); $customerCartQuery = $this->getCustomerCartQuery(); - $this->expectExceptionMessage( - 'The request is allowed for logged in customer' - ); $this->graphQlQuery($customerCartQuery, [], '', $headers); } @@ -144,16 +140,14 @@ public function testGetCustomerCartAfterTokenRevoked() */ public function testRequestCustomerCartTwice() { - $customerToken = $this->generateCustomerToken(); - $headers = ['Authorization' => 'Bearer ' . $customerToken]; $customerCartQuery = $this->getCustomerCartQuery(); - $response = $this->graphQlMutation($customerCartQuery, [], '', $headers); + $response = $this->graphQlMutation($customerCartQuery, [], '', $this->getHeaderMap()); $this->assertArrayHasKey('customerCart', $response); $this->assertArrayHasKey('id', $response['customerCart']); $this->assertNotNull($response['customerCart']['id']); $cartId = $response['customerCart']['id']; $customerCartQuery = $this->getCustomerCartQuery(); - $response2 = $this->graphQlQuery($customerCartQuery, [], '', $headers); + $response2 = $this->graphQlQuery($customerCartQuery, [], '', $this->getHeaderMap()); $this->assertEquals($cartId, $response2['customerCart']['id']); } @@ -192,31 +186,6 @@ public function testGetCustomerCartSecondStore() $this->assertEquals($maskedQuoteIdSecondStore, $responseSecondStore['customerCart']['id']); } - /** - * Query to generate customer token - * - * @return string - */ - private function generateCustomerToken(): string - { - $query = <<graphQlMutation($query); - self::assertArrayHasKey('generateCustomerToken', $response); - self::assertArrayHasKey('token', $response['generateCustomerToken']); - self::assertNotEmpty($response['generateCustomerToken']['token']); - - return $response['generateCustomerToken']['token']; - } - /** * Query to revoke customer token * @@ -232,8 +201,7 @@ private function revokeCustomerToken(): void } QUERY; - $response = $this->graphQlMutation($query, [], '', $this->getHeaderMap()); - $this->assertTrue($response['revokeCustomerToken']['result']); + $this->graphQlMutation($query, [], '', $this->getHeaderMap()); } /**