Actualización

This commit is contained in:
Xes
2025-04-10 12:24:57 +02:00
parent 8969cc929d
commit 45420b6f0d
39760 changed files with 4303286 additions and 0 deletions

View File

@@ -0,0 +1,128 @@
<?php
/*
* This file is part of the xAPI package.
*
* (c) Christian Flothmann <christian.flothmann@xabbuh.de>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Xabbuh\XApi\Client\Tests\Api;
use Xabbuh\XApi\Client\Api\ActivityProfileApiClient;
use Xabbuh\XApi\DataFixtures\DocumentFixtures;
use Xabbuh\XApi\Model\Activity;
use Xabbuh\XApi\Model\ActivityProfile;
use Xabbuh\XApi\Model\ActivityProfileDocument;
use Xabbuh\XApi\Model\IRI;
use Xabbuh\XApi\Serializer\Symfony\DocumentDataSerializer;
/**
* @author Christian Flothmann <christian.flothmann@xabbuh.de>
*/
class ActivityProfileApiClientTest extends ApiClientTest
{
/**
* @var ActivityProfileApiClient
*/
private $client;
protected function setUp(): void
{
parent::setUp();
$this->client = new ActivityProfileApiClient(
$this->requestHandler,
'1.0.1',
new DocumentDataSerializer($this->serializer)
);
}
public function testCreateOrUpdateDocument()
{
$document = DocumentFixtures::getActivityProfileDocument();
$this->validateStoreApiCall(
'post',
'activities/profile',
array(
'activityId' => 'activity-id',
'profileId' => 'profile-id',
),
204,
'',
$document->getData()
);
$this->client->createOrUpdateDocument($document);
}
public function testCreateOrReplaceDocument()
{
$document = DocumentFixtures::getActivityProfileDocument();
$this->validateStoreApiCall(
'put',
'activities/profile',
array(
'activityId' => 'activity-id',
'profileId' => 'profile-id',
),
204,
'',
$document->getData()
);
$this->client->createOrReplaceDocument($document);
}
public function testDeleteDocument()
{
$activityProfile = $this->createActivityProfile();
$this->validateRequest(
'delete',
'activities/profile',
array(
'activityId' => 'activity-id',
'profileId' => 'profile-id',
),
''
);
$this->validateSerializer(array());
$this->client->deleteDocument($activityProfile);
}
public function testGetDocument()
{
$document = DocumentFixtures::getActivityProfileDocument();
$activityProfile = $document->getActivityProfile();
$this->validateRetrieveApiCall(
'get',
'activities/profile',
array(
'activityId' => 'activity-id',
'profileId' => 'profile-id',
),
200,
'DocumentData',
$document->getData()
);
$document = $this->client->getDocument($activityProfile);
$this->assertInstanceOf(ActivityProfileDocument::class, $document);
$this->assertEquals($activityProfile, $document->getActivityProfile());
}
private function createActivityProfile()
{
$activity = new Activity(IRI::fromString('activity-id'));
$activityProfile = new ActivityProfile('profile-id', $activity);
return $activityProfile;
}
}

View File

