MergedTest.php 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Framework\View\Test\Unit\Asset;
  7. use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
  8. use Magento\Framework\View\Asset\File;
  9. use Magento\Framework\View\Asset\Merged;
  10. use Psr\Log\LoggerInterface;
  11. use Magento\Framework\View\Asset\Repository as AssetRepository;
  12. use Magento\Framework\View\Asset\MergeableInterface;
  13. use Magento\Framework\View\Asset\MergeStrategyInterface;
  14. use Magento\Framework\App\View\Deployment\Version\StorageInterface;
  15. /**
  16. * Class MergedTest
  17. */
  18. class MergedTest extends \PHPUnit\Framework\TestCase
  19. {
  20. /**
  21. * @var LoggerInterface|\PHPUnit_Framework_MockObject_MockObject
  22. */
  23. private $logger;
  24. /**
  25. * @var MergeStrategyInterface|\PHPUnit_Framework_MockObject_MockObject
  26. */
  27. private $mergeStrategy;
  28. /**
  29. * @var MergeableInterface|\PHPUnit_Framework_MockObject_MockObject
  30. */
  31. private $assetJsOne;
  32. /**
  33. * @var MergeableInterface|\PHPUnit_Framework_MockObject_MockObject
  34. */
  35. private $assetJsTwo;
  36. /**
  37. * @var AssetRepository|\PHPUnit_Framework_MockObject_MockObject
  38. */
  39. private $assetRepo;
  40. /**
  41. * @var StorageInterface|\PHPUnit_Framework_MockObject_MockObject
  42. */
  43. private $versionStorage;
  44. protected function setUp()
  45. {
  46. $this->assetJsOne = $this->getMockForAbstractClass(MergeableInterface::class);
  47. $this->assetJsOne->expects($this->any())
  48. ->method('getContentType')
  49. ->willReturn('js');
  50. $this->assetJsOne->expects($this->any())
  51. ->method('getPath')
  52. ->willReturn('script_one.js');
  53. $this->assetJsTwo = $this->getMockForAbstractClass(MergeableInterface::class);
  54. $this->assetJsTwo->expects($this->any())
  55. ->method('getContentType')
  56. ->willReturn('js');
  57. $this->assetJsTwo->expects($this->any())
  58. ->method('getPath')
  59. ->willReturn('script_two.js');
  60. $this->logger = $this->createMock(LoggerInterface::class);
  61. $this->mergeStrategy = $this->createMock(MergeStrategyInterface::class);
  62. $this->assetRepo = $this->getMockBuilder(AssetRepository::class)
  63. ->disableOriginalConstructor()
  64. ->getMock();
  65. $this->versionStorage = $this->createMock(StorageInterface::class);
  66. }
  67. /**
  68. * @expectedException \InvalidArgumentException
  69. * @expectedExceptionMessage At least one asset has to be passed for merging.
  70. */
  71. public function testConstructorNothingToMerge()
  72. {
  73. new \Magento\Framework\View\Asset\Merged(
  74. $this->logger,
  75. $this->mergeStrategy,
  76. $this->assetRepo,
  77. [],
  78. $this->versionStorage
  79. );
  80. }
  81. /**
  82. * @expectedException \InvalidArgumentException
  83. * @expectedExceptionMessage Asset has to implement \Magento\Framework\View\Asset\MergeableInterface.
  84. */
  85. public function testConstructorRequireMergeInterface()
  86. {
  87. $assetUrl = new \Magento\Framework\View\Asset\Remote('http://example.com/style.css', 'css');
  88. (new ObjectManager($this))->getObject(Merged::class, [
  89. 'logger' => $this->logger,
  90. 'mergeStrategy' => $this->mergeStrategy,
  91. 'assetRepo' => $this->assetRepo,
  92. 'assets' => [$this->assetJsOne, $assetUrl],
  93. 'versionStorage' => $this->versionStorage,
  94. ]);
  95. }
  96. /**
  97. * @expectedException \InvalidArgumentException
  98. * @expectedExceptionMessage Content type 'css' cannot be merged with 'js'.
  99. */
  100. public function testConstructorIncompatibleContentTypes()
  101. {
  102. $assetCss = $this->getMockForAbstractClass(MergeableInterface::class);
  103. $assetCss->expects($this->any())
  104. ->method('getContentType')
  105. ->willReturn('css');
  106. (new ObjectManager($this))->getObject(Merged::class, [
  107. 'logger' => $this->logger,
  108. 'mergeStrategy' => $this->mergeStrategy,
  109. 'assetRepo' => $this->assetRepo,
  110. 'assets' => [$this->assetJsOne, $assetCss],
  111. 'versionStorage' => $this->versionStorage,
  112. ]);
  113. }
  114. public function testIteratorInterfaceMerge()
  115. {
  116. $assets = [$this->assetJsOne, $this->assetJsTwo];
  117. $this->logger->expects($this->never())->method('critical');
  118. /** @var Merged $merged */
  119. $merged = (new ObjectManager($this))->getObject(Merged::class, [
  120. 'logger' => $this->logger,
  121. 'mergeStrategy' => $this->mergeStrategy,
  122. 'assetRepo' => $this->assetRepo,
  123. 'assets' => $assets,
  124. 'versionStorage' => $this->versionStorage,
  125. ]);
  126. $mergedAsset = $this->createMock(\Magento\Framework\View\Asset\File::class);
  127. $this->mergeStrategy
  128. ->expects($this->once())
  129. ->method('merge')
  130. ->with($assets, $mergedAsset)
  131. ->willReturn(null);
  132. $this->assetRepo->expects($this->once())
  133. ->method('createArbitrary')
  134. ->willReturn($mergedAsset);
  135. $expectedResult = [$mergedAsset];
  136. $this->assertIteratorEquals($expectedResult, $merged);
  137. $this->assertIteratorEquals($expectedResult, $merged); // ensure merging happens only once
  138. }
  139. public function testIteratorInterfaceMergeFailure()
  140. {
  141. $mergeError = new \Exception('File not found');
  142. $assetBroken = $this->getMockForAbstractClass(MergeableInterface::class);
  143. $assetBroken->expects($this->any())
  144. ->method('getContentType')
  145. ->willReturn('js');
  146. $assetBroken->expects($this->any())
  147. ->method('getPath')
  148. ->willThrowException($mergeError);
  149. /** @var Merged $merged */
  150. $merged = (new ObjectManager($this))->getObject(Merged::class, [
  151. 'logger' => $this->logger,
  152. 'mergeStrategy' => $this->mergeStrategy,
  153. 'assetRepo' => $this->assetRepo,
  154. 'assets' => [$this->assetJsOne, $this->assetJsTwo, $assetBroken],
  155. 'versionStorage' => $this->versionStorage,
  156. ]);
  157. $this->logger->expects($this->once())->method('critical')->with($this->identicalTo($mergeError));
  158. $expectedResult = [$this->assetJsOne, $this->assetJsTwo, $assetBroken];
  159. $this->assertIteratorEquals($expectedResult, $merged);
  160. $this->assertIteratorEquals($expectedResult, $merged); // ensure merging attempt happens only once
  161. }
  162. /**
  163. * Assert that iterator items equal to expected ones
  164. *
  165. * @param array $expectedItems
  166. * @param \Iterator $actual
  167. */
  168. protected function assertIteratorEquals(array $expectedItems, \Iterator $actual)
  169. {
  170. $actualItems = [];
  171. foreach ($actual as $actualItem) {
  172. $actualItems[] = $actualItem;
  173. }
  174. $this->assertEquals($expectedItems, $actualItems);
  175. }
  176. }