|
|
@@ -482,4 +482,426 @@ class MarshallerTest extends TestCase {
|
|
|
$this->assertInstanceOf('Cake\ORM\Entity', $result->tags[2]);
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * Test merge() in a simple use.
|
|
|
+ *
|
|
|
+ * @return void
|
|
|
+ */
|
|
|
+ public function testMergeSimple() {
|
|
|
+ $data = [
|
|
|
+ 'title' => 'My title',
|
|
|
+ 'author_id' => 1,
|
|
|
+ 'not_in_schema' => true
|
|
|
+ ];
|
|
|
+ $marshall = new Marshaller($this->articles);
|
|
|
+ $entity = new Entity([
|
|
|
+ 'title' => 'Foo',
|
|
|
+ 'body' => 'My Content'
|
|
|
+ ]);
|
|
|
+ $entity->accessible('*', true);
|
|
|
+ $entity->isNew(false);
|
|
|
+ $entity->clean();
|
|
|
+ $result = $marshall->merge($entity, $data, []);
|
|
|
+
|
|
|
+ $this->assertSame($entity, $result);
|
|
|
+ $this->assertEquals($data + ['body' => 'My Content'], $result->toArray());
|
|
|
+ $this->assertTrue($result->dirty(), 'Should be a dirty entity.');
|
|
|
+ $this->assertFalse($result->isNew(), 'Should not change the entity state');
|
|
|
+ }
|
|
|
+
|
|
|
+/**
|
|
|
+ * Tests that merge respects the entity accessible methods
|
|
|
+ *
|
|
|
+ * @return void
|
|
|
+ */
|
|
|
+ public function testMergeWhitelist() {
|
|
|
+ $data = [
|
|
|
+ 'title' => 'My title',
|
|
|
+ 'author_id' => 1,
|
|
|
+ 'not_in_schema' => true
|
|
|
+ ];
|
|
|
+ $marshall = new Marshaller($this->articles);
|
|
|
+ $entity = new Entity([
|
|
|
+ 'title' => 'Foo',
|
|
|
+ 'body' => 'My Content'
|
|
|
+ ]);
|
|
|
+ $entity->accessible('author_id', true);
|
|
|
+ $entity->isNew(false);
|
|
|
+ $result = $marshall->merge($entity, $data, []);
|
|
|
+
|
|
|
+ $expected = [
|
|
|
+ 'title' => 'Foo',
|
|
|
+ 'body' => 'My Content',
|
|
|
+ 'author_id' => 1
|
|
|
+ ];
|
|
|
+ $this->assertEquals($expected, $result->toArray());
|
|
|
+ }
|
|
|
+
|
|
|
+/**
|
|
|
+ * Tests that fields with the same value are not marked as dirty
|
|
|
+ *
|
|
|
+ * @return void
|
|
|
+ */
|
|
|
+ public function testMergeDirty() {
|
|
|
+ $marshall = new Marshaller($this->articles);
|
|
|
+ $entity = new Entity([
|
|
|
+ 'title' => 'Foo',
|
|
|
+ 'author_id' => 1
|
|
|
+ ]);
|
|
|
+ $data = [
|
|
|
+ 'title' => 'Foo',
|
|
|
+ 'author_id' => 1,
|
|
|
+ 'crazy' => true
|
|
|
+ ];
|
|
|
+ $entity->accessible('*', true);
|
|
|
+ $entity->clean();
|
|
|
+ $result = $marshall->merge($entity, $data, []);
|
|
|
+
|
|
|
+ $expected = [
|
|
|
+ 'title' => 'Foo',
|
|
|
+ 'author_id' => 1,
|
|
|
+ 'crazy' => true
|
|
|
+ ];
|
|
|
+ $this->assertEquals($expected, $result->toArray());
|
|
|
+ $this->assertFalse($entity->dirty('title'));
|
|
|
+ $this->assertFalse($entity->dirty('author_id'));
|
|
|
+ $this->assertTrue($entity->dirty('crazy'));
|
|
|
+ }
|
|
|
+
|
|
|
+/**
|
|
|
+ * Tests merging data into an associated entity
|
|
|
+ *
|
|
|
+ * @return void
|
|
|
+ */
|
|
|
+ public function testMergeWithSingleAssociation() {
|
|
|
+ $user = new Entity([
|
|
|
+ 'username' => 'mark',
|
|
|
+ 'password' => 'secret'
|
|
|
+ ]);
|
|
|
+ $entity = new Entity([
|
|
|
+ 'tile' => 'My Title',
|
|
|
+ 'user' => $user
|
|
|
+ ]);
|
|
|
+ $user->accessible('*', true);
|
|
|
+ $entity->accessible('*', true);
|
|
|
+
|
|
|
+ $data = [
|
|
|
+ 'body' => 'My Content',
|
|
|
+ 'user' => [
|
|
|
+ 'password' => 'not a secret'
|
|
|
+ ]
|
|
|
+ ];
|
|
|
+ $marshall = new Marshaller($this->articles);
|
|
|
+ $marshall->merge($entity, $data, ['Users']);
|
|
|
+ $this->assertEquals('My Content', $entity->body);
|
|
|
+ $this->assertSame($user, $entity->user);
|
|
|
+ $this->assertEquals('mark', $entity->user->username);
|
|
|
+ $this->assertEquals('not a secret', $entity->user->password);
|
|
|
+ $this->assertTrue($entity->dirty('user'));
|
|
|
+ }
|
|
|
+
|
|
|
+/**
|
|
|
+ * Tests that new associated entities can be created when merging data into
|
|
|
+ * a parent entity
|
|
|
+ *
|
|
|
+ * @return void
|
|
|
+ */
|
|
|
+ public function testMergeCreateAssociation() {
|
|
|
+ $entity = new Entity([
|
|
|
+ 'tile' => 'My Title'
|
|
|
+ ]);
|
|
|
+ $entity->accessible('*', true);
|
|
|
+ $data = [
|
|
|
+ 'body' => 'My Content',
|
|
|
+ 'user' => [
|
|
|
+ 'username' => 'mark',
|
|
|
+ 'password' => 'not a secret'
|
|
|
+ ]
|
|
|
+ ];
|
|
|
+ $marshall = new Marshaller($this->articles);
|
|
|
+ $marshall->merge($entity, $data, ['Users']);
|
|
|
+ $this->assertEquals('My Content', $entity->body);
|
|
|
+ $this->assertInstanceOf('Cake\ORM\Entity', $entity->user);
|
|
|
+ $this->assertEquals('mark', $entity->user->username);
|
|
|
+ $this->assertEquals('not a secret', $entity->user->password);
|
|
|
+ $this->assertTrue($entity->dirty('user'));
|
|
|
+ $this->assertNull($entity->user->isNew());
|
|
|
+ }
|
|
|
+
|
|
|
+/**
|
|
|
+ * Tests merging one to many associations
|
|
|
+ *
|
|
|
+ * @return void
|
|
|
+ */
|
|
|
+ public function testMergeMultipleAssociations() {
|
|
|
+ $user = new Entity(['username' => 'mark', 'password' => 'secret']);
|
|
|
+ $comment1 = new Entity(['id' => 1, 'comment' => 'A comment']);
|
|
|
+ $comment2 = new Entity(['id' => 2, 'comment' => 'Another comment']);
|
|
|
+ $entity = new Entity([
|
|
|
+ 'title' => 'My Title',
|
|
|
+ 'user' => $user,
|
|
|
+ 'comments' => [$comment1, $comment2]
|
|
|
+ ]);
|
|
|
+
|
|
|
+ $user->accessible('*', true);
|
|
|
+ $comment1->accessible('*', true);
|
|
|
+ $comment2->accessible('*', true);
|
|
|
+ $entity->accessible('*', true);
|
|
|
+
|
|
|
+ $data = [
|
|
|
+ 'title' => 'Another title',
|
|
|
+ 'user' => ['password' => 'not so secret'],
|
|
|
+ 'comments' => [
|
|
|
+ ['comment' => 'Extra comment 1'],
|
|
|
+ ['id' => 2, 'comment' => 'Altered comment 2'],
|
|
|
+ ['id' => 1, 'comment' => 'Altered comment 1'],
|
|
|
+ ['id' => 3, 'comment' => 'Extra comment 3'],
|
|
|
+ ['comment' => 'Extra comment 2']
|
|
|
+ ]
|
|
|
+ ];
|
|
|
+ $marshall = new Marshaller($this->articles);
|
|
|
+ $result = $marshall->merge($entity, $data, ['Users', 'Comments']);
|
|
|
+ $this->assertSame($entity, $result);
|
|
|
+ $this->assertSame($user, $result->user);
|
|
|
+ $this->assertEquals('not so secret', $entity->user->password);
|
|
|
+ $this->assertSame($comment1, $entity->comments[0]);
|
|
|
+ $this->assertSame($comment2, $entity->comments[1]);
|
|
|
+ $this->assertEquals('Altered comment 1', $entity->comments[0]->comment);
|
|
|
+ $this->assertEquals('Altered comment 2', $entity->comments[1]->comment);
|
|
|
+ $this->assertEquals(
|
|
|
+ ['comment' => 'Extra comment 3', 'id' => 3],
|
|
|
+ $entity->comments[2]->toArray()
|
|
|
+ );
|
|
|
+ $this->assertEquals(
|
|
|
+ ['comment' => 'Extra comment 1'],
|
|
|
+ $entity->comments[3]->toArray()
|
|
|
+ );
|
|
|
+ $this->assertEquals(
|
|
|
+ ['comment' => 'Extra comment 2'],
|
|
|
+ $entity->comments[4]->toArray()
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+/**
|
|
|
+ * Tests that merging data to an entity containing belongsToMany and _ids
|
|
|
+ * will just overwrite the data
|
|
|
+ *
|
|
|
+ * @return void
|
|
|
+ */
|
|
|
+ public function testMergeBelongsToManyEntitiesFromIds() {
|
|
|
+ $entity = new Entity([
|
|
|
+ 'title' => 'Haz tags',
|
|
|
+ 'body' => 'Some content here',
|
|
|
+ 'tags' => [
|
|
|
+ new Entity(['id' => 1, 'name' => 'Cake']),
|
|
|
+ new Entity(['id' => 2, 'name' => 'PHP'])
|
|
|
+ ]
|
|
|
+ ]);
|
|
|
+
|
|
|
+ $data = [
|
|
|
+ 'title' => 'Haz moar tags',
|
|
|
+ 'tags' => ['_ids' => [1, 2, 3]]
|
|
|
+ ];
|
|
|
+ $entity->accessible('*', true);
|
|
|
+ $marshall = new Marshaller($this->articles);
|
|
|
+ $result = $marshall->merge($entity, $data, ['Tags']);
|
|
|
+
|
|
|
+ $this->assertCount(3, $result->tags);
|
|
|
+ $this->assertInstanceOf('Cake\ORM\Entity', $result->tags[0]);
|
|
|
+ $this->assertInstanceOf('Cake\ORM\Entity', $result->tags[1]);
|
|
|
+ $this->assertInstanceOf('Cake\ORM\Entity', $result->tags[2]);
|
|
|
+ }
|
|
|
+
|
|
|
+/**
|
|
|
+ * Test merging the _joinData entity for belongstomany associations.
|
|
|
+ *
|
|
|
+ * @return void
|
|
|
+ */
|
|
|
+ public function testMergeBelongsToManyJoinData() {
|
|
|
+ $data = [
|
|
|
+ 'title' => 'My title',
|
|
|
+ 'body' => 'My content',
|
|
|
+ 'author_id' => 1,
|
|
|
+ 'tags' => [
|
|
|
+ [
|
|
|
+ 'id' => 1,
|
|
|
+ 'tag' => 'news',
|
|
|
+ '_joinData' => [
|
|
|
+ 'active' => 0
|
|
|
+ ]
|
|
|
+ ],
|
|
|
+ [
|
|
|
+ 'id' => 2,
|
|
|
+ 'tag' => 'cakephp',
|
|
|
+ '_joinData' => [
|
|
|
+ 'active' => 0
|
|
|
+ ]
|
|
|
+ ],
|
|
|
+ ],
|
|
|
+ ];
|
|
|
+
|
|
|
+ $options = ['Tags' => ['associated' => ['_joinData']]];
|
|
|
+ $marshall = new Marshaller($this->articles);
|
|
|
+ $entity = $marshall->one($data, $options);
|
|
|
+ $entity->accessible('*', true);
|
|
|
+
|
|
|
+ $data = [
|
|
|
+ 'title' => 'Haz data',
|
|
|
+ 'tags' => [
|
|
|
+ ['id' => 1, 'tag' => 'Cake', '_joinData' => ['foo' => 'bar']],
|
|
|
+ ['tag' => 'new tag', '_joinData' => ['active' => 1, 'foo' => 'baz']]
|
|
|
+ ]
|
|
|
+ ];
|
|
|
+
|
|
|
+ $tag1 = $entity->tags[0];
|
|
|
+ $result = $marshall->merge($entity, $data, $options);
|
|
|
+ $this->assertEquals($data['title'], $result->title);
|
|
|
+ $this->assertEquals('My content', $result->body);
|
|
|
+ $this->assertSame($tag1, $entity->tags[0]);
|
|
|
+ $this->assertSame($tag1->_joinData, $entity->tags[0]->_joinData);
|
|
|
+ $this->assertSame(
|
|
|
+ ['active' => 0, 'foo' => 'bar'],
|
|
|
+ $entity->tags[0]->_joinData->toArray()
|
|
|
+ );
|
|
|
+ $this->assertSame(
|
|
|
+ ['active' => 1, 'foo' => 'baz'],
|
|
|
+ $entity->tags[1]->_joinData->toArray()
|
|
|
+ );
|
|
|
+ $this->assertEquals('new tag', $entity->tags[1]->tag);
|
|
|
+ $this->assertTrue($entity->tags[0]->dirty('_joinData'));
|
|
|
+ $this->assertTrue($entity->tags[1]->dirty('_joinData'));
|
|
|
+ }
|
|
|
+
|
|
|
+/**
|
|
|
+ * Test merging associations inside _joinData
|
|
|
+ *
|
|
|
+ * @return void
|
|
|
+ */
|
|
|
+ public function testMergeJoinDataAssociations() {
|
|
|
+ $data = [
|
|
|
+ 'title' => 'My title',
|
|
|
+ 'body' => 'My content',
|
|
|
+ 'author_id' => 1,
|
|
|
+ 'tags' => [
|
|
|
+ [
|
|
|
+ 'id' => 1,
|
|
|
+ 'tag' => 'news',
|
|
|
+ '_joinData' => [
|
|
|
+ 'active' => 0,
|
|
|
+ 'user' => ['username' => 'Bill']
|
|
|
+ ]
|
|
|
+ ],
|
|
|
+ [
|
|
|
+ 'id' => 2,
|
|
|
+ 'tag' => 'cakephp',
|
|
|
+ '_joinData' => [
|
|
|
+ 'active' => 0
|
|
|
+ ]
|
|
|
+ ],
|
|
|
+ ]
|
|
|
+ ];
|
|
|
+
|
|
|
+ $articlesTags = TableRegistry::get('ArticlesTags');
|
|
|
+ $articlesTags->belongsTo('Users');
|
|
|
+
|
|
|
+ $options = [
|
|
|
+ 'Tags' => [
|
|
|
+ 'associated' => [
|
|
|
+ '_joinData' => ['associated' => ['Users']]
|
|
|
+ ]
|
|
|
+ ]
|
|
|
+ ];
|
|
|
+ $marshall = new Marshaller($this->articles);
|
|
|
+ $entity = $marshall->one($data, $options);
|
|
|
+ $entity->accessible('*', true);
|
|
|
+
|
|
|
+ $data = [
|
|
|
+ 'title' => 'Haz data',
|
|
|
+ 'tags' => [
|
|
|
+ [
|
|
|
+ 'id' => 1,
|
|
|
+ 'tag' => 'news',
|
|
|
+ '_joinData' => [
|
|
|
+ 'foo' => 'bar',
|
|
|
+ 'user' => ['password' => 'secret']
|
|
|
+ ]
|
|
|
+ ],
|
|
|
+ [
|
|
|
+ 'id' => 2,
|
|
|
+ '_joinData' => [
|
|
|
+ 'active' => 1,
|
|
|
+ 'foo' => 'baz',
|
|
|
+ 'user' => ['username' => 'ber']
|
|
|
+ ]
|
|
|
+ ]
|
|
|
+ ]
|
|
|
+ ];
|
|
|
+
|
|
|
+ $tag1 = $entity->tags[0];
|
|
|
+ $result = $marshall->merge($entity, $data, $options);
|
|
|
+ $this->assertEquals($data['title'], $result->title);
|
|
|
+ $this->assertEquals('My content', $result->body);
|
|
|
+ $this->assertSame($tag1, $entity->tags[0]);
|
|
|
+ $this->assertSame($tag1->_joinData, $entity->tags[0]->_joinData);
|
|
|
+ $this->assertEquals('Bill', $entity->tags[0]->_joinData->user->username);
|
|
|
+ $this->assertEquals('secret', $entity->tags[0]->_joinData->user->password);
|
|
|
+ $this->assertEquals('ber', $entity->tags[1]->_joinData->user->username);
|
|
|
+ }
|
|
|
+
|
|
|
+/**
|
|
|
+ * Test mergeMany() with a simple set of data.
|
|
|
+ *
|
|
|
+ * @return void
|
|
|
+ */
|
|
|
+ public function testMergeManySimple() {
|
|
|
+ $entities = [
|
|
|
+ new OpenEntity(['id' => 1, 'comment' => 'First post', 'user_id' => 2]),
|
|
|
+ new OpenEntity(['id' => 2, 'comment' => 'Second post', 'user_id' => 2])
|
|
|
+ ];
|
|
|
+ $entities[0]->clean();
|
|
|
+ $entities[1]->clean();
|
|
|
+
|
|
|
+ $data = [
|
|
|
+ ['id' => 2, 'comment' => 'Changed 2', 'user_id' => 2],
|
|
|
+ ['id' => 1, 'comment' => 'Changed 1', 'user_id' => 1]
|
|
|
+ ];
|
|
|
+ $marshall = new Marshaller($this->comments);
|
|
|
+ $result = $marshall->mergeMany($entities, $data);
|
|
|
+
|
|
|
+ $this->assertSame($entities[0], $result[0]);
|
|
|
+ $this->assertSame($entities[1], $result[1]);
|
|
|
+ $this->assertEquals('Changed 1', $result[0]->comment);
|
|
|
+ $this->assertEquals(1, $result[0]->user_id);
|
|
|
+ $this->assertEquals('Changed 2', $result[1]->comment);
|
|
|
+ $this->assertTrue($result[0]->dirty('user_id'));
|
|
|
+ $this->assertFalse($result[1]->dirty('user_id'));
|
|
|
+ }
|
|
|
+
|
|
|
+/**
|
|
|
+ * Tests that only records found in the data array are returned, those that cannot
|
|
|
+ * be matched are discarded
|
|
|
+ *
|
|
|
+ * @return void
|
|
|
+ */
|
|
|
+ public function testMergeManyWithAppend() {
|
|
|
+ $entities = [
|
|
|
+ new OpenEntity(['comment' => 'First post', 'user_id' => 2]),
|
|
|
+ new OpenEntity(['id' => 2, 'comment' => 'Second post', 'user_id' => 2])
|
|
|
+ ];
|
|
|
+ $entities[0]->clean();
|
|
|
+ $entities[1]->clean();
|
|
|
+
|
|
|
+ $data = [
|
|
|
+ ['id' => 2, 'comment' => 'Changed 2', 'user_id' => 2],
|
|
|
+ ['id' => 1, 'comment' => 'Comment 1', 'user_id' => 1]
|
|
|
+ ];
|
|
|
+ $marshall = new Marshaller($this->comments);
|
|
|
+ $result = $marshall->mergeMany($entities, $data);
|
|
|
+
|
|
|
+ $this->assertCount(2, $result);
|
|
|
+ $this->assertNotSame($entities[0], $result[0]);
|
|
|
+ $this->assertSame($entities[1], $result[0]);
|
|
|
+ $this->assertEquals('Changed 2', $result[0]->comment);
|
|
|
+ }
|
|
|
+
|
|
|
}
|