@@ -0,0 +1,138 @@
<?php
/*
* This file is part of the xAPI package.
*
* (c) Christian Flothmann <christian.flothmann@xabbuh.de>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Xabbuh\XApi\Client\Tests\Api;
use Xabbuh\XApi\Client\Api\AgentProfileApiClient;
use Xabbuh\XApi\DataFixtures\DocumentFixtures;
use Xabbuh\XApi\Model\Agent;
use Xabbuh\XApi\Model\AgentProfile;
use Xabbuh\XApi\Model\AgentProfileDocument;
use Xabbuh\XApi\Model\InverseFunctionalIdentifier;
use Xabbuh\XApi\Model\IRI;
use Xabbuh\XApi\Serializer\Symfony\ActorSerializer;
use Xabbuh\XApi\Serializer\Symfony\DocumentDataSerializer;
/**
* @author Christian Flothmann <christian.flothmann@xabbuh.de>
*/
class AgentProfileApiClientTest extends ApiClientTest
{
/**
* @var AgentProfileApiClient
*/
private $client;
protected function setUp(): void
{
parent::setUp();
$this->client = new AgentProfileApiClient(
$this->requestHandler,
'1.0.1',
new DocumentDataSerializer($this->serializer),
new ActorSerializer($this->serializer)
);
}
public function testCreateOrUpdateDocument()
{
$document = DocumentFixtures::getAgentProfileDocument();
$profile = $document->getAgentProfile();
$this->validateStoreApiCall(
'post',
'agents/profile',
array(
'agent' => 'agent-as-json',
'profileId' => 'profile-id',
),
204,
'',
$document->getData(),
array(array('data' => $profile->getAgent(), 'result' => 'agent-as-json'))
);
$this->client->createOrUpdateDocument($document);
}
public function testCreateOrReplaceDocument()
{
$document = DocumentFixtures::getAgentProfileDocument();
$profile = $document->getAgentProfile();
$this->validateStoreApiCall(
'put',
'agents/profile',
array(
'agent' => 'agent-as-json',
'profileId' => 'profile-id',
),
204,
'',
$document->getData(),
array(array('data' => $profile->getAgent(), 'result' => 'agent-as-json'))
);
$this->client->createOrReplaceDocument($document);
}
public function testDeleteDocument()
{
$profile = $this->createAgentProfile();
$this->validateRequest(
'delete',
'agents/profile',
array(
'agent' => 'agent-as-json',
'profileId' => 'profile-id',
),
''
);
$this->validateSerializer(array(array('data' => $profile->getAgent(), 'result' => 'agent-as-json')));
$this->client->deleteDocument(
$profile
);
}
public function testGetDocument()
{
$document = DocumentFixtures::getAgentProfileDocument();
$profile = $document->getAgentProfile();
$this->validateRetrieveApiCall(
'get',
'agents/profile',
array(
'agent' => 'agent-as-json',
'profileId' => 'profile-id',
),
200,
'DocumentData',
$document->getData(),
array(array('data' => $profile->getAgent(), 'result' => 'agent-as-json'))
);
$document = $this->client->getDocument($profile);
$this->assertInstanceOf(AgentProfileDocument::class, $document);
$this->assertEquals($profile, $document->getAgentProfile());
}
private function createAgentProfile()
{
$agent = new Agent(InverseFunctionalIdentifier::withMbox(IRI::fromString('mailto:christian@example.com')));
$profile = new AgentProfile('profile-id', $agent);
return $profile;
}
}

View File

