Skip to content

Commit 788540b

Browse files
committed
MC-32704: Storefront: My Downloadable Products tab on customer profile page
1 parent 42e615f commit 788540b

File tree

5 files changed

+407
-0
lines changed

5 files changed

+407
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
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\TestFramework\Downloadable\Model;
9+
10+
use Magento\Downloadable\Model\ResourceModel\Link\Purchased as PurchasedResource;
11+
use Magento\Downloadable\Model\ResourceModel\Link\Purchased\CollectionFactory;
12+
13+
/**
14+
* Delete records from downloadable_link_purchased associated with provided order
15+
*/
16+
class RemoveLinkPurchasedByOrderIncrementId
17+
{
18+
/** @var CollectionFactory */
19+
private $linkCollectionFactory;
20+
21+
/** @var PurchasedResource */
22+
private $purchasedResource;
23+
24+
/**
25+
* @param CollectionFactory $linkCollectionFactory
26+
* @param PurchasedResource $purchasedResource
27+
*/
28+
public function __construct(CollectionFactory $linkCollectionFactory, PurchasedResource $purchasedResource)
29+
{
30+
$this->linkCollectionFactory = $linkCollectionFactory;
31+
$this->purchasedResource = $purchasedResource;
32+
}
33+
34+
/**
35+
* Remove records from downloadable_link_purchased related to provided order
36+
*
37+
* @param string $orderIncrementId
38+
* @return void
39+
*/
40+
public function execute(string $orderIncrementId): void
41+
{
42+
$collection = $this->linkCollectionFactory->create();
43+
$collection->addFieldToFilter('order_increment_id', $orderIncrementId);
44+
foreach ($collection as $item) {
45+
$this->purchasedResource->delete($item);
46+
}
47+
}
48+
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
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\Downloadable\Block\Account;
9+
10+
use Magento\Framework\ObjectManagerInterface;
11+
use Magento\Framework\View\Result\Page;
12+
use Magento\Framework\View\Result\PageFactory;
13+
use Magento\TestFramework\Helper\Bootstrap;
14+
use PHPUnit\Framework\TestCase;
15+
16+
/**
17+
* Checks My Downloadable Product link displaying in account dashboard
18+
*
19+
* @magentoAppArea frontend
20+
* @magentoDbIsolation enabled
21+
*/
22+
class LinkTest extends TestCase
23+
{
24+
/** @var ObjectManagerInterface */
25+
private $objectManager;
26+
27+
/** @var Page */
28+
private $page;
29+
30+
/**
31+
* @inheritdoc
32+
*/
33+
protected function setUp()
34+
{
35+
parent::setUp();
36+
37+
$this->objectManager = Bootstrap::getObjectManager();
38+
$this->page = $this->objectManager->get(PageFactory::class)->create();
39+
}
40+
41+
/**
42+
* @return void
43+
*/
44+
public function testMyDownloadableProductLink(): void
45+
{
46+
$this->preparePage();
47+
$block = $this->page->getLayout()->getBlock('customer-account-navigation-downloadable-products-link');
48+
$this->assertNotFalse($block);
49+
$html = $block->toHtml();
50+
$this->assertContains('downloadable/customer/products', $html);
51+
$this->assertEquals('My Downloadable Products', strip_tags($html));
52+
}
53+
54+
/**
55+
* Prepare page before render
56+
*
57+
* @return void
58+
*/
59+
private function preparePage(): void
60+
{
61+
$this->page->addHandle([
62+
'default',
63+
'customer_account',
64+
]);
65+
$this->page->getLayout()->generateXml();
66+
}
67+
}
Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
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\Downloadable\Block\Customer\Products;
9+
10+
use Magento\Customer\Model\Session;
11+
use Magento\Framework\ObjectManagerInterface;
12+
use Magento\Framework\View\LayoutInterface;
13+
use Magento\Sales\Api\Data\OrderInterface;
14+
use Magento\Sales\Api\InvoiceOrderInterface;
15+
use Magento\Sales\Api\OrderRepositoryInterface;
16+
use Magento\Sales\Api\RefundOrderInterface;
17+
use Magento\Sales\Model\OrderFactory;
18+
use Magento\Sales\Model\OrderRepository;
19+
use Magento\TestFramework\Helper\Bootstrap;
20+
use Magento\TestFramework\Helper\Xpath;
21+
use PHPUnit\Framework\TestCase;
22+
23+
/**
24+
* Class to check My Downloadable products tab content
25+
*
26+
* @see ListProducts
27+
* @magentoAppArea frontend
28+
* @magentoAppIsolation enabled
29+
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
30+
*/
31+
class ListProductsTest extends TestCase
32+
{
33+
/** @var string */
34+
private $downloadLinkXpath = "//a[contains(@href, 'downloadable/download/link') and contains(text(), '%s')]";
35+
36+
/** @var string */
37+
private $statusXpath = "//table[@id='my-downloadable-products-table']"
38+
. "//td[@data-th='Status' and contains(text(), '%s')]";
39+
40+
/** @var ObjectManagerInterface */
41+
private $objectManager;
42+
43+
/** @var LayoutInterface */
44+
private $layout;
45+
46+
/** @var Session */
47+
private $customerSession;
48+
49+
/** @var OrderRepositoryInterface */
50+
private $orderRepository;
51+
52+
/** @var InvoiceOrderInterface */
53+
private $invoiceOrder;
54+
55+
/**
56+
* @inheritdoc
57+
*/
58+
protected function setUp()
59+
{
60+
parent::setUp();
61+
62+
$this->objectManager = Bootstrap::getObjectManager();
63+
$this->layout = $this->objectManager->get(LayoutInterface::class);
64+
$this->customerSession = $this->objectManager->get(Session::class);
65+
$this->orderRepository = $this->objectManager->get(OrderRepositoryInterface::class);
66+
$this->invoiceOrder = $this->objectManager->get(InvoiceOrderInterface::class);
67+
}
68+
69+
/**
70+
* @inheritdoc
71+
*/
72+
protected function tearDown()
73+
{
74+
$this->customerSession->logout();
75+
76+
parent::tearDown();
77+
}
78+
79+
/**
80+
* @return void
81+
*/
82+
public function testNoItems(): void
83+
{
84+
$html = $this->createBlock()->toHtml();
85+
$this->assertContains((string)__('You have not purchased any downloadable products yet.'), strip_tags($html));
86+
}
87+
88+
/**
89+
* @magentoDataFixture Magento/Downloadable/_files/order_with_customer_and_downloadable_product.php
90+
*
91+
* @return void
92+
*/
93+
public function testPendingOrder(): void
94+
{
95+
$this->customerSession->loginById(1);
96+
$this->assertEquals(
97+
0,
98+
Xpath::getElementsCountForXpath(
99+
sprintf($this->downloadLinkXpath, 'Downloadable Product Link'),
100+
$this->createBlock()->toHtml()
101+
),
102+
'The download link displayed'
103+
);
104+
}
105+
106+
/**
107+
* @magentoDataFixture Magento/Downloadable/_files/order_with_customer_and_downloadable_product.php
108+
*
109+
* @return void
110+
*/
111+
public function testCompleteOrder(): void
112+
{
113+
$order = $this->getOrder('100000001');
114+
$this->invoiceOrder->execute($order->getId());
115+
$this->customerSession->loginById(1);
116+
$html = $this->createBlock()->toHtml();
117+
$this->assertEquals(
118+
1,
119+
Xpath::getElementsCountForXpath(sprintf($this->downloadLinkXpath, 'Downloadable Product Link'), $html),
120+
'The download link is not found'
121+
);
122+
$this->assertEquals(
123+
1,
124+
Xpath::getElementsCountForXpath(sprintf($this->statusXpath, (string)__('Available')), $html),
125+
'Wrong status displayed'
126+
);
127+
}
128+
129+
/**
130+
* @magentoDataFixture Magento/Downloadable/_files/order_with_customer_and_downloadable_product.php
131+
*
132+
* @return void
133+
*/
134+
public function testClosedOrder(): void
135+
{
136+
$order = $this->getOrder('100000001');
137+
$this->invoiceOrder->execute($order->getId());
138+
$this->objectManager->removeSharedInstance(OrderRepository::class);
139+
$refundOrder = $this->objectManager->create(RefundOrderInterface::class);
140+
$refundOrder->execute($order->getId());
141+
$this->customerSession->loginById(1);
142+
$html = $this->createBlock()->toHtml();
143+
$this->assertEquals(
144+
0,
145+
Xpath::getElementsCountForXpath(sprintf($this->downloadLinkXpath, 'Downloadable Product Link'), $html),
146+
'The download link is displayed for closed order'
147+
);
148+
$this->assertEquals(
149+
1,
150+
Xpath::getElementsCountForXpath(sprintf($this->statusXpath, (string)__('Expired')), $html),
151+
'Wrong status displayed'
152+
);
153+
}
154+
155+
/**
156+
* Load order by increment id
157+
*
158+
* @param $orderIncrementId
159+
* @return OrderInterface
160+
*/
161+
private function getOrder($orderIncrementId): OrderInterface
162+
{
163+
$order = $this->objectManager->get(OrderFactory::class)->create();
164+
165+
return $order->loadByIncrementId($orderIncrementId);
166+
}
167+
168+
/**
169+
* Create ProductsList block
170+
*
171+
* @return ListProducts
172+
*/
173+
private function createBlock(): ListProducts
174+
{
175+
$block = $this->objectManager->create(ListProducts::class);
176+
$block->setTemplate('Magento_Downloadable::customer/products/list.phtml');
177+
$this->layout->addBlock($block, 'downloadable_customer_products_list');
178+
179+
return $block;
180+
}
181+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
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+
use Magento\Catalog\Api\Data\ProductInterface;
9+
use Magento\Downloadable\Api\Data\LinkInterface;
10+
use Magento\Downloadable\Model\Product\Type;
11+
use Magento\Sales\Api\OrderRepositoryInterface;
12+
use Magento\Sales\Model\Order;
13+
use Magento\Sales\Model\Order\Address;
14+
use Magento\Sales\Model\Order\AddressFactory;
15+
use Magento\Sales\Model\Order\ItemFactory;
16+
use Magento\Sales\Model\Order\PaymentFactory;
17+
use Magento\Sales\Model\OrderFactory;
18+
use Magento\Store\Model\StoreManagerInterface;
19+
20+
require __DIR__ . '/../../../Magento/Downloadable/_files/product_downloadable.php';
21+
require __DIR__ . '/../../../Magento/Customer/_files/customer.php';
22+
23+
$addressData = include __DIR__ . '/../../../Magento/Sales/_files/address_data.php';
24+
/** @var AddressFactory $addressFactory */
25+
$addressFactory = $objectManager->get(AddressFactory::class);
26+
$billingAddress = $addressFactory->create(['data' => $addressData]);
27+
$billingAddress->setAddressType(Address::TYPE_BILLING);
28+
/** @var ItemFactory $orderItemFactory */
29+
$orderItemFactory = $objectManager->get(ItemFactory::class);
30+
/** @var PaymentFactory $orderPaymentFactory */
31+
$orderPaymentFactory = $objectManager->get(PaymentFactory::class);
32+
/** @var StoreManagerInterface $storeManager */
33+
$storeManager = $objectManager->get(StoreManagerInterface::class);
34+
/** @var OrderRepositoryInterface $orderRepository */
35+
$orderRepository = $objectManager->create(OrderRepositoryInterface::class);
36+
/** @var OrderFactory $orderFactory */
37+
$orderFactory = $objectManager->get(OrderFactory::class);
38+
39+
$payment = $orderPaymentFactory->create();
40+
$payment->setMethod('checkmo')
41+
->setAdditionalInformation('last_trans_id', '11122')
42+
->setAdditionalInformation(
43+
'metadata',
44+
['type' => 'free', 'fraudulent' => false]
45+
);
46+
/** @var ProductInterface $product */
47+
$product = $productRepository->get('downloadable-product');
48+
/** @var LinkInterface $links */
49+
$links = $product->getExtensionAttributes()->getDownloadableProductLinks();
50+
$link = reset($links);
51+
52+
$orderItem = $orderItemFactory->create();
53+
$orderItem->setProductId($product->getId())
54+
->setQtyOrdered(1)
55+
->setBasePrice($product->getPrice())
56+
->setProductOptions(['links' => [$link->getId()]])
57+
->setPrice($product->getPrice())
58+
->setRowTotal($product->getPrice())
59+
->setProductType(Type::TYPE_DOWNLOADABLE)
60+
->setName($product->getName())
61+
->setSku($product->getSku());
62+
63+
$order = $orderFactory->create();
64+
$order->setIncrementId('100000001')
65+
->setState(Order::STATE_PROCESSING)
66+
->setStatus($order->getConfig()->getStateDefaultStatus(Order::STATE_PROCESSING))
67+
->setSubtotal(100)
68+
->setGrandTotal(100)
69+
->setBaseSubtotal(100)
70+
->setBaseGrandTotal(100)
71+
->setCustomerId($customer->getId())
72+
->setCustomerEmail($customer->getEmail())
73+
->setBillingAddress($billingAddress)
74+
->setStoreId($storeManager->getStore()->getId())
75+
->addItem($orderItem)
76+
->setPayment($payment);
77+
78+
$orderRepository->save($order);

0 commit comments

Comments
 (0)