Skip to content

Commit

Permalink
Merge branch '2.4-develop' into refactor/mftf-customer
Browse files Browse the repository at this point in the history
  • Loading branch information
lbajsarowicz committed Feb 14, 2020
2 parents df511be + 79ab7c8 commit b7e5bcf
Show file tree
Hide file tree
Showing 320 changed files with 9,250 additions and 1,599 deletions.
Expand Up @@ -9,6 +9,9 @@
use Magento\Framework\DataObject;

/**
* Produce html output using the given data source.
*
* phpcs:disable Magento2.Classes.AbstractApi
* Backend grid item abstract renderer
* @api
* @SuppressWarnings(PHPMD.NumberOfChildren)
Expand Down Expand Up @@ -53,7 +56,7 @@ public function getColumn()
* Renders grid column
*
* @param DataObject $row
* @return string
* @return string
*/
public function render(DataObject $row)
{
Expand All @@ -62,7 +65,7 @@ public function render(DataObject $row)
$result .= $this->getColumn()->getEditOnly() ? ''
: '<span class="admin__grid-control-value">' . $this->_getValue($row) . '</span>';

return $result . $this->_getInputValueElement($row) . '</div>' ;
return $result . $this->_getInputValueElement($row) . '</div>';
}
return $this->_getValue($row);
}
Expand Down Expand Up @@ -90,6 +93,7 @@ protected function _getValue(DataObject $row)
if (is_string($getter)) {
return $row->{$getter}();
} elseif (is_callable($getter)) {
//phpcs:ignore Magento2.Functions.DiscouragedFunction
return call_user_func($getter, $row);
}
return '';
Expand Down
Expand Up @@ -10,7 +10,8 @@
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd">
<actionGroup name="LoginActionGroup">
<annotations>
<description>Login to Backend Admin using ENV Admin credentials. PLEASE NOTE: This Action Group does NOT validate that you are Logged In.</description>
<description>DEPRECATED. Please use LoginAsAdmin instead.
Login to Backend Admin using ENV Admin credentials. PLEASE NOTE: This Action Group does NOT validate that you are Logged In.</description>
</annotations>