@@ -0,0 +1,146 @@
<?php
/*
* This file is part of the xAPI package.
*
* (c) Christian Flothmann <christian.flothmann@xabbuh.de>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Xabbuh\XApi\Client\Tests\Api;
use PHPUnit\Framework\TestCase;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
use Symfony\Component\Serializer\SerializerInterface;
use Xabbuh\XApi\Client\Request\HandlerInterface;
use Xabbuh\XApi\Common\Exception\NotFoundException;
use Xabbuh\XApi\Serializer\SerializerRegistry;
use Xabbuh\XApi\Serializer\Symfony\ActorSerializer;
use Xabbuh\XApi\Serializer\Symfony\DocumentDataSerializer;
use Xabbuh\XApi\Serializer\Symfony\StatementResultSerializer;
use Xabbuh\XApi\Serializer\Symfony\StatementSerializer;
/**
* @author Christian Flothmann <christian.flothmann@xabbuh.de>
*/
abstract class ApiClientTest extends TestCase
{
/**
* @var HandlerInterface|\PHPUnit_Framework_MockObject_MockObject
*/
protected $requestHandler;
/**
* @var SerializerInterface|\PHPUnit_Framework_MockObject_MockObject
*/
protected $serializer;
/**
* @var SerializerRegistry
*/
protected $serializerRegistry;
protected function setUp(): void
{
$this->requestHandler = $this->getMockBuilder(HandlerInterface::class)->getMock();
$this->serializer = $this->getMockBuilder(SerializerInterface::class)->getMock();
$this->serializerRegistry = $this->createSerializerRegistry();
}
protected function createSerializerRegistry()
{
$registry = new SerializerRegistry();
$registry->setStatementSerializer(new StatementSerializer($this->serializer));
$registry->setStatementResultSerializer(new StatementResultSerializer($this->serializer));
$registry->setActorSerializer(new ActorSerializer($this->serializer));
$registry->setDocumentDataSerializer(new DocumentDataSerializer($this->serializer));
return $registry;
}
protected function validateSerializer(array $serializerMap)
{
$this
->serializer
->expects($this->any())
->method('serialize')
->willReturnCallback(function ($data) use ($serializerMap) {
foreach ($serializerMap as $entry) {
if ($data == $entry['data']) {
return $entry['result'];
}
}
return '';
});
}
protected function validateRequest($method, $uri, array $urlParameters, $body = null)
{
$request = $this->getMockBuilder(RequestInterface::class)->getMock();
$this
->requestHandler
->expects($this->once())
->method('createRequest')
->with($method, $uri, $urlParameters, $body)
->willReturn($request);
return $request;
}
protected function validateRetrieveApiCall($method, $uri, array $urlParameters, $statusCode, $type, $transformedResult, array $serializerMap = array())
{
$rawResponse = 'the-server-response';
$response = $this->getMockBuilder(ResponseInterface::class)->getMock();
$response->expects($this->any())->method('getStatusCode')->willReturn($statusCode);
$response->expects($this->any())->method('getHeader')->with('Content-Type')->willReturn(array('application/json'));
$response->expects($this->any())->method('getBody')->willReturn($rawResponse);
$request = $this->validateRequest($method, $uri, $urlParameters);
if (404 === $statusCode) {
$this
->requestHandler
->expects($this->once())
->method('executeRequest')
->with($request)
->willThrowException(new NotFoundException('Not found'));
} else {
$this
->requestHandler
->expects($this->once())
->method('executeRequest')
->with($request)
->willReturn($response);
}
$this->validateSerializer($serializerMap);
if ($statusCode < 400) {
$this->serializer
->expects($this->once())
->method('deserialize')
->with($rawResponse, 'Xabbuh\XApi\Model\\'.$type, 'json')
->willReturn($transformedResult);
}
}
protected function validateStoreApiCall($method, $uri, array $urlParameters, $statusCode, $rawResponse, $object, array $serializerMap = array())
{
$rawRequest = 'the-request-body';
$response = $this->getMockBuilder(ResponseInterface::class)->getMock();
$response->expects($this->any())->method('getStatusCode')->willReturn($statusCode);
$response->expects($this->any())->method('getBody')->willReturn($rawResponse);
$request = $this->validateRequest($method, $uri, $urlParameters, $rawRequest);
$this
->requestHandler
->expects($this->once())
->method('executeRequest')
->with($request, array($statusCode))
->willReturn($response);
$serializerMap[] = array('data' => $object, 'result' => $rawRequest);
$this->validateSerializer($serializerMap);
}
}

View File

