| | 123 | // Unfortunately we can't really test the conjunction of reloadOnInsert and reloadOnUpdate when using just |
|---|
| | 124 | // default values. (At least not in a cross-db way.) |
|---|
| | 125 | } |
|---|
| | 126 | |
|---|
| | 127 | /** |
|---|
| | 128 | * Tests the use of default expressions and the reloadOnInsert attribute. |
|---|
| | 129 | * |
|---|
| | 130 | * @link http://propel.phpdb.org/trac/ticket/378 |
|---|
| | 131 | * @link http://propel.phpdb.org/trac/ticket/555 |
|---|
| | 132 | */ |
|---|
| | 133 | public function testDefaultExpresions_ReloadOnInsert() |
|---|
| | 134 | { |
|---|
| | 135 | if (Propel::getDb(BookstoreEmployeePeer::DATABASE_NAME) instanceof DBSqlite) { |
|---|
| | 136 | $this->markTestSkipped("Cannot test default date expressions with SQLite"); |
|---|
| | 137 | } |
|---|
| | 138 | |
|---|
| | 139 | // Create a new bookstore, contest, bookstore_contest, and bookstore_contest_entry |
|---|
| | 140 | |
|---|
| | 141 | $b = new Bookstore(); |
|---|
| | 142 | $b->setStoreName("Barnes & Noble"); |
|---|
| | 143 | $b->save(); |
|---|
| | 144 | |
|---|
| | 145 | $c = new Contest(); |
|---|
| | 146 | $c->setName("Bookathon Contest"); |
|---|
| | 147 | $c->save(); |
|---|
| | 148 | |
|---|
| | 149 | $bc = new BookstoreContest(); |
|---|
| | 150 | $bc->setBookstore($b); |
|---|
| | 151 | $bc->setContest($c); |
|---|
| | 152 | $bc->save(); |
|---|
| | 153 | |
|---|
| | 154 | $c = new Customer(); |
|---|
| | 155 | $c->setName("Happy Customer"); |
|---|
| | 156 | $c->save(); |
|---|
| | 157 | |
|---|
| | 158 | $bce = new BookstoreContestEntry(); |
|---|
| | 159 | $bce->setBookstore($b); |
|---|
| | 160 | $bce->setBookstoreContest($bc); |
|---|
| | 161 | $bce->setCustomer($c); |
|---|
| | 162 | $bce->save(); |
|---|
| | 163 | |
|---|
| | 164 | $this->assertNotNull($bce->getEntryDate(), "Expected a non-null entry_date after save."); |
|---|
| | 165 | } |
|---|
| | 166 | |
|---|
| | 167 | /** |
|---|
| | 168 | * Tests the overriding reloadOnInsert at runtime. |
|---|
| | 169 | * |
|---|
| | 170 | * @link http://propel.phpdb.org/trac/ticket/378 |
|---|
| | 171 | * @link http://propel.phpdb.org/trac/ticket/555 |
|---|
| | 172 | */ |
|---|
| | 173 | public function testDefaultExpresions_ReloadOnInsert_Override() |
|---|
| | 174 | { |
|---|
| | 175 | if (Propel::getDb(BookstoreEmployeePeer::DATABASE_NAME) instanceof DBSqlite) { |
|---|
| | 176 | $this->markTestSkipped("Cannot test default date expressions with SQLite"); |
|---|
| | 177 | } |
|---|
| | 178 | |
|---|
| | 179 | // Create a new bookstore, contest, bookstore_contest, and bookstore_contest_entry |
|---|
| | 180 | $b = new Bookstore(); |
|---|
| | 181 | $b->setStoreName("Barnes & Noble"); |
|---|
| | 182 | $b->save(); |
|---|
| | 183 | |
|---|
| | 184 | $c = new Contest(); |
|---|
| | 185 | $c->setName("Bookathon Contest"); |
|---|
| | 186 | $c->save(); |
|---|
| | 187 | |
|---|
| | 188 | $bc = new BookstoreContest(); |
|---|
| | 189 | $bc->setBookstore($b); |
|---|
| | 190 | $bc->setContest($c); |
|---|
| | 191 | $bc->save(); |
|---|
| | 192 | |
|---|
| | 193 | $c = new Customer(); |
|---|
| | 194 | $c->setName("Happy Customer"); |
|---|
| | 195 | $c->save(); |
|---|
| | 196 | |
|---|
| | 197 | $bce = new BookstoreContestEntry(); |
|---|
| | 198 | $bce->setBookstore($b); |
|---|
| | 199 | $bce->setBookstoreContest($bc); |
|---|
| | 200 | $bce->setCustomer($c); |
|---|
| | 201 | $bce->save(null, $skipReload=true); |
|---|
| | 202 | |
|---|
| | 203 | $this->assertNull($bce->getEntryDate(), "Expected a NULL entry_date after save."); |
|---|
| | 204 | } |
|---|
| | 205 | |
|---|
| | 206 | /** |
|---|
| | 207 | * Tests the use of default expressions and the reloadOnUpdate attribute. |
|---|
| | 208 | * |
|---|
| | 209 | * @link http://propel.phpdb.org/trac/ticket/555 |
|---|
| | 210 | */ |
|---|
| | 211 | public function testDefaultExpresions_ReloadOnUpdate() |
|---|
| | 212 | { |
|---|
| | 213 | $b = new Bookstore(); |
|---|
| | 214 | $b->setStoreName("Foo!"); |
|---|
| | 215 | $b->save(); |
|---|
| | 216 | |
|---|
| | 217 | $sale = new BookstoreSale(); |
|---|
| | 218 | $sale->setBookstore(BookstorePeer::doSelectOne(new Criteria())); |
|---|
| | 219 | $sale->setSaleName("Spring Sale"); |
|---|
| | 220 | $sale->save(); |
|---|
| | 221 | |
|---|
| | 222 | // Expect that default values are set, but not default expressions |
|---|
| | 223 | $this->assertNull($sale->getDiscount(), "Expected discount to be NULL."); |
|---|
| | 224 | |
|---|
| | 225 | $sale->setSaleName("Winter Clearance"); |
|---|
| | 226 | $sale->save(); |
|---|
| | 227 | // Since reloadOnUpdate = true, we expect the discount to be set now. |
|---|
| | 228 | |
|---|
| | 229 | $this->assertNotNull($sale->getDiscount(), "Expected discount to be non-NULL after save."); |
|---|
| | 230 | } |
|---|
| | 231 | |
|---|
| | 232 | /** |
|---|
| | 233 | * Tests the overriding reloadOnUpdate at runtime. |
|---|
| | 234 | * |
|---|
| | 235 | * @link http://propel.phpdb.org/trac/ticket/378 |
|---|
| | 236 | * @link http://propel.phpdb.org/trac/ticket/555 |
|---|
| | 237 | */ |
|---|
| | 238 | public function testDefaultExpresions_ReloadOnUpdate_Override() |
|---|
| | 239 | { |
|---|
| | 240 | $b = new Bookstore(); |
|---|
| | 241 | $b->setStoreName("Foo!"); |
|---|
| | 242 | $b->save(); |
|---|
| | 243 | |
|---|
| | 244 | $sale = new BookstoreSale(); |
|---|
| | 245 | $sale->setBookstore(BookstorePeer::doSelectOne(new Criteria())); |
|---|
| | 246 | $sale->setSaleName("Spring Sale"); |
|---|
| | 247 | $sale->save(); |
|---|
| | 248 | |
|---|
| | 249 | // Expect that default values are set, but not default expressions |
|---|
| | 250 | $this->assertNull($sale->getDiscount(), "Expected discount to be NULL."); |
|---|
| | 251 | |
|---|
| | 252 | $sale->setSaleName("Winter Clearance"); |
|---|
| | 253 | $sale->save(null, $skipReload=true); |
|---|
| | 254 | |
|---|
| | 255 | // Since reloadOnUpdate = true, we expect the discount to be set now. |
|---|
| | 256 | |
|---|
| | 257 | $this->assertNull($sale->getDiscount(), "Expected NULL value for discount after save."); |
|---|
| 601 | | /** |
|---|
| 602 | | * Test the LOB results returned in a resultset. |
|---|
| 603 | | */ |
|---|
| 604 | | public function testLobResults() |
|---|
| 605 | | { |
|---|
| 606 | | |
|---|
| 607 | | $blob_path = TESTS_BASE_DIR . '/etc/lob/tin_drum.gif'; |
|---|
| 608 | | $clob_path = TESTS_BASE_DIR . '/etc/lob/tin_drum.txt'; |
|---|
| 609 | | |
|---|
| 610 | | $book = BookPeer::doSelectOne(new Criteria()); |
|---|
| 611 | | |
|---|
| 612 | | $m1 = new Media(); |
|---|
| 613 | | $m1->setBook($book); |
|---|
| 614 | | $m1->setCoverImage(file_get_contents($blob_path)); |
|---|
| 615 | | $m1->setExcerpt(file_get_contents($clob_path)); |
|---|
| 616 | | $m1->save(); |
|---|
| 617 | | $m1_id = $m1->getId(); |
|---|
| 618 | | |
|---|
| 619 | | $m1->reload(); |
|---|
| 620 | | |
|---|
| 621 | | $img = $m1->getCoverImage(); |
|---|
| 622 | | $txt = $m1->getExcerpt(); |
|---|
| 623 | | |
|---|
| 624 | | $this->assertType('resource', $img, "Expected results of BLOB method to be a resource."); |
|---|
| 625 | | $this->assertType('string', $txt, "Expected results of CLOB method to be a string."); |
|---|
| 626 | | |
|---|
| 627 | | $stat = fstat($img); |
|---|
| 628 | | $size = $stat['size']; |
|---|
| 629 | | |
|---|
| 630 | | $this->assertEquals(filesize($blob_path), $size, "Expected filesize to match stat(blobrsc)"); |
|---|
| 631 | | $this->assertEquals(filesize($clob_path), strlen($txt), "Expected filesize to match clob strlen"); |
|---|
| 632 | | } |
|---|
| 633 | | |
|---|
| 634 | | /** |
|---|
| 635 | | * Tests the setting of LOB (BLOB and CLOB) values. |
|---|
| 636 | | */ |
|---|
| 637 | | public function testLobSetting() |
|---|
| 638 | | { |
|---|
| 639 | | $blob_path = TESTS_BASE_DIR . '/etc/lob/tin_drum.gif'; |
|---|
| 640 | | $blob2_path = TESTS_BASE_DIR . '/etc/lob/propel.gif'; |
|---|
| 641 | | |
|---|
| 642 | | $clob_path = TESTS_BASE_DIR . '/etc/lob/tin_drum.txt'; |
|---|
| 643 | | $book = BookPeer::doSelectOne(new Criteria()); |
|---|
| 644 | | |
|---|
| 645 | | $m1 = new Media(); |
|---|
| 646 | | $m1->setBook($book); |
|---|
| 647 | | $m1->setCoverImage(file_get_contents($blob_path)); |
|---|
| 648 | | $m1->setExcerpt(file_get_contents($clob_path)); |
|---|
| 649 | | $m1->save(); |
|---|
| 650 | | $m1_id = $m1->getId(); |
|---|
| 651 | | |
|---|
| 652 | | // 1) Assert that we've got a valid stream to start with |
|---|
| 653 | | $img = $m1->getCoverImage(); |
|---|
| 654 | | $this->assertType('resource', $img, "Expected results of BLOB method to be a resource."); |
|---|
| 655 | | |
|---|
| 656 | | // 2) Test setting a BLOB column with file contents |
|---|
| 657 | | $m1->setCoverImage(file_get_contents($blob2_path)); |
|---|
| 658 | | $this->assertType('resource', $m1->getCoverImage(), "Expected to get a resource back after setting BLOB with file contents."); |
|---|
| 659 | | |
|---|
| 660 | | // commit those changes & reload |
|---|
| 661 | | $m1->save(); |
|---|
| 662 | | |
|---|
| 663 | | // 3) Verify that we've got a valid resource after reload |
|---|
| 664 | | $m1->reload(); |
|---|
| 665 | | $this->assertType('resource', $m1->getCoverImage(), "Expected to get a resource back after setting reloading object."); |
|---|
| 666 | | |
|---|
| 667 | | // 4) Test isModified() behavior |
|---|
| 668 | | $fp = fopen("php://temp", "r+"); |
|---|
| 669 | | fwrite($fp, file_get_contents($blob2_path)); |
|---|
| 670 | | |
|---|
| 671 | | $m1->setCoverImage($fp); |
|---|
| 672 | | $this->assertTrue($m1->isModified(), "Expected Media object to be modified, despite fact that stream is to same data"); |
|---|
| 673 | | |
|---|
| 674 | | // 5) Test external modification of the stream (and re-setting it into the object) |
|---|
| 675 | | $stream = $m1->getCoverImage(); |
|---|
| 676 | | fwrite($stream, file_get_contents($blob_path)); // change the contents of the stream |
|---|
| 677 | | |
|---|
| 678 | | $m1->setCoverImage($stream); |
|---|
| 679 | | |
|---|
| 680 | | $this->assertTrue($m1->isModified(), "Expected Media object to be modified when stream contents changed."); |
|---|
| 681 | | $this->assertNotEquals(file_get_contents($blob2_path), stream_get_contents($m1->getCoverImage())); |
|---|
| 682 | | |
|---|
| 683 | | $m1->save(); |
|---|
| 684 | | |
|---|
| 685 | | // 6) Assert that when we call the setter with a stream, that the file in db gets updated. |
|---|
| 686 | | |
|---|
| 687 | | $m1->reload(); // start with a fresh copy from db |
|---|
| 688 | | |
|---|
| 689 | | // Ensure that object is set up correctly |
|---|
| 690 | | $this->assertNotEquals(file_get_contents($blob_path), stream_get_contents($m1->getCoverImage()), "The object is not correctly set up to verify the stream-setting test."); |
|---|
| 691 | | |
|---|
| 692 | | $fp = fopen($blob_path, "r"); |
|---|
| 693 | | $m1->setCoverImage($fp); |
|---|
| 694 | | $m1->save(); |
|---|
| 695 | | $m1->reload(); // refresh from db |
|---|
| 696 | | |
|---|
| 697 | | // Assert that we've updated the db |
|---|
| 698 | | $this->assertEquals(file_get_contents($blob_path), stream_get_contents($m1->getCoverImage()), "Expected the updated BLOB value after setting with a stream."); |
|---|
| 699 | | |
|---|
| 700 | | // 7) Assert that 'w' mode works |
|---|
| 701 | | |
|---|
| 702 | | } |
|---|
| 703 | | |
|---|
| 704 | | public function testLobSetting_WriteMode() |
|---|
| 705 | | { |
|---|
| 706 | | $blob_path = TESTS_BASE_DIR . '/etc/lob/tin_drum.gif'; |
|---|
| 707 | | $blob2_path = TESTS_BASE_DIR . '/etc/lob/propel.gif'; |
|---|
| 708 | | |
|---|
| 709 | | $clob_path = TESTS_BASE_DIR . '/etc/lob/tin_drum.txt'; |
|---|
| 710 | | $book = BookPeer::doSelectOne(new Criteria()); |
|---|
| 711 | | |
|---|
| 712 | | $m1 = new Media(); |
|---|
| 713 | | $m1->setBook($book); |
|---|
| 714 | | $m1->setCoverImage(file_get_contents($blob_path)); |
|---|
| 715 | | $m1->setExcerpt(file_get_contents($clob_path)); |
|---|
| 716 | | $m1->save(); |
|---|
| 717 | | |
|---|
| 718 | | MediaPeer::clearInstancePool(); |
|---|
| 719 | | |
|---|
| 720 | | // make sure we have the latest from the db: |
|---|
| 721 | | $m2 = MediaPeer::retrieveByPK($m1->getId()); |
|---|
| 722 | | |
|---|
| 723 | | // now attempt to assign a temporary stream, opened in 'w' mode, to the db |
|---|
| 724 | | |
|---|
| 725 | | $stream = fopen("php://memory", 'w'); |
|---|
| 726 | | fwrite($stream, file_get_contents($blob2_path)); |
|---|
| 727 | | $m2->setCoverImage($stream); |
|---|
| 728 | | $m2->save(); |
|---|
| 729 | | fclose($stream); |
|---|
| 730 | | |
|---|
| 731 | | $m2->reload(); |
|---|
| 732 | | $this->assertEquals(file_get_contents($blob2_path), stream_get_contents($m2->getCoverImage()), "Expected contents to match when setting stream w/ 'w' mode"); |
|---|
| 733 | | |
|---|
| 734 | | $stream2 = fopen("php://memory", 'w+'); |
|---|
| 735 | | fwrite($stream2, file_get_contents($blob_path)); |
|---|
| 736 | | rewind($stream2); |
|---|
| 737 | | $this->assertEquals(file_get_contents($blob_path), stream_get_contents($stream2), "Expecting setup to be correct"); |
|---|
| 738 | | |
|---|
| 739 | | $m2->setCoverImage($stream2); |
|---|
| 740 | | $m2->save(); |
|---|
| 741 | | $m2->reload(); |
|---|
| 742 | | |
|---|
| 743 | | $this->assertEquals(file_get_contents($blob_path), stream_get_contents($m2->getCoverImage()), "Expected contents to match when setting stream w/ 'w+' mode"); |
|---|
| 744 | | |
|---|
| 745 | | } |
|---|
| 746 | | |
|---|
| 747 | | |
|---|
| 837 | | |
|---|
| | 886 | |
|---|
| | 887 | /** |
|---|
| | 888 | * Test copying when an object has composite primary key. |
|---|
| | 889 | * @link http://propel.phpdb.org/trac/ticket/618 |
|---|
| | 890 | */ |
|---|
| | 891 | public function testCopy_CompositePK() |
|---|
| | 892 | { |
|---|
| | 893 | $br = new BookReader(); |
|---|
| | 894 | $br->setName("TestReader"); |
|---|
| | 895 | $br->save(); |
|---|
| | 896 | $br->copy(); |
|---|
| | 897 | |
|---|
| | 898 | $b = new Book(); |
|---|
| | 899 | $b->setTitle("TestBook"); |
|---|
| | 900 | $b->setISBN("XX-XX-XX-XX"); |
|---|
| | 901 | $b->save(); |
|---|
| | 902 | |
|---|
| | 903 | $op = new BookOpinion(); |
|---|
| | 904 | $op->setBookReader($br); |
|---|
| | 905 | $op->setBook($b); |
|---|
| | 906 | $op->setRating(10); |
|---|
| | 907 | $op->setRecommendToFriend(true); |
|---|
| | 908 | $op->save(); |
|---|
| | 909 | |
|---|
| | 910 | |
|---|
| | 911 | $br2 = $br->copy(true); |
|---|
| | 912 | |
|---|
| | 913 | $this->assertNull($br2->getId()); |
|---|
| | 914 | |
|---|
| | 915 | $opinions = $br2->getBookOpinions(); |
|---|
| | 916 | $this->assertEquals(1, count($opinions), "Expected to have a related BookOpinion after copy()"); |
|---|
| | 917 | |
|---|
| | 918 | // We DO expect the reader_id to be null |
|---|
| | 919 | $this->assertNull($opinions[0]->getReaderId()); |
|---|
| | 920 | // but we DO NOT expect the book_id to be null |
|---|
| | 921 | $this->assertEquals($op->getBookId(), $opinions[0]->getBookId()); |
|---|
| | 922 | } |
|---|
| | 923 | |
|---|
| | 924 | /** |
|---|
| | 925 | * Test the toArray() method with new lazyLoad param. |
|---|
| | 926 | * @link http://propel.phpdb.org/trac/ticket/527 |
|---|
| | 927 | */ |
|---|
| | 928 | public function testToArrayLazyLoad() |
|---|
| | 929 | { |
|---|
| | 930 | $c = new Criteria(); |
|---|
| | 931 | $c->add(MediaPeer::COVER_IMAGE, null, Criteria::NOT_EQUAL); |
|---|
| | 932 | $c->add(MediaPeer::EXCERPT, null, Criteria::NOT_EQUAL); |
|---|
| | 933 | |
|---|
| | 934 | $m = MediaPeer::doSelectOne($c); |
|---|
| | 935 | if ($m === null) { |
|---|
| | 936 | $this->fail("Test requires at least one media row w/ cover_image and excerpt NOT NULL"); |
|---|
| | 937 | } |
|---|
| | 938 | |
|---|
| | 939 | $arr1 = $m->toArray(BasePeer::TYPE_COLNAME); |
|---|
| | 940 | $this->assertNotNull($arr1[MediaPeer::COVER_IMAGE]); |
|---|
| | 941 | $this->assertType('resource', $arr1[MediaPeer::COVER_IMAGE]); |
|---|
| | 942 | |
|---|
| | 943 | $arr2 = $m->toArray(BasePeer::TYPE_COLNAME, false); |
|---|
| | 944 | $this->assertNull($arr2[MediaPeer::COVER_IMAGE]); |
|---|
| | 945 | $this->assertNull($arr2[MediaPeer::EXCERPT]); |
|---|
| | 946 | |
|---|
| | 947 | $diffKeys = array_keys(array_diff($arr1, $arr2)); |
|---|
| | 948 | |
|---|
| | 949 | $expectedDiff = array(MediaPeer::COVER_IMAGE, MediaPeer::EXCERPT); |
|---|
| | 950 | |
|---|
| | 951 | $this->assertEquals($expectedDiff, $diffKeys); |
|---|
| | 952 | } |
|---|
| | 953 | |
|---|
| | 954 | /** |
|---|
| | 955 | * Test regexp validator for ticket:542 |
|---|
| | 956 | * @link http://propel.phpdb.org/trac/ticket/542 |
|---|
| | 957 | */ |
|---|
| | 958 | public function testRegexValidator() |
|---|
| | 959 | { |
|---|
| | 960 | $b = new Bookstore(); |
|---|
| | 961 | $b->setWebsite("http://this.is.valid.com/foo.bar"); |
|---|
| | 962 | $res = $b->validate(); |
|---|
| | 963 | $this->assertTrue($res, "Expected URL to validate"); |
|---|
| | 964 | } |
|---|
| | 965 | |
|---|
| | 966 | /** |
|---|
| | 967 | * Test that setting the auto-increment primary key will result in exception. |
|---|
| | 968 | */ |
|---|
| | 969 | public function testSettingAutoIncrementPK() |
|---|
| | 970 | { |
|---|
| | 971 | $b = new Bookstore(); |
|---|
| | 972 | $b->setId(1); |
|---|
| | 973 | $b->setStoreName("Test"); |
|---|
| | 974 | try { |
|---|
| | 975 | $b->save(); |
|---|
| | 976 | $this->fail("Expected setting auto-increment primary key to result in Exception"); |
|---|
| | 977 | } catch (Exception $x) { |
|---|
| | 978 | $this->assertType('PropelException', $x); |
|---|
| | 979 | } |
|---|
| | 980 | |
|---|
| | 981 | // ... but we should silently ignore NULL values, since these are really |
|---|
| | 982 | // the same as "not set" in PHP world. |
|---|
| | 983 | $b = new Bookstore(); |
|---|
| | 984 | $b->setId(null); |
|---|
| | 985 | $b->setStoreName("Test2"); |
|---|
| | 986 | try { |
|---|
| | 987 | $b->save(); |
|---|
| | 988 | } catch (Exception $x) { |
|---|
| | 989 | $this->fail("Expected no exception when setting auto-increment primary key to NULL"); |
|---|
| | 990 | } |
|---|
| | 991 | // success ... |
|---|
| | 992 | } |
|---|
| | 993 | |
|---|
| | 994 | /** |
|---|
| | 995 | * Checks wether we are allowed to specify the primary key on a |
|---|
| | 996 | * table with allowPkInsert=true set |
|---|
| | 997 | * |
|---|
| | 998 | * saves the object, gets it from data-source again and then compares |
|---|
| | 999 | * them for equality (thus the instance pool is also checked) |
|---|
| | 1000 | */ |
|---|
| | 1001 | public function testAllowPkInsertOnIdMethodNativeTable() |
|---|
| | 1002 | { |
|---|
| | 1003 | $cu = new Customer; |
|---|
| | 1004 | $cu->setPrimaryKey(100000); |
|---|
| | 1005 | |
|---|
| | 1006 | $cu->save(); |
|---|
| | 1007 | |
|---|
| | 1008 | $cu2 = CustomerPeer::retrieveByPk(100000); |
|---|
| | 1009 | |
|---|
| | 1010 | $this->assertSame($cu, $cu2); |
|---|
| | 1011 | } |
|---|
| | 1012 | /** |
|---|
| | 1013 | * Checks if it is allowed to save new, empty objects with a auto increment column |
|---|
| | 1014 | */ |
|---|
| | 1015 | public function testAllowEmptyWithAutoIncrement() |
|---|
| | 1016 | { |
|---|
| | 1017 | $bookreader = new BookReader(); |
|---|
| | 1018 | $bookreader->save(); |
|---|
| | 1019 | |
|---|
| | 1020 | $this->assertFalse($bookreader->isNew() ); |
|---|
| | 1021 | } |
|---|