TestFixtureTest.php 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597
  1. <?php
  2. /**
  3. * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
  4. * Copyright (c) Cake Software Foundation, Inc. (http://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. (http://cakefoundation.org)
  11. * @link http://cakephp.org CakePHP(tm) Project
  12. * @since 1.2.0
  13. * @license http://www.opensource.org/licenses/mit-license.php MIT License
  14. */
  15. namespace Cake\Test\TestCase\TestSuite;
  16. use Cake\Database\Schema\Table;
  17. use Cake\Datasource\ConnectionManager;
  18. use Cake\Log\Log;
  19. use Cake\TestSuite\Fixture\TestFixture;
  20. use Cake\TestSuite\TestCase;
  21. use Exception;
  22. /**
  23. * ArticlesFixture class
  24. *
  25. */
  26. class ArticlesFixture extends TestFixture
  27. {
  28. /**
  29. * Table property
  30. *
  31. * @var string
  32. */
  33. public $table = 'articles';
  34. /**
  35. * Fields array
  36. *
  37. * @var array
  38. */
  39. public $fields = [
  40. 'id' => ['type' => 'integer'],
  41. 'name' => ['type' => 'string', 'length' => '255'],
  42. 'created' => ['type' => 'datetime'],
  43. '_constraints' => [
  44. 'primary' => ['type' => 'primary', 'columns' => ['id']]
  45. ]
  46. ];
  47. /**
  48. * Records property
  49. *
  50. * @var array
  51. */
  52. public $records = [
  53. ['name' => 'Gandalf', 'created' => '2009-04-28 19:20:00'],
  54. ['name' => 'Captain Picard', 'created' => '2009-04-28 19:20:00'],
  55. ['name' => 'Chewbacca', 'created' => '2009-04-28 19:20:00']
  56. ];
  57. }
  58. /**
  59. * StringsTestsFixture class
  60. *
  61. */
  62. class StringsTestsFixture extends TestFixture
  63. {
  64. /**
  65. * Table property
  66. *
  67. * @var string
  68. */
  69. public $table = 'strings';
  70. /**
  71. * Fields array
  72. *
  73. * @var array
  74. */
  75. public $fields = [
  76. 'id' => ['type' => 'integer'],
  77. 'name' => ['type' => 'string', 'length' => '255'],
  78. 'email' => ['type' => 'string', 'length' => '255'],
  79. 'age' => ['type' => 'integer', 'default' => 10]
  80. ];
  81. /**
  82. * Records property
  83. *
  84. * @var array
  85. */
  86. public $records = [
  87. ['name' => 'Mark Doe', 'email' => 'mark.doe@email.com'],
  88. ['name' => 'John Doe', 'email' => 'john.doe@email.com', 'age' => 20],
  89. ['email' => 'jane.doe@email.com', 'name' => 'Jane Doe', 'age' => 30]
  90. ];
  91. }
  92. /**
  93. * ImportsFixture class
  94. *
  95. */
  96. class ImportsFixture extends TestFixture
  97. {
  98. /**
  99. * Import property
  100. *
  101. * @var mixed
  102. */
  103. public $import = ['table' => 'posts', 'connection' => 'test'];
  104. /**
  105. * Records property
  106. *
  107. * @var array
  108. */
  109. public $records = [
  110. ['title' => 'Hello!', 'body' => 'Hello world!']
  111. ];
  112. }
  113. /**
  114. * This class allows testing the fixture data insertion when the properties
  115. * $fields and $import are not set
  116. *
  117. */
  118. class LettersFixture extends TestFixture
  119. {
  120. /**
  121. * records property
  122. *
  123. * @var array
  124. */
  125. public $records = [
  126. ['letter' => 'a'],
  127. ['letter' => 'b'],
  128. ['letter' => 'c']
  129. ];
  130. }
  131. /**
  132. * Test case for TestFixture
  133. *
  134. */
  135. class TestFixtureTest extends TestCase
  136. {
  137. /**
  138. * Fixtures for this test.
  139. *
  140. * @var array
  141. */
  142. public $fixtures = ['core.posts'];
  143. /**
  144. * Set up
  145. *
  146. * @return void
  147. */
  148. public function setUp()
  149. {
  150. parent::setUp();
  151. Log::reset();
  152. }
  153. /**
  154. * Tear down
  155. *
  156. * @return void
  157. */
  158. public function tearDown()
  159. {
  160. parent::tearDown();
  161. Log::reset();
  162. }
  163. /**
  164. * test initializing a static fixture
  165. *
  166. * @return void
  167. */
  168. public function testInitStaticFixture()
  169. {
  170. $Fixture = new ArticlesFixture();
  171. $this->assertEquals('articles', $Fixture->table);
  172. $Fixture = new ArticlesFixture();
  173. $Fixture->table = null;
  174. $Fixture->init();
  175. $this->assertEquals('articles', $Fixture->table);
  176. $schema = $Fixture->schema();
  177. $this->assertInstanceOf('Cake\Database\Schema\Table', $schema);
  178. $fields = $Fixture->fields;
  179. unset($fields['_constraints'], $fields['_indexes']);
  180. $this->assertEquals(
  181. array_keys($fields),
  182. $schema->columns(),
  183. 'Fields do not match'
  184. );
  185. $this->assertEquals(array_keys($Fixture->fields['_constraints']), $schema->constraints());
  186. $this->assertEmpty($schema->indexes());
  187. }
  188. /**
  189. * test import fixture initialization
  190. *
  191. * @return void
  192. */
  193. public function testInitImport()
  194. {
  195. $fixture = new ImportsFixture();
  196. $fixture->fields = $fixture->records = null;
  197. $fixture->import = [
  198. 'table' => 'posts',
  199. 'connection' => 'test',
  200. ];
  201. $fixture->init();
  202. $expected = [
  203. 'id',
  204. 'author_id',
  205. 'title',
  206. 'body',
  207. 'published',
  208. ];
  209. $this->assertEquals($expected, $fixture->schema()->columns());
  210. }
  211. /**
  212. * test import fixture initialization
  213. *
  214. * @return void
  215. */
  216. public function testInitImportModel()
  217. {
  218. $fixture = new ImportsFixture();
  219. $fixture->fields = $fixture->records = null;
  220. $fixture->import = [
  221. 'model' => 'Posts',
  222. 'connection' => 'test',
  223. ];
  224. $fixture->init();
  225. $expected = [
  226. 'id',
  227. 'author_id',
  228. 'title',
  229. 'body',
  230. 'published',
  231. ];
  232. $this->assertEquals($expected, $fixture->schema()->columns());
  233. }
  234. /**
  235. * test schema reflection without $import or $fields and without the table existing
  236. * it will throw an exception
  237. *
  238. * @expectedException \Cake\Core\Exception\Exception
  239. * @expectedExceptionMessage Cannot describe schema for table `letters` for fixture `Cake\Test\TestCase\TestSuite\LettersFixture` : the table does not exist.
  240. * @return void
  241. */
  242. public function testInitNoImportNoFieldsException()
  243. {
  244. $fixture = new LettersFixture();
  245. $fixture->init();
  246. }
  247. /**
  248. * test schema reflection without $import or $fields will reflect the schema
  249. *
  250. * @return void
  251. */
  252. public function testInitNoImportNoFields()
  253. {
  254. $db = ConnectionManager::get('test');
  255. $table = new Table('letters', [
  256. 'id' => ['type' => 'integer'],
  257. 'letter' => ['type' => 'string', 'length' => 1]
  258. ]);
  259. $table->addConstraint('primary', ['type' => 'primary', 'columns' => ['id']]);
  260. $sql = $table->createSql($db);
  261. foreach ($sql as $stmt) {
  262. $db->execute($stmt);
  263. }
  264. $fixture = new LettersFixture();
  265. $fixture->init();
  266. $this->assertEquals(['id', 'letter'], $fixture->schema()->columns());
  267. $db = $this->getMockBuilder('Cake\Database\Connection')
  268. ->setMethods(['prepare', 'execute'])
  269. ->disableOriginalConstructor()
  270. ->getMock();
  271. $db->expects($this->never())
  272. ->method('prepare');
  273. $db->expects($this->never())
  274. ->method('execute');
  275. $this->assertTrue($fixture->create($db));
  276. $this->assertTrue($fixture->drop($db));
  277. // Cleanup.
  278. $db = ConnectionManager::get('test');
  279. $db->execute('DROP TABLE letters');
  280. }
  281. /**
  282. * test create method
  283. *
  284. * @return void
  285. */
  286. public function testCreate()
  287. {
  288. $fixture = new ArticlesFixture();
  289. $db = $this->getMockBuilder('Cake\Database\Connection')
  290. ->disableOriginalConstructor()
  291. ->getMock();
  292. $table = $this->getMockBuilder('Cake\Database\Schema\Table')
  293. ->setConstructorArgs(['articles'])
  294. ->getMock();
  295. $table->expects($this->once())
  296. ->method('createSql')
  297. ->with($db)
  298. ->will($this->returnValue(['sql', 'sql']));
  299. $fixture->schema($table);
  300. $statement = $this->getMockBuilder('\PDOStatement')
  301. ->setMethods(['execute', 'closeCursor'])
  302. ->getMock();
  303. $statement->expects($this->atLeastOnce())->method('closeCursor');
  304. $statement->expects($this->atLeastOnce())->method('execute');
  305. $db->expects($this->exactly(2))
  306. ->method('prepare')
  307. ->will($this->returnValue($statement));
  308. $this->assertTrue($fixture->create($db));
  309. }
  310. /**
  311. * test create method, trigger error
  312. *
  313. * @expectedException \PHPUnit_Framework_Error
  314. * @return void
  315. */
  316. public function testCreateError()
  317. {
  318. $fixture = new ArticlesFixture();
  319. $db = $this->getMockBuilder('Cake\Database\Connection')
  320. ->disableOriginalConstructor()
  321. ->getMock();
  322. $table = $this->getMockBuilder('Cake\Database\Schema\Table')
  323. ->setConstructorArgs(['articles'])
  324. ->getMock();
  325. $table->expects($this->once())
  326. ->method('createSql')
  327. ->with($db)
  328. ->will($this->throwException(new Exception('oh noes')));
  329. $fixture->schema($table);
  330. $fixture->create($db);
  331. }
  332. /**
  333. * test the insert method
  334. *
  335. * @return void
  336. */
  337. public function testInsert()
  338. {
  339. $fixture = new ArticlesFixture();
  340. $db = $this->getMockBuilder('Cake\Database\Connection')
  341. ->disableOriginalConstructor()
  342. ->getMock();
  343. $query = $this->getMockBuilder('Cake\Database\Query')
  344. ->setConstructorArgs([$db])
  345. ->getMock();
  346. $db->expects($this->once())
  347. ->method('newQuery')
  348. ->will($this->returnValue($query));
  349. $query->expects($this->once())
  350. ->method('insert')
  351. ->with(['name', 'created'], ['name' => 'string', 'created' => 'datetime'])
  352. ->will($this->returnSelf());
  353. $query->expects($this->once())
  354. ->method('into')
  355. ->with('articles')
  356. ->will($this->returnSelf());
  357. $expected = [
  358. ['name' => 'Gandalf', 'created' => '2009-04-28 19:20:00'],
  359. ['name' => 'Captain Picard', 'created' => '2009-04-28 19:20:00'],
  360. ['name' => 'Chewbacca', 'created' => '2009-04-28 19:20:00']
  361. ];
  362. $query->expects($this->at(2))
  363. ->method('values')
  364. ->with($expected[0])
  365. ->will($this->returnSelf());
  366. $query->expects($this->at(3))
  367. ->method('values')
  368. ->with($expected[1])
  369. ->will($this->returnSelf());
  370. $query->expects($this->at(4))
  371. ->method('values')
  372. ->with($expected[2])
  373. ->will($this->returnSelf());
  374. $statement = $this->getMockBuilder('\PDOStatement')
  375. ->setMethods(['closeCursor'])
  376. ->getMock();
  377. $statement->expects($this->once())->method('closeCursor');
  378. $query->expects($this->once())
  379. ->method('execute')
  380. ->will($this->returnValue($statement));
  381. $this->assertSame($statement, $fixture->insert($db));
  382. }
  383. /**
  384. * test the insert method
  385. *
  386. * @return void
  387. */
  388. public function testInsertImport()
  389. {
  390. $fixture = new ImportsFixture();
  391. $db = $this->getMockBuilder('Cake\Database\Connection')
  392. ->disableOriginalConstructor()
  393. ->getMock();
  394. $query = $this->getMockBuilder('Cake\Database\Query')
  395. ->setConstructorArgs([$db])
  396. ->getMock();
  397. $db->expects($this->once())
  398. ->method('newQuery')
  399. ->will($this->returnValue($query));
  400. $query->expects($this->once())
  401. ->method('insert')
  402. ->with(['title', 'body'], ['title' => 'string', 'body' => 'text'])
  403. ->will($this->returnSelf());
  404. $query->expects($this->once())
  405. ->method('into')
  406. ->with('posts')
  407. ->will($this->returnSelf());
  408. $expected = [
  409. ['title' => 'Hello!', 'body' => 'Hello world!'],
  410. ];
  411. $query->expects($this->at(2))
  412. ->method('values')
  413. ->with($expected[0])
  414. ->will($this->returnSelf());
  415. $statement = $this->getMockBuilder('\PDOStatement')
  416. ->setMethods(['closeCursor'])
  417. ->getMock();
  418. $statement->expects($this->once())->method('closeCursor');
  419. $query->expects($this->once())
  420. ->method('execute')
  421. ->will($this->returnValue($statement));
  422. $this->assertSame($statement, $fixture->insert($db));
  423. }
  424. /**
  425. * test the insert method
  426. *
  427. * @return void
  428. */
  429. public function testInsertStrings()
  430. {
  431. $fixture = new StringsTestsFixture();
  432. $db = $this->getMockBuilder('Cake\Database\Connection')
  433. ->disableOriginalConstructor()
  434. ->getMock();
  435. $query = $this->getMockBuilder('Cake\Database\Query')
  436. ->setConstructorArgs([$db])
  437. ->getMock();
  438. $db->expects($this->once())
  439. ->method('newQuery')
  440. ->will($this->returnValue($query));
  441. $query->expects($this->once())
  442. ->method('insert')
  443. ->with(['name', 'email', 'age'], ['name' => 'string', 'email' => 'string', 'age' => 'integer'])
  444. ->will($this->returnSelf());
  445. $query->expects($this->once())
  446. ->method('into')
  447. ->with('strings')
  448. ->will($this->returnSelf());
  449. $expected = [
  450. ['name' => 'Mark Doe', 'email' => 'mark.doe@email.com', 'age' => null],
  451. ['name' => 'John Doe', 'email' => 'john.doe@email.com', 'age' => 20],
  452. ['name' => 'Jane Doe', 'email' => 'jane.doe@email.com', 'age' => 30],
  453. ];
  454. $query->expects($this->at(2))
  455. ->method('values')
  456. ->with($expected[0])
  457. ->will($this->returnSelf());
  458. $query->expects($this->at(3))
  459. ->method('values')
  460. ->with($expected[1])
  461. ->will($this->returnSelf());
  462. $query->expects($this->at(4))
  463. ->method('values')
  464. ->with($expected[2])
  465. ->will($this->returnSelf());
  466. $statement = $this->getMockBuilder('\PDOStatement')
  467. ->setMethods(['closeCursor'])
  468. ->getMock();
  469. $statement->expects($this->once())->method('closeCursor');
  470. $query->expects($this->once())
  471. ->method('execute')
  472. ->will($this->returnValue($statement));
  473. $this->assertSame($statement, $fixture->insert($db));
  474. }
  475. /**
  476. * Test the drop method
  477. *
  478. * @return void
  479. */
  480. public function testDrop()
  481. {
  482. $fixture = new ArticlesFixture();
  483. $db = $this->getMockBuilder('Cake\Database\Connection')
  484. ->disableOriginalConstructor()
  485. ->getMock();
  486. $statement = $this->getMockBuilder('\PDOStatement')
  487. ->setMethods(['closeCursor'])
  488. ->getMock();
  489. $statement->expects($this->once())->method('closeCursor');
  490. $db->expects($this->once())->method('execute')
  491. ->with('sql')
  492. ->will($this->returnValue($statement));
  493. $table = $this->getMockBuilder('Cake\Database\Schema\Table')
  494. ->setConstructorArgs(['articles'])
  495. ->getMock();
  496. $table->expects($this->once())
  497. ->method('dropSql')
  498. ->with($db)
  499. ->will($this->returnValue(['sql']));
  500. $fixture->schema($table);
  501. $this->assertTrue($fixture->drop($db));
  502. }
  503. /**
  504. * Test the truncate method.
  505. *
  506. * @return void
  507. */
  508. public function testTruncate()
  509. {
  510. $fixture = new ArticlesFixture();
  511. $db = $this->getMockBuilder('Cake\Database\Connection')
  512. ->disableOriginalConstructor()
  513. ->getMock();
  514. $statement = $this->getMockBuilder('\PDOStatement')
  515. ->setMethods(['closeCursor'])
  516. ->getMock();
  517. $statement->expects($this->once())->method('closeCursor');
  518. $db->expects($this->once())->method('execute')
  519. ->with('sql')
  520. ->will($this->returnValue($statement));
  521. $table = $this->getMockBuilder('Cake\Database\Schema\Table')
  522. ->setConstructorArgs(['articles'])
  523. ->getMock();
  524. $table->expects($this->once())
  525. ->method('truncateSql')
  526. ->with($db)
  527. ->will($this->returnValue(['sql']));
  528. $fixture->schema($table);
  529. $this->assertTrue($fixture->truncate($db));
  530. }
  531. }