@@ -0,0 +1,140 @@
<?php
/*
* This file is part of the xAPI package.
*
* (c) Christian Flothmann <christian.flothmann@xabbuh.de>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Xabbuh\XApi\Client\Tests\Api;
use Xabbuh\XApi\Client\Api\StateApiClient;
use Xabbuh\XApi\DataFixtures\DocumentFixtures;
use Xabbuh\XApi\Model\Activity;
use Xabbuh\XApi\Model\Agent;
use Xabbuh\XApi\Model\InverseFunctionalIdentifier;
use Xabbuh\XApi\Model\IRI;
use Xabbuh\XApi\Model\State;
use Xabbuh\XApi\Model\StateDocument;
use Xabbuh\XApi\Serializer\Symfony\ActorSerializer;
use Xabbuh\XApi\Serializer\Symfony\DocumentDataSerializer;
/**
* @author Christian Flothmann <christian.flothmann@xabbuh.de>
*/
class StateApiClientTest extends ApiClientTest
{
/**
* @var StateApiClient
*/
private $client;
protected function setUp(): void
{
parent::setUp();
$this->client = new StateApiClient(
$this->requestHandler,
'1.0.1',
new DocumentDataSerializer($this->serializer),
new ActorSerializer($this->serializer)
);
}
public function testCreateOrUpdateDocument()
{
$document = DocumentFixtures::getStateDocument();
$this->validateStoreApiCall(
'post',
'activities/state',
array(
'activityId' => 'activity-id',
'agent' => 'agent-as-json',
'stateId' => 'state-id',
),
204,
'',
$document->getData(),
array(array('data' => $document->getState()->getActor(), 'result' => 'agent-as-json'))
);
$this->client->createOrUpdateDocument($document);
}
public function testCreateOrReplaceDocument()
{
$document = DocumentFixtures::getStateDocument();
$this->validateStoreApiCall(
'put',
'activities/state',
array(
'activityId' => 'activity-id',
'agent' => 'agent-as-json',
'stateId' => 'state-id',
),
204,
'',
$document->getData(),
array(array('data' => $document->getState()->getActor(), 'result' => 'agent-as-json'))
);
$this->client->createOrReplaceDocument($document);
}
public function testDeleteDocument()
{
$state = $this->createState();
$this->validateRequest(
'delete',
'activities/state',
array(
'activityId' => 'activity-id',
'agent' => 'agent-as-json',
'stateId' => 'state-id',
),
''
);
$this->validateSerializer(array(array('data' => $state->getActor(), 'result' => 'agent-as-json')));
$this->client->deleteDocument($state);
}
public function testGetDocument()
{
$document = DocumentFixtures::getStateDocument();
$state = $document->getState();
$this->validateRetrieveApiCall(
'get',
'activities/state',
array(
'activityId' => 'activity-id',
'agent' => 'agent-as-json',
'stateId' => 'state-id',
),
200,
'DocumentData',
$document->getData(),
array(array('data' => $state->getActor(), 'result' => 'agent-as-json'))
);
$document = $this->client->getDocument($state);
$this->assertInstanceOf(StateDocument::class, $document);
$this->assertEquals($state, $document->getState());
}
private function createState()
{
$agent = new Agent(InverseFunctionalIdentifier::withMbox(IRI::fromString('mailto:alice@example.com')));
$activity = new Activity(IRI::fromString('activity-id'));
$state = new State($activity, $agent, 'state-id');
return $state;
}
}

View File

