Browse Source

Merge remote-tracking branch 'origin/2.0' into 2.0-merge

Conflicts:
	lib/Cake/Test/Case/Console/Command/Task/TemplateTaskTest.php
	lib/Cake/Test/Case/Controller/Component/Auth/FormAuthenticate.php
	lib/Cake/Test/Case/Log/Engine/FileLog.php
	lib/Cake/Test/test_app/Plugin/TestPlugin/View/Helper/plugged_helper.php
	lib/Cake/Test/test_app/Plugin/TestPlugin/View/Helper/test_plugin_app.php
	lib/Cake/tests/Case/Controller/Component/Auth/FormAuthenticate.php
	lib/Cake/tests/Case/Controller/Component/Auth/FormAuthenticateTest.php
	lib/Cake/tests/Case/Log/Engine/FileLog.php
	lib/Cake/tests/Case/Log/Engine/FileLogTest.php
	lib/Cake/tests/test_app/plugins/test_plugin/View/Helper/PluggedHelper.php
	lib/Cake/tests/test_app/plugins/test_plugin/View/Helper/TestPluginAppHelper.php
	lib/Cake/tests/test_app/plugins/test_plugin/View/Helper/plugged_helper.php
	lib/Cake/tests/test_app/plugins/test_plugin/View/Helper/test_plugin_app.php
Jose Lorenzo Rodriguez 15 years ago
parent
commit
91bce16e9d

+ 1 - 0
app/Config/core.php

@@ -279,6 +279,7 @@
  * 		'servers' => array(
  * 			'127.0.0.1:11211' // localhost, default port 11211
  * 		), //[optional]
+ * 		'persistent' => true, // [optional] set this to false for non-persistent connections
  * 		'compress' => false, // [optional] compress data in Memcache (slower, but uses less memory)
  *	));
  *

+ 2 - 1
lib/Cake/Cache/Engine/MemcacheEngine.php

@@ -64,6 +64,7 @@ class MemcacheEngine extends CacheEngine {
 			'engine'=> 'Memcache',
 			'prefix' => Inflector::slug(APP_DIR) . '_',
 			'servers' => array('127.0.0.1'),
+			'persistent' => true,
 			'compress'=> false
 			), $settings)
 		);
