PageRenderTime 63ms CodeModel.GetById 24ms RepoModel.GetById 1ms app.codeStats 0ms

/test/testsuite/generator/builder/om/GeneratedObjectTest.php

https://github.com/mattleff/propel
PHP | 1296 lines | 845 code | 249 blank | 202 comment | 10 complexity | f9bea307f5151527d36a4191cbe9e0a0 MD5 | raw file
  1. <?php
  2. /**
  3. * This file is part of the Propel package.
  4. * For the full copyright and license information, please view the LICENSE
  5. * file that was distributed with this source code.
  6. *
  7. * @license MIT License
  8. */
  9. require_once dirname(__FILE__) . '/../../../../tools/helpers/bookstore/BookstoreEmptyTestBase.php';
  10. /**
  11. * Tests the generated Object classes.
  12. *
  13. * This test uses generated Bookstore classes to test the behavior of various
  14. * object operations. The _idea_ here is to test every possible generated method
  15. * from Object.tpl; if necessary, bookstore will be expanded to accommodate this.
  16. *
  17. * The database is relaoded before every test and flushed after every test. This
  18. * means that you can always rely on the contents of the databases being the same
  19. * for each test method in this class. See the BookstoreDataPopulator::populate()
  20. * method for the exact contents of the database.
  21. *
  22. * @see BookstoreDataPopulator
  23. * @author Hans Lellelid <hans@xmpl.org>
  24. * @package generator.builder.om
  25. */
  26. class GeneratedObjectTest extends BookstoreEmptyTestBase
  27. {
  28. protected function setUp()
  29. {
  30. parent::setUp();
  31. require_once dirname(__FILE__) . '/../../../../tools/helpers/bookstore/behavior/TestAuthor.php';
  32. }
  33. /**
  34. * Test saving an object after setting default values for it.
  35. */
  36. public function testSaveWithDefaultValues()
  37. {
  38. // From the schema.xml, I am relying on the following:
  39. // - that 'Penguin' is the default Name for a Publisher
  40. // - that 2001-01-01 is the default ReviewDate for a Review
  41. // 1) check regular values (VARCHAR)
  42. $pub = new Publisher();
  43. $pub->setName('Penguin');
  44. $pub->save();
  45. $this->assertTrue($pub->getId() !== null, "Expect Publisher to have been saved when default value set.");
  46. // 2) check date/time values
  47. $review = new Review();
  48. // note that this is different from how it's represented in schema, but should resolve to same unix timestamp
  49. $review->setReviewDate('2001-01-01');
  50. $this->assertTrue($review->isModified(), "Expect Review to have been marked 'modified' after default date/time value set.");
  51. }
  52. /**
  53. * Test isModified() to be false after setting default value second time
  54. */
  55. public function testDefaultValueSetTwice()
  56. {
  57. $pub = new Publisher();
  58. $pub->setName('Penguin');
  59. $pub->save();
  60. $pubId = $pub->getId();
  61. PublisherPeer::clearInstancePool();
  62. $pub2 = PublisherPeer::retrieveByPK($pubId);
  63. $pub2->setName('Penguin');
  64. $this->assertFalse($pub2->isModified(), "Expect Publisher to be not modified after setting default value second time.");
  65. }
  66. public function testHasApplyDefaultValues()
  67. {
  68. $this->assertTrue(method_exists('Publisher', 'applyDefaultValues'), 'Tables with default values should have an applyDefaultValues() method');
  69. $this->assertFalse(method_exists('Book', 'applyDefaultValues'), 'Tables with no default values should not have an applyDefaultValues() method');
  70. }
  71. /**
  72. * Test default return values.
  73. */
  74. public function testDefaultValues()
  75. {
  76. $r = new Review();
  77. $this->assertEquals('2001-01-01', $r->getReviewDate('Y-m-d'));
  78. $this->assertFalse($r->isModified(), "expected isModified() to be false");
  79. $acct = new BookstoreEmployeeAccount();
  80. $this->assertEquals(true, $acct->getEnabled());
  81. $this->assertFalse($acct->isModified());
  82. $acct->setLogin("testuser");
  83. $acct->setPassword("testpass");
  84. $this->assertTrue($acct->isModified());
  85. }
  86. /**
  87. * Tests the use of default expressions and the reloadOnInsert and reloadOnUpdate attributes.
  88. *
  89. * @link http://propel.phpdb.org/trac/ticket/378
  90. * @link http://propel.phpdb.org/trac/ticket/555
  91. */
  92. public function testDefaultExpresions()
  93. {
  94. if (Propel::getDb(BookstoreEmployeePeer::DATABASE_NAME) instanceof DBSqlite) {
  95. $this->markTestSkipped("Cannot test default expressions with SQLite");
  96. }
  97. $b = new Bookstore();
  98. $b->setStoreName("Foo!");
  99. $b->save();
  100. $employee = new BookstoreEmployee();
  101. $employee->setName("Johnny Walker");
  102. $acct = new BookstoreEmployeeAccount();
  103. $acct->setBookstoreEmployee($employee);
  104. $acct->setLogin("test-login");
  105. $this->assertNull($acct->getCreated(), "Expected created column to be NULL.");
  106. $this->assertNull($acct->getAuthenticator(), "Expected authenticator column to be NULL.");
  107. $acct->save();
  108. $acct = BookstoreEmployeeAccountPeer::retrieveByPK($acct->getEmployeeId());
  109. $this->assertNotNull($acct->getAuthenticator(), "Expected a valid (non-NULL) authenticator column after save.");
  110. $this->assertEquals('Password', $acct->getAuthenticator(), "Expected authenticator='Password' after save.");
  111. $this->assertNotNull($acct->getCreated(), "Expected a valid date after retrieving saved object.");
  112. $now = new DateTime("now");
  113. $this->assertEquals($now->format("Y-m-d"), $acct->getCreated("Y-m-d"));
  114. $acct->setCreated($now);
  115. $this->assertEquals($now->format("Y-m-d"), $acct->getCreated("Y-m-d"));
  116. // Unfortunately we can't really test the conjunction of reloadOnInsert and reloadOnUpdate when using just
  117. // default values. (At least not in a cross-db way.)
  118. }
  119. /**
  120. * Tests the use of default expressions and the reloadOnInsert attribute.
  121. *
  122. * @link http://propel.phpdb.org/trac/ticket/378
  123. * @link http://propel.phpdb.org/trac/ticket/555
  124. */
  125. public function testDefaultExpresions_ReloadOnInsert()
  126. {
  127. if (Propel::getDb(BookstoreEmployeePeer::DATABASE_NAME) instanceof DBSqlite) {
  128. $this->markTestSkipped("Cannot test default date expressions with SQLite");
  129. }
  130. // Create a new bookstore, contest, bookstore_contest, and bookstore_contest_entry
  131. $b = new Bookstore();
  132. $b->setStoreName("Barnes & Noble");
  133. $b->save();
  134. $c = new Contest();
  135. $c->setName("Bookathon Contest");
  136. $c->save();
  137. $bc = new BookstoreContest();
  138. $bc->setBookstore($b);
  139. $bc->setContest($c);
  140. $bc->save();
  141. $c = new Customer();
  142. $c->setName("Happy Customer");
  143. $c->save();
  144. $bce = new BookstoreContestEntry();
  145. $bce->setBookstore($b);
  146. $bce->setBookstoreContest($bc);
  147. $bce->setCustomer($c);
  148. $bce->save();
  149. $this->assertNotNull($bce->getEntryDate(), "Expected a non-null entry_date after save.");
  150. }
  151. /**
  152. * Tests the overriding reloadOnInsert at runtime.
  153. *
  154. * @link http://propel.phpdb.org/trac/ticket/378
  155. * @link http://propel.phpdb.org/trac/ticket/555
  156. */
  157. public function testDefaultExpresions_ReloadOnInsert_Override()
  158. {
  159. if (Propel::getDb(BookstoreEmployeePeer::DATABASE_NAME) instanceof DBSqlite) {
  160. $this->markTestSkipped("Cannot test default date expressions with SQLite");
  161. }
  162. // Create a new bookstore, contest, bookstore_contest, and bookstore_contest_entry
  163. $b = new Bookstore();
  164. $b->setStoreName("Barnes & Noble");
  165. $b->save();
  166. $c = new Contest();
  167. $c->setName("Bookathon Contest");
  168. $c->save();
  169. $bc = new BookstoreContest();
  170. $bc->setBookstore($b);
  171. $bc->setContest($c);
  172. $bc->save();
  173. $c = new Customer();
  174. $c->setName("Happy Customer");
  175. $c->save();
  176. $bce = new BookstoreContestEntry();
  177. $bce->setBookstore($b);
  178. $bce->setBookstoreContest($bc);
  179. $bce->setCustomer($c);
  180. $bce->save(null, $skipReload=true);
  181. $this->assertNull($bce->getEntryDate(), "Expected a NULL entry_date after save.");
  182. }
  183. /**
  184. * Tests the use of default expressions and the reloadOnUpdate attribute.
  185. *
  186. * @link http://propel.phpdb.org/trac/ticket/555
  187. */
  188. public function testDefaultExpresions_ReloadOnUpdate()
  189. {
  190. $b = new Bookstore();
  191. $b->setStoreName("Foo!");
  192. $b->save();
  193. $sale = new BookstoreSale();
  194. $sale->setBookstore(BookstorePeer::doSelectOne(new Criteria()));
  195. $sale->setSaleName("Spring Sale");
  196. $sale->save();
  197. // Expect that default values are set, but not default expressions
  198. $this->assertNull($sale->getDiscount(), "Expected discount to be NULL.");
  199. $sale->setSaleName("Winter Clearance");
  200. $sale->save();
  201. // Since reloadOnUpdate = true, we expect the discount to be set now.
  202. $this->assertNotNull($sale->getDiscount(), "Expected discount to be non-NULL after save.");
  203. }
  204. /**
  205. * Tests the overriding reloadOnUpdate at runtime.
  206. *
  207. * @link http://propel.phpdb.org/trac/ticket/378
  208. * @link http://propel.phpdb.org/trac/ticket/555
  209. */
  210. public function testDefaultExpresions_ReloadOnUpdate_Override()
  211. {
  212. $b = new Bookstore();
  213. $b->setStoreName("Foo!");
  214. $b->save();
  215. $sale = new BookstoreSale();
  216. $sale->setBookstore(BookstorePeer::doSelectOne(new Criteria()));
  217. $sale->setSaleName("Spring Sale");
  218. $sale->save();
  219. // Expect that default values are set, but not default expressions
  220. $this->assertNull($sale->getDiscount(), "Expected discount to be NULL.");
  221. $sale->setSaleName("Winter Clearance");
  222. $sale->save(null, $skipReload=true);
  223. // Since reloadOnUpdate = true, we expect the discount to be set now.
  224. $this->assertNull($sale->getDiscount(), "Expected NULL value for discount after save.");
  225. }
  226. /**
  227. * Testing creating & saving new object & instance pool.
  228. */
  229. public function testObjectInstances_New()
  230. {
  231. $emp = new BookstoreEmployee();
  232. $emp->setName(md5(microtime()));
  233. $emp->save();
  234. $id = $emp->getId();
  235. $retrieved = BookstoreEmployeePeer::retrieveByPK($id);
  236. $this->assertSame($emp, $retrieved, "Expected same object (from instance pool)");
  237. }
  238. /**
  239. *
  240. */
  241. public function testObjectInstances_Fkeys()
  242. {
  243. // Establish a relationship between one employee and account
  244. // and then change the employee_id and ensure that the account
  245. // is not pulling the old employee.
  246. $pub1 = new Publisher();
  247. $pub1->setName('Publisher 1');
  248. $pub1->save();
  249. $pub2 = new Publisher();
  250. $pub2->setName('Publisher 2');
  251. $pub2->save();
  252. $book = new Book();
  253. $book->setTitle("Book Title");
  254. $book->setISBN("1234");
  255. $book->setPublisher($pub1);
  256. $book->save();
  257. $this->assertSame($pub1, $book->getPublisher());
  258. // now change values behind the scenes
  259. $con = Propel::getConnection(BookstoreEmployeeAccountPeer::DATABASE_NAME);
  260. $con->exec("UPDATE " . BookPeer::TABLE_NAME . " SET "
  261. . " publisher_id = " . $pub2->getId()
  262. . " WHERE id = " . $book->getId());
  263. $book2 = BookPeer::retrieveByPK($book->getId());
  264. $this->assertSame($book, $book2, "Expected same book object instance");
  265. $this->assertEquals($pub1->getId(), $book->getPublisherId(), "Expected book to have OLD publisher id before reload()");
  266. $book->reload();
  267. $this->assertEquals($pub2->getId(), $book->getPublisherId(), "Expected book to have new publisher id");
  268. $this->assertSame($pub2, $book->getPublisher(), "Expected book to have new publisher object associated.");
  269. // Now let's set it back, just to be double sure ...
  270. $con->exec("UPDATE " . BookPeer::TABLE_NAME . " SET "
  271. . " publisher_id = " . $pub1->getId()
  272. . " WHERE id = " . $book->getId());
  273. $book->reload();
  274. $this->assertEquals($pub1->getId(), $book->getPublisherId(), "Expected book to have old publisher id (again).");
  275. $this->assertSame($pub1, $book->getPublisher(), "Expected book to have old publisher object associated (again).");
  276. }
  277. /**
  278. * Test the effect of typecast on primary key values and instance pool retrieval.
  279. */
  280. public function testObjectInstancePoolTypecasting()
  281. {
  282. $reader = new BookReader();
  283. $reader->setName("Tester");
  284. $reader->save();
  285. $readerId = $reader->getId();
  286. $book = new Book();
  287. $book->setTitle("BookTest");
  288. $book->setISBN("TEST");
  289. $book->save();
  290. $bookId = $book->getId();
  291. $opinion = new BookOpinion();
  292. $opinion->setBookId((string)$bookId);
  293. $opinion->setReaderId((string)$readerId);
  294. $opinion->setRating(5);
  295. $opinion->setRecommendToFriend(false);
  296. $opinion->save();
  297. $opinion2 = BookOpinionPeer::retrieveByPK($bookId, $readerId);
  298. $this->assertSame($opinion, $opinion2, "Expected same object to be retrieved from differently type-casted primary key values.");
  299. }
  300. /**
  301. * Test the reload() method.
  302. */
  303. public function testReload()
  304. {
  305. BookstoreDataPopulator::populate();
  306. $a = AuthorPeer::doSelectOne(new Criteria());
  307. $origName = $a->getFirstName();
  308. $a->setFirstName(md5(time()));
  309. $this->assertNotEquals($origName, $a->getFirstName());
  310. $this->assertTrue($a->isModified());
  311. $a->reload();
  312. $this->assertEquals($origName, $a->getFirstName());
  313. $this->assertFalse($a->isModified());
  314. }
  315. /**
  316. * Test reload(deep=true) method.
  317. */
  318. public function testReloadDeep()
  319. {
  320. BookstoreDataPopulator::populate();
  321. // arbitrary book
  322. $b = BookPeer::doSelectOne(new Criteria());
  323. // arbitrary, different author
  324. $c = new Criteria();
  325. $c->add(AuthorPeer::ID, $b->getAuthorId(), Criteria::NOT_EQUAL);
  326. $a = AuthorPeer::doSelectOne($c);
  327. $origAuthor = $b->getAuthor();
  328. $b->setAuthor($a);
  329. $this->assertNotEquals($origAuthor, $b->getAuthor(), "Expected just-set object to be different from obj from DB");
  330. $this->assertTrue($b->isModified());
  331. $b->reload($deep=true);
  332. $this->assertEquals($origAuthor, $b->getAuthor(), "Expected object in DB to be restored");
  333. $this->assertFalse($a->isModified());
  334. }
  335. /**
  336. * Test saving an object and getting correct number of affected rows from save().
  337. * This includes tests of cascading saves to fk-related objects.
  338. */
  339. public function testSaveReturnValues()
  340. {
  341. $author = new Author();
  342. $author->setFirstName("Mark");
  343. $author->setLastName("Kurlansky");
  344. // do not save
  345. $pub = new Publisher();
  346. $pub->setName("Penguin Books");
  347. // do not save
  348. $book = new Book();
  349. $book->setTitle("Salt: A World History");
  350. $book->setISBN("0142001619");
  351. $book->setAuthor($author);
  352. $book->setPublisher($pub);
  353. $affected = $book->save();
  354. $this->assertEquals(3, $affected, "Expected 3 affected rows when saving book + publisher + author.");
  355. // change nothing ...
  356. $affected = $book->save();
  357. $this->assertEquals(0, $affected, "Expected 0 affected rows when saving already-saved book.");
  358. // modify the book (UPDATE)
  359. $book->setTitle("Salt A World History");
  360. $affected = $book->save();
  361. $this->assertEquals(1, $affected, "Expected 1 affected row when saving modified book.");
  362. // modify the related author
  363. $author->setLastName("Kurlanski");
  364. $affected = $book->save();
  365. $this->assertEquals(1, $affected, "Expected 1 affected row when saving book with updated author.");
  366. // modify both the related author and the book
  367. $author->setLastName("Kurlansky");
  368. $book->setTitle("Salt: A World History");
  369. $affected = $book->save();
  370. $this->assertEquals(2, $affected, "Expected 2 affected rows when saving updated book with updated author.");
  371. }
  372. /**
  373. * Test deleting an object using the delete() method.
  374. */
  375. public function testDelete()
  376. {
  377. BookstoreDataPopulator::populate();
  378. // 1) grab an arbitrary object
  379. $book = BookPeer::doSelectOne(new Criteria());
  380. $bookId = $book->getId();
  381. // 2) delete it
  382. $book->delete();
  383. // 3) make sure it can't be save()d now that it's deleted
  384. try {
  385. $book->setTitle("Will Fail");
  386. $book->save();
  387. $this->fail("Expect an exception to be thrown when attempting to save() a deleted object.");
  388. } catch (PropelException $e) {}
  389. // 4) make sure that it doesn't exist in db
  390. $book = BookPeer::retrieveByPK($bookId);
  391. $this->assertNull($book, "Expect NULL from retrieveByPK on deleted Book.");
  392. }
  393. /**
  394. *
  395. */
  396. public function testNoColsModified()
  397. {
  398. $e1 = new BookstoreEmployee();
  399. $e1->setName('Employee 1');
  400. $e2 = new BookstoreEmployee();
  401. $e2->setName('Employee 2');
  402. $super = new BookstoreEmployee();
  403. // we don't know who the supervisor is yet
  404. $super->addSubordinate($e1);
  405. $super->addSubordinate($e2);
  406. $affected = $super->save();
  407. }
  408. /**
  409. * Tests new one-to-one functionality.
  410. */
  411. public function testOneToOne()
  412. {
  413. BookstoreDataPopulator::populate();
  414. $emp = BookstoreEmployeePeer::doSelectOne(new Criteria());
  415. $acct = new BookstoreEmployeeAccount();
  416. $acct->setBookstoreEmployee($emp);
  417. $acct->setLogin("testuser");
  418. $acct->setPassword("testpass");
  419. $this->assertSame($emp->getBookstoreEmployeeAccount(), $acct, "Expected same object instance.");
  420. }
  421. /**
  422. * Test the type sensitivity of the resturning columns.
  423. *
  424. */
  425. public function testTypeSensitive()
  426. {
  427. BookstoreDataPopulator::populate();
  428. $book = BookPeer::doSelectOne(new Criteria());
  429. $r = new Review();
  430. $r->setReviewedBy("testTypeSensitive Tester");
  431. $r->setReviewDate(time());
  432. $r->setBook($book);
  433. $r->setRecommended(true);
  434. $r->save();
  435. $id = $r->getId();
  436. unset($r);
  437. // clear the instance cache to force reload from database.
  438. ReviewPeer::clearInstancePool();
  439. BookPeer::clearInstancePool();
  440. // reload and verify that the types are the same
  441. $r2 = ReviewPeer::retrieveByPK($id);
  442. $this->assertInternalType('integer', $r2->getId(), "Expected getId() to return an integer.");
  443. $this->assertInternalType('string', $r2->getReviewedBy(), "Expected getReviewedBy() to return a string.");
  444. $this->assertInternalType('boolean', $r2->getRecommended(), "Expected getRecommended() to return a boolean.");
  445. $this->assertInstanceOf('Book', $r2->getBook(), "Expected getBook() to return a Book.");
  446. $this->assertInternalType('float', $r2->getBook()->getPrice(), "Expected Book->getPrice() to return a float.");
  447. $this->assertInstanceOf('DateTime', $r2->getReviewDate(null), "Expected Book->getReviewDate() to return a DateTime.");
  448. }
  449. /**
  450. * This is a test for expected exceptions when saving UNIQUE.
  451. * See http://propel.phpdb.org/trac/ticket/2
  452. */
  453. public function testSaveUnique()
  454. {
  455. // The whole test is in a transaction, but this test needs real transactions
  456. $this->con->commit();
  457. $emp = new BookstoreEmployee();
  458. $emp->setName(md5(microtime()));
  459. $acct = new BookstoreEmployeeAccount();
  460. $acct->setBookstoreEmployee($emp);
  461. $acct->setLogin("foo");
  462. $acct->setPassword("bar");
  463. $acct->save();
  464. // now attempt to create a new acct
  465. $acct2 = $acct->copy();
  466. try {
  467. $acct2->save();
  468. $this->fail("Expected PropelException in first attempt to save object with duplicate value for UNIQUE constraint.");
  469. } catch (Exception $x) {
  470. try {
  471. // attempt to save it again
  472. $acct3 = $acct->copy();
  473. $acct3->save();
  474. $this->fail("Expected PropelException in second attempt to save object with duplicate value for UNIQUE constraint.");
  475. } catch (Exception $x) {
  476. // this is expected.
  477. }
  478. // now let's double check that it can succeed if we're not violating the constraint.
  479. $acct3->setLogin("foo2");
  480. $acct3->save();
  481. }
  482. $this->con->beginTransaction();
  483. }
  484. /**
  485. * Test for correct reporting of isModified().
  486. */
  487. public function testIsModified()
  488. {
  489. // 1) Basic test
  490. $a = new Author();
  491. $a->setFirstName("John");
  492. $a->setLastName("Doe");
  493. $a->setAge(25);
  494. $this->assertTrue($a->isModified(), "Expected Author to be modified after setting values.");
  495. $a->save();
  496. $this->assertFalse($a->isModified(), "Expected Author to be unmodified after saving set values.");
  497. // 2) Test behavior with setting vars of different types
  498. // checking setting int col to string val
  499. $a->setAge('25');
  500. $this->assertFalse($a->isModified(), "Expected Author to be unmodified after setting int column to string-cast of same value.");
  501. $a->setFirstName("John2");
  502. $this->assertTrue($a->isModified(), "Expected Author to be modified after changing string column value.");
  503. // checking setting string col to int val
  504. $a->setFirstName("1");
  505. $a->save();
  506. $this->assertFalse($a->isModified(), "Expected Author to be unmodified after saving set values.");
  507. $a->setFirstName(1);
  508. $this->assertFalse($a->isModified(), "Expected Author to be unmodified after setting string column to int-cast of same value.");
  509. // 3) Test for appropriate behavior of NULL
  510. // checking "" -> NULL
  511. $a->setFirstName("");
  512. $a->save();
  513. $this->assertFalse($a->isModified(), "Expected Author to be unmodified after saving set values.");
  514. $a->setFirstName(null);
  515. $this->assertTrue($a->isModified(), "Expected Author to be modified after changing empty string column value to NULL.");
  516. $a->setFirstName("John");
  517. $a->setAge(0);
  518. $a->save();
  519. $this->assertFalse($a->isModified(), "Expected Author to be unmodified after saving set values.");
  520. $a->setAge(null);
  521. $this->assertTrue($a->isModified(), "Expected Author to be modified after changing 0-value int column to NULL.");
  522. $a->save();
  523. $this->assertFalse($a->isModified(), "Expected Author to be unmodified after saving set values.");
  524. $a->setAge(0);
  525. $this->assertTrue($a->isModified(), "Expected Author to be modified after changing NULL-value int column to 0.");
  526. }
  527. /**
  528. * Test the BaseObject#equals().
  529. */
  530. public function testEquals()
  531. {
  532. BookstoreDataPopulator::populate();
  533. $b = BookPeer::doSelectOne(new Criteria());
  534. $c = new Book();
  535. $c->setId($b->getId());
  536. $this->assertTrue($b->equals($c), "Expected Book objects to be equal()");
  537. $a = new Author();
  538. $a->setId($b->getId());
  539. $this->assertFalse($b->equals($a), "Expected Book and Author with same primary key NOT to match.");
  540. }
  541. /**
  542. * Test checking for non-default values.
  543. * @see http://propel.phpdb.org/trac/ticket/331
  544. */
  545. public function testHasOnlyDefaultValues()
  546. {
  547. $emp = new BookstoreEmployee();
  548. $emp->setName(md5(microtime()));
  549. $acct2 = new BookstoreEmployeeAccount();
  550. $acct = new BookstoreEmployeeAccount();
  551. $acct->setBookstoreEmployee($emp);
  552. $acct->setLogin("foo");
  553. $acct->setPassword("bar");
  554. $acct->save();
  555. $this->assertFalse($acct->isModified(), "Expected BookstoreEmployeeAccount NOT to be modified after save().");
  556. $acct->setEnabled(true);
  557. $acct->setPassword($acct2->getPassword());
  558. $this->assertTrue($acct->isModified(), "Expected BookstoreEmployeeAccount to be modified after setting default values.");
  559. $this->assertTrue($acct->hasOnlyDefaultValues(), "Expected BookstoreEmployeeAccount to not have only default values.");
  560. $acct->setPassword("bar");
  561. $this->assertFalse($acct->hasOnlyDefaultValues(), "Expected BookstoreEmployeeAccount to have at one non-default value after setting one value to non-default.");
  562. // Test a default date/time value
  563. $r = new Review();
  564. $r->setReviewDate(new DateTime("now"));
  565. $this->assertFalse($r->hasOnlyDefaultValues());
  566. }
  567. public function testDefaultFkColVal()
  568. {
  569. BookstoreDataPopulator::populate();
  570. $sale = new BookstoreSale();
  571. $this->assertEquals(1, $sale->getBookstoreId(), "Expected BookstoreSale object to have a default bookstore_id of 1.");
  572. $bookstore = BookstorePeer::doSelectOne(new Criteria());
  573. $sale->setBookstore($bookstore);
  574. $this->assertEquals($bookstore->getId(), $sale->getBookstoreId(), "Expected FK id to have changed when assigned a valid FK.");
  575. $sale->setBookstore(null);
  576. $this->assertEquals(1, $sale->getBookstoreId(), "Expected BookstoreSale object to have reset to default ID.");
  577. $sale->setPublisher(null);
  578. $this->assertEquals(null, $sale->getPublisherId(), "Expected BookstoreSale object to have reset to NULL publisher ID.");
  579. }
  580. public function testCountRefFk()
  581. {
  582. $book = new Book();
  583. $book->setTitle("Test Book");
  584. $book->setISBN("TT-EE-SS-TT");
  585. $num = 5;
  586. for ($i=2; $i < $num + 2; $i++) {
  587. $r = new Review();
  588. $r->setReviewedBy('Hans ' . $num);
  589. $dt = new DateTime("now");
  590. $dt->modify("-".$i." weeks");
  591. $r->setReviewDate($dt);
  592. $r->setRecommended(($i % 2) == 0);
  593. $book->addReview($r);
  594. }
  595. $this->assertEquals($num, $book->countReviews(), "Expected countReviews to return $num");
  596. $this->assertEquals($num, count($book->getReviews()), "Expected getReviews to return $num reviews");
  597. $book->save();
  598. BookPeer::clearInstancePool();
  599. ReviewPeer::clearInstancePool();
  600. $book = BookPeer::retrieveByPK($book->getId());
  601. $this->assertEquals($num, $book->countReviews(), "Expected countReviews() to return $num (after save)");
  602. $this->assertEquals($num, count($book->getReviews()), "Expected getReviews() to return $num (after save)");
  603. // Now set different criteria and expect different results
  604. $c = new Criteria();
  605. $c->add(ReviewPeer::RECOMMENDED, false);
  606. $this->assertEquals(floor($num/2), $book->countReviews($c), "Expected " . floor($num/2) . " results from countReviews(recomm=false)");
  607. // Change Criteria, run again -- expect different.
  608. $c = new Criteria();
  609. $c->add(ReviewPeer::RECOMMENDED, true);
  610. $this->assertEquals(ceil($num/2), count($book->getReviews($c)), "Expected " . ceil($num/2) . " results from getReviews(recomm=true)");
  611. $this->assertEquals($num, $book->countReviews(), "Expected countReviews to return $num with new empty Criteria");
  612. }
  613. /**
  614. * Test copyInto method.
  615. */
  616. public function testCopyInto_Deep()
  617. {
  618. BookstoreDataPopulator::populate();
  619. // Test a "normal" object
  620. $c = new Criteria();
  621. $c->add(BookPeer::TITLE, 'Harry%', Criteria::LIKE);
  622. $book = BookPeer::doSelectOne($c);
  623. $reviews = $book->getReviews();
  624. $b2 = $book->copy(true);
  625. $this->assertInstanceOf('Book', $b2);
  626. $this->assertNull($b2->getId());
  627. $r2 = $b2->getReviews();
  628. $this->assertEquals(count($reviews), count($r2));
  629. // Test a one-to-one object
  630. $emp = BookstoreEmployeePeer::doSelectOne(new Criteria());
  631. $e2 = $emp->copy(true);
  632. $this->assertInstanceOf('BookstoreEmployee', $e2);
  633. $this->assertNull($e2->getId());
  634. $this->assertEquals($emp->getBookstoreEmployeeAccount()->getLogin(), $e2->getBookstoreEmployeeAccount()->getLogin());
  635. }
  636. /**
  637. * Test copying when an object has composite primary key.
  638. * @link http://propel.phpdb.org/trac/ticket/618
  639. */
  640. public function testCopy_CompositePK()
  641. {
  642. $br = new BookReader();
  643. $br->setName("TestReader");
  644. $br->save();
  645. $br->copy();
  646. $b = new Book();
  647. $b->setTitle("TestBook");
  648. $b->setISBN("XX-XX-XX-XX");
  649. $b->save();
  650. $op = new BookOpinion();
  651. $op->setBookReader($br);
  652. $op->setBook($b);
  653. $op->setRating(10);
  654. $op->setRecommendToFriend(true);
  655. $op->save();
  656. $br2 = $br->copy(true);
  657. $this->assertNull($br2->getId());
  658. $opinions = $br2->getBookOpinions();
  659. $this->assertEquals(1, count($opinions), "Expected to have a related BookOpinion after copy()");
  660. // We DO expect the reader_id to be null
  661. $this->assertNull($opinions[0]->getReaderId());
  662. // but we DO NOT expect the book_id to be null
  663. $this->assertEquals($op->getBookId(), $opinions[0]->getBookId());
  664. }
  665. public function testToArray()
  666. {
  667. $b = new Book();
  668. $b->setTitle('Don Juan');
  669. $arr1 = $b->toArray();
  670. $expectedKeys = array(
  671. 'Id',
  672. 'Title',
  673. 'ISBN',
  674. 'Price',
  675. 'PublisherId',
  676. 'AuthorId'
  677. );
  678. $this->assertEquals($expectedKeys, array_keys($arr1), 'toArray() returns an associative array with BasePeer::TYPE_PHPNAME keys by default');
  679. $this->assertEquals('Don Juan', $arr1['Title'], 'toArray() returns an associative array representation of the object');
  680. }
  681. public function testToArrayKeyType()
  682. {
  683. $b = new Book();
  684. $b->setTitle('Don Juan');
  685. $arr1 = $b->toArray(BasePeer::TYPE_COLNAME);
  686. $expectedKeys = array(
  687. BookPeer::ID,
  688. BookPeer::TITLE,
  689. BookPeer::ISBN,
  690. BookPeer::PRICE,
  691. BookPeer::PUBLISHER_ID,
  692. BookPeer::AUTHOR_ID
  693. );
  694. $this->assertEquals($expectedKeys, array_keys($arr1), 'toArray() accepts a $keyType parameter to change the result keys');
  695. $this->assertEquals('Don Juan', $arr1[BookPeer::TITLE], 'toArray() returns an associative array representation of the object');
  696. }
  697. /**
  698. * Test the toArray() method with new lazyLoad param.
  699. * @link http://propel.phpdb.org/trac/ticket/527
  700. */
  701. public function testToArrayLazyLoad()
  702. {
  703. BookstoreDataPopulator::populate();
  704. $c = new Criteria();
  705. $c->add(MediaPeer::COVER_IMAGE, null, Criteria::NOT_EQUAL);
  706. $c->add(MediaPeer::EXCERPT, null, Criteria::NOT_EQUAL);
  707. $m = MediaPeer::doSelectOne($c);
  708. if ($m === null) {
  709. $this->fail("Test requires at least one media row w/ cover_image and excerpt NOT NULL");
  710. }
  711. $arr1 = $m->toArray(BasePeer::TYPE_COLNAME);
  712. $this->assertNotNull($arr1[MediaPeer::COVER_IMAGE]);
  713. $this->assertInternalType('resource', $arr1[MediaPeer::COVER_IMAGE]);
  714. $arr2 = $m->toArray(BasePeer::TYPE_COLNAME, false);
  715. $this->assertNull($arr2[MediaPeer::COVER_IMAGE]);
  716. $this->assertNull($arr2[MediaPeer::EXCERPT]);
  717. $diffKeys = array_keys(array_diff($arr1, $arr2));
  718. $expectedDiff = array(MediaPeer::COVER_IMAGE, MediaPeer::EXCERPT);
  719. $this->assertEquals($expectedDiff, $diffKeys);
  720. }
  721. public function testToArrayIncludesForeignObjects()
  722. {
  723. BookstoreDataPopulator::populate();
  724. BookPeer::clearInstancePool();
  725. AuthorPeer::clearInstancePool();
  726. PublisherPeer::clearInstancePool();
  727. $c = new Criteria();
  728. $c->add(BookPeer::TITLE, 'Don Juan');
  729. $books = BookPeer::doSelectJoinAuthor($c);
  730. $book = $books[0];
  731. $arr1 = $book->toArray(BasePeer::TYPE_PHPNAME, null, array(), true);
  732. $expectedKeys = array(
  733. 'Id',
  734. 'Title',
  735. 'ISBN',
  736. 'Price',
  737. 'PublisherId',
  738. 'AuthorId',
  739. 'Author'
  740. );
  741. $this->assertEquals($expectedKeys, array_keys($arr1), 'toArray() can return sub arrays for hydrated related objects');
  742. $this->assertEquals('George', $arr1['Author']['FirstName'], 'toArray() can return sub arrays for hydrated related objects');
  743. $c = new Criteria();
  744. $c->add(BookPeer::TITLE, 'Don Juan');
  745. $books = BookPeer::doSelectJoinAll($c);
  746. $book = $books[0];
  747. $arr2 = $book->toArray(BasePeer::TYPE_PHPNAME, null, array(), true);
  748. $expectedKeys = array(
  749. 'Id',
  750. 'Title',
  751. 'ISBN',
  752. 'Price',
  753. 'PublisherId',
  754. 'AuthorId',
  755. 'Publisher',
  756. 'Author'
  757. );
  758. $this->assertEquals($expectedKeys, array_keys($arr2), 'toArray() can return sub arrays for hydrated related objects');
  759. }
  760. public function testToArrayIncludesForeignReferrers()
  761. {
  762. $a1 = new Author();
  763. $a1->setFirstName('Leo');
  764. $a1->setLastName('Tolstoi');
  765. $arr = $a1->toArray(BasePeer::TYPE_PHPNAME, null, array(), true);
  766. $this->assertFalse(array_key_exists('Books', $arr));
  767. $b1 = new Book();
  768. $b1->setTitle('War and Peace');
  769. $b2 = new Book();
  770. $b2->setTitle('Anna Karenina');
  771. $a1->addBook($b1);
  772. $a1->addBook($b2);
  773. $arr = $a1->toArray(BasePeer::TYPE_PHPNAME, null, array(), true);
  774. $this->assertTrue(array_key_exists('Books', $arr));
  775. $this->assertEquals(2, count($arr['Books']));
  776. $this->assertEquals('War and Peace', $arr['Books']['Book_0']['Title']);
  777. $this->assertEquals('Anna Karenina', $arr['Books']['Book_1']['Title']);
  778. $this->assertEquals('*RECURSION*', $arr['Books']['Book_0']['Author']);
  779. }
  780. /**
  781. * Test regexp validator for ticket:542
  782. * @link http://propel.phpdb.org/trac/ticket/542
  783. */
  784. public function testRegexValidator()
  785. {
  786. $b = new Bookstore();
  787. $b->setWebsite("http://this.is.valid.com/foo.bar");
  788. $res = $b->validate();
  789. $this->assertTrue($res, "Expected URL to validate");
  790. }
  791. /**
  792. * Test that setting the auto-increment primary key will result in exception.
  793. */
  794. public function testSettingAutoIncrementPK()
  795. {
  796. // The whole test is in a transaction, but this test needs real transactions
  797. $this->con->commit();
  798. $b = new Bookstore();
  799. $b->setId(1);
  800. $b->setStoreName("Test");
  801. try {
  802. $b->save();
  803. $this->fail("Expected setting auto-increment primary key to result in Exception");
  804. } catch (Exception $x) {
  805. $this->assertInstanceOf('PropelException', $x);
  806. }
  807. // ... but we should silently ignore NULL values, since these are really
  808. // the same as "not set" in PHP world.
  809. $b = new Bookstore();
  810. $b->setId(null);
  811. $b->setStoreName("Test2");
  812. try {
  813. $b->save();
  814. } catch (Exception $x) {
  815. $this->fail("Expected no exception when setting auto-increment primary key to NULL");
  816. }
  817. // success ...
  818. $this->con->beginTransaction();
  819. }
  820. /**
  821. * Checks wether we are allowed to specify the primary key on a
  822. * table with allowPkInsert=true set
  823. *
  824. * saves the object, gets it from data-source again and then compares
  825. * them for equality (thus the instance pool is also checked)
  826. */
  827. public function testAllowPkInsertOnIdMethodNativeTable()
  828. {
  829. $cu = new Customer;
  830. $cu->setPrimaryKey(100000);
  831. $cu->save();
  832. $this->assertEquals(100000, $cu->getPrimaryKey());
  833. $cu2 = CustomerPeer::retrieveByPk(100000);
  834. $this->assertSame($cu, $cu2);
  835. }
  836. /**
  837. * Checks if it is allowed to save new, empty objects with a auto increment column
  838. */
  839. public function testAllowEmptyWithAutoIncrement()
  840. {
  841. $bookreader = new BookReader();
  842. $bookreader->save();
  843. $this->assertFalse($bookreader->isNew() );
  844. }
  845. /**
  846. * Test foreign key relationships based on references to unique cols but not PK.
  847. * @link http://propel.phpdb.org/trac/ticket/691
  848. */
  849. public function testUniqueFkRel()
  850. {
  851. $employee = new BookstoreEmployee();
  852. $employee->setName("Johnny Walker");
  853. $acct = new BookstoreEmployeeAccount();
  854. $acct->setBookstoreEmployee($employee);
  855. $acct->setLogin("test-login");
  856. $acct->save();
  857. $acctId = $acct->getEmployeeId();
  858. $al = new AcctAuditLog();
  859. $al->setBookstoreEmployeeAccount($acct);
  860. $al->save();
  861. $alId = $al->getId();
  862. BookstoreEmployeePeer::clearInstancePool();
  863. BookstoreEmployeeAccountPeer::clearInstancePool();
  864. AcctAuditLogPeer::clearInstancePool();
  865. $al2 = AcctAuditLogPeer::retrieveByPK($alId);
  866. /* @var $al2 AcctAuditLog */
  867. $mapacct = $al2->getBookstoreEmployeeAccount();
  868. $lookupacct = BookstoreEmployeeAccountPeer::retrieveByPK($acctId);
  869. $logs = $lookupacct->getAcctAuditLogs();
  870. $this->assertTrue(count($logs) == 1, "Expected 1 audit log result.");
  871. $this->assertEquals($logs[0]->getId(), $al->getId(), "Expected returned audit log to match created audit log.");
  872. }
  873. public function testIsPrimaryKeyNull()
  874. {
  875. $b = new Book();
  876. $this->assertTrue($b->isPrimaryKeyNull());
  877. $b->setPrimaryKey(123);
  878. $this->assertFalse($b->isPrimaryKeyNull());
  879. $b->setPrimaryKey(null);
  880. $this->assertTrue($b->isPrimaryKeyNull());
  881. }
  882. public function testIsPrimaryKeyNullCompmosite()
  883. {
  884. $b = new BookOpinion();
  885. $this->assertTrue($b->isPrimaryKeyNull());
  886. $b->setPrimaryKey(array(123, 456));
  887. $this->assertFalse($b->isPrimaryKeyNull());
  888. $b->setPrimaryKey(array(123, null));
  889. $this->assertFalse($b->isPrimaryKeyNull());
  890. $b->setPrimaryKey(array(null, 456));
  891. $this->assertFalse($b->isPrimaryKeyNull());
  892. $b->setPrimaryKey(array(null, null));
  893. $this->assertTrue($b->isPrimaryKeyNull());
  894. }
  895. public function testAddToStringDefault()
  896. {
  897. $this->assertTrue(method_exists('Author', '__toString'), 'addPrimaryString() adds a __toString() method even if no column has the primaryString attribute');
  898. $author = new Author();
  899. $author->setFirstName('Leo');
  900. $author->setLastName('Tolstoi');
  901. $expected = <<<EOF
  902. Id: null
  903. FirstName: Leo
  904. LastName: Tolstoi
  905. Email: null
  906. Age: null
  907. EOF;
  908. $this->assertEquals($expected, (string) $author, 'addPrimaryString() adds a __toString() method returning the YAML representation of the object where no column is defined as primaryString');
  909. }
  910. public function testAddToStringPrimaryString()
  911. {
  912. $this->assertTrue(method_exists('Book', '__toString'), 'addPrimaryString() adds a __toString() method if a column has the primaryString attribute');
  913. $book = new Book();
  914. $book->setTitle('foo');
  915. $this->assertEquals('foo', (string) $book, 'addPrimaryString() adds a __toString() method returning the value of the the first column where primaryString is true');
  916. }
  917. public function testPreInsert()
  918. {
  919. $author = new TestAuthor();
  920. $author->setFirstName("bogus");
  921. $author->setLastName("Lastname");
  922. $author->save();
  923. $this->assertEquals('PreInsertedFirstname', $author->getFirstName());
  924. }
  925. public function testPreUpdate()
  926. {
  927. $author = new TestAuthor();
  928. $author->setFirstName("bogus");
  929. $author->setLastName("Lastname");
  930. $author->save();
  931. $author->setNew(false);
  932. $author->save();
  933. $this->assertEquals('PreUpdatedFirstname', $author->getFirstName());
  934. }
  935. public function testPostInsert()
  936. {
  937. $author = new TestAuthor();
  938. $author->setFirstName("bogus");
  939. $author->setLastName("Lastname");
  940. $author->save();
  941. $this->assertEquals('PostInsertedLastName', $author->getLastName());
  942. }
  943. public function testPostUpdate()
  944. {
  945. $author = new TestAuthor();
  946. $author->setFirstName("bogus");
  947. $author->setLastName("Lastname");
  948. $author->save();
  949. $author->setNew(false);
  950. $author->save();
  951. $this->assertEquals('PostUpdatedLastName', $author->getLastName());
  952. }
  953. public function testPreSave()
  954. {
  955. $author = new TestAuthor();
  956. $author->setFirstName("bogus");
  957. $author->setLastName("Lastname");
  958. $author->save();
  959. $this->assertEquals('pre@save.com', $author->getEmail());
  960. }
  961. public function testPreSaveFalse()
  962. {
  963. $con = Propel::getConnection(AuthorPeer::DATABASE_NAME);
  964. $author = new TestAuthorSaveFalse();
  965. $author->setFirstName("bogus");
  966. $author->setLastName("Lastname");
  967. $res = $author->save($con);
  968. $this->assertEquals(0, $res);
  969. $this->assertEquals('pre@save.com', $author->getEmail());
  970. $this->assertNotEquals(115, $author->getAge());
  971. $this->assertTrue($author->isNew());
  972. $this->assertEquals(1, $con->getNestedTransactionCount());
  973. }
  974. public function testPostSave()
  975. {
  976. $author = new TestAuthor();
  977. $author->setFirstName("bogus");
  978. $author->setLastName("Lastname");
  979. $author->save();
  980. $this->assertEquals(115, $author->getAge());
  981. }
  982. public function testPreDelete()
  983. {
  984. $author = new TestAuthor();
  985. $author->setFirstName("bogus");
  986. $author->setLastName("Lastname");
  987. $author->save();
  988. $author->delete();
  989. $this->assertEquals("Pre-Deleted", $author->getFirstName());
  990. }
  991. public function testPreDeleteFalse()
  992. {
  993. $con = Propel::getConnection(AuthorPeer::DATABASE_NAME);
  994. $author = new TestAuthorDeleteFalse();
  995. $author->setFirstName("bogus");
  996. $author->setLastName("Lastname");
  997. $author->save($con);
  998. $author->delete($con);
  999. $this->assertEquals("Pre-Deleted", $author->getFirstName());
  1000. $this->assertNotEquals("Post-Deleted", $author->getLastName());
  1001. $this->assertFalse($author->isDeleted());
  1002. $this->assertEquals(1, $con->getNestedTransactionCount());
  1003. }
  1004. public function testPostDelete()
  1005. {
  1006. $author = new TestAuthor();
  1007. $author->setFirstName("bogus");
  1008. $author->setLastName("Lastname");
  1009. $author->save();
  1010. $author->delete();
  1011. $this->assertEquals("Post-Deleted", $author->getLastName());
  1012. }
  1013. public function testMagicVirtualColumnGetter()
  1014. {
  1015. $book = new Book();
  1016. $book->setVirtualColumn('Foo', 'bar');
  1017. $this->assertEquals('bar', $book->getFoo(), 'generated __call() catches getters for virtual columns');
  1018. $book = new Book();
  1019. $book->setVirtualColumn('foo', 'bar');
  1020. $this->assertEquals('bar', $book->getFoo(), 'generated __call() catches getters for virtual columns starting with a lowercase character');
  1021. }
  1022. /**
  1023. * @expectedException PropelException
  1024. */
  1025. public function testMagicCallUndefined()
  1026. {
  1027. $book = new Book();
  1028. $book->fooMethodName();
  1029. }
  1030. public static function conditionsForTestReadOnly()
  1031. {
  1032. return array(
  1033. array('reload'),
  1034. array('delete'),
  1035. array('save'),
  1036. array('doSave'),
  1037. );
  1038. }
  1039. /**
  1040. * @dataProvider conditionsForTestReadOnly
  1041. */
  1042. public function testReadOnly($method)
  1043. {
  1044. $cv = new ContestView();
  1045. $this->assertFalse(method_exists($cv, $method), 'readOnly tables end up with no ' . $method . ' method in the generated object class');
  1046. }
  1047. }