33 * Copyright © Magento, Inc. All rights reserved.
44 * See COPYING.txt for license details.
55 */
6+ declare (strict_types=1 );
7+
68namespace Magento \Catalog \Controller \Product ;
79
10+ use Magento \Catalog \Api \Data \ProductInterface ;
11+ use Magento \Catalog \Api \ProductRepositoryInterface ;
12+ use Magento \Catalog \Model \Product ;
13+ use Magento \Eav \Model \AttributeSetSearchResults ;
14+ use Magento \Eav \Model \Entity \Attribute \Set ;
15+ use Magento \Framework \Api \SearchCriteriaBuilder ;
16+ use Magento \Framework \Api \SortOrderBuilder ;
17+ use Magento \Framework \Data \Collection ;
18+ use Magento \Catalog \Api \AttributeSetRepositoryInterface ;
19+ use Magento \Eav \Model \Entity \Type ;
20+ use PHPUnit \Framework \MockObject \MockObject ;
21+ use Psr \Log \LoggerInterface ;
22+ use Magento \Catalog \Api \Data \ProductAttributeInterface ;
23+ use Magento \Catalog \Api \ProductAttributeRepositoryInterface ;
24+ use Magento \Framework \Logger \Monolog as MagentoMonologLogger ;
25+
826/**
9- * @magentoDataFixture Magento/Catalog/controllers/_files/products.php
10- * @magentoDbIsolation disabled
27+ * Integration test for product view front action.
28+ *
29+ * @magentoAppArea frontend
30+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
1131 */
1232class ViewTest extends \Magento \TestFramework \TestCase \AbstractController
1333{
1434 /**
35+ * @var ProductRepositoryInterface $productRepository
36+ */
37+ private $ productRepository ;
38+
39+ /**
40+ * @var AttributeSetRepositoryInterface $attributeSetRepository
41+ */
42+ private $ attributeSetRepository ;
43+
44+ /**
45+ * @var ProductAttributeRepositoryInterface $attributeSetRepository
46+ */
47+ private $ attributeRepository ;
48+
49+ /**
50+ * @var Type $productEntityType
51+ */
52+ private $ productEntityType ;
53+
54+ /**
55+ * @inheritdoc
56+ */
57+ protected function setUp ()
58+ {
59+ parent ::setUp ();
60+
61+ $ this ->productRepository = $ this ->_objectManager ->create (ProductRepositoryInterface::class);
62+ $ this ->attributeSetRepository = $ this ->_objectManager ->create (AttributeSetRepositoryInterface::class);
63+ $ this ->attributeRepository = $ this ->_objectManager ->create (ProductAttributeRepositoryInterface::class);
64+ $ this ->productEntityType = $ this ->_objectManager ->create (Type::class)
65+ ->loadByCode (Product::ENTITY );
66+ }
67+
68+ /**
69+ * @magentoDbIsolation disabled
70+ * @magentoDataFixture Magento/Catalog/controllers/_files/products.php
1571 * @magentoConfigFixture current_store catalog/seo/product_canonical_tag 1
72+ * @return void
1673 */
17- public function testViewActionWithCanonicalTag ()
74+ public function testViewActionWithCanonicalTag (): void
1875 {
1976 $ this ->markTestSkipped (
2077 'MAGETWO-40724: Canonical url from tests sometimes does not equal canonical url from action '
@@ -26,4 +83,98 @@ public function testViewActionWithCanonicalTag()
2683 $ this ->getResponse ()->getBody ()
2784 );
2885 }
86+
87+ /**
88+ * View product with custom attribute when attribute removed from it.
89+ *
90+ * It tests that after changing product attribute set from Default to Custom
91+ * there are no warning messages in log in case Custom not contains attribute from Default.
92+ *
93+ * @magentoDataFixture Magento/Catalog/_files/product_simple_with_country_of_manufacture.php
94+ * @magentoDataFixture Magento/Catalog/_files/attribute_set_based_on_default_without_country_of_manufacture.php
95+ * @return void
96+ */
97+ public function testViewActionCustomAttributeSetWithoutCountryOfManufacture (): void
98+ {
99+ /** @var MockObject|LoggerInterface $logger */
100+ $ logger = $ this ->setupLoggerMock ();
101+
102+ $ product = $ this ->getProductBySku ('simple_with_com ' );
103+ $ attributeSetCustom = $ this ->getProductAttributeSetByName ('custom_attribute_set_wout_com ' );
104+ $ product ->setAttributeSetId ($ attributeSetCustom ->getAttributeSetId ());
105+ $ this ->productRepository ->save ($ product );
106+
107+ /** @var ProductAttributeInterface $attributeCountryOfManufacture */
108+ $ attributeCountryOfManufacture = $ this ->attributeRepository ->get ('country_of_manufacture ' );
109+ $ logger ->expects ($ this ->never ())
110+ ->method ('warning ' )
111+ ->with (
112+ "Attempt to load value of nonexistent EAV attribute " ,
113+ [
114+ 'attribute_id ' => $ attributeCountryOfManufacture ->getAttributeId (),
115+ 'entity_type ' => ProductInterface::class,
116+ ]
117+ );
118+
119+ $ this ->dispatch (sprintf ('catalog/product/view/id/%s/ ' , $ product ->getId ()));
120+ }
121+
122+ /**
123+ * Setup logger mock to check there are no warning messages logged.
124+ *
125+ * @return MockObject
126+ */
127+ private function setupLoggerMock () : MockObject
128+ {
129+ $ logger = $ this ->getMockBuilder (LoggerInterface::class)
130+ ->disableOriginalConstructor ()
131+ ->getMock ();
132+ $ this ->_objectManager ->addSharedInstance ($ logger , MagentoMonologLogger::class);
133+
134+ return $ logger ;
135+ }
136+
137+ /**
138+ * Get product instance by sku.
139+ *
140+ * @param string $sku
141+ * @return Product
142+ */
143+ private function getProductBySku (string $ sku ): Product
144+ {
145+ return $ this ->productRepository ->get ($ sku );
146+ }
147+
148+ /**
149+ * Get product attribute set by name.
150+ *
151+ * @param string $attributeSetName
152+ * @return Set|null
153+ */
154+ private function getProductAttributeSetByName (string $ attributeSetName ): ?Set
155+ {
156+ /** @var SortOrderBuilder $sortOrderBuilder */
157+ $ sortOrderBuilder = $ this ->_objectManager ->create (SortOrderBuilder::class);
158+ /** @var SearchCriteriaBuilder $searchCriteriaBuilder */
159+ $ searchCriteriaBuilder = $ this ->_objectManager ->get (SearchCriteriaBuilder::class);
160+ $ searchCriteriaBuilder ->addFilter ('attribute_set_name ' , $ attributeSetName );
161+ $ searchCriteriaBuilder ->addFilter ('entity_type_id ' , $ this ->productEntityType ->getId ());
162+ $ attributeSetIdSortOrder = $ sortOrderBuilder
163+ ->setField ('attribute_set_id ' )
164+ ->setDirection (Collection::SORT_ORDER_DESC )
165+ ->create ();
166+ $ searchCriteriaBuilder ->addSortOrder ($ attributeSetIdSortOrder );
167+ $ searchCriteriaBuilder ->setPageSize (1 );
168+ $ searchCriteriaBuilder ->setCurrentPage (1 );
169+
170+ /** @var AttributeSetSearchResults $searchResult */
171+ $ searchResult = $ this ->attributeSetRepository ->getList ($ searchCriteriaBuilder ->create ());
172+ $ items = $ searchResult ->getItems ();
173+
174+ if (count ($ items ) > 0 ) {
175+ return reset ($ items );
176+ }
177+
178+ return null ;
179+ }
29180}
0 commit comments