Skip to content

Commit fa04e06

Browse files
committed
Adding a unit test for BelongsToMany::replaceLinks
1 parent 5ce7482 commit fa04e06

File tree

2 files changed

+99
-2
lines changed

2 files changed

+99
-2
lines changed

Cake/ORM/Association/BelongsToMany.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -492,9 +492,10 @@ public function replaceLinks(Entity $sourceEntity, array $targetEntities, array
492492
return $this->junction()->connection()->transactional(
493493
function() use ($sourceEntity, $targetEntities, $primaryValue, $options) {
494494
$foreignKey = (array)$this->foreignKey();
495+
$belongsTo = $this->_junctionTable->association($this->target()->alias());
495496
$existing = $this->_junctionTable->find('all')
496497
->where(array_combine($foreignKey, $primaryValue))
497-
->andWHere($this->conditions());
498+
->andWHere($belongsTo->conditions());
498499

499500
$jointEntities = $this->_collectJointEntities($sourceEntity, $targetEntities);
500501
$inserts = $this->_diffLinks($existing, $jointEntities, $targetEntities);

Cake/Test/TestCase/ORM/Association/BelongsToManyTest.php

Lines changed: 97 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -900,7 +900,8 @@ public function testUnlinkWithoutPropertyClean() {
900900
}
901901

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

922+
/**
923+
* Tests that replaceLinks will delete entities not present in the passed
924+
* array, maintain those are already persisted and were passed and also
925+
* insert the rest.
926+
*
927+
* @return void
928+
*/
929+
public function testReplaceLinkSuccess() {
930+
$connection = \Cake\Database\ConnectionManager::get('test');
931+
$joint = $this->getMock(
932+
'\Cake\ORM\Table',
933+
['delete', 'find'],
934+
[['alias' => 'ArticlesTags', 'connection' => $connection]]
935+
);
936+
$config = [
937+
'sourceTable' => $this->article,
938+
'targetTable' => $this->tag,
939+
'through' => $joint,
940+
'joinTable' => 'tags_articles'
941+
];
942+
$assoc = $this->getMock(
943+
'\Cake\ORM\Association\BelongsToMany',
944+
['_collectJointEntities', 'save'],
945+
['tags', $config]
946+
);
947+
948+
$assoc
949+
->junction()
950+
->association('tags')
951+
->conditions(['foo' => 1]);
952+
953+
$query1 = $this->getMock(
954+
'\Cake\ORM\Query',
955+
['where', 'andWhere', 'addDefaultTypes'],
956+
[$connection, $joint]
957+
);
958+
959+
$joint->expects($this->at(0))->method('find')
960+
->with('all')
961+
->will($this->returnValue($query1));
962+
963+
$query1->expects($this->once())
964+
->method('where')
965+
->with(['article_id' => 1])
966+
->will($this->returnSelf());
967+
$query1->expects($this->at(1))
968+
->method('andWhere')
969+
->with(['foo' => 1])
970+
->will($this->returnSelf());
971+
972+
$existing = [
973+
new Entity(['article_id' => 1, 'tag_id' => 2]),
974+
new Entity(['article_id' => 1, 'tag_id' => 4]),
975+
new Entity(['article_id' => 1, 'tag_id' => 5]),
976+
new Entity(['article_id' => 1, 'tag_id' => 6])
977+
];
978+
$query1->setResult(new \ArrayIterator($existing));
979+
980+
981+
$opts = ['markNew' => false];
982+
$tags = [
983+
new Entity(['id' => 2], $opts),
984+
new Entity(['id' => 3], $opts),
985+
new Entity(['id' => 6, 'articlesTag' => new Entity(['bar' => 'baz'])])
986+
];
987+
$entity = new Entity(['id' => 1, 'test' => $tags], $opts);
988+
989+
$jointEntities = [
990+
new Entity(['article_id' => 1, 'tag_id' => 2]),
991+
];
992+
$assoc->expects($this->once())->method('_collectJointEntities')
993+
->with($entity, $tags)
994+
->will($this->returnValue($jointEntities));
995+
996+
$joint->expects($this->at(1))
997+
->method('delete')
998+
->with($existing[1]);
999+
$joint->expects($this->at(2))
1000+
->method('delete')
1001+
->with($existing[2]);
1002+
1003+
$options = ['foo' => 'bar'];
1004+
$assoc->expects($this->once())
1005+
->method('save')
1006+
->with($entity, $options + ['associated' => false])
1007+
->will($this->returnCallback(function($entity) use ($tags) {
1008+
$this->assertSame([$tags[1], $tags[2]], $entity->get('tags'));
1009+
return true;
1010+
}));
1011+
1012+
$assoc->replaceLinks($entity, $tags, $options);
1013+
$this->assertSame($tags, $entity->tags);
1014+
$this->assertFalse($entity->dirty('tags'));
1015+
}
1016+
9211017
}

0 commit comments

Comments
 (0)