Skip to content

Commit

Permalink
Adding a unit test for BelongsToMany::replaceLinks
Browse files Browse the repository at this point in the history
  • Loading branch information
lorenzo committed Dec 15, 2013
1 parent 5ce7482 commit fa04e06
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 2 deletions.
3 changes: 2 additions & 1 deletion Cake/ORM/Association/BelongsToMany.php
Expand Up @@ -492,9 +492,10 @@ public function replaceLinks(Entity $sourceEntity, array $targetEntities, array
return $this->junction()->connection()->transactional(
function() use ($sourceEntity, $targetEntities, $primaryValue, $options) {
$foreignKey = (array)$this->foreignKey();
$belongsTo = $this->_junctionTable->association($this->target()->alias());
$existing = $this->_junctionTable->find('all')
->where(array_combine($foreignKey, $primaryValue))
->andWHere($this->conditions());
->andWHere($belongsTo->conditions());

$jointEntities = $this->_collectJointEntities($sourceEntity, $targetEntities);
$inserts = $this->_diffLinks($existing, $jointEntities, $targetEntities);
Expand Down
98 changes: 97 additions & 1 deletion Cake/Test/TestCase/ORM/Association/BelongsToManyTest.php
Expand Up @@ -900,7 +900,8 @@ public function testUnlinkWithoutPropertyClean() {
}

/**
* Test liking entities having a non persited source entity
* Tests that replaceLink requires the sourceEntity to have primaryKey values
* for the source entity
*
* @expectedException \InvalidArgumentException
* @expectedExceptionMessage Could not find primary key value for source entity
Expand All @@ -918,4 +919,99 @@ public function testRplaceWithMissingPrimaryKey() {
$assoc->replaceLinks($entity, $tags);
}

/**
* Tests that replaceLinks will delete entities not present in the passed
* array, maintain those are already persisted and were passed and also
* insert the rest.
*
* @return void
*/
public function testReplaceLinkSuccess() {
$connection = \Cake\Database\ConnectionManager::get('test');
$joint = $this->getMock(
'\Cake\ORM\Table',
['delete', 'find'],
[['alias' => 'ArticlesTags', 'connection' => $connection]]
);
$config = [
'sourceTable' => $this->article,
'targetTable' => $this->tag,
'through' => $joint,
'joinTable' => 'tags_articles'
];
$assoc = $this->getMock(
'\Cake\ORM\Association\BelongsToMany',
['_collectJointEntities', 'save'],
['tags', $config]
);

$assoc
->junction()
->association('tags')
->conditions(['foo' => 1]);

$query1 = $this->getMock(
'\Cake\ORM\Query',
['where', 'andWhere', 'addDefaultTypes'],
[$connection, $joint]
);

$joint->expects($this->at(0))->method('find')
->with('all')
->will($this->returnValue($query1));

$query1->expects($this->once())
->method('where')
->with(['article_id' => 1])
->will($this->returnSelf());
$query1->expects($this->at(1))
->method('andWhere')
->with(['foo' => 1])
->will($this->returnSelf());

$existing = [
new Entity(['article_id' => 1, 'tag_id' => 2]),
new Entity(['article_id' => 1, 'tag_id' => 4]),
new Entity(['article_id' => 1, 'tag_id' => 5]),
new Entity(['article_id' => 1, 'tag_id' => 6])
];
$query1->setResult(new \ArrayIterator($existing));


$opts = ['markNew' => false];
$tags = [
new Entity(['id' => 2], $opts),
new Entity(['id' => 3], $opts),
new Entity(['id' => 6, 'articlesTag' => new Entity(['bar' => 'baz'])])
];
$entity = new Entity(['id' => 1, 'test' => $tags], $opts);

$jointEntities = [
new Entity(['article_id' => 1, 'tag_id' => 2]),
];
$assoc->expects($this->once())->method('_collectJointEntities')
->with($entity, $tags)
->will($this->returnValue($jointEntities));

$joint->expects($this->at(1))
->method('delete')
->with($existing[1]);
$joint->expects($this->at(2))
->method('delete')
->with($existing[2]);

$options = ['foo' => 'bar'];
$assoc->expects($this->once())
->method('save')
->with($entity, $options + ['associated' => false])
->will($this->returnCallback(function($entity) use ($tags) {
$this->assertSame([$tags[1], $tags[2]], $entity->get('tags'));
return true;
}));

$assoc->replaceLinks($entity, $tags, $options);
$this->assertSame($tags, $entity->tags);
$this->assertFalse($entity->dirty('tags'));
}

}

0 comments on commit fa04e06

Please sign in to comment.