AbstractConfigFiles.php 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. <?php
  2. /**
  3. * Abstract class that helps in writing tests that validate config xml files
  4. * are valid both individually and when merged.
  5. *
  6. * Copyright © Magento, Inc. All rights reserved.
  7. * See COPYING.txt for license details.
  8. */
  9. namespace Magento\TestFramework\TestCase;
  10. use Magento\Framework\Component\ComponentRegistrar;
  11. abstract class AbstractConfigFiles extends \PHPUnit\Framework\TestCase
  12. {
  13. /**
  14. * @var string
  15. */
  16. protected $_schemaFile;
  17. /**
  18. * @var \Magento\Framework\Config\Reader\Filesystem
  19. */
  20. protected $_reader;
  21. /**
  22. * @var \PHPUnit_Framework_MockObject_MockObject
  23. */
  24. protected $_fileResolverMock;
  25. /**
  26. * @var \Magento\TestFramework\ObjectManager
  27. */
  28. protected $_objectManager;
  29. /**
  30. * @var ComponentRegistrar
  31. */
  32. protected $componentRegistrar;
  33. public function setUp()
  34. {
  35. $this->componentRegistrar = new ComponentRegistrar();
  36. $this->_objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
  37. $xmlFiles = $this->getXmlConfigFiles();
  38. if (!empty($xmlFiles)) {
  39. $this->_fileResolverMock = $this->getMockBuilder(
  40. \Magento\Framework\App\Arguments\FileResolver\Primary::class
  41. )->disableOriginalConstructor()->getMock();
  42. /* Enable Validation regardless of MAGE_MODE */
  43. $validateStateMock = $this->getMockBuilder(
  44. \Magento\Framework\Config\ValidationStateInterface::class
  45. )->disableOriginalConstructor()->getMock();
  46. $validateStateMock->expects($this->any())->method('isValidationRequired')->will($this->returnValue(true));
  47. $this->_reader = $this->_objectManager->create(
  48. $this->_getReaderClassName(),
  49. [
  50. 'configFiles' => $xmlFiles,
  51. 'fileResolver' => $this->_fileResolverMock,
  52. 'validationState' => $validateStateMock
  53. ]
  54. );
  55. $this->_schemaFile = $this->_getXsdPath();
  56. }
  57. }
  58. protected function tearDown()
  59. {
  60. $this->_objectManager->removeSharedInstance($this->_getReaderClassName());
  61. }
  62. /**
  63. * @dataProvider xmlConfigFileProvider
  64. */
  65. public function testXmlConfigFile($file, $skip = false)
  66. {
  67. if ($skip) {
  68. $this->markTestSkipped('There are no xml files in the system for this test.');
  69. }
  70. $validationStateMock = $this->createMock(\Magento\Framework\Config\ValidationStateInterface::class);
  71. $validationStateMock->method('isValidationRequired')
  72. ->willReturn(false);
  73. $domConfig = new \Magento\Framework\Config\Dom($file, $validationStateMock);
  74. $errors = [];
  75. $result = $domConfig->validate($this->_schemaFile, $errors);
  76. $message = "Invalid XML-file: {$file}\n";
  77. foreach ($errors as $error) {
  78. $message .= "{$error}\n";
  79. }
  80. $this->assertTrue($result, $message);
  81. }
  82. public function testMergedConfig()
  83. {
  84. $files = $this->getXmlConfigFiles();
  85. if (empty($files)) {
  86. $this->markTestSkipped('There are no xml files in the system for this test.');
  87. }
  88. // have the file resolver return all relevant xml files
  89. $this->_fileResolverMock->expects($this->any())
  90. ->method('get')
  91. ->will($this->returnValue($this->getXmlConfigFiles()));
  92. try {
  93. // this will merge all xml files and validate them
  94. $this->_reader->read('global');
  95. } catch (\Magento\Framework\Exception\LocalizedException $e) {
  96. $this->fail($e->getMessage());
  97. }
  98. }
  99. /**
  100. * Returns an array of all the config xml files for this test.
  101. *
  102. * Handles the case where no files were found and notifies the test to skip.
  103. * This is needed to avoid a fatal error caused by a provider returning an empty array.
  104. *
  105. * @return array
  106. */
  107. public function xmlConfigFileProvider()
  108. {
  109. $fileList = $this->getXmlConfigFiles();
  110. $result = [];
  111. foreach ($fileList as $fileContent) {
  112. $result[] = [$fileContent];
  113. }
  114. return $result;
  115. }
  116. /**
  117. * Finds all config xml files based on a path glob.
  118. *
  119. * @return \Magento\Framework\Config\FileIterator
  120. */
  121. public function getXmlConfigFiles()
  122. {
  123. $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
  124. /** @var $moduleDirSearch \Magento\Framework\Component\DirSearch */
  125. $moduleDirSearch = $objectManager->get(\Magento\Framework\Component\DirSearch::class);
  126. return $objectManager->get(\Magento\Framework\Config\FileIteratorFactory::class)
  127. ->create($moduleDirSearch->collectFiles(ComponentRegistrar::MODULE, $this->_getConfigFilePathGlob()));
  128. }
  129. /**
  130. * Returns the reader class name that will be instantiated via ObjectManager
  131. *
  132. * @return string reader class name
  133. */
  134. abstract protected function _getReaderClassName();
  135. /**
  136. * Returns a string that represents the path to the config file, starting in the app directory.
  137. *
  138. * Format is glob, so * is allowed.
  139. *
  140. * @return string
  141. */
  142. abstract protected function _getConfigFilePathGlob();
  143. /**
  144. * Returns an absolute path to the XSD file corresponding to the XML files specified in _getConfigFilePathGlob
  145. *
  146. * @return string
  147. */
  148. abstract protected function _getXsdPath();
  149. }