Skip to content
This repository has been archived by the owner on Dec 19, 2019. It is now read-only.

My Account > Change account information and Newsletter subscription #162

Merged

Conversation

nuzil
Copy link
Contributor

@nuzil nuzil commented Aug 28, 2018

Description

Implementing 2 issues:

Customer account edit data and customer newsletter subscription

https://app.zenhub.com/workspace/o/magento/graphql-ce/issues/56
https://app.zenhub.com/workspace/o/magento/graphql-ce/issues/55

Contribution checklist

  • Pull request has a meaningful description of its purpose
  • All commits are accompanied by meaningful commit messages
  • All new or changed code is covered with unit/integration tests (if applicable)
  • All automated tests passed successfully (all builds on Travis CI are green)

@magento-cicd2
Copy link
Contributor

magento-cicd2 commented Aug 28, 2018

CLA assistant check
All committers have signed the CLA.

/**
* @var \Magento\Newsletter\Model\SubscriberFactory
*/
protected $subscriberFactory;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pls, use private access

* @return CustomerInterface
* @throws LocalizedException
* @throws NoSuchEntityException
*/
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need mathod-wrapper over Repository?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, I planned to use it in another location, but currently it not needed anymore

@@ -13,6 +13,11 @@
use Magento\Framework\Serialize\SerializerInterface;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like this class has a lot of responsibility (looks like helper in Magento 1)
Need to split the class


$customerSecure = $this->customerRegistry->retrieveSecureData($customerId);
$hash = $customerSecure->getPasswordHash();
if (!$this->encryptor->validateHash($password, $hash)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can simplify this condition

return !empty($data) ? $data : [];
};

return $this->valueFactory->create($result);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to return something if it is 'command' operation?

@@ -51,3 +51,13 @@ type CustomerAddressRegion @doc(description: "CustomerAddressRegion defines the
region_id: Int @doc(description: "Uniquely identifies the region")
}

