diff --git a/app/code/Magento/Catalog/Controller/Product/Compare/Remove.php b/app/code/Magento/Catalog/Controller/Product/Compare/Remove.php
index f5d56dc9e6b0e..3f94ffd0909aa 100644
--- a/app/code/Magento/Catalog/Controller/Product/Compare/Remove.php
+++ b/app/code/Magento/Catalog/Controller/Product/Compare/Remove.php
@@ -7,6 +7,7 @@
namespace Magento\Catalog\Controller\Product\Compare;
use Magento\Catalog\Model\Product\Attribute\Source\Status;
+use Magento\Catalog\Model\ResourceModel\Product\Compare\Item\Collection;
use Magento\Framework\App\Action\HttpPostActionInterface as HttpPostActionInterface;
use Magento\Framework\Exception\NoSuchEntityException;
diff --git a/app/code/Magento/Catalog/Model/CompareList.php b/app/code/Magento/Catalog/Model/CompareList.php
new file mode 100644
index 0000000000000..5be30d40aacce
--- /dev/null
+++ b/app/code/Magento/Catalog/Model/CompareList.php
@@ -0,0 +1,24 @@
+_init(ResourceModel\Product\Compare\CompareList::class);
+ }
+}
diff --git a/app/code/Magento/Catalog/Model/CompareListIdToMaskedListId.php b/app/code/Magento/Catalog/Model/CompareListIdToMaskedListId.php
new file mode 100644
index 0000000000000..a911980b98894
--- /dev/null
+++ b/app/code/Magento/Catalog/Model/CompareListIdToMaskedListId.php
@@ -0,0 +1,58 @@
+compareListFactory = $compareListFactory;
+ $this->compareListResource = $compareListResource;
+ }
+
+ /**
+ * Get listIdMask by listId
+ *
+ * @param int $listId
+ *
+ * @param int|null $customerId
+ * @return null|string
+ * @throws LocalizedException
+ */
+ public function execute(int $listId, int $customerId = null): ?string
+ {
+ $compareList = $this->compareListFactory->create();
+ $this->compareListResource->load($compareList, $listId, 'list_id');
+ if ((int)$compareList->getCustomerId() !== (int)$customerId) {
+ throw new LocalizedException(__('This customer is not authorized to access this list'));
+ }
+ return $compareList->getListIdMask() ?? null;
+ }
+}
diff --git a/app/code/Magento/Catalog/Model/MaskedListIdToCompareListId.php b/app/code/Magento/Catalog/Model/MaskedListIdToCompareListId.php
new file mode 100644
index 0000000000000..cd1506c970763
--- /dev/null
+++ b/app/code/Magento/Catalog/Model/MaskedListIdToCompareListId.php
@@ -0,0 +1,57 @@
+compareListFactory = $compareListFactory;
+ $this->compareListResource = $compareListResource;
+ }
+
+ /**
+ * Get maskedId by listId
+ *
+ * @param string $maskedListId
+ * @param int $customerId
+ * @return int
+ * @throws LocalizedException
+ */
+ public function execute(string $maskedListId, int $customerId = null): int
+ {
+ $compareList = $this->compareListFactory->create();
+ $this->compareListResource->load($compareList, $maskedListId, 'list_id_mask');
+ if ((int)$compareList->getCustomerId() !== (int)$customerId) {
+ throw new LocalizedException(__('This customer is not authorized to access this list'));
+ }
+ return (int)$compareList->getListId();
+ }
+}
diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Compare/CompareList.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Compare/CompareList.php
new file mode 100644
index 0000000000000..4185df079d55d
--- /dev/null
+++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Compare/CompareList.php
@@ -0,0 +1,25 @@
+_init('catalog_compare_list', 'list_id');
+ }
+}
diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Compare/Item.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Compare/Item.php
index 7eb0552e355fc..ff29a5afa7eda 100644
--- a/app/code/Magento/Catalog/Model/ResourceModel/Product/Compare/Item.php
+++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Compare/Item.php
@@ -45,6 +45,10 @@ public function loadByProduct(\Magento\Catalog\Model\Product\Compare\Item $objec
$select->where('visitor_id = ?', (int)$object->getVisitorId());
}
+ if ($object->getListId()) {
+ $select->where('list_id = ?', (int)$object->getListId());
+ }
+
$data = $connection->fetchRow($select);
if (!$data) {
@@ -140,6 +144,7 @@ public function purgeVisitorByCustomer($object)
/**
* Update (Merge) customer data from visitor
+ *
* After Login process
*
* @param \Magento\Catalog\Model\Product\Compare\Item $object
diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Compare/Item/Collection.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Compare/Item/Collection.php
index 92741cf9ba88e..76f566a364769 100644
--- a/app/code/Magento/Catalog/Model/ResourceModel/Product/Compare/Item/Collection.php
+++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Compare/Item/Collection.php
@@ -31,6 +31,13 @@ class Collection extends \Magento\Catalog\Model\ResourceModel\Product\Collection
*/
protected $_visitorId = 0;
+ /**
+ * List Id Filter
+ *
+ * @var int
+ */
+ protected $listId = 0;
+
/**
* Comparable attributes cache
*
@@ -156,6 +163,30 @@ public function setCustomerId($customerId)
return $this;
}
+ /**
+ * Set listId filter to collection
+ *
+ * @param int $listId
+ *
+ * @return $this
+ */
+ public function setListId(int $listId)
+ {
+ $this->listId = $listId;
+ $this->_addJoinToSelect();
+ return $this;
+ }
+
+ /**
+ * Retrieve listId filter applied to collection
+ *
+ * @return int
+ */
+ public function getListId(): int
+ {
+ return (int)$this->listId;
+ }
+
/**
* Set visitor filter to collection
*
@@ -204,6 +235,10 @@ public function getConditionForJoin()
return ['visitor_id' => $this->getVisitorId()];
}
+ if ($this->getListId()) {
+ return ['list_id' => $this->getListId()];
+ }
+
return ['customer_id' => ['null' => true], 'visitor_id' => '0'];
}
@@ -232,6 +267,82 @@ public function _addJoinToSelect()
return $this;
}
+ /**
+ * Get products ids by for compare list
+ *
+ * @param int $listId
+ *
+ * @return array
+ */
+ public function getProductsByListId(int $listId): array
+ {
+ $select = $this->getConnection()->select()->
+ from(
+ $this->getTable('catalog_compare_item'),
+ 'product_id'
+ )->where(
+ 'list_id = ?',
+ $listId
+ );
+ return $this->getConnection()->fetchCol($select);
+ }
+
+
+ /**
+ * Set list_id for customer compare item
+ *
+ * @param int $listId
+ * @param int $customerId
+ */
+ public function setListIdToCustomerCompareItems(int $listId, int $customerId)
+ {
+ foreach ($this->getCustomerCompareItems($customerId) as $itemId) {
+ $this->getConnection()->update(
+ $this->getTable('catalog_compare_item'),
+ ['list_id' => $listId],
+ ['catalog_compare_item_id = ?' => (int)$itemId]
+ );
+ }
+ }
+
+ /**
+ * Remove compare list if customer compare list empty
+ *
+ * @param int|null $customerId
+ */
+ public function removeCompareList(?int $customerId)
+ {
+ if (empty($this->getCustomerCompareItems($customerId))) {
+ $this->getConnection()->delete(
+ $this->getTable('catalog_compare_list'),
+ ['customer_id = ?' => $customerId]
+ );
+ }
+ }
+
+ /**
+ * Get customer compare items
+ *
+ * @param int|null $customerId
+ * @return array
+ */
+ private function getCustomerCompareItems(?int $customerId): array
+ {
+ if ($customerId) {
+ $select = $this->getConnection()->select()->
+ from(
+ $this->getTable('catalog_compare_item')
+ )->where(
+ 'customer_id = ?',
+ $customerId
+ );
+
+ return $this->getConnection()->fetchCol($select);
+ }
+
+ return [];
+ }
+
/**
* Retrieve comapre products attribute set ids
*
diff --git a/app/code/Magento/Catalog/etc/db_schema.xml b/app/code/Magento/Catalog/etc/db_schema.xml
index ddd66a5bf04bd..ce34914a2f5d4 100644
--- a/app/code/Magento/Catalog/etc/db_schema.xml
+++ b/app/code/Magento/Catalog/etc/db_schema.xml
@@ -547,6 +547,8 @@
default="0" comment="Product ID"/>
+
@@ -558,6 +560,8 @@
referenceColumn="entity_id" onDelete="CASCADE"/>
+
@@ -573,6 +577,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
addProductToCompareList = $addProductToCompareList;
+ $this->getCompareList = $getCompareList;
+ $this->maskedListIdToCompareListId = $maskedListIdToCompareListId;
+ $this->getListIdByCustomerId = $getListIdByCustomerId;
+ }
+
+ /**
+ * Add products to compare list
+ *
+ * @param Field $field
+ * @param ContextInterface $context
+ * @param ResolveInfo $info
+ * @param array|null $value
+ * @param array|null $args
+ *
+ * @return Value|mixed|void
+ *
+ * @throws GraphQlInputException
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+ */
+ public function resolve(
+ Field $field,
+ $context,
+ ResolveInfo $info,
+ array $value = null,
+ array $args = null
+ ) {
+ if (empty($args['input']['uid'])) {
+ throw new GraphQlInputException(__('"uid" value must be specified.'));
+ }
+
+ if (!isset($args['input']['products'])) {
+ throw new GraphQlInputException(__('"products" value must be specified.'));
+ }
+
+ try {
+ $listId = $this->maskedListIdToCompareListId->execute($args['input']['uid'], $context->getUserId());
+ } catch (LocalizedException $exception) {
+ throw new GraphQlInputException(__($exception->getMessage()));
+ }
+
+
+ if (!$listId) {
+ throw new GraphQlInputException(__('"uid" value does not exist'));
+ }
+
+ try {
+ $this->addProductToCompareList->execute($listId, $args['input']['products'], $context);
+ } catch (\Exception $exception) {
+ throw new GraphQlInputException(__($exception->getMessage()));
+ }
+
+ return $this->getCompareList->execute($listId, $context);
+ }
+}
diff --git a/app/code/Magento/CompareListGraphQl/Model/Resolver/AssignCompareListToCustomer.php b/app/code/Magento/CompareListGraphQl/Model/Resolver/AssignCompareListToCustomer.php
new file mode 100644
index 0000000000000..8c43fcf5e9299
--- /dev/null
+++ b/app/code/Magento/CompareListGraphQl/Model/Resolver/AssignCompareListToCustomer.php
@@ -0,0 +1,110 @@
+setCustomerToCompareList = $setCustomerToCompareList;
+ $this->maskedListIdToCompareListId = $maskedListIdToCompareListId;
+ $this->getCompareList = $getCompareList;
+ }
+
+ /**
+ * Assign compare list to customer
+ *
+ * @param Field $field
+ * @param ContextInterface $context
+ * @param ResolveInfo $info
+ * @param array|null $value
+ * @param array|null $args
+ *
+ * @return Value|mixed|void
+ *
+ * @throws GraphQlInputException
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+ */
+ public function resolve(
+ Field $field,
+ $context,
+ ResolveInfo $info,
+ array $value = null,
+ array $args = null
+ ) {
+ if (empty($args['uid'])) {
+ throw new GraphQlInputException(__('"uid" value must be specified'));
+ }
+
+ if (!$context->getUserId()) {
+ throw new GraphQlInputException(__('Customer must be logged'));
+ }
+
+ try {
+ $listId = $this->maskedListIdToCompareListId->execute($args['uid']);
+ } catch (LocalizedException $exception) {
+ throw new GraphQlInputException(__($exception->getMessage()));
+ }
+
+ if ($listId) {
+ try {
+ $result = $this->setCustomerToCompareList->execute($listId, $context->getUserId(), $context);
+ if ($result) {
+ return [
+ 'result' => true,
+ 'compare_list' => $this->getCompareList->execute((int)$result->getListId(), $context)
+ ];
+ }
+ } catch (LocalizedException $exception) {
+ throw new GraphQlInputException(
+ __('Something was wrong during assigning customer.')
+ );
+ }
+ }
+
+ return [
+ 'result' => false
+ ];
+ }
+}
diff --git a/app/code/Magento/CompareListGraphQl/Model/Resolver/CompareList.php b/app/code/Magento/CompareListGraphQl/Model/Resolver/CompareList.php
new file mode 100644
index 0000000000000..861f3ce36d555
--- /dev/null
+++ b/app/code/Magento/CompareListGraphQl/Model/Resolver/CompareList.php
@@ -0,0 +1,85 @@
+getCompareList = $getCompareList;
+ $this->maskedListIdToCompareListId = $maskedListIdToCompareListId;
+ }
+
+ /**
+ * Get compare list
+ *
+ * @param Field $field
+ * @param ContextInterface $context
+ * @param ResolveInfo $info
+ * @param array|null $value
+ * @param array|null $args
+ *
+ * @return array|Value|mixed
+ *
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+ *
+ * @throws GraphQlInputException
+ */
+ public function resolve(
+ Field $field,
+ $context,
+ ResolveInfo $info,
+ array $value = null,
+ array $args = null
+ ) {
+ if (empty($args['uid'])) {
+ throw new GraphQlInputException(__('"uid" value must be specified'));
+ }
+
+ try {
+ $listId = $this->maskedListIdToCompareListId->execute($args['uid'], $context->getUserId());
+ } catch (LocalizedException $exception) {
+ throw new GraphQlInputException(__($exception->getMessage()));
+ }
+
+ if (!$listId) {
+ return null;
+ }
+
+ return $this->getCompareList->execute($listId, $context);
+ }
+}
diff --git a/app/code/Magento/CompareListGraphQl/Model/Resolver/CreateCompareList.php b/app/code/Magento/CompareListGraphQl/Model/Resolver/CreateCompareList.php
new file mode 100644
index 0000000000000..9b0e8fd18298f
--- /dev/null
+++ b/app/code/Magento/CompareListGraphQl/Model/Resolver/CreateCompareList.php
@@ -0,0 +1,124 @@
+mathRandom = $mathRandom;
+ $this->getListIdByCustomerId = $getListIdByCustomerId;
+ $this->addProductToCompareList = $addProductToCompareList;
+ $this->getCompareList = $getCompareList;
+ $this->createCompareList = $createCompareList;
+ }
+
+ /**
+ * Create compare list
+ *
+ * @param Field $field
+ * @param ContextInterface $context
+ * @param ResolveInfo $info
+ * @param array|null $value
+ * @param array|null $args
+ *
+ * @return Value|mixed|void
+ *
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+ * @throws GraphQlInputException
+ * @throws LocalizedException
+ */
+ public function resolve(
+ Field $field,
+ $context,
+ ResolveInfo $info,
+ array $value = null,
+ array $args = null
+ ) {
+ $customerId = $context->getUserId();
+ $products = !empty($args['input']['products']) ? $args['input']['products'] : [];
+ $generatedListId = $this->mathRandom->getUniqueHash();
+ $listId = 0;
+
+ try {
+ if ((0 === $customerId || null === $customerId)) {
+ $listId = $this->createCompareList->execute($generatedListId);
+ $this->addProductToCompareList->execute($listId, $products, $context);
+ }
+
+ if ($customerId) {
+ $listId = $this->getListIdByCustomerId->execute($customerId);
+ if ($listId) {
+ $this->addProductToCompareList->execute($listId, $products, $context);
+ } else {
+ $listId = $this->createCompareList->execute($generatedListId, $customerId);
+ $this->addProductToCompareList->execute($listId, $products, $context);
+ }
+ }
+ } catch (LocalizedException $exception) {
+ throw new GraphQlInputException(
+ __('Something was wrong during creating compare list')
+ );
+ }
+
+ return $this->getCompareList->execute($listId, $context);
+ }
+}
diff --git a/app/code/Magento/CompareListGraphQl/Model/Resolver/CustomerCompareList.php b/app/code/Magento/CompareListGraphQl/Model/Resolver/CustomerCompareList.php
new file mode 100644
index 0000000000000..84d0aad0c9a71
--- /dev/null
+++ b/app/code/Magento/CompareListGraphQl/Model/Resolver/CustomerCompareList.php
@@ -0,0 +1,73 @@
+getCompareList = $getCompareList;
+ $this->getListIdByCustomerId = $getListIdByCustomerId;
+ }
+
+ /**
+ * Get customer compare list
+ *
+ * @param Field $field
+ * @param ContextInterface $context
+ * @param ResolveInfo $info
+ * @param array|null $value
+ * @param array|null $args
+ *
+ * @return Value|mixed|void
+ *
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+ */
+ public function resolve(
+ Field $field,
+ $context,
+ ResolveInfo $info,
+ array $value = null,
+ array $args = null
+ ) {
+ $listId = $this->getListIdByCustomerId->execute((int)$context->getUserId());
+
+ if (!$listId) {
+ return null;
+ }
+
+ return $this->getCompareList->execute($listId, $context);
+ }
+}
diff --git a/app/code/Magento/CompareListGraphQl/Model/Resolver/DeleteCompareList.php b/app/code/Magento/CompareListGraphQl/Model/Resolver/DeleteCompareList.php
new file mode 100644
index 0000000000000..a811478718985
--- /dev/null
+++ b/app/code/Magento/CompareListGraphQl/Model/Resolver/DeleteCompareList.php
@@ -0,0 +1,137 @@
+compareListFactory = $compareListFactory;
+ $this->compareListResource = $compareListResource;
+ $this->maskedListIdToCompareListId = $maskedListIdToCompareListId;
+ $this->getListIdByCustomerId = $getListIdByCustomerId;
+ }
+
+ /**
+ * Remove compare list
+ *
+ * @param Field $field
+ * @param ContextInterface $context
+ * @param ResolveInfo $info
+ * @param array|null $value
+ * @param array|null $args
+ *
+ * @return Value|mixed|void
+ *
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+ * @throws GraphQlInputException
+ */
+ public function resolve(
+ Field $field,
+ $context,
+ ResolveInfo $info,
+ array $value = null,
+ array $args = null
+ ) {
+ if (empty($args['uid'])) {
+ throw new GraphQlInputException(__('"uid" value must be specified'));
+ }
+
+ try {
+ $listId = $this->maskedListIdToCompareListId->execute($args['uid'], $context->getUserId());
+ } catch (LocalizedException $exception) {
+ throw new GraphQlInputException(__($exception->getMessage()));
+ }
+ $removed = ['result' => false];
+
+ if ($userId = $context->getUserId()) {
+ $customerListId = $this->getListIdByCustomerId->execute($userId);
+ if ($listId === $customerListId) {
+ try {
+ $removed['result'] = $this->deleteCompareList($customerListId);
+ } catch (LocalizedException $exception) {
+ throw new GraphQlInputException(
+ __('Something was wrong during removing compare list')
+ );
+ }
+ }
+ }
+
+ if ($listId) {
+ try {
+ $removed['result'] = $this->deleteCompareList($listId);
+ } catch (LocalizedException $exception) {
+ throw new GraphQlInputException(
+ __('Something was wrong during removing compare list')
+ );
+ }
+ }
+
+ return $removed;
+ }
+
+ /**
+ * Delete compare list
+ *
+ * @param int|null $listId
+ * @return bool
+ */
+ private function deleteCompareList(?int $listId): bool
+ {
+ $compareList = $this->compareListFactory->create();
+ $compareList->setListId($listId);
+ $this->compareListResource->delete($compareList);
+
+ return true;
+ }
+}
diff --git a/app/code/Magento/CompareListGraphQl/Model/Resolver/RemoveProductsFromCompareList.php b/app/code/Magento/CompareListGraphQl/Model/Resolver/RemoveProductsFromCompareList.php
new file mode 100644
index 0000000000000..6e4e4d8951cb9
--- /dev/null
+++ b/app/code/Magento/CompareListGraphQl/Model/Resolver/RemoveProductsFromCompareList.php
@@ -0,0 +1,140 @@
+getCompareList = $getCompareList;
+ $this->removeFromCompareList = $removeFromCompareList;
+ $this->maskedListIdToCompareListId = $maskedListIdToCompareListId;
+ $this->getListIdByCustomerId = $getListIdByCustomerId;
+ }
+
+ /**
+ * Remove products from compare list
+ *
+ * @param Field $field
+ * @param ContextInterface $context
+ * @param ResolveInfo $info
+ * @param array|null $value
+ * @param array|null $args
+ *
+ * @return Value|mixed|void
+ *
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+ *
+ * @throws GraphQlInputException
+ */
+ public function resolve(
+ Field $field,
+ $context,
+ ResolveInfo $info,
+ array $value = null,
+ array $args = null
+ ) {
+ if (!isset($args['input']['products'])) {
+ throw new GraphQlInputException(__('"products" value must be specified.'));
+ }
+
+ if (empty($args['input']['uid'])) {
+ throw new GraphQlInputException(__('"uid" value must be specified.'));
+ }
+
+ try {
+ $listId = $this->maskedListIdToCompareListId->execute($args['input']['uid'], $context->getUserId());
+ } catch (LocalizedException $exception) {
+ throw new GraphQlInputException(__($exception->getMessage()));
+ }
+
+ if (!$listId) {
+ throw new GraphQlInputException(__('"uid" value does not exist'));
+ }
+
+ if ($userId = $context->getUserId()) {
+ $customerListId = $this->getListIdByCustomerId->execute($userId);
+ if ($listId === $customerListId) {
+ $this->removeFromCompareList($customerListId, $args);
+ }
+ }
+
+ try {
+ $this->removeFromCompareList->execute($listId, $args['input']['products']);
+ } catch (LocalizedException $exception) {
+ throw new GraphQlInputException(
+ __('Something was wrong during removing products from compare list')
+ );
+ }
+
+ return $this->getCompareList->execute($listId, $context);
+ }
+
+ /**
+ * Remove products from compare list
+ *
+ * @param int $listId
+ * @param array $args
+ * @throws GraphQlInputException
+ */
+ private function removeFromCompareList(int $listId, array $args): void
+ {
+ try {
+ $this->removeFromCompareList->execute($listId, $args['input']['products']);
+ } catch (LocalizedException $exception) {
+ throw new GraphQlInputException(
+ __('Something was wrong during removing products from compare list')
+ );
+ }
+ }
+}
diff --git a/app/code/Magento/CompareListGraphQl/Model/Service/AddToCompareList.php b/app/code/Magento/CompareListGraphQl/Model/Service/AddToCompareList.php
new file mode 100644
index 0000000000000..6f976bdd07d4d
--- /dev/null
+++ b/app/code/Magento/CompareListGraphQl/Model/Service/AddToCompareList.php
@@ -0,0 +1,106 @@
+compareItemFactory = $compareItemFactory;
+ $this->productRepository = $productRepository;
+ $this->itemCollection = $collection;
+ }
+
+ /**
+ * Add products to compare list
+ *
+ * @param int $listId
+ * @param array $products
+ * @param ContextInterface $context
+ *
+ * @return int
+ * @throws \Exception
+ */
+ public function execute(int $listId, array $products, ContextInterface $context): int
+ {
+ $storeId = (int)$context->getExtensionAttributes()->getStore()->getStoreId();
+ $customerId = $context->getUserId();
+ if ($customerId) {
+ $this->itemCollection->setListIdToCustomerCompareItems($listId, $customerId);
+ }
+
+ if (count($products)) {
+ $existedProducts = $this->itemCollection->getProductsByListId($listId);
+ foreach ($products as $productId) {
+ if (array_search($productId, $existedProducts) === false) {
+ if ($this->productExists($productId)) {
+ $item = $this->compareItemFactory->create();
+ if ($customerId) {
+ $item->setCustomerId($customerId);
+ }
+ $item->addProductData($productId);
+ $item->setStoreId($storeId);
+ $item->setListId($listId);
+ $item->save();
+ }
+ }
+ }
+ }
+
+ return (int)$listId;
+ }
+
+ /**
+ * Check product exists.
+ *
+ * @param int $productId
+ *
+ * @return bool
+ */
+ private function productExists($productId)
+ {
+ try {
+ $product = $this->productRepository->getById((int)$productId);
+ return !empty($product->getId());
+ } catch (NoSuchEntityException $e) {
+ return false;
+ }
+ }
+}
diff --git a/app/code/Magento/CompareListGraphQl/Model/Service/Collection/GetComparableItemsCollection.php b/app/code/Magento/CompareListGraphQl/Model/Service/Collection/GetComparableItemsCollection.php
new file mode 100644
index 0000000000000..e766ec85248a1
--- /dev/null
+++ b/app/code/Magento/CompareListGraphQl/Model/Service/Collection/GetComparableItemsCollection.php
@@ -0,0 +1,87 @@
+itemCollectionFactory = $itemCollectionFactory;
+ $this->catalogProductVisibility = $catalogProductVisibility;
+ $this->catalogConfig = $catalogConfig;
+ $this->compareProduct = $compareHelper;
+ }
+
+ /**
+ * Get collection of comparable items
+ *
+ * @param int $listId
+ * @param ContextInterface $context
+ *
+ * @return Collection
+ */
+ public function execute(int $listId, ContextInterface $context): Collection
+ {
+ $this->compareProduct->setAllowUsedFlat(false);
+ $this->items = $this->itemCollectionFactory->create();
+ $this->items->setListId($listId);
+ $this->items->useProductItem()->setStoreId($context->getExtensionAttributes()->getStore()->getStoreId());
+ $this->items->addAttributeToSelect(
+ $this->catalogConfig->getProductAttributes()
+ )->loadComparableAttributes()->addMinimalPrice()->addTaxPercents()->setVisibility(
+ $this->catalogProductVisibility->getVisibleInSiteIds()
+ );
+
+ return $this->items;
+ }
+}
diff --git a/app/code/Magento/CompareListGraphQl/Model/Service/CreateCompareList.php b/app/code/Magento/CompareListGraphQl/Model/Service/CreateCompareList.php
new file mode 100644
index 0000000000000..089bdb1adef17
--- /dev/null
+++ b/app/code/Magento/CompareListGraphQl/Model/Service/CreateCompareList.php
@@ -0,0 +1,57 @@
+compareListFactory = $compareListFactory;
+ $this->compareListResource = $compareListResource;
+ }
+
+ /**
+ * Created new compare list
+ *
+ * @param string $maskedId
+ * @param int $customerId
+ *
+ * @return int
+ */
+ public function execute(string $maskedId, ?int $customerId = null): int
+ {
+ $compareList = $this->compareListFactory->create();
+ $compareList->setListIdMask($maskedId);
+ $compareList->setCustomerId($customerId);
+ $this->compareListResource->save($compareList);
+
+ return (int)$compareList->getListId();
+ }
+}
diff --git a/app/code/Magento/CompareListGraphQl/Model/Service/Customer/GetListIdByCustomerId.php b/app/code/Magento/CompareListGraphQl/Model/Service/Customer/GetListIdByCustomerId.php
new file mode 100644
index 0000000000000..c6437683f6ba7
--- /dev/null
+++ b/app/code/Magento/CompareListGraphQl/Model/Service/Customer/GetListIdByCustomerId.php
@@ -0,0 +1,59 @@
+compareListFactory = $compareListFactory;
+ $this->resourceCompareList = $resourceCompareList;
+ }
+
+ /**
+ * Get listId by Customer ID
+ *
+ * @param int $customerId
+ *
+ * @return int|null
+ */
+ public function execute(int $customerId): ?int
+ {
+ if ($customerId) {
+ /** @var CompareList $compareList */
+ $compareList = $this->compareListFactory->create();
+ $this->resourceCompareList->load($compareList, $customerId, 'customer_id');
+ return (int)$compareList->getListId();
+ }
+
+ return null;
+ }
+}
diff --git a/app/code/Magento/CompareListGraphQl/Model/Service/Customer/SetCustomerToCompareList.php b/app/code/Magento/CompareListGraphQl/Model/Service/Customer/SetCustomerToCompareList.php
new file mode 100644
index 0000000000000..72216c6c70a16
--- /dev/null
+++ b/app/code/Magento/CompareListGraphQl/Model/Service/Customer/SetCustomerToCompareList.php
@@ -0,0 +1,117 @@
+validateCustomer = $validateCustomer;
+ $this->compareListFactory = $compareListFactory;
+ $this->resourceCompareList = $resourceCompareList;
+ $this->getListIdByCustomerId = $getListIdByCustomerId;
+ $this->itemCollectionFactory = $itemCollectionFactory;
+ $this->addProductToCompareList = $addProductToCompareList;
+ }
+
+ /**
+ * Set customer to compare list
+ *
+ * @param int $listId
+ * @param int $customerId
+ *
+ * @return CompareList
+ *
+ * @throws GraphQlAuthenticationException
+ * @throws GraphQlInputException
+ * @throws GraphQlNoSuchEntityException
+ */
+ public function execute(int $listId, int $customerId, ContextInterface $context): ?CompareList
+ {
+ if ($this->validateCustomer->execute($customerId)) {
+ /** @var CompareList $compareListModel */
+ $compareList = $this->compareListFactory->create();
+ $customerListId = $this->getListIdByCustomerId->execute($customerId);
+ $this->resourceCompareList->load($compareList, $listId, 'list_id');
+ if ($customerListId) {
+ $this->items = $this->itemCollectionFactory->create();
+ $products = $this->items->getProductsByListId($listId);
+ $this->addProductToCompareList->execute($customerListId, $products, $context);
+ $this->resourceCompareList->delete($compareList);
+ $compareList = $this->compareListFactory->create();
+ $this->resourceCompareList->load($compareList, $customerListId, 'list_id');
+ return $compareList;
+ }
+ $compareList->setCustomerId($customerId);
+ $this->resourceCompareList->save($compareList);
+ return $compareList;
+ }
+
+ return null;
+ }
+}
diff --git a/app/code/Magento/CompareListGraphQl/Model/Service/Customer/ValidateCustomer.php b/app/code/Magento/CompareListGraphQl/Model/Service/Customer/ValidateCustomer.php
new file mode 100644
index 0000000000000..ab16b17240b1c
--- /dev/null
+++ b/app/code/Magento/CompareListGraphQl/Model/Service/Customer/ValidateCustomer.php
@@ -0,0 +1,94 @@
+authentication = $authentication;
+ $this->accountManagement = $accountManagement;
+ $this->customerRepository = $customerRepository;
+ }
+
+ /**
+ * Customer validate
+ *
+ * @param int $customerId
+ *
+ * @return int
+ *
+ * @throws GraphQlAuthenticationException
+ * @throws GraphQlInputException
+ * @throws GraphQlNoSuchEntityException
+ */
+ public function execute(int $customerId): int
+ {
+ try {
+ $customer = $this->customerRepository->getById($customerId);
+ } catch (NoSuchEntityException $e) {
+ throw new GraphQlNoSuchEntityException(
+ __('Customer with id "%customer_id" does not exist.', ['customer_id' => $customerId]),
+ $e
+ );
+ } catch (LocalizedException $e) {
+ throw new GraphQlInputException(__($e->getMessage()));
+ }
+
+ if (true === $this->authentication->isLocked($customerId)) {
+ throw new GraphQlAuthenticationException(__('The account is locked.'));
+ }
+
+ try {
+ $confirmationStatus = $this->accountManagement->getConfirmationStatus($customerId);
+ } catch (LocalizedException $e) {
+ throw new GraphQlInputException(__($e->getMessage()));
+ }
+
+ if ($confirmationStatus === AccountManagementInterface::ACCOUNT_CONFIRMATION_REQUIRED) {
+ throw new GraphQlAuthenticationException(__("This account isn't confirmed. Verify and try again."));
+ }
+
+ return (int)$customer->getId();
+ }
+}
diff --git a/app/code/Magento/CompareListGraphQl/Model/Service/GetComparableAttributes.php b/app/code/Magento/CompareListGraphQl/Model/Service/GetComparableAttributes.php
new file mode 100644
index 0000000000000..5b051a3825aac
--- /dev/null
+++ b/app/code/Magento/CompareListGraphQl/Model/Service/GetComparableAttributes.php
@@ -0,0 +1,53 @@
+comparableItemsCollection = $comparableItemsCollection;
+ }
+
+ /**
+ * Get comparable attributes
+ *
+ * @param int $listId
+ * @param ContextInterface $context
+ *
+ * @return array
+ */
+ public function execute(int $listId, ContextInterface $context): array
+ {
+ $attributes = [];
+ $itemsCollection = $this->comparableItemsCollection->execute($listId, $context);
+ foreach ($itemsCollection->getComparableAttributes() as $item) {
+ $attributes[] = [
+ 'code' => $item->getAttributeCode(),
+ 'label' => $item->getStoreLabel()
+ ];
+ }
+
+ return $attributes;
+ }
+}
diff --git a/app/code/Magento/CompareListGraphQl/Model/Service/GetComparableItems.php b/app/code/Magento/CompareListGraphQl/Model/Service/GetComparableItems.php
new file mode 100644
index 0000000000000..1cf42553718fd
--- /dev/null
+++ b/app/code/Magento/CompareListGraphQl/Model/Service/GetComparableItems.php
@@ -0,0 +1,122 @@
+blockListCompare = $listCompare;
+ $this->comparableItemsCollection = $comparableItemsCollection;
+ $this->productRepository = $productRepository;
+ }
+
+ /**
+ * Get comparable items
+ *
+ * @param int $listId
+ * @param ContextInterface $context
+ *
+ * @return array
+ * @throws GraphQlInputException
+ */
+ public function execute(int $listId, ContextInterface $context)
+ {
+ $items = [];
+ foreach ($this->comparableItemsCollection->execute($listId, $context) as $item) {
+ /** @var Product $item */
+ $items[] = [
+ 'uid' => $item->getId(),
+ 'product' => $this->getProductData((int)$item->getId()),
+ 'attributes' => $this->getProductComparableAttributes($listId, $item, $context)
+ ];
+ }
+
+ return $items;
+ }
+
+ /**
+ * Get product data
+ *
+ * @param int $productId
+ *
+ * @return array
+ *
+ * @throws GraphQlInputException
+ */
+ private function getProductData(int $productId): array
+ {
+ $productData = [];
+ try {
+ $item = $this->productRepository->getById($productId);
+ $productData = $item->getData();
+ $productData['model'] = $item;
+ } catch (LocalizedException $e) {
+ throw new GraphQlInputException(__($e->getMessage()));
+ }
+
+ return $productData;
+ }
+
+ /**
+ * Get comparable attributes for product
+ *
+ * @param int $listId
+ * @param Product $product
+ * @param ContextInterface $context
+ *
+ * @return array
+ */
+ private function getProductComparableAttributes(int $listId, Product $product, ContextInterface $context): array
+ {
+ $attributes = [];
+ $itemsCollection = $this->comparableItemsCollection->execute($listId, $context);
+ foreach ($itemsCollection->getComparableAttributes() as $item) {
+ $attributes[] = [
+ 'code' => $item->getAttributeCode(),
+ 'value' => $this->blockListCompare->getProductAttributeValue($product, $item)
+ ];
+ }
+
+ return $attributes;
+ }
+}
diff --git a/app/code/Magento/CompareListGraphQl/Model/Service/GetCompareList.php b/app/code/Magento/CompareListGraphQl/Model/Service/GetCompareList.php
new file mode 100644
index 0000000000000..5cef555479838
--- /dev/null
+++ b/app/code/Magento/CompareListGraphQl/Model/Service/GetCompareList.php
@@ -0,0 +1,75 @@
+comparableItemsService = $comparableItemsService;
+ $this->comparableAttributesService = $comparableAttributesService;
+ $this->compareListIdToMaskedListId = $compareListIdToMaskedListId;
+ }
+
+ /**
+ * Get compare list information
+ *
+ * @param int $listId
+ * @param ContextInterface $context
+ *
+ * @return array
+ * @throws GraphQlInputException
+ */
+ public function execute(int $listId, ContextInterface $context)
+ {
+ try {
+ $maskedListId = $this->compareListIdToMaskedListId->execute($listId, $context->getUserId());
+ } catch (LocalizedException $exception) {
+ throw new GraphQlInputException(__($exception->getMessage()));
+ }
+ $comparableItems = $this->comparableItemsService->execute($listId, $context);
+
+ return [
+ 'uid' => $maskedListId,
+ 'items' => $comparableItems,
+ 'attributes' => $this->comparableAttributesService->execute($listId, $context),
+ 'item_count' => count($comparableItems)
+ ];
+ }
+}
diff --git a/app/code/Magento/CompareListGraphQl/Model/Service/RemoveFromCompareList.php b/app/code/Magento/CompareListGraphQl/Model/Service/RemoveFromCompareList.php
new file mode 100644
index 0000000000000..dda400559a412
--- /dev/null
+++ b/app/code/Magento/CompareListGraphQl/Model/Service/RemoveFromCompareList.php
@@ -0,0 +1,59 @@
+compareItemFactory = $compareItemFactory;
+ $this->compareItemResource = $compareItemResource;
+ }
+
+ /**
+ * Remove products from compare list
+ *
+ * @param int $listId
+ * @param array $products
+ */
+ public function execute(int $listId, array $products)
+ {
+ foreach ($products as $productId) {
+ /* @var $item Item */
+ $item = $this->compareItemFactory->create();
+ $item->setListId($listId);
+ $this->compareItemResource->loadByProduct($item, $productId);
+ if ($item->getId()) {
+ $this->compareItemResource->delete($item);
+ }
+ }
+ }
+}
diff --git a/app/code/Magento/CompareListGraphQl/README.md b/app/code/Magento/CompareListGraphQl/README.md
new file mode 100644
index 0000000000000..ed1c38ab33a3b
--- /dev/null
+++ b/app/code/Magento/CompareListGraphQl/README.md
@@ -0,0 +1,4 @@
+# CompareListGraphQl module
+
+The CompareListGraphQl module is designed to implement compare product functionality.
+
diff --git a/app/code/Magento/CompareListGraphQl/composer.json b/app/code/Magento/CompareListGraphQl/composer.json
new file mode 100644
index 0000000000000..dd9c998857258
--- /dev/null
+++ b/app/code/Magento/CompareListGraphQl/composer.json
@@ -0,0 +1,23 @@
+{
+ "name": "magento/module-compare-list-graph-ql",
+ "description": "N/A",
+ "type": "magento2-module",
+ "require": {
+ "php": "~7.3.0||~7.4.0",
+ "magento/framework": "*",
+ "magento/module-catalog": "*",
+ "magento/module-customer": "*"
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "autoload": {
+ "files": [
+ "registration.php"
+ ],
+ "psr-4": {
+ "Magento\\CompareListGraphQl\\": ""
+ }
+ }
+}
diff --git a/app/code/Magento/CompareListGraphQl/etc/module.xml b/app/code/Magento/CompareListGraphQl/etc/module.xml
new file mode 100644
index 0000000000000..b3c330fc38df2
--- /dev/null
+++ b/app/code/Magento/CompareListGraphQl/etc/module.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/CompareListGraphQl/etc/schema.graphqls b/app/code/Magento/CompareListGraphQl/etc/schema.graphqls
new file mode 100644
index 0000000000000..e533d476ddd59
--- /dev/null
+++ b/app/code/Magento/CompareListGraphQl/etc/schema.graphqls
@@ -0,0 +1,64 @@
+# Copyright © Magento, Inc. All rights reserved.
+# See COPYING.txt for license details.
+
+type ComparableItem {
+ uid: ID! @doc(description: "The unique ID of an item in a compare list")
+ product: ProductInterface! @doc(description: "Contains details about a product in a compare list")
+ attributes: [ProductAttribute]! @doc(description: "An array of product attributes that can be used to compare products")
+}
+
+type ProductAttribute {
+ code: String! @doc(description: "The unique identifier for a product attribute code.")
+ value: String! @doc(description:"The display value of the attribute")
+}
+
+type ComparableAttribute {
+ code: String! @doc(description: "An attribute code that is enabled for product comparisons")
+ label: String! @doc(description: "The label of the attribute code")
+}
+
+type CompareList {
+ uid: ID! @doc(description: "The unique ID assigned to the compare list")
+ items: [ComparableItem] @doc(description: "An array of products to compare")
+ attributes: [ComparableAttribute] @doc(description: "An array of attributes that can be used for comparing products")
+ item_count: Int! @doc(description: "The number of items in the compare list")
+}
+
+type Customer {
+ compare_list: CompareList @resolver(class: "\\Magento\\CompareListGraphQl\\Model\\Resolver\\CustomerCompareList") @doc(description: "The contents of the customer's compare list")
+}
+
+type Query {
+ compareList(uid: ID!): CompareList @resolver(class: "\\Magento\\CompareListGraphQl\\Model\\Resolver\\CompareList") @doc(description: "Return products that have been added to the specified compare list")
+}
+
+type Mutation {
+ createCompareList(input: CreateCompareListInput): CompareList @resolver(class: "\\Magento\\CompareListGraphQl\\Model\\Resolver\\CreateCompareList") @doc(description: "Creates a new compare list. The compare list is saved for logged in customers")
+ addProductsToCompareList(input: AddProductsToCompareListInput): CompareList @resolver(class: "\\Magento\\CompareListGraphQl\\Model\\Resolver\\AddProductsToCompareList") @doc(description: "Add products to the specified compare list")
+ removeProductsFromCompareList(input: RemoveProductsFromCompareListInput): CompareList @resolver(class: "\\Magento\\CompareListGraphQl\\Model\\Resolver\\RemoveProductsFromCompareList") @doc(description: "Remove products from the specified compare list")
+ assignCompareListToCustomer(uid: ID!): AssignCompareListToCustomerOutput @resolver(class: "\\Magento\\CompareListGraphQl\\Model\\Resolver\\AssignCompareListToCustomer") @doc(description: "Assign the specified compare list to the logged in customer")
+ deleteCompareList(uid: ID!): DeleteCompareListOutput @resolver(class: "\\Magento\\CompareListGraphQl\\Model\\Resolver\\DeleteCompareList") @doc(description: "Delete the specified compare list")
+}
+
+input CreateCompareListInput {
+ products: [ID!] @doc(description: "An array of product IDs to add to the compare list")
+}
+
+input AddProductsToCompareListInput {
+ uid: ID!, @doc(description: "The unique identifier of the compare list to modify")
+ products: [ID!]! @doc(description: "An array of product IDs to add to the compare list")
+}
+
+input RemoveProductsFromCompareListInput {
+ uid: ID!, @doc(description: "The unique identifier of the compare list to modify")
+ products: [ID!]! @doc(description: "An array of product IDs to remove from the compare list")
+}
+
+type DeleteCompareListOutput {
+ result: Boolean! @doc(description: "Indicates whether the compare list was successfully deleted")
+}
+
+type AssignCompareListToCustomerOutput {
+ result: Boolean!
+ compare_list: CompareList @doc(description: "The contents of the customer's compare list")
+}
diff --git a/app/code/Magento/CompareListGraphQl/registration.php b/app/code/Magento/CompareListGraphQl/registration.php
new file mode 100644
index 0000000000000..bb764b439273d
--- /dev/null
+++ b/app/code/Magento/CompareListGraphQl/registration.php
@@ -0,0 +1,14 @@
+productRepository = $objectManager->get(ProductRepositoryInterface::class);
+ $this->customerTokenService = Bootstrap::getObjectManager()->get(CustomerTokenServiceInterface::class);
+ }
+ /**
+ * Create compare list without product
+ */
+ public function testCreateCompareListWithoutProducts()
+ {
+ $response = $this->createCompareList();
+ $uid = $response['createCompareList']['uid'];
+ $this->uidAssertion($uid);
+ }
+
+ /**
+ * Create compare list with products
+ *
+ * @magentoApiDataFixture Magento/Catalog/_files/multiple_products.php
+ */
+ public function testCreateCompareListWithProducts()
+ {
+ $product1 = $this->productRepository->get(self::PRODUCT_SKU_1);
+ $product2 = $this->productRepository->get(self::PRODUCT_SKU_2);
+
+ $mutation = <<getId()}, {$product2->getId()}]}){
+ uid
+ items {
+ product {
+ sku
+ }
+ }
+ }
+}
+MUTATION;
+ $response = $this->graphQlMutation($mutation);
+ $uid = $response['createCompareList']['uid'];
+ $this->uidAssertion($uid);
+ $this->itemsAssertion($response['createCompareList']['items']);
+ }
+
+ /**
+ * Add products to compare list
+ *
+ * @magentoApiDataFixture Magento/Catalog/_files/multiple_products.php
+ */
+ public function testAddProductToCompareList()
+ {
+ $compareList = $this->createCompareList();
+ $uid = $compareList['createCompareList']['uid'];
+ $this->assertEquals(0, $compareList['createCompareList']['item_count'],'Incorrect count');
+ $this->uidAssertion($uid);
+ $response = $this->addProductsToCompareList($uid);
+ $resultUid = $response['addProductsToCompareList']['uid'];
+ $this->uidAssertion($resultUid);
+ $this->itemsAssertion($response['addProductsToCompareList']['items']);
+ $this->assertEquals(2, $response['addProductsToCompareList']['item_count'],'Incorrect count');
+ $this->assertResponseFields(
+ $response['addProductsToCompareList']['attributes'],
+ [
+ [
+ 'code'=> 'sku',
+ 'label'=> 'SKU'
+ ],
+ [
+ 'code'=> 'description',
+ 'label'=> 'Description'
+ ],
+ [
+ 'code'=> 'short_description',
+ 'label'=> 'Short Description'
+ ]
+ ]
+ );
+ }
+
+ /**
+ * Remove products from compare list
+ *
+ * @magentoApiDataFixture Magento/Catalog/_files/multiple_products.php
+ */
+ public function testRemoveProductFromCompareList()
+ {
+ $compareList = $this->createCompareList();
+ $uid = $compareList['createCompareList']['uid'];
+ $this->uidAssertion($uid);
+ $addProducts = $this->addProductsToCompareList($uid);
+ $this->itemsAssertion($addProducts['addProductsToCompareList']['items']);
+ $this->assertCount(2, $addProducts['addProductsToCompareList']['items']);
+ $product = $this->productRepository->get(self::PRODUCT_SKU_1);
+ $removeFromCompareList = <<getId()}]}) {
+ uid
+ items {
+ product {
+ sku
+ }
+ }
+ }
+}
+MUTATION;
+ $response = $this->graphQlMutation($removeFromCompareList);
+ $this->assertCount(1, $response['removeProductsFromCompareList']['items']);
+ }
+
+ /**
+ * Get compare list query
+ *
+ * @magentoApiDataFixture Magento/Catalog/_files/multiple_products.php
+ */
+ public function testGetCompareList()
+ {
+ $compareList = $this->createCompareList();
+ $uid = $compareList['createCompareList']['uid'];
+ $this->uidAssertion($uid);
+ $addProducts = $this->addProductsToCompareList($uid);
+ $this->itemsAssertion($addProducts['addProductsToCompareList']['items']);
+ $query = <<graphQlQuery($query);
+ $this->itemsAssertion($response['compareList']['items']);
+ }
+
+ /**
+ * Remove compare list
+ *
+ * @magentoApiDataFixture Magento/Catalog/_files/multiple_products.php
+ */
+ public function testDeleteCompareList()
+ {
+ $compareList = $this->createCompareList();
+ $uid = $compareList['createCompareList']['uid'];
+ $this->uidAssertion($uid);
+ $addProducts = $this->addProductsToCompareList($uid);
+ $this->itemsAssertion($addProducts['addProductsToCompareList']['items']);
+ $deleteCompareList = <<graphQlMutation($deleteCompareList);
+ $this->assertTrue($response['deleteCompareList']['result']);
+ $response1 = $this->graphQlMutation($deleteCompareList);
+ $this->assertFalse($response1['deleteCompareList']['result']);
+ }
+
+ /**
+ * Assign compare list to customer
+ *
+ * @magentoApiDataFixture Magento/Catalog/_files/multiple_products.php
+ * @magentoApiDataFixture Magento/Customer/_files/customer.php
+ */
+ public function testAssignCompareListToCustomer()
+ {
+ $compareList = $this->createCompareList();
+ $uid = $compareList['createCompareList']['uid'];
+ $this->uidAssertion($uid);
+ $addProducts = $this->addProductsToCompareList($uid);
+ $this->itemsAssertion($addProducts['addProductsToCompareList']['items']);
+ $currentEmail = 'customer@example.com';
+ $currentPassword = 'password';
+ $customerQuery = <<graphQlQuery(
+ $customerQuery,
+ [],
+ '',
+ $this->getCustomerAuthHeaders($currentEmail, $currentPassword)
+ );
+ $this->assertArrayHasKey('compare_list', $customerResponse['customer']);
+ $this->assertNull($customerResponse['customer']['compare_list']);
+
+ $assignCompareListToCustomer = <<graphQlMutation(
+ $assignCompareListToCustomer,
+ [],
+ '',
+ $this->getCustomerAuthHeaders($currentEmail, $currentPassword)
+ );
+ $this->assertTrue($assignResponse['assignCompareListToCustomer']['result']);
+
+ $customerAssignedResponse = $this->graphQlQuery(
+ $customerQuery,
+ [],
+ '',
+ $this->getCustomerAuthHeaders($currentEmail, $currentPassword)
+ );
+
+ $this->assertArrayHasKey('compare_list', $customerAssignedResponse['customer']);
+ $this->uidAssertion($customerAssignedResponse['customer']['compare_list']['uid']);
+ $this->itemsAssertion($customerAssignedResponse['customer']['compare_list']['items']);
+ }
+
+ /**
+ * Assign compare list of one customer to another customer
+ *
+ * @magentoApiDataFixture Magento/Catalog/_files/multiple_products.php
+ * @magentoApiDataFixture Magento/Customer/_files/two_customers.php
+ */
+ public function testCompareListsNotAccessibleBetweenCustomers()
+ {
+ $uidCustomer1 = $this->createCompareListForCustomer('customer@example.com', 'password');
+ $uidcustomer2 = $this->createCompareListForCustomer('customer_two@example.com', 'password');
+ $assignCompareListToCustomer = <<expectException(ResponseContainsErrorsException::class);
+ $this->expectExceptionMessage($expectedExceptionsMessage);
+ //customer2 not allowed to assign compareList belonging to customer1
+ $this->graphQlMutation(
+ $assignCompareListToCustomer,
+ [],
+ '',
+ $this->getCustomerAuthHeaders('customer_two@example.com', 'password')
+ );
+
+ $deleteCompareList = <<expectException(ResponseContainsErrorsException::class);
+ $this->expectExceptionMessage($expectedExceptionsMessage);
+ //customer1 not allowed to delete compareList belonging to customer2
+ $this->graphQlMutation(
+ $assignCompareListToCustomer,
+ [],
+ '',
+ $this->getCustomerAuthHeaders('customer@example.com', 'password')
+ );
+
+ }
+
+ /**
+ * Get customer Header
+ *
+ * @param string $email
+ * @param string $password
+ *
+ * @return array
+ */
+ private function getCustomerAuthHeaders(string $email, string $password): array
+ {
+ $customerToken = $this->customerTokenService->createCustomerAccessToken($email, $password);
+ return ['Authorization' => 'Bearer ' . $customerToken];
+ }
+
+ /**
+ * Create compare list
+ *
+ * @return array
+ */
+ private function createCompareList(): array
+ {
+ $mutation = <<graphQlMutation($mutation);
+ }
+
+ private function createCompareListForCustomer(string $username, string $password): string
+ {
+ $compareListCustomer = <<graphQlMutation(
+ $compareListCustomer,
+ [],
+ '',
+ $this->getCustomerAuthHeaders($username, $password)
+ );
+
+ return $response['createCompareList']['uid'];
+ }
+
+ /**
+ * Add products to compare list
+ *
+ * @param $uid
+ *
+ * @return array
+ */
+ private function addProductsToCompareList($uid): array
+ {
+ $product1 = $this->productRepository->get(self::PRODUCT_SKU_1);
+ $product2 = $this->productRepository->get(self::PRODUCT_SKU_2);
+ $addProductsToCompareList = <<getId()}, {$product2->getId()}]}) {
+ uid
+ item_count
+ attributes{code label}
+ items {
+ product {
+ sku
+ }
+ }
+ }
+}
+MUTATION;
+ return $this->graphQlMutation($addProductsToCompareList);
+ }
+
+ /**
+ * Assert UID
+ *
+ * @param string $uid
+ */
+ private function uidAssertion(string $uid)
+ {
+ $this->assertIsString($uid);
+ $this->assertEquals(32, strlen($uid));
+ }
+
+ /**
+ * Assert products
+ *
+ * @param array $items
+ */
+ private function itemsAssertion(array $items)
+ {
+ $this->assertArrayHasKey(0, $items);
+ $this->assertArrayHasKey(1, $items);
+ $this->assertEquals(self::PRODUCT_SKU_1, $items[0]['product']['sku']);
+ $this->assertEquals(self::PRODUCT_SKU_2, $items[1]['product']['sku']);
+ }
+}