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

Add endpoint for fetching/deleting vault tokens #307

Merged
merged 8 commits into from
Feb 14, 2019

Conversation

pmclain
Copy link
Contributor

@pmclain pmclain commented Dec 27, 2018

#46

Description (*)

Add query for fetching visible payment tokens:

customerPaymentTokens {
     items {
        public_hash
        details
        payment_method_code
        type
    }
}

The details property is the string value of vault_payment_token.details. This field contains serialized details that vary by the payment implementation. I'm not sure if we want to expose an interface for formatting this information similar to what is used in Magento_InstantPurchase or leave as-is.

Add mutation for deleting payment tokens:

deletePaymentToken (
    public_hash: {{someHash}}
) {
    result
}

Fixed Issues (if relevant)

  1. [Query] My Account > Stored Payment Methods #46: [Query] My Account > Stored Payment Methods

Manual testing scenarios (*)

  1. Configure payment method supporting vault and enable
  2. Checkout via storefront or admin using payment method and select option to save for later
  3. Use query above to retrieve stored payment tokens via graphql requires authentication
  4. Use mutation above to delete stored payment token via graphql requires authentication
  5. Use query above to validate deleted payment token is no longer returned via graphql requires authentication

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)

/**
* Vault payment token repository
*/
class PaymentTokenManagement
Copy link
Contributor

Choose a reason for hiding this comment

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

How about VisibleTokenRetriever or something similar?
*Management should be avoided in class names as too generic.

use Magento\CustomerGraphQl\Model\Customer\CheckCustomerAccount;