@@ -79,7 +80,7 @@ class MemcacheEngine extends CacheEngine {
 			$this->_Memcache = new Memcache();
 			foreach ($this->settings['servers'] as $server) {
 				list($host, $port) = $this->_parseServerString($server);
-				if ($this->_Memcache->addServer($host, $port)) {
+				if ($this->_Memcache->addServer($host, $port, $this->settings['persistent'])) {
 					$return = true;
 				}
 			}

+ 1 - 1
lib/Cake/Console/ShellDispatcher.php

@@ -141,7 +141,7 @@ class ShellDispatcher {
 		set_error_handler(array('ConsoleErrorHandler', 'handleError'), Configure::read('Error.level'));
 
 		if (!defined('FULL_BASE_URL')) {
-			define('FULL_BASE_URL', '/');
+			define('FULL_BASE_URL', 'http://localhost');
 		}
 
 		return true;

+ 1 - 0
lib/Cake/Console/templates/skel/Config/core.php

@@ -279,6 +279,7 @@
  * 		'servers' => array(
  * 			'127.0.0.1:11211' // localhost, default port 11211
  * 		), //[optional]
+ * 		'persistent' => true, // [optional] set this to false for non-persistent connections
  * 		'compress' => false, // [optional] compress data in Memcache (slower, but uses less memory)
  *	));
  *

+ 5 - 19
lib/Cake/Controller/Component/AuthComponent.php

@@ -41,13 +41,6 @@ class AuthComponent extends Component {
 	const ALL = 'all';
 
 /**
- * Maintains current user login state.
- *
- * @var boolean
- */
-	protected $_loggedIn = false;
-
-/**
  * Other components utilized by AuthComponent
  *
  * @var array
@@ -511,16 +504,14 @@ class AuthComponent extends Component {
  */
 	public function login($user = null) {
 		$this->__setDefaults();
-		$this->_loggedIn = false;
 
 		if (empty($user)) {
 			$user = $this->identify($this->request, $this->response);
 		}
 		if ($user) {
 			$this->Session->write(self::$sessionKey, $user);
-			$this->_loggedIn = true;
 		}
-		return $this->_loggedIn;
+		return $this->loggedIn();
 	}
 
 /**
@@ -535,7 +526,6 @@ class AuthComponent extends Component {
 		$this->__setDefaults();
 		$this->Session->delete(self::$sessionKey);
 		$this->Session->delete('Auth.redirect');
-		$this->_loggedIn = false;
 		return Router::normalize($this->logoutRedirect);
 	}
 
@@ -679,23 +669,19 @@ class AuthComponent extends Component {
  * @param object $controller Instantiating controller
  */
 	public function shutdown($controller) {
-		if ($this->_loggedIn) {
+		if ($this->loggedIn()) {
 			$this->Session->delete('Auth.redirect');
 		}
 	}
 
 /**
- * Sets or gets whether the user is logged in
+ * Check whether or not the current user has data in the session, and is considered logged in.
  *
- * @param boolean $logged sets the status of the user, true to logged in, false to logged out
  * @return boolean true if the user is logged in, false otherwise
  * @access public
  */
-	public function loggedIn($logged = null) {
-		if (!is_null($logged)) {
-			$this->_loggedIn = $logged;
-		}
-		return $this->_loggedIn;
+	public function loggedIn() {
+		return $this->user() != array();
 	}
 
 /**

+ 4 - 2
lib/Cake/Routing/Router.php

@@ -1013,9 +1013,11 @@ class Router {
  * are used for CakePHP internals and should not normally be part of an output url.
  *
  * @param mixed $param The params array or CakeRequest object that needs to be reversed.
+ * @param boolean $full Set to true to include the full url including the protocol when reversing
+ *     the url.
  * @return string The string that is the reversed result of the array
  */
-	public static function reverse($params) {
+	public static function reverse($params, $full = false) {
 		if ($params instanceof CakeRequest) {
 			$url = $params->query;
 			$params = $params->params;
@@ -1033,7 +1035,7 @@ class Router {
 		if (!empty($url)) {
 			$params['?'] = $url;
 		}
-		return Router::url($params);
+		return Router::url($params, $full);
 	}
 
 /**

+ 2 - 1
lib/Cake/Test/Case/Cache/Engine/MemcacheTest.php

@@ -50,7 +50,7 @@ class MemcacheEngineTest extends CakeTestCase {
  * @return void
  */
 	function setUp() {
-		$this->skipIf(!class_exists('Memcache'), '%s Apc is not installed or configured properly');
+		$this->skipIf(!class_exists('Memcache'), '%s Memcache is not installed or configured properly');
 		$this->_cacheDisable = Configure::read('Cache.disable');
 		Configure::write('Cache.disable', false);
 		Cache::config('memcache', array(
@@ -86,6 +86,7 @@ class MemcacheEngineTest extends CakeTestCase {
 			'duration'=> 3600,
 			'probability' => 100,
 			'servers' => array('127.0.0.1'),
+			'persistent' => true,
 			'compress' => false,
 			'engine' => 'Memcache'
 		);

+ 2 - 2
lib/Cake/Test/Case/Console/Command/Task/TemplateTaskTest.php

@@ -126,7 +126,7 @@ class TemplateTaskTest extends CakeTestCase {
 	public function testGenerate() {
 		App::build(array(
 			'Console' => array(
-				LIBS . 'Test' . DS .  'test_app' . DS . 'console' . DS
+				LIBS . 'Test' . DS .  'test_app' . DS . 'Console' . DS
 			)
 		));
 		$this->Task->initialize();
@@ -146,7 +146,7 @@ class TemplateTaskTest extends CakeTestCase {
 	public function testGenerateWithTemplateFallbacks() {
 		App::build(array(
 			'Console' => array(
-				LIBS . 'Test' . DS .  'test_app' . DS . 'console' . DS,
+				LIBS . 'Test' . DS .  'test_app' . DS . 'Console' . DS,
 				CAKE_CORE_INCLUDE_PATH . DS . 'console' . DS
 			)
 		));

+ 1 - 1
lib/Cake/Test/Case/Controller/Component/AuthComponentTest.php

@@ -1007,7 +1007,7 @@ class AuthTest extends CakeTestCase {
  * @return void
  */
 	function testShutDown() {
-		$this->Controller->Auth->initialize($this->Controller, array('_loggedIn' => true));
+		$this->Auth->Session->write('Auth.User', 'not empty');
 		$this->Auth->Session->write('Auth.redirect', 'foo');
 		$this->Controller->Auth->loggedIn(true);
 

File diff suppressed because it is too large
+ 18 - 1841
lib/Cake/Test/Case/Model/Behavior/TreeBehaviorTest.php


+ 4 - 4
lib/Cake/Test/Case/Model/Datasource/Database/MssqlTest.php

@@ -17,10 +17,10 @@
  * @license       MIT License (http://www.opensource.org/licenses/mit-license.php)
  */
 
-require_once LIBS.'model'.DS.'model.php';
-require_once LIBS.'model'.DS.'datasources'.DS.'datasource.php';
-require_once LIBS.'model'.DS.'datasources'.DS.'dbo_source.php';
-require_once LIBS.'model'.DS.'datasources'.DS.'dbo'.DS.'dbo_mssql.php';
+require_once LIBS.'Model'.DS.'Model.php';
+require_once LIBS.'Model'.DS.'Datasource'.DS.'DataSource.php';
+require_once LIBS.'Model'.DS.'Datasource'.DS.'DboSource.php';
+require_once LIBS.'Model'.DS.'Datasource'.DS.'Database'.DS.'Mssql.php';
 
 /**
  * DboMssqlTestDb class

+ 11 - 0
lib/Cake/Test/Case/Routing/RouterTest.php

@@ -2337,6 +2337,17 @@ class RouterTest extends CakeTestCase {
 		$result = Router::reverse($request);
 		$expected = '/eng/posts/view/1?test=value';
 		$this->assertEquals($expected, $result);
+
+		$params = array(
+			'lang' => 'eng',
+			'controller' => 'posts',
+			'action' => 'view',
+			'pass' => array(1),
+			'named' => array(),
+			'url' => array('url' => 'eng/posts/view/1')
+		);
+		$result = Router::reverse($params, true);
+		$this->assertPattern('/^http(s)?:\/\//', $result);
 	}
 
 /**

+ 1 - 0
lib/Cake/Test/Case/TestSuite/HtmlCoverageReportTest.php

@@ -18,6 +18,7 @@
  */
 
 App::uses('HtmlCoverageReport', 'TestSuite/Coverage');
+App::uses('CakeBaseReporter', 'TestSuite/Reporter');
 
 class HtmlCoverageReportTest extends CakeTestCase {
 /**

lib/Cake/Test/test_app/Plugin/TestPlugin/View/Helper/plugged_helper.php → lib/Cake/Test/test_app/Plugin/TestPlugin/View/Helper/PluggedHelperHelper.php


lib/Cake/Test/test_app/Plugin/TestPlugin/View/Helper/test_plugin_app.php → lib/Cake/Test/test_app/Plugin/TestPlugin/View/Helper/TestPLuginApp.php


+ 8 - 4
lib/Cake/View/Helper/FormHelper.php

@@ -1287,9 +1287,10 @@ class FormHelper extends AppHelper {
 	}
 
 /**
- * Create a `<button>` tag with `<form>` using POST method.
+ * Create a `<button>` tag with a surrounding `<form>` that submits via POST.
  *
- * This method creates an element <form>. So do not use this method in some opened form.
+ * This method creates a `<form>` element. So do not use this method in some opened form.
+ * Instead use FormHelper::submit() or FormHelper::button() to create buttons inside opened forms.
  *
  * ### Options:
  *
@@ -1315,13 +1316,16 @@ class FormHelper extends AppHelper {
 	}
 
 /**
- * Creates an HTML link, but access the url using method POST. Requires javascript enabled in browser.
+ * Creates an HTML link, but access the url using method POST. 
+ * Requires javascript to be enabled in browser.
  *
- * This method creates an element <form>. So do not use this method in some opened form.
+ * This method creates a `<form>` element. So do not use this method inside an existing form.
+ * Instead you should add a submit button using FormHelper::submit()
  *
  * ### Options:
  *
  * - `data` - Array with key/value to pass in input hidden
+ * - `confirm` - Can be used instead of $confirmMessage.
  * - Other options is the same of HtmlHelper::link() method.
  * - The option `onclick` will be replaced.
  *

+ 80 - 0
lib/Cake/tests/Case/Model/Behavior/TreeBehaviorAfterTest.php

@@ -0,0 +1,80 @@
+<?php
+/**
+ * TreeBehaviorAfterTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/view/1196/Testing>
+ * Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright     Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link          http://book.cakephp.org/view/1196/Testing CakePHP(tm) Tests
+ * @package       cake.tests.cases.libs.model.behaviors
+ * @since         CakePHP(tm) v 1.2.0.5330
+ * @license       MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('Model', 'Model');
+App::uses('AppModel', 'Model');
+require_once(dirname(dirname(__FILE__)) . DS . 'models.php');
+
+
+/**
+ * TreeBehaviorAfterTest class
+ *
+ * @package       cake.tests.cases.libs.model.behaviors
+ */
+class TreeBehaviorAfterTest extends CakeTestCase {
+
+/**
+ * Whether backup global state for each test method or not
+ *
+ * @var bool false
+ * @access public
+ */
+	public $backupGlobals = false;
+
+/**
+ * settings property
+ *
+ * @var array
+ * @access public
+ */
+	public $settings = array(
+		'modelClass' => 'AfterTree',
+		'leftField' => 'lft',
+		'rightField' => 'rght',
+		'parentField' => 'parent_id'
+	);
+
+/**
+ * fixtures property
+ *
+ * @var array
+ * @access public
+ */
+	public $fixtures = array('core.after_tree');
+
+/**
+ * Tests the afterSave callback in the model
+ *
+ * @access public
+ * @return void
+ */
+	function testAftersaveCallback() {
+		$this->Tree = new AfterTree();
+
+		$expected = array('AfterTree' => array('name' => 'Six and One Half Changed in AfterTree::afterSave() but not in database', 'parent_id' => 6, 'lft' => 11, 'rght' => 12));
+		$result = $this->Tree->save(array('AfterTree' => array('name' => 'Six and One Half', 'parent_id' => 6)));
+		$this->assertEqual($result, $expected);
+
+		$expected = array('AfterTree' => array('name' => 'Six and One Half', 'parent_id' => 6, 'lft' => 11, 'rght' => 12, 'id' => 8));
+		$result = $this->Tree->find('all');
+		$this->assertEqual($result[7], $expected);
+	}
+}
+
+

File diff suppressed because it is too large
+ 1277 - 0
lib/Cake/tests/Case/Model/Behavior/TreeBehaviorNumberTest.php


+ 324 - 0
lib/Cake/tests/Case/Model/Behavior/TreeBehaviorScopedTest.php

@@ -0,0 +1,324 @@
+<?php
+/**
+ * TreeBehaviorScopedTest file
+ *
+ * A tree test using scope
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/view/1196/Testing>
+ * Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright     Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link          http://book.cakephp.org/view/1196/Testing CakePHP(tm) Tests
+ * @package       cake.tests.cases.libs.model.behaviors
+ * @since         CakePHP(tm) v 1.2.0.5330
+ * @license       MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('Model', 'Model');
+App::uses('AppModel', 'Model');
+require_once(dirname(dirname(__FILE__)) . DS . 'models.php');
+
+/**
+ * TreeBehaviorScopedTest class
+ *
+ * @package       cake.tests.cases.libs.model.behaviors
+ */
+class TreeBehaviorScopedTest extends CakeTestCase {
+
+/**
+ * Whether backup global state for each test method or not
+ *
+ * @var bool false
+ * @access public
+ */
+	public $backupGlobals = false;
+
+/**
+ * settings property
+ *
+ * @var array
+ * @access public
+ */
+	public $settings = array(
+		'modelClass' => 'FlagTree',
+		'leftField' => 'lft',
+		'rightField' => 'rght',
+		'parentField' => 'parent_id'
+	);
+
+/**
+ * fixtures property
+ *
+ * @var array
+ * @access public
+ */
+	public $fixtures = array('core.flag_tree', 'core.ad', 'core.campaign', 'core.translate', 'core.number_tree_two');
+
+/**
+ * testStringScope method
+ *
+ * @access public
+ * @return void
+ */
+	function testStringScope() {
+		$this->Tree = new FlagTree();
+		$this->Tree->initialize(2, 3);
+
+		$this->Tree->id = 1;
+		$this->Tree->saveField('flag', 1);
+		$this->Tree->id = 2;
+		$this->Tree->saveField('flag', 1);
+
+		$result = $this->Tree->children();
+		$expected = array(
+			array('FlagTree' => array('id' => '3', 'name' => '1.1.1', 'parent_id' => '2', 'lft' => '3', 'rght' => '4', 'flag' => '0')),
+			array('FlagTree' => array('id' => '4', 'name' => '1.1.2', 'parent_id' => '2', 'lft' => '5', 'rght' => '6', 'flag' => '0')),
+			array('FlagTree' => array('id' => '5', 'name' => '1.1.3', 'parent_id' => '2', 'lft' => '7', 'rght' => '8', 'flag' => '0'))
+		);
+		$this->assertEqual($result, $expected);
+
+		$this->Tree->Behaviors->attach('Tree', array('scope' => 'FlagTree.flag = 1'));
+		$this->assertEqual($this->Tree->children(), array());
+
+		$this->Tree->id = 1;
+		$this->Tree->Behaviors->attach('Tree', array('scope' => 'FlagTree.flag = 1'));
+
+		$result = $this->Tree->children();
+		$expected = array(array('FlagTree' => array('id' => '2', 'name' => '1.1', 'parent_id' => '1', 'lft' => '2', 'rght' => '9', 'flag' => '1')));
+		$this->assertEqual($result, $expected);
+
+		$this->assertTrue($this->Tree->delete());
+		$this->assertEqual($this->Tree->find('count'), 11);
+	}
+
+/**
+ * testArrayScope method
+ *
+ * @access public
+ * @return void
+ */
+	function testArrayScope() {
+		$this->Tree = new FlagTree();
+		$this->Tree->initialize(2, 3);
+
+		$this->Tree->id = 1;
+		$this->Tree->saveField('flag', 1);
+		$this->Tree->id = 2;
+		$this->Tree->saveField('flag', 1);
+
+		$result = $this->Tree->children();
+		$expected = array(
+			array('FlagTree' => array('id' => '3', 'name' => '1.1.1', 'parent_id' => '2', 'lft' => '3', 'rght' => '4', 'flag' => '0')),
+			array('FlagTree' => array('id' => '4', 'name' => '1.1.2', 'parent_id' => '2', 'lft' => '5', 'rght' => '6', 'flag' => '0')),
+			array('FlagTree' => array('id' => '5', 'name' => '1.1.3', 'parent_id' => '2', 'lft' => '7', 'rght' => '8', 'flag' => '0'))
+		);
+		$this->assertEqual($result, $expected);
+
+		$this->Tree->Behaviors->attach('Tree', array('scope' => array('FlagTree.flag' => 1)));
+		$this->assertEqual($this->Tree->children(), array());
+
+		$this->Tree->id = 1;
+		$this->Tree->Behaviors->attach('Tree', array('scope' => array('FlagTree.flag' => 1)));
+
+		$result = $this->Tree->children();
+		$expected = array(array('FlagTree' => array('id' => '2', 'name' => '1.1', 'parent_id' => '1', 'lft' => '2', 'rght' => '9', 'flag' => '1')));
+		$this->assertEqual($result, $expected);
+
+		$this->assertTrue($this->Tree->delete());
+		$this->assertEqual($this->Tree->find('count'), 11);
+	}
+
+/**
+ * testMoveUpWithScope method
+ *
+ * @access public
+ * @return void
+ */
+	function testMoveUpWithScope() {
+		$this->Ad = new Ad();
+		$this->Ad->Behaviors->attach('Tree', array('scope'=>'Campaign'));
+		$this->Ad->moveUp(6);
+
+		$this->Ad->id = 4;
+		$result = $this->Ad->children();
+		$this->assertEqual(Set::extract('/Ad/id', $result), array(6, 5));
+		$this->assertEqual(Set::extract('/Campaign/id', $result), array(2, 2));
+	}
+
+/**
+ * testMoveDownWithScope method
+ *
+ * @access public
+ * @return void
+ */
+	function testMoveDownWithScope() {
+		$this->Ad = new Ad();
+		$this->Ad->Behaviors->attach('Tree', array('scope' => 'Campaign'));
+		$this->Ad->moveDown(6);
+
+		$this->Ad->id = 4;
+		$result = $this->Ad->children();
+		$this->assertEqual(Set::extract('/Ad/id', $result), array(5, 6));
+		$this->assertEqual(Set::extract('/Campaign/id', $result), array(2, 2));
+	}
+
+/**
+ * Tests the interaction (non-interference) between TreeBehavior and other behaviors with respect
+ * to callback hooks
+ *
+ * @access public
+ * @return void
+ */
+	function testTranslatingTree() {
+		$this->Tree = new FlagTree();
+		$this->Tree->cacheQueries = false;
+		$this->Tree->Behaviors->attach('Translate', array('name'));
+
+		//Save
+		$this->Tree->locale = 'eng';
+		$data = array('FlagTree' => array(
+			'name' => 'name #1',
+			'locale' => 'eng',
+			'parent_id' => null,
+		));
+		$this->Tree->save($data);
+		$result = $this->Tree->find('all');
+		$expected = array(array('FlagTree' => array(
+			'id' => 1,
+			'name' => 'name #1',
+			'parent_id' => null,
+			'lft' => 1,
+			'rght' => 2,
+			'flag' => 0,
+			'locale' => 'eng',
+		)));
+		$this->assertEqual($result, $expected);
+
+		//update existing record, same locale
+		$this->Tree->create();
+		$data['FlagTree']['name'] = 'Named 2';
+		$this->Tree->id = 1;
+		$this->Tree->save($data);
+		$result = $this->Tree->find('all');
+		$expected = array(array('FlagTree' => array(
+			'id' => 1,
+			'name' => 'Named 2',
+			'parent_id' => null,
+			'lft' => 1,
+			'rght' => 2,
+			'flag' => 0,
+			'locale' => 'eng',
+		)));
+		$this->assertEqual($result, $expected);
+
+		//update different locale, same record
+		$this->Tree->create();
+		$this->Tree->locale = 'deu';
+		$this->Tree->id = 1;
+		$data = array('FlagTree' => array(
+			'id' => 1,
+			'parent_id' => null,
+			'name' => 'namen #1',
+			'locale' => 'deu',
+		));
+		$this->Tree->save($data);
+
+		$this->Tree->locale = 'deu';
+		$result = $this->Tree->find('all');
+		$expected = array(array('FlagTree' => array(
+			'id' => 1,
+			'name' => 'namen #1',
+			'parent_id' => null,
+			'lft' => 1,
+			'rght' => 2,
+			'flag' => 0,
+			'locale' => 'deu',
+		)));
+		$this->assertEqual($result, $expected);
+
+		//Save with bindTranslation
+		$this->Tree->locale = 'eng';
+		$data = array(
+			'name' => array('eng' => 'New title', 'spa' => 'Nuevo leyenda'),
+			'parent_id' => null
+		);
+		$this->Tree->create($data);
+		$this->Tree->save();
+
+		$this->Tree->unbindTranslation();
+		$translations = array('name' => 'Name');
+		$this->Tree->bindTranslation($translations, false);
+		$this->Tree->locale = array('eng', 'spa');
+
+		$result = $this->Tree->read();
+		$expected = array(
+			'FlagTree' => array('id' => 2, 'parent_id' => null, 'locale' => 'eng', 'name' => 'New title', 'flag' => 0, 'lft' => 3, 'rght' => 4),
+			'Name' => array(
+			array('id' => 21, 'locale' => 'eng', 'model' => 'FlagTree', 'foreign_key' => 2, 'field' => 'name', 'content' => 'New title'),
+			array('id' => 22, 'locale' => 'spa', 'model' => 'FlagTree', 'foreign_key' => 2, 'field' => 'name', 'content' => 'Nuevo leyenda')
+			),
+		);
+		$this->assertEqual($result, $expected);
+	}
+
+/**
+ * testGenerateTreeListWithSelfJoin method
+ *
+ * @return void
+ */
+	public function testAliasesWithScopeInTwoTreeAssociations() {
+		extract($this->settings);
+		$this->Tree = new $modelClass();
+		$this->Tree->initialize(2, 2);
+
+		$this->TreeTwo = new NumberTreeTwo();
+
+		$record = $this->Tree->find('first');
+
+		$this->Tree->bindModel(array(
+			'hasMany' => array(
+				'SecondTree' => array(
+					'className' => 'NumberTreeTwo',
+					'foreignKey' => 'number_tree_id'
+				)
+			)
+		));
+		$this->TreeTwo->bindModel(array(
+			'belongsTo' => array(
+				'FirstTree' => array(
+					'className' => $modelClass,
+					'foreignKey' => 'number_tree_id'
+				)
+			)
+		));
+		$this->TreeTwo->Behaviors->attach('Tree', array(
+			'scope' => 'FirstTree'
+		));
+
+		$data = array(
+			'NumberTreeTwo' => array(
+				'name' => 'First',
+				'number_tree_id' => $record['FlagTree']['id']
+			)
+		);
+		$this->TreeTwo->create();
+		$result = $this->TreeTwo->save($data);
+		$this->assertFalse(empty($result));
+
+		$result = $this->TreeTwo->find('first');
+		$expected = array('NumberTreeTwo' => array(
+			'id' => 1,
+			'name' => 'First',
+			'number_tree_id' => $record['FlagTree']['id'],
+			'parent_id' => null,
+			'lft' => 1,
+			'rght' => 2
+		));
+		$this->assertEqual($result, $expected);
+	}
+}

+ 258 - 0
lib/Cake/tests/Case/Model/Behavior/TreeBehaviorUuidTest.php

@@ -0,0 +1,258 @@
+<?php
+/**
+ * TreeBehaviorUuidTest file
+ *
+ * Tree test using UUIDs
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/view/1196/Testing>
+ * Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright     Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link          http://book.cakephp.org/view/1196/Testing CakePHP(tm) Tests
+ * @package       cake.tests.cases.libs.model.behaviors
+ * @since         CakePHP(tm) v 1.2.0.5330
+ * @license       MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('Model', 'Model');
+App::uses('AppModel', 'Model');
+require_once(dirname(dirname(__FILE__)) . DS . 'models.php');
+
+/**
+ * TreeBehaviorUuidTest class
+ *
+ * @package       cake.tests.cases.libs.model.behaviors
+ */
+class TreeBehaviorUuidTest extends CakeTestCase {
+
+/**
+ * Whether backup global state for each test method or not
+ *
+ * @var bool false
+ * @access public
+ */
+	public $backupGlobals = false;
+
+/**
+ * settings property
+ *
+ * @var array
+ * @access public
+ */
+	public $settings = array(
+		'modelClass' => 'UuidTree',
+		'leftField' => 'lft',
+		'rightField' => 'rght',
+		'parentField' => 'parent_id'
+	);
+
+/**
+ * fixtures property
+ *
+ * @var array
+ * @access public
+ */
+	public $fixtures = array('core.uuid_tree');
+
+/**
+ * testMovePromote method
+ *
+ * @return void
+ */
+	public function testMovePromote() {
+		extract($this->settings);
+		$this->Tree = new $modelClass();
+		$this->Tree->initialize(2, 2);
+		$this->Tree->id = null;
+
+		$parent = $this->Tree->find('first', array('conditions' => array($modelClass . '.name' => '1. Root')));
+		$parent_id = $parent[$modelClass]['id'];
+
+		$data = $this->Tree->find('first', array('fields' => array('id'), 'conditions' => array($modelClass . '.name' => '1.1.1')));
+		$this->Tree->id= $data[$modelClass]['id'];
+		$this->Tree->saveField($parentField, $parent_id);
+		$direct = $this->Tree->children($parent_id, true, array('name', $leftField, $rightField));
+		$expects = array(array($modelClass => array('name' => '1.1', $leftField => 2, $rightField => 5)),
+			array($modelClass => array('name' => '1.2', $leftField => 6, $rightField => 11)),
+			array($modelClass => array('name' => '1.1.1', $leftField => 12, $rightField => 13)));
+		$this->assertEqual($direct, $expects);
+		$validTree = $this->Tree->verify();
+		$this->assertIdentical($validTree, true);
+	}
+
+/**
+ * testMoveWithWhitelist method
+ *
+ * @return void
+ */
+	public function testMoveWithWhitelist() {
+		extract($this->settings);
+		$this->Tree = new $modelClass();
+		$this->Tree->initialize(2, 2);
+		$this->Tree->id = null;
+
+		$parent = $this->Tree->find('first', array('conditions' => array($modelClass . '.name' => '1. Root')));
+		$parent_id = $parent[$modelClass]['id'];
+
+		$data = $this->Tree->find('first', array('fields' => array('id'), 'conditions' => array($modelClass . '.name' => '1.1.1')));
+		$this->Tree->id = $data[$modelClass]['id'];
+		$this->Tree->whitelist = array($parentField, 'name', 'description');
+		$this->Tree->saveField($parentField, $parent_id);
+
+		$result = $this->Tree->children($parent_id, true, array('name', $leftField, $rightField));
+		$expected = array(array($modelClass => array('name' => '1.1', $leftField => 2, $rightField => 5)),
+			array($modelClass => array('name' => '1.2', $leftField => 6, $rightField => 11)),
+			array($modelClass => array('name' => '1.1.1', $leftField => 12, $rightField => 13)));
+		$this->assertEqual($result, $expected);
+		$this->assertTrue($this->Tree->verify());
+	}
+
+/**
+ * testRemoveNoChildren method
+ *
+ * @return void
+ */
+	public function testRemoveNoChildren() {
+		extract($this->settings);
+		$this->Tree = new $modelClass();
+		$this->Tree->initialize(2, 2);
+		$initialCount = $this->Tree->find('count');
+
+		$result = $this->Tree->findByName('1.1.1');
+		$this->Tree->removeFromTree($result[$modelClass]['id']);
+
+		$laterCount = $this->Tree->find('count');
+		$this->assertEqual($initialCount, $laterCount);
+
+		$nodes = $this->Tree->find('list', array('order' => $leftField));
+		$expects = array(
+			'1. Root',
+			'1.1',
+			'1.1.2',
+			'1.2',
+			'1.2.1',
+			'1.2.2',
+			'1.1.1',
+		);
+
+		$this->assertEqual(array_values($nodes), $expects);
+
+		$validTree = $this->Tree->verify();
+		$this->assertIdentical($validTree, true);
+	}
+
+/**
+ * testRemoveAndDeleteNoChildren method
+ *
+ * @return void
+ */
+	public function testRemoveAndDeleteNoChildren() {
+		extract($this->settings);
+		$this->Tree = new $modelClass();
+		$this->Tree->initialize(2, 2);
+		$initialCount = $this->Tree->find('count');
+
+		$result = $this->Tree->findByName('1.1.1');
+		$this->Tree->removeFromTree($result[$modelClass]['id'], true);
+
+		$laterCount = $this->Tree->find('count');
+		$this->assertEqual($initialCount - 1, $laterCount);
+
+		$nodes = $this->Tree->find('list', array('order' => $leftField));
+		$expects = array(
+			'1. Root',
+			'1.1',
+			'1.1.2',
+			'1.2',
+			'1.2.1',
+			'1.2.2',
+		);
+		$this->assertEqual(array_values($nodes), $expects);
+
+		$validTree = $this->Tree->verify();
+		$this->assertIdentical($validTree, true);
+	}
+
+/**
+ * testChildren method
+ *
+ * @return void
+ */
+	public function testChildren() {
+		extract($this->settings);
+		$this->Tree = new $modelClass();
+		$this->Tree->initialize(2, 2);
+
+		$data = $this->Tree->find('first', array('conditions' => array($modelClass . '.name' => '1. Root')));
+		$this->Tree->id = $data[$modelClass]['id'];
+
+		$direct = $this->Tree->children(null, true, array('name', $leftField, $rightField));
+		$expects = array(array($modelClass => array('name' => '1.1', $leftField => 2, $rightField => 7)),
+			array($modelClass => array('name' => '1.2', $leftField => 8, $rightField => 13)));
+		$this->assertEqual($direct, $expects);
+
+		$total = $this->Tree->children(null, null, array('name', $leftField, $rightField));
+		$expects = array(array($modelClass => array('name' => '1.1', $leftField => 2, $rightField => 7)),
+			array($modelClass => array('name' => '1.1.1', $leftField => 3, $rightField => 4)),
+			array($modelClass => array('name' => '1.1.2', $leftField => 5, $rightField => 6)),
+			array($modelClass => array('name' => '1.2', $leftField => 8, $rightField => 13)),
+			array($modelClass => array('name' => '1.2.1', $leftField => 9, $rightField => 10)),
+			array($modelClass => array('name' => '1.2.2', $leftField => 11, $rightField => 12)));
+		$this->assertEqual($total, $expects);
+	}
+
+/**
+ * testNoAmbiguousColumn method
+ *
+ * @return void
+ */
+	public function testNoAmbiguousColumn() {
+		extract($this->settings);
+		$this->Tree = new $modelClass();
+		$this->Tree->initialize(2, 2);
+
+		$this->Tree->bindModel(array('belongsTo' => array('Dummy' =>
+			array('className' => $modelClass, 'foreignKey' => $parentField, 'conditions' => array('Dummy.id' => null)))), false);
+
+		$data = $this->Tree->find('first', array('conditions' => array($modelClass . '.name' => '1. Root')));
+		$this->Tree->id = $data[$modelClass]['id'];
+
+		$direct = $this->Tree->children(null, true, array('name', $leftField, $rightField));
+		$expects = array(array($modelClass => array('name' => '1.1', $leftField => 2, $rightField => 7)),
+			array($modelClass => array('name' => '1.2', $leftField => 8, $rightField => 13)));
+		$this->assertEqual($direct, $expects);
+
+		$total = $this->Tree->children(null, null, array('name', $leftField, $rightField));
+		$expects = array(
+			array($modelClass => array('name' => '1.1', $leftField => 2, $rightField => 7)),
+			array($modelClass => array('name' => '1.1.1', $leftField => 3, $rightField => 4)),
+			array($modelClass => array('name' => '1.1.2', $leftField => 5, $rightField => 6)),
+			array($modelClass => array('name' => '1.2', $leftField => 8, $rightField => 13)),
+			array($modelClass => array('name' => '1.2.1', $leftField => 9, $rightField => 10)),
+			array($modelClass => array('name' => '1.2.2', $leftField => 11, $rightField => 12))
+		);
+		$this->assertEqual($total, $expects);
+	}
+
+/**
+ * testGenerateTreeListWithSelfJoin method
+ *
+ * @return void
+ */
+	public function testGenerateTreeListWithSelfJoin() {
+		extract($this->settings);
+		$this->Tree = new $modelClass();
+		$this->Tree->bindModel(array('belongsTo' => array('Dummy' =>
+			array('className' => $modelClass, 'foreignKey' => $parentField, 'conditions' => array('Dummy.id' => null)))), false);
+		$this->Tree->initialize(2, 2);
+
+		$result = $this->Tree->generateTreeList();
+		$expected = array('1. Root', '_1.1', '__1.1.1', '__1.1.2', '_1.2', '__1.2.1', '__1.2.2');
+		$this->assertIdentical(array_values($result), $expected);
+	}
+}