MigrationTest.php 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. /**
  7. * Tests for resource setup model needed for migration process between Magento versions
  8. */
  9. namespace Magento\Framework\Module\Test\Unit\Setup;
  10. class MigrationTest extends \PHPUnit\Framework\TestCase
  11. {
  12. /**
  13. * Result of update class aliases to compare with expected.
  14. * Used in callback for \Magento\Framework\DB\Select::update.
  15. *
  16. * @var array
  17. */
  18. protected $_actualUpdateResult;
  19. /**
  20. * Where conditions to compare with expected.
  21. * Used in callback for \Magento\Framework\DB\Select::where.
  22. *
  23. * @var array
  24. */
  25. protected $_actualWhere;
  26. /**
  27. * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\DB\Select
  28. */
  29. protected $_selectMock;
  30. protected function tearDown()
  31. {
  32. unset($this->_actualUpdateResult);
  33. unset($this->_actualWhere);
  34. unset($this->_selectMock);
  35. }
  36. /**
  37. * Retrieve all necessary objects mocks which used inside customer storage
  38. *
  39. * @param int $tableRowsCount
  40. * @param array $tableData
  41. * @param array $aliasesMap
  42. *
  43. * @return array
  44. */
  45. protected function _getModelDependencies($tableRowsCount = 0, $tableData = [], $aliasesMap = [])
  46. {
  47. $this->_selectMock = $this->createMock(\Magento\Framework\DB\Select::class);
  48. $this->_selectMock->expects($this->any())->method('from')->will($this->returnSelf());
  49. $this->_selectMock->expects(
  50. $this->any()
  51. )->method(
  52. 'where'
  53. )->will(
  54. $this->returnCallback([$this, 'whereCallback'])
  55. );
  56. $connectionMock = $this->createPartialMock(
  57. \Magento\Framework\DB\Adapter\Pdo\Mysql::class,
  58. ['select', 'update', 'fetchAll', 'fetchOne']
  59. );
  60. $connectionMock->expects($this->any())->method('select')->will($this->returnValue($this->_selectMock));
  61. $connectionMock->expects(
  62. $this->any()
  63. )->method(
  64. 'update'
  65. )->will(
  66. $this->returnCallback([$this, 'updateCallback'])
  67. );
  68. $connectionMock->expects($this->any())->method('fetchAll')->will($this->returnValue($tableData));
  69. $connectionMock->expects($this->any())->method('fetchOne')->will($this->returnValue($tableRowsCount));
  70. return [
  71. 'resource_config' => 'not_used',
  72. 'connection_config' => 'not_used',
  73. 'module_config' => 'not_used',
  74. 'base_dir' => 'not_used',
  75. 'path_to_map_file' => 'not_used',
  76. 'connection' => $connectionMock,
  77. 'core_helper' => $this->createMock(\Magento\Framework\Json\Helper\Data::class),
  78. 'aliases_map' => $aliasesMap
  79. ];
  80. }
  81. /**
  82. * Callback for \Magento\Framework\DB\Select::update
  83. *
  84. * @param string $table
  85. * @param array $bind
  86. * @param array $where
  87. */
  88. public function updateCallback($table, array $bind, $where)
  89. {
  90. $fields = array_keys($bind);
  91. $replacements = array_values($bind);
  92. $this->_actualUpdateResult[] = [
  93. 'table' => $table,
  94. 'field' => $fields[0],
  95. 'to' => $replacements[0],
  96. 'from' => $where,
  97. ];
  98. }
  99. /**
  100. * Callback for \Magento\Framework\DB\Select::where
  101. *
  102. * @param string $condition
  103. * @return \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\DB\Select
  104. */
  105. public function whereCallback($condition)
  106. {
  107. if (null === $this->_actualWhere) {
  108. $this->_actualWhere = [];
  109. }
  110. if (!empty($condition) && false === strpos(
  111. $condition,
  112. ' IS NOT NULL'
  113. ) && !in_array(
  114. $condition,
  115. $this->_actualWhere
  116. )
  117. ) {
  118. $this->_actualWhere[] = $condition;
  119. }
  120. return $this->_selectMock;
  121. }
  122. /**
  123. * @covers \Magento\Framework\Module\Setup\Migration::appendClassAliasReplace
  124. */
  125. public function testAppendClassAliasReplace()
  126. {
  127. $setupMock = $this->getMockForAbstractClass(\Magento\Framework\Setup\ModuleDataSetupInterface::class);
  128. $filesystemMock = $this->createMock(\Magento\Framework\Filesystem::class);
  129. $migrationData = $this->createMock(\Magento\Framework\Module\Setup\MigrationData::class);
  130. $setupModel = new \Magento\Framework\Module\Setup\Migration(
  131. $setupMock,
  132. $filesystemMock,
  133. $migrationData,
  134. 'app/etc/aliases_to_classes_map.json',
  135. [],
  136. $this->getSerializerMock()
  137. );
  138. $setupModel->appendClassAliasReplace(
  139. 'tableName',
  140. 'fieldName',
  141. 'entityType',
  142. 'fieldContentType',
  143. ['pk_field1', 'pk_field2'],
  144. 'additionalWhere'
  145. );
  146. $expectedRulesList = [
  147. 'tableName' => [
  148. 'fieldName' => [
  149. 'entity_type' => 'entityType',
  150. 'content_type' => 'fieldContentType',
  151. 'pk_fields' => ['pk_field1', 'pk_field2'],
  152. 'additional_where' => 'additionalWhere',
  153. ],
  154. ],
  155. ];
  156. $this->assertAttributeEquals($expectedRulesList, '_replaceRules', $setupModel);
  157. // Check that replace for the same field is not set twice
  158. $setupModel->appendClassAliasReplace(
  159. 'tableName',
  160. 'fieldName',
  161. 'newEntityType',
  162. 'newFieldContentType',
  163. ['new_pk_field1', 'new_pk_field2'],
  164. 'newAdditionalWhere'
  165. );
  166. $this->assertAttributeEquals($expectedRulesList, '_replaceRules', $setupModel);
  167. }
  168. /**
  169. * @dataProvider updateClassAliasesDataProvider
  170. */
  171. public function testDoUpdateClassAliases($replaceRules, $tableData, $expected, $aliasesMap = [])
  172. {
  173. $this->markTestIncomplete('Requires refactoring of class that is tested, covers to many methods');
  174. $this->_actualUpdateResult = [];
  175. $tableRowsCount = count($tableData);
  176. $setupMock = $this->getMockForAbstractClass(\Magento\Framework\Setup\ModuleDataSetupInterface::class);
  177. $filesystemMock = $this->createMock(\Magento\Framework\Filesystem::class);
  178. $migrationData = $this->createMock(\Magento\Framework\Module\Setup\MigrationData::class);
  179. $setupModel = new \Magento\Framework\Module\Setup\Migration(
  180. $setupMock,
  181. $filesystemMock,
  182. $migrationData,
  183. 'app/etc/aliases_to_classes_map.json',
  184. $this->_getModelDependencies($tableRowsCount, $tableData, $aliasesMap),
  185. $this->getSerializerMock()
  186. );
  187. foreach ($replaceRules as $replaceRule) {
  188. call_user_func_array([$setupModel, 'appendClassAliasReplace'], $replaceRule);
  189. }
  190. $setupModel->doUpdateClassAliases();
  191. $this->assertEquals($expected['updates'], $this->_actualUpdateResult);
  192. if (isset($expected['where'])) {
  193. $this->assertEquals($expected['where'], $this->_actualWhere);
  194. }
  195. if (isset($expected['aliases_map'])) {
  196. $this->assertAttributeEquals($expected['aliases_map'], '_aliasesMap', $setupModel);
  197. }
  198. }
  199. /**
  200. * Data provider for updating class aliases
  201. *
  202. * @return array
  203. */
  204. public function updateClassAliasesDataProvider()
  205. {
  206. return [
  207. 'plain text replace model' => include __DIR__ . '/_files/data_content_plain_model.php',
  208. 'plain text replace resource' => include __DIR__ . '/_files/data_content_plain_resource.php',
  209. 'plain text replace with pk field' => include __DIR__ . '/_files/data_content_plain_pk_fields.php',
  210. 'xml replace' => include __DIR__ . '/_files/data_content_xml.php',
  211. 'wiki markup replace' => include __DIR__ . '/_files/data_content_wiki.php',
  212. 'serialized php replace' => include __DIR__ . '/_files/data_content_serialized.php'
  213. ];
  214. }
  215. /**
  216. * @return \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\Filesystem
  217. */
  218. protected function _getFilesystemMock()
  219. {
  220. $mock = $this->getMockBuilder(\Magento\Framework\Filesystem::class)->disableOriginalConstructor()->getMock();
  221. return $mock;
  222. }
  223. /**
  224. * @return \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\Serialize\Serializer\Json
  225. * @throws \PHPUnit\Framework\Exception
  226. */
  227. private function getSerializerMock()
  228. {
  229. $serializerMock = $this->getMockBuilder(\Magento\Framework\Serialize\Serializer\Json::class)
  230. ->getMock();
  231. $serializerMock->expects($this->any())
  232. ->method('unserialize')
  233. ->willReturnCallback(
  234. function ($serializedData) {
  235. return json_decode($serializedData, true);
  236. }
  237. );
  238. return $serializerMock;
  239. }
  240. }