From 4835285066637047ef47af81759efb2f2fde29dd Mon Sep 17 00:00:00 2001 From: Valerii Naida Date: Wed, 8 May 2019 12:27:02 -0500 Subject: [PATCH] GraphQl-198: Products: access to related/up-sell/cross-sell product fields --- .../DataProvider/RelatedDataProvider.php | 80 -------- ...der.php => RelatedProductDataProvider.php} | 35 +++- .../Model/Resolver/CrossSellProducts.php | 31 ++- .../Model/Resolver/RelatedProducts.php | 30 ++- .../Model/Resolver/UpSellProducts.php | 31 ++- .../RelatedProductGraphQl/etc/graphql/di.xml | 31 --- .../RelatedProduct/GetRelatedProductsTest.php | 178 ++++++++++++++++++ .../ProductRelatedProductsTest.php | 175 ----------------- 8 files changed, 275 insertions(+), 316 deletions(-) delete mode 100644 app/code/Magento/RelatedProductGraphQl/Model/DataProvider/RelatedDataProvider.php rename app/code/Magento/RelatedProductGraphQl/Model/DataProvider/{Products/LinkedProductsDataProvider.php => RelatedProductDataProvider.php} (52%) delete mode 100644 app/code/Magento/RelatedProductGraphQl/etc/graphql/di.xml create mode 100644 dev/tests/api-functional/testsuite/Magento/GraphQl/RelatedProduct/GetRelatedProductsTest.php delete mode 100644 dev/tests/api-functional/testsuite/Magento/GraphQl/RelatedProduct/ProductRelatedProductsTest.php diff --git a/app/code/Magento/RelatedProductGraphQl/Model/DataProvider/RelatedDataProvider.php b/app/code/Magento/RelatedProductGraphQl/Model/DataProvider/RelatedDataProvider.php deleted file mode 100644 index eb437ea31fce1..0000000000000 --- a/app/code/Magento/RelatedProductGraphQl/Model/DataProvider/RelatedDataProvider.php +++ /dev/null @@ -1,80 +0,0 @@ -dataProvider = $dataProvider; - $this->productFieldsSelector = $productFieldsSelector; - $this->linkType = $linkType; - $this->schemaNodeName = $schemaNodeName; - } - - /** - * Related Products Data - * - * @param ResolveInfo $info - * @param array $value - * @return array - */ - public function getProducts(ResolveInfo $info, array $value): array - { - $product = $value['model']; - $fields = $this->productFieldsSelector->getProductFieldsFromInfo($info, $this->schemaNodeName); - $products = $this->dataProvider->getRelatedProducts($product, $fields, $this->linkType); - - $data = []; - foreach ($products as $key => $product) { - $data[$key] = $product->getData(); - $data[$key]['model'] = $product; - } - - return $data; - } -} diff --git a/app/code/Magento/RelatedProductGraphQl/Model/DataProvider/Products/LinkedProductsDataProvider.php b/app/code/Magento/RelatedProductGraphQl/Model/DataProvider/RelatedProductDataProvider.php similarity index 52% rename from app/code/Magento/RelatedProductGraphQl/Model/DataProvider/Products/LinkedProductsDataProvider.php rename to app/code/Magento/RelatedProductGraphQl/Model/DataProvider/RelatedProductDataProvider.php index 9a62a6685a532..04a71da0337de 100644 --- a/app/code/Magento/RelatedProductGraphQl/Model/DataProvider/Products/LinkedProductsDataProvider.php +++ b/app/code/Magento/RelatedProductGraphQl/Model/DataProvider/RelatedProductDataProvider.php @@ -5,7 +5,7 @@ */ declare(strict_types=1); -namespace Magento\RelatedProductGraphQl\Model\DataProvider\Products; +namespace Magento\RelatedProductGraphQl\Model\DataProvider; use Magento\Catalog\Model\Product; use Magento\Catalog\Model\Product\Link; @@ -14,7 +14,7 @@ /** * Related Products Data Provider */ -class LinkedProductsDataProvider +class RelatedProductDataProvider { /** * @var LinkFactory @@ -24,24 +24,45 @@ class LinkedProductsDataProvider /** * @param LinkFactory $linkFactory */ - public function __construct(LinkFactory $linkFactory) - { + public function __construct( + LinkFactory $linkFactory + ) { $this->linkFactory = $linkFactory; } /** - * Get Related Products by Product and Link Type + * Related Products Data + * + * @param Product $product + * @param array $fields + * @param int $linkType + * @return array + */ + public function getData(Product $product, array $fields, int $linkType): array + { + $relatedProducts = $this->getRelatedProducts($product, $fields, $linkType); + + $data = []; + foreach ($relatedProducts as $relatedProduct) { + $relatedProductData = $relatedProduct->getData(); + $relatedProductData['model'] = $relatedProduct; + } + return $data; + } + + /** + * Get Related Products * * @param Product $product * @param array $fields * @param int $linkType * @return Product[] */ - public function getRelatedProducts(Product $product, array $fields, int $linkType): array + private function getRelatedProducts(Product $product, array $fields, int $linkType): array { /** @var Link $link */ $link = $this->linkFactory->create([ 'data' => [ - 'link_type_id' => $linkType + 'link_type_id' => $linkType, ]]); $collection = $link->getProductCollection(); diff --git a/app/code/Magento/RelatedProductGraphQl/Model/Resolver/CrossSellProducts.php b/app/code/Magento/RelatedProductGraphQl/Model/Resolver/CrossSellProducts.php index 3a6fdb855b856..dcaa75b85f599 100644 --- a/app/code/Magento/RelatedProductGraphQl/Model/Resolver/CrossSellProducts.php +++ b/app/code/Magento/RelatedProductGraphQl/Model/Resolver/CrossSellProducts.php @@ -7,7 +7,10 @@ namespace Magento\RelatedProductGraphQl\Model\Resolver; -use Magento\RelatedProductGraphQl\Model\DataProvider\RelatedDataProvider; +use Magento\Catalog\Model\Product\Link; +use Magento\CatalogGraphQl\Model\Resolver\Product\ProductFieldsSelector; +use Magento\Framework\Exception\LocalizedException; +use Magento\RelatedProductGraphQl\Model\DataProvider\RelatedProductDataProvider; use Magento\Framework\GraphQl\Config\Element\Field; use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; @@ -18,18 +21,25 @@ class CrossSellProducts implements ResolverInterface { /** - * @see module di.xml - * @var RelatedDataProvider + * @var ProductFieldsSelector */ - private $dataProvider; + private $productFieldsSelector; /** - * @param RelatedDataProvider $dataProvider + * @var RelatedProductDataProvider + */ + private $relatedProductDataProvider; + + /** + * @param ProductFieldsSelector $productFieldsSelector + * @param RelatedProductDataProvider $relatedProductDataProvider */ public function __construct( - RelatedDataProvider $dataProvider + ProductFieldsSelector $productFieldsSelector, + RelatedProductDataProvider $relatedProductDataProvider ) { - $this->dataProvider = $dataProvider; + $this->productFieldsSelector = $productFieldsSelector; + $this->relatedProductDataProvider = $relatedProductDataProvider; } /** @@ -37,8 +47,13 @@ public function __construct( */ public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null) { - $data = $this->dataProvider->getProducts($info, $value); + if (!isset($value['model'])) { + throw new LocalizedException(__('"model" value should be specified')); + } + $product = $value['model']; + $fields = $this->productFieldsSelector->getProductFieldsFromInfo($info, 'crosssell_products'); + $data = $this->relatedProductDataProvider->getData($product, $fields, Link::LINK_TYPE_CROSSSELL); return $data; } } diff --git a/app/code/Magento/RelatedProductGraphQl/Model/Resolver/RelatedProducts.php b/app/code/Magento/RelatedProductGraphQl/Model/Resolver/RelatedProducts.php index 280e3d9d0ede6..568c3282a6ee8 100644 --- a/app/code/Magento/RelatedProductGraphQl/Model/Resolver/RelatedProducts.php +++ b/app/code/Magento/RelatedProductGraphQl/Model/Resolver/RelatedProducts.php @@ -7,7 +7,10 @@ namespace Magento\RelatedProductGraphQl\Model\Resolver; -use Magento\RelatedProductGraphQl\Model\DataProvider\RelatedDataProvider; +use Magento\Catalog\Model\Product\Link; +use Magento\CatalogGraphQl\Model\Resolver\Product\ProductFieldsSelector; +use Magento\Framework\Exception\LocalizedException; +use Magento\RelatedProductGraphQl\Model\DataProvider\RelatedProductDataProvider; use Magento\Framework\GraphQl\Config\Element\Field; use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; @@ -18,17 +21,25 @@ class RelatedProducts implements ResolverInterface { /** - * @var RelatedDataProvider + * @var ProductFieldsSelector */ - private $dataProvider; + private $productFieldsSelector; /** - * @param RelatedDataProvider $dataProvider + * @var RelatedProductDataProvider + */ + private $relatedProductDataProvider; + + /** + * @param ProductFieldsSelector $productFieldsSelector + * @param RelatedProductDataProvider $relatedProductDataProvider */ public function __construct( - RelatedDataProvider $dataProvider + ProductFieldsSelector $productFieldsSelector, + RelatedProductDataProvider $relatedProductDataProvider ) { - $this->dataProvider = $dataProvider; + $this->productFieldsSelector = $productFieldsSelector; + $this->relatedProductDataProvider = $relatedProductDataProvider; } /** @@ -36,8 +47,13 @@ public function __construct( */ public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null) { - $data = $this->dataProvider->getProducts($info, $value); + if (!isset($value['model'])) { + throw new LocalizedException(__('"model" value should be specified')); + } + $product = $value['model']; + $fields = $this->productFieldsSelector->getProductFieldsFromInfo($info, 'related_products'); + $data = $this->relatedProductDataProvider->getData($product, $fields, Link::LINK_TYPE_RELATED); return $data; } } diff --git a/app/code/Magento/RelatedProductGraphQl/Model/Resolver/UpSellProducts.php b/app/code/Magento/RelatedProductGraphQl/Model/Resolver/UpSellProducts.php index 5299b43f5f54f..df3a62408c53f 100644 --- a/app/code/Magento/RelatedProductGraphQl/Model/Resolver/UpSellProducts.php +++ b/app/code/Magento/RelatedProductGraphQl/Model/Resolver/UpSellProducts.php @@ -7,7 +7,10 @@ namespace Magento\RelatedProductGraphQl\Model\Resolver; -use Magento\RelatedProductGraphQl\Model\DataProvider\RelatedDataProvider; +use Magento\Catalog\Model\Product\Link; +use Magento\CatalogGraphQl\Model\Resolver\Product\ProductFieldsSelector; +use Magento\Framework\Exception\LocalizedException; +use Magento\RelatedProductGraphQl\Model\DataProvider\RelatedProductDataProvider; use Magento\Framework\GraphQl\Config\Element\Field; use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; @@ -18,18 +21,25 @@ class UpSellProducts implements ResolverInterface { /** - * @see module di.xml - * @var RelatedDataProvider + * @var ProductFieldsSelector */ - private $dataProvider; + private $productFieldsSelector; /** - * @param RelatedDataProvider $dataProvider + * @var RelatedProductDataProvider + */ + private $relatedProductDataProvider; + + /** + * @param ProductFieldsSelector $productFieldsSelector + * @param RelatedProductDataProvider $relatedProductDataProvider */ public function __construct( - RelatedDataProvider $dataProvider + ProductFieldsSelector $productFieldsSelector, + RelatedProductDataProvider $relatedProductDataProvider ) { - $this->dataProvider = $dataProvider; + $this->productFieldsSelector = $productFieldsSelector; + $this->relatedProductDataProvider = $relatedProductDataProvider; } /** @@ -37,8 +47,13 @@ public function __construct( */ public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null) { - $data = $this->dataProvider->getProducts($info, $value); + if (!isset($value['model'])) { + throw new LocalizedException(__('"model" value should be specified')); + } + $product = $value['model']; + $fields = $this->productFieldsSelector->getProductFieldsFromInfo($info, 'upsell_products'); + $data = $this->relatedProductDataProvider->getData($product, $fields, Link::LINK_TYPE_UPSELL); return $data; } } diff --git a/app/code/Magento/RelatedProductGraphQl/etc/graphql/di.xml b/app/code/Magento/RelatedProductGraphQl/etc/graphql/di.xml deleted file mode 100644 index f64cf197b250f..0000000000000 --- a/app/code/Magento/RelatedProductGraphQl/etc/graphql/di.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - Magento\Catalog\Model\Product\Link::LINK_TYPE_CROSSSELL - crosssell_products - - - - - Magento\RelatedProductGraphQl\Model\DataProvider\CrossSellDataProvider - - - - - Magento\Catalog\Model\Product\Link::LINK_TYPE_UPSELL - upsell_products - - - - - Magento\RelatedProductGraphQl\Model\DataProvider\UpSellDataProvider - - - diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/RelatedProduct/GetRelatedProductsTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/RelatedProduct/GetRelatedProductsTest.php new file mode 100644 index 0000000000000..3c0b578d850b9 --- /dev/null +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/RelatedProduct/GetRelatedProductsTest.php @@ -0,0 +1,178 @@ +graphQlQuery($query); + + self::assertArrayHasKey('products', $response); + self::assertArrayHasKey('items', $response['products']); + self::assertEquals(1, count($response['products']['items'])); + self::assertArrayHasKey(0, $response['products']['items']); + self::assertArrayHasKey('related_products', $response['products']['items'][0]); + $relatedProducts = $response['products']['items'][0]['related_products']; + self::assertCount(2, $relatedProducts); + self::assertRelatedProducts($relatedProducts); + } + + /** + * @magentoApiDataFixture Magento/Catalog/_files/products_crosssell.php + */ + public function testQueryCrossSellProducts() + { + $productSku = 'simple_with_cross'; + + $query = <<graphQlQuery($query); + + self::assertArrayHasKey('products', $response); + self::assertArrayHasKey('items', $response['products']); + self::assertEquals(1, count($response['products']['items'])); + self::assertArrayHasKey(0, $response['products']['items']); + self::assertArrayHasKey('crosssell_products', $response['products']['items'][0]); + $crossSellProducts = $response['products']['items'][0]['crosssell_products']; + self::assertCount(1, $crossSellProducts); + $crossSellProduct = $crossSellProducts[0]; + self::assertArrayHasKey('sku', $crossSellProduct); + self::assertArrayHasKey('name', $crossSellProduct); + self::assertArrayHasKey('url_key', $crossSellProduct); + self::assertArrayHasKey('id', $crossSellProduct); + self::assertArrayHasKey('created_at', $crossSellProduct); + self::assertEquals($crossSellProduct['sku'], 'simple'); + self::assertEquals($crossSellProduct['name'], 'Simple Cross Sell'); + self::assertEquals($crossSellProduct['url_key'], 'simple-cross-sell'); + self::assertNotEmpty($crossSellProduct['created_at']); + self::assertNotEmpty($crossSellProduct['id']); + } + + /** + * @magentoApiDataFixture Magento/Catalog/_files/products_upsell.php + */ + public function testQueryUpSellProducts() + { + $productSku = 'simple_with_upsell'; + + $query = <<graphQlQuery($query); + + self::assertArrayHasKey('products', $response); + self::assertArrayHasKey('items', $response['products']); + self::assertEquals(1, count($response['products']['items'])); + self::assertArrayHasKey(0, $response['products']['items']); + self::assertArrayHasKey('upsell_products', $response['products']['items'][0]); + $upSellProducts = $response['products']['items'][0]['upsell_products']; + self::assertCount(1, $upSellProducts); + $upSellProduct = $upSellProducts[0]; + self::assertArrayHasKey('sku', $upSellProduct); + self::assertArrayHasKey('name', $upSellProduct); + self::assertArrayHasKey('url_key', $upSellProduct); + self::assertArrayHasKey('id', $upSellProduct); + self::assertArrayHasKey('created_at', $upSellProduct); + self::assertEquals($upSellProduct['sku'], 'simple'); + self::assertEquals($upSellProduct['name'], 'Simple Up Sell'); + self::assertEquals($upSellProduct['url_key'], 'simple-up-sell'); + self::assertNotEmpty($upSellProduct['created_at']); + self::assertNotEmpty($upSellProduct['id']); + } + + /** + * @param array $relatedProducts + */ + private function assertRelatedProducts(array $relatedProducts): void + { + $expectedData = [ + 'simple' => [ + 'name' => 'Simple Related Product', + 'url_key' => 'simple-related-product', + + ], + 'simple_with_cross_two' => [ + 'name' => 'Simple Product With Related Product Two', + 'url_key' => 'simple-product-with-related-product-two', + ] + ]; + + foreach ($relatedProducts as $product) { + self::assertArrayHasKey('sku', $product); + self::assertArrayHasKey('name', $product); + self::assertArrayHasKey('url_key', $product); + self::assertArrayHasKey('id', $product); + self::assertArrayHasKey('created_at', $product); + + self::assertArrayHasKey($product['sku'], $expectedData); + $productExpectedData = $expectedData[$product['sku']]; + + self::assertEquals($product['name'], $productExpectedData['name']); + self::assertEquals($product['url_key'], $productExpectedData['url_key']); + self::assertNotEmpty($product['created_at']); + self::assertNotEmpty($product['id']); + } + } +} diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/RelatedProduct/ProductRelatedProductsTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/RelatedProduct/ProductRelatedProductsTest.php deleted file mode 100644 index 5317e88d7e118..0000000000000 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/RelatedProduct/ProductRelatedProductsTest.php +++ /dev/null @@ -1,175 +0,0 @@ -graphQlQuery($query); - - $this->assertArrayHasKey('products', $response); - $this->assertArrayHasKey('items', $response['products']); - $this->assertEquals(1, count($response['products']['items'])); - $this->assertArrayHasKey(0, $response['products']['items']); - $this->assertArrayHasKey('related_products', $response['products']['items'][0]); - $relatedProducts = $response['products']['items'][0]['related_products']; - $this->assertCount(2, $relatedProducts); - $this->assertRelatedProducts($relatedProducts); - } - - /** - * @magentoApiDataFixture Magento/Catalog/_files/products_crosssell.php - */ - public function testQueryCrossSellProducts() - { - $productSku = 'simple_with_cross'; - - $query = <<graphQlQuery($query); - - $this->assertArrayHasKey('products', $response); - $this->assertArrayHasKey('items', $response['products']); - $this->assertEquals(1, count($response['products']['items'])); - $this->assertArrayHasKey(0, $response['products']['items']); - $this->assertArrayHasKey('crosssell_products', $response['products']['items'][0]); - $crossSellProducts = $response['products']['items'][0]['crosssell_products']; - $this->assertCount(1, $crossSellProducts); - $crossSellProduct = $crossSellProducts[0]; - $this->assertArrayHasKey('sku', $crossSellProduct); - $this->assertArrayHasKey('name', $crossSellProduct); - $this->assertArrayHasKey('url_key', $crossSellProduct); - $this->assertArrayHasKey('id', $crossSellProduct); - $this->assertArrayHasKey('created_at', $crossSellProduct); - $this->assertEquals($crossSellProduct['sku'], 'simple'); - $this->assertEquals($crossSellProduct['name'], 'Simple Cross Sell'); - $this->assertEquals($crossSellProduct['url_key'], 'simple-cross-sell'); - $this->assertNotEmpty($crossSellProduct['created_at']); - $this->assertNotEmpty($crossSellProduct['id']); - } - - /** - * @magentoApiDataFixture Magento/Catalog/_files/products_upsell.php - */ - public function testQueryUpSellProducts() - { - $productSku = 'simple_with_upsell'; - - $query = <<graphQlQuery($query); - - $this->assertArrayHasKey('products', $response); - $this->assertArrayHasKey('items', $response['products']); - $this->assertEquals(1, count($response['products']['items'])); - $this->assertArrayHasKey(0, $response['products']['items']); - $this->assertArrayHasKey('upsell_products', $response['products']['items'][0]); - $upSellProducts = $response['products']['items'][0]['upsell_products']; - $this->assertCount(1, $upSellProducts); - $upSellProduct = $upSellProducts[0]; - $this->assertArrayHasKey('sku', $upSellProduct); - $this->assertArrayHasKey('name', $upSellProduct); - $this->assertArrayHasKey('url_key', $upSellProduct); - $this->assertArrayHasKey('id', $upSellProduct); - $this->assertArrayHasKey('created_at', $upSellProduct); - $this->assertEquals($upSellProduct['sku'], 'simple'); - $this->assertEquals($upSellProduct['name'], 'Simple Up Sell'); - $this->assertEquals($upSellProduct['url_key'], 'simple-up-sell'); - $this->assertNotEmpty($upSellProduct['created_at']); - $this->assertNotEmpty($upSellProduct['id']); - } - - /** - * @param array $relatedProducts - */ - private function assertRelatedProducts(array $relatedProducts): void - { - $expectedData = [ - 'simple' => [ - 'name' => 'Simple Related Product', - 'url_key' => 'simple-related-product', - - ], - 'simple_with_cross_two' => [ - 'name' => 'Simple Product With Related Product Two', - 'url_key' => 'simple-product-with-related-product-two', - ] - ]; - - foreach ($relatedProducts as $product) { - $this->assertArrayHasKey('sku', $product); - $this->assertArrayHasKey('name', $product); - $this->assertArrayHasKey('url_key', $product); - $this->assertArrayHasKey('id', $product); - $this->assertArrayHasKey('created_at', $product); - - $this->assertArrayHasKey($product['sku'], $expectedData); - $productExpectedData = $expectedData[$product['sku']]; - - $this->assertEquals($product['name'], $productExpectedData['name']); - $this->assertEquals($product['url_key'], $productExpectedData['url_key']); - $this->assertNotEmpty($product['created_at']); - $this->assertNotEmpty($product['id']); - } - } -}