<amOnPage url="{{_ENV.MAGENTO_BACKEND_NAME}}" stepKey="navigateToAdmin"/>
Expand Down
4 changes: 2 additions & 2 deletions app/code/Magento/Backend/etc/adminhtml/system.xml
Expand Up @@ -115,15 +115,15 @@
<label>Enable Template Path Hints for Storefront</label>
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
</field>
<field id="template_hints_storefront_show_with_parameter" translate="label" type="select" sortOrder="20" showInDefault="1" showInWebsite="1" showInStore="1">
<field id="template_hints_storefront_show_with_parameter" translate="label comment" type="select" sortOrder="20" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Enable Hints for Storefront with URL Parameter</label>
<depends>
<field id="*/*/template_hints_storefront">1</field>
</depends>
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
<comment>Use URL parameter to enable template path hints for Storefront</comment>
</field>
<field id="template_hints_parameter_value" translate="label" type="text" sortOrder="20" showInDefault="1" showInWebsite="1" showInStore="1" canRestore="1">
<field id="template_hints_parameter_value" translate="label comment" type="text" sortOrder="20" showInDefault="1" showInWebsite="1" showInStore="1" canRestore="1">
<label>Parameter Value</label>
<depends>
<field id="*/*/template_hints_storefront">1</field>
Expand Down
2 changes: 2 additions & 0 deletions app/code/Magento/Backend/i18n/en_US.csv
Expand Up @@ -461,3 +461,5 @@ Pagination,Pagination
"Alternative text for the next pages link in the pagination menu. If empty, default arrow image is used.","Alternative text for the next pages link in the pagination menu. If empty, default arrow image is used."
"Anchor Text for Next","Anchor Text for Next"
"Theme Name","Theme Name"
"Use URL parameter to enable template path hints for Storefront","Use URL parameter to enable template path hints for Storefront"
"Add the following parameter to the URL to show template hints ?templatehints=[parameter_value]","Add the following parameter to the URL to show template hints ?templatehints=[parameter_value]"
Expand Up @@ -117,7 +117,7 @@ define([
options.bin = context.paymentPayload.details.bin;
}

if (shippingAddress) {
if (shippingAddress && this.isValidShippingAddress(shippingAddress)) {
options.additionalInformation = {
shippingGivenName: shippingAddress.firstname,
shippingSurname: shippingAddress.lastname,
Expand Down Expand Up @@ -206,6 +206,25 @@ define([
}

return false;
},

/**
* Validate shipping address
*
* @param {Object} shippingAddress
* @return {Boolean}
*/
isValidShippingAddress: function (shippingAddress) {
var isValid = false;

// check that required fields are not empty
if (shippingAddress.firstname && shippingAddress.lastname && shippingAddress.telephone &&
shippingAddress.street && shippingAddress.city && shippingAddress.regionCode &&
shippingAddress.postcode && shippingAddress.countryId) {
isValid = true;
}

return isValid;
}
};
});
Expand Up @@ -91,7 +91,7 @@ define(
})
.then(function (hostedFieldsInstance) {
self.hostedFieldsInstance = hostedFieldsInstance;
self.isPlaceOrderActionAllowed(true);
self.isPlaceOrderActionAllowed(false);
self.initFormValidationEvents(hostedFieldsInstance);

return self.hostedFieldsInstance;
Expand Down
Expand Up @@ -78,11 +78,7 @@ public function addParentFilterData(int $parentId, int $parentEntityId, string $
public function getOptionsByParentId(int $parentId) : array
{
$options = $this->fetch();
if (!isset($options[$parentId])) {
return [];
}

return $options[$parentId];
return $options[$parentId] ?? [];
}

/**
Expand Down Expand Up @@ -115,7 +111,7 @@ private function fetch() : array

$this->extensionAttributesJoinProcessor->process($optionsCollection);
if (empty($optionsCollection->getData())) {
return null;
return [];
}

/** @var \Magento\Bundle\Model\Option $option */
Expand Down
@@ -0,0 +1,53 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/

declare(strict_types=1);

namespace Magento\Captcha\Test\Unit\Observer;

use Magento\Captcha\Model\ResourceModel\Log;
use Magento\Captcha\Model\ResourceModel\LogFactory;
use Magento\Captcha\Observer\ResetAttemptForBackendObserver;
use Magento\Framework\Event;
use Magento\Framework\Event\Observer;
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;

/**
* Unit test for \Magento\Captcha\Observer\ResetAttemptForBackendObserver
*/
class ResetAttemptForBackendObserverTest extends TestCase
{
/**
* Test that the method resets attempts for Backend
*/
public function testExecuteExpectsDeleteUserAttemptsCalled()
{
$logMock = $this->createMock(Log::class);
$logMock->expects($this->once())->method('deleteUserAttempts')->willReturnSelf();

$resLogFactoryMock = $this->createMock(LogFactory::class);
$resLogFactoryMock->expects($this->once())
->method('create')
->willReturn($logMock);

/** @var MockObject|Observer $eventObserverMock */
$eventObserverMock = $this->createPartialMock(Observer::class, ['getUser']);
$eventMock = $this->createMock(Event::class);
$eventObserverMock->expects($this->once())
->method('getUser')
->willReturn($eventMock);

$objectManager = new ObjectManagerHelper($this);
/** @var ResetAttemptForBackendObserver $observer */
$observer = $objectManager->getObject(
ResetAttemptForBackendObserver::class,
['resLogFactory' => $resLogFactoryMock]
);
$this->assertInstanceOf(Log::class, $observer->execute($eventObserverMock));
}
}
@@ -0,0 +1,52 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/

declare(strict_types=1);

namespace Magento\Captcha\Test\Unit\Observer;

use Magento\Captcha\Model\ResourceModel\Log;
use Magento\Captcha\Model\ResourceModel\LogFactory;
use Magento\Captcha\Observer\ResetAttemptForFrontendObserver;
use Magento\Customer\Model\Customer;
use Magento\Framework\Event\Observer;
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;

/**
* Unit test for \Magento\Captcha\Observer\ResetAttemptForFrontendObserver
*/
class ResetAttemptForFrontendObserverTest extends TestCase
{
/**
* Test that the method resets attempts for Frontend
*/
public function testExecuteExpectsDeleteUserAttemptsCalled()
{
$logMock = $this->createMock(Log::class);
$logMock->expects($this->once())->method('deleteUserAttempts')->willReturnSelf();

$resLogFactoryMock = $this->createMock(LogFactory::class);
$resLogFactoryMock->expects($this->once())
->method('create')
->willReturn($logMock);

/** @var MockObject|Observer $eventObserverMock */
$eventObserverMock = $this->createPartialMock(Observer::class, ['getModel']);
$eventObserverMock->expects($this->once())
->method('getModel')
->willReturn($this->createMock(Customer::class));

$objectManager = new ObjectManagerHelper($this);
/** @var ResetAttemptForFrontendObserver $observer */
$observer = $objectManager->getObject(
ResetAttemptForFrontendObserver::class,
['resLogFactory' => $resLogFactoryMock]
);
$this->assertInstanceOf(Log::class, $observer->execute($eventObserverMock));
}
}
27 changes: 27 additions & 0 deletions app/code/Magento/Catalog/Api/CategoryListDeleteBySkuInterface.php
@@ -0,0 +1,27 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/

namespace Magento\Catalog\Api;

/**
* @api
* @since 100.0.2
*/
interface CategoryListDeleteBySkuInterface
{
/**
* Delete by skus list
*
* @param int $categoryId
* @param string[] $productSkuList
* @return bool
*
* @throws \Magento\Framework\Exception\CouldNotSaveException
* @throws \Magento\Framework\Exception\NoSuchEntityException
* @throws \Magento\Framework\Exception\InputException
*/
public function deleteBySkus(int $categoryId, array $productSkuList): bool;
}
77 changes: 67 additions & 10 deletions app/code/Magento/Catalog/Model/CategoryLinkRepository.php
Expand Up @@ -6,35 +6,52 @@

namespace Magento\Catalog\Model;

use Magento\Framework\Exception\InputException;
use Magento\Catalog\Api\CategoryLinkRepositoryInterface;
use Magento\Catalog\Api\CategoryListDeleteBySkuInterface;
use Magento\Catalog\Api\CategoryRepositoryInterface;
use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\Catalog\Model\ResourceModel\Product;
use Magento\Framework\App\ObjectManager;
use Magento\Framework\Exception\CouldNotSaveException;
use Magento\Framework\Exception\InputException;

class CategoryLinkRepository implements \Magento\Catalog\Api\CategoryLinkRepositoryInterface
/**
* @inheritdoc
*/
class CategoryLinkRepository implements CategoryLinkRepositoryInterface, CategoryListDeleteBySkuInterface
{
/**
* @var CategoryRepository
*/
protected $categoryRepository;

/**
* @var \Magento\Catalog\Api\ProductRepositoryInterface
* @var ProductRepositoryInterface
*/
protected $productRepository;

/**
* @param \Magento\Catalog\Api\CategoryRepositoryInterface $categoryRepository
* @param \Magento\Catalog\Api\ProductRepositoryInterface $productRepository
* @var Product
*/
private $productResource;

/**
* @param CategoryRepositoryInterface $categoryRepository
* @param ProductRepositoryInterface $productRepository
* @param Product $productResource
*/
public function __construct(
\Magento\Catalog\Api\CategoryRepositoryInterface $categoryRepository,
\Magento\Catalog\Api\ProductRepositoryInterface $productRepository
CategoryRepositoryInterface $categoryRepository,
ProductRepositoryInterface $productRepository,
Product $productResource = null
) {
$this->categoryRepository = $categoryRepository;
$this->productRepository = $productRepository;
$this->productResource = $productResource ?? ObjectManager::getInstance()->get(Product::class);
}

/**
* {@inheritdoc}
* @inheritdoc
*/
public function save(\Magento\Catalog\Api\Data\CategoryProductLinkInterface $productLink)
{
Expand All @@ -60,15 +77,15 @@ public function save(\Magento\Catalog\Api\Data\CategoryProductLinkInterface $pro
}

/**
* {@inheritdoc}
* @inheritdoc
*/
public function delete(\Magento\Catalog\Api\Data\CategoryProductLinkInterface $productLink)
{
return $this->deleteByIds($productLink->getCategoryId(), $productLink->getSku());
}

/**
* {@inheritdoc}
* @inheritdoc
*/
public function deleteByIds($categoryId, $sku)
{
Expand Down Expand Up @@ -101,4 +118,44 @@ public function deleteByIds($categoryId, $sku)
}
return true;
}

/**
* @inheritdoc
*/
public function deleteBySkus(int $categoryId, array $productSkuList): bool
{
$category = $this->categoryRepository->get($categoryId);
$products = $this->productResource->getProductsIdsBySkus($productSkuList);

if (!$products) {
throw new InputException(__("The category doesn't contain the specified products."));
}

$productPositions = $category->getProductsPosition();

foreach ($products as $productId) {
if (isset($productPositions[$productId])) {
unset($productPositions[$productId]);
}
}

$category->setPostedProducts($productPositions);

try {
$category->save();
} catch (\Exception $e) {
throw new CouldNotSaveException(
__(
'Could not save products "%products" to category %category',
[
"products" => implode(',', $productSkuList),
"category" => $category->getId()
]
),
$e
);
}

return true;
}
}

0 comments on commit b7e5bcf

Please sign in to comment.