type Mutation {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, need to cover functionality with API-functional tests
Now we have a lot of examples and tests writing is very simple


if (isset($data['email']) && $customer->getEmail() !== $data['email']) {
if (!isset($data['password']) || empty($data['password'])) {
throw new GraphQlInputException(__('For changing "email" you should provide current "password".'));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change exception message to 'Provide the current "password" to change "email".'

array $args = null
) {
if (!isset($args['currentPassword'])) {
throw new GraphQlInputException(__('"currentPassword" value should be specified'));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change exception message to 'Specify the "currentPassword" value.`

}

if (!isset($args['newPassword'])) {
throw new GraphQlInputException(__('"newPassword" value should be specified'));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change exception message to 'Specify the "newPassword" value.'

@@ -43,19 +44,19 @@ public function resolve(
array $value = null,
array $args = null
) {
if (!isset($args['email'])) {
throw new GraphQlInputException(__('"email" value should be specified'));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change exception message to 'Specify the "email" value.'

}

if (!isset($args['password'])) {
throw new GraphQlInputException(__('"password" value should be specified'));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change exception message to 'Specify the "password" value.'

array $args = null
) {
if (!isset($args['input']) || !is_array($args['input']) || empty($args['input'])) {
throw new GraphQlInputException(__('"input" value should be specified'));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change exception message to 'Specify the "input" value.'

generateCustomerToken(email: String!, password: String!): CustomerToken @resolver(class: "\\Magento\\CustomerGraphQl\\Model\\Resolver\\Customer\\Account\\GenerateCustomerToken") @doc(description:"Retrieve Customer token")
changeCustomerPassword(currentPassword: String!, newPassword: String!): Customer @resolver(class: "\\Magento\\CustomerGraphQl\\Model\\Resolver\\Customer\\Account\\ChangePassword") @doc(description:"Changes password for logged in customer")
revokeCustomerToken: Boolean @resolver(class: "\\Magento\\CustomerGraphQl\\Model\\Resolver\\Customer\\Account\\RevokeCustomerToken") @doc(description:"Revoke Customer token")
generateCustomerToken(email: String!, password: String!): CustomerToken @resolver(class: "\\Magento\\CustomerGraphQl\\Model\\Resolver\\GenerateCustomerToken") @doc(description:"Retrieve Customer token")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change the description text to "Retrieve the customer token"

changeCustomerPassword(currentPassword: String!, newPassword: String!): Customer @resolver(class: "\\Magento\\CustomerGraphQl\\Model\\Resolver\\Customer\\Account\\ChangePassword") @doc(description:"Changes password for logged in customer")
revokeCustomerToken: Boolean @resolver(class: "\\Magento\\CustomerGraphQl\\Model\\Resolver\\Customer\\Account\\RevokeCustomerToken") @doc(description:"Revoke Customer token")
generateCustomerToken(email: String!, password: String!): CustomerToken @resolver(class: "\\Magento\\CustomerGraphQl\\Model\\Resolver\\GenerateCustomerToken") @doc(description:"Retrieve Customer token")
changeCustomerPassword(currentPassword: String!, newPassword: String!): Customer @resolver(class: "\\Magento\\CustomerGraphQl\\Model\\Resolver\\ChangePassword") @doc(description:"Changes password for logged in customer")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change the description text to "Changes the password for the logged-in customer"

revokeCustomerToken: Boolean @resolver(class: "\\Magento\\CustomerGraphQl\\Model\\Resolver\\Customer\\Account\\RevokeCustomerToken") @doc(description:"Revoke Customer token")
generateCustomerToken(email: String!, password: String!): CustomerToken @resolver(class: "\\Magento\\CustomerGraphQl\\Model\\Resolver\\GenerateCustomerToken") @doc(description:"Retrieve Customer token")
changeCustomerPassword(currentPassword: String!, newPassword: String!): Customer @resolver(class: "\\Magento\\CustomerGraphQl\\Model\\Resolver\\ChangePassword") @doc(description:"Changes password for logged in customer")
updateCustomer (input: UpdateCustomerInput): UpdateCustomerOutput @resolver(class: "\\Magento\\CustomerGraphQl\\Model\\Resolver\\UpdateCustomer") @doc(description:"Update customer personal information")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change the description text to "Update the customer's personal information"

generateCustomerToken(email: String!, password: String!): CustomerToken @resolver(class: "\\Magento\\CustomerGraphQl\\Model\\Resolver\\GenerateCustomerToken") @doc(description:"Retrieve Customer token")
changeCustomerPassword(currentPassword: String!, newPassword: String!): Customer @resolver(class: "\\Magento\\CustomerGraphQl\\Model\\Resolver\\ChangePassword") @doc(description:"Changes password for logged in customer")
updateCustomer (input: UpdateCustomerInput): UpdateCustomerOutput @resolver(class: "\\Magento\\CustomerGraphQl\\Model\\Resolver\\UpdateCustomer") @doc(description:"Update customer personal information")
revokeCustomerToken: Boolean @resolver(class: "\\Magento\\CustomerGraphQl\\Model\\Resolver\\RevokeCustomerToken") @doc(description:"Revoke Customer token")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change the description text to the "Revoke the customer token"

*/
public function execute(int $customerId, bool $subscriptionStatus): void
{
$subscriber = $this->subscriberFactory->create()->loadByCustomerId($customerId);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does not make sense to load records from DB if the next two conditions fail.

public function execute(?int $customerId, ?int $customerType): void
{
if (true === $this->isCustomerGuest($customerId, $customerType)) {
throw new GraphQlAuthorizationException(__('The current customer isn\'t authorized.'));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Usually it is better to use 'is not' instead of 'isn't' in error message.

* @throws GraphQlNoSuchEntityException
* @throws GraphQlAuthenticationException
*/
public function execute(?int $customerId, ?int $customerType): void
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why customer type is needed here? For guests $customerID will be 0.
Also, why these arguments are optional? We can just ask for (int)$customerId

/**
* Check customer password
*/
class CheckCustomerPassword
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should use nouns as class names. Please consider changing it to CustomerPasswordVerifier or CustomerAuthenticator.

Please fix the names of all affected variables which hold this object as well.

use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;

/**
* @inheritdoc
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need explicit description for the purpose of this class.

@@ -6,7 +6,9 @@
"php": "~7.1.3||~7.2.0",
"magento/module-customer": "*",
"magento/module-authorization": "*",
"magento/module-newsletter": "*",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remember to fix health index etalon tests

revokeCustomerToken: Boolean @resolver(class: "\\Magento\\CustomerGraphQl\\Model\\Resolver\\Customer\\Account\\RevokeCustomerToken") @doc(description:"Revoke Customer token")
generateCustomerToken(email: String!, password: String!): CustomerToken @resolver(class: "\\Magento\\CustomerGraphQl\\Model\\Resolver\\GenerateCustomerToken") @doc(description:"Retrieve Customer token")
changeCustomerPassword(currentPassword: String!, newPassword: String!): Customer @resolver(class: "\\Magento\\CustomerGraphQl\\Model\\Resolver\\ChangePassword") @doc(description:"Changes password for logged in customer")
updateCustomer (input: UpdateCustomerInput): UpdateCustomerOutput @resolver(class: "\\Magento\\CustomerGraphQl\\Model\\Resolver\\UpdateCustomer") @doc(description:"Update customer personal information")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Must be marked as required UpdateCustomerInput!

generateCustomerToken(email: String!, password: String!): CustomerToken @resolver(class: "\\Magento\\CustomerGraphQl\\Model\\Resolver\\GenerateCustomerToken") @doc(description:"Retrieve Customer token")
changeCustomerPassword(currentPassword: String!, newPassword: String!): Customer @resolver(class: "\\Magento\\CustomerGraphQl\\Model\\Resolver\\ChangePassword") @doc(description:"Changes password for logged in customer")
updateCustomer (input: UpdateCustomerInput): UpdateCustomerOutput @resolver(class: "\\Magento\\CustomerGraphQl\\Model\\Resolver\\UpdateCustomer") @doc(description:"Update customer personal information")
revokeCustomerToken: Boolean @resolver(class: "\\Magento\\CustomerGraphQl\\Model\\Resolver\\RevokeCustomerToken") @doc(description:"Revoke Customer token")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's create a wrapper for the revoke result to allow for future extensibility.

use Magento\Framework\Phrase;

/**
* Class GraphQlAlreadyExistsException
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More meaningful description is required for this and other newly introduced exceptions.

@@ -20,7 +20,7 @@
* Fetches the data from persistence models and format it according to the GraphQL schema.
*
* @param \Magento\Framework\GraphQl\Config\Element\Field $field
* @param $context
* @param \Magento\Framework\GraphQl\Query\Resolver\ContextInterface $context
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is fixed in 2.3.0 performance improvements and will result in a conflict. Better revert it here.

@naydav
Copy link
Contributor

naydav commented Oct 10, 2018

All CR fixes will be provided in separate PR

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants