ConfigTest.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339
  1. <?php
  2. /**
  3. * Unit Test for \Magento\Framework\Validator\Config
  4. *
  5. * Copyright © Magento, Inc. All rights reserved.
  6. * See COPYING.txt for license details.
  7. */
  8. namespace Magento\Framework\Validator\Test\Unit;
  9. /**
  10. * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  11. */
  12. class ConfigTest extends \PHPUnit\Framework\TestCase
  13. {
  14. /**
  15. * @var \Magento\Framework\Validator\Config
  16. */
  17. protected $_config;
  18. /**
  19. * @var \Magento\Framework\TestFramework\Unit\Helper\ObjectManager
  20. */
  21. protected $_objectManager;
  22. /** @var \Magento\Framework\Config\Dom\UrnResolver */
  23. protected $urnResolver;
  24. protected function setUp()
  25. {
  26. if (!function_exists('libxml_set_external_entity_loader')) {
  27. $this->markTestSkipped('Skipped on HHVM. Will be fixed in MAGETWO-45033');
  28. }
  29. $this->_objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
  30. $this->urnResolver = new \Magento\Framework\Config\Dom\UrnResolver();
  31. }
  32. /**
  33. * @expectedException \InvalidArgumentException
  34. * @expectedExceptionMessage There must be at least one configuration file specified.
  35. */
  36. public function testConstructException()
  37. {
  38. $this->_initConfig([]);
  39. }
  40. /**
  41. * Inits $_serviceConfig property with specific files or default valid configuration files
  42. *
  43. * @param array|null $files
  44. */
  45. protected function _initConfig(array $files = null)
  46. {
  47. if (null === $files) {
  48. $files = glob(__DIR__ . '/_files/validation/positive/*/validation.xml', GLOB_NOSORT);
  49. }
  50. $configFiles = [];
  51. foreach ($files as $path) {
  52. $configFiles[$path] = file_get_contents($path);
  53. }
  54. $config = new \Magento\Framework\ObjectManager\Config\Config(
  55. new \Magento\Framework\ObjectManager\Relations\Runtime()
  56. );
  57. $factory = new \Magento\Framework\ObjectManager\Factory\Dynamic\Developer($config);
  58. $appObjectManager = new \Magento\Framework\ObjectManager\ObjectManager($factory, $config);
  59. $factory->setObjectManager($appObjectManager);
  60. /** @var \Magento\Framework\Validator\UniversalFactory $universalFactory */
  61. $universalFactory = $appObjectManager->get(\Magento\Framework\Validator\UniversalFactory::class);
  62. /** @var \Magento\Framework\Config\Dom\UrnResolver $urnResolverMock */
  63. $urnResolverMock = $this->createMock(\Magento\Framework\Config\Dom\UrnResolver::class);
  64. $urnResolverMock->expects($this->any())
  65. ->method('getRealPath')
  66. ->with('urn:magento:framework:Validator/etc/validation.xsd')
  67. ->willReturn($this->urnResolver->getRealPath('urn:magento:framework:Validator/etc/validation.xsd'));
  68. $appObjectManager->configure(
  69. [
  70. 'preferences' => [
  71. \Magento\Framework\Config\ValidationStateInterface::class =>
  72. \Magento\Framework\App\Arguments\ValidationState::class,
  73. ],
  74. \Magento\Framework\App\Arguments\ValidationState::class => [
  75. 'arguments' => [
  76. 'appMode' => 'developer',
  77. ]
  78. ]
  79. ]
  80. );
  81. $this->_config = $this->_objectManager->getObject(
  82. \Magento\Framework\Validator\Config::class,
  83. [
  84. 'configFiles' => $configFiles,
  85. 'builderFactory' => $universalFactory,
  86. 'domFactory' => new \Magento\Framework\Config\DomFactory($appObjectManager),
  87. 'urnResolver' => $urnResolverMock
  88. ]
  89. );
  90. }
  91. /**
  92. * @expectedException \InvalidArgumentException
  93. * @expectedExceptionMessage Unknown validation entity "invalid_entity"
  94. */
  95. public function testCreateValidatorInvalidEntityName()
  96. {
  97. $this->_initConfig();
  98. $this->_config->createValidatorBuilder('invalid_entity', null);
  99. }
  100. /**
  101. * @expectedException \InvalidArgumentException
  102. * @expectedExceptionMessage Unknown validation group "invalid_group" in entity "test_entity_a"
  103. */
  104. public function testCreateValidatorInvalidGroupName()
  105. {
  106. $this->_initConfig();
  107. $this->_config->createValidatorBuilder('test_entity_a', 'invalid_group');
  108. }
  109. public function testCreateValidatorInvalidConstraintClass()
  110. {
  111. $this->expectException('InvalidArgumentException');
  112. $this->expectExceptionMessage(
  113. 'Constraint class "stdClass" must implement \Magento\Framework\Validator\ValidatorInterface'
  114. );
  115. $this->_initConfig([__DIR__ . '/_files/validation/negative/invalid_constraint.xml']);
  116. $this->_config->createValidator('test_entity', 'test_group');
  117. }
  118. /**
  119. * @expectedException \InvalidArgumentException
  120. * @expectedExceptionMessage Builder class "UnknownBuilderClass" was not found
  121. */
  122. public function testGetValidatorBuilderClassNotFound()
  123. {
  124. $this->_initConfig([__DIR__ . '/_files/validation/negative/invalid_builder_class.xml']);
  125. $this->_config->createValidatorBuilder('catalog_product', 'create');
  126. }
  127. /**
  128. * @expectedException \InvalidArgumentException
  129. * @expectedExceptionMessage Builder "stdClass" must extend \Magento\Framework\Validator\Builder
  130. */
  131. public function testGetValidatorBuilderInstanceInvalid()
  132. {
  133. $this->_initConfig([__DIR__ . '/_files/validation/negative/invalid_builder_instance.xml']);
  134. $this->_config->createValidatorBuilder('catalog_product', 'create');
  135. }
  136. /**
  137. * Test for getValidatorBuilder
  138. */
  139. public function testGetValidatorBuilderInstance()
  140. {
  141. $this->_initConfig();
  142. $builder = $this->_config->createValidatorBuilder('test_entity_a', 'check_alnum');
  143. $this->assertInstanceOf(\Magento\Framework\Validator\Builder::class, $builder);
  144. }
  145. /**
  146. * @dataProvider getValidationRulesDataProvider
  147. *
  148. * @param string $entityName
  149. * @param string $groupName
  150. * @param mixed $value
  151. * @param bool $expectedResult
  152. * @param array $expectedMessages
  153. */
  154. public function testCreateValidator($entityName, $groupName, $value, $expectedResult, $expectedMessages)
  155. {
  156. $this->_initConfig();
  157. $validator = $this->_config->createValidator($entityName, $groupName);
  158. $actualResult = $validator->isValid($value);
  159. $this->assertEquals($expectedMessages, $validator->getMessages());
  160. $this->assertEquals($expectedResult, $actualResult);
  161. }
  162. /**
  163. * Data provider for testCreateConfigForInvalidXml
  164. *
  165. * @return array
  166. */
  167. public function getValidationRulesDataProvider()
  168. {
  169. $result = [];
  170. // Case 1. Pass check alnum and int properties are not empty and have valid value
  171. $entityName = 'test_entity_a';
  172. $groupName = 'check_alnum_and_int_not_empty_and_have_valid_value';
  173. $value = new \Magento\Framework\DataObject(['int' => 1, 'alnum' => 'abc123']);
  174. $expectedResult = true;
  175. $expectedMessages = [];
  176. $result[] = [$entityName, $groupName, $value, $expectedResult, $expectedMessages];
  177. // Case 2. Fail check alnum is not empty
  178. $value = new \Magento\Framework\DataObject(['int' => 'abc123', 'alnum' => null]);
  179. $expectedResult = false;
  180. $expectedMessages = [
  181. 'alnum' => [
  182. 'isEmpty' => 'Value is required and can\'t be empty',
  183. 'alnumInvalid' => 'Invalid type given. String, integer or float expected',
  184. ],
  185. 'int' => ['notInt' => '\'abc123\' does not appear to be an integer'],
  186. ];
  187. $result[] = [$entityName, $groupName, $value, $expectedResult, $expectedMessages];
  188. // Case 3. Pass check alnum has valid value
  189. $groupName = 'check_alnum';
  190. $value = new \Magento\Framework\DataObject(['int' => 'abc123', 'alnum' => 'abc123']);
  191. $expectedResult = true;
  192. $expectedMessages = [];
  193. $result[] = [$entityName, $groupName, $value, $expectedResult, $expectedMessages];
  194. // Case 4. Fail check alnum has valid value
  195. $value = new \Magento\Framework\DataObject(['int' => 'abc123', 'alnum' => '[abc123]']);
  196. $expectedResult = false;
  197. $expectedMessages = [
  198. 'alnum' => ['notAlnum' => '\'[abc123]\' contains characters which are non alphabetic and no digits'],
  199. ];
  200. $result[] = [$entityName, $groupName, $value, $expectedResult, $expectedMessages];
  201. return $result;
  202. }
  203. /**
  204. * Check builder configuration format
  205. */
  206. public function testBuilderConfiguration()
  207. {
  208. $this->getMockBuilder(\Magento\Framework\Validator\Builder::class)->disableOriginalConstructor()->getMock();
  209. $this->_initConfig([__DIR__ . '/_files/validation/positive/builder/validation.xml']);
  210. $builder = $this->_config->createValidatorBuilder('test_entity_a', 'check_builder');
  211. $this->assertInstanceOf(\Magento\Framework\Validator\Builder::class, $builder);
  212. $expected = [
  213. [
  214. 'alias' => '',
  215. 'class' => \Magento\Framework\Validator\Test\Unit\Test\NotEmpty::class,
  216. 'options' => null,
  217. 'property' => 'int',
  218. 'type' => 'property',
  219. ],
  220. [
  221. 'alias' => 'stub',
  222. 'class' => 'Validator_Stub',
  223. 'options' => [
  224. 'arguments' => [
  225. new \Magento\Framework\Validator\Constraint\Option('test_string_argument'),
  226. new \Magento\Framework\Validator\Constraint\Option(
  227. ['option1' => 'value1', 'option2' => 'value2']
  228. ),
  229. new \Magento\Framework\Validator\Constraint\Option\Callback(
  230. [\Magento\Framework\Validator\Test\Unit\Test\Callback::class, 'getId'],
  231. null,
  232. true
  233. ),
  234. ],
  235. 'callback' => [
  236. new \Magento\Framework\Validator\Constraint\Option\Callback(
  237. [\Magento\Framework\Validator\Test\Unit\Test\Callback::class, 'configureValidator'],
  238. null,
  239. true
  240. ),
  241. ],
  242. 'methods' => [
  243. 'setOptionThree' => [
  244. 'method' => 'setOptionThree',
  245. 'arguments' => [
  246. new \Magento\Framework\Validator\Constraint\Option(
  247. ['argOption' => 'argOptionValue']
  248. ),
  249. new \Magento\Framework\Validator\Constraint\Option\Callback(
  250. [\Magento\Framework\Validator\Test\Unit\Test\Callback::class, 'getId'],
  251. null,
  252. true
  253. ),
  254. new \Magento\Framework\Validator\Constraint\Option('10'),
  255. ],
  256. ],
  257. 'enableOptionFour' => ['method' => 'enableOptionFour'],
  258. ],
  259. ],
  260. 'property' => 'int',
  261. 'type' => 'property'
  262. ],
  263. ];
  264. $this->assertAttributeEquals($expected, '_constraints', $builder);
  265. }
  266. /**
  267. * Check XSD schema validates invalid config files
  268. *
  269. * @dataProvider getInvalidXmlFiles
  270. * @expectedException \Magento\Framework\Exception\LocalizedException
  271. *
  272. * @param array|string $configFile
  273. */
  274. public function testValidateInvalidConfigFiles($configFile)
  275. {
  276. $this->_initConfig((array)$configFile);
  277. }
  278. /**
  279. * Data provider for testValidateInvalidConfigFiles
  280. *
  281. * @return array
  282. */
  283. public function getInvalidXmlFiles()
  284. {
  285. // TODO: add case There are no "entity_constraints" and "property_constraints" elements inside "rule" element
  286. return [
  287. [__DIR__ . '/_files/validation/negative/no_constraint.xml'],
  288. [__DIR__ . '/_files/validation/negative/not_unique_use.xml'],
  289. [__DIR__ . '/_files/validation/negative/no_rule_for_reference.xml'],
  290. [__DIR__ . '/_files/validation/negative/no_name_for_entity.xml'],
  291. [__DIR__ . '/_files/validation/negative/no_name_for_rule.xml'],
  292. [__DIR__ . '/_files/validation/negative/no_name_for_group.xml'],
  293. [__DIR__ . '/_files/validation/negative/no_class_for_constraint.xml'],
  294. [__DIR__ . '/_files/validation/negative/invalid_method.xml'],
  295. [__DIR__ . '/_files/validation/negative/invalid_method_callback.xml'],
  296. [__DIR__ . '/_files/validation/negative/invalid_entity_callback.xml'],
  297. [__DIR__ . '/_files/validation/negative/invalid_child_for_option.xml'],
  298. [__DIR__ . '/_files/validation/negative/invalid_content_for_callback.xml'],
  299. [__DIR__ . '/_files/validation/negative/multiple_callback_in_argument.xml']
  300. ];
  301. }
  302. /**
  303. * Test schema file exists
  304. */
  305. public function testGetSchemaFile()
  306. {
  307. $this->_initConfig();
  308. $this->assertEquals(
  309. $this->urnResolver->getRealPath('urn:magento:framework:Validator/etc/validation.xsd'),
  310. $this->_config->getSchemaFile()
  311. );
  312. $this->assertFileExists($this->_config->getSchemaFile());
  313. }
  314. }