/**
* Payment Token resolver, used for GraphQL request processing.
Copy link
Contributor

Choose a reason for hiding this comment

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

Please update description


**VaultGraphQl** provides type and resolver information for the GraphQl module
to generate Vault (stored payment information) information endpoints. Also
provides endpoints for modifying a payment token.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
provides endpoints for modifying a payment token.
provides mutations for modifying a payment token.

"magento/module-customer-graph-ql": "*"
},
"suggest": {
"magento/module-graph-ql": "*"
Copy link
Contributor

Choose a reason for hiding this comment

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

It is interesting, will it even work without GraphQL module?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No. You caught me copying the composer.json from another module :)

}

type DeletePaymentTokenOutput {
result: Boolean!
Copy link
Contributor

Choose a reason for hiding this comment

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

I believe it makes sense to allow retrieval of updated customerPaymentTokens value as a result of mutation to prevent subsequent query when rendering the list again.

How about having two fields here:

result: Bolean!
customerPaymentTokens: CustomerPaymentTokens

}

type CustomerPaymentTokens {
items: [PaymentToken] @doc(description: "An array of payment tokens")
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
items: [PaymentToken] @doc(description: "An array of payment tokens")
items: [PaymentToken]! @doc(description: "An array of payment tokens")

I assume at least an empty array will always be returned.

type PaymentToken @doc(description: "Stored payment method available to customer") {
public_hash: String! @doc(description: "Token public hash")
payment_method_code: String! @doc(description: "Payment method code associated with token")
type: String! @doc(description: "Token type [card|account]")
Copy link
Contributor

Choose a reason for hiding this comment

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

It can be declared as enum if just two values are possible.

QUERY;
$response = $this->graphQlQuery($query, [], '', $this->getCustomerAuthHeaders($currentEmail, $currentPassword));

$this->assertEquals(1, count($response['customerPaymentTokens']['items']));
Copy link
Contributor

Choose a reason for hiding this comment

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

Ideally, we should validate each field

@pmclain
Copy link
Contributor Author

pmclain commented Jan 8, 2019

@paliarush Thanks for the feedback. The requested changes have been made.

Copy link
Contributor

@keharper keharper left a comment

Choose a reason for hiding this comment

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

My comments are for descriptions and exception messages.

$token = $this->paymentTokenManagement->getByPublicHash($args['public_hash'], $currentUserId);
if (!$token) {
throw new GraphQlNoSuchEntityException(
__('Token could not be found by public hash: %1', $args['public_hash'])
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
__('Token could not be found by public hash: %1', $args['public_hash'])
__('Could not find a token using public hash: %1', $args['public_hash'])

# VaultGraphQl

**VaultGraphQl** provides type and resolver information for the GraphQl module
to generate Vault (stored payment information) information endpoints. Also
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
to generate Vault (stored payment information) information endpoints. Also
to generate Vault (stored payment information) information endpoints. This module also

# See COPYING.txt for license details.

type Mutation {
deletePaymentToken(public_hash: String!): DeletePaymentTokenOutput @resolver(class: "\\Magento\\VaultGraphQl\\Model\\Resolver\\DeletePaymentToken") @doc(description:"Delete customer Payment Token")
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
deletePaymentToken(public_hash: String!): DeletePaymentTokenOutput @resolver(class: "\\Magento\\VaultGraphQl\\Model\\Resolver\\DeletePaymentToken") @doc(description:"Delete customer Payment Token")
deletePaymentToken(public_hash: String!): DeletePaymentTokenOutput @resolver(class: "\\Magento\\VaultGraphQl\\Model\\Resolver\\DeletePaymentToken") @doc(description:"Delete a customer payment token")

}

type Query {
customerPaymentTokens: CustomerPaymentTokens @doc(description: "List of customer payment tokens") @resolver(class: "\\Magento\\VaultGraphQl\\Model\\Resolver\\PaymentTokens")
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
customerPaymentTokens: CustomerPaymentTokens @doc(description: "List of customer payment tokens") @resolver(class: "\\Magento\\VaultGraphQl\\Model\\Resolver\\PaymentTokens")
customerPaymentTokens: CustomerPaymentTokens @doc(description: "Return a list of customer payment tokens") @resolver(class: "\\Magento\\VaultGraphQl\\Model\\Resolver\\PaymentTokens")

}

type PaymentToken @doc(description: "Stored payment method available to customer") {
public_hash: String! @doc(description: "Token public hash")
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
public_hash: String! @doc(description: "Token public hash")
public_hash: String! @doc(description: "The public hash of the token")

items: [PaymentToken]! @doc(description: "An array of payment tokens")
}

type PaymentToken @doc(description: "Stored payment method available to customer") {
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
type PaymentToken @doc(description: "Stored payment method available to customer") {
type PaymentToken @doc(description: "The stored payment method available to the customer") {


type PaymentToken @doc(description: "Stored payment method available to customer") {
public_hash: String! @doc(description: "Token public hash")
payment_method_code: String! @doc(description: "Payment method code associated with token")
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
payment_method_code: String! @doc(description: "Payment method code associated with token")
payment_method_code: String! @doc(description: "The payment method code associated with the token")

@pmclain
Copy link
Contributor Author

pmclain commented Jan 22, 2019

@keharper Thanks for review! The suggested changes have been applied.

pmclain and others added 3 commits January 25, 2019 20:09
There was 1 failure:
1) Magento\Test\Integrity\DependencyTest::testRedundant
Redundant dependencies found!
Module Magento\VaultGraphQl: hard [Magento\GraphQl]
@naydav
Copy link
Contributor

naydav commented Feb 6, 2019

@pmclain
Could you fix static tests errors?

FILE: ...al/testsuite/Magento/GraphQl/Vault/CustomerPaymentTokensTest.php
----------------------------------------------------------------------
FOUND 1 ERROR AFFECTING 1 LINE
----------------------------------------------------------------------
 155 | ERROR | [x] Function closing brace must go on the next line
     |       |     following the body; found 1 blank lines before
     |       |     brace
Magento\Test\Php\LiveCodeTest::testCopyPaste
PHP Copy/Paste Detector has found error(s):
<?xml version="1.0" encoding="UTF-8"?>
<pmd-cpd>
  <duplication lines="35" tokens="110">
    <file path="/var/www/html/app/code/Magento/Vault/Model/PaymentTokenManagement.php" line="129"/>
    <file path="/var/www/html/app/code/Magento/VaultGraphQl/Model/VisibleTokenRetriever.php" line="74"/>
    <codefragment>    public function getVisibleAvailableTokens($customerId)
    {
        $customerFilter = [
            $this-&gt;filterBuilder-&gt;setField(PaymentTokenInterface::CUSTOMER_ID)
                -&gt;setValue($customerId)
                -&gt;create()
            ];
        $visibleFilter = [
            $this-&gt;filterBuilder-&gt;setField(PaymentTokenInterface::IS_VISIBLE)
                -&gt;setValue(1)
                -&gt;create()
            ];
        $isActiveFilter = [
            $this-&gt;filterBuilder-&gt;setField(PaymentTokenInterface::IS_ACTIVE)
                -&gt;setValue(1)
                -&gt;create()
            ];
        $expiresAtFilter = [
            $this-&gt;filterBuilder-&gt;setField(PaymentTokenInterface::EXPIRES_AT)
                -&gt;setConditionType('gt')
                -&gt;setValue(
                    $this-&gt;dateTimeFactory-&gt;create(
                        'now',
                        new \DateTimeZone('UTC')
                    )-&gt;format('Y-m-d 00:00:00')
                )
                -&gt;create()
            ];
        $this-&gt;searchCriteriaBuilder-&gt;addFilters($customerFilter);
        $this-&gt;searchCriteriaBuilder-&gt;addFilters($visibleFilter);
        $this-&gt;searchCriteriaBuilder-&gt;addFilters($isActiveFilter);
        // add filters to different filter groups in order to filter by AND expression
        $searchCriteria = $this-&gt;searchCriteriaBuilder-&gt;addFilters($expiresAtFilter)-&gt;create();

        return $this-&gt;paymentTokenRepository-&gt;getList($searchCriteria)-&gt;getItems();
</codefragment>
  </duplication>
</pmd-cpd>

Thanks

@pmclain
Copy link
Contributor Author

pmclain commented Feb 6, 2019

@naydav cc0b1cd should resolve the static tests.

@magento-engcom-team magento-engcom-team merged commit 867c134 into magento:2.3-develop Feb 14, 2019
@ghost
Copy link

ghost commented Feb 14, 2019

Hi @pmclain, thank you for your contribution!
Please, complete Contribution Survey, it will take less than a minute.
Your feedback will help us to improve contribution process.

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.

5 participants