DataObject::write now throws a ValidationException rather than calling user_error if the call to DataObject::validate fails. This allows the validation exception to be caught and handled by tests or other controllers.

git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@63891 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
Hayden Smith 2008-10-08 20:42:09 +00:00
parent d8dd8097e1
commit fc2c16efdf
3 changed files with 69 additions and 1 deletions

View File

@ -0,0 +1,29 @@
<?php
/**
* Exception thrown by {@link DataObject}::write if validation fails. By throwing an
* exception rather than a user error, the exception can be caught in unit tests and as such
* can be used as a successful test.
*/
class ValidationException extends Exception {
/**
* @var {@link ValidationResult} or string
*/
protected $result;
public function __construct($result = null, $message = null, $code = 0) {
if($result instanceof ValidationResult) {
$this->result = $result;
} else {
$code = $message;
$message = $result;
}
parent::__construct($message, $code);
}
public function getResult() {
return $this->result;
}
}
?>

View File

@ -663,7 +663,7 @@ class DataObject extends ViewableData implements DataObjectInterface {
$valid = $this->validate();
if(!$valid->valid()) {
user_error("Validation error writing a $this->class object: " . $valid->message() . ". Object not written.", E_USER_WARNING);
throw new ValidationException($valid, "Validation error writing a $this->class object: " . $valid->message() . ". Object not written.", E_USER_WARNING);
return false;
}

View File

@ -479,6 +479,30 @@ class DataObjectTest extends SapphireTest {
$reloadedTeam1 = $this->objFromFixture('DataObjectTest_Team', 'team1');
$this->assertEquals('New and improved team 1', $reloadedTeam1->Title);
}
public function testDataObjectValidation() {
$validatedObject = new DataObjectTest_ValidatedObject();
try {
$validatedObject->write();
// If write doesn't throw an exception, this line is executed and the test fails.
$this->assertTrue(false, "Validated object did not throw a ValidationException when saving with DataObject::write");
} catch (ValidationException $validationException) {
// ValidationException wraps a ValidationResult. This result should be invalid
$this->assertFalse($validationException->getResult()->valid(), "ValidationException thrown by DataObject::write contains a valid ValidationResult. The result should be invalid.");
}
$validatedObject->Name = "Mr. Jones";
try {
$validatedObject->write();
$this->assertTrue($validatedObject->isInDB(), "Validated object was not saved to database");
} catch (Exception $exception) {
$this->assertTrue(false, "Validated object threw an unexpected exception of type " . get_class($exception) . " from DataObject::write: " . $exception->getMessage());
}
}
}
class DataObjectTest_Player extends Member implements TestOnly {
@ -547,6 +571,21 @@ class DataObjectTest_Team_Decorator extends DataObjectDecorator implements TestO
}
class DataObjectTest_ValidatedObject extends DataObject implements TestOnly {
static $db = array(
'Name' => 'Varchar(50)'
);
protected function validate() {
if(!empty($this->Name)) {
return new ValidationResult();
} else {
return new ValidationResult(false, "This object needs a name. Otherwise it will have an identity crisis!");
}
}
}
DataObject::add_extension('DataObjectTest_Team', 'DataObjectTest_Team_Decorator');
?>