diff --git a/app/code/Magento/Bundle/Model/Sales/Order/Pdf/Items/Invoice.php b/app/code/Magento/Bundle/Model/Sales/Order/Pdf/Items/Invoice.php
index 64e9f56dd65bc..a7f0a70b45219 100644
--- a/app/code/Magento/Bundle/Model/Sales/Order/Pdf/Items/Invoice.php
+++ b/app/code/Magento/Bundle/Model/Sales/Order/Pdf/Items/Invoice.php
@@ -8,6 +8,7 @@
namespace Magento\Bundle\Model\Sales\Order\Pdf\Items;
use Magento\Framework\Data\Collection\AbstractDb;
+use Magento\Framework\DataObject;
use Magento\Framework\Filesystem;
use Magento\Framework\Filter\FilterManager;
use Magento\Framework\Model\Context;
@@ -69,34 +70,38 @@ public function __construct(
}
/**
- * Draw item line
+ * Draw bundle product item line
*
* @return void
- * @SuppressWarnings(PHPMD.CyclomaticComplexity)
- * @SuppressWarnings(PHPMD.NPathComplexity)
- * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/
public function draw()
{
- $order = $this->getOrder();
- $item = $this->getItem();
- $pdf = $this->getPdf();
- $page = $this->getPage();
+ $draw = $this->drawChildrenItems();
+ $draw = $this->drawCustomOptions($draw);
+ $page = $this->getPdf()->drawLineBlocks($this->getPage(), $draw, ['table_header' => true]);
+
+ $this->setPage($page);
+ }
+
+ /**
+ * Draw bundle product children items
+ *
+ * @return array
+ */
+ private function drawChildrenItems(): array
+ {
$this->_setFontRegular();
- $items = $this->getChildren($item);
$prevOptionId = '';
$drawItems = [];
-
- foreach ($items as $childItem) {
- $line = [];
-
+ $optionId = 0;
+ $lines = [];
+ foreach ($this->getChildren($this->getItem()) as $childItem) {
+ $index = array_key_last($lines) !== null ? array_key_last($lines) + 1 : 0;
$attributes = $this->getSelectionAttributes($childItem);
if (is_array($attributes)) {
$optionId = $attributes['option_id'];
- } else {
- $optionId = 0;
}
if (!isset($drawItems[$optionId])) {
@@ -104,15 +109,13 @@ public function draw()
}
if ($childItem->getOrderItem()->getParentItem() && $prevOptionId != $attributes['option_id']) {
- $line[0] = [
+ $lines[$index][] = [
'font' => 'italic',
'text' => $this->string->split($attributes['option_label'], 45, true, true),
'feed' => 35,
];
- $drawItems[$optionId] = ['lines' => [$line], 'height' => 15];
-
- $line = [];
+ $index++;
$prevOptionId = $attributes['option_id'];
}
@@ -124,35 +127,97 @@ public function draw()
$feed = 35;
$name = $childItem->getName();
}
- $line[] = ['text' => $this->string->split($name, 35, true, true), 'feed' => $feed];
+ $lines[$index][] = ['text' => $this->string->split($name, 35, true, true), 'feed' => $feed];
- // draw SKUs
- if (!$childItem->getOrderItem()->getParentItem()) {
- $text = [];
- foreach ($this->string->split($item->getSku(), 17) as $part) {
- $text[] = $part;
- }
- $line[] = ['text' => $text, 'feed' => 255];
- }
+ $lines = $this->drawSkus($childItem, $lines);
- // draw prices
- if ($this->canShowPriceInfo($childItem)) {
- $price = $order->formatPriceTxt($childItem->getPrice());
- $line[] = ['text' => $price, 'feed' => 395, 'font' => 'bold', 'align' => 'right'];
- $line[] = ['text' => $childItem->getQty() * 1, 'feed' => 435, 'font' => 'bold'];
+ $lines = $this->drawPrices($childItem, $lines);
+ }
+ $drawItems[$optionId]['lines'] = $lines;
- $tax = $order->formatPriceTxt($childItem->getTaxAmount());
- $line[] = ['text' => $tax, 'feed' => 495, 'font' => 'bold', 'align' => 'right'];
+ return $drawItems;
+ }
- $row_total = $order->formatPriceTxt($childItem->getRowTotal());
- $line[] = ['text' => $row_total, 'feed' => 565, 'font' => 'bold', 'align' => 'right'];
+ /**
+ * Draw sku parts
+ *
+ * @param DataObject $childItem
+ * @param array $lines
+ * @return array
+ */
+ private function drawSkus(DataObject $childItem, array $lines): array
+ {
+ $index = array_key_last($lines);
+ if (!$childItem->getOrderItem()->getParentItem()) {
+ $text = [];
+ foreach ($this->string->split($this->getItem()->getSku(), 17) as $part) {
+ $text[] = $part;
}
+ $lines[$index][] = ['text' => $text, 'feed' => 255];
+ }
+
+ return $lines;
+ }
- $drawItems[$optionId]['lines'][] = $line;
+ /**
+ * Draw prices for bundle product children items
+ *
+ * @param DataObject $childItem
+ * @param array $lines
+ * @return array
+ */
+ private function drawPrices(DataObject $childItem, array $lines): array
+ {
+ $index = array_key_last($lines);
+ if ($this->canShowPriceInfo($childItem)) {
+ $lines[$index][] = ['text' => $childItem->getQty() * 1, 'feed' => 435, 'align' => 'right'];
+
+ $tax = $this->getOrder()->formatPriceTxt($childItem->getTaxAmount());
+ $lines[$index][] = ['text' => $tax, 'feed' => 495, 'font' => 'bold', 'align' => 'right'];
+
+ $item = $this->getItem();
+ $this->_item = $childItem;
+ $feedPrice = 380;
+ $feedSubtotal = $feedPrice + 185;
+ foreach ($this->getItemPricesForDisplay() as $priceData) {
+ if (isset($priceData['label'])) {
+ // draw Price label
+ $lines[$index][] = ['text' => $priceData['label'], 'feed' => $feedPrice, 'align' => 'right'];
+ // draw Subtotal label
+ $lines[$index][] = ['text' => $priceData['label'], 'feed' => $feedSubtotal, 'align' => 'right'];
+ $index++;
+ }
+ // draw Price
+ $lines[$index][] = [
+ 'text' => $priceData['price'],
+ 'feed' => $feedPrice,
+ 'font' => 'bold',
+ 'align' => 'right',
+ ];
+ // draw Subtotal
+ $lines[$index][] = [
+ 'text' => $priceData['subtotal'],
+ 'feed' => $feedSubtotal,
+ 'font' => 'bold',
+ 'align' => 'right',
+ ];
+ $index++;
+ }
+ $this->_item = $item;
}
- // custom options
- $options = $item->getOrderItem()->getProductOptions();
+ return $lines;
+ }
+
+ /**
+ * Draw bundle product custom options
+ *
+ * @param array $draw
+ * @return array
+ */
+ private function drawCustomOptions(array $draw): array
+ {
+ $options = $this->getItem()->getOrderItem()->getProductOptions();
if ($options && isset($options['options'])) {
foreach ($options['options'] as $option) {
$lines = [];
@@ -180,12 +245,10 @@ public function draw()
$lines[][] = ['text' => $text, 'feed' => 40];
}
- $drawItems[] = ['lines' => $lines, 'height' => 15];
+ $draw[] = ['lines' => $lines, 'height' => 15];
}
}
- $page = $pdf->drawLineBlocks($page, $drawItems, ['table_header' => true]);
-
- $this->setPage($page);
+ return $draw;
}
}
diff --git a/app/code/Magento/Bundle/Test/Unit/Model/Sales/Order/Pdf/Items/InvoiceTest.php b/app/code/Magento/Bundle/Test/Unit/Model/Sales/Order/Pdf/Items/InvoiceTest.php
new file mode 100644
index 0000000000000..e5bf94241dbd9
--- /dev/null
+++ b/app/code/Magento/Bundle/Test/Unit/Model/Sales/Order/Pdf/Items/InvoiceTest.php
@@ -0,0 +1,184 @@
+createMock(Context::class);
+ $registryMock = $this->createMock(Registry::class);
+ $this->taxDataMock = $this->createMock(Data::class);
+ $directoryMock = $this->createMock(Filesystem\Directory\Read::class);
+ $directoryMock->expects($this->any())->method('getAbsolutePath')->willReturn('');
+ $filesystemMock = $this->createMock(Filesystem::class);
+ $filesystemMock->expects($this->any())->method('getDirectoryRead')->willReturn($directoryMock);
+ $filterManagerMock = $this->createMock(FilterManager::class);
+ $stringUtilsMock = $this->createMock(StringUtils::class);
+ $stringUtilsMock->expects($this->any())->method('split')->willReturnArgument(0);
+ $resourceMock = $this->createMock(AbstractResource::class);
+ $collectionMock = $this->createMock(AbstractDb::class);
+ $serializerMock = $this->createMock(Json::class);
+
+ $this->model = $this->getMockBuilder(Invoice::class)
+ ->setConstructorArgs(
+ [
+ $contextMock,
+ $registryMock,
+ $this->taxDataMock,
+ $filesystemMock,
+ $filterManagerMock,
+ $stringUtilsMock,
+ $serializerMock,
+ $resourceMock,
+ $collectionMock,
+ [],
+ ]
+ )
+ ->onlyMethods(
+ [
+ '_setFontRegular',
+ 'getChildren',
+ 'isShipmentSeparately',
+ 'isChildCalculated',
+ 'getValueHtml',
+ 'getSelectionAttributes',
+ ]
+ )
+ ->getMock();
+ }
+
+ /**
+ * @dataProvider \Magento\Bundle\Test\Unit\Model\Sales\Order\Pdf\Items\InvoiceTestProvider::getData
+ * @param array $expected
+ * @param string $method
+ */
+ public function testDrawPrice(array $expected, string $method): void
+ {
+ $this->taxDataMock->expects($this->any())->method($method)->willReturn(true);
+ $pageMock = $this->createMock(Zend_Pdf_Page::class);
+ $this->model->setPage($pageMock);
+ $pdfMock = $this->createMock(InvoicePdf::class);
+ $pdfMock->expects($this->any())->method('drawLineBlocks')->with(
+ $pageMock,
+ $expected,
+ ['table_header' => true]
+ )->willReturn($pageMock);
+ $this->model->setPdf($pdfMock);
+
+ $this->prepareModel();
+ $this->model->draw();
+ }
+
+ /**
+ * Prepare invoice draw model for test execution
+ *
+ * @return void
+ */
+ private function prepareModel(): void
+ {
+ $parentItem = new DataObject(
+ [
+ 'sku' => 'bundle-simple',
+ 'name' => 'Bundle',
+ 'order_item' => new DataObject(
+ [
+ 'product_options' => [],
+ ]
+ ),
+ ]
+ );
+ $items = [
+ new DataObject(
+ [
+ 'name' => 'Simple1',
+ 'sku' => 'simple1',
+ 'price' => '10.00',
+ 'price_incl_tax' => '10.83',
+ 'row_total' => '20.00',
+ 'row_total_incl_tax' => '21.66',
+ 'qty' => '2',
+ 'tax_amount' => '1.66',
+ 'order_item' => new DataObject(
+ [
+ 'parent_item' => $parentItem,
+ ]
+ ),
+ ]
+ ),
+ new DataObject(
+ [
+ 'name' => 'Simple2',
+ 'sku' => 'simple2',
+ 'price' => '5.00',
+ 'price_incl_tax' => '5.41',
+ 'row_total' => '10.00',
+ 'row_total_incl_tax' => '10.83',
+ 'qty' => '2',
+ 'tax_amount' => '0.83',
+ 'order_item' => new DataObject(
+ [
+ 'parent_item' => $parentItem,
+ ]
+ ),
+ ]
+ ),
+ ];
+ $orderMock = $this->createMock(Order::class);
+
+ $this->model->expects($this->any())->method('getChildren')->willReturn($items);
+ $this->model->expects($this->any())->method('isShipmentSeparately')->willReturn(false);
+ $this->model->expects($this->any())->method('isChildCalculated')->willReturn(true);
+ $this->model->expects($this->at(2))->method('getSelectionAttributes')->willReturn(
+ ['option_id' => 1, 'option_label' => 'test option']
+ );
+ $this->model->expects($this->at(3))->method('getValueHtml')->willReturn($items[0]->getName());
+ $this->model->expects($this->at(5))->method('getSelectionAttributes')->willReturn(
+ ['option_id' => 1, 'option_label' => 'second option']
+ );
+ $this->model->expects($this->at(6))->method('getValueHtml')->willReturn($items[1]->getName());
+
+ $orderMock->expects($this->any())->method('formatPriceTxt')->willReturnArgument(0);
+ $this->model->setOrder($orderMock);
+ $this->model->setItem($parentItem);
+ }
+}
diff --git a/app/code/Magento/Bundle/Test/Unit/Model/Sales/Order/Pdf/Items/InvoiceTestProvider.php b/app/code/Magento/Bundle/Test/Unit/Model/Sales/Order/Pdf/Items/InvoiceTestProvider.php
new file mode 100644
index 0000000000000..7de3d383d006e
--- /dev/null
+++ b/app/code/Magento/Bundle/Test/Unit/Model/Sales/Order/Pdf/Items/InvoiceTestProvider.php
@@ -0,0 +1,329 @@
+ [
+ 'expected' => [
+ 1 => [
+ 'height' => 15,
+ 'lines' => [
+ [
+ [
+ 'text' => 'test option',
+ 'feed' => 35,
+ 'font' => 'italic',
+
+ ],
+ ],
+ [
+ [
+ 'text' => 'Simple1',
+ 'feed' => 40,
+ ],
+ [
+ 'text' => 2,
+ 'feed' => 435,
+ 'align' => 'right',
+ ],
+ [
+ 'text' => 1.66,
+ 'feed' => 495,
+ 'font' => 'bold',
+ 'align' => 'right',
+ ],
+ [
+ 'text' => 'Excl. Tax:',
+ 'feed' => 380,
+ 'align' => 'right',
+ ],
+ [
+ 'text' => 'Excl. Tax:',
+ 'feed' => 565,
+ 'align' => 'right',
+ ],
+ ],
+ [
+ [
+ 'text' => '10.00',
+ 'feed' => 380,
+ 'font' => 'bold',
+ 'align' => 'right',
+ ],
+ [
+ 'text' => '20.00',
+ 'feed' => 565,
+ 'font' => 'bold',
+ 'align' => 'right',
+ ],
+ ],
+ [
+ [
+ 'text' => 'Incl. Tax:',
+ 'feed' => 380,
+ 'align' => 'right',
+ ],
+ [
+ 'text' => 'Incl. Tax:',
+ 'feed' => 565,
+ 'align' => 'right',
+ ],
+ ],
+ [
+ [
+ 'text' => '10.83',
+ 'feed' => 380,
+ 'font' => 'bold',
+ 'align' => 'right',
+ ],
+ [
+ 'text' => '21.66',
+ 'feed' => 565,
+ 'font' => 'bold',
+ 'align' => 'right',
+ ],
+ ],
+ [
+ [
+ 'text' => 'Simple2',
+ 'feed' => 40,
+ ],
+ [
+ 'text' => 2,
+ 'feed' => 435,
+ 'align' => 'right',
+ ],
+ [
+ 'text' => 0.83,
+ 'feed' => 495,
+ 'font' => 'bold',
+ 'align' => 'right',
+ ],
+ [
+ 'text' => 'Excl. Tax:',
+ 'feed' => 380,
+ 'align' => 'right',
+ ],
+ [
+ 'text' => 'Excl. Tax:',
+ 'feed' => 565,
+ 'align' => 'right',
+ ],
+ ],
+ [
+ [
+ 'text' => '5.00',
+ 'feed' => 380,
+ 'font' => 'bold',
+ 'align' => 'right',
+ ],
+ [
+ 'text' => '10.00',
+ 'feed' => 565,
+ 'font' => 'bold',
+ 'align' => 'right',
+ ],
+ ],
+ [
+ [
+ 'text' => 'Incl. Tax:',
+ 'feed' => 380,
+ 'align' => 'right',
+ ],
+ [
+ 'text' => 'Incl. Tax:',
+ 'feed' => 565,
+ 'align' => 'right',
+ ],
+ ],
+ [
+ [
+ 'text' => '5.41',
+ 'feed' => 380,
+ 'font' => 'bold',
+ 'align' => 'right',
+ ],
+ [
+ 'text' => '10.83',
+ 'feed' => 565,
+ 'font' => 'bold',
+ 'align' => 'right',
+ ],
+ ],
+ ],
+ ],
+ ],
+ 'tax_mock_method' => 'displaySalesBothPrices',
+ ],
+ 'including_tax' => [
+ 'expected' => [
+ 1 => [
+ 'height' => 15,
+ 'lines' => [
+ [
+ [
+ 'text' => 'test option',
+ 'feed' => 35,
+ 'font' => 'italic',
+ ],
+ ],
+ [
+ [
+ 'text' => 'Simple1',
+ 'feed' => 40,
+ ],
+ [
+ 'text' => 2,
+ 'feed' => 435,
+ 'align' => 'right',
+ ],
+ [
+ 'text' => 1.66,
+ 'feed' => 495,
+ 'font' => 'bold',
+ 'align' => 'right',
+ ],
+ [
+ 'text' => '10.83',
+ 'feed' => 380,
+ 'font' => 'bold',
+ 'align' => 'right',
+ ],
+ [
+ 'text' => '21.66',
+ 'feed' => 565,
+ 'font' => 'bold',
+ 'align' => 'right',
+ ],
+ ],
+ [
+ [
+ 'text' => 'Simple2',
+ 'feed' => 40,
+ ],
+ [
+ 'text' => 2,
+ 'feed' => 435,
+ 'align' => 'right',
+ ],
+ [
+ 'text' => 0.83,
+ 'feed' => 495,
+ 'font' => 'bold',
+ 'align' => 'right',
+ ],
+ [
+ 'text' => '5.41',
+ 'feed' => 380,
+ 'font' => 'bold',
+ 'align' => 'right',
+ ],
+ [
+ 'text' => '10.83',
+ 'feed' => 565,
+ 'font' => 'bold',
+ 'align' => 'right',
+ ],
+ ],
+ ],
+ ],
+ ],
+ 'tax_mock_method' => 'displaySalesPriceInclTax',
+ ],
+ 'excluding_tax' => [
+ 'expected' => [
+ 1 => [
+ 'height' => 15,
+ 'lines' => [
+ [
+ [
+ 'text' => 'test option',
+ 'feed' => 35,
+ 'font' => 'italic',
+
+ ],
+ ],
+ [
+ [
+ 'text' => 'Simple1',
+ 'feed' => 40,
+ ],
+ [
+ 'text' => 2,
+ 'feed' => 435,
+ 'align' => 'right',
+ ],
+ [
+ 'text' => 1.66,
+ 'feed' => 495,
+ 'font' => 'bold',
+ 'align' => 'right',
+ ],
+ [
+ 'text' => '10.00',
+ 'feed' => 380,
+ 'font' => 'bold',
+ 'align' => 'right',
+ ],
+ [
+ 'text' => '20.00',
+ 'feed' => 565,
+ 'font' => 'bold',
+ 'align' => 'right',
+ ],
+ ],
+ [
+ [
+ 'text' => 'Simple2',
+ 'feed' => 40,
+ ],
+ [
+ 'text' => 2,
+ 'feed' => 435,
+ 'align' => 'right',
+ ],
+ [
+ 'text' => 0.83,
+ 'feed' => 495,
+ 'font' => 'bold',
+ 'align' => 'right',
+ ],
+ [
+ 'text' => '5.00',
+ 'feed' => 380,
+ 'font' => 'bold',
+ 'align' => 'right',
+ ],
+ [
+ 'text' => '10.00',
+ 'feed' => 565,
+ 'font' => 'bold',
+ 'align' => 'right',
+ ],
+ ],
+ ],
+ ],
+ ],
+ 'tax_mock_method' => 'displaySalesPriceExclTax',
+ ],
+ ];
+ }
+}
diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/CreateProductAttributeEntityTest/CreateProductAttributeEntityDateTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/CreateProductAttributeEntityTest/CreateProductAttributeEntityDateTest.xml
index d1f7adb8a902c..9d805b2cf7930 100644
--- a/app/code/Magento/Catalog/Test/Mftf/Test/CreateProductAttributeEntityTest/CreateProductAttributeEntityDateTest.xml
+++ b/app/code/Magento/Catalog/Test/Mftf/Test/CreateProductAttributeEntityTest/CreateProductAttributeEntityDateTest.xml
@@ -14,8 +14,8 @@
-
-
+
+
@@ -34,7 +34,7 @@
-
+
diff --git a/app/code/Magento/Customer/Ui/Component/Listing/Column/Confirmation.php b/app/code/Magento/Customer/Ui/Component/Listing/Column/Confirmation.php
index 26cac677ccd10..6215909a1fbee 100644
--- a/app/code/Magento/Customer/Ui/Component/Listing/Column/Confirmation.php
+++ b/app/code/Magento/Customer/Ui/Component/Listing/Column/Confirmation.php
@@ -6,6 +6,7 @@
namespace Magento\Customer\Ui\Component\Listing\Column;
use Magento\Framework\App\Config\ScopeConfigInterface;
+use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Framework\View\Element\UiComponent\ContextInterface;
use Magento\Framework\View\Element\UiComponentFactory;
use Magento\Ui\Component\Listing\Columns\Column;
@@ -28,7 +29,7 @@ class Confirmation extends Column
* @param ScopeConfigInterface $scopeConfig @deprecated
* @param array $components
* @param array $data
- * @param AccountConfirmation $accountConfirmation
+ * @param AccountConfirmation|null $accountConfirmation
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function __construct(
@@ -65,13 +66,7 @@ public function prepareDataSource(array $dataSource)
*/
private function getFieldLabel(array $item)
{
- $isConfirmationRequired = $this->accountConfirmation->isConfirmationRequired(
- $item['website_id'][0] ?? null,
- $item[$item['id_field_name']],
- $item['email']
- );
-
- if ($isConfirmationRequired) {
+ if ($this->getIsConfirmationRequired($item)) {
if ($item[$this->getData('name')] === null) {
return __('Confirmed');
}
@@ -79,4 +74,27 @@ private function getFieldLabel(array $item)
}
return __('Confirmation Not Required');
}
+
+ /**
+ * Retrieve is confirmation required flag for customer considering requested website may not exist.
+ *
+ * @param array $customer
+ * @return bool
+ */
+ private function getIsConfirmationRequired(array $customer): bool
+ {
+ try {
+ return $this->accountConfirmation->isConfirmationRequired(
+ $customer['website_id'][0] ?? null,
+ $customer[$customer['id_field_name']],
+ $customer['email']
+ );
+ } catch (NoSuchEntityException $e) {
+ return $this->accountConfirmation->isConfirmationRequired(
+ null,
+ $customer[$customer['id_field_name']],
+ $customer['email']
+ );
+ }
+ }
}
diff --git a/app/code/Magento/MessageQueue/Model/ResourceModel/Lock.php b/app/code/Magento/MessageQueue/Model/ResourceModel/Lock.php
index 16c02a7505664..00399e30e8b72 100644
--- a/app/code/Magento/MessageQueue/Model/ResourceModel/Lock.php
+++ b/app/code/Magento/MessageQueue/Model/ResourceModel/Lock.php
@@ -5,46 +5,52 @@
*/
namespace Magento\MessageQueue\Model\ResourceModel;
-use \Magento\Framework\MessageQueue\Lock\ReaderInterface;
-use \Magento\Framework\MessageQueue\Lock\WriterInterface;
+use DateInterval;
+use DateTime;
+use Magento\Framework\MessageQueue\Lock\ReaderInterface;
+use Magento\Framework\MessageQueue\Lock\WriterInterface;
+use Magento\Framework\MessageQueue\LockInterface;
+use Magento\Framework\Model\ResourceModel\Db\AbstractDb;
+use Magento\Framework\Model\ResourceModel\Db\Context;
+use Magento\MessageQueue\Model\LockFactory;
/**
* Class Lock to handle database lock table db transactions.
*/
-class Lock extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb implements ReaderInterface, WriterInterface
+class Lock extends AbstractDb implements ReaderInterface, WriterInterface
{
/**#@+
* Constants
*/
- const QUEUE_LOCK_TABLE = 'queue_lock';
+ public const QUEUE_LOCK_TABLE = 'queue_lock';
/**#@-*/
/**#@-*/
private $dateTime;
/**
- * @var \Magento\MessageQueue\Model\LockFactory
+ * @var LockFactory
*/
private $lockFactory;
/**
- * @var integer
+ * @var int
*/
private $interval;
/**
* Initialize dependencies.
*
- * @param \Magento\Framework\Model\ResourceModel\Db\Context $context
+ * @param Context $context
* @param \Magento\Framework\Stdlib\DateTime\DateTime $dateTime
- * @param \Magento\MessageQueue\Model\LockFactory $lockFactory
- * @param null $connectionName
- * @param integer $interval
+ * @param LockFactory $lockFactory
+ * @param ?string $connectionName
+ * @param int $interval
*/
public function __construct(
- \Magento\Framework\Model\ResourceModel\Db\Context $context,
+ Context $context,
\Magento\Framework\Stdlib\DateTime\DateTime $dateTime,
- \Magento\MessageQueue\Model\LockFactory $lockFactory,
+ LockFactory $lockFactory,
$connectionName = null,
$interval = 86400
) {
@@ -55,7 +61,7 @@ public function __construct(
}
/**
- * {@inheritDoc}
+ * @inheritdoc
*/
protected function _construct()
{
@@ -63,9 +69,9 @@ protected function _construct()
}
/**
- * {@inheritDoc}
+ * @inheritdoc
*/
- public function read(\Magento\Framework\MessageQueue\LockInterface $lock, $code)
+ public function read(LockInterface $lock, $code)
{
$object = $this->lockFactory->create();
$object->load($code, 'message_code');
@@ -75,23 +81,25 @@ public function read(\Magento\Framework\MessageQueue\LockInterface $lock, $code)
}
/**
- * {@inheritDoc}
+ * @inheritdoc
*/
- public function saveLock(\Magento\Framework\MessageQueue\LockInterface $lock)
+ public function saveLock(LockInterface $lock)
{
$object = $this->lockFactory->create();
$object->setMessageCode($lock->getMessageCode());
$object->setCreatedAt($this->dateTime->gmtTimestamp());
$object->save();
+ $lock->setId($object->getId());
+ $lock->setCreatedAt($object->getCreatedAt());
}
/**
- * {@inheritDoc}
+ * @inheritdoc
*/
public function releaseOutdatedLocks()
{
- $date = (new \DateTime())->setTimestamp($this->dateTime->gmtTimestamp());
- $date->add(new \DateInterval('PT' . $this->interval . 'S'));
+ $date = (new DateTime())->setTimestamp($this->dateTime->gmtTimestamp());
+ $date->add(new DateInterval('PT' . $this->interval . 'S'));
$this->getConnection()->delete($this->getTable(self::QUEUE_LOCK_TABLE), ['created_at <= ?' => $date]);
}
}
diff --git a/app/code/Magento/Sales/Model/AdminOrder/Create.php b/app/code/Magento/Sales/Model/AdminOrder/Create.php
index 6bd6e8e4e83e1..4469bb1496f3c 100644
--- a/app/code/Magento/Sales/Model/AdminOrder/Create.php
+++ b/app/code/Magento/Sales/Model/AdminOrder/Create.php
@@ -1755,10 +1755,9 @@ public function importPostData($data)
if (isset($data['comment'])) {
$this->getQuote()->addData($data['comment']);
- if (empty($data['comment']['customer_note_notify'])) {
- $this->getQuote()->setCustomerNoteNotify(false);
- } else {
- $this->getQuote()->setCustomerNoteNotify(true);
+ if ($this->getIsValidate()) {
+ $notify = !empty($data['comment']['customer_note_notify']);
+ $this->getQuote()->setCustomerNoteNotify($notify);
}
}
diff --git a/app/code/Magento/Sales/Model/Order/Invoice.php b/app/code/Magento/Sales/Model/Order/Invoice.php
index 14dd0b14ac1f3..50bbb3083a9ea 100644
--- a/app/code/Magento/Sales/Model/Order/Invoice.php
+++ b/app/code/Magento/Sales/Model/Order/Invoice.php
@@ -679,6 +679,11 @@ public function register()
public function isLast()
{
foreach ($this->getAllItems() as $item) {
+ $orderItem = $item->getOrderItem();
+ if ($orderItem->isDummy()) {
+ continue;
+ }
+
if (!$item->isLast()) {
return false;
}
diff --git a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js
index 0ac35df78e001..45dfaa40f87df 100644
--- a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js
+++ b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js
@@ -620,15 +620,12 @@ define([
* @param {Array} data
*/
parsePagesData: function (data) {
- var pages;
-
this.relatedData = this.deleteProperty ?
_.filter(data, function (elem) {
return elem && elem[this.deleteProperty] !== this.deleteValue;
}, this) : data;
- pages = Math.ceil(this.relatedData.length / this.pageSize) || 1;
- this.pages(pages);
+ this._updatePagesQuantity();
},
/**
@@ -885,6 +882,18 @@ define([
this._sort();
},
+ /**
+ * Update number of pages.
+ *
+ * @private
+ * @return void
+ */
+ _updatePagesQuantity: function () {
+ var pages = Math.ceil(this.relatedData.length / this.pageSize) || 1;
+
+ this.pages(pages);
+ },
+
/**
* Reduce the number of pages
*
@@ -960,6 +969,7 @@ define([
reload: function () {
this.clear();
this.initChildren(false, true);
+ this._updatePagesQuantity();
/* After change page size need to check existing current page */
this._reducePages();
diff --git a/dev/tests/integration/_files/Magento/TestModuleMysqlMq/Model/Processor.php b/dev/tests/integration/_files/Magento/TestModuleMysqlMq/Model/Processor.php
index fb6fd4c5c2802..3d2f722ccb60e 100644
--- a/dev/tests/integration/_files/Magento/TestModuleMysqlMq/Model/Processor.php
+++ b/dev/tests/integration/_files/Magento/TestModuleMysqlMq/Model/Processor.php
@@ -5,13 +5,16 @@
*/
namespace Magento\TestModuleMysqlMq\Model;
+use LogicException;
+use Magento\Framework\MessageQueue\ConnectionLostException;
+
/**
* Test message processor is used by \Magento\MysqlMq\Model\PublisherConsumerTest
*/
class Processor
{
/**
- * @param \Magento\TestModuleMysqlMq\Model\DataObject $message
+ * @param DataObject $message
*/
public function processMessage($message)
{
@@ -23,7 +26,7 @@ public function processMessage($message)
}
/**
- * @param \Magento\TestModuleMysqlMq\Model\DataObject $message
+ * @param DataObject $message
*/
public function processObjectCreated($message)
{
@@ -35,7 +38,7 @@ public function processObjectCreated($message)
}
/**
- * @param \Magento\TestModuleMysqlMq\Model\DataObject $message
+ * @param DataObject $message
*/
public function processCustomObjectCreated($message)
{
@@ -47,7 +50,7 @@ public function processCustomObjectCreated($message)
}
/**
- * @param \Magento\TestModuleMysqlMq\Model\DataObject $message
+ * @param DataObject $message
*/
public function processObjectUpdated($message)
{
@@ -59,13 +62,23 @@ public function processObjectUpdated($message)
}
/**
- * @param \Magento\TestModuleMysqlMq\Model\DataObject $message
+ * @param DataObject $message
*/
public function processMessageWithException($message)
{
file_put_contents($message->getOutputPath(), "Exception processing {$message->getEntityId()}");
- throw new \LogicException(
+ throw new LogicException(
"Exception during message processing happened. Entity: {{$message->getEntityId()}}"
);
}
+
+ /**
+ * @throws ConnectionLostException
+ */
+ public function processMessageWithConnectionException()
+ {
+ throw new ConnectionLostException(
+ "Connection exception during message processing happened."
+ );
+ }
}
diff --git a/dev/tests/integration/_files/Magento/TestModuleMysqlMq/etc/communication.xml b/dev/tests/integration/_files/Magento/TestModuleMysqlMq/etc/communication.xml
index 4d6269dbb7920..1a5a5feb11324 100644
--- a/dev/tests/integration/_files/Magento/TestModuleMysqlMq/etc/communication.xml
+++ b/dev/tests/integration/_files/Magento/TestModuleMysqlMq/etc/communication.xml
@@ -7,6 +7,7 @@
-->
+
diff --git a/dev/tests/integration/_files/Magento/TestModuleMysqlMq/etc/queue.xml b/dev/tests/integration/_files/Magento/TestModuleMysqlMq/etc/queue.xml
index 362237c0c5e62..c879b271c6651 100644
--- a/dev/tests/integration/_files/Magento/TestModuleMysqlMq/etc/queue.xml
+++ b/dev/tests/integration/_files/Magento/TestModuleMysqlMq/etc/queue.xml
@@ -9,6 +9,9 @@
+
+
+
diff --git a/dev/tests/integration/_files/Magento/TestModuleMysqlMq/etc/queue_consumer.xml b/dev/tests/integration/_files/Magento/TestModuleMysqlMq/etc/queue_consumer.xml
index bb495a123a05d..6a3916a23b43b 100644
--- a/dev/tests/integration/_files/Magento/TestModuleMysqlMq/etc/queue_consumer.xml
+++ b/dev/tests/integration/_files/Magento/TestModuleMysqlMq/etc/queue_consumer.xml
@@ -10,5 +10,6 @@
+
diff --git a/dev/tests/integration/_files/Magento/TestModuleMysqlMq/etc/queue_publisher.xml b/dev/tests/integration/_files/Magento/TestModuleMysqlMq/etc/queue_publisher.xml
index a665e10ef5f14..639503a936cb5 100644
--- a/dev/tests/integration/_files/Magento/TestModuleMysqlMq/etc/queue_publisher.xml
+++ b/dev/tests/integration/_files/Magento/TestModuleMysqlMq/etc/queue_publisher.xml
@@ -9,6 +9,9 @@
+
+
+
diff --git a/dev/tests/integration/_files/Magento/TestModuleMysqlMq/etc/queue_topology.xml b/dev/tests/integration/_files/Magento/TestModuleMysqlMq/etc/queue_topology.xml
index 2df5485ee3447..3612438c37f4a 100644
--- a/dev/tests/integration/_files/Magento/TestModuleMysqlMq/etc/queue_topology.xml
+++ b/dev/tests/integration/_files/Magento/TestModuleMysqlMq/etc/queue_topology.xml
@@ -9,6 +9,7 @@
+
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Block/Product/View/Options/Type/DateTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Block/Product/View/Options/Type/DateTest.php
index 91a54d8fc13fa..d21fdf190c0b8 100644
--- a/dev/tests/integration/testsuite/Magento/Catalog/Block/Product/View/Options/Type/DateTest.php
+++ b/dev/tests/integration/testsuite/Magento/Catalog/Block/Product/View/Options/Type/DateTest.php
@@ -20,6 +20,7 @@
/**
* @magentoDataFixture Magento/Catalog/_files/product_simple.php
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
class DateTest extends TestCase
{
@@ -96,9 +97,10 @@ protected function tearDown(): void
}
/**
- * @magentoAppArea frontend
* @param array $data
* @param array $expected
+ * @magentoAppArea frontend
+ * @magentoConfigFixture current_store catalog/custom_options/year_range 2020,2030
* @dataProvider toHtmlWithDropDownDataProvider
*/
public function testToHtmlWithDropDown(array $data, array $expected): void
@@ -108,11 +110,12 @@ public function testToHtmlWithDropDown(array $data, array $expected): void
}
/**
- * @magentoAppArea frontend
- * @magentoConfigFixture current_store catalog/custom_options/use_calendar 1
* @param array $data
* @param array $expected
* @param string|null $locale
+ * @magentoAppArea frontend
+ * @magentoConfigFixture current_store catalog/custom_options/use_calendar 1
+ * @magentoConfigFixture current_store catalog/custom_options/year_range 2020,2030
* @dataProvider toHtmlWithCalendarDataProvider
*/
public function testToHtmlWithCalendar(array $data, array $expected, ?string $locale = null): void
diff --git a/dev/tests/integration/testsuite/Magento/Customer/Ui/Component/Listing/Column/ConfirmationTest.php b/dev/tests/integration/testsuite/Magento/Customer/Ui/Component/Listing/Column/ConfirmationTest.php
new file mode 100644
index 0000000000000..24fe443c8c796
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Customer/Ui/Component/Listing/Column/ConfirmationTest.php
@@ -0,0 +1,127 @@
+confirmation = Bootstrap::getObjectManager()->create(
+ Confirmation::class,
+ [
+ 'components' => [],
+ 'data' => ['name' => 'confirmation'],
+ ]
+ );
+ }
+
+ /**
+ * Verify Confirmation::prepareDataSource() won't throw exception in case requested website doesn't exist.
+ *
+ * @param array $customerDataSource
+ * @param array $expectedResult
+ * @magentoConfigFixture base_website customer/create_account/confirm 1
+ * @dataProvider customersDataProvider
+ *
+ * @return void
+ */
+ public function testPrepareDataSource(array $customerDataSource, array $expectedResult): void
+ {
+ $result = $this->confirmation->prepareDataSource($customerDataSource);
+
+ self::assertEquals($expectedResult, $result);
+ }
+
+ /**
+ * CustomerDataSource data provider.
+ *
+ * @return array
+ */
+ public function customersDataProvider(): array
+ {
+ return [
+ [
+ 'customerDataSource' => [
+ 'data' => [
+ 'items' => [
+ [
+ 'id_field_name' => 'entity_id',
+ 'entity_id' => '1',
+ 'name' => 'John Doe',
+ 'email' => 'john.doe@example.com',
+ 'group_id' => ['1'],
+ 'created_at' => '2020-12-28 07:05:50',
+ 'website_id' => ['1'],
+ 'confirmation' => false,
+ 'created_in' => 'Default Store View',
+ ],
+ [
+ 'id_field_name' => 'entity_id',
+ 'entity_id' => '2',
+ 'name' => 'Jane Doe',
+ 'email' => 'jane.doe@example.com',
+ 'group_id' => ['1'],
+ 'created_at' => '2020-12-28 07:06:17',
+ 'website_id' => ['999999999'],
+ 'confirmation' => null,
+ 'created_in' => 'CustomStoreViewWhichDoesNotExistAnymore',
+ ],
+ ],
+ 'totalRecords' => 2,
+ ],
+ ],
+ 'expectedResult' => [
+ 'data' => [
+ 'items' => [
+ [
+ 'id_field_name' => 'entity_id',
+ 'entity_id' => '1',
+ 'name' => 'John Doe',
+ 'email' => 'john.doe@example.com',
+ 'group_id' => ['1'],
+ 'created_at' => '2020-12-28 07:05:50',
+ 'website_id' => ['1'],
+ 'confirmation' => __('Confirmation Required'),
+ 'created_in' => 'Default Store View',
+ ],
+ [
+ 'id_field_name' => 'entity_id',
+ 'entity_id' => '2',
+ 'name' => 'Jane Doe',
+ 'email' => 'jane.doe@example.com',
+ 'group_id' => ['1'],
+ 'created_at' => '2020-12-28 07:06:17',
+ 'website_id' => ['999999999'],
+ 'confirmation' => __('Confirmed'),
+ 'created_in' => 'CustomStoreViewWhichDoesNotExistAnymore',
+ ],
+ ],
+ 'totalRecords' => 2,
+ ],
+ ],
+ ],
+ ];
+ }
+}
diff --git a/dev/tests/integration/testsuite/Magento/MessageQueue/Model/ConsumerTest.php b/dev/tests/integration/testsuite/Magento/MessageQueue/Model/ConsumerTest.php
new file mode 100644
index 0000000000000..a3515b07f1e0b
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/MessageQueue/Model/ConsumerTest.php
@@ -0,0 +1,109 @@
+objectManager = ObjectManager::getInstance();
+ /** @var ConsumerFactory $factory */
+ $factory = $this->objectManager->get(ConsumerFactory::class);
+ $this->model = $factory->get('demoConsumerWithConnectionException');
+ $this->queueResource = $this->objectManager->get(Queue::class);
+ }
+
+ /**
+ * Test if after connection exception and retry
+ * message doesn't have success status but still has status in progress
+ *
+ * @return void
+ */
+ public function testRunWithException(): void
+ {
+ /** @var EnvelopeFactory $envelopFactory */
+ $envelopFactory = $this->objectManager->get(EnvelopeFactory::class);
+ $messageBody = '{"name":"test"}';
+ $topicName = 'demo.connection.exception';
+ $queueName = 'queue-connection-exception';
+ $envelope = $envelopFactory->create(['body' => $messageBody, 'properties' => ['topic_name' => $topicName]]);
+ /** @var QueueInterface $queue */
+ $queue = $this->objectManager->create(
+ \Magento\MysqlMq\Model\Driver\Queue::class,
+ ['queueName' => $queueName]
+ );
+ $queue->push($envelope);
+ $messages = $this->queueResource->getMessages($queueName, 1);
+ $envelope = $envelopFactory->create(['body' => $messageBody, 'properties' => $messages[0]]);
+ $this->model->process(1);
+ $queue->reject($envelope);
+ $this->model->process(1);
+ $message = $this->getLastMessage($queueName);
+ $this->assertEquals(QueueManagement::MESSAGE_STATUS_IN_PROGRESS, $message['status']);
+ }
+
+ /**
+ * Return last message by queue name
+ *
+ * @param string $queueName
+ * @return array
+ */
+ private function getLastMessage(string $queueName)
+ {
+ $connection = $this->queueResource->getConnection();
+ $select = $connection->select()
+ ->from(
+ ['queue_message' => $this->queueResource->getTable('queue_message')],
+ []
+ )->join(
+ ['queue_message_status' => $this->queueResource->getTable('queue_message_status')],
+ 'queue_message.id = queue_message_status.message_id',
+ [
+ QueueManagement::MESSAGE_QUEUE_RELATION_ID => 'id',
+ QueueManagement::MESSAGE_STATUS => 'status',
+ ]
+ )->join(
+ ['queue' => $this->queueResource->getTable('queue')],
+ 'queue.id = queue_message_status.queue_id',
+ [QueueManagement::MESSAGE_QUEUE_NAME => 'name']
+ )->where('queue.name = ?', $queueName)
+ ->order(['queue_message_status.id DESC']);
+
+ return $connection->fetchRow($select);
+ }
+}
diff --git a/dev/tests/integration/testsuite/Magento/MessageQueue/Model/ResourceModel/LockTest.php b/dev/tests/integration/testsuite/Magento/MessageQueue/Model/ResourceModel/LockTest.php
new file mode 100644
index 0000000000000..bede370db29c4
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/MessageQueue/Model/ResourceModel/LockTest.php
@@ -0,0 +1,28 @@
+get(Lock::class);
+ $lock = $objectManager->create(LockInterface::class);
+ $resourceModel->saveLock($lock);
+ self::assertNotEquals(null, $lock->getId());
+ }
+}
diff --git a/dev/tests/integration/testsuite/Magento/Sales/Controller/Adminhtml/Order/Create/LoadBlockTest.php b/dev/tests/integration/testsuite/Magento/Sales/Controller/Adminhtml/Order/Create/LoadBlockTest.php
index 529b491269643..3567a7e00764f 100644
--- a/dev/tests/integration/testsuite/Magento/Sales/Controller/Adminhtml/Order/Create/LoadBlockTest.php
+++ b/dev/tests/integration/testsuite/Magento/Sales/Controller/Adminhtml/Order/Create/LoadBlockTest.php
@@ -231,6 +231,40 @@ public function testAddProductToOrderFromWishList(): void
$this->assertCount(1, $quoteItems);
}
+ /**
+ * Check that customer notification is NOT disabled after comment is updated.
+ *
+ * @return void
+ * @magentoDataFixture Magento/Checkout/_files/quote_with_customer_without_address.php
+ */
+ public function testUpdateCustomerNote(): void
+ {
+ $customerNote = 'Example Comment';
+ $quoteId = $this->getQuoteByReservedOrderId->execute('test_order_with_customer_without_address')->getId();
+ $this->session->setQuoteId($quoteId);
+ $params = [
+ 'json' => false,
+ 'block' => 'totals',
+ 'as_js_varname' => false,
+ ];
+ $post = $this->hydratePost([
+ 'order' => [
+ 'comment' => [
+ CartInterface::KEY_CUSTOMER_NOTE => $customerNote
+ ],
+ ],
+ ]);
+ $this->dispatchWitParams($params, $post);
+
+ $quote = $this->session->getQuote();
+ $this->assertEquals($customerNote, $quote->getCustomerNote());
+ $this->assertTrue((bool)$quote->getCustomerNoteNotify());
+
+ preg_match('/id="notify_customer"(?.*?)\/>/s', $this->getResponse()->getBody(), $matches);
+ $this->assertArrayHasKey('attributes', $matches);
+ $this->assertStringContainsString('checked="checked"', $matches['attributes']);
+ }
+
/**
* Check customer quotes
*
diff --git a/dev/tests/integration/testsuite/Magento/Sales/Model/Order/InvoiceTest.php b/dev/tests/integration/testsuite/Magento/Sales/Model/Order/InvoiceTest.php
index 8abec6ac6d734..64d5cdb037343 100644
--- a/dev/tests/integration/testsuite/Magento/Sales/Model/Order/InvoiceTest.php
+++ b/dev/tests/integration/testsuite/Magento/Sales/Model/Order/InvoiceTest.php
@@ -3,20 +3,57 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
+declare(strict_types=1);
+
namespace Magento\Sales\Model\Order;
-class InvoiceTest extends \PHPUnit\Framework\TestCase
+use PHPUnit\Framework\TestCase;
+use Magento\TestFramework\Helper\Bootstrap;
+use Magento\Sales\Model\ResourceModel\Order\Collection as OrderCollection;
+use Magento\Sales\Api\InvoiceManagementInterface;
+use Magento\Sales\Api\OrderRepositoryInterface;
+use Magento\Framework\Api\SearchCriteriaBuilder;
+
+/**
+ * Invoice model test.
+ */
+class InvoiceTest extends TestCase
{
/**
- * @var \Magento\Sales\Model\ResourceModel\Order\Collection
+ * @var \Magento\Framework\ObjectManagerInterface
+ */
+ private $objectManager;
+
+ /**
+ * @var OrderCollection
+ */
+ private $collection;
+
+ /**
+ * @var InvoiceManagementInterface
+ */
+ private $invoiceManagement;
+
+ /**
+ * @var OrderRepositoryInterface
+ */
+ private $orderRepository;
+
+ /**
+ * @var SearchCriteriaBuilder
*/
- private $_collection;
+ private $searchCriteriaBuilder;
+ /**
+ * @inheritDoc
+ */
protected function setUp(): void
{
- $this->_collection = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
- \Magento\Sales\Model\ResourceModel\Order\Collection::class
- );
+ $this->objectManager = Bootstrap::getObjectManager();
+ $this->collection = $this->objectManager->create(OrderCollection::class);
+ $this->invoiceManagement = $this->objectManager->get(InvoiceManagementInterface::class);
+ $this->orderRepository = $this->objectManager->get(OrderRepositoryInterface::class);
+ $this->searchCriteriaBuilder = $this->objectManager->get(SearchCriteriaBuilder::class);
}
/**
@@ -27,9 +64,27 @@ public function testOrderTotalItemCount()
$expectedResult = [['total_item_count' => 1]];
$actualResult = [];
/** @var \Magento\Sales\Model\Order $order */
- foreach ($this->_collection->getItems() as $order) {
+ foreach ($this->collection->getItems() as $order) {
$actualResult[] = ['total_item_count' => $order->getData('total_item_count')];
}
$this->assertEquals($expectedResult, $actualResult);
}
+
+ /**
+ * Test order with exactly one configurable.
+ *
+ * @return void
+ * @magentoDataFixture Magento/Sales/_files/order_configurable_product.php
+ */
+ public function testLastInvoiceWithConfigurable(): void
+ {
+ $searchCriteria = $this->searchCriteriaBuilder->addFilter('increment_id', '100000001')
+ ->create();
+ $orders = $this->orderRepository->getList($searchCriteria);
+ $orders = $orders->getItems();
+ $order = array_shift($orders);
+ $invoice = $this->invoiceManagement->prepareInvoice($order);
+
+ self::assertEquals($invoice->isLast(), true);
+ }
}
diff --git a/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/dynamic-rows/dynamic-rows.test.js b/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/dynamic-rows/dynamic-rows.test.js
index fc60fbb0bdccc..1101770b0faa2 100644
--- a/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/dynamic-rows/dynamic-rows.test.js
+++ b/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/dynamic-rows/dynamic-rows.test.js
@@ -171,5 +171,38 @@ define([
};
expect(JSON.stringify(model.labels())).toEqual(JSON.stringify(result));
});
+
+ it('Check _updatePagesQuantity method call.', function () {
+ model._updatePagesQuantity = jasmine.createSpy();
+
+ model.reload();
+
+ expect(model._updatePagesQuantity).toHaveBeenCalled();
+ });
+
+ it('Check number of pages is updated after reloading dynamic-rows.', function () {
+ model.pageSize = 1;
+ model.relatedData = [
+ {
+ name: 'first'
+ },
+ {
+ name: 'second'
+ },
+ {
+ name: 'third'
+ }
+ ];
+
+ model.reload();
+ expect(model.pages()).toEqual(3);
+
+ model.currentPage(3);
+ model.pageSize = 2;
+
+ model.reload();
+ expect(model.pages()).toEqual(2);
+ expect(model.currentPage()).toEqual(2);
+ });
});
});
diff --git a/setup/performance-toolkit/config/di.xml b/setup/performance-toolkit/config/di.xml
index 0b1175b0cd94c..a293edcb216af 100644
--- a/setup/performance-toolkit/config/di.xml
+++ b/setup/performance-toolkit/config/di.xml
@@ -6,4 +6,6 @@
*/
-->
+
+
diff --git a/setup/src/Magento/Setup/Framework/Mail/Template/TransportBuilderMock.php b/setup/src/Magento/Setup/Framework/Mail/Template/TransportBuilderMock.php
new file mode 100644
index 0000000000000..2791487c37ba5
--- /dev/null
+++ b/setup/src/Magento/Setup/Framework/Mail/Template/TransportBuilderMock.php
@@ -0,0 +1,28 @@
+prepareMessage();
+ $this->reset();
+
+ return new TransportInterfaceMock($this->message);
+ }
+}
diff --git a/setup/src/Magento/Setup/Framework/Mail/TransportInterfaceMock.php b/setup/src/Magento/Setup/Framework/Mail/TransportInterfaceMock.php
new file mode 100644
index 0000000000000..64abddc053504
--- /dev/null
+++ b/setup/src/Magento/Setup/Framework/Mail/TransportInterfaceMock.php
@@ -0,0 +1,45 @@
+message = $message;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function sendMessage()
+ {
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function getMessage()
+ {
+ return $this->message;
+ }
+}