@@ -0,0 +1,369 @@
<?php
/*
* This file is part of the xAPI package.
*
* (c) Christian Flothmann <christian.flothmann@xabbuh.de>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Xabbuh\XApi\Client\Tests\Api;
use Xabbuh\XApi\Client\Api\StatementsApiClient;
use Xabbuh\XApi\Common\Exception\NotFoundException;
use Xabbuh\XApi\DataFixtures\StatementFixtures;
use Xabbuh\XApi\Model\Agent;
use Xabbuh\XApi\Model\InverseFunctionalIdentifier;
use Xabbuh\XApi\Model\IRI;
use Xabbuh\XApi\Model\IRL;
use Xabbuh\XApi\Model\Statement;
use Xabbuh\XApi\Model\StatementId;
use Xabbuh\XApi\Model\StatementReference;
use Xabbuh\XApi\Model\StatementResult;
use Xabbuh\XApi\Model\StatementsFilter;
use Xabbuh\XApi\Model\Verb;
use Xabbuh\XApi\Serializer\Symfony\ActorSerializer;
use Xabbuh\XApi\Serializer\Symfony\StatementResultSerializer;
use Xabbuh\XApi\Serializer\Symfony\StatementSerializer;
/**
* @author Christian Flothmann <christian.flothmann@xabbuh.de>
*/
class StatementsApiClientTest extends ApiClientTest
{
/**
* @var StatementsApiClient
*/
private $client;
protected function setUp(): void
{
parent::setUp();
$this->client = new StatementsApiClient(
$this->requestHandler,
'1.0.1',
new StatementSerializer($this->serializer),
new StatementResultSerializer($this->serializer),
new ActorSerializer($this->serializer)
);
}
public function testStoreStatement()
{
$statementId = '12345678-1234-5678-1234-567812345678';
$statement = $this->createStatement();
$this->validateStoreApiCall(
'post',
'statements',
array(),
200,
'["'.$statementId.'"]',
$this->createStatement()
);
$returnedStatement = $this->client->storeStatement($statement);
$expectedStatement = $this->createStatement($statementId);
$this->assertEquals($expectedStatement, $returnedStatement);
}
public function testStoreStatementWithId()
{
$statementId = '12345678-1234-5678-1234-567812345678';
$statement = $this->createStatement($statementId);
$this->validateStoreApiCall(
'put',
'statements',
array('statementId' => $statementId),
204,
'["'.$statementId.'"]',
$statement
);
$this->assertEquals($statement, $this->client->storeStatement($statement));
}
public function testStoreStatementWithIdEnsureThatTheIdIsNotOverwritten()
{
$statementId = '12345678-1234-5678-1234-567812345678';
$statement = $this->createStatement($statementId);
$this->validateStoreApiCall(
'put',
'statements',
array('statementId' => $statementId),
204,
'',
$statement
);
$storedStatement = $this->client->storeStatement($statement);
$this->assertEquals($statementId, $storedStatement->getId()->getValue());
}
public function testStoreStatements()
{
$statementId1 = '12345678-1234-5678-1234-567812345678';
$statementId2 = '12345678-1234-5678-1234-567812345679';
$statement1 = $this->createStatement();
$statement2 = $this->createStatement();
$this->validateStoreApiCall(
'post',
'statements',
array(),
'200',
'["'.$statementId1.'","'.$statementId2.'"]',
array($this->createStatement(), $this->createStatement())
);
$statements = $this->client->storeStatements(array($statement1, $statement2));
$expectedStatement1 = $this->createStatement($statementId1);
$expectedStatement2 = $this->createStatement($statementId2);
$expectedStatements = array($expectedStatement1, $expectedStatement2);
$this->assertNotContains($statements[0], array($statement1, $statement2));
$this->assertNotContains($statements[1], array($statement1, $statement2));
$this->assertEquals($expectedStatements, $statements);
$this->assertEquals($statementId1, $statements[0]->getId()->getValue());
$this->assertEquals($statementId2, $statements[1]->getId()->getValue());
}
public function testStoreStatementsWithNonStatementObject()
{
$this->expectException(\InvalidArgumentException::class);
$statement1 = $this->createStatement();
$statement2 = $this->createStatement();
$this->client->storeStatements(array($statement1, new \stdClass(), $statement2));
}
public function testStoreStatementsWithNonObject()
{
$this->expectException(\InvalidArgumentException::class);
$statement1 = $this->createStatement();
$statement2 = $this->createStatement();
$this->client->storeStatements(array($statement1, 'foo', $statement2));
}
public function testStoreStatementsWithId()
{
$this->expectException(\InvalidArgumentException::class);
$statement1 = $this->createStatement();
$statement2 = $this->createStatement('12345678-1234-5678-1234-567812345679');
$this->client->storeStatements(array($statement1, $statement2));
}
public function testVoidStatement()
{
$voidedStatementId = '12345678-1234-5678-1234-567812345679';
$voidingStatementId = '12345678-1234-5678-1234-567812345678';
$agent = new Agent(InverseFunctionalIdentifier::withMbox(IRI::fromString('mailto:john.doe@example.com')));
$statementReference = new StatementReference(StatementId::fromString($voidedStatementId));
$voidingStatement = new Statement(null, $agent, Verb::createVoidVerb(), $statementReference);
$voidedStatement = $this->createStatement($voidedStatementId);
$this->validateStoreApiCall(
'post',
'statements',
array(),
200,
'["'.$voidingStatementId.'"]',
$voidingStatement
);
$returnedVoidingStatement = $this->client->voidStatement($voidedStatement, $agent);
$expectedVoidingStatement = new Statement(
StatementId::fromString($voidingStatementId),
$agent,
Verb::createVoidVerb(),
$statementReference
);
$this->assertEquals($expectedVoidingStatement, $returnedVoidingStatement);
}
public function testGetStatement()
{
$statementId = '12345678-1234-5678-1234-567812345678';
$statement = $this->createStatement();
$this->validateRetrieveApiCall(
'get',
'statements',
array('statementId' => $statementId, 'attachments' => 'true'),
200,
'Statement',
$statement
);
$this->client->getStatement(StatementId::fromString($statementId));
}
public function testGetStatementWithNotExistingStatement()
{
$this->expectException(NotFoundException::class);
$statementId = '12345678-1234-5678-1234-567812345678';
$this->validateRetrieveApiCall(
'get',
'statements',
array('statementId' => $statementId, 'attachments' => 'true'),
404,
'Statement',
'There is no statement associated with this id'
);
$this->client->getStatement(StatementId::fromString($statementId));
}
public function testGetVoidedStatement()
{
$statementId = '12345678-1234-5678-1234-567812345678';
$statement = $this->createStatement();
$this->validateRetrieveApiCall(
'get',
'statements',
array('voidedStatementId' => $statementId, 'attachments' => 'true'),
200,
'Statement',
$statement
);
$this->client->getVoidedStatement(StatementId::fromString($statementId));
}
public function testGetVoidedStatementWithNotExistingStatement()
{
$this->expectException(NotFoundException::class);
$statementId = '12345678-1234-5678-1234-567812345678';
$this->validateRetrieveApiCall(
'get',
'statements',
array('voidedStatementId' => $statementId, 'attachments' => 'true'),
404,
'Statement',
'There is no statement associated with this id'
);
$this->client->getVoidedStatement(StatementId::fromString($statementId));
}
public function testGetStatements()
{
$statementResult = $this->createStatementResult();
$this->validateRetrieveApiCall(
'get',
'statements',
array(),
200,
'StatementResult',
$statementResult
);
$this->assertEquals($statementResult, $this->client->getStatements());
}
public function testGetStatementsWithStatementsFilter()
{
$filter = new StatementsFilter();
$filter->limit(10)->ascending();
$statementResult = $this->createStatementResult();
$this->validateRetrieveApiCall(
'get',
'statements',
array('limit' => 10, 'ascending' => 'true'),
200,
'StatementResult',
$statementResult
);
$this->assertEquals($statementResult, $this->client->getStatements($filter));
}
public function testGetStatementsWithAgentInStatementsFilter()
{
// {"mbox":"mailto:alice@example.com","objectType":"Agent"}
$filter = new StatementsFilter();
$agent = new Agent(InverseFunctionalIdentifier::withMbox(IRI::fromString('mailto:alice@example.com')));
$filter->byActor($agent);
$statementResult = $this->createStatementResult();
$agentJson = '{"mbox":"mailto:alice@example.com","objectType":"Agent"}';
$this->serializer
->expects($this->once())
->method('serialize')
->with($agent, 'json')
->willReturn($agentJson);
$this->validateRetrieveApiCall(
'get',
'statements',
array('agent' => $agentJson),
200,
'StatementResult',
$statementResult
);
$this->assertEquals($statementResult, $this->client->getStatements($filter));
}
public function testGetStatementsWithVerbInStatementsFilter()
{
$filter = new StatementsFilter();
$verb = new Verb(IRI::fromString('http://adlnet.gov/expapi/verbs/attended'));
$filter->byVerb($verb);
$statementResult = $this->createStatementResult();
$this->validateRetrieveApiCall(
'get',
'statements',
array('verb' => 'http://adlnet.gov/expapi/verbs/attended'),
200,
'StatementResult',
$statementResult
);
$this->assertEquals($statementResult, $this->client->getStatements($filter));
}
public function testGetNextStatements()
{
$moreUrl = '/xapi/statements/more/b381d8eca64a61a42c7b9b4ecc2fabb6';
$previousStatementResult = new StatementResult(array(), IRL::fromString($moreUrl));
$this->validateRetrieveApiCall(
'get',
$moreUrl,
array(),
200,
'StatementResult',
$previousStatementResult
);
$statementResult = $this->client->getNextStatements($previousStatementResult);
$this->assertInstanceOf(StatementResult::class, $statementResult);
}
/**
* @param int $id
*
* @return Statement
*/
private function createStatement($id = null)
{
$statement = StatementFixtures::getMinimalStatement($id);
if (null === $id) {
$statement = $statement->withId(null);
}
return $statement;
}
/**
* @return StatementResult
*/
private function createStatementResult()
{
return new StatementResult(array());
}
}