FixtureManagerTest.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390
  1. <?php
  2. /**
  3. * CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
  4. * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
  5. *
  6. * Licensed under The MIT License
  7. * For full copyright and license information, please see the LICENSE.txt
  8. * Redistributions of files must retain the above copyright notice.
  9. *
  10. * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
  11. * @link https://cakephp.org CakePHP(tm) Project
  12. * @since 3.0.0
  13. * @license https://opensource.org/licenses/mit-license.php MIT License
  14. */
  15. namespace Cake\Test\TestSuite;
  16. use Cake\Core\Plugin;
  17. use Cake\Database\Schema\Table;
  18. use Cake\Datasource\ConnectionManager;
  19. use Cake\Log\Log;
  20. use Cake\ORM\TableRegistry;
  21. use Cake\TestSuite\Fixture\FixtureManager;
  22. use Cake\TestSuite\Stub\ConsoleOutput;
  23. use Cake\TestSuite\TestCase;
  24. /**
  25. * Fixture manager test case.
  26. */
  27. class FixtureManagerTest extends TestCase
  28. {
  29. /**
  30. * Setup method
  31. *
  32. * @return void
  33. */
  34. public function setUp()
  35. {
  36. parent::setUp();
  37. $this->manager = new FixtureManager();
  38. }
  39. public function tearDown()
  40. {
  41. parent::tearDown();
  42. Log::reset();
  43. }
  44. /**
  45. * Test loading core fixtures.
  46. *
  47. * @return void
  48. */
  49. public function testFixturizeCore()
  50. {
  51. $test = $this->getMockBuilder('Cake\TestSuite\TestCase')->getMock();
  52. $test->fixtures = ['core.articles'];
  53. $this->manager->fixturize($test);
  54. $fixtures = $this->manager->loaded();
  55. $this->assertCount(1, $fixtures);
  56. $this->assertArrayHasKey('core.articles', $fixtures);
  57. $this->assertInstanceOf('Cake\Test\Fixture\ArticlesFixture', $fixtures['core.articles']);
  58. }
  59. /**
  60. * Test logging depends on fixture manager debug.
  61. *
  62. * @return void
  63. */
  64. public function testLogSchemaWithDebug()
  65. {
  66. $db = ConnectionManager::get('test');
  67. $restore = $db->logQueries();
  68. $db->logQueries(true);
  69. $this->manager->setDebug(true);
  70. $buffer = new ConsoleOutput();
  71. Log::config('testQueryLogger', [
  72. 'className' => 'Console',
  73. 'stream' => $buffer
  74. ]);
  75. $test = $this->getMockBuilder('Cake\TestSuite\TestCase')->getMock();
  76. $test->fixtures = ['core.articles'];
  77. $this->manager->fixturize($test);
  78. // Need to load/shutdown twice to ensure fixture is created.
  79. $this->manager->load($test);
  80. $this->manager->shutdown();
  81. $this->manager->load($test);
  82. $this->manager->shutdown();
  83. $db->logQueries($restore);
  84. $this->assertContains('CREATE TABLE', implode('', $buffer->messages()));
  85. }
  86. /**
  87. * Test that if a table already exists in the test database, it will dropped
  88. * before being recreated
  89. *
  90. * @return void
  91. */
  92. public function testResetDbIfTableExists()
  93. {
  94. $db = ConnectionManager::get('test');
  95. $restore = $db->logQueries();
  96. $db->logQueries(true);
  97. $this->manager->setDebug(true);
  98. $buffer = new ConsoleOutput();
  99. Log::config('testQueryLogger', [
  100. 'className' => 'Console',
  101. 'stream' => $buffer
  102. ]);
  103. $table = new Table('articles', [
  104. 'id' => ['type' => 'integer', 'unsigned' => true],
  105. 'title' => ['type' => 'string', 'length' => 255],
  106. ]);
  107. $table->addConstraint('primary', ['type' => 'primary', 'columns' => ['id']]);
  108. $sql = $table->createSql($db);
  109. foreach ($sql as $stmt) {
  110. $db->execute($stmt);
  111. }
  112. $test = $this->getMockBuilder('Cake\TestSuite\TestCase')->getMock();
  113. $test->fixtures = ['core.articles'];
  114. $this->manager->fixturize($test);
  115. $this->manager->load($test);
  116. $db->logQueries($restore);
  117. $this->assertContains('DROP TABLE', implode('', $buffer->messages()));
  118. }
  119. /**
  120. * Test loading fixtures with constraints.
  121. *
  122. * @return void
  123. */
  124. public function testFixturizeCoreConstraint()
  125. {
  126. $test = $this->getMockBuilder('Cake\TestSuite\TestCase')->getMock();
  127. $test->fixtures = ['core.articles', 'core.articles_tags', 'core.tags'];
  128. $this->manager->fixturize($test);
  129. $this->manager->load($test);
  130. $table = TableRegistry::get('ArticlesTags');
  131. $schema = $table->schema();
  132. $expectedConstraint = [
  133. 'type' => 'foreign',
  134. 'columns' => [
  135. 'tag_id'
  136. ],
  137. 'references' => [
  138. 'tags',
  139. 'id'
  140. ],
  141. 'update' => 'cascade',
  142. 'delete' => 'cascade',
  143. 'length' => []
  144. ];
  145. $this->assertEquals($expectedConstraint, $schema->constraint('tag_id_fk'));
  146. $this->manager->unload($test);
  147. $this->manager->load($test);
  148. $table = TableRegistry::get('ArticlesTags');
  149. $schema = $table->schema();
  150. $expectedConstraint = [
  151. 'type' => 'foreign',
  152. 'columns' => [
  153. 'tag_id'
  154. ],
  155. 'references' => [
  156. 'tags',
  157. 'id'
  158. ],
  159. 'update' => 'cascade',
  160. 'delete' => 'cascade',
  161. 'length' => []
  162. ];
  163. $this->assertEquals($expectedConstraint, $schema->constraint('tag_id_fk'));
  164. $this->manager->unload($test);
  165. }
  166. /**
  167. * Test loading plugin fixtures.
  168. *
  169. * @return void
  170. */
  171. public function testFixturizePlugin()
  172. {
  173. Plugin::load('TestPlugin');
  174. $test = $this->getMockBuilder('Cake\TestSuite\TestCase')->getMock();
  175. $test->fixtures = ['plugin.test_plugin.articles'];
  176. $this->manager->fixturize($test);
  177. $fixtures = $this->manager->loaded();
  178. $this->assertCount(1, $fixtures);
  179. $this->assertArrayHasKey('plugin.test_plugin.articles', $fixtures);
  180. $this->assertInstanceOf(
  181. 'TestPlugin\Test\Fixture\ArticlesFixture',
  182. $fixtures['plugin.test_plugin.articles']
  183. );
  184. }
  185. /**
  186. * Test loading plugin fixtures.
  187. *
  188. * @return void
  189. */
  190. public function testFixturizePluginSubdirectory()
  191. {
  192. Plugin::load('TestPlugin');
  193. $test = $this->getMockBuilder('Cake\TestSuite\TestCase')->getMock();
  194. $test->fixtures = ['plugin.test_plugin.blog/comments'];
  195. $this->manager->fixturize($test);
  196. $fixtures = $this->manager->loaded();
  197. $this->assertCount(1, $fixtures);
  198. $this->assertArrayHasKey('plugin.test_plugin.blog/comments', $fixtures);
  199. $this->assertInstanceOf(
  200. 'TestPlugin\Test\Fixture\Blog\CommentsFixture',
  201. $fixtures['plugin.test_plugin.blog/comments']
  202. );
  203. }
  204. /**
  205. * Test loading plugin fixtures from a vendor namespaced plugin
  206. *
  207. * @return void
  208. */
  209. public function testFixturizeVendorPlugin()
  210. {
  211. $test = $this->getMockBuilder('Cake\TestSuite\TestCase')->getMock();
  212. $test->fixtures = ['plugin.Company/TestPluginThree.articles'];
  213. $this->manager->fixturize($test);
  214. $fixtures = $this->manager->loaded();
  215. $this->assertCount(1, $fixtures);
  216. $this->assertArrayHasKey('plugin.Company/TestPluginThree.articles', $fixtures);
  217. $this->assertInstanceOf(
  218. 'Company\TestPluginThree\Test\Fixture\ArticlesFixture',
  219. $fixtures['plugin.Company/TestPluginThree.articles']
  220. );
  221. }
  222. /**
  223. * Test loading fixtures with fully-qualified namespaces.
  224. *
  225. * @return void
  226. */
  227. public function testFixturizeClassName()
  228. {
  229. $test = $this->getMockBuilder('Cake\TestSuite\TestCase')->getMock();
  230. $test->fixtures = ['Company\TestPluginThree\Test\Fixture\ArticlesFixture'];
  231. $this->manager->fixturize($test);
  232. $fixtures = $this->manager->loaded();
  233. $this->assertCount(1, $fixtures);
  234. $this->assertArrayHasKey('Company\TestPluginThree\Test\Fixture\ArticlesFixture', $fixtures);
  235. $this->assertInstanceOf(
  236. 'Company\TestPluginThree\Test\Fixture\ArticlesFixture',
  237. $fixtures['Company\TestPluginThree\Test\Fixture\ArticlesFixture']
  238. );
  239. }
  240. /**
  241. * Test that unknown types are handled gracefully.
  242. *
  243. */
  244. public function testFixturizeInvalidType()
  245. {
  246. $this->expectException(\UnexpectedValueException::class);
  247. $this->expectExceptionMessage('Referenced fixture class "Test\Fixture\Derp.derpFixture" not found. Fixture "derp.derp" was referenced');
  248. $test = $this->getMockBuilder('Cake\TestSuite\TestCase')->getMock();
  249. $test->fixtures = ['derp.derp'];
  250. $this->manager->fixturize($test);
  251. }
  252. /**
  253. * Test load uses aliased connections via a mock.
  254. *
  255. * Ensure that FixtureManager uses connection aliases
  256. * protecting 'live' tables from being wiped by mistakes in
  257. * fixture connection names.
  258. *
  259. * @return void
  260. */
  261. public function testLoadConnectionAliasUsage()
  262. {
  263. $connection = ConnectionManager::get('test');
  264. $statement = $this->getMockBuilder('Cake\Database\StatementInterface')
  265. ->getMock();
  266. // This connection should _not_ be used.
  267. $other = $this->getMockBuilder('Cake\Database\Connection')
  268. ->setMethods(['execute'])
  269. ->setConstructorArgs([['driver' => $connection->getDriver()]])
  270. ->getMock();
  271. $other->expects($this->never())
  272. ->method('execute')
  273. ->will($this->returnValue($statement));
  274. // This connection should be used instead of
  275. // the 'other' connection as the alias should not be ignored.
  276. $testOther = $this->getMockBuilder('Cake\Database\Connection')
  277. ->setMethods(['execute'])
  278. ->setConstructorArgs([[
  279. 'database' => $connection->config()['database'],
  280. 'driver' => $connection->getDriver()
  281. ]])
  282. ->getMock();
  283. $testOther->expects($this->atLeastOnce())
  284. ->method('execute')
  285. ->will($this->returnValue($statement));
  286. ConnectionManager::config('other', $other);
  287. ConnectionManager::config('test_other', $testOther);
  288. // Connect the alias making test_other an alias of other.
  289. ConnectionManager::alias('test_other', 'other');
  290. $test = $this->getMockBuilder('Cake\TestSuite\TestCase')->getMock();
  291. $test->fixtures = ['core.other_articles'];
  292. $this->manager->fixturize($test);
  293. $this->manager->load($test);
  294. ConnectionManager::drop('other');
  295. ConnectionManager::drop('test_other');
  296. }
  297. /**
  298. * Test loading fixtures using loadSingle()
  299. *
  300. * @return void
  301. */
  302. public function testLoadSingle()
  303. {
  304. $test = $this->getMockBuilder('Cake\TestSuite\TestCase')->getMock();
  305. $test->autoFixtures = false;
  306. $test->fixtures = ['core.articles', 'core.articles_tags', 'core.tags'];
  307. $this->manager->fixturize($test);
  308. $this->manager->loadSingle('Articles');
  309. $this->manager->loadSingle('Tags');
  310. $this->manager->loadSingle('ArticlesTags');
  311. $table = TableRegistry::get('ArticlesTags');
  312. $results = $table->find('all')->toArray();
  313. $schema = $table->schema();
  314. $expectedConstraint = [
  315. 'type' => 'foreign',
  316. 'columns' => [
  317. 'tag_id'
  318. ],
  319. 'references' => [
  320. 'tags',
  321. 'id'
  322. ],
  323. 'update' => 'cascade',
  324. 'delete' => 'cascade',
  325. 'length' => []
  326. ];
  327. $this->assertEquals($expectedConstraint, $schema->constraint('tag_id_fk'));
  328. $this->assertCount(4, $results);
  329. $this->manager->unload($test);
  330. $this->manager->loadSingle('Articles');
  331. $this->manager->loadSingle('Tags');
  332. $this->manager->loadSingle('ArticlesTags');
  333. $table = TableRegistry::get('ArticlesTags');
  334. $results = $table->find('all')->toArray();
  335. $schema = $table->schema();
  336. $expectedConstraint = [
  337. 'type' => 'foreign',
  338. 'columns' => [
  339. 'tag_id'
  340. ],
  341. 'references' => [
  342. 'tags',
  343. 'id'
  344. ],
  345. 'update' => 'cascade',
  346. 'delete' => 'cascade',
  347. 'length' => []
  348. ];
  349. $this->assertEquals($expectedConstraint, $schema->constraint('tag_id_fk'));
  350. $this->assertCount(4, $results);
  351. $this->manager->unload($test);
  352. }
  353. }