1307 lines
47 KiB
PHP
1307 lines
47 KiB
PHP
<?php /** @noinspection PhpUnhandledExceptionInspection */
|
|
|
|
namespace ActivityPub\Test\Objects;
|
|
|
|
use ActivityPub\Database\PrefixNamingStrategy;
|
|
use ActivityPub\Entities\ActivityPubObject;
|
|
use ActivityPub\Objects\ObjectsService;
|
|
use ActivityPub\Test\TestConfig\ArrayDataSet;
|
|
use ActivityPub\Test\TestConfig\SQLiteTestCase;
|
|
use ActivityPub\Test\TestUtils\TestDateTimeProvider;
|
|
use ActivityPub\Utils\DateTimeProvider;
|
|
use BadMethodCallException;
|
|
use DateTime;
|
|
use Doctrine\ORM\EntityManager;
|
|
use Doctrine\ORM\Tools\Setup;
|
|
use GuzzleHttp\Client;
|
|
use GuzzleHttp\Psr7\Response;
|
|
|
|
class ObjectsServiceTest extends SQLiteTestCase
|
|
{
|
|
/**
|
|
* @var EntityManager
|
|
*/
|
|
protected $entityManager;
|
|
/**
|
|
* @var ObjectsService
|
|
*/
|
|
protected $objectsService;
|
|
/**
|
|
* @var DateTimeProvider
|
|
*/
|
|
protected $dateTimeProvider;
|
|
/**
|
|
* @var Client
|
|
*/
|
|
protected $httpClient;
|
|
|
|
public function testItCreatesObject()
|
|
{
|
|
$fields = array(
|
|
'id' => 'https://example.com/notes/1',
|
|
'type' => 'Note',
|
|
'content' => 'This is a note',
|
|
);
|
|
$now = $this->getTime( 'objects-service.create' );
|
|
$this->objectsService->persist( $fields );
|
|
$expected = new ArrayDataSet( array(
|
|
'objects' => array(
|
|
array( 'id' => 1, 'created' => $now, 'lastUpdated' => $now )
|
|
),
|
|
'fields' => array(
|
|
array(
|
|
'id' => 1,
|
|
'object_id' => 1,
|
|
'name' => 'id',
|
|
'value' => 'https://example.com/notes/1',
|
|
'created' => $now,
|
|
'lastUpdated' => $now,
|
|
'targetObject_id' => null,
|
|
),
|
|
array(
|
|
'id' => 2,
|
|
'object_id' => 1,
|
|
'name' => 'type',
|
|
'value' => 'Note',
|
|
'created' => $now,
|
|
'lastUpdated' => $now,
|
|
'targetObject_id' => null,
|
|
),
|
|
array(
|
|
'id' => 3,
|
|
'object_id' => 1,
|
|
'name' => 'content',
|
|
'value' => 'This is a note',
|
|
'created' => $now,
|
|
'lastUpdated' => $now,
|
|
'targetObject_id' => null,
|
|
),
|
|
),
|
|
) );
|
|
$expectedObjectsTable = $expected->getTable( 'objects' );
|
|
$expectedFieldsTable = $expected->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 );
|
|
}
|
|
|
|
private function getTime( $context )
|
|
{
|
|
return $this->dateTimeProvider
|
|
->getTime( $context )
|
|
->format( "Y-m-d H:i:s" );
|
|
}
|
|
|
|
public function testObjectFieldsSet()
|
|
{
|
|
$fields = array(
|
|
'id' => 'https://example.com/notes/1',
|
|
'type' => 'Note',
|
|
'content' => 'This is a note',
|
|
);
|
|
$object = $this->objectsService->persist( $fields );
|
|
$this->assertCount( 3, $object->getFields() );
|
|
$this->assertEmpty( $object->getReferencingFields() );
|
|
}
|
|
|
|
public function testSerializesToArray()
|
|
{
|
|
$fields = array(
|
|
'id' => 'https://example.com/notes/1',
|
|
'type' => 'Note',
|
|
'content' => 'This is a note',
|
|
);
|
|
$object = $this->objectsService->persist( $fields );
|
|
$this->assertEquals( $fields, $object->asArray() );
|
|
}
|
|
|
|
public function testDeSerOneItemArrays()
|
|
{
|
|
$fields = array(
|
|
'id' => 'https://example.com/collections/1',
|
|
'type' => 'Collection',
|
|
'items' => array( "https://example.com/items/1" ),
|
|
);
|
|
$object = $this->objectsService->persist( $fields );
|
|
$this->assertEquals( $fields, $object->asArray() );
|
|
}
|
|
|
|
public function testDbStartsEmpty()
|
|
{
|
|
$this->assertSame( 0, $this->getConnection()->getRowCount( 'objects' ) );
|
|
$this->assertSame( 0, $this->getConnection()->getRowCount( 'fields' ) );
|
|
}
|
|
|
|
public function testItCreatesNestedObjects()
|
|
{
|
|
$fields = array(
|
|
'id' => 'https://example.com/notes/1',
|
|
'type' => 'Note',
|
|
'content' => 'This is a note',
|
|
'attributedTo' => array(
|
|
'id' => 'https://example.com/actors/1',
|
|
'type' => 'Person',
|
|
),
|
|
);
|
|
$now = $this->getTime( 'objects-service.create' );
|
|
$this->objectsService->persist( $fields );
|
|
$expected = new ArrayDataSet( array(
|
|
'objects' => array(
|
|
array( 'id' => 1, 'created' => $now, 'lastUpdated' => $now ),
|
|
array( 'id' => 2, 'created' => $now, 'lastUpdated' => $now ),
|
|
),
|
|
'fields' => array(
|
|
array(
|
|
'id' => 1,
|
|
'object_id' => 1,
|
|
'name' => 'id',
|
|
'value' => 'https://example.com/notes/1',
|
|
'created' => $now,
|
|
'lastUpdated' => $now,
|
|
'targetObject_id' => null,
|
|
),
|
|
array(
|
|
'id' => 2,
|
|
'object_id' => 1,
|
|
'name' => 'type',
|
|
'value' => 'Note',
|
|
'created' => $now,
|
|
'lastUpdated' => $now,
|
|
'targetObject_id' => null,
|
|
),
|
|
array(
|
|
'id' => 3,
|
|
'object_id' => 1,
|
|
'name' => 'content',
|
|
'value' => 'This is a note',
|
|
'created' => $now,
|
|
'lastUpdated' => $now,
|
|
'targetObject_id' => null,
|
|
),
|
|
array(
|
|
'id' => 4,
|
|
'object_id' => 2,
|
|
'name' => 'id',
|
|
'value' => 'https://example.com/actors/1',
|
|
'created' => $now,
|
|
'lastUpdated' => $now,
|
|
'targetObject_id' => null,
|
|
),
|
|
array(
|
|
'id' => 5,
|
|
'object_id' => 2,
|
|
'name' => 'type',
|
|
'value' => 'Person',
|
|
'created' => $now,
|
|
'lastUpdated' => $now,
|
|
'targetObject_id' => null,
|
|
),
|
|
array(
|
|
'id' => 6,
|
|
'object_id' => 1,
|
|
'name' => 'attributedTo',
|
|
'value' => null,
|
|
'created' => $now,
|
|
'lastUpdated' => $now,
|
|
'targetObject_id' => 2,
|
|
),
|
|
),
|
|
) );
|
|
$expectedObjectsTable = $expected->getTable( 'objects' );
|
|
$expectedFieldsTable = $expected->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 );
|
|
}
|
|
|
|
public function testItSerializesNestedObjects()
|
|
{
|
|
$fields = array(
|
|
'id' => 'https://example.com/notes/1',
|
|
'type' => 'Note',
|
|
'content' => 'This is a note',
|
|
'attributedTo' => array(
|
|
'id' => 'https://example.com/actors/1',
|
|
'type' => 'Person',
|
|
),
|
|
);
|
|
$object = $this->objectsService->persist( $fields );
|
|
$this->assertEquals( $fields, $object->asArray() );
|
|
}
|
|
|
|
public function testItCreatesObjectsWithArray()
|
|
{
|
|
$fields = array(
|
|
'id' => 'https://example.com/collections/1',
|
|
'type' => 'Collection',
|
|
'items' => array(
|
|
"https://example.com/notes/1",
|
|
"https://example.com/notes/2",
|
|
),
|
|
);
|
|
$now = $this->getTime( 'objects-service.create' );
|
|
$this->objectsService->persist( $fields );
|
|
$expected = new ArrayDataSet( array(
|
|
'objects' => array(
|
|
array( 'id' => 1, 'created' => $now, 'lastUpdated' => $now ),
|
|
array( 'id' => 2, 'created' => $now, 'lastUpdated' => $now ),
|
|
),
|
|
'fields' => array(
|
|
array(
|
|
'id' => 1,
|
|
'object_id' => 1,
|
|
'name' => 'id',
|
|
'value' => 'https://example.com/collections/1',
|
|
'created' => $now,
|
|
'lastUpdated' => $now,
|
|
'targetObject_id' => null,
|
|
),
|
|
array(
|
|
'id' => 2,
|
|
'object_id' => 1,
|
|
'name' => 'type',
|
|
'value' => 'Collection',
|
|
'created' => $now,
|
|
'lastUpdated' => $now,
|
|
'targetObject_id' => null,
|
|
),
|
|
array(
|
|
'id' => 3,
|
|
'object_id' => 2,
|
|
'name' => '0',
|
|
'value' => 'https://example.com/notes/1',
|
|
'created' => $now,
|
|
'lastUpdated' => $now,
|
|
'targetObject_id' => null,
|
|
),
|
|
array(
|
|
'id' => 4,
|
|
'object_id' => 2,
|
|
'name' => '1',
|
|
'value' => 'https://example.com/notes/2',
|
|
'created' => $now,
|
|
'lastUpdated' => $now,
|
|
'targetObject_id' => null,
|
|
),
|
|
array(
|
|
'id' => 5,
|
|
'object_id' => 1,
|
|
'name' => 'items',
|
|
'value' => null,
|
|
'created' => $now,
|
|
'lastUpdated' => $now,
|
|
'targetObject_id' => 2,
|
|
),
|
|
),
|
|
) );
|
|
$expectedObjectsTable = $expected->getTable( 'objects' );
|
|
$expectedFieldsTable = $expected->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 );
|
|
}
|
|
|
|
public function testItSerializesArrayFields()
|
|
{
|
|
$fields = array(
|
|
'id' => 'https://example.com/collections/1',
|
|
'type' => 'Collection',
|
|
'items' => array(
|
|
"https://example.com/notes/1",
|
|
"https://example.com/notes/2",
|
|
),
|
|
);
|
|
$object = $this->objectsService->persist( $fields );
|
|
$this->assertEquals( $fields, $object->asArray() );
|
|
}
|
|
|
|
public function testItCreatesNestedObjectArrayFields()
|
|
{
|
|
$fields = array(
|
|
'id' => 'https://example.com/collections/1',
|
|
'type' => 'Collection',
|
|
'items' => array(
|
|
array(
|
|
'id' => 'https://example.com/notes/1',
|
|
'type' => 'Note',
|
|
'content' => 'This is a note',
|
|
),
|
|
array(
|
|
'id' => 'https://example.com/notes/2',
|
|
'type' => 'Note',
|
|
'content' => 'This is another note',
|
|
),
|
|
),
|
|
);
|
|
$now = $this->getTime( 'objects-service.create' );
|
|
$this->objectsService->persist( $fields );
|
|
$expected = new ArrayDataSet( array(
|
|
'objects' => array(
|
|
array( 'id' => 1, 'created' => $now, 'lastUpdated' => $now ),
|
|
array( 'id' => 2, 'created' => $now, 'lastUpdated' => $now ),
|
|
array( 'id' => 3, 'created' => $now, 'lastUpdated' => $now ),
|
|
array( 'id' => 4, 'created' => $now, 'lastUpdated' => $now ),
|
|
),
|
|
'fields' => array(
|
|
array(
|
|
'id' => 1,
|
|
'object_id' => 1,
|
|
'name' => 'id',
|
|
'value' => 'https://example.com/collections/1',
|
|
'created' => $now,
|
|
'lastUpdated' => $now,
|
|
'targetObject_id' => null,
|
|
),
|
|
array(
|
|
'id' => 2,
|
|
'object_id' => 1,
|
|
'name' => 'type',
|
|
'value' => 'Collection',
|
|
'created' => $now,
|
|
'lastUpdated' => $now,
|
|
'targetObject_id' => null,
|
|
),
|
|
array(
|
|
'id' => 3,
|
|
'object_id' => 3,
|
|
'name' => 'id',
|
|
'value' => 'https://example.com/notes/1',
|
|
'created' => $now,
|
|
'lastUpdated' => $now,
|
|
'targetObject_id' => null,
|
|
),
|
|
array(
|
|
'id' => 4,
|
|
'object_id' => 3,
|
|
'name' => 'type',
|
|
'value' => 'Note',
|
|
'created' => $now,
|
|
'lastUpdated' => $now,
|
|
'targetObject_id' => null,
|
|
),
|
|
array(
|
|
'id' => 5,
|
|
'object_id' => 3,
|
|
'name' => 'content',
|
|
'value' => 'This is a note',
|
|
'created' => $now,
|
|
'lastUpdated' => $now,
|
|
'targetObject_id' => null,
|
|
),
|
|
array(
|
|
'id' => 6,
|
|
'object_id' => 2,
|
|
'name' => '0',
|
|
'value' => null,
|
|
'created' => $now,
|
|
'lastUpdated' => $now,
|
|
'targetObject_id' => 3,
|
|
),
|
|
array(
|
|
'id' => 7,
|
|
'object_id' => 4,
|
|
'name' => 'id',
|
|
'value' => 'https://example.com/notes/2',
|
|
'created' => $now,
|
|
'lastUpdated' => $now,
|
|
'targetObject_id' => null,
|
|
),
|
|
array(
|
|
'id' => 8,
|
|
'object_id' => 4,
|
|
'name' => 'type',
|
|
'value' => 'Note',
|
|
'created' => $now,
|
|
'lastUpdated' => $now,
|
|
'targetObject_id' => null,
|
|
),
|
|
array(
|
|
'id' => 9,
|
|
'object_id' => 4,
|
|
'name' => 'content',
|
|
'value' => 'This is another note',
|
|
'created' => $now,
|
|
'lastUpdated' => $now,
|
|
'targetObject_id' => null,
|
|
),
|
|
array(
|
|
'id' => 10,
|
|
'object_id' => 2,
|
|
'name' => '1',
|
|
'value' => null,
|
|
'created' => $now,
|
|
'lastUpdated' => $now,
|
|
'targetObject_id' => 4,
|
|
),
|
|
array(
|
|
'id' => 11,
|
|
'object_id' => 1,
|
|
'name' => 'items',
|
|
'value' => null,
|
|
'created' => $now,
|
|
'lastUpdated' => $now,
|
|
'targetObject_id' => 2,
|
|
),
|
|
),
|
|
) );
|
|
$expectedObjectsTable = $expected->getTable( 'objects' );
|
|
$expectedFieldsTable = $expected->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 );
|
|
}
|
|
|
|
public function testItSerializesNestedObjectsInArrays()
|
|
{
|
|
$fields = array(
|
|
'id' => 'https://example.com/collections/1',
|
|
'type' => 'Collection',
|
|
'items' => array(
|
|
array(
|
|
'id' => 'https://example.com/notes/1',
|
|
'type' => 'Note',
|
|
'content' => 'This is a note',
|
|
),
|
|
array(
|
|
'id' => 'https://example.com/notes/2',
|
|
'type' => 'Note',
|
|
'content' => 'This is another note',
|
|
),
|
|
),
|
|
);
|
|
$object = $this->objectsService->persist( $fields );
|
|
$arr = $object->asArray( 2 );
|
|
$this->assertEquals( $fields, $arr );
|
|
}
|
|
|
|
public function testItQueriesByFieldValue()
|
|
{
|
|
$fields = array(
|
|
'id' => 'https://example.com/notes/1',
|
|
'type' => 'Note',
|
|
'content' => 'This is a note',
|
|
);
|
|
$object = $this->objectsService->persist( $fields );
|
|
$query = array(
|
|
'type' => 'Note',
|
|
);
|
|
$results = $this->objectsService->query( $query );
|
|
$this->assertCount( 1, $results );
|
|
$this->assertContainsOnlyInstancesOf( ActivityPubObject::class, $results );
|
|
$this->assertEquals( $object, $results[0] );
|
|
}
|
|
|
|
public function testDeSerOneItemArrayQuery()
|
|
{
|
|
$fields = array(
|
|
'id' => 'https://example.com/collections/1',
|
|
'type' => 'Collection',
|
|
'items' => array( "https://example.com/items/1" ),
|
|
);
|
|
$this->objectsService->persist( $fields );
|
|
$query = array(
|
|
'id' => 'https://example.com/collections/1'
|
|
);
|
|
$results = $this->objectsService->query( $query );
|
|
$this->assertEquals( $fields, $results[0]->asArray() );
|
|
}
|
|
|
|
public function testItFindsMultipleQueryResults()
|
|
{
|
|
$fieldsOne = array(
|
|
'id' => 'https://example.com/notes/1',
|
|
'type' => 'Note',
|
|
'content' => 'This is a note',
|
|
);
|
|
$objectOne = $this->objectsService->persist( $fieldsOne );
|
|
$fieldsTwo = array(
|
|
'id' => 'https://example.com/notes/2',
|
|
'type' => 'Note',
|
|
'content' => 'This is another note',
|
|
);
|
|
$objectTwo = $this->objectsService->persist( $fieldsTwo );
|
|
$query = array(
|
|
'type' => 'Note',
|
|
);
|
|
$results = $this->objectsService->query( $query );
|
|
$this->assertCount( 2, $results );
|
|
$this->assertContainsOnlyInstancesOf( ActivityPubObject::class, $results );
|
|
$this->assertEquals( $objectOne, $results[0] );
|
|
$this->assertEquals( $objectTwo, $results[1] );
|
|
}
|
|
|
|
public function testItFindsObjectByMultipleFields()
|
|
{
|
|
$fieldsOne = array(
|
|
'id' => 'https://example.com/notes/1',
|
|
'type' => 'Note',
|
|
'content' => 'This is a note',
|
|
);
|
|
$objectOne = $this->objectsService->persist( $fieldsOne );
|
|
$fieldsTwo = array(
|
|
'id' => 'https://example.com/notes/2',
|
|
'type' => 'Note',
|
|
'content' => 'This is another note',
|
|
);
|
|
$objectTwo = $this->objectsService->persist( $fieldsTwo );
|
|
$query = array(
|
|
'type' => 'Note',
|
|
'content' => 'This is a note',
|
|
);
|
|
$results = $this->objectsService->query( $query );
|
|
$this->assertCount( 1, $results );
|
|
$this->assertContainsOnlyInstancesOf( ActivityPubObject::class, $results );
|
|
$this->assertEquals( $objectOne, $results[0] );
|
|
$this->assertNotContains( $objectTwo, $results );
|
|
}
|
|
|
|
public function testItFindsNestedObjectQueryResults()
|
|
{
|
|
$fields = array(
|
|
'id' => 'https://example.com/notes/1',
|
|
'type' => 'Note',
|
|
'content' => 'This is a note',
|
|
'attributedTo' => array(
|
|
'id' => 'https://example.com/actors/1',
|
|
'type' => 'Person',
|
|
),
|
|
);
|
|
$object = $this->objectsService->persist( $fields );
|
|
$query = array(
|
|
'attributedTo' => array(
|
|
'id' => 'https://example.com/actors/1',
|
|
),
|
|
);
|
|
$results = $this->objectsService->query( $query );
|
|
$this->assertCount( 1, $results );
|
|
$this->assertContainsOnlyInstancesOf( ActivityPubObject::class, $results );
|
|
$this->assertEquals( $object, $results[0] );
|
|
}
|
|
|
|
public function testNestedSequentialArrayQueryResults()
|
|
{
|
|
$fieldsOne = array(
|
|
'id' => 'https://example.com/collections/1',
|
|
'type' => 'Collection',
|
|
'items' => array(
|
|
'https://example.com/objects/1',
|
|
array( 'id' => 'example.com/objects/2' ),
|
|
'https://example.com/objects/3'
|
|
),
|
|
);
|
|
$fieldsTwo = array(
|
|
'id' => 'https://example.com/collections/2',
|
|
'type' => 'Collection',
|
|
'items' => array(
|
|
'https://example.com/objects/1',
|
|
array( 'id' => 'example.com/objects/2' ),
|
|
),
|
|
);
|
|
$objectOne = $this->objectsService->persist( $fieldsOne );
|
|
$objectTwo = $this->objectsService->persist( $fieldsTwo );
|
|
$query = array(
|
|
'items' => array(
|
|
'https://example.com/objects/1',
|
|
array( 'id' => 'example.com/objects/2' ),
|
|
'https://example.com/objects/3'
|
|
),
|
|
);
|
|
$results = $this->objectsService->query( $query );
|
|
$this->assertCount( 1, $results );
|
|
$this->assertContainsOnlyInstancesOf( ActivityPubObject::class, $results );
|
|
$this->assertEquals( $objectOne, $results[0] );
|
|
$this->assertEquals( $fieldsOne, $results[0]->asArray( 2 ) );
|
|
$this->assertNotContains( $objectTwo, $results );
|
|
}
|
|
|
|
public function testMultiNestedSequentialObjectQueryResults()
|
|
{
|
|
$fields = array(
|
|
'id' => 'https://example.com/notes/1',
|
|
'type' => 'Note',
|
|
'content' => 'This is a note',
|
|
'attributedTo' => array(
|
|
'id' => 'https://example.com/actors/2',
|
|
'type' => 'Person',
|
|
'following' => array(
|
|
'id' => 'https://example.com/collections/1',
|
|
'type' => 'Collection',
|
|
'items' => array(
|
|
array( 'id' => 'https://example.com/actors/1' ),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
$object = $this->objectsService->persist( $fields );
|
|
$query = array(
|
|
'attributedTo' => array(
|
|
'following' => array(
|
|
'items' => array(
|
|
array( 'id' => 'https://example.com/actors/1' )
|
|
),
|
|
),
|
|
),
|
|
);
|
|
$results = $this->objectsService->query( $query );
|
|
$this->assertCount( 1, $results );
|
|
$this->assertContainsOnlyInstancesOf( ActivityPubObject::class, $results );
|
|
$this->assertEquals( $object, $results[0] );
|
|
$this->assertEquals( $fields, $results[0]->asArray( 4 ) );
|
|
}
|
|
|
|
public function testItReturnsEmptyArrayForNoMatches()
|
|
{
|
|
$fields = array(
|
|
'id' => 'https://example.com/note/1',
|
|
'type' => 'Note',
|
|
'content' => 'This is a note'
|
|
);
|
|
$object = $this->objectsService->persist( $fields );
|
|
$query = array( 'type' => 'Article' );
|
|
$result = $this->objectsService->query( $query );
|
|
$this->assertEmpty( $result );
|
|
$this->assertNotContains( $object, $result );
|
|
}
|
|
|
|
public function testItDoesNotStoreObjectsWithTheSameId()
|
|
{
|
|
$fieldsOne = array(
|
|
'id' => 'https://example.com/notes/1',
|
|
'type' => 'Note',
|
|
'content' => 'This is a note',
|
|
);
|
|
$fieldsTwo = array(
|
|
'id' => 'https://example.com/notes/1',
|
|
'type' => 'Note',
|
|
'content' => 'This is another note',
|
|
);
|
|
$now = $this->getTime( 'objects-service.create' );
|
|
$objectOne = $this->objectsService->persist( $fieldsOne );
|
|
$objectTwo = $this->objectsService->persist( $fieldsTwo );
|
|
$this->assertEquals( $objectOne, $objectTwo );
|
|
$expected = new ArrayDataSet( array(
|
|
'objects' => array(
|
|
array( 'id' => 1, 'created' => $now, 'lastUpdated' => $now )
|
|
),
|
|
'fields' => array(
|
|
array(
|
|
'id' => 1,
|
|
'object_id' => 1,
|
|
'name' => 'id',
|
|
'value' => 'https://example.com/notes/1',
|
|
'created' => $now,
|
|
'lastUpdated' => $now,
|
|
'targetObject_id' => null,
|
|
),
|
|
array(
|
|
'id' => 2,
|
|
'object_id' => 1,
|
|
'name' => 'type',
|
|
'value' => 'Note',
|
|
'created' => $now,
|
|
'lastUpdated' => $now,
|
|
'targetObject_id' => null,
|
|
),
|
|
array(
|
|
'id' => 3,
|
|
'object_id' => 1,
|
|
'name' => 'content',
|
|
'value' => 'This is a note',
|
|
'created' => $now,
|
|
'lastUpdated' => $now,
|
|
'targetObject_id' => null,
|
|
),
|
|
),
|
|
) );
|
|
$expectedObjectsTable = $expected->getTable( 'objects' );
|
|
$expectedFieldsTable = $expected->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 );
|
|
}
|
|
|
|
public function testItGetsById()
|
|
{
|
|
$fields = array(
|
|
'id' => 'https://example.com/note/1',
|
|
'type' => 'Note',
|
|
'content' => 'This is a note'
|
|
);
|
|
$object = $this->objectsService->persist( $fields );
|
|
$found = $this->objectsService->dereference( 'https://example.com/note/1' );
|
|
$this->assertNotNull( $found );
|
|
$this->assertEquals( $object, $found );
|
|
}
|
|
|
|
public function testItReturnsNullIfIdNotFound()
|
|
{
|
|
$fields = array(
|
|
'id' => 'https://example.com/note/1',
|
|
'type' => 'Note',
|
|
'content' => 'This is a note'
|
|
);
|
|
$this->objectsService->persist( $fields );
|
|
$found = $this->objectsService->dereference( 'https://example.com/note/2' );
|
|
$this->assertNull( $found );
|
|
}
|
|
|
|
public function testItUpdatesObject()
|
|
{
|
|
$fields = array(
|
|
'id' => 'https://example.com/notes/1',
|
|
'type' => 'Note',
|
|
'content' => 'This is a note'
|
|
);
|
|
$createTime = $this->getTime( 'objects-service.create' );
|
|
$this->objectsService->persist( $fields );
|
|
$update = array( 'content' => 'This note has been updated' );
|
|
$updateTime = $this->getTime( 'objects-service.update' );
|
|
$this->objectsService->update( 'https://example.com/notes/1', $update );
|
|
$expected = new ArrayDataSet( array(
|
|
'objects' => array(
|
|
array(
|
|
'id' => 1,
|
|
'created' => $createTime,
|
|
'lastUpdated' => $updateTime
|
|
),
|
|
),
|
|
'fields' => array(
|
|
array(
|
|
'id' => 1,
|
|
'object_id' => 1,
|
|
'name' => 'id',
|
|
'value' => 'https://example.com/notes/1',
|
|
'created' => $createTime,
|
|
'lastUpdated' => $createTime,
|
|
'targetObject_id' => null,
|
|
),
|
|
array(
|
|
'id' => 2,
|
|
'object_id' => 1,
|
|
'name' => 'type',
|
|
'value' => 'Note',
|
|
'created' => $createTime,
|
|
'lastUpdated' => $createTime,
|
|
'targetObject_id' => null,
|
|
),
|
|
array(
|
|
'id' => 3,
|
|
'object_id' => 1,
|
|
'name' => 'content',
|
|
'value' => 'This note has been updated',
|
|
'created' => $createTime,
|
|
'lastUpdated' => $updateTime,
|
|
'targetObject_id' => null,
|
|
),
|
|
),
|
|
) );
|
|
$expectedObjectsTable = $expected->getTable( 'objects' );
|
|
$expectedFieldsTable = $expected->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 );
|
|
}
|
|
|
|
public function testItUpdatesObjectFieldToNewObject()
|
|
{
|
|
$fields = array(
|
|
'id' => 'https://example.com/notes/1',
|
|
'type' => 'Note',
|
|
'content' => 'This is a note',
|
|
'attributedTo' => array(
|
|
'id' => 'https://example.com/actors/1',
|
|
),
|
|
);
|
|
$createTime = $this->getTime( 'objects-service.create' );
|
|
$this->objectsService->persist( $fields );
|
|
$update = array( 'attributedTo' => array(
|
|
'id' => 'https://example.com/actors/2',
|
|
) );
|
|
$updateTime = $this->getTime( 'objects-service.update' );
|
|
$this->objectsService->update( 'https://example.com/notes/1', $update );
|
|
$expected = new ArrayDataSet( array(
|
|
'objects' => array(
|
|
array(
|
|
'id' => 1,
|
|
'created' => $createTime,
|
|
'lastUpdated' => $updateTime
|
|
),
|
|
array(
|
|
'id' => 2,
|
|
'created' => $createTime,
|
|
'lastUpdated' => $createTime,
|
|
),
|
|
array(
|
|
'id' => 3,
|
|
'created' => $updateTime,
|
|
'lastUpdated' => $updateTime,
|
|
),
|
|
),
|
|
'fields' => array(
|
|
array(
|
|
'id' => 1,
|
|
'object_id' => 1,
|
|
'name' => 'id',
|
|
'value' => 'https://example.com/notes/1',
|
|
'created' => $createTime,
|
|
'lastUpdated' => $createTime,
|
|
'targetObject_id' => null,
|
|
),
|
|
array(
|
|
'id' => 2,
|
|
'object_id' => 1,
|
|
'name' => 'type',
|
|
'value' => 'Note',
|
|
'created' => $createTime,
|
|
'lastUpdated' => $createTime,
|
|
'targetObject_id' => null,
|
|
),
|
|
array(
|
|
'id' => 3,
|
|
'object_id' => 1,
|
|
'name' => 'content',
|
|
'value' => 'This is a note',
|
|
'created' => $createTime,
|
|
'lastUpdated' => $createTime,
|
|
'targetObject_id' => null,
|
|
),
|
|
array(
|
|
'id' => 4,
|
|
'object_id' => 2,
|
|
'name' => 'id',
|
|
'value' => 'https://example.com/actors/1',
|
|
'created' => $createTime,
|
|
'lastUpdated' => $createTime,
|
|
'targetObject_id' => null,
|
|
),
|
|
array(
|
|
'id' => 5,
|
|
'object_id' => 1,
|
|
'name' => 'attributedTo',
|
|
'value' => null,
|
|
'created' => $createTime,
|
|
'lastUpdated' => $updateTime,
|
|
'targetObject_id' => 3,
|
|
),
|
|
array(
|
|
'id' => 6,
|
|
'object_id' => 3,
|
|
'name' => 'id',
|
|
'value' => 'https://example.com/actors/2',
|
|
'created' => $updateTime,
|
|
'lastUpdated' => $updateTime,
|
|
'targetObject_id' => null,
|
|
),
|
|
),
|
|
) );
|
|
$expectedObjectsTable = $expected->getTable( 'objects' );
|
|
$expectedFieldsTable = $expected->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 );
|
|
}
|
|
|
|
public function testItUpdatesObjectFieldArray()
|
|
{
|
|
$fields = array(
|
|
'id' => 'https://example.com/notes/1',
|
|
'type' => 'Note',
|
|
'content' => 'This is a note',
|
|
'likes' => array(
|
|
'https://example.com/likes/1',
|
|
'https://example.com/likes/2',
|
|
),
|
|
);
|
|
$createTime = $this->getTime( 'objects-service.create' );
|
|
$this->objectsService->persist( $fields );
|
|
$update = array( 'likes' => array(
|
|
'https://example.com/likes/3',
|
|
'https://example.com/likes/4',
|
|
) );
|
|
$updateTime = $this->getTime( 'objects-service.update' );
|
|
$this->objectsService->update( 'https://example.com/notes/1', $update );
|
|
$expected = new ArrayDataSet( array(
|
|
'objects' => array(
|
|
array(
|
|
'id' => 1,
|
|
'created' => $createTime,
|
|
'lastUpdated' => $updateTime
|
|
),
|
|
array(
|
|
'id' => 3,
|
|
'created' => $updateTime,
|
|
'lastUpdated' => $updateTime,
|
|
),
|
|
),
|
|
'fields' => array(
|
|
array(
|
|
'id' => 1,
|
|
'object_id' => 1,
|
|
'name' => 'id',
|
|
'value' => 'https://example.com/notes/1',
|
|
'created' => $createTime,
|
|
'lastUpdated' => $createTime,
|
|
'targetObject_id' => null,
|
|
),
|
|
array(
|
|
'id' => 2,
|
|
'object_id' => 1,
|
|
'name' => 'type',
|
|
'value' => 'Note',
|
|
'created' => $createTime,
|
|
'lastUpdated' => $createTime,
|
|
'targetObject_id' => null,
|
|
),
|
|
array(
|
|
'id' => 3,
|
|
'object_id' => 1,
|
|
'name' => 'content',
|
|
'value' => 'This is a note',
|
|
'created' => $createTime,
|
|
'lastUpdated' => $createTime,
|
|
'targetObject_id' => null,
|
|
),
|
|
array(
|
|
'id' => 6,
|
|
'object_id' => 1,
|
|
'name' => 'likes',
|
|
'value' => null,
|
|
'created' => $createTime,
|
|
'lastUpdated' => $updateTime,
|
|
'targetObject_id' => 3,
|
|
),
|
|
array(
|
|
'id' => 7,
|
|
'object_id' => 3,
|
|
'name' => '0',
|
|
'value' => 'https://example.com/likes/3',
|
|
'created' => $updateTime,
|
|
'lastUpdated' => $updateTime,
|
|
'targetObject_id' => null,
|
|
),
|
|
array(
|
|
'id' => 8,
|
|
'object_id' => 3,
|
|
'name' => '1',
|
|
'value' => 'https://example.com/likes/4',
|
|
'created' => $updateTime,
|
|
'lastUpdated' => $updateTime,
|
|
'targetObject_id' => null,
|
|
),
|
|
),
|
|
) );
|
|
$expectedObjectsTable = $expected->getTable( 'objects' );
|
|
$expectedFieldsTable = $expected->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 );
|
|
}
|
|
|
|
public function testItDeletesObjectField()
|
|
{
|
|
$fields = array(
|
|
'id' => 'https://example.com/notes/1',
|
|
'type' => 'Note',
|
|
'content' => 'This is a note'
|
|
);
|
|
$createTime = $this->getTime( 'objects-service.create' );
|
|
$this->objectsService->persist( $fields );
|
|
$update = array( 'content' => null );
|
|
$updateTime = $this->getTime( 'objects-service.update' );
|
|
$this->objectsService->update( 'https://example.com/notes/1', $update );
|
|
$expected = new ArrayDataSet( array(
|
|
'objects' => array(
|
|
array(
|
|
'id' => 1,
|
|
'created' => $createTime,
|
|
'lastUpdated' => $updateTime
|
|
),
|
|
),
|
|
'fields' => array(
|
|
array(
|
|
'id' => 1,
|
|
'object_id' => 1,
|
|
'name' => 'id',
|
|
'value' => 'https://example.com/notes/1',
|
|
'created' => $createTime,
|
|
'lastUpdated' => $createTime,
|
|
'targetObject_id' => null,
|
|
),
|
|
array(
|
|
'id' => 2,
|
|
'object_id' => 1,
|
|
'name' => 'type',
|
|
'value' => 'Note',
|
|
'created' => $createTime,
|
|
'lastUpdated' => $createTime,
|
|
'targetObject_id' => null,
|
|
),
|
|
),
|
|
) );
|
|
$expectedObjectsTable = $expected->getTable( 'objects' );
|
|
$expectedFieldsTable = $expected->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 );
|
|
}
|
|
|
|
public function testObjectArrayAccess()
|
|
{
|
|
$fields = array(
|
|
'id' => 'https://example.com/notes/1',
|
|
'type' => 'Note',
|
|
'content' => 'This is a note',
|
|
);
|
|
$object = $this->objectsService->persist( $fields );
|
|
$this->assertEquals( $object['content'], 'This is a note' );
|
|
$this->assertNull( $object['attributedTo'] );
|
|
}
|
|
|
|
public function testItThrowsTryingToSetObjectFieldLikeArray()
|
|
{
|
|
$fields = array(
|
|
'id' => 'https://example.com/notes/1',
|
|
'type' => 'Note',
|
|
'content' => 'This is a note',
|
|
);
|
|
$object = $this->objectsService->persist( $fields );
|
|
$this->setExpectedException( BadMethodCallException::class );
|
|
$object['content'] = 'This should break';
|
|
}
|
|
|
|
public function testItThrowsTryingToUnsetObjectFieldLikeArray()
|
|
{
|
|
$fields = array(
|
|
'id' => 'https://example.com/notes/1',
|
|
'type' => 'Note',
|
|
'content' => 'This is a note',
|
|
);
|
|
$object = $this->objectsService->persist( $fields );
|
|
$this->setExpectedException( BadMethodCallException::class );
|
|
unset( $object['content'] );
|
|
}
|
|
|
|
public function testNestedObjectArrayAccess()
|
|
{
|
|
$fields = array(
|
|
'id' => 'https://example.com/notes/1',
|
|
'type' => 'Note',
|
|
'content' => 'This is a note',
|
|
'attributedTo' => array(
|
|
'id' => 'https://example.com/actor/1'
|
|
),
|
|
);
|
|
$object = $this->objectsService->persist( $fields );
|
|
$this->assertEquals( $object['content'], 'This is a note' );
|
|
$this->assertInstanceOf( ActivityPubObject::class, $object['attributedTo'] );
|
|
$this->assertEquals(
|
|
$object['attributedTo']['id'], 'https://example.com/actor/1'
|
|
);
|
|
}
|
|
|
|
public function testItHandlesPersistingCircularReferences()
|
|
{
|
|
$fields = array(
|
|
'id' => 'https://example.com/actors/1',
|
|
'type' => 'Person',
|
|
'publicKey' => array(
|
|
'id' => 'https://example.com/actors/1/key',
|
|
'owner' => 'https://example.com/actors/1',
|
|
'publicKeyPem' => 'thePublicKey',
|
|
),
|
|
);
|
|
$object = $this->objectsService->persist( $fields );
|
|
$expected = array(
|
|
'id' => 'https://example.com/actors/1',
|
|
'type' => 'Person',
|
|
'publicKey' => array(
|
|
'id' => 'https://example.com/actors/1/key',
|
|
'owner' => array(
|
|
'id' => 'https://example.com/actors/1',
|
|
'type' => 'Person',
|
|
'publicKey' => array(
|
|
'id' => 'https://example.com/actors/1/key',
|
|
'owner' => 'https://example.com/actors/1',
|
|
'publicKeyPem' => 'thePublicKey',
|
|
),
|
|
),
|
|
'publicKeyPem' => 'thePublicKey',
|
|
),
|
|
);
|
|
$this->assertEquals( $expected, $object->asArray( 3 ) );
|
|
}
|
|
|
|
public function provideTestReplace()
|
|
{
|
|
return array(
|
|
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( array(
|
|
'id' => 'itDeletesOrphanedNodes',
|
|
'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',
|
|
),
|
|
'expectedQueryResults' => array(
|
|
array(
|
|
'query' => array( 'id' => 'https://example.com/actors/1' ),
|
|
'expectedResult' => array(
|
|
array( 'id' => 'https://example.com/actors/1' )
|
|
),
|
|
),
|
|
array(
|
|
'query' => array( 'bar' => 'baz' ),
|
|
'expectedResult' => array(),
|
|
),
|
|
),
|
|
) ),
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @dataProvider provideTestReplace
|
|
*/
|
|
public function testReplace( $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( 'expectedQueryResults', $testCase ) ) {
|
|
foreach ( $testCase['expectedQueryResults'] as $expectedQueryResult ) {
|
|
$result = array_map(
|
|
function ( ActivityPubObject $obj ) {
|
|
return $obj->asArray();
|
|
},
|
|
$this->objectsService->query( $expectedQueryResult['query'] )
|
|
);
|
|
$this->assertEquals( $expectedQueryResult['expectedResult'], $result );
|
|
}
|
|
}
|
|
}
|
|
|
|
protected function setUp()
|
|
{
|
|
parent::setUp();
|
|
$dbConfig = Setup::createAnnotationMetadataConfiguration(
|
|
array( __DIR__ . '/../../src/Entities' ), true
|
|
);
|
|
$namingStrategy = new PrefixNamingStrategy( '' );
|
|
$dbConfig->setNamingStrategy( $namingStrategy );
|
|
$dbParams = array(
|
|
'driver' => 'pdo_sqlite',
|
|
'path' => $this->getDbPath(),
|
|
);
|
|
$this->entityManager = EntityManager::create( $dbParams, $dbConfig );
|
|
$this->dateTimeProvider = new TestDateTimeProvider( array(
|
|
'objects-service.create' => new DateTime( "12:00" ),
|
|
'objects-service.update' => new DateTime( "12:01" ),
|
|
) );
|
|
$this->httpClient = $this->getMock( Client::class );
|
|
$this->httpClient->method( 'send' )
|
|
->willReturn( new Response( 404 ) );
|
|
$this->objectsService = new ObjectsService(
|
|
$this->entityManager, $this->dateTimeProvider, $this->httpClient
|
|
);
|
|
}
|
|
|
|
protected function getDataSet()
|
|
{
|
|
return new ArrayDataSet( array( 'objects' => array(), 'fields' => array() ) );
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|