diff --git a/app/code/Magento/Sitemap/Model/CategorySitemapItemResolver.php b/app/code/Magento/Sitemap/Model/CategorySitemapItemResolver.php new file mode 100644 index 0000000000000..77dd3f746eef1 --- /dev/null +++ b/app/code/Magento/Sitemap/Model/CategorySitemapItemResolver.php @@ -0,0 +1,109 @@ +categoryFactory = $categoryFactory; + $this->itemFactory = $itemFactory; + $this->scopeConfig = $scopeConfig; + } + + /** + * {@inheritdoc} + */ + public function getItems($storeId) + { + $collection = $this->categoryFactory->create()->getCollection($storeId); + $items = array_map(function($item) use ($storeId) { + return $this->itemFactory->create([ + 'url' => $item->getUrl(), + 'updatedAt' => $item->getUpdatedAt(), + 'images' => $item->getImages(), + 'priority' => $this->getCategoryPriority($storeId), + 'changeFrequency' => $this->getCategoryChangeFrequency($storeId), + ]); + }, $collection); + + return $items; + } + + /** + * Get page priority + * + * @param int $storeId + * @return string + */ + private function getCategoryPriority($storeId) + { + return (string)$this->scopeConfig->getValue( + self::XML_PATH_CATEGORY_PRIORITY, + ScopeInterface::SCOPE_STORE, + $storeId + ); + } + + /** + * Get page change frequency + * + * @param int $storeId + * @return string + */ + private function getCategoryChangeFrequency($storeId) + { + return (string)$this->scopeConfig->getValue( + self::XML_PATH_CATEGORY_CHANGEFREQ, + ScopeInterface::SCOPE_STORE, + $storeId + ); + } +} \ No newline at end of file diff --git a/app/code/Magento/Sitemap/Model/CmsPageSitemapItemResolver.php b/app/code/Magento/Sitemap/Model/CmsPageSitemapItemResolver.php new file mode 100644 index 0000000000000..196d13a8cf251 --- /dev/null +++ b/app/code/Magento/Sitemap/Model/CmsPageSitemapItemResolver.php @@ -0,0 +1,113 @@ +scopeConfig = $scopeConfig; + $this->cmsPageFactory = $cmsPageFactory; + $this->itemFactory = $itemFactory; + } + + /** + * {@inheritdoc} + */ + public function getItems($storeId) + { + $collection = $this->cmsPageFactory->create()->getCollection($storeId); + var_dump($collection); + $items = array_map(function($item) use ($storeId) { + return $this->itemFactory->create([ + 'url' => $item->getUrl(), + 'updatedAt' => $item->getUpdatedAt(), + 'images' => $item->getImages(), + 'priority' => $this->getPagePriority($storeId), + 'changeFrequency' => $this->getPageChangeFrequency($storeId), + ]); + }, $collection); + + var_dump($items); + + return $items; + } + + /** + * Get page priority + * + * @param int $storeId + * @return string + */ + private function getPagePriority($storeId) + { + return (string)$this->scopeConfig->getValue( + self::XML_PATH_PAGE_PRIORITY, + ScopeInterface::SCOPE_STORE, + $storeId + ); + } + + /** + * Get page change frequency + * + * @param int $storeId + * @return string + */ + private function getPageChangeFrequency($storeId) + { + return (string)$this->scopeConfig->getValue( + self::XML_PATH_PAGE_CHANGEFREQ, + ScopeInterface::SCOPE_STORE, + $storeId + ); + } +} \ No newline at end of file diff --git a/app/code/Magento/Sitemap/Model/CompositeSitemapItemResolver.php b/app/code/Magento/Sitemap/Model/CompositeSitemapItemResolver.php new file mode 100644 index 0000000000000..f6f00be2c763c --- /dev/null +++ b/app/code/Magento/Sitemap/Model/CompositeSitemapItemResolver.php @@ -0,0 +1,44 @@ +itemResolvers = $itemResolvers; + } + + /** + * {@inheritdoc} + */ + public function getItems($storeId) + { + $items = []; + + foreach ($this->itemResolvers as $resolver) { + foreach ($resolver->getItems($storeId) as $item) { + $items[] = $item; + } + } + + return $items; + } +} \ No newline at end of file diff --git a/app/code/Magento/Sitemap/Model/ProductSitemapItemResolver.php b/app/code/Magento/Sitemap/Model/ProductSitemapItemResolver.php new file mode 100644 index 0000000000000..5e321b8a9557e --- /dev/null +++ b/app/code/Magento/Sitemap/Model/ProductSitemapItemResolver.php @@ -0,0 +1,108 @@ +scopeConfig = $scopeConfig; + $this->productFactory = $productFactory; + $this->itemFactory = $itemFactory; + } + + /** + * {@inheritdoc} + */ + public function getItems($storeId) + { + $collection = $this->productFactory->create()->getCollection($storeId); + $items = array_map(function($item) use ($storeId) { + return $this->itemFactory->create([ + 'url' => $item->getUrl(), + 'updatedAt' => $item->getUpdatedAt(), + 'images' => $item->getImages(), + 'priority' => $this->getProductPriority($storeId), + 'changeFrequency' => $this->getProductChangeFrequency($storeId), + ]); + }, $collection); + + return $items; + } + + /** + * Get page priority + * + * @param int $storeId + * @return string + */ + private function getProductPriority($storeId) + { + return (string)$this->scopeConfig->getValue( + self::XML_PATH_PRODUCT_PRIORITY, + ScopeInterface::SCOPE_STORE, + $storeId + ); + } + + /** + * Get page change frequency + * + * @param int $storeId + * @return string + */ + private function getProductChangeFrequency($storeId) + { + return (string)$this->scopeConfig->getValue( + self::XML_PATH_PRODUCT_CHANGEFREQ, + ScopeInterface::SCOPE_STORE, + $storeId + ); + } +} \ No newline at end of file diff --git a/app/code/Magento/Sitemap/Model/Sitemap.php b/app/code/Magento/Sitemap/Model/Sitemap.php index ef8363cbcf2ff..cd1c8dc9fbf06 100644 --- a/app/code/Magento/Sitemap/Model/Sitemap.php +++ b/app/code/Magento/Sitemap/Model/Sitemap.php @@ -11,7 +11,6 @@ use Magento\Config\Model\Config\Reader\Source\Deployed\DocumentRoot; use Magento\Framework\App\ObjectManager; use Magento\Robots\Model\Config\Value; -use Magento\Framework\DataObject; /** * Sitemap model @@ -157,6 +156,13 @@ class Sitemap extends \Magento\Framework\Model\AbstractModel implements \Magento */ protected $_cacheTag = true; + /** + * Item resolver + * + * @var SitemapItemResolverInterface + */ + private $itemResolver; + /** * Initialize dependencies. * @@ -176,6 +182,7 @@ class Sitemap extends \Magento\Framework\Model\AbstractModel implements \Magento * @param \Magento\Framework\Data\Collection\AbstractDb|null $resourceCollection * @param array $data * @param DocumentRoot|null $documentRoot + * @param SitemapItemResolverInterface|null $itemResolver * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( @@ -194,7 +201,8 @@ public function __construct( \Magento\Framework\Model\ResourceModel\AbstractResource $resource = null, \Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null, array $data = [], - \Magento\Config\Model\Config\Reader\Source\Deployed\DocumentRoot $documentRoot = null + \Magento\Config\Model\Config\Reader\Source\Deployed\DocumentRoot $documentRoot = null, + SitemapItemResolverInterface $itemResolver = null ) { $this->_escaper = $escaper; $this->_sitemapData = $sitemapData; @@ -207,6 +215,7 @@ public function __construct( $this->_storeManager = $storeManager; $this->_request = $request; $this->dateTime = $dateTime; + $this->itemResolver = $itemResolver ?: ObjectManager::getInstance()->get(SitemapItemResolverInterface::class); parent::__construct($context, $registry, $resource, $resourceCollection, $data); } @@ -236,55 +245,6 @@ protected function _getStream() } } - /** - * Add a sitemap item to the array of sitemap items - * - * @param DataObject $sitemapItem - * @return $this - */ - public function addSitemapItem(DataObject $sitemapItem) - { - $this->_sitemapItems[] = $sitemapItem; - - return $this; - } - - /** - * Collect all sitemap items - * - * @return void - */ - public function collectSitemapItems() - { - /** @var $helper \Magento\Sitemap\Helper\Data */ - $helper = $this->_sitemapData; - $storeId = $this->getStoreId(); - - $this->addSitemapItem(new DataObject( - [ - 'changefreq' => $helper->getCategoryChangefreq($storeId), - 'priority' => $helper->getCategoryPriority($storeId), - 'collection' => $this->_categoryFactory->create()->getCollection($storeId), - ] - )); - - $this->addSitemapItem(new DataObject( - [ - 'changefreq' => $helper->getProductChangefreq($storeId), - 'priority' => $helper->getProductPriority($storeId), - 'collection' => $this->_productFactory->create()->getCollection($storeId), - ] - )); - - $this->addSitemapItem(new DataObject( - [ - 'changefreq' => $helper->getPageChangefreq($storeId), - 'priority' => $helper->getPagePriority($storeId), - 'collection' => $this->_cmsFactory->create()->getCollection($storeId), - ] - )); - } - /** * Initialize sitemap * @@ -292,7 +252,7 @@ public function collectSitemapItems() */ protected function _initSitemapItems() { - $this->collectSitemapItems(); + $this->_sitemapItems = $this->itemResolver->getItems($this->getStoreId()); $this->_tags = [ self::TYPE_INDEX => [ @@ -377,30 +337,30 @@ public function generateXml() { $this->_initSitemapItems(); - /** @var $sitemapItem \Magento\Framework\DataObject */ - foreach ($this->_sitemapItems as $sitemapItem) { - $changefreq = $sitemapItem->getChangefreq(); - $priority = $sitemapItem->getPriority(); - foreach ($sitemapItem->getCollection() as $item) { - $xml = $this->_getSitemapRow( - $item->getUrl(), - $item->getUpdatedAt(), - $changefreq, - $priority, - $item->getImages() - ); - if ($this->_isSplitRequired($xml) && $this->_sitemapIncrement > 0) { - $this->_finalizeSitemap(); - } - if (!$this->_fileSize) { - $this->_createSitemap(); - } - $this->_writeSitemapRow($xml); - // Increase counters - $this->_lineCount++; - $this->_fileSize += strlen($xml); + /** @var $item SitemapItemInterface */ + foreach ($this->_sitemapItems as $item) { + $xml = $this->_getSitemapRow( + $item->getUrl(), + $item->getUpdatedAt(), + $item->getChangeFrequency(), + $item->getPriority(), + $item->getImages() + ); + + if ($this->_isSplitRequired($xml) && $this->_sitemapIncrement > 0) { + $this->_finalizeSitemap(); + } + + if (!$this->_fileSize) { + $this->_createSitemap(); } + + $this->_writeSitemapRow($xml); + // Increase counters + $this->_lineCount++; + $this->_fileSize += strlen($xml); } + $this->_finalizeSitemap(); if ($this->_sitemapIncrement == 1) { diff --git a/app/code/Magento/Sitemap/Model/SitemapItem.php b/app/code/Magento/Sitemap/Model/SitemapItem.php new file mode 100644 index 0000000000000..4a6c4d8fd9e16 --- /dev/null +++ b/app/code/Magento/Sitemap/Model/SitemapItem.php @@ -0,0 +1,93 @@ +url = $url; + $this->priority = $priority; + $this->changeFrequency = $changeFrequency; + $this->updatedAt = $updatedAt; + $this->images = $images; + } + + /** + * {@inheritdoc} + */ + public function getUrl() + { + return $this->url; + } + + /** + * {@inheritdoc} + */ + public function getPriority() + { + return $this->priority; + } + + /** + * {@inheritdoc} + */ + public function getChangeFrequency() + { + return $this->changeFrequency; + } + + /** + * {@inheritdoc} + */ + public function getImages() + { + return $this->images; + } + + /** + * {@inheritdoc} + */ + public function getUpdatedAt() + { + return $this->updatedAt; + } +} \ No newline at end of file diff --git a/app/code/Magento/Sitemap/Model/SitemapItemInterface.php b/app/code/Magento/Sitemap/Model/SitemapItemInterface.php new file mode 100644 index 0000000000000..5c87f1805afa2 --- /dev/null +++ b/app/code/Magento/Sitemap/Model/SitemapItemInterface.php @@ -0,0 +1,50 @@ +getStoreConfigMock([ + CategorySitemapItemResolver::XML_PATH_CATEGORY_CHANGEFREQ => 'daily', + CategorySitemapItemResolver::XML_PATH_CATEGORY_PRIORITY => '1.0', + ]); + + $categoryMock = $this->getCategoryCollectionMock([]); + $cmsPageFactoryMock = $this->getCategoryFactoryMock($categoryMock); + $itemFactoryMock = $this->getItemFactoryMock(); + + $resolver = new CategorySitemapItemResolver($storeConfigMock, $cmsPageFactoryMock, $itemFactoryMock); + self::assertSame([], $resolver->getItems(1)); + } + + /** + * @dataProvider categoryProvider + * @param array $categories + */ + public function testGetItems(array $categories) + { + $storeConfigMock = $this->getStoreConfigMock([ + CategorySitemapItemResolver::XML_PATH_CATEGORY_CHANGEFREQ => 'daily', + CategorySitemapItemResolver::XML_PATH_CATEGORY_PRIORITY => '1.0', + ]); + + $categoryMock = $this->getCategoryCollectionMock($categories); + + $cmsPageFactoryMock = $this->getCategoryFactoryMock($categoryMock); + $itemFactoryMock = $this->getItemFactoryMock(); + + $resolver = new CategorySitemapItemResolver($storeConfigMock, $cmsPageFactoryMock, $itemFactoryMock); + $items = $resolver->getItems(1); + self::assertTrue(count($items) == count($categories)); + foreach($categories as $index => $category) { + self::assertSame($category->getUpdatedAt(), $items[$index]->getUpdatedAt()); + self::assertSame('daily', $items[$index]->getChangeFrequency()); + self::assertSame('1.0', $items[$index]->getPriority()); + self::assertSame($category->getImages(), $items[$index]->getImages()); + self::assertSame($category->getUrl(), $items[$index]->getUrl()); + } + } + + /** + * @return array + */ + public function categoryProvider() + { + return [ + [ + [ + new \Magento\Framework\DataObject( + ['url' => 'category.html', 'updated_at' => '2012-12-21 00:00:00'] + ), + new \Magento\Framework\DataObject( + ['url' => '/category/sub-category.html', 'updated_at' => '2012-12-21 00:00:00'] + ), + ] + ] + ]; + } + + /** + * @param $returnValue + * @return \PHPUnit_Framework_MockObject_MockObject + */ + private function getCategoryFactoryMock($returnValue) + { + $cmsPageFactoryMock = $this->getMockBuilder(CategoryFactory::class) + ->setMethods(['create']) + ->disableOriginalConstructor() + ->getMock(); + + $cmsPageFactoryMock->expects(self::any()) + ->method('create') + ->willReturn($returnValue); + + return $cmsPageFactoryMock; + } + + /** + * @return \PHPUnit_Framework_MockObject_MockObject + */ + private function getItemFactoryMock() + { + $itemFactoryMock = $this->getMockBuilder(SitemapItemInterfaceFactory::class) + ->setMethods(['create']) + ->disableOriginalConstructor() + ->getMock(); + + $itemFactoryMock->expects(self::any()) + ->method('create') + ->willReturnCallback(function ($data) { + $helper = new ObjectManager($this); + + return $helper->getObject(SitemapItem::class, $data); + }); + + return $itemFactoryMock; + } + + /** + * @param array $pathMap + * @return \PHPUnit_Framework_MockObject_MockObject + */ + private function getStoreConfigMock(array $pathMap = []) + { + $scopeConfigMock = $this->getMockForAbstractClass(ScopeConfigInterface::class); + $scopeConfigMock->method('getValue') + ->willReturnCallback(function ($path) use ($pathMap) { + return isset($pathMap[$path]) ? $pathMap[$path] : null; + }); + + return $scopeConfigMock; + } + + /** + * @param $returnValue + * @return \PHPUnit_Framework_MockObject_MockObject + */ + private function getCategoryCollectionMock($returnValue) + { + $sitemapCmsPageMock = $this->getMockBuilder(Category::class) + ->setMethods(['getCollection']) + ->disableOriginalConstructor() + ->getMock(); + + $sitemapCmsPageMock->expects(self::any()) + ->method('getCollection') + ->willReturn($returnValue); + + return $sitemapCmsPageMock; + } +} \ No newline at end of file diff --git a/app/code/Magento/Sitemap/Test/Unit/Model/CmsPageSitemapItemResolverTest.php b/app/code/Magento/Sitemap/Test/Unit/Model/CmsPageSitemapItemResolverTest.php new file mode 100644 index 0000000000000..9bc313120fc04 --- /dev/null +++ b/app/code/Magento/Sitemap/Test/Unit/Model/CmsPageSitemapItemResolverTest.php @@ -0,0 +1,152 @@ +getStoreConfigMock([ + CmsPageSitemapItemResolver::XML_PATH_PAGE_CHANGEFREQ => 'daily', + CmsPageSitemapItemResolver::XML_PATH_PAGE_PRIORITY => '1.0', + ]); + + $cmsPageCollectionMock = $this->getCmsPageCollectionMock([]); + $cmsPageFactoryMock = $this->getCmsPageFactoryMock($cmsPageCollectionMock); + $itemFactoryMock = $this->getItemFactoryMock(); + + $resolver = new CmsPageSitemapItemResolver($storeConfigMock, $cmsPageFactoryMock, $itemFactoryMock); + self::assertSame([], $resolver->getItems(1)); + } + + /** + * @dataProvider pageProvider + * @param array $pages + */ + public function testGetItems(array $pages = []) + { + $storeConfigMock = $this->getStoreConfigMock([ + CmsPageSitemapItemResolver::XML_PATH_PAGE_CHANGEFREQ => 'daily', + CmsPageSitemapItemResolver::XML_PATH_PAGE_PRIORITY => '1.0', + ]); + + $cmsPageMock = $this->getCmsPageCollectionMock($pages); + + $cmsPageFactoryMock = $this->getCmsPageFactoryMock($cmsPageMock); + $itemFactoryMock = $this->getItemFactoryMock(); + + $resolver = new CmsPageSitemapItemResolver($storeConfigMock, $cmsPageFactoryMock, $itemFactoryMock); + $items = $resolver->getItems(1); + self::assertTrue(count($items) == count($pages)); + foreach($pages as $index => $page) {; + self::assertSame($page->getUpdatedAt(), $items[$index]->getUpdatedAt()); + self::assertSame('daily', $items[$index]->getChangeFrequency()); + self::assertSame('1.0', $items[$index]->getPriority()); + self::assertSame($page->getImages(), $items[$index]->getImages()); + self::assertSame($page->getUrl(), $items[$index]->getUrl()); + } + } + + /** + * @return array + */ + public function pageProvider() + { + return [ + [ + [ + new DataObject([ + 'url' => 'http://dummy.url', + 'id' => '/url', + 'updated_at' => '2017-01-01 23:59:59' + ]) + ] + ] + ]; + } + + /** + * @return \PHPUnit_Framework_MockObject_MockObject + */ + private function getItemFactoryMock() + { + $itemFactoryMock = $this->getMockBuilder(SitemapItemInterfaceFactory::class) + ->setMethods(['create']) + ->disableOriginalConstructor() + ->getMock(); + + $itemFactoryMock->expects(self::any()) + ->method('create') + ->willReturnCallback(function ($data) { + $helper = new ObjectManager($this); + + return $helper->getObject(SitemapItem::class, $data); + }); + + return $itemFactoryMock; + } + + /** + * @param $returnValue + * @return \PHPUnit_Framework_MockObject_MockObject + */ + private function getCmsPageFactoryMock($returnValue) + { + $cmsPageFactoryMock = $this->getMockBuilder(PageFactory::class) + ->setMethods(['create']) + ->disableOriginalConstructor() + ->getMock(); + + $cmsPageFactoryMock->expects(self::any()) + ->method('create') + ->willReturn($returnValue); + + return $cmsPageFactoryMock; + } + + /** + * @param array $pathMap + * @return \PHPUnit_Framework_MockObject_MockObject + */ + private function getStoreConfigMock(array $pathMap = []) + { + $scopeConfigMock = $this->getMockForAbstractClass(ScopeConfigInterface::class); + $scopeConfigMock->method('getValue') + ->willReturnCallback(function ($path) use ($pathMap) { + return isset($pathMap[$path]) ? $pathMap[$path] : null; + }); + + return $scopeConfigMock; + } + + /** + * @param $returnValue + * @return \PHPUnit_Framework_MockObject_MockObject + */ + private function getCmsPageCollectionMock($returnValue) + { + $sitemapCmsPageMock = $this->getMockBuilder(Page::class) + ->setMethods(['getCollection']) + ->disableOriginalConstructor() + ->getMock(); + + $sitemapCmsPageMock->expects(self::any()) + ->method('getCollection') + ->willReturn($returnValue); + + return $sitemapCmsPageMock; + } +} \ No newline at end of file diff --git a/app/code/Magento/Sitemap/Test/Unit/Model/CompositeSitemapItemResolverTest.php b/app/code/Magento/Sitemap/Test/Unit/Model/CompositeSitemapItemResolverTest.php new file mode 100644 index 0000000000000..b1db237475f7e --- /dev/null +++ b/app/code/Magento/Sitemap/Test/Unit/Model/CompositeSitemapItemResolverTest.php @@ -0,0 +1,69 @@ +getItems(1)); + } + + /** + * @dataProvider sitemapItemsProvider + * @param array $itemResolverData + * @param array $expectedItems + */ + public function testGetItems($itemResolverData, $expectedItems) + { + $mockResolvers = []; + + foreach($itemResolverData as $data) { + $mockResolver = $this->getMockForAbstractClass(SitemapItemResolverInterface::class); + $mockResolver->expects(self::once()) + ->method('getItems') + ->willReturn($data); + + $mockResolvers[] = $mockResolver; + } + + $resolver = new CompositeSitemapItemResolver($mockResolvers); + $items = $resolver->getItems(1); + + self::assertSame($expectedItems, $items); + } + + /** + * @return array + */ + public function sitemapItemsProvider() + { + $testCases = []; + + for($i = 1; $i < 5; $i++) { + $itemProviders = []; + $expectedItems = []; + for($i = 1; $i < $maxProviders = random_int(1, 5); $i++) { + $items = []; + for($i = 1; $i < $maxItems = random_int(2, 5); $i++) { + $sitemapItem = $this->getMockForAbstractClass(SitemapItemInterface::class); + $items[] = $sitemapItem; + $expectedItems[] = $sitemapItem; + } + $itemProviders[] = $items; + } + + $testCases[] = [$itemProviders, $expectedItems]; + } + + return $testCases; + } +} \ No newline at end of file diff --git a/app/code/Magento/Sitemap/Test/Unit/Model/ProductSitemapItemResolverTest.php b/app/code/Magento/Sitemap/Test/Unit/Model/ProductSitemapItemResolverTest.php new file mode 100644 index 0000000000000..bd7ac0366a95d --- /dev/null +++ b/app/code/Magento/Sitemap/Test/Unit/Model/ProductSitemapItemResolverTest.php @@ -0,0 +1,174 @@ +getStoreConfigMock([ + ProductSitemapItemResolver::XML_PATH_PRODUCT_CHANGEFREQ => 'daily', + ProductSitemapItemResolver::XML_PATH_PRODUCT_PRIORITY => '1.0', + ]); + + $ProductMock = $this->getProductCollectionMock([]); + $cmsPageFactoryMock = $this->getProductFactoryMock($ProductMock); + $itemFactoryMock = $this->getItemFactoryMock(); + + $resolver = new ProductSitemapItemResolver($storeConfigMock, $cmsPageFactoryMock, $itemFactoryMock); + self::assertSame([], $resolver->getItems(1)); + } + + /** + * @dataProvider productProvider + * @param array $categories + */ + public function testGetItems(array $categories) + { + $storeConfigMock = $this->getStoreConfigMock([ + ProductSitemapItemResolver::XML_PATH_PRODUCT_CHANGEFREQ => 'daily', + ProductSitemapItemResolver::XML_PATH_PRODUCT_PRIORITY => '1.0', + ]); + + $ProductMock = $this->getProductCollectionMock($categories); + + $cmsPageFactoryMock = $this->getProductFactoryMock($ProductMock); + $itemFactoryMock = $this->getItemFactoryMock(); + + $resolver = new ProductSitemapItemResolver($storeConfigMock, $cmsPageFactoryMock, $itemFactoryMock); + $items = $resolver->getItems(1); + self::assertTrue(count($items) == count($categories)); + foreach($categories as $index => $product) { + self::assertSame($product->getUpdatedAt(), $items[$index]->getUpdatedAt()); + self::assertSame('daily', $items[$index]->getChangeFrequency()); + self::assertSame('1.0', $items[$index]->getPriority()); + self::assertSame($product->getImages(), $items[$index]->getImages()); + self::assertSame($product->getUrl(), $items[$index]->getUrl()); + } + } + + /** + * @return array + */ + public function productProvider() + { + $storeBaseMediaUrl = 'http://store.com/pub/media/catalog/product/cache/c9e0b0ef589f3508e5ba515cde53c5ff/'; + return [ + [ + [ + new DataObject( + ['url' => 'product.html', 'updated_at' => '2012-12-21 00:00:00'] + ), + new DataObject( + [ + 'url' => 'product2.html', + 'updated_at' => '2012-12-21 00:00:00', + 'images' => new DataObject( + [ + 'collection' => [ + new DataObject( + [ + 'url' => $storeBaseMediaUrl.'i/m/image1.png', + 'caption' => 'caption & > title < "' + ] + ), + new DataObject( + ['url' => $storeBaseMediaUrl.'i/m/image_no_caption.png', 'caption' => null] + ), + ], + 'thumbnail' => $storeBaseMediaUrl.'t/h/thumbnail.jpg', + 'title' => 'Product & > title < "', + ] + ), + ] + ), + ] + ] + ]; + } + + /** + * @param $returnValue + * @return \PHPUnit_Framework_MockObject_MockObject + */ + private function getProductFactoryMock($returnValue) + { + $cmsPageFactoryMock = $this->getMockBuilder(ProductFactory::class) + ->setMethods(['create']) + ->disableOriginalConstructor() + ->getMock(); + + $cmsPageFactoryMock->expects(self::any()) + ->method('create') + ->willReturn($returnValue); + + return $cmsPageFactoryMock; + } + + /** + * @return \PHPUnit_Framework_MockObject_MockObject + */ + private function getItemFactoryMock() + { + $itemFactoryMock = $this->getMockBuilder(SitemapItemInterfaceFactory::class) + ->setMethods(['create']) + ->disableOriginalConstructor() + ->getMock(); + + $itemFactoryMock->expects(self::any()) + ->method('create') + ->willReturnCallback(function ($data) { + $helper = new ObjectManager($this); + + return $helper->getObject(SitemapItem::class, $data); + }); + + return $itemFactoryMock; + } + + /** + * @param array $pathMap + * @return \PHPUnit_Framework_MockObject_MockObject + */ + private function getStoreConfigMock(array $pathMap = []) + { + $scopeConfigMock = $this->getMockForAbstractClass(ScopeConfigInterface::class); + $scopeConfigMock->method('getValue') + ->willReturnCallback(function ($path) use ($pathMap) { + return isset($pathMap[$path]) ? $pathMap[$path] : null; + }); + + return $scopeConfigMock; + } + + /** + * @param $returnValue + * @return \PHPUnit_Framework_MockObject_MockObject + */ + private function getProductCollectionMock($returnValue) + { + $sitemapCmsPageMock = $this->getMockBuilder(Product::class) + ->setMethods(['getCollection']) + ->disableOriginalConstructor() + ->getMock(); + + $sitemapCmsPageMock->expects(self::any()) + ->method('getCollection') + ->willReturn($returnValue); + + return $sitemapCmsPageMock; + } +} \ No newline at end of file diff --git a/app/code/Magento/Sitemap/Test/Unit/Model/SitemapTest.php b/app/code/Magento/Sitemap/Test/Unit/Model/SitemapTest.php index fb1379ecfca28..0b69dd349696e 100644 --- a/app/code/Magento/Sitemap/Test/Unit/Model/SitemapTest.php +++ b/app/code/Magento/Sitemap/Test/Unit/Model/SitemapTest.php @@ -5,6 +5,8 @@ */ namespace Magento\Sitemap\Test\Unit\Model; +use Magento\Sitemap\Model\SitemapItemResolverInterface; + /** * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ @@ -55,6 +57,11 @@ class SitemapTest extends \PHPUnit_Framework_TestCase */ private $storeManagerMock; + /** + * @var \Magento\Sitemap\Model\SitemapItemResolverInterface + */ + private $itemResolverMock; + /** * Set helper mocks, create resource model mock */ @@ -146,6 +153,11 @@ protected function setUp() )->will( $this->returnValue($this->_directoryMock) ); + + $this->itemResolverMock = $this->getMockForAbstractClass(SitemapItemResolverInterface::class); + $this->itemResolverMock->expects(self::any()) + ->method('getItems') + ->willReturn([]); } /** @@ -646,7 +658,8 @@ protected function _getModelConstructorArgs() 'cmsFactory' => $cmsFactory, 'storeManager' => $this->storeManagerMock, 'sitemapData' => $this->_helperMockSitemap, - 'filesystem' => $this->_filesystemMock + 'filesystem' => $this->_filesystemMock, + 'itemResolver' => $this->itemResolverMock, ] ); $constructArguments['resource'] = null; diff --git a/app/code/Magento/Sitemap/etc/di.xml b/app/code/Magento/Sitemap/etc/di.xml index 0b45763c41bae..217c65dc61973 100644 --- a/app/code/Magento/Sitemap/etc/di.xml +++ b/app/code/Magento/Sitemap/etc/di.xml @@ -6,6 +6,8 @@ */ --> + + Magento\Sitemap\Model\ResourceModel\Sitemap @@ -18,4 +20,13 @@ + + + + Magento\Sitemap\Model\CategorySitemapItemResolver + Magento\Sitemap\Model\CmsPageSitemapItemResolver + Magento\Sitemap\Model\ProductSitemapItemResolver + + +