浏览代码

test case to prove soft delete can return true

euromark 12 年之前
父节点
当前提交
9de0dfcfe6
共有 2 个文件被更改,包括 231 次插入18 次删除
  1. 32 18
      Model/Behavior/SoftDeleteBehavior.php
  2. 199 0
      Test/Case/Model/Behavior/SoftDeleteBehaviorTest.php

+ 32 - 18
Model/Behavior/SoftDeleteBehavior.php

@@ -12,26 +12,39 @@
 App::uses('ModelBehavior', 'Model');
 
 /**
- * Utils Plugin
+ * Soft Delete Behavior
  *
- * Utils Soft Delete Behavior
+ * Note: To make delete() return true with SoftDelete attached, you need to modify your AppModel and overwrite
+ * delete() there:
  *
- * @package utils
- * @subpackage utils.models.behaviors
+ * public function delete($id = null, $cascade = true) {
+ *   $result = parent::delete($id, $cascade);
+ *   if (!$result && $this->Behaviors->loaded('SoftDelete')) {
+ *     return $this->softDeleted;
+ *   }
+ *   return $result;
+ * }
+ *
+ * 2013-04-16 ms
  */
 class SoftDeleteBehavior extends ModelBehavior {
 
 	/**
 	 * Default settings
 	 *
-	 * @var array $default
+	 * @var array
 	 */
-	public $default = array('deleted' => 'deleted_date');
+	protected $_defaults = array(
+		'attribute' => 'softDeleted',
+		'fields' => array(
+			'deleted' => 'deleted_date'
+		)
+	);
 
 	/**
 	 * Holds activity flags for models
 	 *
-	 * @var array $runtime
+	 * @var array
 	 */
 	public $runtime = array();
 
@@ -42,14 +55,10 @@ class SoftDeleteBehavior extends ModelBehavior {
 	 * @param array $settings
 	 */
 	public function setup(Model $model, $settings = array()) {
-		if (empty($settings)) {
-			$settings = $this->default;
-		} elseif (!is_array($settings)) {
-			$settings = array($settings);
-		}
+		$settings = array_merge($this->_defaults, $settings);
 
 		$error = 'SoftDeleteBehavior::setup(): model ' . $model->alias . ' has no field ';
-		$fields = $this->_normalizeFields($model, $settings);
+		$fields = $this->_normalizeFields($model, $settings['fields']);
 		foreach ($fields as $flag => $date) {
 			if ($model->hasField($flag)) {
 				if ($date && !$model->hasField($date)) {
@@ -62,8 +71,11 @@ class SoftDeleteBehavior extends ModelBehavior {
 			return;
 		}
 
-		$this->settings[$model->alias] = $fields;
+		$this->settings[$model->alias] = array_merge($settings, array('fields' => $fields));
 		$this->softDelete($model, true);
+
+		$attribute = $this->settings[$model->alias]['attribute'];
+		$model->$attribute = false;
 	}
 
 	/**
@@ -108,7 +120,10 @@ class SoftDeleteBehavior extends ModelBehavior {
 	public function beforeDelete(Model $model, $cascade = true) {
 		$runtime = $this->runtime[$model->alias];
 		if ($runtime) {
-			$this->delete($model, $model->id);
+			if ($this->delete($model, $model->id)) {
+				$attribute = $this->settings[$model->alias]['attribute'];
+				$model->$attribute = true;
+			}
 			return false;
 		}
 		return true;
@@ -193,7 +208,6 @@ class SoftDeleteBehavior extends ModelBehavior {
 			return !empty($this->runtime[$model->alias]) ? $this->runtime[$model->alias] : null;
 		}
 
-
 		$result = !isset($this->runtime[$model->alias]) || $this->runtime[$model->alias] !== $active;
 		$this->runtime[$model->alias] = $active;
 		$this->_softDeleteAssociations($model, $active);
@@ -244,7 +258,7 @@ class SoftDeleteBehavior extends ModelBehavior {
 	protected function _purgeDeletedConditions(Model $model, $expiration = '-90 days') {
 		$purgeDate = date('Y-m-d H:i:s', strtotime($expiration));
 		$conditions = array();
-		foreach ($this->settings[$model->alias] as $flag => $date) {
+		foreach ($this->settings[$model->alias]['fields'] as $flag => $date) {
 			$conditions[$model->alias . '.' . $flag] = true;
 			if ($date) {
 				$conditions[$model->alias . '.' . $date . ' <'] = $purgeDate;
@@ -262,7 +276,7 @@ class SoftDeleteBehavior extends ModelBehavior {
 	 */
 	protected function _normalizeFields(Model $model, $settings = array()) {
 		if (empty($settings)) {
-			$settings = @$this->settings[$model->alias];
+			$settings = $this->settings[$model->alias]['fields'];
 		}
 		$result = array();
 		foreach ($settings as $flag => $date) {

+ 199 - 0
Test/Case/Model/Behavior/SoftDeleteBehaviorTest.php

@@ -0,0 +1,199 @@
+<?php
+/**
+ * Copyright 2009-2010, Cake Development Corporation (http://cakedc.com)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2009-2010, Cake Development Corporation (http://cakedc.com)
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('Model', 'Model');
+App::uses('Behavior', 'Model');
+App::uses('SoftDeleteBehavior', 'Tools.Model/Behavior');
+
+/**
+ * SoftDeleteBehavior Test case
+ */
+class SoftDeleteBehaviorTest extends CakeTestCase {
+
+	/**
+	 * Fixtures property
+	 *
+	 * @var array
+	 */
+	public $fixtures = array('plugin.tools.soft_delete_post');
+
+	/**
+	 * Creates the model instance
+	 *
+	 * @return void
+	 */
+	public function setUp() {
+		parent::setUp();
+
+		$this->Post = new SoftDeletedPost();
+		$this->Behavior = new SoftDeleteTestBehavior();
+	}
+
+	/**
+	 * Destroy the model instance
+	 *
+	 * @return void
+	 */
+	public function tearDown() {
+		parent::tearDown();
+
+		unset($this->Post);
+		unset($this->Behavior);
+		ClassRegistry::flush();
+	}
+
+	/**
+	 * Test saving a item
+	 *
+	 * @return void
+	 */
+	public function testSoftDelete() {
+		$data = $this->Post->read(null, 1);
+		$this->assertEquals($data[$this->Post->alias][$this->Post->primaryKey], 1);
+		$this->assertFalse($this->Post->softDeleted);
+		$result = $this->Post->delete(1);
+		$this->assertFalse($result);
+		$this->assertTrue($this->Post->softDeleted);
+
+		$data = $this->Post->read(null, 1);
+		$this->assertEmpty($data);
+		$this->Post->Behaviors->unload('SoftDeleteTest');
+		$data = $this->Post->read(null, 1);
+		$this->assertEquals($data['Post']['deleted'], 1);
+
+		$this->assertWithinMargin(abs(strtotime($data['Post']['updated']) - strtotime($data['Post']['deleted_date'])), 0, 1);
+	}
+
+	/**
+	 * Test that overwriting delete() on AppModel level makes SoftDelete return true for delete()
+	 *
+	 * @return void
+	 */
+	public function testSoftDeleteReturningTrue() {
+		$this->Post = new ModifiedSoftDeletedPost();
+		$this->Post->Behaviors->load('Tools.SoftDelete');
+
+		$data = $this->Post->read(null, 1);
+		$this->assertEquals($data[$this->Post->alias][$this->Post->primaryKey], 1);
+		//$this->assertFalse($this->Post->softDeleted);
+		$result = $this->Post->delete(1);
+		$this->assertTrue($result);
+		//$this->assertTrue($this->Post->softDeleted);
+	}
+
+	/**
+	 * testUnDelete
+	 *
+	 * @return void
+	 */
+	public function testUnDelete() {
+		$data = $this->Post->read(null, 1);
+		$result = $this->Post->delete(1);
+		$result = $this->Post->undelete(1);
+		$data = $this->Post->read(null, 1);
+		$this->assertEquals($data['Post']['deleted'], 0);
+	}
+
+	/**
+	 * testSoftDeletePurge
+	 *
+	 * @return void
+	 */
+	public function testSoftDeletePurge() {
+		$this->Post->Behaviors->disable('SoftDeleteTest');
+		$data = $this->Post->read(null, 3);
+		$this->assertTrue(!empty($data));
+		$this->Post->Behaviors->enable('SoftDeleteTest');
+		$data = $this->Post->read(null, 3);
+		$this->assertEmpty($data);
+		$count = $this->Post->purgeDeletedCount();
+		$this->assertEquals($count, 1);
+		$this->Post->purgeDeleted();
+
+		$data = $this->Post->read(null, 3);
+		$this->assertEmpty($data);
+		$this->Post->Behaviors->disable('SoftDeleteTest');
+		$data = $this->Post->read(null, 3);
+		$this->assertEmpty($data);
+	}
+
+		// $result = $this->Model->read();
+		// $this->assertEquals($result['SoftDeletedPost']['slug'], 'fourth_Post');
+
+		///Should not update
+		// $this->Model->saveField('title', 'Fourth Post (Part 1)');
+		// $result = $this->Model->read();
+		// $this->assertEquals($result['SoftDeletedPost']['slug'], 'fourth_Post');
+
+		////Should update
+		// $this->Model->Behaviors->SluggableTest->settings['SoftDeletedPost']['update'] = true;
+		// $this->Model->saveField('title', 'Fourth Post (Part 2)');
+		// $result = $this->Model->read();
+		// $this->assertEquals($result['SoftDeletedPost']['slug'], 'fourth_Post_part_2');
+
+		////Updating the item should not update the slug
+		// $this->Model->saveField('body', 'Here goes the content.');
+		// $result = $this->Model->read();
+		// $this->assertEquals($result['SoftDeletedPost']['slug'], 'fourth_Post_part_2');
+
+}
+
+
+/**
+ * SoftDeleteTestBehavior
+ *
+ */
+class SoftDeleteTestBehavior extends SoftDeleteBehavior {
+}
+
+/**
+ * SoftDeletedPost
+ *
+ */
+class SoftDeletedPost extends CakeTestModel {
+
+	/**
+	 * Use Table
+	 *
+	 * @var string
+	 */
+	public $useTable = 'soft_delete_posts';
+
+	/**
+	 * Behaviors
+	 *
+	 * @var array
+	 */
+	public $actsAs = array('Tools.SoftDeleteTest');
+
+	/**
+	 * Alias
+	 *
+	 * @var string
+	 */
+	public $alias = 'Post';
+
+}
+
+/**
+ * SoftDeletedPost returning true on delete()
+ *
+ */
+class ModifiedSoftDeletedPost extends SoftDeletedPost {
+
+	public function delete($id = null, $cascade = true) {
+		$result = parent::delete($id, $cascade);
+		if (!$result && $this->Behaviors->loaded('SoftDelete')) {
+			return $this->softDeleted;
+		}
+		return $result;
+	}
+}