From e3674a31e8487054c9c46f50208eebfc30558c31 Mon Sep 17 00:00:00 2001 From: Jeremy Dormitzer Date: Wed, 30 Jan 2019 11:27:47 -0500 Subject: [PATCH] [WIP] Test update handler --- src/Objects/ObjectsService.php | 66 ++++++++++++-------- test/Objects/ObjectsServiceTest.php | 95 ++++++++++++++++++++++++++++- test/TestConfig/ArrayDataSet.php | 1 + 3 files changed, 134 insertions(+), 28 deletions(-) diff --git a/src/Objects/ObjectsService.php b/src/Objects/ObjectsService.php index 058f9b5..dd653cc 100644 --- a/src/Objects/ObjectsService.php +++ b/src/Objects/ObjectsService.php @@ -246,27 +246,44 @@ class ObjectsService if ( ! $object ) { return; } - foreach( $object->getFields() as $field ) { - if ( array_key_exists( $field->getName(), $updatedFields ) ) { - $newValue = $updatedFields[$field->getName()]; - if ( is_array( $newValue ) ) { - $referencedObject = $this->persist( $newValue, 'objects-service.update' ); - $oldTargetObject = $field->getTargetObject(); - $field->setTargetObject( - $referencedObject, $this->dateTimeProvider->getTime( 'objects-service.update' ) - ); - $this->entityManager->persist( $field ); - if ( $oldTargetObject && ! $oldTargetObject->hasField( 'id' ) ) { - $this->entityManager->remove( $oldTargetObject ); - } - } else if ( $newValue === null ) { - $object->removeField( $field ); - $this->entityManager->persist( $object ); - $this->entityManager->remove( $field ); - } else { - $field->setValue( $newValue, $this->dateTimeProvider->getTime( 'objects-service.update' ) ); - $this->entityManager->persist( $field ); + foreach( $updatedFields as $fieldName => $newValue ) { + if ( $newValue === null && $object->hasField( $fieldName ) ) { + $field = $object->getField( $fieldName ); + if ( $field->hasTargetObject() && ! $field->getTargetObject()->hasField( 'id' ) ) { + $targetObject = $field->getTargetObject(); + // Clear the target object by setting a dummy value + $field->setValue( '' ); + $this->entityManager->remove( $targetObject ); } + $object->removeField( $field ); + $this->entityManager->persist( $object ); + $this->entityManager->remove( $field ); + } else if ( $object->hasField( $fieldName ) ) { + $field = $object->getField( $fieldName ); + $oldTargetObject = $field->getTargetObject(); + if ( is_array( $newValue ) ) { + $newTargetObject = $this->persist( $newValue, 'objects-service.update' ); + $field->setTargetObject( + $newTargetObject, + $this->dateTimeProvider->getTime( 'objects-service.update' ) + ); + } else { + $field->setValue( + $newValue, $this->dateTimeProvider->getTime( 'objects-service.update' ) + ); + } + if ( $oldTargetObject && ! $oldTargetObject->hasField( 'id' ) ) { + $this->entityManager->remove( $oldTargetObject ); + } + $this->entityManager->persist( $field ); + } else { + if ( is_array( $newValue ) ) { + $newTargetObject = $this->persist( $newValue ); + $field = Field::withObject( $object, $fieldName, $newTargetObject ); + } else { + $field = Field::withValue( $object, $fieldName, $newValue ); + } + $this->entityManager->persist( $field ); } } $object->setLastUpdated( $this->dateTimeProvider->getTime( 'objects-service.update' ) ); @@ -289,15 +306,12 @@ class ObjectsService if ( ! $existing ) { return; } - $delta = array(); foreach ( $existing->getFields() as $field ) { - if ( array_key_exists( $field->getName(), $replacement ) ) { - $delta[$field->getName()] = $replacement[$field->getName()]; - } else { - $delta[$field->getName()] = null; + if ( ! array_key_exists( $field->getName(), $replacement ) ) { + $replacement[$field->getName()] = null; } } - return $this->update( $id, $delta ); + return $this->update( $id, $replacement ); } } ?> diff --git a/test/Objects/ObjectsServiceTest.php b/test/Objects/ObjectsServiceTest.php index 75a1acc..c64258b 100644 --- a/test/Objects/ObjectsServiceTest.php +++ b/test/Objects/ObjectsServiceTest.php @@ -10,6 +10,7 @@ use ActivityPub\Entities\Field; use Doctrine\ORM\EntityManager; use ActivityPub\Objects\ObjectsService; use ActivityPub\Database\PrefixNamingStrategy; +use ActivityPub\Test\TestUtils\TestActivityPubObject; use ActivityPub\Test\TestUtils\TestDateTimeProvider; use Doctrine\ORM\Tools\Setup; use GuzzleHttp\Client; @@ -1199,8 +1200,98 @@ class ObjectsServiceTest extends SQLiteTestCase public function testReplace() { - // TODO implement me - $this->assertTrue( false ); + $testCases = array( + array( + 'id' => 'basicTest', + 'object' => array( + 'id' => 'https://example.com/objects/1', + 'type' => 'Article', + 'summary' => 'An article', + ), + 'replacementId' => 'https://example.com/objects/1', + 'replacement' => array( + 'id' => 'https://example.com/objects/1', + 'type' => 'Note', + 'contents' => 'This is a note', + ), + 'expectedObject' => array( + 'id' => 'https://example.com/objects/1', + 'type' => 'Note', + 'contents' => 'This is a note', + ), + ), + array( + 'id' => 'itUpdatesTargetObject', + 'object' => array( + 'id' => 'https://example.com/objects/2', + 'type' => 'Article', + 'attributedTo' => array( + 'id' => 'https://example.com/actors/1' + ), + 'foo' => array( + 'bar' => 'baz', + ), + ), + 'replacementId' => 'https://example.com/objects/2', + 'replacement' => array( + 'id' => 'https://example.com/objects/2', + 'type' => 'Article', + 'attributedTo' => 'https://example.com/actors/1', + ), + 'expectedObject' => array( + 'id' => 'https://example.com/objects/2', + 'type' => 'Article', + 'attributedTo' => 'https://example.com/actors/1', + ), + 'expectedDatabaseState' => array( + 'objects' => array( + array( + 'id' => 1, + 'created' => $this->getTime( 'objects-service.create' ), + 'updated' => $this->getTime( 'objects-service.update' ), + ), + array( + 'id' => 2, + 'created' => $this->getTime( 'objects-service.create' ), + 'updated' => $this->getTime( 'objects-service.update' ), + ), + array( + 'id' => 3, + 'created' => $this->getTime( 'objects-service.create' ), + 'updated' => $this->getTime( 'objects-service.update' ), + ), + ), + 'fields' => array( + + ), + ), + ), + ); + foreach ( $testCases as $testCase ) { + $this->objectsService->persist( $testCase['object'] ); + $replacement = $this->objectsService->replace( + $testCase['replacementId'], + $testCase['replacement'] + ); + $this->assertEquals( + $testCase['expectedObject'], + $replacement->asArray(), + "Error on test $testCase[id]" + ); + if ( array_key_exists( 'expectedDatabaseState', $testCase ) ) { + $expectedDb = new ArrayDataSet( $testCase['expectedDatabaseState'] ); + $expectedObjectsTable = $expectedDb->getTable('objects'); + $expectedFieldsTable = $expectedDb->getTable('fields'); + $objectsQueryTable = $this->getConnection()->createQueryTable( + 'objects', 'SELECT * FROM objects' + ); + $fieldsQueryTable = $this->getConnection()->createQueryTable( + 'fields', 'SELECT * FROM fields' + ); + $this->assertTablesEqual( $expectedObjectsTable, $objectsQueryTable ); + $this->assertTablesEqual( $expectedFieldsTable, $fieldsQueryTable ); + } + } } } ?> diff --git a/test/TestConfig/ArrayDataSet.php b/test/TestConfig/ArrayDataSet.php index 4599cad..5630e54 100644 --- a/test/TestConfig/ArrayDataSet.php +++ b/test/TestConfig/ArrayDataSet.php @@ -1,6 +1,7 @@