TemplateFilesTest.php 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Test\Integrity\Theme;
  7. class TemplateFilesTest extends \Magento\TestFramework\TestCase\AbstractIntegrity
  8. {
  9. /**
  10. * Note that data provider is not used in conventional way in order to not overwhelm test statistics
  11. */
  12. public function testTemplates()
  13. {
  14. $invalidTemplates = [];
  15. foreach ($this->templatesDataProvider() as $template) {
  16. list($area, $themeId, $module, $file, $xml) = $template;
  17. $params = ['area' => $area, 'themeId' => $themeId, 'module' => $module];
  18. try {
  19. $templateFilename = \Magento\TestFramework\Helper\Bootstrap::getObjectmanager()
  20. ->get(\Magento\Framework\View\FileSystem::class)
  21. ->getTemplateFileName($file, $params);
  22. $this->assertFileExists($templateFilename);
  23. } catch (\PHPUnit\Framework\ExpectationFailedException $e) {
  24. $invalidTemplates[] = "File \"{$templateFilename}\" does not exist." .
  25. PHP_EOL .
  26. "Parameters: {$area}/{$themeId} {$module}::{$file}" .
  27. PHP_EOL .
  28. 'Layout update: ' .
  29. $xml;
  30. }
  31. }
  32. $this->assertEmpty(
  33. $invalidTemplates,
  34. "Invalid templates found:\n\n" . implode("\n-----\n", $invalidTemplates)
  35. );
  36. }
  37. public function templatesDataProvider()
  38. {
  39. $templates = [];
  40. $themes = $this->_getDesignThemes();
  41. foreach ($themes as $theme) {
  42. /** @var \Magento\Framework\View\Layout\ProcessorInterface $layoutUpdate */
  43. $layoutUpdate = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
  44. \Magento\Framework\View\Layout\ProcessorInterface::class,
  45. ['theme' => $theme]
  46. );
  47. $layoutTemplates = $this->_getLayoutTemplates($layoutUpdate->getFileLayoutUpdatesXml());
  48. foreach ($layoutTemplates as $templateData) {
  49. $templates[] = array_merge([$theme->getArea(), $theme->getId()], $templateData);
  50. }
  51. }
  52. return $templates;
  53. }
  54. /**
  55. * Get templates list that are defined in layout
  56. *
  57. * @param \SimpleXMLElement $layoutXml
  58. * @return array
  59. * @SuppressWarnings(PHPMD.CyclomaticComplexity)
  60. */
  61. protected function _getLayoutTemplates($layoutXml)
  62. {
  63. $templates = [];
  64. $blocks = $layoutXml->xpath('//block');
  65. foreach ($blocks as $block) {
  66. $attributes = $block->attributes();
  67. if (isset($attributes['template'])) {
  68. $module = $this->_getBlockModule($block);
  69. if (!$this->_isTemplateForDisabledModule($module, (string)$attributes['template'])) {
  70. $templates[] = [$module, (string)$attributes['template'], $block->asXML()];
  71. }
  72. }
  73. }
  74. $layoutTemplates = $layoutXml->xpath('//template');
  75. foreach ($layoutTemplates as $template) {
  76. $action = $template->xpath("parent::*");
  77. $attributes = $action[0]->attributes();
  78. switch ($attributes['method']) {
  79. case 'setTemplate':
  80. $parent = $action[0]->xpath("parent::*");
  81. $attributes = $parent[0]->attributes();
  82. $referenceName = (string)$attributes['name'];
  83. $block = $layoutXml->xpath(
  84. "//block[@name='{$referenceName}'] | //referenceBlock[@name='{$referenceName}']"
  85. );
  86. $module = $this->_getBlockModule($block[0]);
  87. if (!$template->attributes() && !$this->_isTemplateForDisabledModule($module, (string)$template)) {
  88. $templates[] = [$module, (string)$template, $parent[0]->asXml()];
  89. }
  90. break;
  91. case 'addInformationRenderer':
  92. case 'addMergeSettingsBlockType':
  93. $blockType = $action[0]->xpath('block');
  94. $module = $this->_getBlockModule($blockType[0]);
  95. if (!$this->_isTemplateForDisabledModule($module, (string)$template)) {
  96. $templates[] = [$module, (string)$template, $action[0]->asXml()];
  97. }
  98. break;
  99. default:
  100. break;
  101. }
  102. }
  103. return $templates;
  104. }
  105. /**
  106. * Get module name based on block definition in xml layout
  107. *
  108. * @param \SimpleXMLElement $xmlNode
  109. * @return string
  110. */
  111. protected function _getBlockModule($xmlNode)
  112. {
  113. $attributes = $xmlNode->attributes();
  114. if (isset($attributes['type'])) {
  115. $class = (string)$attributes['type'];
  116. } else {
  117. $class = (string)$xmlNode;
  118. }
  119. $blockModule = substr($class, 0, strpos($class, '_Block'));
  120. return $blockModule;
  121. }
  122. /**
  123. * Returns whether template belongs to a disabled module
  124. *
  125. * @param string $blockModule Module of a block that will render this template
  126. * @param string $template
  127. * @return bool
  128. */
  129. protected function _isTemplateForDisabledModule($blockModule, $template)
  130. {
  131. $enabledModules = $this->_getEnabledModules();
  132. if (!isset($enabledModules[$blockModule])) {
  133. return true;
  134. }
  135. return $this->_isFileForDisabledModule($template);
  136. }
  137. }