MigrationsTest.php 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. <?php
  2. /**
  3. * Copyright (c) 2016 Thomas Müller <thomas.mueller@tmit.eu>
  4. * This file is licensed under the Affero General Public License version 3 or
  5. * later.
  6. * See the COPYING-README file.
  7. */
  8. namespace Test\DB;
  9. use Doctrine\DBAL\Schema\Schema;
  10. use OC\DB\Connection;
  11. use OC\DB\MigrationService;
  12. use OC\DB\SchemaWrapper;
  13. use OCP\IDBConnection;
  14. use OCP\Migration\IMigrationStep;
  15. /**
  16. * Class MigrationsTest
  17. *
  18. * @package Test\DB
  19. */
  20. class MigrationsTest extends \Test\TestCase {
  21. /** @var MigrationService | \PHPUnit_Framework_MockObject_MockObject */
  22. private $migrationService;
  23. /** @var \PHPUnit_Framework_MockObject_MockObject | IDBConnection $db */
  24. private $db;
  25. public function setUp() {
  26. parent::setUp();
  27. $this->db = $this->createMock(Connection::class);
  28. $this->db->expects($this->any())->method('getPrefix')->willReturn('test_oc_');
  29. $this->migrationService = new MigrationService('testing', $this->db);
  30. }
  31. public function testGetters() {
  32. $this->assertEquals('testing', $this->migrationService->getApp());
  33. $this->assertEquals(\OC::$SERVERROOT . '/apps/testing/lib/Migration', $this->migrationService->getMigrationsDirectory());
  34. $this->assertEquals('OCA\Testing\Migration', $this->migrationService->getMigrationsNamespace());
  35. $this->assertEquals('test_oc_migrations', $this->migrationService->getMigrationsTableName());
  36. }
  37. public function testCore() {
  38. $this->migrationService = new MigrationService('core', $this->db);
  39. $this->assertEquals('core', $this->migrationService->getApp());
  40. $this->assertEquals(\OC::$SERVERROOT . '/core/Migrations', $this->migrationService->getMigrationsDirectory());
  41. $this->assertEquals('OC\Core\Migrations', $this->migrationService->getMigrationsNamespace());
  42. $this->assertEquals('test_oc_migrations', $this->migrationService->getMigrationsTableName());
  43. }
  44. /**
  45. * @expectedException \InvalidArgumentException
  46. * @expectedExceptionMessage Version 20170130180000 is unknown.
  47. */
  48. public function testExecuteUnknownStep() {
  49. $this->migrationService->executeStep('20170130180000');
  50. }
  51. /**
  52. * @expectedException \Exception
  53. * @expectedExceptionMessage App not found
  54. */
  55. public function testUnknownApp() {
  56. $migrationService = new MigrationService('unknown-bloody-app', $this->db);
  57. }
  58. /**
  59. * @expectedException \Exception
  60. * @expectedExceptionMessage Migration step 'X' is unknown
  61. */
  62. public function testExecuteStepWithUnknownClass() {
  63. $this->migrationService = $this->getMockBuilder(MigrationService::class)
  64. ->setMethods(['findMigrations'])
  65. ->setConstructorArgs(['testing', $this->db])
  66. ->getMock();
  67. $this->migrationService->expects($this->any())->method('findMigrations')->willReturn(
  68. ['20170130180000' => 'X', '20170130180001' => 'Y', '20170130180002' => 'Z', '20170130180003' => 'A']
  69. );
  70. $this->migrationService->executeStep('20170130180000');
  71. }
  72. public function testExecuteStepWithSchemaChange() {
  73. $schema = $this->createMock(Schema::class);
  74. $this->db->expects($this->any())
  75. ->method('createSchema')
  76. ->willReturn($schema);
  77. $this->db->expects($this->once())
  78. ->method('migrateToSchema');
  79. $schemaResult = $this->createMock(SchemaWrapper::class);
  80. $schemaResult->expects($this->once())
  81. ->method('getWrappedSchema')
  82. ->willReturn($this->createMock(Schema::class));
  83. $step = $this->createMock(IMigrationStep::class);
  84. $step->expects($this->at(0))
  85. ->method('preSchemaChange');
  86. $step->expects($this->at(1))
  87. ->method('changeSchema')
  88. ->willReturn($schemaResult);
  89. $step->expects($this->at(2))
  90. ->method('postSchemaChange');
  91. $this->migrationService = $this->getMockBuilder(MigrationService::class)
  92. ->setMethods(['createInstance'])
  93. ->setConstructorArgs(['testing', $this->db])
  94. ->getMock();
  95. $this->migrationService->expects($this->any())
  96. ->method('createInstance')
  97. ->with('20170130180000')
  98. ->willReturn($step);
  99. $this->migrationService->executeStep('20170130180000');
  100. }
  101. public function testExecuteStepWithoutSchemaChange() {
  102. $schema = $this->createMock(Schema::class);
  103. $this->db->expects($this->any())
  104. ->method('createSchema')
  105. ->willReturn($schema);
  106. $this->db->expects($this->never())
  107. ->method('migrateToSchema');
  108. $step = $this->createMock(IMigrationStep::class);
  109. $step->expects($this->at(0))
  110. ->method('preSchemaChange');
  111. $step->expects($this->at(1))
  112. ->method('changeSchema')
  113. ->willReturn(null);
  114. $step->expects($this->at(2))
  115. ->method('postSchemaChange');
  116. $this->migrationService = $this->getMockBuilder(MigrationService::class)
  117. ->setMethods(['createInstance'])
  118. ->setConstructorArgs(['testing', $this->db])
  119. ->getMock();
  120. $this->migrationService->expects($this->any())
  121. ->method('createInstance')
  122. ->with('20170130180000')
  123. ->willReturn($step);
  124. $this->migrationService->executeStep('20170130180000');
  125. }
  126. public function dataGetMigration() {
  127. return [
  128. ['current', '20170130180001'],
  129. ['prev', '20170130180000'],
  130. ['next', '20170130180002'],
  131. ['latest', '20170130180003'],
  132. ];
  133. }
  134. /**
  135. * @dataProvider dataGetMigration
  136. * @param string $alias
  137. * @param string $expected
  138. */
  139. public function testGetMigration($alias, $expected) {
  140. $this->migrationService = $this->getMockBuilder(MigrationService::class)
  141. ->setMethods(['getMigratedVersions', 'findMigrations'])
  142. ->setConstructorArgs(['testing', $this->db])
  143. ->getMock();
  144. $this->migrationService->expects($this->any())->method('getMigratedVersions')->willReturn(
  145. ['20170130180000', '20170130180001']
  146. );
  147. $this->migrationService->expects($this->any())->method('findMigrations')->willReturn(
  148. ['20170130180000' => 'X', '20170130180001' => 'Y', '20170130180002' => 'Z', '20170130180003' => 'A']
  149. );
  150. $this->assertEquals(
  151. ['20170130180000', '20170130180001', '20170130180002', '20170130180003'],
  152. $this->migrationService->getAvailableVersions());
  153. $migration = $this->migrationService->getMigration($alias);
  154. $this->assertEquals($expected, $migration);
  155. }
  156. public function testMigrate() {
  157. $this->migrationService = $this->getMockBuilder(MigrationService::class)
  158. ->setMethods(['getMigratedVersions', 'findMigrations', 'executeStep'])
  159. ->setConstructorArgs(['testing', $this->db])
  160. ->getMock();
  161. $this->migrationService->expects($this->any())->method('getMigratedVersions')->willReturn(
  162. ['20170130180000', '20170130180001']
  163. );
  164. $this->migrationService->expects($this->any())->method('findMigrations')->willReturn(
  165. ['20170130180000' => 'X', '20170130180001' => 'Y', '20170130180002' => 'Z', '20170130180003' => 'A']
  166. );
  167. $this->assertEquals(
  168. ['20170130180000', '20170130180001', '20170130180002', '20170130180003'],
  169. $this->migrationService->getAvailableVersions());
  170. $this->migrationService->expects($this->exactly(2))->method('executeStep')
  171. ->withConsecutive(['20170130180002'], ['20170130180003']);
  172. $this->migrationService->migrate();
  173. }
  174. }