123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726 |
- <?php
- /**
- * Copyright © Magento, Inc. All rights reserved.
- * See COPYING.txt for license details.
- */
- namespace Magento\Sitemap\Test\Unit\Model;
- use Magento\Framework\DataObject;
- use Magento\Framework\Filesystem;
- use Magento\Framework\Filesystem\Directory\Write as DirectoryWrite;
- use Magento\Framework\Filesystem\File\Write;
- use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
- use Magento\Sitemap\Helper\Data;
- use Magento\Sitemap\Model\ItemProvider\ConfigReaderInterface;
- use Magento\Sitemap\Model\ItemProvider\ItemProviderInterface;
- use Magento\Sitemap\Model\ResourceModel\Catalog\Category;
- use Magento\Sitemap\Model\ResourceModel\Catalog\CategoryFactory;
- use Magento\Sitemap\Model\ResourceModel\Catalog\Product;
- use Magento\Sitemap\Model\ResourceModel\Catalog\ProductFactory;
- use Magento\Sitemap\Model\ResourceModel\Cms\Page;
- use Magento\Sitemap\Model\ResourceModel\Cms\PageFactory;
- use Magento\Sitemap\Model\ResourceModel\Sitemap as SitemapResource;
- use Magento\Sitemap\Model\Sitemap;
- use Magento\Sitemap\Model\SitemapConfigReaderInterface;
- use Magento\Sitemap\Model\SitemapItem;
- use Magento\Store\Model\Store;
- use Magento\Store\Model\StoreManagerInterface;
- /**
- * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
- */
- class SitemapTest extends \PHPUnit\Framework\TestCase
- {
- /**
- * @var Data
- */
- private $helperMockSitemap;
- /**
- * @var SitemapResource
- */
- private $resourceMock;
- /**
- * @var Category
- */
- private $sitemapCategoryMock;
- /**
- * @var Product
- */
- private $sitemapProductMock;
- /**
- * @var Page
- */
- private $sitemapCmsPageMock;
- /**
- * @var Filesystem
- */
- private $filesystemMock;
- /**
- * @var DirectoryWrite
- */
- private $directoryMock;
- /**
- * @var Write
- */
- private $fileMock;
- /**
- * @var StoreManagerInterface|\PHPUnit_Framework_MockObject_MockObject
- */
- private $storeManagerMock;
- /**
- * @var ItemProviderInterface|\PHPUnit_Framework_MockObject_MockObject
- */
- private $itemProviderMock;
- /**
- * @var ConfigReaderInterface|\PHPUnit_Framework_MockObject_MockObject
- */
- private $configReaderMock;
- /**
- * Set helper mocks, create resource model mock
- */
- protected function setUp()
- {
- $this->sitemapCategoryMock = $this->getMockBuilder(Category::class)
- ->disableOriginalConstructor()
- ->getMock();
- $this->sitemapProductMock = $this->getMockBuilder(Product::class)
- ->disableOriginalConstructor()
- ->getMock();
- $this->sitemapCmsPageMock = $this->getMockBuilder(Page::class)
- ->disableOriginalConstructor()
- ->getMock();
- $this->helperMockSitemap = $this->getMockBuilder(Data::class)
- ->disableOriginalConstructor()
- ->getMock();
- $resourceMethods = [
- '_construct',
- 'beginTransaction',
- 'rollBack',
- 'save',
- 'addCommitCallback',
- 'commit',
- '__wakeup',
- ];
- $this->resourceMock = $this->getMockBuilder(SitemapResource::class)
- ->setMethods($resourceMethods)
- ->disableOriginalConstructor()
- ->getMock();
- $this->resourceMock->expects($this->any())
- ->method('addCommitCallback')
- ->willReturnSelf();
- $this->fileMock = $this->createMock(Write::class);
- $this->directoryMock = $this->createMock(DirectoryWrite::class);
- $this->directoryMock->expects($this->any())
- ->method('openFile')
- ->willReturn($this->fileMock);
- $this->filesystemMock = $this->getMockBuilder(Filesystem::class)
- ->setMethods(['getDirectoryWrite'])
- ->disableOriginalConstructor()
- ->getMock();
- $this->filesystemMock->expects($this->any())
- ->method('getDirectoryWrite')
- ->willReturn($this->directoryMock);
- $this->configReaderMock = $this->getMockForAbstractClass(SitemapConfigReaderInterface::class);
- $this->itemProviderMock = $this->getMockForAbstractClass(ItemProviderInterface::class);
- }
- /**
- * Check not allowed sitemap path validation
- *
- * @expectedException \Magento\Framework\Exception\LocalizedException
- * @expectedExceptionMessage Please define a correct path.
- */
- public function testNotAllowedPath()
- {
- $model = $this->getModelMock();
- $model->setSitemapPath('../');
- $model->beforeSave();
- }
- /**
- * Check not exists sitemap path validation
- *
- * @expectedException \Magento\Framework\Exception\LocalizedException
- * @expectedExceptionMessage Please create the specified folder "" before saving the sitemap.
- */
- public function testPathNotExists()
- {
- $this->directoryMock->expects($this->once())
- ->method('isExist')
- ->willReturn(false);
- $model = $this->getModelMock();
- $model->beforeSave();
- }
- /**
- * Check not writable sitemap path validation
- *
- * @expectedException \Magento\Framework\Exception\LocalizedException
- * @expectedExceptionMessage Please make sure that "/" is writable by the web-server.
- */
- public function testPathNotWritable()
- {
- $this->directoryMock->expects($this->once())
- ->method('isExist')
- ->willReturn(true);
- $this->directoryMock->expects($this->once())
- ->method('isWritable')
- ->willReturn(false);
- $model = $this->getModelMock();
- $model->beforeSave();
- }
- //@codingStandardsIgnoreStart
- /**
- * Check invalid chars in sitemap filename validation
- *
- * @expectedException \Magento\Framework\Exception\LocalizedException
- * @expectedExceptionMessage Please use only letters (a-z or A-Z), numbers (0-9) or underscores (_) in the filename.
- * No spaces or other characters are allowed.
- */
- //@codingStandardsIgnoreEnd
- public function testFilenameInvalidChars()
- {
- $this->directoryMock->expects($this->once())
- ->method('isExist')
- ->willReturn(true);
- $this->directoryMock->expects($this->once())
- ->method('isWritable')
- ->willReturn(true);
- $model = $this->getModelMock();
- $model->setSitemapFilename('*sitemap?.xml');
- $model->beforeSave();
- }
- /**
- * Data provider for sitemaps
- *
- * 1) Limit set to 50000 urls and 10M per sitemap file (single file)
- * 2) Limit set to 1 url and 10M per sitemap file (multiple files, 1 record per file)
- * 3) Limit set to 50000 urls and 264 bytes per sitemap file (multiple files, 1 record per file)
- *
- * @static
- * @return array
- */
- public static function sitemapDataProvider()
- {
- $expectedSingleFile = ['/sitemap-1-1.xml' => __DIR__ . '/_files/sitemap-single.xml'];
- $expectedMultiFile = [
- '/sitemap-1-1.xml' => __DIR__ . '/_files/sitemap-1-1.xml',
- '/sitemap-1-2.xml' => __DIR__ . '/_files/sitemap-1-2.xml',
- '/sitemap-1-3.xml' => __DIR__ . '/_files/sitemap-1-3.xml',
- '/sitemap-1-4.xml' => __DIR__ . '/_files/sitemap-1-4.xml',
- '/sitemap.xml' => __DIR__ . '/_files/sitemap-index.xml',
- ];
- return [
- [50000, 10485760, $expectedSingleFile, 6],
- [1, 10485760, $expectedMultiFile, 18],
- [50000, 264, $expectedMultiFile, 18],
- ];
- }
- /**
- * Check generation of sitemaps
- *
- * @param int $maxLines
- * @param int $maxFileSize
- * @param array $expectedFile
- * @param int $expectedWrites
- * @dataProvider sitemapDataProvider
- */
- public function testGenerateXml($maxLines, $maxFileSize, $expectedFile, $expectedWrites)
- {
- $actualData = [];
- $model = $this->prepareSitemapModelMock(
- $actualData,
- $maxLines,
- $maxFileSize,
- $expectedFile,
- $expectedWrites,
- null
- );
- $model->generateXml();
- $this->assertCount(count($expectedFile), $actualData, 'Number of generated files is incorrect');
- foreach ($expectedFile as $expectedFileName => $expectedFilePath) {
- $this->assertArrayHasKey(
- $expectedFileName,
- $actualData,
- sprintf('File %s was not generated', $expectedFileName)
- );
- $this->assertXmlStringEqualsXmlFile($expectedFilePath, $actualData[$expectedFileName]);
- }
- }
- /**
- * Data provider for robots.txt
- *
- * @static
- * @return array
- */
- public static function robotsDataProvider()
- {
- $expectedSingleFile = ['/sitemap-1-1.xml' => __DIR__ . '/_files/sitemap-single.xml'];
- $expectedMultiFile = [
- '/sitemap-1-1.xml' => __DIR__ . '/_files/sitemap-1-1.xml',
- '/sitemap-1-2.xml' => __DIR__ . '/_files/sitemap-1-2.xml',
- '/sitemap-1-3.xml' => __DIR__ . '/_files/sitemap-1-3.xml',
- '/sitemap-1-4.xml' => __DIR__ . '/_files/sitemap-1-4.xml',
- '/sitemap.xml' => __DIR__ . '/_files/sitemap-index.xml',
- ];
- return [
- [
- 50000,
- 10485760,
- $expectedSingleFile,
- 6,
- [
- 'robotsStart' => '',
- 'robotsFinish' => 'Sitemap: http://store.com/sitemap.xml',
- 'pushToRobots' => 1
- ],
- ], // empty robots file
- [
- 50000,
- 10485760,
- $expectedSingleFile,
- 6,
- [
- 'robotsStart' => "User-agent: *",
- 'robotsFinish' => "User-agent: *" . PHP_EOL . 'Sitemap: http://store.com/sitemap.xml',
- 'pushToRobots' => 1
- ]
- ], // not empty robots file EOL
- [
- 1,
- 10485760,
- $expectedMultiFile,
- 18,
- [
- 'robotsStart' => "User-agent: *\r\n",
- 'robotsFinish' => "User-agent: *\r\n\r\nSitemap: http://store.com/sitemap.xml",
- 'pushToRobots' => 1
- ]
- ], // not empty robots file WIN
- [
- 50000,
- 264,
- $expectedMultiFile,
- 18,
- [
- 'robotsStart' => "User-agent: *\n",
- 'robotsFinish' => "User-agent: *\n\nSitemap: http://store.com/sitemap.xml",
- 'pushToRobots' => 1
- ]
- ], // not empty robots file UNIX
- [
- 50000,
- 10485760,
- $expectedSingleFile,
- 6,
- ['robotsStart' => '', 'robotsFinish' => '', 'pushToRobots' => 0]
- ] // empty robots file
- ];
- }
- /**
- * Check pushing of sitemaps to robots.txt
- *
- * @param int $maxLines
- * @param int $maxFileSize
- * @param array $expectedFile
- * @param int $expectedWrites
- * @param array $robotsInfo
- * @dataProvider robotsDataProvider
- */
- public function testAddSitemapToRobotsTxt($maxLines, $maxFileSize, $expectedFile, $expectedWrites, $robotsInfo)
- {
- $actualData = [];
- $model = $this->prepareSitemapModelMock(
- $actualData,
- $maxLines,
- $maxFileSize,
- $expectedFile,
- $expectedWrites,
- $robotsInfo
- );
- $model->generateXml();
- }
- /**
- * Prepare mock of Sitemap model
- *
- * @param array $actualData
- * @param int $maxLines
- * @param int $maxFileSize
- * @param array $expectedFile
- * @param int $expectedWrites
- * @param array $robotsInfo
- * @return Sitemap|PHPUnit_Framework_MockObject_MockObject
- * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
- */
- protected function prepareSitemapModelMock(
- &$actualData,
- $maxLines,
- $maxFileSize,
- $expectedFile,
- $expectedWrites,
- $robotsInfo
- ) {
- // Check that all $expectedWrites lines were written
- $actualData = [];
- $currentFile = '';
- $streamWriteCallback = function ($str) use (&$actualData, &$currentFile) {
- if (!array_key_exists($currentFile, $actualData)) {
- $actualData[$currentFile] = '';
- }
- $actualData[$currentFile] .= $str;
- };
- // Check that all expected lines were written
- $this->fileMock->expects(
- $this->exactly($expectedWrites)
- )->method(
- 'write'
- )->will(
- $this->returnCallback($streamWriteCallback)
- );
- $checkFileCallback = function ($file) use (&$currentFile) {
- $currentFile = $file;
- };// Check that all expected file descriptors were created
- $this->directoryMock->expects($this->exactly(count($expectedFile)))->method('openFile')
- ->willReturnCallback($checkFileCallback);
- // Check that all file descriptors were closed
- $this->fileMock->expects($this->exactly(count($expectedFile)))
- ->method('close');
- if (count($expectedFile) == 1) {
- $this->directoryMock->expects($this->once())
- ->method('renameFile')
- ->willReturnCallback(function ($from, $to) {
- \PHPUnit\Framework\Assert::assertEquals('/sitemap-1-1.xml', $from);
- \PHPUnit\Framework\Assert::assertEquals('/sitemap.xml', $to);
- });
- }
- // Check robots txt
- $robotsStart = '';
- if (isset($robotsInfo['robotsStart'])) {
- $robotsStart = $robotsInfo['robotsStart'];
- }
- $robotsFinish = 'Sitemap: http://store.com/sitemap.xml';
- if (isset($robotsInfo['robotsFinish'])) {
- $robotsFinish = $robotsInfo['robotsFinish'];
- }
- $this->directoryMock->expects($this->any())
- ->method('readFile')
- ->willReturn($robotsStart);
- $this->directoryMock->expects($this->any())
- ->method('writeFile')
- ->with(
- $this->equalTo('robots.txt'),
- $this->equalTo($robotsFinish)
- );
- // Mock helper methods
- $pushToRobots = 0;
- if (isset($robotsInfo['pushToRobots'])) {
- $pushToRobots = (int)$robotsInfo['pushToRobots'];
- }
- $this->configReaderMock->expects($this->any())
- ->method('getMaximumLinesNumber')
- ->willReturn($maxLines);
- $this->configReaderMock->expects($this->any())
- ->method('getMaximumFileSize')
- ->willReturn($maxFileSize);
- $this->configReaderMock->expects($this->any())
- ->method('getEnableSubmissionRobots')
- ->willReturn($pushToRobots);
- $model = $this->getModelMock(true);
- $storeMock = $this->getMockBuilder(Store::class)
- ->setMethods(['isFrontUrlSecure', 'getBaseUrl'])
- ->disableOriginalConstructor()
- ->getMock();
- $storeMock->expects($this->atLeastOnce())
- ->method('isFrontUrlSecure')
- ->willReturn(false);
- $storeMock->expects($this->atLeastOnce())
- ->method('getBaseUrl')
- ->with($this->isType('string'), false)
- ->willReturn('http://store.com/');
- $this->storeManagerMock->expects($this->atLeastOnce())
- ->method('getStore')
- ->with(1)
- ->willReturn($storeMock);
- return $model;
- }
- /**
- * Get model mock object
- *
- * @param bool $mockBeforeSave
- * @return Sitemap|PHPUnit_Framework_MockObject_MockObject
- */
- protected function getModelMock($mockBeforeSave = false)
- {
- $methods = [
- '_construct',
- '_getResource',
- '_getBaseDir',
- '_getFileObject',
- '_afterSave',
- '_getCurrentDateTime',
- '_getCategoryItemsCollection',
- '_getProductItemsCollection',
- '_getPageItemsCollection',
- '_getDocumentRoot',
- ];
- if ($mockBeforeSave) {
- $methods[] = 'beforeSave';
- }
- $storeBaseMediaUrl = 'http://store.com/pub/media/catalog/product/cache/c9e0b0ef589f3508e5ba515cde53c5ff/';
- $this->itemProviderMock->expects($this->any())
- ->method('getItems')
- ->willReturn([
- new SitemapItem('category.html', '1.0', 'daily', '2012-12-21 00:00:00'),
- new SitemapItem('/category/sub-category.html', '1.0', 'daily', '2012-12-21 00:00:00'),
- new SitemapItem('product.html', '0.5', 'monthly', '0000-00-00 00:00:00'),
- new SitemapItem(
- 'product2.html',
- '0.5',
- 'monthly',
- '2012-12-21 00:00:00',
- 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 < "',
- ])
- )
- ]);
- /** @var $model Sitemap */
- $model = $this->getMockBuilder(Sitemap::class)
- ->setMethods($methods)
- ->setConstructorArgs($this->getModelConstructorArgs())
- ->getMock();
- $model->expects($this->any())
- ->method('_getResource')
- ->willReturn($this->resourceMock);
- $model->expects($this->any())
- ->method('_getCurrentDateTime')
- ->willReturn('2012-12-21T00:00:00-08:00');
- $model->expects($this->any())
- ->method('_getDocumentRoot')
- ->willReturn('/project');
- $model->setSitemapFilename('sitemap.xml');
- $model->setStoreId(1);
- $model->setSitemapPath('/');
- return $model;
- }
- /**
- * @return array
- */
- private function getModelConstructorArgs()
- {
- $categoryFactory = $this->getMockBuilder(CategoryFactory::class)
- ->disableOriginalConstructor()
- ->getMock();
- $productFactory = $this->getMockBuilder(ProductFactory::class)
- ->disableOriginalConstructor()
- ->getMock();
- $cmsFactory = $this->getMockBuilder(PageFactory::class)
- ->disableOriginalConstructor()
- ->getMock();
- $this->storeManagerMock = $this->getMockBuilder(StoreManagerInterface::class)
- ->setMethods(['getStore'])
- ->getMockForAbstractClass();
- $objectManager = new ObjectManager($this);
- $constructArguments = $objectManager->getConstructArguments(
- Sitemap::class,
- [
- 'categoryFactory' => $categoryFactory,
- 'productFactory' => $productFactory,
- 'cmsFactory' => $cmsFactory,
- 'storeManager' => $this->storeManagerMock,
- 'sitemapData' => $this->helperMockSitemap,
- 'filesystem' => $this->filesystemMock,
- 'itemProvider' => $this->itemProviderMock,
- 'configReader' => $this->configReaderMock,
- ]
- );
- $constructArguments['resource'] = null;
- return $constructArguments;
- }
- /**
- * Check site URL getter
- *
- * @param string $storeBaseUrl
- * @param string $documentRoot
- * @param string $baseDir
- * @param string $sitemapPath
- * @param string $sitemapFileName
- * @param string $result
- * @dataProvider siteUrlDataProvider
- */
- public function testGetSitemapUrl($storeBaseUrl, $documentRoot, $baseDir, $sitemapPath, $sitemapFileName, $result)
- {
- /** @var $model Sitemap */
- $model = $this->getMockBuilder(Sitemap::class)
- ->setMethods(
- [
- '_getStoreBaseUrl',
- '_getDocumentRoot',
- '_getBaseDir',
- '_construct',
- ]
- )
- ->setConstructorArgs($this->getModelConstructorArgs())
- ->getMock();
- $model->expects($this->any())
- ->method('_getStoreBaseUrl')
- ->willReturn($storeBaseUrl);
- $model->expects($this->any())
- ->method('_getDocumentRoot')
- ->willReturn($documentRoot);
- $model->expects($this->any())
- ->method('_getBaseDir')
- ->willReturn($baseDir);
- $this->assertEquals($result, $model->getSitemapUrl($sitemapPath, $sitemapFileName));
- }
- /**
- * Data provider for Check site URL getter
- *
- * @static
- * @return array
- */
- public static function siteUrlDataProvider()
- {
- return [
- [
- 'http://store.com',
- 'c:\\http\\mage2\\',
- 'c:\\http\\mage2\\',
- '/',
- 'sitemap.xml',
- 'http://store.com/sitemap.xml',
- ],
- [
- 'http://store.com/store2',
- 'c:\\http\\mage2\\',
- 'c:\\http\\mage2\\',
- '/sitemaps/store2',
- 'sitemap.xml',
- 'http://store.com/sitemaps/store2/sitemap.xml'
- ],
- [
- 'http://store.com/builds/regression/ee/',
- '/var/www/html',
- '/opt/builds/regression/ee',
- '/',
- 'sitemap.xml',
- 'http://store.com/builds/regression/ee/sitemap.xml'
- ],
- [
- 'http://store.com/store2',
- 'c:\\http\\mage2\\',
- 'c:\\http\\mage2\\store2',
- '/sitemaps/store2',
- 'sitemap.xml',
- 'http://store.com/store2/sitemaps/store2/sitemap.xml'
- ],
- [
- 'http://store2.store.com',
- 'c:\\http\\mage2\\',
- 'c:\\http\\mage2\\',
- '/sitemaps/store2',
- 'sitemap.xml',
- 'http://store2.store.com/sitemaps/store2/sitemap.xml'
- ],
- [
- 'http://store.com',
- '/var/www/store/',
- '/var/www/store/',
- '/',
- 'sitemap.xml',
- 'http://store.com/sitemap.xml'
- ],
- [
- 'http://store.com/store2',
- '/var/www/store/',
- '/var/www/store/store2/',
- '/sitemaps/store2',
- 'sitemap.xml',
- 'http://store.com/store2/sitemaps/store2/sitemap.xml'
- ]
- ];
- }
- }
|