Add some more transaction tests

And remove 2 else clauses.
This commit is contained in:
chinpei215 2014-08-03 22:34:11 +09:00
parent 799500ce6d
commit cb376bf420
2 changed files with 171 additions and 4 deletions

View file

@ -2243,11 +2243,10 @@ class Model extends Object implements CakeEventListener {
$options['validate'] = false; $options['validate'] = false;
} }
$transactionBegun = false;
if ($options['atomic']) { if ($options['atomic']) {
$db = $this->getDataSource(); $db = $this->getDataSource();
$transactionBegun = $db->begin(); $transactionBegun = $db->begin();
} else {
$transactionBegun = false;
} }
try { try {
@ -2378,11 +2377,10 @@ class Model extends Object implements CakeEventListener {
$options['validate'] = false; $options['validate'] = false;
} }
$transactionBegun = false;
if ($options['atomic']) { if ($options['atomic']) {
$db = $this->getDataSource(); $db = $this->getDataSource();
$transactionBegun = $db->begin(); $transactionBegun = $db->begin();
} else {
$transactionBegun = false;
} }
try { try {

View file

@ -36,6 +36,8 @@ class TestAuthor extends Author {
protected $_dataSourceObject; protected $_dataSourceObject;
public $dataForAfterSave;
/** /**
* Helper method to set a datasource object * Helper method to set a datasource object
* *
@ -74,6 +76,8 @@ class TestPost extends Post {
protected $_dataSourceObject; protected $_dataSourceObject;
public $dataForAfterSave;
/** /**
* Helper method to set a datasource object * Helper method to set a datasource object
* *
@ -7499,4 +7503,169 @@ class ModelWriteTest extends BaseModelTest {
return $db; return $db;
} }
/**
* Test that transactions behave correctly on nested saveMany calls.
*
* @return void
*/
public function testTransactionOnNestedSaveMany() {
$this->loadFixtures('Post');
$Post = new TestPost();
$Post->getEventManager()->attach(array($this, 'nestedSaveMany'), 'Model.afterSave');
// begin -> [ begin -> commit ] -> commit
$db = $this->_getMockDboSource(array('begin', 'commit', 'rollback'));
$db->expects($this->exactly(2))->method('begin')->will($this->returnValue(true));
$db->expects($this->exactly(2))->method('commit');
$db->expects($this->never())->method('rollback');
$Post->setDataSourceObject($db);
$data = array(
array('author_id' => 1, 'title' => 'Outer Post'),
);
$Post->dataForAfterSave = array(
array('author_id' => 1, 'title' => 'Inner Post'),
);
$this->assertTrue($Post->saveMany($data));
// begin -> [ begin(false) ] -> commit
$db = $this->_getMockDboSource(array('begin', 'commit', 'rollback'));
$db->expects($this->at(0))->method('begin')->will($this->returnValue(true));
$db->expects($this->at(1))->method('begin')->will($this->returnValue(false));
$db->expects($this->once())->method('commit');
$db->expects($this->never())->method('rollback');
$Post->setDataSourceObject($db);
$data = array(
array('author_id' => 1, 'title' => 'Outer Post'),
);
$Post->dataForAfterSave = array(
array('author_id' => 1, 'title' => 'Inner Post'),
);
$this->assertTrue($Post->saveMany($data));
// begin -> [ begin -> rollback ] -> rollback
$db = $this->_getMockDboSource(array('begin', 'commit', 'rollback'));
$db->expects($this->exactly(2))->method('begin')->will($this->returnValue(true));
$db->expects($this->never())->method('commit');
$db->expects($this->exactly(2))->method('rollback');
$Post->setDataSourceObject($db);
$data = array(
array('author_id' => 1, 'title' => 'Outer Post'),
);
$Post->dataForAfterSave = array(
array('author_id' => 1, 'title' => 'Inner Post', 'body' => $db->expression('PDO_EXCEPTION()')),
);
try {
$Post->saveMany($data);
$this->fail('No exception thrown');
} catch(Exception $e) {
}
}
/**
* Test that transaction behaves correctly on nested saveAssociated calls.
*
* @return void
*/
public function testTransactionOnNestedSaveAssociated() {
$this->loadFixtures('Author', 'Post');
$Author = new TestAuthor();
$Author->getEventManager()->attach(array($this, 'nestedSaveAssociated'), 'Model.afterSave');
// begin -> [ begin -> commit ] -> commit
$db = $this->_getMockDboSource(array('begin', 'commit', 'rollback'));
$db->expects($this->exactly(2))->method('begin')->will($this->returnValue(true));
$db->expects($this->exactly(2))->method('commit');
$db->expects($this->never())->method('rollback');
$Author->setDataSourceObject($db);
$Author->Post->setDataSourceObject($db);
$data = array(
'Author' => array('user' => 'outer'),
'Post' => array(
array('title' => 'Outer Post'),
)
);
$Author->dataForAfterSave = array(
'Author' => array('user' => 'inner'),
'Post' => array(
array('title' => 'Inner Post'),
)
);
$this->assertTrue($Author->saveAssociated($data));
// begin -> [ begin(false) ] -> commit
$db = $this->_getMockDboSource(array('begin', 'commit', 'rollback'));
$db->expects($this->at(0))->method('begin')->will($this->returnValue(true));
$db->expects($this->at(1))->method('begin')->will($this->returnValue(false));
$db->expects($this->once())->method('commit');
$db->expects($this->never())->method('rollback');
$Author->setDataSourceObject($db);
$Author->Post->setDataSourceObject($db);
$data = array(
'Author' => array('user' => 'outer'),
'Post' => array(
array('title' => 'Outer Post'),
)
);
$Author->dataForAfterSave = array(
'Author' => array('user' => 'inner'),
'Post' => array(
array('title' => 'Inner Post'),
)
);
$this->assertTrue($Author->saveAssociated($data));
// begin -> [ begin -> rollback ] -> rollback
$db = $this->_getMockDboSource(array('begin', 'commit', 'rollback'));
$db->expects($this->exactly(2))->method('begin')->will($this->returnValue(true));
$db->expects($this->never())->method('commit');
$db->expects($this->exactly(2))->method('rollback');
$Author->setDataSourceObject($db);
$Author->Post->setDataSourceObject($db);
$data = array(
'Author' => array('user' => 'outer'),
'Post' => array(
array('title' => 'Outer Post'),
)
);
$Author->dataForAfterSave = array(
'Author' => array('user' => 'inner', 'password' => $db->expression('PDO_EXCEPTION()')),
'Post' => array(
array('title' => 'Inner Post'),
)
);
try {
$Author->saveAssociated($data);
$this->fail('No exception thrown');
} catch(Exception $e) {
}
}
/**
* A callback for testing nested saveMany.
*
* @param CakeEvent $event containing the Model
* @return void
*/
public function nestedSaveMany($event) {
$Model = $event->subject;
$Model->saveMany($Model->dataForAfterSave, array('callbacks' => false));
}
/**
* A callback for testing nested saveAssociated.
*
* @param CakeEvent $event containing the Model
* @return void
*/
public function nestedSaveAssociated($event) {
$Model = $event->subject;
$Model->saveAssociated($Model->dataForAfterSave, array('callbacks' => false));
}
} }