Skip to content

Commit 57258eb

Browse files
committed
MC-17592: End-to-end integration to test order with Payflow Link
- added integration test coverage for registered customer and declined order
1 parent b487de9 commit 57258eb

File tree

3 files changed

+334
-19
lines changed

3 files changed

+334
-19
lines changed

dev/tests/integration/testsuite/Magento/Paypal/_files/order_payflow_link_with_payment.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,8 @@
5454

5555
'cancel_url'=> $baseUrl .'paypal/payflow/cancelPayment',
5656
'return_url'=> $baseUrl .'paypal/payflow/returnUrl',
57-
'secure_token_id' => '31f2a7c8d257c70b1c9eb9051b90e0',
58-
'secure_token' => '80IgSbabyj0CtBDWHZZeQN3'
57+
'secure_token_id' => 'mysecuretokenId',
58+
'secure_token' => 'mysecuretoken'
5959
]
6060
);
6161

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,231 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\PaypalGraphQl\Model\Resolver\Customer;
9+
10+
use Magento\Framework\App\ProductMetadataInterface;
11+
use Magento\Framework\App\Request\Http;
12+
use Magento\Framework\DataObject;
13+
use Magento\Framework\Math\Random;
14+
use Magento\Framework\Serialize\SerializerInterface;
15+
use Magento\GraphQl\Controller\GraphQl;
16+
use Magento\GraphQl\Quote\GetMaskedQuoteIdByReservedOrderId;
17+
use Magento\Paypal\Model\Payflow\Request;
18+
use Magento\Paypal\Model\Payflow\Service\Gateway;
19+
use Magento\Quote\Model\QuoteIdToMaskedQuoteId;
20+
use Magento\TestFramework\Helper\Bootstrap;
21+
use Magento\Framework\UrlInterface;
22+
use Magento\TestFramework\ObjectManager;
23+
use PHPUnit\Framework\MockObject\MockObject;
24+
use PHPUnit\Framework\TestCase;
25+
26+
/**
27+
* End to end place order test using payflow_link via graphql endpoint for registered customer
28+
*
29+
* @magentoAppArea graphql
30+
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
31+
*/
32+
class PlaceOrderWithPayflowLinkTest extends TestCase
33+
{
34+
/**
35+
* @var Http
36+
*/
37+
private $request;
38+
39+
/**
40+
* @var SerializerInterface
41+
*/
42+
private $json;
43+
44+
/**
45+
* @var QuoteIdToMaskedQuoteId
46+
*/
47+
private $quoteIdToMaskedId;
48+
49+
/** @var GetMaskedQuoteIdByReservedOrderId */
50+
private $getMaskedQuoteIdByReservedOrderId;
51+
52+
/** @var ObjectManager */
53+
protected $objectManager;
54+
55+
/** @var GraphQl */
56+
protected $graphqlController;
57+
58+
/** @var Gateway|MockObject */
59+
private $gateway;
60+
61+
/** @var Random|MockObject */
62+
private $mathRandom;
63+
64+
/** @var Request|MockObject */
65+
private $payflowRequest;
66+
67+
protected function setUp()
68+
{
69+
parent::setUp();
70+
71+
$this->objectManager = Bootstrap::getObjectManager();
72+
$this->request = $this->objectManager->create(Http::class);
73+
$this->json = $this->objectManager->get(SerializerInterface::class);
74+
$this->getMaskedQuoteIdByReservedOrderId = $this->objectManager->get(GetMaskedQuoteIdByReservedOrderId::class);
75+
$this->quoteIdToMaskedId = $this->objectManager->get(QuoteIdToMaskedQuoteId::class);
76+
77+
$this->graphqlController = $this->objectManager->get(GraphQl::class);
78+
79+
$this->mathRandom = $this->getMockBuilder(Random::class)
80+
->getMock();
81+
$this->gateway = $this->getMockBuilder(Gateway::class)
82+
->disableOriginalConstructor()
83+
->setMethods(['postRequest'])
84+
->getMock();
85+
86+
$requestFactory = $this->getMockBuilder(\Magento\Paypal\Model\Payflow\RequestFactory::class)
87+
->setMethods(['create'])
88+
->disableOriginalConstructor()
89+
->getMock();
90+
91+
$this->payflowRequest = $this->getMockBuilder(\Magento\Paypal\Model\Payflow\Request::class)
92+
->disableOriginalConstructor()
93+
->getMock();
94+
$requestFactory->expects($this->any())->method('create')->will($this->returnValue($this->payflowRequest));
95+
96+
$this->objectManager->addSharedInstance($this->gateway, Gateway::class);
97+
}
98+
99+
/**
100+
* Test place order with payflow link
101+
*
102+
* @magentoConfigFixture default_store payment/payflow_link/active 1
103+
* @magentoConfigFixture default_store payment/payflow_link/sandbox_flag 1
104+
* @magentoDataFixture Magento/Sales/_files/default_rollback.php
105+
* @magentoDataFixture Magento/Customer/_files/customer.php
106+
* @magentoDataFixture Magento/GraphQl/Catalog/_files/simple_product.php
107+
* @magentoDataFixture Magento/GraphQl/Quote/_files/customer/create_empty_cart.php
108+
* @magentoDataFixture Magento/GraphQl/Quote/_files/add_simple_product.php
109+
* @magentoDataFixture Magento/GraphQl/Quote/_files/set_new_shipping_address.php
110+
* @magentoDataFixture Magento/GraphQl/Quote/_files/set_new_billing_address.php
111+
* @magentoDataFixture Magento/GraphQl/Quote/_files/set_flatrate_shipping_method.php
112+
* @return void
113+
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
114+
*/
115+
public function testResolvePlaceOrderWithPayflowLinkForCustomer(): void
116+
{
117+
$paymentMethod = 'payflow_link';
118+
$cartId = $this->getMaskedQuoteIdByReservedOrderId->execute('test_quote');
119+
120+
$url = $this->objectManager->get(UrlInterface::class);
121+
$baseUrl = $url->getBaseUrl();
122+
123+
$query
124+
= <<<QUERY
125+
mutation {
126+
setPaymentMethodOnCart(input: {
127+
cart_id: "$cartId"
128+
payment_method: {
129+
code: "$paymentMethod"
130+
additional_data: {
131+
payflow_link:
132+
{
133+
cancel_url:"{$baseUrl}paypal/payflow/cancelPayment"
134+
return_url:"{$baseUrl}paypal/payflow/returnUrl"
135+
}
136+
}
137+
}
138+
}) {
139+
cart {
140+
selected_payment_method {
141+
code
142+
}
143+
}
144+
}
145+
placeOrder(input: {cart_id: "$cartId"}) {
146+
order {
147+
order_id
148+
}
149+
}
150+
}
151+
QUERY;
152+
153+
$postData = $this->json->serialize(['query' => $query]);
154+
$this->request->setPathInfo('/graphql');
155+
$this->request->setMethod('POST');
156+
$this->request->setContent($postData);
157+
158+
/** @var \Magento\Integration\Model\Oauth\Token $tokenModel */
159+
$tokenModel = $this->objectManager->create(\Magento\Integration\Model\Oauth\Token::class);
160+
$customerToken = $tokenModel->createCustomerToken(1)->getToken();
161+
/** @var \Magento\Framework\Webapi\Request $webApiRequest */
162+
$webApiRequest = $this->objectManager->get(\Magento\Framework\Webapi\Request::class);
163+
$webApiRequest->getHeaders()
164+
->addHeaderLine('Content-Type', 'application/json')
165+
->addHeaderLine('Accept', 'application/json')
166+
->addHeaderLine('Authorization', 'Bearer ' . $customerToken);
167+
$this->request->setHeaders($webApiRequest->getHeaders());
168+
169+
$productMetadata = ObjectManager::getInstance()->get(ProductMetadataInterface::class);
170+
$button = 'Magento_Cart_' . $productMetadata->getEdition();
171+
172+
$payflowLinkResponse = new DataObject(
173+
[
174+
'result' => '0',
175+
'respmsg' => 'Approved',
176+
'pnref' => 'V19A3D27B61E',
177+
'result_code' => '0'
178+
]
179+
);
180+
$this->gateway->expects($this->once())
181+
->method('postRequest')
182+
->willReturn($payflowLinkResponse);
183+
184+
$this->payflowRequest->expects($this->any())
185+
->method('setData')
186+
->willReturnMap(
187+
[
188+
[
189+
'user' => null,
190+
'vendor' => null,
191+
'partner' => null,
192+
'pwd' => null,
193+
'verbosity' => null,
194+
'BUTTONSOURCE' => $button,
195+
'tender' => 'C',
196+
],
197+
$this->returnSelf()
198+
],
199+
['USER1', 1, $this->returnSelf()],
200+
['USER2', '4b102efb018ad34bacea669f401fc8cb', $this->returnSelf()]
201+
);
202+
203+
$response = $this->graphqlController->dispatch($this->request);
204+
$responseData = $this->json->unserialize($response->getContent());
205+
206+
$this->assertArrayNotHasKey('errors', $responseData);
207+
$this->assertArrayHasKey('data', $responseData);
208+
209+
$this->assertEquals(
210+
$paymentMethod,
211+
$responseData['data']['setPaymentMethodOnCart']['cart']['selected_payment_method']['code']
212+
);
213+
214+
$this->assertTrue(
215+
isset($responseData['data']['placeOrder']['order']['order_id'])
216+
);
217+
218+
$this->assertEquals(
219+
'test_quote',
220+
$responseData['data']['placeOrder']['order']['order_id']
221+
);
222+
}
223+
224+
/**
225+
* @inheritdoc
226+
*/
227+
protected function tearDown()
228+
{
229+
$this->objectManager->removeSharedInstance(Gateway::class);
230+
}
231+
}

0 commit comments

Comments
 (0)