From 82a635b3a4eb0fd0e2f030d82495ab717ee11db5 Mon Sep 17 00:00:00 2001 From: Graham Wharton Date: Mon, 8 Oct 2018 16:44:56 +0100 Subject: [PATCH 001/315] Removed setFromByStore and replaced with default parameter to setFrom --- .../Sales/Model/Order/Email/SenderBuilder.php | 16 +---- .../Model/Order/Email/SenderBuilderTest.php | 25 +++---- .../Mail/Template/TransportBuilder.php | 5 +- .../Mail/Template/TransportBuilderByStore.php | 55 --------------- .../Template/TransportBuilderByStoreTest.php | 67 ------------------- .../Unit/Template/TransportBuilderTest.php | 5 +- 6 files changed, 21 insertions(+), 152 deletions(-) delete mode 100644 lib/internal/Magento/Framework/Mail/Template/TransportBuilderByStore.php delete mode 100644 lib/internal/Magento/Framework/Mail/Test/Unit/Template/TransportBuilderByStoreTest.php diff --git a/app/code/Magento/Sales/Model/Order/Email/SenderBuilder.php b/app/code/Magento/Sales/Model/Order/Email/SenderBuilder.php index 7ec089b882972..e5c9c4b4afddc 100644 --- a/app/code/Magento/Sales/Model/Order/Email/SenderBuilder.php +++ b/app/code/Magento/Sales/Model/Order/Email/SenderBuilder.php @@ -5,9 +5,7 @@ */ namespace Magento\Sales\Model\Order\Email; -use Magento\Framework\App\ObjectManager; use Magento\Framework\Mail\Template\TransportBuilder; -use Magento\Framework\Mail\Template\TransportBuilderByStore; use Magento\Sales\Model\Order\Email\Container\IdentityInterface; use Magento\Sales\Model\Order\Email\Container\Template; @@ -28,29 +26,19 @@ class SenderBuilder */ protected $transportBuilder; - /** - * @var TransportBuilderByStore - */ - private $transportBuilderByStore; - /** * @param Template $templateContainer * @param IdentityInterface $identityContainer * @param TransportBuilder $transportBuilder - * @param TransportBuilderByStore $transportBuilderByStore */ public function __construct( Template $templateContainer, IdentityInterface $identityContainer, - TransportBuilder $transportBuilder, - TransportBuilderByStore $transportBuilderByStore = null + TransportBuilder $transportBuilder ) { $this->templateContainer = $templateContainer; $this->identityContainer = $identityContainer; $this->transportBuilder = $transportBuilder; - $this->transportBuilderByStore = $transportBuilderByStore ?: ObjectManager::getInstance()->get( - TransportBuilderByStore::class - ); } /** @@ -110,7 +98,7 @@ protected function configureEmailTemplate() $this->transportBuilder->setTemplateIdentifier($this->templateContainer->getTemplateId()); $this->transportBuilder->setTemplateOptions($this->templateContainer->getTemplateOptions()); $this->transportBuilder->setTemplateVars($this->templateContainer->getTemplateVars()); - $this->transportBuilderByStore->setFromByStore( + $this->transportBuilder->setFrom( $this->identityContainer->getEmailIdentity(), $this->identityContainer->getStore()->getId() ); diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/SenderBuilderTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/SenderBuilderTest.php index 38209bb22aef4..a3b7f6ef574dc 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/SenderBuilderTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/SenderBuilderTest.php @@ -6,7 +6,6 @@ namespace Magento\Sales\Test\Unit\Model\Order\Email; -use Magento\Framework\Mail\Template\TransportBuilderByStore; use Magento\Sales\Model\Order\Email\SenderBuilder; class SenderBuilderTest extends \PHPUnit\Framework\TestCase @@ -36,11 +35,6 @@ class SenderBuilderTest extends \PHPUnit\Framework\TestCase */ private $storeMock; - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - private $transportBuilderByStore; - protected function setUp() { $templateId = 'test_template_id'; @@ -82,11 +76,10 @@ protected function setUp() 'setTemplateIdentifier', 'setTemplateOptions', 'setTemplateVars', + 'setFrom', ] ); - $this->transportBuilderByStore = $this->createMock(TransportBuilderByStore::class); - $this->templateContainerMock->expects($this->once()) ->method('getTemplateId') ->will($this->returnValue($templateId)); @@ -109,8 +102,8 @@ protected function setUp() $this->identityContainerMock->expects($this->once()) ->method('getEmailIdentity') ->will($this->returnValue($emailIdentity)); - $this->transportBuilderByStore->expects($this->once()) - ->method('setFromByStore') + $this->transportBuilder->expects($this->once()) + ->method('setFrom') ->with($this->equalTo($emailIdentity)); $this->identityContainerMock->expects($this->once()) @@ -120,8 +113,7 @@ protected function setUp() $this->senderBuilder = new SenderBuilder( $this->templateContainerMock, $this->identityContainerMock, - $this->transportBuilder, - $this->transportBuilderByStore + $this->transportBuilder ); } @@ -129,6 +121,8 @@ public function testSend() { $customerName = 'test_name'; $customerEmail = 'test_email'; + $identity = 'email_identity_test'; + $transportMock = $this->createMock( \Magento\Sales\Test\Unit\Model\Order\Email\Stub\TransportInterfaceMock::class ); @@ -151,6 +145,9 @@ public function testSend() $this->storeMock->expects($this->once()) ->method('getId') ->willReturn(1); + $this->transportBuilder->expects($this->once()) + ->method('setFrom') + ->with($identity, 1); $this->transportBuilder->expects($this->once()) ->method('addTo') ->with($this->equalTo($customerEmail), $this->equalTo($customerName)); @@ -164,6 +161,7 @@ public function testSend() public function testSendCopyTo() { + $identity = 'email_identity_test'; $transportMock = $this->createMock( \Magento\Sales\Test\Unit\Model\Order\Email\Stub\TransportInterfaceMock::class ); @@ -177,6 +175,9 @@ public function testSendCopyTo() $this->transportBuilder->expects($this->once()) ->method('addTo') ->with($this->equalTo('example@mail.com')); + $this->transportBuilder->expects($this->once()) + ->method('setFrom') + ->with($identity, 1); $this->identityContainerMock->expects($this->once()) ->method('getStore') ->willReturn($this->storeMock); diff --git a/lib/internal/Magento/Framework/Mail/Template/TransportBuilder.php b/lib/internal/Magento/Framework/Mail/Template/TransportBuilder.php index a1c7333f41245..afe5477e84637 100644 --- a/lib/internal/Magento/Framework/Mail/Template/TransportBuilder.php +++ b/lib/internal/Magento/Framework/Mail/Template/TransportBuilder.php @@ -174,11 +174,12 @@ public function setReplyTo($email, $name = null) * Set mail from address * * @param string|array $from + * @param string|int $store * @return $this */ - public function setFrom($from) + public function setFrom($from, $store = null) { - $result = $this->_senderResolver->resolve($from); + $result = $this->_senderResolver->resolve($from, $store); $this->message->setFrom($result['email'], $result['name']); return $this; } diff --git a/lib/internal/Magento/Framework/Mail/Template/TransportBuilderByStore.php b/lib/internal/Magento/Framework/Mail/Template/TransportBuilderByStore.php deleted file mode 100644 index 95f17fed1123c..0000000000000 --- a/lib/internal/Magento/Framework/Mail/Template/TransportBuilderByStore.php +++ /dev/null @@ -1,55 +0,0 @@ -message = $message; - $this->senderResolver = $senderResolver; - } - - /** - * Set mail from address by store. - * - * @param string|array $from - * @param string|int $store - * - * @return $this - */ - public function setFromByStore($from, $store) - { - $result = $this->senderResolver->resolve($from, $store); - $this->message->clearFrom(); - $this->message->setFrom($result['email'], $result['name']); - - return $this; - } -} diff --git a/lib/internal/Magento/Framework/Mail/Test/Unit/Template/TransportBuilderByStoreTest.php b/lib/internal/Magento/Framework/Mail/Test/Unit/Template/TransportBuilderByStoreTest.php deleted file mode 100644 index 58c9b045eed8c..0000000000000 --- a/lib/internal/Magento/Framework/Mail/Test/Unit/Template/TransportBuilderByStoreTest.php +++ /dev/null @@ -1,67 +0,0 @@ -messageMock = $this->createMock(\Magento\Framework\Mail\Message::class); - $this->senderResolverMock = $this->createMock(\Magento\Framework\Mail\Template\SenderResolverInterface::class); - - $this->model = $objectManagerHelper->getObject( - TransportBuilderByStore::class, - [ - 'message' => $this->messageMock, - 'senderResolver' => $this->senderResolverMock, - ] - ); - } - - /** - * @return void - */ - public function testSetFromByStore() - { - $sender = ['email' => 'from@example.com', 'name' => 'name']; - $store = 1; - $this->senderResolverMock->expects($this->once()) - ->method('resolve') - ->with($sender, $store) - ->willReturn($sender); - $this->messageMock->expects($this->once()) - ->method('setFrom') - ->with('from@example.com', 'name') - ->willReturnSelf(); - $this->messageMock->expects($this->once()) - ->method('clearFrom') - ->willReturnSelf(); - - $this->model->setFromByStore($sender, $store); - } -} diff --git a/lib/internal/Magento/Framework/Mail/Test/Unit/Template/TransportBuilderTest.php b/lib/internal/Magento/Framework/Mail/Test/Unit/Template/TransportBuilderTest.php index c3759bc43f81f..8e9858116ffdb 100644 --- a/lib/internal/Magento/Framework/Mail/Test/Unit/Template/TransportBuilderTest.php +++ b/lib/internal/Magento/Framework/Mail/Test/Unit/Template/TransportBuilderTest.php @@ -167,16 +167,17 @@ public function getTransportDataProvider() public function testSetFrom() { $sender = ['email' => 'from@example.com', 'name' => 'name']; + $store = 1; $this->senderResolverMock->expects($this->once()) ->method('resolve') - ->with($sender) + ->with($sender, $store) ->willReturn($sender); $this->messageMock->expects($this->once()) ->method('setFrom') ->with('from@example.com', 'name') ->willReturnSelf(); - $this->builder->setFrom($sender); + $this->builder->setFrom($sender, $store); } /** From 16afc0962463261e4464456b9bdaad4e8f3be924 Mon Sep 17 00:00:00 2001 From: Graham Wharton Date: Tue, 16 Oct 2018 09:31:45 +0100 Subject: [PATCH 002/315] Added new setFromByStore function and deprecated old function. TODO : Rest of Magento codebase still uses deprecated setFrom --- .../Sales/Model/Order/Email/SenderBuilder.php | 2 +- .../Model/Order/Email/SenderBuilderTest.php | 10 +++++----- .../Mail/Template/TransportBuilder.php | 17 ++++++++++++++++- .../Test/Unit/Template/TransportBuilderTest.php | 4 ++-- 4 files changed, 24 insertions(+), 9 deletions(-) diff --git a/app/code/Magento/Sales/Model/Order/Email/SenderBuilder.php b/app/code/Magento/Sales/Model/Order/Email/SenderBuilder.php index e5c9c4b4afddc..af3ace9090834 100644 --- a/app/code/Magento/Sales/Model/Order/Email/SenderBuilder.php +++ b/app/code/Magento/Sales/Model/Order/Email/SenderBuilder.php @@ -98,7 +98,7 @@ protected function configureEmailTemplate() $this->transportBuilder->setTemplateIdentifier($this->templateContainer->getTemplateId()); $this->transportBuilder->setTemplateOptions($this->templateContainer->getTemplateOptions()); $this->transportBuilder->setTemplateVars($this->templateContainer->getTemplateVars()); - $this->transportBuilder->setFrom( + $this->transportBuilder->setFromByStore( $this->identityContainer->getEmailIdentity(), $this->identityContainer->getStore()->getId() ); diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/SenderBuilderTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/SenderBuilderTest.php index a3b7f6ef574dc..86d65cc476668 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/SenderBuilderTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/SenderBuilderTest.php @@ -76,7 +76,7 @@ protected function setUp() 'setTemplateIdentifier', 'setTemplateOptions', 'setTemplateVars', - 'setFrom', + 'setFromByStore', ] ); @@ -103,8 +103,8 @@ protected function setUp() ->method('getEmailIdentity') ->will($this->returnValue($emailIdentity)); $this->transportBuilder->expects($this->once()) - ->method('setFrom') - ->with($this->equalTo($emailIdentity)); + ->method('setFromByStore') + ->with($this->equalTo($emailIdentity), 1); $this->identityContainerMock->expects($this->once()) ->method('getEmailCopyTo') @@ -146,7 +146,7 @@ public function testSend() ->method('getId') ->willReturn(1); $this->transportBuilder->expects($this->once()) - ->method('setFrom') + ->method('setFromByStore') ->with($identity, 1); $this->transportBuilder->expects($this->once()) ->method('addTo') @@ -176,7 +176,7 @@ public function testSendCopyTo() ->method('addTo') ->with($this->equalTo('example@mail.com')); $this->transportBuilder->expects($this->once()) - ->method('setFrom') + ->method('setFromByStore') ->with($identity, 1); $this->identityContainerMock->expects($this->once()) ->method('getStore') diff --git a/lib/internal/Magento/Framework/Mail/Template/TransportBuilder.php b/lib/internal/Magento/Framework/Mail/Template/TransportBuilder.php index afe5477e84637..81edf165fdf75 100644 --- a/lib/internal/Magento/Framework/Mail/Template/TransportBuilder.php +++ b/lib/internal/Magento/Framework/Mail/Template/TransportBuilder.php @@ -172,12 +172,27 @@ public function setReplyTo($email, $name = null) /** * Set mail from address + * + * @deprecated Use setFromByStore + * + * @param string|array $from + * @return $this + */ + public function setFrom($from) + { + $result = $this->_senderResolver->resolve($from); + $this->message->setFrom($result['email'], $result['name']); + return $this; + } + + /** + * Set mail from address by store * * @param string|array $from * @param string|int $store * @return $this */ - public function setFrom($from, $store = null) + public function setFromByStore($from, $store = null) { $result = $this->_senderResolver->resolve($from, $store); $this->message->setFrom($result['email'], $result['name']); diff --git a/lib/internal/Magento/Framework/Mail/Test/Unit/Template/TransportBuilderTest.php b/lib/internal/Magento/Framework/Mail/Test/Unit/Template/TransportBuilderTest.php index 8e9858116ffdb..a2539c1326a49 100644 --- a/lib/internal/Magento/Framework/Mail/Test/Unit/Template/TransportBuilderTest.php +++ b/lib/internal/Magento/Framework/Mail/Test/Unit/Template/TransportBuilderTest.php @@ -173,11 +173,11 @@ public function testSetFrom() ->with($sender, $store) ->willReturn($sender); $this->messageMock->expects($this->once()) - ->method('setFrom') + ->method('setFromByStore') ->with('from@example.com', 'name') ->willReturnSelf(); - $this->builder->setFrom($sender, $store); + $this->builder->setFromByStore($sender, $store); } /** From 47c5f72c9196dc77b50db3c36ec99719a69a18a0 Mon Sep 17 00:00:00 2001 From: Graham Wharton Date: Tue, 16 Oct 2018 09:59:02 +0100 Subject: [PATCH 003/315] Addressed review comments --- .../Sales/Model/Order/Email/SenderBuilder.php | 5 +- .../Mail/Template/TransportBuilder.php | 9 +-- .../Mail/Template/TransportBuilderByStore.php | 62 +++++++++++++++++ .../Template/TransportBuilderByStoreTest.php | 67 +++++++++++++++++++ 4 files changed, 138 insertions(+), 5 deletions(-) create mode 100644 lib/internal/Magento/Framework/Mail/Template/TransportBuilderByStore.php create mode 100644 lib/internal/Magento/Framework/Mail/Test/Unit/Template/TransportBuilderByStoreTest.php diff --git a/app/code/Magento/Sales/Model/Order/Email/SenderBuilder.php b/app/code/Magento/Sales/Model/Order/Email/SenderBuilder.php index af3ace9090834..cda3e3a343f4c 100644 --- a/app/code/Magento/Sales/Model/Order/Email/SenderBuilder.php +++ b/app/code/Magento/Sales/Model/Order/Email/SenderBuilder.php @@ -6,6 +6,7 @@ namespace Magento\Sales\Model\Order\Email; use Magento\Framework\Mail\Template\TransportBuilder; +use Magento\Framework\Mail\Template\TransportBuilderByStore; use Magento\Sales\Model\Order\Email\Container\IdentityInterface; use Magento\Sales\Model\Order\Email\Container\Template; @@ -30,11 +31,13 @@ class SenderBuilder * @param Template $templateContainer * @param IdentityInterface $identityContainer * @param TransportBuilder $transportBuilder + * @param TransportBuilderByStore $transportBuilderByStore */ public function __construct( Template $templateContainer, IdentityInterface $identityContainer, - TransportBuilder $transportBuilder + TransportBuilder $transportBuilder, + TransportBuilderByStore $transportBuilderByStore = null ) { $this->templateContainer = $templateContainer; $this->identityContainer = $identityContainer; diff --git a/lib/internal/Magento/Framework/Mail/Template/TransportBuilder.php b/lib/internal/Magento/Framework/Mail/Template/TransportBuilder.php index 81edf165fdf75..12ab84eb61c11 100644 --- a/lib/internal/Magento/Framework/Mail/Template/TransportBuilder.php +++ b/lib/internal/Magento/Framework/Mail/Template/TransportBuilder.php @@ -173,16 +173,17 @@ public function setReplyTo($email, $name = null) /** * Set mail from address * - * @deprecated Use setFromByStore + * @deprecated This function sets the from address for the first store only. + * new function setFromByStore introduced to allow setting of from address + * based on store. + * @see setFromByStore() * * @param string|array $from * @return $this */ public function setFrom($from) { - $result = $this->_senderResolver->resolve($from); - $this->message->setFrom($result['email'], $result['name']); - return $this; + return($this->setFromByStore($from)); } /** diff --git a/lib/internal/Magento/Framework/Mail/Template/TransportBuilderByStore.php b/lib/internal/Magento/Framework/Mail/Template/TransportBuilderByStore.php new file mode 100644 index 0000000000000..88ad4f105f4b7 --- /dev/null +++ b/lib/internal/Magento/Framework/Mail/Template/TransportBuilderByStore.php @@ -0,0 +1,62 @@ +message = $message; + $this->senderResolver = $senderResolver; + } + + /** + * Set mail from address by store. + * + * @param string|array $from + * @param string|int $store + * + * @return $this + */ + public function setFromByStore($from, $store) + { + $result = $this->senderResolver->resolve($from, $store); + $this->message->clearFrom(); + $this->message->setFrom($result['email'], $result['name']); + + return $this; + } +} \ No newline at end of file diff --git a/lib/internal/Magento/Framework/Mail/Test/Unit/Template/TransportBuilderByStoreTest.php b/lib/internal/Magento/Framework/Mail/Test/Unit/Template/TransportBuilderByStoreTest.php new file mode 100644 index 0000000000000..d9f9a194165d6 --- /dev/null +++ b/lib/internal/Magento/Framework/Mail/Test/Unit/Template/TransportBuilderByStoreTest.php @@ -0,0 +1,67 @@ +messageMock = $this->createMock(\Magento\Framework\Mail\Message::class); + $this->senderResolverMock = $this->createMock(\Magento\Framework\Mail\Template\SenderResolverInterface::class); + + $this->model = $objectManagerHelper->getObject( + TransportBuilderByStore::class, + [ + 'message' => $this->messageMock, + 'senderResolver' => $this->senderResolverMock, + ] + ); + } + + /** + * @return void + */ + public function testSetFromByStore() + { + $sender = ['email' => 'from@example.com', 'name' => 'name']; + $store = 1; + $this->senderResolverMock->expects($this->once()) + ->method('resolve') + ->with($sender, $store) + ->willReturn($sender); + $this->messageMock->expects($this->once()) + ->method('setFrom') + ->with('from@example.com', 'name') + ->willReturnSelf(); + $this->messageMock->expects($this->once()) + ->method('clearFrom') + ->willReturnSelf(); + + $this->model->setFromByStore($sender, $store); + } +} \ No newline at end of file From 8d7a4513ddf4b759a6c6a0d2ace04aa714a396df Mon Sep 17 00:00:00 2001 From: Graham Wharton Date: Tue, 16 Oct 2018 10:03:56 +0100 Subject: [PATCH 004/315] Corrected linefeeds --- .../Mail/Template/TransportBuilderByStore.php | 122 ++++++++-------- .../Template/TransportBuilderByStoreTest.php | 132 +++++++++--------- 2 files changed, 127 insertions(+), 127 deletions(-) diff --git a/lib/internal/Magento/Framework/Mail/Template/TransportBuilderByStore.php b/lib/internal/Magento/Framework/Mail/Template/TransportBuilderByStore.php index 88ad4f105f4b7..105a497a14bdb 100644 --- a/lib/internal/Magento/Framework/Mail/Template/TransportBuilderByStore.php +++ b/lib/internal/Magento/Framework/Mail/Template/TransportBuilderByStore.php @@ -1,62 +1,62 @@ -message = $message; - $this->senderResolver = $senderResolver; - } - - /** - * Set mail from address by store. - * - * @param string|array $from - * @param string|int $store - * - * @return $this - */ - public function setFromByStore($from, $store) - { - $result = $this->senderResolver->resolve($from, $store); - $this->message->clearFrom(); - $this->message->setFrom($result['email'], $result['name']); - - return $this; - } +message = $message; + $this->senderResolver = $senderResolver; + } + + /** + * Set mail from address by store. + * + * @param string|array $from + * @param string|int $store + * + * @return $this + */ + public function setFromByStore($from, $store) + { + $result = $this->senderResolver->resolve($from, $store); + $this->message->clearFrom(); + $this->message->setFrom($result['email'], $result['name']); + + return $this; + } } \ No newline at end of file diff --git a/lib/internal/Magento/Framework/Mail/Test/Unit/Template/TransportBuilderByStoreTest.php b/lib/internal/Magento/Framework/Mail/Test/Unit/Template/TransportBuilderByStoreTest.php index d9f9a194165d6..cebf2a8b15b7f 100644 --- a/lib/internal/Magento/Framework/Mail/Test/Unit/Template/TransportBuilderByStoreTest.php +++ b/lib/internal/Magento/Framework/Mail/Test/Unit/Template/TransportBuilderByStoreTest.php @@ -1,67 +1,67 @@ -messageMock = $this->createMock(\Magento\Framework\Mail\Message::class); - $this->senderResolverMock = $this->createMock(\Magento\Framework\Mail\Template\SenderResolverInterface::class); - - $this->model = $objectManagerHelper->getObject( - TransportBuilderByStore::class, - [ - 'message' => $this->messageMock, - 'senderResolver' => $this->senderResolverMock, - ] - ); - } - - /** - * @return void - */ - public function testSetFromByStore() - { - $sender = ['email' => 'from@example.com', 'name' => 'name']; - $store = 1; - $this->senderResolverMock->expects($this->once()) - ->method('resolve') - ->with($sender, $store) - ->willReturn($sender); - $this->messageMock->expects($this->once()) - ->method('setFrom') - ->with('from@example.com', 'name') - ->willReturnSelf(); - $this->messageMock->expects($this->once()) - ->method('clearFrom') - ->willReturnSelf(); - - $this->model->setFromByStore($sender, $store); - } +messageMock = $this->createMock(\Magento\Framework\Mail\Message::class); + $this->senderResolverMock = $this->createMock(\Magento\Framework\Mail\Template\SenderResolverInterface::class); + + $this->model = $objectManagerHelper->getObject( + TransportBuilderByStore::class, + [ + 'message' => $this->messageMock, + 'senderResolver' => $this->senderResolverMock, + ] + ); + } + + /** + * @return void + */ + public function testSetFromByStore() + { + $sender = ['email' => 'from@example.com', 'name' => 'name']; + $store = 1; + $this->senderResolverMock->expects($this->once()) + ->method('resolve') + ->with($sender, $store) + ->willReturn($sender); + $this->messageMock->expects($this->once()) + ->method('setFrom') + ->with('from@example.com', 'name') + ->willReturnSelf(); + $this->messageMock->expects($this->once()) + ->method('clearFrom') + ->willReturnSelf(); + + $this->model->setFromByStore($sender, $store); + } } \ No newline at end of file From a7cd527a6896c3a2f204e2771b92496ef4089f4e Mon Sep 17 00:00:00 2001 From: Graham Wharton Date: Tue, 16 Oct 2018 10:09:44 +0100 Subject: [PATCH 005/315] Corrected file encoding --- .../Magento/Framework/Mail/Template/TransportBuilderByStore.php | 2 +- .../Mail/Test/Unit/Template/TransportBuilderByStoreTest.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/internal/Magento/Framework/Mail/Template/TransportBuilderByStore.php b/lib/internal/Magento/Framework/Mail/Template/TransportBuilderByStore.php index 105a497a14bdb..82a9c20d59a53 100644 --- a/lib/internal/Magento/Framework/Mail/Template/TransportBuilderByStore.php +++ b/lib/internal/Magento/Framework/Mail/Template/TransportBuilderByStore.php @@ -1,6 +1,6 @@ Date: Tue, 16 Oct 2018 10:11:22 +0100 Subject: [PATCH 006/315] Fixed whitespace issues --- .../Magento/Framework/Mail/Template/TransportBuilderByStore.php | 2 +- .../Mail/Test/Unit/Template/TransportBuilderByStoreTest.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/internal/Magento/Framework/Mail/Template/TransportBuilderByStore.php b/lib/internal/Magento/Framework/Mail/Template/TransportBuilderByStore.php index 82a9c20d59a53..c898f92bbf282 100644 --- a/lib/internal/Magento/Framework/Mail/Template/TransportBuilderByStore.php +++ b/lib/internal/Magento/Framework/Mail/Template/TransportBuilderByStore.php @@ -59,4 +59,4 @@ public function setFromByStore($from, $store) return $this; } -} \ No newline at end of file +} diff --git a/lib/internal/Magento/Framework/Mail/Test/Unit/Template/TransportBuilderByStoreTest.php b/lib/internal/Magento/Framework/Mail/Test/Unit/Template/TransportBuilderByStoreTest.php index 5ae4d8d4478bc..58c9b045eed8c 100644 --- a/lib/internal/Magento/Framework/Mail/Test/Unit/Template/TransportBuilderByStoreTest.php +++ b/lib/internal/Magento/Framework/Mail/Test/Unit/Template/TransportBuilderByStoreTest.php @@ -64,4 +64,4 @@ public function testSetFromByStore() $this->model->setFromByStore($sender, $store); } -} \ No newline at end of file +} From 490e5d22074224ec1965a391abfffc379c31d0ee Mon Sep 17 00:00:00 2001 From: Graham Wharton Date: Tue, 16 Oct 2018 10:22:41 +0100 Subject: [PATCH 007/315] Fixed TransportBuilderTest --- .../Mail/Test/Unit/Template/TransportBuilderTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/internal/Magento/Framework/Mail/Test/Unit/Template/TransportBuilderTest.php b/lib/internal/Magento/Framework/Mail/Test/Unit/Template/TransportBuilderTest.php index a2539c1326a49..1af4dd87b087e 100644 --- a/lib/internal/Magento/Framework/Mail/Test/Unit/Template/TransportBuilderTest.php +++ b/lib/internal/Magento/Framework/Mail/Test/Unit/Template/TransportBuilderTest.php @@ -164,7 +164,7 @@ public function getTransportDataProvider() /** * @return void */ - public function testSetFrom() + public function testSetFromByStore() { $sender = ['email' => 'from@example.com', 'name' => 'name']; $store = 1; @@ -173,7 +173,7 @@ public function testSetFrom() ->with($sender, $store) ->willReturn($sender); $this->messageMock->expects($this->once()) - ->method('setFromByStore') + ->method('setFrom') ->with('from@example.com', 'name') ->willReturnSelf(); From b19b3ed195b870f16a00c673e435b5b9b8184227 Mon Sep 17 00:00:00 2001 From: Graham Wharton Date: Tue, 16 Oct 2018 10:24:30 +0100 Subject: [PATCH 008/315] Fixed whitespace violations --- .../Magento/Framework/Mail/Template/TransportBuilder.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Mail/Template/TransportBuilder.php b/lib/internal/Magento/Framework/Mail/Template/TransportBuilder.php index 12ab84eb61c11..087fdf8503a60 100644 --- a/lib/internal/Magento/Framework/Mail/Template/TransportBuilder.php +++ b/lib/internal/Magento/Framework/Mail/Template/TransportBuilder.php @@ -172,7 +172,7 @@ public function setReplyTo($email, $name = null) /** * Set mail from address - * + * * @deprecated This function sets the from address for the first store only. * new function setFromByStore introduced to allow setting of from address * based on store. From 9f34fd631a55ded6d8a458d219edfc23c1bc5f9b Mon Sep 17 00:00:00 2001 From: Graham Wharton Date: Tue, 16 Oct 2018 17:55:46 +0100 Subject: [PATCH 009/315] Ignore unused parameter in constructor. Left in for backwards compatability purposes. --- app/code/Magento/Sales/Model/Order/Email/SenderBuilder.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/code/Magento/Sales/Model/Order/Email/SenderBuilder.php b/app/code/Magento/Sales/Model/Order/Email/SenderBuilder.php index cda3e3a343f4c..e4dc75ade7c79 100644 --- a/app/code/Magento/Sales/Model/Order/Email/SenderBuilder.php +++ b/app/code/Magento/Sales/Model/Order/Email/SenderBuilder.php @@ -28,6 +28,8 @@ class SenderBuilder protected $transportBuilder; /** + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + * * @param Template $templateContainer * @param IdentityInterface $identityContainer * @param TransportBuilder $transportBuilder From 66478ec59d6cbf77d538f2ea112f32997e491bf8 Mon Sep 17 00:00:00 2001 From: Ihor Sviziev Date: Wed, 17 Oct 2018 08:11:32 +0300 Subject: [PATCH 010/315] magento/magento2#18471 Alternative fix for Multi Store Emails issue Fix small issue --- .../Magento/Framework/Mail/Template/TransportBuilder.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Mail/Template/TransportBuilder.php b/lib/internal/Magento/Framework/Mail/Template/TransportBuilder.php index 087fdf8503a60..35e1651c6a5df 100644 --- a/lib/internal/Magento/Framework/Mail/Template/TransportBuilder.php +++ b/lib/internal/Magento/Framework/Mail/Template/TransportBuilder.php @@ -183,7 +183,7 @@ public function setReplyTo($email, $name = null) */ public function setFrom($from) { - return($this->setFromByStore($from)); + return $this->setFromByStore($from, null); } /** From cc34f00113e1e644e92002f82d34c4bf36aa0e26 Mon Sep 17 00:00:00 2001 From: gwharton <30697781+gwharton@users.noreply.github.com> Date: Sat, 20 Oct 2018 14:11:28 +0100 Subject: [PATCH 011/315] Fixed Whitespace issue --- .../Sales/Test/Unit/Model/Order/Email/SenderBuilderTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/SenderBuilderTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/SenderBuilderTest.php index 86d65cc476668..759d60d9e6613 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/SenderBuilderTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/SenderBuilderTest.php @@ -122,7 +122,7 @@ public function testSend() $customerName = 'test_name'; $customerEmail = 'test_email'; $identity = 'email_identity_test'; - + $transportMock = $this->createMock( \Magento\Sales\Test\Unit\Model\Order\Email\Stub\TransportInterfaceMock::class ); From b271dd889363992514d1555ab9bd21ddfdb7b41d Mon Sep 17 00:00:00 2001 From: Rik Willems Date: Wed, 21 Nov 2018 16:28:44 +0100 Subject: [PATCH 012/315] CLA force push commit --- app/code/Magento/Sales/Setup/UpgradeData.php | 125 ++++++++++++------- 1 file changed, 81 insertions(+), 44 deletions(-) diff --git a/app/code/Magento/Sales/Setup/UpgradeData.php b/app/code/Magento/Sales/Setup/UpgradeData.php index 77b96791e8cea..83f239546960e 100644 --- a/app/code/Magento/Sales/Setup/UpgradeData.php +++ b/app/code/Magento/Sales/Setup/UpgradeData.php @@ -14,9 +14,7 @@ use Magento\Framework\Setup\ModuleContextInterface; use Magento\Framework\Setup\ModuleDataSetupInterface; use Magento\Framework\Setup\UpgradeDataInterface; -use Magento\Quote\Model\QuoteFactory; -use Magento\Sales\Model\OrderFactory; -use Magento\Sales\Model\ResourceModel\Order\Address\CollectionFactory as AddressCollectionFactory; +use Magento\Sales\Model\Order\Address; /** * Data upgrade script @@ -42,21 +40,6 @@ class UpgradeData implements UpgradeDataInterface */ private $aggregatedFieldConverter; - /** - * @var AddressCollectionFactory - */ - private $addressCollectionFactory; - - /** - * @var OrderFactory - */ - private $orderFactory; - - /** - * @var QuoteFactory - */ - private $quoteFactory; - /** * @var State */ @@ -66,26 +49,17 @@ class UpgradeData implements UpgradeDataInterface * @param SalesSetupFactory $salesSetupFactory * @param Config $eavConfig * @param AggregatedFieldDataConverter $aggregatedFieldConverter - * @param AddressCollectionFactory $addressCollFactory - * @param OrderFactory $orderFactory - * @param QuoteFactory $quoteFactory * @param State $state */ public function __construct( SalesSetupFactory $salesSetupFactory, Config $eavConfig, AggregatedFieldDataConverter $aggregatedFieldConverter, - AddressCollectionFactory $addressCollFactory, - OrderFactory $orderFactory, - QuoteFactory $quoteFactory, State $state ) { $this->salesSetupFactory = $salesSetupFactory; $this->eavConfig = $eavConfig; $this->aggregatedFieldConverter = $aggregatedFieldConverter; - $this->addressCollectionFactory = $addressCollFactory; - $this->orderFactory = $orderFactory; - $this->quoteFactory = $quoteFactory; $this->state = $state; } @@ -125,6 +99,7 @@ public function upgrade(ModuleDataSetupInterface $setup, ModuleContextInterface * @param string $setupVersion * @param SalesSetup $salesSetup * @return void + * @throws \Magento\Framework\DB\FieldDataConversionException */ private function convertSerializedDataToJson($setupVersion, SalesSetup $salesSetup) { @@ -173,32 +148,94 @@ private function convertSerializedDataToJson($setupVersion, SalesSetup $salesSet /** * Fill quote_address_id in table sales_order_address if it is empty. - * * @param ModuleDataSetupInterface $setup */ public function fillQuoteAddressIdInSalesOrderAddress(ModuleDataSetupInterface $setup) { - $addressTable = $setup->getTable('sales_order_address'); - $updateOrderAddress = $setup->getConnection() + $this->fillQuoteAddressIdInSalesOrderAddressByType($setup, Address::TYPE_SHIPPING); + $this->fillQuoteAddressIdInSalesOrderAddressByType($setup, Address::TYPE_BILLING); + } + + /** + * @param ModuleDataSetupInterface $setup + * @param string $addressType + */ + public function fillQuoteAddressIdInSalesOrderAddressByType(ModuleDataSetupInterface $setup, $addressType) + { + $salesConnection = $setup->getConnection('sales'); + + $orderTable = $setup->getTable('sales_order', 'sales'); + $orderAddressTable = $setup->getTable('sales_order_address', 'sales'); + + $query = $salesConnection ->select() + ->from( + ['sales_order_address' => $orderAddressTable], + ['entity_id', 'address_type'] + ) ->joinInner( - ['sales_order' => $setup->getTable('sales_order')], - $addressTable . '.parent_id = sales_order.entity_id', - ['quote_address_id' => 'quote_address.address_id'] + ['sales_order' => $orderTable], + 'sales_order_address.parent_id = sales_order.entity_id', + ['quote_id' => 'sales_order.quote_id'] + ) + ->where('sales_order_address.quote_address_id IS NULL') + ->where('sales_order_address.address_type = ?', $addressType) + ->order('sales_order_address.entity_id'); + + $batchSize = 5000; + $result = $salesConnection->query($query); + $count = $result->rowCount(); + $batches = ceil($count / $batchSize); + + for ($batch = $batches; $batch > 0; $batch--) { + $query->limitPage($batch, $batchSize); + $result = $salesConnection->fetchAssoc($query); + + $this->fillQuoteAddressIdInSalesOrderAddressProcessBatch($setup, $result, $addressType); + } + } + /** + * @param ModuleDataSetupInterface $setup + * @param array $orderAddresses + * @param string $addressType + */ + public function fillQuoteAddressIdInSalesOrderAddressProcessBatch( + ModuleDataSetupInterface $setup, + array $orderAddresses, + $addressType + ) { + $salesConnection = $setup->getConnection('sales'); + $quoteConnection = $setup->getConnection('checkout'); + + $quoteAddressTable = $setup->getTable('quote_address', 'checkout'); + $quoteTable = $setup->getTable('quote', 'checkout'); + $salesOrderAddressTable = $setup->getTable('sales_order_address', 'sales'); + + $query = $quoteConnection + ->select() + ->from( + ['quote_address' => $quoteAddressTable], + ['quote_id', 'address_id'] ) ->joinInner( - ['quote_address' => $setup->getTable('quote_address')], - 'sales_order.quote_id = quote_address.quote_id - AND ' . $addressTable . '.address_type = quote_address.address_type', + ['quote' => $quoteTable], + 'quote_address.quote_id = quote.entity_id', [] ) - ->where( - $addressTable . '.quote_address_id IS NULL' - ); - $updateOrderAddress = $setup->getConnection()->updateFromSelect( - $updateOrderAddress, - $addressTable - ); - $setup->getConnection()->query($updateOrderAddress); + ->where('quote.entity_id in (?)', array_column($orderAddresses, 'quote_id')) + ->where('address_type = ?', $addressType); + + $quoteAddresses = $quoteConnection->fetchAssoc($query); + + foreach ($orderAddresses as $orderAddress) { + $bind = [ + 'quote_address_id' => $quoteAddresses[$orderAddress['quote_id']]['address_id'] ?? null, + ]; + $where = [ + 'orderAddressId' => $orderAddress['entity_id'] + ]; + + $salesConnection->update($salesOrderAddressTable, $bind, $where); + } } } From f0a92f2a2ad7e6a8f6c03b7bded7b2092561f07b Mon Sep 17 00:00:00 2001 From: Suneet Date: Tue, 4 Dec 2018 22:52:34 +0530 Subject: [PATCH 013/315] Resolved upgrade issue if manufacturer attribute missing --- .../ConfigurableProduct/Setup/InstallData.php | 24 ++++++++++--------- .../ConfigurableProduct/Setup/UpgradeData.php | 23 +++++++++++------- 2 files changed, 27 insertions(+), 20 deletions(-) diff --git a/app/code/Magento/ConfigurableProduct/Setup/InstallData.php b/app/code/Magento/ConfigurableProduct/Setup/InstallData.php index 1c26f159405dd..f9c94cc684b0d 100644 --- a/app/code/Magento/ConfigurableProduct/Setup/InstallData.php +++ b/app/code/Magento/ConfigurableProduct/Setup/InstallData.php @@ -57,18 +57,20 @@ public function install(ModuleDataSetupInterface $setup, ModuleContextInterface 'color' ]; foreach ($attributes as $attributeCode) { - $relatedProductTypes = explode( - ',', - $eavSetup->getAttribute(\Magento\Catalog\Model\Product::ENTITY, $attributeCode, 'apply_to') - ); - if (!in_array(Configurable::TYPE_CODE, $relatedProductTypes)) { - $relatedProductTypes[] = Configurable::TYPE_CODE; - $eavSetup->updateAttribute( - \Magento\Catalog\Model\Product::ENTITY, - $attributeCode, - 'apply_to', - implode(',', $relatedProductTypes) + if ($attribute = $eavSetup->getAttribute(\Magento\Catalog\Model\Product::ENTITY, $attributeCode, 'apply_to')) { + $relatedProductTypes = explode( + ',', + $attribute ); + if (!in_array(Configurable::TYPE_CODE, $relatedProductTypes)) { + $relatedProductTypes[] = Configurable::TYPE_CODE; + $eavSetup->updateAttribute( + \Magento\Catalog\Model\Product::ENTITY, + $attributeCode, + 'apply_to', + implode(',', $relatedProductTypes) + ); + } } } } diff --git a/app/code/Magento/ConfigurableProduct/Setup/UpgradeData.php b/app/code/Magento/ConfigurableProduct/Setup/UpgradeData.php index 1ff78a632c3bb..c71bb95a584c5 100644 --- a/app/code/Magento/ConfigurableProduct/Setup/UpgradeData.php +++ b/app/code/Magento/ConfigurableProduct/Setup/UpgradeData.php @@ -47,16 +47,18 @@ public function upgrade(ModuleDataSetupInterface $setup, ModuleContextInterface if (version_compare($context->getVersion(), '2.2.0') < 0) { $relatedProductTypes = $this->getRelatedProductTypes('tier_price', $eavSetup); - $key = array_search(Configurable::TYPE_CODE, $relatedProductTypes); - if ($key !== false) { - unset($relatedProductTypes[$key]); - $this->updateRelatedProductTypes('tier_price', $relatedProductTypes, $eavSetup); + if (!empty($relatedProductTypes)) { + $key = array_search(Configurable::TYPE_CODE, $relatedProductTypes); + if ($key !== false) { + unset($relatedProductTypes[$key]); + $this->updateRelatedProductTypes('tier_price', $relatedProductTypes, $eavSetup); + } } } if (version_compare($context->getVersion(), '2.2.1') < 0) { $relatedProductTypes = $this->getRelatedProductTypes('manufacturer', $eavSetup); - if (!in_array(Configurable::TYPE_CODE, $relatedProductTypes)) { + if (!empty($relatedProductTypes) && !in_array(Configurable::TYPE_CODE, $relatedProductTypes)) { $relatedProductTypes[] = Configurable::TYPE_CODE; $this->updateRelatedProductTypes('manufacturer', $relatedProductTypes, $eavSetup); } @@ -78,10 +80,13 @@ public function upgrade(ModuleDataSetupInterface $setup, ModuleContextInterface */ private function getRelatedProductTypes(string $attributeId, EavSetup $eavSetup) { - return explode( - ',', - $eavSetup->getAttribute(Product::ENTITY, $attributeId, 'apply_to') - ); + if($attribute = $eavSetup->getAttribute(Product::ENTITY, $attributeId, 'apply_to')) { + return explode( + ',', + $attribute + ); + } + return []; } /** From dbf5293d42f7f88eae47913b746278cf16045914 Mon Sep 17 00:00:00 2001 From: Suneet Date: Tue, 4 Dec 2018 23:35:35 +0530 Subject: [PATCH 014/315] Fixed code style as per the review --- app/code/Magento/ConfigurableProduct/Setup/InstallData.php | 5 ++++- app/code/Magento/ConfigurableProduct/Setup/UpgradeData.php | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/ConfigurableProduct/Setup/InstallData.php b/app/code/Magento/ConfigurableProduct/Setup/InstallData.php index f9c94cc684b0d..2d6f6579059bc 100644 --- a/app/code/Magento/ConfigurableProduct/Setup/InstallData.php +++ b/app/code/Magento/ConfigurableProduct/Setup/InstallData.php @@ -57,7 +57,10 @@ public function install(ModuleDataSetupInterface $setup, ModuleContextInterface 'color' ]; foreach ($attributes as $attributeCode) { - if ($attribute = $eavSetup->getAttribute(\Magento\Catalog\Model\Product::ENTITY, $attributeCode, 'apply_to')) { + if ($attribute = $eavSetup->getAttribute( + \Magento\Catalog\Model\Product::ENTITY, + $attributeCode, 'apply_to' + )) { $relatedProductTypes = explode( ',', $attribute diff --git a/app/code/Magento/ConfigurableProduct/Setup/UpgradeData.php b/app/code/Magento/ConfigurableProduct/Setup/UpgradeData.php index c71bb95a584c5..8724e244a1fd0 100644 --- a/app/code/Magento/ConfigurableProduct/Setup/UpgradeData.php +++ b/app/code/Magento/ConfigurableProduct/Setup/UpgradeData.php @@ -80,7 +80,10 @@ public function upgrade(ModuleDataSetupInterface $setup, ModuleContextInterface */ private function getRelatedProductTypes(string $attributeId, EavSetup $eavSetup) { - if($attribute = $eavSetup->getAttribute(Product::ENTITY, $attributeId, 'apply_to')) { + if ($attribute = $eavSetup->getAttribute( + Product::ENTITY, + $attributeId, 'apply_to' + )) { return explode( ',', $attribute From 94a3402605fa3d8fc74b025095d292616002b33d Mon Sep 17 00:00:00 2001 From: Stjepan Udovicic Date: Tue, 4 Dec 2018 19:24:45 +0100 Subject: [PATCH 015/315] Fix typo in SQL join --- .../Model/ResourceModel/Product/Indexer/Price/DefaultPrice.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Price/DefaultPrice.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Price/DefaultPrice.php index 7ea85cd3f6f10..8fdeaf00b804f 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Price/DefaultPrice.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Price/DefaultPrice.php @@ -604,7 +604,7 @@ protected function _applyCustomOption() [] )->joinLeft( ['otps' => $this->getTable('catalog_product_option_type_price')], - 'otps.option_type_id = otpd.option_type_id AND otpd.store_id = cs.store_id', + 'otps.option_type_id = otpd.option_type_id AND otps.store_id = cs.store_id', [] )->group( ['i.entity_id', 'i.customer_group_id', 'i.website_id', 'o.option_id'] From 4567a1a95fdd8a4089c808cfd12895de4db1d0e5 Mon Sep 17 00:00:00 2001 From: Suneet Date: Wed, 5 Dec 2018 10:01:14 +0530 Subject: [PATCH 016/315] Fixed code style --- app/code/Magento/ConfigurableProduct/Setup/InstallData.php | 3 ++- app/code/Magento/ConfigurableProduct/Setup/UpgradeData.php | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/ConfigurableProduct/Setup/InstallData.php b/app/code/Magento/ConfigurableProduct/Setup/InstallData.php index 2d6f6579059bc..57cc287aa24aa 100644 --- a/app/code/Magento/ConfigurableProduct/Setup/InstallData.php +++ b/app/code/Magento/ConfigurableProduct/Setup/InstallData.php @@ -59,7 +59,8 @@ public function install(ModuleDataSetupInterface $setup, ModuleContextInterface foreach ($attributes as $attributeCode) { if ($attribute = $eavSetup->getAttribute( \Magento\Catalog\Model\Product::ENTITY, - $attributeCode, 'apply_to' + $attributeCode, + 'apply_to' )) { $relatedProductTypes = explode( ',', diff --git a/app/code/Magento/ConfigurableProduct/Setup/UpgradeData.php b/app/code/Magento/ConfigurableProduct/Setup/UpgradeData.php index 8724e244a1fd0..113839e57791d 100644 --- a/app/code/Magento/ConfigurableProduct/Setup/UpgradeData.php +++ b/app/code/Magento/ConfigurableProduct/Setup/UpgradeData.php @@ -82,7 +82,8 @@ private function getRelatedProductTypes(string $attributeId, EavSetup $eavSetup) { if ($attribute = $eavSetup->getAttribute( Product::ENTITY, - $attributeId, 'apply_to' + $attributeId, + 'apply_to' )) { return explode( ',', From 0935782d1e27027299446103e819edbf76db5259 Mon Sep 17 00:00:00 2001 From: Stjepan Udovicic Date: Sun, 16 Dec 2018 00:07:48 +0100 Subject: [PATCH 017/315] Fix typo in SQL for CustomOptionPriceModifier --- .../Product/Indexer/Price/CustomOptionPriceModifier.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Price/CustomOptionPriceModifier.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Price/CustomOptionPriceModifier.php index 646cd0d4c1a4c..0ca13855cf896 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Price/CustomOptionPriceModifier.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Price/CustomOptionPriceModifier.php @@ -211,7 +211,7 @@ private function getSelectForOptionsWithMultipleValues(string $sourceTable): Sel } else { $select->joinLeft( ['otps' => $this->getTable('catalog_product_option_type_price')], - 'otps.option_type_id = otpd.option_type_id AND otpd.store_id = cwd.default_store_id', + 'otps.option_type_id = otpd.option_type_id AND otps.store_id = cwd.default_store_id', [] ); From 59a4e57a0c36671ff84e8398f413253610a512ac Mon Sep 17 00:00:00 2001 From: Graham Wharton Date: Thu, 10 Jan 2019 10:19:52 +0000 Subject: [PATCH 018/315] Reverted changes made in MAGETWO-96712 --- .../Mail/Template/TransportBuilder.php | 16 ---------- .../Unit/Template/TransportBuilderTest.php | 32 +++---------------- 2 files changed, 4 insertions(+), 44 deletions(-) diff --git a/lib/internal/Magento/Framework/Mail/Template/TransportBuilder.php b/lib/internal/Magento/Framework/Mail/Template/TransportBuilder.php index 1580c0b5eef91..35e1651c6a5df 100644 --- a/lib/internal/Magento/Framework/Mail/Template/TransportBuilder.php +++ b/lib/internal/Magento/Framework/Mail/Template/TransportBuilder.php @@ -48,13 +48,6 @@ class TransportBuilder */ protected $templateOptions; - /** - * Mail from address - * - * @var string|array - */ - private $from; - /** * Mail Transport * @@ -280,7 +273,6 @@ protected function reset() $this->templateIdentifier = null; $this->templateVars = null; $this->templateOptions = null; - $this->from = null; return $this; } @@ -314,14 +306,6 @@ protected function prepareMessage() ->setBody($body) ->setSubject(html_entity_decode($template->getSubject(), ENT_QUOTES)); - if ($this->from) { - $from = $this->_senderResolver->resolve( - $this->from, - $template->getDesignConfig()->getStore() - ); - $this->message->setFrom($from['email'], $from['name']); - } - return $this; } } diff --git a/lib/internal/Magento/Framework/Mail/Test/Unit/Template/TransportBuilderTest.php b/lib/internal/Magento/Framework/Mail/Test/Unit/Template/TransportBuilderTest.php index b18f5d2753ee6..8b3cc7df9a013 100644 --- a/lib/internal/Magento/Framework/Mail/Test/Unit/Template/TransportBuilderTest.php +++ b/lib/internal/Magento/Framework/Mail/Test/Unit/Template/TransportBuilderTest.php @@ -7,7 +7,6 @@ namespace Magento\Framework\Mail\Test\Unit\Template; use Magento\Framework\App\TemplateTypesInterface; -use Magento\Framework\DataObject; use Magento\Framework\Mail\MessageInterface; /** @@ -100,37 +99,17 @@ protected function setUp() */ public function testGetTransport($templateType, $messageType, $bodyText, $templateNamespace) { + $this->builder->setTemplateModel($templateNamespace); + $vars = ['reason' => 'Reason', 'customer' => 'Customer']; $options = ['area' => 'frontend', 'store' => 1]; - $from = 'email_from'; - $sender = ['email' => 'from@example.com', 'name' => 'name']; - - $this->builder->setTemplateModel($templateNamespace); - $this->builder->setFrom($from); - $template = $this->createPartialMock( - \Magento\Framework\Mail\TemplateInterface::class, - [ - 'setVars', - 'isPlain', - 'setOptions', - 'getSubject', - 'getType', - 'processTemplate', - 'getDesignConfig', - ] - ); + $template = $this->createMock(\Magento\Framework\Mail\TemplateInterface::class); $template->expects($this->once())->method('setVars')->with($this->equalTo($vars))->willReturnSelf(); $template->expects($this->once())->method('setOptions')->with($this->equalTo($options))->willReturnSelf(); $template->expects($this->once())->method('getSubject')->willReturn('Email Subject'); $template->expects($this->once())->method('getType')->willReturn($templateType); $template->expects($this->once())->method('processTemplate')->willReturn($bodyText); - $template->method('getDesignConfig')->willReturn(new DataObject($options)); - - $this->senderResolverMock->expects($this->once()) - ->method('resolve') - ->with($from, 1) - ->willReturn($sender); $this->templateFactoryMock->expects($this->once()) ->method('get') @@ -149,9 +128,6 @@ public function testGetTransport($templateType, $messageType, $bodyText, $templa ->method('setBody') ->with($this->equalTo($bodyText)) ->willReturnSelf(); - $this->messageMock->method('setFrom') - ->with($sender['email'], $sender['name']) - ->willReturnSelf(); $transport = $this->createMock(\Magento\Framework\Mail\TransportInterface::class); @@ -184,7 +160,7 @@ public function getTransportDataProvider() ] ]; } - + /** * @return void */ From a8bcb8bb8442a649bf1e62400ca6f147023e53c6 Mon Sep 17 00:00:00 2001 From: Graham Wharton Date: Thu, 10 Jan 2019 10:31:49 +0000 Subject: [PATCH 019/315] Deprecated Magento\Framework\Mail\Message::setFrom function, introduced new function setFromAddress --- lib/internal/Magento/Framework/Mail/Message.php | 15 ++++++++++++++- .../Framework/Mail/Template/TransportBuilder.php | 2 +- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/lib/internal/Magento/Framework/Mail/Message.php b/lib/internal/Magento/Framework/Mail/Message.php index c8f0e75c52800..96566ad82b8eb 100644 --- a/lib/internal/Magento/Framework/Mail/Message.php +++ b/lib/internal/Magento/Framework/Mail/Message.php @@ -89,10 +89,23 @@ public function getBody() /** * @inheritdoc + * + * @deprecated This function is missing the from name. The + * setFromAddress() function sets both from address and from name. + * @see setFromAddress() */ public function setFrom($fromAddress) { - $this->zendMessage->setFrom($fromAddress); + $this->setFromAddress($fromAddress, null); + return $this; + } + + /** + * @inheritdoc + */ + public function setFromAddress($fromAddress, $fromName = null) + { + $this->zendMessage->setFrom($fromAddress, $fromName); return $this; } diff --git a/lib/internal/Magento/Framework/Mail/Template/TransportBuilder.php b/lib/internal/Magento/Framework/Mail/Template/TransportBuilder.php index 35e1651c6a5df..25cbaf73b8d76 100644 --- a/lib/internal/Magento/Framework/Mail/Template/TransportBuilder.php +++ b/lib/internal/Magento/Framework/Mail/Template/TransportBuilder.php @@ -196,7 +196,7 @@ public function setFrom($from) public function setFromByStore($from, $store = null) { $result = $this->_senderResolver->resolve($from, $store); - $this->message->setFrom($result['email'], $result['name']); + $this->message->setFromAddress($result['email'], $result['name']); return $this; } From 573cf7a9fee7c2d8ca9c1c25fe909c93ccf06c49 Mon Sep 17 00:00:00 2001 From: Graham Wharton Date: Thu, 10 Jan 2019 11:26:35 +0000 Subject: [PATCH 020/315] Fixed testSetFromByStore unit test --- .../Framework/Mail/Test/Unit/Template/TransportBuilderTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Mail/Test/Unit/Template/TransportBuilderTest.php b/lib/internal/Magento/Framework/Mail/Test/Unit/Template/TransportBuilderTest.php index 8b3cc7df9a013..77c41cceeb285 100644 --- a/lib/internal/Magento/Framework/Mail/Test/Unit/Template/TransportBuilderTest.php +++ b/lib/internal/Magento/Framework/Mail/Test/Unit/Template/TransportBuilderTest.php @@ -173,7 +173,7 @@ public function testSetFromByStore() ->with($sender, $store) ->willReturn($sender); $this->messageMock->expects($this->once()) - ->method('setFrom') + ->method('setFromAddress') ->with('from@example.com', 'name') ->willReturnSelf(); From 49607ac12e9c2e2316e6adc6ee926b043cbae212 Mon Sep 17 00:00:00 2001 From: Nikita Fomin Date: Fri, 11 Jan 2019 13:45:04 +0200 Subject: [PATCH 021/315] MAGETWO-93326: Automate with MFTF Move Update to Another existing Update --- .../Magento/Ui/Test/Mftf/Section/AdminDataGridTableSection.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Ui/Test/Mftf/Section/AdminDataGridTableSection.xml b/app/code/Magento/Ui/Test/Mftf/Section/AdminDataGridTableSection.xml index 28ee9efc9f0a2..cbe5d9e158bb3 100644 --- a/app/code/Magento/Ui/Test/Mftf/Section/AdminDataGridTableSection.xml +++ b/app/code/Magento/Ui/Test/Mftf/Section/AdminDataGridTableSection.xml @@ -21,5 +21,6 @@ + From c874bf5176c292b13e403724cb91a7d7ebc40fc6 Mon Sep 17 00:00:00 2001 From: Dipti 2Jcommerce Date: Thu, 17 Jan 2019 17:32:15 +0530 Subject: [PATCH 022/315] iPhone5-device-newsletter-subscription-#20167 --- .../web/css/source/_module.less | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/app/design/frontend/Magento/luma/Magento_Newsletter/web/css/source/_module.less b/app/design/frontend/Magento/luma/Magento_Newsletter/web/css/source/_module.less index 9ccd6c190ec0e..aab895392e6dd 100644 --- a/app/design/frontend/Magento/luma/Magento_Newsletter/web/css/source/_module.less +++ b/app/design/frontend/Magento/luma/Magento_Newsletter/web/css/source/_module.less @@ -81,3 +81,24 @@ width: 34%; } } + +// +// Mobile +// _____________________________________________ + +.media-width(@extremum, @break) when (@extremum = 'max') and (@break = @screen__m) { + .block{ + &.newsletter { + input { + font-size: 12px; + padding-left: 30px; + } + + .field { + .control:before{ + font-size: 13px; + } + } + } + } +} From 3b9ba7c6af3b74eb2dea568db860959516abbf71 Mon Sep 17 00:00:00 2001 From: Igor Ludgero Miura Date: Fri, 18 Jan 2019 14:35:47 -0200 Subject: [PATCH 023/315] Remove sku from this condition --- .../Magento/Rule/Model/Condition/Product/AbstractProduct.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Rule/Model/Condition/Product/AbstractProduct.php b/app/code/Magento/Rule/Model/Condition/Product/AbstractProduct.php index c02bbd64e7ca3..b7dd1d6c55f4e 100644 --- a/app/code/Magento/Rule/Model/Condition/Product/AbstractProduct.php +++ b/app/code/Magento/Rule/Model/Condition/Product/AbstractProduct.php @@ -713,7 +713,7 @@ protected function _getAttributeSetId($productId) public function getOperatorForValidate() { $operator = $this->getOperator(); - if (in_array($this->getInputType(), ['category', 'sku'])) { + if (in_array($this->getInputType(), ['category'])) { if ($operator == '==') { $operator = '{}'; } elseif ($operator == '!=') { From 0b0dcfb9c7a943045d7724ee1832da2cbd3e04ff Mon Sep 17 00:00:00 2001 From: Ihor Sviziev Date: Tue, 22 Jan 2019 16:25:51 +0200 Subject: [PATCH 024/315] magento/magento2#19098 2.2.6 Use batches and direct queries to fix sales address upgrade Revert not needed changes --- app/code/Magento/Sales/Setup/UpgradeData.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/app/code/Magento/Sales/Setup/UpgradeData.php b/app/code/Magento/Sales/Setup/UpgradeData.php index 83f239546960e..b35632d6e12d2 100644 --- a/app/code/Magento/Sales/Setup/UpgradeData.php +++ b/app/code/Magento/Sales/Setup/UpgradeData.php @@ -14,7 +14,10 @@ use Magento\Framework\Setup\ModuleContextInterface; use Magento\Framework\Setup\ModuleDataSetupInterface; use Magento\Framework\Setup\UpgradeDataInterface; +use Magento\Quote\Model\QuoteFactory; use Magento\Sales\Model\Order\Address; +use Magento\Sales\Model\OrderFactory; +use Magento\Sales\Model\ResourceModel\Order\Address\CollectionFactory as AddressCollectionFactory; /** * Data upgrade script @@ -49,12 +52,18 @@ class UpgradeData implements UpgradeDataInterface * @param SalesSetupFactory $salesSetupFactory * @param Config $eavConfig * @param AggregatedFieldDataConverter $aggregatedFieldConverter + * @param AddressCollectionFactory $addressCollFactory + * @param OrderFactory $orderFactory + * @param QuoteFactory $quoteFactory * @param State $state */ public function __construct( SalesSetupFactory $salesSetupFactory, Config $eavConfig, AggregatedFieldDataConverter $aggregatedFieldConverter, + AddressCollectionFactory $addressCollFactory, + OrderFactory $orderFactory, + QuoteFactory $quoteFactory, State $state ) { $this->salesSetupFactory = $salesSetupFactory; From 867f47465bfee044b51b621392ca3228fb803a2c Mon Sep 17 00:00:00 2001 From: Arvinda kumar Date: Tue, 15 Jan 2019 16:46:44 +0530 Subject: [PATCH 025/315] issue fixed #20299 Order item details label not aligned in mobile view issue fixed #20299 Order item details label not aligned in mobile view --- .../Magento_Checkout/web/css/source/module/_cart.less | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/_cart.less b/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/_cart.less index 1015bb584ff7b..ce4ba47cc2337 100644 --- a/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/_cart.less +++ b/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/_cart.less @@ -501,6 +501,17 @@ } } } + + .cart.table-wrapper, + .order-items.table-wrapper { + .col.price, + .col.qty, + .col.subtotal, + .col.msrp { + text-align: left; + } + } + } // From 362f81fada5975a193b1a41415725cf9bdad4ef7 Mon Sep 17 00:00:00 2001 From: nmalevanec Date: Wed, 16 Jan 2019 11:52:32 +0200 Subject: [PATCH 026/315] Fix static tests. --- .../luma/Magento_Checkout/web/css/source/module/_cart.less | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/_cart.less b/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/_cart.less index ce4ba47cc2337..fa41682cbd635 100644 --- a/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/_cart.less +++ b/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/_cart.less @@ -501,7 +501,7 @@ } } } - + .cart.table-wrapper, .order-items.table-wrapper { .col.price, @@ -511,7 +511,7 @@ text-align: left; } } - + } // From ef635bf6b8ecf67c729deb38df05c81b9e5b5359 Mon Sep 17 00:00:00 2001 From: Graham Wharton Date: Fri, 25 Jan 2019 13:21:24 +0000 Subject: [PATCH 027/315] Changed references to "Store" to "Scope" in framework components. --- .../Sales/Model/Order/Email/SenderBuilder.php | 2 +- .../Model/Order/Email/SenderBuilderTest.php | 8 ++++---- .../Mail/Template/TransportBuilder.php | 17 ++++++++--------- .../Test/Unit/Template/TransportBuilderTest.php | 8 ++++---- 4 files changed, 17 insertions(+), 18 deletions(-) diff --git a/app/code/Magento/Sales/Model/Order/Email/SenderBuilder.php b/app/code/Magento/Sales/Model/Order/Email/SenderBuilder.php index e4dc75ade7c79..5fb89b7855056 100644 --- a/app/code/Magento/Sales/Model/Order/Email/SenderBuilder.php +++ b/app/code/Magento/Sales/Model/Order/Email/SenderBuilder.php @@ -103,7 +103,7 @@ protected function configureEmailTemplate() $this->transportBuilder->setTemplateIdentifier($this->templateContainer->getTemplateId()); $this->transportBuilder->setTemplateOptions($this->templateContainer->getTemplateOptions()); $this->transportBuilder->setTemplateVars($this->templateContainer->getTemplateVars()); - $this->transportBuilder->setFromByStore( + $this->transportBuilder->setFromByScope( $this->identityContainer->getEmailIdentity(), $this->identityContainer->getStore()->getId() ); diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/SenderBuilderTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/SenderBuilderTest.php index 759d60d9e6613..24cd54e3a46b3 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/SenderBuilderTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/SenderBuilderTest.php @@ -76,7 +76,7 @@ protected function setUp() 'setTemplateIdentifier', 'setTemplateOptions', 'setTemplateVars', - 'setFromByStore', + 'setFromByScope', ] ); @@ -103,7 +103,7 @@ protected function setUp() ->method('getEmailIdentity') ->will($this->returnValue($emailIdentity)); $this->transportBuilder->expects($this->once()) - ->method('setFromByStore') + ->method('setFromByScope') ->with($this->equalTo($emailIdentity), 1); $this->identityContainerMock->expects($this->once()) @@ -146,7 +146,7 @@ public function testSend() ->method('getId') ->willReturn(1); $this->transportBuilder->expects($this->once()) - ->method('setFromByStore') + ->method('setFromByScope') ->with($identity, 1); $this->transportBuilder->expects($this->once()) ->method('addTo') @@ -176,7 +176,7 @@ public function testSendCopyTo() ->method('addTo') ->with($this->equalTo('example@mail.com')); $this->transportBuilder->expects($this->once()) - ->method('setFromByStore') + ->method('setFromByScope') ->with($identity, 1); $this->identityContainerMock->expects($this->once()) ->method('getStore') diff --git a/lib/internal/Magento/Framework/Mail/Template/TransportBuilder.php b/lib/internal/Magento/Framework/Mail/Template/TransportBuilder.php index 25cbaf73b8d76..b5be1cbf52cfd 100644 --- a/lib/internal/Magento/Framework/Mail/Template/TransportBuilder.php +++ b/lib/internal/Magento/Framework/Mail/Template/TransportBuilder.php @@ -173,29 +173,28 @@ public function setReplyTo($email, $name = null) /** * Set mail from address * - * @deprecated This function sets the from address for the first store only. - * new function setFromByStore introduced to allow setting of from address - * based on store. - * @see setFromByStore() + * @deprecated This function sets the from address but does not provide + * a way of setting the correct from addresses based on the scope. + * @see setFromByScope() * * @param string|array $from * @return $this */ public function setFrom($from) { - return $this->setFromByStore($from, null); + return $this->setFromByScope($from, null); } /** - * Set mail from address by store + * Set mail from address by Scope * * @param string|array $from - * @param string|int $store + * @param string|int $scopeId * @return $this */ - public function setFromByStore($from, $store = null) + public function setFromByScope($from, $scopeId = null) { - $result = $this->_senderResolver->resolve($from, $store); + $result = $this->_senderResolver->resolve($from, $scopeId); $this->message->setFromAddress($result['email'], $result['name']); return $this; } diff --git a/lib/internal/Magento/Framework/Mail/Test/Unit/Template/TransportBuilderTest.php b/lib/internal/Magento/Framework/Mail/Test/Unit/Template/TransportBuilderTest.php index 77c41cceeb285..6c5c48fba1b9b 100644 --- a/lib/internal/Magento/Framework/Mail/Test/Unit/Template/TransportBuilderTest.php +++ b/lib/internal/Magento/Framework/Mail/Test/Unit/Template/TransportBuilderTest.php @@ -164,20 +164,20 @@ public function getTransportDataProvider() /** * @return void */ - public function testSetFromByStore() + public function testSetFromByScope() { $sender = ['email' => 'from@example.com', 'name' => 'name']; - $store = 1; + $scopeId = 1; $this->senderResolverMock->expects($this->once()) ->method('resolve') - ->with($sender, $store) + ->with($sender, $scopeId) ->willReturn($sender); $this->messageMock->expects($this->once()) ->method('setFromAddress') ->with('from@example.com', 'name') ->willReturnSelf(); - $this->builder->setFromByStore($sender, $store); + $this->builder->setFromByScope($sender, $scopeId); } /** From f0032eef4ddebeec30caafac764c1c5262ee4ec3 Mon Sep 17 00:00:00 2001 From: Parag Chavare Date: Wed, 23 Jan 2019 17:55:52 +0530 Subject: [PATCH 028/315] bundle-product-radio-button-misalign --- .../Magento/luma/Magento_Bundle/web/css/source/_module.less | 1 + 1 file changed, 1 insertion(+) diff --git a/app/design/frontend/Magento/luma/Magento_Bundle/web/css/source/_module.less b/app/design/frontend/Magento/luma/Magento_Bundle/web/css/source/_module.less index 43ae23bab7895..99c8aa1ad2bae 100644 --- a/app/design/frontend/Magento/luma/Magento_Bundle/web/css/source/_module.less +++ b/app/design/frontend/Magento/luma/Magento_Bundle/web/css/source/_module.less @@ -58,6 +58,7 @@ .field.choice { input { float: left; + margin-top: 4px; } .label { From 7383946a868dbe8c36ffeb1605097addfb08a2f5 Mon Sep 17 00:00:00 2001 From: amol 2jcommerce Date: Wed, 30 Jan 2019 10:22:33 +0530 Subject: [PATCH 029/315] cms-page-top-spacing-issue-2.2 --- .../Magento/luma/Magento_Theme/web/css/source/_module.less | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/design/frontend/Magento/luma/Magento_Theme/web/css/source/_module.less b/app/design/frontend/Magento/luma/Magento_Theme/web/css/source/_module.less index 68938ed206038..9d17ee7256ee4 100644 --- a/app/design/frontend/Magento/luma/Magento_Theme/web/css/source/_module.less +++ b/app/design/frontend/Magento/luma/Magento_Theme/web/css/source/_module.less @@ -441,7 +441,7 @@ .media-width(@extremum, @break) when (@extremum = 'max') and (@break = @screen__m) { .cms-page-view .page-main { - padding-top: 41px; + padding-top: 0; position: relative; } } From 4a9a98a9b6548cecb4c479e7cfb567faa51825d7 Mon Sep 17 00:00:00 2001 From: Ihor Sviziev Date: Wed, 30 Jan 2019 08:30:56 +0200 Subject: [PATCH 030/315] magento/magento2#19098 2.2.6 Use batches and direct queries to fix sales address upgrade Fix static test failures --- app/code/Magento/Sales/Setup/UpgradeData.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/code/Magento/Sales/Setup/UpgradeData.php b/app/code/Magento/Sales/Setup/UpgradeData.php index b35632d6e12d2..0b69458b7656c 100644 --- a/app/code/Magento/Sales/Setup/UpgradeData.php +++ b/app/code/Magento/Sales/Setup/UpgradeData.php @@ -49,6 +49,8 @@ class UpgradeData implements UpgradeDataInterface private $state; /** + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + * * @param SalesSetupFactory $salesSetupFactory * @param Config $eavConfig * @param AggregatedFieldDataConverter $aggregatedFieldConverter From 7c6026e2f62e5edd35b0f75877b556b07801e598 Mon Sep 17 00:00:00 2001 From: Ihor Sviziev Date: Wed, 30 Jan 2019 09:13:37 +0200 Subject: [PATCH 031/315] magento/magento2#19098 2.2.6 Use batches and direct queries to fix sales address upgrade Fix statis test failures --- app/code/Magento/Sales/Setup/UpgradeData.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Sales/Setup/UpgradeData.php b/app/code/Magento/Sales/Setup/UpgradeData.php index 0b69458b7656c..56cbf31c3d695 100644 --- a/app/code/Magento/Sales/Setup/UpgradeData.php +++ b/app/code/Magento/Sales/Setup/UpgradeData.php @@ -171,7 +171,7 @@ public function fillQuoteAddressIdInSalesOrderAddress(ModuleDataSetupInterface $ * @param ModuleDataSetupInterface $setup * @param string $addressType */ - public function fillQuoteAddressIdInSalesOrderAddressByType(ModuleDataSetupInterface $setup, $addressType) + private function fillQuoteAddressIdInSalesOrderAddressByType(ModuleDataSetupInterface $setup, $addressType) { $salesConnection = $setup->getConnection('sales'); @@ -205,12 +205,13 @@ public function fillQuoteAddressIdInSalesOrderAddressByType(ModuleDataSetupInter $this->fillQuoteAddressIdInSalesOrderAddressProcessBatch($setup, $result, $addressType); } } + /** * @param ModuleDataSetupInterface $setup * @param array $orderAddresses * @param string $addressType */ - public function fillQuoteAddressIdInSalesOrderAddressProcessBatch( + private function fillQuoteAddressIdInSalesOrderAddressProcessBatch( ModuleDataSetupInterface $setup, array $orderAddresses, $addressType From 756cefa0b7ff6bc687866809b3f3e25c12943d92 Mon Sep 17 00:00:00 2001 From: "rostyslav.hymon" Date: Wed, 30 Jan 2019 12:11:31 +0000 Subject: [PATCH 032/315] MAGETWO-97630: [Magento Cloud] news_from_date and news_to_date dates incorrect in database with scheduled updates Due to unstable work of intl parsing on different platforms --- app/code/Magento/Cron/Model/Schedule.php | 30 ++-- .../Cron/Test/Unit/Model/ScheduleTest.php | 140 ++++++++++++++---- 2 files changed, 136 insertions(+), 34 deletions(-) diff --git a/app/code/Magento/Cron/Model/Schedule.php b/app/code/Magento/Cron/Model/Schedule.php index 39a58ef360cb3..a9ae04cb0c5d1 100644 --- a/app/code/Magento/Cron/Model/Schedule.php +++ b/app/code/Magento/Cron/Model/Schedule.php @@ -9,6 +9,7 @@ use Magento\Framework\Exception\CronException; use Magento\Framework\App\ObjectManager; use Magento\Framework\Stdlib\DateTime\TimezoneInterface; +use Magento\Framework\Intl\DateTimeFactory; /** * Crontab schedule model @@ -50,13 +51,19 @@ class Schedule extends \Magento\Framework\Model\AbstractModel */ private $timezoneConverter; + /** + * @var DateTimeFactory + */ + private $dateTimeFactory; + /** * @param \Magento\Framework\Model\Context $context * @param \Magento\Framework\Registry $registry * @param \Magento\Framework\Model\ResourceModel\AbstractResource $resource * @param \Magento\Framework\Data\Collection\AbstractDb $resourceCollection * @param array $data - * @param TimezoneInterface $timezoneConverter + * @param TimezoneInterface|null $timezoneConverter + * @param DateTimeFactory|null $dateTimeFactory */ public function __construct( \Magento\Framework\Model\Context $context, @@ -64,10 +71,12 @@ public function __construct( \Magento\Framework\Model\ResourceModel\AbstractResource $resource = null, \Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null, array $data = [], - TimezoneInterface $timezoneConverter = null + TimezoneInterface $timezoneConverter = null, + DateTimeFactory $dateTimeFactory = null ) { parent::__construct($context, $registry, $resource, $resourceCollection, $data); $this->timezoneConverter = $timezoneConverter ?: ObjectManager::getInstance()->get(TimezoneInterface::class); + $this->dateTimeFactory = $dateTimeFactory ?: ObjectManager::getInstance()->get(DateTimeFactory::class); } /** @@ -109,17 +118,20 @@ public function trySchedule() if (!$e || !$time) { return false; } + $configTimeZone = $this->timezoneConverter->getConfigTimezone(); + $storeDateTime = $this->dateTimeFactory->create(null, new \DateTimeZone($configTimeZone)); if (!is_numeric($time)) { //convert time from UTC to admin store timezone //we assume that all schedules in configuration (crontab.xml and DB tables) are in admin store timezone - $time = $this->timezoneConverter->date($time)->format('Y-m-d H:i'); - $time = strtotime($time); + $dateTimeUtc = $this->dateTimeFactory->create($time); + $time = $dateTimeUtc->getTimestamp(); } - $match = $this->matchCronExpression($e[0], strftime('%M', $time)) - && $this->matchCronExpression($e[1], strftime('%H', $time)) - && $this->matchCronExpression($e[2], strftime('%d', $time)) - && $this->matchCronExpression($e[3], strftime('%m', $time)) - && $this->matchCronExpression($e[4], strftime('%w', $time)); + $time = $storeDateTime->setTimestamp($time); + $match = $this->matchCronExpression($e[0], $time->format('i')) + && $this->matchCronExpression($e[1], $time->format('H')) + && $this->matchCronExpression($e[2], $time->format('d')) + && $this->matchCronExpression($e[3], $time->format('m')) + && $this->matchCronExpression($e[4], $time->format('w')); return $match; } diff --git a/app/code/Magento/Cron/Test/Unit/Model/ScheduleTest.php b/app/code/Magento/Cron/Test/Unit/Model/ScheduleTest.php index e9f4c61c7f551..76e9627ad7098 100644 --- a/app/code/Magento/Cron/Test/Unit/Model/ScheduleTest.php +++ b/app/code/Magento/Cron/Test/Unit/Model/ScheduleTest.php @@ -6,6 +6,9 @@ namespace Magento\Cron\Test\Unit\Model; use Magento\Cron\Model\Schedule; +use Magento\Framework\Intl\DateTimeFactory; +use Magento\Framework\Stdlib\DateTime\TimezoneInterface; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; /** * Class \Magento\Cron\Test\Unit\Model\ObserverTest @@ -18,11 +21,27 @@ class ScheduleTest extends \PHPUnit\Framework\TestCase */ protected $helper; + /** + * @var \Magento\Cron\Model\ResourceModel\Schedule + */ protected $resourceJobMock; + /** + * @var TimezoneInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $timezoneConverter; + + /** + * @var DateTimeFactory|\PHPUnit_Framework_MockObject_MockObject + */ + private $dateTimeFactory; + + /** + * @inheritdoc + */ protected function setUp() { - $this->helper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); + $this->helper = new ObjectManager($this); $this->resourceJobMock = $this->getMockBuilder(\Magento\Cron\Model\ResourceModel\Schedule::class) ->disableOriginalConstructor() @@ -32,18 +51,30 @@ protected function setUp() $this->resourceJobMock->expects($this->any()) ->method('getIdFieldName') ->will($this->returnValue('id')); + + $this->timezoneConverter = $this->getMockBuilder(TimezoneInterface::class) + ->setMethods(['date']) + ->getMockForAbstractClass(); + + $this->dateTimeFactory = $this->getMockBuilder(DateTimeFactory::class) + ->setMethods(['create']) + ->getMock(); } /** + * Test for SetCronExpr + * * @param string $cronExpression * @param array $expected + * + * @return void * @dataProvider setCronExprDataProvider */ public function testSetCronExpr($cronExpression, $expected) { // 1. Create mocks - /** @var \Magento\Cron\Model\Schedule $model */ - $model = $this->helper->getObject(\Magento\Cron\Model\Schedule::class); + /** @var Schedule $model */ + $model = $this->helper->getObject(Schedule::class); // 2. Run tested method $model->setCronExpr($cronExpression); @@ -61,7 +92,7 @@ public function testSetCronExpr($cronExpression, $expected) * * @return array */ - public function setCronExprDataProvider() + public function setCronExprDataProvider(): array { return [ ['1 2 3 4 5', [1, 2, 3, 4, 5]], @@ -121,27 +152,33 @@ public function setCronExprDataProvider() } /** + * Test for SetCronExprException + * * @param string $cronExpression + * + * @return void * @expectedException \Magento\Framework\Exception\CronException * @dataProvider setCronExprExceptionDataProvider */ public function testSetCronExprException($cronExpression) { // 1. Create mocks - /** @var \Magento\Cron\Model\Schedule $model */ - $model = $this->helper->getObject(\Magento\Cron\Model\Schedule::class); + /** @var Schedule $model */ + $model = $this->helper->getObject(Schedule::class); // 2. Run tested method $model->setCronExpr($cronExpression); } /** + * Data provider + * * Here is a list of allowed characters and values for Cron expression * http://docs.oracle.com/cd/E12058_01/doc/doc.1014/e12030/cron_expressions.htm * * @return array */ - public function setCronExprExceptionDataProvider() + public function setCronExprExceptionDataProvider(): array { return [ [''], @@ -153,17 +190,31 @@ public function setCronExprExceptionDataProvider() } /** + * Test for trySchedule + * * @param int $scheduledAt * @param array $cronExprArr * @param $expected + * + * @return void * @dataProvider tryScheduleDataProvider */ public function testTrySchedule($scheduledAt, $cronExprArr, $expected) { // 1. Create mocks + $this->timezoneConverter->method('getConfigTimezone') + ->willReturn('UTC'); + + $this->dateTimeFactory->method('create') + ->willReturn(new \DateTime()); + /** @var \Magento\Cron\Model\Schedule $model */ $model = $this->helper->getObject( - \Magento\Cron\Model\Schedule::class + \Magento\Cron\Model\Schedule::class, + [ + 'timezoneConverter' => $this->timezoneConverter, + 'dateTimeFactory' => $this->dateTimeFactory, + ] ); // 2. Set fixtures @@ -177,22 +228,29 @@ public function testTrySchedule($scheduledAt, $cronExprArr, $expected) $this->assertEquals($expected, $result); } + /** + * Test for tryScheduleWithConversionToAdminStoreTime + * + * @return void + */ public function testTryScheduleWithConversionToAdminStoreTime() { $scheduledAt = '2011-12-13 14:15:16'; $cronExprArr = ['*', '*', '*', '*', '*']; - // 1. Create mocks - $timezoneConverter = $this->createMock(\Magento\Framework\Stdlib\DateTime\TimezoneInterface::class); - $timezoneConverter->expects($this->once()) - ->method('date') - ->with($scheduledAt) - ->willReturn(new \DateTime($scheduledAt)); + $this->timezoneConverter->method('getConfigTimezone') + ->willReturn('UTC'); + + $this->dateTimeFactory->method('create') + ->willReturn(new \DateTime()); /** @var \Magento\Cron\Model\Schedule $model */ $model = $this->helper->getObject( \Magento\Cron\Model\Schedule::class, - ['timezoneConverter' => $timezoneConverter] + [ + 'timezoneConverter' => $this->timezoneConverter, + 'dateTimeFactory' => $this->dateTimeFactory, + ] ); // 2. Set fixtures @@ -207,11 +265,15 @@ public function testTryScheduleWithConversionToAdminStoreTime() } /** + * Data provider + * * @return array */ - public function tryScheduleDataProvider() + public function tryScheduleDataProvider(): array { $date = '2011-12-13 14:15:16'; + $timestamp = (new \DateTime($date))->getTimestamp(); + $day = 'Monday'; return [ [$date, [], false], [$date, null, false], @@ -219,19 +281,23 @@ public function tryScheduleDataProvider() [$date, [], false], [$date, null, false], [$date, false, false], - [strtotime($date), ['*', '*', '*', '*', '*'], true], - [strtotime($date), ['15', '*', '*', '*', '*'], true], - [strtotime($date), ['*', '14', '*', '*', '*'], true], - [strtotime($date), ['*', '*', '13', '*', '*'], true], - [strtotime($date), ['*', '*', '*', '12', '*'], true], - [strtotime('Monday'), ['*', '*', '*', '*', '1'], true], + [$timestamp, ['*', '*', '*', '*', '*'], true], + [$timestamp, ['15', '*', '*', '*', '*'], true], + [$timestamp, ['*', '14', '*', '*', '*'], true], + [$timestamp, ['*', '*', '13', '*', '*'], true], + [$timestamp, ['*', '*', '*', '12', '*'], true], + [(new \DateTime($day))->getTimestamp(), ['*', '*', '*', '*', '1'], true], ]; } /** + * Test for matchCronExpression + * * @param string $cronExpressionPart * @param int $dateTimePart * @param bool $expectedResult + * + * @return void * @dataProvider matchCronExpressionDataProvider */ public function testMatchCronExpression($cronExpressionPart, $dateTimePart, $expectedResult) @@ -248,9 +314,11 @@ public function testMatchCronExpression($cronExpressionPart, $dateTimePart, $exp } /** + * Data provider + * * @return array */ - public function matchCronExpressionDataProvider() + public function matchCronExpressionDataProvider(): array { return [ ['*', 0, true], @@ -287,7 +355,11 @@ public function matchCronExpressionDataProvider() } /** + * Test for matchCronExpressionException + * * @param string $cronExpressionPart + * + * @return void * @expectedException \Magento\Framework\Exception\CronException * @dataProvider matchCronExpressionExceptionDataProvider */ @@ -304,9 +376,11 @@ public function testMatchCronExpressionException($cronExpressionPart) } /** + * Data provider + * * @return array */ - public function matchCronExpressionExceptionDataProvider() + public function matchCronExpressionExceptionDataProvider(): array { return [ ['1/2/3'], //Invalid cron expression, expecting 'match/modulus': 1/2/3 @@ -317,8 +391,12 @@ public function matchCronExpressionExceptionDataProvider() } /** + * Test for GetNumeric + * * @param mixed $param * @param int $expectedResult + * + * @return void * @dataProvider getNumericDataProvider */ public function testGetNumeric($param, $expectedResult) @@ -335,9 +413,11 @@ public function testGetNumeric($param, $expectedResult) } /** + * Data provider + * * @return array */ - public function getNumericDataProvider() + public function getNumericDataProvider(): array { return [ [null, false], @@ -362,6 +442,11 @@ public function getNumericDataProvider() ]; } + /** + * Test for tryLockJobSuccess + * + * @return void + */ public function testTryLockJobSuccess() { $scheduleId = 1; @@ -386,6 +471,11 @@ public function testTryLockJobSuccess() $this->assertEquals(Schedule::STATUS_RUNNING, $model->getStatus()); } + /** + * Test for tryLockJobFailure + * + * @return void + */ public function testTryLockJobFailure() { $scheduleId = 1; From c495f31900cc2250bb63bcd57242d518aa894d92 Mon Sep 17 00:00:00 2001 From: Mahesh Singh Date: Fri, 1 Feb 2019 00:44:04 +0530 Subject: [PATCH 033/315] issue #20380 fixed for 2.2 --- app/code/Magento/Sales/Model/Order.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Sales/Model/Order.php b/app/code/Magento/Sales/Model/Order.php index 1972aa71080c8..8b58f7abb6a27 100644 --- a/app/code/Magento/Sales/Model/Order.php +++ b/app/code/Magento/Sales/Model/Order.php @@ -1298,12 +1298,12 @@ public function getTrackingNumbers() * Retrieve shipping method * * @param bool $asObject return carrier code and shipping method data as object - * @return string|\Magento\Framework\DataObject + * @return string|null|\Magento\Framework\DataObject */ public function getShippingMethod($asObject = false) { $shippingMethod = parent::getShippingMethod(); - if (!$asObject) { + if (!$asObject || !$shippingMethod) { return $shippingMethod; } else { list($carrierCode, $method) = explode('_', $shippingMethod, 2); From c60d395347569dd4feb3be07dab5b8a5738b6e85 Mon Sep 17 00:00:00 2001 From: Ihor Sviziev Date: Fri, 1 Feb 2019 09:22:04 +0200 Subject: [PATCH 034/315] magento/magento2#19098 2.2.6 Use batches and direct queries to fix sales address upgrade Fix static test failure --- app/code/Magento/Sales/Setup/UpgradeData.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Sales/Setup/UpgradeData.php b/app/code/Magento/Sales/Setup/UpgradeData.php index 56cbf31c3d695..0f9833ed8f7f2 100644 --- a/app/code/Magento/Sales/Setup/UpgradeData.php +++ b/app/code/Magento/Sales/Setup/UpgradeData.php @@ -50,7 +50,7 @@ class UpgradeData implements UpgradeDataInterface /** * @SuppressWarnings(PHPMD.UnusedFormalParameter) - * + * * @param SalesSetupFactory $salesSetupFactory * @param Config $eavConfig * @param AggregatedFieldDataConverter $aggregatedFieldConverter From bef07b690a96fbc6bbe7b53d59b746a10c7cb949 Mon Sep 17 00:00:00 2001 From: DmytroPaidych Date: Fri, 1 Feb 2019 09:50:55 +0200 Subject: [PATCH 035/315] MAGETWO-97236: Delete Product Staging Update when the Product is used --- .../Catalog/Test/Mftf/Data/ProductData.xml | 5 +- .../Test/Mftf/Data/ProductLinkData.xml | 19 +++ .../Test/Mftf/Data/ProductLinksData.xml | 14 +++ .../Catalog/Test/Mftf/Data/WidgetsData.xml | 15 +++ .../Test/Mftf/Metadata/product-meta.xml | 3 + .../Test/Mftf/Page/AdminNewWidgetPage.xml | 14 +++ .../Test/Mftf/Page/StorefrontProductPage.xml | 3 +- .../Mftf/Section/AdminNewWidgetSection.xml | 14 +++ ...dminNewWidgetSelectProductPopupSection.xml | 15 +++ ...StorefrontProducRelatedProductsSection.xml | 14 +++ .../Mftf/Page/AdminUrlRewriteEditPage.xml | 14 +++ .../Section/AdminUrlRewriteEditSection.xml | 14 +++ .../AdminCreateWidgetActionGroup.xml | 108 +++++++++--------- .../Test/Mftf/Page/AdminNewWidgetPage.xml | 4 +- .../Mftf/Section/AdminNewWidgetSection.xml | 3 +- 15 files changed, 203 insertions(+), 56 deletions(-) create mode 100644 app/code/Magento/Catalog/Test/Mftf/Data/ProductLinkData.xml create mode 100644 app/code/Magento/Catalog/Test/Mftf/Data/ProductLinksData.xml create mode 100644 app/code/Magento/Catalog/Test/Mftf/Data/WidgetsData.xml create mode 100644 app/code/Magento/Catalog/Test/Mftf/Page/AdminNewWidgetPage.xml create mode 100644 app/code/Magento/Catalog/Test/Mftf/Section/AdminNewWidgetSection.xml create mode 100644 app/code/Magento/Catalog/Test/Mftf/Section/AdminNewWidgetSelectProductPopupSection.xml create mode 100644 app/code/Magento/Catalog/Test/Mftf/Section/StorefrontProducRelatedProductsSection.xml create mode 100644 app/code/Magento/UrlRewrite/Test/Mftf/Page/AdminUrlRewriteEditPage.xml create mode 100644 app/code/Magento/UrlRewrite/Test/Mftf/Section/AdminUrlRewriteEditSection.xml diff --git a/app/code/Magento/Catalog/Test/Mftf/Data/ProductData.xml b/app/code/Magento/Catalog/Test/Mftf/Data/ProductData.xml index 39f4f0f2d997d..86bdb1a102172 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Data/ProductData.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Data/ProductData.xml @@ -7,7 +7,7 @@ --> + xsi:noNamespaceSchemaLocation="urn:magento:mftf:DataGenerator/etc/dataProfileSchema.xsd"> testSku simple @@ -282,4 +282,7 @@ 1 EavStock1 + + + diff --git a/app/code/Magento/Catalog/Test/Mftf/Data/ProductLinkData.xml b/app/code/Magento/Catalog/Test/Mftf/Data/ProductLinkData.xml new file mode 100644 index 0000000000000..000bb2095002c --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/Data/ProductLinkData.xml @@ -0,0 +1,19 @@ + + + + + + + + related + simple + 1 + Qty1000 + + diff --git a/app/code/Magento/Catalog/Test/Mftf/Data/ProductLinksData.xml b/app/code/Magento/Catalog/Test/Mftf/Data/ProductLinksData.xml new file mode 100644 index 0000000000000..bd4f807880ab8 --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/Data/ProductLinksData.xml @@ -0,0 +1,14 @@ + + + + + + RelatedProductLink + + diff --git a/app/code/Magento/Catalog/Test/Mftf/Data/WidgetsData.xml b/app/code/Magento/Catalog/Test/Mftf/Data/WidgetsData.xml new file mode 100644 index 0000000000000..83f0a56c21545 --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/Data/WidgetsData.xml @@ -0,0 +1,15 @@ + + + + + + Catalog Product Link + Product Link Block Template + + diff --git a/app/code/Magento/Catalog/Test/Mftf/Metadata/product-meta.xml b/app/code/Magento/Catalog/Test/Mftf/Metadata/product-meta.xml index 1bf7d0b0d988f..23be8408d4a1e 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Metadata/product-meta.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Metadata/product-meta.xml @@ -121,4 +121,7 @@ application/json + + application/json + diff --git a/app/code/Magento/Catalog/Test/Mftf/Page/AdminNewWidgetPage.xml b/app/code/Magento/Catalog/Test/Mftf/Page/AdminNewWidgetPage.xml new file mode 100644 index 0000000000000..e23a503266e33 --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/Page/AdminNewWidgetPage.xml @@ -0,0 +1,14 @@ + + + + + +
+ + diff --git a/app/code/Magento/Catalog/Test/Mftf/Page/StorefrontProductPage.xml b/app/code/Magento/Catalog/Test/Mftf/Page/StorefrontProductPage.xml index 9fcbcc199176b..fdfee62f6dc0b 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Page/StorefrontProductPage.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Page/StorefrontProductPage.xml @@ -7,11 +7,12 @@ --> + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/PageObject.xsd">
+
diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/AdminNewWidgetSection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/AdminNewWidgetSection.xml new file mode 100644 index 0000000000000..5329ad48c8f43 --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/Section/AdminNewWidgetSection.xml @@ -0,0 +1,14 @@ + + + + +
+ +
+
diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/AdminNewWidgetSelectProductPopupSection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/AdminNewWidgetSelectProductPopupSection.xml new file mode 100644 index 0000000000000..0da67849f85c6 --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/Section/AdminNewWidgetSelectProductPopupSection.xml @@ -0,0 +1,15 @@ + + + + +
+ + +
+
diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/StorefrontProducRelatedProductsSection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/StorefrontProducRelatedProductsSection.xml new file mode 100644 index 0000000000000..a7b72bbaa78aa --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/Section/StorefrontProducRelatedProductsSection.xml @@ -0,0 +1,14 @@ + + + + +
+ +
+
diff --git a/app/code/Magento/UrlRewrite/Test/Mftf/Page/AdminUrlRewriteEditPage.xml b/app/code/Magento/UrlRewrite/Test/Mftf/Page/AdminUrlRewriteEditPage.xml new file mode 100644 index 0000000000000..b43e0e05ad55d --- /dev/null +++ b/app/code/Magento/UrlRewrite/Test/Mftf/Page/AdminUrlRewriteEditPage.xml @@ -0,0 +1,14 @@ + + + + + +
+ + diff --git a/app/code/Magento/UrlRewrite/Test/Mftf/Section/AdminUrlRewriteEditSection.xml b/app/code/Magento/UrlRewrite/Test/Mftf/Section/AdminUrlRewriteEditSection.xml new file mode 100644 index 0000000000000..7095214e72c43 --- /dev/null +++ b/app/code/Magento/UrlRewrite/Test/Mftf/Section/AdminUrlRewriteEditSection.xml @@ -0,0 +1,14 @@ + + + + +
+ +
+
diff --git a/app/code/Magento/Widget/Test/Mftf/ActionGroup/AdminCreateWidgetActionGroup.xml b/app/code/Magento/Widget/Test/Mftf/ActionGroup/AdminCreateWidgetActionGroup.xml index b6dfc00c0ff9e..f146e793db882 100644 --- a/app/code/Magento/Widget/Test/Mftf/ActionGroup/AdminCreateWidgetActionGroup.xml +++ b/app/code/Magento/Widget/Test/Mftf/ActionGroup/AdminCreateWidgetActionGroup.xml @@ -7,58 +7,64 @@ --> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/code/Magento/Widget/Test/Mftf/Page/AdminNewWidgetPage.xml b/app/code/Magento/Widget/Test/Mftf/Page/AdminNewWidgetPage.xml index 8eb0a5f65318e..5946bb81d9485 100644 --- a/app/code/Magento/Widget/Test/Mftf/Page/AdminNewWidgetPage.xml +++ b/app/code/Magento/Widget/Test/Mftf/Page/AdminNewWidgetPage.xml @@ -7,8 +7,8 @@ --> - + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/PageObject.xsd"> +
diff --git a/app/code/Magento/Widget/Test/Mftf/Section/AdminNewWidgetSection.xml b/app/code/Magento/Widget/Test/Mftf/Section/AdminNewWidgetSection.xml index adf234baede72..57f07d9795b68 100644 --- a/app/code/Magento/Widget/Test/Mftf/Section/AdminNewWidgetSection.xml +++ b/app/code/Magento/Widget/Test/Mftf/Section/AdminNewWidgetSection.xml @@ -7,7 +7,7 @@ --> + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd">
@@ -17,6 +17,7 @@ + From 9b6ef590ed0fc95c5da7e5ebfacf5b2452dead5e Mon Sep 17 00:00:00 2001 From: Serhiy Zhovnir Date: Sun, 3 Feb 2019 19:19:10 +0200 Subject: [PATCH 036/315] #18698 Fixed order email sending via order async email sending when order was created with disabled email sending --- app/code/Magento/Sales/Model/Order/Email/Sender/OrderSender.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Sales/Model/Order/Email/Sender/OrderSender.php b/app/code/Magento/Sales/Model/Order/Email/Sender/OrderSender.php index f06da0de0fd00..7ac11ca073d26 100644 --- a/app/code/Magento/Sales/Model/Order/Email/Sender/OrderSender.php +++ b/app/code/Magento/Sales/Model/Order/Email/Sender/OrderSender.php @@ -97,7 +97,7 @@ public function __construct( */ public function send(Order $order, $forceSyncMode = false) { - $order->setSendEmail(true); + $order->setSendEmail($this->identityContainer->isEnabled()); if (!$this->globalConfig->getValue('sales_email/general/async_sending') || $forceSyncMode) { if ($this->checkAndSend($order)) { From f4bec9aec5a22af59021b937fc09555823d3598e Mon Sep 17 00:00:00 2001 From: amol 2jcommerce Date: Mon, 4 Feb 2019 20:20:11 +0530 Subject: [PATCH 037/315] admin-store-view-label-not-alignment-2 --- .../web/css/source/module/main/actions-bar/_store-switcher.less | 1 + 1 file changed, 1 insertion(+) diff --git a/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/main/actions-bar/_store-switcher.less b/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/main/actions-bar/_store-switcher.less index 80bebb22a9043..8daa7d5808d06 100644 --- a/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/main/actions-bar/_store-switcher.less +++ b/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/main/actions-bar/_store-switcher.less @@ -235,6 +235,7 @@ .store-view { &:not(.store-switcher) { float: left; + margin-top: 13px; } .store-switcher-label { From d7fb21ae94273dc5c5e0fd445cc9a3049883ded1 Mon Sep 17 00:00:00 2001 From: DmytroPaidych Date: Tue, 5 Feb 2019 13:03:11 +0200 Subject: [PATCH 038/315] MAGETWO-97236: Delete Product Staging Update when the Product is used --- .../UrlRewrite/Test/Mftf/Page/AdminUrlRewriteEditPage.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/UrlRewrite/Test/Mftf/Page/AdminUrlRewriteEditPage.xml b/app/code/Magento/UrlRewrite/Test/Mftf/Page/AdminUrlRewriteEditPage.xml index b43e0e05ad55d..f51b9321e6911 100644 --- a/app/code/Magento/UrlRewrite/Test/Mftf/Page/AdminUrlRewriteEditPage.xml +++ b/app/code/Magento/UrlRewrite/Test/Mftf/Page/AdminUrlRewriteEditPage.xml @@ -8,7 +8,7 @@ - +
From 7ef7fdeb39623fb5e9da437724993396817609df Mon Sep 17 00:00:00 2001 From: Serhiy Yelahin Date: Tue, 5 Feb 2019 13:22:39 +0200 Subject: [PATCH 039/315] MAGETWO-97950: Minicart isn't updated for disabled products --- .../frontend/templates/cart/noItems.phtml | 7 ++++ .../view/frontend/web/js/empty-cart.js | 12 ++++++ ...efrontGuestCheckoutDisabledProductTest.xml | 41 ++++++++++++++++--- 3 files changed, 54 insertions(+), 6 deletions(-) create mode 100644 app/code/Magento/Checkout/view/frontend/web/js/empty-cart.js diff --git a/app/code/Magento/Checkout/view/frontend/templates/cart/noItems.phtml b/app/code/Magento/Checkout/view/frontend/templates/cart/noItems.phtml index 1c0c221a550cd..67ac4a9335565 100644 --- a/app/code/Magento/Checkout/view/frontend/templates/cart/noItems.phtml +++ b/app/code/Magento/Checkout/view/frontend/templates/cart/noItems.phtml @@ -13,3 +13,10 @@ $block->escapeUrl($block->getContinueShoppingUrl())) ?>

getChildHtml('shopping.cart.table.after') ?> + \ No newline at end of file diff --git a/app/code/Magento/Checkout/view/frontend/web/js/empty-cart.js b/app/code/Magento/Checkout/view/frontend/web/js/empty-cart.js new file mode 100644 index 0000000000000..27d38697afe39 --- /dev/null +++ b/app/code/Magento/Checkout/view/frontend/web/js/empty-cart.js @@ -0,0 +1,12 @@ +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +define([ + 'Magento_Customer/js/customer-data' +], function (customerData) { + 'use strict'; + + customerData.reload(['cart'], false); +}); diff --git a/app/code/Magento/Quote/Test/Mftf/Test/StorefrontGuestCheckoutDisabledProductTest.xml b/app/code/Magento/Quote/Test/Mftf/Test/StorefrontGuestCheckoutDisabledProductTest.xml index a2f08353a4f3b..034c2bc6f051b 100644 --- a/app/code/Magento/Quote/Test/Mftf/Test/StorefrontGuestCheckoutDisabledProductTest.xml +++ b/app/code/Magento/Quote/Test/Mftf/Test/StorefrontGuestCheckoutDisabledProductTest.xml @@ -22,6 +22,9 @@ + + + @@ -70,7 +73,10 @@ + + + @@ -79,13 +85,11 @@ - - @@ -94,8 +98,6 @@ - - @@ -113,10 +115,37 @@ - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 078830a669c090b763e6e844b9116ba3ff19d141 Mon Sep 17 00:00:00 2001 From: Serhii Voloshkov Date: Tue, 5 Feb 2019 15:26:49 +0200 Subject: [PATCH 040/315] MAGETWO-94450: Rewards points earned from coupon code are not applied to guests that create accounts after checking out --- .../AdminCustomerMainActionsSection.xml | 3 +- .../Test/Mftf/Data/SalesRuleData.xml | 41 ++++++++++++++++++- .../Data/SalesRuleExtensionAttributeData.xml | 13 ++++++ .../sales-rule-extension-attribute-meta.xml | 12 ++++++ .../Test/Mftf/Metadata/sales_rule-meta.xml | 6 +-- 5 files changed, 68 insertions(+), 7 deletions(-) create mode 100644 app/code/Magento/SalesRule/Test/Mftf/Data/SalesRuleExtensionAttributeData.xml create mode 100644 app/code/Magento/SalesRule/Test/Mftf/Metadata/sales-rule-extension-attribute-meta.xml diff --git a/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerMainActionsSection.xml b/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerMainActionsSection.xml index 0a77890033295..9553752539757 100644 --- a/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerMainActionsSection.xml +++ b/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerMainActionsSection.xml @@ -7,8 +7,9 @@ --> + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd">
+
diff --git a/app/code/Magento/SalesRule/Test/Mftf/Data/SalesRuleData.xml b/app/code/Magento/SalesRule/Test/Mftf/Data/SalesRuleData.xml index 595aedc2b604f..25aaa6dd5a23d 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Data/SalesRuleData.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Data/SalesRuleData.xml @@ -7,7 +7,7 @@ --> + xsi:noNamespaceSchemaLocation="urn:magento:mftf:DataGenerator/etc/dataProfileSchema.xsd"> salesRule Sales Rule Descritpion @@ -141,7 +141,6 @@ 0 0 - SimpleSalesRule Sales Rule Description @@ -168,6 +167,44 @@ 10 1 + + SalesRuleReward + Sales Rule with Reward Point + + 1 + + + 0 + 1 + 2 + 3 + + 10 + true + true + true + 0 + by_percent + 0 + 0 + 0 + false + 0 + true + NO_COUPON + false + 10 + 0 + SalesRuleExtensionAttribute + + + + SalesRule + Main Website + 'NOT LOGGED IN', 'General', 'Wholesale', 'Retailer' + Fixed amount discount for whole cart + 0 + SalesRule diff --git a/app/code/Magento/SalesRule/Test/Mftf/Data/SalesRuleExtensionAttributeData.xml b/app/code/Magento/SalesRule/Test/Mftf/Data/SalesRuleExtensionAttributeData.xml new file mode 100644 index 0000000000000..43ff4d897c143 --- /dev/null +++ b/app/code/Magento/SalesRule/Test/Mftf/Data/SalesRuleExtensionAttributeData.xml @@ -0,0 +1,13 @@ + + + + + 200 + + diff --git a/app/code/Magento/SalesRule/Test/Mftf/Metadata/sales-rule-extension-attribute-meta.xml b/app/code/Magento/SalesRule/Test/Mftf/Metadata/sales-rule-extension-attribute-meta.xml new file mode 100644 index 0000000000000..51c4ac24a7426 --- /dev/null +++ b/app/code/Magento/SalesRule/Test/Mftf/Metadata/sales-rule-extension-attribute-meta.xml @@ -0,0 +1,12 @@ + + + + integer + + diff --git a/app/code/Magento/SalesRule/Test/Mftf/Metadata/sales_rule-meta.xml b/app/code/Magento/SalesRule/Test/Mftf/Metadata/sales_rule-meta.xml index 0d4c4356a20a7..38009c510d2be 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Metadata/sales_rule-meta.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Metadata/sales_rule-meta.xml @@ -6,7 +6,7 @@ */ --> + xsi:noNamespaceSchemaLocation="urn:magento:mftf:DataGenerator/etc/dataOperation.xsd"> application/json @@ -30,6 +30,7 @@ string boolean boolean + sales-rule-extension-attribute SalesRuleStoreLabel @@ -67,9 +68,6 @@ string empty_extension_attribute - - integer - From 532ca5d9cc11685ceed4fa1923662fa0e037e4b3 Mon Sep 17 00:00:00 2001 From: Serhiy Yelahin Date: Tue, 5 Feb 2019 16:14:00 +0200 Subject: [PATCH 041/315] MAGETWO-97950: Minicart isn't updated for disabled products --- .../Mftf/Test/StorefrontGuestCheckoutDisabledProductTest.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Quote/Test/Mftf/Test/StorefrontGuestCheckoutDisabledProductTest.xml b/app/code/Magento/Quote/Test/Mftf/Test/StorefrontGuestCheckoutDisabledProductTest.xml index 034c2bc6f051b..e5e7c3834bf7d 100644 --- a/app/code/Magento/Quote/Test/Mftf/Test/StorefrontGuestCheckoutDisabledProductTest.xml +++ b/app/code/Magento/Quote/Test/Mftf/Test/StorefrontGuestCheckoutDisabledProductTest.xml @@ -74,7 +74,7 @@ - + @@ -123,7 +123,7 @@ - + From d70186b5835f4839413c283a5f319618998b762e Mon Sep 17 00:00:00 2001 From: Serhiy Zhovnir Date: Tue, 5 Feb 2019 21:14:09 +0200 Subject: [PATCH 042/315] #18698 Fix PHPUnit test --- .../Unit/Model/Order/Email/Sender/OrderSenderTest.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/OrderSenderTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/OrderSenderTest.php index 46c44c03b1514..88053ea684ce8 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/OrderSenderTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/OrderSenderTest.php @@ -64,7 +64,7 @@ public function testSend($configValue, $forceSyncMode, $emailSendingResult, $sen $this->orderMock->expects($this->once()) ->method('setSendEmail') - ->with(true); + ->with($emailSendingResult); $this->globalConfig->expects($this->once()) ->method('getValue') @@ -72,7 +72,7 @@ public function testSend($configValue, $forceSyncMode, $emailSendingResult, $sen ->willReturn($configValue); if (!$configValue || $forceSyncMode) { - $this->identityContainerMock->expects($this->once()) + $this->identityContainerMock->expects($this->exactly(2)) ->method('isEnabled') ->willReturn($emailSendingResult); @@ -118,7 +118,7 @@ public function testSend($configValue, $forceSyncMode, $emailSendingResult, $sen $this->orderMock->expects($this->once()) ->method('setEmailSent') - ->with(true); + ->with($emailSendingResult); $this->orderResourceMock->expects($this->once()) ->method('saveAttribute') @@ -210,7 +210,7 @@ public function testSendVirtualOrder($isVirtualOrder, $formatCallCount, $expecte ->with('sales_email/general/async_sending') ->willReturn(false); - $this->identityContainerMock->expects($this->once()) + $this->identityContainerMock->expects($this->exactly(2)) ->method('isEnabled') ->willReturn(true); From 03f4af3ec92c1487f1564f3967e729edf137518c Mon Sep 17 00:00:00 2001 From: DianaRusin Date: Wed, 6 Feb 2019 14:05:59 +0200 Subject: [PATCH 043/315] MAGETWO-95182: Order placed by new customer before they registered is displayed in the admin under the name Guest --- ...ontCheckCustomerInfoCreatedByGuestTest.xml | 61 +++++++++++++++++++ .../AssignOrderToCustomerObserver.php | 11 ++++ .../AssignOrderToCustomerObserverTest.php | 33 ++++++++-- 3 files changed, 99 insertions(+), 6 deletions(-) create mode 100644 app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckCustomerInfoCreatedByGuestTest.xml diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckCustomerInfoCreatedByGuestTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckCustomerInfoCreatedByGuestTest.xml new file mode 100644 index 0000000000000..adc308b490c33 --- /dev/null +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckCustomerInfoCreatedByGuestTest.xml @@ -0,0 +1,61 @@ + + + + + + + + + + <description value="Check customer information after placing the order as the guest who created an account"/> + <severity value="MAJOR"/> + <testCaseId value="MC-13839"/> + <useCaseId value="MAGETWO-95820"/> + <group value="checkout"/> + <group value="customer"/> + </annotations> + + <before> + <createData entity="_defaultCategory" stepKey="createCategory"/> + <createData entity="_defaultProduct" stepKey="createProduct"> + <requiredEntity createDataKey="createCategory"/> + </createData> + </before> + + <after> + <actionGroup ref="CustomerLogoutStorefrontActionGroup" stepKey="customerLogoutFromStorefront" /> + <deleteData createDataKey="createProduct" stepKey="deleteProduct" /> + <deleteData createDataKey="createCategory" stepKey="deleteCategory" /> + <actionGroup ref="logout" stepKey="logoutFromAdmin"/> + </after> + + <amOnPage url="{{StorefrontProductPage.url($$createProduct.name$$)}}" stepKey="navigateToProductPage"/> + <actionGroup ref="addToCartFromStorefrontProductPage" stepKey="addToCartFromStorefrontProductPage"> + <argument name="productName" value="$$createProduct.name$$"/> + </actionGroup> + <actionGroup ref="GoToCheckoutFromMinicartActionGroup" stepKey="goToCheckoutFromMinicart"/> + <actionGroup ref="GuestCheckoutFillingShippingSectionActionGroup" stepKey="guestCheckoutFillingShippingSection"> + <argument name="customerVar" value="CustomerEntityOne"/> + <argument name="customerAddressVar" value="CustomerAddressSimple"/> + </actionGroup> + <actionGroup ref="CheckoutPlaceOrderActionGroup" stepKey="placeOrder"> + <argument name="orderNumberMessage" value="CONST.successGuestCheckoutOrderNumberMessage"/> + <argument name="emailYouMessage" value="CONST.successCheckoutEmailYouMessage" /> + </actionGroup> + <grabTextFrom selector="{{CheckoutSuccessMainSection.orderNumber}}" stepKey="grabOrderNumber"/> + <click selector="{{CheckoutSuccessRegisterSection.createAccountButton}}" stepKey="clickCreateAccountButton"/> + <fillField selector="{{StorefrontCustomerCreateFormSection.passwordField}}" userInput="{{CustomerEntityOne.password}}" stepKey="typePassword"/> + <fillField selector="{{StorefrontCustomerCreateFormSection.confirmPasswordField}}" userInput="{{CustomerEntityOne.password}}" stepKey="typeConfirmationPassword"/> + <click selector="{{StorefrontCustomerCreateFormSection.createAccountButton}}" stepKey="clickOnCreateAccount"/> + <see selector="{{StorefrontMessagesSection.successMessage}}" userInput="Thank you for registering" stepKey="verifyAccountCreated"/> + <actionGroup ref="LoginAsAdmin" stepKey="loginToAdmin"/> + <amOnPage url="{{AdminOrderDetailsPage.url('$grabOrderNumber')}}" stepKey="navigateToOrderPage"/> + <see userInput="{{CustomerEntityOne.firstname}}" selector="{{AdminOrderDetailsInformationSection.customerName}}" stepKey="seeCustomerName"/> + </test> +</tests> diff --git a/app/code/Magento/Sales/Observer/AssignOrderToCustomerObserver.php b/app/code/Magento/Sales/Observer/AssignOrderToCustomerObserver.php index 9857fa39fa51a..80e909941c5ce 100644 --- a/app/code/Magento/Sales/Observer/AssignOrderToCustomerObserver.php +++ b/app/code/Magento/Sales/Observer/AssignOrderToCustomerObserver.php @@ -57,6 +57,17 @@ public function execute(Observer $observer) $orderId = $delegateData['__sales_assign_order_id']; $order = $this->orderRepository->get($orderId); if (!$order->getCustomerId() && $customer->getId()) { + // Assign customer info to order after customer creation. + $order->setCustomerId($customer->getId()) + ->setCustomerIsGuest(0) + ->setCustomerEmail($customer->getEmail()) + ->setCustomerFirstname($customer->getFirstname()) + ->setCustomerLastname($customer->getLastname()) + ->setCustomerMiddlename($customer->getMiddlename()) + ->setCustomerPrefix($customer->getPrefix()) + ->setCustomerSuffix($customer->getSuffix()) + ->setCustomerGroupId($customer->getGroupId()); + $this->assignmentService->execute($order, $customer); } } diff --git a/app/code/Magento/Sales/Test/Unit/Observer/AssignOrderToCustomerObserverTest.php b/app/code/Magento/Sales/Test/Unit/Observer/AssignOrderToCustomerObserverTest.php index 18371274049e3..8890f01130c82 100644 --- a/app/code/Magento/Sales/Test/Unit/Observer/AssignOrderToCustomerObserverTest.php +++ b/app/code/Magento/Sales/Test/Unit/Observer/AssignOrderToCustomerObserverTest.php @@ -52,9 +52,10 @@ protected function setUp() * * @dataProvider getCustomerIds * @param null|int $customerId + * @param null|int $customerOrderId * @return void */ - public function testAssignOrderToCustomerAfterGuestOrder($customerId) + public function testAssignOrderToCustomerAfterGuestOrder($customerId, $customerOrderId) { $orderId = 1; /** @var Observer|PHPUnit_Framework_MockObject_MockObject $observerMock */ @@ -64,7 +65,12 @@ public function testAssignOrderToCustomerAfterGuestOrder($customerId) ->setMethods(['getData']) ->getMock(); /** @var CustomerInterface|PHPUnit_Framework_MockObject_MockObject $customerMock */ - $customerMock = $this->createMock(CustomerInterface::class); + $customerMock = $this->getMockBuilder(CustomerInterface::class) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + $customerMock->expects($this->any()) + ->method('getId') + ->willReturn($customerId); /** @var OrderInterface|PHPUnit_Framework_MockObject_MockObject $orderMock */ $orderMock = $this->getMockBuilder(OrderInterface::class) ->disableOriginalConstructor() @@ -75,13 +81,24 @@ public function testAssignOrderToCustomerAfterGuestOrder($customerId) ['delegate_data', null, ['__sales_assign_order_id' => $orderId]], ['customer_data_object', null, $customerMock] ]); - $orderMock->expects($this->once())->method('getCustomerId')->willReturn($customerId); + $orderMock->expects($this->any())->method('getCustomerId')->willReturn($customerOrderId); $this->orderRepositoryMock->expects($this->once())->method('get')->with($orderId) ->willReturn($orderMock); - if ($customerId) { + if (!$customerOrderId && $customerId) { + $orderMock->expects($this->once())->method('setCustomerId')->willReturn($orderMock); + $orderMock->expects($this->once())->method('setCustomerIsGuest')->willReturn($orderMock); + $orderMock->expects($this->once())->method('setCustomerEmail')->willReturn($orderMock); + $orderMock->expects($this->once())->method('setCustomerFirstname')->willReturn($orderMock); + $orderMock->expects($this->once())->method('setCustomerLastname')->willReturn($orderMock); + $orderMock->expects($this->once())->method('setCustomerMiddlename')->willReturn($orderMock); + $orderMock->expects($this->once())->method('setCustomerPrefix')->willReturn($orderMock); + $orderMock->expects($this->once())->method('setCustomerSuffix')->willReturn($orderMock); + $orderMock->expects($this->once())->method('setCustomerGroupId')->willReturn($orderMock); + $this->assignmentMock->expects($this->once())->method('execute')->with($orderMock, $customerMock); $this->sut->execute($observerMock); + return; } @@ -94,8 +111,12 @@ public function testAssignOrderToCustomerAfterGuestOrder($customerId) * * @return array */ - public function getCustomerIds() + public function getCustomerIds(): array { - return [[null, 1]]; + return [ + [null, null], + [1, null], + [1, 1], + ]; } } From 004de84450feaa72f125145c7c46cc730008fa80 Mon Sep 17 00:00:00 2001 From: Viktor Sevch <svitja@ukr.net> Date: Thu, 7 Feb 2019 11:35:26 +0200 Subject: [PATCH 044/315] MAGETWO-95463: Order Sales Report includes canceled orders --- .../Block/Adminhtml/Sales/Sales/Grid.php | 68 ++++++++++++- .../GenerateOrderReportActionGroup.xml | 22 +++++ .../Test/Mftf/Page/OrdersReportPage.xml | 14 +++ .../Section/AdminOrderReportFilterSection.xml | 16 ++++ .../AdminOrderReportMainActionsSection.xml | 15 +++ .../Section/AdminOrderReportTableSection.xml | 15 +++ .../CancelOrdersInOrderSalesReportTest.xml | 95 +++++++++++++++++++ 7 files changed, 242 insertions(+), 3 deletions(-) create mode 100644 app/code/Magento/Reports/Test/Mftf/ActionGroup/GenerateOrderReportActionGroup.xml create mode 100644 app/code/Magento/Reports/Test/Mftf/Page/OrdersReportPage.xml create mode 100644 app/code/Magento/Reports/Test/Mftf/Section/AdminOrderReportFilterSection.xml create mode 100644 app/code/Magento/Reports/Test/Mftf/Section/AdminOrderReportMainActionsSection.xml create mode 100644 app/code/Magento/Reports/Test/Mftf/Section/AdminOrderReportTableSection.xml create mode 100644 app/code/Magento/Reports/Test/Mftf/Test/CancelOrdersInOrderSalesReportTest.xml diff --git a/app/code/Magento/Reports/Block/Adminhtml/Sales/Sales/Grid.php b/app/code/Magento/Reports/Block/Adminhtml/Sales/Sales/Grid.php index 1f90309721c23..9c80f6aa423b8 100644 --- a/app/code/Magento/Reports/Block/Adminhtml/Sales/Sales/Grid.php +++ b/app/code/Magento/Reports/Block/Adminhtml/Sales/Sales/Grid.php @@ -6,23 +6,58 @@ namespace Magento\Reports\Block\Adminhtml\Sales\Sales; +use Magento\Framework\DataObject; use Magento\Reports\Block\Adminhtml\Grid\Column\Renderer\Currency; +use Magento\Framework\App\ObjectManager; +use Magento\Sales\Model\Order\ConfigFactory; +use Magento\Sales\Model\Order; /** * Adminhtml sales report grid block * - * @author Magento Core Team <core@magentocommerce.com> * @SuppressWarnings(PHPMD.DepthOfInheritance) */ class Grid extends \Magento\Reports\Block\Adminhtml\Grid\AbstractGrid { /** - * GROUP BY criteria - * * @var string */ protected $_columnGroupBy = 'period'; + /** + * @var ConfigFactory + */ + private $configFactory; + + /** + * @param \Magento\Backend\Block\Template\Context $context + * @param \Magento\Backend\Helper\Data $backendHelper + * @param \Magento\Reports\Model\ResourceModel\Report\Collection\Factory $resourceFactory + * @param \Magento\Reports\Model\Grouped\CollectionFactory $collectionFactory + * @param \Magento\Reports\Helper\Data $reportsData + * @param array $data + * @param ConfigFactory|null $configFactory + */ + public function __construct( + \Magento\Backend\Block\Template\Context $context, + \Magento\Backend\Helper\Data $backendHelper, + \Magento\Reports\Model\ResourceModel\Report\Collection\Factory $resourceFactory, + \Magento\Reports\Model\Grouped\CollectionFactory $collectionFactory, + \Magento\Reports\Helper\Data $reportsData, + array $data = [], + ConfigFactory $configFactory = null + ) { + parent::__construct( + $context, + $backendHelper, + $resourceFactory, + $collectionFactory, + $reportsData, + $data + ); + $this->configFactory = $configFactory ?: ObjectManager::getInstance()->get(ConfigFactory::class); + } + /** * {@inheritdoc} * @codeCoverageIgnore @@ -328,4 +363,31 @@ protected function _prepareColumns() return parent::_prepareColumns(); } + + /** + * @inheritdoc + * + * Filter canceled statuses for orders. + * + * @return Grid + */ + protected function _prepareCollection() + { + /** @var DataObject $filterData */ + $filterData = $this->getData('filter_data'); + if (!$filterData->hasData('order_statuses')) { + $orderConfig = $this->configFactory->create(); + $statusValues = []; + $canceledStatuses = $orderConfig->getStateStatuses(Order::STATE_CANCELED); + $statusCodes = array_keys($orderConfig->getStatuses()); + foreach ($statusCodes as $code) { + if (!isset($canceledStatuses[$code])) { + $statusValues[] = $code; + } + } + $filterData->setData('order_statuses', $statusValues); + } + + return parent::_prepareCollection(); + } } diff --git a/app/code/Magento/Reports/Test/Mftf/ActionGroup/GenerateOrderReportActionGroup.xml b/app/code/Magento/Reports/Test/Mftf/ActionGroup/GenerateOrderReportActionGroup.xml new file mode 100644 index 0000000000000..79b9c21b0db6a --- /dev/null +++ b/app/code/Magento/Reports/Test/Mftf/ActionGroup/GenerateOrderReportActionGroup.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + <actionGroup name="GenerateOrderReportActionGroup"> + <arguments> + <argument name="orderFromDate" type="string"/> + <argument name="orderToDate" type="string"/> + </arguments> + <click selector="{{AdminOrderReportMainActionsSection.here}}" stepKey="refreshStatistics" /> + <fillField selector="{{AdminOrderReportFilterSection.dateFrom}}" userInput="{{orderFromDate}}" stepKey="fillFromDate"/> + <fillField selector="{{AdminOrderReportFilterSection.dateTo}}" userInput="{{orderToDate}}" stepKey="fillToDate"/> + <selectOption selector="{{AdminOrderReportFilterSection.orderStatus}}" userInput="Any" stepKey="selectAnyOption" /> + <click selector="{{AdminOrderReportMainActionsSection.showReport}}" stepKey="showReport" /> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Reports/Test/Mftf/Page/OrdersReportPage.xml b/app/code/Magento/Reports/Test/Mftf/Page/OrdersReportPage.xml new file mode 100644 index 0000000000000..46509089b97ba --- /dev/null +++ b/app/code/Magento/Reports/Test/Mftf/Page/OrdersReportPage.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<pages xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/PageObject.xsd"> + <page name="OrdersReportPage" url="reports/report_sales/sales/" area="admin" module="Reports"> + <section name="OrderReportFilterSection"/> + <section name="OrderReportMainSection"/> + <section name="GeneratedReportSection" /> + </page> +</pages> diff --git a/app/code/Magento/Reports/Test/Mftf/Section/AdminOrderReportFilterSection.xml b/app/code/Magento/Reports/Test/Mftf/Section/AdminOrderReportFilterSection.xml new file mode 100644 index 0000000000000..33527e1262020 --- /dev/null +++ b/app/code/Magento/Reports/Test/Mftf/Section/AdminOrderReportFilterSection.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> + <section name="AdminOrderReportFilterSection"> + <element name="dateFrom" type="input" selector="#sales_report_from"/> + <element name="dateTo" type="input" selector="#sales_report_to"/> + <element name="orderStatus" type="select" selector="#sales_report_show_order_statuses"/> + </section> +</sections> diff --git a/app/code/Magento/Reports/Test/Mftf/Section/AdminOrderReportMainActionsSection.xml b/app/code/Magento/Reports/Test/Mftf/Section/AdminOrderReportMainActionsSection.xml new file mode 100644 index 0000000000000..e9a56f538fd9c --- /dev/null +++ b/app/code/Magento/Reports/Test/Mftf/Section/AdminOrderReportMainActionsSection.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> + <section name="AdminOrderReportMainActionsSection"> + <element name="showReport" type="button" selector="#filter_form_submit"/> + <element name="here" type="text" selector="//a[contains(text(), 'here')]"/> + </section> +</sections> diff --git a/app/code/Magento/Reports/Test/Mftf/Section/AdminOrderReportTableSection.xml b/app/code/Magento/Reports/Test/Mftf/Section/AdminOrderReportTableSection.xml new file mode 100644 index 0000000000000..e920d28bcf386 --- /dev/null +++ b/app/code/Magento/Reports/Test/Mftf/Section/AdminOrderReportTableSection.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> + <section name="AdminOrderReportTableSection"> + <element name="ordersCount" type="text" selector=".totals .col-orders.col-orders_count.col-number"/> + <element name="canceledOrders" type="text" selector=".totals .col-canceled.col-total_canceled_amount.a-right"/> + </section> +</sections> diff --git a/app/code/Magento/Reports/Test/Mftf/Test/CancelOrdersInOrderSalesReportTest.xml b/app/code/Magento/Reports/Test/Mftf/Test/CancelOrdersInOrderSalesReportTest.xml new file mode 100644 index 0000000000000..c229fb1cf0271 --- /dev/null +++ b/app/code/Magento/Reports/Test/Mftf/Test/CancelOrdersInOrderSalesReportTest.xml @@ -0,0 +1,95 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="CancelOrdersInOrderSalesReportTest"> + <annotations> + <features value="Reports"/> + <stories value="Order Sales Report"/> + <group value="reports"/> + <title value="Canceled orders in order sales report"/> + <description value="Verify canceling of orders in order sales report"/> + <severity value="MAJOR"/> + <testCaseId value="MC-13838"/> + <useCaseId value="MAGETWO-95463"/> + </annotations> + <before> + <!-- create new product --> + <createData entity="_defaultCategory" stepKey="createCategory"/> + <createData entity="SimpleProduct" stepKey="createSimpleProduct"> + <requiredEntity createDataKey="createCategory"/> + </createData> + <!-- create new customer--> + <createData entity="Simple_US_Customer" stepKey="createCustomer"/> + <!--login to Admin--> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + </before> + <after> + <deleteData createDataKey="createCustomer" stepKey="deleteCustomer"/> + <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> + <deleteData createDataKey="createSimpleProduct" stepKey="deleteProduct"/> + <actionGroup ref="logout" stepKey="logout"/> + </after> + + <!--Create new order--> + <comment userInput="Admin creates order" stepKey="adminCreateOrderComment"/> + <actionGroup ref="navigateToNewOrderPageExistingCustomer" stepKey="startToCreateNewOrder"> + <argument name="customer" value="$$createCustomer$$"/> + </actionGroup> + <actionGroup ref="addSimpleProductToOrder" stepKey="addSimpleProductToOrderWithUserDefinedQty"> + <argument name="product" value="$$createSimpleProduct$$"/> + <argument name="quantity" value="1"/> + </actionGroup> + <!-- Select shipping --> + <actionGroup ref="orderSelectFlatRateShipping" stepKey="selectFlatRateShipping"/> + <!--Select payment--> + <actionGroup ref="SelectCheckMoneyPaymentMethod" stepKey="selectCheckMoneyPayment"/> + <!--Submit Order--> + <click selector="{{AdminOrderFormActionSection.submitOrder}}" stepKey="clickSubmitOrder"/> + <see selector="{{AdminMessagesSection.success}}" userInput="You created the order." stepKey="seeSuccessMessage"/> + <!--Create order invoice--> + <comment userInput="Admin creates invoice for order" stepKey="adminCreateInvoiceComment" /> + <actionGroup ref="StartCreateInvoiceFromOrderPage" stepKey="createInvoice"/> + <actionGroup ref="SubmitInvoice" stepKey="submitInvoice"/> <!--Invoice created successfully--> + <!--Ship Order--> + <comment userInput="Admin creates shipment" stepKey="adminCreatesShipmentComment"/> + <actionGroup ref="StartCreateShipmentFromOrderPage" stepKey="createShipment"/> + <actionGroup ref="SubmitShipment" stepKey="submitShipment"/> + + <!--Create new order--> + <comment userInput="Admin creates order" stepKey="adminCreateOrderComment1"/> + <actionGroup ref="navigateToNewOrderPageExistingCustomer" stepKey="startToCreateNewOrder1"> + <argument name="customer" value="$$createCustomer$$"/> + </actionGroup> + <actionGroup ref="addSimpleProductToOrder" stepKey="addSimpleProductToOrderWithUserDefinedQty1"> + <argument name="product" value="$$createSimpleProduct$$"/> + <argument name="quantity" value="1"/> + </actionGroup> + <!-- Select shipping --> + <actionGroup ref="orderSelectFlatRateShipping" stepKey="selectFlatRateShipping1"/> + <!--Select payment--> + <actionGroup ref="SelectCheckMoneyPaymentMethod" stepKey="selectCheckMoneyPayment1"/> + <!--Submit Order--> + <click selector="{{AdminOrderFormActionSection.submitOrder}}" stepKey="clickSubmitOrder1"/> + <see selector="{{AdminMessagesSection.success}}" userInput="You created the order." stepKey="seeSuccessMessage1"/> + <!-- Cancel order --> + <actionGroup ref="cancelPendingOrder" stepKey="cancelOrder"/> + + <!-- Generate Order report --> + <amOnPage url="{{OrdersReportPage.url}}" stepKey="goToOrdersReportPage1"/> + <!-- Get date --> + <generateDate date="+0 day" format="m/d/Y" stepKey="generateEndDate"/> + <generateDate date="-1 day" format="m/d/Y" stepKey="generateStartDate"/> + <actionGroup ref="GenerateOrderReportActionGroup" stepKey="generateReportAfterCancelOrder"> + <argument name="orderFromDate" value="$generateStartDate"/> + <argument name="orderToDate" value="$generateEndDate"/> + </actionGroup> + <waitForElement selector="{{AdminOrderReportTableSection.ordersCount}}" stepKey="waitForOrdersCount"/> + <see selector="{{AdminOrderReportTableSection.canceledOrders}}" userInput="$0.00" stepKey="seeCanceledOrderPrice"/> + </test> +</tests> From 3803660262f766bc71e54e593b94584d91418bd0 Mon Sep 17 00:00:00 2001 From: Cristiano Casciotti <teknoman84@gmail.com> Date: Thu, 7 Feb 2019 11:37:13 +0100 Subject: [PATCH 045/315] Added RewriteBase directive template in .htaccess file into pub/media folder --- pub/media/.htaccess | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pub/media/.htaccess b/pub/media/.htaccess index 28e65b490fbb8..d8793a891430a 100644 --- a/pub/media/.htaccess +++ b/pub/media/.htaccess @@ -23,6 +23,9 @@ SetHandler default-handler Options +FollowSymLinks RewriteEngine on + ## you can put here your pub/media folder path relative to web root + #RewriteBase /magento/pub/media/ + ############################################ ## never rewrite for existing files RewriteCond %{REQUEST_FILENAME} !-f From 402d83d2225aba6fe2c719d853d550a53e4848ca Mon Sep 17 00:00:00 2001 From: OlgaVasyltsun <olga.vasyltsun@gmail.com> Date: Thu, 7 Feb 2019 14:13:50 +0200 Subject: [PATCH 046/315] MAGETWO-73432: Change EAV model --- .../AdminAddCustomerAddressActionGroup.xml | 26 +++++++++++++++++++ .../Test/Mftf/Page/AdminEditCustomerPage.xml | 1 + .../AdminCustomerAccountNewAddressSection.xml | 19 ++++++++++++++ app/code/Magento/Eav/Model/Entity/Type.php | 7 ++--- 4 files changed, 48 insertions(+), 5 deletions(-) create mode 100644 app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminAddCustomerAddressActionGroup.xml create mode 100644 app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerAccountNewAddressSection.xml diff --git a/app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminAddCustomerAddressActionGroup.xml b/app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminAddCustomerAddressActionGroup.xml new file mode 100644 index 0000000000000..f042c272cbfce --- /dev/null +++ b/app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminAddCustomerAddressActionGroup.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + <actionGroup name="AdminAddCustomerAddressActionGroup" > + <arguments> + <argument name="customerAddress" defaultValue="CustomerAddressSimple"/> + </arguments> + <click selector="{{AdminCustomerAccountAddressSection.addresses}}" stepKey="proceedToAddresses"/> + <click selector="{{AdminCustomerAccountAddressSection.addNewAddress}}" stepKey="addNewAddresses"/> + <waitForPageLoad time="60" stepKey="waitAddressFieldsLoaded" /> + <fillField userInput="{{customerAddress.street[0]}}" selector="{{AdminCustomerAccountNewAddressSection.street}}" stepKey="fillStreetAddress"/> + <fillField userInput="{{customerAddress.city}}" selector="{{AdminCustomerAccountNewAddressSection.city}}" stepKey="fillCity"/> + <selectOption userInput="{{US_Address_CA.country_id}}" selector="{{AdminCustomerAccountNewAddressSection.country}}" stepKey="selectCountry"/> + <selectOption userInput="{{US_Address_CA.state}}" selector="{{AdminCustomerAccountNewAddressSection.region}}" stepKey="selectState"/> + <fillField userInput="{{customerAddress.postcode}}" selector="{{AdminCustomerAccountNewAddressSection.zip}}" stepKey="fillZipCode"/> + <fillField userInput="{{customerAddress.telephone}}" selector="{{AdminCustomerAccountNewAddressSection.phone}}" stepKey="fillPhone"/> + <click selector="{{AdminMainActionsSection.save}}" stepKey="saveCustomer"/> + <see selector="{{AdminMessagesSection.success}}" userInput="You saved the customer." stepKey="CustomerIsSaved"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Customer/Test/Mftf/Page/AdminEditCustomerPage.xml b/app/code/Magento/Customer/Test/Mftf/Page/AdminEditCustomerPage.xml index 72d5d90bdc05f..b5a87009315b3 100644 --- a/app/code/Magento/Customer/Test/Mftf/Page/AdminEditCustomerPage.xml +++ b/app/code/Magento/Customer/Test/Mftf/Page/AdminEditCustomerPage.xml @@ -12,5 +12,6 @@ <section name="AdminCustomerMainActionsSection"/> <section name="AdminCustomerAccountAddressSection"/> <section name="AdminCustomerAccountEditAddressSection"/> + <section name="AdminAddCustomerAddressActionGroup"/> </page> </pages> diff --git a/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerAccountNewAddressSection.xml b/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerAccountNewAddressSection.xml new file mode 100644 index 0000000000000..4f1bf69c6e687 --- /dev/null +++ b/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerAccountNewAddressSection.xml @@ -0,0 +1,19 @@ +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> + <section name="AdminCustomerAccountNewAddressSection"> + <element name="firstName" type="button" selector="input[name*='address'][name*='new'][name*='firstname']"/> + <element name="lastName" type="button" selector="input[name*='address'][name*='new'][name*='lastname']"/> + <element name="street" type="button" selector="input[name*='new'][name*='street']"/> + <element name="city" type="input" selector="input[name*='new'][name*='city']"/> + <element name="country" type="select" selector="select[name*='address'][name*='new'][name*='country']" timeout="10"/> + <element name="region" type="select" selector="select[name*='address'][name*='new'][name*='region_id']"/> + <element name="zip" type="input" selector="input[name*='new'][name*='postcode']"/> + <element name="phone" type="text" selector="input[name*='new'][name*='telephone']" /> + </section> +</sections> diff --git a/app/code/Magento/Eav/Model/Entity/Type.php b/app/code/Magento/Eav/Model/Entity/Type.php index aa298d7d547bf..5ee15287e8899 100644 --- a/app/code/Magento/Eav/Model/Entity/Type.php +++ b/app/code/Magento/Eav/Model/Entity/Type.php @@ -167,11 +167,8 @@ public function getAttributeCollection($setId = null) */ protected function _getAttributeCollection() { - $collection = $this->_attributeFactory->create()->getCollection(); - $objectsModel = $this->getAttributeModel(); - if ($objectsModel) { - $collection->setModel($objectsModel); - } + $collection = $this->_universalFactory->create($this->getEntityAttributeCollection()); + $collection->setItemObjectClass($this->getAttributeModel()); return $collection; } From 69b16da0598cf159040915723bcb1c26f5aa697e Mon Sep 17 00:00:00 2001 From: OlgaVasyltsun <olga.vasyltsun@gmail.com> Date: Thu, 7 Feb 2019 16:34:04 +0200 Subject: [PATCH 047/315] MAGETWO-73432: Change EAV model --- .../Magento/Customer/Test/Mftf/Page/AdminEditCustomerPage.xml | 2 +- .../Test/Mftf/Section/AdminCustomerAccountAddressSection.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Customer/Test/Mftf/Page/AdminEditCustomerPage.xml b/app/code/Magento/Customer/Test/Mftf/Page/AdminEditCustomerPage.xml index b5a87009315b3..7cd36c12c80bd 100644 --- a/app/code/Magento/Customer/Test/Mftf/Page/AdminEditCustomerPage.xml +++ b/app/code/Magento/Customer/Test/Mftf/Page/AdminEditCustomerPage.xml @@ -12,6 +12,6 @@ <section name="AdminCustomerMainActionsSection"/> <section name="AdminCustomerAccountAddressSection"/> <section name="AdminCustomerAccountEditAddressSection"/> - <section name="AdminAddCustomerAddressActionGroup"/> + <section name="AdminCustomerAccountNewAddressSection"/> </page> </pages> diff --git a/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerAccountAddressSection.xml b/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerAccountAddressSection.xml index db9619dde671f..334a5d81901ea 100644 --- a/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerAccountAddressSection.xml +++ b/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerAccountAddressSection.xml @@ -7,7 +7,7 @@ <sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> <section name="AdminCustomerAccountAddressSection"> - <element name="addresses" type="button" selector="a#tab_address"/> + <element name="addresses" type="button" selector="a#tab_address" timeout="30"/> <element name="addNewAddress" type="button" selector=".address-list-actions button.scalable.add span"/> </section> </sections> From fe02088e52243c48b0a11c86c53862be8bfc573e Mon Sep 17 00:00:00 2001 From: Jason Woods <devel@jasonwoods.me.uk> Date: Thu, 7 Feb 2019 20:16:21 +0000 Subject: [PATCH 048/315] Fix admin quote address being lost when removing all items, causing broken quote process until address is updated --- app/code/Magento/Checkout/etc/di.xml | 3 --- app/code/Magento/Checkout/etc/frontend/di.xml | 3 +++ .../Checkout/Plugin/Model/Quote/ResetQuoteAddressesTest.php | 1 + 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Checkout/etc/di.xml b/app/code/Magento/Checkout/etc/di.xml index 71dfd12bb4779..4ebd594a28562 100644 --- a/app/code/Magento/Checkout/etc/di.xml +++ b/app/code/Magento/Checkout/etc/di.xml @@ -49,7 +49,4 @@ </argument> </arguments> </type> - <type name="Magento\Quote\Model\Quote"> - <plugin name="clear_addresses_after_product_delete" type="Magento\Checkout\Plugin\Model\Quote\ResetQuoteAddresses"/> - </type> </config> diff --git a/app/code/Magento/Checkout/etc/frontend/di.xml b/app/code/Magento/Checkout/etc/frontend/di.xml index d80f88786c87b..e203fe5077d26 100644 --- a/app/code/Magento/Checkout/etc/frontend/di.xml +++ b/app/code/Magento/Checkout/etc/frontend/di.xml @@ -95,4 +95,7 @@ </argument> </arguments> </type> + <type name="Magento\Quote\Model\Quote"> + <plugin name="clear_addresses_after_product_delete" type="Magento\Checkout\Plugin\Model\Quote\ResetQuoteAddresses"/> + </type> </config> diff --git a/dev/tests/integration/testsuite/Magento/Checkout/Plugin/Model/Quote/ResetQuoteAddressesTest.php b/dev/tests/integration/testsuite/Magento/Checkout/Plugin/Model/Quote/ResetQuoteAddressesTest.php index 43108dbca1f5e..85dede0d84c2d 100644 --- a/dev/tests/integration/testsuite/Magento/Checkout/Plugin/Model/Quote/ResetQuoteAddressesTest.php +++ b/dev/tests/integration/testsuite/Magento/Checkout/Plugin/Model/Quote/ResetQuoteAddressesTest.php @@ -21,6 +21,7 @@ class ResetQuoteAddressesTest extends \PHPUnit\Framework\TestCase { /** * @magentoDataFixture Magento/Checkout/_files/quote_with_virtual_product_and_address.php + * @magentoAppArea frontend * * @return void */ From c412fc8ba3e7a96d7b2787220f7370c940740772 Mon Sep 17 00:00:00 2001 From: Viktor Sevch <svitja@ukr.net> Date: Fri, 8 Feb 2019 10:10:11 +0200 Subject: [PATCH 049/315] MAGETWO-95463: Order Sales Report includes canceled orders --- .../Mftf/ActionGroup/GenerateOrderReportActionGroup.xml | 6 +++--- .../{OrdersReportPage.xml => AdminOrdersReportPage.xml} | 8 ++++---- .../Mftf/Section/AdminOrderReportMainActionsSection.xml | 4 ++-- .../Test/Mftf/Test/CancelOrdersInOrderSalesReportTest.xml | 4 ++-- 4 files changed, 11 insertions(+), 11 deletions(-) rename app/code/Magento/Reports/Test/Mftf/Page/{OrdersReportPage.xml => AdminOrdersReportPage.xml} (52%) diff --git a/app/code/Magento/Reports/Test/Mftf/ActionGroup/GenerateOrderReportActionGroup.xml b/app/code/Magento/Reports/Test/Mftf/ActionGroup/GenerateOrderReportActionGroup.xml index 79b9c21b0db6a..8ddfd4092645f 100644 --- a/app/code/Magento/Reports/Test/Mftf/ActionGroup/GenerateOrderReportActionGroup.xml +++ b/app/code/Magento/Reports/Test/Mftf/ActionGroup/GenerateOrderReportActionGroup.xml @@ -13,10 +13,10 @@ <argument name="orderFromDate" type="string"/> <argument name="orderToDate" type="string"/> </arguments> - <click selector="{{AdminOrderReportMainActionsSection.here}}" stepKey="refreshStatistics" /> + <click selector="{{AdminOrderReportMainActionsSection.refreshStatistics}}" stepKey="refreshStatistics"/> <fillField selector="{{AdminOrderReportFilterSection.dateFrom}}" userInput="{{orderFromDate}}" stepKey="fillFromDate"/> <fillField selector="{{AdminOrderReportFilterSection.dateTo}}" userInput="{{orderToDate}}" stepKey="fillToDate"/> - <selectOption selector="{{AdminOrderReportFilterSection.orderStatus}}" userInput="Any" stepKey="selectAnyOption" /> - <click selector="{{AdminOrderReportMainActionsSection.showReport}}" stepKey="showReport" /> + <selectOption selector="{{AdminOrderReportFilterSection.orderStatus}}" userInput="Any" stepKey="selectAnyOption"/> + <click selector="{{AdminOrderReportMainActionsSection.showReport}}" stepKey="showReport"/> </actionGroup> </actionGroups> diff --git a/app/code/Magento/Reports/Test/Mftf/Page/OrdersReportPage.xml b/app/code/Magento/Reports/Test/Mftf/Page/AdminOrdersReportPage.xml similarity index 52% rename from app/code/Magento/Reports/Test/Mftf/Page/OrdersReportPage.xml rename to app/code/Magento/Reports/Test/Mftf/Page/AdminOrdersReportPage.xml index 46509089b97ba..f0b51f6e39357 100644 --- a/app/code/Magento/Reports/Test/Mftf/Page/OrdersReportPage.xml +++ b/app/code/Magento/Reports/Test/Mftf/Page/AdminOrdersReportPage.xml @@ -6,9 +6,9 @@ */ --> <pages xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/PageObject.xsd"> - <page name="OrdersReportPage" url="reports/report_sales/sales/" area="admin" module="Reports"> - <section name="OrderReportFilterSection"/> - <section name="OrderReportMainSection"/> - <section name="GeneratedReportSection" /> + <page name="AdminOrdersReportPage" url="reports/report_sales/sales/" area="admin" module="Reports"> + <section name="AdminOrderReportFilterSection"/> + <section name="AdminOrderReportMainActionsSection"/> + <section name="AdminOrderReportTableSection"/> </page> </pages> diff --git a/app/code/Magento/Reports/Test/Mftf/Section/AdminOrderReportMainActionsSection.xml b/app/code/Magento/Reports/Test/Mftf/Section/AdminOrderReportMainActionsSection.xml index e9a56f538fd9c..c4a96537740ee 100644 --- a/app/code/Magento/Reports/Test/Mftf/Section/AdminOrderReportMainActionsSection.xml +++ b/app/code/Magento/Reports/Test/Mftf/Section/AdminOrderReportMainActionsSection.xml @@ -9,7 +9,7 @@ <sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> <section name="AdminOrderReportMainActionsSection"> - <element name="showReport" type="button" selector="#filter_form_submit"/> - <element name="here" type="text" selector="//a[contains(text(), 'here')]"/> + <element name="showReport" type="button" time="30" selector="#filter_form_submit"/> + <element name="refreshStatistics" type="text" time="30" selector="//a[contains(text(), 'here')]"/> </section> </sections> diff --git a/app/code/Magento/Reports/Test/Mftf/Test/CancelOrdersInOrderSalesReportTest.xml b/app/code/Magento/Reports/Test/Mftf/Test/CancelOrdersInOrderSalesReportTest.xml index c229fb1cf0271..009e4b8e5f6f1 100644 --- a/app/code/Magento/Reports/Test/Mftf/Test/CancelOrdersInOrderSalesReportTest.xml +++ b/app/code/Magento/Reports/Test/Mftf/Test/CancelOrdersInOrderSalesReportTest.xml @@ -55,7 +55,7 @@ <!--Create order invoice--> <comment userInput="Admin creates invoice for order" stepKey="adminCreateInvoiceComment" /> <actionGroup ref="StartCreateInvoiceFromOrderPage" stepKey="createInvoice"/> - <actionGroup ref="SubmitInvoice" stepKey="submitInvoice"/> <!--Invoice created successfully--> + <actionGroup ref="SubmitInvoice" stepKey="submitInvoice"/> <!--Ship Order--> <comment userInput="Admin creates shipment" stepKey="adminCreatesShipmentComment"/> <actionGroup ref="StartCreateShipmentFromOrderPage" stepKey="createShipment"/> @@ -81,7 +81,7 @@ <actionGroup ref="cancelPendingOrder" stepKey="cancelOrder"/> <!-- Generate Order report --> - <amOnPage url="{{OrdersReportPage.url}}" stepKey="goToOrdersReportPage1"/> + <amOnPage url="{{AdminOrdersReportPage.url}}" stepKey="goToAdminOrdersReportPage"/> <!-- Get date --> <generateDate date="+0 day" format="m/d/Y" stepKey="generateEndDate"/> <generateDate date="-1 day" format="m/d/Y" stepKey="generateStartDate"/> From acad817a34f70172f56d5c2601d094e274c12492 Mon Sep 17 00:00:00 2001 From: serhii balko <serhii.balko@transoftgroup.com> Date: Fri, 8 Feb 2019 13:49:17 +0200 Subject: [PATCH 050/315] MAGETWO-97528: Custom Customer Attribute is not updating on one website --- .../Controller/Adminhtml/Index/Save.php | 38 ++++++++-- .../Controller/Adminhtml/Index/SaveTest.php | 75 +++++++++++-------- .../Controller/Adminhtml/IndexTest.php | 36 +++++++++ 3 files changed, 112 insertions(+), 37 deletions(-) diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Index/Save.php b/app/code/Magento/Customer/Controller/Adminhtml/Index/Save.php index 3a03e9064a0a3..ffff916053dbd 100644 --- a/app/code/Magento/Customer/Controller/Adminhtml/Index/Save.php +++ b/app/code/Magento/Customer/Controller/Adminhtml/Index/Save.php @@ -283,11 +283,9 @@ protected function _extractCustomerAddressData(array & $extractedCustomerData) public function execute() { $returnToEdit = false; - $originalRequestData = $this->getRequest()->getPostValue(); - $customerId = $this->getCurrentCustomerId(); - if ($originalRequestData) { + if ($this->getRequest()->getPostValue()) { try { // optional fields might be set in request for future processing by observers in other modules $customerData = $this->_extractCustomerData(); @@ -375,7 +373,7 @@ public function execute() $messages = $exception->getMessage(); } $this->_addSessionErrorMessages($messages); - $this->_getSession()->setCustomerFormData($originalRequestData); + $this->_getSession()->setCustomerFormData($this->retrieveFormattedFormData()); $returnToEdit = true; } catch (\Magento\Framework\Exception\AbstractAggregateException $exception) { $errors = $exception->getErrors(); @@ -384,18 +382,19 @@ public function execute() $messages[] = $error->getMessage(); } $this->_addSessionErrorMessages($messages); - $this->_getSession()->setCustomerFormData($originalRequestData); + $this->_getSession()->setCustomerFormData($this->retrieveFormattedFormData()); $returnToEdit = true; } catch (LocalizedException $exception) { $this->_addSessionErrorMessages($exception->getMessage()); - $this->_getSession()->setCustomerFormData($originalRequestData); + $this->_getSession()->setCustomerFormData($this->retrieveFormattedFormData()); $returnToEdit = true; } catch (\Exception $exception) { $this->messageManager->addException($exception, __('Something went wrong while saving the customer.')); - $this->_getSession()->setCustomerFormData($originalRequestData); + $this->_getSession()->setCustomerFormData($this->retrieveFormattedFormData()); $returnToEdit = true; } } + $resultRedirect = $this->resultRedirectFactory->create(); if ($returnToEdit) { if ($customerId) { @@ -501,4 +500,29 @@ private function disableAddressValidation(CustomerInterface $customer) $addressModel->setShouldIgnoreValidation(true); } } + + /** + * Retrieve formatted form data + * + * @return array + */ + private function retrieveFormattedFormData(): array + { + $originalRequestData = $originalRequestData = $this->getRequest()->getPostValue(); + + /* Customer data filtration */ + if (isset($originalRequestData['customer'])) { + $customerData = $this->_extractData( + 'adminhtml_customer', + CustomerMetadataInterface::ENTITY_TYPE_CUSTOMER, + [], + 'customer' + ); + + $customerData = array_intersect_key($customerData, $originalRequestData['customer']); + $originalRequestData['customer'] = array_merge($originalRequestData['customer'], $customerData); + } + + return $originalRequestData; + } } diff --git a/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/SaveTest.php b/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/SaveTest.php index e703e7499d731..09082a0a9de53 100644 --- a/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/SaveTest.php +++ b/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/SaveTest.php @@ -886,22 +886,24 @@ public function testExecuteWithNewCustomerAndValidationException() 'customer' => [ 'coolness' => false, 'disable_auto_group_change' => 'false', + 'dob' => '3/12/1996', ], 'subscription' => $subscription, ]; $extractedData = [ 'coolness' => false, 'disable_auto_group_change' => 'false', + 'dob' => '1996-03-12', ]; /** @var AttributeMetadataInterface|\PHPUnit_Framework_MockObject_MockObject $customerFormMock */ $attributeMock = $this->getMockBuilder( \Magento\Customer\Api\Data\AttributeMetadataInterface::class )->disableOriginalConstructor()->getMock(); - $attributeMock->expects($this->once()) + $attributeMock->expects($this->exactly(2)) ->method('getAttributeCode') ->willReturn('coolness'); - $attributeMock->expects($this->once()) + $attributeMock->expects($this->exactly(2)) ->method('getFrontendInput') ->willReturn('int'); $attributes = [$attributeMock]; @@ -912,7 +914,7 @@ public function testExecuteWithNewCustomerAndValidationException() [null, null, $postValue], [CustomerMetadataInterface::ENTITY_TYPE_CUSTOMER, null, $postValue['customer']], ]); - $this->requestMock->expects($this->exactly(2)) + $this->requestMock->expects($this->any()) ->method('getPost') ->willReturnMap( [ @@ -925,12 +927,12 @@ public function testExecuteWithNewCustomerAndValidationException() $objectMock = $this->getMockBuilder(\Magento\Framework\DataObject::class) ->disableOriginalConstructor() ->getMock(); - $objectMock->expects($this->once()) + $objectMock->expects($this->exactly(2)) ->method('getData') ->with('customer') ->willReturn($postValue['customer']); - $this->objectFactoryMock->expects($this->once()) + $this->objectFactoryMock->expects($this->exactly(2)) ->method('create') ->with(['data' => $postValue]) ->willReturn($objectMock); @@ -938,19 +940,19 @@ public function testExecuteWithNewCustomerAndValidationException() $customerFormMock = $this->getMockBuilder( \Magento\Customer\Model\Metadata\Form::class )->disableOriginalConstructor()->getMock(); - $customerFormMock->expects($this->once()) + $customerFormMock->expects($this->exactly(2)) ->method('extractData') ->with($this->requestMock, 'customer') ->willReturn($extractedData); - $customerFormMock->expects($this->once()) + $customerFormMock->expects($this->exactly(2)) ->method('compactData') ->with($extractedData) ->willReturn($extractedData); - $customerFormMock->expects($this->once()) + $customerFormMock->expects($this->exactly(2)) ->method('getAttributes') ->willReturn($attributes); - $this->formFactoryMock->expects($this->once()) + $this->formFactoryMock->expects($this->exactly(2)) ->method('create') ->with( CustomerMetadataInterface::ENTITY_TYPE_CUSTOMER, @@ -998,7 +1000,10 @@ public function testExecuteWithNewCustomerAndValidationException() $this->sessionMock->expects($this->once()) ->method('setCustomerFormData') - ->with($postValue); + ->with([ + 'customer' => $extractedData, + 'subscription' => $subscription, + ]); /** @var Redirect|\PHPUnit_Framework_MockObject_MockObject $redirectMock */ $redirectMock = $this->getMockBuilder(\Magento\Framework\Controller\Result\Redirect::class) @@ -1029,22 +1034,24 @@ public function testExecuteWithNewCustomerAndLocalizedException() 'customer' => [ 'coolness' => false, 'disable_auto_group_change' => 'false', + 'dob' => '3/12/1996', ], 'subscription' => $subscription, ]; $extractedData = [ 'coolness' => false, 'disable_auto_group_change' => 'false', + 'dob' => '1996-03-12', ]; /** @var AttributeMetadataInterface|\PHPUnit_Framework_MockObject_MockObject $customerFormMock */ $attributeMock = $this->getMockBuilder( \Magento\Customer\Api\Data\AttributeMetadataInterface::class )->disableOriginalConstructor()->getMock(); - $attributeMock->expects($this->once()) + $attributeMock->expects($this->exactly(2)) ->method('getAttributeCode') ->willReturn('coolness'); - $attributeMock->expects($this->once()) + $attributeMock->expects($this->exactly(2)) ->method('getFrontendInput') ->willReturn('int'); $attributes = [$attributeMock]; @@ -1055,7 +1062,7 @@ public function testExecuteWithNewCustomerAndLocalizedException() [null, null, $postValue], [CustomerMetadataInterface::ENTITY_TYPE_CUSTOMER, null, $postValue['customer']], ]); - $this->requestMock->expects($this->exactly(2)) + $this->requestMock->expects($this->any()) ->method('getPost') ->willReturnMap( [ @@ -1068,12 +1075,12 @@ public function testExecuteWithNewCustomerAndLocalizedException() $objectMock = $this->getMockBuilder(\Magento\Framework\DataObject::class) ->disableOriginalConstructor() ->getMock(); - $objectMock->expects($this->once()) + $objectMock->expects($this->exactly(2)) ->method('getData') ->with('customer') ->willReturn($postValue['customer']); - $this->objectFactoryMock->expects($this->once()) + $this->objectFactoryMock->expects($this->exactly(2)) ->method('create') ->with(['data' => $postValue]) ->willReturn($objectMock); @@ -1082,19 +1089,19 @@ public function testExecuteWithNewCustomerAndLocalizedException() $customerFormMock = $this->getMockBuilder( \Magento\Customer\Model\Metadata\Form::class )->disableOriginalConstructor()->getMock(); - $customerFormMock->expects($this->once()) + $customerFormMock->expects($this->exactly(2)) ->method('extractData') ->with($this->requestMock, 'customer') ->willReturn($extractedData); - $customerFormMock->expects($this->once()) + $customerFormMock->expects($this->exactly(2)) ->method('compactData') ->with($extractedData) ->willReturn($extractedData); - $customerFormMock->expects($this->once()) + $customerFormMock->expects($this->exactly(2)) ->method('getAttributes') ->willReturn($attributes); - $this->formFactoryMock->expects($this->once()) + $this->formFactoryMock->expects($this->exactly(2)) ->method('create') ->with( CustomerMetadataInterface::ENTITY_TYPE_CUSTOMER, @@ -1141,7 +1148,10 @@ public function testExecuteWithNewCustomerAndLocalizedException() $this->sessionMock->expects($this->once()) ->method('setCustomerFormData') - ->with($postValue); + ->with([ + 'customer' => $extractedData, + 'subscription' => $subscription, + ]); /** @var Redirect|\PHPUnit_Framework_MockObject_MockObject $redirectMock */ $redirectMock = $this->getMockBuilder(\Magento\Framework\Controller\Result\Redirect::class) @@ -1172,22 +1182,24 @@ public function testExecuteWithNewCustomerAndException() 'customer' => [ 'coolness' => false, 'disable_auto_group_change' => 'false', + 'dob' => '3/12/1996', ], 'subscription' => $subscription, ]; $extractedData = [ 'coolness' => false, 'disable_auto_group_change' => 'false', + 'dob' => '1996-03-12', ]; /** @var AttributeMetadataInterface|\PHPUnit_Framework_MockObject_MockObject $customerFormMock */ $attributeMock = $this->getMockBuilder( \Magento\Customer\Api\Data\AttributeMetadataInterface::class )->disableOriginalConstructor()->getMock(); - $attributeMock->expects($this->once()) + $attributeMock->expects($this->exactly(2)) ->method('getAttributeCode') ->willReturn('coolness'); - $attributeMock->expects($this->once()) + $attributeMock->expects($this->exactly(2)) ->method('getFrontendInput') ->willReturn('int'); $attributes = [$attributeMock]; @@ -1198,7 +1210,7 @@ public function testExecuteWithNewCustomerAndException() [null, null, $postValue], [CustomerMetadataInterface::ENTITY_TYPE_CUSTOMER, null, $postValue['customer']], ]); - $this->requestMock->expects($this->exactly(2)) + $this->requestMock->expects($this->any()) ->method('getPost') ->willReturnMap( [ @@ -1211,12 +1223,12 @@ public function testExecuteWithNewCustomerAndException() $objectMock = $this->getMockBuilder(\Magento\Framework\DataObject::class) ->disableOriginalConstructor() ->getMock(); - $objectMock->expects($this->once()) + $objectMock->expects($this->exactly(2)) ->method('getData') ->with('customer') ->willReturn($postValue['customer']); - $this->objectFactoryMock->expects($this->once()) + $this->objectFactoryMock->expects($this->exactly(2)) ->method('create') ->with(['data' => $postValue]) ->willReturn($objectMock); @@ -1224,19 +1236,19 @@ public function testExecuteWithNewCustomerAndException() $customerFormMock = $this->getMockBuilder( \Magento\Customer\Model\Metadata\Form::class )->disableOriginalConstructor()->getMock(); - $customerFormMock->expects($this->once()) + $customerFormMock->expects($this->exactly(2)) ->method('extractData') ->with($this->requestMock, 'customer') ->willReturn($extractedData); - $customerFormMock->expects($this->once()) + $customerFormMock->expects($this->exactly(2)) ->method('compactData') ->with($extractedData) ->willReturn($extractedData); - $customerFormMock->expects($this->once()) + $customerFormMock->expects($this->exactly(2)) ->method('getAttributes') ->willReturn($attributes); - $this->formFactoryMock->expects($this->once()) + $this->formFactoryMock->expects($this->exactly(2)) ->method('create') ->with( CustomerMetadataInterface::ENTITY_TYPE_CUSTOMER, @@ -1285,7 +1297,10 @@ public function testExecuteWithNewCustomerAndException() $this->sessionMock->expects($this->once()) ->method('setCustomerFormData') - ->with($postValue); + ->with([ + 'customer' => $extractedData, + 'subscription' => $subscription, + ]); /** @var Redirect|\PHPUnit_Framework_MockObject_MockObject $redirectMock */ $redirectMock = $this->getMockBuilder(\Magento\Framework\Controller\Result\Redirect::class) diff --git a/dev/tests/integration/testsuite/Magento/Customer/Controller/Adminhtml/IndexTest.php b/dev/tests/integration/testsuite/Magento/Customer/Controller/Adminhtml/IndexTest.php index 36df9cbf851bd..ccf9c45da8660 100644 --- a/dev/tests/integration/testsuite/Magento/Customer/Controller/Adminhtml/IndexTest.php +++ b/dev/tests/integration/testsuite/Magento/Customer/Controller/Adminhtml/IndexTest.php @@ -509,6 +509,42 @@ public function testSaveActionCoreException() $this->assertRedirect($this->stringStartsWith($this->_baseControllerUrl . 'new/key/')); } + /** + * @magentoDataFixture Magento/Customer/_files/customer_sample.php + */ + public function testSaveActionCoreExceptionFormatFormData() + { + $post = [ + 'customer' => [ + 'website_id' => 1, + 'email' => 'customer@example.com', + 'dob' => '12/3/1996', + ], + ]; + $postFormatted = [ + 'customer' => [ + 'website_id' => 1, + 'email' => 'customer@example.com', + 'dob' => '1996-12-03', + ], + ]; + $this->getRequest()->setPostValue($post); + $this->dispatch('backend/customer/index/save'); + /* + * Check that error message is set + */ + $this->assertSessionMessages( + $this->equalTo(['A customer with the same email already exists in an associated website.']), + \Magento\Framework\Message\MessageInterface::TYPE_ERROR + ); + $this->assertEquals( + $postFormatted, + Bootstrap::getObjectManager()->get(\Magento\Backend\Model\Session::class)->getCustomerFormData(), + 'Customer form data should be formatted' + ); + $this->assertRedirect($this->stringStartsWith($this->_baseControllerUrl . 'new/key/')); + } + /** * @magentoDataFixture Magento/Customer/_files/customer_sample.php */ From 6e515402393b02e954841ecdb3dabc09e1907432 Mon Sep 17 00:00:00 2001 From: serhii balko <serhii.balko@transoftgroup.com> Date: Fri, 8 Feb 2019 15:32:26 +0200 Subject: [PATCH 051/315] MAGETWO-97528: Custom Customer Attribute is not updating on one website --- app/code/Magento/Customer/Controller/Adminhtml/Index/Save.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Index/Save.php b/app/code/Magento/Customer/Controller/Adminhtml/Index/Save.php index ffff916053dbd..5b61c0aaf5e2f 100644 --- a/app/code/Magento/Customer/Controller/Adminhtml/Index/Save.php +++ b/app/code/Magento/Customer/Controller/Adminhtml/Index/Save.php @@ -520,7 +520,7 @@ private function retrieveFormattedFormData(): array ); $customerData = array_intersect_key($customerData, $originalRequestData['customer']); - $originalRequestData['customer'] = array_merge($originalRequestData['customer'], $customerData); + $originalRequestData['customer'] = array_merge($originalRequestData['customer'], $customerData); } return $originalRequestData; From 42a7099e70eb1e369cc120654e79e8620d7db687 Mon Sep 17 00:00:00 2001 From: Stas Kozar <stas.kozar@transoftgroup.com> Date: Fri, 8 Feb 2019 15:33:54 +0200 Subject: [PATCH 052/315] MAGETWO-86215: Static blocks with same ID appear in place of correct block --- .../Magento/Cms/Model/ResourceModel/Block.php | 23 ++++--- .../AdminCreateNewCMSBlockActionGroup.xml | 21 +++++++ .../AdminDeleteCMSBlockActionGroup.xml | 21 +++++++ .../Section/AdminCmsBlockContentSection.xml | 3 + ...teStaticBlockOnDuplicateIdentifierTest.xml | 61 +++++++++++++++++++ 5 files changed, 122 insertions(+), 7 deletions(-) create mode 100644 app/code/Magento/Cms/Test/Mftf/ActionGroup/AdminCreateNewCMSBlockActionGroup.xml create mode 100644 app/code/Magento/Cms/Test/Mftf/ActionGroup/AdminDeleteCMSBlockActionGroup.xml create mode 100644 app/code/Magento/Cms/Test/Mftf/Test/CheckCreateStaticBlockOnDuplicateIdentifierTest.xml diff --git a/app/code/Magento/Cms/Model/ResourceModel/Block.php b/app/code/Magento/Cms/Model/ResourceModel/Block.php index 9aab54b02bc14..30e817713755c 100644 --- a/app/code/Magento/Cms/Model/ResourceModel/Block.php +++ b/app/code/Magento/Cms/Model/ResourceModel/Block.php @@ -95,9 +95,11 @@ protected function _beforeSave(AbstractModel $object) } /** + * Get block id. + * * @param AbstractModel $object * @param mixed $value - * @param null $field + * @param string $field * @return bool|int|string * @throws LocalizedException * @throws \Exception @@ -183,10 +185,12 @@ public function getIsUniqueBlockToStores(AbstractModel $object) $entityMetadata = $this->metadataPool->getMetadata(BlockInterface::class); $linkField = $entityMetadata->getLinkField(); - if ($this->_storeManager->isSingleStoreMode()) { - $stores = [Store::DEFAULT_STORE_ID]; - } else { - $stores = (array)$object->getData('store_id'); + $stores = (array)$object->getData('store_id'); + $isDefaultStore = $this->_storeManager->isSingleStoreMode() + || array_search(Store::DEFAULT_STORE_ID, $stores) !== false; + + if (!$isDefaultStore) { + $stores[] = Store::DEFAULT_STORE_ID; } $select = $this->getConnection()->select() @@ -196,8 +200,11 @@ public function getIsUniqueBlockToStores(AbstractModel $object) 'cb.' . $linkField . ' = cbs.' . $linkField, [] ) - ->where('cb.identifier = ?', $object->getData('identifier')) - ->where('cbs.store_id IN (?)', $stores); + ->where('cb.identifier = ? ', $object->getData('identifier')); + + if (!$isDefaultStore) { + $select->where('cbs.store_id IN (?)', $stores); + } if ($object->getId()) { $select->where('cb.' . $entityMetadata->getIdentifierField() . ' <> ?', $object->getId()); @@ -236,6 +243,8 @@ public function lookupStoreIds($id) } /** + * Save an object. + * * @param AbstractModel $object * @return $this * @throws \Exception diff --git a/app/code/Magento/Cms/Test/Mftf/ActionGroup/AdminCreateNewCMSBlockActionGroup.xml b/app/code/Magento/Cms/Test/Mftf/ActionGroup/AdminCreateNewCMSBlockActionGroup.xml new file mode 100644 index 0000000000000..ce240f9f47e99 --- /dev/null +++ b/app/code/Magento/Cms/Test/Mftf/ActionGroup/AdminCreateNewCMSBlockActionGroup.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + <actionGroup name="FillCMSBlockInformation"> + <arguments> + <argument name="title" type="string" defaultValue="{{DefaultCmsBlock.title}}"/> + <argument name="identifier" type="string" defaultValue="{{DefaultCmsBlock.identifier}}"/> + <argument name="content" type="string" defaultValue="{{DefaultCmsBlock.content}}"/> + </arguments> + <fillField selector="{{AdminCmsBlockContentSection.title}}" userInput="{{title}}" stepKey="fillFieldTitle"/> + <fillField selector="{{AdminCmsBlockContentSection.identifier}}" userInput="{{identifier}}" stepKey="fillFieldIdentifier"/> + <selectOption selector="{{AdminCmsBlockContentSection.storeView}}" userInput="All Store View" stepKey="selectAllStoreView" /> + <fillField selector="{{AdminCmsBlockContentSection.content}}" userInput="{{content}}" stepKey="fillContentField"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Cms/Test/Mftf/ActionGroup/AdminDeleteCMSBlockActionGroup.xml b/app/code/Magento/Cms/Test/Mftf/ActionGroup/AdminDeleteCMSBlockActionGroup.xml new file mode 100644 index 0000000000000..b5ff9c3639c8b --- /dev/null +++ b/app/code/Magento/Cms/Test/Mftf/ActionGroup/AdminDeleteCMSBlockActionGroup.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + <actionGroup name="DeleteCMSBlockActionGroup"> + <arguments> + <argument name="cmsBlockTitle" type="string" defaultValue="{{DefaultCmsBlock.title}}"/> + </arguments> + <amOnPage url="{{AdminCmsBlockGridPage.url}}" stepKey="navigateToCMSPagesGrid"/> + <click selector="{{CmsPagesPageActionsSection.select(cmsBlockTitle)}}" stepKey="clickOnSelect"/> + <click selector="{{CmsPagesPageActionsSection.delete(cmsBlockTitle)}}" stepKey="clickOnDelete"/> + <waitForElementVisible selector="{{AdminConfirmationModalSection.message}}" stepKey="waitForConfirmModal"/> + <click selector="{{AdminConfirmationModalSection.ok}}" stepKey="confirm"/> + <see userInput="You deleted the block." stepKey="VerifyBlockIsDeleted"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Cms/Test/Mftf/Section/AdminCmsBlockContentSection.xml b/app/code/Magento/Cms/Test/Mftf/Section/AdminCmsBlockContentSection.xml index 9614f13f9e3d3..20e55c49ec235 100644 --- a/app/code/Magento/Cms/Test/Mftf/Section/AdminCmsBlockContentSection.xml +++ b/app/code/Magento/Cms/Test/Mftf/Section/AdminCmsBlockContentSection.xml @@ -11,5 +11,8 @@ <section name="AdminCmsBlockContentSection"> <element name="content" type="textarea" selector="#cms_block_form_content"/> <element name="insertWidgetButton" type="button" selector=".scalable.action-add-widget.plugin"/> + <element name="title" type="input" selector="input[name=title]"/> + <element name="identifier" type="input" selector="input[name=identifier]"/> + <element name="storeView" type="multiselect" selector="select[name=store_id]"/> </section> </sections> diff --git a/app/code/Magento/Cms/Test/Mftf/Test/CheckCreateStaticBlockOnDuplicateIdentifierTest.xml b/app/code/Magento/Cms/Test/Mftf/Test/CheckCreateStaticBlockOnDuplicateIdentifierTest.xml new file mode 100644 index 0000000000000..371e6529590e7 --- /dev/null +++ b/app/code/Magento/Cms/Test/Mftf/Test/CheckCreateStaticBlockOnDuplicateIdentifierTest.xml @@ -0,0 +1,61 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="CheckCreateStaticBlockOnDuplicateIdentifierTest"> + <annotations> + <features value="Cms"/> + <stories value="Create a CMS Block via the Admin"/> + <title value="Check static blocks: ID should be unique per Store View"/> + <description value="Check static blocks: ID should be unique per Store View"/> + <severity value="CRITICAL"/> + <testCaseId value="MC-13912"/> + <group value="Cms"/> + </annotations> + <before> + <actionGroup ref="LoginAsAdmin" stepKey="LoginAsAdmin"/> + <actionGroup ref="AdminCreateWebsiteActionGroup" stepKey="createSecondWebsite"> + <argument name="newWebsiteName" value="{{SecondWebsite.name}}"/> + <argument name="websiteCode" value="{{SecondWebsite.code}}"/> + </actionGroup> + <actionGroup ref="AdminCreateNewStoreGroupActionGroup" stepKey="createSecondStoreGroup"> + <argument name="website" value="{{SecondWebsite.name}}"/> + <argument name="storeGroupName" value="{{SecondStoreGroupUnique.name}}"/> + <argument name="storeGroupCode" value="{{SecondStoreGroupUnique.code}}"/> + </actionGroup> + <actionGroup ref="AdminCreateStoreViewActionGroup" stepKey="createSecondStoreView"> + <argument name="storeGroup" value="SecondStoreGroupUnique"/> + <argument name="customStore" value="SecondStoreUnique"/> + </actionGroup> + </before> + <after> + <actionGroup ref="DeleteCMSBlockActionGroup" stepKey="deleteCMSBlockActionGroup"/> + <actionGroup ref="AdminDeleteWebsiteActionGroup" stepKey="deleteWebsite"> + <argument name="websiteName" value="{{SecondWebsite.name}}"/> + </actionGroup> + </after> + <!--Go to Cms blocks page--> + <amOnPage url="{{AdminCmsBlockGridPage.url}}" stepKey="navigateToCMSBlocksGridPage"/> + <!--Click to create new block--> + <click selector="{{AdminMainActionsSection.add}}" stepKey="addNewBlock"/> + <actionGroup ref="FillCMSBlockInformation" stepKey="FillOutBlockContent"/> + <click selector="{{AdminMainActionsSection.save}}" stepKey="clickSaveBlockButton"/> + <see seelctor="AdminMessagesSection.success" userInput="You saved the block." stepKey="verifyBlockIsSaved"/> + <!--Go to Cms blocks page--> + <amOnPage url="{{AdminCmsBlockGridPage.url}}" stepKey="navigateToCMSBlocksGridPage1"/> + <click selector="{{AdminMainActionsSection.add}}" stepKey="addNewBlock1"/> + <actionGroup ref="FillCMSBlockInformation" stepKey="FillOutBlockContent1"/> + <unselectOption selector="{{AdminCmsBlockContentSection.storeView}}" userInput="All Store Views" stepKey="unselectAllStoreViewOption" /> + <selectOption selector="{{AdminCmsBlockContentSection.storeView}}" parameterArray="[Default Store View, {{SecondStoreUnique.name}}]" stepKey="selectStoreViews" /> + <click selector="{{AdminMainActionsSection.save}}" stepKey="clickSaveBlockButton1"/> + <waitForPageLoad stepKey="waitForErrorMessageAppear"/> + <!--Verify that corresponding message is displayed--> + <see selector="{{AdminMessagesSection.error}}" userInput="A block identifier with the same properties already exists in the selected store." stepKey="verifyErrorMessage"/> + </test> +</tests> From 9d858b3b8c9e30b7414d7c85fa271dc310feed0b Mon Sep 17 00:00:00 2001 From: NazarKlovanych <nazarn96@gmail.com> Date: Fri, 8 Feb 2019 16:26:29 +0200 Subject: [PATCH 053/315] fix-issue21073 --- .../Edit/Action/Attribute/Tab/Inventory.php | 29 +++++++++++++++++-- .../product/edit/action/inventory.phtml | 2 +- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Action/Attribute/Tab/Inventory.php b/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Action/Attribute/Tab/Inventory.php index 4aebd521fe60d..d11a6d632657f 100644 --- a/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Action/Attribute/Tab/Inventory.php +++ b/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Action/Attribute/Tab/Inventory.php @@ -5,6 +5,8 @@ */ namespace Magento\Catalog\Block\Adminhtml\Product\Edit\Action\Attribute\Tab; +use Magento\Customer\Api\Data\GroupInterface; + /** * Products mass update inventory tab * @@ -29,6 +31,11 @@ class Inventory extends \Magento\Backend\Block\Widget implements \Magento\Backen */ protected $disabledFields = []; + /** + * @var \Magento\Framework\Serialize\SerializerInterface + */ + private $serializer; + /** * @param \Magento\Backend\Block\Template\Context $context * @param \Magento\CatalogInventory\Model\Source\Backorders $backorders @@ -39,10 +46,13 @@ public function __construct( \Magento\Backend\Block\Template\Context $context, \Magento\CatalogInventory\Model\Source\Backorders $backorders, \Magento\CatalogInventory\Api\StockConfigurationInterface $stockConfiguration, - array $data = [] + array $data = [], + \Magento\Framework\Serialize\SerializerInterface $serializer = null ) { $this->_backorders = $backorders; $this->stockConfiguration = $stockConfiguration; + $this->serializer = $serializer ?? \Magento\Framework\App\ObjectManager::getInstance() + ->get(\Magento\Framework\Serialize\SerializerInterface::class); parent::__construct($context, $data); } @@ -74,7 +84,7 @@ public function getFieldSuffix() public function getStoreId() { $storeId = $this->getRequest()->getParam('store'); - return (int)$storeId; + return (int) $storeId; } /** @@ -88,6 +98,21 @@ public function getDefaultConfigValue($field) return $this->stockConfiguration->getDefaultConfigValue($field); } + /** + * Returns min_sale_qty configuration for the ALL Customer Group + * @return int + */ + public function getDefaultMinSaleQty() + { + $default = $this->stockConfiguration->getDefaultConfigValue('min_sale_qty'); + if (!is_numeric($default)) { + $default = $this->serializer->unserialize($default); + $default = isset($default[GroupInterface::CUST_GROUP_ALL]) ? $default[GroupInterface::CUST_GROUP_ALL] : 1; + } + + return (int) $default; + } + /** * Tab settings * diff --git a/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/edit/action/inventory.phtml b/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/edit/action/inventory.phtml index efc06d675c369..96e07ceb4d305 100644 --- a/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/edit/action/inventory.phtml +++ b/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/edit/action/inventory.phtml @@ -132,7 +132,7 @@ <div class="field"> <input type="text" class="input-text validate-number" id="inventory_min_sale_qty" name="<?= /* @escapeNotVerified */ $block->getFieldSuffix() ?>[min_sale_qty]" - value="<?= /* @escapeNotVerified */ $block->getDefaultConfigValue('min_sale_qty') * 1 ?>" + value="<?= /* @escapeNotVerified */ $block->getDefaultMinSaleQty() * 1 ?>" disabled="disabled"/> </div> <div class="field choice"> From 9d0f7691131080b51b8da3ef06fff015ff37e023 Mon Sep 17 00:00:00 2001 From: Myroslav Dobra <dmaraptor@gmail.com> Date: Fri, 8 Feb 2019 17:27:51 +0200 Subject: [PATCH 054/315] MAGETWO-73534: [GITHUB] Url rewrite for product is broken after using massaction #8227 --- .../Page/AdminProductUpdateAttributesPage.xml | 14 ++++ .../Section/AdminProductFiltersSection.xml | 3 +- .../Mftf/Section/AdminProductSEOSection.xml | 1 + .../Section/AdminUpdateAttributesSection.xml | 17 +++++ .../ProductToWebsiteChangeObserver.php | 17 +++-- ...minUrlForProductRewrittenCorrectlyTest.xml | 72 +++++++++++++++++++ 6 files changed, 117 insertions(+), 7 deletions(-) create mode 100644 app/code/Magento/Catalog/Test/Mftf/Page/AdminProductUpdateAttributesPage.xml create mode 100644 app/code/Magento/Catalog/Test/Mftf/Section/AdminUpdateAttributesSection.xml create mode 100644 app/code/Magento/CatalogUrlRewrite/Test/Mftf/Test/AdminUrlForProductRewrittenCorrectlyTest.xml diff --git a/app/code/Magento/Catalog/Test/Mftf/Page/AdminProductUpdateAttributesPage.xml b/app/code/Magento/Catalog/Test/Mftf/Page/AdminProductUpdateAttributesPage.xml new file mode 100644 index 0000000000000..84996a3814571 --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/Page/AdminProductUpdateAttributesPage.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<pages xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/PageObject.xsd"> + <page name="AdminProductUpdateAttributesPage" url="catalog/product_action_attribute/edit/" area="admin" module="Magento_Catalog"> + <section name="AdminUpdateAttributesHeaderSection"/> + <section name="AdminUpdateAttributesWebsiteSection"/> + </page> +</pages> diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductFiltersSection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductFiltersSection.xml index 6844006e4e399..8e13f9c38f805 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductFiltersSection.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductFiltersSection.xml @@ -7,12 +7,13 @@ --> <sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/SectionObject.xsd"> + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> <section name="AdminProductFiltersSection"> <element name="FiltersButton" type="button" selector="#container > div > div.admin__data-grid-header > div:nth-child(1) > div.data-grid-filters-actions-wrap > div > button"/> <element name="clearFiltersButton" type="button" selector="//div[@class='admin__data-grid-header']//button[@class='action-tertiary action-clear']" timeout="10"/> <element name="NameInput" type="input" selector="input[name=name]"/> <element name="SkuInput" type="input" selector="input[name=sku]"/> <element name="Apply" type="button" selector="button[data-action=grid-filter-apply]" timeout="30"/> + <element name="allCheckbox" type="checkbox" selector="div[data-role='grid-wrapper'] label[data-bind='attr: {for: ko.uid}']" timeout="30"/> </section> </sections> diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductSEOSection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductSEOSection.xml index 1d49d05363612..90c3856933be9 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductSEOSection.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductSEOSection.xml @@ -11,5 +11,6 @@ <section name="AdminProductSEOSection"> <element name="sectionHeader" type="button" selector="div[data-index='search-engine-optimization']" timeout="30"/> <element name="urlKeyInput" type="input" selector="input[name='product[url_key]']"/> + <element name="useDefaultUrl" type="checkbox" selector="input[name='use_default[url_key]']"/> </section> </sections> diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/AdminUpdateAttributesSection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/AdminUpdateAttributesSection.xml new file mode 100644 index 0000000000000..051fda092d151 --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/Section/AdminUpdateAttributesSection.xml @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> + <section name="AdminUpdateAttributesHeaderSection"> + <element name="saveButton" type="button" selector="button[data-ui-id='page-actions-toolbar-save-button']" timeout="30"/> + </section> + <section name="AdminUpdateAttributesWebsiteSection"> + <element name="website" type="button" selector="#attributes_update_tabs_websites"/> + <element name="addProductToWebsite" type="checkbox" selector="#add-products-to-website-content .website-checkbox"/> + </section> +</sections> diff --git a/app/code/Magento/CatalogUrlRewrite/Observer/ProductToWebsiteChangeObserver.php b/app/code/Magento/CatalogUrlRewrite/Observer/ProductToWebsiteChangeObserver.php index fc2056e83ec70..94798753ca63f 100644 --- a/app/code/Magento/CatalogUrlRewrite/Observer/ProductToWebsiteChangeObserver.php +++ b/app/code/Magento/CatalogUrlRewrite/Observer/ProductToWebsiteChangeObserver.php @@ -14,6 +14,9 @@ use Magento\UrlRewrite\Model\UrlPersistInterface; use Magento\UrlRewrite\Service\V1\Data\UrlRewrite; +/** + * Observer to assign the products to website. + */ class ProductToWebsiteChangeObserver implements ObserverInterface { /** @@ -69,12 +72,14 @@ public function execute(\Magento\Framework\Event\Observer $observer) $this->request->getParam('store_id', Store::DEFAULT_STORE_ID) ); - $this->urlPersist->deleteByData([ - UrlRewrite::ENTITY_ID => $product->getId(), - UrlRewrite::ENTITY_TYPE => ProductUrlRewriteGenerator::ENTITY_TYPE, - ]); - if ($product->getVisibility() != Visibility::VISIBILITY_NOT_VISIBLE) { - $this->urlPersist->replace($this->productUrlRewriteGenerator->generate($product)); + if (!empty($this->productUrlRewriteGenerator->generate($product))) { + $this->urlPersist->deleteByData([ + UrlRewrite::ENTITY_ID => $product->getId(), + UrlRewrite::ENTITY_TYPE => ProductUrlRewriteGenerator::ENTITY_TYPE, + ]); + if ($product->getVisibility() != Visibility::VISIBILITY_NOT_VISIBLE) { + $this->urlPersist->replace($this->productUrlRewriteGenerator->generate($product)); + } } } } diff --git a/app/code/Magento/CatalogUrlRewrite/Test/Mftf/Test/AdminUrlForProductRewrittenCorrectlyTest.xml b/app/code/Magento/CatalogUrlRewrite/Test/Mftf/Test/AdminUrlForProductRewrittenCorrectlyTest.xml new file mode 100644 index 0000000000000..558e19885e112 --- /dev/null +++ b/app/code/Magento/CatalogUrlRewrite/Test/Mftf/Test/AdminUrlForProductRewrittenCorrectlyTest.xml @@ -0,0 +1,72 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="AdminUrlForProductRewrittenCorrectlyTest"> + <annotations> + <features value="CatalogUrlRewrite"/> + <stories value="Url rewrites for products"/> + <title value="Check that URL for product rewritten correctly"/> + <description value="Check that URL for product rewritten correctly"/> + <severity value="MAJOR"/> + <testCaseId value="MC-13913"/> + <useCaseId value="MAGETWO-73534"/> + <group value="catalog"/> + <group value="catalogUrlRewrite"/> + </annotations> + <before> + <!--Create product--> + <createData entity="_defaultCategory" stepKey="category"/> + <createData entity="ApiSimpleProduct" stepKey="createProduct"> + <requiredEntity createDataKey="category"/> + </createData> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + </before> + <after> + <!--Delete created data--> + <deleteData createDataKey="createProduct" stepKey="deleteSimpleProduct"/> + <deleteData createDataKey="category" stepKey="deleteCategory"/> + <actionGroup ref="logout" stepKey="logout"/> + </after> + + + <!--Open Created product--> + <amOnPage url="{{AdminProductEditPage.url($$createProduct.id$$)}}" stepKey="openProductEditPage"/> + <!--Switch to Default Store view--> + <actionGroup ref="SwitchToTheNewStoreView" stepKey="selectDefaultStoreView"> + <argument name="storeViewName" value="_defaultStore"/> + </actionGroup> + + <!--Set use default url--> + <click selector="{{AdminProductSEOSection.sectionHeader}}" stepKey="openSearchEngineOptimizationTab"/> + <waitForElementVisible selector="{{AdminProductSEOSection.useDefaultUrl}}" time="30" stepKey="waitForUseDefaultUrlCheckbox"/> + <uncheckOption selector="{{AdminProductSEOSection.useDefaultUrl}}" stepKey="uncheckUseDefaultUrlCheckbox"/> + <fillField selector="{{AdminProductSEOSection.urlKeyInput}}" userInput="$$createProduct.custom_attributes[url_key]$$-updated" stepKey="changeUrlKey"/> + <actionGroup ref="saveProductForm" stepKey="saveProduct"/> + + <!--Select product and go toUpdate Attribute page--> + <amOnPage url="{{AdminProductIndexPage.url}}" stepKey="openProductsGrid"/> + <actionGroup ref="filterProductGridBySku" stepKey="filterGridBySku"> + <argument name="product" value="$$createProduct$$"/> + </actionGroup> + <click selector="{{AdminProductFiltersSection.allCheckbox}}" stepKey="selectFilteredProduct"/> + <click selector="{{AdminProductGridSection.bulkActionDropdown}}" stepKey="clickActionDropdown"/> + <click selector="{{AdminProductGridSection.bulkActionOption('Update attributes')}}" stepKey="clickBulkUpdateAttributes"/> + <waitForPageLoad stepKey="waitForUpdateAttributesPageLoad"/> + <seeInCurrentUrl url="{{AdminProductUpdateAttributesPage.url}}" stepKey="seeInUrlAttributeUpdatePage"/> + <click selector="{{AdminUpdateAttributesWebsiteSection.website}}" stepKey="openWebsitesTab"/> + <waitForAjaxLoad stepKey="waitForLoadWebSiteTab"/> + <click selector="{{AdminUpdateAttributesWebsiteSection.addProductToWebsite}}" stepKey="checkAddProductToWebsiteCheckbox"/> + <click selector="{{AdminUpdateAttributesHeaderSection.saveButton}}" stepKey="clickSave"/> + <see selector="{{AdminMessagesSection.success}}" userInput="A total of 1 record(s) were updated." stepKey="seeSaveSuccessMessage"/> + <!--Got to Store front product page and check url--> + <amOnPage url="{{StorefrontProductPage.url($$createProduct.custom_attributes[url_key]$$-updated)}}" stepKey="navigateToSimpleProductPage"/> + <seeInCurrentUrl url="{{StorefrontProductPage.url($$createProduct.custom_attributes[url_key]$$-updated)}}" stepKey="seeProductNewUrl"/> + <see selector="{{StorefrontProductInfoMainSection.productSku}}" userInput="$$createProduct.sku$$" stepKey="seeCorrectSku"/> + </test> +</tests> From 786b2fa832fcc75d5343a2f6f5bffb6aee8f4a79 Mon Sep 17 00:00:00 2001 From: Mastiuhin Olexandr <mastiuhin.olexandr@transoftgroup.com> Date: Fri, 8 Feb 2019 21:52:18 +0200 Subject: [PATCH 055/315] MAGETWO-97425: Country of Manufacture displays empty under More Information tab --- .../Catalog/Block/Product/View/Attributes.php | 8 +++++++- .../Unit/Block/Product/View/AttributesTest.php | 16 ++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Block/Product/View/Attributes.php b/app/code/Magento/Catalog/Block/Product/View/Attributes.php index b353e477a056c..8494b690bad9f 100644 --- a/app/code/Magento/Catalog/Block/Product/View/Attributes.php +++ b/app/code/Magento/Catalog/Block/Product/View/Attributes.php @@ -16,6 +16,8 @@ use Magento\Framework\Pricing\PriceCurrencyInterface; /** + * Attributes attributes block + * * @api * @since 100.0.2 */ @@ -56,6 +58,8 @@ public function __construct( } /** + * Returns a Product. + * * @return Product */ public function getProduct() @@ -67,6 +71,8 @@ public function getProduct() } /** + * Additional data. + * * $excludeAttr is optional array of attribute codes to * exclude them from additional data array * @@ -89,7 +95,7 @@ public function getAdditionalData(array $excludeAttr = []) $value = $this->priceCurrency->convertAndFormat($value); } - if (is_string($value) && strlen($value)) { + if (is_string($value) && strlen(trim($value))) { $data[$attribute->getAttributeCode()] = [ 'label' => __($attribute->getStoreLabel()), 'value' => $value, diff --git a/app/code/Magento/Catalog/Test/Unit/Block/Product/View/AttributesTest.php b/app/code/Magento/Catalog/Test/Unit/Block/Product/View/AttributesTest.php index 4602a0d99f6f1..a42b167bb432a 100644 --- a/app/code/Magento/Catalog/Test/Unit/Block/Product/View/AttributesTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Block/Product/View/AttributesTest.php @@ -138,6 +138,22 @@ public function testGetAttributeNoValue() $this->assertTrue(empty($attributes['phrase'])); } + /** + * Test getAttribute whitespaces. + * + * @return void + */ + public function testGetAttributeWhitespacesValue() + { + $this->phrase = ' '; + $this->frontendAttribute + ->expects($this->any()) + ->method('getValue') + ->willReturn($this->phrase); + $attributes = $this->attributesBlock->getAdditionalData(); + $this->assertTrue(empty($attributes['phrase'])); + } + /** * @return void */ From 35b532f379d47eef2343ddbd2a96bfd1a18339fc Mon Sep 17 00:00:00 2001 From: serhii balko <serhii.balko@transoftgroup.com> Date: Mon, 11 Feb 2019 08:18:51 +0200 Subject: [PATCH 056/315] MAGETWO-97528: Custom Customer Attribute is not updating on one website --- app/code/Magento/Customer/Controller/Adminhtml/Index/Save.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Index/Save.php b/app/code/Magento/Customer/Controller/Adminhtml/Index/Save.php index 5b61c0aaf5e2f..561039990f705 100644 --- a/app/code/Magento/Customer/Controller/Adminhtml/Index/Save.php +++ b/app/code/Magento/Customer/Controller/Adminhtml/Index/Save.php @@ -508,7 +508,7 @@ private function disableAddressValidation(CustomerInterface $customer) */ private function retrieveFormattedFormData(): array { - $originalRequestData = $originalRequestData = $this->getRequest()->getPostValue(); + $originalRequestData = $this->getRequest()->getPostValue(); /* Customer data filtration */ if (isset($originalRequestData['customer'])) { From d234115d69b0d9bb1eaf72eef4f99d9c12d01c3b Mon Sep 17 00:00:00 2001 From: Serhii Voloshkov <serhii.voloshkov@transoftgroup.com> Date: Mon, 11 Feb 2019 10:12:55 +0200 Subject: [PATCH 057/315] MAGETWO-94450: Rewards points earned from coupon code are not applied to guests that create accounts after checking out --- .../Magento/SalesRule/Test/Mftf/Data/SalesRuleData.xml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/app/code/Magento/SalesRule/Test/Mftf/Data/SalesRuleData.xml b/app/code/Magento/SalesRule/Test/Mftf/Data/SalesRuleData.xml index 2200f1eb45d7d..e85eea62d473e 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Data/SalesRuleData.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Data/SalesRuleData.xml @@ -206,14 +206,6 @@ <data key="discountAmount">0</data> </entity> - <entity name="PriceRuleWithCondition" type="SalesRule"> - <data key="name" unique="suffix">SalesRule</data> - <data key="websites">Main Website</data> - <data key="customerGroups">'NOT LOGGED IN', 'General', 'Wholesale', 'Retailer'</data> - <data key="apply">Fixed amount discount for whole cart</data> - <data key="discountAmount">0</data> - </entity> - <entity name="SalesRuleNoCouponWithFixedDiscount" extends="ApiCartRule"> <data key="simple_action">by_fixed</data> </entity> From 8b4759fe28a1c2a8afc75f1ebde4010a4b2ec6ac Mon Sep 17 00:00:00 2001 From: DianaRusin <rusind95@gmail.com> Date: Mon, 11 Feb 2019 11:27:34 +0200 Subject: [PATCH 058/315] MAGETWO-95182: Order placed by new customer before they registered is displayed in the admin under the name Guest --- .../StorefrontCheckCustomerInfoCreatedByGuestTest.xml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckCustomerInfoCreatedByGuestTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckCustomerInfoCreatedByGuestTest.xml index adc308b490c33..32cc254543bca 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckCustomerInfoCreatedByGuestTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckCustomerInfoCreatedByGuestTest.xml @@ -11,14 +11,15 @@ <test name="StorefrontCheckCustomerInfoCreatedByGuestTest"> <annotations> <features value="Checkout"/> - <stories value="Check customer information created by guest"/> - <title value="Check Customer Information Created By Guest"/> + <stories value="Check order customer information created by guest"/> + <title value="Check Order Customer Information Created By Guest"/> <description value="Check customer information after placing the order as the guest who created an account"/> <severity value="MAJOR"/> <testCaseId value="MC-13839"/> - <useCaseId value="MAGETWO-95820"/> + <useCaseId value="MAGETWO-95182"/> <group value="checkout"/> <group value="customer"/> + <group value="sales"/> </annotations> <before> @@ -29,10 +30,10 @@ </before> <after> - <actionGroup ref="CustomerLogoutStorefrontActionGroup" stepKey="customerLogoutFromStorefront" /> <deleteData createDataKey="createProduct" stepKey="deleteProduct" /> <deleteData createDataKey="createCategory" stepKey="deleteCategory" /> <actionGroup ref="logout" stepKey="logoutFromAdmin"/> + <actionGroup ref="CustomerLogoutStorefrontActionGroup" stepKey="customerLogoutFromStorefront" /> </after> <amOnPage url="{{StorefrontProductPage.url($$createProduct.name$$)}}" stepKey="navigateToProductPage"/> @@ -44,6 +45,7 @@ <argument name="customerVar" value="CustomerEntityOne"/> <argument name="customerAddressVar" value="CustomerAddressSimple"/> </actionGroup> + <actionGroup ref="CheckoutSelectCheckMoneyOrderPaymentActionGroup" stepKey="selectPaymentMethod"/> <actionGroup ref="CheckoutPlaceOrderActionGroup" stepKey="placeOrder"> <argument name="orderNumberMessage" value="CONST.successGuestCheckoutOrderNumberMessage"/> <argument name="emailYouMessage" value="CONST.successCheckoutEmailYouMessage" /> From 16f7465bef4cc8129e2fe4fa7ec8d686c9965243 Mon Sep 17 00:00:00 2001 From: Mastiuhin Olexandr <mastiuhin.olexandr@transoftgroup.com> Date: Mon, 11 Feb 2019 12:12:16 +0200 Subject: [PATCH 059/315] MAGETWO-97425: Country of Manufacture displays empty under More Information tab --- .../Block/Product/View/AttributesTest.php | 29 ++++++++----------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Unit/Block/Product/View/AttributesTest.php b/app/code/Magento/Catalog/Test/Unit/Block/Product/View/AttributesTest.php index a42b167bb432a..66a62b444b4af 100644 --- a/app/code/Magento/Catalog/Test/Unit/Block/Product/View/AttributesTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Block/Product/View/AttributesTest.php @@ -125,33 +125,28 @@ protected function setUp() } /** + * Get attribute with no value phrase + * + * @param string $phrase * @return void + * @dataProvider noValue */ - public function testGetAttributeNoValue() + public function testGetAttributeNoValue(string $phrase) { - $this->phrase = ''; - $this->frontendAttribute - ->expects($this->any()) - ->method('getValue') - ->willReturn($this->phrase); + $this->frontendAttribute->method('getValue') + ->willReturn($phrase); $attributes = $this->attributesBlock->getAdditionalData(); - $this->assertTrue(empty($attributes['phrase'])); + $this->assertArrayNotHasKey('phrase', $attributes); } /** - * Test getAttribute whitespaces. + * No value data provider * - * @return void + * @return array */ - public function testGetAttributeWhitespacesValue() + public function noValue() { - $this->phrase = ' '; - $this->frontendAttribute - ->expects($this->any()) - ->method('getValue') - ->willReturn($this->phrase); - $attributes = $this->attributesBlock->getAdditionalData(); - $this->assertTrue(empty($attributes['phrase'])); + return [[' '], ['']]; } /** From 572693882f7a39768bfe31fbaa206fc696072ada Mon Sep 17 00:00:00 2001 From: Mastiuhin Olexandr <mastiuhin.olexandr@transoftgroup.com> Date: Mon, 11 Feb 2019 12:38:06 +0200 Subject: [PATCH 060/315] MAGETWO-97425: Country of Manufacture displays empty under More Information tab --- .../Catalog/Test/Unit/Block/Product/View/AttributesTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Test/Unit/Block/Product/View/AttributesTest.php b/app/code/Magento/Catalog/Test/Unit/Block/Product/View/AttributesTest.php index 66a62b444b4af..69133c1429be5 100644 --- a/app/code/Magento/Catalog/Test/Unit/Block/Product/View/AttributesTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Block/Product/View/AttributesTest.php @@ -144,7 +144,7 @@ public function testGetAttributeNoValue(string $phrase) * * @return array */ - public function noValue() + public function noValue(): array { return [[' '], ['']]; } From d56f551f500e98e8b17d72e726378e9300904add Mon Sep 17 00:00:00 2001 From: Myroslav Dobra <dmaraptor@gmail.com> Date: Mon, 11 Feb 2019 13:01:11 +0200 Subject: [PATCH 061/315] MAGETWO-98182: [FT] [MFTF] StorefrontPurchaseProductCustomOptionsDifferentStoreViewsTest fails because of bad design --- ...ctCustomOptionsDifferentStoreViewsTest.xml | 93 ++++++++++--------- .../Mftf/ActionGroup/CheckoutActionGroup.xml | 2 +- .../AdminCreateStoreViewActionGroup.xml | 4 +- .../StorefrontSwitchStoreViewActionGroup.xml | 2 +- 4 files changed, 53 insertions(+), 48 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/StorefrontPurchaseProductCustomOptionsDifferentStoreViewsTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/StorefrontPurchaseProductCustomOptionsDifferentStoreViewsTest.xml index 68dbe628e9817..5a3ac4ddd8495 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/StorefrontPurchaseProductCustomOptionsDifferentStoreViewsTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/StorefrontPurchaseProductCustomOptionsDifferentStoreViewsTest.xml @@ -7,7 +7,7 @@ --> <tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> <test name="StorefrontPurchaseProductCustomOptionsDifferentStoreViewsTest"> <annotations> <features value="Purchase a product with Custom Options on different Store Views"/> @@ -16,9 +16,6 @@ <severity value="CRITICAL"/> <testCaseId value="MAGETWO-77831"/> <group value="product"/> - <skip> - <issueId value="MAGETWO-98182"/> - </skip> </annotations> <before> @@ -65,18 +62,24 @@ <actionGroup ref="AdminDeleteStoreViewActionGroup" stepKey="deleteStoreView2"> <argument name="customStore" value="customStoreFR"/> </actionGroup> + <actionGroup ref="clearFiltersAdminDataGrid" stepKey="clearWebsitesGridFilters"/> + + <amOnPage url="{{AdminOrdersPage.url}}" stepKey="onOrdersPage"/> + <actionGroup ref="clearFiltersAdminDataGrid" stepKey="clearOrdersGridFilters"/> + + <amOnPage url="{{AdminProductIndexPage.url}}" stepKey="amOnProductGridPage"/> + <actionGroup ref="clearFiltersAdminDataGrid" stepKey="clearProductsGridFilters"/> </after> <!-- Open Product Grid, Filter product and open --> <amOnPage url="{{AdminProductIndexPage.url}}" stepKey="amOnProductGridPage"/> - <waitForPageLoad time="30" stepKey="waitForPageLoad1"/> - <actionGroup ref="SearchForProductOnBackendActionGroup" stepKey="filterGroupedProductOptions"> <argument name="product" value="_defaultProduct"/> </actionGroup> - <click selector="{{AdminProductGridSection.productGridXRowYColumnButton('1', '2')}}" stepKey="openProductForEdit"/> - <waitForPageLoad time="30" stepKey="waitForPageLoad2"/> + <actionGroup ref="OpenEditProductOnBackendActionGroup" stepKey="openEditProductPage"> + <argument name="product" value="$$createProduct$$"/> + </actionGroup> <!-- Update Product with Option Value DropDown 1--> @@ -100,15 +103,12 @@ <!-- Switcher to Store FR--> - <scrollToTopOfPage stepKey="scrollToTopOfPage1"/> - - <click selector="{{AdminProductFormActionSection.changeStoreButton}}" stepKey="clickStoreSwitcher"/> - <click selector="{{AdminProductFormActionSection.selectStoreView(customStoreFR.name)}}" stepKey="clickStoreView"/> - <click selector="{{AdminConfirmationModalSection.ok}}" stepKey="acceptMessage"/> + <actionGroup ref="AdminSwitchStoreViewActionGroup" stepKey="switchToStoreFR"> + <argument name="scopeName" value="customStoreFR.name"/> + </actionGroup> <!-- Open tab Customizable Options --> - <waitForPageLoad time="10" stepKey="waitForPageLoad4"/> <conditionalClick selector="{{AdminProductCustomizableOptionsSection.customizableOptions}}" dependentSelector="{{AdminProductCustomizableOptionsSection.checkIfCustomizableOptionsTabOpen}}" visible="true" stepKey="clickIfContentTabCloses3"/> <!-- Update Option Customizable Options and Option Value 1--> @@ -128,16 +128,13 @@ <!-- Login Customer Storefront --> - <amOnPage url="{{StorefrontCustomerSignInPage.url}}" stepKey="amOnSignInPage"/> - <waitForPageLoad time="30" stepKey="waitForPageLoad6"/> - <fillField userInput="$$createCustomer.email$$" selector="{{StorefrontCustomerSignInFormSection.emailField}}" stepKey="fillEmail"/> - <fillField userInput="$$createCustomer.password$$" selector="{{StorefrontCustomerSignInFormSection.passwordField}}" stepKey="fillPassword"/> - <click selector="{{StorefrontCustomerSignInFormSection.signInAccountButton}}" stepKey="clickSignInAccountButton"/> + <actionGroup ref="CustomerLoginOnStorefront" stepKey="customerLogin"> + <argument name="customer" value="$$createCustomer$$" /> + </actionGroup> <!-- Go to Product Page --> <amOnPage url="{{StorefrontHomePage.url}}$$createProduct.custom_attributes[url_key]$$.html" stepKey="amOnProduct1Page"/> - <waitForPageLoad time="30" stepKey="waitForPageLoad7"/> <seeElement selector="{{StorefrontProductInfoMainSection.productOptionDropDownTitle('Custom Options 1')}}" stepKey="seeProductOptionDropDownTitle"/> <seeElement selector="{{StorefrontProductInfoMainSection.productOptionDropDownOptionTitle('Custom Options 1', 'option1')}}" stepKey="seeproductOptionDropDownOptionTitle1"/> @@ -156,10 +153,7 @@ </actionGroup> <!-- Checking the correctness of displayed custom options for user parameters on checkout --> - - <click selector="{{StorefrontMiniCartSection.show}}" stepKey="clickCart"/> - <click selector="{{StorefrontMiniCartSection.goToCheckout}}" stepKey="goToCheckout"/> - <waitForPageLoad stepKey="s33"/> + <actionGroup ref="GoToCheckoutFromMinicartActionGroup" stepKey="goToCheckoutFromMinicart" /> <conditionalClick selector="{{CheckoutPaymentSection.cartItemsArea}}" dependentSelector="{{CheckoutPaymentSection.cartItemsArea}}" visible="true" stepKey="exposeMiniCart"/> @@ -177,20 +171,28 @@ <conditionalClick selector="{{CheckoutPaymentSection.productOptionsByProductItemPrice('150')}}" dependentSelector="{{CheckoutPaymentSection.productOptionsActiveByProductItemPrice('150')}}" visible="false" stepKey="exposeProductOptions1"/> <see selector="{{CheckoutPaymentSection.productOptionsActiveByProductItemPrice('150')}}" userInput="option2" stepKey="seeProductOptionValueDropdown1Input2"/> - <click selector="{{CheckoutShippingSection.next}}" stepKey="clickNext"/> - <waitForPageLoad time="30" stepKey="waitForPageLoad8"/> <!-- Place Order --> - <actionGroup ref="CheckoutSelectCheckMoneyOrderPaymentActionGroup" stepKey="selectCheckMoneyOrder1"/> - <click selector="{{CheckoutPaymentSection.placeOrder}}" stepKey="clickPlaceOrder"/> + <!--Select shipping method--> + <actionGroup ref="CheckoutSelectFlatRateShippingMethodActionGroup" stepKey="selectFlatRateShippingMethod"/> + <waitForElementVisible selector="{{CheckoutShippingSection.next}}" time="30" stepKey="waitForNextButton"/> + <click selector="{{CheckoutShippingSection.next}}" stepKey="clickNext"/> + <waitForLoadingMaskToDisappear stepKey="waitForLoadingMaskAfterClickNext"/> + <!--Select payment method--> + <actionGroup ref="CheckoutSelectCheckMoneyOrderPaymentActionGroup" stepKey="selectPaymentMethod"/> + <!-- Place Order --> + <actionGroup ref="CheckoutPlaceOrderActionGroup" stepKey="customerPlaceOrder"> + <argument name="orderNumberMessage" value="CONST.successCheckoutOrderNumberMessage"/> + <argument name="emailYouMessage" value="CONST.successCheckoutEmailYouMessage"/> + </actionGroup> <grabTextFrom selector="{{CheckoutSuccessMainSection.orderNumber22}}" stepKey="grabOrderNumber"/> <!-- Open Order --> <amOnPage url="{{AdminOrdersPage.url}}" stepKey="onOrdersPage"/> - <waitForPageLoad time="30" stepKey="waitForPageLoad9"/> + <actionGroup ref="clearFiltersAdminDataGrid" stepKey="clearOrdersGridFilters"/> <fillField selector="{{OrdersGridSection.search}}" userInput="{$grabOrderNumber}" stepKey="fillOrderNum"/> <click selector="{{OrdersGridSection.submitSearch}}" stepKey="submitSearch"/> <waitForLoadingMaskToDisappear stepKey="waitForLoadingMask4"/> @@ -205,14 +207,12 @@ <!-- Switch to FR Store View Storefront --> <amOnPage url="{{StorefrontHomePage.url}}" stepKey="amOnProduct4Page"/> - <waitForPageLoad time="30" stepKey="waitForPageLoad11"/> - <click selector="{{StorefrontHeaderSection.storeViewSwitcher}}" stepKey="clickStoreViewSwitcher1"/> - <waitForElementVisible selector="{{StorefrontHeaderSection.storeViewDropdown}}" stepKey="waitForStoreViewDropdown1"/> - <click selector="{{StorefrontHeaderSection.storeViewOption(customStoreFR.code)}}" stepKey="selectStoreView1"/> - <waitForPageLoad stepKey="waitForPageLoad12"/> + + <actionGroup ref="StorefrontSwitchStoreViewActionGroup" stepKey="switchStore"> + <argument name="storeView" value="customStoreFR"/> + </actionGroup> <amOnPage url="{{StorefrontHomePage.url}}$$createProduct.custom_attributes[url_key]$$.html" stepKey="amOnProduct2Page"/> - <waitForPageLoad time="30" stepKey="waitForPageLoad13"/> <seeElement selector="{{StorefrontProductInfoMainSection.productOptionDropDownTitle('FR Custom Options 1')}}" stepKey="seeProductFrOptionDropDownTitle"/> <seeElement selector="{{StorefrontProductInfoMainSection.productOptionDropDownOptionTitle('FR Custom Options 1', 'FR option1')}}" stepKey="productFrOptionDropDownOptionTitle1"/> @@ -232,9 +232,7 @@ <!-- Checking the correctness of displayed custom options for user parameters on checkout --> - <click selector="{{StorefrontMiniCartSection.show}}" stepKey="clickCart1"/> - <click selector="{{StorefrontMiniCartSection.goToCheckout}}" stepKey="goToCheckout1"/> - <waitForPageLoad stepKey="s34"/> + <actionGroup ref="GoToCheckoutFromMinicartActionGroup" stepKey="goToCheckoutFromMinicart2" /> <conditionalClick selector="{{CheckoutPaymentSection.cartItemsArea}}" dependentSelector="{{CheckoutPaymentSection.cartItemsArea}}" visible="true" stepKey="exposeMiniCart1"/> @@ -252,18 +250,26 @@ <conditionalClick selector="{{CheckoutPaymentSection.productOptionsByProductItemPrice('150')}}" dependentSelector="{{CheckoutPaymentSection.productOptionsActiveByProductItemPrice('150')}}" visible="false" stepKey="exposeProductOptions3"/> <see selector="{{CheckoutPaymentSection.productOptionsActiveByProductItemPrice('150')}}" userInput="FR option2" stepKey="seeProductFrOptionValueDropdown1Input3"/> - <click selector="{{CheckoutShippingSection.next}}" stepKey="clickNext1"/> - <waitForPageLoad time="30" stepKey="waitForPageLoad14"/> <!-- Place Order --> - <actionGroup ref="CheckoutSelectCheckMoneyOrderPaymentActionGroup" stepKey="selectCheckMoneyOrder2"/> - <click selector="{{CheckoutPaymentSection.placeOrder}}" stepKey="clickPlaceOrder1"/> + <!--Select shipping method--> + <actionGroup ref="CheckoutSelectFlatRateShippingMethodActionGroup" stepKey="selectFlatRateShippingMethod2"/> + <waitForElementVisible selector="{{CheckoutShippingSection.next}}" time="30" stepKey="waitForNextButton2"/> + <click selector="{{CheckoutShippingSection.next}}" stepKey="clickNext2"/> + <waitForLoadingMaskToDisappear stepKey="waitForLoadingMaskAfterClickNext2"/> + + <!--Select payment method--> + <actionGroup ref="CheckoutSelectCheckMoneyOrderPaymentActionGroup" stepKey="selectPaymentMethod2"/> + <!-- Place Order --> + <actionGroup ref="CheckoutPlaceOrderActionGroup" stepKey="customerPlaceOrder2"> + <argument name="orderNumberMessage" value="CONST.successCheckoutOrderNumberMessage"/> + <argument name="emailYouMessage" value="CONST.successCheckoutEmailYouMessage"/> + </actionGroup> <!-- Open Product Grid, Filter product and open --> <amOnPage url="{{AdminProductIndexPage.url}}" stepKey="amOnProductGridPage1"/> - <waitForPageLoad time="30" stepKey="waitForPageLoad15"/> <actionGroup ref="SearchForProductOnBackendActionGroup" stepKey="filterGroupedProductOptions1"> <argument name="product" value="_defaultProduct"/> @@ -297,7 +303,6 @@ <!--Go to Product Page--> <amOnPage url="{{StorefrontHomePage.url}}$$createProduct.custom_attributes[url_key]$$.html" stepKey="amOnProduct2Page2"/> - <waitForPageLoad time="30" stepKey="waitForPageLoad20"/> <seeElement selector="{{StorefrontProductInfoMainSection.productOptionDropDownTitle('Custom Options 1')}}" stepKey="seeProductOptionDropDownTitle1"/> <seeElement selector="{{StorefrontProductInfoMainSection.productOptionDropDownOptionTitle('Custom Options 1', 'option1')}}" stepKey="seeProductOptionDropDownOptionTitle3"/> diff --git a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/CheckoutActionGroup.xml b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/CheckoutActionGroup.xml index f79d59028c468..e3dbb3870896d 100644 --- a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/CheckoutActionGroup.xml +++ b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/CheckoutActionGroup.xml @@ -37,7 +37,7 @@ <argument name="orderNumberMessage"/> <argument name="emailYouMessage"/> </arguments> - <waitForElement selector="{{CheckoutPaymentSection.placeOrder}}" time="30" stepKey="waitForPlaceOrderButton"/> + <waitForElementVisible selector="{{CheckoutPaymentSection.placeOrder}}" time="30" stepKey="waitForPlaceOrderButton"/> <click selector="{{CheckoutPaymentSection.placeOrder}}" stepKey="clickPlaceOrder"/> <see selector="{{CheckoutSuccessMainSection.success}}" userInput="{{orderNumberMessage}}" stepKey="seeOrderNumber"/> <see selector="{{CheckoutSuccessMainSection.success}}" userInput="{{emailYouMessage}}" stepKey="seeEmailYou"/> diff --git a/app/code/Magento/Store/Test/Mftf/ActionGroup/AdminCreateStoreViewActionGroup.xml b/app/code/Magento/Store/Test/Mftf/ActionGroup/AdminCreateStoreViewActionGroup.xml index f1c6f4d87e0d6..2f541feacd9c2 100644 --- a/app/code/Magento/Store/Test/Mftf/ActionGroup/AdminCreateStoreViewActionGroup.xml +++ b/app/code/Magento/Store/Test/Mftf/ActionGroup/AdminCreateStoreViewActionGroup.xml @@ -24,8 +24,8 @@ <waitForElementVisible selector="{{AdminConfirmationModalSection.ok}}" stepKey="waitForModal" /> <see selector="{{AdminConfirmationModalSection.title}}" userInput="Warning message" stepKey="seeWarning" /> <click selector="{{AdminConfirmationModalSection.ok}}" stepKey="dismissModal" /> - <waitForElementVisible selector="{{AdminStoresGridSection.storeFilterTextField}}" stepKey="waitForPageReolad"/> - <see userInput="You saved the store view." stepKey="seeSavedMessage" /> + <waitForElementVisible selector="{{AdminMessagesSection.success}}" stepKey="waitForPageReolad"/> + <see selector="{{AdminMessagesSection.success}}" userInput="You saved the store view." stepKey="seeSavedMessage" /> </actionGroup> <actionGroup name="AdminCreateStoreViewUseStringArgumentsActionGroup" extends="AdminCreateStoreViewActionGroup"> <arguments> diff --git a/app/code/Magento/Store/Test/Mftf/ActionGroup/StorefrontSwitchStoreViewActionGroup.xml b/app/code/Magento/Store/Test/Mftf/ActionGroup/StorefrontSwitchStoreViewActionGroup.xml index e6ebd229e4683..c62ed55c7df49 100644 --- a/app/code/Magento/Store/Test/Mftf/ActionGroup/StorefrontSwitchStoreViewActionGroup.xml +++ b/app/code/Magento/Store/Test/Mftf/ActionGroup/StorefrontSwitchStoreViewActionGroup.xml @@ -13,7 +13,7 @@ </arguments> <click selector="{{StorefrontHeaderSection.storeViewSwitcher}}" stepKey="clickStoreViewSwitcher"/> <waitForElementVisible selector="{{StorefrontHeaderSection.storeViewDropdown}}" stepKey="waitForStoreViewDropdown"/> - <click selector="{{StorefrontHeaderSection.storeViewOption(storeView.name)}}" stepKey="clickSelectStoreView"/> + <click selector="{{StorefrontHeaderSection.storeViewOption(storeView.code)}}" stepKey="clickSelectStoreView"/> <waitForPageLoad stepKey="waitForPageLoad"/> </actionGroup> </actionGroups> From adc050d34fd58ea809d963d3aa0dfc49ce9bcb01 Mon Sep 17 00:00:00 2001 From: OlgaVasyltsun <olga.vasyltsun@gmail.com> Date: Mon, 11 Feb 2019 13:36:57 +0200 Subject: [PATCH 062/315] MAGETWO-96489: Anchor categories are not showing products after enabling subcategories --- app/code/Magento/Catalog/Model/Category.php | 20 +++++-- .../StorefrontCategoryActionGroup.xml | 6 +++ .../Section/StorefrontCategoryMainSection.xml | 1 + ...vailableAfterEnablingSubCategoriesTest.xml | 54 +++++++++++++++++++ .../Catalog/Test/Unit/Model/CategoryTest.php | 24 ++++++--- 5 files changed, 92 insertions(+), 13 deletions(-) create mode 100644 app/code/Magento/Catalog/Test/Mftf/Test/StorefrontProductAvailableAfterEnablingSubCategoriesTest.xml diff --git a/app/code/Magento/Catalog/Model/Category.php b/app/code/Magento/Catalog/Model/Category.php index 00b093b2918f1..0bf4ac49acf1d 100644 --- a/app/code/Magento/Catalog/Model/Category.php +++ b/app/code/Magento/Catalog/Model/Category.php @@ -1130,10 +1130,15 @@ public function reindex() } } $productIndexer = $this->indexerRegistry->get(Indexer\Category\Product::INDEXER_ID); - if (!$productIndexer->isScheduled() - && (!empty($this->getAffectedProductIds()) || $this->dataHasChangedFor('is_anchor')) - ) { - $productIndexer->reindexList($this->getPathIds()); + + if (!empty($this->getAffectedProductIds()) + || $this->dataHasChangedFor('is_anchor') + || $this->dataHasChangedFor('is_active')) { + if (!$productIndexer->isScheduled()) { + $productIndexer->reindexList($this->getPathIds()); + } else { + $productIndexer->invalidate(); + } } } @@ -1167,6 +1172,11 @@ public function getIdentities() if ($this->hasDataChanges() || $this->isDeleted() || $this->dataHasChangedFor(self::KEY_INCLUDE_IN_MENU)) { $identities[] = Product::CACHE_PRODUCT_CATEGORY_TAG . '_' . $this->getId(); + if ($this->dataHasChangedFor('is_anchor') || $this->dataHasChangedFor('is_active')) { + foreach ($this->getPathIds() as $id) { + $identities[] = Product::CACHE_PRODUCT_CATEGORY_TAG . '_' . $id; + } + } } if ($this->isObjectNew()) { @@ -1174,7 +1184,7 @@ public function getIdentities() } } - return $identities; + return array_unique($identities); } /** diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/StorefrontCategoryActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/StorefrontCategoryActionGroup.xml index 2551bd61580ed..e46bfc7ee8b02 100644 --- a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/StorefrontCategoryActionGroup.xml +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/StorefrontCategoryActionGroup.xml @@ -19,6 +19,12 @@ <see userInput="{{category.name}}" selector="{{StorefrontCategoryMainSection.categoryTitle}}" stepKey="assertCategoryName"/> <see userInput="{{productCount}}" selector="{{StorefrontCategoryMainSection.productCount}} span" stepKey="assertProductCount"/> </actionGroup> + <!--Check category is empty--> + <actionGroup name="StorefrontCheckEmptyCategoryActionGroup" extends="StorefrontCheckCategoryActionGroup"> + <remove keyForRemoval="assertProductCount"/> + <amOnPage url="{{StorefrontCategoryPage.url(category.name)}}" before="checkUrl" stepKey="goToCategoryStorefront"/> + <see selector="{{StorefrontCategoryMainSection.categoryEmptyMessage}}" userInput="We can't find products matching the selection." stepKey="seeCategoryEmpty"/> + </actionGroup> <!-- Check simple product on the category page --> <actionGroup name="StorefrontCheckCategorySimpleProduct"> diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/StorefrontCategoryMainSection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/StorefrontCategoryMainSection.xml index 1f1a4ce9133e7..3c769f9dbc0ce 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Section/StorefrontCategoryMainSection.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Section/StorefrontCategoryMainSection.xml @@ -22,5 +22,6 @@ <element name="categoryPageProductImagePlaceholderSmall" type="text" selector=".products-grid img[src*='placeholder/small_image.jpg']"/> <element name="categoryPageProductImage" type="text" selector=".products-grid img[src*='/{{var1}}']" parameterized="true"/> <element name="categoryPageProductName" type="text" selector=".products.list.items.product-items li:nth-of-type({{line}}) .product-item-link" timeout="30" parameterized="true"/> + <element name="categoryEmptyMessage" type="text" selector=".column.main .message.info.empty"/> </section> </sections> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/StorefrontProductAvailableAfterEnablingSubCategoriesTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/StorefrontProductAvailableAfterEnablingSubCategoriesTest.xml new file mode 100644 index 0000000000000..fe7858313c848 --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/Test/StorefrontProductAvailableAfterEnablingSubCategoriesTest.xml @@ -0,0 +1,54 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="StorefrontProductAvailableAfterEnablingSubCategoriesTest"> + <annotations> + <features value="Catalog"/> + <stories value="Show category products on storefront"/> + <title value="Check that parent categories are showing products after enabling subcategories"/> + <description value="Check that parent categories are showing products after enabling subcategories"/> + <severity value="MAJOR"/> + <testCaseId value="MC-13914"/> + <useCaseId value="MAGETWO-96489"/> + <group value="Catalog"/> + </annotations> + <before> + <createData entity="_defaultCategory" stepKey="createCategory"/> + <createData entity="SubCategoryWithParent" stepKey="createSubCategory"> + <requiredEntity createDataKey="createCategory"/> + <field key="is_active">false</field> + </createData> + <createData entity="ApiSimpleProduct" stepKey="createSimpleProduct"> + <requiredEntity createDataKey="createSubCategory"/> + </createData> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + </before> + <after> + <deleteData createDataKey="createSimpleProduct" stepKey="deleteSimpleProduct"/> + <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> + <actionGroup ref="logout" stepKey="logout"/> + </after> + <!--Check anchor category is empty--> + <actionGroup ref="StorefrontCheckEmptyCategoryActionGroup" stepKey="checkEmptyAnchorCategory"> + <argument name="category" value="$$createCategory$$"/> + <argument name="productCount" value="0"/> + </actionGroup> + <!--Enable subcategory--> + <actionGroup ref="AdminNavigateToCategoryInTree" stepKey="openCreatedSubCategory"> + <argument name="category" value="$$createSubCategory$$"/> + </actionGroup> + <click selector="{{AdminCategoryBasicFieldSection.enableCategoryLabel}}" stepKey="enableCategory"/> + <actionGroup ref="saveCategoryForm" stepKey="saveCategory"/> + <!--Check created product in anchor category on storefront--> + <amOnPage url="{{StorefrontCategoryPage.url($$createCategory.name$$)}}" stepKey="goToCategoryStorefront"/> + <actionGroup ref="StorefrontCheckCategorySimpleProduct" stepKey="seeCreatedProduct"> + <argument name="product" value="$$createSimpleProduct$$"/> + </actionGroup> + </test> +</tests> diff --git a/app/code/Magento/Catalog/Test/Unit/Model/CategoryTest.php b/app/code/Magento/Catalog/Test/Unit/Model/CategoryTest.php index a53b87dcf1567..c84753ad4adcb 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/CategoryTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/CategoryTest.php @@ -348,13 +348,15 @@ public function testReindexFlatEnabled($flatScheduled, $productScheduled, $expec public function reindexFlatDisabledTestDataProvider() { return [ - [false, null, null, null, 0], - [true, null, null, null, 0], - [false, [], null, null, 0], - [false, ["1", "2"], null, null, 1], - [false, null, 1, null, 1], - [false, ["1", "2"], 0, 1, 1], - [false, null, 1, 1, 0], + [false, null, null, null, null, null, 0], + [true, null, null, null, null, null, 0], + [false, [], null, null, null, null, 0], + [false, ["1", "2"], null, null, null, null, 1], + [false, null, 1, null, null, null, 1], + [false, ["1", "2"], 0, 1, null, null, 1], + [false, null, 1, 1, null, null, 0], + [false, ["1", "2"], null, null, 0, 1, 1], + [false, ["1", "2"], null, null, 1, 0, 1], ]; } @@ -363,6 +365,8 @@ public function reindexFlatDisabledTestDataProvider() * @param array $affectedIds * @param int|string $isAnchorOrig * @param int|string $isAnchor + * @param mixed $isActiveOrig + * @param mixed $isActive, * @param int $expectedProductReindexCall * * @dataProvider reindexFlatDisabledTestDataProvider @@ -372,12 +376,16 @@ public function testReindexFlatDisabled( $affectedIds, $isAnchorOrig, $isAnchor, + $isActiveOrig, + $isActive, $expectedProductReindexCall ) { $this->category->setAffectedProductIds($affectedIds); $this->category->setData('is_anchor', $isAnchor); $this->category->setOrigData('is_anchor', $isAnchorOrig); $this->category->setAffectedProductIds($affectedIds); + $this->category->setData('is_active', $isActive); + $this->category->setOrigData('is_active', $isActiveOrig); $pathIds = ['path/1/2', 'path/2/3']; $this->category->setData('path_ids', $pathIds); @@ -387,7 +395,7 @@ public function testReindexFlatDisabled( ->method('isFlatEnabled') ->will($this->returnValue(false)); - $this->productIndexer->expects($this->exactly(1)) + $this->productIndexer->expects($this->any()) ->method('isScheduled') ->willReturn($productScheduled); $this->productIndexer->expects($this->exactly($expectedProductReindexCall)) From ba2ad3863e53d4f05bbc6f669b61f82715268a81 Mon Sep 17 00:00:00 2001 From: OlgaVasyltsun <olga.vasyltsun@gmail.com> Date: Mon, 11 Feb 2019 15:16:46 +0200 Subject: [PATCH 063/315] MAGETWO-96489: Anchor categories are not showing products after enabling subcategories --- app/code/Magento/Catalog/Model/Category.php | 31 +++++++++++++++------ 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Category.php b/app/code/Magento/Catalog/Model/Category.php index 0bf4ac49acf1d..aa99918753e81 100644 --- a/app/code/Magento/Catalog/Model/Category.php +++ b/app/code/Magento/Catalog/Model/Category.php @@ -1170,15 +1170,8 @@ public function getIdentities() $identities[] = self::CACHE_TAG . '_' . $this->getId(); } - if ($this->hasDataChanges() || $this->isDeleted() || $this->dataHasChangedFor(self::KEY_INCLUDE_IN_MENU)) { - $identities[] = Product::CACHE_PRODUCT_CATEGORY_TAG . '_' . $this->getId(); - if ($this->dataHasChangedFor('is_anchor') || $this->dataHasChangedFor('is_active')) { - foreach ($this->getPathIds() as $id) { - $identities[] = Product::CACHE_PRODUCT_CATEGORY_TAG . '_' . $id; - } - } - } - + $identities = $this->getCategoryRelationIdentities($identities); + if ($this->isObjectNew()) { $identities[] = self::CACHE_TAG; } @@ -1470,5 +1463,25 @@ public function setExtensionAttributes(\Magento\Catalog\Api\Data\CategoryExtensi return $this->_setExtensionAttributes($extensionAttributes); } + /** + * Return category relation identities. + * + * @param array $identities + * @return array + */ + private function getCategoryRelationIdentities(array $identities): array + { + if ($this->hasDataChanges() || $this->isDeleted() || $this->dataHasChangedFor(self::KEY_INCLUDE_IN_MENU)) { + $identities[] = Product::CACHE_PRODUCT_CATEGORY_TAG . '_' . $this->getId(); + if ($this->dataHasChangedFor('is_anchor') || $this->dataHasChangedFor('is_active')) { + foreach ($this->getPathIds() as $id) { + $identities[] = Product::CACHE_PRODUCT_CATEGORY_TAG . '_' . $id; + } + } + } + + return $identities; + } + //@codeCoverageIgnoreEnd } From f461c3dcbd63f8cdf0fe18ab4de7c89ece0dde71 Mon Sep 17 00:00:00 2001 From: Mastiuhin Olexandr <mastiuhin.olexandr@transoftgroup.com> Date: Mon, 11 Feb 2019 15:29:41 +0200 Subject: [PATCH 064/315] MAGETWO-97425: Country of Manufacture displays empty under More Information tab --- .../Catalog/Test/Unit/Block/Product/View/AttributesTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Unit/Block/Product/View/AttributesTest.php b/app/code/Magento/Catalog/Test/Unit/Block/Product/View/AttributesTest.php index 69133c1429be5..2310b1f8b871c 100644 --- a/app/code/Magento/Catalog/Test/Unit/Block/Product/View/AttributesTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Block/Product/View/AttributesTest.php @@ -129,7 +129,7 @@ protected function setUp() * * @param string $phrase * @return void - * @dataProvider noValue + * @dataProvider noValueProvider */ public function testGetAttributeNoValue(string $phrase) { @@ -144,7 +144,7 @@ public function testGetAttributeNoValue(string $phrase) * * @return array */ - public function noValue(): array + public function noValueProvider(): array { return [[' '], ['']]; } From b4f47f947d6e6b50518553dd9c22e4e722fb86b9 Mon Sep 17 00:00:00 2001 From: Pavel Bystritsky <p.bystritsky@yandex.ru> Date: Mon, 11 Feb 2019 17:22:36 +0200 Subject: [PATCH 065/315] ENGCOM-4000: Integration test fix. --- .../Magento/Rule/Model/Condition/Product/AbstractProduct.php | 2 +- .../Magento/CatalogWidget/Block/Product/ProductListTest.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Rule/Model/Condition/Product/AbstractProduct.php b/app/code/Magento/Rule/Model/Condition/Product/AbstractProduct.php index b7dd1d6c55f4e..bedac8c1108e5 100644 --- a/app/code/Magento/Rule/Model/Condition/Product/AbstractProduct.php +++ b/app/code/Magento/Rule/Model/Condition/Product/AbstractProduct.php @@ -713,7 +713,7 @@ protected function _getAttributeSetId($productId) public function getOperatorForValidate() { $operator = $this->getOperator(); - if (in_array($this->getInputType(), ['category'])) { + if ('category' === $this->getInputType()) { if ($operator == '==') { $operator = '{}'; } elseif ($operator == '!=') { diff --git a/dev/tests/integration/testsuite/Magento/CatalogWidget/Block/Product/ProductListTest.php b/dev/tests/integration/testsuite/Magento/CatalogWidget/Block/Product/ProductListTest.php index 08e9ebbd1f9f0..4251e01f4299a 100644 --- a/dev/tests/integration/testsuite/Magento/CatalogWidget/Block/Product/ProductListTest.php +++ b/dev/tests/integration/testsuite/Magento/CatalogWidget/Block/Product/ProductListTest.php @@ -83,7 +83,7 @@ public function testCreateCollectionWithMultipleSkuCondition() { $encodedConditions = '^[`1`:^[`type`:`Magento||CatalogWidget||Model||Rule||Condition||Combine`,' . '`aggregator`:`all`,`value`:`1`,`new_child`:``^],`1--1`:^[`type`:`Magento||CatalogWidget||Model||Rule|' . - '|Condition||Product`,`attribute`:`sku`,`operator`:`==`,`value`:`simple1, simple2`^]^]'; + '|Condition||Product`,`attribute`:`sku`,`operator`:`()`,`value`:`simple1, simple2`^]^]'; $this->block->setData('conditions_encoded', $encodedConditions); $this->performAssertions(2); } From bbabad9c2ecb7fb7bf0152e601a95f282adaea91 Mon Sep 17 00:00:00 2001 From: Myroslav Dobra <dmaraptor@gmail.com> Date: Tue, 12 Feb 2019 10:45:43 +0200 Subject: [PATCH 066/315] MAGETWO-98182: [FT] [MFTF] StorefrontPurchaseProductCustomOptionsDifferentStoreViewsTest fails because of bad design --- ...roductCustomOptionsDifferentStoreViewsTest.xml | 15 ++++++--------- .../Test/Mftf/ActionGroup/CheckoutActionGroup.xml | 2 +- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/StorefrontPurchaseProductCustomOptionsDifferentStoreViewsTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/StorefrontPurchaseProductCustomOptionsDifferentStoreViewsTest.xml index 5a3ac4ddd8495..e7054839ef4d0 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/StorefrontPurchaseProductCustomOptionsDifferentStoreViewsTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/StorefrontPurchaseProductCustomOptionsDifferentStoreViewsTest.xml @@ -64,8 +64,7 @@ </actionGroup> <actionGroup ref="clearFiltersAdminDataGrid" stepKey="clearWebsitesGridFilters"/> - <amOnPage url="{{AdminOrdersPage.url}}" stepKey="onOrdersPage"/> - <actionGroup ref="clearFiltersAdminDataGrid" stepKey="clearOrdersGridFilters"/> + <actionGroup ref="AdminOrdersGridClearFiltersActionGroup" stepKey="clearOrdersGridFilter"/> <amOnPage url="{{AdminProductIndexPage.url}}" stepKey="amOnProductGridPage"/> <actionGroup ref="clearFiltersAdminDataGrid" stepKey="clearProductsGridFilters"/> @@ -191,11 +190,9 @@ <!-- Open Order --> - <amOnPage url="{{AdminOrdersPage.url}}" stepKey="onOrdersPage"/> - <actionGroup ref="clearFiltersAdminDataGrid" stepKey="clearOrdersGridFilters"/> - <fillField selector="{{OrdersGridSection.search}}" userInput="{$grabOrderNumber}" stepKey="fillOrderNum"/> - <click selector="{{OrdersGridSection.submitSearch}}" stepKey="submitSearch"/> - <waitForLoadingMaskToDisappear stepKey="waitForLoadingMask4"/> + <actionGroup ref="filterOrderGridById" stepKey="openOrdersGrid"> + <argument name="orderId" value="{$grabOrderNumber}"/> + </actionGroup> <click selector="{{OrdersGridSection.firstRow}}" stepKey="clickOrderRow"/> <waitForPageLoad time="30" stepKey="waitForPageLoad10"/> @@ -212,7 +209,7 @@ <argument name="storeView" value="customStoreFR"/> </actionGroup> - <amOnPage url="{{StorefrontHomePage.url}}$$createProduct.custom_attributes[url_key]$$.html" stepKey="amOnProduct2Page"/> + <amOnPage url="{{StorefrontProductPage.url($$createProduct.custom_attributes[url_key]$$)}}" stepKey="amOnProduct2Page"/> <seeElement selector="{{StorefrontProductInfoMainSection.productOptionDropDownTitle('FR Custom Options 1')}}" stepKey="seeProductFrOptionDropDownTitle"/> <seeElement selector="{{StorefrontProductInfoMainSection.productOptionDropDownOptionTitle('FR Custom Options 1', 'FR option1')}}" stepKey="productFrOptionDropDownOptionTitle1"/> @@ -302,7 +299,7 @@ <!--Go to Product Page--> - <amOnPage url="{{StorefrontHomePage.url}}$$createProduct.custom_attributes[url_key]$$.html" stepKey="amOnProduct2Page2"/> + <amOnPage url="{{StorefrontProductPage.url($$createProduct.custom_attributes[url_key]$$)}}" stepKey="amOnProduct2Page2"/> <seeElement selector="{{StorefrontProductInfoMainSection.productOptionDropDownTitle('Custom Options 1')}}" stepKey="seeProductOptionDropDownTitle1"/> <seeElement selector="{{StorefrontProductInfoMainSection.productOptionDropDownOptionTitle('Custom Options 1', 'option1')}}" stepKey="seeProductOptionDropDownOptionTitle3"/> diff --git a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/CheckoutActionGroup.xml b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/CheckoutActionGroup.xml index e3dbb3870896d..d20616b4384d1 100644 --- a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/CheckoutActionGroup.xml +++ b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/CheckoutActionGroup.xml @@ -7,7 +7,7 @@ --> <actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/actionGroupSchema.xsd"> + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> <!-- Checkout select Check/Money Order payment --> <actionGroup name="CheckoutSelectCheckMoneyOrderPaymentActionGroup"> <waitForLoadingMaskToDisappear stepKey="waitForLoadingMask"/> From c1afe36da67f59029dcb566431214509a544b3f7 Mon Sep 17 00:00:00 2001 From: Stas Kozar <stas.kozar@transoftgroup.com> Date: Tue, 12 Feb 2019 12:33:49 +0200 Subject: [PATCH 067/315] MAGETWO-86215: Static blocks with same ID appear in place of correct block --- .../Magento/Cms/Model/ResourceModel/Block.php | 2 +- .../ActionGroup/AdminCmsBlockActionGroup.xml | 46 +++++++++++++++++++ .../AdminCreateNewCMSBlockActionGroup.xml | 21 --------- .../AdminDeleteCMSBlockActionGroup.xml | 21 --------- .../Test/Mftf/Page/AdminCmsBlockNewPage.xml | 14 ++++++ ...teStaticBlockOnDuplicateIdentifierTest.xml | 33 ++++++------- 6 files changed, 74 insertions(+), 63 deletions(-) create mode 100644 app/code/Magento/Cms/Test/Mftf/ActionGroup/AdminCmsBlockActionGroup.xml delete mode 100644 app/code/Magento/Cms/Test/Mftf/ActionGroup/AdminCreateNewCMSBlockActionGroup.xml delete mode 100644 app/code/Magento/Cms/Test/Mftf/ActionGroup/AdminDeleteCMSBlockActionGroup.xml create mode 100644 app/code/Magento/Cms/Test/Mftf/Page/AdminCmsBlockNewPage.xml diff --git a/app/code/Magento/Cms/Model/ResourceModel/Block.php b/app/code/Magento/Cms/Model/ResourceModel/Block.php index 30e817713755c..6eae76f9790c9 100644 --- a/app/code/Magento/Cms/Model/ResourceModel/Block.php +++ b/app/code/Magento/Cms/Model/ResourceModel/Block.php @@ -200,7 +200,7 @@ public function getIsUniqueBlockToStores(AbstractModel $object) 'cb.' . $linkField . ' = cbs.' . $linkField, [] ) - ->where('cb.identifier = ? ', $object->getData('identifier')); + ->where('cb.identifier = ? ', $object->getData('identifier')); if (!$isDefaultStore) { $select->where('cbs.store_id IN (?)', $stores); diff --git a/app/code/Magento/Cms/Test/Mftf/ActionGroup/AdminCmsBlockActionGroup.xml b/app/code/Magento/Cms/Test/Mftf/ActionGroup/AdminCmsBlockActionGroup.xml new file mode 100644 index 0000000000000..0ee5b3280a7c3 --- /dev/null +++ b/app/code/Magento/Cms/Test/Mftf/ActionGroup/AdminCmsBlockActionGroup.xml @@ -0,0 +1,46 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + <actionGroup name="FillCmsBlockForm"> + <arguments> + <argument name="title" type="string" defaultValue="{{DefaultCmsBlock.title}}"/> + <argument name="identifier" type="string" defaultValue="{{DefaultCmsBlock.identifier}}"/> + <argument name="store" type="string" defaultValue="All Store View"/> + <argument name="content" type="string" defaultValue="{{DefaultCmsBlock.content}}"/> + </arguments> + <fillField selector="{{AdminCmsBlockContentSection.title}}" userInput="{{title}}" stepKey="fillFieldTitle"/> + <fillField selector="{{AdminCmsBlockContentSection.identifier}}" userInput="{{identifier}}" stepKey="fillFieldIdentifier"/> + <selectOption selector="{{AdminCmsBlockContentSection.storeView}}" userInput="{{store}}" stepKey="selectStore" /> + <fillField selector="{{AdminCmsBlockContentSection.content}}" userInput="{{content}}" stepKey="fillContentField"/> + </actionGroup> + <actionGroup name="DeleteCmsBlockActionGroup"> + <arguments> + <argument name="cmsBlockTitle" type="string" defaultValue="{{DefaultCmsBlock.title}}"/> + </arguments> + <amOnPage url="{{AdminCmsBlockGridPage.url}}" stepKey="navigateToCmsBlockListingPage"/> + <click selector="{{CmsPagesPageActionsSection.select(cmsBlockTitle)}}" stepKey="clickOnSelect"/> + <click selector="{{CmsPagesPageActionsSection.delete(cmsBlockTitle)}}" stepKey="clickOnDelete"/> + <waitForElementVisible selector="{{AdminConfirmationModalSection.message}}" stepKey="waitForConfirmModal"/> + <click selector="{{AdminConfirmationModalSection.ok}}" stepKey="confirm"/> + <see selector="{{AdminMessagesSection.success}}" userInput="You deleted the block." stepKey="verifyBlockIsDeleted"/> + </actionGroup> + <actionGroup name="NavigateToCreateCmsBlockActionGroup"> + <amOnPage url="{{AdminCmsBlockNewPage.url}}" stepKey="navigateToCreateCmsBlockPage"/> + </actionGroup> + <actionGroup name="SaveCmsBlockActionGroup"> + <click selector="{{AdminMainActionsSection.save}}" stepKey="clickSaveBlockButton"/> + <see selector="{{AdminMessagesSection.success}}" userInput="You saved the block." stepKey="verifyMessage"/> + </actionGroup> + <actionGroup name="SaveCmsBlockWithErrorActionGroup" extends="SaveCmsBlockActionGroup"> + <arguments> + <argument name="errorMessage" type="string" defaultValue="A block identifier with the same properties already exists in the selected store."/> + </arguments> + <see selector="{{AdminMessagesSection.error}}" userInput="{{errorMessage}}" stepKey="verifyMessage"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Cms/Test/Mftf/ActionGroup/AdminCreateNewCMSBlockActionGroup.xml b/app/code/Magento/Cms/Test/Mftf/ActionGroup/AdminCreateNewCMSBlockActionGroup.xml deleted file mode 100644 index ce240f9f47e99..0000000000000 --- a/app/code/Magento/Cms/Test/Mftf/ActionGroup/AdminCreateNewCMSBlockActionGroup.xml +++ /dev/null @@ -1,21 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> - <actionGroup name="FillCMSBlockInformation"> - <arguments> - <argument name="title" type="string" defaultValue="{{DefaultCmsBlock.title}}"/> - <argument name="identifier" type="string" defaultValue="{{DefaultCmsBlock.identifier}}"/> - <argument name="content" type="string" defaultValue="{{DefaultCmsBlock.content}}"/> - </arguments> - <fillField selector="{{AdminCmsBlockContentSection.title}}" userInput="{{title}}" stepKey="fillFieldTitle"/> - <fillField selector="{{AdminCmsBlockContentSection.identifier}}" userInput="{{identifier}}" stepKey="fillFieldIdentifier"/> - <selectOption selector="{{AdminCmsBlockContentSection.storeView}}" userInput="All Store View" stepKey="selectAllStoreView" /> - <fillField selector="{{AdminCmsBlockContentSection.content}}" userInput="{{content}}" stepKey="fillContentField"/> - </actionGroup> -</actionGroups> diff --git a/app/code/Magento/Cms/Test/Mftf/ActionGroup/AdminDeleteCMSBlockActionGroup.xml b/app/code/Magento/Cms/Test/Mftf/ActionGroup/AdminDeleteCMSBlockActionGroup.xml deleted file mode 100644 index b5ff9c3639c8b..0000000000000 --- a/app/code/Magento/Cms/Test/Mftf/ActionGroup/AdminDeleteCMSBlockActionGroup.xml +++ /dev/null @@ -1,21 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> - <actionGroup name="DeleteCMSBlockActionGroup"> - <arguments> - <argument name="cmsBlockTitle" type="string" defaultValue="{{DefaultCmsBlock.title}}"/> - </arguments> - <amOnPage url="{{AdminCmsBlockGridPage.url}}" stepKey="navigateToCMSPagesGrid"/> - <click selector="{{CmsPagesPageActionsSection.select(cmsBlockTitle)}}" stepKey="clickOnSelect"/> - <click selector="{{CmsPagesPageActionsSection.delete(cmsBlockTitle)}}" stepKey="clickOnDelete"/> - <waitForElementVisible selector="{{AdminConfirmationModalSection.message}}" stepKey="waitForConfirmModal"/> - <click selector="{{AdminConfirmationModalSection.ok}}" stepKey="confirm"/> - <see userInput="You deleted the block." stepKey="VerifyBlockIsDeleted"/> - </actionGroup> -</actionGroups> diff --git a/app/code/Magento/Cms/Test/Mftf/Page/AdminCmsBlockNewPage.xml b/app/code/Magento/Cms/Test/Mftf/Page/AdminCmsBlockNewPage.xml new file mode 100644 index 0000000000000..2868d832ad762 --- /dev/null +++ b/app/code/Magento/Cms/Test/Mftf/Page/AdminCmsBlockNewPage.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<pages xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/PageObject.xsd"> + <page name="AdminCmsBlockNewPage" url="/cms/block/new/" area="admin" module="Magento_Cms"> + <section name="AdminCmsBlockContentSection"/> + </page> +</pages> diff --git a/app/code/Magento/Cms/Test/Mftf/Test/CheckCreateStaticBlockOnDuplicateIdentifierTest.xml b/app/code/Magento/Cms/Test/Mftf/Test/CheckCreateStaticBlockOnDuplicateIdentifierTest.xml index 371e6529590e7..f7ed9776c066c 100644 --- a/app/code/Magento/Cms/Test/Mftf/Test/CheckCreateStaticBlockOnDuplicateIdentifierTest.xml +++ b/app/code/Magento/Cms/Test/Mftf/Test/CheckCreateStaticBlockOnDuplicateIdentifierTest.xml @@ -11,12 +11,13 @@ <test name="CheckCreateStaticBlockOnDuplicateIdentifierTest"> <annotations> <features value="Cms"/> - <stories value="Create a CMS Block via the Admin"/> + <stories value="Create CMS Block"/> <title value="Check static blocks: ID should be unique per Store View"/> <description value="Check static blocks: ID should be unique per Store View"/> <severity value="CRITICAL"/> <testCaseId value="MC-13912"/> - <group value="Cms"/> + <useCaseId value="MAGETWO-86215"/> + <group value="cms"/> </annotations> <before> <actionGroup ref="LoginAsAdmin" stepKey="LoginAsAdmin"/> @@ -35,27 +36,19 @@ </actionGroup> </before> <after> - <actionGroup ref="DeleteCMSBlockActionGroup" stepKey="deleteCMSBlockActionGroup"/> + <actionGroup ref="DeleteCmsBlockActionGroup" stepKey="deleteCMSBlockActionGroup"/> <actionGroup ref="AdminDeleteWebsiteActionGroup" stepKey="deleteWebsite"> <argument name="websiteName" value="{{SecondWebsite.name}}"/> </actionGroup> + <actionGroup ref="logout" stepKey="logout"/> </after> - <!--Go to Cms blocks page--> - <amOnPage url="{{AdminCmsBlockGridPage.url}}" stepKey="navigateToCMSBlocksGridPage"/> - <!--Click to create new block--> - <click selector="{{AdminMainActionsSection.add}}" stepKey="addNewBlock"/> - <actionGroup ref="FillCMSBlockInformation" stepKey="FillOutBlockContent"/> - <click selector="{{AdminMainActionsSection.save}}" stepKey="clickSaveBlockButton"/> - <see seelctor="AdminMessagesSection.success" userInput="You saved the block." stepKey="verifyBlockIsSaved"/> - <!--Go to Cms blocks page--> - <amOnPage url="{{AdminCmsBlockGridPage.url}}" stepKey="navigateToCMSBlocksGridPage1"/> - <click selector="{{AdminMainActionsSection.add}}" stepKey="addNewBlock1"/> - <actionGroup ref="FillCMSBlockInformation" stepKey="FillOutBlockContent1"/> - <unselectOption selector="{{AdminCmsBlockContentSection.storeView}}" userInput="All Store Views" stepKey="unselectAllStoreViewOption" /> - <selectOption selector="{{AdminCmsBlockContentSection.storeView}}" parameterArray="[Default Store View, {{SecondStoreUnique.name}}]" stepKey="selectStoreViews" /> - <click selector="{{AdminMainActionsSection.save}}" stepKey="clickSaveBlockButton1"/> - <waitForPageLoad stepKey="waitForErrorMessageAppear"/> - <!--Verify that corresponding message is displayed--> - <see selector="{{AdminMessagesSection.error}}" userInput="A block identifier with the same properties already exists in the selected store." stepKey="verifyErrorMessage"/> + <actionGroup ref="NavigateToCreateCmsBlockActionGroup" stepKey="NavigateToCreateCmsBlock"/> + <actionGroup ref="FillCmsBlockForm" stepKey="fillCmsBlockForm"/> + <actionGroup ref="SaveCmsBlockActionGroup" stepKey="saveCmsBlock"/> + <actionGroup ref="NavigateToCreateCmsBlockActionGroup" stepKey="NavigateToCreateCmsBlock1"/> + <actionGroup ref="FillCmsBlockForm" stepKey="fillCmsBlockForm1"> + <argument name="store" parameterArray="[{{_defaultStore.name}},{{SecondStoreUnique.name}}]"/> + </actionGroup> + <actionGroup ref="SaveCmsBlockWithErrorActionGroup" stepKey="saveCmsBlock1"/> </test> </tests> From 73c4bca05b737f3962687dcb3c9a888d1a3110e5 Mon Sep 17 00:00:00 2001 From: OlgaVasyltsun <olga.vasyltsun@gmail.com> Date: Tue, 12 Feb 2019 14:33:24 +0200 Subject: [PATCH 068/315] MAGETWO-90192: Prefix in checkout not starting with blank value --- .../Block/Checkout/LayoutProcessor.php | 38 ++++++++----------- .../Mftf/Section/CheckoutShippingSection.xml | 3 ++ .../Magento/Customer/Block/Widget/Name.php | 7 +++- .../CustomerNameAddressOptionsConfigData.xml | 38 +++++++++++++++++++ ...tomer_name_address_options_config-meta.xml | 25 ++++++++++++ 5 files changed, 88 insertions(+), 23 deletions(-) create mode 100644 app/code/Magento/Customer/Test/Mftf/Data/CustomerNameAddressOptionsConfigData.xml create mode 100644 app/code/Magento/Customer/Test/Mftf/Metadata/customer_name_address_options_config-meta.xml diff --git a/app/code/Magento/Checkout/Block/Checkout/LayoutProcessor.php b/app/code/Magento/Checkout/Block/Checkout/LayoutProcessor.php index f47e514948d69..c5d4d68b06225 100644 --- a/app/code/Magento/Checkout/Block/Checkout/LayoutProcessor.php +++ b/app/code/Magento/Checkout/Block/Checkout/LayoutProcessor.php @@ -6,8 +6,11 @@ namespace Magento\Checkout\Block\Checkout; use Magento\Checkout\Helper\Data; +use Magento\Customer\Model\AttributeMetadataDataProvider; +use Magento\Customer\Model\Options; use Magento\Framework\App\ObjectManager; use Magento\Store\Api\StoreResolverInterface; +use Magento\Ui\Component\Form\AttributeMapper; /** * Class LayoutProcessor @@ -15,12 +18,12 @@ class LayoutProcessor implements \Magento\Checkout\Block\Checkout\LayoutProcessorInterface { /** - * @var \Magento\Customer\Model\AttributeMetadataDataProvider + * @var AttributeMetadataDataProvider */ private $attributeMetadataDataProvider; /** - * @var \Magento\Ui\Component\Form\AttributeMapper + * @var AttributeMapper */ protected $attributeMapper; @@ -30,7 +33,7 @@ class LayoutProcessor implements \Magento\Checkout\Block\Checkout\LayoutProcesso protected $merger; /** - * @var \Magento\Customer\Model\Options + * @var Options */ private $options; @@ -50,30 +53,21 @@ class LayoutProcessor implements \Magento\Checkout\Block\Checkout\LayoutProcesso private $shippingConfig; /** - * @param \Magento\Customer\Model\AttributeMetadataDataProvider $attributeMetadataDataProvider - * @param \Magento\Ui\Component\Form\AttributeMapper $attributeMapper + * @param AttributeMetadataDataProvider $attributeMetadataDataProvider + * @param AttributeMapper $attributeMapper * @param AttributeMerger $merger + * @param Options|null $options */ public function __construct( - \Magento\Customer\Model\AttributeMetadataDataProvider $attributeMetadataDataProvider, - \Magento\Ui\Component\Form\AttributeMapper $attributeMapper, - AttributeMerger $merger + AttributeMetadataDataProvider $attributeMetadataDataProvider, + AttributeMapper $attributeMapper, + AttributeMerger $merger, + Options $options = null ) { $this->attributeMetadataDataProvider = $attributeMetadataDataProvider; $this->attributeMapper = $attributeMapper; $this->merger = $merger; - } - - /** - * @deprecated 100.0.11 - * @return \Magento\Customer\Model\Options - */ - private function getOptions() - { - if (!is_object($this->options)) { - $this->options = ObjectManager::getInstance()->get(\Magento\Customer\Model\Options::class); - } - return $this->options; + $this->options = $options ?? ObjectManager::getInstance()->get(Options::class); } /** @@ -143,8 +137,8 @@ private function convertElementsToSelect($elements, $attributesToConvert) public function process($jsLayout) { $attributesToConvert = [ - 'prefix' => [$this->getOptions(), 'getNamePrefixOptions'], - 'suffix' => [$this->getOptions(), 'getNameSuffixOptions'], + 'prefix' => [$this->options, 'getNamePrefixOptions'], + 'suffix' => [$this->options, 'getNameSuffixOptions'], ]; $elements = $this->getAddressAttributes(); diff --git a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingSection.xml b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingSection.xml index 76c9e9f674e6a..66cd480051905 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingSection.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingSection.xml @@ -33,5 +33,8 @@ <element name="addCountry" type="select" selector="#shipping-new-address-form select[name='country_id']"/> <element name="addSaveButton" type="button" selector=".action.primary.action-save-address"/> <element name="editActiveAddress" type="button" selector="//div[@class='shipping-address-item selected-item']//span[text()='Edit']" timeout="30"/> + <element name="namePrefix" type="input" selector="select[name=prefix]"/> + <element name="nameSuffix" type="selector" selector="[name='suffix']"/> + <element name="nameSuffixOption" type="text" selector="select[name='suffix'] option[value='{{arg}}']" parameterized="true" timeout="30"/> </section> </sections> diff --git a/app/code/Magento/Customer/Block/Widget/Name.php b/app/code/Magento/Customer/Block/Widget/Name.php index 35f3bbefb8f00..4411f40fe41f3 100644 --- a/app/code/Magento/Customer/Block/Widget/Name.php +++ b/app/code/Magento/Customer/Block/Widget/Name.php @@ -245,10 +245,13 @@ public function getStoreLabel($attributeCode) */ public function getAttributeValidationClass($attributeCode) { - return $this->_addressHelper->getAttributeValidationClass($attributeCode); + $attributeMetadata = $this->_getAttribute($attributeCode); + return $attributeMetadata ? $attributeMetadata->getFrontendClass() : ''; } /** + * Check if attribute is required + * * @param string $attributeCode * @return bool */ @@ -259,6 +262,8 @@ private function _isAttributeRequired($attributeCode) } /** + * Check if attribute is visible + * * @param string $attributeCode * @return bool */ diff --git a/app/code/Magento/Customer/Test/Mftf/Data/CustomerNameAddressOptionsConfigData.xml b/app/code/Magento/Customer/Test/Mftf/Data/CustomerNameAddressOptionsConfigData.xml new file mode 100644 index 0000000000000..1331f288286e5 --- /dev/null +++ b/app/code/Magento/Customer/Test/Mftf/Data/CustomerNameAddressOptionsConfigData.xml @@ -0,0 +1,38 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<entities xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:DataGenerator/etc/dataProfileSchema.xsd"> + <entity name="CustomerPrefixOptions" type="customer_name_address_options"> + <requiredEntity type="prefix_options">PrefixOptions</requiredEntity> + </entity> + <entity name="PrefixOptions" type="prefix_options"> + <data key="value">Mr;Mrs;Ms;Dr</data> + </entity> + + <entity name="DefaultCustomerPrefixOptions" type="customer_name_address_options"> + <requiredEntity type="prefix_options">DefaultPrefixOptions</requiredEntity> + </entity> + <entity name="DefaultPrefixOptions" type="prefix_options"> + <data key="value"></data> + </entity> + + <entity name="CustomerSuffixOptions" type="customer_name_address_options"> + <requiredEntity type="suffix_options">SuffixOptions</requiredEntity> + </entity> + <entity name="SuffixOptions" type="suffix_options"> + <data key="value">Jr;Sr</data> + </entity> + + <entity name="DefaultCustomerSuffixOptions" type="customer_name_address_options"> + <requiredEntity type="suffix_options">DefaultSuffixOptions</requiredEntity> + </entity> + <entity name="DefaultSuffixOptions" type="suffix_options"> + <data key="value"></data> + </entity> +</entities> diff --git a/app/code/Magento/Customer/Test/Mftf/Metadata/customer_name_address_options_config-meta.xml b/app/code/Magento/Customer/Test/Mftf/Metadata/customer_name_address_options_config-meta.xml new file mode 100644 index 0000000000000..07175a09fe3e1 --- /dev/null +++ b/app/code/Magento/Customer/Test/Mftf/Metadata/customer_name_address_options_config-meta.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<operations xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:DataGenerator/etc/dataOperation.xsd"> + <operation name="CustomerConfigNameAddressOptions" dataType="customer_name_address_options" type="create" auth="adminFormKey" url="/admin/system_config/save/section/customer/" method="POST" successRegex="/messages-message-success/"> + <object key="groups" dataType="customer_name_address_options"> + <object key="address" dataType="customer_name_address_options"> + <object key="fields" dataType="customer_name_address_options"> + <object key="prefix_options" dataType="prefix_options"> + <field key="value">string</field> + </object> + <object key="suffix_options" dataType="suffix_options"> + <field key="value">string</field> + </object> + </object> + </object> + </object> + </operation> +</operations> From 08142ff4aa1efb22ce10056fd7afc08ff2d63c18 Mon Sep 17 00:00:00 2001 From: Viktor Sevch <svitja@ukr.net> Date: Tue, 12 Feb 2019 15:27:19 +0200 Subject: [PATCH 069/315] MAGETWO-97242: Stabilize AdminAbleToShipPartiallyInvoicedItemsTest --- ...inAbleToShipPartiallyInvoicedItemsTest.xml | 3 - .../order/creditmemo/create/items.phtml | 67 +++++++++++-------- .../order/invoice/create/items.phtml | 53 ++++++++------- 3 files changed, 67 insertions(+), 56 deletions(-) diff --git a/app/code/Magento/Sales/Test/Mftf/Test/AdminAbleToShipPartiallyInvoicedItemsTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/AdminAbleToShipPartiallyInvoicedItemsTest.xml index cb761dc358abb..d196783744c46 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/AdminAbleToShipPartiallyInvoicedItemsTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/AdminAbleToShipPartiallyInvoicedItemsTest.xml @@ -14,9 +14,6 @@ <severity value="CRITICAL"/> <testCaseId value="MAGETWO-95524"/> <group value="sales"/> - <skip> - <issueId value="MAGETWO-97664"/> - </skip> </annotations> <before> <createData entity="_defaultCategory" stepKey="createCategory"/> diff --git a/app/code/Magento/Sales/view/adminhtml/templates/order/creditmemo/create/items.phtml b/app/code/Magento/Sales/view/adminhtml/templates/order/creditmemo/create/items.phtml index a73740c249b67..dc7d8fbebd46a 100644 --- a/app/code/Magento/Sales/view/adminhtml/templates/order/creditmemo/create/items.phtml +++ b/app/code/Magento/Sales/view/adminhtml/templates/order/creditmemo/create/items.phtml @@ -140,67 +140,76 @@ </section> <script> -require(['jquery', 'prototype'], function(jQuery){ +require(['jquery'], function(jQuery){ //<![CDATA[ -var submitButtons = $$('.submit-button'); -var updateButtons = $$('.update-button,.update-totals-button'); -var fields = $$('.qty-input,.order-subtotal-table input[type="text"]'); +var submitButtons = jQuery('.submit-button'); +var updateButtons = jQuery('.update-button,.update-totals-button'); +var fields = jQuery('.qty-input,.order-subtotal-table input[type="text"]'); -updateButtons.each(function (elem) {elem.disabled=true;elem.addClassName('disabled');}); +function enableButtons(buttons) { + buttons.removeClass('disabled').prop('disabled',false); +}; -for(var i=0;i<fields.length;i++){ - fields[i].observe('change', checkButtonsRelation) - fields[i].baseValue = fields[i].value; -} +function disableButtons(buttons) { + buttons.addClass('disabled').prop('disabled',true); +}; + +disableButtons(updateButtons); + +fields.on('change', checkButtonsRelation); +fields.each(function (i,elem) { + elem.baseValue = elem.value; +}); function checkButtonsRelation() { var hasChanges = false; - fields.each(function (elem) { + fields.each(function (i,elem) { if (elem.baseValue != elem.value) { hasChanges = true; } }.bind(this)); if (hasChanges) { - submitButtons.each(function (elem) {elem.disabled=true;elem.addClassName('disabled');}); - updateButtons.each(function (elem) {elem.disabled=false;elem.removeClassName('disabled');}); + disableButtons(submitButtons); + enableButtons(updateButtons); } else { - submitButtons.each(function (elem) {elem.disabled=false;elem.removeClassName('disabled');}); - updateButtons.each(function (elem) {elem.disabled=true;elem.addClassName('disabled');}); + enableButtons(submitButtons); + disableButtons(updateButtons); } } submitCreditMemo = function() { - if ($('creditmemo_do_offline')) $('creditmemo_do_offline').value=0; + var creditMemoOffline = jQuery('#creditmemo_do_offline'); + if (creditMemoOffline.length) { + creditMemoOffline.prop('value',0); + } // Temporary solution will be replaced after refactoring order functionality jQuery('#edit_form').triggerHandler('save'); } submitCreditMemoOffline = function() { - if ($('creditmemo_do_offline')) $('creditmemo_do_offline').value=1; + var creditMemoOffline = jQuery('#creditmemo_do_offline'); + if (creditMemoOffline.length) { + creditMemoOffline.prop('value', 1); + } // Temporary solution will be replaced after refactoring order functionality jQuery('#edit_form').triggerHandler('save'); } -var sendEmailCheckbox = $('send_email'); - -if (sendEmailCheckbox) { - var notifyCustomerCheckbox = $('notify_customer'); - var creditmemoCommentText = $('creditmemo_comment_text'); - Event.observe(sendEmailCheckbox, 'change', bindSendEmail); +var sendEmailCheckbox = jQuery('#send_email'); +if (sendEmailCheckbox.length) { + var notifyCustomerCheckbox = jQuery('#notify_customer'); + sendEmailCheckbox.on('change', bindSendEmail); bindSendEmail(); } -function bindSendEmail() -{ - if (sendEmailCheckbox.checked == true) { - notifyCustomerCheckbox.disabled = false; - //creditmemoCommentText.disabled = false; +function bindSendEmail() { + if (sendEmailCheckbox.prop('checked') == true) { + notifyCustomerCheckbox.prop('disabled',false); } else { - notifyCustomerCheckbox.disabled = true; - //creditmemoCommentText.disabled = true; + notifyCustomerCheckbox.prop('disabled',true); } } diff --git a/app/code/Magento/Sales/view/adminhtml/templates/order/invoice/create/items.phtml b/app/code/Magento/Sales/view/adminhtml/templates/order/invoice/create/items.phtml index 4a77c3b166de9..8efdca2fce8e2 100644 --- a/app/code/Magento/Sales/view/adminhtml/templates/order/invoice/create/items.phtml +++ b/app/code/Magento/Sales/view/adminhtml/templates/order/invoice/create/items.phtml @@ -134,56 +134,61 @@ </section> <script> -require(['jquery', 'prototype'], function(jQuery){ +require(['jquery'], function(jQuery){ //<![CDATA[ -var submitButtons = $$('.submit-button'); -var updateButtons = $$('.update-button'); +var submitButtons = jQuery('.submit-button'); +var updateButtons = jQuery('.update-button'); var enableSubmitButtons = <?= (int) !$block->getDisableSubmitButton() ?>; -var fields = $$('.qty-input'); +var fields = jQuery('.qty-input'); -updateButtons.each(function (elem) {elem.disabled=true;elem.addClassName('disabled');}); +function enableButtons(buttons) { + buttons.removeClass('disabled').prop('disabled',false); +}; -for(var i=0;i<fields.length;i++){ - jQuery(fields[i]).on('keyup', checkButtonsRelation); - fields[i].baseValue = fields[i].value; -} +function disableButtons(buttons) { + buttons.addClass('disabled').prop('disabled',true); +}; + +disableButtons(updateButtons); + +fields.on('keyup', checkButtonsRelation); +fields.each(function (i,elem) { + elem.baseValue = elem.value; +}); function checkButtonsRelation() { var hasChanges = false; - fields.each(function (elem) { + fields.each(function (i,elem) { if (elem.baseValue != elem.value) { hasChanges = true; } }.bind(this)); if (hasChanges) { - submitButtons.each(function (elem) {elem.disabled=true;elem.addClassName('disabled');}); - updateButtons.each(function (elem) {elem.disabled=false;elem.removeClassName('disabled');}); + disableButtons(submitButtons); + enableButtons(updateButtons); } else { if (enableSubmitButtons) { - submitButtons.each(function (elem) {elem.disabled=false;elem.removeClassName('disabled');}); + enableButtons(submitButtons); } - updateButtons.each(function (elem) {elem.disabled=true;elem.addClassName('disabled');}); + disableButtons(updateButtons); } } -var sendEmailCheckbox = $('send_email'); -if (sendEmailCheckbox) { - var notifyCustomerCheckbox = $('notify_customer'); - var invoiceCommentText = $('invoice_comment_text'); - Event.observe(sendEmailCheckbox, 'change', bindSendEmail); +var sendEmailCheckbox = jQuery('#send_email'); +if (sendEmailCheckbox.length) { + var notifyCustomerCheckbox = jQuery('#notify_customer'); + sendEmailCheckbox.on('change', bindSendEmail); bindSendEmail(); } function bindSendEmail() { - if (sendEmailCheckbox.checked == true) { - notifyCustomerCheckbox.disabled = false; - //invoiceCommentText.disabled = false; + if (sendEmailCheckbox.prop('checked') == true) { + notifyCustomerCheckbox.prop('disabled',false); } else { - notifyCustomerCheckbox.disabled = true; - //invoiceCommentText.disabled = true; + notifyCustomerCheckbox.prop('disabled',true); } } From 115b1bcbd38495e269ada16e0515b883104a7f7f Mon Sep 17 00:00:00 2001 From: Myroslav Dobra <dmaraptor@gmail.com> Date: Tue, 12 Feb 2019 15:38:52 +0200 Subject: [PATCH 070/315] MAGETWO-96636: MFTF test fix --- ...efrontBraintreeFillCardDataActionGroup.xml | 32 +++++++++++++++++++ .../Test/Mftf/Data/BraintreeData.xml | 3 +- ...ntBraintreePaymentConfigurationSection.xml | 24 ++++++++++++++ .../Data/ProductConfigurableAttributeData.xml | 2 +- .../AdminCreditMemoActionGroup.xml | 27 ++++++++++++++++ .../Section/AdminCreditMemoTotalSection.xml | 4 ++- .../AdminOrderDetailsMainActionsSection.xml | 2 +- .../Section/AdminOrderViewTabsSection.xml | 1 + 8 files changed, 90 insertions(+), 5 deletions(-) create mode 100644 app/code/Magento/Braintree/Test/Mftf/ActionGroup/StorefrontBraintreeFillCardDataActionGroup.xml create mode 100644 app/code/Magento/Braintree/Test/Mftf/Section/StorefrontBraintreePaymentConfigurationSection.xml create mode 100644 app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminCreditMemoActionGroup.xml diff --git a/app/code/Magento/Braintree/Test/Mftf/ActionGroup/StorefrontBraintreeFillCardDataActionGroup.xml b/app/code/Magento/Braintree/Test/Mftf/ActionGroup/StorefrontBraintreeFillCardDataActionGroup.xml new file mode 100644 index 0000000000000..561d660a1bb75 --- /dev/null +++ b/app/code/Magento/Braintree/Test/Mftf/ActionGroup/StorefrontBraintreeFillCardDataActionGroup.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + <actionGroup name="StorefrontBraintreeFillCardDataActionGroup"> + <arguments> + <argument name="cardData" defaultValue="BraintreeCard"/> + </arguments> + <switchToIFrame selector="{{StorefrontBraintreePaymentConfigurationSection.cardFrame}}" stepKey="switchToIframe"/> + <waitForElementVisible selector="{{StorefrontBraintreePaymentConfigurationSection.cardCode}}" stepKey="waitCardCodeElement"/> + <fillField selector="{{StorefrontBraintreePaymentConfigurationSection.cardCode}}" userInput="{{cardData.card_number}}" stepKey="setCardCode"/> + <switchToIFrame stepKey="switchBack"/> + <switchToIFrame selector="{{StorefrontBraintreePaymentConfigurationSection.monthFrame}}" stepKey="switchToIframe1"/> + <waitForElementVisible selector="{{StorefrontBraintreePaymentConfigurationSection.month}}" stepKey="waitMonthElement"/> + <fillField selector="{{StorefrontBraintreePaymentConfigurationSection.month}}" userInput="{{cardData.exp_month}}" stepKey="setMonth"/> + <switchToIFrame stepKey="switchBack1"/> + <switchToIFrame selector="{{StorefrontBraintreePaymentConfigurationSection.yearFrame}}" stepKey="switchToIframe2"/> + <waitForElementVisible selector="{{StorefrontBraintreePaymentConfigurationSection.year}}" stepKey="waitYearElement"/> + <fillField selector="{{StorefrontBraintreePaymentConfigurationSection.year}}" userInput="{{cardData.exp_year}}" stepKey="setYear"/> + <switchToIFrame stepKey="switchBack2"/> + <switchToIFrame selector="{{StorefrontBraintreePaymentConfigurationSection.codeFrame}}" stepKey="switchToIframe3"/> + <waitForElementVisible selector="{{StorefrontBraintreePaymentConfigurationSection.verificationNumber}}" stepKey="waitVerificationNumber"/> + <fillField selector="{{StorefrontBraintreePaymentConfigurationSection.verificationNumber}}" userInput="{{cardData.cvv}}" stepKey="setVerificationNumber"/> + <switchToIFrame stepKey="SwitchBackToWindow"/> + <waitForPageLoad stepKey="waitForPageLoad"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Braintree/Test/Mftf/Data/BraintreeData.xml b/app/code/Magento/Braintree/Test/Mftf/Data/BraintreeData.xml index 0c57147ca950e..4e8526a2b0e2b 100644 --- a/app/code/Magento/Braintree/Test/Mftf/Data/BraintreeData.xml +++ b/app/code/Magento/Braintree/Test/Mftf/Data/BraintreeData.xml @@ -7,7 +7,7 @@ --> <entities xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/DataGenerator/etc/dataProfileSchema.xsd"> + xsi:noNamespaceSchemaLocation="urn:magento:mftf:DataGenerator/etc/dataProfileSchema.xsd"> <entity name="SampleBraintreeConfig" type="braintree_config_state"> <requiredEntity type="title">SampleTitle</requiredEntity> <requiredEntity type="payment_action">SamplePaymentAction</requiredEntity> @@ -113,5 +113,4 @@ <data key="exp_year">20</data> <data key="cvv">113</data> </entity> - </entities> diff --git a/app/code/Magento/Braintree/Test/Mftf/Section/StorefrontBraintreePaymentConfigurationSection.xml b/app/code/Magento/Braintree/Test/Mftf/Section/StorefrontBraintreePaymentConfigurationSection.xml new file mode 100644 index 0000000000000..d4cc3fe0f113d --- /dev/null +++ b/app/code/Magento/Braintree/Test/Mftf/Section/StorefrontBraintreePaymentConfigurationSection.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> + <section name="StorefrontBraintreePaymentConfigurationSection"> + <element name="creditCard" type="radio" selector="#braintree"/> + <element name="paymentMethodContainer" type="block" selector=".payment-method-braintree"/> + <element name="paymentMethod" type="radio" selector="//div[@class='payment-group']//input[contains(@id, 'braintree_cc_vault_')]"/> + <element name="cardFrame" type="iframe" selector="braintree-hosted-field-number"/> + <element name="monthFrame" type="iframe" selector="braintree-hosted-field-expirationMonth"/> + <element name="yearFrame" type="iframe" selector="braintree-hosted-field-expirationYear"/> + <element name="codeFrame" type="iframe" selector="braintree-hosted-field-cvv"/> + <element name="cardCode" type="input" selector="#credit-card-number"/> + <element name="month" type="input" selector="#expiration-month"/> + <element name="year" type="input" selector="#expiration-year"/> + <element name="verificationNumber" type="input" selector="#cvv"/> + </section> +</sections> diff --git a/app/code/Magento/Catalog/Test/Mftf/Data/ProductConfigurableAttributeData.xml b/app/code/Magento/Catalog/Test/Mftf/Data/ProductConfigurableAttributeData.xml index 0446a9db14f1a..8d588a192ed90 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Data/ProductConfigurableAttributeData.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Data/ProductConfigurableAttributeData.xml @@ -7,7 +7,7 @@ --> <entities xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/dataProfileSchema.xsd"> + xsi:noNamespaceSchemaLocation="urn:magento:mftf:DataGenerator/etc/dataProfileSchema.xsd"> <entity name="colorProductAttribute" type="product_attribute"> <data key="default_label" unique="suffix">Color</data> <data key="attribute_quantity">1</data> diff --git a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminCreditMemoActionGroup.xml b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminCreditMemoActionGroup.xml new file mode 100644 index 0000000000000..7197afb4a20df --- /dev/null +++ b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminCreditMemoActionGroup.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + <actionGroup name="StartCreateCreditMemoFromOrderPage"> + <click selector="{{AdminOrderDetailsMainActionsSection.creditMemo}}" stepKey="clickCreditMemoButton"/> + <conditionalClick selector="{{AdminConfirmationModalSection.ok}}" dependentSelector="{{AdminConfirmationModalSection.ok}}" + visible="true" stepKey="acceptModal"/> + <seeInCurrentUrl url="{{AdminCreditMemoNewPage.url}}" stepKey="seeNewCreditMemoUrl"/> + <see selector="{{AdminHeaderSection.pageTitle}}" userInput="New Memo" stepKey="seeNewCreditMemoPageTitle"/> + </actionGroup> + + <actionGroup name="SubmitCreditMemo"> + <waitForElementNotVisible selector="{{AdminCreditMemoTotalSection.submitRefundOfflineDisabled}}" stepKey="waitButtonEnabled"/> + <click selector="{{AdminCreditMemoTotalSection.submitRefundOffline}}" stepKey="clickSubmitCreditMemo"/> + <waitForElementVisible selector="{{AdminMessagesSection.successMessage}}" stepKey="waitForMessageAppears"/> + <see selector="{{AdminMessagesSection.successMessage}}" userInput="You created the credit memo." stepKey="seeCreditMemoCreateSuccess"/> + <grabFromCurrentUrl regex="~/order_id/(\d+)/~" stepKey="grabOrderId"/> + <seeInCurrentUrl url="{{AdminOrderDetailsPage.url('$grabOrderId')}}" stepKey="seeViewOrderPageCreditMemo"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Sales/Test/Mftf/Section/AdminCreditMemoTotalSection.xml b/app/code/Magento/Sales/Test/Mftf/Section/AdminCreditMemoTotalSection.xml index 648f519455b56..73ea29836e242 100644 --- a/app/code/Magento/Sales/Test/Mftf/Section/AdminCreditMemoTotalSection.xml +++ b/app/code/Magento/Sales/Test/Mftf/Section/AdminCreditMemoTotalSection.xml @@ -13,6 +13,8 @@ <element name="refundShipping" type="input" selector=".order-subtotal-table tbody input[name='creditmemo[shipping_amount]']"/> <element name="updateTotals" type="button" selector=".update-totals-button" timeout="30"/> <element name="submitRefundOffline" type="button" selector=".order-totals-actions button[title='Refund Offline']" timeout="30"/> - <element name="submitRefundOfflineEnabled" type="button" selector=".order-totals-actions button[data-ui-id='order-items-submit-button'][class='action-default scalable save submit-button primary']" timeout="30"/> + <element name="submitRefundOfflineEnabled" type="button" selector=".order-totals-actions button[data-ui-id='order-items-submit-button'].action-default.scalable.save.submit-button.primary']" timeout="30"/> + <element name="adjustmentRefund" type="input" selector=".order-subtotal-table tbody input[name='creditmemo[adjustment_positive]']"/> + <element name="submitRefundOfflineDisabled" type="button" selector="//*[@class='order-totals-actions']//button[@title='Refund Offline' and contains(@class, 'disabled')]" timeout="30"/> </section> </sections> diff --git a/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderDetailsMainActionsSection.xml b/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderDetailsMainActionsSection.xml index eac238584b030..3794def0ac77a 100644 --- a/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderDetailsMainActionsSection.xml +++ b/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderDetailsMainActionsSection.xml @@ -7,7 +7,7 @@ --> <sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/SectionObject.xsd"> + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> <section name="AdminOrderDetailsMainActionsSection"> <element name="back" type="button" selector="#back" timeout="30"/> <element name="cancel" type="button" selector="#order-view-cancel-button" timeout="30"/> diff --git a/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderViewTabsSection.xml b/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderViewTabsSection.xml index 78d0a45bce460..0037c482fcd72 100644 --- a/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderViewTabsSection.xml +++ b/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderViewTabsSection.xml @@ -12,5 +12,6 @@ <element name="invoices" type="button" selector="#sales_order_view_tabs_order_invoices"/> <element name="creditMemos" type="button" selector="#sales_order_view_tabs_order_creditmemos"/> <element name="shipments" type="button" selector="#sales_order_view_tabs_order_shipments"/> + <element name="commentsHistory" type="button" selector="#sales_order_view_tabs_order_history" timeout="30"/> </section> </sections> From 99e83429832c29904823ff06819bd39e685b973e Mon Sep 17 00:00:00 2001 From: Stas Kozar <stas.kozar@transoftgroup.com> Date: Tue, 12 Feb 2019 16:15:49 +0200 Subject: [PATCH 071/315] MAGETWO-86215: Static blocks with same ID appear in place of correct block --- app/code/Magento/Cms/Model/ResourceModel/Block.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Cms/Model/ResourceModel/Block.php b/app/code/Magento/Cms/Model/ResourceModel/Block.php index 6eae76f9790c9..9b4bc5ec3ea11 100644 --- a/app/code/Magento/Cms/Model/ResourceModel/Block.php +++ b/app/code/Magento/Cms/Model/ResourceModel/Block.php @@ -200,7 +200,7 @@ public function getIsUniqueBlockToStores(AbstractModel $object) 'cb.' . $linkField . ' = cbs.' . $linkField, [] ) - ->where('cb.identifier = ? ', $object->getData('identifier')); + ->where('cb.identifier = ?', $object->getData('identifier')); if (!$isDefaultStore) { $select->where('cbs.store_id IN (?)', $stores); From 3c54afad8d0aa02ce4d6e2e1b64fdd19a627c635 Mon Sep 17 00:00:00 2001 From: Stas Kozar <stas.kozar@transoftgroup.com> Date: Tue, 12 Feb 2019 17:11:35 +0200 Subject: [PATCH 072/315] MAGETWO-86215: Static blocks with same ID appear in place of correct block --- .../Mftf/ActionGroup/AdminCmsBlockActionGroup.xml | 11 ++++++----- ...heckCreateStaticBlockOnDuplicateIdentifierTest.xml | 10 +++++----- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/app/code/Magento/Cms/Test/Mftf/ActionGroup/AdminCmsBlockActionGroup.xml b/app/code/Magento/Cms/Test/Mftf/ActionGroup/AdminCmsBlockActionGroup.xml index 0ee5b3280a7c3..da7a3ea0c16c2 100644 --- a/app/code/Magento/Cms/Test/Mftf/ActionGroup/AdminCmsBlockActionGroup.xml +++ b/app/code/Magento/Cms/Test/Mftf/ActionGroup/AdminCmsBlockActionGroup.xml @@ -11,21 +11,21 @@ <arguments> <argument name="title" type="string" defaultValue="{{DefaultCmsBlock.title}}"/> <argument name="identifier" type="string" defaultValue="{{DefaultCmsBlock.identifier}}"/> - <argument name="store" type="string" defaultValue="All Store View"/> + <argument name="store" type="string" defaultValue="[All Store View]"/> <argument name="content" type="string" defaultValue="{{DefaultCmsBlock.content}}"/> </arguments> <fillField selector="{{AdminCmsBlockContentSection.title}}" userInput="{{title}}" stepKey="fillFieldTitle"/> <fillField selector="{{AdminCmsBlockContentSection.identifier}}" userInput="{{identifier}}" stepKey="fillFieldIdentifier"/> - <selectOption selector="{{AdminCmsBlockContentSection.storeView}}" userInput="{{store}}" stepKey="selectStore" /> + <selectOption selector="{{AdminCmsBlockContentSection.storeView}}" parameterArray="{{store}}" stepKey="selectStore" /> <fillField selector="{{AdminCmsBlockContentSection.content}}" userInput="{{content}}" stepKey="fillContentField"/> </actionGroup> <actionGroup name="DeleteCmsBlockActionGroup"> <arguments> - <argument name="cmsBlockTitle" type="string" defaultValue="{{DefaultCmsBlock.title}}"/> + <argument name="cmsBlockIdentifier" type="string" defaultValue="{{DefaultCmsBlock.identifier}}"/> </arguments> <amOnPage url="{{AdminCmsBlockGridPage.url}}" stepKey="navigateToCmsBlockListingPage"/> - <click selector="{{CmsPagesPageActionsSection.select(cmsBlockTitle)}}" stepKey="clickOnSelect"/> - <click selector="{{CmsPagesPageActionsSection.delete(cmsBlockTitle)}}" stepKey="clickOnDelete"/> + <click selector="{{CmsPagesPageActionsSection.select(cmsBlockIdentifier)}}" stepKey="clickOnSelect"/> + <click selector="{{CmsPagesPageActionsSection.delete(cmsBlockIdentifier)}}" stepKey="clickOnDelete"/> <waitForElementVisible selector="{{AdminConfirmationModalSection.message}}" stepKey="waitForConfirmModal"/> <click selector="{{AdminConfirmationModalSection.ok}}" stepKey="confirm"/> <see selector="{{AdminMessagesSection.success}}" userInput="You deleted the block." stepKey="verifyBlockIsDeleted"/> @@ -34,6 +34,7 @@ <amOnPage url="{{AdminCmsBlockNewPage.url}}" stepKey="navigateToCreateCmsBlockPage"/> </actionGroup> <actionGroup name="SaveCmsBlockActionGroup"> + <scrollToTopOfPage stepKey="scrollToTopOfPage"/> <click selector="{{AdminMainActionsSection.save}}" stepKey="clickSaveBlockButton"/> <see selector="{{AdminMessagesSection.success}}" userInput="You saved the block." stepKey="verifyMessage"/> </actionGroup> diff --git a/app/code/Magento/Cms/Test/Mftf/Test/CheckCreateStaticBlockOnDuplicateIdentifierTest.xml b/app/code/Magento/Cms/Test/Mftf/Test/CheckCreateStaticBlockOnDuplicateIdentifierTest.xml index f7ed9776c066c..e2e510f85cf0a 100644 --- a/app/code/Magento/Cms/Test/Mftf/Test/CheckCreateStaticBlockOnDuplicateIdentifierTest.xml +++ b/app/code/Magento/Cms/Test/Mftf/Test/CheckCreateStaticBlockOnDuplicateIdentifierTest.xml @@ -42,13 +42,13 @@ </actionGroup> <actionGroup ref="logout" stepKey="logout"/> </after> - <actionGroup ref="NavigateToCreateCmsBlockActionGroup" stepKey="NavigateToCreateCmsBlock"/> + <actionGroup ref="NavigateToCreateCmsBlockActionGroup" stepKey="navigateToCreateCmsBlock"/> <actionGroup ref="FillCmsBlockForm" stepKey="fillCmsBlockForm"/> <actionGroup ref="SaveCmsBlockActionGroup" stepKey="saveCmsBlock"/> - <actionGroup ref="NavigateToCreateCmsBlockActionGroup" stepKey="NavigateToCreateCmsBlock1"/> - <actionGroup ref="FillCmsBlockForm" stepKey="fillCmsBlockForm1"> - <argument name="store" parameterArray="[{{_defaultStore.name}},{{SecondStoreUnique.name}}]"/> + <actionGroup ref="NavigateToCreateCmsBlockActionGroup" stepKey="navigateToCreateCmsBlock1"/> + <actionGroup ref="FillCmsBlockForm" stepKey="fillDuplicateCmsBlockForm"> + <argument name="store" value="[{{_defaultStore.name}},{{SecondStoreUnique.name}}]"/> </actionGroup> - <actionGroup ref="SaveCmsBlockWithErrorActionGroup" stepKey="saveCmsBlock1"/> + <actionGroup ref="SaveCmsBlockWithErrorActionGroup" stepKey="assertErrorMessageOnSave"/> </test> </tests> From ecc08cbc02d71ca733bcbb88d545730b5ec3713c Mon Sep 17 00:00:00 2001 From: Stas Kozar <stas.kozar@transoftgroup.com> Date: Tue, 12 Feb 2019 17:59:03 +0200 Subject: [PATCH 073/315] MAGETWO-86215: Static blocks with same ID appear in place of correct block --- .../Cms/Test/Mftf/ActionGroup/AdminCmsBlockActionGroup.xml | 6 +++--- .../CheckCreateStaticBlockOnDuplicateIdentifierTest.xml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Cms/Test/Mftf/ActionGroup/AdminCmsBlockActionGroup.xml b/app/code/Magento/Cms/Test/Mftf/ActionGroup/AdminCmsBlockActionGroup.xml index da7a3ea0c16c2..62cc5f06fedcc 100644 --- a/app/code/Magento/Cms/Test/Mftf/ActionGroup/AdminCmsBlockActionGroup.xml +++ b/app/code/Magento/Cms/Test/Mftf/ActionGroup/AdminCmsBlockActionGroup.xml @@ -21,11 +21,11 @@ </actionGroup> <actionGroup name="DeleteCmsBlockActionGroup"> <arguments> - <argument name="cmsBlockIdentifier" type="string" defaultValue="{{DefaultCmsBlock.identifier}}"/> + <argument name="identifier" type="string" defaultValue="{{DefaultCmsBlock.identifier}}"/> </arguments> <amOnPage url="{{AdminCmsBlockGridPage.url}}" stepKey="navigateToCmsBlockListingPage"/> - <click selector="{{CmsPagesPageActionsSection.select(cmsBlockIdentifier)}}" stepKey="clickOnSelect"/> - <click selector="{{CmsPagesPageActionsSection.delete(cmsBlockIdentifier)}}" stepKey="clickOnDelete"/> + <click selector="{{CmsPagesPageActionsSection.select(identifier)}}" stepKey="clickOnSelect"/> + <click selector="{{CmsPagesPageActionsSection.delete(identifier)}}" stepKey="clickOnDelete"/> <waitForElementVisible selector="{{AdminConfirmationModalSection.message}}" stepKey="waitForConfirmModal"/> <click selector="{{AdminConfirmationModalSection.ok}}" stepKey="confirm"/> <see selector="{{AdminMessagesSection.success}}" userInput="You deleted the block." stepKey="verifyBlockIsDeleted"/> diff --git a/app/code/Magento/Cms/Test/Mftf/Test/CheckCreateStaticBlockOnDuplicateIdentifierTest.xml b/app/code/Magento/Cms/Test/Mftf/Test/CheckCreateStaticBlockOnDuplicateIdentifierTest.xml index e2e510f85cf0a..b79997578e675 100644 --- a/app/code/Magento/Cms/Test/Mftf/Test/CheckCreateStaticBlockOnDuplicateIdentifierTest.xml +++ b/app/code/Magento/Cms/Test/Mftf/Test/CheckCreateStaticBlockOnDuplicateIdentifierTest.xml @@ -45,7 +45,7 @@ <actionGroup ref="NavigateToCreateCmsBlockActionGroup" stepKey="navigateToCreateCmsBlock"/> <actionGroup ref="FillCmsBlockForm" stepKey="fillCmsBlockForm"/> <actionGroup ref="SaveCmsBlockActionGroup" stepKey="saveCmsBlock"/> - <actionGroup ref="NavigateToCreateCmsBlockActionGroup" stepKey="navigateToCreateCmsBlock1"/> + <actionGroup ref="NavigateToCreateCmsBlockActionGroup" stepKey="navigateToCreateDuplicateCmsBlock"/> <actionGroup ref="FillCmsBlockForm" stepKey="fillDuplicateCmsBlockForm"> <argument name="store" value="[{{_defaultStore.name}},{{SecondStoreUnique.name}}]"/> </actionGroup> From 11cafc3ce9b662ab0ea871c36761f59565343a37 Mon Sep 17 00:00:00 2001 From: hiren <hiren@wagento.com> Date: Sun, 3 Feb 2019 13:39:37 +0530 Subject: [PATCH 074/315] Solved swagger response of product attribute option is_default --- .../Directory/Model/ResourceModel/Country/Collection.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Directory/Model/ResourceModel/Country/Collection.php b/app/code/Magento/Directory/Model/ResourceModel/Country/Collection.php index da5ad64f8b239..02fed61c44863 100644 --- a/app/code/Magento/Directory/Model/ResourceModel/Country/Collection.php +++ b/app/code/Magento/Directory/Model/ResourceModel/Country/Collection.php @@ -328,7 +328,7 @@ private function addDefaultCountryToOptions(array &$options) foreach ($options as $key => $option) { if (isset($defaultCountry[$option['value']])) { - $options[$key]['is_default'] = $defaultCountry[$option['value']]; + $options[$key]['is_default'] = !empty($defaultCountry[$option['value']]); } } } From 5482702cbe8579dca95a3e60788de614f9c4c5fc Mon Sep 17 00:00:00 2001 From: Arvinda kumar <arvindakumar@cedcommerce.com> Date: Fri, 1 Feb 2019 12:35:10 +0530 Subject: [PATCH 075/315] Email to a Friend form not full responsive and remove link not position on correct place Email to a Friend form not full responsive and remove link not position on correct place --- .../web/css/source/_module.less | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/app/design/frontend/Magento/luma/Magento_SendFriend/web/css/source/_module.less b/app/design/frontend/Magento/luma/Magento_SendFriend/web/css/source/_module.less index baf5468b18485..75ce71dea1e78 100644 --- a/app/design/frontend/Magento/luma/Magento_SendFriend/web/css/source/_module.less +++ b/app/design/frontend/Magento/luma/Magento_SendFriend/web/css/source/_module.less @@ -44,3 +44,24 @@ } } } +.media-width(@extremum, @break) when (@extremum = 'max') and (@break = @screen__m) { + .form.send.friend { + .fieldset { + .field { + .control { + width: 100%; + } + } + padding-bottom: 10px; + } + .action { + &.remove { + right: 0; + margin-left: 0; + text-align: right; + width: 65px; + top: 100%; + } + } + } +} From bb12b351d2209dc680987fd8835e474fd7858be3 Mon Sep 17 00:00:00 2001 From: Arvinda kumar <arvindakumar@cedcommerce.com> Date: Mon, 4 Feb 2019 14:46:05 +0530 Subject: [PATCH 076/315] _module.less updated _module.less updated --- .../luma/Magento_SendFriend/web/css/source/_module.less | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/app/design/frontend/Magento/luma/Magento_SendFriend/web/css/source/_module.less b/app/design/frontend/Magento/luma/Magento_SendFriend/web/css/source/_module.less index 75ce71dea1e78..d8f198c57b30c 100644 --- a/app/design/frontend/Magento/luma/Magento_SendFriend/web/css/source/_module.less +++ b/app/design/frontend/Magento/luma/Magento_SendFriend/web/css/source/_module.less @@ -47,19 +47,17 @@ .media-width(@extremum, @break) when (@extremum = 'max') and (@break = @screen__m) { .form.send.friend { .fieldset { + padding-bottom: @indent__xs; .field { .control { width: 100%; } } - padding-bottom: 10px; } .action { &.remove { right: 0; margin-left: 0; - text-align: right; - width: 65px; top: 100%; } } From 89309ce2c23a454c4f281bfda40551d55bb5c3bc Mon Sep 17 00:00:00 2001 From: Arvinda kumar <arvindakumar@cedcommerce.com> Date: Mon, 4 Feb 2019 14:53:01 +0530 Subject: [PATCH 077/315] _module.less updated _module.less updated --- .../web/css/source/_module.less | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/app/design/frontend/Magento/luma/Magento_SendFriend/web/css/source/_module.less b/app/design/frontend/Magento/luma/Magento_SendFriend/web/css/source/_module.less index d8f198c57b30c..77cef1e9a15f8 100644 --- a/app/design/frontend/Magento/luma/Magento_SendFriend/web/css/source/_module.less +++ b/app/design/frontend/Magento/luma/Magento_SendFriend/web/css/source/_module.less @@ -10,6 +10,13 @@ & when (@media-common = true) { .form.send.friend { &:extend(.abs-add-fields all); + .fieldset { + .field { + .control { + width: 100%; + } + } + } } .product-social-links .action.mailto.friend { @@ -21,6 +28,7 @@ } } + // // Desktop // _____________________________________________ @@ -47,12 +55,7 @@ .media-width(@extremum, @break) when (@extremum = 'max') and (@break = @screen__m) { .form.send.friend { .fieldset { - padding-bottom: @indent__xs; - .field { - .control { - width: 100%; - } - } + padding-bottom: @indent__xs; } .action { &.remove { From fd220482e5eccf050c080944fc3bd4564eed32b2 Mon Sep 17 00:00:00 2001 From: Arvinda kumar <arvindakumar@cedcommerce.com> Date: Mon, 4 Feb 2019 15:23:33 +0530 Subject: [PATCH 078/315] _module.less updated _module.less updated --- .../luma/Magento_SendFriend/web/css/source/_module.less | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/design/frontend/Magento/luma/Magento_SendFriend/web/css/source/_module.less b/app/design/frontend/Magento/luma/Magento_SendFriend/web/css/source/_module.less index 77cef1e9a15f8..0c475b2c59aee 100644 --- a/app/design/frontend/Magento/luma/Magento_SendFriend/web/css/source/_module.less +++ b/app/design/frontend/Magento/luma/Magento_SendFriend/web/css/source/_module.less @@ -10,6 +10,7 @@ & when (@media-common = true) { .form.send.friend { &:extend(.abs-add-fields all); + .fieldset { .field { .control { @@ -28,7 +29,6 @@ } } - // // Desktop // _____________________________________________ @@ -57,6 +57,7 @@ .fieldset { padding-bottom: @indent__xs; } + .action { &.remove { right: 0; From 8932e147a31ee5ac01fe0a673cfac805c1cb9c20 Mon Sep 17 00:00:00 2001 From: Pavel Bystritsky <p.bystritsky@yandex.ru> Date: Tue, 5 Feb 2019 13:56:58 +0200 Subject: [PATCH 079/315] ENGCOM-4115: Static test fix. --- .../luma/Magento_SendFriend/web/css/source/_module.less | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/design/frontend/Magento/luma/Magento_SendFriend/web/css/source/_module.less b/app/design/frontend/Magento/luma/Magento_SendFriend/web/css/source/_module.less index 0c475b2c59aee..3435736a54a6a 100644 --- a/app/design/frontend/Magento/luma/Magento_SendFriend/web/css/source/_module.less +++ b/app/design/frontend/Magento/luma/Magento_SendFriend/web/css/source/_module.less @@ -60,9 +60,9 @@ .action { &.remove { - right: 0; margin-left: 0; - top: 100%; + right: 0; + top: 100%; } } } From 41742d06877a02e2fb27817fb023dde111b6d326 Mon Sep 17 00:00:00 2001 From: Andrii Meysar <andrii.meysar@transoftgroup.com> Date: Tue, 12 Feb 2019 21:23:32 +0200 Subject: [PATCH 080/315] MAGETWO-86215: Static blocks with same ID appear in place of correct block --- .../Test/CheckCreateStaticBlockOnDuplicateIdentifierTest.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Cms/Test/Mftf/Test/CheckCreateStaticBlockOnDuplicateIdentifierTest.xml b/app/code/Magento/Cms/Test/Mftf/Test/CheckCreateStaticBlockOnDuplicateIdentifierTest.xml index b79997578e675..ac1b68269740f 100644 --- a/app/code/Magento/Cms/Test/Mftf/Test/CheckCreateStaticBlockOnDuplicateIdentifierTest.xml +++ b/app/code/Magento/Cms/Test/Mftf/Test/CheckCreateStaticBlockOnDuplicateIdentifierTest.xml @@ -18,6 +18,7 @@ <testCaseId value="MC-13912"/> <useCaseId value="MAGETWO-86215"/> <group value="cms"/> + <group value="WYSIWYGDisabled"/> </annotations> <before> <actionGroup ref="LoginAsAdmin" stepKey="LoginAsAdmin"/> From e9102ecb206fd19b73493b0f7e1e00dbc92d661f Mon Sep 17 00:00:00 2001 From: amol 2jcommerce <amol@2jcommerce.in> Date: Wed, 13 Feb 2019 10:34:24 +0530 Subject: [PATCH 081/315] fixes-customer-information-wishlist-configurable-product-alignment-2.2 --- .../product/composite/fieldset/configurable.phtml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/ConfigurableProduct/view/adminhtml/templates/catalog/product/composite/fieldset/configurable.phtml b/app/code/Magento/ConfigurableProduct/view/adminhtml/templates/catalog/product/composite/fieldset/configurable.phtml index a8712cdc183de..190ecccbfdb76 100644 --- a/app/code/Magento/ConfigurableProduct/view/adminhtml/templates/catalog/product/composite/fieldset/configurable.phtml +++ b/app/code/Magento/ConfigurableProduct/view/adminhtml/templates/catalog/product/composite/fieldset/configurable.phtml @@ -17,9 +17,9 @@ <legend class="legend admin__legend"> <span><?= /* @escapeNotVerified */ __('Associated Products') ?></span> </legend> - <div class="product-options"> - <div class="field admin__field _required required"> - <?php foreach ($_attributes as $_attribute): ?> + <div class="product-options fieldset admin__fieldset"> + <?php foreach ($_attributes as $_attribute): ?> + <div class="field admin__field _required required"> <label class="label admin__field-label"><?php /* @escapeNotVerified */ echo $_attribute->getProductAttribute() ->getStoreLabel($_product->getStoreId()); @@ -34,8 +34,8 @@ <option><?= /* @escapeNotVerified */ __('Choose an Option...') ?></option> </select> </div> - <?php endforeach; ?> - </div> + </div> + <?php endforeach; ?> </div> </fieldset> <script> From 30e61f499761ba83ace058d230e91807dbd45803 Mon Sep 17 00:00:00 2001 From: Serhii Voloshkov <serhii.voloshkov@transoftgroup.com> Date: Wed, 13 Feb 2019 08:38:22 +0200 Subject: [PATCH 082/315] MAGETWO-94421: Default addresses not selected when checking out from cart --- .../Customer/Test/Mftf/Data/CustomerData.xml | 10 +++++ .../ActionGroup/AdminOrderActionGroup.xml | 45 +++++++++++++++++++ .../AdminOrderFormShippingAddressSection.xml | 23 ++++++++++ 3 files changed, 78 insertions(+) create mode 100644 app/code/Magento/Sales/Test/Mftf/Section/AdminOrderFormShippingAddressSection.xml diff --git a/app/code/Magento/Customer/Test/Mftf/Data/CustomerData.xml b/app/code/Magento/Customer/Test/Mftf/Data/CustomerData.xml index a8b8cece39fad..7082a799ed748 100644 --- a/app/code/Magento/Customer/Test/Mftf/Data/CustomerData.xml +++ b/app/code/Magento/Customer/Test/Mftf/Data/CustomerData.xml @@ -44,6 +44,16 @@ <data key="website_id">0</data> <requiredEntity type="address">US_Address_TX</requiredEntity> </entity> + <entity name="Simple_Customer_Without_Address" type="customer"> + <data key="group_id">1</data> + <data key="email" unique="prefix">John.Doe@example.com</data> + <data key="firstname">John</data> + <data key="lastname">Doe</data> + <data key="fullname">John Doe</data> + <data key="password">pwdTest123!</data> + <data key="store_id">0</data> + <data key="website_id">0</data> + </entity> <entity name="Simple_US_Customer_For_Update" type="customer"> <var key="id" entityKey="id" entityType="customer"/> <data key="firstname">Jane</data> diff --git a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderActionGroup.xml b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderActionGroup.xml index bb3bfdc03d340..2f7bd98572f8b 100644 --- a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderActionGroup.xml +++ b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderActionGroup.xml @@ -174,6 +174,51 @@ <fillField selector="{{AdminOrderFormBillingAddressSection.postalCode}}" userInput="{{address.postcode}}" stepKey="fillPostalCode"/> <fillField selector="{{AdminOrderFormBillingAddressSection.phone}}" userInput="{{address.telephone}}" stepKey="fillPhone"/> </actionGroup> + <!--Check customer billing address fields--> + <actionGroup name="checkOrderCustomerBillingInformation"> + <arguments> + <argument name="customer"/> + <argument name="address"/> + </arguments> + <seeInField selector="{{AdminOrderFormBillingAddressSection.firstName}}" userInput="{{customer.firstname}}" stepKey="checkFirstName"/> + <seeInField selector="{{AdminOrderFormBillingAddressSection.lastName}}" userInput="{{customer.lastname}}" stepKey="checkLastName"/> + <seeInField selector="{{AdminOrderFormBillingAddressSection.streetLine1}}" userInput="{{address.street[0]}}" stepKey="checkStreet"/> + <seeInField selector="{{AdminOrderFormBillingAddressSection.city}}" userInput="{{address.city}}" stepKey="checkCity"/> + <seeInField selector="{{AdminOrderFormBillingAddressSection.country}}" userInput="{{address.country_id}}" stepKey="checkCountry"/> + <seeInField selector="{{AdminOrderFormBillingAddressSection.state}}" userInput="{{address.state}}" stepKey="checkState"/> + <seeInField selector="{{AdminOrderFormBillingAddressSection.postalCode}}" userInput="{{address.postcode}}" stepKey="checkPostCode"/> + <seeInField selector="{{AdminOrderFormBillingAddressSection.phone}}" userInput="{{address.telephone}}" stepKey="checkTelephone"/> + </actionGroup> + <!--Fill customer shipping address--> + <actionGroup name="fillOrderCustomerShippingInformation"> + <arguments> + <argument name="customer"/> + <argument name="address"/> + </arguments> + <fillField selector="{{AdminOrderFormShippingAddressSection.firstName}}" userInput="{{customer.firstname}}" stepKey="fillFirstName"/> + <fillField selector="{{AdminOrderFormShippingAddressSection.lastName}}" userInput="{{customer.lastname}}" stepKey="fillLastName"/> + <fillField selector="{{AdminOrderFormShippingAddressSection.streetLine1}}" userInput="{{address.street[0]}}" stepKey="fillStreetLine1"/> + <fillField selector="{{AdminOrderFormShippingAddressSection.city}}" userInput="{{address.city}}" stepKey="fillCity"/> + <selectOption selector="{{AdminOrderFormShippingAddressSection.country}}" userInput="{{address.country_id}}" stepKey="fillCountry"/> + <selectOption selector="{{AdminOrderFormShippingAddressSection.state}}" userInput="{{address.state}}" stepKey="fillState"/> + <fillField selector="{{AdminOrderFormShippingAddressSection.postalCode}}" userInput="{{address.postcode}}" stepKey="fillPostalCode"/> + <fillField selector="{{AdminOrderFormShippingAddressSection.phone}}" userInput="{{address.telephone}}" stepKey="fillPhone"/> + </actionGroup> + <!--Check customer shipping address fields--> + <actionGroup name="checkOrderCustomerShippingInformation"> + <arguments> + <argument name="customer"/> + <argument name="address"/> + </arguments> + <seeInField selector="{{AdminOrderFormShippingAddressSection.firstName}}" userInput="{{customer.firstname}}" stepKey="checkFirstName"/> + <seeInField selector="{{AdminOrderFormShippingAddressSection.lastName}}" userInput="{{customer.lastname}}" stepKey="checkLastName"/> + <seeInField selector="{{AdminOrderFormShippingAddressSection.streetLine1}}" userInput="{{address.street[0]}}" stepKey="checkStreet"/> + <seeInField selector="{{AdminOrderFormShippingAddressSection.city}}" userInput="{{address.city}}" stepKey="checkCity"/> + <seeInField selector="{{AdminOrderFormShippingAddressSection.country}}" userInput="{{address.country_id}}" stepKey="checkCountry"/> + <seeInField selector="{{AdminOrderFormShippingAddressSection.state}}" userInput="{{address.state}}" stepKey="checkState"/> + <seeInField selector="{{AdminOrderFormShippingAddressSection.postalCode}}" userInput="{{address.postcode}}" stepKey="checkPostCode"/> + <seeInField selector="{{AdminOrderFormShippingAddressSection.phone}}" userInput="{{address.telephone}}" stepKey="checkTelephone"/> + </actionGroup> <!--Select flat rate shipping method--> <actionGroup name="orderSelectFlatRateShipping"> <click selector="{{AdminOrderFormPaymentSection.header}}" stepKey="unfocus"/> diff --git a/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderFormShippingAddressSection.xml b/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderFormShippingAddressSection.xml new file mode 100644 index 0000000000000..aae90589a390f --- /dev/null +++ b/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderFormShippingAddressSection.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> + <section name="AdminOrderFormShippingAddressSection"> + <element name="firstName" type="input" selector="#order-shipping_address_firstname" timeout="30"/> + <element name="lastName" type="input" selector="#order-shipping_address_lastname" timeout="30"/> + <element name="streetLine1" type="input" selector="#order-shipping_address_street0" timeout="30"/> + <element name="city" type="input" selector="#order-shipping_address_city" timeout="30"/> + <element name="country" type="select" selector="#order-shipping_address_country_id" timeout="30"/> + <element name="state" type="select" selector="#order-shipping_address_region_id" timeout="30"/> + <element name="postalCode" type="input" selector="#order-shipping_address_postcode" timeout="30"/> + <element name="phone" type="input" selector="#order-shipping_address_telephone" timeout="30"/> + <element name="saveAddress" type="checkbox" selector="#order-shipping_address_save_in_address_book"/> + <element name="sameAsBilling" type="checkbox" selector="#order-shipping_same_as_billing"/> + </section> +</sections> From ef8e4f5a7d779278010a5d0b261759c75889ed53 Mon Sep 17 00:00:00 2001 From: Serhii Voloshkov <serhii.voloshkov@transoftgroup.com> Date: Wed, 13 Feb 2019 08:46:01 +0200 Subject: [PATCH 083/315] MAGETWO-94421: Default addresses not selected when checking out from cart --- app/code/Magento/Sales/Test/Mftf/Page/AdminOrderCreatePage.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Sales/Test/Mftf/Page/AdminOrderCreatePage.xml b/app/code/Magento/Sales/Test/Mftf/Page/AdminOrderCreatePage.xml index e67a2c3b961d9..ca4239bb060ca 100644 --- a/app/code/Magento/Sales/Test/Mftf/Page/AdminOrderCreatePage.xml +++ b/app/code/Magento/Sales/Test/Mftf/Page/AdminOrderCreatePage.xml @@ -7,12 +7,13 @@ --> <pages xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/PageObject.xsd"> + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/PageObject.xsd"> <page name="AdminOrderCreatePage" url="sales/order_create/index" area="admin" module="Magento_Sales"> <section name="AdminOrderFormSelectWebsiteSection"/> <section name="AdminOrderFormActionSection"/> <section name="AdminOrderFormAccountSection"/> <section name="AdminOrderFormBillingAddressSection"/> + <section name="AdminOrderFormShippingAddressSection"/> <section name="AdminOrderFormPaymentSection"/> <section name="AdminOrderFormItemsSection"/> <section name="AdminOrderFormTotalSection"/> From 118d4d587aaa83944aa487ad95ba8fd41dc794de Mon Sep 17 00:00:00 2001 From: OlgaVasyltsun <olga.vasyltsun@gmail.com> Date: Wed, 13 Feb 2019 09:16:32 +0200 Subject: [PATCH 084/315] MAGETWO-73432: Change EAV model --- .../ActionGroup/AdminAddCustomerAddressActionGroup.xml | 9 ++++----- .../Mftf/Section/AdminCustomerAccountAddressSection.xml | 4 ++-- .../Section/AdminCustomerAccountNewAddressSection.xml | 6 +++--- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminAddCustomerAddressActionGroup.xml b/app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminAddCustomerAddressActionGroup.xml index f042c272cbfce..1ffc258e78a43 100644 --- a/app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminAddCustomerAddressActionGroup.xml +++ b/app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminAddCustomerAddressActionGroup.xml @@ -7,20 +7,19 @@ --> <actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> - <actionGroup name="AdminAddCustomerAddressActionGroup" > + <actionGroup name="AdminAddCustomerAddressWithRegionTypeSelectActionGroup" > <arguments> <argument name="customerAddress" defaultValue="CustomerAddressSimple"/> </arguments> <click selector="{{AdminCustomerAccountAddressSection.addresses}}" stepKey="proceedToAddresses"/> <click selector="{{AdminCustomerAccountAddressSection.addNewAddress}}" stepKey="addNewAddresses"/> - <waitForPageLoad time="60" stepKey="waitAddressFieldsLoaded" /> <fillField userInput="{{customerAddress.street[0]}}" selector="{{AdminCustomerAccountNewAddressSection.street}}" stepKey="fillStreetAddress"/> <fillField userInput="{{customerAddress.city}}" selector="{{AdminCustomerAccountNewAddressSection.city}}" stepKey="fillCity"/> - <selectOption userInput="{{US_Address_CA.country_id}}" selector="{{AdminCustomerAccountNewAddressSection.country}}" stepKey="selectCountry"/> - <selectOption userInput="{{US_Address_CA.state}}" selector="{{AdminCustomerAccountNewAddressSection.region}}" stepKey="selectState"/> + <selectOption userInput="{{customerAddress.country_id}}" selector="{{AdminCustomerAccountNewAddressSection.country}}" stepKey="selectCountry"/> + <selectOption userInput="{{customerAddress.state}}" selector="{{AdminCustomerAccountNewAddressSection.regionId}}" stepKey="selectState"/> <fillField userInput="{{customerAddress.postcode}}" selector="{{AdminCustomerAccountNewAddressSection.zip}}" stepKey="fillZipCode"/> <fillField userInput="{{customerAddress.telephone}}" selector="{{AdminCustomerAccountNewAddressSection.phone}}" stepKey="fillPhone"/> <click selector="{{AdminMainActionsSection.save}}" stepKey="saveCustomer"/> - <see selector="{{AdminMessagesSection.success}}" userInput="You saved the customer." stepKey="CustomerIsSaved"/> + <see userInput="You saved the customer." selector="{{AdminMessagesSection.success}}" stepKey="customerIsSaved"/> </actionGroup> </actionGroups> diff --git a/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerAccountAddressSection.xml b/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerAccountAddressSection.xml index 334a5d81901ea..70042e2a71467 100644 --- a/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerAccountAddressSection.xml +++ b/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerAccountAddressSection.xml @@ -7,7 +7,7 @@ <sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> <section name="AdminCustomerAccountAddressSection"> - <element name="addresses" type="button" selector="a#tab_address" timeout="30"/> - <element name="addNewAddress" type="button" selector=".address-list-actions button.scalable.add span"/> + <element name="addresses" type="button" selector="#tab_address" timeout="30"/> + <element name="addNewAddress" type="button" selector=".address-list-actions button.scalable.add span" timeout="30"/> </section> </sections> diff --git a/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerAccountNewAddressSection.xml b/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerAccountNewAddressSection.xml index 4f1bf69c6e687..8445343c9b9c0 100644 --- a/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerAccountNewAddressSection.xml +++ b/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerAccountNewAddressSection.xml @@ -12,8 +12,8 @@ <element name="street" type="button" selector="input[name*='new'][name*='street']"/> <element name="city" type="input" selector="input[name*='new'][name*='city']"/> <element name="country" type="select" selector="select[name*='address'][name*='new'][name*='country']" timeout="10"/> - <element name="region" type="select" selector="select[name*='address'][name*='new'][name*='region_id']"/> - <element name="zip" type="input" selector="input[name*='new'][name*='postcode']"/> - <element name="phone" type="text" selector="input[name*='new'][name*='telephone']" /> + <element name="regionId" type="select" selector="select[name*='address'][name*='new'][name*='region_id']"/> + <element name="zip" type="input" selector="input[name*='address'][name*='new'][name*='postcode']"/> + <element name="phone" type="text" selector="input[name*='address'][name*='new'][name*='telephone']" /> </section> </sections> From e6fa7e1d601905cb10fbb996386eb27f7de5292d Mon Sep 17 00:00:00 2001 From: Stas Kozar <stas.kozar@transoftgroup.com> Date: Wed, 13 Feb 2019 09:37:31 +0200 Subject: [PATCH 085/315] MAGETWO-86215: Static blocks with same ID appear in place of correct block --- .../Cms/Test/Mftf/ActionGroup/AdminCmsBlockActionGroup.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Cms/Test/Mftf/ActionGroup/AdminCmsBlockActionGroup.xml b/app/code/Magento/Cms/Test/Mftf/ActionGroup/AdminCmsBlockActionGroup.xml index 62cc5f06fedcc..d9dc9ec10670c 100644 --- a/app/code/Magento/Cms/Test/Mftf/ActionGroup/AdminCmsBlockActionGroup.xml +++ b/app/code/Magento/Cms/Test/Mftf/ActionGroup/AdminCmsBlockActionGroup.xml @@ -24,6 +24,7 @@ <argument name="identifier" type="string" defaultValue="{{DefaultCmsBlock.identifier}}"/> </arguments> <amOnPage url="{{AdminCmsBlockGridPage.url}}" stepKey="navigateToCmsBlockListingPage"/> + <conditionalClick selector="{{AdminDataGridHeaderSection.clearFilters}}" dependentSelector="{{AdminDataGridHeaderSection.clearFilters}}" visible="true" stepKey="clearExistingFilters"/> <click selector="{{CmsPagesPageActionsSection.select(identifier)}}" stepKey="clickOnSelect"/> <click selector="{{CmsPagesPageActionsSection.delete(identifier)}}" stepKey="clickOnDelete"/> <waitForElementVisible selector="{{AdminConfirmationModalSection.message}}" stepKey="waitForConfirmModal"/> From da56acdd8fc5d3d952ca7d0d6b552a9a22efa286 Mon Sep 17 00:00:00 2001 From: Stas Kozar <stas.kozar@transoftgroup.com> Date: Wed, 13 Feb 2019 11:10:22 +0200 Subject: [PATCH 086/315] MAGETWO-86215: Static blocks with same ID appear in place of correct block --- .../Cms/Test/Mftf/ActionGroup/AdminCmsBlockActionGroup.xml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Cms/Test/Mftf/ActionGroup/AdminCmsBlockActionGroup.xml b/app/code/Magento/Cms/Test/Mftf/ActionGroup/AdminCmsBlockActionGroup.xml index d9dc9ec10670c..36eb3e3c351e9 100644 --- a/app/code/Magento/Cms/Test/Mftf/ActionGroup/AdminCmsBlockActionGroup.xml +++ b/app/code/Magento/Cms/Test/Mftf/ActionGroup/AdminCmsBlockActionGroup.xml @@ -24,12 +24,16 @@ <argument name="identifier" type="string" defaultValue="{{DefaultCmsBlock.identifier}}"/> </arguments> <amOnPage url="{{AdminCmsBlockGridPage.url}}" stepKey="navigateToCmsBlockListingPage"/> - <conditionalClick selector="{{AdminDataGridHeaderSection.clearFilters}}" dependentSelector="{{AdminDataGridHeaderSection.clearFilters}}" visible="true" stepKey="clearExistingFilters"/> + <conditionalClick selector="{{AdminDataGridHeaderSection.clearFilters}}" dependentSelector="{{AdminDataGridHeaderSection.clearFilters}}" visible="true" stepKey="clearExistingFiltersBeforeDelete"/> + <click selector="{{AdminDataGridHeaderSection.filters}}" stepKey="openCmsBlockFilters"/> + <fillField selector="{{AdminDataGridHeaderSection.filterFieldInput('identifier')}}" userInput="{{identifier}}" stepKey="fillFilter"/> + <click selector="{{AdminDataGridHeaderSection.applyFilters}}" stepKey="clickApplyFilters"/> <click selector="{{CmsPagesPageActionsSection.select(identifier)}}" stepKey="clickOnSelect"/> <click selector="{{CmsPagesPageActionsSection.delete(identifier)}}" stepKey="clickOnDelete"/> <waitForElementVisible selector="{{AdminConfirmationModalSection.message}}" stepKey="waitForConfirmModal"/> <click selector="{{AdminConfirmationModalSection.ok}}" stepKey="confirm"/> <see selector="{{AdminMessagesSection.success}}" userInput="You deleted the block." stepKey="verifyBlockIsDeleted"/> + <conditionalClick selector="{{AdminDataGridHeaderSection.clearFilters}}" dependentSelector="{{AdminDataGridHeaderSection.clearFilters}}" visible="true" stepKey="clearExistingFiltersAfterDelete"/> </actionGroup> <actionGroup name="NavigateToCreateCmsBlockActionGroup"> <amOnPage url="{{AdminCmsBlockNewPage.url}}" stepKey="navigateToCreateCmsBlockPage"/> From 934b6e2cfa898d628c88e09fc88406e36b716e78 Mon Sep 17 00:00:00 2001 From: Myroslav Dobra <dmaraptor@gmail.com> Date: Wed, 13 Feb 2019 12:20:47 +0200 Subject: [PATCH 087/315] MAGETWO-96636: MFTF test fix --- .../StorefrontBraintreeFillCardDataActionGroup.xml | 9 +++++++-- .../Braintree/Test/Mftf/Page/CheckoutPage.xml | 14 ++++++++++++++ ...refrontBraintreePaymentConfigurationSection.xml | 6 ++---- 3 files changed, 23 insertions(+), 6 deletions(-) create mode 100644 app/code/Magento/Braintree/Test/Mftf/Page/CheckoutPage.xml diff --git a/app/code/Magento/Braintree/Test/Mftf/ActionGroup/StorefrontBraintreeFillCardDataActionGroup.xml b/app/code/Magento/Braintree/Test/Mftf/ActionGroup/StorefrontBraintreeFillCardDataActionGroup.xml index 561d660a1bb75..93f239b5c38a1 100644 --- a/app/code/Magento/Braintree/Test/Mftf/ActionGroup/StorefrontBraintreeFillCardDataActionGroup.xml +++ b/app/code/Magento/Braintree/Test/Mftf/ActionGroup/StorefrontBraintreeFillCardDataActionGroup.xml @@ -7,13 +7,18 @@ --> <actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + <actionGroup name="StorefrontBraintreeSelectPaymentMethodActionGroup"> + <click selector="{{StorefrontBraintreePaymentConfigurationSection.creditCardBraintreePaymentMethod}}" stepKey="selectBraintreePaymentMethod"/> + </actionGroup> + <actionGroup name="StorefrontBraintreeFillCardDataActionGroup"> <arguments> <argument name="cardData" defaultValue="BraintreeCard"/> </arguments> + <scrollTo selector="{{StorefrontBraintreePaymentConfigurationSection.creditCardBraintreePaymentMethod}}" stepKey="scrollToCreditCardSection"/> <switchToIFrame selector="{{StorefrontBraintreePaymentConfigurationSection.cardFrame}}" stepKey="switchToIframe"/> - <waitForElementVisible selector="{{StorefrontBraintreePaymentConfigurationSection.cardCode}}" stepKey="waitCardCodeElement"/> - <fillField selector="{{StorefrontBraintreePaymentConfigurationSection.cardCode}}" userInput="{{cardData.card_number}}" stepKey="setCardCode"/> + <waitForElementVisible selector="{{StorefrontBraintreePaymentConfigurationSection.cardNumber}}" stepKey="waitCardNumberElement"/> + <fillField selector="{{StorefrontBraintreePaymentConfigurationSection.cardNumber}}" userInput="{{cardData.card_number}}" stepKey="setCardNumber"/> <switchToIFrame stepKey="switchBack"/> <switchToIFrame selector="{{StorefrontBraintreePaymentConfigurationSection.monthFrame}}" stepKey="switchToIframe1"/> <waitForElementVisible selector="{{StorefrontBraintreePaymentConfigurationSection.month}}" stepKey="waitMonthElement"/> diff --git a/app/code/Magento/Braintree/Test/Mftf/Page/CheckoutPage.xml b/app/code/Magento/Braintree/Test/Mftf/Page/CheckoutPage.xml new file mode 100644 index 0000000000000..bc23a1e1fe3f7 --- /dev/null +++ b/app/code/Magento/Braintree/Test/Mftf/Page/CheckoutPage.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<pages xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/PageObject.xsd"> + <page name="CheckoutPage" url="/checkout" area="storefront" module="Magento_Checkout"> + <section name="StorefrontBraintreePaymentConfigurationSection"/> + </page> +</pages> diff --git a/app/code/Magento/Braintree/Test/Mftf/Section/StorefrontBraintreePaymentConfigurationSection.xml b/app/code/Magento/Braintree/Test/Mftf/Section/StorefrontBraintreePaymentConfigurationSection.xml index d4cc3fe0f113d..f72eed9179764 100644 --- a/app/code/Magento/Braintree/Test/Mftf/Section/StorefrontBraintreePaymentConfigurationSection.xml +++ b/app/code/Magento/Braintree/Test/Mftf/Section/StorefrontBraintreePaymentConfigurationSection.xml @@ -9,14 +9,12 @@ <sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> <section name="StorefrontBraintreePaymentConfigurationSection"> - <element name="creditCard" type="radio" selector="#braintree"/> - <element name="paymentMethodContainer" type="block" selector=".payment-method-braintree"/> - <element name="paymentMethod" type="radio" selector="//div[@class='payment-group']//input[contains(@id, 'braintree_cc_vault_')]"/> + <element name="creditCardBraintreePaymentMethod" type="radio" selector="#braintree" timeout="30"/> <element name="cardFrame" type="iframe" selector="braintree-hosted-field-number"/> <element name="monthFrame" type="iframe" selector="braintree-hosted-field-expirationMonth"/> <element name="yearFrame" type="iframe" selector="braintree-hosted-field-expirationYear"/> <element name="codeFrame" type="iframe" selector="braintree-hosted-field-cvv"/> - <element name="cardCode" type="input" selector="#credit-card-number"/> + <element name="cardNumber" type="input" selector="#credit-card-number"/> <element name="month" type="input" selector="#expiration-month"/> <element name="year" type="input" selector="#expiration-year"/> <element name="verificationNumber" type="input" selector="#cvv"/> From 9ace1ea71b185544340c29a809e0c44159952852 Mon Sep 17 00:00:00 2001 From: Stas Kozar <stas.kozar@transoftgroup.com> Date: Wed, 13 Feb 2019 12:22:26 +0200 Subject: [PATCH 088/315] MAGETWO-86215: Static blocks with same ID appear in place of correct block --- .../Test/Mftf/ActionGroup/AdminCmsBlockActionGroup.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Cms/Test/Mftf/ActionGroup/AdminCmsBlockActionGroup.xml b/app/code/Magento/Cms/Test/Mftf/ActionGroup/AdminCmsBlockActionGroup.xml index 36eb3e3c351e9..597df165f61d1 100644 --- a/app/code/Magento/Cms/Test/Mftf/ActionGroup/AdminCmsBlockActionGroup.xml +++ b/app/code/Magento/Cms/Test/Mftf/ActionGroup/AdminCmsBlockActionGroup.xml @@ -21,15 +21,15 @@ </actionGroup> <actionGroup name="DeleteCmsBlockActionGroup"> <arguments> - <argument name="identifier" type="string" defaultValue="{{DefaultCmsBlock.identifier}}"/> + <argument name="cmsBlockIdentifier" type="string" defaultValue="{{DefaultCmsBlock.identifier}}"/> </arguments> <amOnPage url="{{AdminCmsBlockGridPage.url}}" stepKey="navigateToCmsBlockListingPage"/> <conditionalClick selector="{{AdminDataGridHeaderSection.clearFilters}}" dependentSelector="{{AdminDataGridHeaderSection.clearFilters}}" visible="true" stepKey="clearExistingFiltersBeforeDelete"/> <click selector="{{AdminDataGridHeaderSection.filters}}" stepKey="openCmsBlockFilters"/> - <fillField selector="{{AdminDataGridHeaderSection.filterFieldInput('identifier')}}" userInput="{{identifier}}" stepKey="fillFilter"/> + <fillField selector="{{AdminDataGridHeaderSection.filterFieldInput('identifier')}}" userInput="{{cmsBlockIdentifier}}" stepKey="fillFilter"/> <click selector="{{AdminDataGridHeaderSection.applyFilters}}" stepKey="clickApplyFilters"/> - <click selector="{{CmsPagesPageActionsSection.select(identifier)}}" stepKey="clickOnSelect"/> - <click selector="{{CmsPagesPageActionsSection.delete(identifier)}}" stepKey="clickOnDelete"/> + <click selector="{{CmsPagesPageActionsSection.select(cmsBlockIdentifier)}}" stepKey="clickOnSelect"/> + <click selector="{{CmsPagesPageActionsSection.delete(cmsBlockIdentifier)}}" stepKey="clickOnDelete"/> <waitForElementVisible selector="{{AdminConfirmationModalSection.message}}" stepKey="waitForConfirmModal"/> <click selector="{{AdminConfirmationModalSection.ok}}" stepKey="confirm"/> <see selector="{{AdminMessagesSection.success}}" userInput="You deleted the block." stepKey="verifyBlockIsDeleted"/> From 8787ab7561d2c04179c6326d6c7a8e8b28e423c5 Mon Sep 17 00:00:00 2001 From: Myroslav Dobra <dmaraptor@gmail.com> Date: Wed, 13 Feb 2019 12:25:27 +0200 Subject: [PATCH 089/315] MAGETWO-73534: [GITHUB] Url rewrite for product is broken after using massaction #8227 --- .../Test/Mftf/Test/AdminUrlForProductRewrittenCorrectlyTest.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/app/code/Magento/CatalogUrlRewrite/Test/Mftf/Test/AdminUrlForProductRewrittenCorrectlyTest.xml b/app/code/Magento/CatalogUrlRewrite/Test/Mftf/Test/AdminUrlForProductRewrittenCorrectlyTest.xml index 558e19885e112..d52395342c092 100644 --- a/app/code/Magento/CatalogUrlRewrite/Test/Mftf/Test/AdminUrlForProductRewrittenCorrectlyTest.xml +++ b/app/code/Magento/CatalogUrlRewrite/Test/Mftf/Test/AdminUrlForProductRewrittenCorrectlyTest.xml @@ -34,7 +34,6 @@ <actionGroup ref="logout" stepKey="logout"/> </after> - <!--Open Created product--> <amOnPage url="{{AdminProductEditPage.url($$createProduct.id$$)}}" stepKey="openProductEditPage"/> <!--Switch to Default Store view--> From daa8996bbda2e7ca938a7e3a3e8afc40502cd98f Mon Sep 17 00:00:00 2001 From: gwharton <30697781+gwharton@users.noreply.github.com> Date: Wed, 13 Feb 2019 13:42:27 +0000 Subject: [PATCH 090/315] Changed setFromByStore to setFromByScope in deprecation comments. --- .../Magento/Framework/Mail/Template/TransportBuilderByStore.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Mail/Template/TransportBuilderByStore.php b/lib/internal/Magento/Framework/Mail/Template/TransportBuilderByStore.php index baac867fd6ce8..bdb7619d7fe07 100644 --- a/lib/internal/Magento/Framework/Mail/Template/TransportBuilderByStore.php +++ b/lib/internal/Magento/Framework/Mail/Template/TransportBuilderByStore.php @@ -13,7 +13,7 @@ * * @deprecated The ability to set From address based on store is now available * in the \Magento\Framework\Mail\Template\TransportBuilder class - * @see \Magento\Framework\Mail\Template\TransportBuilder::setFromByStore + * @see \Magento\Framework\Mail\Template\TransportBuilder::setFromByScope */ class TransportBuilderByStore { From 85cdc9d41bb027aca3ce5b4412f67e8af634c141 Mon Sep 17 00:00:00 2001 From: milindsingh <milind7@live.com> Date: Sat, 29 Dec 2018 00:08:12 +0530 Subject: [PATCH 091/315] Issue fix #20010 Wrong price amount in opengraph Issue fix #20010 Wrong price amount in opengraph --- .../frontend/templates/product/view/opengraph/general.phtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/view/frontend/templates/product/view/opengraph/general.phtml b/app/code/Magento/Catalog/view/frontend/templates/product/view/opengraph/general.phtml index a2b91a5eeb99f..40f86c7e68d6c 100644 --- a/app/code/Magento/Catalog/view/frontend/templates/product/view/opengraph/general.phtml +++ b/app/code/Magento/Catalog/view/frontend/templates/product/view/opengraph/general.phtml @@ -14,7 +14,7 @@ <meta property="og:image" content="<?= $block->escapeUrl($block->getImage($block->getProduct(), 'product_base_image')->getImageUrl()) ?>" /> <meta property="og:description" content="<?= $block->escapeHtmlAttr($block->stripTags($block->getProduct()->getShortDescription())) ?>" /> <meta property="og:url" content="<?= $block->escapeUrl($block->getProduct()->getProductUrl()) ?>" /> -<?php if ($priceAmount = $block->getProduct()->getFinalPrice()):?> +<?php if ($priceAmount = $block->getProduct()->getPriceInfo()->getPrice(\Magento\Catalog\Pricing\Price\FinalPrice::PRICE_CODE)->getAmount()):?> <meta property="product:price:amount" content="<?= /* @escapeNotVerified */ $priceAmount ?>"/> <?= $block->getChildHtml('meta.currency') ?> <?php endif;?> From f40d13914fae5a44b056d2cd1ef8dd7964020b78 Mon Sep 17 00:00:00 2001 From: Patrick McLain <pat@pmclain.com> Date: Fri, 8 Feb 2019 18:17:34 -0500 Subject: [PATCH 092/315] Add alt text to saved payment method for accessibility Fixes #21089 --- .../Magento/Payment/Model/CcConfigProvider.php | 5 +++-- .../Test/Unit/Model/CcConfigProviderTest.php | 14 +++++++++++--- .../view/frontend/web/template/payment/form.html | 3 ++- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/Payment/Model/CcConfigProvider.php b/app/code/Magento/Payment/Model/CcConfigProvider.php index 15bdd0072a51a..ba3721e6cfc2b 100644 --- a/app/code/Magento/Payment/Model/CcConfigProvider.php +++ b/app/code/Magento/Payment/Model/CcConfigProvider.php @@ -69,7 +69,7 @@ public function getIcons() } $types = $this->ccConfig->getCcAvailableTypes(); - foreach (array_keys($types) as $code) { + foreach ($types as $code => $label) { if (!array_key_exists($code, $this->icons)) { $asset = $this->ccConfig->createAsset('Magento_Payment::images/cc/' . strtolower($code) . '.png'); $placeholder = $this->assetSource->findSource($asset); @@ -78,7 +78,8 @@ public function getIcons() $this->icons[$code] = [ 'url' => $asset->getUrl(), 'width' => $width, - 'height' => $height + 'height' => $height, + 'title' => __($label), ]; } } diff --git a/app/code/Magento/Payment/Test/Unit/Model/CcConfigProviderTest.php b/app/code/Magento/Payment/Test/Unit/Model/CcConfigProviderTest.php index a8856166995fc..ff6aea44645cf 100644 --- a/app/code/Magento/Payment/Test/Unit/Model/CcConfigProviderTest.php +++ b/app/code/Magento/Payment/Test/Unit/Model/CcConfigProviderTest.php @@ -42,12 +42,14 @@ public function testGetConfig() 'vi' => [ 'url' => 'http://cc.card/vi.png', 'width' => getimagesize($imagesDirectoryPath . 'vi.png')[0], - 'height' => getimagesize($imagesDirectoryPath . 'vi.png')[1] + 'height' => getimagesize($imagesDirectoryPath . 'vi.png')[1], + 'title' => __('Visa'), ], 'ae' => [ 'url' => 'http://cc.card/ae.png', 'width' => getimagesize($imagesDirectoryPath . 'ae.png')[0], - 'height' => getimagesize($imagesDirectoryPath . 'ae.png')[1] + 'height' => getimagesize($imagesDirectoryPath . 'ae.png')[1], + 'title' => __('American Express'), ] ] ] @@ -56,11 +58,13 @@ public function testGetConfig() $ccAvailableTypesMock = [ 'vi' => [ + 'title' => 'Visa', 'fileId' => 'Magento_Payment::images/cc/vi.png', 'path' => $imagesDirectoryPath . 'vi.png', 'url' => 'http://cc.card/vi.png' ], 'ae' => [ + 'title' => 'American Express', 'fileId' => 'Magento_Payment::images/cc/ae.png', 'path' => $imagesDirectoryPath . 'ae.png', 'url' => 'http://cc.card/ae.png' @@ -68,7 +72,11 @@ public function testGetConfig() ]; $assetMock = $this->createMock(\Magento\Framework\View\Asset\File::class); - $this->ccConfigMock->expects($this->once())->method('getCcAvailableTypes')->willReturn($ccAvailableTypesMock); + $this->ccConfigMock->expects($this->once())->method('getCcAvailableTypes') + ->willReturn(array_combine( + array_keys($ccAvailableTypesMock), + array_column($ccAvailableTypesMock, 'title') + )); $this->ccConfigMock->expects($this->atLeastOnce()) ->method('createAsset') diff --git a/app/code/Magento/Vault/view/frontend/web/template/payment/form.html b/app/code/Magento/Vault/view/frontend/web/template/payment/form.html index 0ef330cd3014e..49cc488060120 100644 --- a/app/code/Magento/Vault/view/frontend/web/template/payment/form.html +++ b/app/code/Magento/Vault/view/frontend/web/template/payment/form.html @@ -19,7 +19,8 @@ <img data-bind="attr: { 'src': getIcons(getCardType()).url, 'width': getIcons(getCardType()).width, - 'height': getIcons(getCardType()).height + 'height': getIcons(getCardType()).height, + 'alt': getIcons(getCardType()).title }" class="payment-icon"> <span translate="'ending'"></span> <span text="getMaskedCard()"></span> From 4a0dc53116e94291e4a466241853383ea1eb9b77 Mon Sep 17 00:00:00 2001 From: nmalevanec <mikola.malevanec@transoftgroup.com> Date: Tue, 12 Feb 2019 10:44:55 +0200 Subject: [PATCH 093/315] Fix static test. --- app/code/Magento/Payment/Model/CcConfigProvider.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Payment/Model/CcConfigProvider.php b/app/code/Magento/Payment/Model/CcConfigProvider.php index ba3721e6cfc2b..497ce93c30c71 100644 --- a/app/code/Magento/Payment/Model/CcConfigProvider.php +++ b/app/code/Magento/Payment/Model/CcConfigProvider.php @@ -44,7 +44,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function getConfig() { From 79d5de06262da335e0762ad6f0e47e85c0199fe1 Mon Sep 17 00:00:00 2001 From: Sunil Patel <patelsunil42@gmail.com> Date: Wed, 6 Feb 2019 12:08:57 +0530 Subject: [PATCH 094/315] disable add to cart until page load --- .../view/frontend/templates/product/view/addtocart.phtml | 2 +- .../Magento/Catalog/view/frontend/web/js/validate-product.js | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Catalog/view/frontend/templates/product/view/addtocart.phtml b/app/code/Magento/Catalog/view/frontend/templates/product/view/addtocart.phtml index 9c18a18ff5837..fc578c7652419 100644 --- a/app/code/Magento/Catalog/view/frontend/templates/product/view/addtocart.phtml +++ b/app/code/Magento/Catalog/view/frontend/templates/product/view/addtocart.phtml @@ -32,7 +32,7 @@ <button type="submit" title="<?= /* @escapeNotVerified */ $buttonTitle ?>" class="action primary tocart" - id="product-addtocart-button"> + id="product-addtocart-button" disabled> <span><?= /* @escapeNotVerified */ $buttonTitle ?></span> </button> <?= $block->getChildHtml('', true) ?> diff --git a/app/code/Magento/Catalog/view/frontend/web/js/validate-product.js b/app/code/Magento/Catalog/view/frontend/web/js/validate-product.js index c0637cb672dc6..ab848aa442f81 100644 --- a/app/code/Magento/Catalog/view/frontend/web/js/validate-product.js +++ b/app/code/Magento/Catalog/view/frontend/web/js/validate-product.js @@ -13,7 +13,8 @@ define([ $.widget('mage.productValidate', { options: { bindSubmit: false, - radioCheckboxClosest: '.nested' + radioCheckboxClosest: '.nested', + addToCartButtonSelector: '.action.tocart' }, /** @@ -41,6 +42,7 @@ define([ return false; } }); + $(this.options.addToCartButtonSelector).attr('disabled',false); } }); From 410dc5101e1e6e78f9976af13f07966a1bbc8d1f Mon Sep 17 00:00:00 2001 From: Pavel Bystritsky <p.bystritsky@yandex.ru> Date: Mon, 11 Feb 2019 15:14:09 +0200 Subject: [PATCH 095/315] ENGCOM-4178: Static test fix. --- .../Magento/Catalog/view/frontend/web/js/validate-product.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/view/frontend/web/js/validate-product.js b/app/code/Magento/Catalog/view/frontend/web/js/validate-product.js index ab848aa442f81..755e777a01f77 100644 --- a/app/code/Magento/Catalog/view/frontend/web/js/validate-product.js +++ b/app/code/Magento/Catalog/view/frontend/web/js/validate-product.js @@ -42,7 +42,7 @@ define([ return false; } }); - $(this.options.addToCartButtonSelector).attr('disabled',false); + $(this.options.addToCartButtonSelector).attr('disabled', false); } }); From 474cc79c77289c596466f8ab95422b94edc61786 Mon Sep 17 00:00:00 2001 From: Govind Sharma <govindpokhrelsharma@cedcoss.com> Date: Tue, 8 Jan 2019 16:07:42 +0530 Subject: [PATCH 096/315] Fixed issue #19891 Fixed issue #19891 added check of attribute type_id --- .../Catalog/Controller/Adminhtml/Product/Attribute/Validate.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Validate.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Validate.php index 3a81b4633b2ff..b4bb7fd05f740 100644 --- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Validate.php +++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Validate.php @@ -100,7 +100,7 @@ public function execute() $attributeCode ); - if ($attribute->getId() && !$attributeId || $attributeCode === 'product_type') { + if ($attribute->getId() && !$attributeId || $attributeCode === 'product_type' || $attributeCode === 'type_id') { $message = strlen($this->getRequest()->getParam('attribute_code')) ? __('An attribute with this code already exists.') : __('An attribute with the same code (%1) already exists.', $attributeCode); From 180db3301dedcc50a1098c3b97ca715dd6f978e1 Mon Sep 17 00:00:00 2001 From: amol 2jcommerce <amol@2jcommerce.in> Date: Thu, 14 Feb 2019 10:51:02 +0530 Subject: [PATCH 097/315] focus-not-proper-on-configurable-product-swatches-2.2 --- .../Magento/Swatches/view/frontend/web/css/swatches.css | 8 ++++++++ .../luma/Magento_Catalog/web/css/source/_module.less | 5 +++++ 2 files changed, 13 insertions(+) diff --git a/app/code/Magento/Swatches/view/frontend/web/css/swatches.css b/app/code/Magento/Swatches/view/frontend/web/css/swatches.css index 67b9fffcf1282..fb1dcff2ecfb0 100644 --- a/app/code/Magento/Swatches/view/frontend/web/css/swatches.css +++ b/app/code/Magento/Swatches/view/frontend/web/css/swatches.css @@ -31,6 +31,10 @@ margin-top: 10px; } +.swatch-attribute-options:focus { + box-shadow: none; +} + .swatch-option { /*width: 30px;*/ padding: 1px 2px; @@ -47,6 +51,10 @@ text-overflow: ellipsis; } +.swatch-option:focus { + box-shadow: 0 0 3px 1px #68a8e0; +} + .swatch-option.text { background: #F0F0F0; color: #686868; diff --git a/app/design/frontend/Magento/luma/Magento_Catalog/web/css/source/_module.less b/app/design/frontend/Magento/luma/Magento_Catalog/web/css/source/_module.less index 228c6947c938b..365b7736b7e14 100644 --- a/app/design/frontend/Magento/luma/Magento_Catalog/web/css/source/_module.less +++ b/app/design/frontend/Magento/luma/Magento_Catalog/web/css/source/_module.less @@ -294,6 +294,11 @@ } .product-options-wrapper { + .fieldset { + &:focus { + box-shadow: none; + } + } .fieldset-product-options-inner { .legend { .lib-css(font-weight, @font-weight__semibold); From b4568442e60ba5ecbb5d325e5d72d55d8e4f3e95 Mon Sep 17 00:00:00 2001 From: OlgaVasyltsun <olga.vasyltsun@gmail.com> Date: Thu, 14 Feb 2019 08:01:03 +0200 Subject: [PATCH 098/315] MAGETWO-95762: Resource model changes --- .../Model/ResourceModel/AbstractResource.php | 12 +++++-- .../Catalog/Model/ResourceModel/Product.php | 23 ++++++++---- .../Mftf/Section/AdminProductFormSection.xml | 1 + .../Eav/Model/Entity/AbstractEntity.php | 28 ++++++++++----- .../Attribute/UniqueValidationInterface.php | 35 +++++++++++++++++++ .../Entity/Attribute/UniqueValidator.php | 33 +++++++++++++++++ app/code/Magento/Eav/etc/di.xml | 1 + 7 files changed, 115 insertions(+), 18 deletions(-) create mode 100644 app/code/Magento/Eav/Model/Entity/Attribute/UniqueValidationInterface.php create mode 100644 app/code/Magento/Eav/Model/Entity/Attribute/UniqueValidator.php diff --git a/app/code/Magento/Catalog/Model/ResourceModel/AbstractResource.php b/app/code/Magento/Catalog/Model/ResourceModel/AbstractResource.php index 12009e62fd27e..7f50c7edbb049 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/AbstractResource.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/AbstractResource.php @@ -9,6 +9,10 @@ namespace Magento\Catalog\Model\ResourceModel; use Magento\Eav\Model\Entity\Attribute\AbstractAttribute; +use Magento\Eav\Model\Entity\Attribute\Backend\AbstractBackend; +use Magento\Eav\Model\Entity\Attribute\Frontend\AbstractFrontend; +use Magento\Eav\Model\Entity\Attribute\Source\AbstractSource; +use Magento\Eav\Model\Entity\Attribute\UniqueValidationInterface; /** * Catalog entity abstract model @@ -39,16 +43,18 @@ abstract class AbstractResource extends \Magento\Eav\Model\Entity\AbstractEntity * @param \Magento\Store\Model\StoreManagerInterface $storeManager * @param \Magento\Catalog\Model\Factory $modelFactory * @param array $data + * @param UniqueValidationInterface|null $uniqueValidator */ public function __construct( \Magento\Eav\Model\Entity\Context $context, \Magento\Store\Model\StoreManagerInterface $storeManager, \Magento\Catalog\Model\Factory $modelFactory, - $data = [] + $data = [], + UniqueValidationInterface $uniqueValidator = null ) { $this->_storeManager = $storeManager; $this->_modelFactory = $modelFactory; - parent::__construct($context, $data); + parent::__construct($context, $data, $uniqueValidator); } /** @@ -88,7 +94,7 @@ protected function _isApplicableAttribute($object, $attribute) /** * Check whether attribute instance (attribute, backend, frontend or source) has method and applicable * - * @param AbstractAttribute|\Magento\Eav\Model\Entity\Attribute\Backend\AbstractBackend|\Magento\Eav\Model\Entity\Attribute\Frontend\AbstractFrontend|\Magento\Eav\Model\Entity\Attribute\Source\AbstractSource $instance + * @param AbstractAttribute|AbstractBackend|AbstractFrontend|AbstractSource $instance * @param string $method * @param array $args array of arguments * @return boolean diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product.php b/app/code/Magento/Catalog/Model/ResourceModel/Product.php index b4b78996f762f..6998431d19a8f 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Product.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Product.php @@ -8,6 +8,7 @@ use Magento\Catalog\Model\ResourceModel\Product\Website\Link as ProductWebsiteLink; use Magento\Framework\App\ObjectManager; use Magento\Catalog\Model\Indexer\Category\Product\TableMaintainer; +use Magento\Eav\Model\Entity\Attribute\UniqueValidationInterface; /** * Product entity resource model @@ -101,6 +102,7 @@ class Product extends AbstractResource * @param \Magento\Catalog\Model\Product\Attribute\DefaultAttributes $defaultAttributes * @param array $data * @param TableMaintainer|null $tableMaintainer + * @param UniqueValidationInterface|null $uniqueValidator * * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ @@ -115,7 +117,8 @@ public function __construct( \Magento\Eav\Model\Entity\TypeFactory $typeFactory, \Magento\Catalog\Model\Product\Attribute\DefaultAttributes $defaultAttributes, $data = [], - TableMaintainer $tableMaintainer = null + TableMaintainer $tableMaintainer = null, + UniqueValidationInterface $uniqueValidator = null ) { $this->_categoryCollectionFactory = $categoryCollectionFactory; $this->_catalogCategory = $catalogCategory; @@ -127,7 +130,8 @@ public function __construct( $context, $storeManager, $modelFactory, - $data + $data, + $uniqueValidator ); $this->connectionName = 'catalog'; $this->tableMaintainer = $tableMaintainer ?: ObjectManager::getInstance()->get(TableMaintainer::class); @@ -289,7 +293,7 @@ protected function _afterSave(\Magento\Framework\DataObject $product) } /** - * {@inheritdoc} + * @inheritdoc */ public function delete($object) { @@ -575,7 +579,7 @@ public function countAll() } /** - * {@inheritdoc} + * @inheritdoc */ public function validate($object) { @@ -615,7 +619,7 @@ public function load($object, $entityId, $attributes = []) } /** - * {@inheritdoc} + * @inheritdoc * @SuppressWarnings(PHPMD.UnusedLocalVariable) * @since 101.0.0 */ @@ -657,6 +661,8 @@ public function save(\Magento\Framework\Model\AbstractModel $object) } /** + * Retrieve entity manager object + * * @return \Magento\Framework\EntityManager\EntityManager */ private function getEntityManager() @@ -669,6 +675,8 @@ private function getEntityManager() } /** + * Retrieve ProductWebsiteLink object + * * @deprecated 101.1.0 * @return ProductWebsiteLink */ @@ -678,6 +686,8 @@ private function getProductWebsiteLink() } /** + * Retrieve CategoryLink object + * * @deprecated 101.1.0 * @return \Magento\Catalog\Model\ResourceModel\Product\CategoryLink */ @@ -692,9 +702,10 @@ private function getProductCategoryLink() /** * Extends parent method to be appropriate for product. + * * Store id is required to correctly identify attribute value we are working with. * - * {@inheritdoc} + * @inheritdoc * @since 101.1.0 */ protected function getAttributeRow($entity, $object, $attribute) diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductFormSection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductFormSection.xml index 7a97a75556769..ed5a0480325dd 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductFormSection.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductFormSection.xml @@ -40,6 +40,7 @@ <element name="attributeSetDropDown" type="select" selector="div[data-index='attribute_set_id'] .action-select.admin__action-multiselect"/> <element name="requiredNameIndicator" type="text" selector=" return window.getComputedStyle(document.querySelector('._required[data-index=name]>.admin__field-label span'), ':after').getPropertyValue('content');"/> <element name="requiredSkuIndicator" type="text" selector=" return window.getComputedStyle(document.querySelector('._required[data-index=sku]>.admin__field-label span'), ':after').getPropertyValue('content');"/> + <element name="customSelectField" type="select" selector="select[name='product[{{attributeCode}}]']" parameterized="true"/> </section> <section name="ProductInWebsitesSection"> <element name="sectionHeader" type="button" selector="div[data-index='websites']" timeout="30"/> diff --git a/app/code/Magento/Eav/Model/Entity/AbstractEntity.php b/app/code/Magento/Eav/Model/Entity/AbstractEntity.php index 40b884aec529f..7f01cf268d06b 100644 --- a/app/code/Magento/Eav/Model/Entity/AbstractEntity.php +++ b/app/code/Magento/Eav/Model/Entity/AbstractEntity.php @@ -12,6 +12,7 @@ use Magento\Eav\Model\Entity\Attribute\Backend\AbstractBackend; use Magento\Eav\Model\Entity\Attribute\Frontend\AbstractFrontend; use Magento\Eav\Model\Entity\Attribute\Source\AbstractSource; +use Magento\Eav\Model\Entity\Attribute\UniqueValidationInterface; use Magento\Framework\App\Config\Element; use Magento\Framework\DataObject; use Magento\Framework\DB\Adapter\DuplicateException; @@ -217,12 +218,21 @@ abstract class AbstractEntity extends AbstractResource implements EntityInterfac */ protected $objectRelationProcessor; + /** + * @var UniqueValidationInterface + */ + private $uniqueValidator; + /** * @param Context $context * @param array $data + * @param UniqueValidationInterface|null $uniqueValidator */ - public function __construct(Context $context, $data = []) - { + public function __construct( + Context $context, + $data = [], + UniqueValidationInterface $uniqueValidator = null + ) { $this->_eavConfig = $context->getEavConfig(); $this->_resource = $context->getResource(); $this->_attrSetEntity = $context->getAttributeSetEntity(); @@ -231,6 +241,8 @@ public function __construct(Context $context, $data = []) $this->_universalFactory = $context->getUniversalFactory(); $this->transactionManager = $context->getTransactionManager(); $this->objectRelationProcessor = $context->getObjectRelationProcessor(); + $this->uniqueValidator = $uniqueValidator ?: + ObjectManager::getInstance()->get(UniqueValidationInterface::class); parent::__construct(); $properties = get_object_vars($this); foreach ($data as $key => $value) { @@ -499,6 +511,7 @@ public function addAttributeByScope(AbstractAttribute $attribute, $entity = null /** * Get attributes by scope * + * @param string $suffix * @return array */ private function getAttributesByScope($suffix) @@ -969,12 +982,8 @@ public function checkAttributeUniqueValue(AbstractAttribute $attribute, $object) $data = $connection->fetchCol($select, $bind); - $objectId = $object->getData($entityIdField); - if ($objectId) { - if (isset($data[0])) { - return $data[0] == $objectId; - } - return true; + if ($object->getData($entityIdField)) { + return $this->uniqueValidator->validate($attribute, $object, $this, $entityIdField, $data); } return !count($data); @@ -1984,7 +1993,8 @@ public function afterDelete(DataObject $object) /** * Load attributes for object - * if the object will not pass all attributes for this entity type will be loaded + * + * If the object will not pass all attributes for this entity type will be loaded * * @param array $attributes * @param AbstractEntity|null $object diff --git a/app/code/Magento/Eav/Model/Entity/Attribute/UniqueValidationInterface.php b/app/code/Magento/Eav/Model/Entity/Attribute/UniqueValidationInterface.php new file mode 100644 index 0000000000000..f4912f25ae1de --- /dev/null +++ b/app/code/Magento/Eav/Model/Entity/Attribute/UniqueValidationInterface.php @@ -0,0 +1,35 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Eav\Model\Entity\Attribute; + +use Magento\Framework\DataObject; +use Magento\Eav\Model\Entity\AbstractEntity; + +/** + * Interface for unique attribute validator. + */ +interface UniqueValidationInterface +{ + /** + * Validate if attribute value is unique. + * + * @param AbstractAttribute $attribute + * @param DataObject $object + * @param AbstractEntity $entity + * @param string $entityLinkField + * @param array $entityIds + * @return bool + */ + public function validate( + AbstractAttribute $attribute, + DataObject $object, + AbstractEntity $entity, + string $entityLinkField, + array $entityIds + ); +} diff --git a/app/code/Magento/Eav/Model/Entity/Attribute/UniqueValidator.php b/app/code/Magento/Eav/Model/Entity/Attribute/UniqueValidator.php new file mode 100644 index 0000000000000..da0d0e07f303a --- /dev/null +++ b/app/code/Magento/Eav/Model/Entity/Attribute/UniqueValidator.php @@ -0,0 +1,33 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Eav\Model\Entity\Attribute; + +use Magento\Framework\DataObject; +use Magento\Eav\Model\Entity\AbstractEntity; + +/** + * Class for validate unique attribute value. + */ +class UniqueValidator implements UniqueValidationInterface +{ + /** + * @inheritdoc + */ + public function validate( + AbstractAttribute $attribute, + DataObject $object, + AbstractEntity $entity, + string $entityLinkField, + array $entityIds + ) { + if (isset($entityIds[0])) { + return $entityIds[0] == $object->getData($entityLinkField); + } + return true; + } +} diff --git a/app/code/Magento/Eav/etc/di.xml b/app/code/Magento/Eav/etc/di.xml index c8afd10aa3eee..92c1ef11b9c1f 100644 --- a/app/code/Magento/Eav/etc/di.xml +++ b/app/code/Magento/Eav/etc/di.xml @@ -8,6 +8,7 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> <preference for="Magento\Eav\Model\Entity\Setup\PropertyMapperInterface" type="Magento\Eav\Model\Entity\Setup\PropertyMapper\Composite" /> <preference for="Magento\Eav\Model\Entity\AttributeLoaderInterface" type="Magento\Eav\Model\Entity\AttributeLoader" /> + <preference for="Magento\Eav\Model\Entity\Attribute\UniqueValidationInterface" type="Magento\Eav\Model\Entity\Attribute\UniqueValidator" /> <preference for="Magento\Eav\Api\Data\AttributeInterface" type="Magento\Eav\Model\Entity\Attribute" /> <preference for="Magento\Eav\Api\AttributeRepositoryInterface" type="Magento\Eav\Model\AttributeRepository" /> <preference for="Magento\Eav\Api\Data\AttributeGroupInterface" type="Magento\Eav\Model\Entity\Attribute\Group" /> From 67ef38c5e05a9d0b49996abdf98da7df1abea1ad Mon Sep 17 00:00:00 2001 From: eduard13 <e.chitoraga@atwix.com> Date: Sat, 9 Feb 2019 16:25:39 +0200 Subject: [PATCH 099/315] Improves the UX by moving the customer to the Dashboard's Recent Orders --- .../Magento/Sales/view/frontend/templates/reorder/sidebar.phtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Sales/view/frontend/templates/reorder/sidebar.phtml b/app/code/Magento/Sales/view/frontend/templates/reorder/sidebar.phtml index 9b3633fde60b4..a2ab3d02b13ea 100644 --- a/app/code/Magento/Sales/view/frontend/templates/reorder/sidebar.phtml +++ b/app/code/Magento/Sales/view/frontend/templates/reorder/sidebar.phtml @@ -57,7 +57,7 @@ </button> </div> <div class="secondary"> - <a class="action view" href="<?= /* @escapeNotVerified */ $block->getUrl('customer/account') ?>"> + <a class="action view" href="<?= /* @escapeNotVerified */ $block->getUrl('customer/account') ?>#my-orders-table"> <span><?= /* @escapeNotVerified */ __('View All') ?></span> </a> </div> From c3f6d09a9a0afb5d0a4e4bac5fc9e6e292ff7bbf Mon Sep 17 00:00:00 2001 From: Viktor Sevch <svitja@ukr.net> Date: Thu, 14 Feb 2019 13:12:36 +0200 Subject: [PATCH 100/315] MAGETWO-95422: Layered Navigation shows options not available in Catalog --- .../AdminProductAttributeActionGroup.xml | 34 +++++++++++++++++ .../Test/Mftf/Data/FrontendLabelData.xml | 1 + .../Mftf/Section/AdminProductFormSection.xml | 1 + ...inCreateConfigurableProductActionGroup.xml | 37 +++++++++++++++++++ 4 files changed, 73 insertions(+) diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductAttributeActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductAttributeActionGroup.xml index 1c6f115c2cfce..e82633f1321f0 100644 --- a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductAttributeActionGroup.xml +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductAttributeActionGroup.xml @@ -74,4 +74,38 @@ <click selector="{{AdminDataGridTableSection.row('1')}}" stepKey="clickOnAttributeRow"/> <waitForPageLoad stepKey="waitForAttributePageLoad" /> </actionGroup> + <actionGroup name="StartCreateProductAttribute"> + <arguments> + <argument name="attributeCode" type="string"/> + <argument name="attributeType" type="string" defaultValue="select"/> + </arguments> + <amOnPage url="{{ProductAttributePage.url}}" stepKey="goToNewProductAttributePage"/> + <fillField selector="{{AttributePropertiesSection.defaultLabel}}" userInput="{{attributeCode}}" stepKey="fillDefaultLabel"/> + <selectOption selector="{{AttributePropertiesSection.inputType}}" userInput="{{attributeType}}" stepKey="selectInputType"/> + <waitForElementVisible selector="{{AdminNewAttributePanelSection.addOption}}" stepKey="waitForElementVisible"/> + </actionGroup> + <actionGroup name="AddOptionToProductAttribute"> + <arguments> + <argument name="optionName" type="string"/> + <argument name="optionNumber" type="string"/> + </arguments> + <click selector="{{AdminNewAttributePanelSection.addOption}}" stepKey="clickAddOption"/> + <waitForElementVisible selector="{{AdminNewAttributePanelSection.optionAdminValue('optionNumber')}}" time="30" stepKey="waitForOptionRow"/> + <fillField selector="{{AdminNewAttributePanelSection.optionAdminValue('optionNumber')}}" userInput="{{optionName}}" stepKey="fillAdminLabel"/> + </actionGroup> + <actionGroup name="SetScopeToProductAttribute"> + <arguments> + <argument name="scope" type="string" defaultValue="1"/> + </arguments> + <click selector="{{AttributePropertiesSection.AdvancedProperties}}" stepKey="expandAdvancedProperties"/> + <selectOption selector="{{AttributePropertiesSection.scope}}" userInput="{{scope}}" stepKey="selectGlobalScope"/> + </actionGroup> + <actionGroup name="SetUseInLayeredNavigationToProductAttribute"> + <arguments> + <argument name="useInLayeredNavigation" type="string" defaultValue="1"/> + </arguments> + <scrollToTopOfPage stepKey="scrollToTop"/> + <click selector="{{StorefrontPropertiesSection.storefrontPropertiesTab}}" stepKey="goToStorefrontProperties"/> + <selectOption selector="{{AttributePropertiesSection.useInLayeredNavigation}}" userInput="{{useInLayeredNavigation}}" stepKey="selectUseInLayeredNavigation"/> + </actionGroup> </actionGroups> diff --git a/app/code/Magento/Catalog/Test/Mftf/Data/FrontendLabelData.xml b/app/code/Magento/Catalog/Test/Mftf/Data/FrontendLabelData.xml index 7b01b6b4e5189..ec8a355523d63 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Data/FrontendLabelData.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Data/FrontendLabelData.xml @@ -16,6 +16,7 @@ <entity name="ProductAttributeFrontendLabelThree" type="FrontendLabel"> <data key="store_id">0</data> <data key="label" unique="suffix">attributeThree</data> + <data key="default_label" unique="suffix">attributeThree</data> </entity> <entity name="ColorAttributeFrontandLabel" type="FrontendLabel"> <data key="store_id">0</data> diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductFormSection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductFormSection.xml index 7a97a75556769..b01daff9b4f0f 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductFormSection.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductFormSection.xml @@ -180,6 +180,7 @@ <element name="applySinglePriceToAllSkus" type="radio" selector=".admin__field-label[for='apply-single-price-radio']"/> <element name="singlePrice" type="input" selector="#apply-single-price-input"/> <element name="attributeByName" type="input" selector="//label[text()='{{var}}']/preceding-sibling::input" parameterized="true"/> + <element name="checkboxByName" type="input" selector="//div[text()='{{var}}']//ancestor::tr//input" parameterized="true"/> </section> <section name="AdminNewAttributePanel"> <element name="saveAttribute" type="button" selector="#save" timeout="30"/> diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/ActionGroup/AdminCreateConfigurableProductActionGroup.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/ActionGroup/AdminCreateConfigurableProductActionGroup.xml index e16ee43978a1e..6c47a24315c9a 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Mftf/ActionGroup/AdminCreateConfigurableProductActionGroup.xml +++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/ActionGroup/AdminCreateConfigurableProductActionGroup.xml @@ -90,4 +90,41 @@ <waitForElementVisible selector="{{AdminCreateProductConfigurationsPanel.next}}" stepKey="waitForNextPageOpened2"/> <click selector="{{AdminCreateProductConfigurationsPanel.next}}" stepKey="generateProducts"/> </actionGroup> + + <actionGroup name="AdminCreateConfigurableProductTwoAttributesWithOptionsActionGroup" extends="AdminCreateConfigurableProductActionGroup"> + <arguments> + <argument name="attributeOption" type="string"/> + <argument name="attributeOption1" type="string"/> + <argument name="configurableAttributeCode1" type="string"/> + <argument name="attribute1Option" type="string"/> + <argument name="attribute1Option1" type="string"/> + <argument name="attribute1Option2" type="string"/> + </arguments> + + <remove keyForRemoval="startEditAttrSet"/> + <remove keyForRemoval="searchForAttrSet"/> + <remove keyForRemoval="waitForLoad"/> + <remove keyForRemoval="selectAttrSetProd"/> + <remove keyForRemoval="saveEditedProductForProduct"/> + <remove keyForRemoval="clickClearFilters"/> + <remove keyForRemoval="clickFiltersExpand"/> + <remove keyForRemoval="fillFilter"/> + <remove keyForRemoval="clickSearch"/> + <remove keyForRemoval="clickAttributeColorCheckbox"/> + <remove keyForRemoval="clickOnSelectAllSecond"/> + + <fillField userInput="{{configurationsPrice}}" selector="{{AdminProductFormSection.productPrice}}" stepKey="fillPrice"/> + <fillField userInput="{{configurationsQty}}" selector="{{AdminProductFormSection.productQuantity}}" stepKey="fillQuantity"/> + + <!--Select attributes --> + <click selector="{{AdminCreateProductConfigurationsPanel.checkboxByName(configurableAttributeCode)}}" after="openConfigurationPanel" stepKey="selectAttribute"/> + <click selector="{{AdminCreateProductConfigurationsPanel.checkboxByName(configurableAttributeCode1)}}" after="selectAttribute" stepKey="selectAttribute1"/> + + <!--Select options--> + <click selector="{{AdminCreateProductConfigurationsPanel.attributeByName(attributeOption)}}" after="clickNextButton" stepKey="selectAttributeOption"/> + <click selector="{{AdminCreateProductConfigurationsPanel.attributeByName(attributeOption1)}}" after="selectAttributeOption" stepKey="selectAttributeOption1"/> + <click selector="{{AdminCreateProductConfigurationsPanel.attributeByName(attribute1Option)}}" after="selectAttributeOption1" stepKey="selectAttribute1Option"/> + <click selector="{{AdminCreateProductConfigurationsPanel.attributeByName(attribute1Option1)}}" after="selectAttribute1Option" stepKey="selectAttribute1Option1"/> + <click selector="{{AdminCreateProductConfigurationsPanel.attributeByName(attribute1Option2)}}" after="selectAttribute1Option1" stepKey="selectAttribute1Option2"/> + </actionGroup> </actionGroups> From b94cbd86babdc607d8f59cd018fbdb31a6455b28 Mon Sep 17 00:00:00 2001 From: Mastiuhin Olexandr <mastiuhin.olexandr@transoftgroup.com> Date: Thu, 14 Feb 2019 14:24:15 +0200 Subject: [PATCH 101/315] MAGETWO-90953: Incorrect page caching with enabled maintenance mode when accessing from the exclude IP list. --- .../Observer/SwitchPageCacheOnMaintenance.php | 108 ++++++++++ .../PageCacheState.php | 74 +++++++ .../SwitchPageCacheOnMaintenanceTest.php | 161 ++++++++++++++ app/code/Magento/PageCache/etc/events.xml | 3 + .../PageCacheStateTest.php | 69 ++++++ .../Magento/Framework/App/MaintenanceMode.php | 14 +- .../App/Test/Unit/MaintenanceModeTest.php | 199 +++++++++++++----- 7 files changed, 569 insertions(+), 59 deletions(-) create mode 100644 app/code/Magento/PageCache/Observer/SwitchPageCacheOnMaintenance.php create mode 100644 app/code/Magento/PageCache/Observer/SwitchPageCacheOnMaintenance/PageCacheState.php create mode 100644 app/code/Magento/PageCache/Test/Unit/Observer/SwitchPageCacheOnMaintenanceTest.php create mode 100644 dev/tests/integration/testsuite/Magento/PageCache/Observer/SwitchPageCacheOnMaintenance/PageCacheStateTest.php diff --git a/app/code/Magento/PageCache/Observer/SwitchPageCacheOnMaintenance.php b/app/code/Magento/PageCache/Observer/SwitchPageCacheOnMaintenance.php new file mode 100644 index 0000000000000..7a1cc8934c017 --- /dev/null +++ b/app/code/Magento/PageCache/Observer/SwitchPageCacheOnMaintenance.php @@ -0,0 +1,108 @@ +<?php +/** + * + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +declare(strict_types=1); + +namespace Magento\PageCache\Observer; + +use Magento\Framework\Event\ObserverInterface; +use Magento\Framework\Event\Observer; +use Magento\Framework\App\Cache\Manager; +use Magento\PageCache\Model\Cache\Type as PageCacheType; +use Magento\PageCache\Observer\SwitchPageCacheOnMaintenance\PageCacheState; + +/** + * Switch Page Cache on maintenance. + */ +class SwitchPageCacheOnMaintenance implements ObserverInterface +{ + /** + * @var Manager + */ + private $cacheManager; + + /** + * @var PageCacheState + */ + private $pageCacheStateStorage; + + /** + * @param Manager $cacheManager + * @param PageCacheState $pageCacheStateStorage + */ + public function __construct(Manager $cacheManager, PageCacheState $pageCacheStateStorage) + { + $this->cacheManager = $cacheManager; + $this->pageCacheStateStorage = $pageCacheStateStorage; + } + + /** + * Switches Full Page Cache. + * + * Depending on enabling or disabling Maintenance Mode it turns off or restores Full Page Cache state. + * + * @param Observer $observer + * @return void + */ + public function execute(Observer $observer) + { + if ($observer->getData('isOn')) { + $this->pageCacheStateStorage->save($this->isFullPageCacheEnabled()); + $this->turnOffFullPageCache(); + } else { + $this->restoreFullPageCacheState(); + } + } + + /** + * Turns off Full Page Cache. + * + * @return void + */ + private function turnOffFullPageCache() + { + if (!$this->isFullPageCacheEnabled()) { + return; + } + + $this->cacheManager->clean([PageCacheType::TYPE_IDENTIFIER]); + $this->cacheManager->setEnabled([PageCacheType::TYPE_IDENTIFIER], false); + } + + /** + * Full Page Cache state. + * + * @return bool + */ + private function isFullPageCacheEnabled(): bool + { + $cacheStatus = $this->cacheManager->getStatus(); + + if (!array_key_exists(PageCacheType::TYPE_IDENTIFIER, $cacheStatus)) { + return false; + } + + return (bool)$cacheStatus[PageCacheType::TYPE_IDENTIFIER]; + } + + /** + * Restores Full Page Cache state. + * + * Returns FPC to previous state that was before maintenance mode turning on. + * + * @return void + */ + private function restoreFullPageCacheState() + { + $storedPageCacheState = $this->pageCacheStateStorage->isEnabled(); + $this->pageCacheStateStorage->flush(); + + if ($storedPageCacheState) { + $this->cacheManager->setEnabled([PageCacheType::TYPE_IDENTIFIER], true); + } + } +} diff --git a/app/code/Magento/PageCache/Observer/SwitchPageCacheOnMaintenance/PageCacheState.php b/app/code/Magento/PageCache/Observer/SwitchPageCacheOnMaintenance/PageCacheState.php new file mode 100644 index 0000000000000..4180885fcbc54 --- /dev/null +++ b/app/code/Magento/PageCache/Observer/SwitchPageCacheOnMaintenance/PageCacheState.php @@ -0,0 +1,74 @@ +<?php +/** + * + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +declare(strict_types=1); + +namespace Magento\PageCache\Observer\SwitchPageCacheOnMaintenance; + +use Magento\Framework\Filesystem; +use Magento\Framework\App\Filesystem\DirectoryList; + +/** + * Page Cache state. + */ +class PageCacheState +{ + /** + * Full Page Cache Off state file name. + */ + const PAGE_CACHE_STATE_FILENAME = '.maintenance.fpc.state'; + + /** + * @var Filesystem\Directory\WriteInterface + */ + private $flagDir; + + /** + * @param Filesystem $fileSystem + */ + public function __construct(Filesystem $fileSystem) + { + $this->flagDir = $fileSystem->getDirectoryWrite(DirectoryList::VAR_DIR); + } + + /** + * Saves Full Page Cache state. + * + * Saves FPC state across requests. + * + * @param bool $state + * @return void + */ + public function save(bool $state) + { + $this->flagDir->writeFile(self::PAGE_CACHE_STATE_FILENAME, (string)$state); + } + + /** + * Returns stored Full Page Cache state. + * + * @return bool + */ + public function isEnabled(): bool + { + if (!$this->flagDir->isExist(self::PAGE_CACHE_STATE_FILENAME)) { + return false; + } + + return (bool)$this->flagDir->readFile(self::PAGE_CACHE_STATE_FILENAME); + } + + /** + * Flushes Page Cache state storage. + * + * @return void + */ + public function flush() + { + $this->flagDir->delete(self::PAGE_CACHE_STATE_FILENAME); + } +} diff --git a/app/code/Magento/PageCache/Test/Unit/Observer/SwitchPageCacheOnMaintenanceTest.php b/app/code/Magento/PageCache/Test/Unit/Observer/SwitchPageCacheOnMaintenanceTest.php new file mode 100644 index 0000000000000..8c4661cddd44c --- /dev/null +++ b/app/code/Magento/PageCache/Test/Unit/Observer/SwitchPageCacheOnMaintenanceTest.php @@ -0,0 +1,161 @@ +<?php +/** + * + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +declare(strict_types=1); + +namespace Magento\PageCache\Test\Unit\Observer; + +use PHPUnit\Framework\TestCase; +use Magento\PageCache\Observer\SwitchPageCacheOnMaintenance; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; +use Magento\Framework\App\Cache\Manager; +use Magento\Framework\Event\Observer; +use Magento\PageCache\Model\Cache\Type as PageCacheType; +use Magento\PageCache\Observer\SwitchPageCacheOnMaintenance\PageCacheState; + +/** + * SwitchPageCacheOnMaintenance observer test. + */ +class SwitchPageCacheOnMaintenanceTest extends TestCase +{ + /** + * @var SwitchPageCacheOnMaintenance + */ + private $model; + + /** + * @var Manager|\PHPUnit_Framework_MockObject_MockObject + */ + private $cacheManager; + + /** + * @var PageCacheState|\PHPUnit_Framework_MockObject_MockObject + */ + private $pageCacheStateStorage; + + /** + * @var Observer|\PHPUnit_Framework_MockObject_MockObject + */ + private $observer; + + /** + * @inheritdoc + */ + protected function setUp() + { + $objectManager = new ObjectManager($this); + $this->cacheManager = $this->createMock(Manager::class); + $this->pageCacheStateStorage = $this->createMock(PageCacheState::class); + $this->observer = $this->createMock(Observer::class); + + $this->model = $objectManager->getObject(SwitchPageCacheOnMaintenance::class, [ + 'cacheManager' => $this->cacheManager, + 'pageCacheStateStorage' => $this->pageCacheStateStorage, + ]); + } + + /** + * Tests execute when setting maintenance mode to on. + * + * @param array $cacheStatus + * @param bool $cacheState + * @param int $flushCacheCalls + * @return void + * @dataProvider enablingPageCacheStateProvider + */ + public function testExecuteWhileMaintenanceEnabling(array $cacheStatus, bool $cacheState, int $flushCacheCalls) + { + $this->observer->method('getData') + ->with('isOn') + ->willReturn(true); + $this->cacheManager->method('getStatus') + ->willReturn($cacheStatus); + + // Page Cache state will be stored. + $this->pageCacheStateStorage->expects($this->once()) + ->method('save') + ->with($cacheState); + + // Page Cache will be cleaned and disabled + $this->cacheManager->expects($this->exactly($flushCacheCalls)) + ->method('clean') + ->with([PageCacheType::TYPE_IDENTIFIER]); + $this->cacheManager->expects($this->exactly($flushCacheCalls)) + ->method('setEnabled') + ->with([PageCacheType::TYPE_IDENTIFIER], false); + + $this->model->execute($this->observer); + } + + /** + * Tests execute when setting Maintenance Mode to off. + * + * @param bool $storedCacheState + * @param int $enableCacheCalls + * @return void + * @dataProvider disablingPageCacheStateProvider + */ + public function testExecuteWhileMaintenanceDisabling(bool $storedCacheState, int $enableCacheCalls) + { + $this->observer->method('getData') + ->with('isOn') + ->willReturn(false); + + $this->pageCacheStateStorage->method('isEnabled') + ->willReturn($storedCacheState); + + // Nullify Page Cache state. + $this->pageCacheStateStorage->expects($this->once()) + ->method('flush'); + + // Page Cache will be enabled. + $this->cacheManager->expects($this->exactly($enableCacheCalls)) + ->method('setEnabled') + ->with([PageCacheType::TYPE_IDENTIFIER]); + + $this->model->execute($this->observer); + } + + /** + * Page Cache state data provider. + * + * @return array + */ + public function enablingPageCacheStateProvider(): array + { + return [ + 'page_cache_is_enable' => [ + 'cache_status' => [PageCacheType::TYPE_IDENTIFIER => 1], + 'cache_state' => true, + 'flush_cache_calls' => 1, + ], + 'page_cache_is_missing_in_system' => [ + 'cache_status' => [], + 'cache_state' => false, + 'flush_cache_calls' => 0, + ], + 'page_cache_is_disable' => [ + 'cache_status' => [PageCacheType::TYPE_IDENTIFIER => 0], + 'cache_state' => false, + 'flush_cache_calls' => 0, + ], + ]; + } + + /** + * Page Cache state data provider. + * + * @return array + */ + public function disablingPageCacheStateProvider(): array + { + return [ + ['stored_cache_state' => true, 'enable_cache_calls' => 1], + ['stored_cache_state' => false, 'enable_cache_calls' => 0], + ]; + } +} diff --git a/app/code/Magento/PageCache/etc/events.xml b/app/code/Magento/PageCache/etc/events.xml index 7584f5f36d69c..3f0a2532ae60a 100644 --- a/app/code/Magento/PageCache/etc/events.xml +++ b/app/code/Magento/PageCache/etc/events.xml @@ -57,4 +57,7 @@ <event name="customer_logout"> <observer name="FlushFormKey" instance="Magento\PageCache\Observer\FlushFormKey"/> </event> + <event name="maintenance_mode_changed"> + <observer name="page_cache_switcher_for_maintenance" instance="Magento\PageCache\Observer\SwitchPageCacheOnMaintenance"/> + </event> </config> diff --git a/dev/tests/integration/testsuite/Magento/PageCache/Observer/SwitchPageCacheOnMaintenance/PageCacheStateTest.php b/dev/tests/integration/testsuite/Magento/PageCache/Observer/SwitchPageCacheOnMaintenance/PageCacheStateTest.php new file mode 100644 index 0000000000000..456e6df3a7421 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/PageCache/Observer/SwitchPageCacheOnMaintenance/PageCacheStateTest.php @@ -0,0 +1,69 @@ +<?php +/** + * + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +declare(strict_types=1); + +namespace Magento\PageCache\Observer\SwitchPageCacheOnMaintenance; + +use PHPUnit\Framework\TestCase; +use Magento\TestFramework\Helper\Bootstrap; + +/** + * Page Cache state test. + */ +class PageCacheStateTest extends TestCase +{ + /** + * @var PageCacheState + */ + private $pageCacheStateStorage; + + /** + * @inheritdoc + */ + protected function setUp() + { + $objectManager = Bootstrap::getObjectManager(); + $this->pageCacheStateStorage = $objectManager->get(PageCacheState::class); + } + + /** + * Tests save state. + * + * @param bool $state + * @return void + * @dataProvider saveStateProvider + */ + public function testSave(bool $state) + { + $this->pageCacheStateStorage->save($state); + $this->assertEquals($state, $this->pageCacheStateStorage->isEnabled()); + } + + /** + * Tests flush state. + * + * @return void + */ + public function testFlush() + { + $this->pageCacheStateStorage->save(true); + $this->assertTrue($this->pageCacheStateStorage->isEnabled()); + $this->pageCacheStateStorage->flush(); + $this->assertFalse($this->pageCacheStateStorage->isEnabled()); + } + + /** + * Save state provider. + * + * @return array + */ + public function saveStateProvider(): array + { + return [[true], [false]]; + } +} diff --git a/lib/internal/Magento/Framework/App/MaintenanceMode.php b/lib/internal/Magento/Framework/App/MaintenanceMode.php index 4e4328cb72aef..225375c7df463 100644 --- a/lib/internal/Magento/Framework/App/MaintenanceMode.php +++ b/lib/internal/Magento/Framework/App/MaintenanceMode.php @@ -7,6 +7,7 @@ use Magento\Framework\App\Filesystem\DirectoryList; use Magento\Framework\Filesystem; +use Magento\Framework\Event\Manager; /** * Application Maintenance Mode @@ -39,13 +40,18 @@ class MaintenanceMode protected $flagDir; /** - * Constructor - * + * @var Manager + */ + private $eventManager; + + /** * @param \Magento\Framework\Filesystem $filesystem + * @param Manager|null $eventManager */ - public function __construct(Filesystem $filesystem) + public function __construct(Filesystem $filesystem, Manager $eventManager = null) { $this->flagDir = $filesystem->getDirectoryWrite(self::FLAG_DIR); + $this->eventManager = $eventManager ?: ObjectManager::getInstance()->get(Manager::class); } /** @@ -73,6 +79,8 @@ public function isOn($remoteAddr = '') */ public function set($isOn) { + $this->eventManager->dispatch('maintenance_mode_changed', ['isOn' => $isOn]); + if ($isOn) { return $this->flagDir->touch(self::FLAG_FILENAME); } diff --git a/lib/internal/Magento/Framework/App/Test/Unit/MaintenanceModeTest.php b/lib/internal/Magento/Framework/App/Test/Unit/MaintenanceModeTest.php index 5d1c22a38af4d..09bcbd760c87a 100644 --- a/lib/internal/Magento/Framework/App/Test/Unit/MaintenanceModeTest.php +++ b/lib/internal/Magento/Framework/App/Test/Unit/MaintenanceModeTest.php @@ -6,9 +6,17 @@ namespace Magento\Framework\App\Test\Unit; -use \Magento\Framework\App\MaintenanceMode; +use Magento\Framework\App\MaintenanceMode; +use Magento\Framework\Event\Manager; +use Magento\Framework\Filesystem\Directory\WriteInterface; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; +use Magento\Framework\Filesystem; +use PHPUnit\Framework\TestCase; -class MaintenanceModeTest extends \PHPUnit\Framework\TestCase +/** + * MaintenanceMode Test + */ +class MaintenanceModeTest extends TestCase { /** * @var MaintenanceMode @@ -16,141 +24,213 @@ class MaintenanceModeTest extends \PHPUnit\Framework\TestCase protected $model; /** - * @var \Magento\Framework\Filesystem\Directory\WriteInterface | \PHPUnit_Framework_MockObject_MockObject + * @var WriteInterface|\PHPUnit_Framework_MockObject_MockObject */ protected $flagDir; + /** + * @var Manager|\PHPUnit_Framework_MockObject_MockObject + */ + private $eventManager; + + /** + * @inheritdoc + */ protected function setup() { - $this->flagDir = $this->getMockForAbstractClass(\Magento\Framework\Filesystem\Directory\WriteInterface::class); - $filesystem = $this->createMock(\Magento\Framework\Filesystem::class); - $filesystem->expects($this->any()) - ->method('getDirectoryWrite') - ->will($this->returnValue($this->flagDir)); + $this->flagDir = $this->getMockForAbstractClass(WriteInterface::class); + $filesystem = $this->createMock(Filesystem::class); + $filesystem->method('getDirectoryWrite') + ->willReturn($this->flagDir); + $this->eventManager = $this->createMock(Manager::class); - $this->model = new MaintenanceMode($filesystem); + $objectManager = new ObjectManager($this); + $this->model = $objectManager->getObject(MaintenanceMode::class, [ + 'filesystem' => $filesystem, + 'eventManager' => $this->eventManager, + ]); } + /** + * Is On initial test + * + * @return void + */ public function testIsOnInitial() { - $this->flagDir->expects($this->once())->method('isExist') + $this->flagDir->expects($this->once()) + ->method('isExist') ->with(MaintenanceMode::FLAG_FILENAME) - ->will($this->returnValue(false)); + ->willReturn(false); $this->assertFalse($this->model->isOn()); } + /** + * Is On without ip test + * + * @return void + */ public function testisOnWithoutIP() { $mapisExist = [ [MaintenanceMode::FLAG_FILENAME, true], [MaintenanceMode::IP_FILENAME, false], ]; - $this->flagDir->expects($this->exactly(2))->method('isExist') - ->will(($this->returnValueMap($mapisExist))); + $this->flagDir->expects($this->exactly(2)) + ->method('isExist') + ->willReturnMap($mapisExist); $this->assertTrue($this->model->isOn()); } + /** + * Is On with IP test + * + * @return void + */ public function testisOnWithIP() { $mapisExist = [ [MaintenanceMode::FLAG_FILENAME, true], [MaintenanceMode::IP_FILENAME, true], ]; - $this->flagDir->expects($this->exactly(2))->method('isExist') - ->will(($this->returnValueMap($mapisExist))); + $this->flagDir->expects($this->exactly(2)) + ->method('isExist') + ->willReturnMap($mapisExist); $this->assertFalse($this->model->isOn()); } + /** + * Is On with IP but no Maintenance files test + * + * @return void + */ public function testisOnWithIPNoMaintenance() { - $this->flagDir->expects($this->once())->method('isExist') + $this->flagDir->expects($this->once()) + ->method('isExist') ->with(MaintenanceMode::FLAG_FILENAME) ->willReturn(false); $this->assertFalse($this->model->isOn()); } + /** + * Maintenance Mode On test + * + * Tests common scenario with Full Page Cache is set to On + * + * @return void + */ public function testMaintenanceModeOn() { - $this->flagDir->expects($this->at(0))->method('isExist')->with(MaintenanceMode::FLAG_FILENAME) - ->will($this->returnValue(false)); - $this->flagDir->expects($this->at(1))->method('touch')->will($this->returnValue(true)); - $this->flagDir->expects($this->at(2))->method('isExist')->with(MaintenanceMode::FLAG_FILENAME) - ->will($this->returnValue(true)); - $this->flagDir->expects($this->at(3))->method('isExist')->with(MaintenanceMode::IP_FILENAME) - ->will($this->returnValue(false)); + $this->eventManager->expects($this->once()) + ->method('dispatch') + ->with('maintenance_mode_changed', ['isOn' => true]); - $this->assertFalse($this->model->isOn()); - $this->assertTrue($this->model->set(true)); - $this->assertTrue($this->model->isOn()); + $this->flagDir->expects($this->once()) + ->method('touch') + ->with(MaintenanceMode::FLAG_FILENAME); + + $this->model->set(true); } + /** + * Maintenance Mode Off test + * + * Tests common scenario when before Maintenance Mode Full Page Cache was setted to on + * + * @return void + */ public function testMaintenanceModeOff() { - $this->flagDir->expects($this->at(0))->method('isExist')->with(MaintenanceMode::FLAG_FILENAME) - ->will($this->returnValue(true)); - $this->flagDir->expects($this->at(1))->method('delete')->with(MaintenanceMode::FLAG_FILENAME) - ->will($this->returnValue(false)); - $this->flagDir->expects($this->at(2))->method('isExist')->with(MaintenanceMode::FLAG_FILENAME) - ->will($this->returnValue(false)); - - $this->assertFalse($this->model->set(false)); - $this->assertFalse($this->model->isOn()); + $this->eventManager->expects($this->once()) + ->method('dispatch') + ->with('maintenance_mode_changed', ['isOn' => false]); + + $this->flagDir->method('isExist') + ->with(MaintenanceMode::FLAG_FILENAME) + ->willReturn(true); + + $this->flagDir->expects($this->once()) + ->method('delete') + ->with(MaintenanceMode::FLAG_FILENAME); + + $this->model->set(false); } + /** + * Set empty addresses test + * + * @return void + */ public function testSetAddresses() { $mapisExist = [ [MaintenanceMode::FLAG_FILENAME, true], [MaintenanceMode::IP_FILENAME, true], ]; - $this->flagDir->expects($this->any())->method('isExist')->will($this->returnValueMap($mapisExist)); - $this->flagDir->expects($this->any())->method('writeFile') + $this->flagDir->method('isExist') + ->willReturnMap($mapisExist); + $this->flagDir->method('writeFile') ->with(MaintenanceMode::IP_FILENAME) - ->will($this->returnValue(true)); + ->willReturn(true); - $this->flagDir->expects($this->any())->method('readFile') + $this->flagDir->method('readFile') ->with(MaintenanceMode::IP_FILENAME) - ->will($this->returnValue('')); + ->willReturn(''); $this->model->setAddresses(''); $this->assertEquals([''], $this->model->getAddressInfo()); } + /** + * Set single address test + * + * @return void + */ public function testSetSingleAddresses() { $mapisExist = [ [MaintenanceMode::FLAG_FILENAME, true], [MaintenanceMode::IP_FILENAME, true], ]; - $this->flagDir->expects($this->any())->method('isExist')->will($this->returnValueMap($mapisExist)); - $this->flagDir->expects($this->any())->method('delete')->will($this->returnValueMap($mapisExist)); + $this->flagDir->method('isExist') + ->willReturnMap($mapisExist); + $this->flagDir->method('delete') + ->willReturnMap($mapisExist); - $this->flagDir->expects($this->any())->method('writeFile') - ->will($this->returnValue(10)); + $this->flagDir->method('writeFile') + ->willReturn(10); - $this->flagDir->expects($this->any())->method('readFile') + $this->flagDir->method('readFile') ->with(MaintenanceMode::IP_FILENAME) - ->will($this->returnValue('address1')); + ->willReturn('address1'); $this->model->setAddresses('address1'); $this->assertEquals(['address1'], $this->model->getAddressInfo()); } + /** + * Is On when multiple addresses test was setted + * + * @return void + */ public function testOnSetMultipleAddresses() { $mapisExist = [ [MaintenanceMode::FLAG_FILENAME, true], [MaintenanceMode::IP_FILENAME, true], ]; - $this->flagDir->expects($this->any())->method('isExist')->will($this->returnValueMap($mapisExist)); - $this->flagDir->expects($this->any())->method('delete')->will($this->returnValueMap($mapisExist)); + $this->flagDir->method('isExist') + ->willReturnMap($mapisExist); + $this->flagDir->method('delete') + ->willReturnMap($mapisExist); - $this->flagDir->expects($this->any())->method('writeFile') - ->will($this->returnValue(10)); + $this->flagDir->method('writeFile') + ->willReturn(10); - $this->flagDir->expects($this->any())->method('readFile') + $this->flagDir->method('readFile') ->with(MaintenanceMode::IP_FILENAME) - ->will($this->returnValue('address1,10.50.60.123')); + ->willReturn('address1,10.50.60.123'); $expectedArray = ['address1', '10.50.60.123']; $this->model->setAddresses('address1,10.50.60.123'); @@ -159,18 +239,25 @@ public function testOnSetMultipleAddresses() $this->assertTrue($this->model->isOn('address3')); } + /** + * Is Off when multiple addresses test was setted + * + * @return void + */ public function testOffSetMultipleAddresses() { $mapisExist = [ [MaintenanceMode::FLAG_FILENAME, false], [MaintenanceMode::IP_FILENAME, true], ]; - $this->flagDir->expects($this->any())->method('isExist')->will($this->returnValueMap($mapisExist)); - $this->flagDir->expects($this->any())->method('delete')->will($this->returnValueMap($mapisExist)); + $this->flagDir->method('isExist') + ->willReturnMap($mapisExist); + $this->flagDir->method('delete') + ->willReturnMap($mapisExist); - $this->flagDir->expects($this->any())->method('readFile') + $this->flagDir->method('readFile') ->with(MaintenanceMode::IP_FILENAME) - ->will($this->returnValue('address1,10.50.60.123')); + ->willReturn('address1,10.50.60.123'); $expectedArray = ['address1', '10.50.60.123']; $this->model->setAddresses('address1,10.50.60.123'); From af81dcee6846e82cd0855971b490c69a923deacc Mon Sep 17 00:00:00 2001 From: Pavel Bystritsky <p.bystritsky@yandex.ru> Date: Thu, 14 Feb 2019 14:42:21 +0200 Subject: [PATCH 102/315] ENGCOM-4000: MFTF test fix. --- .../Test/Mftf/ActionGroup/AdminCreateWidgetActionGroup.xml | 2 ++ app/code/Magento/Widget/Test/Mftf/Data/WidgetsData.xml | 1 + .../Magento/Widget/Test/Mftf/Section/AdminNewWidgetSection.xml | 2 ++ 3 files changed, 5 insertions(+) diff --git a/app/code/Magento/Widget/Test/Mftf/ActionGroup/AdminCreateWidgetActionGroup.xml b/app/code/Magento/Widget/Test/Mftf/ActionGroup/AdminCreateWidgetActionGroup.xml index dfb33b197d74f..0acbc33fcb06b 100644 --- a/app/code/Magento/Widget/Test/Mftf/ActionGroup/AdminCreateWidgetActionGroup.xml +++ b/app/code/Magento/Widget/Test/Mftf/ActionGroup/AdminCreateWidgetActionGroup.xml @@ -32,6 +32,8 @@ <click selector="{{AdminNewWidgetSection.addNewCondition}}" stepKey="clickAddNewCondition"/> <selectOption selector="{{AdminNewWidgetSection.selectCondition}}" userInput="{{widget.condition}}" stepKey="selectCondition"/> <waitForElement selector="{{AdminNewWidgetSection.ruleParameter}}" stepKey="waitRuleParameter"/> + <click selector="{{AdminNewWidgetSection.ruleParameterEdit}}" stepKey="clickRuleParameterEdit"/> + <selectOption selector="{{AdminNewWidgetSection.ruleParameterEditSelect}}" userInput="{{widget.ruleIsOneOf}}" stepKey="selectRuleParameterEdit"/> <click selector="{{AdminNewWidgetSection.ruleParameter}}" stepKey="clickRuleParameter"/> <click selector="{{AdminNewWidgetSection.openChooser}}" stepKey="clickChooser"/> <waitForPageLoad stepKey="waitForAjaxLoad"/> diff --git a/app/code/Magento/Widget/Test/Mftf/Data/WidgetsData.xml b/app/code/Magento/Widget/Test/Mftf/Data/WidgetsData.xml index d7db8fe50cb7f..ce56a6d92dd97 100644 --- a/app/code/Magento/Widget/Test/Mftf/Data/WidgetsData.xml +++ b/app/code/Magento/Widget/Test/Mftf/Data/WidgetsData.xml @@ -18,6 +18,7 @@ <data key="condition">SKU</data> <data key="display_on">All Pages</data> <data key="container">Main Content Area</data> + <data key="ruleIsOneOf">is one of</data> </entity> <entity name="DynamicBlocksRotatorWidget" type="widget"> <data key="type">Banner Rotator</data> diff --git a/app/code/Magento/Widget/Test/Mftf/Section/AdminNewWidgetSection.xml b/app/code/Magento/Widget/Test/Mftf/Section/AdminNewWidgetSection.xml index 37ad425114d5c..389d7bd1ab0e1 100644 --- a/app/code/Magento/Widget/Test/Mftf/Section/AdminNewWidgetSection.xml +++ b/app/code/Magento/Widget/Test/Mftf/Section/AdminNewWidgetSection.xml @@ -20,6 +20,8 @@ <element name="widgetOptions" type="select" selector="#widget_instace_tabs_properties_section"/> <element name="addNewCondition" type="select" selector=".rule-param.rule-param-new-child"/> <element name="selectCondition" type="input" selector="#conditions__1__new_child"/> + <element name="ruleParameterEdit" type="select" selector="#conditions__1__children>li:nth-child(1)>span:nth-child(3)>a"/> + <element name="ruleParameterEditSelect" type="select" selector="#conditions__1__children>li:nth-child(1)>span:nth-child(3)>span>select"/> <element name="ruleParameter" type="select" selector="#conditions__1__children>li:nth-child(1)>span:nth-child(4)>a"/> <element name="setRuleParameter" type="input" selector="#conditions__1--1__value"/> <element name="applyParameter" type="button" selector=".rule-param-apply"/> From de8d46fac2925323f84d47b1711440c7e12dedb0 Mon Sep 17 00:00:00 2001 From: Stas Kozar <stas.kozar@transoftgroup.com> Date: Thu, 14 Feb 2019 15:07:57 +0200 Subject: [PATCH 103/315] MAGETWO-94147: Swatch Attribute is not displayed in the Widget CMS --- ...minCategoryProductAttributeActionGroup.xml | 8 +- .../Block/Product/ProductsList.php | 80 ++++++++++++++- .../layout/catalog_widget_product_list.xml | 14 +++ .../product/widget/content/grid.phtml | 99 ++++++++++--------- .../CreateNewPageWithWidgetActionGroup.xml | 49 +++++++++ .../DeletePageByUrlKeyActionGroup.xml | 10 +- .../Section/CmsNewPagePageActionsSection.xml | 1 + .../Section/AdminNewAttributePanelSection.xml | 9 +- ...figurationsWithVisualSwatchActionGroup.xml | 11 ++- ...SwatchAttributesDisplayInWidgetCMSTest.xml | 71 +++++++++++++ .../layout/catalog_widget_product_list.xml | 14 +++ .../view/frontend/layout/cms_page_view.xml | 12 +++ 12 files changed, 324 insertions(+), 54 deletions(-) create mode 100644 app/code/Magento/CatalogWidget/view/frontend/layout/catalog_widget_product_list.xml create mode 100644 app/code/Magento/Cms/Test/Mftf/ActionGroup/CreateNewPageWithWidgetActionGroup.xml create mode 100644 app/code/Magento/Swatches/Test/Mftf/Test/StorefrontSwatchAttributesDisplayInWidgetCMSTest.xml create mode 100644 app/code/Magento/Swatches/view/frontend/layout/catalog_widget_product_list.xml create mode 100644 app/code/Magento/Swatches/view/frontend/layout/cms_page_view.xml diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminCategoryProductAttributeActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminCategoryProductAttributeActionGroup.xml index 5c71342264212..21e41732369e9 100644 --- a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminCategoryProductAttributeActionGroup.xml +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminCategoryProductAttributeActionGroup.xml @@ -7,15 +7,14 @@ --> <actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/actionGroupSchema.xsd"> + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> <!--Action to delete product attribute--> <actionGroup name="DeleteProductAttribute"> <arguments> <argument name="productAttribute"/> </arguments> <amOnPage url="{{AdminProductAttributeGridPage.url}}" stepKey="goToProductAttributesGridPage"/> - <waitForPageLoad time="30" stepKey="waitForProductAttributesGridPageLoad"/> - <click selector="{{AdminProductAttributeGridSection.resetFilter}}" stepKey="resetFilter"/> + <conditionalClick selector="{{AdminDataGridHeaderSection.clearFilters}}" dependentSelector="{{AdminDataGridHeaderSection.clearFilters}}" visible="true" stepKey="clearExistingFiltersBeforeDelete"/> <fillField selector="{{AdminProductAttributeGridSection.gridFilterFrontEndLabel}}" userInput="{{productAttribute.default_label}}" stepKey="fillAttributeDefaultLabelInput"/> <click selector="{{AdminProductAttributeGridSection.search}}" stepKey="searchForAttribute"/> @@ -23,7 +22,8 @@ <waitForPageLoad time="30" stepKey="waitForPageLoad"/> <click selector="{{AdminProductAttributeEditSection.deleteAttribute}}" stepKey="deleteProductAttribute"/> <waitForElementVisible selector="{{AdminConfirmationModalSection.message}}" stepKey="waitingForWarningModal"/> - <click selector="{{AdminConfirmationModalSection.ok}}" stepKey="confirmStoreDelete"/> + <click selector="{{AdminConfirmationModalSection.ok}}" stepKey="confirmDelete"/> + <conditionalClick selector="{{AdminDataGridHeaderSection.clearFilters}}" dependentSelector="{{AdminDataGridHeaderSection.clearFilters}}" visible="true" stepKey="clearExistingFiltersAfterDelete"/> </actionGroup> <actionGroup name="navigateToProductAttribute"> diff --git a/app/code/Magento/CatalogWidget/Block/Product/ProductsList.php b/app/code/Magento/CatalogWidget/Block/Product/ProductsList.php index cb462ada0fc91..f5a69418c5938 100644 --- a/app/code/Magento/CatalogWidget/Block/Product/ProductsList.php +++ b/app/code/Magento/CatalogWidget/Block/Product/ProductsList.php @@ -11,6 +11,10 @@ use Magento\Framework\Pricing\PriceCurrencyInterface; use Magento\Framework\Serialize\Serializer\Json; use Magento\Widget\Block\BlockInterface; +use Magento\Framework\Url\EncoderInterface; +use Magento\Framework\View\LayoutFactory; +use Magento\Catalog\Model\Product; +use Magento\Framework\App\ActionInterface; /** * Catalog Products List widget block @@ -94,6 +98,21 @@ class ProductsList extends \Magento\Catalog\Block\Product\AbstractProduct implem */ private $json; + /** + * @var LayoutFactory + */ + private $layoutFactory; + + /** + * @var \Magento\Framework\Url\EncoderInterface|null + */ + private $urlEncoder; + + /** + * @var \Magento\Framework\View\Element\RendererList + */ + private $rendererListBlock; + /** * @param \Magento\Catalog\Block\Product\Context $context * @param \Magento\Catalog\Model\ResourceModel\Product\CollectionFactory $productCollectionFactory @@ -104,6 +123,10 @@ class ProductsList extends \Magento\Catalog\Block\Product\AbstractProduct implem * @param \Magento\Widget\Helper\Conditions $conditionsHelper * @param array $data * @param Json|null $json + * @param LayoutFactory|null $layoutFactory + * @param \Magento\Framework\Url\EncoderInterface|null $urlEncoder + * + * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( \Magento\Catalog\Block\Product\Context $context, @@ -114,7 +137,9 @@ public function __construct( \Magento\CatalogWidget\Model\Rule $rule, \Magento\Widget\Helper\Conditions $conditionsHelper, array $data = [], - Json $json = null + Json $json = null, + LayoutFactory $layoutFactory = null, + EncoderInterface $urlEncoder = null ) { $this->productCollectionFactory = $productCollectionFactory; $this->catalogProductVisibility = $catalogProductVisibility; @@ -123,6 +148,8 @@ public function __construct( $this->rule = $rule; $this->conditionsHelper = $conditionsHelper; $this->json = $json ?: ObjectManager::getInstance()->get(Json::class); + $this->layoutFactory = $layoutFactory ?: ObjectManager::getInstance()->get(LayoutFactory::class); + $this->urlEncoder = $urlEncoder ?: ObjectManager::getInstance()->get(EncoderInterface::class); parent::__construct( $context, $data @@ -210,6 +237,39 @@ public function getProductPriceHtml( return $price; } + /** + * @inheritdoc + */ + protected function getDetailsRendererList() + { + /** @var $layout \Magento\Framework\View\LayoutInterface */ + $layout = $this->layoutFactory->create(['cacheable' => false]); + $layout->getUpdate()->addHandle('catalog_widget_product_list')->load(); + $layout->generateXml(); + $layout->generateElements(); + + return $layout->getBlock('category.product.type.widget.details.renderers'); + } + + /** + * Get post parameters. + * + * @param Product $product + * @return array + */ + public function getAddToCartPostParams(Product $product) + { + $url = $this->getAddToCartUrl($product); + + return [ + 'action' => $url, + 'data' => [ + 'product' => $product->getEntityId(), + ActionInterface::PARAM_NAME_URL_ENCODED => $this->urlEncoder->encode($url), + ] + ]; + } + /** * {@inheritdoc} */ @@ -400,6 +460,24 @@ private function getPriceCurrency() } /** + * @inheritdoc + */ + public function getAddToCartUrl($product, $additional = []) + { + $requestingPageUrl = $this->getRequest()->getParam('requesting_page_url'); + + if (!empty($requestingPageUrl)) { + $additional['useUencPlaceholder'] = true; + $url = parent::getAddToCartUrl($product, $additional); + return str_replace('%25uenc%25', $this->urlEncoder->encode($requestingPageUrl), $url); + } + + return parent::getAddToCartUrl($product, $additional); + } + + /** + * Get widget block name + * * @return string */ private function getWidgetPagerBlockName() diff --git a/app/code/Magento/CatalogWidget/view/frontend/layout/catalog_widget_product_list.xml b/app/code/Magento/CatalogWidget/view/frontend/layout/catalog_widget_product_list.xml new file mode 100644 index 0000000000000..4fe7af7f34683 --- /dev/null +++ b/app/code/Magento/CatalogWidget/view/frontend/layout/catalog_widget_product_list.xml @@ -0,0 +1,14 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd"> + <body> + <block class="Magento\Framework\View\Element\RendererList" name="category.product.type.widget.details.renderers"> + <block class="Magento\Framework\View\Element\Template" name="category.product.type.details.renderers.default" as="default"/> + </block> + </body> +</page> diff --git a/app/code/Magento/CatalogWidget/view/frontend/templates/product/widget/content/grid.phtml b/app/code/Magento/CatalogWidget/view/frontend/templates/product/widget/content/grid.phtml index 574cbe1107e88..0217838b7fd8b 100644 --- a/app/code/Magento/CatalogWidget/view/frontend/templates/product/widget/content/grid.phtml +++ b/app/code/Magento/CatalogWidget/view/frontend/templates/product/widget/content/grid.phtml @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +use Magento\Framework\App\Action\Action; // @codingStandardsIgnoreFile @@ -48,57 +49,67 @@ <?= $block->escapeHtml($_item->getName()) ?> </a> </strong> - <?php - echo $block->getProductPriceHtml($_item, $type); - ?> - <?php if ($templateType): ?> <?= $block->getReviewsSummaryHtml($_item, $templateType) ?> <?php endif; ?> + <?= $block->getProductPriceHtml($_item, $type) ?> + + <?= $block->getProductDetailsHtml($_item) ?> + <?php if ($showWishlist || $showCompare || $showCart): ?> - <div class="product-item-actions"> - <?php if ($showCart): ?> - <div class="actions-primary"> - <?php if ($_item->isSaleable()): ?> - <?php if ($_item->getTypeInstance()->hasRequiredOptions($_item)): ?> - <button class="action tocart primary" data-mage-init='{"redirectUrl":{"url":"<?= $block->escapeUrl($block->getAddToCartUrl($_item)) ?>"}}' type="button" title="<?= $block->escapeHtmlAttr(__('Add to Cart')) ?>"> - <span><?= $block->escapeHtml(__('Add to Cart')) ?></span> - </button> - <?php else: ?> - <?php - $postDataHelper = $this->helper('Magento\Framework\Data\Helper\PostHelper'); - $postData = $postDataHelper->getPostData($block->getAddToCartUrl($_item), ['product' => $_item->getEntityId()]) - ?> - <button class="action tocart primary" data-post='<?= /* @noEscape */ $postData ?>' type="button" title="<?= $block->escapeHtmlAttr(__('Add to Cart')) ?>"> - <span><?= $block->escapeHtml(__('Add to Cart')) ?></span> - </button> + <div class="product-item-inner"> + <div class="product-item-actions"> + <?php if ($showCart): ?> + <div class="actions-primary"> + <?php if ($_item->isSaleable()): ?> + <?php $postParams = $block->getAddToCartPostParams($_item); ?> + <form data-role="tocart-form" + data-product-sku="<?= $block->escapeHtml($_item->getSku()) ?>" + action="<?= /* @NoEscape */ + $postParams['action'] ?>" method="post"> + <input type="hidden" name="product" + value="<?= /* @escapeNotVerified */ + $postParams['data']['product'] ?>"> + <input type="hidden" name="<?= /* @escapeNotVerified */ + Action::PARAM_NAME_URL_ENCODED ?>" + value="<?= /* @escapeNotVerified */ + $postParams['data'][Action::PARAM_NAME_URL_ENCODED] ?>"> + <?= $block->getBlockHtml('formkey') ?> + <button type="submit" + title="<?= $block->escapeHtml(__('Add to Cart')) ?>" + class="action tocart primary"> + <span><?= /* @escapeNotVerified */ + __('Add to Cart') ?></span> + </button> + </form> + <?php else: ?> + + <?php if ($_item->getIsSalable()): ?> + <div class="stock available"><span><?= $block->escapeHtml(__('In stock')) ?></span></div> + <?php else: ?> + <div class="stock unavailable"><span><?= $block->escapeHtml(__('Out of stock')) ?></span></div> + <?php endif; ?> + <?php endif; ?> + </div> + <?php endif; ?> + <?php if ($showWishlist || $showCompare): ?> + <div class="actions-secondary" data-role="add-to-links"> + <?php if ($this->helper('Magento\Wishlist\Helper\Data')->isAllow() && $showWishlist): ?> + <a href="#" + data-post='<?= /* @noEscape */ $block->getAddToWishlistParams($_item) ?>' class="action towishlist" data-action="add-to-wishlist" title="<?= $block->escapeHtmlAttr(__('Add to Wish List')) ?>"> + <span><?= $block->escapeHtml(__('Add to Wish List')) ?></span> + </a> <?php endif; ?> - <?php else: ?> - <?php if ($_item->getIsSalable()): ?> - <div class="stock available"><span><?= $block->escapeHtml(__('In stock')) ?></span></div> - <?php else: ?> - <div class="stock unavailable"><span><?= $block->escapeHtml(__('Out of stock')) ?></span></div> + <?php if ($block->getAddToCompareUrl() && $showCompare): ?> + <?php $compareHelper = $this->helper('Magento\Catalog\Helper\Product\Compare');?> + <a href="#" class="action tocompare" data-post='<?= /* @noEscape */ $compareHelper->getPostDataParams($_item) ?>' title="<?= $block->escapeHtmlAttr(__('Add to Compare')) ?>"> + <span><?= $block->escapeHtml(__('Add to Compare')) ?></span> + </a> <?php endif; ?> - <?php endif; ?> - </div> - <?php endif; ?> - <?php if ($showWishlist || $showCompare): ?> - <div class="actions-secondary" data-role="add-to-links"> - <?php if ($this->helper('Magento\Wishlist\Helper\Data')->isAllow() && $showWishlist): ?> - <a href="#" - data-post='<?= /* @noEscape */ $block->getAddToWishlistParams($_item) ?>' class="action towishlist" data-action="add-to-wishlist" title="<?= $block->escapeHtmlAttr(__('Add to Wish List')) ?>"> - <span><?= $block->escapeHtml(__('Add to Wish List')) ?></span> - </a> - <?php endif; ?> - <?php if ($block->getAddToCompareUrl() && $showCompare): ?> - <?php $compareHelper = $this->helper('Magento\Catalog\Helper\Product\Compare');?> - <a href="#" class="action tocompare" data-post='<?= /* @noEscape */ $compareHelper->getPostDataParams($_item) ?>' title="<?= $block->escapeHtmlAttr(__('Add to Compare')) ?>"> - <span><?= $block->escapeHtml(__('Add to Compare')) ?></span> - </a> - <?php endif; ?> - </div> - <?php endif; ?> + </div> + <?php endif; ?> + </div> </div> <?php endif; ?> </div> diff --git a/app/code/Magento/Cms/Test/Mftf/ActionGroup/CreateNewPageWithWidgetActionGroup.xml b/app/code/Magento/Cms/Test/Mftf/ActionGroup/CreateNewPageWithWidgetActionGroup.xml new file mode 100644 index 0000000000000..6a6bb9edaa43a --- /dev/null +++ b/app/code/Magento/Cms/Test/Mftf/ActionGroup/CreateNewPageWithWidgetActionGroup.xml @@ -0,0 +1,49 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + <actionGroup name="CreateNewPageWithWidgetWithCategoryCondition"> + <arguments> + <argument name="cmsPage" defaultValue="_defaultCmsPage"/> + <argument name="categoryId" type="string"/> + <argument name="conditionOperator" type="string" defaultValue="is"/> + <argument name="widgetType" type="string" defaultValue="Catalog Products List"/> + </arguments> + <amOnPage url="{{CmsNewPagePage.url}}" stepKey="amOnCMSNewPage"/> + <fillField selector="{{CmsNewPagePageBasicFieldsSection.pageTitle}}" userInput="{{cmsPage.title}}" stepKey="fillFieldTitle"/> + + <click selector="{{CmsNewPagePageSeoSection.header}}" stepKey="clickExpandSearchEngineOptimisation"/> + <fillField selector="{{CmsNewPagePageSeoSection.urlKey}}" userInput="{{cmsPage.identifier}}" stepKey="fillFieldUrlKey"/> + + <click selector="{{CmsNewPagePageContentSection.header}}" stepKey="clickExpandContent"/> + <click selector="{{CmsNewPagePageActionsSection.insertWidgetButton}}" stepKey="clickInsertWidgetButton"/> + <waitForElementVisible selector="{{AdminNewWidgetSection.widgetTypeDropDown}}" time="10" stepKey="waitForInsertWidgetFrame"/> + + <selectOption selector="{{AdminNewWidgetSection.widgetTypeDropDown}}" userInput="{{widgetType}}" stepKey="selectCatalogProductListOption"/> + <waitForElementVisible selector="{{AdminNewWidgetSection.addNewCondition}}" stepKey="waitForConditionsElementBecomeAvailable"/> + + <click selector="{{AdminNewWidgetSection.addNewCondition}}" stepKey="clickToAddCondition"/> + <waitForElementVisible selector="{{AdminNewWidgetSection.selectCondition}}" stepKey="waitForSelectBoxOpened"/> + + <selectOption selector="{{AdminNewWidgetSection.selectCondition}}" userInput="Category" stepKey="selectCategoryCondition"/> + <waitForElementVisible selector="{{AdminNewWidgetSection.ruleParameter}}" stepKey="seeConditionsAdded"/> + + <click selector="{{AdminNewWidgetSection.conditionOperator}}" stepKey="clickToConditionIs"/> + <selectOption selector="{{AdminNewWidgetSection.conditionOperatorSelect('1')}}" userInput="{{conditionOperator}}" stepKey="selectOperator"/> + + <click selector="{{AdminNewWidgetSection.ruleParameter}}" stepKey="clickAddConditionItem"/> + <waitForElementVisible selector="{{AdminNewWidgetSection.setRuleParameter}}" stepKey="waitForConditionFieldOpened"/> + + <fillField selector="{{AdminNewWidgetSection.setRuleParameter}}" userInput="{{categoryId}}" stepKey="setCategoryId"/> + <click selector="{{AdminNewWidgetSection.insertWidget}}" stepKey="clickInsertWidget"/> + + <waitForElementVisible selector="{{AdminMainActionsSection.save}}" stepKey="waitForInsertWidgetSaved"/> + <click selector="{{AdminMainActionsSection.save}}" stepKey="clickSaveButton"/> + <see userInput="You saved the page." stepKey="seeSavedPageMsgOnForm"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Cms/Test/Mftf/ActionGroup/DeletePageByUrlKeyActionGroup.xml b/app/code/Magento/Cms/Test/Mftf/ActionGroup/DeletePageByUrlKeyActionGroup.xml index 05e61ac86e166..3e034199ac1a2 100644 --- a/app/code/Magento/Cms/Test/Mftf/ActionGroup/DeletePageByUrlKeyActionGroup.xml +++ b/app/code/Magento/Cms/Test/Mftf/ActionGroup/DeletePageByUrlKeyActionGroup.xml @@ -6,18 +6,22 @@ */ --> <actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/actionGroupSchema.xsd"> + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> <actionGroup name="DeletePageByUrlKeyActionGroup"> <arguments> - <argument name="urlKey" type="string"/> + <argument name="urlKey" type="string" defaultValue="{{_defaultCmsPage.identifier}}"/> </arguments> <amOnPage url="{{CmsPagesPage.url}}" stepKey="amOnCMSPagesIndexPage"/> - <waitForPageLoad stepKey="waitForPageLoad1"/> + <conditionalClick selector="{{AdminDataGridHeaderSection.clearFilters}}" dependentSelector="{{AdminDataGridHeaderSection.clearFilters}}" visible="true" stepKey="clearExistingFiltersBeforeDelete"/> + <click selector="{{AdminDataGridHeaderSection.filters}}" stepKey="openCmsPageFilters"/> + <fillField selector="{{AdminDataGridHeaderSection.filterFieldInput('identifier')}}" userInput="{{urlKey}}" stepKey="fillFilter"/> + <click selector="{{AdminDataGridHeaderSection.applyFilters}}" stepKey="clickApplyFilters"/> <click selector="{{CmsPagesPageActionsSection.select(urlKey)}}" stepKey="clickSelect"/> <click selector="{{CmsPagesPageActionsSection.delete(urlKey)}}" stepKey="clickDelete"/> <waitForElementVisible selector="{{CmsPagesPageActionsSection.deleteConfirm}}" stepKey="waitForOkButtonToBeVisible"/> <click selector="{{CmsPagesPageActionsSection.deleteConfirm}}" stepKey="clickOkButton"/> <waitForPageLoad stepKey="waitForPageLoad3"/> <see userInput="The page has been deleted." stepKey="seeSuccessMessage"/> + <conditionalClick selector="{{AdminDataGridHeaderSection.clearFilters}}" dependentSelector="{{AdminDataGridHeaderSection.clearFilters}}" visible="true" stepKey="clearExistingFiltersAfterDelete"/> </actionGroup> </actionGroups> diff --git a/app/code/Magento/Cms/Test/Mftf/Section/CmsNewPagePageActionsSection.xml b/app/code/Magento/Cms/Test/Mftf/Section/CmsNewPagePageActionsSection.xml index f60fced7d05d4..da9efa0dab62a 100644 --- a/app/code/Magento/Cms/Test/Mftf/Section/CmsNewPagePageActionsSection.xml +++ b/app/code/Magento/Cms/Test/Mftf/Section/CmsNewPagePageActionsSection.xml @@ -11,5 +11,6 @@ <section name="CmsNewPagePageActionsSection"> <element name="savePage" type="button" selector="#save" timeout="30"/> <element name="saveAndContinueEdit" type="button" selector="#save_and_continue" timeout="10"/> + <element name="insertWidgetButton" type="button" selector=".scalable.action-add-widget.plugin"/> </section> </sections> diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/Section/AdminNewAttributePanelSection.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/Section/AdminNewAttributePanelSection.xml index 429d535952f76..7a722959c9996 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Mftf/Section/AdminNewAttributePanelSection.xml +++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/Section/AdminNewAttributePanelSection.xml @@ -7,7 +7,7 @@ --> <sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/SectionObject.xsd"> + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> <section name="AdminNewAttributePanelSection"> <element name="container" type="text" selector="#create_new_attribute"/> <element name="saveAttribute" type="button" selector="#save"/> @@ -21,5 +21,12 @@ <element name="deleteOption" type="button" selector="#delete_button_option_{{row}}" parameterized="true"/> <element name="attributeSelect" type="select" selector="product[{{var}}]" parameterized="true"/> <element name="attributeName" type="select" selector="//option[text()='{{var}}']" parameterized="true"/> + <element name="useInSearch" type="select" selector="#is_searchable"/> + <element name="visibleInAdvancedSearch" type="select" selector="#is_visible_in_advanced_search"/> + <element name="comparableOnStorefront" type="select" selector="#is_comparable"/> + <element name="useInLayeredNavigation" type="select" selector="#is_filterable"/> + <element name="visibleOnCatalogPagesOnStorefront" type="select" selector="#is_visible_on_front"/> + <element name="useInProductListing" type="select" selector="#used_in_product_listing"/> + <element name="storefrontPropertiesTab" type="button" selector="#front_fieldset-wrapper"/> </section> </sections> diff --git a/app/code/Magento/Swatches/Test/Mftf/ActionGroup/CreateConfigurationsWithVisualSwatchActionGroup.xml b/app/code/Magento/Swatches/Test/Mftf/ActionGroup/CreateConfigurationsWithVisualSwatchActionGroup.xml index 4eb4ca0b1327b..4d6896086f91b 100644 --- a/app/code/Magento/Swatches/Test/Mftf/ActionGroup/CreateConfigurationsWithVisualSwatchActionGroup.xml +++ b/app/code/Magento/Swatches/Test/Mftf/ActionGroup/CreateConfigurationsWithVisualSwatchActionGroup.xml @@ -7,7 +7,7 @@ --> <actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/actionGroupSchema.xsd"> + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> <actionGroup name="CreateConfigurationsWithVisualSwatch"> <arguments> <argument name="attribute" defaultValue="VisualSwatchAttribute"/> @@ -59,4 +59,13 @@ <click selector="{{AdminChooseAffectedAttributeSetSection.confirm}}" stepKey="clickOnConfirmInPopup"/> <seeElement selector="{{AdminMessagesSection.success}}" stepKey="seeSaveProductMessage"/> </actionGroup> + <actionGroup name="CreateConfigurationsWithVisualSwatchVisibleOnStorefront" extends="CreateConfigurationsWithVisualSwatch"> + <click selector="{{AdminNewAttributePanelSection.storefrontPropertiesTab}}" after="fillDefaultStoreLabel2" stepKey="expandStorefrontPropertiesTab"/> + <selectOption selector="{{AdminNewAttributePanelSection.useInSearch}}" userInput="1" after="expandStorefrontPropertiesTab" stepKey="enableUseInSearch"/> + <selectOption selector="{{AdminNewAttributePanelSection.visibleInAdvancedSearch}}" userInput="1" after="enableUseInSearch" stepKey="enableVisibleInAdvancedSearch"/> + <selectOption selector="{{AdminNewAttributePanelSection.comparableOnStorefront}}" userInput="1" after="enableVisibleInAdvancedSearch" stepKey="enableComparableOnStorefront"/> + <selectOption selector="{{AdminNewAttributePanelSection.useInLayeredNavigation}}" userInput="1" after="enableComparableOnStorefront" stepKey="enableUseInLayeredNavigation"/> + <selectOption selector="{{AdminNewAttributePanelSection.visibleOnCatalogPagesOnStorefront}}" userInput="1" after="enableUseInLayeredNavigation" stepKey="enableVisibleOnCatalogPagesOnStorefront"/> + <selectOption selector="{{AdminNewAttributePanelSection.useInProductListing}}" userInput="1" after="enableVisibleOnCatalogPagesOnStorefront" stepKey="enableUseInProductListing"/> + </actionGroup> </actionGroups> diff --git a/app/code/Magento/Swatches/Test/Mftf/Test/StorefrontSwatchAttributesDisplayInWidgetCMSTest.xml b/app/code/Magento/Swatches/Test/Mftf/Test/StorefrontSwatchAttributesDisplayInWidgetCMSTest.xml new file mode 100644 index 0000000000000..167d7ac007eef --- /dev/null +++ b/app/code/Magento/Swatches/Test/Mftf/Test/StorefrontSwatchAttributesDisplayInWidgetCMSTest.xml @@ -0,0 +1,71 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="StorefrontSwatchAttributesDisplayInWidgetCMSTest"> + <annotations> + <features value="Swatches"/> + <stories value="Create/configure swatches product attribute"/> + <title value="Swatch Attribute is not displayed in the Widget CMS"/> + <description value="Swatch Attribute is not displayed in the Widget CMS"/> + <severity value="MAJOR"/> + <testCaseId value="MC-14844"/> + <useCaseId value="MAGETWO-94147"/> + <group value="configurableProduct"/> + <group value="swatches"/> + <group value="cms"/> + <group value="WYSIWYGDisabled"/> + </annotations> + + <before> + <!--create category--> + <createData entity="_defaultCategory" stepKey="createCategory"/> + <!--Login--> + <actionGroup ref="LoginAsAdmin" stepKey="loginToAdmin"/> + <!--Create a configurable swatch product via the UI --> + <amOnPage url="{{AdminProductIndexPage.url}}" stepKey="goToProductIndex"/> + <actionGroup ref="goToCreateProductPage" stepKey="goToCreateProductPage"> + <argument name="product" value="BaseConfigurableProduct"/> + </actionGroup> + <actionGroup ref="fillMainProductForm" stepKey="fillProductForm"> + <argument name="product" value="BaseConfigurableProduct"/> + </actionGroup> + <searchAndMultiSelectOption selector="{{AdminProductFormSection.categoriesDropdown}}" parameterArray="[$$createCategory.name$$]" stepKey="searchAndSelectCategory"/> + <!--Add swatch attribute to configurable product--> + <actionGroup ref="CreateConfigurationsWithVisualSwatchVisibleOnStorefront" stepKey="addSwatchToProduct"/> + <!--Create CMS page--> + <actionGroup ref="CreateNewPageWithWidgetWithCategoryCondition" stepKey="createCMSPageWithWidget"> + <argument name="categoryId" value="$$createCategory.id$$"/> + <argument name="conditionOperator" value="contains"/> + </actionGroup> + </before> + + <after> + <!--delete created category--> + <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> + <!--delete created configurable product--> + <actionGroup ref="DeleteAllProductsOnProductsGridPageFilteredByName" stepKey="deleteAllCreatedProducts"> + <argument name="product" value="BaseConfigurableProduct"/> + </actionGroup> + <actionGroup ref="clearFiltersAdminDataGrid" stepKey="clearGridFilter"/> + <!--delete created attribute product--> + <actionGroup ref="DeleteProductAttribute" stepKey="deleteAttribute"> + <argument name="productAttribute" value="VisualSwatchAttribute"/> + </actionGroup> + <!--delete created page product--> + <actionGroup ref="DeletePageByUrlKeyActionGroup" stepKey="deletePage"/> + <!--logout--> + <actionGroup ref="logout" stepKey="logoutFromAdmin"/> + </after> + <!--Open Storefront page for the new created page--> + <amOnPage url="{{StorefrontHomePage.url}}{{_defaultCmsPage.identifier}}" stepKey="gotToCreatedCmsPage"/> + <seeElement selector="{{StorefrontProductInfoMainSection.swatchOptionByLabel(VisualSwatchOption1.default_label)}}" stepKey="assertAddedWidgetS"/> + <seeElement selector="{{StorefrontProductInfoMainSection.swatchOptionByLabel(VisualSwatchOption2.default_label)}}" stepKey="assertAddedWidgetM"/> + </test> +</tests> diff --git a/app/code/Magento/Swatches/view/frontend/layout/catalog_widget_product_list.xml b/app/code/Magento/Swatches/view/frontend/layout/catalog_widget_product_list.xml new file mode 100644 index 0000000000000..fce81408cd14d --- /dev/null +++ b/app/code/Magento/Swatches/view/frontend/layout/catalog_widget_product_list.xml @@ -0,0 +1,14 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd"> + <body> + <referenceBlock name="category.product.type.widget.details.renderers"> + <block class="Magento\Swatches\Block\Product\Renderer\Listing\Configurable" name="category.product.type.details.renderers.configurable" as="configurable" template="Magento_Swatches::product/listing/renderer.phtml" ifconfig="catalog/frontend/show_swatches_in_product_list"/> + </referenceBlock> + </body> +</page> diff --git a/app/code/Magento/Swatches/view/frontend/layout/cms_page_view.xml b/app/code/Magento/Swatches/view/frontend/layout/cms_page_view.xml new file mode 100644 index 0000000000000..2ef1e2fb2e803 --- /dev/null +++ b/app/code/Magento/Swatches/view/frontend/layout/cms_page_view.xml @@ -0,0 +1,12 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd"> + <head> + <css src="Magento_Swatches::css/swatches.css"/> + </head> +</page> From b141ccb3bce6ff40bd0f1701f626a7831d398382 Mon Sep 17 00:00:00 2001 From: Viktor Petryk <victor.petryk@transoftgroup.com> Date: Thu, 14 Feb 2019 16:17:53 +0200 Subject: [PATCH 104/315] MAGETWO-73524: WebAPI: product "has_options" flag not updated when options added via API --- .../Model/Product/Option/SaveHandler.php | 6 ++ .../UpdateProductCustomOptionsAttributes.php | 58 +++++++++++++++++ .../Magento/Catalog/etc/webapi_rest/di.xml | 3 + .../Magento/Catalog/etc/webapi_soap/di.xml | 3 + .../Api/ProductCustomOptionRepositoryTest.php | 64 +++++++++---------- 5 files changed, 100 insertions(+), 34 deletions(-) create mode 100644 app/code/Magento/Catalog/Plugin/Model/Product/Option/UpdateProductCustomOptionsAttributes.php diff --git a/app/code/Magento/Catalog/Model/Product/Option/SaveHandler.php b/app/code/Magento/Catalog/Model/Product/Option/SaveHandler.php index c4a2d60414a7b..d15e8ef5efa55 100644 --- a/app/code/Magento/Catalog/Model/Product/Option/SaveHandler.php +++ b/app/code/Magento/Catalog/Model/Product/Option/SaveHandler.php @@ -28,6 +28,8 @@ public function __construct( } /** + * Perform action on relation/extension attribute. + * * @param object $entity * @param array $arguments * @return \Magento\Catalog\Api\Data\ProductInterface|object @@ -35,6 +37,10 @@ public function __construct( */ public function execute($entity, $arguments = []) { + if ($entity->getOptionsSaved()) { + return $entity; + } + $options = $entity->getOptions(); $optionIds = []; diff --git a/app/code/Magento/Catalog/Plugin/Model/Product/Option/UpdateProductCustomOptionsAttributes.php b/app/code/Magento/Catalog/Plugin/Model/Product/Option/UpdateProductCustomOptionsAttributes.php new file mode 100644 index 0000000000000..2d25bd695763e --- /dev/null +++ b/app/code/Magento/Catalog/Plugin/Model/Product/Option/UpdateProductCustomOptionsAttributes.php @@ -0,0 +1,58 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Catalog\Plugin\Model\Product\Option; + +/** + * Plugin for updating product 'has_options' and 'required_options' attributes. + */ +class UpdateProductCustomOptionsAttributes +{ + /** + * @var \Magento\Catalog\Api\ProductRepositoryInterface + */ + private $productRepository; + + /** + * @param \Magento\Catalog\Api\ProductRepositoryInterface $productRepository + */ + public function __construct(\Magento\Catalog\Api\ProductRepositoryInterface $productRepository) + { + $this->productRepository = $productRepository; + } + + /** + * Update product 'has_options' and 'required_options' attributes after option save. + * + * @param \Magento\Catalog\Api\ProductCustomOptionRepositoryInterface $subject + * @param \Magento\Catalog\Api\Data\ProductCustomOptionInterface $option + * + * @return \Magento\Catalog\Api\Data\ProductCustomOptionInterface + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function afterSave( + \Magento\Catalog\Api\ProductCustomOptionRepositoryInterface $subject, + \Magento\Catalog\Api\Data\ProductCustomOptionInterface $option + ) { + $product = $this->productRepository->get($option->getProductSku()); + if (!$product->getHasOptions() + || ($option->getIsRequire() + && !$product->getRequiredOptions()) + ) { + $product->setCanSaveCustomOptions(true); + $product->setOptionsSaved(true); + $currentOptions = array_filter($product->getOptions(), function ($iOption) use ($option) { + return $option->getOptionId() != $iOption->getOptionId(); + }); + $currentOptions[] = $option; + $product->setOptions($currentOptions); + $product->save(); + } + + return $option; + } +} diff --git a/app/code/Magento/Catalog/etc/webapi_rest/di.xml b/app/code/Magento/Catalog/etc/webapi_rest/di.xml index 49c5eff91ee49..7c86c1f2e3929 100644 --- a/app/code/Magento/Catalog/etc/webapi_rest/di.xml +++ b/app/code/Magento/Catalog/etc/webapi_rest/di.xml @@ -20,4 +20,7 @@ <plugin name="get_catalog_category_product_index_table_name" type="Magento\Catalog\Model\Indexer\Category\Product\Plugin\TableResolver"/> <plugin name="get_catalog_product_price_index_table_name" type="Magento\Catalog\Model\Indexer\Product\Price\Plugin\TableResolver"/> </type> + <type name="Magento\Catalog\Api\ProductCustomOptionRepositoryInterface"> + <plugin name="updateProductCustomOptionsAttributes" type="Magento\Catalog\Plugin\Model\Product\Option\UpdateProductCustomOptionsAttributes"/> + </type> </config> diff --git a/app/code/Magento/Catalog/etc/webapi_soap/di.xml b/app/code/Magento/Catalog/etc/webapi_soap/di.xml index 2a5d60222e9f8..44cdd473bf74e 100644 --- a/app/code/Magento/Catalog/etc/webapi_soap/di.xml +++ b/app/code/Magento/Catalog/etc/webapi_soap/di.xml @@ -19,4 +19,7 @@ <plugin name="get_catalog_category_product_index_table_name" type="Magento\Catalog\Model\Indexer\Category\Product\Plugin\TableResolver"/> <plugin name="get_catalog_product_price_index_table_name" type="Magento\Catalog\Model\Indexer\Product\Price\Plugin\TableResolver"/> </type> + <type name="Magento\Catalog\Api\ProductCustomOptionRepositoryInterface"> + <plugin name="updateProductCustomOptionsAttributes" type="Magento\Catalog\Plugin\Model\Product\Option\UpdateProductCustomOptionsAttributes"/> + </type> </config> diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductCustomOptionRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductCustomOptionRepositoryTest.php index 1927d967a181c..5cffcea0fa832 100644 --- a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductCustomOptionRepositoryTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductCustomOptionRepositoryTest.php @@ -5,32 +5,38 @@ * See COPYING.txt for license details. */ -// @codingStandardsIgnoreFile - namespace Magento\Catalog\Api; +use Magento\Catalog\Model\ProductFactory; use Magento\Catalog\Model\ProductRepository; +use Magento\Framework\ObjectManagerInterface; use Magento\TestFramework\Helper\Bootstrap; use Magento\TestFramework\TestCase\WebapiAbstract; class ProductCustomOptionRepositoryTest extends WebapiAbstract { /** - * @var \Magento\Framework\ObjectManagerInterface + * @var ObjectManagerInterface */ protected $objectManager; const SERVICE_NAME = 'catalogProductCustomOptionRepositoryV1'; /** - * @var \Magento\Catalog\Model\ProductFactory + * @var ProductFactory */ protected $productFactory; + /** + * @var ProductRepository + */ + private $productRepository; + protected function setUp() { - $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); - $this->productFactory = $this->objectManager->get(\Magento\Catalog\Model\ProductFactory::class); + $this->objectManager = Bootstrap::getObjectManager(); + $this->productFactory = $this->objectManager->get(ProductFactory::class); + $this->productRepository = $this->objectManager->create(ProductRepository::class); } /** @@ -40,12 +46,8 @@ protected function setUp() public function testRemove() { $sku = 'simple'; - /** @var ProductRepository $productRepository */ - $productRepository = $this->objectManager->create( - \Magento\Catalog\Model\ProductRepository::class - ); - /** @var \Magento\Catalog\Model\Product $product */ - $product = $productRepository->get($sku, false, null, true); + /** @var \Magento\Catalog\Model\Product $product */ + $product = $this->productRepository->get($sku, false, null, true); $customOptions = $product->getOptions(); $optionId = array_pop($customOptions)->getId(); $serviceInfo = [ @@ -60,8 +62,8 @@ public function testRemove() ], ]; $this->assertTrue($this->_webApiCall($serviceInfo, ['sku' => $sku, 'optionId' => $optionId])); - /** @var \Magento\Catalog\Model\Product $product */ - $product = $productRepository->get($sku, false, null, true); + /** @var \Magento\Catalog\Model\Product $product */ + $product = $this->productRepository->get($sku, false, null, true); $this->assertNull($product->getOptionById($optionId)); $this->assertEquals(9, count($product->getOptions())); } @@ -164,6 +166,7 @@ public function testSave($optionData) ]; $result = $this->_webApiCall($serviceInfo, ['option' => $optionDataPost]); + $product = $this->productRepository->get($productSku); unset($result['product_sku']); unset($result['option_id']); if (!empty($result['values'])) { @@ -172,6 +175,10 @@ public function testSave($optionData) } } $this->assertEquals($optionData, $result); + $this->assertTrue($product->getHasOptions() == 1); + if ($optionDataPost['is_require']) { + $this->assertTrue($product->getRequiredOptions() == 1); + } } public function optionDataProvider() @@ -182,7 +189,7 @@ public function optionDataProvider() $fixtureOptions[$item['type']] = [ 'optionData' => $item, ]; - }; + } return $fixtureOptions; } @@ -191,6 +198,7 @@ public function optionDataProvider() * @magentoApiDataFixture Magento/Catalog/_files/product_without_options.php * @magentoAppIsolation enabled * @dataProvider optionNegativeDataProvider + * @param array $optionData */ public function testAddNegative($optionData) { @@ -244,12 +252,7 @@ public function optionNegativeDataProvider() public function testUpdate() { $productSku = 'simple'; - /** @var ProductRepository $productRepository */ - $productRepository = $this->objectManager->create( - \Magento\Catalog\Model\ProductRepository::class - ); - - $options = $productRepository->get($productSku, true)->getOptions(); + $options = $this->productRepository->get($productSku, true)->getOptions(); $option = array_shift($options); $optionId = $option->getOptionId(); $optionDataPost = [ @@ -292,11 +295,10 @@ public function testUpdate() } /** - * @param string $optionType - * * @magentoApiDataFixture Magento/Catalog/_files/product_with_options.php * @magentoAppIsolation enabled * @dataProvider validOptionDataProvider + * @param string $optionType * @SuppressWarnings(PHPMD.UnusedLocalVariable) */ public function testUpdateOptionAddingNewValue($optionType) @@ -310,14 +312,10 @@ public function testUpdateOptionAddingNewValue($optionType) 'sort_order' => 100, ]; - /** @var ProductRepository $productRepository */ - $productRepository = $this->objectManager->create( - \Magento\Catalog\Model\ProductRepository::class - ); - /** @var \Magento\Catalog\Model\Product $product */ - $product = $productRepository->get('simple', false, null, true); + /** @var \Magento\Catalog\Model\Product $product */ + $product = $this->productRepository->get('simple', false, null, true); - /**@var $option \Magento\Catalog\Model\Product\Option */ + /** @var \Magento\Catalog\Model\Product\Option $option */ foreach ($product->getOptions() as $option) { if ($option->getType() == $optionType) { $fixtureOption = $option; @@ -361,7 +359,7 @@ public function testUpdateOptionAddingNewValue($optionType) $data['option_id'] = $fixtureOption->getId(); $valueObject = $this->_webApiCall( $serviceInfo, - [ 'option_id' => $fixtureOption->getId(), 'option' => $data] + ['option_id' => $fixtureOption->getId(), 'option' => $data] ); } else { $valueObject = $this->_webApiCall($serviceInfo, ['option' => $data]); @@ -397,9 +395,7 @@ public function testUpdateNegative($optionData, $message, $exceptionCode) { $this->_markTestAsRestOnly(); $productSku = 'simple'; - /** @var ProductRepository $productRepository */ - $productRepository = $this->objectManager->create(ProductRepository::class); - $options = $productRepository->get($productSku, true)->getOptions(); + $options = $this->productRepository->get($productSku, true)->getOptions(); $option = array_shift($options); $optionId = $option->getOptionId(); From d16f704fe32ee28e6ef989e5733b284eede1a9ac Mon Sep 17 00:00:00 2001 From: Stas Kozar <stas.kozar@transoftgroup.com> Date: Thu, 14 Feb 2019 16:34:14 +0200 Subject: [PATCH 105/315] MAGETWO-94147: Swatch Attribute is not displayed in the Widget CMS --- .../Magento/CatalogWidget/Block/Product/ProductsList.php | 5 ----- 1 file changed, 5 deletions(-) diff --git a/app/code/Magento/CatalogWidget/Block/Product/ProductsList.php b/app/code/Magento/CatalogWidget/Block/Product/ProductsList.php index f5a69418c5938..6a89bf23c3c7d 100644 --- a/app/code/Magento/CatalogWidget/Block/Product/ProductsList.php +++ b/app/code/Magento/CatalogWidget/Block/Product/ProductsList.php @@ -108,11 +108,6 @@ class ProductsList extends \Magento\Catalog\Block\Product\AbstractProduct implem */ private $urlEncoder; - /** - * @var \Magento\Framework\View\Element\RendererList - */ - private $rendererListBlock; - /** * @param \Magento\Catalog\Block\Product\Context $context * @param \Magento\Catalog\Model\ResourceModel\Product\CollectionFactory $productCollectionFactory From 079d5d5f99f1cd6db5d03fb1adba3e685fd3b8f9 Mon Sep 17 00:00:00 2001 From: Pratik Oza <magepratik@gmail.com> Date: Thu, 14 Feb 2019 20:12:09 +0530 Subject: [PATCH 106/315] Fixed product advanced pricing design issue --- app/code/Magento/Ui/view/base/web/templates/form/field.html | 4 ++-- .../Magento/backend/web/css/source/forms/_fields.less | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Ui/view/base/web/templates/form/field.html b/app/code/Magento/Ui/view/base/web/templates/form/field.html index ed84e158819a2..6a095b4da14ed 100644 --- a/app/code/Magento/Ui/view/base/web/templates/form/field.html +++ b/app/code/Magento/Ui/view/base/web/templates/form/field.html @@ -8,8 +8,8 @@ visible="visible" css="$data.additionalClasses" attr="'data-index': index"> - <div class="admin__field-label"> - <label if="$data.label" visible="$data.labelVisible" attr="for: uid"> + <div class="admin__field-label" visible="$data.labelVisible"> + <label if="$data.label" attr="for: uid"> <span translate="label" attr="'data-config-scope': $data.scopeLabel" /> </label> </div> diff --git a/app/design/adminhtml/Magento/backend/web/css/source/forms/_fields.less b/app/design/adminhtml/Magento/backend/web/css/source/forms/_fields.less index 41aff7796090d..5879c397e6bee 100644 --- a/app/design/adminhtml/Magento/backend/web/css/source/forms/_fields.less +++ b/app/design/adminhtml/Magento/backend/web/css/source/forms/_fields.less @@ -527,7 +527,6 @@ & > .admin__field-label { #mix-grid .column(@field-label-grid__column, @field-grid__columns); - background: @color-white; cursor: pointer; left: 0; position: absolute; From 7d8ee689643bbee0445379aa64e242c7b0592050 Mon Sep 17 00:00:00 2001 From: Stas Kozar <stas.kozar@transoftgroup.com> Date: Thu, 14 Feb 2019 16:56:58 +0200 Subject: [PATCH 107/315] MAGETWO-94147: Swatch Attribute is not displayed in the Widget CMS --- app/code/Magento/CatalogWidget/Block/Product/ProductsList.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/code/Magento/CatalogWidget/Block/Product/ProductsList.php b/app/code/Magento/CatalogWidget/Block/Product/ProductsList.php index 6a89bf23c3c7d..3c8599133588b 100644 --- a/app/code/Magento/CatalogWidget/Block/Product/ProductsList.php +++ b/app/code/Magento/CatalogWidget/Block/Product/ProductsList.php @@ -173,6 +173,7 @@ protected function _construct() * Get key pieces for caching block content * * @return array + * @SuppressWarnings(PHPMD.RequestAwareBlockMethod) */ public function getCacheKeyInfo() { @@ -278,6 +279,7 @@ protected function _beforeToHtml() * Prepare and return product collection * * @return \Magento\Catalog\Model\ResourceModel\Product\Collection + * @SuppressWarnings(PHPMD.RequestAwareBlockMethod) */ public function createCollection() { From 69972709ad74896c4d3d5ce28020e07571aeb8fa Mon Sep 17 00:00:00 2001 From: Myroslav Dobra <dmaraptor@gmail.com> Date: Thu, 14 Feb 2019 17:51:06 +0200 Subject: [PATCH 108/315] MAGETWO-96636: MFTF test fix --- .../Test/Mftf/ActionGroup/AdminCreditMemoActionGroup.xml | 3 ++- .../Test/Mftf/Section/AdminCreditMemoItemsSection.xml | 2 +- .../Test/Mftf/Section/AdminCreditMemoTotalSection.xml | 6 ++---- .../Test/AdminAbleToShipPartiallyInvoicedItemsTest.xml | 2 +- .../Test/Mftf/Test/AdminCheckingCreditMemoTotalsTest.xml | 9 ++------- 5 files changed, 8 insertions(+), 14 deletions(-) diff --git a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminCreditMemoActionGroup.xml b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminCreditMemoActionGroup.xml index 7197afb4a20df..de1ed79db81ad 100644 --- a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminCreditMemoActionGroup.xml +++ b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminCreditMemoActionGroup.xml @@ -12,12 +12,13 @@ <click selector="{{AdminOrderDetailsMainActionsSection.creditMemo}}" stepKey="clickCreditMemoButton"/> <conditionalClick selector="{{AdminConfirmationModalSection.ok}}" dependentSelector="{{AdminConfirmationModalSection.ok}}" visible="true" stepKey="acceptModal"/> + <waitForPageLoad time="30" stepKey="waitPageLoaded"/> <seeInCurrentUrl url="{{AdminCreditMemoNewPage.url}}" stepKey="seeNewCreditMemoUrl"/> <see selector="{{AdminHeaderSection.pageTitle}}" userInput="New Memo" stepKey="seeNewCreditMemoPageTitle"/> </actionGroup> <actionGroup name="SubmitCreditMemo"> - <waitForElementNotVisible selector="{{AdminCreditMemoTotalSection.submitRefundOfflineDisabled}}" stepKey="waitButtonEnabled"/> + <waitForElementVisible selector="{{AdminCreditMemoTotalSection.submitRefundOffline}}" stepKey="waitButtonEnabled"/> <click selector="{{AdminCreditMemoTotalSection.submitRefundOffline}}" stepKey="clickSubmitCreditMemo"/> <waitForElementVisible selector="{{AdminMessagesSection.successMessage}}" stepKey="waitForMessageAppears"/> <see selector="{{AdminMessagesSection.successMessage}}" userInput="You created the credit memo." stepKey="seeCreditMemoCreateSuccess"/> diff --git a/app/code/Magento/Sales/Test/Mftf/Section/AdminCreditMemoItemsSection.xml b/app/code/Magento/Sales/Test/Mftf/Section/AdminCreditMemoItemsSection.xml index 496fae2b548a7..15d4df39416f2 100644 --- a/app/code/Magento/Sales/Test/Mftf/Section/AdminCreditMemoItemsSection.xml +++ b/app/code/Magento/Sales/Test/Mftf/Section/AdminCreditMemoItemsSection.xml @@ -10,6 +10,6 @@ xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> <section name="AdminCreditMemoItemsSection"> <element name="itemQtyToRefund" type="input" selector=".order-creditmemo-tables tbody:nth-of-type({{row}}) .col-refund .qty-input" parameterized="true"/> - <element name="updateQty" type="button" selector=".order-creditmemo-tables tfoot button[data-ui-id='order-items-update-button']" timeout="30"/> + <element name="updateQty" type="button" selector=".order-creditmemo-tables tfoot button[data-ui-id='order-items-update-button']:not([class~='disabled'])" timeout="30"/> </section> </sections> diff --git a/app/code/Magento/Sales/Test/Mftf/Section/AdminCreditMemoTotalSection.xml b/app/code/Magento/Sales/Test/Mftf/Section/AdminCreditMemoTotalSection.xml index 73ea29836e242..e087873fe62c2 100644 --- a/app/code/Magento/Sales/Test/Mftf/Section/AdminCreditMemoTotalSection.xml +++ b/app/code/Magento/Sales/Test/Mftf/Section/AdminCreditMemoTotalSection.xml @@ -11,10 +11,8 @@ <section name="AdminCreditMemoTotalSection"> <element name="total" type="text" selector="//table[contains(@class,'order-subtotal-table')]/tbody/tr/td[contains(text(), '{{total}}')]/following-sibling::td/span/span[contains(@class, 'price')]" parameterized="true"/> <element name="refundShipping" type="input" selector=".order-subtotal-table tbody input[name='creditmemo[shipping_amount]']"/> - <element name="updateTotals" type="button" selector=".update-totals-button" timeout="30"/> - <element name="submitRefundOffline" type="button" selector=".order-totals-actions button[title='Refund Offline']" timeout="30"/> - <element name="submitRefundOfflineEnabled" type="button" selector=".order-totals-actions button[data-ui-id='order-items-submit-button'].action-default.scalable.save.submit-button.primary']" timeout="30"/> + <element name="updateTotals" type="button" selector="button[class~='update-totals-button']:not([class~='disabled'])" timeout="30"/> + <element name="submitRefundOffline" type="button" selector=".order-totals-actions button[title='Refund Offline']:not([class~='disabled'])" timeout="30"/> <element name="adjustmentRefund" type="input" selector=".order-subtotal-table tbody input[name='creditmemo[adjustment_positive]']"/> - <element name="submitRefundOfflineDisabled" type="button" selector="//*[@class='order-totals-actions']//button[@title='Refund Offline' and contains(@class, 'disabled')]" timeout="30"/> </section> </sections> diff --git a/app/code/Magento/Sales/Test/Mftf/Test/AdminAbleToShipPartiallyInvoicedItemsTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/AdminAbleToShipPartiallyInvoicedItemsTest.xml index cb761dc358abb..1abb23ebddba0 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/AdminAbleToShipPartiallyInvoicedItemsTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/AdminAbleToShipPartiallyInvoicedItemsTest.xml @@ -119,7 +119,7 @@ <!--Submit refund--> <scrollTo selector="{{AdminCreditMemoItemsSection.itemQtyToRefund('1')}}" stepKey="scrollToItemsToRefund"/> <seeInField selector="{{AdminCreditMemoItemsSection.itemQtyToRefund('1')}}" userInput="5" after="scrollToItemsToRefund" stepKey="checkQtyOfItemsToRefund"/> - <waitForElementVisible selector="{{AdminCreditMemoTotalSection.submitRefundOfflineEnabled}}" stepKey="waitForSubmitRefundOfflineEnabled"/> + <waitForElementVisible selector="{{AdminCreditMemoTotalSection.submitRefundOffline}}" stepKey="waitForSubmitRefundOfflineEnabled"/> <click selector="{{AdminCreditMemoTotalSection.submitRefundOffline}}" stepKey="submitRefundOffline"/> <!--Verify Credit Memo created successfully--> <waitForElementVisible diff --git a/app/code/Magento/Sales/Test/Mftf/Test/AdminCheckingCreditMemoTotalsTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/AdminCheckingCreditMemoTotalsTest.xml index b73c66d49d690..e9fff90bdd632 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/AdminCheckingCreditMemoTotalsTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/AdminCheckingCreditMemoTotalsTest.xml @@ -91,15 +91,10 @@ <click selector="{{AdminOrderInvoiceViewMainActionsSection.creditMemo}}" stepKey="clickCreditMemo"/> <see selector="{{AdminHeaderSection.pageTitle}}" userInput="New Memo" stepKey="seeNewMemoPageTitle"/> <fillField selector="{{AdminCreditMemoTotalSection.refundShipping}}" userInput="0" stepKey="setRefundShipping"/> + <waitForElementVisible selector="{{AdminCreditMemoTotalSection.updateTotals}}" time="30" stepKey="waitUpdateTotalsButtonEnabled"/> <click selector="{{AdminCreditMemoTotalSection.updateTotals}}" stepKey="clickUpdateTotals"/> <waitForLoadingMaskToDisappear stepKey="waitForUpdateTotals"/> - <click selector="{{AdminCreditMemoTotalSection.submitRefundOffline}}" stepKey="clickRefundOffline"/> - <waitForElementVisible - selector="{{AdminMessagesSection.success}}" - time="10" - stepKey="waitForMessage"/> - <see selector="{{AdminMessagesSection.success}}" userInput="You created the credit memo." - stepKey="seeCreatedCreditMemoSuccessMessage"/> + <actionGroup ref="SubmitCreditMemo" stepKey="submitCreditMemo"/> <!--Go to Credit Memo tab--> <click selector="{{AdminOrderViewTabsSection.creditMemos}}" stepKey="clickCreditMemosTab"/> From 544d99c4a30f0e89604fd2ef78dc3c6f1edb96c7 Mon Sep 17 00:00:00 2001 From: eduard13 <e.chitoraga@atwix.com> Date: Sat, 9 Feb 2019 15:56:46 +0200 Subject: [PATCH 109/315] Fixing compare block product removing action from sidebar --- .../luma/Magento_Catalog/web/css/source/_module.less | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/app/design/frontend/Magento/luma/Magento_Catalog/web/css/source/_module.less b/app/design/frontend/Magento/luma/Magento_Catalog/web/css/source/_module.less index 6aa0e50f3c393..4bf41343919d0 100644 --- a/app/design/frontend/Magento/luma/Magento_Catalog/web/css/source/_module.less +++ b/app/design/frontend/Magento/luma/Magento_Catalog/web/css/source/_module.less @@ -534,6 +534,15 @@ } } + .block-compare { + .action { + &.delete { + &:extend(.abs-remove-button-for-blocks all); + right: initial; + } + } + } + .action.tocart { border-radius: 0; } From d77bc6acaccaecddc4bda3415d268ed21ef94981 Mon Sep 17 00:00:00 2001 From: gauravagarwal1001 <37572719+gauravagarwal1001@users.noreply.github.com> Date: Tue, 12 Feb 2019 14:38:45 +0530 Subject: [PATCH 110/315] Updated Account.php --- .../Magento/Sales/Block/Adminhtml/Order/Create/Form/Account.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Sales/Block/Adminhtml/Order/Create/Form/Account.php b/app/code/Magento/Sales/Block/Adminhtml/Order/Create/Form/Account.php index b61a5cf83734b..dc93e8ba8417c 100644 --- a/app/code/Magento/Sales/Block/Adminhtml/Order/Create/Form/Account.php +++ b/app/code/Magento/Sales/Block/Adminhtml/Order/Create/Form/Account.php @@ -199,7 +199,7 @@ private function extractValuesFromAttributes(array $attributes, int $storeId): a if (isset($defaultValue) && !isset($formValues[$code])) { $formValues[$code] = $defaultValue; } - if ($code === 'group_id' && empty($defaultValue)) { + if ($code === 'group_id' && empty($formValues[$code])) { $formValues[$code] = $this->getDefaultCustomerGroup($storeId); } } From 16f096cac91bbcae3d2dae2d18a4d0f8095a337e Mon Sep 17 00:00:00 2001 From: Nainesh <nainesh@2jcommerce.in> Date: Thu, 7 Feb 2019 16:11:21 +0530 Subject: [PATCH 111/315] quantity-not-center-align-on-review-order --- .../Magento_Multishipping/web/css/source/_module.less | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/app/design/frontend/Magento/luma/Magento_Multishipping/web/css/source/_module.less b/app/design/frontend/Magento/luma/Magento_Multishipping/web/css/source/_module.less index 9761f36b96344..7fe2f2c58e655 100644 --- a/app/design/frontend/Magento/luma/Magento_Multishipping/web/css/source/_module.less +++ b/app/design/frontend/Magento/luma/Magento_Multishipping/web/css/source/_module.less @@ -345,6 +345,15 @@ .data.table { &:extend(.abs-checkout-order-review all); + &.table-order-review { + > tbody { + > tr { + > td.col.qty { + text-align: center; + } + } + } + } } } From d893e08e7fc2db2032d559e4f2a97ef36368cd64 Mon Sep 17 00:00:00 2001 From: Nainesh <nainesh@2jcommerce.in> Date: Thu, 7 Feb 2019 17:12:25 +0530 Subject: [PATCH 112/315] quantity-not-center-align-on-review-order --- .../Magento_Multishipping/web/css/source/_module.less | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/app/design/frontend/Magento/luma/Magento_Multishipping/web/css/source/_module.less b/app/design/frontend/Magento/luma/Magento_Multishipping/web/css/source/_module.less index 7fe2f2c58e655..7977fb16c524c 100644 --- a/app/design/frontend/Magento/luma/Magento_Multishipping/web/css/source/_module.less +++ b/app/design/frontend/Magento/luma/Magento_Multishipping/web/css/source/_module.less @@ -348,8 +348,15 @@ &.table-order-review { > tbody { > tr { - > td.col.qty { - text-align: center; + > td { + &.col { + &.subtotal { + border-bottom: none; + } + &.qty { + text-align: center; + } + } } } } From 512430af08837ba1ef8d8d4a598a98db90b47636 Mon Sep 17 00:00:00 2001 From: Arvinda kumar <arvindakumar@cedcommerce.com> Date: Wed, 6 Feb 2019 14:03:31 +0530 Subject: [PATCH 113/315] issue fixed #20919 Email label and email field not aligned from left for reorder of guest user issue fixed #20919 Email label and email field not aligned from left for reorder of guest user --- .../css/source/module/order/_order-account.less | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/module/order/_order-account.less b/app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/module/order/_order-account.less index e14bcbcddd47f..5494cf46c6f9d 100644 --- a/app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/module/order/_order-account.less +++ b/app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/module/order/_order-account.less @@ -27,3 +27,18 @@ width: 50%; } } +.page-create-order { + .order-details { + &:not(.order-details-existing-customer) { + .order-account-information { + .field-email { + margin-left: -30px; + } + + .field-group_id { + margin-right: 30px; + } + } + } + } +} From c1057381bcde28433edfafe62d339405facd7139 Mon Sep 17 00:00:00 2001 From: Arvinda kumar <arvindakumar@cedcommerce.com> Date: Wed, 6 Feb 2019 09:53:28 -0800 Subject: [PATCH 114/315] _order-account.less updated _order-account.less updated --- .../web/css/source/module/order/_order-account.less | 1 + 1 file changed, 1 insertion(+) diff --git a/app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/module/order/_order-account.less b/app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/module/order/_order-account.less index 5494cf46c6f9d..f66e94940c55d 100644 --- a/app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/module/order/_order-account.less +++ b/app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/module/order/_order-account.less @@ -27,6 +27,7 @@ width: 50%; } } + .page-create-order { .order-details { &:not(.order-details-existing-customer) { From 573072bb73aca09240a55933eb4e232e0df62d52 Mon Sep 17 00:00:00 2001 From: Parag Chavare <parag@2jcommerce.in> Date: Mon, 4 Feb 2019 16:55:00 +0530 Subject: [PATCH 115/315] bundle-product-table-data-grouped-alignment :: Bundle product table data grouped alignment in mobile view --- .../web/css/source/_module.less | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/app/design/frontend/Magento/luma/Magento_GroupedProduct/web/css/source/_module.less b/app/design/frontend/Magento/luma/Magento_GroupedProduct/web/css/source/_module.less index 088372808aa6a..ef323eab94e68 100644 --- a/app/design/frontend/Magento/luma/Magento_GroupedProduct/web/css/source/_module.less +++ b/app/design/frontend/Magento/luma/Magento_GroupedProduct/web/css/source/_module.less @@ -133,10 +133,19 @@ } .media-width(@extremum, @break) when (@extremum = 'max') and (@break = @screen__m) { + .product-add-form{ .table-wrapper.grouped { - .lib-css(margin-left, -@layout__width-xs-indent); - .lib-css(margin-right, -@layout__width-xs-indent); + .lib-css(margin-left, -@layout__width-xs-indent); + .lib-css(margin-right, -@layout__width-xs-indent); + .table.data.grouped{ + tr{ + td{ + padding: 5px 10px 5px 15px; + } + } + } } + } } // From 30d4e283b4555b35cb63cfd34ca3895ae0f7d43a Mon Sep 17 00:00:00 2001 From: Pavel Bystritsky <p.bystritsky@yandex.ru> Date: Tue, 5 Feb 2019 15:41:33 +0200 Subject: [PATCH 116/315] ENGCOM-4111: Static test fixed. --- .../web/css/source/_module.less | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/app/design/frontend/Magento/luma/Magento_GroupedProduct/web/css/source/_module.less b/app/design/frontend/Magento/luma/Magento_GroupedProduct/web/css/source/_module.less index ef323eab94e68..fe49d6679a613 100644 --- a/app/design/frontend/Magento/luma/Magento_GroupedProduct/web/css/source/_module.less +++ b/app/design/frontend/Magento/luma/Magento_GroupedProduct/web/css/source/_module.less @@ -133,19 +133,19 @@ } .media-width(@extremum, @break) when (@extremum = 'max') and (@break = @screen__m) { - .product-add-form{ - .table-wrapper.grouped { - .lib-css(margin-left, -@layout__width-xs-indent); - .lib-css(margin-right, -@layout__width-xs-indent); - .table.data.grouped{ - tr{ - td{ - padding: 5px 10px 5px 15px; - } + .product-add-form { + .table-wrapper.grouped { + .lib-css(margin-left, -@layout__width-xs-indent); + .lib-css(margin-right, -@layout__width-xs-indent); + .table.data.grouped { + tr { + td { + padding: 5px 10px 5px 15px; + } + } + } } - } } - } } // From 4b07a5c8806a22758c46d17d4493de2c3c362044 Mon Sep 17 00:00:00 2001 From: priti <priti@2jcommerce.in> Date: Tue, 22 Jan 2019 16:59:10 +0530 Subject: [PATCH 117/315] view-order-price-subtotal-alignment-not-proper-mobile --- .../Magento/luma/Magento_Sales/web/css/source/_module.less | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/design/frontend/Magento/luma/Magento_Sales/web/css/source/_module.less b/app/design/frontend/Magento/luma/Magento_Sales/web/css/source/_module.less index 1e4a92fa0701f..c8bdc56621f7b 100644 --- a/app/design/frontend/Magento/luma/Magento_Sales/web/css/source/_module.less +++ b/app/design/frontend/Magento/luma/Magento_Sales/web/css/source/_module.less @@ -503,6 +503,11 @@ } } } + .order-items.table-wrapper { + .col.price, .col.qty, .col.subtotal, .col.msrp { + text-align: left; + } + } } .media-width(@extremum, @break) when (@extremum = 'max') and (@break = @screen__m) { From ef4cdb62bc1044e2f2fcb402465f7f8b5b92f52a Mon Sep 17 00:00:00 2001 From: priti <priti@2jcommerce.in> Date: Tue, 22 Jan 2019 19:50:13 +0530 Subject: [PATCH 118/315] view-order-price-subtotal-alignment-not-proper-mobile --- .../Magento/blank/Magento_Sales/web/css/source/_module.less | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/design/frontend/Magento/blank/Magento_Sales/web/css/source/_module.less b/app/design/frontend/Magento/blank/Magento_Sales/web/css/source/_module.less index 1ea1e2c483d0b..a85820ab441e9 100644 --- a/app/design/frontend/Magento/blank/Magento_Sales/web/css/source/_module.less +++ b/app/design/frontend/Magento/blank/Magento_Sales/web/css/source/_module.less @@ -294,6 +294,11 @@ } } } + .order-items.table-wrapper { + .col.price, .col.qty, .col.subtotal, .col.msrp { + text-align: left; + } + } } .media-width(@extremum, @break) when (@extremum = 'max') and (@break = @screen__m) { From e956712022174e1eaf46b152b25b60e98515e674 Mon Sep 17 00:00:00 2001 From: priti <priti@2jcommerce.in> Date: Thu, 31 Jan 2019 12:31:40 +0530 Subject: [PATCH 119/315] view-order-price-subtotal-alignment-not-proper-mobile --- .../Magento/luma/Magento_Sales/web/css/source/_module.less | 5 ----- 1 file changed, 5 deletions(-) diff --git a/app/design/frontend/Magento/luma/Magento_Sales/web/css/source/_module.less b/app/design/frontend/Magento/luma/Magento_Sales/web/css/source/_module.less index c8bdc56621f7b..1e4a92fa0701f 100644 --- a/app/design/frontend/Magento/luma/Magento_Sales/web/css/source/_module.less +++ b/app/design/frontend/Magento/luma/Magento_Sales/web/css/source/_module.less @@ -503,11 +503,6 @@ } } } - .order-items.table-wrapper { - .col.price, .col.qty, .col.subtotal, .col.msrp { - text-align: left; - } - } } .media-width(@extremum, @break) when (@extremum = 'max') and (@break = @screen__m) { From 597c4af3d5ea9b47200108adac46909d95a3b808 Mon Sep 17 00:00:00 2001 From: Pavel Bystritsky <p.bystritsky@yandex.ru> Date: Mon, 4 Feb 2019 12:38:59 +0200 Subject: [PATCH 120/315] ENGCOM-4069: Static test fix. --- .../Magento/blank/Magento_Sales/web/css/source/_module.less | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/design/frontend/Magento/blank/Magento_Sales/web/css/source/_module.less b/app/design/frontend/Magento/blank/Magento_Sales/web/css/source/_module.less index a85820ab441e9..44eb06ac5ce19 100644 --- a/app/design/frontend/Magento/blank/Magento_Sales/web/css/source/_module.less +++ b/app/design/frontend/Magento/blank/Magento_Sales/web/css/source/_module.less @@ -295,7 +295,10 @@ } } .order-items.table-wrapper { - .col.price, .col.qty, .col.subtotal, .col.msrp { + .col.price, + .col.qty, + .col.subtotal, + .col.msrp { text-align: left; } } From 77c780d5ae54a8ec982648d6104cff6da50e35a6 Mon Sep 17 00:00:00 2001 From: Shikha Mishra <shikhamishra@cedcoss.com> Date: Sun, 3 Feb 2019 10:37:39 +0530 Subject: [PATCH 121/315] Updated Options.php --- app/code/Magento/Customer/Model/Options.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Customer/Model/Options.php b/app/code/Magento/Customer/Model/Options.php index 7747e309d82a6..19cac4a7bc326 100644 --- a/app/code/Magento/Customer/Model/Options.php +++ b/app/code/Magento/Customer/Model/Options.php @@ -91,7 +91,7 @@ private function prepareNamePrefixSuffixOptions($options, $isOptional = false) return false; } $result = []; - $options = explode(';', $options); + $options = array_filter(explode(';', $options)); foreach ($options as $value) { $value = $this->escaper->escapeHtml(trim($value)); $result[$value] = $value; From 5eeecac645d53a3c543247a1d6e6c26752ee5012 Mon Sep 17 00:00:00 2001 From: Pavel Bystritsky <p.bystritsky@yandex.ru> Date: Fri, 8 Feb 2019 15:39:40 +0200 Subject: [PATCH 122/315] ENGCOM-4146: Static test fix. --- app/code/Magento/Customer/Model/Options.php | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Customer/Model/Options.php b/app/code/Magento/Customer/Model/Options.php index 19cac4a7bc326..71e70f8e14208 100644 --- a/app/code/Magento/Customer/Model/Options.php +++ b/app/code/Magento/Customer/Model/Options.php @@ -8,7 +8,11 @@ use Magento\Config\Model\Config\Source\Nooptreq as NooptreqSource; use Magento\Customer\Helper\Address as AddressHelper; use Magento\Framework\Escaper; +use Magento\Store\Api\Data\StoreInterface; +/** + * Customer Options. + */ class Options { /** @@ -38,7 +42,7 @@ public function __construct( /** * Retrieve name prefix dropdown options * - * @param null $store + * @param null|string|bool|int|StoreInterface $store * @return array|bool */ public function getNamePrefixOptions($store = null) @@ -52,7 +56,7 @@ public function getNamePrefixOptions($store = null) /** * Retrieve name suffix dropdown options * - * @param null $store + * @param null|string|bool|int|StoreInterface $store * @return array|bool */ public function getNameSuffixOptions($store = null) @@ -64,7 +68,9 @@ public function getNameSuffixOptions($store = null) } /** - * @param $options + * Unserialize and clear name prefix or suffix options. + * + * @param string $options * @param bool $isOptional * @return array|bool * @@ -78,6 +84,7 @@ protected function _prepareNamePrefixSuffixOptions($options, $isOptional = false /** * Unserialize and clear name prefix or suffix options + * * If field is optional, add an empty first option. * * @param string $options From a47ea3820a0c3886b2a73ca8feb76a1ea3a1d1b8 Mon Sep 17 00:00:00 2001 From: "Leandro F. L" <lfluvisotto@gmail.com> Date: Sun, 27 Jan 2019 21:46:01 -0200 Subject: [PATCH 123/315] It is recommended to use the &&, || operators, instead of and, or to prevent confusion. --- .../Adminhtml/Product/Attribute/Validate.php | 2 +- .../Controller/Transparent/RequestSecureToken.php | 2 +- .../Security/Model/SecurityChecker/Quantity.php | 2 +- app/code/Magento/SendFriend/Model/SendFriend.php | 12 ++++++------ app/code/Magento/Tax/Model/Sales/Total/Quote/Tax.php | 2 +- .../testsuite/Magento/Test/Integrity/ClassesTest.php | 2 +- lib/internal/Magento/Framework/Filter/Template.php | 2 +- lib/internal/Magento/Framework/Message/Manager.php | 2 +- .../Setup/Model/ConfigOptionsList/Session.php | 2 +- 9 files changed, 14 insertions(+), 14 deletions(-) diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Validate.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Validate.php index 3a81b4633b2ff..40a2ce692e404 100644 --- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Validate.php +++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Validate.php @@ -158,7 +158,7 @@ private function isUniqueAdminValues(array $optionsValues, array $deletedOptions { $adminValues = []; foreach ($optionsValues as $optionKey => $values) { - if (!(isset($deletedOptions[$optionKey]) and $deletedOptions[$optionKey] === '1')) { + if (!(isset($deletedOptions[$optionKey]) && $deletedOptions[$optionKey] === '1')) { $adminValues[] = reset($values); } } diff --git a/app/code/Magento/Paypal/Controller/Transparent/RequestSecureToken.php b/app/code/Magento/Paypal/Controller/Transparent/RequestSecureToken.php index 2efae34a96459..a6d55c91b6105 100644 --- a/app/code/Magento/Paypal/Controller/Transparent/RequestSecureToken.php +++ b/app/code/Magento/Paypal/Controller/Transparent/RequestSecureToken.php @@ -82,7 +82,7 @@ public function execute() /** @var Quote $quote */ $quote = $this->sessionManager->getQuote(); - if (!$quote or !$quote instanceof Quote) { + if (!$quote || !$quote instanceof Quote) { return $this->getErrorResponse(); } diff --git a/app/code/Magento/Security/Model/SecurityChecker/Quantity.php b/app/code/Magento/Security/Model/SecurityChecker/Quantity.php index 7f1d85abeb74b..eb6ba6cef16bc 100644 --- a/app/code/Magento/Security/Model/SecurityChecker/Quantity.php +++ b/app/code/Magento/Security/Model/SecurityChecker/Quantity.php @@ -53,7 +53,7 @@ public function check($securityEventType, $accountReference = null, $longIp = nu { $isEnabled = $this->securityConfig->getPasswordResetProtectionType() != ResetMethod::OPTION_NONE; $allowedAttemptsNumber = $this->securityConfig->getMaxNumberPasswordResetRequests(); - if ($isEnabled and $allowedAttemptsNumber) { + if ($isEnabled && $allowedAttemptsNumber) { $collection = $this->prepareCollection($securityEventType, $accountReference, $longIp); if ($collection->count() >= $allowedAttemptsNumber) { throw new SecurityViolationException( diff --git a/app/code/Magento/SendFriend/Model/SendFriend.php b/app/code/Magento/SendFriend/Model/SendFriend.php index c69d6342b4892..79bac0e680952 100644 --- a/app/code/Magento/SendFriend/Model/SendFriend.php +++ b/app/code/Magento/SendFriend/Model/SendFriend.php @@ -236,7 +236,7 @@ public function validate() } $email = $this->getSender()->getEmail(); - if (empty($email) or !\Zend_Validate::is($email, \Magento\Framework\Validator\EmailAddress::class)) { + if (empty($email) || !\Zend_Validate::is($email, \Magento\Framework\Validator\EmailAddress::class)) { $errors[] = __('Invalid Sender Email'); } @@ -281,13 +281,13 @@ public function setRecipients($recipients) // validate array if (!is_array( $recipients - ) or !isset( + ) || !isset( $recipients['email'] - ) or !isset( + ) || !isset( $recipients['name'] - ) or !is_array( + ) || !is_array( $recipients['email'] - ) or !is_array( + ) || !is_array( $recipients['name'] ) ) { @@ -487,7 +487,7 @@ protected function _sentCountByCookies($increment = false) $oldTimes = explode(',', $oldTimes); foreach ($oldTimes as $oldTime) { $periodTime = $time - $this->_sendfriendData->getPeriod(); - if (is_numeric($oldTime) and $oldTime >= $periodTime) { + if (is_numeric($oldTime) && $oldTime >= $periodTime) { $newTimes[] = $oldTime; } } diff --git a/app/code/Magento/Tax/Model/Sales/Total/Quote/Tax.php b/app/code/Magento/Tax/Model/Sales/Total/Quote/Tax.php index 82e2048283a9b..94ea0417be69f 100755 --- a/app/code/Magento/Tax/Model/Sales/Total/Quote/Tax.php +++ b/app/code/Magento/Tax/Model/Sales/Total/Quote/Tax.php @@ -264,7 +264,7 @@ protected function processExtraTaxables(Address\Total $total, array $itemsByType { $extraTaxableDetails = []; foreach ($itemsByType as $itemType => $itemTaxDetails) { - if ($itemType != self::ITEM_TYPE_PRODUCT and $itemType != self::ITEM_TYPE_SHIPPING) { + if ($itemType != self::ITEM_TYPE_PRODUCT && $itemType != self::ITEM_TYPE_SHIPPING) { foreach ($itemTaxDetails as $itemCode => $itemTaxDetail) { /** @var \Magento\Tax\Api\Data\TaxDetailsInterface $taxDetails */ $taxDetails = $itemTaxDetail[self::KEY_ITEM]; diff --git a/dev/tests/static/testsuite/Magento/Test/Integrity/ClassesTest.php b/dev/tests/static/testsuite/Magento/Test/Integrity/ClassesTest.php index 5c1e342e1bc81..4b31b80f1d7b3 100644 --- a/dev/tests/static/testsuite/Magento/Test/Integrity/ClassesTest.php +++ b/dev/tests/static/testsuite/Magento/Test/Integrity/ClassesTest.php @@ -191,7 +191,7 @@ private function assertClassesExist($classes, $path) foreach ($classes as $class) { $class = trim($class, '\\'); try { - if (strrchr($class, '\\') === false and !Classes::isVirtual($class)) { + if (strrchr($class, '\\') === false && !Classes::isVirtual($class)) { $badUsages[] = $class; continue; } else { diff --git a/lib/internal/Magento/Framework/Filter/Template.php b/lib/internal/Magento/Framework/Filter/Template.php index 40799bfe0a6b5..a2e772853efcb 100644 --- a/lib/internal/Magento/Framework/Filter/Template.php +++ b/lib/internal/Magento/Framework/Filter/Template.php @@ -227,7 +227,7 @@ public function templateDirective($construction) { // Processing of {template config_path=... [...]} statement $templateParameters = $this->getParameters($construction[2]); - if (!isset($templateParameters['config_path']) or !$this->getTemplateProcessor()) { + if (!isset($templateParameters['config_path']) || !$this->getTemplateProcessor()) { // Not specified template or not set include processor $replacedValue = '{Error in template processing}'; } else { diff --git a/lib/internal/Magento/Framework/Message/Manager.php b/lib/internal/Magento/Framework/Message/Manager.php index f31892a938fb1..75b351515839c 100644 --- a/lib/internal/Magento/Framework/Message/Manager.php +++ b/lib/internal/Magento/Framework/Message/Manager.php @@ -226,7 +226,7 @@ public function addUniqueMessages(array $messages, $group = null) $items = $this->getMessages(false, $group)->getItems(); foreach ($messages as $message) { - if ($message instanceof MessageInterface and !in_array($message, $items, false)) { + if ($message instanceof MessageInterface && !in_array($message, $items, false)) { $this->addMessage($message, $group); } } diff --git a/setup/src/Magento/Setup/Model/ConfigOptionsList/Session.php b/setup/src/Magento/Setup/Model/ConfigOptionsList/Session.php index 3b3fbf33a02e2..1c64d8994630d 100644 --- a/setup/src/Magento/Setup/Model/ConfigOptionsList/Session.php +++ b/setup/src/Magento/Setup/Model/ConfigOptionsList/Session.php @@ -301,7 +301,7 @@ public function validate(array $options, DeploymentConfig $deploymentConfig) if (isset($options[self::INPUT_KEY_SESSION_REDIS_LOG_LEVEL])) { $level = $options[self::INPUT_KEY_SESSION_REDIS_LOG_LEVEL]; - if (($level < 0) or ($level > 7)) { + if (($level < 0) || ($level > 7)) { $errors[] = "Invalid Redis log level '{$level}'. Valid range is 0-7, inclusive."; } } From 30273c63f3ed6127bb58cb6d64b8b7ca7aee6c03 Mon Sep 17 00:00:00 2001 From: Pavel Bystritsky <p.bystritsky@yandex.ru> Date: Mon, 28 Jan 2019 16:50:22 +0200 Subject: [PATCH 124/315] ENGCOM-3980: Static test fix. --- .../Paypal/Controller/Transparent/RequestSecureToken.php | 2 ++ .../Magento/Security/Model/SecurityChecker/Quantity.php | 2 +- app/code/Magento/SendFriend/Model/SendFriend.php | 3 +++ app/code/Magento/Tax/Model/Sales/Total/Quote/Tax.php | 1 + lib/internal/Magento/Framework/Message/Manager.php | 2 ++ setup/src/Magento/Setup/Model/ConfigOptionsList/Session.php | 6 +++--- 6 files changed, 12 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Paypal/Controller/Transparent/RequestSecureToken.php b/app/code/Magento/Paypal/Controller/Transparent/RequestSecureToken.php index a6d55c91b6105..3738a479816b3 100644 --- a/app/code/Magento/Paypal/Controller/Transparent/RequestSecureToken.php +++ b/app/code/Magento/Paypal/Controller/Transparent/RequestSecureToken.php @@ -106,6 +106,8 @@ public function execute() } /** + * Get error response. + * * @return Json */ private function getErrorResponse() diff --git a/app/code/Magento/Security/Model/SecurityChecker/Quantity.php b/app/code/Magento/Security/Model/SecurityChecker/Quantity.php index eb6ba6cef16bc..cbf41980c51d3 100644 --- a/app/code/Magento/Security/Model/SecurityChecker/Quantity.php +++ b/app/code/Magento/Security/Model/SecurityChecker/Quantity.php @@ -47,7 +47,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function check($securityEventType, $accountReference = null, $longIp = null) { diff --git a/app/code/Magento/SendFriend/Model/SendFriend.php b/app/code/Magento/SendFriend/Model/SendFriend.php index 79bac0e680952..38525a9f83a12 100644 --- a/app/code/Magento/SendFriend/Model/SendFriend.php +++ b/app/code/Magento/SendFriend/Model/SendFriend.php @@ -16,6 +16,7 @@ * @method \Magento\SendFriend\Model\SendFriend setTime(int $value) * * @author Magento Core Team <core@magentocommerce.com> + * @SuppressWarnings(PHPMD.CookieAndSessionMisuse) * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * * @api @@ -162,6 +163,8 @@ protected function _construct() } /** + * Send email. + * * @return $this * @throws CoreException */ diff --git a/app/code/Magento/Tax/Model/Sales/Total/Quote/Tax.php b/app/code/Magento/Tax/Model/Sales/Total/Quote/Tax.php index 94ea0417be69f..865b656918cc1 100755 --- a/app/code/Magento/Tax/Model/Sales/Total/Quote/Tax.php +++ b/app/code/Magento/Tax/Model/Sales/Total/Quote/Tax.php @@ -407,6 +407,7 @@ protected function enhanceTotalData( /** * Process model configuration array. + * * This method can be used for changing totals collect sort order * * @param array $config diff --git a/lib/internal/Magento/Framework/Message/Manager.php b/lib/internal/Magento/Framework/Message/Manager.php index 75b351515839c..4e73b6112f9d8 100644 --- a/lib/internal/Magento/Framework/Message/Manager.php +++ b/lib/internal/Magento/Framework/Message/Manager.php @@ -11,6 +11,8 @@ /** * Message manager model + * + * @SuppressWarnings(PHPMD.CookieAndSessionMisuse) * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class Manager implements ManagerInterface diff --git a/setup/src/Magento/Setup/Model/ConfigOptionsList/Session.php b/setup/src/Magento/Setup/Model/ConfigOptionsList/Session.php index 1c64d8994630d..b5fbfd795363f 100644 --- a/setup/src/Magento/Setup/Model/ConfigOptionsList/Session.php +++ b/setup/src/Magento/Setup/Model/ConfigOptionsList/Session.php @@ -124,7 +124,7 @@ class Session implements ConfigOptionsListInterface ]; /** - * {@inheritdoc} + * @inheritdoc * @SuppressWarnings(PHPMD.ExcessiveMethodLength) */ public function getOptions() @@ -250,7 +250,7 @@ public function getOptions() } /** - * {@inheritdoc} + * @inheritdoc */ public function createConfig(array $options, DeploymentConfig $deploymentConfig) { @@ -281,7 +281,7 @@ public function createConfig(array $options, DeploymentConfig $deploymentConfig) } /** - * {@inheritdoc} + * @inheritdoc */ public function validate(array $options, DeploymentConfig $deploymentConfig) { From da3a606adcdce1e1f55e2e74e106cf3f67a650db Mon Sep 17 00:00:00 2001 From: Abrar pathan <abrarkhan@krishtechnolabs.com> Date: Fri, 8 Feb 2019 17:55:10 +0530 Subject: [PATCH 125/315] fixed-issue-21070 --- .../Magento_Sales/web/css/source/_module.less | 24 +++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/app/design/frontend/Magento/luma/Magento_Sales/web/css/source/_module.less b/app/design/frontend/Magento/luma/Magento_Sales/web/css/source/_module.less index 1e4a92fa0701f..815517670438a 100644 --- a/app/design/frontend/Magento/luma/Magento_Sales/web/css/source/_module.less +++ b/app/design/frontend/Magento/luma/Magento_Sales/web/css/source/_module.less @@ -555,13 +555,13 @@ margin: 0 @tab-control__margin-right 0 0; a { - padding: @tab-control__padding-top @tab-control__padding-right; + padding: @tab-control__padding-top @indent__base; } strong { border-bottom: 0; margin-bottom: -1px; - padding: @tab-control__padding-top @tab-control__padding-right @tab-control__padding-bottom + 1 @tab-control__padding-left; + padding: @tab-control__padding-top @indent__base @tab-control__padding-bottom + 1 @indent__base; } } } @@ -687,3 +687,23 @@ } } } + +.media-width(@extremum, @break) when (@extremum = 'min') and (@break = @screen__l) { + + .order-links { + .item { + margin: 0 @tab-control__margin-right 0 0; + + a { + padding: @tab-control__padding-top @tab-control__padding-right; + } + + strong { + border-bottom: 0; + margin-bottom: -1px; + padding: @tab-control__padding-top @tab-control__padding-right @tab-control__padding-bottom + 1 @tab-control__padding-left; + } + } + } + +} \ No newline at end of file From 6acd8a4c1265c3f6da08b9d7722a77d83def245f Mon Sep 17 00:00:00 2001 From: Dmytro Cheshun <d.cheshun@atwix.com> Date: Sun, 10 Feb 2019 22:59:38 +0200 Subject: [PATCH 126/315] Update _module.less Code refactoring, remove the redundant rules --- .../Magento/luma/Magento_Sales/web/css/source/_module.less | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/app/design/frontend/Magento/luma/Magento_Sales/web/css/source/_module.less b/app/design/frontend/Magento/luma/Magento_Sales/web/css/source/_module.less index 815517670438a..314f0d0ee6298 100644 --- a/app/design/frontend/Magento/luma/Magento_Sales/web/css/source/_module.less +++ b/app/design/frontend/Magento/luma/Magento_Sales/web/css/source/_module.less @@ -689,7 +689,6 @@ } .media-width(@extremum, @break) when (@extremum = 'min') and (@break = @screen__l) { - .order-links { .item { margin: 0 @tab-control__margin-right 0 0; @@ -699,11 +698,8 @@ } strong { - border-bottom: 0; - margin-bottom: -1px; padding: @tab-control__padding-top @tab-control__padding-right @tab-control__padding-bottom + 1 @tab-control__padding-left; } } } - -} \ No newline at end of file +} From caac0c28ad050f70531bd061935e56c9b93788f9 Mon Sep 17 00:00:00 2001 From: Nikita Shcherbatykh <nikita.shcherbatykh@transoftgroup.com> Date: Fri, 15 Feb 2019 10:54:38 +0200 Subject: [PATCH 127/315] MAGETWO-97684: State is always required in backend in customer address form --- .../Magento/Customer/Block/Adminhtml/Edit/Renderer/Region.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Customer/Block/Adminhtml/Edit/Renderer/Region.php b/app/code/Magento/Customer/Block/Adminhtml/Edit/Renderer/Region.php index 9a025211c9b0a..0aeed1562c51e 100644 --- a/app/code/Magento/Customer/Block/Adminhtml/Edit/Renderer/Region.php +++ b/app/code/Magento/Customer/Block/Adminhtml/Edit/Renderer/Region.php @@ -48,7 +48,7 @@ public function render(\Magento\Framework\Data\Form\Element\AbstractElement $ele $regionId = $element->getForm()->getElement('region_id')->getValue(); - $html = '<div class="field field-state required admin__field _required">'; + $html = '<div class="field field-state admin__field">'; $element->setClass('input-text admin__control-text'); $element->setRequired(true); $html .= $element->getLabelHtml() . '<div class="control admin__field-control">'; From 46572afd1a9f142958207718311dad47b667d606 Mon Sep 17 00:00:00 2001 From: Vasilii <v.burlacu@atwix.com> Date: Wed, 23 Jan 2019 11:38:32 +0200 Subject: [PATCH 128/315] magento/magento2#18347 - Element 'css', attribute 'as': The attribute 'as' is not allowed. (CSS preloading) - Added as attribute to linkType with 3 possible options: style, script and font --- lib/internal/Magento/Framework/View/Layout/etc/head.xsd | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/lib/internal/Magento/Framework/View/Layout/etc/head.xsd b/lib/internal/Magento/Framework/View/Layout/etc/head.xsd index a913507ae17b3..15762dc2f0ae6 100644 --- a/lib/internal/Magento/Framework/View/Layout/etc/head.xsd +++ b/lib/internal/Magento/Framework/View/Layout/etc/head.xsd @@ -20,6 +20,15 @@ <xs:attribute name="type" type="xs:string"/> <xs:attribute name="order" type="xs:integer"/> <xs:attribute name="src_type" type="xs:string"/> + <xs:attribute name="as"> + <xs:simpleType> + <xs:restriction base="xs:string"> + <xs:enumeration value="font" /> + <xs:enumeration value="script" /> + <xs:enumeration value="style" /> + </xs:restriction> + </xs:simpleType> + </xs:attribute> </xs:complexType> <xs:complexType name="metaType"> From f0670b6675875620a0a92c57e96d943de3eb6e1b Mon Sep 17 00:00:00 2001 From: Shikha Mishra <shikhamishra@cedcoss.com> Date: Thu, 27 Dec 2018 22:12:21 +0530 Subject: [PATCH 129/315] Updated Download.php --- app/code/Magento/Downloadable/Helper/Download.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/code/Magento/Downloadable/Helper/Download.php b/app/code/Magento/Downloadable/Helper/Download.php index 910eaa42f0e84..50f8d757d5537 100644 --- a/app/code/Magento/Downloadable/Helper/Download.php +++ b/app/code/Magento/Downloadable/Helper/Download.php @@ -200,6 +200,9 @@ public function getContentType() return $this->_downloadableFile->getFileType($this->_resourceFile); } } elseif ($this->_linkType == self::LINK_TYPE_URL) { + if(is_array($this->_handle->stat($this->_resourceFile)['type'])){ + return end($this->_handle->stat($this->_resourceFile)['type']); + }else return $this->_handle->stat($this->_resourceFile)['type']; } return $this->_contentType; From 04f6cfedfd6ec39fcbe0d8ae8ae298c2c62f734d Mon Sep 17 00:00:00 2001 From: Shikha Mishra <shikhamishra@cedcoss.com> Date: Thu, 27 Dec 2018 22:17:42 +0530 Subject: [PATCH 130/315] Updated Http.php --- lib/internal/Magento/Framework/Filesystem/Driver/Http.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/internal/Magento/Framework/Filesystem/Driver/Http.php b/lib/internal/Magento/Framework/Filesystem/Driver/Http.php index 5c7fdb0630186..c4350c970f9e6 100644 --- a/lib/internal/Magento/Framework/Filesystem/Driver/Http.php +++ b/lib/internal/Magento/Framework/Filesystem/Driver/Http.php @@ -39,6 +39,11 @@ public function isExists($path) if (strpos($status, '302 Found') !== false && isset($headers[1])) { $status = $headers[1]; } + + /* Handling 301 redirection */ + if (strpos($status, '301 Moved Permanently') !== false && isset($headers[1])) { + $status = $headers[1]; + } if (strpos($status, '200 OK') === false) { $result = false; From a89e6ed21e7044fa29d75866d7041af9b209fb7c Mon Sep 17 00:00:00 2001 From: Milind Singh <milind7@live.com> Date: Sat, 29 Dec 2018 15:00:45 +0530 Subject: [PATCH 131/315] Update Download.php --- app/code/Magento/Downloadable/Helper/Download.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Downloadable/Helper/Download.php b/app/code/Magento/Downloadable/Helper/Download.php index 50f8d757d5537..0da899dcbce84 100644 --- a/app/code/Magento/Downloadable/Helper/Download.php +++ b/app/code/Magento/Downloadable/Helper/Download.php @@ -200,10 +200,11 @@ public function getContentType() return $this->_downloadableFile->getFileType($this->_resourceFile); } } elseif ($this->_linkType == self::LINK_TYPE_URL) { - if(is_array($this->_handle->stat($this->_resourceFile)['type'])){ + if (is_array($this->_handle->stat($this->_resourceFile)['type'])) { return end($this->_handle->stat($this->_resourceFile)['type']); - }else - return $this->_handle->stat($this->_resourceFile)['type']; + } else { + return $this->_handle->stat($this->_resourceFile)['type']; + } } return $this->_contentType; } From 7058adb9fba8fb58c6d62ee7f4e1f27f2a7f58fc Mon Sep 17 00:00:00 2001 From: Chris Snedaker <df2002@gmail.com> Date: Mon, 31 Dec 2018 04:45:25 -0500 Subject: [PATCH 132/315] Updated to reduce overall complexity of function --- .../Magento/Downloadable/Helper/Download.php | 27 +++++++++---------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/app/code/Magento/Downloadable/Helper/Download.php b/app/code/Magento/Downloadable/Helper/Download.php index 0da899dcbce84..adb3378f23e46 100644 --- a/app/code/Magento/Downloadable/Helper/Download.php +++ b/app/code/Magento/Downloadable/Helper/Download.php @@ -185,26 +185,23 @@ public function getFileSize() * * @return string */ - public function getContentType() + public function getContentType() { $this->_getHandle(); - if ($this->_linkType == self::LINK_TYPE_FILE) { - if (function_exists( - 'mime_content_type' - ) && ($contentType = mime_content_type( - $this->_workingDirectory->getAbsolutePath($this->_resourceFile) - )) + if ($this->_linkType === self::LINK_TYPE_FILE) { + if (function_exists('mime_content_type') + && ($contentType = mime_content_type( + $this->_workingDirectory->getAbsolutePath($this->_resourceFile) + )) ) { return $contentType; - } else { - return $this->_downloadableFile->getFileType($this->_resourceFile); - } - } elseif ($this->_linkType == self::LINK_TYPE_URL) { - if (is_array($this->_handle->stat($this->_resourceFile)['type'])) { - return end($this->_handle->stat($this->_resourceFile)['type']); - } else { - return $this->_handle->stat($this->_resourceFile)['type']; } + return $this->_downloadableFile->getFileType($this->_resourceFile); + } + if ($this->_linkType === self::LINK_TYPE_URL) { + return (is_array($this->_handle->stat($this->_resourceFile)['type']) + ? end($this->_handle->stat($this->_resourceFile)['type']) + : $this->_handle->stat($this->_resourceFile)['type']); } return $this->_contentType; } From dac6687ed0b2eba02bd3e67913b2929afc940c9c Mon Sep 17 00:00:00 2001 From: Chris Snedaker <df2002@gmail.com> Date: Mon, 31 Dec 2018 04:51:05 -0500 Subject: [PATCH 133/315] Merged logic and reduced overall complexity of function Note: if() constructions that return boolean values based on conditions, can be simplified to return the condition instead. --- .../Framework/Filesystem/Driver/Http.php | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/lib/internal/Magento/Framework/Filesystem/Driver/Http.php b/lib/internal/Magento/Framework/Filesystem/Driver/Http.php index c4350c970f9e6..55935f2f149ce 100644 --- a/lib/internal/Magento/Framework/Filesystem/Driver/Http.php +++ b/lib/internal/Magento/Framework/Filesystem/Driver/Http.php @@ -27,31 +27,18 @@ class Http extends File * * @param string $path * @return bool - * @throws FileSystemException */ public function isExists($path) { $headers = array_change_key_case(get_headers($this->getScheme() . $path, 1), CASE_LOWER); - $status = $headers[0]; - /* Handling 302 redirection */ - if (strpos($status, '302 Found') !== false && isset($headers[1])) { - $status = $headers[1]; - } - - /* Handling 301 redirection */ - if (strpos($status, '301 Moved Permanently') !== false && isset($headers[1])) { + /* Handling 301 or 302 redirection */ + if (isset($headers[1]) && preg_match('/^30[12]/', $status)) { $status = $headers[1]; } - if (strpos($status, '200 OK') === false) { - $result = false; - } else { - $result = true; - } - - return $result; + return !(strpos($status, '200 OK') === false); } /** From fc90509ec4cac3785de7f2cc537476a87e89e611 Mon Sep 17 00:00:00 2001 From: Shikha Mishra <shikhamishra@cedcoss.com> Date: Wed, 2 Jan 2019 21:23:35 +0530 Subject: [PATCH 134/315] Updated Http.php --- lib/internal/Magento/Framework/Filesystem/Driver/Http.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Filesystem/Driver/Http.php b/lib/internal/Magento/Framework/Filesystem/Driver/Http.php index 55935f2f149ce..46ad773cff201 100644 --- a/lib/internal/Magento/Framework/Filesystem/Driver/Http.php +++ b/lib/internal/Magento/Framework/Filesystem/Driver/Http.php @@ -34,7 +34,7 @@ public function isExists($path) $status = $headers[0]; /* Handling 301 or 302 redirection */ - if (isset($headers[1]) && preg_match('/^30[12]/', $status)) { + if (isset($headers[1]) && preg_match('/30[12]/', $status)) { $status = $headers[1]; } From 71a5f5d302088d638cec73dd7835358beba84f15 Mon Sep 17 00:00:00 2001 From: Shikha Mishra <shikhamishra@cedcoss.com> Date: Tue, 22 Jan 2019 00:23:36 +0530 Subject: [PATCH 135/315] updated Download.php --- app/code/Magento/Downloadable/Helper/Download.php | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Downloadable/Helper/Download.php b/app/code/Magento/Downloadable/Helper/Download.php index adb3378f23e46..58ae9a1050c9d 100644 --- a/app/code/Magento/Downloadable/Helper/Download.php +++ b/app/code/Magento/Downloadable/Helper/Download.php @@ -255,10 +255,19 @@ public function setResource($resourceFile, $linkType = self::LINK_TYPE_FILE) ); } } + + /** + * check header + */ $this->_resourceFile = $resourceFile; + $headers = array_change_key_case(get_headers($this->_resourceFile, 1), CASE_LOWER); + if(isset($headers['location'])){ + $this->_resourceFile = is_array($headers['location']) ? current($headers['location']): + $headers['location']; + } + $this->_linkType = $linkType; - return $this; } From 0fc730bb0c3545b3ff241d097efb74ad160c8e6d Mon Sep 17 00:00:00 2001 From: Prince Patel <mail.mageprince@gmail.com> Date: Wed, 23 Jan 2019 12:25:44 +0530 Subject: [PATCH 136/315] Update Download.php --- app/code/Magento/Downloadable/Helper/Download.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Downloadable/Helper/Download.php b/app/code/Magento/Downloadable/Helper/Download.php index 58ae9a1050c9d..349a22c383eb5 100644 --- a/app/code/Magento/Downloadable/Helper/Download.php +++ b/app/code/Magento/Downloadable/Helper/Download.php @@ -185,7 +185,7 @@ public function getFileSize() * * @return string */ - public function getContentType() + public function getContentType() { $this->_getHandle(); if ($this->_linkType === self::LINK_TYPE_FILE) { From be3a5456339f66f98d2aaa42eebafbe9fcfa389f Mon Sep 17 00:00:00 2001 From: Shikha Mishra <shikhamishra@cedcoss.com> Date: Mon, 28 Jan 2019 23:22:46 +0530 Subject: [PATCH 137/315] updated Download.php --- .../Magento/Downloadable/Helper/Download.php | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/app/code/Magento/Downloadable/Helper/Download.php b/app/code/Magento/Downloadable/Helper/Download.php index 349a22c383eb5..4832773f13d49 100644 --- a/app/code/Magento/Downloadable/Helper/Download.php +++ b/app/code/Magento/Downloadable/Helper/Download.php @@ -256,15 +256,17 @@ public function setResource($resourceFile, $linkType = self::LINK_TYPE_FILE) } } - /** - * check header - */ - $this->_resourceFile = $resourceFile; - $headers = array_change_key_case(get_headers($this->_resourceFile, 1), CASE_LOWER); - if(isset($headers['location'])){ - $this->_resourceFile = is_array($headers['location']) ? current($headers['location']): - $headers['location']; + + /** + * check header for urls + */ + if ($this->_linkType === self::LINK_TYPE_URL) { + $headers = array_change_key_case(get_headers($this->_resourceFile, 1), CASE_LOWER); + if(isset($headers['location'])){ + $this->_resourceFile = is_array($headers['location']) ? current($headers['location']): + $headers['location']; + } } $this->_linkType = $linkType; From e5d04fa7171ad496e6d2836f56e6eff4d8a2e44d Mon Sep 17 00:00:00 2001 From: Shikha Mishra <shikhamishra@cedcoss.com> Date: Mon, 28 Jan 2019 23:46:54 +0530 Subject: [PATCH 138/315] Updated Download.php --- app/code/Magento/Downloadable/Helper/Download.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Downloadable/Helper/Download.php b/app/code/Magento/Downloadable/Helper/Download.php index 4832773f13d49..9b91c18a33cbd 100644 --- a/app/code/Magento/Downloadable/Helper/Download.php +++ b/app/code/Magento/Downloadable/Helper/Download.php @@ -261,7 +261,7 @@ public function setResource($resourceFile, $linkType = self::LINK_TYPE_FILE) /** * check header for urls */ - if ($this->_linkType === self::LINK_TYPE_URL) { + if ($linkType === self::LINK_TYPE_URL) { $headers = array_change_key_case(get_headers($this->_resourceFile, 1), CASE_LOWER); if(isset($headers['location'])){ $this->_resourceFile = is_array($headers['location']) ? current($headers['location']): From 9817c50262fcdd45246bf59475795689e7cbca30 Mon Sep 17 00:00:00 2001 From: nmalevanec <mikola.malevanec@transoftgroup.com> Date: Mon, 11 Feb 2019 12:36:21 +0200 Subject: [PATCH 139/315] Fix static test. --- app/code/Magento/Downloadable/Helper/Download.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Downloadable/Helper/Download.php b/app/code/Magento/Downloadable/Helper/Download.php index 9b91c18a33cbd..e98d400794dd1 100644 --- a/app/code/Magento/Downloadable/Helper/Download.php +++ b/app/code/Magento/Downloadable/Helper/Download.php @@ -15,6 +15,7 @@ /** * Downloadable Products Download Helper * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + * @SuppressWarnings(PHPMD.CookieAndSessionMisuse) */ class Download extends \Magento\Framework\App\Helper\AbstractHelper { @@ -263,9 +264,9 @@ public function setResource($resourceFile, $linkType = self::LINK_TYPE_FILE) */ if ($linkType === self::LINK_TYPE_URL) { $headers = array_change_key_case(get_headers($this->_resourceFile, 1), CASE_LOWER); - if(isset($headers['location'])){ - $this->_resourceFile = is_array($headers['location']) ? current($headers['location']): - $headers['location']; + if (isset($headers['location'])) { + $this->_resourceFile = is_array($headers['location']) ? current($headers['location']) + : $headers['location']; } } From cbf2c011a88210984dc77dda7a5ddd5a55ee72f7 Mon Sep 17 00:00:00 2001 From: Emipro <git@emiprotechnologies.com> Date: Fri, 7 Dec 2018 14:33:48 +0530 Subject: [PATCH 140/315] Fixed Custom option price calculation is wrong with multi currency when option price type is percentage. --- app/code/Magento/Catalog/Block/Product/View/Options.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Catalog/Block/Product/View/Options.php b/app/code/Magento/Catalog/Block/Product/View/Options.php index 0720c018f6a9b..1f8041d115f89 100644 --- a/app/code/Magento/Catalog/Block/Product/View/Options.php +++ b/app/code/Magento/Catalog/Block/Product/View/Options.php @@ -160,7 +160,7 @@ public function hasOptions() */ protected function _getPriceConfiguration($option) { - $optionPrice = $this->pricingHelper->currency($option->getPrice(true), false, false); + $optionPrice = $option->getPrice(true); $data = [ 'prices' => [ 'oldPrice' => [ @@ -195,7 +195,7 @@ protected function _getPriceConfiguration($option) ], ], 'type' => $option->getPriceType(), - 'name' => $option->getTitle() + 'name' => $option->getTitle(), ]; return $data; } @@ -231,7 +231,7 @@ public function getJsonConfig() //pass the return array encapsulated in an object for the other modules to be able to alter it eg: weee $this->_eventManager->dispatch('catalog_product_option_price_configuration_after', ['configObj' => $configObj]); - $config=$configObj->getConfig(); + $config = $configObj->getConfig(); return $this->_jsonEncoder->encode($config); } From ee8402fd25974d64c98a8da28fcbf042251b4da6 Mon Sep 17 00:00:00 2001 From: Emipro <git@emiprotechnologies.com> Date: Fri, 7 Dec 2018 15:50:55 +0530 Subject: [PATCH 141/315] solved fixed price calculation --- app/code/Magento/Catalog/Block/Product/View/Options.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Block/Product/View/Options.php b/app/code/Magento/Catalog/Block/Product/View/Options.php index 1f8041d115f89..ece517d033f87 100644 --- a/app/code/Magento/Catalog/Block/Product/View/Options.php +++ b/app/code/Magento/Catalog/Block/Product/View/Options.php @@ -20,6 +20,11 @@ */ class Options extends \Magento\Framework\View\Element\Template { + /** + * Option type percent + */ + protected static $typePercent = 'percent'; + /** * @var Product */ @@ -160,7 +165,8 @@ public function hasOptions() */ protected function _getPriceConfiguration($option) { - $optionPrice = $option->getPrice(true); + $option->getPriceType() == self::$typePercent ? $optionPrice = $option->getPrice(true) : + $optionPrice = $this->pricingHelper->currency($option->getPrice(true), false, false); $data = [ 'prices' => [ 'oldPrice' => [ From 5c073d9de2b11eb16548cc79f49ebf4b19f2ae71 Mon Sep 17 00:00:00 2001 From: Emipro <git@emiprotechnologies.com> Date: Sat, 9 Feb 2019 12:08:11 +0530 Subject: [PATCH 142/315] Update Code for Price Calculation --- .../Magento/Catalog/Block/Product/View/Options.php | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/app/code/Magento/Catalog/Block/Product/View/Options.php b/app/code/Magento/Catalog/Block/Product/View/Options.php index ece517d033f87..10f73b6012f66 100644 --- a/app/code/Magento/Catalog/Block/Product/View/Options.php +++ b/app/code/Magento/Catalog/Block/Product/View/Options.php @@ -12,6 +12,7 @@ namespace Magento\Catalog\Block\Product\View; use Magento\Catalog\Model\Product; +use Magento\Catalog\Model\Product\Option\Value; /** * @api @@ -20,11 +21,6 @@ */ class Options extends \Magento\Framework\View\Element\Template { - /** - * Option type percent - */ - protected static $typePercent = 'percent'; - /** * @var Product */ @@ -165,8 +161,10 @@ public function hasOptions() */ protected function _getPriceConfiguration($option) { - $option->getPriceType() == self::$typePercent ? $optionPrice = $option->getPrice(true) : - $optionPrice = $this->pricingHelper->currency($option->getPrice(true), false, false); + $optionPrice = $option->getPrice(true); + if($option->getPriceType() != Value::TYPE_PERCENT) { + $optionPrice = $this->pricingHelper->currency($optionPrice, false, false); + } $data = [ 'prices' => [ 'oldPrice' => [ From 040c20e30db0ba6d83675bfc9c9b1e47fbc48da5 Mon Sep 17 00:00:00 2001 From: Pavel Bystritsky <p.bystritsky@yandex.ru> Date: Tue, 12 Feb 2019 16:30:29 +0200 Subject: [PATCH 143/315] ENGCOM-4217: Static test fix. --- .../Magento/Catalog/Block/Product/View/Options.php | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/Catalog/Block/Product/View/Options.php b/app/code/Magento/Catalog/Block/Product/View/Options.php index 10f73b6012f66..c457b20cd0904 100644 --- a/app/code/Magento/Catalog/Block/Product/View/Options.php +++ b/app/code/Magento/Catalog/Block/Product/View/Options.php @@ -4,17 +4,15 @@ * See COPYING.txt for license details. */ -/** - * Product options block - * - * @author Magento Core Team <core@magentocommerce.com> - */ namespace Magento\Catalog\Block\Product\View; use Magento\Catalog\Model\Product; use Magento\Catalog\Model\Product\Option\Value; /** + * Product options block + * + * @author Magento Core Team <core@magentocommerce.com> * @api * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * @since 100.0.2 @@ -122,6 +120,8 @@ public function setProduct(Product $product = null) } /** + * Get group of option. + * * @param string $type * @return string */ @@ -143,6 +143,8 @@ public function getOptions() } /** + * Check if block has options. + * * @return bool */ public function hasOptions() @@ -162,7 +164,7 @@ public function hasOptions() protected function _getPriceConfiguration($option) { $optionPrice = $option->getPrice(true); - if($option->getPriceType() != Value::TYPE_PERCENT) { + if ($option->getPriceType() !== Value::TYPE_PERCENT) { $optionPrice = $this->pricingHelper->currency($optionPrice, false, false); } $data = [ From b138428c2b64c1755bd6dcb8d1c4e6a8376e857d Mon Sep 17 00:00:00 2001 From: Suneet <suneet64@gmail.com> Date: Sun, 3 Feb 2019 14:06:17 +0530 Subject: [PATCH 144/315] Fixed issue if there are multiple skus in catalog rule condition combination. --- .../Magento/Rule/Model/Condition/Product/AbstractProduct.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/code/Magento/Rule/Model/Condition/Product/AbstractProduct.php b/app/code/Magento/Rule/Model/Condition/Product/AbstractProduct.php index c02bbd64e7ca3..8baa843f8ade8 100644 --- a/app/code/Magento/Rule/Model/Condition/Product/AbstractProduct.php +++ b/app/code/Magento/Rule/Model/Condition/Product/AbstractProduct.php @@ -520,6 +520,10 @@ public function loadArray($arr) ) ? $this->_localeFormat->getNumber( $arr['is_value_parsed'] ) : false; + } elseif (!empty($arr['operator']) && $arr['operator'] == '()') { + if (isset($arr['value'])) { + $arr['value'] = preg_replace('/\s*,\s*/', ',', $arr['value']); + } } return parent::loadArray($arr); From 1750a5883aedee5200d54eaf816bc23ceb40d10f Mon Sep 17 00:00:00 2001 From: Pavel Bystritsky <p.bystritsky@yandex.ru> Date: Fri, 8 Feb 2019 15:58:56 +0200 Subject: [PATCH 145/315] ENGCOM-4149: Static test fix. --- .../Magento/Rule/Model/Condition/Product/AbstractProduct.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Rule/Model/Condition/Product/AbstractProduct.php b/app/code/Magento/Rule/Model/Condition/Product/AbstractProduct.php index 8baa843f8ade8..e5d613f7c9558 100644 --- a/app/code/Magento/Rule/Model/Condition/Product/AbstractProduct.php +++ b/app/code/Magento/Rule/Model/Condition/Product/AbstractProduct.php @@ -95,8 +95,8 @@ abstract class AbstractProduct extends \Magento\Rule\Model\Condition\AbstractCon * @param \Magento\Catalog\Model\ResourceModel\Product $productResource * @param \Magento\Eav\Model\ResourceModel\Entity\Attribute\Set\Collection $attrSetCollection * @param \Magento\Framework\Locale\FormatInterface $localeFormat - * @param ProductCategoryList|null $categoryList * @param array $data + * @param ProductCategoryList|null $categoryList * * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ @@ -710,6 +710,7 @@ protected function _getAttributeSetId($productId) /** * Correct '==' and '!=' operators + * * Categories can't be equal because product is included categories selected by administrator and in their parents * * @return string From 69cf6cebcd8ad8d51dc3d88fe89b6f3375bf311c Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Fri, 15 Feb 2019 14:29:58 +0100 Subject: [PATCH 146/315] Removed unnecessary line-break in DocBlock --- app/code/Magento/Customer/Model/Options.php | 1 - 1 file changed, 1 deletion(-) diff --git a/app/code/Magento/Customer/Model/Options.php b/app/code/Magento/Customer/Model/Options.php index 71e70f8e14208..f8761b4888a32 100644 --- a/app/code/Magento/Customer/Model/Options.php +++ b/app/code/Magento/Customer/Model/Options.php @@ -84,7 +84,6 @@ protected function _prepareNamePrefixSuffixOptions($options, $isOptional = false /** * Unserialize and clear name prefix or suffix options - * * If field is optional, add an empty first option. * * @param string $options From 16715de4e59421d4dd1165717ff384b7c026691f Mon Sep 17 00:00:00 2001 From: Viktor Sevch <svitja@ukr.net> Date: Fri, 15 Feb 2019 16:08:26 +0200 Subject: [PATCH 147/315] MAGETWO-97242: Stabilize AdminAbleToShipPartiallyInvoicedItemsTest --- .../templates/order/creditmemo/create/items.phtml | 14 +++++++------- .../templates/order/invoice/create/items.phtml | 12 ++++++------ 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/app/code/Magento/Sales/view/adminhtml/templates/order/creditmemo/create/items.phtml b/app/code/Magento/Sales/view/adminhtml/templates/order/creditmemo/create/items.phtml index dc7d8fbebd46a..b0b52b199978a 100644 --- a/app/code/Magento/Sales/view/adminhtml/templates/order/creditmemo/create/items.phtml +++ b/app/code/Magento/Sales/view/adminhtml/templates/order/creditmemo/create/items.phtml @@ -148,23 +148,23 @@ var updateButtons = jQuery('.update-button,.update-totals-button'); var fields = jQuery('.qty-input,.order-subtotal-table input[type="text"]'); function enableButtons(buttons) { - buttons.removeClass('disabled').prop('disabled',false); + buttons.removeClass('disabled').prop('disabled', false); }; function disableButtons(buttons) { - buttons.addClass('disabled').prop('disabled',true); + buttons.addClass('disabled').prop('disabled', true); }; disableButtons(updateButtons); fields.on('change', checkButtonsRelation); -fields.each(function (i,elem) { +fields.each(function (i, elem) { elem.baseValue = elem.value; }); function checkButtonsRelation() { var hasChanges = false; - fields.each(function (i,elem) { + fields.each(function (i, elem) { if (elem.baseValue != elem.value) { hasChanges = true; } @@ -182,7 +182,7 @@ function checkButtonsRelation() { submitCreditMemo = function() { var creditMemoOffline = jQuery('#creditmemo_do_offline'); if (creditMemoOffline.length) { - creditMemoOffline.prop('value',0); + creditMemoOffline.prop('value', 0); } // Temporary solution will be replaced after refactoring order functionality jQuery('#edit_form').triggerHandler('save'); @@ -206,10 +206,10 @@ if (sendEmailCheckbox.length) { function bindSendEmail() { if (sendEmailCheckbox.prop('checked') == true) { - notifyCustomerCheckbox.prop('disabled',false); + notifyCustomerCheckbox.prop('disabled', false); } else { - notifyCustomerCheckbox.prop('disabled',true); + notifyCustomerCheckbox.prop('disabled', true); } } diff --git a/app/code/Magento/Sales/view/adminhtml/templates/order/invoice/create/items.phtml b/app/code/Magento/Sales/view/adminhtml/templates/order/invoice/create/items.phtml index 8efdca2fce8e2..0d873645bce86 100644 --- a/app/code/Magento/Sales/view/adminhtml/templates/order/invoice/create/items.phtml +++ b/app/code/Magento/Sales/view/adminhtml/templates/order/invoice/create/items.phtml @@ -143,23 +143,23 @@ var enableSubmitButtons = <?= (int) !$block->getDisableSubmitButton() ?>; var fields = jQuery('.qty-input'); function enableButtons(buttons) { - buttons.removeClass('disabled').prop('disabled',false); + buttons.removeClass('disabled').prop('disabled', false); }; function disableButtons(buttons) { - buttons.addClass('disabled').prop('disabled',true); + buttons.addClass('disabled').prop('disabled', true); }; disableButtons(updateButtons); fields.on('keyup', checkButtonsRelation); -fields.each(function (i,elem) { +fields.each(function (i, elem) { elem.baseValue = elem.value; }); function checkButtonsRelation() { var hasChanges = false; - fields.each(function (i,elem) { + fields.each(function (i, elem) { if (elem.baseValue != elem.value) { hasChanges = true; } @@ -185,10 +185,10 @@ if (sendEmailCheckbox.length) { function bindSendEmail() { if (sendEmailCheckbox.prop('checked') == true) { - notifyCustomerCheckbox.prop('disabled',false); + notifyCustomerCheckbox.prop('disabled', false); } else { - notifyCustomerCheckbox.prop('disabled',true); + notifyCustomerCheckbox.prop('disabled', true); } } From 4d9e6c8f946594af042c9d8eec8e82ecc63aa307 Mon Sep 17 00:00:00 2001 From: hiren pandya <infinitehdp@gmail.com> Date: Sat, 13 Oct 2018 11:52:27 +0530 Subject: [PATCH 148/315] Special price date from issue resolve --- .../Controller/Adminhtml/Product/Initialization/Helper.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php index 7153f9fd0f3f9..17b08373a0efa 100644 --- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php +++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php @@ -463,6 +463,7 @@ private function fillProductOptions(Product $product, array $productOptions) private function convertSpecialFromDateStringToObject($productData) { if (isset($productData['special_from_date']) && $productData['special_from_date'] != '') { + $productData['special_from_date'] = $this->dateFilter->filter($productData['special_from_date']); $productData['special_from_date'] = new \DateTime($productData['special_from_date']); } From 523567461e74dd4580fe8e4e59d71aeae8191042 Mon Sep 17 00:00:00 2001 From: hiren pandya <hiren.pandya@krishtechnolabs.com> Date: Sat, 13 Oct 2018 13:00:58 +0530 Subject: [PATCH 149/315] Revert "Special price date from issue resolve" This reverts commit 4e382cc735a883c9dcd8eaeeedc185d7faa06a7f. --- .../Controller/Adminhtml/Product/Initialization/Helper.php | 1 - 1 file changed, 1 deletion(-) diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php index 17b08373a0efa..7153f9fd0f3f9 100644 --- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php +++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php @@ -463,7 +463,6 @@ private function fillProductOptions(Product $product, array $productOptions) private function convertSpecialFromDateStringToObject($productData) { if (isset($productData['special_from_date']) && $productData['special_from_date'] != '') { - $productData['special_from_date'] = $this->dateFilter->filter($productData['special_from_date']); $productData['special_from_date'] = new \DateTime($productData['special_from_date']); } From ad5bf08df72a5115b2777ebf55b2fc8530c88d3e Mon Sep 17 00:00:00 2001 From: hiren pandya <hiren.pandya@krishtechnolabs.com> Date: Sat, 13 Oct 2018 13:03:07 +0530 Subject: [PATCH 150/315] Special price date from issue resolve --- .../Controller/Adminhtml/Product/Initialization/Helper.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php index 7153f9fd0f3f9..67eb10564333f 100644 --- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php +++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php @@ -463,6 +463,7 @@ private function fillProductOptions(Product $product, array $productOptions) private function convertSpecialFromDateStringToObject($productData) { if (isset($productData['special_from_date']) && $productData['special_from_date'] != '') { + $productData['special_from_date'] = $this->dateFilter->filter($productData['special_from_date']); $productData['special_from_date'] = new \DateTime($productData['special_from_date']); } From 0d95f7eef9c182fa96325285a00e915a08b30676 Mon Sep 17 00:00:00 2001 From: Oleksandr Iegorov <oiegorov@magento.com> Date: Fri, 15 Feb 2019 15:14:21 -0600 Subject: [PATCH 151/315] MAGETWO-96001: Update FedEx Shipping Dates behavior in Tracking Popup --- .../DataProviders/Tracking/ChangeTitle.php | 33 +++++++++++ .../Block/Tracking/PopupDeliveryDate.php | 55 +++++++++++++++++++ app/code/Magento/Fedex/etc/di.xml | 6 ++ .../Tracking/DeliveryDateTitle.php | 26 +++++++++ .../layout/shipping_tracking_popup.xml | 6 +- .../frontend/templates/tracking/details.phtml | 2 +- 6 files changed, 126 insertions(+), 2 deletions(-) create mode 100644 app/code/Magento/Fedex/Plugin/Block/DataProviders/Tracking/ChangeTitle.php create mode 100644 app/code/Magento/Fedex/Plugin/Block/Tracking/PopupDeliveryDate.php create mode 100644 app/code/Magento/Shipping/Block/DataProviders/Tracking/DeliveryDateTitle.php diff --git a/app/code/Magento/Fedex/Plugin/Block/DataProviders/Tracking/ChangeTitle.php b/app/code/Magento/Fedex/Plugin/Block/DataProviders/Tracking/ChangeTitle.php new file mode 100644 index 0000000000000..bb0d22bd76e6a --- /dev/null +++ b/app/code/Magento/Fedex/Plugin/Block/DataProviders/Tracking/ChangeTitle.php @@ -0,0 +1,33 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Fedex\Plugin\Block\DataProviders\Tracking; + +use Magento\Fedex\Model\Carrier; +use Magento\Shipping\Model\Tracking\Result\Status; +use Magento\Shipping\Block\DataProviders\Tracking\DeliveryDateTitle as Subject; + +/** + * Plugin to change delivery date title with FedEx customized value + */ +class ChangeTitle +{ + /** + * @param Subject $subject + * @param string $result + * @param Status $trackingStatus + * @return string + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function afterGetTitle(Subject $subject, string $result, Status $trackingStatus): string + { + if ($trackingStatus->getCarrier() === Carrier::CODE) { + $result = __('Expected Delivery:'); + } + return $result; + } +} diff --git a/app/code/Magento/Fedex/Plugin/Block/Tracking/PopupDeliveryDate.php b/app/code/Magento/Fedex/Plugin/Block/Tracking/PopupDeliveryDate.php new file mode 100644 index 0000000000000..942d21dfa5e47 --- /dev/null +++ b/app/code/Magento/Fedex/Plugin/Block/Tracking/PopupDeliveryDate.php @@ -0,0 +1,55 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Fedex\Plugin\Block\Tracking; + +use Magento\Shipping\Block\Tracking\Popup; +use Magento\Fedex\Model\Carrier; +use Magento\Shipping\Model\Tracking\Result\Status; + +/** + * Plugin to update delivery date value in case if Fedex used + */ +class PopupDeliveryDate +{ + /** + * Show only date for expected delivery in case if Fedex is a carrier + * + * @param Popup $subject + * @param string $result + * @param string $date + * @param string $time + * @return string + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function afterFormatDeliveryDateTime(Popup $subject, string $result, string $date, string $time): string + { + if ($this->getCarrier($subject) === Carrier::CODE) { + $result = $subject->formatDeliveryDate($date); + } + return $result; + } + + /** + * Retrieve carrier name from tracking info + * + * @param Popup $subject + * @return string + */ + private function getCarrier(Popup $subject): string + { + foreach ($subject->getTrackingInfo() as $trackingData) { + foreach ($trackingData as $trackingInfo) { + if ($trackingInfo instanceof Status) { + $carrier = $trackingInfo->getCarrier(); + return $carrier; + } + } + } + return ''; + } +} diff --git a/app/code/Magento/Fedex/etc/di.xml b/app/code/Magento/Fedex/etc/di.xml index f17f8f2afe663..c542b1f04d1eb 100644 --- a/app/code/Magento/Fedex/etc/di.xml +++ b/app/code/Magento/Fedex/etc/di.xml @@ -22,4 +22,10 @@ </argument> </arguments> </type> + <type name="Magento\Shipping\Block\DataProviders\Tracking\DeliveryDateTitle"> + <plugin name="update_delivery_date_title" type="Magento\Fedex\Plugin\Block\DataProviders\Tracking\ChangeTitle"/> + </type> + <type name="Magento\Shipping\Block\Tracking\Popup"> + <plugin name="update_delivery_date_value" type="Magento\Fedex\Plugin\Block\Tracking\PopupDeliveryDate"/> + </type> </config> diff --git a/app/code/Magento/Shipping/Block/DataProviders/Tracking/DeliveryDateTitle.php b/app/code/Magento/Shipping/Block/DataProviders/Tracking/DeliveryDateTitle.php new file mode 100644 index 0000000000000..e4c31629b9db7 --- /dev/null +++ b/app/code/Magento/Shipping/Block/DataProviders/Tracking/DeliveryDateTitle.php @@ -0,0 +1,26 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Shipping\Block\DataProviders\Tracking; + +use Magento\Framework\View\Element\Block\ArgumentInterface; +use Magento\Shipping\Model\Tracking\Result\Status; + +/** + * Extension point to provide ability to change tracking details titles + */ +class DeliveryDateTitle implements ArgumentInterface +{ + /** + * @param Status $trackingStatus + * @return string + */ + public function getTitle(Status $trackingStatus): string + { + return $trackingStatus->getCarrier() ? __('Delivered on:') : ''; + } +} diff --git a/app/code/Magento/Shipping/view/frontend/layout/shipping_tracking_popup.xml b/app/code/Magento/Shipping/view/frontend/layout/shipping_tracking_popup.xml index 1f5b0ae4630ad..67d03da2599bf 100644 --- a/app/code/Magento/Shipping/view/frontend/layout/shipping_tracking_popup.xml +++ b/app/code/Magento/Shipping/view/frontend/layout/shipping_tracking_popup.xml @@ -8,7 +8,11 @@ <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="empty" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd"> <body> <referenceContainer name="content"> - <block class="Magento\Shipping\Block\Tracking\Popup" name="shipping.tracking.popup" template="Magento_Shipping::tracking/popup.phtml" cacheable="false" /> + <block class="Magento\Shipping\Block\Tracking\Popup" name="shipping.tracking.popup" template="Magento_Shipping::tracking/popup.phtml" cacheable="false"> + <arguments> + <argument name="delivery_date_title" xsi:type="object">Magento\Shipping\Block\DataProviders\Tracking\DeliveryDateTitle</argument> + </arguments> + </block> </referenceContainer> </body> </page> diff --git a/app/code/Magento/Shipping/view/frontend/templates/tracking/details.phtml b/app/code/Magento/Shipping/view/frontend/templates/tracking/details.phtml index 9253b47f82f5d..e8584d8f6ad51 100644 --- a/app/code/Magento/Shipping/view/frontend/templates/tracking/details.phtml +++ b/app/code/Magento/Shipping/view/frontend/templates/tracking/details.phtml @@ -77,7 +77,7 @@ $number = is_object($track) ? $track->getTracking() : $track['number']; <?php if ($track->getDeliverydate()): ?> <tr> - <th class="col label" scope="row"><?= $block->escapeHtml(__('Delivered on:')) ?></th> + <th class="col label" scope="row"><?= $block->escapeHtml($parentBlock->getDeliveryDateTitle()->getTitle($track)) ?></th> <td class="col value"> <?= /* @noEscape */ $parentBlock->formatDeliveryDateTime($track->getDeliverydate(), $track->getDeliverytime()) ?> </td> From 4b7b06b0b254753acba2cd7f3a017f1429252e44 Mon Sep 17 00:00:00 2001 From: Oleksandr Iegorov <oiegorov@magento.com> Date: Fri, 15 Feb 2019 16:43:45 -0600 Subject: [PATCH 152/315] MAGETWO-96001: Update FedEx Shipping Dates behavior in Tracking Popup --- .../Plugin/Block/DataProviders/Tracking/ChangeTitle.php | 7 +++---- .../Block/DataProviders/Tracking/DeliveryDateTitle.php | 5 ++--- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/app/code/Magento/Fedex/Plugin/Block/DataProviders/Tracking/ChangeTitle.php b/app/code/Magento/Fedex/Plugin/Block/DataProviders/Tracking/ChangeTitle.php index bb0d22bd76e6a..d148b91aa3e7a 100644 --- a/app/code/Magento/Fedex/Plugin/Block/DataProviders/Tracking/ChangeTitle.php +++ b/app/code/Magento/Fedex/Plugin/Block/DataProviders/Tracking/ChangeTitle.php @@ -3,7 +3,6 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ -declare(strict_types=1); namespace Magento\Fedex\Plugin\Block\DataProviders\Tracking; @@ -18,12 +17,12 @@ class ChangeTitle { /** * @param Subject $subject - * @param string $result + * @param \Magento\Framework\Phrase|string $result * @param Status $trackingStatus - * @return string + * @return \Magento\Framework\Phrase|string * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ - public function afterGetTitle(Subject $subject, string $result, Status $trackingStatus): string + public function afterGetTitle(Subject $subject, $result, Status $trackingStatus): string { if ($trackingStatus->getCarrier() === Carrier::CODE) { $result = __('Expected Delivery:'); diff --git a/app/code/Magento/Shipping/Block/DataProviders/Tracking/DeliveryDateTitle.php b/app/code/Magento/Shipping/Block/DataProviders/Tracking/DeliveryDateTitle.php index e4c31629b9db7..dc66c4f0bd018 100644 --- a/app/code/Magento/Shipping/Block/DataProviders/Tracking/DeliveryDateTitle.php +++ b/app/code/Magento/Shipping/Block/DataProviders/Tracking/DeliveryDateTitle.php @@ -3,7 +3,6 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ -declare(strict_types=1); namespace Magento\Shipping\Block\DataProviders\Tracking; @@ -17,9 +16,9 @@ class DeliveryDateTitle implements ArgumentInterface { /** * @param Status $trackingStatus - * @return string + * @return \Magento\Framework\Phrase|string */ - public function getTitle(Status $trackingStatus): string + public function getTitle(Status $trackingStatus) { return $trackingStatus->getCarrier() ? __('Delivered on:') : ''; } From 864f7fbf5eb89033846da2166fa0177dbcc71e14 Mon Sep 17 00:00:00 2001 From: Myroslav Dobra <dmaraptor@gmail.com> Date: Sat, 16 Feb 2019 01:00:17 +0200 Subject: [PATCH 153/315] MAGETWO-98182: [FT] [MFTF] StorefrontPurchaseProductCustomOptionsDifferentStoreViewsTest fails because of bad design --- .../Test/Mftf/ActionGroup/AdminSwitchStoreViewActionGroup.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Store/Test/Mftf/ActionGroup/AdminSwitchStoreViewActionGroup.xml b/app/code/Magento/Store/Test/Mftf/ActionGroup/AdminSwitchStoreViewActionGroup.xml index d540a0000655f..244992cafa2a3 100644 --- a/app/code/Magento/Store/Test/Mftf/ActionGroup/AdminSwitchStoreViewActionGroup.xml +++ b/app/code/Magento/Store/Test/Mftf/ActionGroup/AdminSwitchStoreViewActionGroup.xml @@ -16,6 +16,7 @@ <waitForElementVisible selector="{{AdminConfirmationModalSection.ok}}" stepKey="waitingForInformationModal"/> <click selector="{{AdminConfirmationModalSection.ok}}" stepKey="confirmScopeSwitch"/> <waitForPageLoad stepKey="waitForScopeSwitched"/> + <scrollTo selector="{{AdminMainActionsSection.storeViewDropdown}}" stepKey="scrollToStoreSwitcher"/> <see userInput="{{scopeName}}" selector="{{AdminMainActionsSection.storeSwitcher}}" stepKey="seeNewScopeName"/> </actionGroup> From e84fbf2d2b19a2daf33c9974535007f3da7e746f Mon Sep 17 00:00:00 2001 From: Myroslav Dobra <dmaraptor@gmail.com> Date: Sat, 16 Feb 2019 06:34:56 +0200 Subject: [PATCH 154/315] MAGETWO-98182: [FT] [MFTF] StorefrontPurchaseProductCustomOptionsDifferentStoreViewsTest fails because of bad design --- .../Test/Mftf/ActionGroup/AdminSwitchStoreViewActionGroup.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Store/Test/Mftf/ActionGroup/AdminSwitchStoreViewActionGroup.xml b/app/code/Magento/Store/Test/Mftf/ActionGroup/AdminSwitchStoreViewActionGroup.xml index 244992cafa2a3..1c56c3cc44220 100644 --- a/app/code/Magento/Store/Test/Mftf/ActionGroup/AdminSwitchStoreViewActionGroup.xml +++ b/app/code/Magento/Store/Test/Mftf/ActionGroup/AdminSwitchStoreViewActionGroup.xml @@ -16,7 +16,7 @@ <waitForElementVisible selector="{{AdminConfirmationModalSection.ok}}" stepKey="waitingForInformationModal"/> <click selector="{{AdminConfirmationModalSection.ok}}" stepKey="confirmScopeSwitch"/> <waitForPageLoad stepKey="waitForScopeSwitched"/> - <scrollTo selector="{{AdminMainActionsSection.storeViewDropdown}}" stepKey="scrollToStoreSwitcher"/> + <scrollToTopOfPage stepKey="scrollToStoreSwitcher"/> <see userInput="{{scopeName}}" selector="{{AdminMainActionsSection.storeSwitcher}}" stepKey="seeNewScopeName"/> </actionGroup> From b0208801bbf228a5bea108824207d4ff11cb0e32 Mon Sep 17 00:00:00 2001 From: Yannis Livasov <melaxon@users.noreply.github.com> Date: Mon, 31 Dec 2018 18:25:27 +0300 Subject: [PATCH 155/315] hardcoded table name hardcoded table name --- app/code/Magento/Directory/Model/ResourceModel/Currency.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Directory/Model/ResourceModel/Currency.php b/app/code/Magento/Directory/Model/ResourceModel/Currency.php index ffbcce11cb4f6..5339b0c9eb5bd 100644 --- a/app/code/Magento/Directory/Model/ResourceModel/Currency.php +++ b/app/code/Magento/Directory/Model/ResourceModel/Currency.php @@ -216,7 +216,7 @@ protected function _getRatesByCode($code, $toCurrencies = null) $connection = $this->getConnection(); $bind = [':currency_from' => $code]; $select = $connection->select()->from( - $this->getTable('directory_currency_rate'), + $this->_currencyRateTable, ['currency_to', 'rate'] )->where( 'currency_from = :currency_from' From 7ef43a1fbde1263c4aba103e3b390b9ffbb525c4 Mon Sep 17 00:00:00 2001 From: Aki Ojalehto <aki@ojalehto.eu> Date: Sun, 21 Jan 2018 21:49:31 +0200 Subject: [PATCH 156/315] Refactor getFrontName --- lib/internal/Magento/Framework/View/Context.php | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/lib/internal/Magento/Framework/View/Context.php b/lib/internal/Magento/Framework/View/Context.php index 0c3932ffe4bd7..c3f1c3e691c84 100644 --- a/lib/internal/Magento/Framework/View/Context.php +++ b/lib/internal/Magento/Framework/View/Context.php @@ -332,15 +332,11 @@ public function getModuleName() } /** - * Retrieve the module name - * - * @return string - * - * @todo alias of getModuleName + * @see getModuleName */ public function getFrontName() { - return $this->getRequest()->getModuleName(); + return $this->getModuleName(); } /** From 1a05beb053d2f36f9df194834d655d68787629d4 Mon Sep 17 00:00:00 2001 From: amol 2jcommerce <amol@2jcommerce.in> Date: Mon, 18 Feb 2019 10:38:57 +0530 Subject: [PATCH 157/315] update branch 2.2-develop-PR-port-20519 --- .../Magento/luma/Magento_Bundle/web/css/source/_module.less | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/design/frontend/Magento/luma/Magento_Bundle/web/css/source/_module.less b/app/design/frontend/Magento/luma/Magento_Bundle/web/css/source/_module.less index 99c8aa1ad2bae..262e2d68d1ea3 100644 --- a/app/design/frontend/Magento/luma/Magento_Bundle/web/css/source/_module.less +++ b/app/design/frontend/Magento/luma/Magento_Bundle/web/css/source/_module.less @@ -61,6 +61,10 @@ margin-top: 4px; } + input[type="checkbox"] { + margin-top: 2px; + } + .label { &:extend(.abs-add-clearfix all); display: block; From a12d7af12c33180657f038c007521c7cf55e07f6 Mon Sep 17 00:00:00 2001 From: amol 2jcommerce <amol@2jcommerce.in> Date: Mon, 18 Feb 2019 11:19:36 +0530 Subject: [PATCH 158/315] branch updated 2.2-develop-PR-port-20466 --- .../Magento_Checkout/web/css/source/module/_cart.less | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/_cart.less b/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/_cart.less index 67057967451d8..e764093668a07 100644 --- a/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/_cart.less +++ b/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/_cart.less @@ -422,6 +422,14 @@ &:extend(.abs-sidebar-totals-mobile all); } } + .order-items.table-wrapper { + .col.price, + .col.qty, + .col.subtotal, + .col.msrp { + text-align: left; + } + } } .media-width(@extremum, @break) when (@extremum = 'max') and (@break = @screen__m) { From 17d416a1d0fda6d3d2cc8730198d354a56ce4923 Mon Sep 17 00:00:00 2001 From: amol 2jcommerce <amol@2jcommerce.in> Date: Mon, 18 Feb 2019 12:31:48 +0530 Subject: [PATCH 159/315] updated branch fixes-customer-information-wishlist-configurable-product-alignment-2.2 --- .../Test/Block/Adminhtml/Product/Composite/Configure.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Composite/Configure.xml b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Composite/Configure.xml index a66753c2adf23..9614f0d1bf7b5 100644 --- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Composite/Configure.xml +++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Composite/Configure.xml @@ -9,7 +9,7 @@ <fields> <qty /> <attribute> - <selector>//div[@class="product-options"]//label[.="%s"]//following-sibling::*//select</selector> + <selector>//div[contains(@class, "product-options")]//div//label[.="%s"]//following-sibling::*//select</selector> <strategy>xpath</strategy> <input>select</input> </attribute> From be57683357f8a6819a575f051d0ea96bcdfc1548 Mon Sep 17 00:00:00 2001 From: Stjepan Udovicic <stjepan.udovicic@inchoo.net> Date: Mon, 18 Feb 2019 08:07:09 +0100 Subject: [PATCH 160/315] Backport ENGCOM-3616: Static test fix --- .../Indexer/Price/CustomOptionPriceModifier.php | 10 ++++++++++ .../Product/Indexer/Price/DefaultPrice.php | 14 ++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Price/CustomOptionPriceModifier.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Price/CustomOptionPriceModifier.php index 646cd0d4c1a4c..ce0b7a4111d2c 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Price/CustomOptionPriceModifier.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Price/CustomOptionPriceModifier.php @@ -127,6 +127,8 @@ public function modifyPrice(IndexTableStructure $priceTable, array $entityIds = } /** + * Check if custom options exist. + * * @param IndexTableStructure $priceTable * @return bool * @throws \Exception @@ -154,6 +156,8 @@ private function checkIfCustomOptionsExist(IndexTableStructure $priceTable): boo } /** + * Get connection. + * * @return \Magento\Framework\DB\Adapter\AdapterInterface */ private function getConnection() @@ -373,6 +377,8 @@ private function getSelectAggregated(string $sourceTable): Select } /** + * Get select for update. + * * @param string $sourceTable * @return \Magento\Framework\DB\Select */ @@ -402,6 +408,8 @@ private function getSelectForUpdate(string $sourceTable): Select } /** + * Get table name. + * * @param string $tableName * @return string */ @@ -411,6 +419,8 @@ private function getTable(string $tableName): string } /** + * Is price scope global. + * * @return bool */ private function isPriceGlobal(): bool diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Price/DefaultPrice.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Price/DefaultPrice.php index 8fdeaf00b804f..aab4577de3770 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Price/DefaultPrice.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Price/DefaultPrice.php @@ -10,6 +10,7 @@ /** * Default Product Type Price Indexer Resource model + * * For correctly work need define product type id * * @api @@ -208,6 +209,8 @@ public function reindexEntity($entityIds) } /** + * Reindex prices. + * * @param null|int|array $entityIds * @return \Magento\Catalog\Model\ResourceModel\Product\Indexer\Price\DefaultPrice */ @@ -802,6 +805,8 @@ public function getIdxTable($table = null) } /** + * Check if product exists. + * * @return bool */ protected function hasEntity() @@ -823,6 +828,8 @@ protected function hasEntity() } /** + * Get total tier price expression. + * * @param \Zend_Db_Expr $priceExpression * @return \Zend_Db_Expr */ @@ -862,6 +869,13 @@ private function getTotalTierPriceExpression(\Zend_Db_Expr $priceExpression) ); } + /** + * Get tier price expression for table. + * + * @param string $tableAlias + * @param \Zend_Db_Expr $priceExpression + * @return \Zend_Db_Expr + */ private function getTierPriceExpressionForTable($tableAlias, \Zend_Db_Expr $priceExpression) { return $this->getConnection()->getCheckSql( From 9f1a322c239f940457b30ceadf137628651e04ad Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza <enarc@atwix.com> Date: Mon, 18 Feb 2019 09:28:45 +0100 Subject: [PATCH 161/315] Changed indent to meet the standard --- .../web/css/source/_module.less | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/app/design/frontend/Magento/luma/Magento_Newsletter/web/css/source/_module.less b/app/design/frontend/Magento/luma/Magento_Newsletter/web/css/source/_module.less index aab895392e6dd..d7ee1319c9a43 100644 --- a/app/design/frontend/Magento/luma/Magento_Newsletter/web/css/source/_module.less +++ b/app/design/frontend/Magento/luma/Magento_Newsletter/web/css/source/_module.less @@ -87,18 +87,18 @@ // _____________________________________________ .media-width(@extremum, @break) when (@extremum = 'max') and (@break = @screen__m) { - .block{ - &.newsletter { - input { - font-size: 12px; - padding-left: 30px; - } - - .field { - .control:before{ - font-size: 13px; + .block { + &.newsletter { + input { + font-size: 12px; + padding-left: 30px; + } + + .field { + .control:before { + font-size: 13px; + } + } } - } } - } } From 139833bcd2d776d2af8ba043e01844355834d327 Mon Sep 17 00:00:00 2001 From: "rostyslav.hymon" <rostyslav.hymon@transoftgroup.com> Date: Mon, 18 Feb 2019 10:44:33 +0200 Subject: [PATCH 162/315] MAGETWO-98044: Customer Group Regression issues from MAGETWO-96886 --- .../Magento/Backend/Model/Session/Quote.php | 3 +- .../Test/Unit/Model/Session/QuoteTest.php | 5 +- .../Adminhtml/Order/Create/Form/Account.php | 27 +----- .../Order/Create/Form/AccountTest.php | 83 ++++++++++++++----- 4 files changed, 70 insertions(+), 48 deletions(-) diff --git a/app/code/Magento/Backend/Model/Session/Quote.php b/app/code/Magento/Backend/Model/Session/Quote.php index 11edaa26f443f..e32f1bc57596e 100644 --- a/app/code/Magento/Backend/Model/Session/Quote.php +++ b/app/code/Magento/Backend/Model/Session/Quote.php @@ -149,7 +149,8 @@ public function getQuote() $this->_quote = $this->quoteFactory->create(); if ($this->getStoreId()) { if (!$this->getQuoteId()) { - $this->_quote->setCustomerGroupId($this->groupManagement->getDefaultGroup()->getId()); + $customerGroupId = $this->groupManagement->getDefaultGroup($this->getStoreId())->getId(); + $this->_quote->setCustomerGroupId($customerGroupId); $this->_quote->setIsActive(false); $this->_quote->setStoreId($this->getStoreId()); diff --git a/app/code/Magento/Backend/Test/Unit/Model/Session/QuoteTest.php b/app/code/Magento/Backend/Test/Unit/Model/Session/QuoteTest.php index 869d4ba3f45b1..d159225089afc 100644 --- a/app/code/Magento/Backend/Test/Unit/Model/Session/QuoteTest.php +++ b/app/code/Magento/Backend/Test/Unit/Model/Session/QuoteTest.php @@ -267,7 +267,10 @@ public function testGetQuoteWithoutQuoteId() $cartInterfaceMock->expects($this->atLeastOnce())->method('getId')->willReturn($quoteId); $defaultGroup = $this->getMockBuilder(\Magento\Customer\Api\Data\GroupInterface::class)->getMock(); $defaultGroup->expects($this->any())->method('getId')->will($this->returnValue($customerGroupId)); - $this->groupManagementMock->expects($this->any())->method('getDefaultGroup')->willReturn($defaultGroup); + $this->groupManagementMock + ->method('getDefaultGroup') + ->with($storeId) + ->willReturn($defaultGroup); $dataCustomerMock = $this->getMockBuilder(\Magento\Customer\Api\Data\CustomerInterface::class) ->disableOriginalConstructor() diff --git a/app/code/Magento/Sales/Block/Adminhtml/Order/Create/Form/Account.php b/app/code/Magento/Sales/Block/Adminhtml/Order/Create/Form/Account.php index dc93e8ba8417c..11f3faa9d042e 100644 --- a/app/code/Magento/Sales/Block/Adminhtml/Order/Create/Form/Account.php +++ b/app/code/Magento/Sales/Block/Adminhtml/Order/Create/Form/Account.php @@ -11,7 +11,6 @@ use Magento\Framework\Api\ExtensibleDataObjectConverter; use Magento\Framework\Data\Form\Element\AbstractElement; use Magento\Framework\Pricing\PriceCurrencyInterface; -use Magento\Store\Model\ScopeInterface; /** * Create order account form @@ -135,8 +134,9 @@ protected function _prepareForm() $this->_addAttributesToForm($attributes, $fieldset); $this->_form->addFieldNameSuffix('order[account]'); - $storeId = (int)$this->_sessionQuote->getStoreId(); - $this->_form->setValues($this->extractValuesFromAttributes($attributes, $storeId)); + + $formValues = $this->extractValuesFromAttributes($attributes); + $this->_form->setValues($formValues); return $this; } @@ -188,10 +188,9 @@ public function getFormValues() * Extract the form values from attributes. * * @param array $attributes - * @param int $storeId * @return array */ - private function extractValuesFromAttributes(array $attributes, int $storeId): array + private function extractValuesFromAttributes(array $attributes): array { $formValues = $this->getFormValues(); foreach ($attributes as $code => $attribute) { @@ -199,26 +198,8 @@ private function extractValuesFromAttributes(array $attributes, int $storeId): a if (isset($defaultValue) && !isset($formValues[$code])) { $formValues[$code] = $defaultValue; } - if ($code === 'group_id' && empty($formValues[$code])) { - $formValues[$code] = $this->getDefaultCustomerGroup($storeId); - } } return $formValues; } - - /** - * Gets default customer group. - * - * @param int $storeId - * @return string|null - */ - private function getDefaultCustomerGroup(int $storeId) - { - return $this->_scopeConfig->getValue( - 'customer/create_account/default_group', - ScopeInterface::SCOPE_STORE, - $storeId - ); - } } diff --git a/dev/tests/integration/testsuite/Magento/Sales/Block/Adminhtml/Order/Create/Form/AccountTest.php b/dev/tests/integration/testsuite/Magento/Sales/Block/Adminhtml/Order/Create/Form/AccountTest.php index ce3f3a3e1fc8e..cc051c11aabf8 100644 --- a/dev/tests/integration/testsuite/Magento/Sales/Block/Adminhtml/Order/Create/Form/AccountTest.php +++ b/dev/tests/integration/testsuite/Magento/Sales/Block/Adminhtml/Order/Create/Form/AccountTest.php @@ -5,7 +5,6 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ - declare(strict_types=1); namespace Magento\Sales\Block\Adminhtml\Order\Create\Form; @@ -23,7 +22,10 @@ use PHPUnit\Framework\MockObject\MockObject; /** + * Class for test Account + * * @magentoAppArea adminhtml + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class AccountTest extends \PHPUnit\Framework\TestCase { @@ -43,23 +45,33 @@ class AccountTest extends \PHPUnit\Framework\TestCase private $session; /** - * @magentoDataFixture Magento/Sales/_files/quote.php + * @inheritdoc */ protected function setUp() { $this->objectManager = Bootstrap::getObjectManager(); - $quote = $this->objectManager->create(Quote::class)->load(1); + parent::setUp(); + } + + /** + * Test for get form with existing customer + * + * @magentoDataFixture Magento/Customer/_files/customer.php + */ + public function testGetFormWithCustomer() + { + $customerGroup = 2; + $quote = $this->objectManager->create(Quote::class); $this->session = $this->getMockBuilder(SessionQuote::class) ->disableOriginalConstructor() - ->setMethods(['getCustomerId', 'getStore', 'getStoreId', 'getQuote', 'getQuoteId']) + ->setMethods(['getCustomerId','getQuote']) ->getMock(); - $this->session->method('getCustomerId') - ->willReturn(1); $this->session->method('getQuote') ->willReturn($quote); - $this->session->method('getQuoteId') - ->willReturn($quote->getId()); + $this->session->method('getCustomerId') + ->willReturn(1); + /** @var LayoutInterface $layout */ $layout = $this->objectManager->get(LayoutInterface::class); $this->accountBlock = $layout->createBlock( @@ -67,18 +79,20 @@ protected function setUp() 'address_block' . rand(), ['sessionQuote' => $this->session] ); - parent::setUp(); - } - /** - * @magentoDataFixture Magento/Customer/_files/customer.php - */ - public function testGetForm() - { + $fixtureCustomerId = 1; + /** @var \Magento\Customer\Api\CustomerRepositoryInterface $customerRepository */ + $customerRepository = $this->objectManager->get(\Magento\Customer\Api\CustomerRepositoryInterface::class); + /** @var \Magento\Customer\Api\Data\CustomerInterface $customer */ + $customer = $customerRepository->getById($fixtureCustomerId); + $customer->setGroupId($customerGroup); + $customerRepository->save($customer); + $expectedFields = ['group_id', 'email']; $form = $this->accountBlock->getForm(); self::assertEquals(1, $form->getElements()->count(), "Form has invalid number of fieldsets"); $fieldset = $form->getElements()[0]; + $content = $form->toHtml(); self::assertEquals(count($expectedFields), $fieldset->getElements()->count()); @@ -88,22 +102,45 @@ public function testGetForm() sprintf('Unexpected field "%s" in form.', $element->getId()) ); } + + self::assertContains( + '<option value="'.$customerGroup.'" selected="selected">Wholesale</option>', + $content, + 'The Customer Group specified for the chosen customer should be selected.' + ); + + self::assertContains( + 'value="'.$customer->getEmail().'"', + $content, + 'The Customer Email specified for the chosen customer should be input ' + ); } /** * Tests a case when user defined custom attribute has default value. * - * @magentoDataFixture Magento/Customer/_files/customer.php - * @magentoConfigFixture current_store customer/create_account/default_group 3 + * @magentoDataFixture Magento/Store/_files/core_second_third_fixturestore.php + * @magentoConfigFixture current_store customer/create_account/default_group 2 + * @magentoConfigFixture secondstore_store customer/create_account/default_group 3 */ public function testGetFormWithUserDefinedAttribute() { + /** @var \Magento\Store\Model\StoreManagerInterface $storeManager */ + $storeManager = Bootstrap::getObjectManager()->get(\Magento\Store\Model\StoreManagerInterface::class); + $secondStore = $storeManager->getStore('secondstore'); + + $quoteSession = $this->objectManager->get(SessionQuote::class); + $quoteSession->setStoreId($secondStore->getId()); + $formFactory = $this->getFormFactoryMock(); $this->objectManager->addSharedInstance($formFactory, FormFactory::class); /** @var LayoutInterface $layout */ $layout = $this->objectManager->get(LayoutInterface::class); - $accountBlock = $layout->createBlock(Account::class, 'address_block' . rand()); + $accountBlock = $layout->createBlock( + Account::class, + 'address_block' . rand() + ); $form = $accountBlock->getForm(); $form->setUseContainer(true); @@ -116,7 +153,7 @@ public function testGetFormWithUserDefinedAttribute() ); self::assertContains( - '<option value="3" selected="selected">Customer Group 1</option>', + '<option value="3" selected="selected">Retailer</option>', $content, 'The Customer Group specified for the chosen store should be selected.' ); @@ -162,13 +199,13 @@ private function createCustomerGroupAttribute(): AttributeMetadataInterface { /** @var Option $option1 */ $option1 = $this->objectManager->create(Option::class); - $option1->setValue(3); - $option1->setLabel('Customer Group 1'); + $option1->setValue(2); + $option1->setLabel('Wholesale'); /** @var Option $option2 */ $option2 = $this->objectManager->create(Option::class); - $option2->setValue(4); - $option2->setLabel('Customer Group 2'); + $option2->setValue(3); + $option2->setLabel('Retailer'); /** @var AttributeMetadataInterfaceFactory $attributeMetadataFactory */ $attributeMetadataFactory = $this->objectManager->create(AttributeMetadataInterfaceFactory::class); From 67b3c9cab030bbaf1f0fbb1d5d0d6c228453edaf Mon Sep 17 00:00:00 2001 From: Sergii Ivashchenko <serg.ivashchenko@gmail.com> Date: Mon, 18 Feb 2019 12:02:51 +0000 Subject: [PATCH 163/315] magento/magento2#21273: Fixed functional tests --- .../Controller/Adminhtml/Product/Initialization/Helper.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php index 67eb10564333f..5e9579290535c 100644 --- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php +++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php @@ -463,7 +463,7 @@ private function fillProductOptions(Product $product, array $productOptions) private function convertSpecialFromDateStringToObject($productData) { if (isset($productData['special_from_date']) && $productData['special_from_date'] != '') { - $productData['special_from_date'] = $this->dateFilter->filter($productData['special_from_date']); + $productData['special_from_date'] = $this->getDateTimeFilter()->filter($productData['special_from_date']); $productData['special_from_date'] = new \DateTime($productData['special_from_date']); } From 7b8ec8085d29f84fadac67a4e17753a66f4e6ddf Mon Sep 17 00:00:00 2001 From: nmalevanec <mikola.malevanec@transoftgroup.com> Date: Mon, 18 Feb 2019 14:09:19 +0200 Subject: [PATCH 164/315] Fix functional tests. --- app/code/Magento/Ui/view/base/web/js/form/element/country.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Ui/view/base/web/js/form/element/country.js b/app/code/Magento/Ui/view/base/web/js/form/element/country.js index f64a80bf535ec..c75301018e190 100644 --- a/app/code/Magento/Ui/view/base/web/js/form/element/country.js +++ b/app/code/Magento/Ui/view/base/web/js/form/element/country.js @@ -49,7 +49,7 @@ define([ if (!this.value()) { defaultCountry = _.filter(result, function (item) { - return item['is_default'] && item['is_default'].includes(value); + return item['is_default'] && _.contains(item['is_default'], value); }); if (defaultCountry.length) { From ac3787a77391f075081061c9f8d88f63939b49c1 Mon Sep 17 00:00:00 2001 From: Sergii Ivashchenko <serg.ivashchenko@gmail.com> Date: Mon, 18 Feb 2019 15:04:23 +0000 Subject: [PATCH 165/315] magento-engcom/magento2ce#2594: Fixed unit test --- .../Product/Initialization/Helper.php | 9 ++++++++- .../Product/Initialization/HelperTest.php | 19 +++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php index 5e9579290535c..f11d16755ef0d 100644 --- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php +++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php @@ -19,6 +19,8 @@ use Magento\Catalog\Controller\Adminhtml\Product\Initialization\Helper\AttributeFilter; /** + * Product helper + * * @api * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * @since 100.0.2 @@ -104,7 +106,7 @@ class Helper * @param \Magento\Backend\Helper\Js $jsHelper * @param \Magento\Framework\Stdlib\DateTime\Filter\Date $dateFilter * @param CustomOptionFactory|null $customOptionFactory - * @param ProductLinkFactory |null $productLinkFactory + * @param ProductLinkFactory|null $productLinkFactory * @param ProductRepositoryInterface|null $productRepository * @param LinkTypeProvider|null $linkTypeProvider * @param AttributeFilter|null $attributeFilter @@ -365,6 +367,8 @@ private function overwriteValue($optionId, $option, $overwriteOptions) } /** + * Get link resolver instance + * * @return LinkResolver * @deprecated 101.0.0 */ @@ -377,6 +381,8 @@ private function getLinkResolver() } /** + * Get DateTimeFilter instance + * * @return \Magento\Framework\Stdlib\DateTime\Filter\DateTime * @deprecated 101.0.0 */ @@ -391,6 +397,7 @@ private function getDateTimeFilter() /** * Remove ids of non selected websites from $websiteIds array and return filtered data + * * $websiteIds parameter expects array with website ids as keys and 1 (selected) or 0 (non selected) as values * Only one id (default website ID) will be set to $websiteIds array when the single store mode is turned on * diff --git a/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/Initialization/HelperTest.php b/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/Initialization/HelperTest.php index aed87f918ebb8..c889c58e3df3a 100644 --- a/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/Initialization/HelperTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/Initialization/HelperTest.php @@ -95,6 +95,14 @@ class HelperTest extends \PHPUnit\Framework\TestCase */ protected $attributeFilterMock; + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $dateTimeFilterMock; + + /** + * @inheritdoc + */ protected function setUp() { $this->objectManager = new ObjectManager($this); @@ -167,6 +175,11 @@ protected function setUp() $resolverProperty = $helperReflection->getProperty('linkResolver'); $resolverProperty->setAccessible(true); $resolverProperty->setValue($this->helper, $this->linkResolverMock); + + $this->dateTimeFilterMock = $this->createMock(\Magento\Framework\Stdlib\DateTime\Filter\DateTime::class); + $dateTimeFilterProperty = $helperReflection->getProperty('dateTimeFilter'); + $dateTimeFilterProperty->setAccessible(true); + $dateTimeFilterProperty->setValue($this->helper, $this->dateTimeFilterMock); } /** @@ -208,6 +221,12 @@ public function testInitialize( if (!empty($tierPrice)) { $productData = array_merge($productData, ['tier_price' => $tierPrice]); } + + $this->dateTimeFilterMock->expects($this->once()) + ->method('filter') + ->with($specialFromDate) + ->willReturn($specialFromDate); + $attributeNonDate = $this->getMockBuilder(\Magento\Catalog\Model\ResourceModel\Eav\Attribute::class) ->disableOriginalConstructor() ->getMock(); From b16221b1b76dd18bb1fbebbe4b26ed394e4e3657 Mon Sep 17 00:00:00 2001 From: Viktor Petryk <victor.petryk@transoftgroup.com> Date: Mon, 18 Feb 2019 20:54:51 +0200 Subject: [PATCH 166/315] MAGETWO-94190: [Magento Cloud] Error when saving Bundle product --- .../Bundle/Model/Product/SaveHandler.php | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/app/code/Magento/Bundle/Model/Product/SaveHandler.php b/app/code/Magento/Bundle/Model/Product/SaveHandler.php index 09fce9222e63d..dbd07f188f90b 100644 --- a/app/code/Magento/Bundle/Model/Product/SaveHandler.php +++ b/app/code/Magento/Bundle/Model/Product/SaveHandler.php @@ -7,6 +7,7 @@ use Magento\Bundle\Api\ProductOptionRepositoryInterface as OptionRepository; use Magento\Bundle\Api\ProductLinkManagementInterface; +use Magento\Catalog\Api\Data\ProductInterface; use Magento\Framework\App\ObjectManager; use Magento\Framework\EntityManager\MetadataPool; use Magento\Framework\EntityManager\Operation\ExtensionInterface; @@ -49,12 +50,11 @@ public function __construct( } /** + * Perform action on Bundle product relation/extension attribute. + * * @param object $entity * @param array $arguments - * @return \Magento\Catalog\Api\Data\ProductInterface|object - * @throws \Magento\Framework\Exception\NoSuchEntityException - * @throws \Magento\Framework\Exception\InputException - * @throws \Magento\Framework\Exception\CouldNotSaveException + * @return ProductInterface|object * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function execute($entity, $arguments = []) @@ -78,7 +78,7 @@ public function execute($entity, $arguments = []) $options = $bundleProductOptions ?: []; if (!$entity->getCopyFromView()) { - $this->processRemovedOptions($entity->getSku(), $existingOptionsIds, $optionIds); + $this->processRemovedOptions($entity, $existingOptionsIds, $optionIds); $newOptionsIds = array_diff($optionIds, $existingOptionsIds); $this->saveOptions($entity, $options, $newOptionsIds); @@ -92,10 +92,10 @@ public function execute($entity, $arguments = []) } /** + * Remove option product links. + * * @param string $entitySku * @param \Magento\Bundle\Api\Data\OptionInterface $option - * @throws \Magento\Framework\Exception\NoSuchEntityException - * @throws \Magento\Framework\Exception\InputException * @return void */ protected function removeOptionLinks($entitySku, $option) @@ -152,21 +152,21 @@ private function getOptionIds(array $options) } /** - * Removes old options that no longer exists + * Removes old options that no longer exists. * - * @param string $entitySku + * @param ProductInterface $entity * @param array $existingOptionsIds * @param array $optionIds - * @throws \Magento\Framework\Exception\NoSuchEntityException - * @throws \Magento\Framework\Exception\InputException - * @throws \Magento\Framework\Exception\CouldNotSaveException * @return void */ - private function processRemovedOptions($entitySku, array $existingOptionsIds, array $optionIds) + private function processRemovedOptions(ProductInterface $entity, array $existingOptionsIds, array $optionIds) { + $metadata = $this->metadataPool->getMetadata(ProductInterface::class); + $parentId = $entity->getData($metadata->getLinkField()); foreach (array_diff($existingOptionsIds, $optionIds) as $optionId) { - $option = $this->optionRepository->get($entitySku, $optionId); - $this->removeOptionLinks($entitySku, $option); + $option = $this->optionRepository->get($entity->getSku(), $optionId); + $option->setParentId($parentId); + $this->removeOptionLinks($entity->getSku(), $option); $this->optionRepository->delete($option); } } From 9dccad1672b750908268b2577104e94a8857886a Mon Sep 17 00:00:00 2001 From: mageprince <mail.mageprince@gmail.com> Date: Tue, 19 Feb 2019 11:03:37 +0530 Subject: [PATCH 167/315] Minimum Qty Allowed in Shopping Cart not working on related product --- app/code/Magento/Checkout/Model/Cart.php | 40 +++++++++++++++--------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/app/code/Magento/Checkout/Model/Cart.php b/app/code/Magento/Checkout/Model/Cart.php index c0ba9616754bb..0eb59fc70d92f 100644 --- a/app/code/Magento/Checkout/Model/Cart.php +++ b/app/code/Magento/Checkout/Model/Cart.php @@ -15,6 +15,7 @@ * Shopping cart model * * @api + * @SuppressWarnings(PHPMD.CookieAndSessionMisuse) * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * @deprecated 100.1.0 Use \Magento\Quote\Model\Quote instead */ @@ -354,22 +355,10 @@ protected function _getProductRequest($requestInfo) public function addProduct($productInfo, $requestInfo = null) { $product = $this->_getProduct($productInfo); - $request = $this->_getProductRequest($requestInfo); $productId = $product->getId(); if ($productId) { - $stockItem = $this->stockRegistry->getStockItem($productId, $product->getStore()->getWebsiteId()); - $minimumQty = $stockItem->getMinSaleQty(); - //If product quantity is not specified in request and there is set minimal qty for it - if ($minimumQty - && $minimumQty > 0 - && !$request->getQty() - ) { - $request->setQty($minimumQty); - } - } - - if ($productId) { + $request = $this->getQtyRequest($product, $requestInfo); try { $result = $this->getQuote()->addProduct($product, $request); } catch (\Magento\Framework\Exception\LocalizedException $e) { @@ -425,8 +414,9 @@ public function addProductsByIds($productIds) } $product = $this->_getProduct($productId); if ($product->getId() && $product->isVisibleInCatalog()) { + $request = $this->getQtyRequest($product); try { - $this->getQuote()->addProduct($product); + $this->getQuote()->addProduct($product, $request); } catch (\Exception $e) { $allAdded = false; } @@ -747,4 +737,26 @@ private function getRequestInfoFilter() } return $this->requestInfoFilter; } + + /** + * Get request quantity + * + * @param Product $product + * @param \Magento\Framework\DataObject|int|array $request + * @return int|DataObject + */ + private function getQtyRequest($product, $request = 0) + { + $request = $this->_getProductRequest($request); + $stockItem = $this->stockRegistry->getStockItem($product->getId(), $product->getStore()->getWebsiteId()); + $minimumQty = $stockItem->getMinSaleQty(); + //If product quantity is not specified in request and there is set minimal qty for it + if ($minimumQty + && $minimumQty > 0 + && !$request->getQty() + ) { + $request->setQty($minimumQty); + } + return $request; + } } From 1e4055d7e734be1cf69312a40147a68c5183e1bc Mon Sep 17 00:00:00 2001 From: eduard13 <e.chitoraga@atwix.com> Date: Tue, 19 Feb 2019 08:28:26 +0200 Subject: [PATCH 168/315] Fixing the state of dropdown icon --- .../templates/grid/filters/elements/ui-select-optgroup.html | 2 +- .../base/web/templates/grid/filters/elements/ui-select.html | 3 ++- .../backend/web/css/source/actions/_actions-multiselect.less | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Ui/view/base/web/templates/grid/filters/elements/ui-select-optgroup.html b/app/code/Magento/Ui/view/base/web/templates/grid/filters/elements/ui-select-optgroup.html index 56244422a6b43..1ad0e7505ec9d 100644 --- a/app/code/Magento/Ui/view/base/web/templates/grid/filters/elements/ui-select-optgroup.html +++ b/app/code/Magento/Ui/view/base/web/templates/grid/filters/elements/ui-select-optgroup.html @@ -19,7 +19,7 @@ css: { _selected: $parent.root.isSelected(option.value), _hover: $parent.root.isHovered(option, $element), - _expended: $parent.root.getLevelVisibility($data), + _expended: $parent.root.getLevelVisibility($data) || $data.visible, _unclickable: $parent.root.isLabelDecoration($data), _last: $parent.root.addLastElement($data), '_with-checkbox': $parent.root.showCheckbox diff --git a/app/code/Magento/Ui/view/base/web/templates/grid/filters/elements/ui-select.html b/app/code/Magento/Ui/view/base/web/templates/grid/filters/elements/ui-select.html index a96a4163caf7e..0411063c11512 100644 --- a/app/code/Magento/Ui/view/base/web/templates/grid/filters/elements/ui-select.html +++ b/app/code/Magento/Ui/view/base/web/templates/grid/filters/elements/ui-select.html @@ -125,12 +125,13 @@ css: { _selected: $parent.isSelected(option.value), _hover: $parent.isHovered(option, $element), - _expended: $parent.getLevelVisibility($data), + _expended: $parent.getLevelVisibility($data) && $parent.showLevels($data), _unclickable: $parent.isLabelDecoration($data), _last: $parent.addLastElement($data), '_with-checkbox': $parent.showCheckbox }, click: function(data, event){ + $parent.showLevels($data); $parent.toggleOptionSelected($data, $index(), event); }, clickBubble: false diff --git a/app/design/adminhtml/Magento/backend/web/css/source/actions/_actions-multiselect.less b/app/design/adminhtml/Magento/backend/web/css/source/actions/_actions-multiselect.less index 213dd3d0f8e25..fc56ec1b6570a 100644 --- a/app/design/adminhtml/Magento/backend/web/css/source/actions/_actions-multiselect.less +++ b/app/design/adminhtml/Magento/backend/web/css/source/actions/_actions-multiselect.less @@ -330,7 +330,7 @@ border-top: @action-multiselect-tree-lines; height: 1px; top: @action-multiselect-menu-item__padding + @action-multiselect-tree-arrow__size/2; - width: @action-multiselect-tree-menu-item__margin-left + @action-multiselect-menu-item__padding; + width: @action-multiselect-tree-menu-item__margin-left; } // Vertical dotted line From 8da71964e8c0c937458f6499863821ad10438f75 Mon Sep 17 00:00:00 2001 From: Serhiy Yelahin <serhiy.yelahin@transoftgroup.com> Date: Tue, 19 Feb 2019 10:42:11 +0200 Subject: [PATCH 169/315] MAGETWO-97332: Configurable product is displayed as In Stock in product grid when it's set to out of stock --- ...uantityAndStockStatusFieldToCollection.php | 32 ++++++++ .../CatalogInventory/etc/adminhtml/di.xml | 1 + .../Product/QuantityAndStockStatusTest.php | 77 +++++++++++++++++++ ...nd_stock_status_attribute_used_in_grid.php | 18 +++++ ...status_attribute_used_in_grid_rollback.php | 18 +++++ 5 files changed, 146 insertions(+) create mode 100644 app/code/Magento/CatalogInventory/Ui/DataProvider/Product/AddQuantityAndStockStatusFieldToCollection.php create mode 100644 dev/tests/integration/testsuite/Magento/Catalog/Ui/DataProvider/Product/QuantityAndStockStatusTest.php create mode 100644 dev/tests/integration/testsuite/Magento/Catalog/_files/quantity_and_stock_status_attribute_used_in_grid.php create mode 100644 dev/tests/integration/testsuite/Magento/Catalog/_files/quantity_and_stock_status_attribute_used_in_grid_rollback.php diff --git a/app/code/Magento/CatalogInventory/Ui/DataProvider/Product/AddQuantityAndStockStatusFieldToCollection.php b/app/code/Magento/CatalogInventory/Ui/DataProvider/Product/AddQuantityAndStockStatusFieldToCollection.php new file mode 100644 index 0000000000000..d66a783c6720d --- /dev/null +++ b/app/code/Magento/CatalogInventory/Ui/DataProvider/Product/AddQuantityAndStockStatusFieldToCollection.php @@ -0,0 +1,32 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\CatalogInventory\Ui\DataProvider\Product; + +use Magento\Framework\Data\Collection; +use Magento\Ui\DataProvider\AddFieldToCollectionInterface; + +/** + * Add quantity_and_stock_status field to collection + */ +class AddQuantityAndStockStatusFieldToCollection implements AddFieldToCollectionInterface +{ + /** + * @inheritdoc + */ + public function addField(Collection $collection, $field, $alias = null) + { + $collection->joinField( + 'quantity_and_stock_status', + 'cataloginventory_stock_item', + 'is_in_stock', + 'product_id=entity_id', + '{{table}}.stock_id=1', + 'left' + ); + } +} diff --git a/app/code/Magento/CatalogInventory/etc/adminhtml/di.xml b/app/code/Magento/CatalogInventory/etc/adminhtml/di.xml index 803a6dae492a0..601f7ef61973b 100644 --- a/app/code/Magento/CatalogInventory/etc/adminhtml/di.xml +++ b/app/code/Magento/CatalogInventory/etc/adminhtml/di.xml @@ -23,6 +23,7 @@ <arguments> <argument name="addFieldStrategies" xsi:type="array"> <item name="qty" xsi:type="object">Magento\CatalogInventory\Ui\DataProvider\Product\AddQuantityFieldToCollection</item> + <item name="quantity_and_stock_status" xsi:type="object">Magento\CatalogInventory\Ui\DataProvider\Product\AddQuantityAndStockStatusFieldToCollection</item> </argument> <argument name="addFilterStrategies" xsi:type="array"> <item name="qty" xsi:type="object">Magento\CatalogInventory\Ui\DataProvider\Product\AddQuantityFilterToCollection</item> diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Ui/DataProvider/Product/QuantityAndStockStatusTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Ui/DataProvider/Product/QuantityAndStockStatusTest.php new file mode 100644 index 0000000000000..00fc5d3a46ec4 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/Ui/DataProvider/Product/QuantityAndStockStatusTest.php @@ -0,0 +1,77 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Catalog\Ui\DataProvider\Product; + +use Magento\CatalogInventory\Model\Stock\StockItemRepository; +use Magento\CatalogInventory\Ui\DataProvider\Product\AddQuantityAndStockStatusFieldToCollection; +use PHPUnit\Framework\TestCase; +use Magento\TestFramework\Helper\Bootstrap; +use Magento\CatalogInventory\Api\StockRegistryInterface; + +/** + * Quantity and stock status test + */ +class QuantityAndStockStatusTest extends TestCase +{ + /** + * @var string + */ + private static $quantityAndStockStatus = 'quantity_and_stock_status'; + + /** + * @var \Magento\Framework\ObjectManagerInterface + */ + private $objectManager; + + /** + * @inheritdoc + */ + protected function setUp() + { + $this->objectManager = Bootstrap::getObjectManager(); + } + + /** + * Test product stock status in the products grid column + * + * @magentoDataFixture Magento/Catalog/_files/quantity_and_stock_status_attribute_used_in_grid.php + * @magentoDataFixture Magento/Catalog/_files/products.php + */ + public function testProductStockStatus() + { + /** @var StockItemRepository $stockItemRepository */ + $stockItemRepository = $this->objectManager->create(StockItemRepository::class); + + /** @var StockRegistryInterface $stockRegistry */ + $stockRegistry = $this->objectManager->create(StockRegistryInterface::class); + + $stockItem = $stockRegistry->getStockItemBySku('simple'); + $stockItem->setIsInStock(false); + $stockItemRepository->save($stockItem); + $savedStockStatus = (int)$stockItem->getIsInStock(); + + $dataProvider = $this->objectManager->create( + ProductDataProvider::class, + [ + 'name' => 'product_listing_data_source', + 'primaryFieldName' => 'entity_id', + 'requestFieldName' => 'id', + 'addFieldStrategies' => [ + 'quantity_and_stock_status' => + $this->objectManager->get(AddQuantityAndStockStatusFieldToCollection::class) + ] + ] + ); + + $dataProvider->addField(self::$quantityAndStockStatus); + $data = $dataProvider->getData(); + $dataProviderStockStatus = $data['items'][0][self::$quantityAndStockStatus]; + + $this->assertEquals($dataProviderStockStatus, $savedStockStatus); + } +} diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/quantity_and_stock_status_attribute_used_in_grid.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/quantity_and_stock_status_attribute_used_in_grid.php new file mode 100644 index 0000000000000..1870eaba566d8 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/quantity_and_stock_status_attribute_used_in_grid.php @@ -0,0 +1,18 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); +$eavSetupFactory = $objectManager->create(\Magento\Eav\Setup\EavSetupFactory::class); +/** @var \Magento\Eav\Setup\EavSetup $eavSetup */ +$eavSetup = $eavSetupFactory->create(); +$eavSetup->updateAttribute( + \Magento\Catalog\Model\Product::ENTITY, + 'quantity_and_stock_status', + [ + 'is_used_in_grid' => 1, + ] +); diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/quantity_and_stock_status_attribute_used_in_grid_rollback.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/quantity_and_stock_status_attribute_used_in_grid_rollback.php new file mode 100644 index 0000000000000..fba12f19fdca8 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/quantity_and_stock_status_attribute_used_in_grid_rollback.php @@ -0,0 +1,18 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); +$eavSetupFactory = $objectManager->create(\Magento\Eav\Setup\EavSetupFactory::class); +/** @var \Magento\Eav\Setup\EavSetup $eavSetup */ +$eavSetup = $eavSetupFactory->create(); +$eavSetup->updateAttribute( + \Magento\Catalog\Model\Product::ENTITY, + 'quantity_and_stock_status', + [ + 'is_used_in_grid' => 0, + ] +); From 9746716226a11b4f19a6e1351c4428df2dcc3742 Mon Sep 17 00:00:00 2001 From: Nazarn96 <nazarn96@gmail.com> Date: Tue, 19 Feb 2019 11:38:45 +0200 Subject: [PATCH 170/315] Backport-issue-195196 --- .../Test/Mftf/Test/StorefrontGuestCheckoutTest.xml | 2 +- app/code/Magento/Customer/Test/Mftf/Data/CustomerData.xml | 1 + app/code/Magento/Quote/Model/QuoteManagement.php | 8 ++++++++ .../Magento/Quote/Test/Unit/Model/QuoteManagementTest.php | 2 +- .../testsuite/Magento/Quote/Model/QuoteTest.php | 3 +++ 5 files changed, 14 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontGuestCheckoutTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontGuestCheckoutTest.xml index dff957457da95..3d72582d83082 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontGuestCheckoutTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontGuestCheckoutTest.xml @@ -69,7 +69,7 @@ <waitForLoadingMaskToDisappear stepKey="waitForLoadingMaskToDisappearOnSearch"/> <click selector="{{OrdersGridSection.firstRow}}" stepKey="clickOrderRow"/> <see selector="{{OrderDetailsInformationSection.orderStatus}}" userInput="Pending" stepKey="seeAdminOrderStatus"/> - <see selector="{{OrderDetailsInformationSection.accountInformation}}" userInput="Guest" stepKey="seeAdminOrderGuest"/> + <see selector="{{OrderDetailsInformationSection.accountInformation}}" userInput="{{CustomerEntityOne.fullname}}" stepKey="seeAdminOrderGuest"/> <see selector="{{OrderDetailsInformationSection.accountInformation}}" userInput="{{CustomerEntityOne.email}}" stepKey="seeAdminOrderEmail"/> <see selector="{{OrderDetailsInformationSection.billingAddress}}" userInput="{{CustomerAddressSimple.street[0]}}" stepKey="seeAdminOrderBillingAddress"/> <see selector="{{OrderDetailsInformationSection.shippingAddress}}" userInput="{{CustomerAddressSimple.street[0]}}" stepKey="seeAdminOrderShippingAddress"/> diff --git a/app/code/Magento/Customer/Test/Mftf/Data/CustomerData.xml b/app/code/Magento/Customer/Test/Mftf/Data/CustomerData.xml index 74da84c01b861..6c7fdb9134685 100644 --- a/app/code/Magento/Customer/Test/Mftf/Data/CustomerData.xml +++ b/app/code/Magento/Customer/Test/Mftf/Data/CustomerData.xml @@ -21,6 +21,7 @@ <data key="firstname">John</data> <data key="lastname">Doe</data> <data key="middlename">S</data> + <data key="fullname">John Doe</data>s <data key="password">pwdTest123!</data> <data key="prefix">Mr</data> <data key="suffix">Sr</data> diff --git a/app/code/Magento/Quote/Model/QuoteManagement.php b/app/code/Magento/Quote/Model/QuoteManagement.php index e2ee8bbad01b9..bf1caa2434638 100644 --- a/app/code/Magento/Quote/Model/QuoteManagement.php +++ b/app/code/Magento/Quote/Model/QuoteManagement.php @@ -25,6 +25,7 @@ /** * Class QuoteManagement * + * @SuppressWarnings(PHPMD.CookieAndSessionMisuse) * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * @SuppressWarnings(PHPMD.TooManyFields) */ @@ -355,6 +356,13 @@ public function placeOrder($cartId, PaymentInterface $paymentMethod = null) if ($quote->getCheckoutMethod() === self::METHOD_GUEST) { $quote->setCustomerId(null); $quote->setCustomerEmail($quote->getBillingAddress()->getEmail()); + if ($quote->getCustomerFirstname() === null && $quote->getCustomerLastname() === null) { + $quote->setCustomerFirstname($quote->getBillingAddress()->getFirstname()); + $quote->setCustomerLastname($quote->getBillingAddress()->getLastname()); + if ($quote->getBillingAddress()->getMiddlename() === null) { + $quote->setCustomerMiddlename($quote->getBillingAddress()->getMiddlename()); + } + } $quote->setCustomerIsGuest(true); $quote->setCustomerGroupId(\Magento\Customer\Api\Data\GroupInterface::NOT_LOGGED_IN_ID); } diff --git a/app/code/Magento/Quote/Test/Unit/Model/QuoteManagementTest.php b/app/code/Magento/Quote/Test/Unit/Model/QuoteManagementTest.php index 145a18fb34ca3..cdfd0df8f9927 100644 --- a/app/code/Magento/Quote/Test/Unit/Model/QuoteManagementTest.php +++ b/app/code/Magento/Quote/Test/Unit/Model/QuoteManagementTest.php @@ -642,7 +642,7 @@ public function testPlaceOrderIfCustomerIsGuest() $addressMock = $this->createPartialMock(\Magento\Quote\Model\Quote\Address::class, ['getEmail']); $addressMock->expects($this->once())->method('getEmail')->willReturn($email); - $this->quoteMock->expects($this->once())->method('getBillingAddress')->with()->willReturn($addressMock); + $this->quoteMock->expects($this->any())->method('getBillingAddress')->with()->willReturn($addressMock); $this->quoteMock->expects($this->once())->method('setCustomerIsGuest')->with(true)->willReturnSelf(); $this->quoteMock->expects($this->once()) diff --git a/dev/tests/integration/testsuite/Magento/Quote/Model/QuoteTest.php b/dev/tests/integration/testsuite/Magento/Quote/Model/QuoteTest.php index 802358c2c83c7..3a516befc37ff 100644 --- a/dev/tests/integration/testsuite/Magento/Quote/Model/QuoteTest.php +++ b/dev/tests/integration/testsuite/Magento/Quote/Model/QuoteTest.php @@ -131,6 +131,9 @@ public function testUpdateCustomerData() $this->assertContains($item, $actual); } $this->assertEquals('test@example.com', $quote->getCustomerEmail()); + $this->assertEquals('Joe', $quote->getCustomerFirstname()); + $this->assertEquals('Dou', $quote->getCustomerLastname()); + $this->assertEquals('Ivan', $quote->getCustomerMiddlename()); } /** From 5d42fa8d04ba2fe7ad45ad5a2a6e79f6d0cf0ebe Mon Sep 17 00:00:00 2001 From: nmalevanec <mikola.malevanec@transoftgroup.com> Date: Tue, 19 Feb 2019 13:27:13 +0200 Subject: [PATCH 171/315] Fix functional test. --- .../Mftf/Section/AdminOrderFormConfigureProductSection.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderFormConfigureProductSection.xml b/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderFormConfigureProductSection.xml index 83d417f6f8555..efffa48103b93 100644 --- a/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderFormConfigureProductSection.xml +++ b/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderFormConfigureProductSection.xml @@ -9,8 +9,8 @@ <sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> <section name="AdminOrderFormConfigureProductSection"> - <element name="optionSelect" type="select" selector="//div[@class='product-options']/div/div/select[../../label[text() = '{{option}}']]" parameterized="true"/> + <element name="optionSelect" type="select" selector="//div[contains(@class, 'product-options')]//div//label[.='{{option}}']//following-sibling::*//select" parameterized="true"/> <element name="quantity" type="input" selector="#product_composite_configure_input_qty"/> <element name="ok" type="button" selector=".modal-header .page-actions button[data-role='action']" timeout="30"/> </section> -</sections> \ No newline at end of file +</sections> From 7a2b275c22324e9b2684698167372dc10a196dbe Mon Sep 17 00:00:00 2001 From: Serhii Voloshkov <serhii.voloshkov@transoftgroup.com> Date: Tue, 19 Feb 2019 16:59:11 +0200 Subject: [PATCH 172/315] MAGETWO-95904: Header Minicart, Shopping cart page and Checkout page show incorrect product name --- .../Magento/Checkout/Block/Cart/Sidebar.php | 5 +- .../Magento/Checkout/CustomerData/Cart.php | 3 +- .../StorefrontMiniCartActionGroup.xml | 2 +- .../CheckoutShippingGuestInfoSection.xml | 4 +- ...tOnCheckoutPageDifferentStoreViewsTest.xml | 87 +++++++++++++++++++ .../Test/Unit/Block/Cart/SidebarTest.php | 14 ++- .../Test/Unit/CustomerData/CartTest.php | 13 ++- .../view/frontend/web/js/view/minicart.js | 7 +- .../Block/Adminhtml/Edit/Tab/View/Cart.php | 2 +- app/code/Magento/Quote/Model/Quote.php | 6 +- .../Quote/Plugin/UpdateQuoteItemStore.php | 73 ++++++++++++++++ app/code/Magento/Quote/etc/frontend/di.xml | 3 + 12 files changed, 204 insertions(+), 15 deletions(-) create mode 100644 app/code/Magento/Checkout/Test/Mftf/Test/StorefrontProductNameMinicartOnCheckoutPageDifferentStoreViewsTest.xml create mode 100644 app/code/Magento/Quote/Plugin/UpdateQuoteItemStore.php diff --git a/app/code/Magento/Checkout/Block/Cart/Sidebar.php b/app/code/Magento/Checkout/Block/Cart/Sidebar.php index 5c237eecf0a9f..7453d3c62e862 100644 --- a/app/code/Magento/Checkout/Block/Cart/Sidebar.php +++ b/app/code/Magento/Checkout/Block/Cart/Sidebar.php @@ -67,7 +67,7 @@ public function __construct( } /** - * Returns minicart config + * Returns minicart config. * * @return array */ @@ -82,7 +82,8 @@ public function getConfig() 'baseUrl' => $this->getBaseUrl(), 'minicartMaxItemsVisible' => $this->getMiniCartMaxItemsCount(), 'websiteId' => $this->_storeManager->getStore()->getWebsiteId(), - 'maxItemsToDisplay' => $this->getMaxItemsToDisplay() + 'maxItemsToDisplay' => $this->getMaxItemsToDisplay(), + 'storeId' => $this->_storeManager->getStore()->getId(), ]; } diff --git a/app/code/Magento/Checkout/CustomerData/Cart.php b/app/code/Magento/Checkout/CustomerData/Cart.php index 01e91d75c02d9..9154e9c99478e 100644 --- a/app/code/Magento/Checkout/CustomerData/Cart.php +++ b/app/code/Magento/Checkout/CustomerData/Cart.php @@ -98,7 +98,8 @@ public function getSectionData() 'items' => $this->getRecentItems(), 'extra_actions' => $this->layout->createBlock(\Magento\Catalog\Block\ShortcutButtons::class)->toHtml(), 'isGuestCheckoutAllowed' => $this->isGuestCheckoutAllowed(), - 'website_id' => $this->getQuote()->getStore()->getWebsiteId() + 'website_id' => $this->getQuote()->getStore()->getWebsiteId(), + 'storeId' => $this->getQuote()->getStore()->getStoreId(), ]; } diff --git a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/StorefrontMiniCartActionGroup.xml b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/StorefrontMiniCartActionGroup.xml index 7a5c5e1d15872..3390dc588b69b 100644 --- a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/StorefrontMiniCartActionGroup.xml +++ b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/StorefrontMiniCartActionGroup.xml @@ -15,7 +15,7 @@ </actionGroup> <actionGroup name="assertOneProductNameInMiniCart"> <arguments> - <argument name="productName"/> + <argument name="productName" type="string"/> </arguments> <conditionalClick selector="{{StorefrontMinicartSection.showCart}}" dependentSelector="{{StorefrontMinicartSection.miniCartOpened}}" visible="false" stepKey="openMiniCart"/> <waitForElementVisible selector="{{StorefrontMinicartSection.viewAndEditCart}}" stepKey="waitForViewAndEditCartVisible"/> diff --git a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingGuestInfoSection.xml b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingGuestInfoSection.xml index 8e043f85a0b95..0a243d54cedef 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingGuestInfoSection.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingGuestInfoSection.xml @@ -7,7 +7,7 @@ --> <sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/SectionObject.xsd"> + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> <section name="CheckoutShippingGuestInfoSection"> <element name="email" type="input" selector="#customer-email"/> <element name="firstName" type="input" selector="input[name=firstname]"/> @@ -17,5 +17,7 @@ <element name="region" type="select" selector="select[name=region_id]"/> <element name="postcode" type="input" selector="input[name=postcode]"/> <element name="telephone" type="input" selector="input[name=telephone]"/> + <element name="itemInCart" type="button" selector="div.items-in-cart div.title"/> + <element name="productName" type="text" selector="div.items-in-cart strong.product-item-name"/> </section> </sections> diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontProductNameMinicartOnCheckoutPageDifferentStoreViewsTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontProductNameMinicartOnCheckoutPageDifferentStoreViewsTest.xml new file mode 100644 index 0000000000000..a810aa7107ff1 --- /dev/null +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontProductNameMinicartOnCheckoutPageDifferentStoreViewsTest.xml @@ -0,0 +1,87 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="StorefrontProductNameMinicartOnCheckoutPageDifferentStoreViewsTest"> + <annotations> + <title value="Checking Product name with custom store views"/> + <description value="Checking Product name in Minicart and on Checkout page with custom store views"/> + <stories value="Verify product name with custom store view"/> + <severity value="MAJOR"/> + <testCaseId value="MC-14944"/> + <features value="Checkout"/> + <group value="checkout"/> + </annotations> + <before> + <!--Login as Admin--> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + <!--Create a product--> + <createData entity="SimpleSubCategory" stepKey="createCategory"/> + <createData entity="SimpleProduct" stepKey="createProduct"> + <requiredEntity createDataKey="createCategory"/> + </createData> + <!-- Create store view --> + <actionGroup ref="AdminCreateStoreViewActionGroup" stepKey="createStoreView"> + <argument name="customStore" value="customStore"/> + </actionGroup> + </before> + <after> + <!--Delete product--> + <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> + <deleteData createDataKey="createProduct" stepKey="deleteProduct"/> + <!--Delete store view--> + <actionGroup ref="AdminDeleteStoreViewActionGroup" stepKey="deleteStoreView"> + <argument name="customStore" value="customStore"/> + </actionGroup> + <!--Logout from admin--> + <actionGroup ref="logout" stepKey="logout"/> + </after> + + <!--Go to created product page--> + <amOnPage url="{{AdminProductEditPage.url($$createProduct.id$$)}}" stepKey="goToEditPage"/> + + <!--Switch to second store view and change the product name--> + <actionGroup ref="SwitchToTheNewStoreView" stepKey="switchToCustomStoreView"> + <argument name="storeViewName" value="customStore"/> + </actionGroup> + <click selector="{{AdminProductFormSection.productNameUseDefault}}" stepKey="uncheckUseDefault"/> + <fillField selector="{{AdminProductFormSection.productName}}" userInput="$$createProduct.name$$-new" stepKey="fillProductName"/> + <click selector="{{AdminProductFormActionSection.saveButton}}" stepKey="saveProduct"/> + + <!--Add product to cart--> + <amOnPage url="{{StorefrontProductPage.url($$createProduct.name$$)}}" stepKey="amOnProductPage"/> + <actionGroup ref="addToCartFromStorefrontProductPage" stepKey="addToCartFromStorefrontProductPage"> + <argument name="productName" value="$createProduct.name$$"/> + </actionGroup> + + <!--Check simple product in minicart--> + <actionGroup ref="assertOneProductNameInMiniCart" stepKey="assertProductNameInMiniCart1"> + <argument name="productName" value="$$createProduct.name$$"/> + </actionGroup> + + <!--Switch to second store view--> + <actionGroup ref="StorefrontSwitchStoreViewActionGroup" stepKey="switchStoreView"> + <argument name="storeView" value="customStore"/> + </actionGroup> + + <!--Check simple product in minicart--> + <actionGroup ref="assertOneProductNameInMiniCart" stepKey="assertProductNameInMiniCart2"> + <argument name="productName" value="$$createProduct.name$$-new"/> + </actionGroup> + + <!--Go to Shopping Cart--> + <actionGroup ref="clickViewAndEditCartFromMiniCart" stepKey="goToCheckoutFromMinicart"/> + <seeElement selector="{{CheckoutCartProductSection.productLinkByName($$createProduct.name$$-new)}}" stepKey="assertProductName"/> + + <!--Proceed to checkout--> + <actionGroup ref="GoToCheckoutFromMinicartActionGroup" stepKey="goToCheckoutPage"/> + <conditionalClick selector="{{CheckoutShippingGuestInfoSection.itemInCart}}" dependentSelector="{{CheckoutShippingGuestInfoSection.itemInCart}}" visible="true" stepKey="clickItemsInCart"/> + <see selector="{{CheckoutShippingGuestInfoSection.productName}}" userInput="$$createProduct.name$$-new" stepKey="seeProductNameAtCheckout"/> + </test> +</tests> diff --git a/app/code/Magento/Checkout/Test/Unit/Block/Cart/SidebarTest.php b/app/code/Magento/Checkout/Test/Unit/Block/Cart/SidebarTest.php index 88751b899d7c9..015d8ccbe928f 100644 --- a/app/code/Magento/Checkout/Test/Unit/Block/Cart/SidebarTest.php +++ b/app/code/Magento/Checkout/Test/Unit/Block/Cart/SidebarTest.php @@ -6,6 +6,8 @@ namespace Magento\Checkout\Test\Unit\Block\Cart; /** + * Unit tests for Magento\Checkout\Block\Cart\Sidebar. + * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class SidebarTest extends \PHPUnit\Framework\TestCase @@ -123,6 +125,11 @@ public function testGetTotalsHtml() $this->assertEquals($totalsHtml, $this->model->getTotalsHtml()); } + /** + * Unit test for getConfig method. + * + * @return void + */ public function testGetConfig() { $websiteId = 100; @@ -144,14 +151,15 @@ public function testGetConfig() 'baseUrl' => $baseUrl, 'minicartMaxItemsVisible' => 3, 'websiteId' => 100, - 'maxItemsToDisplay' => 8 + 'maxItemsToDisplay' => 8, + 'storeId' => null, ]; $valueMap = [ ['checkout/cart', [], $shoppingCartUrl], ['checkout', [], $checkoutUrl], ['checkout/sidebar/updateItemQty', ['_secure' => false], $updateItemQtyUrl], - ['checkout/sidebar/removeItem', ['_secure' => false], $removeItemUrl] + ['checkout/sidebar/removeItem', ['_secure' => false], $removeItemUrl], ]; $this->requestMock->expects($this->any()) @@ -161,7 +169,7 @@ public function testGetConfig() $this->urlBuilderMock->expects($this->exactly(4)) ->method('getUrl') ->willReturnMap($valueMap); - $this->storeManagerMock->expects($this->exactly(2))->method('getStore')->willReturn($storeMock); + $this->storeManagerMock->expects($this->atLeastOnce())->method('getStore')->willReturn($storeMock); $storeMock->expects($this->once())->method('getBaseUrl')->willReturn($baseUrl); $this->imageHelper->expects($this->once())->method('getFrame')->willReturn(false); diff --git a/app/code/Magento/Checkout/Test/Unit/CustomerData/CartTest.php b/app/code/Magento/Checkout/Test/Unit/CustomerData/CartTest.php index 75e181cbabd08..9f718f00b4b9d 100644 --- a/app/code/Magento/Checkout/Test/Unit/CustomerData/CartTest.php +++ b/app/code/Magento/Checkout/Test/Unit/CustomerData/CartTest.php @@ -7,6 +7,8 @@ namespace Magento\Checkout\Test\Unit\CustomerData; /** + * Unit tests for Magento\Checkout\CustomerData\Cart. + * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class CartTest extends \PHPUnit\Framework\TestCase @@ -78,6 +80,11 @@ public function testIsGuestCheckoutAllowed() $this->assertTrue($this->model->isGuestCheckoutAllowed()); } + /** + * Unit test for getSectionData method. + * + * @return void + */ public function testGetSectionData() { $summaryQty = 100; @@ -113,7 +120,7 @@ public function testGetSectionData() $storeMock = $this->createPartialMock(\Magento\Store\Model\System\Store::class, ['getWebsiteId']); $storeMock->expects($this->once())->method('getWebsiteId')->willReturn($websiteId); - $quoteMock->expects($this->once())->method('getStore')->willReturn($storeMock); + $quoteMock->expects($this->atLeastOnce())->method('getStore')->willReturn($storeMock); $productMock = $this->createPartialMock( \Magento\Catalog\Model\Product::class, @@ -162,6 +169,7 @@ public function testGetSectionData() 'isGuestCheckoutAllowed' => 1, 'website_id' => $websiteId, 'subtotalAmount' => 200, + 'storeId' => null, ]; $this->assertEquals($expectedResult, $this->model->getSectionData()); } @@ -199,7 +207,7 @@ public function testGetSectionDataWithCompositeProduct() $storeMock = $this->createPartialMock(\Magento\Store\Model\System\Store::class, ['getWebsiteId']); $storeMock->expects($this->once())->method('getWebsiteId')->willReturn($websiteId); - $quoteMock->expects($this->once())->method('getStore')->willReturn($storeMock); + $quoteMock->expects($this->atLeastOnce())->method('getStore')->willReturn($storeMock); $this->checkoutCartMock->expects($this->once())->method('getSummaryQty')->willReturn($summaryQty); $this->checkoutHelperMock->expects($this->once()) @@ -265,6 +273,7 @@ public function testGetSectionDataWithCompositeProduct() 'isGuestCheckoutAllowed' => 1, 'website_id' => $websiteId, 'subtotalAmount' => 200, + 'storeId' => null, ]; $this->assertEquals($expectedResult, $this->model->getSectionData()); } diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/minicart.js b/app/code/Magento/Checkout/view/frontend/web/js/view/minicart.js index a2f8c8c56ff33..5e29fa209a641 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/view/minicart.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/view/minicart.js @@ -81,6 +81,7 @@ define([ maxItemsToDisplay: window.checkout.maxItemsToDisplay, cart: {}, + // jscs:disable requireCamelCaseOrUpperCaseIdentifiers /** * @override */ @@ -101,12 +102,16 @@ define([ self.isLoading(true); }); - if (cartData()['website_id'] !== window.checkout.websiteId) { + if (cartData().website_id !== window.checkout.websiteId || + cartData().store_id !== window.checkout.storeId + ) { customerData.reload(['cart'], false); } return this._super(); }, + //jscs:enable requireCamelCaseOrUpperCaseIdentifiers + isLoading: ko.observable(false), initSidebar: initSidebar, diff --git a/app/code/Magento/Customer/Block/Adminhtml/Edit/Tab/View/Cart.php b/app/code/Magento/Customer/Block/Adminhtml/Edit/Tab/View/Cart.php index 3f2c7cda7608d..d0973d3baf383 100644 --- a/app/code/Magento/Customer/Block/Adminhtml/Edit/Tab/View/Cart.php +++ b/app/code/Magento/Customer/Block/Adminhtml/Edit/Tab/View/Cart.php @@ -94,7 +94,7 @@ protected function _prepareCollection() $quote = $this->getQuote(); if ($quote) { - $collection = $quote->getItemsCollection(false); + $collection = $quote->getItemsCollection(true); } else { $collection = $this->_dataCollectionFactory->create(); } diff --git a/app/code/Magento/Quote/Model/Quote.php b/app/code/Magento/Quote/Model/Quote.php index a3f5d1aaa6a6a..6ea70e63fdbf6 100644 --- a/app/code/Magento/Quote/Model/Quote.php +++ b/app/code/Magento/Quote/Model/Quote.php @@ -1354,7 +1354,7 @@ public function addShippingAddress(\Magento\Quote\Api\Data\AddressInterface $add } /** - * Retrieve quote items collection + * Retrieve quote items collection. * * @param bool $useCache * @return \Magento\Eav\Model\Entity\Collection\AbstractCollection @@ -1362,10 +1362,10 @@ public function addShippingAddress(\Magento\Quote\Api\Data\AddressInterface $add */ public function getItemsCollection($useCache = true) { - if ($this->hasItemsCollection()) { + if ($this->hasItemsCollection() && $useCache) { return $this->getData('items_collection'); } - if (null === $this->_items) { + if (null === $this->_items || !$useCache) { $this->_items = $this->_quoteItemCollectionFactory->create(); $this->extensionAttributesJoinProcessor->process($this->_items); $this->_items->setQuote($this); diff --git a/app/code/Magento/Quote/Plugin/UpdateQuoteItemStore.php b/app/code/Magento/Quote/Plugin/UpdateQuoteItemStore.php new file mode 100644 index 0000000000000..4d3e2dff70f9b --- /dev/null +++ b/app/code/Magento/Quote/Plugin/UpdateQuoteItemStore.php @@ -0,0 +1,73 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Quote\Plugin; + +use Magento\Checkout\Model\Session; +use Magento\Quote\Model\QuoteRepository; +use Magento\Store\Api\Data\StoreInterface; +use Magento\Store\Model\StoreSwitcherInterface; + +/** + * Updates quote items store id. + * + * @SuppressWarnings(PHPMD.CookieAndSessionMisuse) + */ +class UpdateQuoteItemStore +{ + /** + * @var QuoteRepository + */ + private $quoteRepository; + + /** + * @var Session + */ + private $checkoutSession; + + /** + * @param QuoteRepository $quoteRepository + * @param Session $checkoutSession + */ + public function __construct( + QuoteRepository $quoteRepository, + Session $checkoutSession + ) { + $this->quoteRepository = $quoteRepository; + $this->checkoutSession = $checkoutSession; + } + + /** + * Update store id in active quote after store view switching. + * + * @param StoreSwitcherInterface $subject + * @param string $result + * @param StoreInterface $fromStore store where we came from + * @param StoreInterface $targetStore store where to go to + * @param string $redirectUrl original url requested for redirect after switching + * @return string url to be redirected after switching + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function afterSwitch( + StoreSwitcherInterface $subject, + string $result, + StoreInterface $fromStore, + StoreInterface $targetStore, + string $redirectUrl + ): string { + $quote = $this->checkoutSession->getQuote(); + if ($quote->getIsActive()) { + $quote->setStoreId( + $targetStore->getId() + ); + $quote->getItemsCollection(false); + $this->quoteRepository->save($quote); + } + + return $result; + } +} diff --git a/app/code/Magento/Quote/etc/frontend/di.xml b/app/code/Magento/Quote/etc/frontend/di.xml index 25acd6763ba56..91f4cfbf60aba 100644 --- a/app/code/Magento/Quote/etc/frontend/di.xml +++ b/app/code/Magento/Quote/etc/frontend/di.xml @@ -12,6 +12,9 @@ <argument name="checkoutSession" xsi:type="object">Magento\Checkout\Model\Session\Proxy</argument> </arguments> </type> + <type name="Magento\Store\Model\StoreSwitcherInterface"> + <plugin name="update_quote_item_store_after_switch_store_view" type="Magento\Quote\Plugin\UpdateQuoteItemStore"/> + </type> <type name="Magento\Store\Api\StoreCookieManagerInterface"> <plugin name="update_quote_store_after_switch_store_view" type="Magento\Quote\Plugin\UpdateQuoteStore"/> </type> From 0c5f4a16d48e0e510db3cdd111e7b426bf43c510 Mon Sep 17 00:00:00 2001 From: Volodymyr Zaets <vzaets@magento.com> Date: Tue, 19 Feb 2019 15:27:47 -0600 Subject: [PATCH 173/315] Add ignore tag for static test --- .../web/css/source/module/order/_order-account.less | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/module/order/_order-account.less b/app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/module/order/_order-account.less index f66e94940c55d..7958378be2c5b 100644 --- a/app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/module/order/_order-account.less +++ b/app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/module/order/_order-account.less @@ -35,10 +35,11 @@ .field-email { margin-left: -30px; } - + //@codingStandardsIgnoreStart .field-group_id { margin-right: 30px; } + //@codingStandardsIgnoreEnd } } } From eaf914bfdf964b434f8a575e9141a566a0d96a72 Mon Sep 17 00:00:00 2001 From: Yogesh Suhagiya <yksuhagiya@gmail.com> Date: Wed, 13 Feb 2019 11:03:55 +0530 Subject: [PATCH 174/315] Added translation for comment tag --- app/code/Magento/Msrp/etc/adminhtml/system.xml | 2 +- app/code/Magento/Msrp/i18n/en_US.csv | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Msrp/etc/adminhtml/system.xml b/app/code/Magento/Msrp/etc/adminhtml/system.xml index 8ce0ea67343f8..c20d753a2e794 100644 --- a/app/code/Magento/Msrp/etc/adminhtml/system.xml +++ b/app/code/Magento/Msrp/etc/adminhtml/system.xml @@ -10,7 +10,7 @@ <section id="sales"> <group id="msrp" translate="label" type="text" sortOrder="110" showInDefault="1" showInWebsite="1" showInStore="0"> <label>Minimum Advertised Price</label> - <field id="enabled" translate="label" type="select" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="0" canRestore="1"> + <field id="enabled" translate="label comment" type="select" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="0" canRestore="1"> <label>Enable MAP</label> <source_model>Magento\Config\Model\Config\Source\Yesno</source_model> <comment> diff --git a/app/code/Magento/Msrp/i18n/en_US.csv b/app/code/Magento/Msrp/i18n/en_US.csv index d647f8527ec15..d47d72b2bdc9a 100644 --- a/app/code/Magento/Msrp/i18n/en_US.csv +++ b/app/code/Magento/Msrp/i18n/en_US.csv @@ -13,6 +13,7 @@ Price,Price "Add to Cart","Add to Cart" "Minimum Advertised Price","Minimum Advertised Price" "Enable MAP","Enable MAP" +"<strong style=""color:red"">Warning!</strong> Enabling MAP by default will hide all product prices on Storefront.","<strong style=""color:red"">Warning!</strong> Enabling MAP by default will hide all product prices on Storefront." "Display Actual Price","Display Actual Price" "Default Popup Text Message","Default Popup Text Message" "Default ""What's This"" Text Message","Default ""What's This"" Text Message" From d78ccf6cec8e3f2dee6d47afe49545967fe3a2b3 Mon Sep 17 00:00:00 2001 From: Serhii Voloshkov <serhii.voloshkov@transoftgroup.com> Date: Wed, 20 Feb 2019 10:08:30 +0200 Subject: [PATCH 175/315] MAGETWO-95904: Header Minicart, Shopping cart page and Checkout page show incorrect product name --- app/code/Magento/Checkout/Block/Cart/Sidebar.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/code/Magento/Checkout/Block/Cart/Sidebar.php b/app/code/Magento/Checkout/Block/Cart/Sidebar.php index 7453d3c62e862..5e3234e9f4cc8 100644 --- a/app/code/Magento/Checkout/Block/Cart/Sidebar.php +++ b/app/code/Magento/Checkout/Block/Cart/Sidebar.php @@ -133,6 +133,7 @@ public function getShoppingCartUrl() * * @return string * @codeCoverageIgnore + * @SuppressWarnings(PHPMD.RequestAwareBlockMethod) */ public function getUpdateItemQtyUrl() { @@ -144,6 +145,7 @@ public function getUpdateItemQtyUrl() * * @return string * @codeCoverageIgnore + * @SuppressWarnings(PHPMD.RequestAwareBlockMethod) */ public function getRemoveItemUrl() { From 39b96e9a4962aeff34052e7807f773ac19ac4836 Mon Sep 17 00:00:00 2001 From: Serhii Voloshkov <serhii.voloshkov@transoftgroup.com> Date: Wed, 20 Feb 2019 12:13:56 +0200 Subject: [PATCH 176/315] MAGETWO-94834: Cannot translate specific admin sections with inline translation --- app/code/Magento/Ui/view/base/web/js/grid/search/search.js | 2 +- .../base/web/templates/grid/controls/bookmarks/bookmarks.html | 2 +- .../view/base/web/templates/grid/controls/bookmarks/view.html | 2 +- .../Magento/Ui/view/base/web/templates/grid/search/search.html | 3 ++- app/code/Magento/Ui/view/base/web/templates/grid/submenu.html | 2 +- .../Ui/view/base/web/templates/grid/tree-massactions.html | 2 +- 6 files changed, 7 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/Ui/view/base/web/js/grid/search/search.js b/app/code/Magento/Ui/view/base/web/js/grid/search/search.js index fa445a2577adb..be825a391cf07 100644 --- a/app/code/Magento/Ui/view/base/web/js/grid/search/search.js +++ b/app/code/Magento/Ui/view/base/web/js/grid/search/search.js @@ -18,7 +18,7 @@ define([ return Element.extend({ defaults: { template: 'ui/grid/search/search', - placeholder: $t('Search by keyword'), + placeholder: 'Search by keyword', label: $t('Keyword'), value: '', previews: [], diff --git a/app/code/Magento/Ui/view/base/web/templates/grid/controls/bookmarks/bookmarks.html b/app/code/Magento/Ui/view/base/web/templates/grid/controls/bookmarks/bookmarks.html index 3ef64fd4b5371..36a3232c3e61a 100644 --- a/app/code/Magento/Ui/view/base/web/templates/grid/controls/bookmarks/bookmarks.html +++ b/app/code/Magento/Ui/view/base/web/templates/grid/controls/bookmarks/bookmarks.html @@ -6,7 +6,7 @@ --> <div class="admin__action-dropdown-wrap admin__data-grid-action-bookmarks" collapsible> <button class="admin__action-dropdown" type="button" toggleCollapsible> - <span class="admin__action-dropdown-text" text="activeView.label"/> + <span class="admin__action-dropdown-text" translate="activeView.label"/> </button> <ul class="admin__action-dropdown-menu"> <repeat args="foreach: viewsArray, item: '$view'"> diff --git a/app/code/Magento/Ui/view/base/web/templates/grid/controls/bookmarks/view.html b/app/code/Magento/Ui/view/base/web/templates/grid/controls/bookmarks/view.html index b52669e2cd28d..521ce9fc806ac 100644 --- a/app/code/Magento/Ui/view/base/web/templates/grid/controls/bookmarks/view.html +++ b/app/code/Magento/Ui/view/base/web/templates/grid/controls/bookmarks/view.html @@ -30,7 +30,7 @@ </div> <div class="action-dropdown-menu-item"> - <a href="" class="action-dropdown-menu-link" text="$view().label" click="applyView.bind($data, $view().index)" closeCollapsible/> + <a href="" class="action-dropdown-menu-link" translate="$view().label" click="applyView.bind($data, $view().index)" closeCollapsible/> <div class="action-dropdown-menu-item-actions" if="$view().editable"> <button class="action-edit" type="button" attr="title: $t('Edit bookmark')" click="editView.bind($data, $view().index)"> diff --git a/app/code/Magento/Ui/view/base/web/templates/grid/search/search.html b/app/code/Magento/Ui/view/base/web/templates/grid/search/search.html index 39d996e05c3a6..13b82a93eca25 100644 --- a/app/code/Magento/Ui/view/base/web/templates/grid/search/search.html +++ b/app/code/Magento/Ui/view/base/web/templates/grid/search/search.html @@ -10,9 +10,10 @@ </label> <input class="admin__control-text data-grid-search-control" type="text" data-bind=" + i18n: placeholder, attr: { id: index, - placeholder: placeholder + placeholder: $t(placeholder) }, textInput: inputValue, keyboard: { diff --git a/app/code/Magento/Ui/view/base/web/templates/grid/submenu.html b/app/code/Magento/Ui/view/base/web/templates/grid/submenu.html index c5d87a4b16c4e..610d78e00b81d 100644 --- a/app/code/Magento/Ui/view/base/web/templates/grid/submenu.html +++ b/app/code/Magento/Ui/view/base/web/templates/grid/submenu.html @@ -6,7 +6,7 @@ --> <ul class="action-submenu" each="data: action.actions, as: 'action'" css="_active: action.visible"> <li css="_visible: $data.visible"> - <span class="action-menu-item" text="label" click="$parent.applyAction.bind($parent, type)"/> + <span class="action-menu-item" translate="label" click="$parent.applyAction.bind($parent, type)"/> <render args="name: $parent.submenuTemplate, data: $parent" if="$data.actions"/> </li> </ul> diff --git a/app/code/Magento/Ui/view/base/web/templates/grid/tree-massactions.html b/app/code/Magento/Ui/view/base/web/templates/grid/tree-massactions.html index 1aeb48b7c7698..d11d4aa243737 100644 --- a/app/code/Magento/Ui/view/base/web/templates/grid/tree-massactions.html +++ b/app/code/Magento/Ui/view/base/web/templates/grid/tree-massactions.html @@ -11,7 +11,7 @@ <div class="action-menu-items"> <ul class="action-menu" each="data: actions, as: 'action'" css="_active: opened"> <li css="_visible: $data.visible, _parent: $data.actions"> - <span class="action-menu-item" text="label" click="$parent.applyAction.bind($parent, type)"/> + <span class="action-menu-item" translate="label" click="$parent.applyAction.bind($parent, type)"/> <render args="name: $parent.submenuTemplate, data: $parent" if="$data.actions"/> </li> </ul> From f5df1a8e4e4a97ee5ce6b7f1fdd0e5f90a41c679 Mon Sep 17 00:00:00 2001 From: Jaimin Sutariya <jaimin.sutariya@krishtechnolabs.com> Date: Sun, 27 Jan 2019 14:06:01 +0530 Subject: [PATCH 177/315] Removed direct use of SessionManager class, used SessionManagerInterface instead --- .../Customer/CustomerData/Plugin/SessionChecker.php | 8 ++++---- app/code/Magento/Customer/etc/frontend/di.xml | 4 ++-- .../Controller/Transparent/RequestSecureToken.php | 11 +++++++---- lib/internal/Magento/Framework/View/Context.php | 7 +++++-- 4 files changed, 18 insertions(+), 12 deletions(-) diff --git a/app/code/Magento/Customer/CustomerData/Plugin/SessionChecker.php b/app/code/Magento/Customer/CustomerData/Plugin/SessionChecker.php index aa73e275ee0ca..6497b039c7790 100644 --- a/app/code/Magento/Customer/CustomerData/Plugin/SessionChecker.php +++ b/app/code/Magento/Customer/CustomerData/Plugin/SessionChecker.php @@ -5,7 +5,7 @@ */ namespace Magento\Customer\CustomerData\Plugin; -use Magento\Framework\Session\SessionManager; +use Magento\Framework\Session\SessionManagerInterface; use Magento\Framework\Stdlib\Cookie\CookieMetadataFactory; use Magento\Framework\Stdlib\Cookie\PhpCookieManager; @@ -36,10 +36,10 @@ public function __construct( /** * Delete frontend session cookie if customer session is expired * - * @param SessionManager $sessionManager + * @param SessionManagerInterface $sessionManager * @return void */ - public function beforeStart(SessionManager $sessionManager) + public function beforeStart(SessionManagerInterface $sessionManager) { if (!$this->cookieManager->getCookie($sessionManager->getName()) && $this->cookieManager->getCookie('mage-cache-sessid') @@ -49,4 +49,4 @@ public function beforeStart(SessionManager $sessionManager) $this->cookieManager->deleteCookie('mage-cache-sessid', $metadata); } } -} +} \ No newline at end of file diff --git a/app/code/Magento/Customer/etc/frontend/di.xml b/app/code/Magento/Customer/etc/frontend/di.xml index 4a45c4ad48d19..c31742519e581 100644 --- a/app/code/Magento/Customer/etc/frontend/di.xml +++ b/app/code/Magento/Customer/etc/frontend/di.xml @@ -57,7 +57,7 @@ <type name="Magento\Checkout\Block\Cart\Sidebar"> <plugin name="customer_cart" type="Magento\Customer\Model\Cart\ConfigPlugin" /> </type> - <type name="Magento\Framework\Session\SessionManager"> + <type name="Magento\Framework\Session\SessionManagerInterface"> <plugin name="session_checker" type="Magento\Customer\CustomerData\Plugin\SessionChecker" /> </type> <type name="Magento\Authorization\Model\CompositeUserContext"> @@ -77,4 +77,4 @@ </argument> </arguments> </type> -</config> +</config> \ No newline at end of file diff --git a/app/code/Magento/Paypal/Controller/Transparent/RequestSecureToken.php b/app/code/Magento/Paypal/Controller/Transparent/RequestSecureToken.php index 3738a479816b3..68e5e888364b2 100644 --- a/app/code/Magento/Paypal/Controller/Transparent/RequestSecureToken.php +++ b/app/code/Magento/Paypal/Controller/Transparent/RequestSecureToken.php @@ -11,6 +11,7 @@ use Magento\Framework\Controller\ResultInterface; use Magento\Framework\Session\Generic; use Magento\Framework\Session\SessionManager; +use Magento\Framework\Session\SessionManagerInterface; use Magento\Paypal\Model\Payflow\Service\Request\SecureToken; use Magento\Paypal\Model\Payflow\Transparent; use Magento\Quote\Model\Quote; @@ -39,7 +40,7 @@ class RequestSecureToken extends \Magento\Framework\App\Action\Action private $secureTokenService; /** - * @var SessionManager + * @var SessionManager|SessionManagerInterface */ private $sessionManager; @@ -55,6 +56,7 @@ class RequestSecureToken extends \Magento\Framework\App\Action\Action * @param SecureToken $secureTokenService * @param SessionManager $sessionManager * @param Transparent $transparent + * @param SessionManagerInterface|null $sessionManagerInterface */ public function __construct( Context $context, @@ -62,12 +64,13 @@ public function __construct( Generic $sessionTransparent, SecureToken $secureTokenService, SessionManager $sessionManager, - Transparent $transparent + Transparent $transparent, + SessionManagerInterface $sessionInterface = null ) { $this->resultJsonFactory = $resultJsonFactory; $this->sessionTransparent = $sessionTransparent; $this->secureTokenService = $secureTokenService; - $this->sessionManager = $sessionManager; + $this->sessionManager = $sessionInterface ?: $sessionManager; $this->transparent = $transparent; parent::__construct($context); } @@ -120,4 +123,4 @@ private function getErrorResponse() ] ); } -} +} \ No newline at end of file diff --git a/lib/internal/Magento/Framework/View/Context.php b/lib/internal/Magento/Framework/View/Context.php index c3f1c3e691c84..c3876b8ca74de 100644 --- a/lib/internal/Magento/Framework/View/Context.php +++ b/lib/internal/Magento/Framework/View/Context.php @@ -14,6 +14,7 @@ use Magento\Framework\Event\ManagerInterface; use Psr\Log\LoggerInterface as Logger; use Magento\Framework\Session\SessionManager; +use Magento\Framework\Session\SessionManagerInterface; use Magento\Framework\TranslateInterface; use Magento\Framework\UrlInterface; use Magento\Framework\View\ConfigInterface as ViewConfig; @@ -144,6 +145,7 @@ class Context * @param Logger $logger * @param AppState $appState * @param LayoutInterface $layout + * @param SessionManagerInterface|null $sessionManager * * @todo reduce parameter number * @@ -163,7 +165,8 @@ public function __construct( CacheState $cacheState, Logger $logger, AppState $appState, - LayoutInterface $layout + LayoutInterface $layout, + SessionManagerInterface $sessionManager = null ) { $this->request = $request; $this->eventManager = $eventManager; @@ -171,7 +174,7 @@ public function __construct( $this->translator = $translator; $this->cache = $cache; $this->design = $design; - $this->session = $session; + $this->session = $sessionManager ?: $session; $this->scopeConfig = $scopeConfig; $this->frontController = $frontController; $this->viewConfig = $viewConfig; From 737a79eb5aae8b7b3bb7065707f7e643aa750ede Mon Sep 17 00:00:00 2001 From: Sergii Ivashchenko <serg.ivashchenko@gmail.com> Date: Sat, 16 Feb 2019 17:56:34 +0000 Subject: [PATCH 178/315] magento/magento2#19359: Fixed static tests --- .../Customer/CustomerData/Plugin/SessionChecker.php | 7 ++++++- .../Paypal/Controller/Transparent/RequestSecureToken.php | 4 ++-- lib/internal/Magento/Framework/View/Context.php | 2 ++ 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Customer/CustomerData/Plugin/SessionChecker.php b/app/code/Magento/Customer/CustomerData/Plugin/SessionChecker.php index 6497b039c7790..f82a4d15ae8bf 100644 --- a/app/code/Magento/Customer/CustomerData/Plugin/SessionChecker.php +++ b/app/code/Magento/Customer/CustomerData/Plugin/SessionChecker.php @@ -9,6 +9,9 @@ use Magento\Framework\Stdlib\Cookie\CookieMetadataFactory; use Magento\Framework\Stdlib\Cookie\PhpCookieManager; +/** + * Class SessionChecker + */ class SessionChecker { /** @@ -38,6 +41,8 @@ public function __construct( * * @param SessionManagerInterface $sessionManager * @return void + * @throws \Magento\Framework\Exception\InputException + * @throws \Magento\Framework\Stdlib\Cookie\FailureToSendException */ public function beforeStart(SessionManagerInterface $sessionManager) { @@ -49,4 +54,4 @@ public function beforeStart(SessionManagerInterface $sessionManager) $this->cookieManager->deleteCookie('mage-cache-sessid', $metadata); } } -} \ No newline at end of file +} diff --git a/app/code/Magento/Paypal/Controller/Transparent/RequestSecureToken.php b/app/code/Magento/Paypal/Controller/Transparent/RequestSecureToken.php index 68e5e888364b2..497e32157de05 100644 --- a/app/code/Magento/Paypal/Controller/Transparent/RequestSecureToken.php +++ b/app/code/Magento/Paypal/Controller/Transparent/RequestSecureToken.php @@ -56,7 +56,7 @@ class RequestSecureToken extends \Magento\Framework\App\Action\Action * @param SecureToken $secureTokenService * @param SessionManager $sessionManager * @param Transparent $transparent - * @param SessionManagerInterface|null $sessionManagerInterface + * @param SessionManagerInterface|null $sessionInterface */ public function __construct( Context $context, @@ -123,4 +123,4 @@ private function getErrorResponse() ] ); } -} \ No newline at end of file +} diff --git a/lib/internal/Magento/Framework/View/Context.php b/lib/internal/Magento/Framework/View/Context.php index c3876b8ca74de..508d63d158bd7 100644 --- a/lib/internal/Magento/Framework/View/Context.php +++ b/lib/internal/Magento/Framework/View/Context.php @@ -335,6 +335,8 @@ public function getModuleName() } /** + * Get Front Name + * * @see getModuleName */ public function getFrontName() From e53106c9e2a46cf83c95a0ce01347d31a1715fac Mon Sep 17 00:00:00 2001 From: Stas Kozar <stas.kozar@transoftgroup.com> Date: Wed, 20 Feb 2019 13:11:28 +0200 Subject: [PATCH 179/315] MAGETWO-94147: Swatch Attribute is not displayed in the Widget CMS --- ...minCategoryProductAttributeActionGroup.xml | 7 +-- .../Block/Product/ProductsList.php | 25 +++++++--- ...up.xml => CreateNewCmsPageActionGroup.xml} | 50 ++++++++++--------- .../DeletePageByUrlKeyActionGroup.xml | 10 ++-- .../Cms/Test/Mftf/Page/StorefrontCmsPage.xml | 13 +++++ .../Section/CmsNewPagePageActionsSection.xml | 2 +- ...SwatchAttributesDisplayInWidgetCMSTest.xml | 7 ++- 7 files changed, 71 insertions(+), 43 deletions(-) rename app/code/Magento/Cms/Test/Mftf/ActionGroup/{CreateNewPageWithWidgetActionGroup.xml => CreateNewCmsPageActionGroup.xml} (58%) create mode 100644 app/code/Magento/Cms/Test/Mftf/Page/StorefrontCmsPage.xml diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminCategoryProductAttributeActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminCategoryProductAttributeActionGroup.xml index 21e41732369e9..11b5aabf0cee9 100644 --- a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminCategoryProductAttributeActionGroup.xml +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminCategoryProductAttributeActionGroup.xml @@ -14,16 +14,17 @@ <argument name="productAttribute"/> </arguments> <amOnPage url="{{AdminProductAttributeGridPage.url}}" stepKey="goToProductAttributesGridPage"/> + <waitForPageLoad time="30" stepKey="waitForProductAttributesGridPageLoad"/> <conditionalClick selector="{{AdminDataGridHeaderSection.clearFilters}}" dependentSelector="{{AdminDataGridHeaderSection.clearFilters}}" visible="true" stepKey="clearExistingFiltersBeforeDelete"/> <fillField selector="{{AdminProductAttributeGridSection.gridFilterFrontEndLabel}}" userInput="{{productAttribute.default_label}}" stepKey="fillAttributeDefaultLabelInput"/> - <click selector="{{AdminProductAttributeGridSection.search}}" stepKey="searchForAttribute"/> + <click selector="{{AdminDataGridHeaderSection.applyFilters}}" stepKey="applyFilters"/> <click selector="{{AdminProductAttributeGridSection.firstRow}}" stepKey="clickFirstRow"/> <waitForPageLoad time="30" stepKey="waitForPageLoad"/> - <click selector="{{AdminProductAttributeEditSection.deleteAttribute}}" stepKey="deleteProductAttribute"/> + <click selector="{{AdminMainActionsSection.delete}}" stepKey="deleteProductAttribute"/> <waitForElementVisible selector="{{AdminConfirmationModalSection.message}}" stepKey="waitingForWarningModal"/> <click selector="{{AdminConfirmationModalSection.ok}}" stepKey="confirmDelete"/> - <conditionalClick selector="{{AdminDataGridHeaderSection.clearFilters}}" dependentSelector="{{AdminDataGridHeaderSection.clearFilters}}" visible="true" stepKey="clearExistingFiltersAfterDelete"/> + <see selector="{{AdminMessagesSection.success}}" userInput="You deleted the product attribute." stepKey="seeSuccessMessage"/> </actionGroup> <actionGroup name="navigateToProductAttribute"> diff --git a/app/code/Magento/CatalogWidget/Block/Product/ProductsList.php b/app/code/Magento/CatalogWidget/Block/Product/ProductsList.php index 3c8599133588b..41f5123f3b772 100644 --- a/app/code/Magento/CatalogWidget/Block/Product/ProductsList.php +++ b/app/code/Magento/CatalogWidget/Block/Product/ProductsList.php @@ -104,10 +104,15 @@ class ProductsList extends \Magento\Catalog\Block\Product\AbstractProduct implem private $layoutFactory; /** - * @var \Magento\Framework\Url\EncoderInterface|null + * @var \Magento\Framework\Url\EncoderInterface */ private $urlEncoder; + /** + * @var \Magento\Framework\View\Element\RendererList + */ + private $rendererListBlock; + /** * @param \Magento\Catalog\Block\Product\Context $context * @param \Magento\Catalog\Model\ResourceModel\Product\CollectionFactory $productCollectionFactory @@ -238,13 +243,17 @@ public function getProductPriceHtml( */ protected function getDetailsRendererList() { - /** @var $layout \Magento\Framework\View\LayoutInterface */ - $layout = $this->layoutFactory->create(['cacheable' => false]); - $layout->getUpdate()->addHandle('catalog_widget_product_list')->load(); - $layout->generateXml(); - $layout->generateElements(); + if (empty($this->rendererListBlock)) { + /** @var $layout \Magento\Framework\View\LayoutInterface */ + $layout = $this->layoutFactory->create(['cacheable' => false]); + $layout->getUpdate()->addHandle('catalog_widget_product_list')->load(); + $layout->generateXml(); + $layout->generateElements(); + + $this->rendererListBlock = $layout->getBlock('category.product.type.widget.details.renderers'); + } - return $layout->getBlock('category.product.type.widget.details.renderers'); + return $this->rendererListBlock; } /** @@ -253,7 +262,7 @@ protected function getDetailsRendererList() * @param Product $product * @return array */ - public function getAddToCartPostParams(Product $product) + public function getAddToCartPostParams(Product $product): array { $url = $this->getAddToCartUrl($product); diff --git a/app/code/Magento/Cms/Test/Mftf/ActionGroup/CreateNewPageWithWidgetActionGroup.xml b/app/code/Magento/Cms/Test/Mftf/ActionGroup/CreateNewCmsPageActionGroup.xml similarity index 58% rename from app/code/Magento/Cms/Test/Mftf/ActionGroup/CreateNewPageWithWidgetActionGroup.xml rename to app/code/Magento/Cms/Test/Mftf/ActionGroup/CreateNewCmsPageActionGroup.xml index 6a6bb9edaa43a..667dc79d2d6b4 100644 --- a/app/code/Magento/Cms/Test/Mftf/ActionGroup/CreateNewPageWithWidgetActionGroup.xml +++ b/app/code/Magento/Cms/Test/Mftf/ActionGroup/CreateNewCmsPageActionGroup.xml @@ -7,43 +7,45 @@ --> <actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> - <actionGroup name="CreateNewPageWithWidgetWithCategoryCondition"> + <actionGroup name="CreateNewCmsPageActionGroup"> <arguments> <argument name="cmsPage" defaultValue="_defaultCmsPage"/> - <argument name="categoryId" type="string"/> - <argument name="conditionOperator" type="string" defaultValue="is"/> - <argument name="widgetType" type="string" defaultValue="Catalog Products List"/> </arguments> <amOnPage url="{{CmsNewPagePage.url}}" stepKey="amOnCMSNewPage"/> <fillField selector="{{CmsNewPagePageBasicFieldsSection.pageTitle}}" userInput="{{cmsPage.title}}" stepKey="fillFieldTitle"/> - <click selector="{{CmsNewPagePageSeoSection.header}}" stepKey="clickExpandSearchEngineOptimisation"/> <fillField selector="{{CmsNewPagePageSeoSection.urlKey}}" userInput="{{cmsPage.identifier}}" stepKey="fillFieldUrlKey"/> + <scrollToTopOfPage stepKey="scrollToTopOfPage"/> + <click selector="{{AdminMainActionsSection.save}}" stepKey="clickSaveButton"/> + <see selector="{{AdminMessagesSection.success}}" userInput="You saved the page." stepKey="seeSaveSuccessMessage"/> + </actionGroup> - <click selector="{{CmsNewPagePageContentSection.header}}" stepKey="clickExpandContent"/> - <click selector="{{CmsNewPagePageActionsSection.insertWidgetButton}}" stepKey="clickInsertWidgetButton"/> - <waitForElementVisible selector="{{AdminNewWidgetSection.widgetTypeDropDown}}" time="10" stepKey="waitForInsertWidgetFrame"/> - - <selectOption selector="{{AdminNewWidgetSection.widgetTypeDropDown}}" userInput="{{widgetType}}" stepKey="selectCatalogProductListOption"/> - <waitForElementVisible selector="{{AdminNewWidgetSection.addNewCondition}}" stepKey="waitForConditionsElementBecomeAvailable"/> + <actionGroup name="CreateNewPageWithWidgetWithCategoryCondition" extends="CreateNewCmsPageActionGroup"> + <arguments> + <argument name="categoryId" type="string"/> + <argument name="conditionOperator" type="string" defaultValue="is"/> + <argument name="widgetType" type="string" defaultValue="Catalog Products List"/> + </arguments> + <click selector="{{CmsNewPagePageContentSection.header}}" after="fillFieldUrlKey" stepKey="clickExpandContent"/> + <click selector="{{CmsNewPagePageActionsSection.insertWidgetButton}}" after="clickExpandContent" stepKey="clickInsertWidgetButton"/> - <click selector="{{AdminNewWidgetSection.addNewCondition}}" stepKey="clickToAddCondition"/> - <waitForElementVisible selector="{{AdminNewWidgetSection.selectCondition}}" stepKey="waitForSelectBoxOpened"/> + <selectOption selector="{{AdminNewWidgetSection.widgetTypeDropDown}}" userInput="{{widgetType}}" after="clickInsertWidgetButton" stepKey="selectCatalogProductListOption"/> + <waitForElementVisible selector="{{AdminNewWidgetSection.addNewCondition}}" after="selectCatalogProductListOption" stepKey="waitForConditionsElementBecomeAvailable"/> - <selectOption selector="{{AdminNewWidgetSection.selectCondition}}" userInput="Category" stepKey="selectCategoryCondition"/> - <waitForElementVisible selector="{{AdminNewWidgetSection.ruleParameter}}" stepKey="seeConditionsAdded"/> + <click selector="{{AdminNewWidgetSection.addNewCondition}}" after="waitForConditionsElementBecomeAvailable" stepKey="clickToAddCondition"/> + <waitForElementVisible selector="{{AdminNewWidgetSection.selectCondition}}" after="clickToAddCondition" stepKey="waitForSelectBoxOpened"/> - <click selector="{{AdminNewWidgetSection.conditionOperator}}" stepKey="clickToConditionIs"/> - <selectOption selector="{{AdminNewWidgetSection.conditionOperatorSelect('1')}}" userInput="{{conditionOperator}}" stepKey="selectOperator"/> + <selectOption selector="{{AdminNewWidgetSection.selectCondition}}" userInput="Category" after="waitForSelectBoxOpened" stepKey="selectCategoryCondition"/> + <waitForElementVisible selector="{{AdminNewWidgetSection.ruleParameter}}" after="selectCategoryCondition" stepKey="seeConditionsAdded"/> - <click selector="{{AdminNewWidgetSection.ruleParameter}}" stepKey="clickAddConditionItem"/> - <waitForElementVisible selector="{{AdminNewWidgetSection.setRuleParameter}}" stepKey="waitForConditionFieldOpened"/> + <click selector="{{AdminNewWidgetSection.conditionOperator}}" after="seeConditionsAdded" stepKey="clickToConditionIs"/> + <selectOption selector="{{AdminNewWidgetSection.conditionOperatorSelect('1')}}" after="clickToConditionIs" userInput="{{conditionOperator}}" stepKey="selectOperator"/> - <fillField selector="{{AdminNewWidgetSection.setRuleParameter}}" userInput="{{categoryId}}" stepKey="setCategoryId"/> - <click selector="{{AdminNewWidgetSection.insertWidget}}" stepKey="clickInsertWidget"/> + <click selector="{{AdminNewWidgetSection.ruleParameter}}" after="selectOperator" stepKey="clickAddConditionItem"/> + <waitForElementVisible selector="{{AdminNewWidgetSection.setRuleParameter}}" after="clickAddConditionItem" stepKey="waitForConditionFieldOpened"/> - <waitForElementVisible selector="{{AdminMainActionsSection.save}}" stepKey="waitForInsertWidgetSaved"/> - <click selector="{{AdminMainActionsSection.save}}" stepKey="clickSaveButton"/> - <see userInput="You saved the page." stepKey="seeSavedPageMsgOnForm"/> + <fillField selector="{{AdminNewWidgetSection.setRuleParameter}}" userInput="{{categoryId}}" after="waitForConditionFieldOpened" stepKey="setCategoryId"/> + <click selector="{{AdminNewWidgetSection.insertWidget}}" after="setCategoryId" stepKey="clickInsertWidget"/> + <waitForElementVisible selector="{{AdminMainActionsSection.save}}" after="clickInsertWidget" stepKey="waitForInsertWidgetSaved"/> </actionGroup> </actionGroups> diff --git a/app/code/Magento/Cms/Test/Mftf/ActionGroup/DeletePageByUrlKeyActionGroup.xml b/app/code/Magento/Cms/Test/Mftf/ActionGroup/DeletePageByUrlKeyActionGroup.xml index 3e034199ac1a2..fd20954dc7a9e 100644 --- a/app/code/Magento/Cms/Test/Mftf/ActionGroup/DeletePageByUrlKeyActionGroup.xml +++ b/app/code/Magento/Cms/Test/Mftf/ActionGroup/DeletePageByUrlKeyActionGroup.xml @@ -9,19 +9,19 @@ xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> <actionGroup name="DeletePageByUrlKeyActionGroup"> <arguments> - <argument name="urlKey" type="string" defaultValue="{{_defaultCmsPage.identifier}}"/> + <argument name="urlKey" type="string"/> </arguments> <amOnPage url="{{CmsPagesPage.url}}" stepKey="amOnCMSPagesIndexPage"/> + <waitForPageLoad time="30" stepKey="waitForCmsPageListingLoaded"/> <conditionalClick selector="{{AdminDataGridHeaderSection.clearFilters}}" dependentSelector="{{AdminDataGridHeaderSection.clearFilters}}" visible="true" stepKey="clearExistingFiltersBeforeDelete"/> <click selector="{{AdminDataGridHeaderSection.filters}}" stepKey="openCmsPageFilters"/> <fillField selector="{{AdminDataGridHeaderSection.filterFieldInput('identifier')}}" userInput="{{urlKey}}" stepKey="fillFilter"/> <click selector="{{AdminDataGridHeaderSection.applyFilters}}" stepKey="clickApplyFilters"/> <click selector="{{CmsPagesPageActionsSection.select(urlKey)}}" stepKey="clickSelect"/> <click selector="{{CmsPagesPageActionsSection.delete(urlKey)}}" stepKey="clickDelete"/> - <waitForElementVisible selector="{{CmsPagesPageActionsSection.deleteConfirm}}" stepKey="waitForOkButtonToBeVisible"/> - <click selector="{{CmsPagesPageActionsSection.deleteConfirm}}" stepKey="clickOkButton"/> - <waitForPageLoad stepKey="waitForPageLoad3"/> - <see userInput="The page has been deleted." stepKey="seeSuccessMessage"/> + <waitForElementVisible selector="{{AdminConfirmationModalSection.ok}}" stepKey="waitForOkButtonToBeVisible"/> + <click selector="{{AdminConfirmationModalSection.ok}}" stepKey="clickOkButton"/> + <see selector="{{AdminMessagesSection.success}}" userInput="The page has been deleted." stepKey="seeSuccessMessage"/> <conditionalClick selector="{{AdminDataGridHeaderSection.clearFilters}}" dependentSelector="{{AdminDataGridHeaderSection.clearFilters}}" visible="true" stepKey="clearExistingFiltersAfterDelete"/> </actionGroup> </actionGroups> diff --git a/app/code/Magento/Cms/Test/Mftf/Page/StorefrontCmsPage.xml b/app/code/Magento/Cms/Test/Mftf/Page/StorefrontCmsPage.xml new file mode 100644 index 0000000000000..b2de3a225f8ce --- /dev/null +++ b/app/code/Magento/Cms/Test/Mftf/Page/StorefrontCmsPage.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<pages xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/PageObject.xsd"> + <page name="StorefrontCmsPage" url="/{{urlKey}}" area="storefront" module="Magento_Cms" parameterized="true"> + </page> +</pages> diff --git a/app/code/Magento/Cms/Test/Mftf/Section/CmsNewPagePageActionsSection.xml b/app/code/Magento/Cms/Test/Mftf/Section/CmsNewPagePageActionsSection.xml index da9efa0dab62a..740650d6fdfa9 100644 --- a/app/code/Magento/Cms/Test/Mftf/Section/CmsNewPagePageActionsSection.xml +++ b/app/code/Magento/Cms/Test/Mftf/Section/CmsNewPagePageActionsSection.xml @@ -11,6 +11,6 @@ <section name="CmsNewPagePageActionsSection"> <element name="savePage" type="button" selector="#save" timeout="30"/> <element name="saveAndContinueEdit" type="button" selector="#save_and_continue" timeout="10"/> - <element name="insertWidgetButton" type="button" selector=".scalable.action-add-widget.plugin"/> + <element name="insertWidgetButton" type="button" selector=".scalable.action-add-widget.plugin" timeout="30"/> </section> </sections> diff --git a/app/code/Magento/Swatches/Test/Mftf/Test/StorefrontSwatchAttributesDisplayInWidgetCMSTest.xml b/app/code/Magento/Swatches/Test/Mftf/Test/StorefrontSwatchAttributesDisplayInWidgetCMSTest.xml index 167d7ac007eef..cd376e9e0124d 100644 --- a/app/code/Magento/Swatches/Test/Mftf/Test/StorefrontSwatchAttributesDisplayInWidgetCMSTest.xml +++ b/app/code/Magento/Swatches/Test/Mftf/Test/StorefrontSwatchAttributesDisplayInWidgetCMSTest.xml @@ -58,13 +58,16 @@ <actionGroup ref="DeleteProductAttribute" stepKey="deleteAttribute"> <argument name="productAttribute" value="VisualSwatchAttribute"/> </actionGroup> + <actionGroup ref="clearFiltersAdminDataGrid" stepKey="clearGridFilter1"/> <!--delete created page product--> - <actionGroup ref="DeletePageByUrlKeyActionGroup" stepKey="deletePage"/> + <actionGroup ref="DeletePageByUrlKeyActionGroup" stepKey="deletePage"> + <argument name="urlKey" value="{{_defaultCmsPage.identifier}}"/> + </actionGroup> <!--logout--> <actionGroup ref="logout" stepKey="logoutFromAdmin"/> </after> <!--Open Storefront page for the new created page--> - <amOnPage url="{{StorefrontHomePage.url}}{{_defaultCmsPage.identifier}}" stepKey="gotToCreatedCmsPage"/> + <amOnPage url="{{StorefrontCmsPage.url(_defaultCmsPage.identifier)}}" stepKey="goToCreatedCmsPage"/> <seeElement selector="{{StorefrontProductInfoMainSection.swatchOptionByLabel(VisualSwatchOption1.default_label)}}" stepKey="assertAddedWidgetS"/> <seeElement selector="{{StorefrontProductInfoMainSection.swatchOptionByLabel(VisualSwatchOption2.default_label)}}" stepKey="assertAddedWidgetM"/> </test> From c753b2a081ccba854124002069ec65c198883ba3 Mon Sep 17 00:00:00 2001 From: Serhii Dzhepa <sdzhepa@adobe.com> Date: Wed, 20 Feb 2019 10:55:31 -0600 Subject: [PATCH 180/315] Fixed format for @codingStandardsIgnoreStart --- .../web/css/source/module/order/_order-account.less | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/module/order/_order-account.less b/app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/module/order/_order-account.less index 7958378be2c5b..5c30a00c9a0d7 100644 --- a/app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/module/order/_order-account.less +++ b/app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/module/order/_order-account.less @@ -35,11 +35,13 @@ .field-email { margin-left: -30px; } - //@codingStandardsIgnoreStart + /** + * @codingStandardsIgnoreStart + */ .field-group_id { margin-right: 30px; } - //@codingStandardsIgnoreEnd + // @codingStandardsIgnoreEnd } } } From 7affb7d6dad35e4d24385518f6d90ae14f91329b Mon Sep 17 00:00:00 2001 From: Oleksandr Iegorov <oiegorov@magento.com> Date: Wed, 20 Feb 2019 12:24:06 -0600 Subject: [PATCH 181/315] MAGETWO-96001: Update FedEx Shipping Dates behavior in Tracking Popup --- .../Fedex/Plugin/Block/DataProviders/Tracking/ChangeTitle.php | 4 +++- .../Block/DataProviders/Tracking/DeliveryDateTitle.php | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Fedex/Plugin/Block/DataProviders/Tracking/ChangeTitle.php b/app/code/Magento/Fedex/Plugin/Block/DataProviders/Tracking/ChangeTitle.php index d148b91aa3e7a..b271251c4d214 100644 --- a/app/code/Magento/Fedex/Plugin/Block/DataProviders/Tracking/ChangeTitle.php +++ b/app/code/Magento/Fedex/Plugin/Block/DataProviders/Tracking/ChangeTitle.php @@ -16,13 +16,15 @@ class ChangeTitle { /** + * Update title in case if Fedex used as carrier + * * @param Subject $subject * @param \Magento\Framework\Phrase|string $result * @param Status $trackingStatus * @return \Magento\Framework\Phrase|string * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ - public function afterGetTitle(Subject $subject, $result, Status $trackingStatus): string + public function afterGetTitle(Subject $subject, $result, Status $trackingStatus) { if ($trackingStatus->getCarrier() === Carrier::CODE) { $result = __('Expected Delivery:'); diff --git a/app/code/Magento/Shipping/Block/DataProviders/Tracking/DeliveryDateTitle.php b/app/code/Magento/Shipping/Block/DataProviders/Tracking/DeliveryDateTitle.php index dc66c4f0bd018..661068d42c35d 100644 --- a/app/code/Magento/Shipping/Block/DataProviders/Tracking/DeliveryDateTitle.php +++ b/app/code/Magento/Shipping/Block/DataProviders/Tracking/DeliveryDateTitle.php @@ -15,6 +15,8 @@ class DeliveryDateTitle implements ArgumentInterface { /** + * Return title if carrier is defined + * * @param Status $trackingStatus * @return \Magento\Framework\Phrase|string */ From 8bcfa65db7adea4a5819ea9ed40ca79452769f1c Mon Sep 17 00:00:00 2001 From: Oleksandr Iegorov <oiegorov@magento.com> Date: Wed, 20 Feb 2019 13:15:39 -0600 Subject: [PATCH 182/315] MAGETWO-96001: Update FedEx Shipping Dates behavior in Tracking Popup --- .../Magento/Fedex/Plugin/Block/Tracking/PopupDeliveryDate.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/code/Magento/Fedex/Plugin/Block/Tracking/PopupDeliveryDate.php b/app/code/Magento/Fedex/Plugin/Block/Tracking/PopupDeliveryDate.php index 942d21dfa5e47..e1597707f9d02 100644 --- a/app/code/Magento/Fedex/Plugin/Block/Tracking/PopupDeliveryDate.php +++ b/app/code/Magento/Fedex/Plugin/Block/Tracking/PopupDeliveryDate.php @@ -3,7 +3,6 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ -declare(strict_types=1); namespace Magento\Fedex\Plugin\Block\Tracking; @@ -26,7 +25,7 @@ class PopupDeliveryDate * @return string * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ - public function afterFormatDeliveryDateTime(Popup $subject, string $result, string $date, string $time): string + public function afterFormatDeliveryDateTime(Popup $subject, $result, $date, $time) { if ($this->getCarrier($subject) === Carrier::CODE) { $result = $subject->formatDeliveryDate($date); From 9a88b705c26626e5a9b705e99c713ef58a401d1c Mon Sep 17 00:00:00 2001 From: Stas Kozar <stas.kozar@transoftgroup.com> Date: Thu, 21 Feb 2019 10:43:53 +0200 Subject: [PATCH 183/315] MAGETWO-94147: Swatch Attribute is not displayed in the Widget CMS --- .../Test/StorefrontSwatchAttributesDisplayInWidgetCMSTest.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Swatches/Test/Mftf/Test/StorefrontSwatchAttributesDisplayInWidgetCMSTest.xml b/app/code/Magento/Swatches/Test/Mftf/Test/StorefrontSwatchAttributesDisplayInWidgetCMSTest.xml index cd376e9e0124d..f5bb9372266e0 100644 --- a/app/code/Magento/Swatches/Test/Mftf/Test/StorefrontSwatchAttributesDisplayInWidgetCMSTest.xml +++ b/app/code/Magento/Swatches/Test/Mftf/Test/StorefrontSwatchAttributesDisplayInWidgetCMSTest.xml @@ -68,6 +68,7 @@ </after> <!--Open Storefront page for the new created page--> <amOnPage url="{{StorefrontCmsPage.url(_defaultCmsPage.identifier)}}" stepKey="goToCreatedCmsPage"/> + <waitForElementVisible selector="{{StorefrontProductInfoMainSection.swatchOptionByLabel(VisualSwatchOption1.default_label)}}" stepKey="waitForSwatchOptionsAppear"/> <seeElement selector="{{StorefrontProductInfoMainSection.swatchOptionByLabel(VisualSwatchOption1.default_label)}}" stepKey="assertAddedWidgetS"/> <seeElement selector="{{StorefrontProductInfoMainSection.swatchOptionByLabel(VisualSwatchOption2.default_label)}}" stepKey="assertAddedWidgetM"/> </test> From 927408d63aa9612cf0c9a9932a9cf5c40f9a4ce8 Mon Sep 17 00:00:00 2001 From: nmalevanec <mikola.malevanec@transoftgroup.com> Date: Thu, 21 Feb 2019 13:04:57 +0200 Subject: [PATCH 184/315] Fix static tests. --- .../Magento/luma/Magento_Bundle/web/css/source/_module.less | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/design/frontend/Magento/luma/Magento_Bundle/web/css/source/_module.less b/app/design/frontend/Magento/luma/Magento_Bundle/web/css/source/_module.less index 262e2d68d1ea3..544414e447bed 100644 --- a/app/design/frontend/Magento/luma/Magento_Bundle/web/css/source/_module.less +++ b/app/design/frontend/Magento/luma/Magento_Bundle/web/css/source/_module.less @@ -61,7 +61,7 @@ margin-top: 4px; } - input[type="checkbox"] { + input[type='checkbox'] { margin-top: 2px; } From d7cf4b76d12bebefad1278c655e71df3e8056b7c Mon Sep 17 00:00:00 2001 From: serhii balko <serhii.balko@transoftgroup.com> Date: Thu, 21 Feb 2019 13:18:35 +0200 Subject: [PATCH 185/315] MAGETWO-96870: Tax applied on child product is based on Tax Class of parent product --- .../Sales/Total/Quote/CommonTaxCollector.php | 44 +++++++++ .../Total/Quote/CommonTaxCollectorTest.php | 94 +++++++++++++++++++ .../Magento/ConfigurableProduct/composer.json | 3 +- .../Magento/ConfigurableProduct/etc/di.xml | 3 + 4 files changed, 143 insertions(+), 1 deletion(-) create mode 100644 app/code/Magento/ConfigurableProduct/Plugin/Tax/Model/Sales/Total/Quote/CommonTaxCollector.php create mode 100644 app/code/Magento/ConfigurableProduct/Test/Unit/Plugin/Tax/Model/Sales/Total/Quote/CommonTaxCollectorTest.php diff --git a/app/code/Magento/ConfigurableProduct/Plugin/Tax/Model/Sales/Total/Quote/CommonTaxCollector.php b/app/code/Magento/ConfigurableProduct/Plugin/Tax/Model/Sales/Total/Quote/CommonTaxCollector.php new file mode 100644 index 0000000000000..8bdde2aeb0cff --- /dev/null +++ b/app/code/Magento/ConfigurableProduct/Plugin/Tax/Model/Sales/Total/Quote/CommonTaxCollector.php @@ -0,0 +1,44 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\ConfigurableProduct\Plugin\Tax\Model\Sales\Total\Quote; + +use Magento\ConfigurableProduct\Model\Product\Type\Configurable; +use Magento\Quote\Model\Quote\Item\AbstractItem; +use Magento\Tax\Api\Data\QuoteDetailsItemInterface; +use Magento\Tax\Api\Data\QuoteDetailsItemInterfaceFactory; + +/** + * Plugin for CommonTaxCollector to apply Tax Class ID from child item for configurable product + */ +class CommonTaxCollector +{ + /** + * Apply Tax Class ID from child item for configurable product + * + * @param \Magento\Tax\Model\Sales\Total\Quote\CommonTaxCollector $subject + * @param QuoteDetailsItemInterface $result + * @param QuoteDetailsItemInterfaceFactory $itemDataObjectFactory + * @param AbstractItem $item + * @return QuoteDetailsItemInterface + * + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function afterMapItem( + \Magento\Tax\Model\Sales\Total\Quote\CommonTaxCollector $subject, + QuoteDetailsItemInterface $result, + QuoteDetailsItemInterfaceFactory $itemDataObjectFactory, + AbstractItem $item + ) : QuoteDetailsItemInterface { + if ($item->getProduct()->getTypeId() === Configurable::TYPE_CODE && $item->getHasChildren()) { + $childItem = $item->getChildren()[0]; + $result->getTaxClassKey()->setValue($childItem->getProduct()->getTaxClassId()); + } + + return $result; + } +} diff --git a/app/code/Magento/ConfigurableProduct/Test/Unit/Plugin/Tax/Model/Sales/Total/Quote/CommonTaxCollectorTest.php b/app/code/Magento/ConfigurableProduct/Test/Unit/Plugin/Tax/Model/Sales/Total/Quote/CommonTaxCollectorTest.php new file mode 100644 index 0000000000000..1a5c6c0003bfa --- /dev/null +++ b/app/code/Magento/ConfigurableProduct/Test/Unit/Plugin/Tax/Model/Sales/Total/Quote/CommonTaxCollectorTest.php @@ -0,0 +1,94 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\ConfigurableProduct\Test\Unit\Plugin\Tax\Model\Sales\Total\Quote; + +use Magento\Catalog\Model\Product; +use Magento\ConfigurableProduct\Model\Product\Type\Configurable; +use Magento\ConfigurableProduct\Plugin\Tax\Model\Sales\Total\Quote\CommonTaxCollector as CommonTaxCollectorPlugin; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; +use Magento\Quote\Model\Quote\Item\AbstractItem; +use Magento\Tax\Api\Data\QuoteDetailsItemInterface; +use Magento\Tax\Api\Data\QuoteDetailsItemInterfaceFactory; +use Magento\Tax\Api\Data\TaxClassKeyInterface; +use Magento\Tax\Model\Sales\Total\Quote\CommonTaxCollector; +use PHPUnit\Framework\MockObject\MockObject; + +/** + * Test for CommonTaxCollector plugin + */ +class CommonTaxCollectorTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var ObjectManager + */ + private $objectManager; + + /** + * @var CommonTaxCollectorPlugin + */ + private $commonTaxCollectorPlugin; + + /** + * @inheritdoc + */ + public function setUp() + { + $this->objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); + $this->commonTaxCollectorPlugin = $this->objectManager->getObject(CommonTaxCollectorPlugin::class); + } + + /** + * Test to apply Tax Class Id from child item for configurable product + */ + public function testAfterMapItem() + { + $childTaxClassId = 10; + + /** @var Product|MockObject $childProductMock */ + $childProductMock = $this->createPartialMock( + Product::class, + ['getTaxClassId'] + ); + $childProductMock->method('getTaxClassId')->willReturn($childTaxClassId); + /* @var AbstractItem|MockObject $quoteItemMock */ + $childQuoteItemMock = $this->createMock( + AbstractItem::class + ); + $childQuoteItemMock->method('getProduct')->willReturn($childProductMock); + + /** @var Product|MockObject $productMock */ + $productMock = $this->createPartialMock( + Product::class, + ['getTypeId'] + ); + $productMock->method('getTypeId')->willReturn(Configurable::TYPE_CODE); + /* @var AbstractItem|MockObject $quoteItemMock */ + $quoteItemMock = $this->createPartialMock( + AbstractItem::class, + ['getProduct', 'getHasChildren', 'getChildren', 'getQuote', 'getAddress', 'getOptionByCode'] + ); + $quoteItemMock->method('getProduct')->willReturn($productMock); + $quoteItemMock->method('getHasChildren')->willReturn(true); + $quoteItemMock->method('getChildren')->willReturn([$childQuoteItemMock]); + + /* @var TaxClassKeyInterface|MockObject $taxClassObjectMock */ + $taxClassObjectMock = $this->createMock(TaxClassKeyInterface::class); + $taxClassObjectMock->expects($this->once())->method('setValue')->with($childTaxClassId); + + /* @var QuoteDetailsItemInterface|MockObject $quoteDetailsItemMock */ + $quoteDetailsItemMock = $this->createMock(QuoteDetailsItemInterface::class); + $quoteDetailsItemMock->method('getTaxClassKey')->willReturn($taxClassObjectMock); + + $this->commonTaxCollectorPlugin->afterMapItem( + $this->createMock(CommonTaxCollector::class), + $quoteDetailsItemMock, + $this->createMock(QuoteDetailsItemInterfaceFactory::class), + $quoteItemMock + ); + } +} diff --git a/app/code/Magento/ConfigurableProduct/composer.json b/app/code/Magento/ConfigurableProduct/composer.json index 74e611af2cbbc..c33dc148cddb1 100644 --- a/app/code/Magento/ConfigurableProduct/composer.json +++ b/app/code/Magento/ConfigurableProduct/composer.json @@ -22,7 +22,8 @@ "magento/module-sales-rule": "101.0.*", "magento/module-product-video": "100.2.*", "magento/module-configurable-sample-data": "Sample Data version:100.2.*", - "magento/module-product-links-sample-data": "Sample Data version:100.2.*" + "magento/module-product-links-sample-data": "Sample Data version:100.2.*", + "magento/module-tax": "100.2.*" }, "type": "magento2-module", "version": "100.2.7", diff --git a/app/code/Magento/ConfigurableProduct/etc/di.xml b/app/code/Magento/ConfigurableProduct/etc/di.xml index e6e0da721e150..a390cb375befc 100644 --- a/app/code/Magento/ConfigurableProduct/etc/di.xml +++ b/app/code/Magento/ConfigurableProduct/etc/di.xml @@ -245,4 +245,7 @@ </argument> </arguments> </type> + <type name="Magento\Tax\Model\Sales\Total\Quote\CommonTaxCollector"> + <plugin name="apply_tax_class_id" type="Magento\ConfigurableProduct\Plugin\Tax\Model\Sales\Total\Quote\CommonTaxCollector" /> + </type> </config> From 990c249c874c5192ee0688042d93014d4908c061 Mon Sep 17 00:00:00 2001 From: OlgaVasyltsun <olga.vasyltsun@gmail.com> Date: Fri, 22 Feb 2019 11:29:52 +0200 Subject: [PATCH 186/315] MAGETWO-90192: Prefix in checkout not starting with blank value --- .../Checkout/Test/Mftf/Section/CheckoutShippingSection.xml | 5 +++-- app/code/Magento/Customer/Block/Widget/Name.php | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingSection.xml b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingSection.xml index 66cd480051905..b735abc665022 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingSection.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingSection.xml @@ -33,8 +33,9 @@ <element name="addCountry" type="select" selector="#shipping-new-address-form select[name='country_id']"/> <element name="addSaveButton" type="button" selector=".action.primary.action-save-address"/> <element name="editActiveAddress" type="button" selector="//div[@class='shipping-address-item selected-item']//span[text()='Edit']" timeout="30"/> - <element name="namePrefix" type="input" selector="select[name=prefix]"/> + <element name="namePrefix" type="select" selector="select[name=prefix]"/> + <element name="namePrefixOption" type="text" selector="select[name=prefix] option[value='{{optionValue}}']" parameterized="true"/> <element name="nameSuffix" type="selector" selector="[name='suffix']"/> - <element name="nameSuffixOption" type="text" selector="select[name='suffix'] option[value='{{arg}}']" parameterized="true" timeout="30"/> + <element name="nameSuffixOption" type="text" selector="select[name='suffix'] option[value='{{optionValue}}']" parameterized="true" timeout="30"/> </section> </sections> diff --git a/app/code/Magento/Customer/Block/Widget/Name.php b/app/code/Magento/Customer/Block/Widget/Name.php index 4411f40fe41f3..2576545601c73 100644 --- a/app/code/Magento/Customer/Block/Widget/Name.php +++ b/app/code/Magento/Customer/Block/Widget/Name.php @@ -246,6 +246,7 @@ public function getStoreLabel($attributeCode) public function getAttributeValidationClass($attributeCode) { $attributeMetadata = $this->_getAttribute($attributeCode); + return $attributeMetadata ? $attributeMetadata->getFrontendClass() : ''; } From c1d0a23162bb18cd943fe02d7386c740246aea0c Mon Sep 17 00:00:00 2001 From: OlgaVasyltsun <olga.vasyltsun@gmail.com> Date: Fri, 22 Feb 2019 15:23:25 +0200 Subject: [PATCH 187/315] MAGETWO-95762: Resource model changes --- .../Catalog/Model/ResourceModel/AbstractResource.php | 2 +- app/code/Magento/Catalog/Model/ResourceModel/Product.php | 6 +++--- .../Catalog/Test/Mftf/Section/AdminProductFormSection.xml | 2 +- .../Model/Entity/Attribute/UniqueValidationInterface.php | 2 +- .../Magento/Eav/Model/Entity/Attribute/UniqueValidator.php | 3 ++- 5 files changed, 8 insertions(+), 7 deletions(-) diff --git a/app/code/Magento/Catalog/Model/ResourceModel/AbstractResource.php b/app/code/Magento/Catalog/Model/ResourceModel/AbstractResource.php index 7f50c7edbb049..6614b10ef609e 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/AbstractResource.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/AbstractResource.php @@ -101,7 +101,7 @@ protected function _isApplicableAttribute($object, $attribute) */ protected function _isCallableAttributeInstance($instance, $method, $args) { - if ($instance instanceof \Magento\Eav\Model\Entity\Attribute\Backend\AbstractBackend + if ($instance instanceof AbstractBackend && ($method == 'beforeSave' || $method == 'afterSave') ) { $attributeCode = $instance->getAttribute()->getAttributeCode(); diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product.php b/app/code/Magento/Catalog/Model/ResourceModel/Product.php index 6998431d19a8f..e438e2f54113d 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Product.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Product.php @@ -661,7 +661,7 @@ public function save(\Magento\Framework\Model\AbstractModel $object) } /** - * Retrieve entity manager object + * Retrieve entity manager object. * * @return \Magento\Framework\EntityManager\EntityManager */ @@ -675,7 +675,7 @@ private function getEntityManager() } /** - * Retrieve ProductWebsiteLink object + * Retrieve ProductWebsiteLink object. * * @deprecated 101.1.0 * @return ProductWebsiteLink @@ -686,7 +686,7 @@ private function getProductWebsiteLink() } /** - * Retrieve CategoryLink object + * Retrieve CategoryLink object. * * @deprecated 101.1.0 * @return \Magento\Catalog\Model\ResourceModel\Product\CategoryLink diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductFormSection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductFormSection.xml index ed5a0480325dd..5e7fe16727f65 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductFormSection.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductFormSection.xml @@ -40,7 +40,7 @@ <element name="attributeSetDropDown" type="select" selector="div[data-index='attribute_set_id'] .action-select.admin__action-multiselect"/> <element name="requiredNameIndicator" type="text" selector=" return window.getComputedStyle(document.querySelector('._required[data-index=name]>.admin__field-label span'), ':after').getPropertyValue('content');"/> <element name="requiredSkuIndicator" type="text" selector=" return window.getComputedStyle(document.querySelector('._required[data-index=sku]>.admin__field-label span'), ':after').getPropertyValue('content');"/> - <element name="customSelectField" type="select" selector="select[name='product[{{attributeCode}}]']" parameterized="true"/> + <element name="customAttributeDropdownField" type="select" selector="select[name='product[{{attributeCode}}]']" parameterized="true"/> </section> <section name="ProductInWebsitesSection"> <element name="sectionHeader" type="button" selector="div[data-index='websites']" timeout="30"/> diff --git a/app/code/Magento/Eav/Model/Entity/Attribute/UniqueValidationInterface.php b/app/code/Magento/Eav/Model/Entity/Attribute/UniqueValidationInterface.php index f4912f25ae1de..50a6ff9329fc9 100644 --- a/app/code/Magento/Eav/Model/Entity/Attribute/UniqueValidationInterface.php +++ b/app/code/Magento/Eav/Model/Entity/Attribute/UniqueValidationInterface.php @@ -31,5 +31,5 @@ public function validate( AbstractEntity $entity, string $entityLinkField, array $entityIds - ); + ): bool; } diff --git a/app/code/Magento/Eav/Model/Entity/Attribute/UniqueValidator.php b/app/code/Magento/Eav/Model/Entity/Attribute/UniqueValidator.php index da0d0e07f303a..9aa501daf1584 100644 --- a/app/code/Magento/Eav/Model/Entity/Attribute/UniqueValidator.php +++ b/app/code/Magento/Eav/Model/Entity/Attribute/UniqueValidator.php @@ -24,10 +24,11 @@ public function validate( AbstractEntity $entity, string $entityLinkField, array $entityIds - ) { + ): bool { if (isset($entityIds[0])) { return $entityIds[0] == $object->getData($entityLinkField); } + return true; } } From 4fe746122005744398f848393e78aa11dc3254f8 Mon Sep 17 00:00:00 2001 From: Viktor Sevch <svitja@ukr.net> Date: Fri, 22 Feb 2019 15:45:54 +0200 Subject: [PATCH 188/315] MAGETWO-95422: Layered Navigation shows options not available in Catalog --- .../AdminProductAttributeActionGroup.xml | 2 +- .../Mftf/Page/AdminProductAttributeNewPage.xml | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 app/code/Magento/Catalog/Test/Mftf/Page/AdminProductAttributeNewPage.xml diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductAttributeActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductAttributeActionGroup.xml index e82633f1321f0..f043b82f2d44f 100644 --- a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductAttributeActionGroup.xml +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductAttributeActionGroup.xml @@ -79,7 +79,7 @@ <argument name="attributeCode" type="string"/> <argument name="attributeType" type="string" defaultValue="select"/> </arguments> - <amOnPage url="{{ProductAttributePage.url}}" stepKey="goToNewProductAttributePage"/> + <amOnPage url="{{AdminProductAttributeNewPage.url}}" stepKey="goToNewProductAttributePage"/> <fillField selector="{{AttributePropertiesSection.defaultLabel}}" userInput="{{attributeCode}}" stepKey="fillDefaultLabel"/> <selectOption selector="{{AttributePropertiesSection.inputType}}" userInput="{{attributeType}}" stepKey="selectInputType"/> <waitForElementVisible selector="{{AdminNewAttributePanelSection.addOption}}" stepKey="waitForElementVisible"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Page/AdminProductAttributeNewPage.xml b/app/code/Magento/Catalog/Test/Mftf/Page/AdminProductAttributeNewPage.xml new file mode 100644 index 0000000000000..9116e9ae7446f --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/Page/AdminProductAttributeNewPage.xml @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<pages xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/PageObject.xsd"> + <page name="AdminProductAttributeNewPage" url="catalog/product_attribute/new/" area="admin" module="Magento_Catalog"> + <section name="AttributePropertiesSection"/> + <section name="StorefrontPropertiesSection"/> + <section name="AdvancedAttributePropertiesSection"/> + <section name="AdminAttributeOptionsSection"/> + <section name="AttributeManageSwatchSection"/> + </page> +</pages> From b60001e94c0dadfba2beaca493376ffc08e2659e Mon Sep 17 00:00:00 2001 From: Stas Kozar <stas.kozar@transoftgroup.com> Date: Fri, 22 Feb 2019 17:02:55 +0200 Subject: [PATCH 189/315] MAGETWO-95616: Changing Attribute Set may lead to exception "Attempt to load value of nonexistent EAV attribute" --- .../Eav/Model/ResourceModel/ReadHandler.php | 77 ++++- .../Model/ResourceModel/ReadHandlerTest.php | 273 ++++++++++++------ .../Framework/DB/Sql/UnionExpression.php | 20 +- .../DB/Test/Unit/Sql/UnionExpressionTest.php | 44 ++- 4 files changed, 307 insertions(+), 107 deletions(-) diff --git a/app/code/Magento/Eav/Model/ResourceModel/ReadHandler.php b/app/code/Magento/Eav/Model/ResourceModel/ReadHandler.php index cd2fe7477ca60..18bb62b3f7d93 100644 --- a/app/code/Magento/Eav/Model/ResourceModel/ReadHandler.php +++ b/app/code/Magento/Eav/Model/ResourceModel/ReadHandler.php @@ -5,13 +5,19 @@ */ namespace Magento\Eav\Model\ResourceModel; +use Magento\Eav\Model\Config; use Magento\Framework\DataObject; +use Magento\Framework\DB\Select; +use Magento\Framework\DB\Sql\UnionExpression; use Magento\Framework\EntityManager\MetadataPool; use Magento\Framework\EntityManager\Operation\AttributeInterface; use Magento\Framework\Model\Entity\ScopeInterface; use Magento\Framework\Model\Entity\ScopeResolver; use Psr\Log\LoggerInterface; +/** + * EAV read handler. + */ class ReadHandler implements AttributeInterface { /** @@ -30,23 +36,21 @@ class ReadHandler implements AttributeInterface private $logger; /** - * @var \Magento\Eav\Model\Config + * @var Config */ private $config; /** - * ReadHandler constructor. - * * @param MetadataPool $metadataPool * @param ScopeResolver $scopeResolver * @param LoggerInterface $logger - * @param \Magento\Eav\Model\Config $config + * @param Config $config */ public function __construct( MetadataPool $metadataPool, ScopeResolver $scopeResolver, LoggerInterface $logger, - \Magento\Eav\Model\Config $config + Config $config ) { $this->metadataPool = $metadataPool; $this->scopeResolver = $scopeResolver; @@ -86,6 +90,8 @@ private function getEntityAttributes(string $entityType, DataObject $entity): ar } /** + * Get context variables. + * * @param ScopeInterface $scope * @return array */ @@ -99,6 +105,8 @@ protected function getContextVariables(ScopeInterface $scope) } /** + * Execute read handler. + * * @param string $entityType * @param array $entityData * @param array $arguments @@ -129,33 +137,40 @@ public function execute($entityType, $entityData, $arguments = []) } } if (count($attributeTables)) { - $attributeTables = array_keys($attributeTables); - foreach ($attributeTables as $attributeTable) { + $identifiers = null; + foreach ($attributeTables as $attributeTable => $attributeIds) { $select = $connection->select() ->from( ['t' => $attributeTable], ['value' => 't.value', 'attribute_id' => 't.attribute_id'] ) - ->where($metadata->getLinkField() . ' = ?', $entityData[$metadata->getLinkField()]); + ->where($metadata->getLinkField() . ' = ?', $entityData[$metadata->getLinkField()]) + ->where('attribute_id IN (?)', $attributeIds); + $attributeIdentifiers = []; foreach ($context as $scope) { //TODO: if (in table exists context field) $select->where( - $metadata->getEntityConnection()->quoteIdentifier($scope->getIdentifier()) . ' IN (?)', + $connection->quoteIdentifier($scope->getIdentifier()) . ' IN (?)', $this->getContextVariables($scope) - )->order('t.' . $scope->getIdentifier() . ' DESC'); + ); + $attributeIdentifiers[] = $scope->getIdentifier(); } + $attributeIdentifiers = array_unique($attributeIdentifiers); + $identifiers = array_intersect($identifiers ?? $attributeIdentifiers, $attributeIdentifiers); $selects[] = $select; } - $unionSelect = new \Magento\Framework\DB\Sql\UnionExpression( - $selects, - \Magento\Framework\DB\Select::SQL_UNION_ALL - ); - foreach ($connection->fetchAll($unionSelect) as $attributeValue) { + $this->applyIdentifierForSelects($selects, $identifiers); + $unionSelect = new UnionExpression($selects, Select::SQL_UNION_ALL, '( %s )'); + $orderedUnionSelect = $connection->select(); + $orderedUnionSelect->from(['u' => $unionSelect]); + $this->applyIdentifierForUnion($orderedUnionSelect, $identifiers); + $attributes = $connection->fetchAll($orderedUnionSelect); + foreach ($attributes as $attributeValue) { if (isset($attributesMap[$attributeValue['attribute_id']])) { $entityData[$attributesMap[$attributeValue['attribute_id']]] = $attributeValue['value']; } else { $this->logger->warning( - "Attempt to load value of nonexistent EAV attribute '{$attributeValue['attribute_id']}' + "Attempt to load value of nonexistent EAV attribute '{$attributeValue['attribute_id']}' for entity type '$entityType'." ); } @@ -163,4 +178,34 @@ public function execute($entityType, $entityData, $arguments = []) } return $entityData; } + + /** + * Apply identifiers column on select array. + * + * @param Select[] $selects + * @param array $identifiers + * @return void + */ + private function applyIdentifierForSelects(array $selects, array $identifiers) + { + foreach ($selects as $select) { + foreach ($identifiers as $identifier) { + $select->columns($identifier, 't'); + } + } + } + + /** + * Apply identifiers order on union select. + * + * @param Select $unionSelect + * @param array $identifiers + * @return void + */ + private function applyIdentifierForUnion(Select $unionSelect, array $identifiers) + { + foreach ($identifiers as $identifier) { + $unionSelect->order($identifier); + } + } } diff --git a/app/code/Magento/Eav/Test/Unit/Model/ResourceModel/ReadHandlerTest.php b/app/code/Magento/Eav/Test/Unit/Model/ResourceModel/ReadHandlerTest.php index 82e9033496b78..5f74579e32a12 100644 --- a/app/code/Magento/Eav/Test/Unit/Model/ResourceModel/ReadHandlerTest.php +++ b/app/code/Magento/Eav/Test/Unit/Model/ResourceModel/ReadHandlerTest.php @@ -5,19 +5,30 @@ */ namespace Magento\Eav\Test\Unit\Model\ResourceModel; +use Magento\Eav\Model\Config; use Magento\Eav\Model\Entity\Attribute\AbstractAttribute; +use Magento\Eav\Model\Entity\Attribute\Backend\AbstractBackend; +use Magento\Eav\Model\ResourceModel\ReadHandler; +use Magento\Framework\DataObject; +use Magento\Framework\DB\Adapter\AdapterInterface; +use Magento\Framework\DB\Select; +use Magento\Framework\DB\Sql\UnionExpression; use Magento\Framework\EntityManager\EntityMetadataInterface; +use Magento\Framework\EntityManager\MetadataPool; +use Magento\Framework\Model\Entity\ScopeResolver; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; +use Magento\Framework\Model\Entity\ScopeInterface; +use Psr\Log\LoggerInterface; class ReadHandlerTest extends \PHPUnit\Framework\TestCase { /** - * @var \Magento\Eav\Model\Config|\PHPUnit_Framework_MockObject_MockObject + * @var Config|\PHPUnit_Framework_MockObject_MockObject */ private $configMock; /** - * @var \Magento\Framework\EntityManager\MetadataPool|\PHPUnit_Framework_MockObject_MockObject + * @var MetadataPool|\PHPUnit_Framework_MockObject_MockObject */ private $metadataPoolMock; @@ -27,112 +38,206 @@ class ReadHandlerTest extends \PHPUnit\Framework\TestCase private $metadataMock; /** - * @var \Magento\Eav\Model\ResourceModel\ReadHandler + * @var ScopeResolver|\PHPUnit_Framework_MockObject_MockObject */ - private $readHandler; + private $scopeResolverMock; /** - * @var \Magento\Framework\Model\Entity\ScopeResolver|\PHPUnit_Framework_MockObject_MockObject + * @var LoggerInterface|\PHPUnit_Framework_MockObject_MockObject */ - private $scopeResolverMock; + private $loggerMock; + + /** + * @var ScopeInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $scopeMock; + + /** + * @var AdapterInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $connectionMock; + + /** + * @var AbstractAttribute|\PHPUnit_Framework_MockObject_MockObject + */ + private $attributeMock; + + /** + * @var ObjectManager + */ + private $objectManager; + /** + * @var ReadHandler + */ + private $readHandler; + + /** + * @inheritdoc + */ protected function setUp() { - $objectManager = new ObjectManager($this); - $args = $objectManager->getConstructArguments(\Magento\Eav\Model\ResourceModel\ReadHandler::class); - $this->metadataPoolMock = $args['metadataPool']; - $this->metadataMock = $this->getMockBuilder(EntityMetadataInterface::class) - ->disableOriginalConstructor() - ->getMock(); - $this->metadataPoolMock->expects($this->any()) - ->method('getMetadata') - ->willReturn($this->metadataMock); - $this->configMock = $args['config']; - $this->scopeResolverMock = $args['scopeResolver']; - $this->scopeResolverMock->method('getEntityContext') - ->willReturn([]); + $this->objectManager = new ObjectManager($this); - $this->readHandler = $objectManager->getObject(\Magento\Eav\Model\ResourceModel\ReadHandler::class, $args); + $this->metadataPoolMock = $this->createMock(MetadataPool::class); + $this->scopeResolverMock = $this->createMock(ScopeResolver::class); + $this->loggerMock = $this->createMock(LoggerInterface::class); + $this->configMock = $this->createMock(Config::class); + $this->metadataMock = $this->createMock(EntityMetadataInterface::class); + $this->scopeMock = $this->createMock(ScopeInterface::class); + $this->connectionMock = $this->createMock(AdapterInterface::class); + $this->attributeMock = $this->createMock(AbstractAttribute::class); + + $this->readHandler = $this->objectManager->getObject(ReadHandler::class, + [ + 'metadataPool' => $this->metadataPoolMock, + 'scopeResolver' => $this->scopeResolverMock, + 'logger' => $this->loggerMock, + 'config' => $this->configMock, + ] + ); } /** - * @param string $eavEntityType - * @param int $callNum - * @param array $expected - * @param bool $isStatic - * @dataProvider executeDataProvider + * @return void */ - public function testExecute($eavEntityType, $callNum, array $expected, $isStatic = true) + public function testExecuteNew() { + $eavEntityType = 'env-entity-type'; $entityData = ['linkField' => 'theLinkField']; - $this->metadataMock->method('getEavEntityType') - ->willReturn($eavEntityType); - $connectionMock = $this->getMockBuilder(\Magento\Framework\DB\Adapter\AdapterInterface::class) - ->disableOriginalConstructor() - ->getMock(); - $selectMock = $this->getMockBuilder(\Magento\Framework\DB\Select::class) - ->disableOriginalConstructor() - ->getMock(); - $selectMock->method('from') + $attributeId = '1'; + $attributeCode = 'attribute_code'; + $identifier = 'store_id'; + $expectedEntityData = [ + 'linkField' => 'theLinkField', + $attributeCode => $attributeId, + ]; + $entityDataObject = $this->objectManager->getObject(DataObject::class, ['data' => $entityData]); + $abstractBackendMock = $this->createMock(AbstractBackend::class); + $selectMock = $this->createMock(Select::class); + $orderedUnionSelectMock = $this->createMock(Select::class); + $fallbackScopeMock = $this->createMock(ScopeInterface::class); + + $this->metadataPoolMock->expects($this->exactly(2)) + ->method('getMetadata') + ->willReturn($this->metadataMock); + $this->metadataMock->expects($this->exactly(2))->method('getEavEntityType')->willReturn($eavEntityType); + $this->scopeResolverMock->expects($this->once()) + ->method('getEntityContext') + ->with($eavEntityType, $entityData) + ->willReturn([$this->scopeMock]); + $this->metadataMock->expects($this->once())->method('getEntityConnection')->willReturn($this->connectionMock); + $this->configMock->expects($this->once()) + ->method('getEntityAttributes') + ->with($eavEntityType, $entityDataObject) + ->willReturn([$this->attributeMock]); + $this->attributeMock->expects($this->once())->method('isStatic')->willReturn(false); + $this->attributeMock->expects($this->once())->method('getBackend')->willReturn($abstractBackendMock); + $abstractBackendMock->expects($this->once())->method('getTable')->willReturn('some_table'); + $this->attributeMock->expects($this->exactly(2))->method('getAttributeId')->willReturn($attributeId); + $this->attributeMock->expects($this->once())->method('getAttributeCode')->willReturn($attributeCode); + $this->connectionMock->expects($this->at(0))->method('select')->willReturn($selectMock); + $selectMock->expects($this->at(0)) + ->method('from') + ->with( + [ + 't' => 'some_table' + ], + ['value' => 't.value', 'attribute_id' => 't.attribute_id'] + ) + ->willReturnSelf(); + $this->metadataMock->expects($this->exactly(2))->method('getLinkField')->willReturn('linkField'); + $selectMock->expects($this->at(1)) + ->method('where') + ->with('linkField = ?', 'theLinkField') ->willReturnSelf(); - $selectMock->method('where') + $selectMock->expects($this->at(2)) + ->method('where') + ->with('attribute_id IN (?)', [$attributeId]) ->willReturnSelf(); - $connectionMock->method('select') - ->willReturn($selectMock); - $connectionMock->method('fetchAll') - ->willReturn( + $this->scopeMock->expects($this->exactly(2))->method('getIdentifier')->willReturn($identifier); + $this->connectionMock->expects($this->at(1)) + ->method('quoteIdentifier') + ->with($identifier) + ->willReturn("`$identifier`"); + $selectMock->expects($this->at(3)) + ->method('where') + ->with( + "`$identifier` IN (?)", [ - [ - 'attribute_id' => 'attributeId', - 'value' => 'attributeValue', - ] + 0 => '1', + 1 => 0, ] - ); - $this->metadataMock->method('getEntityConnection') - ->willReturn($connectionMock); - $this->metadataMock->method('getLinkField') - ->willReturn('linkField'); - - $attributeMock = $this->getMockBuilder(AbstractAttribute::class) - ->disableOriginalConstructor() - ->getMock(); - $attributeMock->method('isStatic') - ->willReturn($isStatic); - $backendMock = $this->getMockBuilder(\Magento\Eav\Model\Entity\Attribute\Backend\AbstractBackend::class) - ->disableOriginalConstructor() - ->getMock(); - $backendMock->method('getTable') - ->willReturn('backendTable'); - $attributeMock->method('getBackend') - ->willReturn($backendMock); - $attributeMock->method('getAttributeId') - ->willReturn('attributeId'); - $attributeMock->method('getAttributeCode') - ->willReturn('attributeCode'); - $this->configMock->expects($this->exactly($callNum)) + )->willReturnSelf(); + $this->scopeMock->expects($this->once())->method('getValue')->willReturn('1'); + $this->scopeMock->expects($this->exactly(2))->method('getFallback')->willReturn($fallbackScopeMock); + $fallbackScopeMock->expects($this->once())->method('getValue')->willReturn(0); + $fallbackScopeMock->expects($this->once())->method('getFallback')->willReturn(null); + $selectMock->expects($this->at(4))->method('columns')->with($identifier, 't')->willReturnSelf(); + $this->connectionMock->expects($this->at(2))->method('select')->willReturn($orderedUnionSelectMock); + + $unionSelect = $this->objectManager->getObject(UnionExpression::class, + [ + 'parts' => [$selectMock], + 'type' => 'UNION ALL', + 'pattern' => '( %s )', + ] + ); + $orderedUnionSelectMock->expects($this->once())->method('from')->with(['u' => $unionSelect])->willReturnSelf(); + $orderedUnionSelectMock->expects($this->once())->method('order')->with($identifier)->willReturnSelf(); + $this->connectionMock->expects($this->at(3)) + ->method('fetchAll') + ->with($orderedUnionSelectMock) + ->willReturn([ + [ + 'attribute_id' => '1', + 'value' => '1', + 'store_id' => '1', + ] + ]); + + $this->assertEquals($expectedEntityData, $this->readHandler->execute($eavEntityType, $entityData)); + } + + /** + * @return void + */ + public function testExecuteWithStaticAttributeAttributes() + { + $eavEntityType = 'env-entity-type'; + $entityData = ['linkField' => 'theLinkField']; + $entityDataObject = $this->objectManager->getObject(DataObject::class, ['data' => $entityData]); + $this->attributeMock = $this->createMock(AbstractAttribute::class); + + $this->metadataPoolMock->expects($this->exactly(2)) + ->method('getMetadata') + ->willReturn($this->metadataMock); + $this->metadataMock->expects($this->exactly(2))->method('getEavEntityType')->willReturn($eavEntityType); + $this->scopeResolverMock->expects($this->once()) + ->method('getEntityContext') + ->with($eavEntityType, $entityData) + ->willReturn([$this->scopeMock]); + $this->metadataMock->expects($this->once())->method('getEntityConnection')->willReturn($this->connectionMock); + $this->configMock->expects($this->once()) ->method('getEntityAttributes') - ->willReturn([$attributeMock]); - $this->assertEquals($expected, $this->readHandler->execute('entity_type', $entityData)); + ->with($eavEntityType, $entityDataObject) + ->willReturn([$this->attributeMock]); + $this->attributeMock->expects($this->once())->method('isStatic')->willReturn(true); + + $this->assertEquals($entityData, $this->readHandler->execute($eavEntityType, $entityData)); } /** - * @return array + * @return void */ - public function executeDataProvider() + public function testExecuteWithoutAttribute() { - return [ - 'null entity type' => [null, 0, ['linkField' => 'theLinkField']], - 'static attribute' => ['env-entity-type', 1, ['linkField' => 'theLinkField']], - 'non-static attribute' => [ - 'env-entity-type', - 1, - [ - 'linkField' => 'theLinkField', - 'attributeCode' => 'attributeValue' - ], - false - ], - ]; + $entityData = ['linkField' => 'theLinkField']; + + $this->metadataPoolMock->expects($this->once())->method('getMetadata')->willReturn($this->metadataMock); + $this->metadataMock->expects($this->once())->method('getEavEntityType')->willReturn(null); + + $this->assertEquals($entityData, $this->readHandler->execute('env-entity-type', $entityData)); } /** diff --git a/lib/internal/Magento/Framework/DB/Sql/UnionExpression.php b/lib/internal/Magento/Framework/DB/Sql/UnionExpression.php index 3ce78177d875f..9957c6ffb8272 100644 --- a/lib/internal/Magento/Framework/DB/Sql/UnionExpression.php +++ b/lib/internal/Magento/Framework/DB/Sql/UnionExpression.php @@ -22,18 +22,25 @@ class UnionExpression extends Expression */ protected $type; + /** + * @var string + */ + private $pattern; + /** * @param Select[] $parts - * @param string $type + * @param string $type (optional) + * @param string $pattern (optional) */ - public function __construct(array $parts, $type = Select::SQL_UNION) + public function __construct(array $parts, string $type = Select::SQL_UNION, string $pattern = '') { $this->parts = $parts; $this->type = $type; + $this->pattern = $pattern; } /** - * @return string + * @inheritdoc */ public function __toString() { @@ -45,6 +52,11 @@ public function __toString() $parts[] = $part; } } - return implode($parts, $this->type); + $sql = implode($parts, $this->type); + if ($this->pattern) { + return sprintf($this->pattern, $sql); + } + + return $sql; } } diff --git a/lib/internal/Magento/Framework/DB/Test/Unit/Sql/UnionExpressionTest.php b/lib/internal/Magento/Framework/DB/Test/Unit/Sql/UnionExpressionTest.php index 1a3a91ea6bd54..a5aca9707081b 100644 --- a/lib/internal/Magento/Framework/DB/Test/Unit/Sql/UnionExpressionTest.php +++ b/lib/internal/Magento/Framework/DB/Test/Unit/Sql/UnionExpressionTest.php @@ -6,11 +6,22 @@ namespace Magento\Framework\DB\Test\Unit\Sql; use Magento\Framework\DB\Select; +use Magento\Framework\DB\Sql\UnionExpression; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; class UnionExpressionTest extends \PHPUnit\Framework\TestCase { - public function testToString() + /** + * @param string $type + * @param string $pattern + * @param string $expectedSql + * @return void + * @dataProvider toStringDataProvider + */ + public function testToString(string $type, string $pattern, string $expectedSql) { + $objectManager = new ObjectManager($this); + $sqlMock = $this->getMockBuilder(\Magento\Framework\DB\Select::class) ->disableOriginalConstructor() ->getMock(); @@ -21,7 +32,34 @@ public function testToString() $sqlMock, '(test_column)' ]; - $model = new \Magento\Framework\DB\Sql\UnionExpression($parts); - $this->assertEquals('(test_assemble)' . Select::SQL_UNION . '(test_column)', $model->__toString()); + $model = $objectManager->getObject( + UnionExpression::class, + [ + 'parts' => $parts, + 'type' => $type, + 'pattern' => $pattern, + ] + ); + + $this->assertEquals($expectedSql, $model->__toString()); + } + + /** + * @return array + */ + public function toStringDataProvider(): array + { + return [ + [ + 'type' => Select::SQL_UNION, + 'pattern' => '', + 'expectedSql' => "(test_assemble)" . Select::SQL_UNION . "(test_column)", + ], + [ + 'type' => Select::SQL_UNION, + 'pattern' => 'test_with_pattern %s', + 'expectedSql' => "test_with_pattern (test_assemble)" . Select::SQL_UNION . "(test_column)", + ], + ]; } } From abc3e7c17b11cfc99edc06495a5da47c0c82d9f0 Mon Sep 17 00:00:00 2001 From: Alexandre Jardin <info@ajardin.fr> Date: Tue, 5 Feb 2019 15:11:29 +0100 Subject: [PATCH 190/315] Make the module list more deterministic --- .../Framework/Module/ModuleList/Loader.php | 36 +++++++++++-- .../Test/Unit/ModuleList/LoaderTest.php | 51 +++++++++++++++++++ 2 files changed, 82 insertions(+), 5 deletions(-) diff --git a/lib/internal/Magento/Framework/Module/ModuleList/Loader.php b/lib/internal/Magento/Framework/Module/ModuleList/Loader.php index bdfb77762b41c..80958f65e110e 100644 --- a/lib/internal/Magento/Framework/Module/ModuleList/Loader.php +++ b/lib/internal/Magento/Framework/Module/ModuleList/Loader.php @@ -126,16 +126,21 @@ private function getModuleConfigs() * * @param array $origList * @return array - * @SuppressWarnings(PHPMD.UnusedLocalVariable) + * @throws \Exception */ - private function sortBySequence($origList) + private function sortBySequence(array $origList): array { ksort($origList); + $modules = $this->prearrangeModules($origList); + $expanded = []; - foreach ($origList as $moduleName => $value) { + foreach ($modules as $moduleName => $value) { + $sequence = $this->expandSequence($origList, $moduleName); + asort($sequence); + $expanded[] = [ 'name' => $moduleName, - 'sequence' => $this->expandSequence($origList, $moduleName), + 'sequence' => $sequence, ]; } @@ -143,7 +148,7 @@ private function sortBySequence($origList) $total = count($expanded); for ($i = 0; $i < $total - 1; $i++) { for ($j = $i; $j < $total; $j++) { - if (in_array($expanded[$j]['name'], $expanded[$i]['sequence'])) { + if (in_array($expanded[$j]['name'], $expanded[$i]['sequence'], true)) { $temp = $expanded[$i]; $expanded[$i] = $expanded[$j]; $expanded[$j] = $temp; @@ -159,6 +164,27 @@ private function sortBySequence($origList) return $result; } + /** + * Prearrange all modules by putting those from Magento before the others + * + * @param array $modules + * @return array + */ + private function prearrangeModules(array $modules): array + { + $breakdown = ['magento' => [], 'others' => []]; + + foreach ($modules as $moduleName => $moduleDetails) { + if (strpos($moduleName, 'Magento_') !== false) { + $breakdown['magento'][$moduleName] = $moduleDetails; + } else { + $breakdown['others'][$moduleName] = $moduleDetails; + } + } + + return array_merge($breakdown['magento'], $breakdown['others']); + } + /** * Accumulate information about all transitive "sequence" references * diff --git a/lib/internal/Magento/Framework/Module/Test/Unit/ModuleList/LoaderTest.php b/lib/internal/Magento/Framework/Module/Test/Unit/ModuleList/LoaderTest.php index fe613450fd485..a62bb5fa70f97 100644 --- a/lib/internal/Magento/Framework/Module/Test/Unit/ModuleList/LoaderTest.php +++ b/lib/internal/Magento/Framework/Module/Test/Unit/ModuleList/LoaderTest.php @@ -160,4 +160,55 @@ public function testLoadCircular() ])); $this->loader->load(); } + + /** + * @throws \Magento\Framework\Exception\LocalizedException + */ + public function testLoadPrearranged(): void + { + $fixtures = [ + 'Foo_Bar' => ['name' => 'Foo_Bar', 'sequence' => ['Magento_Store']], + 'Magento_Directory' => ['name' => 'Magento_Directory', 'sequence' => ['Magento_Store']], + 'Magento_Store' => ['name' => 'Magento_Store', 'sequence' => []], + 'Magento_Theme' => ['name' => 'Magento_Theme', 'sequence' => ['Magento_Store', 'Magento_Directory']], + 'Test_HelloWorld' => ['name' => 'Test_HelloWorld', 'sequence' => ['Magento_Theme']] + ]; + + $index = 0; + foreach ($fixtures as $name => $fixture) { + $this->converter->expects($this->at($index++))->method('convert')->willReturn([$name => $fixture]); + } + + $this->registry->expects($this->once()) + ->method('getPaths') + ->willReturn([ + '/path/to/Foo_Bar', + '/path/to/Magento_Directory', + '/path/to/Magento_Store', + '/path/to/Magento_Theme', + '/path/to/Test_HelloWorld' + ]); + + $this->driver->expects($this->exactly(5)) + ->method('fileGetContents') + ->will($this->returnValueMap([ + ['/path/to/Foo_Bar/etc/module.xml', null, null, self::$sampleXml], + ['/path/to/Magento_Directory/etc/module.xml', null, null, self::$sampleXml], + ['/path/to/Magento_Store/etc/module.xml', null, null, self::$sampleXml], + ['/path/to/Magento_Theme/etc/module.xml', null, null, self::$sampleXml], + ['/path/to/Test_HelloWorld/etc/module.xml', null, null, self::$sampleXml], + ])); + + // Load the full module list information + $result = $this->loader->load(); + + $this->assertSame( + ['Magento_Store', 'Magento_Directory', 'Magento_Theme', 'Foo_Bar', 'Test_HelloWorld'], + array_keys($result) + ); + + foreach ($fixtures as $name => $fixture) { + $this->assertSame($fixture, $result[$name]); + } + } } From 4b2c1b47998775c114b443ae3dae78d532727598 Mon Sep 17 00:00:00 2001 From: nmalevanec <mikola.malevanec@transoftgroup.com> Date: Wed, 20 Feb 2019 13:30:27 +0200 Subject: [PATCH 191/315] Fix static tests. --- lib/internal/Magento/Framework/Module/ModuleList/Loader.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Module/ModuleList/Loader.php b/lib/internal/Magento/Framework/Module/ModuleList/Loader.php index 80958f65e110e..72421f793f131 100644 --- a/lib/internal/Magento/Framework/Module/ModuleList/Loader.php +++ b/lib/internal/Magento/Framework/Module/ModuleList/Loader.php @@ -134,7 +134,7 @@ private function sortBySequence(array $origList): array $modules = $this->prearrangeModules($origList); $expanded = []; - foreach ($modules as $moduleName => $value) { + foreach (array_keys($modules) as $moduleName) { $sequence = $this->expandSequence($origList, $moduleName); asort($sequence); From 730987f7405376c7d9cf8964ef61f74a09c2c019 Mon Sep 17 00:00:00 2001 From: eduard13 <e.chitoraga@atwix.com> Date: Mon, 25 Feb 2019 08:30:09 +0200 Subject: [PATCH 192/315] Adjusting the Unit Test --- .../Framework/Module/Test/Unit/ModuleList/LoaderTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Module/Test/Unit/ModuleList/LoaderTest.php b/lib/internal/Magento/Framework/Module/Test/Unit/ModuleList/LoaderTest.php index a62bb5fa70f97..827a0df8e4930 100644 --- a/lib/internal/Magento/Framework/Module/Test/Unit/ModuleList/LoaderTest.php +++ b/lib/internal/Magento/Framework/Module/Test/Unit/ModuleList/LoaderTest.php @@ -164,7 +164,7 @@ public function testLoadCircular() /** * @throws \Magento\Framework\Exception\LocalizedException */ - public function testLoadPrearranged(): void + public function testLoadPrearranged() { $fixtures = [ 'Foo_Bar' => ['name' => 'Foo_Bar', 'sequence' => ['Magento_Store']], From b42950aedf52033f1199c2c570a4ac2866649102 Mon Sep 17 00:00:00 2001 From: Stas Kozar <stas.kozar@transoftgroup.com> Date: Mon, 25 Feb 2019 10:10:59 +0200 Subject: [PATCH 193/315] MAGETWO-95616: Changing Attribute Set may lead to exception "Attempt to load value of nonexistent EAV attribute" --- .../Unit/Model/ResourceModel/ReadHandlerTest.php | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Eav/Test/Unit/Model/ResourceModel/ReadHandlerTest.php b/app/code/Magento/Eav/Test/Unit/Model/ResourceModel/ReadHandlerTest.php index 5f74579e32a12..10a6d99caa5f7 100644 --- a/app/code/Magento/Eav/Test/Unit/Model/ResourceModel/ReadHandlerTest.php +++ b/app/code/Magento/Eav/Test/Unit/Model/ResourceModel/ReadHandlerTest.php @@ -88,7 +88,8 @@ protected function setUp() $this->connectionMock = $this->createMock(AdapterInterface::class); $this->attributeMock = $this->createMock(AbstractAttribute::class); - $this->readHandler = $this->objectManager->getObject(ReadHandler::class, + $this->readHandler = $this->objectManager->getObject( + ReadHandler::class, [ 'metadataPool' => $this->metadataPoolMock, 'scopeResolver' => $this->scopeResolverMock, @@ -143,9 +144,11 @@ public function testExecuteNew() [ 't' => 'some_table' ], - ['value' => 't.value', 'attribute_id' => 't.attribute_id'] - ) - ->willReturnSelf(); + [ + 'value' => 't.value', + 'attribute_id' => 't.attribute_id', + ] + )->willReturnSelf(); $this->metadataMock->expects($this->exactly(2))->method('getLinkField')->willReturn('linkField'); $selectMock->expects($this->at(1)) ->method('where') @@ -176,7 +179,8 @@ public function testExecuteNew() $selectMock->expects($this->at(4))->method('columns')->with($identifier, 't')->willReturnSelf(); $this->connectionMock->expects($this->at(2))->method('select')->willReturn($orderedUnionSelectMock); - $unionSelect = $this->objectManager->getObject(UnionExpression::class, + $unionSelect = $this->objectManager->getObject( + UnionExpression::class, [ 'parts' => [$selectMock], 'type' => 'UNION ALL', From 8bda0fded8562be036a17f099bec3b6e86de5c09 Mon Sep 17 00:00:00 2001 From: Stas Kozar <stas.kozar@transoftgroup.com> Date: Mon, 25 Feb 2019 11:49:42 +0200 Subject: [PATCH 194/315] MAGETWO-95616: Changing Attribute Set may lead to exception "Attempt to load value of nonexistent EAV attribute" --- .../Test/Unit/Model/ResourceModel/ReadHandlerTest.php | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Eav/Test/Unit/Model/ResourceModel/ReadHandlerTest.php b/app/code/Magento/Eav/Test/Unit/Model/ResourceModel/ReadHandlerTest.php index 10a6d99caa5f7..66977a34a5adc 100644 --- a/app/code/Magento/Eav/Test/Unit/Model/ResourceModel/ReadHandlerTest.php +++ b/app/code/Magento/Eav/Test/Unit/Model/ResourceModel/ReadHandlerTest.php @@ -20,6 +20,11 @@ use Magento\Framework\Model\Entity\ScopeInterface; use Psr\Log\LoggerInterface; +/** + * Test for Magento\Eav\Model\ResourceModel\ReadHandler class. + * + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + */ class ReadHandlerTest extends \PHPUnit\Framework\TestCase { /** @@ -102,7 +107,7 @@ protected function setUp() /** * @return void */ - public function testExecuteNew() + public function testExecute() { $eavEntityType = 'env-entity-type'; $entityData = ['linkField' => 'theLinkField']; @@ -119,9 +124,7 @@ public function testExecuteNew() $orderedUnionSelectMock = $this->createMock(Select::class); $fallbackScopeMock = $this->createMock(ScopeInterface::class); - $this->metadataPoolMock->expects($this->exactly(2)) - ->method('getMetadata') - ->willReturn($this->metadataMock); + $this->metadataPoolMock->expects($this->exactly(2))->method('getMetadata')->willReturn($this->metadataMock); $this->metadataMock->expects($this->exactly(2))->method('getEavEntityType')->willReturn($eavEntityType); $this->scopeResolverMock->expects($this->once()) ->method('getEntityContext') From dcc772199cb4c0faa0a8cc44dbea9f911dfab468 Mon Sep 17 00:00:00 2001 From: Anton Evers <evers@adobe.com> Date: Wed, 2 Jan 2019 14:02:29 +0100 Subject: [PATCH 195/315] Make it possible to generate sales PDF's using the API --- .../base/templates/info/pdf/default.phtml | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 app/code/Magento/Payment/view/base/templates/info/pdf/default.phtml diff --git a/app/code/Magento/Payment/view/base/templates/info/pdf/default.phtml b/app/code/Magento/Payment/view/base/templates/info/pdf/default.phtml new file mode 100644 index 0000000000000..7acac62f65d38 --- /dev/null +++ b/app/code/Magento/Payment/view/base/templates/info/pdf/default.phtml @@ -0,0 +1,23 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +// @codingStandardsIgnoreFile +/** + * @see \Magento\Payment\Block\Info + * @var \Magento\Payment\Block\Info $block + */ +?> +<?= $block->escapeHtml($block->getMethod()->getTitle()) ?>{{pdf_row_separator}} + +<?php if ($specificInfo = $block->getSpecificInformation()):?> + <?php foreach ($specificInfo as $label => $value):?> + <?= $block->escapeHtml($label) ?>: + <?= $block->escapeHtml(implode(' ', $block->getValueAsArray($value))) ?> + {{pdf_row_separator}} + <?php endforeach; ?> +<?php endif;?> + +<?= $block->escapeHtml(implode('{{pdf_row_separator}}', $block->getChildPdfAsArray())) ?> From 21386b3ee4c7d3d1c06af3d7e44b3b675c8c8288 Mon Sep 17 00:00:00 2001 From: Anton Evers <evers@adobe.com> Date: Thu, 3 Jan 2019 13:54:57 +0100 Subject: [PATCH 196/315] Make it possible to generate sales PDF's using the API --- .../base/templates/info/pdf/checkmo.phtml | 26 +++++++++++++++++++ .../templates/info/pdf/purchaseorder.phtml | 11 ++++++++ 2 files changed, 37 insertions(+) create mode 100644 app/code/Magento/OfflinePayments/view/base/templates/info/pdf/checkmo.phtml create mode 100644 app/code/Magento/OfflinePayments/view/base/templates/info/pdf/purchaseorder.phtml diff --git a/app/code/Magento/OfflinePayments/view/base/templates/info/pdf/checkmo.phtml b/app/code/Magento/OfflinePayments/view/base/templates/info/pdf/checkmo.phtml new file mode 100644 index 0000000000000..4d63577319d5b --- /dev/null +++ b/app/code/Magento/OfflinePayments/view/base/templates/info/pdf/checkmo.phtml @@ -0,0 +1,26 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +// @codingStandardsIgnoreFile +/** + * @var $block \Magento\OfflinePayments\Block\Info\Checkmo + */ +?> +<?= $block->escapeHtml($block->getMethod()->getTitle()) ?> + {{pdf_row_separator}} +<?php if ($block->getInfo()->getAdditionalInformation()): ?> + {{pdf_row_separator}} + <?php if ($block->getPayableTo()): ?> + <?= $block->escapeHtml(__('Make Check payable to: %1', $block->getPayableTo())) ?> + {{pdf_row_separator}} + <?php endif; ?> + <?php if ($block->getMailingAddress()): ?> + <?= $block->escapeHtml(__('Send Check to:')) ?> + {{pdf_row_separator}} + <?= /* @noEscape */ nl2br($block->escapeHtml($block->getMailingAddress())) ?> + {{pdf_row_separator}} + <?php endif; ?> +<?php endif; ?> diff --git a/app/code/Magento/OfflinePayments/view/base/templates/info/pdf/purchaseorder.phtml b/app/code/Magento/OfflinePayments/view/base/templates/info/pdf/purchaseorder.phtml new file mode 100644 index 0000000000000..4a6ea1c00b21c --- /dev/null +++ b/app/code/Magento/OfflinePayments/view/base/templates/info/pdf/purchaseorder.phtml @@ -0,0 +1,11 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +/** + * @var $block \Magento\OfflinePayments\Block\Info\Purchaseorder + */ +?> +<?= $block->escapeHtml(__('Purchase Order Number: %1', $block->getInfo()->getPoNumber())) ?> + {{pdf_row_separator}} From cd9287867dbe0843614ef6ac9cf75da203505d82 Mon Sep 17 00:00:00 2001 From: LisovyiEvhenii <lisovyievhenii@gmail.com> Date: Thu, 24 Jan 2019 15:34:04 +0200 Subject: [PATCH 197/315] #13982: Customer Login Block sets the title for the page when rendered. Move setPageTitle from Block to layout configs --- app/code/Magento/Customer/Block/Form/Login.php | 9 --------- .../view/frontend/layout/customer_account_login.xml | 5 +++++ 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/app/code/Magento/Customer/Block/Form/Login.php b/app/code/Magento/Customer/Block/Form/Login.php index 7b265ae1f0f32..d3d3306a49b44 100644 --- a/app/code/Magento/Customer/Block/Form/Login.php +++ b/app/code/Magento/Customer/Block/Form/Login.php @@ -47,15 +47,6 @@ public function __construct( $this->_customerSession = $customerSession; } - /** - * @return $this - */ - protected function _prepareLayout() - { - $this->pageConfig->getTitle()->set(__('Customer Login')); - return parent::_prepareLayout(); - } - /** * Retrieve form posting url * diff --git a/app/code/Magento/Customer/view/frontend/layout/customer_account_login.xml b/app/code/Magento/Customer/view/frontend/layout/customer_account_login.xml index d49dae6dee58f..00f9c4ed84d24 100644 --- a/app/code/Magento/Customer/view/frontend/layout/customer_account_login.xml +++ b/app/code/Magento/Customer/view/frontend/layout/customer_account_login.xml @@ -7,6 +7,11 @@ --> <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd"> <body> + <referenceBlock name="page.main.title"> + <action method="setPageTitle"> + <argument name="title" translate="true" xsi:type="string">Customer Login</argument> + </action> + </referenceBlock> <referenceContainer name="content"> <!-- customer.form.login.extra --> <container name="customer.login.container" label="Customer Login Container" htmlTag="div" htmlClass="login-container"> From f1de3406cd8cfb3454baef8a72ed2d2cc0d4f10e Mon Sep 17 00:00:00 2001 From: LisovyiEvhenii <lisovyievhenii@gmail.com> Date: Fri, 25 Jan 2019 10:32:37 +0200 Subject: [PATCH 198/315] #13982: fix page title to be displayed both in head's <title> and page's title --- .../view/frontend/layout/customer_account_login.xml | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Customer/view/frontend/layout/customer_account_login.xml b/app/code/Magento/Customer/view/frontend/layout/customer_account_login.xml index 00f9c4ed84d24..3518df736c4ac 100644 --- a/app/code/Magento/Customer/view/frontend/layout/customer_account_login.xml +++ b/app/code/Magento/Customer/view/frontend/layout/customer_account_login.xml @@ -6,12 +6,10 @@ */ --> <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd"> + <head> + <title>Customer Login + - - - Customer Login - - From 2e58ab6009c68ea1e4e0095897517c68273995f9 Mon Sep 17 00:00:00 2001 From: Vinai Kopp Date: Sun, 3 Feb 2019 17:46:26 +0530 Subject: [PATCH 199/315] magento/magento2#20773: Make autoloader PSR-4 compliant --- .../Code/Generator/AutoloaderTest.php | 85 +++++++++++++++++++ .../Framework/Code/Generator/Autoloader.php | 70 +++++++++++++-- 2 files changed, 146 insertions(+), 9 deletions(-) create mode 100644 dev/tests/integration/testsuite/Magento/Framework/Code/Generator/AutoloaderTest.php diff --git a/dev/tests/integration/testsuite/Magento/Framework/Code/Generator/AutoloaderTest.php b/dev/tests/integration/testsuite/Magento/Framework/Code/Generator/AutoloaderTest.php new file mode 100644 index 0000000000000..0e1b51b3ae273 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Framework/Code/Generator/AutoloaderTest.php @@ -0,0 +1,85 @@ +createMock(LoggerInterface::class); + $this->getTestFrameworkObjectManager()->addSharedInstance($loggerTestDouble, MagentoMonologLogger::class); + } + + /** + * @after + */ + public function removeLoggerTestDouble(): void + { + $this->getTestFrameworkObjectManager()->removeSharedInstance(MagentoMonologLogger::class); + } + + /** + * @param \RuntimeException $testException + * @return Generator|MockObject + */ + private function createExceptionThrowingGeneratorTestDouble(\RuntimeException $testException) + { + /** @var Generator|MockObject $generatorStub */ + $generatorStub = $this->createMock(Generator::class); + $generatorStub->method('generateClass')->willThrowException($testException); + + return $generatorStub; + } + + public function testLogsExceptionDuringGeneration(): void + { + $exceptionMessage = 'Test exception thrown during generation'; + $testException = new \RuntimeException($exceptionMessage); + + $loggerMock = ObjectManager::getInstance()->get(LoggerInterface::class); + $loggerMock->expects($this->once())->method('debug')->with($exceptionMessage, ['exception' => $testException]); + + $autoloader = new Autoloader($this->createExceptionThrowingGeneratorTestDouble($testException)); + $this->assertNull($autoloader->load(NonExistingClassName::class)); + } + + public function testFiltersDuplicateExceptionMessages(): void + { + $exceptionMessage = 'Test exception thrown during generation'; + $testException = new \RuntimeException($exceptionMessage); + + $loggerMock = ObjectManager::getInstance()->get(LoggerInterface::class); + $loggerMock->expects($this->once())->method('debug')->with($exceptionMessage, ['exception' => $testException]); + + $autoloader = new Autoloader($this->createExceptionThrowingGeneratorTestDouble($testException)); + $autoloader->load(OneNonExistingClassName::class); + $autoloader->load(AnotherNonExistingClassName::class); + } +} diff --git a/lib/internal/Magento/Framework/Code/Generator/Autoloader.php b/lib/internal/Magento/Framework/Code/Generator/Autoloader.php index c214008393609..1afa97729b158 100644 --- a/lib/internal/Magento/Framework/Code/Generator/Autoloader.php +++ b/lib/internal/Magento/Framework/Code/Generator/Autoloader.php @@ -3,37 +3,89 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ + namespace Magento\Framework\Code\Generator; +use Magento\Framework\App\ObjectManager; use Magento\Framework\Code\Generator; +use Psr\Log\LoggerInterface; class Autoloader { /** - * @var \Magento\Framework\Code\Generator + * @var Generator */ protected $_generator; /** - * @param \Magento\Framework\Code\Generator $generator + * Enables guarding against spamming the debug log with duplicate messages, as + * the generation exception will be thrown multiple times within a single request. + * + * @var string + */ + private $lastGenerationErrorMessage; + + /** + * @param Generator $generator */ - public function __construct( - \Magento\Framework\Code\Generator $generator - ) { + public function __construct(Generator $generator) + { $this->_generator = $generator; } /** * Load specified class name and generate it if necessary * + * According to PSR-4 section 2.4 an autoloader MUST NOT throw an exception and SHOULD NOT return a value. + * + * @see https://www.php-fig.org/psr/psr-4/ + * * @param string $className - * @return bool True if class was loaded + * @return void */ public function load($className) { - if (!class_exists($className)) { - return Generator::GENERATION_ERROR != $this->_generator->generateClass($className); + if (! class_exists($className)) { + try { + $this->_generator->generateClass($className); + } catch (\Exception $exception) { + $this->tryToLogExceptionMessageIfNotDuplicate($exception); + } + } + } + + /** + * @param \Exception $exception + */ + private function tryToLogExceptionMessageIfNotDuplicate(\Exception $exception): void + { + if ($this->lastGenerationErrorMessage !== $exception->getMessage()) { + $this->lastGenerationErrorMessage = $exception->getMessage(); + $this->tryToLogException($exception); + } + } + + /** + * Try to capture the exception message. + * + * The Autoloader is instantiated before the ObjectManager, so the LoggerInterface can not be injected. + * The Logger is instantiated in the try/catch block because ObjectManager might still not be initialized. + * In that case the exception message can not be captured. + * + * The debug level is used for logging in case class generation fails for a common class, but a custom + * autoloader is used later in the stack. A more severe log level would fill the logs with messages on production. + * The exception message now can be accessed in developer mode if debug logging is enabled. + * + * @param \Exception $exception + * @return void + */ + private function tryToLogException(\Exception $exception): void + { + try { + $logger = ObjectManager::getInstance()->get(LoggerInterface::class); + $logger->debug($exception->getMessage(), ['exception' => $exception]); + } catch (\Exception $ignoreThisException) { + // Do not take an action here, since the original exception might have been caused by logger } - return true; } } From 3de1647e51215ba933f007cab64e9483f2487c61 Mon Sep 17 00:00:00 2001 From: nmalevanec Date: Fri, 22 Feb 2019 11:55:31 +0200 Subject: [PATCH 200/315] Fix static tests. --- lib/internal/Magento/Framework/Code/Generator/Autoloader.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/internal/Magento/Framework/Code/Generator/Autoloader.php b/lib/internal/Magento/Framework/Code/Generator/Autoloader.php index 1afa97729b158..35c138147e9d3 100644 --- a/lib/internal/Magento/Framework/Code/Generator/Autoloader.php +++ b/lib/internal/Magento/Framework/Code/Generator/Autoloader.php @@ -10,6 +10,9 @@ use Magento\Framework\Code\Generator; use Psr\Log\LoggerInterface; +/** + * Class loader and generator. + */ class Autoloader { /** @@ -55,6 +58,8 @@ public function load($className) } /** + * Log exception. + * * @param \Exception $exception */ private function tryToLogExceptionMessageIfNotDuplicate(\Exception $exception): void From b635e090921616459f254b63ae7de80f51a9e228 Mon Sep 17 00:00:00 2001 From: Nazarn96 Date: Mon, 25 Feb 2019 13:59:50 +0200 Subject: [PATCH 201/315] Backport-issue-195196 --- app/code/Magento/Eav/Model/Attribute/Data/File.php | 2 +- .../Magento/Ui/view/base/web/js/form/element/file-uploader.js | 3 ++- app/code/Magento/Variable/view/adminhtml/web/variables.js | 3 ++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Eav/Model/Attribute/Data/File.php b/app/code/Magento/Eav/Model/Attribute/Data/File.php index d6476eefc59b1..1ee66915453c3 100644 --- a/app/code/Magento/Eav/Model/Attribute/Data/File.php +++ b/app/code/Magento/Eav/Model/Attribute/Data/File.php @@ -146,7 +146,7 @@ protected function _validateByRules($value) return $this->_fileValidator->getMessages(); } - if (!empty($value['tmp_name']) && !is_uploaded_file($value['tmp_name'])) { + if (!empty($value['tmp_name']) && !file_exists($value['tmp_name'])) { return [__('"%1" is not a valid file.', $label)]; } diff --git a/app/code/Magento/Ui/view/base/web/js/form/element/file-uploader.js b/app/code/Magento/Ui/view/base/web/js/form/element/file-uploader.js index 4b178622c28cf..1fbde3601cc18 100644 --- a/app/code/Magento/Ui/view/base/web/js/form/element/file-uploader.js +++ b/app/code/Magento/Ui/view/base/web/js/form/element/file-uploader.js @@ -14,7 +14,8 @@ define([ 'Magento_Ui/js/lib/validation/validator', 'Magento_Ui/js/form/element/abstract', 'mage/translate', - 'jquery/file-uploader' + 'jquery/file-uploader', + 'mage/adminhtml/tools' ], function ($, _, utils, uiAlert, validator, Element, $t) { 'use strict'; diff --git a/app/code/Magento/Variable/view/adminhtml/web/variables.js b/app/code/Magento/Variable/view/adminhtml/web/variables.js index d519053b5265a..e91f172f59fe7 100644 --- a/app/code/Magento/Variable/view/adminhtml/web/variables.js +++ b/app/code/Magento/Variable/view/adminhtml/web/variables.js @@ -9,7 +9,8 @@ define([ 'mage/translate', 'Magento_Ui/js/modal/modal', 'jquery/ui', - 'prototype' + 'prototype', + 'mage/adminhtml/tools' ], function (jQuery, $t) { 'use strict'; From 102d5972b4c69f5efb6e7ee5100120d06716ecb4 Mon Sep 17 00:00:00 2001 From: Serhii Voloshkov Date: Mon, 25 Feb 2019 14:44:29 +0200 Subject: [PATCH 202/315] MAGETWO-94421: Default addresses not selected when checking out from cart --- .../Sales/Test/Mftf/ActionGroup/AdminOrderActionGroup.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderActionGroup.xml b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderActionGroup.xml index 4af8128d7ac14..eabe51776894e 100644 --- a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderActionGroup.xml +++ b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderActionGroup.xml @@ -181,7 +181,7 @@ - + @@ -196,7 +196,7 @@ - + @@ -211,7 +211,7 @@ - + From 4369bba58d160670363fb3c67a9f36f5d287e429 Mon Sep 17 00:00:00 2001 From: Nikita Shcherbatykh Date: Mon, 25 Feb 2019 15:35:48 +0200 Subject: [PATCH 203/315] MAGETWO-96895: [Magento Cloud] Import doesn't work with skip error entries --- .../Model/Import/Product.php | 112 ++++++--- .../Test/Unit/Model/Import/ProductTest.php | 219 +++++++++--------- .../Magento/ImportExport/Model/Import.php | 7 - .../Model/Import/ProductTest.php | 7 +- .../Adminhtml/Import/ValidateTest.php | 9 +- 5 files changed, 201 insertions(+), 153 deletions(-) diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product.php b/app/code/Magento/CatalogImportExport/Model/Import/Product.php index 3578123e94dc1..f1d1868621fff 100644 --- a/app/code/Magento/CatalogImportExport/Model/Import/Product.php +++ b/app/code/Magento/CatalogImportExport/Model/Import/Product.php @@ -3,12 +3,14 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ + namespace Magento\CatalogImportExport\Model\Import; use Magento\Catalog\Model\Config as CatalogConfig; use Magento\Catalog\Model\Product\Visibility; use Magento\CatalogImportExport\Model\Import\Product\MediaGalleryProcessor; use Magento\CatalogImportExport\Model\Import\Product\RowValidatorInterface as ValidatorInterface; +use Magento\CatalogImportExport\Model\StockItemImporterInterface; use Magento\CatalogInventory\Api\Data\StockItemInterface; use Magento\Framework\App\Filesystem\DirectoryList; use Magento\Framework\Exception\LocalizedException; @@ -638,6 +640,13 @@ class Product extends \Magento\ImportExport\Model\Import\Entity\AbstractEntity */ private $_logger; + /** + * "Duplicate multiselect values" error array key + * + * @var string + */ + private static $errorDuplicateMultiselectValues = 'duplicatedMultiselectValues'; + /** * {@inheritdoc} */ @@ -767,7 +776,6 @@ class Product extends \Magento\ImportExport\Model\Import\Entity\AbstractEntity * @param CatalogConfig $catalogConfig * @param MediaGalleryProcessor $mediaProcessor * @param ProductRepositoryInterface|null $productRepository - * @throws \Magento\Framework\Exception\LocalizedException * * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ @@ -857,11 +865,8 @@ public function __construct( $string, $errorAggregator ); - $this->_optionEntity = isset( - $data['option_entity'] - ) ? $data['option_entity'] : $optionFactory->create( - ['data' => ['product_entity' => $this]] - ); + $this->_optionEntity = $data['option_entity'] + ?? $optionFactory->create(['data' => ['product_entity' => $this]]); $this->_initAttributeSets() ->_initTypeModels() @@ -869,6 +874,9 @@ public function __construct( $this->validator->init($this); $this->productRepository = $productRepository ?? \Magento\Framework\App\ObjectManager::getInstance() ->get(ProductRepositoryInterface::class); + + $errorMessageText = 'Value for multiselect attribute %s contains duplicated values'; + $this->_messageTemplates[self::$errorDuplicateMultiselectValues] = $errorMessageText; } /** @@ -884,7 +892,7 @@ public function isAttributeValid($attrCode, array $attrParams, array $rowData, $ { if (!$this->validator->isAttributeValid($attrCode, $attrParams, $rowData)) { foreach ($this->validator->getMessages() as $message) { - $this->addRowError($message, $rowNum, $attrCode); + $this->skipRow($rowNum, $message, ProcessingError::ERROR_LEVEL_NOT_CRITICAL, $attrCode); } return false; } @@ -1592,7 +1600,7 @@ protected function _saveProducts() if (!empty($rowData[self::URL_KEY])) { // If url_key column and its value were in the CSV file $rowData[self::URL_KEY] = $urlKey; - } else if ($this->isNeedToChangeUrlKey($rowData)) { + } elseif ($this->isNeedToChangeUrlKey($rowData)) { // If url_key column was empty or even not declared in the CSV file but by the rules it is need to // be setteed. In case when url_key is generating from name column we have to ensure that the bunch // of products will pass for the event with url_key column. @@ -1604,7 +1612,9 @@ protected function _saveProducts() if (null === $rowSku) { $this->getErrorAggregator()->addRowToSkip($rowNum); continue; - } elseif (self::SCOPE_STORE == $rowScope) { + } + + if (self::SCOPE_STORE == $rowScope) { // set necessary data from SCOPE_DEFAULT row $rowData[self::COL_TYPE] = $this->skuProcessor->getNewSku($rowSku)['type_id']; $rowData['attribute_set_id'] = $this->skuProcessor->getNewSku($rowSku)['attr_set_id']; @@ -1740,13 +1750,7 @@ protected function _saveProducts() $uploadedImages[$columnImage] = $uploadedFile; } else { unset($rowData[$column]); - $this->addRowError( - ValidatorInterface::ERROR_MEDIA_URL_NOT_ACCESSIBLE, - $rowNum, - null, - null, - ProcessingError::ERROR_LEVEL_NOT_CRITICAL - ); + $this->skipRow($rowNum, ValidatorInterface::ERROR_MEDIA_URL_NOT_ACCESSIBLE); } } else { $uploadedFile = $uploadedImages[$columnImage]; @@ -2380,32 +2384,35 @@ public function validateRow(array $rowData, $rowNum) // BEHAVIOR_DELETE and BEHAVIOR_REPLACE use specific validation logic if (Import::BEHAVIOR_REPLACE == $this->getBehavior()) { if (self::SCOPE_DEFAULT == $rowScope && !$this->isSkuExist($sku)) { - $this->addRowError(ValidatorInterface::ERROR_SKU_NOT_FOUND_FOR_DELETE, $rowNum); + $this->skipRow($rowNum, ValidatorInterface::ERROR_SKU_NOT_FOUND_FOR_DELETE); return false; } } if (Import::BEHAVIOR_DELETE == $this->getBehavior()) { if (self::SCOPE_DEFAULT == $rowScope && !$this->isSkuExist($sku)) { - $this->addRowError(ValidatorInterface::ERROR_SKU_NOT_FOUND_FOR_DELETE, $rowNum); + $this->skipRow($rowNum, ValidatorInterface::ERROR_SKU_NOT_FOUND_FOR_DELETE); return false; } return true; } + // if product doesn't exist, need to throw critical error else all errors should be not critical. + $errorLevel = $this->getValidationErrorLevel($sku); + if (!$this->validator->isValid($rowData)) { foreach ($this->validator->getMessages() as $message) { - $this->addRowError($message, $rowNum, $this->validator->getInvalidAttribute()); + $this->skipRow($rowNum, $message, $errorLevel, $this->validator->getInvalidAttribute()); } } if (null === $sku) { - $this->addRowError(ValidatorInterface::ERROR_SKU_IS_EMPTY, $rowNum); + $this->skipRow($rowNum, ValidatorInterface::ERROR_SKU_IS_EMPTY, $errorLevel); } elseif (false === $sku) { - $this->addRowError(ValidatorInterface::ERROR_ROW_IS_ORPHAN, $rowNum); + $this->skipRow($rowNum, ValidatorInterface::ERROR_ROW_IS_ORPHAN, $errorLevel); } elseif (self::SCOPE_STORE == $rowScope && !$this->storeResolver->getStoreCodeToId($rowData[self::COL_STORE]) ) { - $this->addRowError(ValidatorInterface::ERROR_INVALID_STORE, $rowNum); + $this->skipRow($rowNum, ValidatorInterface::ERROR_INVALID_STORE, $errorLevel); } // SKU is specified, row is SCOPE_DEFAULT, new product block begins @@ -2420,19 +2427,15 @@ public function validateRow(array $rowData, $rowNum) $this->prepareNewSkuData($sku) ); } else { - $this->addRowError(ValidatorInterface::ERROR_TYPE_UNSUPPORTED, $rowNum); + $this->skipRow($rowNum, ValidatorInterface::ERROR_TYPE_UNSUPPORTED, $errorLevel); } } else { // validate new product type and attribute set - if (!isset($rowData[self::COL_TYPE]) || !isset($this->_productTypeModels[$rowData[self::COL_TYPE]])) { - $this->addRowError(ValidatorInterface::ERROR_INVALID_TYPE, $rowNum); - } elseif (!isset( - $rowData[self::COL_ATTR_SET] - ) || !isset( - $this->_attrSetNameToId[$rowData[self::COL_ATTR_SET]] - ) + if (!isset($rowData[self::COL_TYPE], $this->_productTypeModels[$rowData[self::COL_TYPE]])) { + $this->skipRow($rowNum, ValidatorInterface::ERROR_INVALID_TYPE, $errorLevel); + } elseif (!isset($rowData[self::COL_ATTR_SET], $this->_attrSetNameToId[$rowData[self::COL_ATTR_SET]]) ) { - $this->addRowError(ValidatorInterface::ERROR_INVALID_ATTR_SET, $rowNum); + $this->skipRow($rowNum, ValidatorInterface::ERROR_INVALID_ATTR_SET, $errorLevel); } elseif (is_null($this->skuProcessor->getNewSku($sku))) { $this->skuProcessor->addNewSku( $sku, @@ -2488,8 +2491,11 @@ public function validateRow(array $rowData, $rowNum) ValidatorInterface::ERROR_DUPLICATE_URL_KEY, $rowNum, $rowData[self::COL_NAME], - $message - ); + $message, + $errorLevel + ) + ->getErrorAggregator() + ->addRowToSkip($rowNum); } } } @@ -2499,9 +2505,10 @@ public function validateRow(array $rowData, $rowNum) $newFromTimestamp = strtotime($this->dateTime->formatDate($rowData[self::COL_NEW_FROM_DATE], false)); $newToTimestamp = strtotime($this->dateTime->formatDate($rowData[self::COL_NEW_TO_DATE], false)); if ($newFromTimestamp > $newToTimestamp) { - $this->addRowError( - ValidatorInterface::ERROR_NEW_TO_DATE, + $this->skipRow( $rowNum, + ValidatorInterface::ERROR_NEW_TO_DATE, + $errorLevel, $rowData[self::COL_NEW_TO_DATE] ); } @@ -3029,4 +3036,39 @@ private function retrieveProductBySku(string $sku) return $product; } + + /** + * Add row as skipped + * + * @param int $rowNum + * @param string $errorCode Error code or simply column name + * @param string $errorLevel error level + * @param string|null $colName optional column name + * @return $this + */ + private function skipRow( + int $rowNum, + string $errorCode, + string $errorLevel = ProcessingError::ERROR_LEVEL_NOT_CRITICAL, + $colName = null + ): self { + $this->addRowError($errorCode, $rowNum, $colName, null, $errorLevel); + $this->getErrorAggregator() + ->addRowToSkip($rowNum); + + return $this; + } + + /** + * Returns errorLevel for validation + * + * @param string $sku + * @return string + */ + private function getValidationErrorLevel(string $sku): string + { + return (!$this->isSkuExist($sku) && Import::BEHAVIOR_REPLACE !== $this->getBehavior()) + ? ProcessingError::ERROR_LEVEL_CRITICAL + : ProcessingError::ERROR_LEVEL_NOT_CRITICAL; + } } diff --git a/app/code/Magento/CatalogImportExport/Test/Unit/Model/Import/ProductTest.php b/app/code/Magento/CatalogImportExport/Test/Unit/Model/Import/ProductTest.php index 1cd19852f393c..3f72fcc39f548 100644 --- a/app/code/Magento/CatalogImportExport/Test/Unit/Model/Import/ProductTest.php +++ b/app/code/Magento/CatalogImportExport/Test/Unit/Model/Import/ProductTest.php @@ -3,10 +3,14 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ + namespace Magento\CatalogImportExport\Test\Unit\Model\Import; +use Magento\CatalogImportExport\Model\Import\Product; +use Magento\CatalogImportExport\Model\Import\Product\ImageTypeProcessor; use Magento\Framework\App\Filesystem\DirectoryList; use Magento\ImportExport\Model\Import; +use PHPUnit_Framework_MockObject_MockObject as MockObject; /** * Class ProductTest @@ -25,126 +29,126 @@ class ProductTest extends \Magento\ImportExport\Test\Unit\Model\Import\AbstractI const ENTITY_ID = 13; - /** @var \Magento\Framework\DB\Adapter\AdapterInterface|\PHPUnit_Framework_MockObject_MockObject */ + /** @var \Magento\Framework\DB\Adapter\AdapterInterface| MockObject */ protected $_connection; - /** @var \Magento\Framework\Json\Helper\Data|\PHPUnit_Framework_MockObject_MockObject */ + /** @var \Magento\Framework\Json\Helper\Data| MockObject */ protected $jsonHelper; - /** @var \Magento\ImportExport\Model\ResourceModel\Import\Data|\PHPUnit_Framework_MockObject_MockObject */ + /** @var \Magento\ImportExport\Model\ResourceModel\Import\Data| MockObject */ protected $_dataSourceModel; - /** @var \Magento\Framework\App\ResourceConnection|\PHPUnit_Framework_MockObject_MockObject */ + /** @var \Magento\Framework\App\ResourceConnection| MockObject */ protected $resource; - /** @var \Magento\ImportExport\Model\ResourceModel\Helper|\PHPUnit_Framework_MockObject_MockObject */ + /** @var \Magento\ImportExport\Model\ResourceModel\Helper| MockObject */ protected $_resourceHelper; - /** @var \Magento\Framework\Stdlib\StringUtils|\PHPUnit_Framework_MockObject_MockObject */ + /** @var \Magento\Framework\Stdlib\StringUtils|MockObject */ protected $string; - /** @var \Magento\Framework\Event\ManagerInterface|\PHPUnit_Framework_MockObject_MockObject */ + /** @var \Magento\Framework\Event\ManagerInterface|MockObject */ protected $_eventManager; - /** @var \Magento\CatalogInventory\Api\StockRegistryInterface|\PHPUnit_Framework_MockObject_MockObject */ + /** @var \Magento\CatalogInventory\Api\StockRegistryInterface|MockObject */ protected $stockRegistry; - /** @var \Magento\CatalogImportExport\Model\Import\Product\OptionFactory|\PHPUnit_Framework_MockObject_MockObject */ + /** @var \Magento\CatalogImportExport\Model\Import\Product\OptionFactory|MockObject */ protected $optionFactory; - /** @var \Magento\CatalogInventory\Api\StockConfigurationInterface|\PHPUnit_Framework_MockObject_MockObject */ + /** @var \Magento\CatalogInventory\Api\StockConfigurationInterface|MockObject */ protected $stockConfiguration; - /** @var \Magento\CatalogInventory\Model\Spi\StockStateProviderInterface|\PHPUnit_Framework_MockObject_MockObject */ + /** @var \Magento\CatalogInventory\Model\Spi\StockStateProviderInterface|MockObject */ protected $stockStateProvider; - /** @var \Magento\CatalogImportExport\Model\Import\Product\Option|\PHPUnit_Framework_MockObject_MockObject */ + /** @var \Magento\CatalogImportExport\Model\Import\Product\Option|MockObject */ protected $optionEntity; - /** @var \Magento\Framework\Stdlib\DateTime|\PHPUnit_Framework_MockObject_MockObject */ + /** @var \Magento\Framework\Stdlib\DateTime|MockObject */ protected $dateTime; /** @var array */ protected $data; - /** @var \Magento\ImportExport\Helper\Data|\PHPUnit_Framework_MockObject_MockObject */ + /** @var \Magento\ImportExport\Helper\Data|MockObject */ protected $importExportData; - /** @var \Magento\ImportExport\Model\ResourceModel\Import\Data|\PHPUnit_Framework_MockObject_MockObject */ + /** @var \Magento\ImportExport\Model\ResourceModel\Import\Data|MockObject */ protected $importData; - /** @var \Magento\Eav\Model\Config|\PHPUnit_Framework_MockObject_MockObject */ + /** @var \Magento\Eav\Model\Config|MockObject */ protected $config; - /** @var \Magento\ImportExport\Model\ResourceModel\Helper|\PHPUnit_Framework_MockObject_MockObject */ + /** @var \Magento\ImportExport\Model\ResourceModel\Helper|MockObject */ protected $resourceHelper; - /** @var \Magento\Catalog\Helper\Data|\PHPUnit_Framework_MockObject_MockObject */ + /** @var \Magento\Catalog\Helper\Data|MockObject */ protected $_catalogData; - /** @var \Magento\ImportExport\Model\Import\Config|\PHPUnit_Framework_MockObject_MockObject */ + /** @var \Magento\ImportExport\Model\Import\Config|MockObject */ protected $_importConfig; - /** @var \PHPUnit_Framework_MockObject_MockObject */ + /** @var MockObject */ protected $_resourceFactory; // @codingStandardsIgnoreStart - /** @var \Magento\Eav\Model\ResourceModel\Entity\Attribute\Set\CollectionFactory|\PHPUnit_Framework_MockObject_MockObject */ + /** @var \Magento\Eav\Model\ResourceModel\Entity\Attribute\Set\CollectionFactory|MockObject */ protected $_setColFactory; - /** @var \Magento\CatalogImportExport\Model\Import\Product\Type\Factory|\PHPUnit_Framework_MockObject_MockObject */ + /** @var \Magento\CatalogImportExport\Model\Import\Product\Type\Factory|MockObject */ protected $_productTypeFactory; - /** @var \Magento\Catalog\Model\ResourceModel\Product\LinkFactory|\PHPUnit_Framework_MockObject_MockObject */ + /** @var \Magento\Catalog\Model\ResourceModel\Product\LinkFactory|MockObject */ protected $_linkFactory; - /** @var \Magento\CatalogImportExport\Model\Import\Proxy\ProductFactory|\PHPUnit_Framework_MockObject_MockObject */ + /** @var \Magento\CatalogImportExport\Model\Import\Proxy\ProductFactory|MockObject */ protected $_proxyProdFactory; - /** @var \Magento\CatalogImportExport\Model\Import\UploaderFactory|\PHPUnit_Framework_MockObject_MockObject */ + /** @var \Magento\CatalogImportExport\Model\Import\UploaderFactory|MockObject */ protected $_uploaderFactory; - /** @var \Magento\Framework\Filesystem|\PHPUnit_Framework_MockObject_MockObject */ + /** @var \Magento\Framework\Filesystem|MockObject */ protected $_filesystem; - /** @var \Magento\Framework\Filesystem\Directory\WriteInterface|\PHPUnit_Framework_MockObject_MockObject */ + /** @var \Magento\Framework\Filesystem\Directory\WriteInterface|MockObject */ protected $_mediaDirectory; - /** @var \Magento\CatalogInventory\Model\ResourceModel\Stock\ItemFactory|\PHPUnit_Framework_MockObject_MockObject */ + /** @var \Magento\CatalogInventory\Model\ResourceModel\Stock\ItemFactory|MockObject */ protected $_stockResItemFac; - /** @var \Magento\Framework\Stdlib\DateTime\TimezoneInterface|\PHPUnit_Framework_MockObject_MockObject */ + /** @var \Magento\Framework\Stdlib\DateTime\TimezoneInterface|MockObject */ protected $_localeDate; - /** @var \Magento\Framework\Indexer\IndexerRegistry|\PHPUnit_Framework_MockObject_MockObject */ + /** @var \Magento\Framework\Indexer\IndexerRegistry|MockObject */ protected $indexerRegistry; - /** @var \Psr\Log\LoggerInterface|\PHPUnit_Framework_MockObject_MockObject */ + /** @var \Psr\Log\LoggerInterface|MockObject */ protected $_logger; - /** @var \Magento\CatalogImportExport\Model\Import\Product\StoreResolver|\PHPUnit_Framework_MockObject_MockObject */ + /** @var \Magento\CatalogImportExport\Model\Import\Product\StoreResolver|MockObject */ protected $storeResolver; - /** @var \Magento\CatalogImportExport\Model\Import\Product\SkuProcessor|\PHPUnit_Framework_MockObject_MockObject */ + /** @var \Magento\CatalogImportExport\Model\Import\Product\SkuProcessor|MockObject */ protected $skuProcessor; - /** @var \Magento\CatalogImportExport\Model\Import\Product\CategoryProcessor|\PHPUnit_Framework_MockObject_MockObject */ + /** @var \Magento\CatalogImportExport\Model\Import\Product\CategoryProcessor|MockObject */ protected $categoryProcessor; - /** @var \Magento\CatalogImportExport\Model\Import\Product\Validator|\PHPUnit_Framework_MockObject_MockObject */ + /** @var \Magento\CatalogImportExport\Model\Import\Product\Validator|MockObject */ protected $validator; - /** @var \Magento\Framework\Model\ResourceModel\Db\ObjectRelationProcessor|\PHPUnit_Framework_MockObject_MockObject */ + /** @var \Magento\Framework\Model\ResourceModel\Db\ObjectRelationProcessor|MockObject */ protected $objectRelationProcessor; - /** @var \Magento\Framework\Model\ResourceModel\Db\TransactionManagerInterface|\PHPUnit_Framework_MockObject_MockObject */ + /** @var \Magento\Framework\Model\ResourceModel\Db\TransactionManagerInterface|MockObject */ protected $transactionManager; - /** @var \Magento\CatalogImportExport\Model\Import\Product\TaxClassProcessor|\PHPUnit_Framework_MockObject_MockObject */ + /** @var \Magento\CatalogImportExport\Model\Import\Product\TaxClassProcessor|MockObject */ // @codingStandardsIgnoreEnd protected $taxClassProcessor; - /** @var \Magento\CatalogImportExport\Model\Import\Product */ + /** @var Product */ protected $importProduct; /** @@ -152,10 +156,10 @@ class ProductTest extends \Magento\ImportExport\Test\Unit\Model\Import\AbstractI */ protected $errorAggregator; - /** @var \Magento\Framework\App\Config\ScopeConfigInterface|\PHPUnit_Framework_MockObject_MockObject*/ + /** @var \Magento\Framework\App\Config\ScopeConfigInterface|MockObject */ protected $scopeConfig; - /** @var \Magento\Catalog\Model\Product\Url|\PHPUnit_Framework_MockObject_MockObject*/ + /** @var \Magento\Catalog\Model\Product\Url|MockObject */ protected $productUrl; /** @@ -334,7 +338,7 @@ protected function setUp() $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); $this->importProduct = $objectManager->getObject( - \Magento\CatalogImportExport\Model\Import\Product::class, + Product::class, [ 'jsonHelper' => $this->jsonHelper, 'importExportData' => $this->importExportData, @@ -375,7 +379,7 @@ protected function setUp() 'data' => $this->data ] ); - $reflection = new \ReflectionClass(\Magento\CatalogImportExport\Model\Import\Product::class); + $reflection = new \ReflectionClass(Product::class); $reflectionProperty = $reflection->getProperty('metadataPool'); $reflectionProperty->setAccessible(true); $reflectionProperty->setValue($this->importProduct, $metadataPoolMock); @@ -584,7 +588,7 @@ public function testGetMultipleValueSeparatorFromParameters() public function testDeleteProductsForReplacement() { - $importProduct = $this->getMockBuilder(\Magento\CatalogImportExport\Model\Import\Product::class) + $importProduct = $this->getMockBuilder(Product::class) ->disableOriginalConstructor() ->setMethods([ 'setParameters', '_deleteProducts' @@ -650,7 +654,7 @@ public function testValidateRowIsAlreadyValidated() */ public function testValidateRow($rowScope, $oldSku, $expectedResult, $behaviour = Import::BEHAVIOR_DELETE) { - $importProduct = $this->getMockBuilder(\Magento\CatalogImportExport\Model\Import\Product::class) + $importProduct = $this->getMockBuilder(Product::class) ->disableOriginalConstructor() ->setMethods(['getBehavior', 'getRowScope', 'getErrorAggregator']) ->getMock(); @@ -662,7 +666,7 @@ public function testValidateRow($rowScope, $oldSku, $expectedResult, $behaviour ->method('getErrorAggregator') ->willReturn($this->getErrorAggregatorObject()); $importProduct->expects($this->once())->method('getRowScope')->willReturn($rowScope); - $skuKey = \Magento\CatalogImportExport\Model\Import\Product::COL_SKU; + $skuKey = Product::COL_SKU; $rowData = [ $skuKey => 'sku', ]; @@ -674,18 +678,22 @@ public function testValidateRow($rowScope, $oldSku, $expectedResult, $behaviour public function testValidateRowDeleteBehaviourAddRowErrorCall() { - $importProduct = $this->getMockBuilder(\Magento\CatalogImportExport\Model\Import\Product::class) + $importProduct = $this->getMockBuilder(Product::class) ->disableOriginalConstructor() - ->setMethods(['getBehavior', 'getRowScope', 'addRowError']) + ->setMethods(['getBehavior', 'getRowScope', 'addRowError', 'getErrorAggregator']) ->getMock(); $importProduct->expects($this->exactly(2))->method('getBehavior') ->willReturn(\Magento\ImportExport\Model\Import::BEHAVIOR_DELETE); $importProduct->expects($this->once())->method('getRowScope') - ->willReturn(\Magento\CatalogImportExport\Model\Import\Product::SCOPE_DEFAULT); + ->willReturn(Product::SCOPE_DEFAULT); $importProduct->expects($this->once())->method('addRowError'); + $importProduct->method('getErrorAggregator') + ->willReturn( + $this->getErrorAggregatorObject(['addRowToSkip']) + ); $rowData = [ - \Magento\CatalogImportExport\Model\Import\Product::COL_SKU => 'sku', + Product::COL_SKU => 'sku', ]; $importProduct->validateRow($rowData, 0); @@ -696,7 +704,7 @@ public function testValidateRowValidatorCheck() $messages = ['validator message']; $this->validator->expects($this->once())->method('getMessages')->willReturn($messages); $rowData = [ - \Magento\CatalogImportExport\Model\Import\Product::COL_SKU => 'sku', + Product::COL_SKU => 'sku', ]; $rowNum = 0; $this->importProduct->validateRow($rowData, $rowNum); @@ -798,7 +806,7 @@ public function getStoreIdByCodeDataProvider() return [ [ '$storeCode' => null, - '$expectedResult' => \Magento\CatalogImportExport\Model\Import\Product::SCOPE_DEFAULT, + '$expectedResult' => Product::SCOPE_DEFAULT, ], [ '$storeCode' => 'value', @@ -813,17 +821,17 @@ public function getStoreIdByCodeDataProvider() public function testValidateRowCheckSpecifiedSku($sku, $expectedError) { $importProduct = $this->createModelMockWithErrorAggregator( - [ 'addRowError', 'getOptionEntity', 'getRowScope'], + ['addRowError', 'getOptionEntity', 'getRowScope'], ['isRowInvalid' => true] ); $rowNum = 0; $rowData = [ - \Magento\CatalogImportExport\Model\Import\Product::COL_SKU => $sku, - \Magento\CatalogImportExport\Model\Import\Product::COL_STORE => '', + Product::COL_SKU => $sku, + Product::COL_STORE => '', ]; - $this->storeResolver->expects($this->any())->method('getStoreCodeToId')->willReturn(null); + $this->storeResolver->method('getStoreCodeToId')->willReturn(null); $this->setPropertyValue($importProduct, 'storeResolver', $this->storeResolver); $this->setPropertyValue($importProduct, 'skuProcessor', $this->skuProcessor); @@ -832,7 +840,7 @@ public function testValidateRowCheckSpecifiedSku($sku, $expectedError) $importProduct ->expects($this->once()) ->method('getRowScope') - ->willReturn(\Magento\CatalogImportExport\Model\Import\Product::SCOPE_STORE); + ->willReturn(Product::SCOPE_STORE); $importProduct->expects($this->at(1))->method('addRowError')->with($expectedError, $rowNum)->willReturn(null); $importProduct->validateRow($rowData, $rowNum); @@ -846,7 +854,7 @@ public function testValidateRowProcessEntityIncrement() $errorAggregator->method('isRowInvalid')->willReturn(true); $this->setPropertyValue($this->importProduct, '_processedEntitiesCount', $count); $this->setPropertyValue($this->importProduct, 'errorAggregator', $errorAggregator); - $rowData = [\Magento\CatalogImportExport\Model\Import\Product::COL_SKU => false]; + $rowData = [Product::COL_SKU => false]; //suppress validator $this->_setValidatorMockInImportProduct($this->importProduct); $this->importProduct->validateRow($rowData, $rowNum); @@ -856,14 +864,14 @@ public function testValidateRowProcessEntityIncrement() public function testValidateRowValidateExistingProductTypeAddNewSku() { $importProduct = $this->createModelMockWithErrorAggregator( - [ 'addRowError', 'getOptionEntity'], + ['addRowError', 'getOptionEntity'], ['isRowInvalid' => true] ); $sku = 'sku'; $rowNum = 0; $rowData = [ - \Magento\CatalogImportExport\Model\Import\Product::COL_SKU => $sku, + Product::COL_SKU => $sku, ]; $oldSku = [ $sku => [ @@ -886,7 +894,7 @@ public function testValidateRowValidateExistingProductTypeAddNewSku() $this->setPropertyValue($importProduct, '_oldSku', $oldSku); $expectedData = [ - 'entity_id' => $oldSku[$sku]['entity_id'], //entity_id_val + 'entity_id' => $oldSku[$sku]['entity_id'], //entity_id_val 'type_id' => $oldSku[$sku]['type_id'],// type_id_val 'attr_set_id' => $oldSku[$sku]['attr_set_id'], //attr_set_id_val 'attr_set_code' => $_attrSetIdToName[$oldSku[$sku]['attr_set_id']],//attr_set_id_val @@ -904,7 +912,7 @@ public function testValidateRowValidateExistingProductTypeAddErrorRowCall() $sku = 'sku'; $rowNum = 0; $rowData = [ - \Magento\CatalogImportExport\Model\Import\Product::COL_SKU => $sku, + Product::COL_SKU => $sku, ]; $oldSku = [ $sku => [ @@ -929,6 +937,11 @@ public function testValidateRowValidateExistingProductTypeAddErrorRowCall() /** * @dataProvider validateRowValidateNewProductTypeAddRowErrorCallDataProvider + * @param string $colType + * @param string $productTypeModelsColType + * @param string $colAttrSet + * @param string $attrSetNameToIdColAttrSet + * @param string $error */ public function testValidateRowValidateNewProductTypeAddRowErrorCall( $colType, @@ -940,15 +953,15 @@ public function testValidateRowValidateNewProductTypeAddRowErrorCall( $sku = 'sku'; $rowNum = 0; $rowData = [ - \Magento\CatalogImportExport\Model\Import\Product::COL_SKU => $sku, - \Magento\CatalogImportExport\Model\Import\Product::COL_TYPE => $colType, - \Magento\CatalogImportExport\Model\Import\Product::COL_ATTR_SET => $colAttrSet, + Product::COL_SKU => $sku, + Product::COL_TYPE => $colType, + Product::COL_ATTR_SET => $colAttrSet, ]; $_attrSetNameToId = [ - $rowData[\Magento\CatalogImportExport\Model\Import\Product::COL_ATTR_SET] => $attrSetNameToIdColAttrSet, + $rowData[Product::COL_ATTR_SET] => $attrSetNameToIdColAttrSet, ]; $_productTypeModels = [ - $rowData[\Magento\CatalogImportExport\Model\Import\Product::COL_TYPE] => $productTypeModelsColType, + $rowData[Product::COL_TYPE] => $productTypeModelsColType, ]; $oldSku = [ $sku => null, @@ -976,29 +989,25 @@ public function testValidateRowValidateNewProductTypeGetNewSkuCall() $sku = 'sku'; $rowNum = 0; $rowData = [ - \Magento\CatalogImportExport\Model\Import\Product::COL_SKU => $sku, - \Magento\CatalogImportExport\Model\Import\Product::COL_TYPE => 'value', - \Magento\CatalogImportExport\Model\Import\Product::COL_ATTR_SET => 'value', + Product::COL_SKU => $sku, + Product::COL_TYPE => 'value', + Product::COL_ATTR_SET => 'value', ]; $_productTypeModels = [ - $rowData[\Magento\CatalogImportExport\Model\Import\Product::COL_TYPE] => 'value', + $rowData[Product::COL_TYPE] => 'value', ]; $oldSku = [ $sku => null, ]; $_attrSetNameToId = [ - $rowData[\Magento\CatalogImportExport\Model\Import\Product::COL_ATTR_SET] => 'attr_set_code_val' + $rowData[Product::COL_ATTR_SET] => 'attr_set_code_val', ]; $expectedData = [ 'entity_id' => null, - 'type_id' => $rowData[\Magento\CatalogImportExport\Model\Import\Product::COL_TYPE],//value + 'type_id' => $rowData[Product::COL_TYPE], //attr_set_id_val - 'attr_set_id' => $_attrSetNameToId[ - $rowData[ - \Magento\CatalogImportExport\Model\Import\Product::COL_ATTR_SET - ] - ], - 'attr_set_code' => $rowData[\Magento\CatalogImportExport\Model\Import\Product::COL_ATTR_SET],//value + 'attr_set_id' => $_attrSetNameToId[$rowData[Product::COL_ATTR_SET]], + 'attr_set_code' => $rowData[Product::COL_ATTR_SET], 'row_id' => null ]; $importProduct = $this->createModelMockWithErrorAggregator( @@ -1034,8 +1043,8 @@ public function testValidateRowSetAttributeSetCodeIntoRowData() $sku = 'sku'; $rowNum = 0; $rowData = [ - \Magento\CatalogImportExport\Model\Import\Product::COL_SKU => $sku, - \Magento\CatalogImportExport\Model\Import\Product::COL_ATTR_SET => 'col_attr_set_val', + Product::COL_SKU => $sku, + Product::COL_ATTR_SET => 'col_attr_set_val', ]; $expectedAttrSetCode = 'new_attr_set_code'; $newSku = [ @@ -1043,8 +1052,8 @@ public function testValidateRowSetAttributeSetCodeIntoRowData() 'type_id' => 'new_type_id_val', ]; $expectedRowData = [ - \Magento\CatalogImportExport\Model\Import\Product::COL_SKU => $sku, - \Magento\CatalogImportExport\Model\Import\Product::COL_ATTR_SET => $newSku['attr_set_code'], + Product::COL_SKU => $sku, + Product::COL_ATTR_SET => $newSku['attr_set_code'], ]; $oldSku = [ $sku => [ @@ -1078,8 +1087,8 @@ public function testValidateValidateOptionEntity() $sku = 'sku'; $rowNum = 0; $rowData = [ - \Magento\CatalogImportExport\Model\Import\Product::COL_SKU => $sku, - \Magento\CatalogImportExport\Model\Import\Product::COL_ATTR_SET => 'col_attr_set_val', + Product::COL_SKU => $sku, + Product::COL_ATTR_SET => 'col_attr_set_val', ]; $oldSku = [ $sku => [ @@ -1336,7 +1345,7 @@ public function validateRowDataProvider() { return [ [ - '$rowScope' => \Magento\CatalogImportExport\Model\Import\Product::SCOPE_DEFAULT, + '$rowScope' => Product::SCOPE_DEFAULT, '$oldSku' => null, '$expectedResult' => false, ], @@ -1351,12 +1360,12 @@ public function validateRowDataProvider() '$expectedResult' => true, ], [ - '$rowScope' => \Magento\CatalogImportExport\Model\Import\Product::SCOPE_DEFAULT, + '$rowScope' => Product::SCOPE_DEFAULT, '$oldSku' => true, '$expectedResult' => true, ], [ - '$rowScope' => \Magento\CatalogImportExport\Model\Import\Product::SCOPE_DEFAULT, + '$rowScope' => Product::SCOPE_DEFAULT, '$oldSku' => null, '$expectedResult' => false, '$behaviour' => Import::BEHAVIOR_REPLACE @@ -1377,7 +1386,7 @@ public function isAttributeValidAssertAttrValidDataProvider() '$rowData' => [ 'code' => str_repeat( 'a', - \Magento\CatalogImportExport\Model\Import\Product::DB_MAX_VARCHAR_LENGTH - 1 + Product::DB_MAX_VARCHAR_LENGTH - 1 ), ], ], @@ -1430,7 +1439,7 @@ public function isAttributeValidAssertAttrValidDataProvider() '$rowData' => [ 'code' => str_repeat( 'a', - \Magento\CatalogImportExport\Model\Import\Product::DB_MAX_TEXT_LENGTH - 1 + Product::DB_MAX_TEXT_LENGTH - 1 ), ], ], @@ -1450,7 +1459,7 @@ public function isAttributeValidAssertAttrInvalidDataProvider() '$rowData' => [ 'code' => str_repeat( 'a', - \Magento\CatalogImportExport\Model\Import\Product::DB_MAX_VARCHAR_LENGTH + 1 + Product::DB_MAX_VARCHAR_LENGTH + 1 ), ], ], @@ -1503,7 +1512,7 @@ public function isAttributeValidAssertAttrInvalidDataProvider() '$rowData' => [ 'code' => str_repeat( 'a', - \Magento\CatalogImportExport\Model\Import\Product::DB_MAX_TEXT_LENGTH + 1 + Product::DB_MAX_TEXT_LENGTH + 1 ), ], ], @@ -1515,8 +1524,8 @@ public function isAttributeValidAssertAttrInvalidDataProvider() */ public function getRowScopeDataProvider() { - $colSku = \Magento\CatalogImportExport\Model\Import\Product::COL_SKU; - $colStore = \Magento\CatalogImportExport\Model\Import\Product::COL_STORE; + $colSku = Product::COL_SKU; + $colStore = Product::COL_STORE; return [ [ @@ -1524,21 +1533,21 @@ public function getRowScopeDataProvider() $colSku => null, $colStore => 'store', ], - '$expectedResult' => \Magento\CatalogImportExport\Model\Import\Product::SCOPE_STORE + '$expectedResult' => Product::SCOPE_STORE, ], [ '$rowData' => [ $colSku => 'sku', $colStore => null, ], - '$expectedResult' => \Magento\CatalogImportExport\Model\Import\Product::SCOPE_DEFAULT + '$expectedResult' => Product::SCOPE_DEFAULT, ], [ '$rowData' => [ $colSku => 'sku', $colStore => 'store', ], - '$expectedResult' => \Magento\CatalogImportExport\Model\Import\Product::SCOPE_STORE + '$expectedResult' => Product::SCOPE_STORE, ], ]; } @@ -1615,9 +1624,9 @@ protected function overrideMethod(&$object, $methodName, array $parameters = []) * * @see _rewriteGetOptionEntityInImportProduct() * @see _setValidatorMockInImportProduct() - * @param \Magento\CatalogImportExport\Model\Import\Product + * @param Product * Param should go with rewritten getOptionEntity method. - * @return \Magento\CatalogImportExport\Model\Import\Product\Option|\PHPUnit_Framework_MockObject_MockObject + * @return \Magento\CatalogImportExport\Model\Import\Product\Option|MockObject */ private function _suppressValidateRowOptionValidatorInvalidRows($importProduct) { @@ -1633,8 +1642,8 @@ private function _suppressValidateRowOptionValidatorInvalidRows($importProduct) * Used in group of validateRow method's tests. * Set validator mock in importProduct, return true for isValid method. * - * @param \Magento\CatalogImportExport\Model\Import\Product - * @return \Magento\CatalogImportExport\Model\Import\Product\Validator|\PHPUnit_Framework_MockObject_MockObject + * @param Product + * @return \Magento\CatalogImportExport\Model\Import\Product\Validator|MockObject */ private function _setValidatorMockInImportProduct($importProduct) { @@ -1648,9 +1657,9 @@ private function _setValidatorMockInImportProduct($importProduct) * Used in group of validateRow method's tests. * Make getOptionEntity return option mock. * - * @param \Magento\CatalogImportExport\Model\Import\Product + * @param Product * Param should go with rewritten getOptionEntity method. - * @return \Magento\CatalogImportExport\Model\Import\Product\Option|\PHPUnit_Framework_MockObject_MockObject + * @return \Magento\CatalogImportExport\Model\Import\Product\Option|MockObject */ private function _rewriteGetOptionEntityInImportProduct($importProduct) { @@ -1665,12 +1674,12 @@ private function _rewriteGetOptionEntityInImportProduct($importProduct) /** * @param array $methods * @param array $errorAggregatorMethods - * @return \PHPUnit_Framework_MockObject_MockObject + * @return MockObject */ protected function createModelMockWithErrorAggregator(array $methods = [], array $errorAggregatorMethods = []) { $methods[] = 'getErrorAggregator'; - $importProduct = $this->getMockBuilder(\Magento\CatalogImportExport\Model\Import\Product::class) + $importProduct = $this->getMockBuilder(Product::class) ->disableOriginalConstructor() ->setMethods($methods) ->getMock(); diff --git a/app/code/Magento/ImportExport/Model/Import.php b/app/code/Magento/ImportExport/Model/Import.php index 6ff2ca8c4d0eb..2d8b84cd035ff 100644 --- a/app/code/Magento/ImportExport/Model/Import.php +++ b/app/code/Magento/ImportExport/Model/Import.php @@ -626,13 +626,6 @@ public function validateSource(\Magento\ImportExport\Model\Import\AbstractSource $errorsCount = $errorAggregator->getErrorsCount(); $result = !$errorsCount; - $validationStrategy = $this->getData(self::FIELD_NAME_VALIDATION_STRATEGY); - if ($errorsCount - && $validationStrategy === ProcessingErrorAggregatorInterface::VALIDATION_STRATEGY_SKIP_ERRORS - ) { - $this->messageManager->addWarningMessage(__('Skipped errors: %1', $errorsCount)); - $result = true; - } if ($result) { $this->addLogComment(__('Import data validation is complete.')); diff --git a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php index 9cc7c452e646f..6e361dfb05de0 100644 --- a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php +++ b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php @@ -1388,10 +1388,15 @@ public function testValidateUrlKeys($importFile, $expectedErrors) )->setSource( $source )->validateData(); + $urlKeyErrors = $errors->getErrorsByCode([RowValidatorInterface::ERROR_DUPLICATE_URL_KEY]); $this->assertEquals( $expectedErrors[RowValidatorInterface::ERROR_DUPLICATE_URL_KEY], - count($errors->getErrorsByCode([RowValidatorInterface::ERROR_DUPLICATE_URL_KEY])) + count($urlKeyErrors) ); + + foreach ($urlKeyErrors as $error) { + $this->assertEquals('critical', $error->getErrorLevel()); + } } /** diff --git a/dev/tests/integration/testsuite/Magento/ImportExport/Controller/Adminhtml/Import/ValidateTest.php b/dev/tests/integration/testsuite/Magento/ImportExport/Controller/Adminhtml/Import/ValidateTest.php index aab94361f752c..674335d361ffb 100644 --- a/dev/tests/integration/testsuite/Magento/ImportExport/Controller/Adminhtml/Import/ValidateTest.php +++ b/dev/tests/integration/testsuite/Magento/ImportExport/Controller/Adminhtml/Import/ValidateTest.php @@ -3,9 +3,11 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ + namespace Magento\ImportExport\Controller\Adminhtml\Import; use Magento\Framework\Filesystem\DirectoryList; +use Magento\Framework\HTTP\Adapter\FileTransferFactory; use Magento\ImportExport\Model\Import; use Magento\ImportExport\Model\Import\ErrorProcessing\ProcessingErrorAggregatorInterface; @@ -61,10 +63,7 @@ public function testValidationReturn(string $fileName, string $mimeType, string $this->_objectManager->configure( [ - 'preferences' => [ - \Magento\Framework\HTTP\Adapter\FileTransferFactory::class => - \Magento\ImportExport\Controller\Adminhtml\Import\HttpFactoryMock::class - ] + 'preferences' => [FileTransferFactory::class => HttpFactoryMock::class] ] ); @@ -81,7 +80,7 @@ public function testValidationReturn(string $fileName, string $mimeType, string /** * @return array */ - public function validationDataProvider() + public function validationDataProvider(): array { return [ [ From a58911f6e0d5e78765b90688097e10deb8bb0231 Mon Sep 17 00:00:00 2001 From: Nikita Shcherbatykh Date: Mon, 25 Feb 2019 17:20:56 +0200 Subject: [PATCH 204/315] MAGETWO-96895: [Magento Cloud] Import doesn't work with skip error entries --- .../Magento/CatalogImportExport/Model/Import/Product.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product.php b/app/code/Magento/CatalogImportExport/Model/Import/Product.php index f1d1868621fff..9cb6d4bd2390d 100644 --- a/app/code/Magento/CatalogImportExport/Model/Import/Product.php +++ b/app/code/Magento/CatalogImportExport/Model/Import/Product.php @@ -875,7 +875,7 @@ public function __construct( $this->productRepository = $productRepository ?? \Magento\Framework\App\ObjectManager::getInstance() ->get(ProductRepositoryInterface::class); - $errorMessageText = 'Value for multiselect attribute %s contains duplicated values'; + $errorMessageText = __('Value for multiselect attribute %s contains duplicated values'); $this->_messageTemplates[self::$errorDuplicateMultiselectValues] = $errorMessageText; } @@ -3062,10 +3062,10 @@ private function skipRow( /** * Returns errorLevel for validation * - * @param string $sku + * @param string|bool|null $sku * @return string */ - private function getValidationErrorLevel(string $sku): string + private function getValidationErrorLevel($sku): string { return (!$this->isSkuExist($sku) && Import::BEHAVIOR_REPLACE !== $this->getBehavior()) ? ProcessingError::ERROR_LEVEL_CRITICAL From 0673cb94424d049ea827b1298dedd7c3c1daa3e8 Mon Sep 17 00:00:00 2001 From: Viktor Petryk Date: Mon, 25 Feb 2019 18:24:21 +0200 Subject: [PATCH 205/315] MAGETWO-73524: WebAPI: product "has_options" flag not updated when options added via API --- .../Option/UpdateProductCustomOptionsAttributes.php | 5 +++-- .../Catalog/Api/ProductCustomOptionRepositoryTest.php | 11 +++++++---- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/Catalog/Plugin/Model/Product/Option/UpdateProductCustomOptionsAttributes.php b/app/code/Magento/Catalog/Plugin/Model/Product/Option/UpdateProductCustomOptionsAttributes.php index 2d25bd695763e..ada96d4fd48f4 100644 --- a/app/code/Magento/Catalog/Plugin/Model/Product/Option/UpdateProductCustomOptionsAttributes.php +++ b/app/code/Magento/Catalog/Plugin/Model/Product/Option/UpdateProductCustomOptionsAttributes.php @@ -45,8 +45,9 @@ public function afterSave( ) { $product->setCanSaveCustomOptions(true); $product->setOptionsSaved(true); - $currentOptions = array_filter($product->getOptions(), function ($iOption) use ($option) { - return $option->getOptionId() != $iOption->getOptionId(); + $optionId = $option->getOptionId(); + $currentOptions = array_filter($product->getOptions(), function ($optionItem) use ($optionId) { + return $optionId != $optionItem->getOptionId(); }); $currentOptions[] = $option; $product->setOptions($currentOptions); diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductCustomOptionRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductCustomOptionRepositoryTest.php index 5cffcea0fa832..e99a892b184ec 100644 --- a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductCustomOptionRepositoryTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductCustomOptionRepositoryTest.php @@ -32,6 +32,9 @@ class ProductCustomOptionRepositoryTest extends WebapiAbstract */ private $productRepository; + /** + * @inheritdoc + */ protected function setUp() { $this->objectManager = Bootstrap::getObjectManager(); @@ -175,9 +178,9 @@ public function testSave($optionData) } } $this->assertEquals($optionData, $result); - $this->assertTrue($product->getHasOptions() == 1); + $this->assertEquals(1, $product->getHasOptions()); if ($optionDataPost['is_require']) { - $this->assertTrue($product->getRequiredOptions() == 1); + $this->assertEquals(1, $product->getRequiredOptions()); } } @@ -200,7 +203,7 @@ public function optionDataProvider() * @dataProvider optionNegativeDataProvider * @param array $optionData */ - public function testAddNegative($optionData) + public function testAddNegative(array $optionData) { $productSku = 'simple'; $optionDataPost = $optionData; @@ -301,7 +304,7 @@ public function testUpdate() * @param string $optionType * @SuppressWarnings(PHPMD.UnusedLocalVariable) */ - public function testUpdateOptionAddingNewValue($optionType) + public function testUpdateOptionAddingNewValue(string $optionType) { $fixtureOption = null; $valueData = [ From bb6cf0e62024cf3e2ad74107f2856b9e5462df60 Mon Sep 17 00:00:00 2001 From: Stas Kozar Date: Tue, 26 Feb 2019 10:15:02 +0200 Subject: [PATCH 206/315] MAGETWO-95616: Changing Attribute Set may lead to exception "Attempt to load value of nonexistent EAV attribute" --- .../Eav/Test/Unit/Model/ResourceModel/ReadHandlerTest.php | 2 +- lib/internal/Magento/Framework/DB/Sql/UnionExpression.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Eav/Test/Unit/Model/ResourceModel/ReadHandlerTest.php b/app/code/Magento/Eav/Test/Unit/Model/ResourceModel/ReadHandlerTest.php index 66977a34a5adc..9020f22c497b6 100644 --- a/app/code/Magento/Eav/Test/Unit/Model/ResourceModel/ReadHandlerTest.php +++ b/app/code/Magento/Eav/Test/Unit/Model/ResourceModel/ReadHandlerTest.php @@ -145,7 +145,7 @@ public function testExecute() ->method('from') ->with( [ - 't' => 'some_table' + 't' => 'some_table', ], [ 'value' => 't.value', diff --git a/lib/internal/Magento/Framework/DB/Sql/UnionExpression.php b/lib/internal/Magento/Framework/DB/Sql/UnionExpression.php index 9957c6ffb8272..6961426fcc7f1 100644 --- a/lib/internal/Magento/Framework/DB/Sql/UnionExpression.php +++ b/lib/internal/Magento/Framework/DB/Sql/UnionExpression.php @@ -32,7 +32,7 @@ class UnionExpression extends Expression * @param string $type (optional) * @param string $pattern (optional) */ - public function __construct(array $parts, string $type = Select::SQL_UNION, string $pattern = '') + public function __construct(array $parts, $type = Select::SQL_UNION, $pattern = '') { $this->parts = $parts; $this->type = $type; From 6c09eca826e4ad3b4215748ae52054383b6163da Mon Sep 17 00:00:00 2001 From: Serhii Voloshkov Date: Tue, 26 Feb 2019 12:37:48 +0200 Subject: [PATCH 207/315] MAGETWO-95904: Header Minicart, Shopping cart page and Checkout page show incorrect product name --- .../Magento/Checkout/Block/Cart/Sidebar.php | 2 + .../CheckoutShippingGuestInfoSection.xml | 2 - ...tOnCheckoutPageDifferentStoreViewsTest.xml | 19 ++- .../view/frontend/web/js/view/minicart.js | 4 +- .../Quote/Plugin/UpdateQuoteItemStore.php | 4 +- .../Unit/Plugin/UpdateQuoteItemStoreTest.php | 143 ++++++++++++++++++ 6 files changed, 159 insertions(+), 15 deletions(-) create mode 100644 app/code/Magento/Quote/Test/Unit/Plugin/UpdateQuoteItemStoreTest.php diff --git a/app/code/Magento/Checkout/Block/Cart/Sidebar.php b/app/code/Magento/Checkout/Block/Cart/Sidebar.php index 7453d3c62e862..5e3234e9f4cc8 100644 --- a/app/code/Magento/Checkout/Block/Cart/Sidebar.php +++ b/app/code/Magento/Checkout/Block/Cart/Sidebar.php @@ -133,6 +133,7 @@ public function getShoppingCartUrl() * * @return string * @codeCoverageIgnore + * @SuppressWarnings(PHPMD.RequestAwareBlockMethod) */ public function getUpdateItemQtyUrl() { @@ -144,6 +145,7 @@ public function getUpdateItemQtyUrl() * * @return string * @codeCoverageIgnore + * @SuppressWarnings(PHPMD.RequestAwareBlockMethod) */ public function getRemoveItemUrl() { diff --git a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingGuestInfoSection.xml b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingGuestInfoSection.xml index 0a243d54cedef..115eb92c48268 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingGuestInfoSection.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingGuestInfoSection.xml @@ -17,7 +17,5 @@ - -
diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontProductNameMinicartOnCheckoutPageDifferentStoreViewsTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontProductNameMinicartOnCheckoutPageDifferentStoreViewsTest.xml index a810aa7107ff1..4622a6bd1ebf6 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontProductNameMinicartOnCheckoutPageDifferentStoreViewsTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontProductNameMinicartOnCheckoutPageDifferentStoreViewsTest.xml @@ -10,22 +10,23 @@ xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <description value="Checking Product name in Minicart and on Checkout page with custom store views"/> - <stories value="Verify product name with custom store view"/> + <stories value="Checkout via Guest Checkout"/> <severity value="MAJOR"/> <testCaseId value="MC-14944"/> - <features value="Checkout"/> + <useCaseId value="MAGETWO-95904"/> <group value="checkout"/> </annotations> <before> - <!--Login as Admin--> - <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> <!--Create a product--> <createData entity="SimpleSubCategory" stepKey="createCategory"/> <createData entity="SimpleProduct" stepKey="createProduct"> <requiredEntity createDataKey="createCategory"/> </createData> + <!--Login as Admin--> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> <!-- Create store view --> <actionGroup ref="AdminCreateStoreViewActionGroup" stepKey="createStoreView"> <argument name="customStore" value="customStore"/> @@ -39,6 +40,7 @@ <actionGroup ref="AdminDeleteStoreViewActionGroup" stepKey="deleteStoreView"> <argument name="customStore" value="customStore"/> </actionGroup> + <actionGroup ref="clearFiltersAdminDataGrid" stepKey="clearGridFilter"/> <!--Logout from admin--> <actionGroup ref="logout" stepKey="logout"/> </after> @@ -55,7 +57,7 @@ <click selector="{{AdminProductFormActionSection.saveButton}}" stepKey="saveProduct"/> <!--Add product to cart--> - <amOnPage url="{{StorefrontProductPage.url($$createProduct.name$$)}}" stepKey="amOnProductPage"/> + <amOnPage url="{{StorefrontProductPage.url($$createProduct.sku$$)}}" stepKey="amOnProductPage"/> <actionGroup ref="addToCartFromStorefrontProductPage" stepKey="addToCartFromStorefrontProductPage"> <argument name="productName" value="$createProduct.name$$"/> </actionGroup> @@ -76,12 +78,13 @@ </actionGroup> <!--Go to Shopping Cart--> - <actionGroup ref="clickViewAndEditCartFromMiniCart" stepKey="goToCheckoutFromMinicart"/> + <actionGroup ref="clickViewAndEditCartFromMiniCart" stepKey="goToShoppingCartFromMinicart"/> <seeElement selector="{{CheckoutCartProductSection.productLinkByName($$createProduct.name$$-new)}}" stepKey="assertProductName"/> <!--Proceed to checkout--> <actionGroup ref="GoToCheckoutFromMinicartActionGroup" stepKey="goToCheckoutPage"/> - <conditionalClick selector="{{CheckoutShippingGuestInfoSection.itemInCart}}" dependentSelector="{{CheckoutShippingGuestInfoSection.itemInCart}}" visible="true" stepKey="clickItemsInCart"/> - <see selector="{{CheckoutShippingGuestInfoSection.productName}}" userInput="$$createProduct.name$$-new" stepKey="seeProductNameAtCheckout"/> + <conditionalClick selector="{{CheckoutOrderSummarySection.miniCartTab}}" dependentSelector="{{CheckoutOrderSummarySection.miniCartTab}}" visible="true" stepKey="clickItemsInCart"/> + <waitForElementVisible selector="{{CheckoutOrderSummarySection.productItemName}}" stepKey="waitForProduct"/> + <see selector="{{CheckoutOrderSummarySection.productItemName}}" userInput="$$createProduct.name$$-new" stepKey="seeProductNameAtCheckout"/> </test> </tests> diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/minicart.js b/app/code/Magento/Checkout/view/frontend/web/js/view/minicart.js index 5e29fa209a641..da1b1a41e2fa9 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/view/minicart.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/view/minicart.js @@ -102,8 +102,8 @@ define([ self.isLoading(true); }); - if (cartData().website_id !== window.checkout.websiteId || - cartData().store_id !== window.checkout.storeId + if (cartData().website_id !== window.checkout.websiteId + || cartData().store_id !== window.checkout.storeId ) { customerData.reload(['cart'], false); } diff --git a/app/code/Magento/Quote/Plugin/UpdateQuoteItemStore.php b/app/code/Magento/Quote/Plugin/UpdateQuoteItemStore.php index 4d3e2dff70f9b..0ac589b11b53b 100644 --- a/app/code/Magento/Quote/Plugin/UpdateQuoteItemStore.php +++ b/app/code/Magento/Quote/Plugin/UpdateQuoteItemStore.php @@ -61,9 +61,7 @@ public function afterSwitch( ): string { $quote = $this->checkoutSession->getQuote(); if ($quote->getIsActive()) { - $quote->setStoreId( - $targetStore->getId() - ); + $quote->setStoreId($targetStore->getId()); $quote->getItemsCollection(false); $this->quoteRepository->save($quote); } diff --git a/app/code/Magento/Quote/Test/Unit/Plugin/UpdateQuoteItemStoreTest.php b/app/code/Magento/Quote/Test/Unit/Plugin/UpdateQuoteItemStoreTest.php new file mode 100644 index 0000000000000..f6146c824aabc --- /dev/null +++ b/app/code/Magento/Quote/Test/Unit/Plugin/UpdateQuoteItemStoreTest.php @@ -0,0 +1,143 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Quote\Test\Unit\Plugin; + +use Magento\Quote\Model\ResourceModel\Quote\Item; +use Magento\Store\Model\StoreSwitcherInterface; +use Magento\Quote\Plugin\UpdateQuoteItemStore; +use Magento\Quote\Model\QuoteRepository; +use Magento\Checkout\Model\Session; +use Magento\Store\Model\Store; +use Magento\Quote\Model\Quote; + +/** + * Unit test for Magento\Quote\Plugin\UpdateQuoteItemStore. + */ +class UpdateQuoteItemStoreTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var UpdateQuoteItemStore + */ + private $model; + + /** + * @var StoreSwitcherInterface|\PHPUnit_Framework_MockObject_MockObject + */ + protected $subjectMock; + + /** + * @var QuoteRepository|\PHPUnit_Framework_MockObject_MockObject + */ + private $quoteRepositoryMock; + + /** + * @var Quote|\PHPUnit_Framework_MockObject_MockObject + */ + private $quoteMock; + + /** + * @var Session|\PHPUnit_Framework_MockObject_MockObject + */ + private $checkoutSessionMock; + + /** + * @var Store|\PHPUnit_Framework_MockObject_MockObject + */ + private $storeMock; + + /** + * @inheritdoc + */ + protected function setUp() + { + $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); + $this->checkoutSessionMock = $this->createPartialMock( + Session::class, + ['getQuote'] + ); + $this->quoteMock = $this->createPartialMock( + Quote::class, + ['getIsActive', 'setStoreId', 'getItemsCollection'] + ); + $this->storeMock = $this->createPartialMock( + Store::class, + ['getId'] + ); + $this->quoteRepositoryMock = $this->createPartialMock( + QuoteRepository::class, + ['save'] + ); + $this->subjectMock = $this->createMock(StoreSwitcherInterface::class); + + $this->checkoutSessionMock->expects($this->once())->method('getQuote')->willReturn($this->quoteMock); + + $this->model = $objectManager->getObject( + UpdateQuoteItemStore::class, + [ + 'quoteRepository' => $this->quoteRepositoryMock, + 'checkoutSession' => $this->checkoutSessionMock, + ] + ); + } + + /** + * Unit test for afterSwitch method with active quote. + * + * @return void + */ + public function testWithActiveQuote() + { + $storeId = 1; + $this->quoteMock->expects($this->once())->method('getIsActive')->willReturn(true); + $this->storeMock->expects($this->once())->method('getId')->willReturn($storeId); + $this->quoteMock->expects($this->once())->method('setStoreId')->with($storeId)->willReturnSelf(); + $quoteItem = $this->createMock(Item::class); + $this->quoteMock->expects($this->once())->method('getItemsCollection')->willReturnSelf($quoteItem); + + $this->model->afterSwitch( + $this->subjectMock, + 'magento2.loc', + $this->storeMock, + $this->storeMock, + 'magento2.loc' + ); + } + + /** + * Unit test for afterSwitch method without active quote. + * + * @dataProvider getIsActive + * @param bool|null $isActive + * @return void + */ + public function testWithoutActiveQuote($isActive) + { + $this->quoteMock->expects($this->once())->method('getIsActive')->willReturn($isActive); + $this->quoteRepositoryMock->expects($this->never())->method('save'); + + $this->model->afterSwitch( + $this->subjectMock, + 'magento2.loc', + $this->storeMock, + $this->storeMock, + 'magento2.loc' + ); + } + + /** + * Data provider for method testWithoutActiveQuote. + * @return array + */ + public function getIsActive() + { + return [ + [false], + [null], + ]; + } +} From 835cdbeb44c27fa67b1d933dceee33ad4261f0a2 Mon Sep 17 00:00:00 2001 From: Serhii Voloshkov <serhii.voloshkov@transoftgroup.com> Date: Tue, 26 Feb 2019 14:13:15 +0200 Subject: [PATCH 208/315] MAGETWO-95904: Header Minicart, Shopping cart page and Checkout page show incorrect product name --- .../Magento/Checkout/view/frontend/web/js/view/minicart.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/minicart.js b/app/code/Magento/Checkout/view/frontend/web/js/view/minicart.js index da1b1a41e2fa9..5e29fa209a641 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/view/minicart.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/view/minicart.js @@ -102,8 +102,8 @@ define([ self.isLoading(true); }); - if (cartData().website_id !== window.checkout.websiteId - || cartData().store_id !== window.checkout.storeId + if (cartData().website_id !== window.checkout.websiteId || + cartData().store_id !== window.checkout.storeId ) { customerData.reload(['cart'], false); } From 3a68a8de9749280fcc48f10daa85238217fb0bf0 Mon Sep 17 00:00:00 2001 From: Serhii Voloshkov <serhii.voloshkov@transoftgroup.com> Date: Tue, 26 Feb 2019 15:23:04 +0200 Subject: [PATCH 209/315] MAGETWO-94421: Default addresses not selected when checking out from cart --- .../Sales/Test/Mftf/ActionGroup/AdminOrderActionGroup.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderActionGroup.xml b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderActionGroup.xml index eabe51776894e..479b631db0b71 100644 --- a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderActionGroup.xml +++ b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderActionGroup.xml @@ -296,4 +296,10 @@ <waitForElementVisible selector="{{AdminOrderFormPaymentSection.paymentBlock}}" stepKey="waitForPaymentOptions"/> <conditionalClick selector="{{AdminOrderFormPaymentSection.checkMoneyOption}}" dependentSelector="{{AdminOrderFormPaymentSection.checkMoneyOption}}" visible="true" stepKey="checkCheckMoneyOption"/> </actionGroup> + <!--Submit order--> + <actionGroup name="SubmitOrderActionGroup"> + <click selector="{{AdminOrderFormActionSection.submitOrder}}" stepKey="clickSubmitOrder"/> + <waitForElementVisible selector="{{AdminMessagesSection.success}}" stepKey="waitForSuccessMessage"/> + <see selector="{{AdminMessagesSection.success}}" userInput="You created the order." stepKey="seeOrderSuccessMessage"/> + </actionGroup> </actionGroups> From 806fb3736273279d042ba3f88878eb07e54c9b16 Mon Sep 17 00:00:00 2001 From: Nikita Shcherbatykh <nikita.shcherbatykh@transoftgroup.com> Date: Tue, 26 Feb 2019 16:56:51 +0200 Subject: [PATCH 210/315] MAGETWO-97975: Shipping tax rounding issue --- .../Magento/SalesRule/Model/Validator.php | 22 +-- .../Test/Unit/Model/ValidatorTest.php | 148 ++++++++++-------- .../ui_component/sales_rule_form.xml | 2 +- .../web/js/form/element/apply_to_shipping.js | 37 +++++ .../TestCase/CreateSalesRuleEntityTest.xml | 1 - 5 files changed, 131 insertions(+), 79 deletions(-) create mode 100644 app/code/Magento/SalesRule/view/adminhtml/web/js/form/element/apply_to_shipping.js diff --git a/app/code/Magento/SalesRule/Model/Validator.php b/app/code/Magento/SalesRule/Model/Validator.php index 201df99aa5187..64e170580a449 100644 --- a/app/code/Magento/SalesRule/Model/Validator.php +++ b/app/code/Magento/SalesRule/Model/Validator.php @@ -184,6 +184,8 @@ protected function _getRules(Address $address = null) } /** + * Address id getter. + * * @param Address $address * @return string */ @@ -329,21 +331,7 @@ public function processShippingAmount(Address $address) $baseDiscountAmount = $rule->getDiscountAmount(); break; case \Magento\SalesRule\Model\Rule::CART_FIXED_ACTION: - $cartRules = $address->getCartFixedRules(); - if (!isset($cartRules[$rule->getId()])) { - $cartRules[$rule->getId()] = $rule->getDiscountAmount(); - } - if ($cartRules[$rule->getId()] > 0) { - $quoteAmount = $this->priceCurrency->convert($cartRules[$rule->getId()], $quote->getStore()); - $discountAmount = min($shippingAmount - $address->getShippingDiscountAmount(), $quoteAmount); - $baseDiscountAmount = min( - $baseShippingAmount - $address->getBaseShippingDiscountAmount(), - $cartRules[$rule->getId()] - ); - $cartRules[$rule->getId()] -= $baseDiscountAmount; - } - - $address->setCartFixedRules($cartRules); + // Shouldn't be proceed according to MAGETWO-96403 break; } @@ -521,6 +509,8 @@ public function sortItemsByPriority($items, Address $address = null) } /** + * Rule total items getter. + * * @param int $key * @return array * @throws \Magento\Framework\Exception\LocalizedException @@ -535,6 +525,8 @@ public function getRuleItemTotalsInfo($key) } /** + * Decrease rule items count. + * * @param int $key * @return $this */ diff --git a/app/code/Magento/SalesRule/Test/Unit/Model/ValidatorTest.php b/app/code/Magento/SalesRule/Test/Unit/Model/ValidatorTest.php index 42448565791c5..5a4ce40c12288 100644 --- a/app/code/Magento/SalesRule/Test/Unit/Model/ValidatorTest.php +++ b/app/code/Magento/SalesRule/Test/Unit/Model/ValidatorTest.php @@ -5,6 +5,13 @@ */ namespace Magento\SalesRule\Test\Unit\Model; +use Magento\Framework\Pricing\PriceCurrencyInterface; +use Magento\Quote\Model\Quote; +use Magento\SalesRule\Model\Rule; +use Magento\SalesRule\Model\Validator; +use Magento\Store\Model\Store; +use PHPUnit_Framework_MockObject_MockObject as MockObject; + /** * Class ValidatorTest * @@SuppressWarnings(PHPMD.CouplingBetweenObjects) @@ -17,50 +24,55 @@ class ValidatorTest extends \PHPUnit\Framework\TestCase protected $helper; /** - * @var \Magento\SalesRule\Model\Validator + * @var Validator */ protected $model; /** - * @var \Magento\Quote\Model\Quote\Item|\PHPUnit_Framework_MockObject_MockObject + * @var \Magento\Quote\Model\Quote\Item|MockObject */ protected $item; /** - * @var \Magento\Quote\Model\Quote\Address|\PHPUnit_Framework_MockObject_MockObject + * @var \Magento\Quote\Model\Quote\Address|MockObject */ protected $addressMock; /** - * @var \Magento\SalesRule\Model\RulesApplier|\PHPUnit_Framework_MockObject_MockObject + * @var \Magento\SalesRule\Model\RulesApplier|MockObject */ protected $rulesApplier; /** - * @var \Magento\SalesRule\Model\Validator\Pool|\PHPUnit_Framework_MockObject_MockObject + * @var \Magento\SalesRule\Model\Validator\Pool|MockObject */ protected $validators; /** - * @var \Magento\SalesRule\Model\Utility|\PHPUnit_Framework_MockObject_MockObject + * @var \Magento\SalesRule\Model\Utility|MockObject */ protected $utility; /** - * @var \Magento\SalesRule\Model\ResourceModel\Rule\Collection|\PHPUnit_Framework_MockObject_MockObject + * @var \Magento\SalesRule\Model\ResourceModel\Rule\Collection|MockObject */ protected $ruleCollection; /** - * @var \Magento\Catalog\Helper\Data|\PHPUnit_Framework_MockObject_MockObject + * @var \Magento\Catalog\Helper\Data|MockObject */ protected $catalogData; /** - * @var \Magento\Framework\Message\ManagerInterface|\PHPUnit_Framework_MockObject_MockObject + * @var \Magento\Framework\Message\ManagerInterface|MockObject */ protected $messageManager; + /** + * @var PriceCurrencyInterface|MockObject + */ + private $priceCurrency; + protected function setUp() { $this->helper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); @@ -74,6 +86,7 @@ protected function setUp() ->setMethods( [ 'getShippingAmountForDiscount', + 'getBaseShippingAmountForDiscount', 'getQuote', 'getCustomAttributesCodes', 'setCartFixedRules' @@ -81,7 +94,7 @@ protected function setUp() ) ->getMock(); - /** @var \Magento\Quote\Model\Quote\Item\AbstractItem|\PHPUnit_Framework_MockObject_MockObject $item */ + /** @var \Magento\Quote\Model\Quote\Item\AbstractItem|MockObject $item */ $this->item = $this->createPartialMock( \Magento\Quote\Model\Quote\Item::class, ['__wakeup', 'getAddress', 'getParentItemId'] @@ -100,10 +113,13 @@ protected function setUp() ->disableOriginalConstructor() ->getMock(); $ruleCollectionFactoryMock = $this->prepareRuleCollectionMock($this->ruleCollection); + $this->priceCurrency = $this->getMockBuilder(PriceCurrencyInterface::class) + ->disableOriginalConstructor() + ->getMock(); - /** @var \Magento\SalesRule\Model\Validator|\PHPUnit_Framework_MockObject_MockObject $validator */ + /** @var Validator|MockObject $validator */ $this->model = $this->helper->getObject( - \Magento\SalesRule\Model\Validator::class, + Validator::class, [ 'context' => $context, 'registry' => $registry, @@ -112,7 +128,8 @@ protected function setUp() 'utility' => $this->utility, 'rulesApplier' => $this->rulesApplier, 'validators' => $this->validators, - 'messageManager' => $this->messageManager + 'messageManager' => $this->messageManager, + 'priceCurrency' => $this->priceCurrency ] ); $this->model->setWebsiteId(1); @@ -131,7 +148,7 @@ protected function setUp() } /** - * @return \Magento\Quote\Model\Quote\Item|\PHPUnit_Framework_MockObject_MockObject + * @return \Magento\Quote\Model\Quote\Item|MockObject */ protected function getQuoteItemMock() { @@ -145,8 +162,8 @@ protected function getQuoteItemMock() $itemSimple = $this->createPartialMock(\Magento\Quote\Model\Quote\Item::class, ['getAddress', '__wakeup']); $itemSimple->expects($this->any())->method('getAddress')->will($this->returnValue($this->addressMock)); - /** @var $quote \Magento\Quote\Model\Quote */ - $quote = $this->createPartialMock(\Magento\Quote\Model\Quote::class, ['getStoreId', '__wakeup']); + /** @var $quote Quote */ + $quote = $this->createPartialMock(Quote::class, ['getStoreId', '__wakeup']); $quote->expects($this->any())->method('getStoreId')->will($this->returnValue(1)); $itemData = include $fixturePath . 'quote_item_downloadable.php'; @@ -168,7 +185,7 @@ public function testCanApplyRules() $this->model->getCouponCode() ); $item = $this->getQuoteItemMock(); - $rule = $this->createMock(\Magento\SalesRule\Model\Rule::class); + $rule = $this->createMock(Rule::class); $actionsCollection = $this->createPartialMock(\Magento\Rule\Model\Action\Collection::class, ['validate']); $actionsCollection->expects($this->any()) ->method('validate') @@ -278,7 +295,7 @@ public function testApplyRulesThatAppliedRuleIdsAreCollected() public function testInit() { $this->assertInstanceOf( - \Magento\SalesRule\Model\Validator::class, + Validator::class, $this->model->init( $this->model->getWebsiteId(), $this->model->getCustomerGroupId(), @@ -314,7 +331,7 @@ public function testCanApplyDiscount() public function testInitTotalsCanApplyDiscount() { $rule = $this->createPartialMock( - \Magento\SalesRule\Model\Rule::class, + Rule::class, ['getSimpleAction', 'getActions', 'getId'] ); $item1 = $this->getMockForAbstractClass( @@ -337,7 +354,7 @@ public function testInitTotalsCanApplyDiscount() $rule->expects($this->any()) ->method('getSimpleAction') - ->willReturn(\Magento\SalesRule\Model\Rule::CART_FIXED_ACTION); + ->willReturn(Rule::CART_FIXED_ACTION); $iterator = new \ArrayIterator([$rule]); $this->ruleCollection->expects($this->once())->method('getIterator')->willReturn($iterator); $validator = $this->getMockBuilder(\Magento\Framework\Validator\AbstractValidator::class) @@ -392,7 +409,7 @@ public function testInitTotalsNoItems() /** * @param $ruleCollection - * @return \PHPUnit_Framework_MockObject_MockObject + * @return MockObject */ protected function prepareRuleCollectionMock($ruleCollection) { @@ -427,14 +444,14 @@ public function testProcessShippingAmountNoRules() $this->model->getCouponCode() ); $this->assertInstanceOf( - \Magento\SalesRule\Model\Validator::class, + Validator::class, $this->model->processShippingAmount($this->setupAddressMock()) ); } public function testProcessShippingAmountProcessDisabled() { - $ruleMock = $this->getMockBuilder(\Magento\SalesRule\Model\Rule::class) + $ruleMock = $this->getMockBuilder(Rule::class) ->disableOriginalConstructor() ->setMethods([]) ->getMock(); @@ -448,51 +465,54 @@ public function testProcessShippingAmountProcessDisabled() $this->model->getCouponCode() ); $this->assertInstanceOf( - \Magento\SalesRule\Model\Validator::class, + Validator::class, $this->model->processShippingAmount($this->setupAddressMock()) ); } /** + * Tests shipping amounts according to rule simple action. + * * @param string $action + * @param int $ruleDiscount + * @param int $shippingDiscount * @dataProvider dataProviderActions */ - public function testProcessShippingAmountActions($action) + public function testProcessShippingAmountActions($action, $ruleDiscount, $shippingDiscount): void { - $discountAmount = 50; + $shippingAmount = 5; - $ruleMock = $this->getMockBuilder(\Magento\SalesRule\Model\Rule::class) + $ruleMock = $this->getMockBuilder(Rule::class) ->disableOriginalConstructor() ->setMethods(['getApplyToShipping', 'getSimpleAction', 'getDiscountAmount']) ->getMock(); - $ruleMock->expects($this->any()) - ->method('getApplyToShipping') + $ruleMock->method('getApplyToShipping') ->willReturn(true); - $ruleMock->expects($this->any()) - ->method('getDiscountAmount') - ->willReturn($discountAmount); - $ruleMock->expects($this->any()) - ->method('getSimpleAction') + $ruleMock->method('getDiscountAmount') + ->willReturn($ruleDiscount); + $ruleMock->method('getSimpleAction') ->willReturn($action); $iterator = new \ArrayIterator([$ruleMock]); - $this->ruleCollection->expects($this->any()) - ->method('getIterator') + $this->ruleCollection->method('getIterator') ->willReturn($iterator); - $this->utility->expects($this->any()) - ->method('canProcessRule') + $this->utility->method('canProcessRule') ->willReturn(true); + $this->priceCurrency->method('convert') + ->willReturn($ruleDiscount); + $this->model->init( $this->model->getWebsiteId(), $this->model->getCustomerGroupId(), $this->model->getCouponCode() ); - $this->assertInstanceOf( - \Magento\SalesRule\Model\Validator::class, - $this->model->processShippingAmount($this->setupAddressMock(5)) - ); + + $addressMock = $this->setupAddressMock($shippingAmount); + + self::assertInstanceOf(Validator::class, $this->model->processShippingAmount($addressMock)); + self::assertEquals($shippingDiscount, $addressMock->getShippingDiscountAmount()); } /** @@ -501,44 +521,48 @@ public function testProcessShippingAmountActions($action) public static function dataProviderActions() { return [ - [\Magento\SalesRule\Model\Rule::TO_PERCENT_ACTION], - [\Magento\SalesRule\Model\Rule::BY_PERCENT_ACTION], - [\Magento\SalesRule\Model\Rule::TO_FIXED_ACTION], - [\Magento\SalesRule\Model\Rule::BY_FIXED_ACTION], - [\Magento\SalesRule\Model\Rule::CART_FIXED_ACTION], + [Rule::TO_PERCENT_ACTION, 50, 2.5], + [Rule::BY_PERCENT_ACTION, 50, 2.5], + [Rule::TO_FIXED_ACTION, 5, 0], + [Rule::BY_FIXED_ACTION, 5, 5], + [Rule::CART_FIXED_ACTION, 5, 0], ]; } /** * @param null|int $shippingAmount - * @return \PHPUnit_Framework_MockObject_MockObject + * @return MockObject */ protected function setupAddressMock($shippingAmount = null) { - $storeMock = $this->getMockBuilder(\Magento\Store\Model\Store::class) + $storeMock = $this->getMockBuilder(Store::class) ->disableOriginalConstructor() ->setMethods([]) ->getMock(); - $quoteMock = $this->getMockBuilder(\Magento\Quote\Model\Quote::class) + + $quoteMock = $this->getMockBuilder(Quote::class) ->disableOriginalConstructor() ->setMethods(['setAppliedRuleIds', 'getStore']) ->getMock(); - $quoteMock->expects($this->any()) - ->method('getStore') + + $quoteMock->method('getStore') ->willReturn($storeMock); - $quoteMock->expects($this->any()) - ->method('setAppliedRuleIds') + + $quoteMock->method('setAppliedRuleIds') ->willReturnSelf(); - $this->addressMock->expects($this->any()) - ->method('getShippingAmountForDiscount') + $this->addressMock->method('getShippingAmountForDiscount') ->willReturn($shippingAmount); - $this->addressMock->expects($this->any()) - ->method('getQuote') + + $this->addressMock->method('getBaseShippingAmountForDiscount') + ->willReturn($shippingAmount); + + $this->addressMock->method('getQuote') ->willReturn($quoteMock); - $this->addressMock->expects($this->any()) - ->method('getCustomAttributesCodes') + + $this->addressMock->method('getCustomAttributesCodes') ->willReturn([]); + return $this->addressMock; } @@ -546,7 +570,7 @@ public function testReset() { $this->utility->expects($this->once()) ->method('resetRoundingDeltas'); - $quoteMock = $this->getMockBuilder(\Magento\Quote\Model\Quote::class) + $quoteMock = $this->getMockBuilder(Quote::class) ->disableOriginalConstructor() ->getMock(); $addressMock = $this->getMockBuilder(\Magento\Quote\Model\Quote\Address::class) @@ -560,6 +584,6 @@ public function testReset() $this->model->getCustomerGroupId(), $this->model->getCouponCode() ); - $this->assertInstanceOf(\Magento\SalesRule\Model\Validator::class, $this->model->reset($addressMock)); + $this->assertInstanceOf(Validator::class, $this->model->reset($addressMock)); } } diff --git a/app/code/Magento/SalesRule/view/adminhtml/ui_component/sales_rule_form.xml b/app/code/Magento/SalesRule/view/adminhtml/ui_component/sales_rule_form.xml index 9b579f47759a6..570eb0bf151f0 100644 --- a/app/code/Magento/SalesRule/view/adminhtml/ui_component/sales_rule_form.xml +++ b/app/code/Magento/SalesRule/view/adminhtml/ui_component/sales_rule_form.xml @@ -452,7 +452,7 @@ <dataScope>discount_step</dataScope> </settings> </field> - <field name="apply_to_shipping" component="Magento_Ui/js/form/element/single-checkbox-toggle-notice" formElement="checkbox"> + <field name="apply_to_shipping" component="Magento_SalesRule/js/form/element/apply_to_shipping" formElement="checkbox"> <argument name="data" xsi:type="array"> <item name="config" xsi:type="array"> <item name="source" xsi:type="string">sales_rule</item> diff --git a/app/code/Magento/SalesRule/view/adminhtml/web/js/form/element/apply_to_shipping.js b/app/code/Magento/SalesRule/view/adminhtml/web/js/form/element/apply_to_shipping.js new file mode 100644 index 0000000000000..dfb3f909345b3 --- /dev/null +++ b/app/code/Magento/SalesRule/view/adminhtml/web/js/form/element/apply_to_shipping.js @@ -0,0 +1,37 @@ +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +define([ + 'Magento_Ui/js/form/element/single-checkbox-toggle-notice' +], function (Checkbox) { + 'use strict'; + + return Checkbox.extend({ + defaults: { + imports: { + toggleDisabled: '${ $.parentName }.simple_action:value' + } + }, + + /** + * Toggle element disabled state according to simple action value. + * + * @param {String} action + */ + toggleDisabled: function (action) { + switch (action) { + case 'cart_fixed': + this.disabled(true); + break; + default: + this.disabled(false); + } + + if (this.disabled()) { + this.checked(false); + } + } + }); +}); diff --git a/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/CreateSalesRuleEntityTest.xml b/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/CreateSalesRuleEntityTest.xml index 586ad2acee203..4995c1feb048e 100644 --- a/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/CreateSalesRuleEntityTest.xml +++ b/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/CreateSalesRuleEntityTest.xml @@ -75,7 +75,6 @@ <data name="salesRule/data/coupon_code" xsi:type="string">Lorem ipsum dolor sit amet, consectetur adipiscing elit - %isolation%</data> <data name="salesRule/data/simple_action" xsi:type="string">Fixed amount discount for whole cart</data> <data name="salesRule/data/discount_amount" xsi:type="string">60</data> - <data name="salesRule/data/apply_to_shipping" xsi:type="string">No</data> <data name="salesRule/data/simple_free_shipping" xsi:type="string">No</data> <data name="salesRule/data/store_labels/0" xsi:type="string">Coupon code+Fixed amount discount for whole cart</data> <data name="productForSalesRule1/dataset" xsi:type="string">simple_for_salesrule_1</data> From dd8202e943c112b716b80c99a2596b16545b9a00 Mon Sep 17 00:00:00 2001 From: Serhii Voloshkov <serhii.voloshkov@transoftgroup.com> Date: Tue, 26 Feb 2019 17:00:34 +0200 Subject: [PATCH 211/315] MAGETWO-95904: Header Minicart, Shopping cart page and Checkout page show incorrect product name --- ...ProductNameMinicartOnCheckoutPageDifferentStoreViewsTest.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontProductNameMinicartOnCheckoutPageDifferentStoreViewsTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontProductNameMinicartOnCheckoutPageDifferentStoreViewsTest.xml index 4622a6bd1ebf6..9fee0302345d5 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontProductNameMinicartOnCheckoutPageDifferentStoreViewsTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontProductNameMinicartOnCheckoutPageDifferentStoreViewsTest.xml @@ -57,7 +57,7 @@ <click selector="{{AdminProductFormActionSection.saveButton}}" stepKey="saveProduct"/> <!--Add product to cart--> - <amOnPage url="{{StorefrontProductPage.url($$createProduct.sku$$)}}" stepKey="amOnProductPage"/> + <amOnPage url="{{StorefrontProductPage.url($$createProduct.custom_attributes[url_key]$$)}}" stepKey="amOnProductPage"/> <actionGroup ref="addToCartFromStorefrontProductPage" stepKey="addToCartFromStorefrontProductPage"> <argument name="productName" value="$createProduct.name$$"/> </actionGroup> From 97b8f5f60c4e970988ddbf3737740cdfae3054f8 Mon Sep 17 00:00:00 2001 From: Nazarn96 <nazarn96@gmail.com> Date: Wed, 27 Feb 2019 10:58:14 +0200 Subject: [PATCH 212/315] Removing unused legacy price code --- lib/web/mage/adminhtml/tools.js | 6 ------ 1 file changed, 6 deletions(-) diff --git a/lib/web/mage/adminhtml/tools.js b/lib/web/mage/adminhtml/tools.js index f23a0193cb6b2..ed4bab7102ae5 100644 --- a/lib/web/mage/adminhtml/tools.js +++ b/lib/web/mage/adminhtml/tools.js @@ -89,12 +89,6 @@ function checkByProductPriceType(elem) { } -Event.observe(window, 'load', function () { - if ($('price_default') && $('price_default').checked) { - $('price').disabled = 'disabled'; - } -}); - function toggleSeveralValueElements(checkbox, containers, excludedElements, checked) { 'use strict'; From ca2d3bd42541d2b61616f81a69f004a1a07aa483 Mon Sep 17 00:00:00 2001 From: Viktor Sevch <svitja@ukr.net> Date: Wed, 27 Feb 2019 13:00:17 +0200 Subject: [PATCH 213/315] MAGETWO-92495: [Magento Cloud] - Wrong color image when filtering by color filter --- .../Product/Renderer/Listing/Configurable.php | 36 +++++-- app/code/Magento/Swatches/Helper/Data.php | 13 +-- .../Renderer/Listing/ConfigurableTest.php | 100 +++++++++++++++++- .../Swatches/Test/Unit/Helper/DataTest.php | 2 + 4 files changed, 134 insertions(+), 17 deletions(-) diff --git a/app/code/Magento/Swatches/Block/Product/Renderer/Listing/Configurable.php b/app/code/Magento/Swatches/Block/Product/Renderer/Listing/Configurable.php index 85633475205ed..3df47ee749587 100644 --- a/app/code/Magento/Swatches/Block/Product/Renderer/Listing/Configurable.php +++ b/app/code/Magento/Swatches/Block/Product/Renderer/Listing/Configurable.php @@ -8,6 +8,8 @@ use Magento\Catalog\Block\Product\Context; use Magento\Catalog\Helper\Product as CatalogProduct; use Magento\Catalog\Model\Product; +use Magento\Catalog\Model\Layer\Resolver; +use Magento\Catalog\Model\Layer\Category as CategoryLayer; use Magento\ConfigurableProduct\Helper\Data; use Magento\ConfigurableProduct\Model\ConfigurableAttributeData; use Magento\Customer\Helper\Session\CurrentCustomer; @@ -39,6 +41,12 @@ class Configurable extends \Magento\Swatches\Block\Product\Renderer\Configurable private $variationPrices; /** + * @var \Magento\Catalog\Model\Layer\Resolver + */ + private $layerResolver; + + /** + * @SuppressWarnings(PHPMD.ExcessiveParameterList) * @param Context $context * @param ArrayUtils $arrayUtils * @param EncoderInterface $jsonEncoder @@ -49,11 +57,11 @@ class Configurable extends \Magento\Swatches\Block\Product\Renderer\Configurable * @param ConfigurableAttributeData $configurableAttributeData * @param SwatchData $swatchHelper * @param Media $swatchMediaHelper - * @param array $data other data - * @param SwatchAttributesProvider $swatchAttributesProvider + * @param array $data + * @param SwatchAttributesProvider|null $swatchAttributesProvider * @param \Magento\Framework\Locale\Format|null $localeFormat * @param \Magento\ConfigurableProduct\Model\Product\Type\Configurable\Variations\Prices|null $variationPrices - * @SuppressWarnings(PHPMD.ExcessiveParameterList) + * @param Resolver $layerResolver */ public function __construct( Context $context, @@ -69,7 +77,8 @@ public function __construct( array $data = [], SwatchAttributesProvider $swatchAttributesProvider = null, \Magento\Framework\Locale\Format $localeFormat = null, - \Magento\ConfigurableProduct\Model\Product\Type\Configurable\Variations\Prices $variationPrices = null + \Magento\ConfigurableProduct\Model\Product\Type\Configurable\Variations\Prices $variationPrices = null, + Resolver $layerResolver = null ) { parent::__construct( $context, @@ -91,10 +100,11 @@ public function __construct( $this->variationPrices = $variationPrices ?: ObjectManager::getInstance()->get( \Magento\ConfigurableProduct\Model\Product\Type\Configurable\Variations\Prices::class ); + $this->layerResolver = $layerResolver ?: ObjectManager::getInstance()->get(Resolver::class); } /** - * @return string + * @inheritdoc */ protected function getRendererTemplate() { @@ -120,7 +130,7 @@ protected function _toHtml() } /** - * @return array + * @inheritdoc */ protected function getSwatchAttributesData() { @@ -182,6 +192,7 @@ protected function getOptionImages() * Add images to result json config in case of Layered Navigation is used * * @return array + * @SuppressWarnings(PHPMD.RequestAwareBlockMethod) * @since 100.2.0 */ protected function _getAdditionalConfig() @@ -246,4 +257,17 @@ private function getLayeredAttributesIfExists(Product $configurableProduct, arra return $layeredAttributes; } + + /** + * @inheritdoc + */ + public function getCacheKeyInfo() + { + $cacheKeyInfo = parent::getCacheKeyInfo(); + /** @var CategoryLayer $catalogLayer */ + $catalogLayer = $this->layerResolver->get(); + $cacheKeyInfo[] = $catalogLayer->getStateKey(); + + return $cacheKeyInfo; + } } diff --git a/app/code/Magento/Swatches/Helper/Data.php b/app/code/Magento/Swatches/Helper/Data.php index ae35f5203dd73..2c00224083bfc 100644 --- a/app/code/Magento/Swatches/Helper/Data.php +++ b/app/code/Magento/Swatches/Helper/Data.php @@ -249,18 +249,15 @@ public function loadVariationByFallback(Product $parentProduct, array $attribute $this->addFilterByParent($productCollection, $parentId); $configurableAttributes = $this->getAttributesFromConfigurable($parentProduct); - $allAttributesArray = []; + + $resultAttributesToFilter = []; foreach ($configurableAttributes as $attribute) { - if (!empty($attribute['default_value'])) { - $allAttributesArray[$attribute['attribute_code']] = $attribute['default_value']; + $attributeCode = $attribute->getData('attribute_code'); + if (array_key_exists($attributeCode, $attributes)) { + $resultAttributesToFilter[$attributeCode] = $attributes[$attributeCode]; } } - $resultAttributesToFilter = array_merge( - $attributes, - array_diff_key($allAttributesArray, $attributes) - ); - $this->addFilterByAttributes($productCollection, $resultAttributesToFilter); $variationProduct = $productCollection->getFirstItem(); diff --git a/app/code/Magento/Swatches/Test/Unit/Block/Product/Renderer/Listing/ConfigurableTest.php b/app/code/Magento/Swatches/Test/Unit/Block/Product/Renderer/Listing/ConfigurableTest.php index 6b72422d05014..adcdcad25e337 100644 --- a/app/code/Magento/Swatches/Test/Unit/Block/Product/Renderer/Listing/ConfigurableTest.php +++ b/app/code/Magento/Swatches/Test/Unit/Block/Product/Renderer/Listing/ConfigurableTest.php @@ -61,6 +61,18 @@ class ConfigurableTest extends \PHPUnit\Framework\TestCase /** @var \PHPUnit_Framework_MockObject_MockObject */ private $variationPricesMock; + /** @var \PHPUnit_Framework_MockObject_MockObject */ + private $layerResolverMock; + + /** @var ObjectManagerHelper */ + private $objectManagerHelper; + + /** @var \Magento\Store\Model\StoreManagerInterface|\PHPUnit_Framework_MockObject_MockObject */ + private $storeManagerMock; + + /** @var \Magento\Customer\Model\Session|\PHPUnit_Framework_MockObject_MockObject */ + private $customerSessionMock; + public function setUp() { $this->arrayUtils = $this->createMock(\Magento\Framework\Stdlib\ArrayUtils::class); @@ -82,9 +94,35 @@ public function setUp() $this->variationPricesMock = $this->createMock( \Magento\ConfigurableProduct\Model\Product\Type\Configurable\Variations\Prices::class ); + $this->layerResolverMock = $this->createMock(\Magento\Catalog\Model\Layer\Resolver::class); + + $this->storeManagerMock = $this->getMockBuilder(\Magento\Store\Model\StoreManagerInterface::class) + ->setMethods(['getStore']) + ->getMockForAbstractClass(); + $this->customerSessionMock = $this->getMockBuilder(\Magento\Customer\Model\Session::class) + ->disableOriginalConstructor() + ->setMethods(['getCustomerGroupId']) + ->getMock(); + + $this->objectManagerHelper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); + $this->prepareObjectManager([ + [ + \Magento\Framework\Locale\Format::class, + $this->createMock(\Magento\Framework\Locale\Format::class), + ], + [ + \Magento\ConfigurableProduct\Model\Product\Type\Configurable\Variations\Prices::class, + $this->createMock( + \Magento\ConfigurableProduct\Model\Product\Type\Configurable\Variations\Prices::class + ), + ], + [ + \Magento\Customer\Model\Session::class, + $this->customerSessionMock, + ], + ]); - $objectManagerHelper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); - $this->configurable = $objectManagerHelper->getObject( + $this->configurable = $this->objectManagerHelper->getObject( \Magento\Swatches\Block\Product\Renderer\Listing\Configurable::class, [ 'scopeConfig' => $this->scopeConfig, @@ -100,9 +138,15 @@ public function setUp() 'priceCurrency' => $this->priceCurrency, 'configurableAttributeData' => $this->configurableAttributeData, 'data' => [], - 'variationPrices' => $this->variationPricesMock + 'variationPrices' => $this->variationPricesMock, + 'layerResolver' => $this->layerResolverMock, ] ); + $this->objectManagerHelper->setBackwardCompatibleProperty( + $this->configurable, + '_storeManager', + $this->storeManagerMock + ); } /** @@ -235,4 +279,54 @@ public function testGetPricesJson() $this->jsonEncoder->expects($this->once())->method('encode')->with($expectedPrices); $this->configurable->getPricesJson(); } + + /** + * @param $map + */ + private function prepareObjectManager($map) + { + $objectManagerMock = $this->getMockBuilder(\Magento\Framework\ObjectManagerInterface::class) + ->setMethods(['getInstance']) + ->getMockForAbstractClass(); + $objectManagerMock->expects($this->any())->method('getInstance')->willReturnSelf(); + $objectManagerMock->expects($this->any()) + ->method('get') + ->will($this->returnValueMap($map)); + $reflectionClass = new \ReflectionClass(\Magento\Framework\App\ObjectManager::class); + $reflectionProperty = $reflectionClass->getProperty('_instance'); + $reflectionProperty->setAccessible(true); + $reflectionProperty->setValue($objectManagerMock); + } + + /** + * Test receiving cache key info. + */ + public function testGetCacheKeyInfo() + { + $expected = [ + 0 => 'BLOCK_TPL', + 1 => 'default', + 2 => NULL, + 'base_url' => NULL, + 'template' => NULL, + 3 => 'USD', + 4 => NULL, + 5 => 'STORE_1_CAT_25_CUSTGROUP_0_color_53', + ]; + $stateKey = 'STORE_1_CAT_25_CUSTGROUP_0_color_53'; + + $storeMock = $this->getMockBuilder(\Magento\Store\Api\Data\StoreInterface::class)->getMockForAbstractClass(); + $storeMock->expects($this->any())->method('getCode')->willReturn('default'); + $this->storeManagerMock->expects($this->any())->method('getStore')->willReturn($storeMock); + $currency = $this->getMockBuilder(\Magento\Directory\Model\Currency::class) + ->disableOriginalConstructor() + ->getMock(); + $this->priceCurrency->expects($this->once())->method('getCurrency')->willReturn($currency); + $currency->expects($this->once())->method('getCode')->willReturn('USD'); + $layer = $this->createMock(\Magento\Catalog\Model\Layer::class); + $this->layerResolverMock->expects($this->once())->method('get')->willReturn($layer); + $layer->expects($this->once())->method('getStateKey')->willReturn($stateKey); + + $this->assertEquals($this->configurable->getCacheKeyInfo(), $expected); + } } diff --git a/app/code/Magento/Swatches/Test/Unit/Helper/DataTest.php b/app/code/Magento/Swatches/Test/Unit/Helper/DataTest.php index 5732018f7615f..58f9ea821f0b4 100644 --- a/app/code/Magento/Swatches/Test/Unit/Helper/DataTest.php +++ b/app/code/Magento/Swatches/Test/Unit/Helper/DataTest.php @@ -278,6 +278,8 @@ public function testLoadVariationByFallback($product) $metadataMock = $this->createMock(\Magento\Framework\EntityManager\EntityMetadataInterface::class); $this->metaDataPoolMock->expects($this->once())->method('getMetadata')->willReturn($metadataMock); $metadataMock->expects($this->once())->method('getLinkField')->willReturn('id'); + $this->productMock->expects($this->once())->method('getTypeInstance')->willReturn($this->configurableMock); + $this->attributeMock->method('getData')->with('attribute_code')->willReturn('color'); $this->getSwatchAttributes($product); From e5145576095fe77d839e138f68fbf9e4f49c21fc Mon Sep 17 00:00:00 2001 From: Viktor Sevch <svitja@ukr.net> Date: Wed, 27 Feb 2019 14:28:00 +0200 Subject: [PATCH 214/315] MAGETWO-92495: [Magento Cloud] - Wrong color image when filtering by color filter --- .../Block/Product/Renderer/Listing/ConfigurableTest.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Swatches/Test/Unit/Block/Product/Renderer/Listing/ConfigurableTest.php b/app/code/Magento/Swatches/Test/Unit/Block/Product/Renderer/Listing/ConfigurableTest.php index adcdcad25e337..fce0f6609ad73 100644 --- a/app/code/Magento/Swatches/Test/Unit/Block/Product/Renderer/Listing/ConfigurableTest.php +++ b/app/code/Magento/Swatches/Test/Unit/Block/Product/Renderer/Listing/ConfigurableTest.php @@ -306,11 +306,11 @@ public function testGetCacheKeyInfo() $expected = [ 0 => 'BLOCK_TPL', 1 => 'default', - 2 => NULL, - 'base_url' => NULL, - 'template' => NULL, + 2 => null, + 'base_url' => null, + 'template' => null, 3 => 'USD', - 4 => NULL, + 4 => null, 5 => 'STORE_1_CAT_25_CUSTGROUP_0_color_53', ]; $stateKey = 'STORE_1_CAT_25_CUSTGROUP_0_color_53'; From abcf202ef6bc9c3d9b3276215126e7404b5326e7 Mon Sep 17 00:00:00 2001 From: Nazarn96 <nazarn96@gmail.com> Date: Wed, 27 Feb 2019 15:40:40 +0200 Subject: [PATCH 215/315] fix wrong check CustomerMiddleName --- app/code/Magento/Quote/Model/QuoteManagement.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Quote/Model/QuoteManagement.php b/app/code/Magento/Quote/Model/QuoteManagement.php index bf1caa2434638..e21ae7fa1af37 100644 --- a/app/code/Magento/Quote/Model/QuoteManagement.php +++ b/app/code/Magento/Quote/Model/QuoteManagement.php @@ -359,7 +359,7 @@ public function placeOrder($cartId, PaymentInterface $paymentMethod = null) if ($quote->getCustomerFirstname() === null && $quote->getCustomerLastname() === null) { $quote->setCustomerFirstname($quote->getBillingAddress()->getFirstname()); $quote->setCustomerLastname($quote->getBillingAddress()->getLastname()); - if ($quote->getBillingAddress()->getMiddlename() === null) { + if ($quote->getCustomerMiddlename() === null) { $quote->setCustomerMiddlename($quote->getBillingAddress()->getMiddlename()); } } From 7d9d9e116c3b4dff0e737ed304ff74b6803d704b Mon Sep 17 00:00:00 2001 From: serhii balko <serhii.balko@transoftgroup.com> Date: Wed, 27 Feb 2019 15:57:41 +0200 Subject: [PATCH 216/315] MAGETWO-98365: [Magento Cloud] Recalculation of Tier prices after customer logs in --- .../Model/Product/Type/Configurable/Price.php | 19 +-- .../Product/Type/Configurable/PriceTest.php | 109 +++++++++++++++--- 2 files changed, 107 insertions(+), 21 deletions(-) diff --git a/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable/Price.php b/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable/Price.php index bee334596e990..f2bf3116af9e4 100644 --- a/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable/Price.php +++ b/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable/Price.php @@ -7,14 +7,15 @@ */ namespace Magento\ConfigurableProduct\Model\Product\Type\Configurable; +use Magento\Catalog\Model\Product; + +/** + * Class Price for configurable product + */ class Price extends \Magento\Catalog\Model\Product\Type\Price { /** - * Get product final price - * - * @param float $qty - * @param \Magento\Catalog\Model\Product $product - * @return float + * @inheritdoc */ public function getFinalPrice($qty, $product) { @@ -22,7 +23,10 @@ public function getFinalPrice($qty, $product) return $product->getCalculatedFinalPrice(); } if ($product->getCustomOption('simple_product') && $product->getCustomOption('simple_product')->getProduct()) { - $finalPrice = parent::getFinalPrice($qty, $product->getCustomOption('simple_product')->getProduct()); + /** @var Product $simpleProduct */ + $simpleProduct = $product->getCustomOption('simple_product')->getProduct(); + $simpleProduct->setCustomerGroupId($product->getCustomerGroupId()); + $finalPrice = parent::getFinalPrice($qty, $simpleProduct); } else { $priceInfo = $product->getPriceInfo(); $finalPrice = $priceInfo->getPrice('final_price')->getAmount()->getValue(); @@ -35,7 +39,7 @@ public function getFinalPrice($qty, $product) } /** - * {@inheritdoc} + * @inheritdoc */ public function getPrice($product) { @@ -48,6 +52,7 @@ public function getPrice($product) } } } + return 0; } } diff --git a/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Product/Type/Configurable/PriceTest.php b/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Product/Type/Configurable/PriceTest.php index 64b9b3776442a..0fc650a4113c6 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Product/Type/Configurable/PriceTest.php +++ b/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Product/Type/Configurable/PriceTest.php @@ -6,22 +6,47 @@ namespace Magento\ConfigurableProduct\Test\Unit\Model\Product\Type\Configurable; +use Magento\Catalog\Model\Product; +use Magento\Catalog\Model\Product\Configuration\Item\Option; +use Magento\ConfigurableProduct\Model\Product\Type\Configurable\Price as ConfigurablePrice; +use Magento\Framework\Event\ManagerInterface; +use Magento\Framework\Pricing\Amount\AmountInterface; +use Magento\Framework\Pricing\Price\PriceInterface; +use Magento\Framework\Pricing\PriceInfo\Base as PriceInfoBase; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; +use PHPUnit_Framework_MockObject_MockObject as MockObject; class PriceTest extends \PHPUnit\Framework\TestCase { - /** @var \Magento\ConfigurableProduct\Model\Product\Type\Configurable\Price */ + /** + * @var ObjectManagerHelper + */ + protected $objectManagerHelper; + + /** + * @var ConfigurablePrice + */ protected $model; - /** @var ObjectManagerHelper */ - protected $objectManagerHelper; + /** + * @var ManagerInterface|MockObject + */ + private $eventManagerMock; + /** + * @inheritdoc + */ protected function setUp() { $this->objectManagerHelper = new ObjectManagerHelper($this); + $this->eventManagerMock = $this->createPartialMock( + ManagerInterface::class, + ['dispatch'] + ); $this->model = $this->objectManagerHelper->getObject( - \Magento\ConfigurableProduct\Model\Product\Type\Configurable\Price::class + ConfigurablePrice::class, + ['eventManager' => $this->eventManagerMock] ); } @@ -29,29 +54,29 @@ public function testGetFinalPrice() { $finalPrice = 10; $qty = 1; - $configurableProduct = $this->getMockBuilder(\Magento\Catalog\Model\Product::class) - ->disableOriginalConstructor() - ->setMethods(['getCustomOption', 'getPriceInfo', 'setFinalPrice', '__wakeUp']) - ->getMock(); - $customOption = $this->getMockBuilder(\Magento\Catalog\Model\Product\Configuration\Item\Option::class) + + /** @var Product|MockObject $configurableProduct */ + $configurableProduct = $this->getMockBuilder(Product::class) ->disableOriginalConstructor() - ->setMethods(['getProduct']) + ->setMethods(['getCustomOption', 'getPriceInfo', 'setFinalPrice']) ->getMock(); - $priceInfo = $this->getMockBuilder(\Magento\Framework\Pricing\PriceInfo\Base::class) + /** @var PriceInfoBase|MockObject $priceInfo */ + $priceInfo = $this->getMockBuilder(PriceInfoBase::class) ->disableOriginalConstructor() ->setMethods(['getPrice']) ->getMock(); - $price = $this->getMockBuilder(\Magento\Framework\Pricing\Price\PriceInterface::class) + /** @var PriceInterface|MockObject $price */ + $price = $this->getMockBuilder(PriceInterface::class) ->disableOriginalConstructor() ->getMock(); - $amount = $this->getMockBuilder(\Magento\Framework\Pricing\Amount\AmountInterface::class) + /** @var AmountInterface|MockObject $amount */ + $amount = $this->getMockBuilder(AmountInterface::class) ->disableOriginalConstructor() ->getMock(); $configurableProduct->expects($this->any()) ->method('getCustomOption') ->willReturnMap([['simple_product', false], ['option_ids', false]]); - $customOption->expects($this->never())->method('getProduct'); $configurableProduct->expects($this->once())->method('getPriceInfo')->willReturn($priceInfo); $priceInfo->expects($this->once())->method('getPrice')->with('final_price')->willReturn($price); $price->expects($this->once())->method('getAmount')->willReturn($amount); @@ -60,4 +85,60 @@ public function testGetFinalPrice() $this->assertEquals($finalPrice, $this->model->getFinalPrice($qty, $configurableProduct)); } + + public function testGetFinalPriceWithSimpleProduct() + { + $finalPrice = 10; + $qty = 1; + $customerGroupId = 1; + + /** @var Product|MockObject $configurableProduct */ + $configurableProduct = $this->createPartialMock( + Product::class, + ['getCustomOption', 'setFinalPrice', 'getCustomerGroupId'] + ); + /** @var Option|MockObject $customOption */ + $customOption = $this->createPartialMock( + Option::class, + ['getProduct'] + ); + /** @var Product|MockObject $simpleProduct */ + $simpleProduct = $this->createPartialMock( + Product::class, + ['setCustomerGroupId', 'setFinalPrice', 'getPrice', 'getTierPrice', 'getData', 'getCustomOption'] + ); + + $configurableProduct->method('getCustomOption') + ->willReturnMap([ + ['simple_product', $customOption], + ['option_ids', false] + ]); + $configurableProduct->method('getCustomerGroupId')->willReturn($customerGroupId); + $configurableProduct->expects($this->atLeastOnce()) + ->method('setFinalPrice') + ->with($finalPrice) + ->willReturnSelf(); + $customOption->method('getProduct')->willReturn($simpleProduct); + $simpleProduct->expects($this->atLeastOnce()) + ->method('setCustomerGroupId') + ->with($customerGroupId) + ->willReturnSelf(); + $simpleProduct->method('getPrice')->willReturn($finalPrice); + $simpleProduct->method('getTierPrice')->with($qty)->willReturn($finalPrice); + $simpleProduct->expects($this->atLeastOnce()) + ->method('setFinalPrice') + ->with($finalPrice) + ->willReturnSelf(); + $simpleProduct->method('getData')->with('final_price')->willReturn($finalPrice); + $simpleProduct->method('getCustomOption')->with('option_ids')->willReturn(false); + $this->eventManagerMock->expects($this->once()) + ->method('dispatch') + ->with('catalog_product_get_final_price', ['product' => $simpleProduct, 'qty' => $qty]); + + $this->assertEquals( + $finalPrice, + $this->model->getFinalPrice($qty, $configurableProduct), + 'The final price calculation is wrong' + ); + } } From 6147df8f07634378d5232deee846443b17222137 Mon Sep 17 00:00:00 2001 From: Nikita Shcherbatykh <nikita.shcherbatykh@transoftgroup.com> Date: Thu, 28 Feb 2019 10:30:34 +0200 Subject: [PATCH 217/315] MAGETWO-97975: Shipping tax rounding issue --- app/code/Magento/SalesRule/Test/Unit/Model/ValidatorTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/SalesRule/Test/Unit/Model/ValidatorTest.php b/app/code/Magento/SalesRule/Test/Unit/Model/ValidatorTest.php index 5a4ce40c12288..a4b45813a10bc 100644 --- a/app/code/Magento/SalesRule/Test/Unit/Model/ValidatorTest.php +++ b/app/code/Magento/SalesRule/Test/Unit/Model/ValidatorTest.php @@ -478,7 +478,7 @@ public function testProcessShippingAmountProcessDisabled() * @param int $shippingDiscount * @dataProvider dataProviderActions */ - public function testProcessShippingAmountActions($action, $ruleDiscount, $shippingDiscount): void + public function testProcessShippingAmountActions($action, $ruleDiscount, $shippingDiscount) { $shippingAmount = 5; From 77391fca341d90c63a1d04e66bc7c4c434bd6a71 Mon Sep 17 00:00:00 2001 From: Viktor Sevch <svitja@ukr.net> Date: Thu, 28 Feb 2019 13:37:07 +0200 Subject: [PATCH 218/315] MAGETWO-92495: [Magento Cloud] - Wrong color image when filtering by color filter --- .../Unit/Block/Product/Renderer/Listing/ConfigurableTest.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/code/Magento/Swatches/Test/Unit/Block/Product/Renderer/Listing/ConfigurableTest.php b/app/code/Magento/Swatches/Test/Unit/Block/Product/Renderer/Listing/ConfigurableTest.php index fce0f6609ad73..a876a4dcc85c1 100644 --- a/app/code/Magento/Swatches/Test/Unit/Block/Product/Renderer/Listing/ConfigurableTest.php +++ b/app/code/Magento/Swatches/Test/Unit/Block/Product/Renderer/Listing/ConfigurableTest.php @@ -73,6 +73,9 @@ class ConfigurableTest extends \PHPUnit\Framework\TestCase /** @var \Magento\Customer\Model\Session|\PHPUnit_Framework_MockObject_MockObject */ private $customerSessionMock; + /** + * @inheritdoc + */ public function setUp() { $this->arrayUtils = $this->createMock(\Magento\Framework\Stdlib\ArrayUtils::class); From d49a58f3604a39937bc9da4ad9dfdabe08082b7f Mon Sep 17 00:00:00 2001 From: "rostyslav.hymon" <rostyslav.hymon@transoftgroup.com> Date: Thu, 28 Feb 2019 13:40:47 +0200 Subject: [PATCH 219/315] MAGETWO-97523: Quick Order does not show a correct link for configurable variations --- ...mple_products_not_visible_individually.php | 32 +++++++++++++++++++ ...ucts_not_visible_individually_rollback.php | 27 ++++++++++++++++ 2 files changed, 59 insertions(+) create mode 100644 dev/tests/integration/testsuite/Magento/Catalog/_files/simple_products_not_visible_individually.php create mode 100644 dev/tests/integration/testsuite/Magento/Catalog/_files/simple_products_not_visible_individually_rollback.php diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/simple_products_not_visible_individually.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/simple_products_not_visible_individually.php new file mode 100644 index 0000000000000..dfb8ce4d4741f --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/simple_products_not_visible_individually.php @@ -0,0 +1,32 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +/** @var $product \Magento\Catalog\Model\Product */ +$product = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(\Magento\Catalog\Model\Product::class); +$product->isObjectNew(true); +$product->setTypeId(\Magento\Catalog\Model\Product\Type::TYPE_SIMPLE) + ->setId(67) + ->setAttributeSetId(4) + ->setName('Simple Product Not visible 1') + ->setSku('simple_not_visible_1') + ->setTaxClassId('none') + ->setDescription('description') + ->setShortDescription('short description') + ->setOptionsContainer('container1') + ->setMsrpDisplayActualPriceType(\Magento\Msrp\Model\Product\Attribute\Source\Type::TYPE_IN_CART) + ->setPrice(10) + ->setWeight(1) + ->setMetaTitle('meta title product Not visible') + ->setMetaKeyword('meta keyword') + ->setMetaDescription('meta description') + ->setVisibility(\Magento\Catalog\Model\Product\Visibility::VISIBILITY_NOT_VISIBLE) + ->setStatus(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED) + ->setWebsiteIds([1]) + ->setCategoryIds([300]) + ->setStockData(['use_config_manage_stock' => 1, 'qty' => 30, 'is_qty_decimal' => 0, 'is_in_stock' => 1]) + ->setSpecialPrice('5.99') + ->save(); diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/simple_products_not_visible_individually_rollback.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/simple_products_not_visible_individually_rollback.php new file mode 100644 index 0000000000000..bbdcfd7acf081 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/simple_products_not_visible_individually_rollback.php @@ -0,0 +1,27 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +use Magento\Framework\Exception\NoSuchEntityException; + +\Magento\TestFramework\Helper\Bootstrap::getInstance()->getInstance()->reinitialize(); + +/** @var \Magento\Framework\Registry $registry */ +$registry = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(\Magento\Framework\Registry::class); + +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', true); + +/** @var \Magento\Catalog\Api\ProductRepositoryInterface $productRepository */ +$productRepository = \Magento\TestFramework\Helper\Bootstrap::getObjectManager() + ->get(\Magento\Catalog\Api\ProductRepositoryInterface::class); +try { + $product = $productRepository->get('simple_not_visible_1', false, null, true); + $productRepository->delete($product); +} catch (NoSuchEntityException $e) { +} +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', false); From 8493e59539df034b78b3424c37c3c87c927c724a Mon Sep 17 00:00:00 2001 From: Shikha Mishra <shikhamishra@cedcoss.com> Date: Tue, 19 Feb 2019 20:00:48 +0530 Subject: [PATCH 220/315] Fixed #15059 Cannot reorder from the first try --- app/code/Magento/Sales/Model/AdminOrder/Create.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Sales/Model/AdminOrder/Create.php b/app/code/Magento/Sales/Model/AdminOrder/Create.php index 12d2a5396ddc4..313cd1eadec8d 100644 --- a/app/code/Magento/Sales/Model/AdminOrder/Create.php +++ b/app/code/Magento/Sales/Model/AdminOrder/Create.php @@ -583,6 +583,7 @@ public function initFromOrder(\Magento\Sales\Model\Order $order) } $quote->getShippingAddress()->unsCachedItemsAll(); + $quote->getBillingAddress()->unsCachedItemsAll(); $quote->setTotalsCollectedFlag(false); $this->quoteRepository->save($quote); From 65e9346166084c859b0e1d58e8448aabc9f4bc49 Mon Sep 17 00:00:00 2001 From: nmalevanec <mikola.malevanec@transoftgroup.com> Date: Thu, 21 Feb 2019 10:49:29 +0200 Subject: [PATCH 221/315] Fix static tests. --- app/code/Magento/Sales/Model/AdminOrder/Create.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Sales/Model/AdminOrder/Create.php b/app/code/Magento/Sales/Model/AdminOrder/Create.php index 313cd1eadec8d..99393f77397c1 100644 --- a/app/code/Magento/Sales/Model/AdminOrder/Create.php +++ b/app/code/Magento/Sales/Model/AdminOrder/Create.php @@ -24,6 +24,7 @@ * @SuppressWarnings(PHPMD.TooManyFields) * @SuppressWarnings(PHPMD.ExcessiveClassComplexity) * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + * @SuppressWarnings(PHPMD.CookieAndSessionMisuse) * @since 100.0.2 */ class Create extends \Magento\Framework\DataObject implements \Magento\Checkout\Model\Cart\CartInterface From eaad776629a933b944663ef35c4bac08143d0592 Mon Sep 17 00:00:00 2001 From: Jitheesh <jitheeshvo@gmail.com> Date: Fri, 22 Feb 2019 10:01:45 +0530 Subject: [PATCH 222/315] As low as displays incorrect pricing on category page, tax appears to be added twice #21383 - excluded tax from min price --- .../Catalog/Pricing/Price/MinimalTierPriceCalculator.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Pricing/Price/MinimalTierPriceCalculator.php b/app/code/Magento/Catalog/Pricing/Price/MinimalTierPriceCalculator.php index 387ef9416ef68..af81e67e86fce 100644 --- a/app/code/Magento/Catalog/Pricing/Price/MinimalTierPriceCalculator.php +++ b/app/code/Magento/Catalog/Pricing/Price/MinimalTierPriceCalculator.php @@ -58,6 +58,6 @@ public function getAmount(SaleableInterface $saleableItem) return $value === null ? null - : $this->calculator->getAmount($value, $saleableItem); + : $this->calculator->getAmount($value, $saleableItem, 'tax'); } } From aa7fee51fb66d75800c7c454da013b75d565ebe4 Mon Sep 17 00:00:00 2001 From: nmalevanec <mikola.malevanec@transoftgroup.com> Date: Tue, 26 Feb 2019 11:57:48 +0200 Subject: [PATCH 223/315] Fix static tests. --- .../Pricing/Price/MinimalTierPriceCalculator.php | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Catalog/Pricing/Price/MinimalTierPriceCalculator.php b/app/code/Magento/Catalog/Pricing/Price/MinimalTierPriceCalculator.php index af81e67e86fce..a5e573caa381e 100644 --- a/app/code/Magento/Catalog/Pricing/Price/MinimalTierPriceCalculator.php +++ b/app/code/Magento/Catalog/Pricing/Price/MinimalTierPriceCalculator.php @@ -29,8 +29,10 @@ public function __construct(CalculatorInterface $calculator) } /** - * Get raw value of "as low as" as a minimal among tier prices - * {@inheritdoc} + * Get raw value of "as low as" as a minimal among tier prices{@inheritdoc} + * + * @param SaleableInterface $saleableItem + * @return float|null */ public function getValue(SaleableInterface $saleableItem) { @@ -49,8 +51,10 @@ public function getValue(SaleableInterface $saleableItem) } /** - * Return calculated amount object that keeps "as low as" value - * {@inheritdoc} + * Return calculated amount object that keeps "as low as" value{@inheritdoc} + * + * @param SaleableInterface $saleableItem + * @return AmountInterface|null */ public function getAmount(SaleableInterface $saleableItem) { From 7bb5dd47e92e4d20da612e62bae7822de48d1bee Mon Sep 17 00:00:00 2001 From: Wojtek Naruniec <wojtek@mediotype.com> Date: Mon, 18 Feb 2019 13:16:20 +0100 Subject: [PATCH 224/315] Skip cart validation if empty cart action is executed --- .../view/frontend/web/js/action/update-shopping-cart.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/code/Magento/Checkout/view/frontend/web/js/action/update-shopping-cart.js b/app/code/Magento/Checkout/view/frontend/web/js/action/update-shopping-cart.js index ce1527b3d72d6..9d79e34b10f17 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/action/update-shopping-cart.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/action/update-shopping-cart.js @@ -35,6 +35,11 @@ define([ return true; } + var action = this.element.find('#update_cart_action_container').val(); + if (action === 'empty_cart') { + return true; + } + if (this.isValid()) { event.preventDefault(); this.validateItems(this.options.validationURL, this.element.serialize()); From 847115efd5068b40a4d274702d6086f0d6549adc Mon Sep 17 00:00:00 2001 From: Wojtek Naruniec <wojtek@mediotype.com> Date: Fri, 22 Feb 2019 10:17:42 +0100 Subject: [PATCH 225/315] Move element id to component parameters, fix JS coding style --- .../Checkout/view/frontend/templates/cart/form.phtml | 3 ++- .../view/frontend/web/js/action/update-shopping-cart.js | 6 ++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Checkout/view/frontend/templates/cart/form.phtml b/app/code/Magento/Checkout/view/frontend/templates/cart/form.phtml index 1005c11e44d95..84ab9b13d8f3a 100644 --- a/app/code/Magento/Checkout/view/frontend/templates/cart/form.phtml +++ b/app/code/Magento/Checkout/view/frontend/templates/cart/form.phtml @@ -14,7 +14,8 @@ method="post" id="form-validate" data-mage-init='{"Magento_Checkout/js/action/update-shopping-cart": - {"validationURL" : "/checkout/cart/updateItemQty"} + {"validationURL" : "/checkout/cart/updateItemQty", + "updateCartActionContainer": "#update_cart_action_container"} }' class="form form-cart"> <?= $block->getBlockHtml('formkey') ?> diff --git a/app/code/Magento/Checkout/view/frontend/web/js/action/update-shopping-cart.js b/app/code/Magento/Checkout/view/frontend/web/js/action/update-shopping-cart.js index 9d79e34b10f17..7686dcad6e050 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/action/update-shopping-cart.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/action/update-shopping-cart.js @@ -14,7 +14,8 @@ define([ $.widget('mage.updateShoppingCart', { options: { validationURL: '', - eventName: 'updateCartItemQty' + eventName: 'updateCartItemQty', + updateCartActionContainer: '' }, /** @inheritdoc */ @@ -31,11 +32,12 @@ define([ * @return {Boolean} */ onSubmit: function (event) { + var action = this.element.find(this.options.updateCartActionContainer).val(); + if (!this.options.validationURL) { return true; } - var action = this.element.find('#update_cart_action_container').val(); if (action === 'empty_cart') { return true; } From 42b03bb7cd92320bb6b689b82101ac4eb91b1b93 Mon Sep 17 00:00:00 2001 From: Oleksandr Kravchuk <swnsma@gmail.com> Date: Fri, 22 Feb 2019 13:46:04 +0200 Subject: [PATCH 226/315] Simplify. --- .../view/frontend/web/js/action/update-shopping-cart.js | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/app/code/Magento/Checkout/view/frontend/web/js/action/update-shopping-cart.js b/app/code/Magento/Checkout/view/frontend/web/js/action/update-shopping-cart.js index 7686dcad6e050..1920bc4d7ac41 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/action/update-shopping-cart.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/action/update-shopping-cart.js @@ -34,11 +34,7 @@ define([ onSubmit: function (event) { var action = this.element.find(this.options.updateCartActionContainer).val(); - if (!this.options.validationURL) { - return true; - } - - if (action === 'empty_cart') { + if (!this.options.validationURL || action === 'empty_cart') { return true; } From 13c6edd690905c704cb69ff245d5ce7faff0aefe Mon Sep 17 00:00:00 2001 From: Ilan Parmentier <ilan.parmentier@artbambou.com> Date: Thu, 31 Jan 2019 14:44:29 +0100 Subject: [PATCH 227/315] Update details.phtml Good afternoon, I just encountered a problem with product's tabs in product info. I realized when description or other custom tabs have links, when you click on it, nothing happen. It caused by the script mage/tabs.js in details.phtml. The current link to trigger the tab is declared with data-role="switch" instead of a data-role="trigger". https://github.com/magento/magento2/blob/4f232511ceba6f1f7bf6f73b3b5609bd087f8c74/app/code/Magento/Catalog/view/frontend/templates/product/view/details.phtml#L24-L37 When not even the trigger and the header is declared respectively by data-role="heading" and data-role="trigger", the script based it search on the current collapsible panel declared by data-role="collapsible". https://github.com/magento/magento2/blob/4f232511ceba6f1f7bf6f73b3b5609bd087f8c74/lib/web/mage/tabs.js#L99-L124 You can simply try by adding a link in the product description. Tell me if I am wrong. Cheers, Ilan PARMENTIER --- .../Catalog/view/frontend/templates/product/view/details.phtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/view/frontend/templates/product/view/details.phtml b/app/code/Magento/Catalog/view/frontend/templates/product/view/details.phtml index 038bea86e7d4e..bbbc950e6712e 100644 --- a/app/code/Magento/Catalog/view/frontend/templates/product/view/details.phtml +++ b/app/code/Magento/Catalog/view/frontend/templates/product/view/details.phtml @@ -25,7 +25,7 @@ data-role="collapsible" id="tab-label-<?= /* @escapeNotVerified */ $alias ?>"> <a class="data switch" tabindex="-1" - data-toggle="switch" + data-toggle="trigger" href="#<?= /* @escapeNotVerified */ $alias ?>" id="tab-label-<?= /* @escapeNotVerified */ $alias ?>-title"> <?= /* @escapeNotVerified */ $label ?> From e5676cfb72590fff072c8dfff931740587ff2213 Mon Sep 17 00:00:00 2001 From: Ilan Parmentier <ilan.parmentier@artbambou.com> Date: Mon, 18 Feb 2019 15:37:52 +0100 Subject: [PATCH 228/315] Misconfigured aria-labelledby for product tabs Good afternoon, I find out attribute aria-labelledby is misconfigured. It must be declared for the content of the tab and not the title, in particular, for a parent tag. Ilan PARMENTIER Source : https://www.w3.org/TR/wai-aria-practices/examples/tabs/tabs-1/tabs.html#sc1_label --- .../view/frontend/templates/product/view/details.phtml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Catalog/view/frontend/templates/product/view/details.phtml b/app/code/Magento/Catalog/view/frontend/templates/product/view/details.phtml index 038bea86e7d4e..19a058006b18c 100644 --- a/app/code/Magento/Catalog/view/frontend/templates/product/view/details.phtml +++ b/app/code/Magento/Catalog/view/frontend/templates/product/view/details.phtml @@ -21,7 +21,6 @@ $label = $block->getChildData($alias, 'title'); ?> <div class="data item title" - aria-labelledby="tab-label-<?= /* @escapeNotVerified */ $alias ?>-title" data-role="collapsible" id="tab-label-<?= /* @escapeNotVerified */ $alias ?>"> <a class="data switch" tabindex="-1" @@ -31,7 +30,8 @@ <?= /* @escapeNotVerified */ $label ?> </a> </div> - <div class="data item content" id="<?= /* @escapeNotVerified */ $alias ?>" data-role="content"> + <div class="data item content" + aria-labelledby="tab-label-<?= /* @escapeNotVerified */ $alias ?>-title" id="<?= /* @escapeNotVerified */ $alias ?>" data-role="content"> <?= /* @escapeNotVerified */ $html ?> </div> <?php endforeach;?> From 342afb26a16ea02b5a09d8e6a1de077a7ea09004 Mon Sep 17 00:00:00 2001 From: Dominic <d.fernando@ism-apac.com> Date: Sun, 10 Feb 2019 11:12:20 +0530 Subject: [PATCH 229/315] fixed-pagination-issue-admin-review-grid --- lib/web/mage/adminhtml/grid.js | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/lib/web/mage/adminhtml/grid.js b/lib/web/mage/adminhtml/grid.js index c9af869d79161..b16b2c9defce0 100644 --- a/lib/web/mage/adminhtml/grid.js +++ b/lib/web/mage/adminhtml/grid.js @@ -531,12 +531,19 @@ define([ /** * @param {Object} event */ - inputPage: function (event) { + inputPage: function (event, lastId) { var element = Event.element(event), - keyCode = event.keyCode || event.which; + keyCode = event.keyCode || event.which, + enteredValue = parseInt(element.value), + lastId = parseInt(lastId); + if (keyCode == Event.KEY_RETURN) { //eslint-disable-line eqeqeq - this.setPage(element.value); + if (enteredValue > lastId) { + this.setPage(lastId); + } else { + this.setPage(element.value); + } } /*if(keyCode>47 && keyCode<58){ From 36ebc6542767c48c6f939e1fe1fe0f0faf2949f2 Mon Sep 17 00:00:00 2001 From: Dominic <d.fernando@ism-apac.com> Date: Sun, 10 Feb 2019 11:27:50 +0530 Subject: [PATCH 230/315] fixed-pagination-issue-admin-review-grid --- lib/web/mage/adminhtml/grid.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/web/mage/adminhtml/grid.js b/lib/web/mage/adminhtml/grid.js index b16b2c9defce0..b7e696ae8f4bd 100644 --- a/lib/web/mage/adminhtml/grid.js +++ b/lib/web/mage/adminhtml/grid.js @@ -530,6 +530,7 @@ define([ /** * @param {Object} event + * @param int lastId */ inputPage: function (event, lastId) { var element = Event.element(event), From 5392ee7a7d7d10dd61d5c712d9a23304830445e9 Mon Sep 17 00:00:00 2001 From: Dominic <d.fernando@ism-apac.com> Date: Sun, 10 Feb 2019 11:31:49 +0530 Subject: [PATCH 231/315] fixed-pagination-issue-admin-review-grid-clean-code --- lib/web/mage/adminhtml/grid.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/web/mage/adminhtml/grid.js b/lib/web/mage/adminhtml/grid.js index b7e696ae8f4bd..e27dd9c2a0d26 100644 --- a/lib/web/mage/adminhtml/grid.js +++ b/lib/web/mage/adminhtml/grid.js @@ -538,12 +538,11 @@ define([ enteredValue = parseInt(element.value), lastId = parseInt(lastId); - if (keyCode == Event.KEY_RETURN) { //eslint-disable-line eqeqeq if (enteredValue > lastId) { this.setPage(lastId); } else { - this.setPage(element.value); + this.setPage(enteredValue); } } From 73b57d441f2a5494098c112482fe9316d802fb99 Mon Sep 17 00:00:00 2001 From: nmalevanec <mikola.malevanec@transoftgroup.com> Date: Mon, 25 Feb 2019 16:00:48 +0200 Subject: [PATCH 232/315] Fix static tests. --- lib/web/mage/adminhtml/grid.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/web/mage/adminhtml/grid.js b/lib/web/mage/adminhtml/grid.js index e27dd9c2a0d26..5f7a709f04fea 100644 --- a/lib/web/mage/adminhtml/grid.js +++ b/lib/web/mage/adminhtml/grid.js @@ -530,17 +530,17 @@ define([ /** * @param {Object} event - * @param int lastId + * @param {*} lastId */ inputPage: function (event, lastId) { var element = Event.element(event), keyCode = event.keyCode || event.which, - enteredValue = parseInt(element.value), - lastId = parseInt(lastId); + enteredValue = parseInt(element.value, 10), + pageId = parseInt(lastId, 10); if (keyCode == Event.KEY_RETURN) { //eslint-disable-line eqeqeq - if (enteredValue > lastId) { - this.setPage(lastId); + if (enteredValue > pageId) { + this.setPage(pageId); } else { this.setPage(enteredValue); } From d504aa1ca7f42156d0ca3f08a4f3905b40df8066 Mon Sep 17 00:00:00 2001 From: mageprince <mail.mageprince@gmail.com> Date: Fri, 1 Mar 2019 14:57:52 +0530 Subject: [PATCH 233/315] 2.2-develop-backport-21401 --- app/code/Magento/Checkout/Controller/Cart/Addgroup.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/code/Magento/Checkout/Controller/Cart/Addgroup.php b/app/code/Magento/Checkout/Controller/Cart/Addgroup.php index 8654bdbde5893..1876d3ca37d94 100644 --- a/app/code/Magento/Checkout/Controller/Cart/Addgroup.php +++ b/app/code/Magento/Checkout/Controller/Cart/Addgroup.php @@ -41,6 +41,8 @@ public function execute() } } $this->cart->save(); + } else { + $this->messageManager->addErrorMessage(__('Please select at least one product to add to cart')); } return $this->_goBack(); } From e9e306a6b57f738db813835e459209dcdf1e9381 Mon Sep 17 00:00:00 2001 From: Mastiuhin Olexandr <mastiuhin.olexandr@transoftgroup.com> Date: Fri, 1 Mar 2019 16:19:08 +0200 Subject: [PATCH 234/315] MAGETWO-97271: Configurable product can be added as a variation to another Configurable product in the admin --- .../Unit/Ui/Component/ColumnFactoryTest.php | 156 ++++++++++++++++++ .../Catalog/Ui/Component/ColumnFactory.php | 6 +- .../Modifier/Data/AssociatedProductsTest.php | 64 ++++++- 3 files changed, 224 insertions(+), 2 deletions(-) create mode 100644 app/code/Magento/Catalog/Test/Unit/Ui/Component/ColumnFactoryTest.php diff --git a/app/code/Magento/Catalog/Test/Unit/Ui/Component/ColumnFactoryTest.php b/app/code/Magento/Catalog/Test/Unit/Ui/Component/ColumnFactoryTest.php new file mode 100644 index 0000000000000..c4a7aa4037bec --- /dev/null +++ b/app/code/Magento/Catalog/Test/Unit/Ui/Component/ColumnFactoryTest.php @@ -0,0 +1,156 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Catalog\Test\Unit\Ui\Component; + +use PHPUnit\Framework\TestCase; +use Magento\Catalog\Ui\Component\ColumnFactory; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; +use Magento\Catalog\Api\Data\ProductAttributeInterface; +use Magento\Framework\View\Element\UiComponent\ContextInterface; +use Magento\Framework\View\Element\UiComponentFactory; +use Magento\Ui\Component\Listing\Columns\ColumnInterface; +use Magento\Ui\Component\Filters\FilterModifier; + +/** + * ColumnFactory test. + */ +class ColumnFactoryTest extends TestCase +{ + /** + * @var ColumnFactory + */ + private $columnFactory; + + /** + * @var ObjectManager + */ + private $objectManager; + + /** + * @var ProductAttributeInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $attribute; + + /** + * @var ContextInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $context; + + /** + * @var UiComponentFactory|\PHPUnit_Framework_MockObject_MockObject + */ + private $uiComponentFactory; + + /** + * @var ColumnInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $column; + + /** + * @inheritdoc + */ + protected function setUp() + { + $this->objectManager = new ObjectManager($this); + + $this->attribute = $this->getMockBuilder(ProductAttributeInterface::class) + ->setMethods(['usesSource']) + ->getMockForAbstractClass(); + $this->context = $this->createMock(ContextInterface::class); + $this->uiComponentFactory = $this->createMock(UiComponentFactory::class); + $this->column = $this->getMockForAbstractClass(ColumnInterface::class); + $this->uiComponentFactory->method('create') + ->willReturn($this->column); + + $this->columnFactory = $this->objectManager->getObject(ColumnFactory::class, [ + 'componentFactory' => $this->uiComponentFactory + ]); + } + + /** + * Tests the create method will return correct object. + * + * @return void + */ + public function testCreatedObject() + { + $this->context->method('getRequestParam') + ->with(FilterModifier::FILTER_MODIFIER, []) + ->willReturn([]); + + $object = $this->columnFactory->create($this->attribute, $this->context); + $this->assertEquals( + $this->column, + $object, + 'Object must be the same which the ui component factory creates.' + ); + } + + /** + * Tests create method with not filterable in grid attribute. + * + * @param array $filterModifiers + * @param null|string $filter + * + * @return void + * @dataProvider filterModifiersProvider + */ + public function testCreateWithNotFilterableInGridAttribute(array $filterModifiers, $filter) + { + $componentFactoryArgument = [ + 'data' => [ + 'config' => [ + 'label' => __(null), + 'dataType' => 'text', + 'add_field' => true, + 'visible' => null, + 'filter' => $filter, + 'component' => 'Magento_Ui/js/grid/columns/column', + ], + ], + 'context' => $this->context, + ]; + + $this->context->method('getRequestParam') + ->with(FilterModifier::FILTER_MODIFIER, []) + ->willReturn($filterModifiers); + $this->attribute->method('getIsFilterableInGrid') + ->willReturn(false); + $this->attribute->method('getAttributeCode') + ->willReturn('color'); + + $this->uiComponentFactory->expects($this->once()) + ->method('create') + ->with($this->anything(), $this->anything(), $componentFactoryArgument); + + $this->columnFactory->create($this->attribute, $this->context); + } + + /** + * Filter modifiers data provider. + * + * @return array + */ + public function filterModifiersProvider(): array + { + return [ + 'without' => [ + 'filter_modifiers' => [], + 'filter' => null, + ], + 'with' => [ + 'filter_modifiers' => [ + 'color' => [ + 'condition_type' => 'notnull', + ], + ], + 'filter' => 'text', + ], + ]; + } +} diff --git a/app/code/Magento/Catalog/Ui/Component/ColumnFactory.php b/app/code/Magento/Catalog/Ui/Component/ColumnFactory.php index cbc67fee8a5a3..40687e37e1538 100644 --- a/app/code/Magento/Catalog/Ui/Component/ColumnFactory.php +++ b/app/code/Magento/Catalog/Ui/Component/ColumnFactory.php @@ -5,6 +5,8 @@ */ namespace Magento\Catalog\Ui\Component; +use Magento\Ui\Component\Filters\FilterModifier; + /** * @api * @since 100.0.2 @@ -54,13 +56,15 @@ public function __construct(\Magento\Framework\View\Element\UiComponentFactory $ */ public function create($attribute, $context, array $config = []) { + $filterModifiers = $context->getRequestParam(FilterModifier::FILTER_MODIFIER, []); + $columnName = $attribute->getAttributeCode(); $config = array_merge([ 'label' => __($attribute->getDefaultFrontendLabel()), 'dataType' => $this->getDataType($attribute), 'add_field' => true, 'visible' => $attribute->getIsVisibleInGrid(), - 'filter' => ($attribute->getIsFilterableInGrid()) + 'filter' => ($attribute->getIsFilterableInGrid() || array_key_exists($columnName, $filterModifiers)) ? $this->getFilterType($attribute->getFrontendInput()) : null, ], $config); diff --git a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Ui/DataProvider/Product/Form/Modifier/Data/AssociatedProductsTest.php b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Ui/DataProvider/Product/Form/Modifier/Data/AssociatedProductsTest.php index 234f0aae6a3ea..63858e91b64f2 100644 --- a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Ui/DataProvider/Product/Form/Modifier/Data/AssociatedProductsTest.php +++ b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Ui/DataProvider/Product/Form/Modifier/Data/AssociatedProductsTest.php @@ -5,7 +5,19 @@ */ namespace Magento\ConfigurableProduct\Ui\DataProvider\Product\Form\Modifier\Data; -class AssociatedProductsTest extends \PHPUnit\Framework\TestCase +use Magento\Framework\View\Element\UiComponentFactory; +use Magento\Ui\Component\Filters\FilterModifier; +use Magento\Framework\View\Element\UiComponent\ContextInterface; +use Magento\ConfigurableProduct\Ui\DataProvider\Product\Form\Modifier\ConfigurablePanel; +use Magento\Framework\App\RequestInterface; +use PHPUnit\Framework\TestCase; + +/** + * AssociatedProductsTest + * + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + */ +class AssociatedProductsTest extends TestCase { /** * @var \Magento\Framework\ObjectManagerInterface $objectManager @@ -17,6 +29,9 @@ class AssociatedProductsTest extends \PHPUnit\Framework\TestCase */ private $registry; + /** + * @inheritdoc + */ public function setUp() { $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); @@ -64,6 +79,53 @@ public function testGetProductMatrix($interfaceLocale) } } + /** + * Tests configurable product won't appear in product listing. + * + * Tests configurable product won't appear in configurable associated product listing if its options attribute + * is not filterable in grid. + * + * @return void + * @magentoDataFixture Magento/ConfigurableProduct/_files/product_configurable.php + * @magentoAppArea adminhtml + */ + public function testAddManuallyConfigurationsWithNotFilterableInGridAttribute() + { + /** @var RequestInterface $request */ + $request = $this->objectManager->get(RequestInterface::class); + $request->setParams([ + FilterModifier::FILTER_MODIFIER => [ + 'test_configurable' => [ + 'condition_type' => 'notnull', + ], + ], + 'attributes_codes' => [ + 'test_configurable' + ], + ]); + $context = $this->objectManager->create(ContextInterface::class, ['request' => $request]); + /** @var UiComponentFactory $uiComponentFactory */ + $uiComponentFactory = $this->objectManager->get(UiComponentFactory::class); + $uiComponent = $uiComponentFactory->create( + ConfigurablePanel::ASSOCIATED_PRODUCT_LISTING, + null, + ['context' => $context] + ); + + foreach ($uiComponent->getChildComponents() as $childUiComponent) { + $childUiComponent->prepare(); + } + + $dataSource = $uiComponent->getDataSourceData(); + $skus = array_column($dataSource['data']['items'], 'sku'); + + $this->assertNotContains( + 'configurable', + $skus, + 'Only products with specified attribute should be in product list' + ); + } + /** * @return array */ From 9f0ef596df5e7e97d4057e4a84eaf18f08cbb5e0 Mon Sep 17 00:00:00 2001 From: Maksym Novik <m.novik@ism-ukraine.com> Date: Fri, 1 Mar 2019 17:02:10 +0200 Subject: [PATCH 235/315] Static tests: forbid 'or' instead of '||' #21062. Added Squiz.Operators.ValidLogicalOperators rule --- dev/tests/static/framework/Magento/ruleset.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/dev/tests/static/framework/Magento/ruleset.xml b/dev/tests/static/framework/Magento/ruleset.xml index 56a5a9e55c30e..fac0842214d92 100644 --- a/dev/tests/static/framework/Magento/ruleset.xml +++ b/dev/tests/static/framework/Magento/ruleset.xml @@ -25,5 +25,6 @@ <rule ref="Squiz.Commenting.DocCommentAlignment"/> <rule ref="Squiz.Functions.GlobalFunction"/> + <rule ref="Squiz.Operators.ValidLogicalOperators"/> <rule ref="Squiz.WhiteSpace.LogicalOperatorSpacing"/> </ruleset> From 42d7504d1def753cf8bedfdac9b1b4a7d165aab8 Mon Sep 17 00:00:00 2001 From: Viktor Petryk <victor.petryk@transoftgroup.com> Date: Mon, 4 Mar 2019 10:11:49 +0200 Subject: [PATCH 236/315] MAGETWO-94190: [Magento Cloud] Error when saving Bundle product --- .../Unit/Model/Product/SaveHandlerTest.php | 275 ++++++++++++++++++ 1 file changed, 275 insertions(+) create mode 100644 app/code/Magento/Bundle/Test/Unit/Model/Product/SaveHandlerTest.php diff --git a/app/code/Magento/Bundle/Test/Unit/Model/Product/SaveHandlerTest.php b/app/code/Magento/Bundle/Test/Unit/Model/Product/SaveHandlerTest.php new file mode 100644 index 0000000000000..94e5b72b10e3c --- /dev/null +++ b/app/code/Magento/Bundle/Test/Unit/Model/Product/SaveHandlerTest.php @@ -0,0 +1,275 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Bundle\Test\Unit\Model\Product; + +use Magento\Bundle\Api\Data\LinkInterface; +use Magento\Bundle\Api\Data\OptionInterface; +use Magento\Bundle\Api\ProductLinkManagementInterface; +use Magento\Bundle\Api\ProductOptionRepositoryInterface; +use Magento\Bundle\Model\Product\SaveHandler; +use Magento\Catalog\Api\Data\ProductExtensionInterface; +use Magento\Catalog\Api\Data\ProductInterface; +use Magento\Framework\EntityManager\EntityMetadataInterface; +use Magento\Framework\EntityManager\MetadataPool; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; +use PHPUnit_Framework_MockObject_MockObject as MockObject; + +class SaveHandlerTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var ObjectManager + */ + private $objectManager; + /** + * @var ProductInterface|MockObject + */ + private $productMock; + + /** + * @var ProductExtensionInterface|MockObject + */ + private $productExtensionMock; + + /** + * @var OptionInterface|MockObject + */ + private $optionMock; + + /** + * @var ProductOptionRepositoryInterface|MockObject + */ + private $optionRepositoryMock; + + /** + * @var ProductLinkManagementInterface|MockObject + */ + private $productLinkManagementMock; + + /** + * @var LinkInterface|MockObject + */ + private $linkMock; + + /** + * @var MetadataPool|MockObject + */ + private $metadataPoolMock; + + /** + * @var EntityMetadataInterface|MockObject + */ + private $metadataMock; + + /** + * @var SaveHandler + */ + private $saveHandler; + + /** + * @inheritdoc + */ + protected function setUp() + { + $this->objectManager = new ObjectManager($this); + + $this->productMock = $this->getMockBuilder(ProductInterface::class) + ->setMethods( + [ + 'getExtensionAttributes', + 'getCopyFromView', + 'getData', + 'getTypeId', + 'getSku', + ] + ) + ->getMockForAbstractClass(); + $this->productExtensionMock = $this->getMockBuilder(ProductExtensionInterface::class) + ->setMethods(['getBundleProductOptions']) + ->getMockForAbstractClass(); + $this->optionMock = $this->getMockBuilder(OptionInterface::class) + ->setMethods( + [ + 'setParentId', + 'getId', + 'getOptionId', + ] + ) + ->getMockForAbstractClass(); + $this->optionRepositoryMock = $this->createMock(ProductOptionRepositoryInterface::class); + $this->productLinkManagementMock = $this->createMock(ProductLinkManagementInterface::class); + $this->linkMock = $this->createMock(LinkInterface::class); + $this->metadataPoolMock = $this->createMock(MetadataPool::class); + $this->metadataMock = $this->createMock(EntityMetadataInterface::class); + $this->metadataPoolMock->expects($this->any()) + ->method('getMetadata') + ->willReturn($this->metadataMock); + + $this->saveHandler = $this->objectManager->getObject( + SaveHandler::class, + [ + 'optionRepository' => $this->optionRepositoryMock, + 'productLinkManagement' => $this->productLinkManagementMock, + 'metadataPool' => $this->metadataPoolMock, + ] + ); + } + + /** + * @return void + */ + public function testExecuteWithInvalidProductType() + { + $productType = 'simple'; + + $this->productMock->expects($this->once()) + ->method('getExtensionAttributes') + ->willReturn($this->productExtensionMock); + $this->productExtensionMock->expects($this->once()) + ->method('getBundleProductOptions') + ->willReturn([]); + $this->productMock->expects($this->once()) + ->method('getTypeId') + ->willReturn($productType); + + $entity = $this->saveHandler->execute($this->productMock); + $this->assertSame($this->productMock, $entity); + } + + /** + * @return void + */ + public function testExecuteWithoutExistingOption() + { + $productType = 'bundle'; + $productSku = 'product-sku'; + $optionId = ''; + + $this->productMock->expects($this->once()) + ->method('getExtensionAttributes') + ->willReturn($this->productExtensionMock); + $this->productExtensionMock->expects($this->once()) + ->method('getBundleProductOptions') + ->willReturn([$this->optionMock]); + + $this->productMock->expects($this->once()) + ->method('getTypeId') + ->willReturn($productType); + + $this->productMock->expects($this->once()) + ->method('getSku') + ->willReturn($productSku); + $this->optionRepositoryMock->expects($this->once()) + ->method('getList') + ->with($productSku) + ->willReturn([]); + + $this->optionMock->expects($this->any()) + ->method('getOptionId') + ->willReturn($optionId); + + $this->productMock->expects($this->once()) + ->method('getCopyFromView') + ->willReturn(false); + + $this->optionMock->expects($this->never())->method('setOptionId'); + $this->optionRepositoryMock->expects($this->once()) + ->method('save') + ->with($this->productMock, $this->optionMock) + ->willReturn($optionId); + + $this->saveHandler->execute($this->productMock); + } + + /** + * @return void + */ + public function testExecuteWithExistingOption() + { + $productType = 'bundle'; + $productSku = 'product-sku'; + $productLinkSku = 'product-link-sku'; + $linkField = 'entity_id'; + $parentId = 1; + $existingOptionId = 1; + $optionId = 2; + + /** @var OptionInterface|MockObject $existingOptionMock */ + $existingOptionMock = $this->getMockBuilder(OptionInterface::class) + ->setMethods(['getOptionId']) + ->getMockForAbstractClass(); + + $this->productMock->expects($this->once()) + ->method('getExtensionAttributes') + ->willReturn($this->productExtensionMock); + $this->productExtensionMock->expects($this->once()) + ->method('getBundleProductOptions') + ->willReturn([$this->optionMock]); + $this->productMock->expects($this->once()) + ->method('getTypeId') + ->willReturn($productType); + + $this->productMock->expects($this->exactly(3)) + ->method('getSku') + ->willReturn($productSku); + $this->optionRepositoryMock->expects($this->once()) + ->method('getList') + ->with($productSku) + ->willReturn([$existingOptionMock]); + + $existingOptionMock->expects($this->any()) + ->method('getOptionId') + ->willReturn($existingOptionId); + $this->optionMock->expects($this->any()) + ->method('getOptionId') + ->willReturn($optionId); + + $this->productMock->expects($this->once()) + ->method('getCopyFromView') + ->willReturn(false); + $this->metadataMock->expects($this->once()) + ->method('getLinkField') + ->willReturn($linkField); + $this->productMock->expects($this->once()) + ->method('getData') + ->with($linkField) + ->willReturn($parentId); + + $this->optionRepositoryMock->expects($this->once()) + ->method('get') + ->with($productSku, $existingOptionId) + ->willReturn($this->optionMock); + $this->optionMock->expects($this->once()) + ->method('setParentId') + ->with($parentId) + ->willReturnSelf(); + $this->optionMock->expects($this->once()) + ->method('getProductLinks') + ->willReturn([$this->linkMock]); + $this->linkMock->expects($this->once()) + ->method('getSku') + ->willReturn($productLinkSku); + + $this->optionMock->expects($this->any()) + ->method('getId') + ->willReturn($existingOptionId); + $this->productLinkManagementMock->expects($this->once()) + ->method('removeChild') + ->with($productSku, $existingOptionId, $productLinkSku) + ->willReturn(true); + $this->optionRepositoryMock->expects($this->once()) + ->method('delete') + ->with($this->optionMock) + ->willReturn(true); + + $this->optionRepositoryMock->expects($this->once()) + ->method('save') + ->with($this->productMock, $this->optionMock) + ->willReturn($optionId); + + $this->saveHandler->execute($this->productMock); + } +} From 79429edd3f660bac9c26e09afab5abefe6c8a178 Mon Sep 17 00:00:00 2001 From: nmalevanec <mikola.malevanec@transoftgroup.com> Date: Mon, 4 Mar 2019 10:31:10 +0200 Subject: [PATCH 237/315] Fix functional tests. --- app/code/Magento/Customer/Test/Mftf/Data/CustomerData.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Customer/Test/Mftf/Data/CustomerData.xml b/app/code/Magento/Customer/Test/Mftf/Data/CustomerData.xml index c4b1c14d09890..078d210d9cb61 100644 --- a/app/code/Magento/Customer/Test/Mftf/Data/CustomerData.xml +++ b/app/code/Magento/Customer/Test/Mftf/Data/CustomerData.xml @@ -21,7 +21,7 @@ <data key="firstname">John</data> <data key="lastname">Doe</data> <data key="middlename">S</data> - <data key="fullname">John Doe</data>s + <data key="fullname">John Doe</data> <data key="password">pwdTest123!</data> <data key="prefix">Mr</data> <data key="suffix">Sr</data> From d8110c23e4f66ce819b4be90b12a1e4eb190b178 Mon Sep 17 00:00:00 2001 From: Pavel Bystritsky <p.bystritsky@yandex.ru> Date: Mon, 4 Mar 2019 16:50:27 +0200 Subject: [PATCH 238/315] ENGCOM-4000: Crash fix. --- .../Model/Condition/Product/AbstractProduct.php | 8 -------- .../Block/Product/ProductListTest.php | 15 --------------- 2 files changed, 23 deletions(-) diff --git a/app/code/Magento/Rule/Model/Condition/Product/AbstractProduct.php b/app/code/Magento/Rule/Model/Condition/Product/AbstractProduct.php index bedac8c1108e5..a428794b41a0f 100644 --- a/app/code/Magento/Rule/Model/Condition/Product/AbstractProduct.php +++ b/app/code/Magento/Rule/Model/Condition/Product/AbstractProduct.php @@ -137,7 +137,6 @@ public function getDefaultOperatorInputByType() */ $this->_defaultOperatorInputByType['category'] = ['==', '!=', '{}', '!{}', '()', '!()']; $this->_arrayInputTypes[] = 'category'; - $this->_defaultOperatorInputByType['sku'] = ['==', '!=', '{}', '!{}', '()', '!()']; } return $this->_defaultOperatorInputByType; } @@ -383,9 +382,6 @@ public function getInputType() if ($this->getAttributeObject()->getAttributeCode() == 'category_ids') { return 'category'; } - if ($this->getAttributeObject()->getAttributeCode() == 'sku') { - return 'sku'; - } switch ($this->getAttributeObject()->getFrontendInput()) { case 'select': return 'select'; @@ -610,10 +606,6 @@ public function getBindArgumentValue() $this->getValueParsed() )->__toString() ); - } elseif ($this->getAttribute() === 'sku') { - $value = $this->getData('value'); - $value = preg_split('#\s*[,;]\s*#', $value, null, PREG_SPLIT_NO_EMPTY); - $this->setValueParsed($value); } return parent::getBindArgumentValue(); diff --git a/dev/tests/integration/testsuite/Magento/CatalogWidget/Block/Product/ProductListTest.php b/dev/tests/integration/testsuite/Magento/CatalogWidget/Block/Product/ProductListTest.php index 4251e01f4299a..5774f1cf76ae9 100644 --- a/dev/tests/integration/testsuite/Magento/CatalogWidget/Block/Product/ProductListTest.php +++ b/dev/tests/integration/testsuite/Magento/CatalogWidget/Block/Product/ProductListTest.php @@ -73,21 +73,6 @@ public function testCreateCollection() $this->performAssertions(2); } - /** - * Test product list widget can process condition with multiple product sku. - * - * @magentoDbIsolation disabled - * @magentoDataFixture Magento/Catalog/_files/multiple_products.php - */ - public function testCreateCollectionWithMultipleSkuCondition() - { - $encodedConditions = '^[`1`:^[`type`:`Magento||CatalogWidget||Model||Rule||Condition||Combine`,' . - '`aggregator`:`all`,`value`:`1`,`new_child`:``^],`1--1`:^[`type`:`Magento||CatalogWidget||Model||Rule|' . - '|Condition||Product`,`attribute`:`sku`,`operator`:`()`,`value`:`simple1, simple2`^]^]'; - $this->block->setData('conditions_encoded', $encodedConditions); - $this->performAssertions(2); - } - /** * Test product list widget can process condition with dropdown type of attribute * From 41e694f19ab1c66019abad1910bb9fe8fb0d9a3a Mon Sep 17 00:00:00 2001 From: Viktor Petryk <victor.petryk@transoftgroup.com> Date: Mon, 4 Mar 2019 17:14:45 +0200 Subject: [PATCH 239/315] MAGETWO-94190: [Magento Cloud] Error when saving Bundle product --- .../Bundle/Test/Unit/Model/Product/SaveHandlerTest.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/code/Magento/Bundle/Test/Unit/Model/Product/SaveHandlerTest.php b/app/code/Magento/Bundle/Test/Unit/Model/Product/SaveHandlerTest.php index 94e5b72b10e3c..a5b9fb4e1b268 100644 --- a/app/code/Magento/Bundle/Test/Unit/Model/Product/SaveHandlerTest.php +++ b/app/code/Magento/Bundle/Test/Unit/Model/Product/SaveHandlerTest.php @@ -18,12 +18,16 @@ use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; use PHPUnit_Framework_MockObject_MockObject as MockObject; +/** + * Unit tests for \Magento\Bundle\Model\Product\SaveHandler class. + */ class SaveHandlerTest extends \PHPUnit\Framework\TestCase { /** * @var ObjectManager */ private $objectManager; + /** * @var ProductInterface|MockObject */ From 080743fba05fdcc4cfb98fd9bcdc15e39d7e02d9 Mon Sep 17 00:00:00 2001 From: Shikha Mishra <shikhamishra@cedcoss.com> Date: Mon, 25 Feb 2019 22:38:49 +0530 Subject: [PATCH 240/315] Fixed #21425 Date design change show not correctly value in backend --- .../Magento/Backend/Block/System/Design/Edit/Tab/General.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Backend/Block/System/Design/Edit/Tab/General.php b/app/code/Magento/Backend/Block/System/Design/Edit/Tab/General.php index 5a09e1f17f617..3fe187e6e7694 100644 --- a/app/code/Magento/Backend/Block/System/Design/Edit/Tab/General.php +++ b/app/code/Magento/Backend/Block/System/Design/Edit/Tab/General.php @@ -90,7 +90,7 @@ protected function _prepareForm() ] ); - $dateFormat = $this->_localeDate->getDateFormat(\IntlDateFormatter::SHORT); + $dateFormat = $this->_localeDate->getDateFormatWithLongYear(); $fieldset->addField( 'date_from', 'date', From 2b41017794d74966ed2df9932d7d1d33518475f1 Mon Sep 17 00:00:00 2001 From: nmalevanec <mikola.malevanec@transoftgroup.com> Date: Thu, 28 Feb 2019 10:36:58 +0200 Subject: [PATCH 241/315] Fix static tests. --- .../Magento/Backend/Block/System/Design/Edit/Tab/General.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/code/Magento/Backend/Block/System/Design/Edit/Tab/General.php b/app/code/Magento/Backend/Block/System/Design/Edit/Tab/General.php index 3fe187e6e7694..6004d08b4b738 100644 --- a/app/code/Magento/Backend/Block/System/Design/Edit/Tab/General.php +++ b/app/code/Magento/Backend/Block/System/Design/Edit/Tab/General.php @@ -6,6 +6,9 @@ namespace Magento\Backend\Block\System\Design\Edit\Tab; +/** + * General system tab block. + */ class General extends \Magento\Backend\Block\Widget\Form\Generic { /** From b169fe3f94c7107bb9f88380b530d00a812f765a Mon Sep 17 00:00:00 2001 From: Jitheesh <jitheeshvo@gmail.com> Date: Wed, 20 Feb 2019 16:14:06 +0530 Subject: [PATCH 242/315] Checkout Page Cancel button is not working #21327 - hide cancel button if billing address is not available on current quote --- .../Checkout/view/frontend/web/js/view/billing-address.js | 6 ++++++ .../view/frontend/web/template/billing-address.html | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/billing-address.js b/app/code/Magento/Checkout/view/frontend/web/js/view/billing-address.js index 6f9a1a46826da..121a94a14852f 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/view/billing-address.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/view/billing-address.js @@ -201,6 +201,12 @@ function ( this.isAddressDetailsVisible(true); } }, + /** + * Manage cancel button visibility + */ + canUseCancelBillingAddress: ko.computed(function () { + return quote.billingAddress() || lastSelectedBillingAddress; + }), /** * Restore billing address diff --git a/app/code/Magento/Checkout/view/frontend/web/template/billing-address.html b/app/code/Magento/Checkout/view/frontend/web/template/billing-address.html index 5f735fbb4daa9..63edb5057b933 100644 --- a/app/code/Magento/Checkout/view/frontend/web/template/billing-address.html +++ b/app/code/Magento/Checkout/view/frontend/web/template/billing-address.html @@ -22,7 +22,7 @@ <button class="action action-update" type="button" data-bind="click: updateAddress"> <span data-bind="i18n: 'Update'"></span> </button> - <button class="action action-cancel" type="button" data-bind="click: cancelAddressEdit"> + <button class="action action-cancel" type="button" data-bind="click: cancelAddressEdit, visible: canUseCancelBillingAddress()"> <span data-bind="i18n: 'Cancel'"></span> </button> </div> From b2d04ca9882e660cf60de599b1446620f5f5ae91 Mon Sep 17 00:00:00 2001 From: Jitheesh <jitheeshvo@gmail.com> Date: Thu, 21 Feb 2019 10:28:32 +0530 Subject: [PATCH 243/315] Checkout Page Cancel button is not working #21327 - CR fix --- .../Checkout/view/frontend/web/js/view/billing-address.js | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/billing-address.js b/app/code/Magento/Checkout/view/frontend/web/js/view/billing-address.js index 121a94a14852f..4ea6fb5e5df75 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/view/billing-address.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/view/billing-address.js @@ -201,6 +201,7 @@ function ( this.isAddressDetailsVisible(true); } }, + /** * Manage cancel button visibility */ From b4af1319de272df127c3a4c0945e871f258f91ab Mon Sep 17 00:00:00 2001 From: Jitheesh <jitheeshvo@gmail.com> Date: Fri, 22 Feb 2019 11:21:44 +0530 Subject: [PATCH 244/315] Checkout Page Cancel button is not working - Code style issues fixed --- .../Checkout/view/frontend/web/js/view/billing-address.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/billing-address.js b/app/code/Magento/Checkout/view/frontend/web/js/view/billing-address.js index 4ea6fb5e5df75..d68b0682eb511 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/view/billing-address.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/view/billing-address.js @@ -201,7 +201,7 @@ function ( this.isAddressDetailsVisible(true); } }, - + /** * Manage cancel button visibility */ From ce1c1a2e8f2342efb287934066e70587fe16c30d Mon Sep 17 00:00:00 2001 From: Nick de Kleijn <nick.dekleijn@gmail.com> Date: Tue, 15 Jan 2019 16:39:08 +0100 Subject: [PATCH 245/315] #20310 change product_price_value based on tax setting --- .../Magento/Tax/Plugin/Checkout/CustomerData/Cart.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/app/code/Magento/Tax/Plugin/Checkout/CustomerData/Cart.php b/app/code/Magento/Tax/Plugin/Checkout/CustomerData/Cart.php index 87f65ef311ac2..c1b495d4ecf98 100644 --- a/app/code/Magento/Tax/Plugin/Checkout/CustomerData/Cart.php +++ b/app/code/Magento/Tax/Plugin/Checkout/CustomerData/Cart.php @@ -68,6 +68,14 @@ public function afterGetSectionData(\Magento\Checkout\CustomerData\Cart $subject $this->itemPriceRenderer->setItem($item); $this->itemPriceRenderer->setTemplate('checkout/cart/item/price/sidebar.phtml'); $result['items'][$key]['product_price']=$this->itemPriceRenderer->toHtml(); + if($this->itemPriceRenderer->displayPriceExclTax()) { + $result['items'][$key]['product_price_value'] = $item->getCalculationPrice(); + } elseif ($this->itemPriceRenderer->displayPriceInclTax()) { + $result['items'][$key]['product_price_value'] = $item->getPriceInclTax(); + } elseif ($this->itemPriceRenderer->displayBothPrices()) { + $result['items'][$key]['product_price_value']['incl_tax'] = $item->getPriceInclTax(); + $result['items'][$key]['product_price_value']['excl_tax'] = $item->getCalculationPrice(); + } } } } From c821730fa110d93f92a87feb3e1bc8253c6ba820 Mon Sep 17 00:00:00 2001 From: nmalevanec <mikola.malevanec@transoftgroup.com> Date: Tue, 26 Feb 2019 14:23:30 +0200 Subject: [PATCH 246/315] Fix static and functional tests. --- .../Magento/Tax/Plugin/Checkout/CustomerData/Cart.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Tax/Plugin/Checkout/CustomerData/Cart.php b/app/code/Magento/Tax/Plugin/Checkout/CustomerData/Cart.php index c1b495d4ecf98..208833733ae3f 100644 --- a/app/code/Magento/Tax/Plugin/Checkout/CustomerData/Cart.php +++ b/app/code/Magento/Tax/Plugin/Checkout/CustomerData/Cart.php @@ -6,6 +6,10 @@ namespace Magento\Tax\Plugin\Checkout\CustomerData; +/** + * Process quote items price, considering tax configuration. + * @SuppressWarnings(PHPMD.CookieAndSessionMisuse) + */ class Cart { /** @@ -68,11 +72,13 @@ public function afterGetSectionData(\Magento\Checkout\CustomerData\Cart $subject $this->itemPriceRenderer->setItem($item); $this->itemPriceRenderer->setTemplate('checkout/cart/item/price/sidebar.phtml'); $result['items'][$key]['product_price']=$this->itemPriceRenderer->toHtml(); - if($this->itemPriceRenderer->displayPriceExclTax()) { + if ($this->itemPriceRenderer->displayPriceExclTax()) { $result['items'][$key]['product_price_value'] = $item->getCalculationPrice(); } elseif ($this->itemPriceRenderer->displayPriceInclTax()) { $result['items'][$key]['product_price_value'] = $item->getPriceInclTax(); } elseif ($this->itemPriceRenderer->displayBothPrices()) { + //unset product price value in case price already has been set as scalar value. + unset($result['items'][$key]['product_price_value']); $result['items'][$key]['product_price_value']['incl_tax'] = $item->getPriceInclTax(); $result['items'][$key]['product_price_value']['excl_tax'] = $item->getCalculationPrice(); } From eea46883e0941bec6bc71350338160dbe68877da Mon Sep 17 00:00:00 2001 From: Viktor Petryk <victor.petryk@transoftgroup.com> Date: Tue, 5 Mar 2019 10:55:53 +0200 Subject: [PATCH 247/315] MAGETWO-94190: [Magento Cloud] Error when saving Bundle product --- .../Magento/Bundle/Test/Unit/Model/Product/SaveHandlerTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Bundle/Test/Unit/Model/Product/SaveHandlerTest.php b/app/code/Magento/Bundle/Test/Unit/Model/Product/SaveHandlerTest.php index a5b9fb4e1b268..41e6c2c160e0a 100644 --- a/app/code/Magento/Bundle/Test/Unit/Model/Product/SaveHandlerTest.php +++ b/app/code/Magento/Bundle/Test/Unit/Model/Product/SaveHandlerTest.php @@ -150,7 +150,7 @@ public function testExecuteWithoutExistingOption() { $productType = 'bundle'; $productSku = 'product-sku'; - $optionId = ''; + $optionId = null; $this->productMock->expects($this->once()) ->method('getExtensionAttributes') From 2c956f661caf1a10b1b6e6afea185fd473313fd3 Mon Sep 17 00:00:00 2001 From: Cristiano Casciotti <teknoman84@gmail.com> Date: Tue, 5 Mar 2019 12:02:18 +0100 Subject: [PATCH 248/315] Fix for issue #21510 --- app/code/Magento/Indexer/Model/Indexer.php | 2 +- .../Magento/Indexer/Test/Unit/Model/IndexerTest.php | 10 ++++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Indexer/Model/Indexer.php b/app/code/Magento/Indexer/Model/Indexer.php index 4e9b3dbdb8866..afeff3f38d63a 100644 --- a/app/code/Magento/Indexer/Model/Indexer.php +++ b/app/code/Magento/Indexer/Model/Indexer.php @@ -361,7 +361,7 @@ public function getLatestUpdated() return $this->getView()->getUpdated(); } } - return $this->getState()->getUpdated(); + return $this->getState()->getUpdated() ?: ''; } /** diff --git a/app/code/Magento/Indexer/Test/Unit/Model/IndexerTest.php b/app/code/Magento/Indexer/Test/Unit/Model/IndexerTest.php index 6b7cc12218990..ae0d721a549bd 100644 --- a/app/code/Magento/Indexer/Test/Unit/Model/IndexerTest.php +++ b/app/code/Magento/Indexer/Test/Unit/Model/IndexerTest.php @@ -164,7 +164,12 @@ public function testGetLatestUpdated($getViewIsEnabled, $getViewGetUpdated, $get } } } else { - $this->assertEquals($getStateGetUpdated, $this->model->getLatestUpdated()); + $actualGetLatestUpdated = $this->model->getLatestUpdated(); + $this->assertEquals($getStateGetUpdated, $actualGetLatestUpdated); + + if ($getStateGetUpdated === null) { + $this->assertNotNull($actualGetLatestUpdated); + } } } @@ -182,7 +187,8 @@ public function getLatestUpdatedDataProvider() [true, '', '06-Jan-1944'], [true, '06-Jan-1944', ''], [true, '', ''], - [true, '06-Jan-1944', '05-Jan-1944'] + [true, '06-Jan-1944', '05-Jan-1944'], + [false, null, null], ]; } From d5ed9e89b41c6d407869d4cf00f8293fb5f6e41f Mon Sep 17 00:00:00 2001 From: Cristiano Casciotti <teknoman84@gmail.com> Date: Tue, 5 Mar 2019 14:27:58 +0100 Subject: [PATCH 249/315] Changed variable name for codacy quality review --- app/code/Magento/Indexer/Test/Unit/Model/IndexerTest.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Indexer/Test/Unit/Model/IndexerTest.php b/app/code/Magento/Indexer/Test/Unit/Model/IndexerTest.php index ae0d721a549bd..ca2da9585f934 100644 --- a/app/code/Magento/Indexer/Test/Unit/Model/IndexerTest.php +++ b/app/code/Magento/Indexer/Test/Unit/Model/IndexerTest.php @@ -164,11 +164,11 @@ public function testGetLatestUpdated($getViewIsEnabled, $getViewGetUpdated, $get } } } else { - $actualGetLatestUpdated = $this->model->getLatestUpdated(); - $this->assertEquals($getStateGetUpdated, $actualGetLatestUpdated); + $getLatestUpdated = $this->model->getLatestUpdated(); + $this->assertEquals($getStateGetUpdated, $getLatestUpdated); if ($getStateGetUpdated === null) { - $this->assertNotNull($actualGetLatestUpdated); + $this->assertNotNull($getLatestUpdated); } } } From ca72609de5bdd2ff1d74eb5957a8acca125eadba Mon Sep 17 00:00:00 2001 From: NazarKlovanych <nazarn96@gmail.com> Date: Fri, 8 Feb 2019 16:26:58 +0200 Subject: [PATCH 250/315] [backport]fix wrong check CustomerMiddleName --- .../Edit/Action/Attribute/Tab/Inventory.php | 39 +++++-------------- .../product/edit/action/inventory.phtml | 9 ++++- 2 files changed, 17 insertions(+), 31 deletions(-) diff --git a/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Action/Attribute/Tab/Inventory.php b/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Action/Attribute/Tab/Inventory.php index d11a6d632657f..edeb7f94c3ae5 100644 --- a/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Action/Attribute/Tab/Inventory.php +++ b/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Action/Attribute/Tab/Inventory.php @@ -5,8 +5,6 @@ */ namespace Magento\Catalog\Block\Adminhtml\Product\Edit\Action\Attribute\Tab; -use Magento\Customer\Api\Data\GroupInterface; - /** * Products mass update inventory tab * @@ -31,11 +29,6 @@ class Inventory extends \Magento\Backend\Block\Widget implements \Magento\Backen */ protected $disabledFields = []; - /** - * @var \Magento\Framework\Serialize\SerializerInterface - */ - private $serializer; - /** * @param \Magento\Backend\Block\Template\Context $context * @param \Magento\CatalogInventory\Model\Source\Backorders $backorders @@ -46,13 +39,10 @@ public function __construct( \Magento\Backend\Block\Template\Context $context, \Magento\CatalogInventory\Model\Source\Backorders $backorders, \Magento\CatalogInventory\Api\StockConfigurationInterface $stockConfiguration, - array $data = [], - \Magento\Framework\Serialize\SerializerInterface $serializer = null + array $data = [] ) { $this->_backorders = $backorders; $this->stockConfiguration = $stockConfiguration; - $this->serializer = $serializer ?? \Magento\Framework\App\ObjectManager::getInstance() - ->get(\Magento\Framework\Serialize\SerializerInterface::class); parent::__construct($context, $data); } @@ -80,11 +70,11 @@ public function getFieldSuffix() * Retrieve current store id * * @return int + * @SuppressWarnings(PHPMD.RequestAwareBlockMethod) */ public function getStoreId() { - $storeId = $this->getRequest()->getParam('store'); - return (int) $storeId; + return (int)$this->getRequest()->getParam('store'); } /** @@ -98,21 +88,6 @@ public function getDefaultConfigValue($field) return $this->stockConfiguration->getDefaultConfigValue($field); } - /** - * Returns min_sale_qty configuration for the ALL Customer Group - * @return int - */ - public function getDefaultMinSaleQty() - { - $default = $this->stockConfiguration->getDefaultConfigValue('min_sale_qty'); - if (!is_numeric($default)) { - $default = $this->serializer->unserialize($default); - $default = isset($default[GroupInterface::CUST_GROUP_ALL]) ? $default[GroupInterface::CUST_GROUP_ALL] : 1; - } - - return (int) $default; - } - /** * Tab settings * @@ -124,6 +99,8 @@ public function getTabLabel() } /** + * Return Tab title. + * * @return \Magento\Framework\Phrase */ public function getTabTitle() @@ -132,7 +109,7 @@ public function getTabTitle() } /** - * @return bool + * @inheritdoc */ public function canShowTab() { @@ -140,7 +117,7 @@ public function canShowTab() } /** - * @return bool + * @inheritdoc */ public function isHidden() { @@ -148,6 +125,8 @@ public function isHidden() } /** + * Get availability status. + * * @param string $fieldName * @return bool * @SuppressWarnings(PHPMD.UnusedFormalParameter) diff --git a/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/edit/action/inventory.phtml b/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/edit/action/inventory.phtml index 96e07ceb4d305..64c8ba7dcf49f 100644 --- a/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/edit/action/inventory.phtml +++ b/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/edit/action/inventory.phtml @@ -30,6 +30,13 @@ }); </script> +<?php +$defaultMinSaleQty = $block->getDefaultConfigValue('min_sale_qty'); +if (!is_numeric($defaultMinSaleQty)) { + $defaultMinSaleQty = json_decode($defaultMinSaleQty, true); + $defaultMinSaleQty = (float) $defaultMinSaleQty[\Magento\Customer\Api\Data\GroupInterface::CUST_GROUP_ALL] ?? 1; +} +?> <div class="fieldset-wrapper form-inline advanced-inventory-edit"> <div class="fieldset-wrapper-title"> <strong class="title"> @@ -132,7 +139,7 @@ <div class="field"> <input type="text" class="input-text validate-number" id="inventory_min_sale_qty" name="<?= /* @escapeNotVerified */ $block->getFieldSuffix() ?>[min_sale_qty]" - value="<?= /* @escapeNotVerified */ $block->getDefaultMinSaleQty() * 1 ?>" + value="<?= /* @escapeNotVerified */ $defaultMinSaleQty ?>" disabled="disabled"/> </div> <div class="field choice"> From ab2de1505b5b98d746c3623269e19fdb283676b5 Mon Sep 17 00:00:00 2001 From: Prakash <prakash@2jcommerce.in> Date: Fri, 8 Feb 2019 19:34:23 +0530 Subject: [PATCH 251/315] Fixes for product tabbing issue --- lib/web/mage/tabs.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/web/mage/tabs.js b/lib/web/mage/tabs.js index b441477ab8d8a..e4d196fcbbca8 100644 --- a/lib/web/mage/tabs.js +++ b/lib/web/mage/tabs.js @@ -71,6 +71,9 @@ define([ anchorId = anchor.replace('#', ''); if (anchor && isValid) { + if(anchorId == 'review-form'){ + anchorId = anchorId.replace('-form', 's'); + } $.each(self.contents, function (i) { if ($(this).attr('id') === anchorId) { self.collapsibles.not(self.collapsibles.eq(i)).collapsible('forceDeactivate'); From c6c6ead1aaaa5e45b992aff7d564a44c2276e083 Mon Sep 17 00:00:00 2001 From: Prakash <prakash@2jcommerce.in> Date: Wed, 13 Feb 2019 11:59:25 +0530 Subject: [PATCH 252/315] Fixes for tabbing issue on product --- lib/web/mage/tabs.js | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/lib/web/mage/tabs.js b/lib/web/mage/tabs.js index e4d196fcbbca8..ee3119e90d3a8 100644 --- a/lib/web/mage/tabs.js +++ b/lib/web/mage/tabs.js @@ -70,12 +70,9 @@ define([ isValid = $.mage.isValidSelector(anchor), anchorId = anchor.replace('#', ''); - if (anchor && isValid) { - if(anchorId == 'review-form'){ - anchorId = anchorId.replace('-form', 's'); - } + if (anchor && isValid) { $.each(self.contents, function (i) { - if ($(this).attr('id') === anchorId) { + if ($(this).attr('id') === anchorId || $(this).find('#' + anchorId).length) { self.collapsibles.not(self.collapsibles.eq(i)).collapsible('forceDeactivate'); return false; From 905085d16039d44c5a1159d2fc68a68062291f37 Mon Sep 17 00:00:00 2001 From: Volodymyr Zaets <vzaets@magento.com> Date: Wed, 13 Feb 2019 17:58:30 +0200 Subject: [PATCH 253/315] Remove spaces --- lib/web/mage/tabs.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/web/mage/tabs.js b/lib/web/mage/tabs.js index ee3119e90d3a8..65c452d33bf12 100644 --- a/lib/web/mage/tabs.js +++ b/lib/web/mage/tabs.js @@ -70,7 +70,7 @@ define([ isValid = $.mage.isValidSelector(anchor), anchorId = anchor.replace('#', ''); - if (anchor && isValid) { + if (anchor && isValid) { $.each(self.contents, function (i) { if ($(this).attr('id') === anchorId || $(this).find('#' + anchorId).length) { self.collapsibles.not(self.collapsibles.eq(i)).collapsible('forceDeactivate'); From 887433247a7d0da1237c0d7f60fe5bee1dfa4324 Mon Sep 17 00:00:00 2001 From: milindsingh <milind7@live.com> Date: Tue, 8 Jan 2019 22:29:19 +0530 Subject: [PATCH 254/315] Issue fixed #20128 : Date range returns same start and end date --- .../Magento/Reports/Model/ResourceModel/Order/Collection.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Reports/Model/ResourceModel/Order/Collection.php b/app/code/Magento/Reports/Model/ResourceModel/Order/Collection.php index fd9adbe734101..da7ab97a1b211 100644 --- a/app/code/Magento/Reports/Model/ResourceModel/Order/Collection.php +++ b/app/code/Magento/Reports/Model/ResourceModel/Order/Collection.php @@ -445,7 +445,7 @@ public function getDateRange($range, $customStart, $customEnd, $returnObjects = break; case 'custom': - $dateStart = $customStart ? $customStart : $dateEnd; + $dateStart = $customStart ? $customStart : $dateStart; $dateEnd = $customEnd ? $customEnd : $dateEnd; break; From 1c45357d60ef44975e12bad55fa7f2ef9107cad9 Mon Sep 17 00:00:00 2001 From: LisovyiEvhenii <lisovyievhenii@gmail.com> Date: Fri, 25 Jan 2019 13:14:09 +0200 Subject: [PATCH 255/315] #14882: product_types.xml doesn't allow numbers in modelInstance. Fix module and models name pattern for product_types_base.xsd, product_options.xsd, import.xsd, export.xsd. Adjust unit tests, related to these files --- .../Config/_files/invalidProductOptionsXmlArray.php | 8 ++++---- .../Config/_files/invalidProductTypesXmlArray.php | 8 ++++---- .../Config/_files/valid_product_types_merged.xml | 9 +++++++++ app/code/Magento/Catalog/etc/product_options.xsd | 4 ++-- app/code/Magento/Catalog/etc/product_types_base.xsd | 4 ++-- .../Export/Config/_files/invalidExportXmlArray.php | 10 +++++----- .../Config/_files/invalidImportMergedXmlArray.php | 10 +++++----- .../Import/Config/_files/invalidImportXmlArray.php | 12 ++++++------ app/code/Magento/ImportExport/etc/export.xsd | 4 ++-- app/code/Magento/ImportExport/etc/import.xsd | 4 ++-- 10 files changed, 41 insertions(+), 32 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Unit/Model/ProductOptions/Config/_files/invalidProductOptionsXmlArray.php b/app/code/Magento/Catalog/Test/Unit/Model/ProductOptions/Config/_files/invalidProductOptionsXmlArray.php index 034b04b6a757d..31f3ec07bf063 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/ProductOptions/Config/_files/invalidProductOptionsXmlArray.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/ProductOptions/Config/_files/invalidProductOptionsXmlArray.php @@ -29,12 +29,12 @@ ], ], 'renderer_attribute_with_invalid_value' => [ - '<?xml version="1.0"?><config><option name="name_one" renderer="true12"><inputType name="name_one"/>' . + '<?xml version="1.0"?><config><option name="name_one" renderer="123true"><inputType name="name_one"/>' . '</option></config>', [ - "Element 'option', attribute 'renderer': [facet 'pattern'] The value 'true12' is not accepted by the " . - "pattern '[a-zA-Z_\\\\]+'.\nLine: 1\n", - "Element 'option', attribute 'renderer': 'true12' is not a valid value of the atomic" . + "Element 'option', attribute 'renderer': [facet 'pattern'] The value '123true' is not accepted by the " . + "pattern '[a-zA-Z_\\\\]+[a-zA-Z0-9_\\\\]+'.\nLine: 1\n", + "Element 'option', attribute 'renderer': '123true' is not a valid value of the atomic" . " type 'modelName'.\nLine: 1\n" ], ], diff --git a/app/code/Magento/Catalog/Test/Unit/Model/ProductTypes/Config/_files/invalidProductTypesXmlArray.php b/app/code/Magento/Catalog/Test/Unit/Model/ProductTypes/Config/_files/invalidProductTypesXmlArray.php index e1847bea53fcb..1850ff476a809 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/ProductTypes/Config/_files/invalidProductTypesXmlArray.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/ProductTypes/Config/_files/invalidProductTypesXmlArray.php @@ -23,7 +23,7 @@ '<?xml version="1.0"?><config><type name="some_name" modelInstance="123" /></config>', [ "Element 'type', attribute 'modelInstance': [facet 'pattern'] The value '123' is not accepted by the" . - " pattern '[a-zA-Z_\\\\]+'.\nLine: 1\n", + " pattern '[a-zA-Z_\\\\]+[a-zA-Z0-9_\\\\]+'.\nLine: 1\n", "Element 'type', attribute 'modelInstance': '123' is not a valid value of the atomic type" . " 'modelName'.\nLine: 1\n" ], @@ -57,7 +57,7 @@ '<?xml version="1.0"?><config><type name="some_name"><priceModel instance="123123" /></type></config>', [ "Element 'priceModel', attribute 'instance': [facet 'pattern'] The value '123123' is not accepted " . - "by the pattern '[a-zA-Z_\\\\]+'.\nLine: 1\n", + "by the pattern '[a-zA-Z_\\\\]+[a-zA-Z0-9_\\\\]+'.\nLine: 1\n", "Element 'priceModel', attribute 'instance': '123123' is not a valid value of the atomic type" . " 'modelName'.\nLine: 1\n" ], @@ -66,7 +66,7 @@ '<?xml version="1.0"?><config><type name="some_name"><indexerModel instance="123" /></type></config>', [ "Element 'indexerModel', attribute 'instance': [facet 'pattern'] The value '123' is not accepted by " . - "the pattern '[a-zA-Z_\\\\]+'.\nLine: 1\n", + "the pattern '[a-zA-Z_\\\\]+[a-zA-Z0-9_\\\\]+'.\nLine: 1\n", "Element 'indexerModel', attribute 'instance': '123' is not a valid value of the atomic type" . " 'modelName'.\nLine: 1\n" ], @@ -83,7 +83,7 @@ '<?xml version="1.0"?><config><type name="some_name"><stockIndexerModel instance="1234"/></type></config>', [ "Element 'stockIndexerModel', attribute 'instance': [facet 'pattern'] The value '1234' is not " . - "accepted by the pattern '[a-zA-Z_\\\\]+'.\nLine: 1\n", + "accepted by the pattern '[a-zA-Z_\\\\]+[a-zA-Z0-9_\\\\]+'.\nLine: 1\n", "Element 'stockIndexerModel', attribute 'instance': '1234' is not a valid value of the atomic " . "type 'modelName'.\nLine: 1\n" ], diff --git a/app/code/Magento/Catalog/Test/Unit/Model/ProductTypes/Config/_files/valid_product_types_merged.xml b/app/code/Magento/Catalog/Test/Unit/Model/ProductTypes/Config/_files/valid_product_types_merged.xml index 7edbc399a9476..701338774baa5 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/ProductTypes/Config/_files/valid_product_types_merged.xml +++ b/app/code/Magento/Catalog/Test/Unit/Model/ProductTypes/Config/_files/valid_product_types_merged.xml @@ -15,6 +15,14 @@ <stockIndexerModel instance="instance_name"/> </type> <type label="some_label" name="some_name2" modelInstance="model_name"> + <allowedSelectionTypes> + <type name="some_name" /> + </allowedSelectionTypes> + <priceModel instance="instance_name_with_digits_123" /> + <indexerModel instance="instance_name_with_digits_123" /> + <stockIndexerModel instance="instance_name_with_digits_123"/> + </type> + <type label="some_label" name="some_name3" modelInstance="model_name"> <allowedSelectionTypes> <type name="some_name" /> </allowedSelectionTypes> @@ -25,5 +33,6 @@ <composableTypes> <type name="some_name"/> <type name="some_name2"/> + <type name="some_name3"/> </composableTypes> </config> diff --git a/app/code/Magento/Catalog/etc/product_options.xsd b/app/code/Magento/Catalog/etc/product_options.xsd index 3bc24a9099262..e57eb4e715918 100644 --- a/app/code/Magento/Catalog/etc/product_options.xsd +++ b/app/code/Magento/Catalog/etc/product_options.xsd @@ -61,11 +61,11 @@ <xs:simpleType name="modelName"> <xs:annotation> <xs:documentation> - Model name can contain only [a-zA-Z_\\]. + Model name can contain only [a-zA-Z_\\]+[a-zA-Z0-9_\\]+. </xs:documentation> </xs:annotation> <xs:restriction base="xs:string"> - <xs:pattern value="[a-zA-Z_\\]+" /> + <xs:pattern value="[a-zA-Z_\\]+[a-zA-Z0-9_\\]+" /> </xs:restriction> </xs:simpleType> </xs:schema> diff --git a/app/code/Magento/Catalog/etc/product_types_base.xsd b/app/code/Magento/Catalog/etc/product_types_base.xsd index 6cc35fd7bee37..fdefc95c277b1 100644 --- a/app/code/Magento/Catalog/etc/product_types_base.xsd +++ b/app/code/Magento/Catalog/etc/product_types_base.xsd @@ -92,11 +92,11 @@ <xs:simpleType name="modelName"> <xs:annotation> <xs:documentation> - Model name can contain only [a-zA-Z_\\]. + Model name can contain only [a-zA-Z_\\]+[a-zA-Z0-9_\\]+. </xs:documentation> </xs:annotation> <xs:restriction base="xs:string"> - <xs:pattern value="[a-zA-Z_\\]+" /> + <xs:pattern value="[a-zA-Z_\\]+[a-zA-Z0-9_\\]+" /> </xs:restriction> </xs:simpleType> </xs:schema> diff --git a/app/code/Magento/ImportExport/Test/Unit/Model/Export/Config/_files/invalidExportXmlArray.php b/app/code/Magento/ImportExport/Test/Unit/Model/Export/Config/_files/invalidExportXmlArray.php index 288a99770974a..251ccae6d7a8a 100644 --- a/app/code/Magento/ImportExport/Test/Unit/Model/Export/Config/_files/invalidExportXmlArray.php +++ b/app/code/Magento/ImportExport/Test/Unit/Model/Export/Config/_files/invalidExportXmlArray.php @@ -22,15 +22,15 @@ 'attributes_with_type_modelName_and_invalid_value' => [ '<?xml version="1.0"?><config><entity name="Name/one" model="model_one" ' . 'entityAttributeFilterType="model_one"/><entityType entity="Name/one" name="name_one" model="1"/>' - . ' <fileFormat name="name_one" model="model1"/></config>', + . ' <fileFormat name="name_one" model="1model"/></config>', [ "Element 'entityType', attribute 'model': [facet 'pattern'] The value '1' is not accepted by the " . - "pattern '[A-Za-z_\\\\]+'.\nLine: 1\n", + "pattern '[a-zA-Z_\\\\]+[a-zA-Z0-9_\\\\]+'.\nLine: 1\n", "Element 'entityType', attribute 'model': '1' is not a valid value of the atomic type" . " 'modelName'.\nLine: 1\n", - "Element 'fileFormat', attribute 'model': [facet 'pattern'] The value 'model1' is not " . - "accepted by the pattern '[A-Za-z_\\\\]+'.\nLine: 1\n", - "Element 'fileFormat', attribute 'model': 'model1' is not a valid " . + "Element 'fileFormat', attribute 'model': [facet 'pattern'] The value '1model' is not " . + "accepted by the pattern '[a-zA-Z_\\\\]+[a-zA-Z0-9_\\\\]+'.\nLine: 1\n", + "Element 'fileFormat', attribute 'model': '1model' is not a valid " . "value of the atomic type 'modelName'.\nLine: 1\n" ], ], diff --git a/app/code/Magento/ImportExport/Test/Unit/Model/Import/Config/_files/invalidImportMergedXmlArray.php b/app/code/Magento/ImportExport/Test/Unit/Model/Import/Config/_files/invalidImportMergedXmlArray.php index 357b35e8a313c..e51d46536abc0 100644 --- a/app/code/Magento/ImportExport/Test/Unit/Model/Import/Config/_files/invalidImportMergedXmlArray.php +++ b/app/code/Magento/ImportExport/Test/Unit/Model/Import/Config/_files/invalidImportMergedXmlArray.php @@ -26,12 +26,12 @@ ["Element 'entity', attribute 'notallowed': The attribute 'notallowed' is not allowed.\nLine: 1\n"], ], 'entity_model_with_invalid_value' => [ - '<?xml version="1.0"?><config><entity name="test_name" label="test_label" model="afwer34" ' . + '<?xml version="1.0"?><config><entity name="test_name" label="test_label" model="34afwer" ' . 'behaviorModel="test" /></config>', [ - "Element 'entity', attribute 'model': [facet 'pattern'] The value 'afwer34' is not " . - "accepted by the pattern '[A-Za-z_\\\\]+'.\nLine: 1\n", - "Element 'entity', attribute 'model': 'afwer34' is not a valid value of the atomic type" . + "Element 'entity', attribute 'model': [facet 'pattern'] The value '34afwer' is not " . + "accepted by the pattern '[a-zA-Z_\\\\]+[a-zA-Z0-9_\\\\]+'.\nLine: 1\n", + "Element 'entity', attribute 'model': '34afwer' is not a valid value of the atomic type" . " 'modelName'.\nLine: 1\n" ], ], @@ -40,7 +40,7 @@ '</config>', [ "Element 'entity', attribute 'behaviorModel': [facet 'pattern'] The value '666' is not accepted by " . - "the pattern '[A-Za-z_\\\\]+'.\nLine: 1\n", + "the pattern '[a-zA-Z_\\\\]+[a-zA-Z0-9_\\\\]+'.\nLine: 1\n", "Element 'entity', attribute 'behaviorModel': '666' is not a valid value of the atomic type" . " 'modelName'.\nLine: 1\n" ], diff --git a/app/code/Magento/ImportExport/Test/Unit/Model/Import/Config/_files/invalidImportXmlArray.php b/app/code/Magento/ImportExport/Test/Unit/Model/Import/Config/_files/invalidImportXmlArray.php index c913b53e8b531..4b9d8e1c32f6d 100644 --- a/app/code/Magento/ImportExport/Test/Unit/Model/Import/Config/_files/invalidImportXmlArray.php +++ b/app/code/Magento/ImportExport/Test/Unit/Model/Import/Config/_files/invalidImportXmlArray.php @@ -19,7 +19,7 @@ '<?xml version="1.0"?><config><entity name="some_name" model="12345"/></config>', [ "Element 'entity', attribute 'model': [facet 'pattern'] The value '12345' is not accepted by " . - "the pattern '[A-Za-z_\\\\]+'.\nLine: 1\n", + "the pattern '[a-zA-Z_\\\\]+[a-zA-Z0-9_\\\\]+'.\nLine: 1\n", "Element 'entity', attribute 'model': '12345' is not a valid value of the atomic type" . " 'modelName'.\nLine: 1\n" ], @@ -28,7 +28,7 @@ '<?xml version="1.0"?><config><entity name="some_name" behaviorModel="=--09"/></config>', [ "Element 'entity', attribute 'behaviorModel': [facet 'pattern'] The value '=--09' is not " . - "accepted by the pattern '[A-Za-z_\\\\]+'.\nLine: 1\n", + "accepted by the pattern '[a-zA-Z_\\\\]+[a-zA-Z0-9_\\\\]+'.\nLine: 1\n", "Element 'entity', attribute 'behaviorModel': '=--09' is not a valid value of the atomic type" . " 'modelName'.\nLine: 1\n" ], @@ -46,11 +46,11 @@ ["Element 'entityType': The attribute 'model' is required but missing.\nLine: 1\n"], ], 'entitytype_with_invalid_model_attribute_value' => [ - '<?xml version="1.0"?><config><entityType entity="entity_name" name="some_name" model="test1"/></config>', + '<?xml version="1.0"?><config><entityType entity="entity_name" name="some_name" model="1test"/></config>', [ - "Element 'entityType', attribute 'model': [facet 'pattern'] The value 'test1' is not " . - "accepted by the pattern '[A-Za-z_\\\\]+'.\nLine: 1\n", - "Element 'entityType', attribute 'model': 'test1' is not a valid value of the atomic type" . + "Element 'entityType', attribute 'model': [facet 'pattern'] The value '1test' is not " . + "accepted by the pattern '[a-zA-Z_\\\\]+[a-zA-Z0-9_\\\\]+'.\nLine: 1\n", + "Element 'entityType', attribute 'model': '1test' is not a valid value of the atomic type" . " 'modelName'.\nLine: 1\n" ], ], diff --git a/app/code/Magento/ImportExport/etc/export.xsd b/app/code/Magento/ImportExport/etc/export.xsd index 65728a9be5c62..b196ae0cb6f11 100644 --- a/app/code/Magento/ImportExport/etc/export.xsd +++ b/app/code/Magento/ImportExport/etc/export.xsd @@ -71,11 +71,11 @@ <xs:simpleType name="modelName"> <xs:annotation> <xs:documentation> - Model name can contain only [A-Za-z_\\]. + Model name can contain only [a-zA-Z_\\]+[a-zA-Z0-9_\\]+. </xs:documentation> </xs:annotation> <xs:restriction base="xs:string"> - <xs:pattern value="[A-Za-z_\\]+" /> + <xs:pattern value="[a-zA-Z_\\]+[a-zA-Z0-9_\\]+" /> </xs:restriction> </xs:simpleType> </xs:schema> diff --git a/app/code/Magento/ImportExport/etc/import.xsd b/app/code/Magento/ImportExport/etc/import.xsd index aefa6541d7e13..42bd365878eb2 100644 --- a/app/code/Magento/ImportExport/etc/import.xsd +++ b/app/code/Magento/ImportExport/etc/import.xsd @@ -61,11 +61,11 @@ <xs:simpleType name="modelName"> <xs:annotation> <xs:documentation> - Model name can contain only [A-Za-z_\\]. + Model name can contain only [a-zA-Z_\\]+[a-zA-Z0-9_\\]+. </xs:documentation> </xs:annotation> <xs:restriction base="xs:string"> - <xs:pattern value="[A-Za-z_\\]+" /> + <xs:pattern value="[a-zA-Z_\\]+[a-zA-Z0-9_\\]+" /> </xs:restriction> </xs:simpleType> </xs:schema> From ab8d312286fa448f408727ea6fff9e790424cb34 Mon Sep 17 00:00:00 2001 From: LisovyiEvhenii <lisovyievhenii@gmail.com> Date: Tue, 29 Jan 2019 15:50:21 +0200 Subject: [PATCH 256/315] #14882: improve regular expression --- .../Config/_files/invalidProductOptionsXmlArray.php | 2 +- .../Config/_files/invalidProductTypesXmlArray.php | 8 ++++---- app/code/Magento/Catalog/etc/product_options.xsd | 4 ++-- app/code/Magento/Catalog/etc/product_types_base.xsd | 4 ++-- .../Model/Export/Config/_files/invalidExportXmlArray.php | 4 ++-- .../Import/Config/_files/invalidImportMergedXmlArray.php | 4 ++-- .../Model/Import/Config/_files/invalidImportXmlArray.php | 6 +++--- app/code/Magento/ImportExport/etc/export.xsd | 4 ++-- app/code/Magento/ImportExport/etc/import.xsd | 4 ++-- 9 files changed, 20 insertions(+), 20 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Unit/Model/ProductOptions/Config/_files/invalidProductOptionsXmlArray.php b/app/code/Magento/Catalog/Test/Unit/Model/ProductOptions/Config/_files/invalidProductOptionsXmlArray.php index 31f3ec07bf063..cfb54c3aefd0f 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/ProductOptions/Config/_files/invalidProductOptionsXmlArray.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/ProductOptions/Config/_files/invalidProductOptionsXmlArray.php @@ -33,7 +33,7 @@ '</option></config>', [ "Element 'option', attribute 'renderer': [facet 'pattern'] The value '123true' is not accepted by the " . - "pattern '[a-zA-Z_\\\\]+[a-zA-Z0-9_\\\\]+'.\nLine: 1\n", + "pattern '([\\\\]?[a-zA-Z_][a-zA-Z0-9_]*)+'.\nLine: 1\n", "Element 'option', attribute 'renderer': '123true' is not a valid value of the atomic" . " type 'modelName'.\nLine: 1\n" ], diff --git a/app/code/Magento/Catalog/Test/Unit/Model/ProductTypes/Config/_files/invalidProductTypesXmlArray.php b/app/code/Magento/Catalog/Test/Unit/Model/ProductTypes/Config/_files/invalidProductTypesXmlArray.php index 1850ff476a809..868252da8190c 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/ProductTypes/Config/_files/invalidProductTypesXmlArray.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/ProductTypes/Config/_files/invalidProductTypesXmlArray.php @@ -23,7 +23,7 @@ '<?xml version="1.0"?><config><type name="some_name" modelInstance="123" /></config>', [ "Element 'type', attribute 'modelInstance': [facet 'pattern'] The value '123' is not accepted by the" . - " pattern '[a-zA-Z_\\\\]+[a-zA-Z0-9_\\\\]+'.\nLine: 1\n", + " pattern '([\\\\]?[a-zA-Z_][a-zA-Z0-9_]*)+'.\nLine: 1\n", "Element 'type', attribute 'modelInstance': '123' is not a valid value of the atomic type" . " 'modelName'.\nLine: 1\n" ], @@ -57,7 +57,7 @@ '<?xml version="1.0"?><config><type name="some_name"><priceModel instance="123123" /></type></config>', [ "Element 'priceModel', attribute 'instance': [facet 'pattern'] The value '123123' is not accepted " . - "by the pattern '[a-zA-Z_\\\\]+[a-zA-Z0-9_\\\\]+'.\nLine: 1\n", + "by the pattern '([\\\\]?[a-zA-Z_][a-zA-Z0-9_]*)+'.\nLine: 1\n", "Element 'priceModel', attribute 'instance': '123123' is not a valid value of the atomic type" . " 'modelName'.\nLine: 1\n" ], @@ -66,7 +66,7 @@ '<?xml version="1.0"?><config><type name="some_name"><indexerModel instance="123" /></type></config>', [ "Element 'indexerModel', attribute 'instance': [facet 'pattern'] The value '123' is not accepted by " . - "the pattern '[a-zA-Z_\\\\]+[a-zA-Z0-9_\\\\]+'.\nLine: 1\n", + "the pattern '([\\\\]?[a-zA-Z_][a-zA-Z0-9_]*)+'.\nLine: 1\n", "Element 'indexerModel', attribute 'instance': '123' is not a valid value of the atomic type" . " 'modelName'.\nLine: 1\n" ], @@ -83,7 +83,7 @@ '<?xml version="1.0"?><config><type name="some_name"><stockIndexerModel instance="1234"/></type></config>', [ "Element 'stockIndexerModel', attribute 'instance': [facet 'pattern'] The value '1234' is not " . - "accepted by the pattern '[a-zA-Z_\\\\]+[a-zA-Z0-9_\\\\]+'.\nLine: 1\n", + "accepted by the pattern '([\\\\]?[a-zA-Z_][a-zA-Z0-9_]*)+'.\nLine: 1\n", "Element 'stockIndexerModel', attribute 'instance': '1234' is not a valid value of the atomic " . "type 'modelName'.\nLine: 1\n" ], diff --git a/app/code/Magento/Catalog/etc/product_options.xsd b/app/code/Magento/Catalog/etc/product_options.xsd index e57eb4e715918..734c8f378d5d7 100644 --- a/app/code/Magento/Catalog/etc/product_options.xsd +++ b/app/code/Magento/Catalog/etc/product_options.xsd @@ -61,11 +61,11 @@ <xs:simpleType name="modelName"> <xs:annotation> <xs:documentation> - Model name can contain only [a-zA-Z_\\]+[a-zA-Z0-9_\\]+. + Model name can contain only ([\\]?[a-zA-Z_][a-zA-Z0-9_]*)+. </xs:documentation> </xs:annotation> <xs:restriction base="xs:string"> - <xs:pattern value="[a-zA-Z_\\]+[a-zA-Z0-9_\\]+" /> + <xs:pattern value="([\\]?[a-zA-Z_][a-zA-Z0-9_]*)+" /> </xs:restriction> </xs:simpleType> </xs:schema> diff --git a/app/code/Magento/Catalog/etc/product_types_base.xsd b/app/code/Magento/Catalog/etc/product_types_base.xsd index fdefc95c277b1..dec952bcf492e 100644 --- a/app/code/Magento/Catalog/etc/product_types_base.xsd +++ b/app/code/Magento/Catalog/etc/product_types_base.xsd @@ -92,11 +92,11 @@ <xs:simpleType name="modelName"> <xs:annotation> <xs:documentation> - Model name can contain only [a-zA-Z_\\]+[a-zA-Z0-9_\\]+. + Model name can contain only ([\\]?[a-zA-Z_][a-zA-Z0-9_]*)+. </xs:documentation> </xs:annotation> <xs:restriction base="xs:string"> - <xs:pattern value="[a-zA-Z_\\]+[a-zA-Z0-9_\\]+" /> + <xs:pattern value="([\\]?[a-zA-Z_][a-zA-Z0-9_]*)+" /> </xs:restriction> </xs:simpleType> </xs:schema> diff --git a/app/code/Magento/ImportExport/Test/Unit/Model/Export/Config/_files/invalidExportXmlArray.php b/app/code/Magento/ImportExport/Test/Unit/Model/Export/Config/_files/invalidExportXmlArray.php index 251ccae6d7a8a..179f3f3cadab0 100644 --- a/app/code/Magento/ImportExport/Test/Unit/Model/Export/Config/_files/invalidExportXmlArray.php +++ b/app/code/Magento/ImportExport/Test/Unit/Model/Export/Config/_files/invalidExportXmlArray.php @@ -25,11 +25,11 @@ . ' <fileFormat name="name_one" model="1model"/></config>', [ "Element 'entityType', attribute 'model': [facet 'pattern'] The value '1' is not accepted by the " . - "pattern '[a-zA-Z_\\\\]+[a-zA-Z0-9_\\\\]+'.\nLine: 1\n", + "pattern '([\\\\]?[a-zA-Z_][a-zA-Z0-9_]*)+'.\nLine: 1\n", "Element 'entityType', attribute 'model': '1' is not a valid value of the atomic type" . " 'modelName'.\nLine: 1\n", "Element 'fileFormat', attribute 'model': [facet 'pattern'] The value '1model' is not " . - "accepted by the pattern '[a-zA-Z_\\\\]+[a-zA-Z0-9_\\\\]+'.\nLine: 1\n", + "accepted by the pattern '([\\\\]?[a-zA-Z_][a-zA-Z0-9_]*)+'.\nLine: 1\n", "Element 'fileFormat', attribute 'model': '1model' is not a valid " . "value of the atomic type 'modelName'.\nLine: 1\n" ], diff --git a/app/code/Magento/ImportExport/Test/Unit/Model/Import/Config/_files/invalidImportMergedXmlArray.php b/app/code/Magento/ImportExport/Test/Unit/Model/Import/Config/_files/invalidImportMergedXmlArray.php index e51d46536abc0..409c1af9cb38a 100644 --- a/app/code/Magento/ImportExport/Test/Unit/Model/Import/Config/_files/invalidImportMergedXmlArray.php +++ b/app/code/Magento/ImportExport/Test/Unit/Model/Import/Config/_files/invalidImportMergedXmlArray.php @@ -30,7 +30,7 @@ 'behaviorModel="test" /></config>', [ "Element 'entity', attribute 'model': [facet 'pattern'] The value '34afwer' is not " . - "accepted by the pattern '[a-zA-Z_\\\\]+[a-zA-Z0-9_\\\\]+'.\nLine: 1\n", + "accepted by the pattern '([\\\\]?[a-zA-Z_][a-zA-Z0-9_]*)+'.\nLine: 1\n", "Element 'entity', attribute 'model': '34afwer' is not a valid value of the atomic type" . " 'modelName'.\nLine: 1\n" ], @@ -40,7 +40,7 @@ '</config>', [ "Element 'entity', attribute 'behaviorModel': [facet 'pattern'] The value '666' is not accepted by " . - "the pattern '[a-zA-Z_\\\\]+[a-zA-Z0-9_\\\\]+'.\nLine: 1\n", + "the pattern '([\\\\]?[a-zA-Z_][a-zA-Z0-9_]*)+'.\nLine: 1\n", "Element 'entity', attribute 'behaviorModel': '666' is not a valid value of the atomic type" . " 'modelName'.\nLine: 1\n" ], diff --git a/app/code/Magento/ImportExport/Test/Unit/Model/Import/Config/_files/invalidImportXmlArray.php b/app/code/Magento/ImportExport/Test/Unit/Model/Import/Config/_files/invalidImportXmlArray.php index 4b9d8e1c32f6d..c7b06a8731f02 100644 --- a/app/code/Magento/ImportExport/Test/Unit/Model/Import/Config/_files/invalidImportXmlArray.php +++ b/app/code/Magento/ImportExport/Test/Unit/Model/Import/Config/_files/invalidImportXmlArray.php @@ -19,7 +19,7 @@ '<?xml version="1.0"?><config><entity name="some_name" model="12345"/></config>', [ "Element 'entity', attribute 'model': [facet 'pattern'] The value '12345' is not accepted by " . - "the pattern '[a-zA-Z_\\\\]+[a-zA-Z0-9_\\\\]+'.\nLine: 1\n", + "the pattern '([\\\\]?[a-zA-Z_][a-zA-Z0-9_]*)+'.\nLine: 1\n", "Element 'entity', attribute 'model': '12345' is not a valid value of the atomic type" . " 'modelName'.\nLine: 1\n" ], @@ -28,7 +28,7 @@ '<?xml version="1.0"?><config><entity name="some_name" behaviorModel="=--09"/></config>', [ "Element 'entity', attribute 'behaviorModel': [facet 'pattern'] The value '=--09' is not " . - "accepted by the pattern '[a-zA-Z_\\\\]+[a-zA-Z0-9_\\\\]+'.\nLine: 1\n", + "accepted by the pattern '([\\\\]?[a-zA-Z_][a-zA-Z0-9_]*)+'.\nLine: 1\n", "Element 'entity', attribute 'behaviorModel': '=--09' is not a valid value of the atomic type" . " 'modelName'.\nLine: 1\n" ], @@ -49,7 +49,7 @@ '<?xml version="1.0"?><config><entityType entity="entity_name" name="some_name" model="1test"/></config>', [ "Element 'entityType', attribute 'model': [facet 'pattern'] The value '1test' is not " . - "accepted by the pattern '[a-zA-Z_\\\\]+[a-zA-Z0-9_\\\\]+'.\nLine: 1\n", + "accepted by the pattern '([\\\\]?[a-zA-Z_][a-zA-Z0-9_]*)+'.\nLine: 1\n", "Element 'entityType', attribute 'model': '1test' is not a valid value of the atomic type" . " 'modelName'.\nLine: 1\n" ], diff --git a/app/code/Magento/ImportExport/etc/export.xsd b/app/code/Magento/ImportExport/etc/export.xsd index b196ae0cb6f11..f62dbc891ef0f 100644 --- a/app/code/Magento/ImportExport/etc/export.xsd +++ b/app/code/Magento/ImportExport/etc/export.xsd @@ -71,11 +71,11 @@ <xs:simpleType name="modelName"> <xs:annotation> <xs:documentation> - Model name can contain only [a-zA-Z_\\]+[a-zA-Z0-9_\\]+. + Model name can contain only ([\\]?[a-zA-Z_][a-zA-Z0-9_]*)+. </xs:documentation> </xs:annotation> <xs:restriction base="xs:string"> - <xs:pattern value="[a-zA-Z_\\]+[a-zA-Z0-9_\\]+" /> + <xs:pattern value="([\\]?[a-zA-Z_][a-zA-Z0-9_]*)+" /> </xs:restriction> </xs:simpleType> </xs:schema> diff --git a/app/code/Magento/ImportExport/etc/import.xsd b/app/code/Magento/ImportExport/etc/import.xsd index 42bd365878eb2..e73038ebc0710 100644 --- a/app/code/Magento/ImportExport/etc/import.xsd +++ b/app/code/Magento/ImportExport/etc/import.xsd @@ -61,11 +61,11 @@ <xs:simpleType name="modelName"> <xs:annotation> <xs:documentation> - Model name can contain only [a-zA-Z_\\]+[a-zA-Z0-9_\\]+. + Model name can contain only ([\\]?[a-zA-Z_][a-zA-Z0-9_]*)+. </xs:documentation> </xs:annotation> <xs:restriction base="xs:string"> - <xs:pattern value="[a-zA-Z_\\]+[a-zA-Z0-9_\\]+" /> + <xs:pattern value="([\\]?[a-zA-Z_][a-zA-Z0-9_]*)+" /> </xs:restriction> </xs:simpleType> </xs:schema> From 290b998c6309d52e77c0c226e5317643ce915677 Mon Sep 17 00:00:00 2001 From: Oleksandr Iegorov <oiegorov@magento.com> Date: Wed, 6 Mar 2019 10:00:23 -0600 Subject: [PATCH 257/315] MAGETWO-98208: URLs not using SEO friendly format if you assign to website --- .../ProductToWebsiteChangeObserver.php | 9 +- .../ProductToWebsiteChangeObserverTest.php | 193 ++++++++++++++++++ 2 files changed, 201 insertions(+), 1 deletion(-) create mode 100644 app/code/Magento/CatalogUrlRewrite/Test/Unit/Observer/ProductToWebsiteChangeObserverTest.php diff --git a/app/code/Magento/CatalogUrlRewrite/Observer/ProductToWebsiteChangeObserver.php b/app/code/Magento/CatalogUrlRewrite/Observer/ProductToWebsiteChangeObserver.php index 94798753ca63f..12334a2a773cb 100644 --- a/app/code/Magento/CatalogUrlRewrite/Observer/ProductToWebsiteChangeObserver.php +++ b/app/code/Magento/CatalogUrlRewrite/Observer/ProductToWebsiteChangeObserver.php @@ -13,6 +13,8 @@ use Magento\Store\Model\Store; use Magento\UrlRewrite\Model\UrlPersistInterface; use Magento\UrlRewrite\Service\V1\Data\UrlRewrite; +use Magento\Framework\Exception\NoSuchEntityException; +use Magento\UrlRewrite\Model\Exception\UrlAlreadyExistsException; /** * Observer to assign the products to website. @@ -61,21 +63,26 @@ public function __construct( * Generate urls for UrlRewrite and save it in storage * * @param \Magento\Framework\Event\Observer $observer + * @throws NoSuchEntityException + * @throws UrlAlreadyExistsException * @return void */ public function execute(\Magento\Framework\Event\Observer $observer) { foreach ($observer->getEvent()->getProducts() as $productId) { + $storeId = $this->request->getParam('store_id', Store::DEFAULT_STORE_ID); + $product = $this->productRepository->getById( $productId, false, - $this->request->getParam('store_id', Store::DEFAULT_STORE_ID) + $storeId ); if (!empty($this->productUrlRewriteGenerator->generate($product))) { $this->urlPersist->deleteByData([ UrlRewrite::ENTITY_ID => $product->getId(), UrlRewrite::ENTITY_TYPE => ProductUrlRewriteGenerator::ENTITY_TYPE, + UrlRewrite::STORE_ID => $storeId, ]); if ($product->getVisibility() != Visibility::VISIBILITY_NOT_VISIBLE) { $this->urlPersist->replace($this->productUrlRewriteGenerator->generate($product)); diff --git a/app/code/Magento/CatalogUrlRewrite/Test/Unit/Observer/ProductToWebsiteChangeObserverTest.php b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Observer/ProductToWebsiteChangeObserverTest.php new file mode 100644 index 0000000000000..f383c949b4295 --- /dev/null +++ b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Observer/ProductToWebsiteChangeObserverTest.php @@ -0,0 +1,193 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +declare(strict_types=1); + +namespace Magento\CatalogUrlRewrite\Test\Unit\Observer; + +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; +use Magento\Framework\App\RequestInterface; +use Magento\Framework\Event; +use Magento\Framework\Event\Observer; +use Magento\Catalog\Model\Product; +use Magento\Catalog\Model\Product\Visibility; +use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\CatalogUrlRewrite\Observer\ProductToWebsiteChangeObserver; +use Magento\CatalogUrlRewrite\Model\ProductUrlRewriteGenerator; +use Magento\UrlRewrite\Model\UrlPersistInterface; +use Magento\UrlRewrite\Service\V1\Data\UrlRewrite; +use Magento\Store\Model\Store; + +/** + * Test for ProductToWebsiteChangeObserver + * + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + */ +class ProductToWebsiteChangeObserverTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var ProductRepositoryInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $productRepository; + + /** + * @var ProductUrlRewriteGenerator|\PHPUnit_Framework_MockObject_MockObject + */ + private $productUrlRewriteGenerator; + + /** + * @var UrlPersistInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $urlPersist; + + /** + * @var Event|\PHPUnit_Framework_MockObject_MockObject + */ + private $event; + + /** + * @var Observer|\PHPUnit_Framework_MockObject_MockObject + */ + private $observer; + + /** + * @var Product|\PHPUnit_Framework_MockObject_MockObject + */ + private $product; + + /** + * @var RequestInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $request; + + /** + * @var ObjectManager + */ + private $objectManager; + + /** + * @var ProductToWebsiteChangeObserver + */ + private $model; + + /** + * @var int + */ + private $productId; + + /** + * @inheritDoc + */ + protected function setUp() + { + $this->productId = 3; + + $this->urlPersist = $this->getMockBuilder(UrlPersistInterface::class) + ->setMethods(['deleteByData', 'replace']) + ->getMockForAbstractClass(); + $this->productRepository = $this->getMockBuilder(ProductRepositoryInterface::class) + ->setMethods(['getById']) + ->getMockForAbstractClass(); + $this->product = $this->getMockBuilder(Product::class) + ->disableOriginalConstructor() + ->setMethods(['getId', 'getVisibility']) + ->getMock(); + $this->product->expects($this->any()) + ->method('getId') + ->willReturn($this->productId); + $this->productRepository->expects($this->any()) + ->method('getById') + ->with($this->productId, false, Store::DEFAULT_STORE_ID) + ->willReturn($this->product); + $this->productUrlRewriteGenerator = $this->getMockBuilder(ProductUrlRewriteGenerator::class) + ->disableOriginalConstructor() + ->setMethods(['generate']) + ->getMock(); + $this->event = $this->getMockBuilder(Event::class) + ->disableOriginalConstructor() + ->setMethods(['getProducts']) + ->getMock(); + $this->event->expects($this->any()) + ->method('getProducts') + ->willReturn([$this->productId]); + $this->observer = $this->getMockBuilder(Observer::class) + ->disableOriginalConstructor() + ->setMethods(['getEvent']) + ->getMock(); + $this->observer->expects($this->any()) + ->method('getEvent') + ->willReturn($this->event); + $this->request = $this->getMockBuilder(RequestInterface::class) + ->setMethods(['getParam']) + ->getMockForAbstractClass(); + $this->request->expects($this->any()) + ->method('getParam') + ->with('store_id', Store::DEFAULT_STORE_ID) + ->willReturn(Store::DEFAULT_STORE_ID); + + $this->objectManager = new ObjectManager($this); + $this->model = $this->objectManager->getObject( + ProductToWebsiteChangeObserver::class, + [ + 'productUrlRewriteGenerator' => $this->productUrlRewriteGenerator, + 'urlPersist' => $this->urlPersist, + 'productRepository' => $this->productRepository, + 'request' => $this->request + ] + ); + } + + /** + * @param array $urlRewriteGeneratorResult + * @param int $numberDeleteByData + * @param int $productVisibility + * @param int $numberReplace + * @throws \Magento\Framework\Exception\NoSuchEntityException + * @throws \Magento\UrlRewrite\Model\Exception\UrlAlreadyExistsException + * @dataProvider executeDataProvider + */ + public function testExecute( + array $urlRewriteGeneratorResult, + int $numberDeleteByData, + int $productVisibility, + int $numberReplace + ) { + $this->productUrlRewriteGenerator->expects($this->any()) + ->method('generate') + ->willReturn($urlRewriteGeneratorResult); + $this->urlPersist->expects($this->exactly($numberDeleteByData)) + ->method('deleteByData') + ->with( + [ + UrlRewrite::ENTITY_ID => $this->productId, + UrlRewrite::ENTITY_TYPE => ProductUrlRewriteGenerator::ENTITY_TYPE, + UrlRewrite::STORE_ID => Store::DEFAULT_STORE_ID + ] + ); + $this->product->expects($this->any()) + ->method('getVisibility') + ->willReturn($productVisibility); + $this->urlPersist->expects($this->exactly($numberReplace)) + ->method('replace') + ->with($urlRewriteGeneratorResult); + + $this->model->execute($this->observer); + } + + /** + * Data provider for testExecute + * + * @return array + */ + public function executeDataProvider(): array + { + return [ + [[], 0, Visibility::VISIBILITY_NOT_VISIBLE, 0], + [['someRewrite'], 1, Visibility::VISIBILITY_NOT_VISIBLE, 0], + [['someRewrite'], 1, Visibility::VISIBILITY_BOTH, 1], + ]; + } +} From 715bd00fa49db50bdff175d8918e006120bcf2b9 Mon Sep 17 00:00:00 2001 From: Andrey Nikolaev <tonikolaev@gmail.com> Date: Wed, 13 Feb 2019 00:58:25 +0300 Subject: [PATCH 258/315] Fix issue with custom option file uploading --- lib/internal/Magento/Framework/Filesystem/DirectoryList.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/internal/Magento/Framework/Filesystem/DirectoryList.php b/lib/internal/Magento/Framework/Filesystem/DirectoryList.php index f07932d45ecb6..96818e4ff3b70 100644 --- a/lib/internal/Magento/Framework/Filesystem/DirectoryList.php +++ b/lib/internal/Magento/Framework/Filesystem/DirectoryList.php @@ -97,6 +97,10 @@ public function __construct($root, array $config = []) $this->root = $this->normalizePath($root); $this->directories = static::getDefaultConfig(); $this->directories[self::SYS_TMP] = [self::PATH => realpath(sys_get_temp_dir())]; + $uploadTmpDir = ini_get('upload_tmp_dir'); + if ($uploadTmpDir) { + $this->directories[self::SYS_TMP] = [self::PATH => realpath($uploadTmpDir)]; + } // inject custom values from constructor foreach ($this->directories as $code => $dir) { From 63e268c1332f8040cdb8b5c4583125b6e9e25dd4 Mon Sep 17 00:00:00 2001 From: Andrey Nikolaev <tonikolaev@gmail.com> Date: Wed, 13 Feb 2019 20:29:51 +0300 Subject: [PATCH 259/315] Simplify code by using ternary operator. --- .../Magento/Framework/Filesystem/DirectoryList.php | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/lib/internal/Magento/Framework/Filesystem/DirectoryList.php b/lib/internal/Magento/Framework/Filesystem/DirectoryList.php index 96818e4ff3b70..1d73b79398d27 100644 --- a/lib/internal/Magento/Framework/Filesystem/DirectoryList.php +++ b/lib/internal/Magento/Framework/Filesystem/DirectoryList.php @@ -96,11 +96,8 @@ public function __construct($root, array $config = []) static::validate($config); $this->root = $this->normalizePath($root); $this->directories = static::getDefaultConfig(); - $this->directories[self::SYS_TMP] = [self::PATH => realpath(sys_get_temp_dir())]; - $uploadTmpDir = ini_get('upload_tmp_dir'); - if ($uploadTmpDir) { - $this->directories[self::SYS_TMP] = [self::PATH => realpath($uploadTmpDir)]; - } + $sysTmpPath = ini_get('upload_tmp_dir') ? ini_get('upload_tmp_dir') : sys_get_temp_dir(); + $this->directories[self::SYS_TMP] = [self::PATH => realpath($sysTmpPath)]; // inject custom values from constructor foreach ($this->directories as $code => $dir) { From 4b3127e50242bea2e2e6bf6ea2b137470b219684 Mon Sep 17 00:00:00 2001 From: nmalevanec <mikola.malevanec@transoftgroup.com> Date: Mon, 4 Mar 2019 17:02:18 +0200 Subject: [PATCH 260/315] Fix static tests. --- lib/internal/Magento/Framework/Filesystem/DirectoryList.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Filesystem/DirectoryList.php b/lib/internal/Magento/Framework/Filesystem/DirectoryList.php index 1d73b79398d27..ef27cc19c4697 100644 --- a/lib/internal/Magento/Framework/Filesystem/DirectoryList.php +++ b/lib/internal/Magento/Framework/Filesystem/DirectoryList.php @@ -8,6 +8,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ + namespace Magento\Framework\Filesystem; /** @@ -96,7 +97,7 @@ public function __construct($root, array $config = []) static::validate($config); $this->root = $this->normalizePath($root); $this->directories = static::getDefaultConfig(); - $sysTmpPath = ini_get('upload_tmp_dir') ? ini_get('upload_tmp_dir') : sys_get_temp_dir(); + $sysTmpPath = get_cfg_var('upload_tmp_dir') ?: sys_get_temp_dir(); $this->directories[self::SYS_TMP] = [self::PATH => realpath($sysTmpPath)]; // inject custom values from constructor From ec51033a066a2684350d30bab3b459f0b7f04960 Mon Sep 17 00:00:00 2001 From: Jamie Pates <cyanoxide@gmail.com> Date: Fri, 8 Mar 2019 15:56:30 +0000 Subject: [PATCH 261/315] Improve swatch table overflow handling Add overflow:auto to the three swatch tables to allow for scrolling if the amount of inputs exceeds the available space and increase the min width of inputs (150px) within the table for better usability. Intentionally left original input width (50px) as a fallback. --- .../Swatches/view/adminhtml/web/css/swatches.css | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Swatches/view/adminhtml/web/css/swatches.css b/app/code/Magento/Swatches/view/adminhtml/web/css/swatches.css index 02a3f0324d955..67a5537e3274f 100644 --- a/app/code/Magento/Swatches/view/adminhtml/web/css/swatches.css +++ b/app/code/Magento/Swatches/view/adminhtml/web/css/swatches.css @@ -150,7 +150,19 @@ } .col-swatch-min-width { - min-width: 30px; + min-width: 65px; +} + +[class^=swatch-col], +[class^=col-]:not(.col-draggable):not(.col-default) { + min-width: 150px; +} + +#swatch-visual-options-panel, +#swatch-text-options-panel, +#manage-options-panel { + overflow: auto; + width: 100%; } .swatches-visual-col.unavailable:after { From f80d38218d0d42a297fe6f6727f5d63191093fad Mon Sep 17 00:00:00 2001 From: Mahesh Singh <mahesh721@webkul.com> Date: Fri, 15 Feb 2019 23:56:52 +0530 Subject: [PATCH 262/315] sort order added to downloable product links column --- .../Product/Form/Modifier/Links.php | 36 ++++++++++++------- .../Product/Form/Modifier/Samples.php | 12 ++++--- 2 files changed, 32 insertions(+), 16 deletions(-) diff --git a/app/code/Magento/Downloadable/Ui/DataProvider/Product/Form/Modifier/Links.php b/app/code/Magento/Downloadable/Ui/DataProvider/Product/Form/Modifier/Links.php index a352c4bdf7bc3..e367405416f0d 100644 --- a/app/code/Magento/Downloadable/Ui/DataProvider/Product/Form/Modifier/Links.php +++ b/app/code/Magento/Downloadable/Ui/DataProvider/Product/Form/Modifier/Links.php @@ -208,12 +208,12 @@ protected function getRecord() 'children', $record, [ - 'container_link_title' => $this->getTitleColumn(), - 'container_link_price' => $this->getPriceColumn(), - 'container_file' => $this->getFileColumn(), - 'container_sample' => $this->getSampleColumn(), - 'is_shareable' => $this->getShareableColumn(), - 'max_downloads' => $this->getMaxDownloadsColumn(), + 'container_link_title' => $this->getTitleColumn(10), + 'container_link_price' => $this->getPriceColumn(20), + 'container_file' => $this->getFileColumn(30), + 'container_sample' => $this->getSampleColumn(40), + 'is_shareable' => $this->getShareableColumn(50), + 'max_downloads' => $this->getMaxDownloadsColumn(60), 'position' => $recordPosition, 'action_delete' => $recordActionDelete, ] @@ -221,9 +221,10 @@ protected function getRecord() } /** + * @param int $sortOrder * @return array */ - protected function getTitleColumn() + protected function getTitleColumn($sortOrder) { $titleContainer['arguments']['data']['config'] = [ 'componentType' => Container::NAME, @@ -232,6 +233,7 @@ protected function getTitleColumn() 'label' => __('Title'), 'showLabel' => false, 'dataScope' => '', + 'sortOrder' => $sortOrder, ]; $titleField['arguments']['data']['config'] = [ 'formElement' => Form\Element\Input::NAME, @@ -247,9 +249,10 @@ protected function getTitleColumn() } /** + * @param int $sortOrder * @return array */ - protected function getPriceColumn() + protected function getPriceColumn($sortOrder) { $priceContainer['arguments']['data']['config'] = [ 'componentType' => Container::NAME, @@ -258,6 +261,7 @@ protected function getPriceColumn() 'label' => __('Price'), 'showLabel' => false, 'dataScope' => '', + 'sortOrder' => $sortOrder, ]; $priceField['arguments']['data']['config'] = [ 'formElement' => Form\Element\Input::NAME, @@ -281,9 +285,10 @@ protected function getPriceColumn() } /** + * @param int $sortOrder * @return array */ - protected function getFileColumn() + protected function getFileColumn($sortOrder) { $fileContainer['arguments']['data']['config'] = [ 'componentType' => Container::NAME, @@ -292,6 +297,7 @@ protected function getFileColumn() 'label' => __('File'), 'showLabel' => false, 'dataScope' => '', + 'sortOrder' => $sortOrder, ]; $fileTypeField['arguments']['data']['config'] = [ 'formElement' => Form\Element\Select::NAME, @@ -344,9 +350,10 @@ protected function getFileColumn() } /** + * @param int $sortOrder * @return array */ - protected function getSampleColumn() + protected function getSampleColumn($sortOrder) { $sampleContainer['arguments']['data']['config'] = [ 'componentType' => Container::NAME, @@ -355,6 +362,7 @@ protected function getSampleColumn() 'label' => __('Sample'), 'showLabel' => false, 'dataScope' => '', + 'sortOrder' => $sortOrder, ]; $sampleTypeField['arguments']['data']['config'] = [ 'formElement' => Form\Element\Select::NAME, @@ -403,9 +411,10 @@ protected function getSampleColumn() } /** + * @param int $sortOrder * @return array */ - protected function getShareableColumn() + protected function getShareableColumn($sortOrder) { $shareableField['arguments']['data']['config'] = [ 'label' => __('Shareable'), @@ -413,6 +422,7 @@ protected function getShareableColumn() 'componentType' => Form\Field::NAME, 'dataType' => Form\Element\DataType\Number::NAME, 'dataScope' => 'is_shareable', + 'sortOrder' => $sortOrder, 'options' => $this->shareable->toOptionArray(), ]; @@ -420,9 +430,10 @@ protected function getShareableColumn() } /** + * @param int $sortOrder * @return array */ - protected function getMaxDownloadsColumn() + protected function getMaxDownloadsColumn($sortOrder) { $maxDownloadsContainer['arguments']['data']['config'] = [ 'componentType' => Container::NAME, @@ -431,6 +442,7 @@ protected function getMaxDownloadsColumn() 'label' => __('Max. Downloads'), 'showLabel' => false, 'dataScope' => '', + 'sortOrder' => $sortOrder, ]; $numberOfDownloadsField['arguments']['data']['config'] = [ 'formElement' => Form\Element\Input::NAME, diff --git a/app/code/Magento/Downloadable/Ui/DataProvider/Product/Form/Modifier/Samples.php b/app/code/Magento/Downloadable/Ui/DataProvider/Product/Form/Modifier/Samples.php index 1587163ba8121..0dd94f2584218 100644 --- a/app/code/Magento/Downloadable/Ui/DataProvider/Product/Form/Modifier/Samples.php +++ b/app/code/Magento/Downloadable/Ui/DataProvider/Product/Form/Modifier/Samples.php @@ -183,8 +183,8 @@ protected function getRecord() 'children', $record, [ - 'container_sample_title' => $this->getTitleColumn(), - 'container_sample' => $this->getSampleColumn(), + 'container_sample_title' => $this->getTitleColumn(10), + 'container_sample' => $this->getSampleColumn(20), 'position' => $recordPosition, 'action_delete' => $recordActionDelete, ] @@ -192,9 +192,10 @@ protected function getRecord() } /** + * @param int $sortOrder * @return array */ - protected function getTitleColumn() + protected function getTitleColumn($sortOrder) { $titleContainer['arguments']['data']['config'] = [ 'componentType' => Container::NAME, @@ -203,6 +204,7 @@ protected function getTitleColumn() 'showLabel' => false, 'label' => __('Title'), 'dataScope' => '', + 'sortOrder' => $sortOrder, ]; $titleField['arguments']['data']['config'] = [ 'formElement' => Form\Element\Input::NAME, @@ -218,9 +220,10 @@ protected function getTitleColumn() } /** + * @param int $sortOrder * @return array */ - protected function getSampleColumn() + protected function getSampleColumn($sortOrder) { $sampleContainer['arguments']['data']['config'] = [ 'componentType' => Container::NAME, @@ -229,6 +232,7 @@ protected function getSampleColumn() 'label' => __('File'), 'showLabel' => false, 'dataScope' => '', + 'sortOrder' => $sortOrder, ]; $sampleType['arguments']['data']['config'] = [ 'formElement' => Form\Element\Select::NAME, From b7ad0754b9f78510ec1f47ddf866d70ed05f91fc Mon Sep 17 00:00:00 2001 From: Mahesh Singh <mahesh721@webkul.com> Date: Tue, 19 Feb 2019 22:42:35 +0530 Subject: [PATCH 263/315] backward compatibilty fixed --- .../Product/Form/Modifier/Links.php | 42 ++++++++----------- .../Product/Form/Modifier/Samples.php | 14 +++---- 2 files changed, 24 insertions(+), 32 deletions(-) diff --git a/app/code/Magento/Downloadable/Ui/DataProvider/Product/Form/Modifier/Links.php b/app/code/Magento/Downloadable/Ui/DataProvider/Product/Form/Modifier/Links.php index e367405416f0d..e4889b160963f 100644 --- a/app/code/Magento/Downloadable/Ui/DataProvider/Product/Form/Modifier/Links.php +++ b/app/code/Magento/Downloadable/Ui/DataProvider/Product/Form/Modifier/Links.php @@ -208,12 +208,12 @@ protected function getRecord() 'children', $record, [ - 'container_link_title' => $this->getTitleColumn(10), - 'container_link_price' => $this->getPriceColumn(20), - 'container_file' => $this->getFileColumn(30), - 'container_sample' => $this->getSampleColumn(40), - 'is_shareable' => $this->getShareableColumn(50), - 'max_downloads' => $this->getMaxDownloadsColumn(60), + 'container_link_title' => $this->getTitleColumn(), + 'container_link_price' => $this->getPriceColumn(), + 'container_file' => $this->getFileColumn(), + 'container_sample' => $this->getSampleColumn(), + 'is_shareable' => $this->getShareableColumn(), + 'max_downloads' => $this->getMaxDownloadsColumn(), 'position' => $recordPosition, 'action_delete' => $recordActionDelete, ] @@ -221,10 +221,9 @@ protected function getRecord() } /** - * @param int $sortOrder * @return array */ - protected function getTitleColumn($sortOrder) + protected function getTitleColumn() { $titleContainer['arguments']['data']['config'] = [ 'componentType' => Container::NAME, @@ -233,7 +232,7 @@ protected function getTitleColumn($sortOrder) 'label' => __('Title'), 'showLabel' => false, 'dataScope' => '', - 'sortOrder' => $sortOrder, + 'sortOrder' => 10, ]; $titleField['arguments']['data']['config'] = [ 'formElement' => Form\Element\Input::NAME, @@ -249,10 +248,9 @@ protected function getTitleColumn($sortOrder) } /** - * @param int $sortOrder * @return array */ - protected function getPriceColumn($sortOrder) + protected function getPriceColumn() { $priceContainer['arguments']['data']['config'] = [ 'componentType' => Container::NAME, @@ -261,7 +259,7 @@ protected function getPriceColumn($sortOrder) 'label' => __('Price'), 'showLabel' => false, 'dataScope' => '', - 'sortOrder' => $sortOrder, + 'sortOrder' => 20, ]; $priceField['arguments']['data']['config'] = [ 'formElement' => Form\Element\Input::NAME, @@ -285,10 +283,9 @@ protected function getPriceColumn($sortOrder) } /** - * @param int $sortOrder * @return array */ - protected function getFileColumn($sortOrder) + protected function getFileColumn() { $fileContainer['arguments']['data']['config'] = [ 'componentType' => Container::NAME, @@ -297,7 +294,7 @@ protected function getFileColumn($sortOrder) 'label' => __('File'), 'showLabel' => false, 'dataScope' => '', - 'sortOrder' => $sortOrder, + 'sortOrder' => 30, ]; $fileTypeField['arguments']['data']['config'] = [ 'formElement' => Form\Element\Select::NAME, @@ -350,10 +347,9 @@ protected function getFileColumn($sortOrder) } /** - * @param int $sortOrder * @return array */ - protected function getSampleColumn($sortOrder) + protected function getSampleColumn() { $sampleContainer['arguments']['data']['config'] = [ 'componentType' => Container::NAME, @@ -362,7 +358,7 @@ protected function getSampleColumn($sortOrder) 'label' => __('Sample'), 'showLabel' => false, 'dataScope' => '', - 'sortOrder' => $sortOrder, + 'sortOrder' => 40, ]; $sampleTypeField['arguments']['data']['config'] = [ 'formElement' => Form\Element\Select::NAME, @@ -411,10 +407,9 @@ protected function getSampleColumn($sortOrder) } /** - * @param int $sortOrder * @return array */ - protected function getShareableColumn($sortOrder) + protected function getShareableColumn() { $shareableField['arguments']['data']['config'] = [ 'label' => __('Shareable'), @@ -422,7 +417,7 @@ protected function getShareableColumn($sortOrder) 'componentType' => Form\Field::NAME, 'dataType' => Form\Element\DataType\Number::NAME, 'dataScope' => 'is_shareable', - 'sortOrder' => $sortOrder, + 'sortOrder' => 50, 'options' => $this->shareable->toOptionArray(), ]; @@ -430,10 +425,9 @@ protected function getShareableColumn($sortOrder) } /** - * @param int $sortOrder * @return array */ - protected function getMaxDownloadsColumn($sortOrder) + protected function getMaxDownloadsColumn() { $maxDownloadsContainer['arguments']['data']['config'] = [ 'componentType' => Container::NAME, @@ -442,7 +436,7 @@ protected function getMaxDownloadsColumn($sortOrder) 'label' => __('Max. Downloads'), 'showLabel' => false, 'dataScope' => '', - 'sortOrder' => $sortOrder, + 'sortOrder' => 60, ]; $numberOfDownloadsField['arguments']['data']['config'] = [ 'formElement' => Form\Element\Input::NAME, diff --git a/app/code/Magento/Downloadable/Ui/DataProvider/Product/Form/Modifier/Samples.php b/app/code/Magento/Downloadable/Ui/DataProvider/Product/Form/Modifier/Samples.php index 0dd94f2584218..b12c415b0b0b1 100644 --- a/app/code/Magento/Downloadable/Ui/DataProvider/Product/Form/Modifier/Samples.php +++ b/app/code/Magento/Downloadable/Ui/DataProvider/Product/Form/Modifier/Samples.php @@ -183,8 +183,8 @@ protected function getRecord() 'children', $record, [ - 'container_sample_title' => $this->getTitleColumn(10), - 'container_sample' => $this->getSampleColumn(20), + 'container_sample_title' => $this->getTitleColumn(), + 'container_sample' => $this->getSampleColumn(), 'position' => $recordPosition, 'action_delete' => $recordActionDelete, ] @@ -192,10 +192,9 @@ protected function getRecord() } /** - * @param int $sortOrder * @return array */ - protected function getTitleColumn($sortOrder) + protected function getTitleColumn() { $titleContainer['arguments']['data']['config'] = [ 'componentType' => Container::NAME, @@ -204,7 +203,7 @@ protected function getTitleColumn($sortOrder) 'showLabel' => false, 'label' => __('Title'), 'dataScope' => '', - 'sortOrder' => $sortOrder, + 'sortOrder' => 10, ]; $titleField['arguments']['data']['config'] = [ 'formElement' => Form\Element\Input::NAME, @@ -220,10 +219,9 @@ protected function getTitleColumn($sortOrder) } /** - * @param int $sortOrder * @return array */ - protected function getSampleColumn($sortOrder) + protected function getSampleColumn() { $sampleContainer['arguments']['data']['config'] = [ 'componentType' => Container::NAME, @@ -232,7 +230,7 @@ protected function getSampleColumn($sortOrder) 'label' => __('File'), 'showLabel' => false, 'dataScope' => '', - 'sortOrder' => $sortOrder, + 'sortOrder' => 20, ]; $sampleType['arguments']['data']['config'] = [ 'formElement' => Form\Element\Select::NAME, From a9016e9a58187fa8bb81cfecd6e0bc5bfdd6ce90 Mon Sep 17 00:00:00 2001 From: nmalevanec <mikola.malevanec@transoftgroup.com> Date: Mon, 4 Mar 2019 15:31:18 +0200 Subject: [PATCH 264/315] Fix static tests. --- .../Product/Form/Modifier/Links.php | 32 +++++++++++++++---- .../Product/Form/Modifier/Samples.php | 22 +++++++++---- 2 files changed, 41 insertions(+), 13 deletions(-) diff --git a/app/code/Magento/Downloadable/Ui/DataProvider/Product/Form/Modifier/Links.php b/app/code/Magento/Downloadable/Ui/DataProvider/Product/Form/Modifier/Links.php index e4889b160963f..9ab664cb27839 100644 --- a/app/code/Magento/Downloadable/Ui/DataProvider/Product/Form/Modifier/Links.php +++ b/app/code/Magento/Downloadable/Ui/DataProvider/Product/Form/Modifier/Links.php @@ -3,22 +3,24 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ + namespace Magento\Downloadable\Ui\DataProvider\Product\Form\Modifier; -use Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\AbstractModifier; use Magento\Catalog\Model\Locator\LocatorInterface; +use Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\AbstractModifier; use Magento\Downloadable\Model\Product\Type; -use Magento\Downloadable\Model\Source\TypeUpload; use Magento\Downloadable\Model\Source\Shareable; -use Magento\Store\Model\StoreManagerInterface; +use Magento\Downloadable\Model\Source\TypeUpload; use Magento\Framework\Stdlib\ArrayManager; -use Magento\Ui\Component\DynamicRows; use Magento\Framework\UrlInterface; +use Magento\Store\Model\StoreManagerInterface; use Magento\Ui\Component\Container; +use Magento\Ui\Component\DynamicRows; use Magento\Ui\Component\Form; /** - * Class adds a grid with links + * Class adds a grid with links. + * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class Links extends AbstractModifier @@ -86,7 +88,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function modifyData(array $data) { @@ -101,7 +103,7 @@ public function modifyData(array $data) } /** - * {@inheritdoc} + * @inheritdoc * @SuppressWarnings(PHPMD.ExcessiveMethodLength) */ public function modifyMeta(array $meta) @@ -160,6 +162,8 @@ public function modifyMeta(array $meta) } /** + * Get dynamic rows meta. + * * @return array */ protected function getDynamicRows() @@ -180,6 +184,8 @@ protected function getDynamicRows() } /** + * Get single link record meta. + * * @return array */ protected function getRecord() @@ -221,6 +227,8 @@ protected function getRecord() } /** + * Get link title meta. + * * @return array */ protected function getTitleColumn() @@ -248,6 +256,8 @@ protected function getTitleColumn() } /** + * Get link price meta. + * * @return array */ protected function getPriceColumn() @@ -283,6 +293,8 @@ protected function getPriceColumn() } /** + * Get link file element meta. + * * @return array */ protected function getFileColumn() @@ -347,6 +359,8 @@ protected function getFileColumn() } /** + * Get sample container meta. + * * @return array */ protected function getSampleColumn() @@ -407,6 +421,8 @@ protected function getSampleColumn() } /** + * Get link "is sharable" element meta. + * * @return array */ protected function getShareableColumn() @@ -425,6 +441,8 @@ protected function getShareableColumn() } /** + * Get link "max downloads" element meta. + * * @return array */ protected function getMaxDownloadsColumn() diff --git a/app/code/Magento/Downloadable/Ui/DataProvider/Product/Form/Modifier/Samples.php b/app/code/Magento/Downloadable/Ui/DataProvider/Product/Form/Modifier/Samples.php index b12c415b0b0b1..3890ee5b9e2b2 100644 --- a/app/code/Magento/Downloadable/Ui/DataProvider/Product/Form/Modifier/Samples.php +++ b/app/code/Magento/Downloadable/Ui/DataProvider/Product/Form/Modifier/Samples.php @@ -3,21 +3,23 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ + namespace Magento\Downloadable\Ui\DataProvider\Product\Form\Modifier; -use Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\AbstractModifier; use Magento\Catalog\Model\Locator\LocatorInterface; +use Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\AbstractModifier; use Magento\Downloadable\Model\Product\Type; use Magento\Downloadable\Model\Source\TypeUpload; -use Magento\Store\Model\StoreManagerInterface; use Magento\Framework\Stdlib\ArrayManager; -use Magento\Ui\Component\DynamicRows; use Magento\Framework\UrlInterface; +use Magento\Store\Model\StoreManagerInterface; use Magento\Ui\Component\Container; +use Magento\Ui\Component\DynamicRows; use Magento\Ui\Component\Form; /** - * Class adds a grid with samples + * Class adds a grid with samples. + * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class Samples extends AbstractModifier @@ -77,7 +79,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function modifyData(array $data) { @@ -90,7 +92,7 @@ public function modifyData(array $data) } /** - * {@inheritdoc} + * @inheritdoc * @SuppressWarnings(PHPMD.ExcessiveMethodLength) */ public function modifyMeta(array $meta) @@ -135,6 +137,8 @@ public function modifyMeta(array $meta) } /** + * Get sample rows meta. + * * @return array */ protected function getDynamicRows() @@ -155,6 +159,8 @@ protected function getDynamicRows() } /** + * Get single sample row meta. + * * @return array */ protected function getRecord() @@ -192,6 +198,8 @@ protected function getRecord() } /** + * Get sample title meta. + * * @return array */ protected function getTitleColumn() @@ -219,6 +227,8 @@ protected function getTitleColumn() } /** + * Get sample element meta. + * * @return array */ protected function getSampleColumn() From 6cb1f94d4396de971014683b5c2ff1a65b9695ff Mon Sep 17 00:00:00 2001 From: Serhiy Yelahin <serhiy.yelahin@transoftgroup.com> Date: Mon, 11 Mar 2019 15:00:31 +0200 Subject: [PATCH 265/315] MAGETWO-95020: Clicking on a Root Category causes all other Root Categories to be expanded to the top-level categories --- .../Catalog/Block/Adminhtml/Category/Tree.php | 34 +++++++++++++++++-- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Catalog/Block/Adminhtml/Category/Tree.php b/app/code/Magento/Catalog/Block/Adminhtml/Category/Tree.php index ed615b41644e2..020666838a79a 100644 --- a/app/code/Magento/Catalog/Block/Adminhtml/Category/Tree.php +++ b/app/code/Magento/Catalog/Block/Adminhtml/Category/Tree.php @@ -73,7 +73,7 @@ public function __construct( } /** - * @return void + * @inheritdoc */ protected function _construct() { @@ -82,7 +82,7 @@ protected function _construct() } /** - * @return $this + * @inheritdoc */ protected function _prepareLayout() { @@ -182,6 +182,8 @@ public function getSuggestedCategoriesJson($namePart) } /** + * Get add root button html + * * @return string */ public function getAddRootButtonHtml() @@ -190,6 +192,8 @@ public function getAddRootButtonHtml() } /** + * Get add sub button html + * * @return string */ public function getAddSubButtonHtml() @@ -198,6 +202,8 @@ public function getAddSubButtonHtml() } /** + * Get expand button html + * * @return string */ public function getExpandButtonHtml() @@ -206,6 +212,8 @@ public function getExpandButtonHtml() } /** + * Get collapse button html + * * @return string */ public function getCollapseButtonHtml() @@ -214,6 +222,8 @@ public function getCollapseButtonHtml() } /** + * Get store switcher + * * @return string */ public function getStoreSwitcherHtml() @@ -222,6 +232,8 @@ public function getStoreSwitcherHtml() } /** + * Get loader tree url + * * @param bool|null $expanded * @return string */ @@ -235,6 +247,8 @@ public function getLoadTreeUrl($expanded = null) } /** + * Get nodes url + * * @return string */ public function getNodesUrl() @@ -243,6 +257,8 @@ public function getNodesUrl() } /** + * Get switcher tree url + * * @return string */ public function getSwitchTreeUrl() @@ -254,6 +270,8 @@ public function getSwitchTreeUrl() } /** + * Get is was expanded + * * @return bool * @SuppressWarnings(PHPMD.BooleanGetMethodName) */ @@ -263,6 +281,8 @@ public function getIsWasExpanded() } /** + * Get move url + * * @return string */ public function getMoveUrl() @@ -271,6 +291,8 @@ public function getMoveUrl() } /** + * Get tree + * * @param mixed|null $parenNodeCategory * @return array */ @@ -282,6 +304,8 @@ public function getTree($parenNodeCategory = null) } /** + * Get tree json + * * @param mixed|null $parenNodeCategory * @return string */ @@ -367,7 +391,7 @@ protected function _getNodeJson($node, $level = 0) } } - if ($isParent || $node->getLevel() < 2) { + if ($isParent || $node->getLevel() < 1) { $item['expanded'] = true; } @@ -390,6 +414,8 @@ public function buildNodeName($node) } /** + * Is category movable + * * @param Node|array $node * @return bool */ @@ -403,6 +429,8 @@ protected function _isCategoryMoveable($node) } /** + * Is parent selected category + * * @param Node|array $node * @return bool */ From adf4425136c276f0e482f154198c4f39cc15d00d Mon Sep 17 00:00:00 2001 From: eduard13 <e.chitoraga@atwix.com> Date: Mon, 11 Mar 2019 16:40:15 +0200 Subject: [PATCH 266/315] Made configurable product variations table cell label hidden --- .../Form/Modifier/ConfigurablePanel.php | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/app/code/Magento/ConfigurableProduct/Ui/DataProvider/Product/Form/Modifier/ConfigurablePanel.php b/app/code/Magento/ConfigurableProduct/Ui/DataProvider/Product/Form/Modifier/ConfigurablePanel.php index 9fd225e8acaab..dcdffddbeeec0 100644 --- a/app/code/Magento/ConfigurableProduct/Ui/DataProvider/Product/Form/Modifier/ConfigurablePanel.php +++ b/app/code/Magento/ConfigurableProduct/Ui/DataProvider/Product/Form/Modifier/ConfigurablePanel.php @@ -5,14 +5,14 @@ */ namespace Magento\ConfigurableProduct\Ui\DataProvider\Product\Form\Modifier; +use Magento\Catalog\Model\Locator\LocatorInterface; use Magento\Catalog\Model\Product\Attribute\Backend\Sku; use Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\AbstractModifier; +use Magento\Framework\UrlInterface; use Magento\Ui\Component\Container; -use Magento\Ui\Component\Form; use Magento\Ui\Component\DynamicRows; +use Magento\Ui\Component\Form; use Magento\Ui\Component\Modal; -use Magento\Framework\UrlInterface; -use Magento\Catalog\Model\Locator\LocatorInterface; /** * Data provider for Configurable panel @@ -90,7 +90,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function modifyData(array $data) { @@ -98,7 +98,7 @@ public function modifyData(array $data) } /** - * {@inheritdoc} + * @inheritdoc * @SuppressWarnings(PHPMD.ExcessiveMethodLength) */ public function modifyMeta(array $meta) @@ -197,7 +197,7 @@ public function modifyMeta(array $meta) 'autoRender' => false, 'componentType' => 'insertListing', 'component' => 'Magento_ConfigurableProduct/js' - .'/components/associated-product-insert-listing', + . '/components/associated-product-insert-listing', 'dataScope' => $this->associatedListingPrefix . static::ASSOCIATED_PRODUCT_LISTING, 'externalProvider' => $this->associatedListingPrefix @@ -328,14 +328,12 @@ protected function getButtonSet() 'component' => 'Magento_Ui/js/form/components/button', 'actions' => [ [ - 'targetName' => - $this->dataScopeName . '.configurableModal', + 'targetName' => $this->dataScopeName . '.configurableModal', 'actionName' => 'trigger', 'params' => ['active', true], ], [ - 'targetName' => - $this->dataScopeName . '.configurableModal', + 'targetName' => $this->dataScopeName . '.configurableModal', 'actionName' => 'openModal', ], ], @@ -574,6 +572,7 @@ protected function getColumn( 'dataType' => Form\Element\DataType\Text::NAME, 'dataScope' => $name, 'visibleIfCanEdit' => false, + 'labelVisible' => false, 'imports' => [ 'visible' => '!${$.provider}:${$.parentScope}.canEdit' ], @@ -592,6 +591,7 @@ protected function getColumn( 'component' => 'Magento_Ui/js/form/components/group', 'label' => $label, 'dataScope' => '', + 'showLabel' => false ]; $container['children'] = [ $name . '_edit' => $fieldEdit, From b4283aa17b03927d8f2b0983b9b519b684610b5e Mon Sep 17 00:00:00 2001 From: Jitheesh <jitheeshvo@gmail.com> Date: Thu, 28 Feb 2019 15:04:11 +0530 Subject: [PATCH 267/315] Setting default sorting #21493 - Fixed default sort direction --- app/code/Magento/Customer/Block/Adminhtml/Edit/Tab/Orders.php | 3 ++- .../Magento/Customer/Block/Adminhtml/Edit/Tab/View/Cart.php | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Customer/Block/Adminhtml/Edit/Tab/Orders.php b/app/code/Magento/Customer/Block/Adminhtml/Edit/Tab/Orders.php index bb190260e4776..c1266febff99d 100644 --- a/app/code/Magento/Customer/Block/Adminhtml/Edit/Tab/Orders.php +++ b/app/code/Magento/Customer/Block/Adminhtml/Edit/Tab/Orders.php @@ -63,7 +63,8 @@ protected function _construct() { parent::_construct(); $this->setId('customer_orders_grid'); - $this->setDefaultSort('created_at', 'desc'); + $this->setDefaultSort('created_at'); + $this->setDefaultDir('desc'); $this->setUseAjax(true); } diff --git a/app/code/Magento/Customer/Block/Adminhtml/Edit/Tab/View/Cart.php b/app/code/Magento/Customer/Block/Adminhtml/Edit/Tab/View/Cart.php index d0973d3baf383..988a157805b36 100644 --- a/app/code/Magento/Customer/Block/Adminhtml/Edit/Tab/View/Cart.php +++ b/app/code/Magento/Customer/Block/Adminhtml/Edit/Tab/View/Cart.php @@ -77,7 +77,8 @@ protected function _construct() { parent::_construct(); $this->setId('customer_view_cart_grid'); - $this->setDefaultSort('added_at', 'desc'); + $this->setDefaultSort('added_at'); + $this->setDefaultDir('desc'); $this->setSortable(false); $this->setPagerVisibility(false); $this->setFilterVisibility(false); From a4a487829684c76c3b5dfd7e5786a9352dfb915f Mon Sep 17 00:00:00 2001 From: Sarfaraz Bheda <sarfaraz.bheda@krishtechnolabs.com> Date: Sat, 24 Nov 2018 16:16:25 +0530 Subject: [PATCH 268/315] 19276 - Fixed price renderer issue --- .../Swatches/view/frontend/web/js/swatch-renderer.js | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js b/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js index 3e28982ad44d3..2cb8bd1c25d46 100644 --- a/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js +++ b/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js @@ -918,7 +918,8 @@ define([ $productPrice = $product.find(this.options.selectorProductPrice), options = _.object(_.keys($widget.optionsMap), {}), result, - tierPriceHtml; + tierPriceHtml, + isShow; $widget.element.find('.' + $widget.options.classes.attributeClass + '[option-selected]').each(function () { var attributeId = $(this).attr('attribute-id'); @@ -935,11 +936,9 @@ define([ } ); - if (typeof result != 'undefined' && result.oldPrice.amount !== result.finalPrice.amount) { - $(this.options.slyOldPriceSelector).show(); - } else { - $(this.options.slyOldPriceSelector).hide(); - } + isShow = typeof result != 'undefined' && result.oldPrice.amount !== result.finalPrice.amount; + + $product.find(this.options.slyOldPriceSelector)[isShow ? 'show' : 'hide'](); if (typeof result != 'undefined' && result.tierPrices.length) { if (this.options.tierPriceTemplate) { From ec22cec535a36c0708cf2d0ce7fae97a11c4a644 Mon Sep 17 00:00:00 2001 From: Ievgen Shakhsuvarov <ishakhsuvarov@magento.com> Date: Mon, 4 Mar 2019 14:28:51 -0600 Subject: [PATCH 269/315] ENGCOM-4389: Adjust module naming convention to be compatible with 2.3.1 --- .../static/testsuite/Magento/Test/Integrity/ComposerTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tests/static/testsuite/Magento/Test/Integrity/ComposerTest.php b/dev/tests/static/testsuite/Magento/Test/Integrity/ComposerTest.php index 6fc84486c626b..2f1ab7a75bc83 100644 --- a/dev/tests/static/testsuite/Magento/Test/Integrity/ComposerTest.php +++ b/dev/tests/static/testsuite/Magento/Test/Integrity/ComposerTest.php @@ -452,7 +452,7 @@ private function convertModuleToPackageName($moduleName) { list($vendor, $name) = explode('_', $moduleName, 2); $package = 'module'; - foreach (preg_split('/([A-Z][a-z\d]+)/', $name, -1, PREG_SPLIT_DELIM_CAPTURE) as $chunk) { + foreach (preg_split('/([A-Z\d][a-z]*)/', $name, -1, PREG_SPLIT_DELIM_CAPTURE) as $chunk) { $package .= $chunk ? "-{$chunk}" : ''; } return strtolower("{$vendor}/{$package}"); From 46810b0771c4b646c6791f17347848082f3ec0b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20F=C3=BChr?= <d.fuehr@techdivision.com> Date: Wed, 30 Jan 2019 16:03:13 +0100 Subject: [PATCH 270/315] 14857: prevent cache drop for frontend caches on sitemap generation https://github.com/magento/magento2/issues/14857 Introduces a (dummy) cache tag for frontend in sitemap and robots generation. This prevents the default and page_cache to be dropped completely. The cache tag for full_page cache is not modified. --- app/code/Magento/Robots/Model/Config/Value.php | 2 +- app/code/Magento/Sitemap/Model/Sitemap.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Robots/Model/Config/Value.php b/app/code/Magento/Robots/Model/Config/Value.php index 83c21d6602fca..0619e9fd88a78 100644 --- a/app/code/Magento/Robots/Model/Config/Value.php +++ b/app/code/Magento/Robots/Model/Config/Value.php @@ -35,7 +35,7 @@ class Value extends ConfigValue implements IdentityInterface * @var string * @since 100.2.0 */ - protected $_cacheTag = true; + protected $_cacheTag = [self::CACHE_TAG]; /** * @var StoreResolver diff --git a/app/code/Magento/Sitemap/Model/Sitemap.php b/app/code/Magento/Sitemap/Model/Sitemap.php index dda1697da7fdf..823e403ff8fa2 100644 --- a/app/code/Magento/Sitemap/Model/Sitemap.php +++ b/app/code/Magento/Sitemap/Model/Sitemap.php @@ -160,7 +160,7 @@ class Sitemap extends \Magento\Framework\Model\AbstractModel implements \Magento * @var string * @since 100.2.0 */ - protected $_cacheTag = true; + protected $_cacheTag = [Value::CACHE_TAG]; /** * Last mode min timestamp value From c5993ce4e0c1b4a9e460d45734a63cebaea7488a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20F=C3=BChr?= <d.fuehr@techdivision.com> Date: Thu, 31 Jan 2019 13:58:32 +0100 Subject: [PATCH 271/315] amend touched DocBlocks --- app/code/Magento/Robots/Model/Config/Value.php | 3 +-- app/code/Magento/Sitemap/Model/Sitemap.php | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Robots/Model/Config/Value.php b/app/code/Magento/Robots/Model/Config/Value.php index 0619e9fd88a78..e520810ee5ef9 100644 --- a/app/code/Magento/Robots/Model/Config/Value.php +++ b/app/code/Magento/Robots/Model/Config/Value.php @@ -30,9 +30,8 @@ class Value extends ConfigValue implements IdentityInterface const CACHE_TAG = 'robots'; /** - * Model cache tag for clear cache in after save and after delete + * @inheritdoc * - * @var string * @since 100.2.0 */ protected $_cacheTag = [self::CACHE_TAG]; diff --git a/app/code/Magento/Sitemap/Model/Sitemap.php b/app/code/Magento/Sitemap/Model/Sitemap.php index 823e403ff8fa2..ff95276827336 100644 --- a/app/code/Magento/Sitemap/Model/Sitemap.php +++ b/app/code/Magento/Sitemap/Model/Sitemap.php @@ -155,9 +155,8 @@ class Sitemap extends \Magento\Framework\Model\AbstractModel implements \Magento protected $dateTime; /** - * Model cache tag for clear cache in after save and after delete + * @inheritdoc * - * @var string * @since 100.2.0 */ protected $_cacheTag = [Value::CACHE_TAG]; From a69a3d01a9e94e98ec224cf575c4b536ded92a4a Mon Sep 17 00:00:00 2001 From: nmalevanec <mikola.malevanec@transoftgroup.com> Date: Fri, 1 Mar 2019 15:26:43 +0200 Subject: [PATCH 272/315] Fix static tests. --- app/code/Magento/Robots/Model/Config/Value.php | 1 + app/code/Magento/Sitemap/Model/Sitemap.php | 1 + 2 files changed, 2 insertions(+) diff --git a/app/code/Magento/Robots/Model/Config/Value.php b/app/code/Magento/Robots/Model/Config/Value.php index e520810ee5ef9..4c80588d814f6 100644 --- a/app/code/Magento/Robots/Model/Config/Value.php +++ b/app/code/Magento/Robots/Model/Config/Value.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ + namespace Magento\Robots\Model\Config; use Magento\Framework\App\Cache\TypeListInterface; diff --git a/app/code/Magento/Sitemap/Model/Sitemap.php b/app/code/Magento/Sitemap/Model/Sitemap.php index ff95276827336..7279f6eda85d7 100644 --- a/app/code/Magento/Sitemap/Model/Sitemap.php +++ b/app/code/Magento/Sitemap/Model/Sitemap.php @@ -1,4 +1,5 @@ <?php + /** * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. From 9a839d176f1d8d1ec46d5ce47f7a8ba6cea76067 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20F=C3=BChr?= <d.fuehr@techdivision.com> Date: Tue, 22 Jan 2019 11:43:21 +0100 Subject: [PATCH 273/315] 19117: fix performance leak in salesrule collection Github Issue: https://github.com/magento/magento2/issues/19117 Refactored sql query that created a huge temporary table for each request, when a greater amount of salesrules and coupon codes exists in database. The sorting of this table took a lot of cpu time. The statement now consists of two subselects that drill down the remaining lines as far as possible, so that the remaining temporary table is minimal and easily sorted. example: for 2,000 salesrules and 3,000,000 coupon codes the original query took about 2.4 seconds (mbp, server, aws). the optimized query takes about 5ms (about 100ms on aws). --- .../Model/ResourceModel/Rule/Collection.php | 185 ++++++++++-------- 1 file changed, 101 insertions(+), 84 deletions(-) diff --git a/app/code/Magento/SalesRule/Model/ResourceModel/Rule/Collection.php b/app/code/Magento/SalesRule/Model/ResourceModel/Rule/Collection.php index 5e6f3847c8e31..352b5d4c809c9 100644 --- a/app/code/Magento/SalesRule/Model/ResourceModel/Rule/Collection.php +++ b/app/code/Magento/SalesRule/Model/ResourceModel/Rule/Collection.php @@ -107,12 +107,15 @@ protected function mapAssociatedEntities($entityType, $objectField) $associatedEntities = $this->getConnection()->fetchAll($select); - array_map(function ($associatedEntity) use ($entityInfo, $ruleIdField, $objectField) { - $item = $this->getItemByColumnValue($ruleIdField, $associatedEntity[$ruleIdField]); - $itemAssociatedValue = $item->getData($objectField) === null ? [] : $item->getData($objectField); - $itemAssociatedValue[] = $associatedEntity[$entityInfo['entity_id_field']]; - $item->setData($objectField, $itemAssociatedValue); - }, $associatedEntities); + array_map( + function ($associatedEntity) use ($entityInfo, $ruleIdField, $objectField) { + $item = $this->getItemByColumnValue($ruleIdField, $associatedEntity[$ruleIdField]); + $itemAssociatedValue = $item->getData($objectField) === null ? [] : $item->getData($objectField); + $itemAssociatedValue[] = $associatedEntity[$entityInfo['entity_id_field']]; + $item->setData($objectField, $itemAssociatedValue); + }, + $associatedEntities + ); } /** @@ -144,6 +147,7 @@ protected function _afterLoad() * @use $this->addWebsiteGroupDateFilter() * @SuppressWarnings(PHPMD.UnusedFormalParameter) * @return $this + * @throws \Zend_Db_Select_Exception */ public function setValidationFilter( $websiteId, @@ -153,32 +157,21 @@ public function setValidationFilter( Address $address = null ) { if (!$this->getFlag('validation_filter')) { - /* We need to overwrite joinLeft if coupon is applied */ - $this->getSelect()->reset(); - parent::_initSelect(); - $this->addWebsiteGroupDateFilter($websiteId, $customerGroupId, $now); - $select = $this->getSelect(); + $this->prepareSelect($websiteId, $customerGroupId, $now); - $connection = $this->getConnection(); - if (strlen($couponCode)) { - $noCouponWhereCondition = $connection->quoteInto( - 'main_table.coupon_type = ?', - \Magento\SalesRule\Model\Rule::COUPON_TYPE_NO_COUPON - ); - $relatedRulesIds = $this->getCouponRelatedRuleIds($couponCode); - - $select->where( - $noCouponWhereCondition . ' OR main_table.rule_id IN (?)', - $relatedRulesIds, - Select::TYPE_CONDITION - ); + $noCouponRules = $this->getNoCouponCodeSelect(); + + if ($couponCode) { + $couponRules = $this->getCouponCodeSelect($couponCode); + $allAllowedRules = $this->getConnection()->select(); + $allAllowedRules->union([$noCouponRules, $couponRules], \Zend_Db_Select::SQL_UNION_ALL); + + $this->_select = $allAllowedRules; } else { - $this->addFieldToFilter( - 'main_table.coupon_type', - \Magento\SalesRule\Model\Rule::COUPON_TYPE_NO_COUPON - ); + $this->_select = $noCouponRules; } + $this->setOrder('sort_order', self::SORT_ORDER_ASC); $this->setFlag('validation_filter', true); } @@ -187,72 +180,96 @@ public function setValidationFilter( } /** - * Get rules ids related to coupon code + * Recreate the default select object for specific needs of salesrule evaluation with coupon codes. * - * @param string $couponCode - * @return array + * @param $websiteId + * @param $customerGroupId + * @param $now */ - private function getCouponRelatedRuleIds(string $couponCode): array + private function prepareSelect($websiteId, $customerGroupId, $now) { - $connection = $this->getConnection(); - $select = $connection->select()->from( - ['main_table' => $this->getTable('salesrule')], - 'rule_id' + $this->getSelect()->reset(); + parent::_initSelect(); + + $this->addWebsiteGroupDateFilter($websiteId, $customerGroupId, $now); + } + + /** + * Return select object to determine all active rules not needing a coupon code. + * + * @return Select + */ + private function getNoCouponCodeSelect() + { + $noCouponSelect = clone $this->getSelect(); + + $noCouponSelect->where( + 'main_table.coupon_type = ?', + Rule::COUPON_TYPE_NO_COUPON ); - $select->joinLeft( - ['rule_coupons' => $this->getTable('salesrule_coupon')], - $connection->quoteInto( - 'main_table.rule_id = rule_coupons.rule_id AND main_table.coupon_type != ?', - \Magento\SalesRule\Model\Rule::COUPON_TYPE_NO_COUPON, - null - ) + + $noCouponSelect->columns([Coupon::KEY_CODE => new \Zend_Db_Expr('NULL')]); + + return $noCouponSelect; + } + + /** + * Determine all active rules that are valid for the given coupon code. + * + * @param $couponCode + * @return Select + */ + private function getCouponCodeSelect($couponCode) + { + $couponSelect = clone $this->getSelect(); + + $this->joinCouponTable($couponCode, $couponSelect); + + $notExpired = $this->getConnection()->quoteInto( + '(rule_coupons.expiration_date IS NULL OR rule_coupons.expiration_date >= ?)', + $this->_date->date()->format('Y-m-d') ); - $autoGeneratedCouponCondition = [ - $connection->quoteInto( - "main_table.coupon_type = ?", - \Magento\SalesRule\Model\Rule::COUPON_TYPE_AUTO - ), - $connection->quoteInto( - "rule_coupons.type = ?", - \Magento\SalesRule\Api\Data\CouponInterface::TYPE_GENERATED - ), - ]; - - $orWhereConditions = [ - "(" . implode($autoGeneratedCouponCondition, " AND ") . ")", - $connection->quoteInto( - '(main_table.coupon_type = ? AND main_table.use_auto_generation = 1 AND rule_coupons.type = 1)', - \Magento\SalesRule\Model\Rule::COUPON_TYPE_SPECIFIC - ), - $connection->quoteInto( - '(main_table.coupon_type = ? AND main_table.use_auto_generation = 0 AND rule_coupons.type = 0)', - \Magento\SalesRule\Model\Rule::COUPON_TYPE_SPECIFIC - ), - ]; - - $andWhereConditions = [ - $connection->quoteInto( - 'rule_coupons.code = ?', - $couponCode - ), - $connection->quoteInto( - '(rule_coupons.expiration_date IS NULL OR rule_coupons.expiration_date >= ?)', - $this->_date->date()->format('Y-m-d') - ), - ]; - - $orWhereCondition = implode(' OR ', $orWhereConditions); - $andWhereCondition = implode(' AND ', $andWhereConditions); - - $select->where( - '(' . $orWhereCondition . ') AND ' . $andWhereCondition, + $isAutogeneratedCoupon = + $this->getConnection()->quoteInto('main_table.coupon_type = ?', Rule::COUPON_TYPE_AUTO) + . ' AND ' . + $this->getConnection()->quoteInto('rule_coupons.type = ?', CouponInterface::TYPE_GENERATED); + + $isValidSpecificCoupon = + $this->getConnection()->quoteInto('(main_table.coupon_type = ?)', Rule::COUPON_TYPE_SPECIFIC) + . ' AND (' . + '(main_table.use_auto_generation = 1 AND rule_coupons.type = 1)' + . ' OR ' . + '(main_table.use_auto_generation = 0 AND rule_coupons.type = 0)' + . ')'; + + $couponSelect->where( + "$notExpired AND ($isAutogeneratedCoupon OR $isValidSpecificCoupon)", null, Select::TYPE_CONDITION ); - $select->group('main_table.rule_id'); - return $connection->fetchCol($select); + return $couponSelect; + } + + /** + * @param $couponCode + * @param Select $couponSelect + */ + private function joinCouponTable($couponCode, Select $couponSelect) + { + $couponJoinCondition = + 'main_table.rule_id = rule_coupons.rule_id' + . ' AND ' . + $this->getConnection()->quoteInto('main_table.coupon_type <> ?', Rule::COUPON_TYPE_NO_COUPON) + . ' AND ' . + $this->getConnection()->quoteInto('rule_coupons.code = ?', $couponCode); + + $couponSelect->joinInner( + ['rule_coupons' => $this->getTable('salesrule_coupon')], + $couponJoinCondition, + [Coupon::KEY_CODE] + ); } /** From 8e7ddbf4656b15fd37b1321cadabed9d9175ea6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20F=C3=BChr?= <d.fuehr@techdivision.com> Date: Tue, 22 Jan 2019 20:56:31 +0100 Subject: [PATCH 274/315] Fix integration error preventing coupon codes to be applied. --- .../SalesRule/Model/ResourceModel/Rule/Collection.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/SalesRule/Model/ResourceModel/Rule/Collection.php b/app/code/Magento/SalesRule/Model/ResourceModel/Rule/Collection.php index 352b5d4c809c9..2a6bf17342504 100644 --- a/app/code/Magento/SalesRule/Model/ResourceModel/Rule/Collection.php +++ b/app/code/Magento/SalesRule/Model/ResourceModel/Rule/Collection.php @@ -167,7 +167,10 @@ public function setValidationFilter( $allAllowedRules = $this->getConnection()->select(); $allAllowedRules->union([$noCouponRules, $couponRules], \Zend_Db_Select::SQL_UNION_ALL); - $this->_select = $allAllowedRules; + $wrapper = $this->getConnection()->select(); + $wrapper->from($allAllowedRules); + + $this->_select = $wrapper; } else { $this->_select = $noCouponRules; } From a3e87bdfbefe486eb5217b8dbdded50fffde1236 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20F=C3=BChr?= <d.fuehr@techdivision.com> Date: Wed, 23 Jan 2019 09:32:43 +0100 Subject: [PATCH 275/315] Rename variable to comply to codestyle standards --- .../SalesRule/Model/ResourceModel/Rule/Collection.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/SalesRule/Model/ResourceModel/Rule/Collection.php b/app/code/Magento/SalesRule/Model/ResourceModel/Rule/Collection.php index 2a6bf17342504..04c54bf5b7e01 100644 --- a/app/code/Magento/SalesRule/Model/ResourceModel/Rule/Collection.php +++ b/app/code/Magento/SalesRule/Model/ResourceModel/Rule/Collection.php @@ -233,12 +233,12 @@ private function getCouponCodeSelect($couponCode) $this->_date->date()->format('Y-m-d') ); - $isAutogeneratedCoupon = + $isAutogenerated = $this->getConnection()->quoteInto('main_table.coupon_type = ?', Rule::COUPON_TYPE_AUTO) . ' AND ' . $this->getConnection()->quoteInto('rule_coupons.type = ?', CouponInterface::TYPE_GENERATED); - $isValidSpecificCoupon = + $isValidSpecific = $this->getConnection()->quoteInto('(main_table.coupon_type = ?)', Rule::COUPON_TYPE_SPECIFIC) . ' AND (' . '(main_table.use_auto_generation = 1 AND rule_coupons.type = 1)' @@ -247,7 +247,7 @@ private function getCouponCodeSelect($couponCode) . ')'; $couponSelect->where( - "$notExpired AND ($isAutogeneratedCoupon OR $isValidSpecificCoupon)", + "$notExpired AND ($isAutogenerated OR $isValidSpecific)", null, Select::TYPE_CONDITION ); From bfd1d4f7c38c0fe3c8e17449b621bbc5c996d59b Mon Sep 17 00:00:00 2001 From: nmalevanec <mikola.malevanec@transoftgroup.com> Date: Fri, 1 Mar 2019 15:09:21 +0200 Subject: [PATCH 276/315] Fix static tests. --- .../Model/ResourceModel/Rule/Collection.php | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/app/code/Magento/SalesRule/Model/ResourceModel/Rule/Collection.php b/app/code/Magento/SalesRule/Model/ResourceModel/Rule/Collection.php index 04c54bf5b7e01..9446a053f6d0e 100644 --- a/app/code/Magento/SalesRule/Model/ResourceModel/Rule/Collection.php +++ b/app/code/Magento/SalesRule/Model/ResourceModel/Rule/Collection.php @@ -157,7 +157,6 @@ public function setValidationFilter( Address $address = null ) { if (!$this->getFlag('validation_filter')) { - $this->prepareSelect($websiteId, $customerGroupId, $now); $noCouponRules = $this->getNoCouponCodeSelect(); @@ -165,7 +164,7 @@ public function setValidationFilter( if ($couponCode) { $couponRules = $this->getCouponCodeSelect($couponCode); $allAllowedRules = $this->getConnection()->select(); - $allAllowedRules->union([$noCouponRules, $couponRules], \Zend_Db_Select::SQL_UNION_ALL); + $allAllowedRules->union([$noCouponRules, $couponRules], Select::SQL_UNION_ALL); $wrapper = $this->getConnection()->select(); $wrapper->from($allAllowedRules); @@ -185,9 +184,9 @@ public function setValidationFilter( /** * Recreate the default select object for specific needs of salesrule evaluation with coupon codes. * - * @param $websiteId - * @param $customerGroupId - * @param $now + * @param int $websiteId + * @param int $customerGroupId + * @param string $now */ private function prepareSelect($websiteId, $customerGroupId, $now) { @@ -219,7 +218,7 @@ private function getNoCouponCodeSelect() /** * Determine all active rules that are valid for the given coupon code. * - * @param $couponCode + * @param string $couponCode * @return Select */ private function getCouponCodeSelect($couponCode) @@ -256,7 +255,9 @@ private function getCouponCodeSelect($couponCode) } /** - * @param $couponCode + * Join coupon table to select. + * + * @param string $couponCode * @param Select $couponSelect */ private function joinCouponTable($couponCode, Select $couponSelect) From 8b8a46c4beb8cf3c4c0d881660f442d4df545782 Mon Sep 17 00:00:00 2001 From: Ihor Sviziev <ihor-sviziev@users.noreply.github.com> Date: Tue, 12 Mar 2019 11:41:14 +0200 Subject: [PATCH 277/315] magento/magento2#19098 2.2.6 Use batches and direct queries to fix sales address upgrade Fix field name --- app/code/Magento/Sales/Setup/UpgradeData.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Sales/Setup/UpgradeData.php b/app/code/Magento/Sales/Setup/UpgradeData.php index 0f9833ed8f7f2..ee60eef03726d 100644 --- a/app/code/Magento/Sales/Setup/UpgradeData.php +++ b/app/code/Magento/Sales/Setup/UpgradeData.php @@ -244,7 +244,7 @@ private function fillQuoteAddressIdInSalesOrderAddressProcessBatch( 'quote_address_id' => $quoteAddresses[$orderAddress['quote_id']]['address_id'] ?? null, ]; $where = [ - 'orderAddressId' => $orderAddress['entity_id'] + 'entity_id' => $orderAddress['entity_id'] ]; $salesConnection->update($salesOrderAddressTable, $bind, $where); From 571cf9bfd6ba69ef2c8f4f7a6f1dacb17452a495 Mon Sep 17 00:00:00 2001 From: Ihor Sviziev <ihor-sviziev@users.noreply.github.com> Date: Tue, 12 Mar 2019 11:55:18 +0200 Subject: [PATCH 278/315] magento/magento2#21699 Backport Fix performance leak in salesrule collection Unify PRs to be the same --- .../Magento/SalesRule/Model/ResourceModel/Rule/Collection.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/SalesRule/Model/ResourceModel/Rule/Collection.php b/app/code/Magento/SalesRule/Model/ResourceModel/Rule/Collection.php index 9446a053f6d0e..105bbeaa11d1b 100644 --- a/app/code/Magento/SalesRule/Model/ResourceModel/Rule/Collection.php +++ b/app/code/Magento/SalesRule/Model/ResourceModel/Rule/Collection.php @@ -163,6 +163,7 @@ public function setValidationFilter( if ($couponCode) { $couponRules = $this->getCouponCodeSelect($couponCode); + $allAllowedRules = $this->getConnection()->select(); $allAllowedRules->union([$noCouponRules, $couponRules], Select::SQL_UNION_ALL); From ea34b66bd90957d7495428f3adff94f83c92dbb5 Mon Sep 17 00:00:00 2001 From: Ihor Sviziev <ihor-sviziev@users.noreply.github.com> Date: Tue, 12 Mar 2019 11:58:07 +0200 Subject: [PATCH 279/315] magento/magento2#21699 Backport Fix performance leak in salesrule collection Unify PRs to be the same --- .../Magento/SalesRule/Model/ResourceModel/Rule/Collection.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/code/Magento/SalesRule/Model/ResourceModel/Rule/Collection.php b/app/code/Magento/SalesRule/Model/ResourceModel/Rule/Collection.php index 105bbeaa11d1b..c45400f65047f 100644 --- a/app/code/Magento/SalesRule/Model/ResourceModel/Rule/Collection.php +++ b/app/code/Magento/SalesRule/Model/ResourceModel/Rule/Collection.php @@ -9,6 +9,9 @@ use Magento\Framework\DB\Select; use Magento\Framework\Serialize\Serializer\Json; use Magento\Quote\Model\Quote\Address; +use Magento\SalesRule\Api\Data\CouponInterface; +use Magento\SalesRule\Model\Coupon; +use Magento\SalesRule\Model\Rule; /** * Sales Rules resource collection model. From dbf671438ef01bf9cc8882c7a36bb28bea280434 Mon Sep 17 00:00:00 2001 From: Ihor Sviziev <ihor-sviziev@users.noreply.github.com> Date: Tue, 12 Mar 2019 12:00:20 +0200 Subject: [PATCH 280/315] magento/magento2#21699 Backport Fix performance leak in salesrule collection Unify PRs to be the same --- .../Magento/SalesRule/Model/ResourceModel/Rule/Collection.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/SalesRule/Model/ResourceModel/Rule/Collection.php b/app/code/Magento/SalesRule/Model/ResourceModel/Rule/Collection.php index c45400f65047f..423cd1543117b 100644 --- a/app/code/Magento/SalesRule/Model/ResourceModel/Rule/Collection.php +++ b/app/code/Magento/SalesRule/Model/ResourceModel/Rule/Collection.php @@ -147,10 +147,10 @@ protected function _afterLoad() * @param string $couponCode * @param string|null $now * @param Address $address allow extensions to further filter out rules based on quote address + * @throws \Zend_Db_Select_Exception * @use $this->addWebsiteGroupDateFilter() * @SuppressWarnings(PHPMD.UnusedFormalParameter) * @return $this - * @throws \Zend_Db_Select_Exception */ public function setValidationFilter( $websiteId, From 57508634320241a9582d390760e118ee55af6760 Mon Sep 17 00:00:00 2001 From: Dmytro Horytskyi <horytsky@adobe.com> Date: Tue, 12 Mar 2019 09:51:59 -0500 Subject: [PATCH 281/315] MAGETWO-98626: [Magento Cloud] Translated Arabic URL's are returning 404's --- .../UrlRewrite/Model/Storage/DbStorage.php | 121 ++++++++++++------ .../Model/UrlFinderInterfaceTest.php | 71 ++++++++++ .../UrlRewrite/_files/url_rewrites.php | 42 ++++++ .../_files/url_rewrites_rollback.php | 20 +++ 4 files changed, 218 insertions(+), 36 deletions(-) create mode 100644 dev/tests/integration/testsuite/Magento/UrlRewrite/Model/UrlFinderInterfaceTest.php create mode 100644 dev/tests/integration/testsuite/Magento/UrlRewrite/_files/url_rewrites.php create mode 100644 dev/tests/integration/testsuite/Magento/UrlRewrite/_files/url_rewrites_rollback.php diff --git a/app/code/Magento/UrlRewrite/Model/Storage/DbStorage.php b/app/code/Magento/UrlRewrite/Model/Storage/DbStorage.php index 60b845f95e5cc..f98801c266109 100644 --- a/app/code/Magento/UrlRewrite/Model/Storage/DbStorage.php +++ b/app/code/Magento/UrlRewrite/Model/Storage/DbStorage.php @@ -14,6 +14,9 @@ use Psr\Log\LoggerInterface; use Magento\UrlRewrite\Service\V1\Data\UrlRewrite as UrlRewriteData; +/** + * DB storage implementation for url rewrites + */ class DbStorage extends AbstractStorage { /** @@ -37,7 +40,7 @@ class DbStorage extends AbstractStorage protected $resource; /** - * @var \Psr\Log\LoggerInterface + * @var LoggerInterface */ private $logger; @@ -45,7 +48,7 @@ class DbStorage extends AbstractStorage * @param \Magento\UrlRewrite\Service\V1\Data\UrlRewriteFactory $urlRewriteFactory * @param DataObjectHelper $dataObjectHelper * @param \Magento\Framework\App\ResourceConnection $resource - * @param \Psr\Log\LoggerInterface|null $logger + * @param LoggerInterface|null $logger */ public function __construct( UrlRewriteFactory $urlRewriteFactory, @@ -56,7 +59,7 @@ public function __construct( $this->connection = $resource->getConnection(); $this->resource = $resource; $this->logger = $logger ?: \Magento\Framework\App\ObjectManager::getInstance() - ->get(\Psr\Log\LoggerInterface::class); + ->get(LoggerInterface::class); parent::__construct($urlRewriteFactory, $dataObjectHelper); } @@ -97,42 +100,18 @@ protected function doFindOneByData(array $data) $result = null; $requestPath = $data[UrlRewrite::REQUEST_PATH]; - - $data[UrlRewrite::REQUEST_PATH] = [ + $decodedRequestPath = urldecode($requestPath); + $data[UrlRewrite::REQUEST_PATH] = array_unique([ rtrim($requestPath, '/'), rtrim($requestPath, '/') . '/', - ]; + rtrim($decodedRequestPath, '/'), + rtrim($decodedRequestPath, '/') . '/', + ]); $resultsFromDb = $this->connection->fetchAll($this->prepareSelect($data)); - - if (count($resultsFromDb) === 1) { - $resultFromDb = current($resultsFromDb); - $redirectTypes = [OptionProvider::TEMPORARY, OptionProvider::PERMANENT]; - - // If request path matches the DB value or it's redirect - we can return result from DB - $canReturnResultFromDb = ($resultFromDb[UrlRewrite::REQUEST_PATH] === $requestPath - || in_array((int)$resultFromDb[UrlRewrite::REDIRECT_TYPE], $redirectTypes, true)); - - // Otherwise return 301 redirect to request path from DB results - $result = $canReturnResultFromDb ? $resultFromDb : [ - UrlRewrite::ENTITY_TYPE => 'custom', - UrlRewrite::ENTITY_ID => '0', - UrlRewrite::REQUEST_PATH => $requestPath, - UrlRewrite::TARGET_PATH => $resultFromDb[UrlRewrite::REQUEST_PATH], - UrlRewrite::REDIRECT_TYPE => OptionProvider::PERMANENT, - UrlRewrite::STORE_ID => $resultFromDb[UrlRewrite::STORE_ID], - UrlRewrite::DESCRIPTION => null, - UrlRewrite::IS_AUTOGENERATED => '0', - UrlRewrite::METADATA => null, - ]; - } else { - // If we have 2 results - return the row that matches request path - foreach ($resultsFromDb as $resultFromDb) { - if ($resultFromDb[UrlRewrite::REQUEST_PATH] === $requestPath) { - $result = $resultFromDb; - break; - } - } + if ($resultsFromDb) { + $urlRewrite = $this->extractMostRelevantUrlRewrite($requestPath, $resultsFromDb); + $result = $this->prepareUrlRewrite($requestPath, $urlRewrite); } return $result; @@ -142,8 +121,78 @@ protected function doFindOneByData(array $data) } /** - * @param UrlRewrite[] $urls + * Extract most relevant url rewrite from url rewrites list + * + * @param string $requestPath + * @param array $urlRewrites + * @return array|null + */ + private function extractMostRelevantUrlRewrite(string $requestPath, array $urlRewrites) + { + $prioritizedUrlRewrites = []; + foreach ($urlRewrites as $urlRewrite) { + switch (true) { + case $urlRewrite[UrlRewrite::REQUEST_PATH] === $requestPath: + $priority = 1; + break; + case $urlRewrite[UrlRewrite::REQUEST_PATH] === urldecode($requestPath): + $priority = 2; + break; + case rtrim($urlRewrite[UrlRewrite::REQUEST_PATH], '/') === rtrim($requestPath, '/'): + $priority = 3; + break; + case rtrim($urlRewrite[UrlRewrite::REQUEST_PATH], '/') === rtrim(urldecode($requestPath), '/'): + $priority = 4; + break; + default: + $priority = 5; + break; + } + $prioritizedUrlRewrites[$priority] = $urlRewrite; + } + ksort($prioritizedUrlRewrites); + + return array_shift($prioritizedUrlRewrites); + } + + /** + * Prepare url rewrite * + * If request path matches the DB value or it's redirect - we can return result from DB + * Otherwise return 301 redirect to request path from DB results + * + * @param string $requestPath + * @param array $urlRewrite + * @return array + */ + private function prepareUrlRewrite(string $requestPath, array $urlRewrite): array + { + $redirectTypes = [OptionProvider::TEMPORARY, OptionProvider::PERMANENT]; + $canReturnResultFromDb = ( + in_array($urlRewrite[UrlRewrite::REQUEST_PATH], [$requestPath, urldecode($requestPath)], true) + || in_array((int) $urlRewrite[UrlRewrite::REDIRECT_TYPE], $redirectTypes, true) + ); + if (!$canReturnResultFromDb) { + $urlRewrite = [ + UrlRewrite::ENTITY_TYPE => 'custom', + UrlRewrite::ENTITY_ID => '0', + UrlRewrite::REQUEST_PATH => $requestPath, + UrlRewrite::TARGET_PATH => $urlRewrite[UrlRewrite::REQUEST_PATH], + UrlRewrite::REDIRECT_TYPE => OptionProvider::PERMANENT, + UrlRewrite::STORE_ID => $urlRewrite[UrlRewrite::STORE_ID], + UrlRewrite::DESCRIPTION => null, + UrlRewrite::IS_AUTOGENERATED => '0', + UrlRewrite::METADATA => null, + ]; + } + + return $urlRewrite; + } + + /** + * Delete old url rewrites + * + * @param UrlRewrite[] $urls * @return void */ private function deleteOldUrls(array $urls) diff --git a/dev/tests/integration/testsuite/Magento/UrlRewrite/Model/UrlFinderInterfaceTest.php b/dev/tests/integration/testsuite/Magento/UrlRewrite/Model/UrlFinderInterfaceTest.php new file mode 100644 index 0000000000000..b6055f14e79d2 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/UrlRewrite/Model/UrlFinderInterfaceTest.php @@ -0,0 +1,71 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\UrlRewrite\Model; + +use Magento\TestFramework\Helper\Bootstrap; +use Magento\UrlRewrite\Service\V1\Data\UrlRewrite; + +/** + * @magentoDataFixture Magento/UrlRewrite/_files/url_rewrites.php + */ +class UrlFinderInterfaceTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var UrlFinderInterface + */ + private $urlFinder; + + /** + * @inheritdoc + */ + protected function setUp() + { + $this->urlFinder = Bootstrap::getObjectManager()->create(UrlFinderInterface::class); + } + + /** + * @dataProvider findOneDataProvider + * @param string $requestPath + * @param string $targetPath + * @param int $redirectType + */ + public function testFindOneByData(string $requestPath, string $targetPath, int $redirectType) + { + $data = [ + UrlRewrite::REQUEST_PATH => $requestPath, + ]; + $urlRewrite = $this->urlFinder->findOneByData($data); + $this->assertEquals($targetPath, $urlRewrite->getTargetPath()); + $this->assertEquals($redirectType, $urlRewrite->getRedirectType()); + } + + /** + * @return array + */ + public function findOneDataProvider(): array + { + return [ + ['string', 'test_page1', 0], + ['string/', 'string', 301], + ['string_permanent', 'test_page1', 301], + ['string_permanent/', 'test_page1', 301], + ['string_temporary', 'test_page1', 302], + ['string_temporary/', 'test_page1', 302], + ['строка', 'test_page1', 0], + ['строка/', 'строка', 301], + [urlencode('строка'), 'test_page2', 0], + [urlencode('строка') . '/', urlencode('строка'), 301], + ['другая_строка', 'test_page1', 302], + ['другая_строка/', 'test_page1', 302], + [urlencode('другая_строка'), 'test_page1', 302], + [urlencode('другая_строка') . '/', 'test_page1', 302], + ['السلسلة', 'test_page1', 0], + [urlencode('السلسلة'), 'test_page1', 0], + ]; + } +} diff --git a/dev/tests/integration/testsuite/Magento/UrlRewrite/_files/url_rewrites.php b/dev/tests/integration/testsuite/Magento/UrlRewrite/_files/url_rewrites.php new file mode 100644 index 0000000000000..9edc6507308ee --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/UrlRewrite/_files/url_rewrites.php @@ -0,0 +1,42 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + +$rewritesData = [ + [ + 'string', 'test_page1', 0 + ], + [ + 'string_permanent', 'test_page1', \Magento\UrlRewrite\Model\OptionProvider::PERMANENT + ], + [ + 'string_temporary', 'test_page1', \Magento\UrlRewrite\Model\OptionProvider::TEMPORARY + ], + [ + 'строка', 'test_page1', 0 + ], + [ + urlencode('строка'), 'test_page2', 0 + ], + [ + 'другая_строка', 'test_page1', \Magento\UrlRewrite\Model\OptionProvider::TEMPORARY + ], + [ + 'السلسلة', 'test_page1', 0 + ], +]; + +$rewriteResource = $objectManager->create(\Magento\UrlRewrite\Model\ResourceModel\UrlRewrite::class); +foreach ($rewritesData as $rewriteData) { + list ($requestPath, $targetPath, $redirectType) = $rewriteData; + $rewrite = $objectManager->create(\Magento\UrlRewrite\Model\UrlRewrite::class); + $rewrite->setEntityType('custom') + ->setRequestPath($requestPath) + ->setTargetPath($targetPath) + ->setRedirectType($redirectType); + $rewriteResource->save($rewrite); +} diff --git a/dev/tests/integration/testsuite/Magento/UrlRewrite/_files/url_rewrites_rollback.php b/dev/tests/integration/testsuite/Magento/UrlRewrite/_files/url_rewrites_rollback.php new file mode 100644 index 0000000000000..a98f947d614e0 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/UrlRewrite/_files/url_rewrites_rollback.php @@ -0,0 +1,20 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + +$registry = $objectManager->get(\Magento\Framework\Registry::class); +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', true); + +$urlRewriteCollection = $objectManager->create(\Magento\UrlRewrite\Model\ResourceModel\UrlRewriteCollection::class); +$collection = $urlRewriteCollection + ->addFieldToFilter('target_path', ['test_page1', 'test_page2']) + ->load() + ->walk('delete'); + +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', false); From df364432458bc551964a14cc1c1aaa50110c72e3 Mon Sep 17 00:00:00 2001 From: Ihor Sviziev <ihor-sviziev@users.noreply.github.com> Date: Tue, 12 Mar 2019 20:08:59 +0200 Subject: [PATCH 282/315] magento/magento2#19098 Use batches and direct queries to fix sales address upgrade --- app/code/Magento/Sales/Setup/UpgradeData.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Sales/Setup/UpgradeData.php b/app/code/Magento/Sales/Setup/UpgradeData.php index ee60eef03726d..2e5a454e62fdd 100644 --- a/app/code/Magento/Sales/Setup/UpgradeData.php +++ b/app/code/Magento/Sales/Setup/UpgradeData.php @@ -244,7 +244,7 @@ private function fillQuoteAddressIdInSalesOrderAddressProcessBatch( 'quote_address_id' => $quoteAddresses[$orderAddress['quote_id']]['address_id'] ?? null, ]; $where = [ - 'entity_id' => $orderAddress['entity_id'] + 'entity_id = ?' => $orderAddress['entity_id'] ]; $salesConnection->update($salesOrderAddressTable, $bind, $where); From 5cc67fc4f8468dc340f9a9c210b6aa9c1db694c2 Mon Sep 17 00:00:00 2001 From: Dmytro Horytskyi <horytsky@adobe.com> Date: Tue, 12 Mar 2019 15:44:08 -0500 Subject: [PATCH 283/315] MAGETWO-98470: Special price not removing at website scope --- .../Eav/Model/Entity/AbstractEntity.php | 8 +++-- .../Model/ResourceModel/ProductTest.php | 34 ++++++++++++++++--- 2 files changed, 34 insertions(+), 8 deletions(-) diff --git a/app/code/Magento/Eav/Model/Entity/AbstractEntity.php b/app/code/Magento/Eav/Model/Entity/AbstractEntity.php index 7f01cf268d06b..7f6734b8b6b60 100644 --- a/app/code/Magento/Eav/Model/Entity/AbstractEntity.php +++ b/app/code/Magento/Eav/Model/Entity/AbstractEntity.php @@ -1695,14 +1695,16 @@ public function saveAttribute(DataObject $object, $attributeCode) $connection->beginTransaction(); try { - $select = $connection->select()->from($table, 'value_id')->where($where); - $origValueId = $connection->fetchOne($select); + $select = $connection->select()->from($table, ['value_id', 'value'])->where($where); + $origRow = $connection->fetchRow($select); + $origValueId = $origRow['value_id'] ?? false; + $origValue = $origRow['value'] ?? null; if ($origValueId === false && $newValue !== null) { $this->_insertAttribute($object, $attribute, $newValue); } elseif ($origValueId !== false && $newValue !== null) { $this->_updateAttribute($object, $attribute, $origValueId, $newValue); - } elseif ($origValueId !== false && $newValue === null) { + } elseif ($origValueId !== false && $newValue === null && $origValue !== null) { $connection->delete($table, $where); } $this->_processAttributeValues(); diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/ProductTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/ProductTest.php index 7954e2c36227f..476f01eb277df 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/ProductTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/ProductTest.php @@ -12,6 +12,11 @@ class ProductTest extends TestCase { + /** + * @var ProductRepositoryInterface + */ + private $productRepository; + /** * @var Product */ @@ -29,7 +34,8 @@ protected function setUp() { $this->objectManager = Bootstrap::getObjectManager(); - $this->model = $this->objectManager->get(Product::class); + $this->productRepository = $this->objectManager->create(ProductRepositoryInterface::class); + $this->model = $this->objectManager->create(Product::class); } /** @@ -42,11 +48,29 @@ public function testGetAttributeRawValue() $sku = 'simple'; $attribute = 'name'; - /** @var ProductRepositoryInterface $productRepository */ - $productRepository = $this->objectManager->get(ProductRepositoryInterface::class); - $product = $productRepository->get($sku); - + $product = $this->productRepository->get($sku); $actual = $this->model->getAttributeRawValue($product->getId(), $attribute, null); self::assertEquals($product->getName(), $actual); } + + /** + * @magentoAppArea adminhtml + * @magentoDataFixture Magento/Catalog/_files/product_special_price.php + * @magentoAppIsolation enabled + * @magentoConfigFixture default_store catalog/price/scope 1 + */ + public function testUpdateStoreSpecificSpecialPrice() + { + /** @var \Magento\Catalog\Model\Product $product */ + $product = $this->productRepository->get('simple', true, 1); + $this->assertEquals(5.99, $product->getSpecialPrice()); + + $product->setSpecialPrice(''); + $this->model->save($product); + $product = $this->productRepository->get('simple', false, 1, true); + $this->assertEmpty($product->getSpecialPrice()); + + $product = $this->productRepository->get('simple', false, 0, true); + $this->assertEquals(5.99, $product->getSpecialPrice()); + } } From f8a1eb526a4dbac17f093fb29fb3a5e9e853ae82 Mon Sep 17 00:00:00 2001 From: Dmytro Horytskyi <horytsky@adobe.com> Date: Tue, 12 Mar 2019 17:31:13 -0500 Subject: [PATCH 284/315] MAGETWO-98554: [Magento cloud] Media directories not sorted --- app/code/Magento/Cms/Model/Wysiwyg/Images/Storage.php | 3 ++- .../Cms/Test/Unit/Model/Wysiwyg/Images/StorageTest.php | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Cms/Model/Wysiwyg/Images/Storage.php b/app/code/Magento/Cms/Model/Wysiwyg/Images/Storage.php index 2cd1647a1bf22..90dcf3dc8df78 100644 --- a/app/code/Magento/Cms/Model/Wysiwyg/Images/Storage.php +++ b/app/code/Magento/Cms/Model/Wysiwyg/Images/Storage.php @@ -270,7 +270,8 @@ public function getDirsCollection($path) $collection = $this->getCollection($path) ->setCollectDirs(true) ->setCollectFiles(false) - ->setCollectRecursively(false); + ->setCollectRecursively(false) + ->setOrder('basename', \Magento\Framework\Data\Collection\Filesystem::SORT_ORDER_ASC); $conditions = $this->getConditionsForExcludeDirs(); diff --git a/app/code/Magento/Cms/Test/Unit/Model/Wysiwyg/Images/StorageTest.php b/app/code/Magento/Cms/Test/Unit/Model/Wysiwyg/Images/StorageTest.php index 906a7d4fbc605..20c0b2075f5c3 100644 --- a/app/code/Magento/Cms/Test/Unit/Model/Wysiwyg/Images/StorageTest.php +++ b/app/code/Magento/Cms/Test/Unit/Model/Wysiwyg/Images/StorageTest.php @@ -414,6 +414,10 @@ protected function generalTestGetDirsCollection($path, $collectionArray = [], $e ->method('setCollectRecursively') ->with(false) ->willReturnSelf(); + $storageCollectionMock->expects($this->once()) + ->method('setOrder') + ->with('basename', \Magento\Framework\Data\Collection\Filesystem::SORT_ORDER_ASC) + ->willReturnSelf(); $storageCollectionMock->expects($this->once()) ->method('getIterator') ->willReturn(new \ArrayIterator($collectionArray)); From 2aed503fbb4b8bdee75bcc25ebded80b65ad8b5e Mon Sep 17 00:00:00 2001 From: Denis Kopylov <dkopylov@magenius.team> Date: Mon, 25 Feb 2019 19:06:22 +0300 Subject: [PATCH 285/315] Add review summary to wishlist (https://github.com/magento/magento2/issues/21419) --- .../Block/Customer/Wishlist/Item/Column/Actions.php | 1 + .../Block/Customer/Wishlist/Item/Column/Comment.php | 1 + .../Block/Customer/Wishlist/Item/Column/Edit.php | 1 + .../Block/Customer/Wishlist/Item/Column/Info.php | 1 + .../Block/Customer/Wishlist/Item/Column/Remove.php | 1 + .../view/frontend/layout/wishlist_index_index.xml | 13 +++++++------ .../frontend/templates/item/column/actions.phtml | 2 +- .../frontend/templates/item/column/comment.phtml | 2 +- .../view/frontend/templates/item/column/edit.phtml | 2 +- .../view/frontend/templates/item/column/name.phtml | 2 +- .../frontend/templates/item/column/remove.phtml | 2 +- .../frontend/templates/item/column/review.phtml | 10 ++++++++++ 12 files changed, 27 insertions(+), 11 deletions(-) create mode 100644 app/code/Magento/Wishlist/view/frontend/templates/item/column/review.phtml diff --git a/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Column/Actions.php b/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Column/Actions.php index cafb6a5291481..0cf6b6a9867d1 100644 --- a/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Column/Actions.php +++ b/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Column/Actions.php @@ -13,6 +13,7 @@ /** * @api + * @deprecated Empty class * @since 100.0.2 */ class Actions extends \Magento\Wishlist\Block\Customer\Wishlist\Item\Column diff --git a/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Column/Comment.php b/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Column/Comment.php index 2d75956858a0a..5f40e96bfa6ff 100644 --- a/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Column/Comment.php +++ b/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Column/Comment.php @@ -13,6 +13,7 @@ /** * @api + * @deprecated Empty class * @since 100.0.2 */ class Comment extends \Magento\Wishlist\Block\Customer\Wishlist\Item\Column diff --git a/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Column/Edit.php b/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Column/Edit.php index 53ca78c63524d..c4e94ec503175 100644 --- a/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Column/Edit.php +++ b/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Column/Edit.php @@ -13,6 +13,7 @@ /** * @api + * @deprecated Empty class * @since 100.0.2 */ class Edit extends \Magento\Wishlist\Block\Customer\Wishlist\Item\Column diff --git a/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Column/Info.php b/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Column/Info.php index 33fb0f7325cdd..f83c122910ebd 100644 --- a/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Column/Info.php +++ b/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Column/Info.php @@ -13,6 +13,7 @@ /** * @api + * @deprecated Empty class * @since 100.0.2 */ class Info extends \Magento\Wishlist\Block\Customer\Wishlist\Item\Column diff --git a/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Column/Remove.php b/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Column/Remove.php index 57703b9300db8..3e6f225842e01 100644 --- a/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Column/Remove.php +++ b/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Column/Remove.php @@ -13,6 +13,7 @@ /** * @api + * @deprecated Empty class * @since 100.0.2 */ class Remove extends \Magento\Wishlist\Block\Customer\Wishlist\Item\Column diff --git a/app/code/Magento/Wishlist/view/frontend/layout/wishlist_index_index.xml b/app/code/Magento/Wishlist/view/frontend/layout/wishlist_index_index.xml index 243a06062425a..836f7f404a381 100644 --- a/app/code/Magento/Wishlist/view/frontend/layout/wishlist_index_index.xml +++ b/app/code/Magento/Wishlist/view/frontend/layout/wishlist_index_index.xml @@ -16,7 +16,8 @@ <block class="Magento\Wishlist\Block\Rss\Link" name="wishlist.rss.link" template="Magento_Wishlist::rss/wishlist.phtml"/> <block class="Magento\Wishlist\Block\Customer\Wishlist\Items" name="customer.wishlist.items" as="items" template="Magento_Wishlist::item/list.phtml" cacheable="false"> <block class="Magento\Wishlist\Block\Customer\Wishlist\Item\Column\Image" name="customer.wishlist.item.image" template="Magento_Wishlist::item/column/image.phtml" cacheable="false"/> - <block class="Magento\Wishlist\Block\Customer\Wishlist\Item\Column\Info" name="customer.wishlist.item.name" template="Magento_Wishlist::item/column/name.phtml" cacheable="false"/> + <block class="Magento\Wishlist\Block\Customer\Wishlist\Item\Column" name="customer.wishlist.item.name" template="Magento_Wishlist::item/column/name.phtml" cacheable="false"/> + <block class="Magento\Wishlist\Block\Customer\Wishlist\Item\Column" name="customer.wishlist.item.review" template="Magento_Wishlist::item/column/review.phtml" cacheable="false"/> <block class="Magento\Wishlist\Block\Customer\Wishlist\Item\Column\Cart" name="customer.wishlist.item.price" template="Magento_Wishlist::item/column/price.phtml" cacheable="false"> <block class="Magento\Catalog\Pricing\Render" name="product.price.render.wishlist"> <arguments> @@ -28,11 +29,11 @@ </block> <block class="Magento\Wishlist\Block\Customer\Wishlist\Item\Options" name="customer.wishlist.item.options" cacheable="false"/> </block> - <block class="Magento\Wishlist\Block\Customer\Wishlist\Item\Column\Actions" name="customer.wishlist.item.inner" template="Magento_Wishlist::item/column/actions.phtml" cacheable="false"> + <block class="Magento\Wishlist\Block\Customer\Wishlist\Item\Column" name="customer.wishlist.item.inner" template="Magento_Wishlist::item/column/actions.phtml" cacheable="false"> <arguments> <argument name="css_class" xsi:type="string">product-item-inner</argument> </arguments> - <block class="Magento\Wishlist\Block\Customer\Wishlist\Item\Column\Comment" name="customer.wishlist.item.comment" template="Magento_Wishlist::item/column/comment.phtml" cacheable="false"> + <block class="Magento\Wishlist\Block\Customer\Wishlist\Item\Column" name="customer.wishlist.item.comment" template="Magento_Wishlist::item/column/comment.phtml" cacheable="false"> <arguments> <argument name="title" translate="true" xsi:type="string">Product Details and Comment</argument> </arguments> @@ -43,12 +44,12 @@ </arguments> </block> - <block class="Magento\Wishlist\Block\Customer\Wishlist\Item\Column\Actions" name="customer.wishlist.item.actions" template="Magento_Wishlist::item/column/actions.phtml" cacheable="false"> + <block class="Magento\Wishlist\Block\Customer\Wishlist\Item\Column" name="customer.wishlist.item.actions" template="Magento_Wishlist::item/column/actions.phtml" cacheable="false"> <arguments> <argument name="css_class" xsi:type="string">product-item-actions</argument> </arguments> - <block class="Magento\Wishlist\Block\Customer\Wishlist\Item\Column\Edit" name="customer.wishlist.item.edit" template="Magento_Wishlist::item/column/edit.phtml" before="-" cacheable="false"/> - <block class="Magento\Wishlist\Block\Customer\Wishlist\Item\Column\Remove" name="customer.wishlist.item.remove" template="Magento_Wishlist::item/column/remove.phtml" cacheable="false"/> + <block class="Magento\Wishlist\Block\Customer\Wishlist\Item\Column" name="customer.wishlist.item.edit" template="Magento_Wishlist::item/column/edit.phtml" before="-" cacheable="false"/> + <block class="Magento\Wishlist\Block\Customer\Wishlist\Item\Column" name="customer.wishlist.item.remove" template="Magento_Wishlist::item/column/remove.phtml" cacheable="false"/> </block> </block> </block> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/item/column/actions.phtml b/app/code/Magento/Wishlist/view/frontend/templates/item/column/actions.phtml index 0b50df8c59fbb..7fa55a839b2ea 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/item/column/actions.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/item/column/actions.phtml @@ -6,7 +6,7 @@ // @codingStandardsIgnoreFile -/** @var \Magento\Wishlist\Block\Customer\Wishlist\Item\Column\Actions $block */ +/** @var \Magento\Wishlist\Block\Customer\Wishlist\Item\Column $block */ ?> <?php $children = $block->getChildNames(); ?> <?php if ($children): ?> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/item/column/comment.phtml b/app/code/Magento/Wishlist/view/frontend/templates/item/column/comment.phtml index 17e2404ee23cf..45bd7494fed4f 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/item/column/comment.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/item/column/comment.phtml @@ -6,7 +6,7 @@ // @codingStandardsIgnoreFile -/* @var \Magento\Wishlist\Block\Customer\Wishlist\Item\Column\Comment $block */ +/* @var \Magento\Wishlist\Block\Customer\Wishlist\Item\Column $block */ /* @var \Magento\Wishlist\Model\Item $item */ $item = $block->getItem(); diff --git a/app/code/Magento/Wishlist/view/frontend/templates/item/column/edit.phtml b/app/code/Magento/Wishlist/view/frontend/templates/item/column/edit.phtml index 1898ef6fc0d66..81d770d556734 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/item/column/edit.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/item/column/edit.phtml @@ -6,7 +6,7 @@ // @codingStandardsIgnoreFile -/** @var \Magento\Wishlist\Block\Customer\Wishlist\Item\Column\Edit $block */ +/** @var \Magento\Wishlist\Block\Customer\Wishlist\Item\Column $block */ /** @var \Magento\Wishlist\Model\Item $item */ $item = $block->getItem(); diff --git a/app/code/Magento/Wishlist/view/frontend/templates/item/column/name.phtml b/app/code/Magento/Wishlist/view/frontend/templates/item/column/name.phtml index 265f4635a6be3..53c5f35f886ea 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/item/column/name.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/item/column/name.phtml @@ -6,7 +6,7 @@ // @codingStandardsIgnoreFile -/** @var \Magento\Wishlist\Block\Customer\Wishlist\Item\Column\Info $block */ +/** @var \Magento\Wishlist\Block\Customer\Wishlist\Item\Column $block */ /** @var \Magento\Wishlist\Model\Item $item */ $item = $block->getItem(); diff --git a/app/code/Magento/Wishlist/view/frontend/templates/item/column/remove.phtml b/app/code/Magento/Wishlist/view/frontend/templates/item/column/remove.phtml index 57ae439d9995b..0bd78ba38ba58 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/item/column/remove.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/item/column/remove.phtml @@ -6,7 +6,7 @@ // @codingStandardsIgnoreFile -/* @var \Magento\Wishlist\Block\Customer\Wishlist\Item\Column\Remove $block */ +/* @var \Magento\Wishlist\Block\Customer\Wishlist\Item\Column $block */ ?> <a href="#" data-role="remove" data-post-remove='<?= /* @noEscape */ $block->getItemRemoveParams($block->getItem()) ?>' title="<?= $block->escapeHtmlAttr(__('Remove Item')) ?>" class="btn-remove action delete"> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/item/column/review.phtml b/app/code/Magento/Wishlist/view/frontend/templates/item/column/review.phtml new file mode 100644 index 0000000000000..9120cc9fa684e --- /dev/null +++ b/app/code/Magento/Wishlist/view/frontend/templates/item/column/review.phtml @@ -0,0 +1,10 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +/** @var \Magento\Wishlist\Block\Customer\Wishlist\Item\Column $block */ +$product = $block->getItem()->getProduct(); +?> +<?= $block->getReviewsSummaryHtml($product, 'short') ?> From f0b3b92960f79366325ed8ce7f68e97bc23d5b71 Mon Sep 17 00:00:00 2001 From: Denis Kopylov <dkopylov@magenius.team> Date: Tue, 26 Feb 2019 19:31:34 +0300 Subject: [PATCH 286/315] Revert usage of deprecate marked classes in layout --- .../view/frontend/layout/wishlist_index_index.xml | 12 ++++++------ .../frontend/templates/item/column/actions.phtml | 2 +- .../frontend/templates/item/column/comment.phtml | 2 +- .../view/frontend/templates/item/column/edit.phtml | 2 +- .../view/frontend/templates/item/column/name.phtml | 2 +- .../view/frontend/templates/item/column/remove.phtml | 2 +- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/app/code/Magento/Wishlist/view/frontend/layout/wishlist_index_index.xml b/app/code/Magento/Wishlist/view/frontend/layout/wishlist_index_index.xml index 836f7f404a381..218b5ac1c879b 100644 --- a/app/code/Magento/Wishlist/view/frontend/layout/wishlist_index_index.xml +++ b/app/code/Magento/Wishlist/view/frontend/layout/wishlist_index_index.xml @@ -16,7 +16,7 @@ <block class="Magento\Wishlist\Block\Rss\Link" name="wishlist.rss.link" template="Magento_Wishlist::rss/wishlist.phtml"/> <block class="Magento\Wishlist\Block\Customer\Wishlist\Items" name="customer.wishlist.items" as="items" template="Magento_Wishlist::item/list.phtml" cacheable="false"> <block class="Magento\Wishlist\Block\Customer\Wishlist\Item\Column\Image" name="customer.wishlist.item.image" template="Magento_Wishlist::item/column/image.phtml" cacheable="false"/> - <block class="Magento\Wishlist\Block\Customer\Wishlist\Item\Column" name="customer.wishlist.item.name" template="Magento_Wishlist::item/column/name.phtml" cacheable="false"/> + <block class="Magento\Wishlist\Block\Customer\Wishlist\Item\Column\Info" name="customer.wishlist.item.name" template="Magento_Wishlist::item/column/name.phtml" cacheable="false"/> <block class="Magento\Wishlist\Block\Customer\Wishlist\Item\Column" name="customer.wishlist.item.review" template="Magento_Wishlist::item/column/review.phtml" cacheable="false"/> <block class="Magento\Wishlist\Block\Customer\Wishlist\Item\Column\Cart" name="customer.wishlist.item.price" template="Magento_Wishlist::item/column/price.phtml" cacheable="false"> <block class="Magento\Catalog\Pricing\Render" name="product.price.render.wishlist"> @@ -29,11 +29,11 @@ </block> <block class="Magento\Wishlist\Block\Customer\Wishlist\Item\Options" name="customer.wishlist.item.options" cacheable="false"/> </block> - <block class="Magento\Wishlist\Block\Customer\Wishlist\Item\Column" name="customer.wishlist.item.inner" template="Magento_Wishlist::item/column/actions.phtml" cacheable="false"> + <block class="Magento\Wishlist\Block\Customer\Wishlist\Item\Column\Actions" name="customer.wishlist.item.inner" template="Magento_Wishlist::item/column/actions.phtml" cacheable="false"> <arguments> <argument name="css_class" xsi:type="string">product-item-inner</argument> </arguments> - <block class="Magento\Wishlist\Block\Customer\Wishlist\Item\Column" name="customer.wishlist.item.comment" template="Magento_Wishlist::item/column/comment.phtml" cacheable="false"> + <block class="Magento\Wishlist\Block\Customer\Wishlist\Item\Column\Comment" name="customer.wishlist.item.comment" template="Magento_Wishlist::item/column/comment.phtml" cacheable="false"> <arguments> <argument name="title" translate="true" xsi:type="string">Product Details and Comment</argument> </arguments> @@ -44,12 +44,12 @@ </arguments> </block> - <block class="Magento\Wishlist\Block\Customer\Wishlist\Item\Column" name="customer.wishlist.item.actions" template="Magento_Wishlist::item/column/actions.phtml" cacheable="false"> + <block class="Magento\Wishlist\Block\Customer\Wishlist\Item\Column\Actions" name="customer.wishlist.item.actions" template="Magento_Wishlist::item/column/actions.phtml" cacheable="false"> <arguments> <argument name="css_class" xsi:type="string">product-item-actions</argument> </arguments> - <block class="Magento\Wishlist\Block\Customer\Wishlist\Item\Column" name="customer.wishlist.item.edit" template="Magento_Wishlist::item/column/edit.phtml" before="-" cacheable="false"/> - <block class="Magento\Wishlist\Block\Customer\Wishlist\Item\Column" name="customer.wishlist.item.remove" template="Magento_Wishlist::item/column/remove.phtml" cacheable="false"/> + <block class="Magento\Wishlist\Block\Customer\Wishlist\Item\Column\Edit" name="customer.wishlist.item.edit" template="Magento_Wishlist::item/column/edit.phtml" before="-" cacheable="false"/> + <block class="Magento\Wishlist\Block\Customer\Wishlist\Item\Column\Remove" name="customer.wishlist.item.remove" template="Magento_Wishlist::item/column/remove.phtml" cacheable="false"/> </block> </block> </block> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/item/column/actions.phtml b/app/code/Magento/Wishlist/view/frontend/templates/item/column/actions.phtml index 7fa55a839b2ea..0b50df8c59fbb 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/item/column/actions.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/item/column/actions.phtml @@ -6,7 +6,7 @@ // @codingStandardsIgnoreFile -/** @var \Magento\Wishlist\Block\Customer\Wishlist\Item\Column $block */ +/** @var \Magento\Wishlist\Block\Customer\Wishlist\Item\Column\Actions $block */ ?> <?php $children = $block->getChildNames(); ?> <?php if ($children): ?> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/item/column/comment.phtml b/app/code/Magento/Wishlist/view/frontend/templates/item/column/comment.phtml index 45bd7494fed4f..17e2404ee23cf 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/item/column/comment.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/item/column/comment.phtml @@ -6,7 +6,7 @@ // @codingStandardsIgnoreFile -/* @var \Magento\Wishlist\Block\Customer\Wishlist\Item\Column $block */ +/* @var \Magento\Wishlist\Block\Customer\Wishlist\Item\Column\Comment $block */ /* @var \Magento\Wishlist\Model\Item $item */ $item = $block->getItem(); diff --git a/app/code/Magento/Wishlist/view/frontend/templates/item/column/edit.phtml b/app/code/Magento/Wishlist/view/frontend/templates/item/column/edit.phtml index 81d770d556734..1898ef6fc0d66 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/item/column/edit.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/item/column/edit.phtml @@ -6,7 +6,7 @@ // @codingStandardsIgnoreFile -/** @var \Magento\Wishlist\Block\Customer\Wishlist\Item\Column $block */ +/** @var \Magento\Wishlist\Block\Customer\Wishlist\Item\Column\Edit $block */ /** @var \Magento\Wishlist\Model\Item $item */ $item = $block->getItem(); diff --git a/app/code/Magento/Wishlist/view/frontend/templates/item/column/name.phtml b/app/code/Magento/Wishlist/view/frontend/templates/item/column/name.phtml index 53c5f35f886ea..265f4635a6be3 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/item/column/name.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/item/column/name.phtml @@ -6,7 +6,7 @@ // @codingStandardsIgnoreFile -/** @var \Magento\Wishlist\Block\Customer\Wishlist\Item\Column $block */ +/** @var \Magento\Wishlist\Block\Customer\Wishlist\Item\Column\Info $block */ /** @var \Magento\Wishlist\Model\Item $item */ $item = $block->getItem(); diff --git a/app/code/Magento/Wishlist/view/frontend/templates/item/column/remove.phtml b/app/code/Magento/Wishlist/view/frontend/templates/item/column/remove.phtml index 0bd78ba38ba58..57ae439d9995b 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/item/column/remove.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/item/column/remove.phtml @@ -6,7 +6,7 @@ // @codingStandardsIgnoreFile -/* @var \Magento\Wishlist\Block\Customer\Wishlist\Item\Column $block */ +/* @var \Magento\Wishlist\Block\Customer\Wishlist\Item\Column\Remove $block */ ?> <a href="#" data-role="remove" data-post-remove='<?= /* @noEscape */ $block->getItemRemoveParams($block->getItem()) ?>' title="<?= $block->escapeHtmlAttr(__('Remove Item')) ?>" class="btn-remove action delete"> From d9b01e35fb0e068b25db777a128144fede1c37fd Mon Sep 17 00:00:00 2001 From: Denis Kopylov <dkopylov@magenius.team> Date: Tue, 5 Mar 2019 09:42:36 +0300 Subject: [PATCH 287/315] Change deprecation annotation (https://github.com/magento/magento2/issues/21419) --- .../Wishlist/Block/Customer/Wishlist/Item/Column/Actions.php | 2 +- .../Wishlist/Block/Customer/Wishlist/Item/Column/Comment.php | 2 +- .../Wishlist/Block/Customer/Wishlist/Item/Column/Edit.php | 2 +- .../Wishlist/Block/Customer/Wishlist/Item/Column/Info.php | 2 +- .../Wishlist/Block/Customer/Wishlist/Item/Column/Remove.php | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Column/Actions.php b/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Column/Actions.php index 0cf6b6a9867d1..41ce705c77607 100644 --- a/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Column/Actions.php +++ b/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Column/Actions.php @@ -13,7 +13,7 @@ /** * @api - * @deprecated Empty class + * @deprecated * @since 100.0.2 */ class Actions extends \Magento\Wishlist\Block\Customer\Wishlist\Item\Column diff --git a/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Column/Comment.php b/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Column/Comment.php index 5f40e96bfa6ff..f63d083bf56b6 100644 --- a/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Column/Comment.php +++ b/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Column/Comment.php @@ -13,7 +13,7 @@ /** * @api - * @deprecated Empty class + * @deprecated * @since 100.0.2 */ class Comment extends \Magento\Wishlist\Block\Customer\Wishlist\Item\Column diff --git a/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Column/Edit.php b/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Column/Edit.php index c4e94ec503175..1fc73c05f6f86 100644 --- a/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Column/Edit.php +++ b/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Column/Edit.php @@ -13,7 +13,7 @@ /** * @api - * @deprecated Empty class + * @deprecated * @since 100.0.2 */ class Edit extends \Magento\Wishlist\Block\Customer\Wishlist\Item\Column diff --git a/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Column/Info.php b/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Column/Info.php index f83c122910ebd..e6067392bae48 100644 --- a/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Column/Info.php +++ b/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Column/Info.php @@ -13,7 +13,7 @@ /** * @api - * @deprecated Empty class + * @deprecated * @since 100.0.2 */ class Info extends \Magento\Wishlist\Block\Customer\Wishlist\Item\Column diff --git a/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Column/Remove.php b/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Column/Remove.php index 3e6f225842e01..724ffd90f87db 100644 --- a/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Column/Remove.php +++ b/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Column/Remove.php @@ -13,7 +13,7 @@ /** * @api - * @deprecated Empty class + * @deprecated * @since 100.0.2 */ class Remove extends \Magento\Wishlist\Block\Customer\Wishlist\Item\Column From 9661291658022dc4b9ff60cc73bc320b101d48be Mon Sep 17 00:00:00 2001 From: Pavel Bystritsky <p.bystritsky@yandex.ru> Date: Tue, 12 Mar 2019 17:01:01 +0200 Subject: [PATCH 288/315] ENGCOM-4460: Static test fix. --- .../Wishlist/Block/Customer/Wishlist/Item/Column/Actions.php | 4 ++-- .../Wishlist/Block/Customer/Wishlist/Item/Column/Comment.php | 4 ++-- .../Wishlist/Block/Customer/Wishlist/Item/Column/Edit.php | 4 ++-- .../Wishlist/Block/Customer/Wishlist/Item/Column/Info.php | 4 ++-- .../Wishlist/Block/Customer/Wishlist/Item/Column/Remove.php | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Column/Actions.php b/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Column/Actions.php index 41ce705c77607..40882ae00dae1 100644 --- a/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Column/Actions.php +++ b/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Column/Actions.php @@ -5,13 +5,13 @@ */ /** - * Wishlist for item column in customer wishlist - * * @author Magento Core Team <core@magentocommerce.com> */ namespace Magento\Wishlist\Block\Customer\Wishlist\Item\Column; /** + * Model for item column in customer wishlist. + * * @api * @deprecated * @since 100.0.2 diff --git a/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Column/Comment.php b/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Column/Comment.php index f63d083bf56b6..53f67626e956d 100644 --- a/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Column/Comment.php +++ b/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Column/Comment.php @@ -5,13 +5,13 @@ */ /** - * Wishlist block customer item cart column - * * @author Magento Core Team <core@magentocommerce.com> */ namespace Magento\Wishlist\Block\Customer\Wishlist\Item\Column; /** + * Wishlist block customer item cart column. + * * @api * @deprecated * @since 100.0.2 diff --git a/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Column/Edit.php b/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Column/Edit.php index 1fc73c05f6f86..c4c786961694b 100644 --- a/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Column/Edit.php +++ b/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Column/Edit.php @@ -5,13 +5,13 @@ */ /** - * Edit item in customer wishlist table - * * @author Magento Core Team <core@magentocommerce.com> */ namespace Magento\Wishlist\Block\Customer\Wishlist\Item\Column; /** + * Edit item in customer wishlist table. + * * @api * @deprecated * @since 100.0.2 diff --git a/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Column/Info.php b/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Column/Info.php index e6067392bae48..b7eaf53fc23b5 100644 --- a/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Column/Info.php +++ b/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Column/Info.php @@ -5,13 +5,13 @@ */ /** - * Wishlist block customer item cart column - * * @author Magento Core Team <core@magentocommerce.com> */ namespace Magento\Wishlist\Block\Customer\Wishlist\Item\Column; /** + * Wishlist block customer item cart column. + * * @api * @deprecated * @since 100.0.2 diff --git a/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Column/Remove.php b/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Column/Remove.php index 724ffd90f87db..09f5014edead6 100644 --- a/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Column/Remove.php +++ b/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Column/Remove.php @@ -5,13 +5,13 @@ */ /** - * Delete item column in customer wishlist table - * * @author Magento Core Team <core@magentocommerce.com> */ namespace Magento\Wishlist\Block\Customer\Wishlist\Item\Column; /** + * Delete item column in customer wishlist table + * * @api * @deprecated * @since 100.0.2 From 630445197f7bbee7c71855b6771ab6f881e3502f Mon Sep 17 00:00:00 2001 From: Serhiy Yelahin <serhiy.yelahin@transoftgroup.com> Date: Fri, 15 Mar 2019 09:53:49 +0200 Subject: [PATCH 289/315] MAGETWO-95020: Clicking on a Root Category causes all other Root Categories to be expanded to the top-level categories --- app/code/Magento/Catalog/Block/Adminhtml/Category/Tree.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/code/Magento/Catalog/Block/Adminhtml/Category/Tree.php b/app/code/Magento/Catalog/Block/Adminhtml/Category/Tree.php index 020666838a79a..a7bb242daf86f 100644 --- a/app/code/Magento/Catalog/Block/Adminhtml/Category/Tree.php +++ b/app/code/Magento/Catalog/Block/Adminhtml/Category/Tree.php @@ -284,6 +284,7 @@ public function getIsWasExpanded() * Get move url * * @return string + * @SuppressWarnings(PHPMD.RequestAwareBlockMethod) */ public function getMoveUrl() { @@ -450,6 +451,7 @@ protected function _isParentSelectedCategory($node) * Check if page loaded by outside link to category edit * * @return boolean + * @SuppressWarnings(PHPMD.RequestAwareBlockMethod) */ public function isClearEdit() { From f31e7f0949db2d817461473f57f162e550f253c2 Mon Sep 17 00:00:00 2001 From: Pavel Bystritsky <p.bystritsky@yandex.ru> Date: Fri, 15 Mar 2019 11:05:28 +0200 Subject: [PATCH 290/315] ENGCOM-4182: Static test fix. --- .../Adminhtml/Product/Edit/Action/Attribute/Tab/Inventory.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Action/Attribute/Tab/Inventory.php b/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Action/Attribute/Tab/Inventory.php index edeb7f94c3ae5..964872b6e51bd 100644 --- a/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Action/Attribute/Tab/Inventory.php +++ b/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Action/Attribute/Tab/Inventory.php @@ -109,7 +109,7 @@ public function getTabTitle() } /** - * @inheritdoc + * @inheritdoc */ public function canShowTab() { @@ -117,7 +117,7 @@ public function canShowTab() } /** - * @inheritdoc + * @inheritdoc */ public function isHidden() { From 27d113fc9295cff8909913a41867d64dbbcfb377 Mon Sep 17 00:00:00 2001 From: Vitaliy Boyko <v.boyko@atwix.com> Date: Wed, 13 Mar 2019 10:58:31 +0200 Subject: [PATCH 291/315] Vitalii Boiko: fixed wrong proxing in the inventory observer --- app/code/Magento/CatalogInventory/etc/di.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/CatalogInventory/etc/di.xml b/app/code/Magento/CatalogInventory/etc/di.xml index 535e91ba30f52..8c47865da6aa7 100644 --- a/app/code/Magento/CatalogInventory/etc/di.xml +++ b/app/code/Magento/CatalogInventory/etc/di.xml @@ -44,7 +44,7 @@ </type> <type name="Magento\CatalogInventory\Observer\UpdateItemsStockUponConfigChangeObserver"> <arguments> - <argument name="resourceStock" xsi:type="object">Magento\CatalogInventory\Model\ResourceModel\Stock\Proxy</argument> + <argument name="resourceStockItem" xsi:type="object">Magento\CatalogInventory\Model\ResourceModel\Stock\Item\Proxy</argument> </arguments> </type> <type name="Magento\Catalog\Model\Layer"> From 095b9f4ef371d9e5692f42b655c81294f14c5137 Mon Sep 17 00:00:00 2001 From: Ananth Iyer <iyerananth3@gmail.com> Date: Mon, 25 Feb 2019 23:48:59 +0530 Subject: [PATCH 292/315] Disable dropdown in JavaScript and CSS Settings in developer configuration --- app/code/Magento/Backend/etc/adminhtml/system.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Backend/etc/adminhtml/system.xml b/app/code/Magento/Backend/etc/adminhtml/system.xml index e3411166ee4a4..44ab1dcc00176 100644 --- a/app/code/Magento/Backend/etc/adminhtml/system.xml +++ b/app/code/Magento/Backend/etc/adminhtml/system.xml @@ -153,15 +153,15 @@ </group> <group id="js" translate="label" type="text" sortOrder="100" showInDefault="1" showInWebsite="1" showInStore="1"> <label>JavaScript Settings</label> - <field id="merge_files" translate="label" type="select" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1"> + <field id="merge_files" translate="label" type="select" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1" canRestore="1"> <label>Merge JavaScript Files</label> <source_model>Magento\Config\Model\Config\Source\Yesno</source_model> </field> - <field id="enable_js_bundling" translate="label" type="select" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1"> + <field id="enable_js_bundling" translate="label" type="select" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1" canRestore="1"> <label>Enable JavaScript Bundling</label> <source_model>Magento\Config\Model\Config\Source\Yesno</source_model> </field> - <field id="minify_files" translate="label comment" type="select" sortOrder="20" showInDefault="1" showInWebsite="1" showInStore="1"> + <field id="minify_files" translate="label comment" type="select" sortOrder="20" showInDefault="1" showInWebsite="1" showInStore="1" canRestore="1"> <label>Minify JavaScript Files</label> <source_model>Magento\Config\Model\Config\Source\Yesno</source_model> <comment>Minification is not applied in developer mode.</comment> @@ -169,11 +169,11 @@ </group> <group id="css" translate="label" type="text" sortOrder="110" showInDefault="1" showInWebsite="1" showInStore="1"> <label>CSS Settings</label> - <field id="merge_css_files" translate="label" type="select" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1"> + <field id="merge_css_files" translate="label" type="select" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1" canRestore="1"> <label>Merge CSS Files</label> <source_model>Magento\Config\Model\Config\Source\Yesno</source_model> </field> - <field id="minify_files" translate="label comment" type="select" sortOrder="20" showInDefault="1" showInWebsite="1" showInStore="1"> + <field id="minify_files" translate="label comment" type="select" sortOrder="20" showInDefault="1" showInWebsite="1" showInStore="1" canRestore="1"> <label>Minify CSS Files</label> <source_model>Magento\Config\Model\Config\Source\Yesno</source_model> <comment>Minification is not applied in developer mode.</comment> From e7fb7fe185639ca6f811c63023eb0d04ceda892b Mon Sep 17 00:00:00 2001 From: Aditi Singh <36220507+aditisinghcedcoss@users.noreply.github.com> Date: Fri, 28 Dec 2018 13:09:54 +0530 Subject: [PATCH 293/315] Update AbstactSource.php Issue #13612 fixed. --- .../Eav/Model/Entity/Attribute/Source/AbstractSource.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Eav/Model/Entity/Attribute/Source/AbstractSource.php b/app/code/Magento/Eav/Model/Entity/Attribute/Source/AbstractSource.php index 0991b3f9f4b23..8d5b501654749 100644 --- a/app/code/Magento/Eav/Model/Entity/Attribute/Source/AbstractSource.php +++ b/app/code/Magento/Eav/Model/Entity/Attribute/Source/AbstractSource.php @@ -73,7 +73,7 @@ public function getOptionText($value) } } // End - if (isset($options[$value])) { + if (is_scalar($value) && isset($options[$value])) { return $options[$value]; } return false; From dcf808e1922de7665c27d8d7b9f292ca96c333b9 Mon Sep 17 00:00:00 2001 From: Pavel Bystritsky <p.bystritsky@yandex.ru> Date: Fri, 25 Jan 2019 13:24:27 +0200 Subject: [PATCH 294/315] ENGCOM-3810: Static test fix. --- .../Eav/Model/Entity/Attribute/Source/AbstractSource.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/code/Magento/Eav/Model/Entity/Attribute/Source/AbstractSource.php b/app/code/Magento/Eav/Model/Entity/Attribute/Source/AbstractSource.php index 8d5b501654749..36ad026029056 100644 --- a/app/code/Magento/Eav/Model/Entity/Attribute/Source/AbstractSource.php +++ b/app/code/Magento/Eav/Model/Entity/Attribute/Source/AbstractSource.php @@ -80,6 +80,8 @@ public function getOptionText($value) } /** + * Get option id. + * * @param string $value * @return null|string */ From ab7aee90f55ccd02738ff98a69e6e29b083faed8 Mon Sep 17 00:00:00 2001 From: Danilo Argentiero <danilo.argentiero@magespecialist.it> Date: Fri, 25 Aug 2017 10:28:49 +0200 Subject: [PATCH 295/315] Issue #10645 - Allow BEM class via attribute tag. --- lib/internal/Magento/Framework/View/Page/Config.php | 2 +- .../View/Test/Unit/Page/Config/Generator/BodyTest.php | 4 ++-- .../Framework/View/Test/Unit/Page/Config/StructureTest.php | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/internal/Magento/Framework/View/Page/Config.php b/lib/internal/Magento/Framework/View/Page/Config.php index 226abc538112b..ee6c8f1d555b6 100644 --- a/lib/internal/Magento/Framework/View/Page/Config.php +++ b/lib/internal/Magento/Framework/View/Page/Config.php @@ -498,7 +498,7 @@ public function addRss($title, $href) */ public function addBodyClass($className) { - $className = preg_replace('#[^a-z0-9]+#', '-', strtolower($className)); + $className = preg_replace('#[^a-z0-9-]+#', '-', strtolower($className)); $bodyClasses = $this->getElementAttribute(self::ELEMENT_TYPE_BODY, self::BODY_ATTRIBUTE_CLASS); $bodyClasses = $bodyClasses ? explode(' ', $bodyClasses) : []; $bodyClasses[] = $className; diff --git a/lib/internal/Magento/Framework/View/Test/Unit/Page/Config/Generator/BodyTest.php b/lib/internal/Magento/Framework/View/Test/Unit/Page/Config/Generator/BodyTest.php index 0f59c302f943f..ed926afa00856 100644 --- a/lib/internal/Magento/Framework/View/Test/Unit/Page/Config/Generator/BodyTest.php +++ b/lib/internal/Magento/Framework/View/Test/Unit/Page/Config/Generator/BodyTest.php @@ -57,13 +57,13 @@ public function testProcess() ->method('getPageConfigStructure') ->willReturn($structureMock); - $bodyClasses = ['class_1', 'class_2']; + $bodyClasses = ['class_1', 'class--2']; $structureMock->expects($this->once()) ->method('getBodyClasses') ->will($this->returnValue($bodyClasses)); $this->pageConfigMock->expects($this->exactly(2)) ->method('addBodyClass') - ->withConsecutive(['class_1'], ['class_2']); + ->withConsecutive(['class_1'], ['class--2']); $this->assertEquals( $this->bodyGenerator, diff --git a/lib/internal/Magento/Framework/View/Test/Unit/Page/Config/StructureTest.php b/lib/internal/Magento/Framework/View/Test/Unit/Page/Config/StructureTest.php index ed15a356cc4c7..d2eba5d2fa1b3 100644 --- a/lib/internal/Magento/Framework/View/Test/Unit/Page/Config/StructureTest.php +++ b/lib/internal/Magento/Framework/View/Test/Unit/Page/Config/StructureTest.php @@ -58,7 +58,7 @@ public function testSetElementAttribute() public function testSetBodyClass() { $class1 = 'class_1'; - $class2 = 'class_2'; + $class2 = 'class--2'; $expected = [$class1, $class2]; $this->structure->setBodyClass($class1); $this->structure->setBodyClass($class2); From 743c034291d62a4329350d637832ad0ef7b8439b Mon Sep 17 00:00:00 2001 From: Danilo Argentiero <danilo.argentiero@magespecialist.it> Date: Fri, 25 Aug 2017 14:55:17 +0200 Subject: [PATCH 296/315] Issue #10645 Allow underscore charachter for BEM class via attribute tag --- lib/internal/Magento/Framework/View/Page/Config.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/View/Page/Config.php b/lib/internal/Magento/Framework/View/Page/Config.php index ee6c8f1d555b6..da7bcb128f4b8 100644 --- a/lib/internal/Magento/Framework/View/Page/Config.php +++ b/lib/internal/Magento/Framework/View/Page/Config.php @@ -498,7 +498,7 @@ public function addRss($title, $href) */ public function addBodyClass($className) { - $className = preg_replace('#[^a-z0-9-]+#', '-', strtolower($className)); + $className = preg_replace('#[^a-z0-9-_]+#', '-', strtolower($className)); $bodyClasses = $this->getElementAttribute(self::ELEMENT_TYPE_BODY, self::BODY_ATTRIBUTE_CLASS); $bodyClasses = $bodyClasses ? explode(' ', $bodyClasses) : []; $bodyClasses[] = $className; From 3fa5a07399597cf9487f457361dd15b2b36ee5d4 Mon Sep 17 00:00:00 2001 From: Pavel Bystritsky <p.bystritsky@yandex.ru> Date: Mon, 4 Mar 2019 16:51:03 +0200 Subject: [PATCH 297/315] ENGCOM-4000: Upgrade data script. --- .../CatalogWidget/Setup/UpgradeData.php | 103 ++++++++++++++++++ app/code/Magento/CatalogWidget/etc/module.xml | 2 +- 2 files changed, 104 insertions(+), 1 deletion(-) create mode 100644 app/code/Magento/CatalogWidget/Setup/UpgradeData.php diff --git a/app/code/Magento/CatalogWidget/Setup/UpgradeData.php b/app/code/Magento/CatalogWidget/Setup/UpgradeData.php new file mode 100644 index 0000000000000..5ebdbe2390d51 --- /dev/null +++ b/app/code/Magento/CatalogWidget/Setup/UpgradeData.php @@ -0,0 +1,103 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\CatalogWidget\Setup; + +use Magento\CatalogWidget\Block\Product\ProductsList; +use Magento\CatalogWidget\Model\Rule\Condition\Product as ConditionProduct; +use Magento\Framework\Serialize\Serializer\Json as Serializer; +use Magento\Framework\Setup\ModuleContextInterface; +use Magento\Framework\Setup\ModuleDataSetupInterface; +use Magento\Framework\Setup\UpgradeDataInterface; + +/** + * Upgrade data for CatalogWidget module. + */ +class UpgradeData implements UpgradeDataInterface +{ + /** + * @var Serializer + */ + private $serializer; + + /** + * @param Serializer $serializer + */ + public function __construct( + Serializer $serializer + ) { + $this->serializer = $serializer; + } + + /** + * @inheritdoc + */ + public function upgrade(ModuleDataSetupInterface $setup, ModuleContextInterface $context) + { + if (version_compare($context->getVersion(), '2.0.1', '<')) { + $this->replaceIsWithIsOneOf($setup); + } + } + + /** + * Replace 'is' condition with 'is one of' in database. + * + * If 'is' product list condition is used with multiple skus it should be replaced by 'is one of' condition. + * + * @param ModuleDataSetupInterface $setup + */ + private function replaceIsWithIsOneOf(ModuleDataSetupInterface $setup) + { + $tableName = $setup->getTable('widget_instance'); + $connection = $setup->getConnection(); + $select = $connection->select() + ->from( + $tableName, + [ + 'instance_id', + 'widget_parameters', + ] + )->where('instance_type = ? ', ProductsList::class); + + $result = $setup->getConnection()->fetchAll($select); + + if ($result) { + $updatedData = $this->updateWidgetData($result); + + $connection->insertOnDuplicate( + $tableName, + $updatedData + ); + } + } + + /** + * Replace 'is' condition with 'is one of' in widget parameters. + * + * @param array $result + * @return array + */ + private function updateWidgetData(array $result): array + { + return array_map( + function ($widgetData) { + $widgetParameters = $this->serializer->unserialize($widgetData['widget_parameters']); + foreach ($widgetParameters['conditions'] as &$condition) { + if (ConditionProduct::class === $condition['type'] && + 'sku' === $condition['attribute'] && + '==' === $condition['operator']) { + $condition['operator'] = '()'; + } + } + $widgetData['widget_parameters'] = $this->serializer->serialize($widgetParameters); + + return $widgetData; + }, + $result + ); + } +} diff --git a/app/code/Magento/CatalogWidget/etc/module.xml b/app/code/Magento/CatalogWidget/etc/module.xml index 8954f11f954f7..1f2d84bef2d6b 100644 --- a/app/code/Magento/CatalogWidget/etc/module.xml +++ b/app/code/Magento/CatalogWidget/etc/module.xml @@ -6,7 +6,7 @@ */ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd"> - <module name="Magento_CatalogWidget" setup_version="2.0.0"> + <module name="Magento_CatalogWidget" setup_version="2.0.1"> <sequence> <module name="Magento_Catalog"/> <module name="Magento_Widget"/> From 3dea8d0f34f9e4d033a7a82a22cbe93f418635ff Mon Sep 17 00:00:00 2001 From: Pavel Bystritsky <p.bystritsky@yandex.ru> Date: Tue, 19 Mar 2019 12:11:31 +0200 Subject: [PATCH 298/315] ENGCOM-4513: Static test fix. --- .../Wishlist/view/frontend/templates/item/column/review.phtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Wishlist/view/frontend/templates/item/column/review.phtml b/app/code/Magento/Wishlist/view/frontend/templates/item/column/review.phtml index 9120cc9fa684e..3fd492233bdd5 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/item/column/review.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/item/column/review.phtml @@ -7,4 +7,4 @@ /** @var \Magento\Wishlist\Block\Customer\Wishlist\Item\Column $block */ $product = $block->getItem()->getProduct(); ?> -<?= $block->getReviewsSummaryHtml($product, 'short') ?> +<?= $block->getReviewsSummaryHtml($product, 'short'); From 079ecb3689e76e1d5ed85de20f19b59eb347cd66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karla=20Saarem=C3=A4e?= <karlasaaremae@gmail.com> Date: Fri, 8 Mar 2019 13:48:06 +0200 Subject: [PATCH 299/315] remove refactored code not needed with correct html classes --- .../css/source/module/checkout/_fields.less | 28 ------------------- 1 file changed, 28 deletions(-) diff --git a/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_fields.less b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_fields.less index 4479c070a4e17..8dec680b58726 100644 --- a/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_fields.less +++ b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_fields.less @@ -55,31 +55,3 @@ } } } - -// -// Desktop -// _____________________________________________ - -.media-width(@extremum, @break) when (@extremum = 'min') and (@break = @screen__m) { - // ToDo UI: remove with global blank theme .field.required update - .opc-wrapper { - .fieldset { - > .field { - &.required, - &._required { - position: relative; - - > label { - padding-right: 25px; - - &:after { - margin-left: @indent__s; - position: absolute; - top: 9px; - } - } - } - } - } - } -} From 943fb3374c379c9d00236251d6901a371ee98682 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karla=20Saarem=C3=A4e?= <karlasaaremae@gmail.com> Date: Fri, 8 Mar 2019 13:52:26 +0200 Subject: [PATCH 300/315] fix asterisk added correct class for asterisk --- .../frontend/web/template/checkout/checkout-agreements.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/CheckoutAgreements/view/frontend/web/template/checkout/checkout-agreements.html b/app/code/Magento/CheckoutAgreements/view/frontend/web/template/checkout/checkout-agreements.html index a448537d64e83..db9da71ebf739 100644 --- a/app/code/Magento/CheckoutAgreements/view/frontend/web/template/checkout/checkout-agreements.html +++ b/app/code/Magento/CheckoutAgreements/view/frontend/web/template/checkout/checkout-agreements.html @@ -5,17 +5,17 @@ */ --> <div data-role="checkout-agreements"> - <div class="checkout-agreements" data-bind="visible: isVisible"> + <div class="checkout-agreements fieldset" data-bind="visible: isVisible"> <!-- ko foreach: agreements --> <!-- ko if: ($parent.isAgreementRequired($data)) --> - <div class="checkout-agreement required"> + <div class="checkout-agreement field required"> <input type="checkbox" class="required-entry" data-bind="attr: { 'id': $parent.getCheckboxId($parentContext, agreementId), 'name': 'agreement[' + agreementId + ']', 'value': agreementId }"/> - <label data-bind="attr: {'for': $parent.getCheckboxId($parentContext, agreementId)}"> + <label class="label" data-bind="attr: {'for': $parent.getCheckboxId($parentContext, agreementId)}"> <button type="button" class="action action-show" data-bind="click: function(data, event) { return $parent.showContent(data, event) }" From 745df9a3c45a38bbb6da3bfc81d01f7ad2f5563b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karla=20Saarem=C3=A4e?= <karlasaaremae@gmail.com> Date: Wed, 13 Mar 2019 11:38:58 +0200 Subject: [PATCH 301/315] add choice class --- .../frontend/web/template/checkout/checkout-agreements.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/CheckoutAgreements/view/frontend/web/template/checkout/checkout-agreements.html b/app/code/Magento/CheckoutAgreements/view/frontend/web/template/checkout/checkout-agreements.html index db9da71ebf739..4b1a68624e547 100644 --- a/app/code/Magento/CheckoutAgreements/view/frontend/web/template/checkout/checkout-agreements.html +++ b/app/code/Magento/CheckoutAgreements/view/frontend/web/template/checkout/checkout-agreements.html @@ -8,7 +8,7 @@ <div class="checkout-agreements fieldset" data-bind="visible: isVisible"> <!-- ko foreach: agreements --> <!-- ko if: ($parent.isAgreementRequired($data)) --> - <div class="checkout-agreement field required"> + <div class="checkout-agreement field choice required"> <input type="checkbox" class="required-entry" data-bind="attr: { 'id': $parent.getCheckboxId($parentContext, agreementId), From 8c609c4f546316d3726594cb8ea71f1e91a6594f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karla=20Saarem=C3=A4e?= <karlasaaremae@gmail.com> Date: Wed, 13 Mar 2019 11:53:26 +0200 Subject: [PATCH 302/315] fix choice aligment --- .../web/css/source/module/checkout/_payments.less | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_payments.less b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_payments.less index 5f8134193c67f..35445b0989e86 100644 --- a/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_payments.less +++ b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_payments.less @@ -209,6 +209,13 @@ .fieldset { > .field { margin: 0 0 @indent__base; + + &.choice { + &:before { + padding: 0; + width: 0; + } + } &.type { .control { From 0c65f5dc8917af75e159951136e934c7162873d0 Mon Sep 17 00:00:00 2001 From: Stanislav Idolov <sidolov@magento.com> Date: Tue, 19 Mar 2019 15:57:05 -0500 Subject: [PATCH 303/315] magento-engcom/magento2ce#2686: Skipped unstable test --- .../Magento/Backend/Controller/Adminhtml/DashboardTest.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dev/tests/integration/testsuite/Magento/Backend/Controller/Adminhtml/DashboardTest.php b/dev/tests/integration/testsuite/Magento/Backend/Controller/Adminhtml/DashboardTest.php index 07af21505f180..20fbe2a3f3f62 100644 --- a/dev/tests/integration/testsuite/Magento/Backend/Controller/Adminhtml/DashboardTest.php +++ b/dev/tests/integration/testsuite/Magento/Backend/Controller/Adminhtml/DashboardTest.php @@ -21,6 +21,8 @@ public function testAjaxBlockAction() public function testTunnelAction() { + $this->markTestSkipped('MAGETWO-98803'); + $testUrl = \Magento\Backend\Block\Dashboard\Graph::API_URL . '?cht=p3&chd=t:60,40&chs=250x100&chl=Hello|World'; $handle = curl_init(); curl_setopt($handle, CURLOPT_URL, $testUrl); From 9529d318c284fc153b4edba9c24b428e57395b95 Mon Sep 17 00:00:00 2001 From: AleksLi <aleksliwork@gmail.com> Date: Sun, 17 Feb 2019 19:32:44 +0100 Subject: [PATCH 304/315] magento/magento2#12396: Total Amount cart rule without tax - Added new condition type to give user opportunity to choose the configuration. --- app/code/Magento/SalesRule/Model/Rule/Condition/Address.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/SalesRule/Model/Rule/Condition/Address.php b/app/code/Magento/SalesRule/Model/Rule/Condition/Address.php index fd5953697c7db..96867222d170a 100644 --- a/app/code/Magento/SalesRule/Model/Rule/Condition/Address.php +++ b/app/code/Magento/SalesRule/Model/Rule/Condition/Address.php @@ -58,6 +58,7 @@ public function __construct( public function loadAttributeOptions() { $attributes = [ + 'base_subtotal_with_discount' => __('Subtotal (Excl. Tax)'), 'base_subtotal' => __('Subtotal'), 'total_qty' => __('Total Items Quantity'), 'weight' => __('Total Weight'), From 362bbf239373ed70d11da43b04a861b76e5d4190 Mon Sep 17 00:00:00 2001 From: nmalevanec <mikola.malevanec@transoftgroup.com> Date: Fri, 15 Mar 2019 13:39:25 +0200 Subject: [PATCH 305/315] Fix functional tests. --- .../Mtf/Client/Element/ConditionsElement.php | 2 +- .../Client/Element/SelectconditionElement.php | 20 +++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 dev/tests/functional/lib/Magento/Mtf/Client/Element/SelectconditionElement.php diff --git a/dev/tests/functional/lib/Magento/Mtf/Client/Element/ConditionsElement.php b/dev/tests/functional/lib/Magento/Mtf/Client/Element/ConditionsElement.php index 6dbf2b1aa6a12..f532b12c61492 100644 --- a/dev/tests/functional/lib/Magento/Mtf/Client/Element/ConditionsElement.php +++ b/dev/tests/functional/lib/Magento/Mtf/Client/Element/ConditionsElement.php @@ -285,7 +285,7 @@ protected function addCondition($type, ElementInterface $context) $newCondition->find($this->addNew, Locator::SELECTOR_XPATH)->click(); try { - $newCondition->find($this->typeNew, Locator::SELECTOR_XPATH, 'select')->setValue($type); + $newCondition->find($this->typeNew, Locator::SELECTOR_XPATH, 'selectcondition')->setValue($type); $isSetType = true; } catch (\PHPUnit_Extensions_Selenium2TestCase_WebDriverException $e) { $isSetType = false; diff --git a/dev/tests/functional/lib/Magento/Mtf/Client/Element/SelectconditionElement.php b/dev/tests/functional/lib/Magento/Mtf/Client/Element/SelectconditionElement.php new file mode 100644 index 0000000000000..1fe096670135d --- /dev/null +++ b/dev/tests/functional/lib/Magento/Mtf/Client/Element/SelectconditionElement.php @@ -0,0 +1,20 @@ +<?php +/** + * Copyright © 2017 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +declare(strict_types=1); + +namespace Magento\Mtf\Client\Element; + +/** + * @inheritdoc + */ +class SelectconditionElement extends SelectElement +{ + /** + * @inheritdoc + */ + protected $optionByValue = './/option[normalize-space(.)=%s]'; +} From a5608f0d6c9c476d18f9dfe59a9053b7fac29393 Mon Sep 17 00:00:00 2001 From: nmalevanec <mikola.malevanec@transoftgroup.com> Date: Fri, 15 Mar 2019 17:38:44 +0200 Subject: [PATCH 306/315] Fix functional tests. --- .../Mtf/Client/Element/ConditionsElement.php | 19 ++++++++++++++++--- .../Client/Element/SelectconditionElement.php | 2 +- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/dev/tests/functional/lib/Magento/Mtf/Client/Element/ConditionsElement.php b/dev/tests/functional/lib/Magento/Mtf/Client/Element/ConditionsElement.php index f532b12c61492..9edd087020a72 100644 --- a/dev/tests/functional/lib/Magento/Mtf/Client/Element/ConditionsElement.php +++ b/dev/tests/functional/lib/Magento/Mtf/Client/Element/ConditionsElement.php @@ -195,6 +195,13 @@ class ConditionsElement extends SimpleElement */ protected $exception; + /** + * Condition option text selector. + * + * @var string + */ + private $conditionOptionTextSelector = '//option[normalize-space(text())="%s"]'; + /** * @inheritdoc */ @@ -282,10 +289,16 @@ protected function addCondition($type, ElementInterface $context) $count = 0; do { - $newCondition->find($this->addNew, Locator::SELECTOR_XPATH)->click(); - try { - $newCondition->find($this->typeNew, Locator::SELECTOR_XPATH, 'selectcondition')->setValue($type); + $specificType = $newCondition->find( + sprintf($this->conditionOptionTextSelector, $type), + Locator::SELECTOR_XPATH + )->isPresent(); + $newCondition->find($this->addNew, Locator::SELECTOR_XPATH)->click(); + $condition = $specificType + ? $newCondition->find($this->typeNew, Locator::SELECTOR_XPATH, 'selectcondition') + : $newCondition->find($this->typeNew, Locator::SELECTOR_XPATH, 'select'); + $condition->setValue($type); $isSetType = true; } catch (\PHPUnit_Extensions_Selenium2TestCase_WebDriverException $e) { $isSetType = false; diff --git a/dev/tests/functional/lib/Magento/Mtf/Client/Element/SelectconditionElement.php b/dev/tests/functional/lib/Magento/Mtf/Client/Element/SelectconditionElement.php index 1fe096670135d..15a799eac5188 100644 --- a/dev/tests/functional/lib/Magento/Mtf/Client/Element/SelectconditionElement.php +++ b/dev/tests/functional/lib/Magento/Mtf/Client/Element/SelectconditionElement.php @@ -1,6 +1,6 @@ <?php /** - * Copyright © 2017 Magento. All rights reserved. + * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ From dd3a94a7a0bd2ec81c6a58538efa0ff0882b7367 Mon Sep 17 00:00:00 2001 From: eduard13 <e.chitoraga@atwix.com> Date: Wed, 20 Mar 2019 10:40:09 +0200 Subject: [PATCH 307/315] Fixing the Pending Reviews label and adding menu for pending reviews --- app/code/Magento/Review/Block/Adminhtml/Edit.php | 4 ++-- .../Magento/Review/Controller/Adminhtml/Product/Save.php | 7 ++++++- app/code/Magento/Review/etc/acl.xml | 2 +- app/code/Magento/Review/etc/adminhtml/menu.xml | 1 + 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Review/Block/Adminhtml/Edit.php b/app/code/Magento/Review/Block/Adminhtml/Edit.php index d6868eae6fcbc..f6f0ccef9b4e7 100644 --- a/app/code/Magento/Review/Block/Adminhtml/Edit.php +++ b/app/code/Magento/Review/Block/Adminhtml/Edit.php @@ -159,13 +159,13 @@ protected function _construct() } if ($this->getRequest()->getParam('ret', false) == 'pending') { - $this->buttonList->update('back', 'onclick', 'setLocation(\'' . $this->getUrl('catalog/*/pending') . '\')'); + $this->buttonList->update('back', 'onclick', 'setLocation(\'' . $this->getUrl('review/*/pending') . '\')'); $this->buttonList->update( 'delete', 'onclick', 'deleteConfirm(' . '\'' . __( 'Are you sure you want to do this?' - ) . '\' ' . '\'' . $this->getUrl( + ) . '\', ' . '\'' . $this->getUrl( '*/*/delete', [$this->_objectId => $this->getRequest()->getParam($this->_objectId), 'ret' => 'pending'] ) . '\'' . ')' diff --git a/app/code/Magento/Review/Controller/Adminhtml/Product/Save.php b/app/code/Magento/Review/Controller/Adminhtml/Product/Save.php index 7159b1825dc4d..857f36b19a19c 100644 --- a/app/code/Magento/Review/Controller/Adminhtml/Product/Save.php +++ b/app/code/Magento/Review/Controller/Adminhtml/Product/Save.php @@ -9,9 +9,14 @@ use Magento\Framework\Controller\ResultFactory; use Magento\Framework\Exception\LocalizedException; +/** + * Save Review action. + */ class Save extends ProductController { /** + * Save Review action. + * * @return \Magento\Backend\Model\View\Result\Redirect * @SuppressWarnings(PHPMD.CyclomaticComplexity) */ @@ -63,7 +68,7 @@ public function execute() if ($nextId) { $resultRedirect->setPath('review/*/edit', ['id' => $nextId]); } elseif ($this->getRequest()->getParam('ret') == 'pending') { - $resultRedirect->setPath('*/*/pending'); + $resultRedirect->setPath('review/*/pending'); } else { $resultRedirect->setPath('*/*/'); } diff --git a/app/code/Magento/Review/etc/acl.xml b/app/code/Magento/Review/etc/acl.xml index 397cc1cce61d6..09b80750da14d 100644 --- a/app/code/Magento/Review/etc/acl.xml +++ b/app/code/Magento/Review/etc/acl.xml @@ -17,7 +17,7 @@ <resource id="Magento_Backend::marketing"> <resource id="Magento_Backend::marketing_user_content"> <resource id="Magento_Review::reviews_all" title="Reviews" translate="title" sortOrder="10"/> - <resource id="Magento_Review::pending" title="Reviews" translate="title" sortOrder="20"/> + <resource id="Magento_Review::pending" title="Pending Reviews" translate="title" sortOrder="20"/> </resource> </resource> </resource> diff --git a/app/code/Magento/Review/etc/adminhtml/menu.xml b/app/code/Magento/Review/etc/adminhtml/menu.xml index e3532483f88af..8b56f36bce68e 100644 --- a/app/code/Magento/Review/etc/adminhtml/menu.xml +++ b/app/code/Magento/Review/etc/adminhtml/menu.xml @@ -9,6 +9,7 @@ <menu> <add id="Magento_Review::catalog_reviews_ratings_ratings" title="Rating" translate="title" module="Magento_Review" sortOrder="60" parent="Magento_Backend::stores_attributes" action="review/rating/" resource="Magento_Review::ratings"/> <add id="Magento_Review::catalog_reviews_ratings_reviews_all" title="Reviews" translate="title" module="Magento_Review" parent="Magento_Backend::marketing_user_content" sortOrder="10" action="review/product/index" resource="Magento_Review::reviews_all"/> + <add id="Magento_Review::catalog_reviews_ratings_pending" title="Pending Reviews" translate="title" module="Magento_Review" parent="Magento_Backend::marketing_user_content" sortOrder="15" action="review/product/pending" resource="Magento_Review::pending"/> <add id="Magento_Review::report_review" title="Reviews" translate="title" module="Magento_Reports" sortOrder="20" parent="Magento_Reports::report" resource="Magento_Reports::review"/> <add id="Magento_Review::report_review_customer" title="By Customers" translate="title" sortOrder="10" module="Magento_Review" parent="Magento_Review::report_review" action="reports/report_review/customer" resource="Magento_Reports::review_customer"/> <add id="Magento_Review::report_review_product" title="By Products" translate="title" sortOrder="20" module="Magento_Review" parent="Magento_Review::report_review" action="reports/report_review/product" resource="Magento_Reports::review_product"/> From 229da15cd22f9688b1018dd796da655571132a3c Mon Sep 17 00:00:00 2001 From: eduard13 <e.chitoraga@atwix.com> Date: Sat, 16 Mar 2019 10:33:50 +0200 Subject: [PATCH 308/315] Covering the Share Wishist by integration test --- .../Magento/Wishlist/Controller/ShareTest.php | 92 +++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 dev/tests/integration/testsuite/Magento/Wishlist/Controller/ShareTest.php diff --git a/dev/tests/integration/testsuite/Magento/Wishlist/Controller/ShareTest.php b/dev/tests/integration/testsuite/Magento/Wishlist/Controller/ShareTest.php new file mode 100644 index 0000000000000..83d79a43620ff --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Wishlist/Controller/ShareTest.php @@ -0,0 +1,92 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Wishlist\Controller; + +use Magento\Customer\Model\Session; +use Magento\Framework\App\Area; +use Magento\Framework\Data\Form\FormKey; +use Magento\Framework\Message\MessageInterface; +use Magento\TestFramework\Helper\Bootstrap; +use Magento\TestFramework\Request; +use Magento\TestFramework\TestCase\AbstractController; + +/** + * @magentoAppIsolation enabled + */ +class ShareTest extends AbstractController +{ + /** + * Test share wishlist with correct data + * + * @magentoDataFixture Magento/Wishlist/_files/wishlist.php + */ + public function testSuccessfullyShareWishlist() + { + $this->login(1); + $this->prepareRequestData(); + $this->dispatch('wishlist/index/send/'); + + $this->assertSessionMessages( + $this->equalTo(['Your wish list has been shared.']), + MessageInterface::TYPE_SUCCESS + ); + } + + /** + * Test share wishlist with incorrect data + * + * @magentoDataFixture Magento/Wishlist/_files/wishlist.php + */ + public function testShareWishlistWithoutEmails() + { + $this->login(1); + $this->prepareRequestData(true); + $this->dispatch('wishlist/index/send/'); + + $this->assertSessionMessages( + $this->equalTo(['Please enter an email address.']), + MessageInterface::TYPE_ERROR + ); + } + + /** + * Login the user + * + * @param string $customerId Customer to mark as logged in for the session + * @return void + */ + protected function login($customerId) + { + /** @var Session $session */ + $session = $this->_objectManager->get(Session::class); + $session->loginById($customerId); + } + + /** + * Prepares the request with data + * + * @param bool $invalidData + * @return void + */ + private function prepareRequestData($invalidData = false) + { + Bootstrap::getInstance()->loadArea(Area::AREA_FRONTEND); + $emails = !$invalidData ? 'email-1@example.com,email-1@example.com' : ''; + + /** @var FormKey $formKey */ + $formKey = $this->_objectManager->get(FormKey::class); + $post = [ + 'emails' => $emails, + 'message' => '', + 'form_key' => $formKey->getFormKey(), + ]; + + $this->getRequest()->setMethod(Request::METHOD_POST); + $this->getRequest()->setPostValue($post); + } +} From 89bcefa5296d551ef4fa568066f235f6b30c65f4 Mon Sep 17 00:00:00 2001 From: eduard13 <e.chitoraga@atwix.com> Date: Sat, 16 Mar 2019 16:07:32 +0200 Subject: [PATCH 309/315] Covering the Wishlist classes by integration and Unit Tests --- .../Product/AttributeValueProviderTest.php | 178 ++++++++++++++++++ .../Magento/Wishlist/Controller/ShareTest.php | 2 +- 2 files changed, 179 insertions(+), 1 deletion(-) create mode 100644 app/code/Magento/Wishlist/Test/Unit/Model/Product/AttributeValueProviderTest.php diff --git a/app/code/Magento/Wishlist/Test/Unit/Model/Product/AttributeValueProviderTest.php b/app/code/Magento/Wishlist/Test/Unit/Model/Product/AttributeValueProviderTest.php new file mode 100644 index 0000000000000..baafbdef47fe8 --- /dev/null +++ b/app/code/Magento/Wishlist/Test/Unit/Model/Product/AttributeValueProviderTest.php @@ -0,0 +1,178 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Wishlist\Test\Unit\Model\Product; + +use Magento\Catalog\Model\Product; +use Magento\Catalog\Model\ResourceModel\Product\Collection; +use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory; +use Magento\Framework\DB\Adapter\AdapterInterface; +use Magento\Wishlist\Model\Product\AttributeValueProvider; +use PHPUnit\Framework\TestCase; +use PHPUnit_Framework_MockObject_MockObject; + +/** + * @covers CreditCardTokenFormatter + */ +class AttributeValueProviderTest extends TestCase +{ + /** + * @var AttributeValueProvider|PHPUnit_Framework_MockObject_MockObject + */ + private $attributeValueProvider; + + /** + * @var CollectionFactory|PHPUnit_Framework_MockObject_MockObject + */ + private $productCollectionFactoryMock; + + /** + * @var @var Product|PHPUnit_Framework_MockObject_MockObject + */ + private $productMock; + + /** + * @var AdapterInterface|PHPUnit_Framework_MockObject_MockObject + */ + private $connectionMock; + + /** + * Set Up + * + * @return void + */ + protected function setUp() + { + $this->productCollectionFactoryMock = $this->createPartialMock( + CollectionFactory::class, + ['create'] + ); + $this->attributeValueProvider = new AttributeValueProvider( + $this->productCollectionFactoryMock + ); + } + + /** + * Get attribute text when the flat table is disabled + * + * @param int $productId + * @param string $attributeCode + * @param string $attributeText + * @return void + * @dataProvider attributeDataProvider + */ + public function testGetAttributeTextWhenFlatIsDisabled(int $productId, string $attributeCode, string $attributeText) + { + $this->productMock = $this->getMockBuilder(Product::class) + ->disableOriginalConstructor() + ->setMethods(['getData']) + ->getMock(); + + $this->productMock->expects($this->any()) + ->method('getData') + ->with($attributeCode) + ->willReturn($attributeText); + + $productCollection = $this->getMockBuilder(Collection::class) + ->disableOriginalConstructor() + ->setMethods([ + 'addIdFilter', 'addStoreFilter', 'addAttributeToSelect', 'isEnabledFlat', 'getFirstItem' + ])->getMock(); + + $productCollection->expects($this->any()) + ->method('addIdFilter') + ->willReturnSelf(); + $productCollection->expects($this->any()) + ->method('addStoreFilter') + ->willReturnSelf(); + $productCollection->expects($this->any()) + ->method('addAttributeToSelect') + ->willReturnSelf(); + $productCollection->expects($this->any()) + ->method('isEnabledFlat') + ->willReturn(false); + $productCollection->expects($this->any()) + ->method('getFirstItem') + ->willReturn($this->productMock); + + $this->productCollectionFactoryMock->expects($this->atLeastOnce()) + ->method('create') + ->willReturn($productCollection); + + $actual = $this->attributeValueProvider->getRawAttributeValue($productId, $attributeCode); + + $this->assertEquals($attributeText, $actual); + } + + + /** + * Get attribute text when the flat table is enabled + * + * @dataProvider attributeDataProvider + * @param int $productId + * @param string $attributeCode + * @param string $attributeText + * @return void + */ + public function testGetAttributeTextWhenFlatIsEnabled(int $productId, string $attributeCode, string $attributeText) + { + $this->connectionMock = $this->getMockBuilder(AdapterInterface::class)->getMockForAbstractClass(); + $this->connectionMock->expects($this->any()) + ->method('fetchRow') + ->willReturn([ + $attributeCode => $attributeText + ]); + $this->productMock = $this->getMockBuilder(Product::class) + ->disableOriginalConstructor() + ->setMethods(['getData']) + ->getMock(); + $this->productMock->expects($this->any()) + ->method('getData') + ->with($attributeCode) + ->willReturn($attributeText); + + $productCollection = $this->getMockBuilder(Collection::class) + ->disableOriginalConstructor() + ->setMethods([ + 'addIdFilter', 'addStoreFilter', 'addAttributeToSelect', 'isEnabledFlat', 'getConnection' + ])->getMock(); + + $productCollection->expects($this->any()) + ->method('addIdFilter') + ->willReturnSelf(); + $productCollection->expects($this->any()) + ->method('addStoreFilter') + ->willReturnSelf(); + $productCollection->expects($this->any()) + ->method('addAttributeToSelect') + ->willReturnSelf(); + $productCollection->expects($this->any()) + ->method('isEnabledFlat') + ->willReturn(true); + $productCollection->expects($this->any()) + ->method('getConnection') + ->willReturn($this->connectionMock); + + $this->productCollectionFactoryMock->expects($this->atLeastOnce()) + ->method('create') + ->willReturn($productCollection); + + $actual = $this->attributeValueProvider->getRawAttributeValue($productId, $attributeCode); + + $this->assertEquals($attributeText, $actual); + } + + /** + * @return array + */ + public function attributeDataProvider(): array + { + return [ + [1, 'attribute_code', 'Attribute Text'] + ]; + } +} diff --git a/dev/tests/integration/testsuite/Magento/Wishlist/Controller/ShareTest.php b/dev/tests/integration/testsuite/Magento/Wishlist/Controller/ShareTest.php index 83d79a43620ff..47705262caaf3 100644 --- a/dev/tests/integration/testsuite/Magento/Wishlist/Controller/ShareTest.php +++ b/dev/tests/integration/testsuite/Magento/Wishlist/Controller/ShareTest.php @@ -76,7 +76,7 @@ protected function login($customerId) private function prepareRequestData($invalidData = false) { Bootstrap::getInstance()->loadArea(Area::AREA_FRONTEND); - $emails = !$invalidData ? 'email-1@example.com,email-1@example.com' : ''; + $emails = !$invalidData ? 'email-1@example.com,email-2@example.com' : ''; /** @var FormKey $formKey */ $formKey = $this->_objectManager->get(FormKey::class); From 0cd94e2ea07bfe29b21efacfae61bd92be646576 Mon Sep 17 00:00:00 2001 From: eduard13 <e.chitoraga@atwix.com> Date: Sat, 16 Mar 2019 16:12:16 +0200 Subject: [PATCH 310/315] Small adjustment --- .../Test/Unit/Model/Product/AttributeValueProviderTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Wishlist/Test/Unit/Model/Product/AttributeValueProviderTest.php b/app/code/Magento/Wishlist/Test/Unit/Model/Product/AttributeValueProviderTest.php index baafbdef47fe8..e5f6b84bfc3da 100644 --- a/app/code/Magento/Wishlist/Test/Unit/Model/Product/AttributeValueProviderTest.php +++ b/app/code/Magento/Wishlist/Test/Unit/Model/Product/AttributeValueProviderTest.php @@ -16,7 +16,7 @@ use PHPUnit_Framework_MockObject_MockObject; /** - * @covers CreditCardTokenFormatter + * AttributeValueProviderTest */ class AttributeValueProviderTest extends TestCase { From afa9a80a9cbe246cf37d544ad9209ed8adfe8ed4 Mon Sep 17 00:00:00 2001 From: eduard13 <e.chitoraga@atwix.com> Date: Sat, 16 Mar 2019 16:17:55 +0200 Subject: [PATCH 311/315] Small adjustments --- .../Test/Unit/Model/Product/AttributeValueProviderTest.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/code/Magento/Wishlist/Test/Unit/Model/Product/AttributeValueProviderTest.php b/app/code/Magento/Wishlist/Test/Unit/Model/Product/AttributeValueProviderTest.php index e5f6b84bfc3da..fb0113eb6ae75 100644 --- a/app/code/Magento/Wishlist/Test/Unit/Model/Product/AttributeValueProviderTest.php +++ b/app/code/Magento/Wishlist/Test/Unit/Model/Product/AttributeValueProviderTest.php @@ -31,7 +31,7 @@ class AttributeValueProviderTest extends TestCase private $productCollectionFactoryMock; /** - * @var @var Product|PHPUnit_Framework_MockObject_MockObject + * @var Product|PHPUnit_Framework_MockObject_MockObject */ private $productMock; @@ -108,7 +108,6 @@ public function testGetAttributeTextWhenFlatIsDisabled(int $productId, string $a $this->assertEquals($attributeText, $actual); } - /** * Get attribute text when the flat table is enabled * From 95c1bc86ca8e5de7e5607d1b83d0fa46e9ded636 Mon Sep 17 00:00:00 2001 From: nmalevanec <mikola.malevanec@transoftgroup.com> Date: Thu, 21 Mar 2019 10:49:12 +0200 Subject: [PATCH 312/315] Fix static test. --- app/code/Magento/Review/Block/Adminhtml/Edit.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/code/Magento/Review/Block/Adminhtml/Edit.php b/app/code/Magento/Review/Block/Adminhtml/Edit.php index f6f0ccef9b4e7..9331a3d4610e0 100644 --- a/app/code/Magento/Review/Block/Adminhtml/Edit.php +++ b/app/code/Magento/Review/Block/Adminhtml/Edit.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ + namespace Magento\Review\Block\Adminhtml; /** @@ -56,6 +57,7 @@ public function __construct( * * @return void * @SuppressWarnings(PHPMD.ExcessiveMethodLength) + * @SuppressWarnings(PHPMD.RequestAwareBlockMethod) */ protected function _construct() { From c4312eb23f5d3b9502f866322c4b71dea23be2fd Mon Sep 17 00:00:00 2001 From: Pratik Oza <magepratik@gmail.com> Date: Thu, 21 Mar 2019 18:50:55 +0530 Subject: [PATCH 313/315] [Backport] [TASK] Remove translation of attribute store label in getAdditionalData --- app/code/Magento/Catalog/Block/Product/View/Attributes.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Block/Product/View/Attributes.php b/app/code/Magento/Catalog/Block/Product/View/Attributes.php index 8494b690bad9f..69c8b78b017d2 100644 --- a/app/code/Magento/Catalog/Block/Product/View/Attributes.php +++ b/app/code/Magento/Catalog/Block/Product/View/Attributes.php @@ -97,7 +97,7 @@ public function getAdditionalData(array $excludeAttr = []) if (is_string($value) && strlen(trim($value))) { $data[$attribute->getAttributeCode()] = [ - 'label' => __($attribute->getStoreLabel()), + 'label' => $attribute->getStoreLabel(), 'value' => $value, 'code' => $attribute->getAttributeCode(), ]; From a65bc160e85ea7f31e9da3349d355c823e7ea271 Mon Sep 17 00:00:00 2001 From: Stanislav Idolov <sidolov@magento.com> Date: Fri, 22 Mar 2019 16:43:36 -0500 Subject: [PATCH 314/315] magento-engcom/magento2ce#2699: Removed void return type --- .../Unit/Gateway/Request/VaultCaptureDataBuilderTest.php | 2 +- .../Magento/Framework/Code/Generator/AutoloaderTest.php | 8 ++++---- .../Magento/Framework/Code/Generator/Autoloader.php | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/app/code/Magento/Braintree/Test/Unit/Gateway/Request/VaultCaptureDataBuilderTest.php b/app/code/Magento/Braintree/Test/Unit/Gateway/Request/VaultCaptureDataBuilderTest.php index 80d333db80f0a..6925e37b580ac 100644 --- a/app/code/Magento/Braintree/Test/Unit/Gateway/Request/VaultCaptureDataBuilderTest.php +++ b/app/code/Magento/Braintree/Test/Unit/Gateway/Request/VaultCaptureDataBuilderTest.php @@ -111,7 +111,7 @@ public function testBuild() * @expectedException \Magento\Payment\Gateway\Command\CommandException * @expectedExceptionMessage The Payment Token is not available to perform the request. */ - public function testBuildWithoutPaymentToken(): void + public function testBuildWithoutPaymentToken() { $amount = 30.00; $buildSubject = [ diff --git a/dev/tests/integration/testsuite/Magento/Framework/Code/Generator/AutoloaderTest.php b/dev/tests/integration/testsuite/Magento/Framework/Code/Generator/AutoloaderTest.php index 0e1b51b3ae273..aaa3aa6c97a7e 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/Code/Generator/AutoloaderTest.php +++ b/dev/tests/integration/testsuite/Magento/Framework/Code/Generator/AutoloaderTest.php @@ -31,7 +31,7 @@ private function getTestFrameworkObjectManager() /** * @before */ - public function setupLoggerTestDouble(): void + public function setupLoggerTestDouble() { $loggerTestDouble = $this->createMock(LoggerInterface::class); $this->getTestFrameworkObjectManager()->addSharedInstance($loggerTestDouble, MagentoMonologLogger::class); @@ -40,7 +40,7 @@ public function setupLoggerTestDouble(): void /** * @after */ - public function removeLoggerTestDouble(): void + public function removeLoggerTestDouble() { $this->getTestFrameworkObjectManager()->removeSharedInstance(MagentoMonologLogger::class); } @@ -58,7 +58,7 @@ private function createExceptionThrowingGeneratorTestDouble(\RuntimeException $t return $generatorStub; } - public function testLogsExceptionDuringGeneration(): void + public function testLogsExceptionDuringGeneration() { $exceptionMessage = 'Test exception thrown during generation'; $testException = new \RuntimeException($exceptionMessage); @@ -70,7 +70,7 @@ public function testLogsExceptionDuringGeneration(): void $this->assertNull($autoloader->load(NonExistingClassName::class)); } - public function testFiltersDuplicateExceptionMessages(): void + public function testFiltersDuplicateExceptionMessages() { $exceptionMessage = 'Test exception thrown during generation'; $testException = new \RuntimeException($exceptionMessage); diff --git a/lib/internal/Magento/Framework/Code/Generator/Autoloader.php b/lib/internal/Magento/Framework/Code/Generator/Autoloader.php index 35c138147e9d3..f8e469fe05265 100644 --- a/lib/internal/Magento/Framework/Code/Generator/Autoloader.php +++ b/lib/internal/Magento/Framework/Code/Generator/Autoloader.php @@ -62,7 +62,7 @@ public function load($className) * * @param \Exception $exception */ - private function tryToLogExceptionMessageIfNotDuplicate(\Exception $exception): void + private function tryToLogExceptionMessageIfNotDuplicate(\Exception $exception) { if ($this->lastGenerationErrorMessage !== $exception->getMessage()) { $this->lastGenerationErrorMessage = $exception->getMessage(); @@ -84,7 +84,7 @@ private function tryToLogExceptionMessageIfNotDuplicate(\Exception $exception): * @param \Exception $exception * @return void */ - private function tryToLogException(\Exception $exception): void + private function tryToLogException(\Exception $exception) { try { $logger = ObjectManager::getInstance()->get(LoggerInterface::class); From aed827085358b282be7ba4763f5ed252310f5515 Mon Sep 17 00:00:00 2001 From: niravkrish <nirav.patel@krishtechnolabs.com> Date: Thu, 21 Feb 2019 12:02:47 +0530 Subject: [PATCH 315/315] Fixed Inline block edit identifier validation. --- .../Cms/view/adminhtml/ui_component/cms_block_listing.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/app/code/Magento/Cms/view/adminhtml/ui_component/cms_block_listing.xml b/app/code/Magento/Cms/view/adminhtml/ui_component/cms_block_listing.xml index 9f886f6f1345e..793fc7d26cb4a 100644 --- a/app/code/Magento/Cms/view/adminhtml/ui_component/cms_block_listing.xml +++ b/app/code/Magento/Cms/view/adminhtml/ui_component/cms_block_listing.xml @@ -146,7 +146,6 @@ <editor> <validation> <rule name="required-entry" xsi:type="boolean">true</rule> - <rule name="validate-xml-identifier" xsi:type="boolean">true</rule> </validation> <editorType>text</editorType> </editor>