Yaffs site version 1.1
[yaffs-website] / vendor / gabordemooij / redbean / testing / RedUNIT / Base / Foreignkeys.php
diff --git a/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Foreignkeys.php b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Foreignkeys.php
new file mode 100644 (file)
index 0000000..c2d28b5
--- /dev/null
@@ -0,0 +1,439 @@
+<?php
+
+namespace RedUNIT\Base;
+
+use RedUNIT\Base as Base;
+use RedBeanPHP\Facade as R;
+use RedBeanPHP\Observer as Observer;
+use RedBeanPHP\OODBBean as OODBBean;
+use RedBeanPHP\Adapter as Adapter;
+use RedBeanPHP\QueryWriter\AQueryWriter as AQueryWriter;
+
+/**
+ * Foreignkeys
+ *
+ * Tests whether foreign keys are correctly generated and whether
+ * depending beans are correctly removed. Also tests auto resolving
+ * types inferred by inspecting foreign keys.
+ *
+ * @file    RedUNIT/Base/Foreignkeys.php
+ * @desc    Tests foreign key handling and dynamic foreign keys with
+ * @author  Gabor de Mooij and the RedBeanPHP Community
+ * @license New BSD/GPLv2
+ *
+ * (c) G.J.G.T. (Gabor) de Mooij and the RedBeanPHP Community.
+ * This source file is subject to the New BSD/GPLv2 License that is bundled
+ * with this source code in the file license.txt.
+ */
+class Foreignkeys extends Base implements Observer
+{
+       /**
+        * To log the queries
+        *
+        * @var array
+        */
+       private $queries = array();
+
+       /**
+        * Test whether aliases are not used if not necessary:
+        * when using fetchAs() or R::aliases().
+        *
+        * @return void
+        */
+       public function testAutoResolvAvoid()
+       {
+               R::setAutoResolve( TRUE );
+               R::nuke();
+               $book = R::dispense( 'book' );
+               $page = R::dispense( 'page' );
+               $book->cover = $page;
+               R::store( $book );
+               $book = $book->fresh();
+               asrt( $book->getMeta('sys.autoresolved.cover'), NULL );
+               $book->cover;
+               asrt( $book->getMeta('sys.autoresolved.cover'), 'page' );
+               R::nuke();
+               $book = R::dispense( 'book' );
+               $page = R::dispense( 'page' );
+               $book->cover = $page;
+               R::store( $book );
+               $book = $book->fresh();
+               asrt( $book->getMeta('sys.autoresolved.cover'), NULL );
+               $book->fetchAs('page')->cover;
+               asrt( $book->getMeta('sys.autoresolved.cover'), NULL );
+               R::nuke();
+               R::aliases( array( 'cover' => 'page' ) );
+               $book = R::dispense( 'book' );
+               $page = R::dispense( 'page' );
+               $book->cover = $page;
+               R::store( $book );
+               $book = $book->fresh();
+               asrt( $book->getMeta('sys.autoresolved.cover'), NULL );
+               $cover = $book->cover;
+               asrt( ( $cover instanceof OODBBean ), TRUE );
+               asrt( $cover->getMeta( 'type' ), 'page' );
+               asrt( $book->getMeta('sys.autoresolved.cover'), NULL );
+               R::aliases( array() );
+               R::nuke();
+               R::setAutoResolve( FALSE );
+               $book = R::dispense( 'book' );
+               $page = R::dispense( 'page' );
+               $book->cover = $page;
+               R::store( $book );
+               $book = $book->fresh();
+               asrt( $book->getMeta('sys.autoresolved.cover'), NULL );
+               $book->cover;
+               asrt( $book->getMeta('sys.autoresolved.cover'), NULL );
+               R::setAutoResolve( TRUE );
+       }
+
+       /**
+        * Test whether unique constraints are properly created using
+        * reflection.
+        *
+        * @return void
+        */
+       public function testUniqueInspect()
+       {
+               $writer = R::getWriter();
+               R::nuke();
+               $book = R::dispense( 'book' );
+               $category = R::dispense( 'category' );
+               $book->sharedCategory[] = $category;
+               R::store( $book );
+               asrt( count( get_uniques_for_type('book_category') ), 1 );
+               asrt( are_cols_in_unique( 'book_category', array( 'book_id', 'category_id' ) ), TRUE );
+               R::nuke();
+               $book = R::dispense( 'book' );
+               $category = R::dispense( 'category' );
+               $book->via( 'library' )->sharedCategory[] = $category;
+               R::store( $book );
+               asrt( count( get_uniques_for_type('book_category') ), 0 );
+               asrt( are_cols_in_unique( 'book_category', array( 'book_id', 'category_id' ) ), FALSE );
+               asrt( count( get_uniques_for_type('library') ), 1 );
+               asrt( are_cols_in_unique( 'library', array( 'book_id', 'category_id' ) ), TRUE );
+               AQueryWriter::clearRenames();
+               R::nuke();
+               $book = R::dispense( 'book' );
+               $category = R::dispense( 'category' );
+               $book->sharedCategory[] = $category;
+               R::store( $book );
+               asrt( count( get_uniques_for_type('book_category') ), 1 );
+               asrt( are_cols_in_unique( 'book_category', array( 'book_id', 'category_id' ) ), TRUE );
+               asrt( count( get_uniques_for_type('library') ), 0 );
+               asrt( are_cols_in_unique( 'library', array( 'book_id', 'category_id' ) ), FALSE );
+               R::nuke();
+               $book = R::dispense( 'book' );
+               $book2 = R::dispense( 'book' );
+               $book->sharedBook[] = $book2;
+               R::store( $book );
+               asrt( count( get_uniques_for_type('book_book') ), 1 );
+               asrt( are_cols_in_unique( 'book_book', array( 'book_id', 'book2_id' ) ), TRUE );
+               try {
+                       $result = R::getWriter()->addUniqueConstraint( 'nonexistant', array( 'a', 'b' ) );
+               } catch( \Exception $e ) {
+                       print_r( $e ); exit;
+               }
+               pass(); //dont crash!
+               asrt( $result, FALSE );
+       }
+
+       /**
+        * Tests foreign keys but checks using ProxyWriter.
+        *
+        * @return void
+        */
+       public function testFKInspect()
+       {
+               $faultyWriter = new \FaultyWriter( R::getDatabaseAdapter() );
+               try {
+                       $null = \ProxyWriter::callMethod( $faultyWriter, 'getForeignKeyForTypeProperty', 'test', 'test' );
+                       pass();
+               } catch( \Exception $e ) {
+                       fail();
+               }
+               asrt( is_null( $null ), TRUE );
+               $writer = R::getWriter();
+               R::nuke();
+               $book = R::dispense( 'book' );
+               $page = R::dispense( 'page' );
+               $book->xownPage[] = $page;
+               R::store( $book );
+               $keys = \ProxyWriter::callMethod( $writer, 'getForeignKeyForTypeProperty', 'page', 'book_id' );
+               asrt( is_array( $keys ), TRUE );
+               asrt( $keys['on_delete'], 'CASCADE' );
+               $keys = \ProxyWriter::callMethod( $writer, 'getForeignKeyForTypeProperty', 'page', 'id' );
+               asrt( is_null( $keys ), TRUE );
+               R::nuke();
+               $book = R::dispense( 'book' );
+               $page = R::dispense( 'page' );
+               $book->ownPage[] = $page;
+               R::store( $book );
+               $keys = \ProxyWriter::callMethod( $writer, 'getForeignKeyForTypeProperty', 'page', 'book_id' );
+               asrt( is_array( $keys ), TRUE );
+               asrt( $keys['on_delete'], 'SET NULL' );
+               $keys = \ProxyWriter::callMethod( $writer, 'getForeignKeyForTypeProperty', 'page', 'id' );
+               asrt( is_null( $keys ), TRUE );
+               R::nuke();
+               $book = R::dispense( 'book' );
+               $page = R::dispense( 'page' );
+               $book->alias('magazine')->xownPage[] = $page;
+               R::store( $book );
+               $keys = \ProxyWriter::callMethod( $writer, 'getForeignKeyForTypeProperty', 'page', 'magazine_id' );
+               asrt( is_array( $keys ), TRUE );
+               asrt( $keys['on_delete'], 'CASCADE' );
+               $keys = \ProxyWriter::callMethod( $writer, 'getForeignKeyForTypeProperty', 'page', 'book_id' );
+               asrt( is_null( $keys ), TRUE );
+               $keys = \ProxyWriter::callMethod( $writer, 'getForeignKeyForTypeProperty', 'page', 'id' );
+               asrt( is_null( $keys ), TRUE );
+               R::nuke();
+               $book = R::dispense( 'book' );
+               $page = R::dispense( 'page' );
+               $book->cover= $page;
+               R::store( $book );
+               $keys = \ProxyWriter::callMethod( $writer, 'getForeignKeyForTypeProperty', 'book', 'cover_id' );
+               asrt( is_array( $keys ), TRUE );
+               asrt( $keys['on_delete'], 'SET NULL' );
+               $keys = \ProxyWriter::callMethod( $writer, 'getForeignKeyForTypeProperty', 'book', 'page_id' );
+               asrt( is_null( $keys ), TRUE );
+               $keys = \ProxyWriter::callMethod( $writer, 'getForeignKeyForTypeProperty', 'book', 'id' );
+               asrt( is_null( $keys ), TRUE );
+               R::nuke();
+               $book = R::dispense( 'book' );
+               $category = R::dispense( 'category' );
+               $book->sharedTag[] = $category;
+               R::store( $book );
+               $keys = \ProxyWriter::callMethod( $writer, 'getForeignKeyForTypeProperty', 'book_category', 'book_id' );
+               asrt( is_array( $keys ), TRUE );
+               $keys = \ProxyWriter::callMethod( $writer, 'getForeignKeyForTypeProperty', 'book_category', 'category_id' );
+               asrt( is_array( $keys ), TRUE );
+               $keys = \ProxyWriter::callMethod( $writer, 'getForeignKeyForTypeProperty', 'book_category', 'id' );
+               asrt( is_null( $keys ), TRUE );
+       }
+
+       /**
+        * Test dependencies.
+        *
+        * @return void
+        */
+       public function testDependency()
+       {
+               $can = $this->createBeanInCan( FALSE );
+
+               asrt( R::count( 'bean' ), 1 );
+
+               R::trash( $can );
+
+               // Bean stays
+               asrt( R::count( 'bean' ), 1 );
+       }
+
+       /**
+        * Test dependencies (variation).
+        *
+        * @return void
+        */
+       public function testDependency2()
+       {
+               $can = $this->createBeanInCan( TRUE );
+
+               asrt( R::count( 'bean' ), 1 );
+
+               R::trash( $can );
+
+               // Bean gone
+               asrt( R::count( 'bean' ), 0 );
+
+               $can = $this->createBeanInCan( FALSE );
+
+               asrt( R::count( 'bean' ), 1 );
+
+               R::trash( $can );
+
+               // Bean stays, constraint removed
+               asrt( R::count( 'bean' ), 0 );
+
+               //need to recreate table to get rid of constraint!
+               R::nuke();
+
+               $can = $this->createBeanInCan( FALSE );
+
+               asrt( R::count( 'bean' ), 1 );
+
+               R::trash( $can );
+
+               // Bean stays, constraint removed
+               asrt( R::count( 'bean' ), 1 );
+
+       }
+
+       /**
+        * Tests dependencies (variation).
+        *
+        * @return void
+        */
+       public function testDependency3()
+       {
+               R::nuke();
+
+               $can = $this->createCanForBean();
+
+               asrt( R::count( 'bean' ), 1 );
+
+               R::trash( $can );
+
+               asrt( R::count( 'bean' ), 1 );
+       }
+
+       /**
+        * Tests dependencies (variation).
+        *
+        * @return void
+        */
+       public function testDependency4()
+       {
+               R::nuke();
+
+               $can = $this->createBeanInCan( TRUE );
+
+               R::store( $can );
+
+               R::trash( $can );
+
+               $can = $this->createCanForBean();
+
+               asrt( R::count( 'bean' ), 1 );
+
+               R::trash( $can );
+
+               asrt( R::count( 'bean' ), 0 );
+
+               $can = $this->createBeanInCan( TRUE );
+
+               R::store( $can );
+
+               R::trash( $can );
+
+               $can = $this->createCanForBean();
+
+               asrt( R::count( 'bean' ), 1 );
+
+               R::trash( $can );
+
+               asrt( R::count( 'bean' ), 0 );
+       }
+
+       /**
+        * Issue #171
+        * The index name argument is not unique in processEmbeddedBean etc.
+        *
+        * @return void
+        */
+       public function testIssue171()
+       {
+               R::getDatabaseAdapter()->addEventListener( 'sql_exec', $this );
+
+               $account = R::dispense( 'account' );
+               $user    = R::dispense( 'user' );
+               $player  = R::dispense( 'player' );
+
+               $account->ownUser[] = $user;
+
+               R::store( $account );
+
+               asrt( strpos( implode( ',', $this->queries ), 'index_foreignkey_user_account' ) !== FALSE, TRUE );
+
+               $this->queries = array();
+
+               $account->ownPlayer[] = $player;
+
+               R::store( $account );
+
+               asrt( strpos( implode( ',', $this->queries ), 'index_foreignkey_player_accou' ) !== FALSE, TRUE );
+       }
+
+       /**
+        * Tests whether foreign keys are created correctly for certain
+        * relations.
+        *
+        * @return void
+        */
+       public function testCreationOfForeignKeys()
+       {
+               $this->queries = array();
+
+               $account = R::dispense( 'account' );
+               $user    = R::dispense( 'user' );
+               $player  = R::dispense( 'player' );
+
+               $user->account = $account;
+
+               R::store( $user );
+
+               asrt( strpos( implode( ',', $this->queries ), 'index_foreignkey_user_account' ) !== FALSE, TRUE );
+
+               $this->queries = array();
+
+               $player->account = $account;
+
+               R::store( $player );
+
+               asrt( strpos( implode( ',', $this->queries ), 'index_foreignkey_player_accou' ) !== FALSE, TRUE );
+       }
+
+       /**
+        * Test helper method.
+        * Creates a bean in a can. The bean will get a reference
+        * to the can and can be made dependent.
+        *
+        * @return OODBBean $can
+        */
+       private function createBeanInCan( $isExcl )
+       {
+               $can  = R::dispense( 'can' );
+               $bean = R::dispense( 'bean' );
+
+               $can->name   = 'bakedbeans';
+               $bean->taste = 'salty';
+
+               if ($isExcl) {
+                       $can->xownBean[] = $bean;
+               } else {
+                       $can->ownBean[] = $bean;
+               }
+
+               R::store( $can );
+
+               return $can;
+       }
+
+       /**
+        * Test helper method.
+        * Creates a bean in a can beginning with the bean. The bean will get a reference
+        * to the can and can be made dependent.
+        *
+        * @return OODBBean $can
+        */
+       private function createCanForBean()
+       {
+               $can  = R::dispense( 'can' );
+               $bean = R::dispense( 'bean' );
+
+               $bean->can = $can;
+
+               R::store( $bean );
+
+               return $can;
+       }
+
+       /**
+        * Log queries
+        *
+        * @param string          $event
+        * @param Adapter $info
+        */
+       public function onEvent( $event, $info )
+       {
+               $this->queries[] = $info->getSQL();
+       }
+}