Browse Source

add model tests

euromark 11 years ago
parent
commit
7c78f75bab
2 changed files with 232 additions and 112 deletions
  1. 53 98
      Model/MyModel.php
  2. 179 14
      Test/Case/Model/MyModelTest.php

+ 53 - 98
Model/MyModel.php

@@ -191,7 +191,6 @@ class MyModel extends Model {
 	 * @param string $value or array $keys or NULL for complete array result
 	 * @param array $options (actual data)
 	 * @return mixed string/array
-	 * static enums
 	 */
 	public static function enum($value, $options, $default = null) {
 		if ($value !== null && !is_array($value)) {
@@ -355,24 +354,6 @@ class MyModel extends Model {
 	}
 
 	/**
-	 * Workaround for a cake bug which sets empty fields to NULL in Model::set()
-	 * we cannot use if (isset() && empty()) statements without this fix
-	 *
-	 * @param array $fields (which are supposed to be present in $this->data[$this->alias])
-	 * @param boolean $force (if init should be forced, otherwise only if array_key exists)
-	 * @return void
-	 */
-	public function init($fields = array(), $force = false) {
-		foreach ($fields as $field) {
-			if ($force || array_key_exists($field, $this->data[$this->alias])) {
-				if (!isset($this->data[$this->alias][$field])) {
-					$this->data[$this->alias][$field] = '';
-				}
-			}
-		}
-	}
-
-	/**
 	 * Fix for non atomic queries (MyISAM  etc) and saveAll to still return just the boolean result
 	 * Otherwise you would have to iterate over all result values to find out if the save was successful.
 	 *
@@ -419,7 +400,7 @@ class MyModel extends Model {
 	 * - key: functioName or other key used
 	 * @return boolean Success
 	 */
-	public function deleteCache($key) {
+	public function deleteCache($key = null) {
 		$key = Inflector::underscore($key);
 		if (!empty($key)) {
 			return Cache::delete(strtolower(Inflector::underscore($this->alias)) . '__' . $key, 'sql');
@@ -577,16 +558,6 @@ class MyModel extends Model {
 		return parent::find($type, $query);
 	}
 
-	/*
-	public function _findCount($state, $query, $results = array()) {
-		if (isset($query['fields'])) {
-			unset($query['fields']);
-		}
-		pr($results);
-		return parent::_findCount($state, $query, $results = array());
-	}
-	*/
-
 	/**
 	 * This code will add formatted list functionallity to find you can easy replace the $this->Model->find('list'); with $this->Model->find('formattedlist', array('fields' => array('Model.id', 'Model.field1', 'Model.field2', 'Model.field3'), 'format' => '%s-%s %s')); and get option tag output of: Model.field1-Model.field2 Model.field3. Even better part is being able to setup your own format for the output!
 	 *
@@ -668,7 +639,6 @@ class MyModel extends Model {
 					break;
 				default:
 					$res = parent::find($type, $options);
-					break;
 			}
 			if (!empty($this->useCache)) {
 				Cache::write($this->cacheName, $res, $this->cacheConfig);
@@ -684,51 +654,6 @@ class MyModel extends Model {
 		return $res;
 	}
 
-	/*
-	USAGE of formattetlist:
-	$this->Model->find('formattedlist',
-	array(
-	'fields'=>array(
-	'Model.id', // allows start with the value="" tags field
-	'Model.field1', // then put them in order of how you want the format to output.
-	'Model.field2',
-	'Model.field3',
-	'Model.field4',
-	'Model.field5',
-	),
-	'format'=>'%s-%s%s %s%s'
-	)
-	);
-	*/
-
-	/*
-	neighbor find problem:
-	This means it will sort the results on Model.created ASC and DESC.
-	However, in certain situations you would like to order on more than one
-	field. For example, on a rating and a uploaddate. Requirements could look
-	like: Get next en previous record of a certain Model based on the top
-	rated. When the rating is equal those should be ordered on creation date.
-	I suggest something similar to:
-
-	$this->Movie->find('neighbors', array(
-	'scope' => array(
-	array(
-	'field' => 'rating',
-	'order' => 'DESC',
-	'value' => 4.85
-	),
-	array(
-	'field' => 'created',
-	'order' => 'DESC',
-	'value' => '2009-05-26 06:20:03'
-	)
-	)
-	'conditions' => array(
-	'approved' => true,
-	'processed' => true
-	)
-	*/
-
 	/**
 	 * Core-fix for multiple sort orders
 	 *
@@ -832,8 +757,6 @@ class MyModel extends Model {
 		return $this->getDataSource()->delete($this, $conditions);
 	}
 
-/** Validation Functions **/
-
 	/**
 	 * Overwrite invalidate to allow last => true
 	 *
@@ -1339,7 +1262,6 @@ class MyModel extends Model {
 	public function validateNotBlocked($params) {
 		$email = array_shift($params);
 		if (!isset($this->Blacklist)) {
-			//App::uses('Blacklist', 'Tools.Model'
 			$this->Blacklist = ClassRegistry::init('Tools.Blacklist');
 		}
 		if ($this->Blacklist->isBlacklisted(Blacklist::TYPE_EMAIL, $email)) {
@@ -1387,10 +1309,13 @@ class MyModel extends Model {
 	 * @param array $data (optional)
 	 * @return array
 	 */
-	public function whitelist($fieldList, $data = null) {
+	public function whitelist(array $fieldList, $data = null) {
 		$model = $this->alias;
 		if ($data === null) {
-			$data = $this->data;
+			$data =& $this->data;
+		}
+		if (empty($data[$model])) {
+			return array();
 		}
 		foreach ($data[$model] as $key => $val) {
 			if (!in_array($key, $fieldList)) {
@@ -1401,6 +1326,49 @@ class MyModel extends Model {
 	}
 
 	/**
+	 * Instead of whitelisting this will remove all blacklisted keys.
+	 *
+	 * @param array $blacklist
+	 * - array: fields to blacklist
+	 * - boolean TRUE: removes all foreign_keys (_id)
+	 * note: one-dimensional
+	 * @return array
+	 */
+	public function blacklist($blacklist, $data = null) {
+		$model = $this->alias;
+		if ($data === null) {
+			$data =& $this->data;
+		}
+		if (empty($data[$model])) {
+			return array();
+		}
+		if ($blacklist === true) {
+			foreach ($data[$model] as $key => $value) {
+				if (substr($key, -3, 3) === '_id') {
+					unset($data[$model][$key]);
+				}
+			}
+			return;
+		}
+		foreach ($blacklist as $key) {
+			if (isset($data[$model][$key])) {
+				unset($data[$model][$key]);
+			}
+		}
+		return $data;
+	}
+
+	/**
+	 * Generate a whitelist, based on the current schema and a passed blacklist.
+	 *
+	 * @param array $blacklist
+	 * @return array
+	 */
+	public function generateWhitelistFromBlacklist(array $blacklist) {
+		return array_diff(array_keys($this->schema()), $blacklist);
+	}
+
+	/**
 	 * Make sure required fields exists - in order to properly validate them
 	 *
 	 * @param array: field1, field2 - or field1, Model2.field1 etc
@@ -1474,22 +1442,6 @@ class MyModel extends Model {
 	}
 
 	/**
-	 * Instead of whitelisting
-	 *
-	 * @param array $blackList
-	 * - array: fields to blacklist
-	 * - boolean TRUE: removes all foreign_keys (_id and _key)
-	 * note: one-dimensional
-	 * @return array
-	 */
-	public function blacklist($blackList = array()) {
-		if ($blackList === true) {
-			//TODO
-		}
-		return array_diff(array_keys($this->schema()), (array)$blackList);
-	}
-
-	/**
 	 * Shortcut method to find a specific entry via primary key.
 	 *
 	 * Either provide the id directly:
@@ -1553,7 +1505,10 @@ class MyModel extends Model {
 	 * @param array $options
 	 * @return array
 	 */
-	public function getRelatedInUse($modelName, $groupField, $type = 'all', $options = array()) {
+	public function getRelatedInUse($modelName, $groupField = null, $type = 'all', $options = array()) {
+		if ($groupField === null) {
+			$groupField = $this->belongsTo[$modelName]['foreignKey'];
+		}
 		$defaults = array(
 			'contain' => array($modelName),
 			'group' => $groupField,

+ 179 - 14
Test/Case/Model/MyModelTest.php

@@ -26,6 +26,11 @@ class MyModelTest extends MyCakeTestCase {
 		$this->assertInstanceOf('MyModel', $this->Post);
 	}
 
+	/**
+	 * MyModelTest::testGet()
+	 *
+	 * @return void
+	 */
 	public function testGet() {
 		$record = $this->Post->get(2);
 		$this->assertEquals(2, $record['Post']['id']);
@@ -37,6 +42,34 @@ class MyModelTest extends MyCakeTestCase {
 		$this->assertEquals(3, $record['Author']['id']);
 	}
 
+	/**
+	 * MyModelTest::testGetRelatedInUse()
+	 *
+	 * @return void
+	 */
+	public function testGetRelatedInUse() {
+		$this->Post->Author->displayField = 'user';
+		$results = $this->Post->getRelatedInUse('Author', 'author_id', 'list');
+		$expected = array(1 => 'mariano', 3 => 'larry');
+		$this->assertEquals($expected, $results);
+	}
+
+	/**
+	 * MyModelTest::testGetFieldInUse()
+	 *
+	 * @return void
+	 */
+	public function testGetFieldInUse() {
+		$results = $this->Post->getFieldInUse('author_id', 'list');
+		$expected = array(1 => 'First Post', 2 => 'Second Post');
+		$this->assertEquals($expected, $results);
+	}
+
+	/**
+	 * MyModelTest::testEnum()
+	 *
+	 * @return void
+	 */
 	public function testEnum() {
 		$array = array(
 			1 => 'foo',
@@ -58,6 +91,8 @@ class MyModelTest extends MyCakeTestCase {
 
 	/**
 	 * More tests in MyModel Test directly
+	 *
+	 * @return void
 	 */
 	public function testGetFalse() {
 		$this->User->order = array();
@@ -67,6 +102,8 @@ class MyModelTest extends MyCakeTestCase {
 
 	/**
 	 * Test auto inc value of the current table
+	 *
+	 * @return void
 	 */
 	public function testGetNextAutoIncrement() {
 		$this->out($this->_header(__FUNCTION__), true);
@@ -81,6 +118,11 @@ class MyModelTest extends MyCakeTestCase {
 		}
 	}
 
+	/**
+	 * MyModelTest::testDeconstruct()
+	 *
+	 * @return void
+	 */
 	public function testDeconstruct() {
 		$data = array('year' => '2010', 'month' => '10', 'day' => 11);
 		$res = $this->User->deconstruct('User.dob', $data);
@@ -92,6 +134,8 @@ class MyModelTest extends MyCakeTestCase {
 
 	/**
 	 * Test that strings are correctly escaped using '
+	 *
+	 * @return void
 	 */
 	public function testEscapeValue() {
 		$res = $this->User->escapeValue(4);
@@ -117,6 +161,11 @@ class MyModelTest extends MyCakeTestCase {
 		$this->assertSame('`User`.`dob`', $res);
 	}
 
+	/**
+	 * MyModelTest::testSaveAll()
+	 *
+	 * @return void
+	 */
 	public function testSaveAll() {
 		$records = array(
 			array('title' => 'x', 'body' => 'bx'),
@@ -152,6 +201,8 @@ class MyModelTest extends MyCakeTestCase {
 
 	/**
 	 * Test truncate
+	 *
+	 * @return void
 	 */
 	public function testTruncate() {
 		$is = $this->User->find('count');
@@ -172,6 +223,7 @@ class MyModelTest extends MyCakeTestCase {
 	 * Test that 2.x invalidates() can behave like 1.x invalidates()
 	 * and that you are able to abort on single errors (similar to using last=>true)
 	 *
+	 * @return void
 	 */
 	public function testInvalidates() {
 		$TestModel = new AppTestModel();
@@ -218,6 +270,11 @@ class MyModelTest extends MyCakeTestCase {
 		$this->assertEquals($expected, $result);
 	}
 
+	/**
+	 * MyModelTest::testValidateIdentical()
+	 *
+	 * @return void
+	 */
 	public function testValidateIdentical() {
 		$this->out($this->_header(__FUNCTION__), true);
 		$this->User->data = array($this->User->alias => array('y' => 'efg'));
@@ -237,6 +294,11 @@ class MyModelTest extends MyCakeTestCase {
 		$this->assertTrue($is);
 	}
 
+	/**
+	 * MyModelTest::testValidateKey()
+	 *
+	 * @return void
+	 */
 	public function testValidateKey() {
 		$this->out($this->_header(__FUNCTION__), true);
 		//$this->User->data = array($this->User->alias=>array('y'=>'efg'));
@@ -282,6 +344,11 @@ class MyModelTest extends MyCakeTestCase {
 		$this->assertTrue($is);
 	}
 
+	/**
+	 * MyModelTest::testValidateEnum()
+	 *
+	 * @return void
+	 */
 	public function testValidateEnum() {
 		$this->out($this->_header(__FUNCTION__), true);
 		//$this->User->data = array($this->User->alias=>array('y'=>'efg'));
@@ -299,6 +366,11 @@ class MyModelTest extends MyCakeTestCase {
 		$this->assertTrue($is);
 	}
 
+	/**
+	 * MyModelTest::testGuaranteeFields()
+	 *
+	 * @return void
+	 */
 	public function testGuaranteeFields() {
 		$this->out($this->_header(__FUNCTION__), true);
 		$res = $this->User->guaranteeFields(array());
@@ -316,6 +388,44 @@ class MyModelTest extends MyCakeTestCase {
 		$this->assertEquals($res, array($this->modelName => array('x' => ''), 'OtherModel' => array('y' => '')));
 	}
 
+	/**
+	 * MyModelTest::testRequireFields()
+	 *
+	 * @return void
+	 */
+	public function testRequireFields() {
+		$this->User->requireFields(array('foo', 'bar'));
+		$data = array(
+			'foo' => 'foo',
+		);
+		$this->User->set($data);
+		$result = $this->User->validates();
+		$this->assertFalse($result);
+
+		$data = array(
+			'foo' => 'foo',
+			'bar' => '',
+		);
+		$this->User->set($data);
+		$result = $this->User->validates();
+		$this->assertTrue($result);
+
+		// Allow field to be empty as long as it is present
+		$this->User->requireFields(array('foo', 'test'), true);
+		$data = array(
+			'foo' => 'foo',
+			'test' => ''
+		);
+		$this->User->set($data);
+		$result = $this->User->validates();
+		$this->assertTrue($result);
+	}
+
+	/**
+	 * MyModelTest::testSet()
+	 *
+	 * @return void
+	 */
 	public function testSet() {
 		$this->out($this->_header(__FUNCTION__), true);
 		$data = array($this->modelName => array('x' => 'hey'), 'OtherModel' => array('y' => ''));
@@ -332,6 +442,11 @@ class MyModelTest extends MyCakeTestCase {
 		$this->assertEquals($res, array($this->modelName => array('x' => 'hey', 'z' => ''), 'OtherModel' => array('y' => '')));
 	}
 
+	/**
+	 * MyModelTest::testValidateWithGuaranteeFields()
+	 *
+	 * @return void
+	 */
 	public function testValidateWithGuaranteeFields() {
 		$this->out($this->_header(__FUNCTION__), true);
 		$data = array($this->modelName => array('x' => 'hey'), 'OtherModel' => array('y' => ''));
@@ -347,25 +462,50 @@ class MyModelTest extends MyCakeTestCase {
 		$this->assertEquals($res, array($this->modelName => array('x' => 'hey', 'z' => ''), 'OtherModel' => array('y' => '')));
 	}
 
-	// not really working?
+	public function testWhitelist() {
+		$data = array(
+			'name' => 'foo',
+			'x' => 'y',
+			'z' => 'yes'
+		);
+		$this->User->set($data);
+		$result = $this->User->whitelist(array('name', 'x'));
+		$this->assertEquals(array('name', 'x'), array_keys($this->User->data['User']));
+	}
 
+	/**
+	 * MyModelTest::testBlacklist()
+	 * Note that one should always prefer a whitelist over a blacklist.
+	 *
+	 * @return void
+	 */
 	public function testBlacklist() {
-		$this->out($this->_header(__FUNCTION__), true);
-		$data = array($this->modelName => array('name' => 'e', 'x' => 'hey'), 'OtherModel' => array('y' => ''));
-
-		$schema = $this->User->schema();
-
-		$data = $this->User->blacklist(array('x', 'z'));
-		$this->out($data);
-		if (!empty($schema)) {
-			$this->assertTrue(!empty($data));
-		} else {
-			$this->assertTrue(empty($data));
-		}
+		$data = array(
+			'name' => 'foo',
+			'x' => 'y',
+			'z' => 'yes'
+		);
+		$this->User->set($data);
+		$this->User->blacklist(array('x'));
+		$this->assertEquals(array('name', 'z'), array_keys($this->User->data['User']));
+	}
 
-		//$this->assertEquals($data, array($this->modelName=>array('x'=>'hey', 'z'=>''), 'OtherModel'=>array('y'=>'')));
+	/**
+	 * MyModelTest::testGenerateWhitelistFromBlacklist()
+	 *
+	 * @return void
+	 */
+	public function testGenerateWhitelistFromBlacklist() {
+		$result = $this->User->generateWhitelistFromBlacklist(array('password'));
+		$expected = array('id', 'user', 'created', 'updated');
+		$this->assertEquals($expected, array_values($expected));
 	}
 
+	/**
+	 * MyModelTest::testInvalidate()
+	 *
+	 * @return void
+	 */
 	public function testInvalidate() {
 		$this->out($this->_header(__FUNCTION__), true);
 		$this->User->create();
@@ -405,6 +545,11 @@ class MyModelTest extends MyCakeTestCase {
 		$this->assertTrue(!empty($res) && $res['fieldy'][0] === 'a 1 b 2 c 3 4 5 6 7 h 8');
 	}
 
+	/**
+	 * MyModelTest::testValidateDate()
+	 *
+	 * @return void
+	 */
 	public function testValidateDate() {
 		$this->out($this->_header(__FUNCTION__), true);
 		$data = array('field' => '2010-01-22');
@@ -484,6 +629,11 @@ class MyModelTest extends MyCakeTestCase {
 		$this->assertTrue($res);
 	}
 
+	/**
+	 * MyModelTest::testValidateDatetime()
+	 *
+	 * @return void
+	 */
 	public function testValidateDatetime() {
 		$this->out($this->_header(__FUNCTION__), true);
 		$data = array('field' => '2010-01-22 11:11:11');
@@ -554,6 +704,11 @@ class MyModelTest extends MyCakeTestCase {
 		$this->assertFalse($res);
 	}
 
+	/**
+	 * MyModelTest::testValidateTime()
+	 *
+	 * @return void
+	 */
 	public function testValidateTime() {
 		$this->out($this->_header(__FUNCTION__), true);
 		$data = array('field' => '11:21:11');
@@ -579,6 +734,11 @@ class MyModelTest extends MyCakeTestCase {
 		$this->assertFalse($res);
 	}
 
+	/**
+	 * MyModelTest::testValidateUrl()
+	 *
+	 * @return void
+	 */
 	public function testValidateUrl() {
 		$this->out($this->_header(__FUNCTION__), true);
 		$data = array('field' => 'www.dereuromark.de');
@@ -638,6 +798,11 @@ class MyModelTest extends MyCakeTestCase {
 		$this->assertTrue($res);
 	}
 
+	/**
+	 * MyModelTest::testValidateUnique()
+	 *
+	 * @return void
+	 */
 	public function testValidateUnique() {
 		$this->out($this->_header(__FUNCTION__), true);