This commit is contained in:
Xes
2025-08-14 22:41:49 +02:00
parent 2de81ccc46
commit 8ce45119b6
39774 changed files with 4309466 additions and 0 deletions

View File

@@ -0,0 +1,124 @@
<?php
namespace spec\Xabbuh\XApi\Client\Request;
use Http\Client\HttpClient;
use Http\Message\RequestFactory;
use PhpSpec\ObjectBehavior;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
use Xabbuh\XApi\Common\Exception\AccessDeniedException;
use Xabbuh\XApi\Common\Exception\ConflictException;
use Xabbuh\XApi\Common\Exception\NotFoundException;
use Xabbuh\XApi\Common\Exception\XApiException;
class HandlerSpec extends ObjectBehavior
{
function let(HttpClient $client, RequestFactory $requestFactory)
{
$this->beConstructedWith($client, $requestFactory, 'http://example.com/xapi/', '1.0.1');
}
function it_throws_an_exception_if_a_request_is_created_with_an_invalid_method()
{
$this->shouldThrow('\InvalidArgumentException')->during('createRequest', array('options', '/xapi/statements'));
}
function it_returns_get_request_created_by_the_http_client(RequestFactory $requestFactory, RequestInterface $request)
{
$requestFactory->createRequest('GET', 'http://example.com/xapi/statements', array(
'X-Experience-API-Version' => '1.0.1',
'Content-Type' => 'application/json',
), null)->willReturn($request);
$this->createRequest('get', '/statements')->shouldReturn($request);
$this->createRequest('GET', '/statements')->shouldReturn($request);
}
function it_returns_post_request_created_by_the_http_client(RequestFactory $requestFactory, RequestInterface $request)
{
$requestFactory->createRequest('POST', 'http://example.com/xapi/statements', array(
'X-Experience-API-Version' => '1.0.1',
'Content-Type' => 'application/json',
), 'body')->willReturn($request);
$this->createRequest('post', '/statements', array(), 'body')->shouldReturn($request);
$this->createRequest('POST', '/statements', array(), 'body')->shouldReturn($request);
}
function it_returns_put_request_created_by_the_http_client(RequestFactory $requestFactory, RequestInterface $request)
{
$requestFactory->createRequest('PUT', 'http://example.com/xapi/statements', array(
'X-Experience-API-Version' => '1.0.1',
'Content-Type' => 'application/json',
), 'body')->willReturn($request);
$this->createRequest('put', '/statements', array(), 'body')->shouldReturn($request);
$this->createRequest('PUT', '/statements', array(), 'body')->shouldReturn($request);
}
function it_returns_delete_request_created_by_the_http_client(RequestFactory $requestFactory, RequestInterface $request)
{
$requestFactory->createRequest('DELETE', 'http://example.com/xapi/statements', array(
'X-Experience-API-Version' => '1.0.1',
'Content-Type' => 'application/json',
), null)->willReturn($request);
$this->createRequest('delete', '/statements')->shouldReturn($request);
$this->createRequest('DELETE', '/statements')->shouldReturn($request);
}
function it_throws_an_access_denied_exception_when_a_401_status_code_is_returned(HttpClient $client, RequestInterface $request, ResponseInterface $response)
{
$client->sendRequest($request)->willReturn($response);
$response->getStatusCode()->willReturn(401);
$response->getBody()->willReturn('body');
$this->shouldThrow(AccessDeniedException::class)->during('executeRequest', array($request, array(200)));
}
function it_throws_an_access_denied_exception_when_a_403_status_code_is_returned(HttpClient $client, RequestInterface $request, ResponseInterface $response)
{
$client->sendRequest($request)->willReturn($response);
$response->getStatusCode()->willReturn(403);
$response->getBody()->willReturn('body');
$this->shouldThrow(AccessDeniedException::class)->during('executeRequest', array($request, array(200)));
}
function it_throws_a_not_found_exception_when_a_404_status_code_is_returned(HttpClient $client, RequestInterface $request, ResponseInterface $response)
{
$client->sendRequest($request)->willReturn($response);
$response->getStatusCode()->willReturn(404);
$response->getBody()->willReturn('body');
$this->shouldThrow(NotFoundException::class)->during('executeRequest', array($request, array(200)));
}
function it_throws_a_conflict_exception_when_a_409_status_code_is_returned(HttpClient $client, RequestInterface $request, ResponseInterface $response)
{
$client->sendRequest($request)->willReturn($response);
$response->getStatusCode()->willReturn(409);
$response->getBody()->willReturn('body');
$this->shouldThrow(ConflictException::class)->during('executeRequest', array($request, array(200)));
}
function it_throws_an_xapi_exception_when_an_unexpected_status_code_is_returned(HttpClient $client, RequestInterface $request, ResponseInterface $response)
{
$client->sendRequest($request)->willReturn($response);
$response->getStatusCode()->willReturn(204);
$response->getBody()->willReturn('body');
$this->shouldThrow(XApiException::class)->during('executeRequest', array($request, array(200)));
}
function it_returns_the_response_on_success(HttpClient $client, RequestInterface $request, ResponseInterface $response)
{
$client->sendRequest($request)->willReturn($response);
$response->getStatusCode()->willReturn(200);
$response->getBody()->willReturn('body');
$this->executeRequest($request, array(200))->shouldReturn($response);
}
}

View File

@@ -0,0 +1,139 @@
<?php
namespace spec\Xabbuh\XApi\Client;
use Http\Client\HttpClient;
use Http\Discovery\HttpClientDiscovery;
use Http\Discovery\MessageFactoryDiscovery;
use Http\Message\RequestFactory;
use PhpSpec\Exception\Example\SkippingException;
use PhpSpec\ObjectBehavior;
use Xabbuh\Http\Authentication\OAuth1;
use Xabbuh\XApi\Client\XApiClientBuilderInterface;
use Xabbuh\XApi\Client\XApiClientInterface;
class XApiClientBuilderSpec extends ObjectBehavior
{
function it_is_an_xapi_client_builder()
{
$this->shouldHaveType(XApiClientBuilderInterface::class);
}
function it_creates_an_xapi_client(HttpClient $httpClient, RequestFactory $requestFactory)
{
$this->setHttpClient($httpClient);
$this->setRequestFactory($requestFactory);
$this->setBaseUrl('http://example.com/xapi/');
$this->build()->shouldHaveType(XApiClientInterface::class);
}
function its_methods_can_be_chained(HttpClient $httpClient, RequestFactory $requestFactory)
{
$this->setHttpClient($httpClient)->shouldReturn($this);
$this->setRequestFactory($requestFactory)->shouldReturn($this);
$this->setBaseUrl('http://example.com/xapi/')->shouldReturn($this);
$this->setVersion('1.0.0')->shouldReturn($this);
$this->setAuth('foo', 'bar')->shouldReturn($this);
$this->setOAuthCredentials('consumer key', 'consumer secret', 'token', 'token secret')->shouldReturn($this);
}
function it_throws_an_exception_if_the_http_client_is_not_configured(RequestFactory $requestFactory)
{
if ($this->isAbleToDiscoverHttpClient()) {
throw new SkippingException('The builder does not throw an exception if it can automatically discover an HTTP client.');
}
$this->setRequestFactory($requestFactory);
$this->setBaseUrl('http://example.com/xapi/');
$this->shouldThrow('\LogicException')->during('build');
}
function it_throws_an_exception_if_the_request_factory_is_not_configured(HttpClient $httpClient)
{
if ($this->isAbleToDiscoverRequestFactory()) {
throw new SkippingException('The builder does not throw an exception if it can automatically discover a request factory.');
}
$this->setHttpClient($httpClient);
$this->setBaseUrl('http://example.com/xapi/');
$this->shouldThrow('\LogicException')->during('build');
}
function it_can_build_the_client_when_it_is_able_to_discover_the_http_client_and_the_request_factory_without_configuring_them_explicitly()
{
if (!class_exists(HttpClientDiscovery::class)) {
throw new SkippingException(sprintf('The "%s" class is required to let the builder auto discover the HTTP client and request factory.', HttpClientDiscovery::class));
}
if (!$this->isAbleToDiscoverHttpClient()) {
throw new SkippingException('Unable to discover an HTTP client.');
}
if (!$this->isAbleToDiscoverRequestFactory()) {
throw new SkippingException('Unable to discover a request factory.');
}
$this->setBaseUrl('http://example.com/xapi/');
$this->build()->shouldReturnAnInstanceOf(XApiClientInterface::class);
}
function it_throws_an_exception_if_the_base_uri_is_not_configured(HttpClient $httpClient, RequestFactory $requestFactory)
{
$this->setHttpClient($httpClient);
$this->setRequestFactory($requestFactory);
$this->shouldThrow('\LogicException')->during('build');
}
function it_throws_an_exception_when_oauth_credentials_are_configured_but_the_auth_package_is_missing(HttpClient $httpClient, RequestFactory $requestFactory)
{
if (class_exists(OAuth1::class)) {
throw new SkippingException('OAuth1 credentials can be used when the "xabbuh/oauth1-authentication" package is present.');
}
$this->setHttpClient($httpClient);
$this->setRequestFactory($requestFactory);
$this->setBaseUrl('http://example.com/xapi/');
$this->setOAuthCredentials('consumer_key', 'consumer_secret', 'access_token', 'token_secret');
$this->shouldThrow(new \LogicException('The "xabbuh/oauth1-authentication package is needed to use OAuth1 authorization.'))->during('build');
}
function it_accepts_oauth_credentials_when_the_auth_package_is_present(HttpClient $httpClient, RequestFactory $requestFactory)
{
if (!class_exists(OAuth1::class)) {
throw new SkippingException('OAuth1 credentials cannot be used when the "xabbuh/oauth1-authentication" package is missing.');
}
$this->setHttpClient($httpClient);
$this->setRequestFactory($requestFactory);
$this->setBaseUrl('http://example.com/xapi/');
$this->setOAuthCredentials('consumer_key', 'consumer_secret', 'access_token', 'token_secret');
$this->build();
}
private function isAbleToDiscoverHttpClient()
{
try {
HttpClientDiscovery::find();
return true;
} catch (\Exception $e) {
return false;
}
}
private function isAbleToDiscoverRequestFactory()
{
try {
MessageFactoryDiscovery::find();
return true;
} catch (\Exception $e) {
return false;
}
}
}

View File

@@ -0,0 +1,54 @@
<?php
namespace spec\Xabbuh\XApi\Client;
use PhpSpec\ObjectBehavior;
use Xabbuh\XApi\Client\Api\ActivityProfileApiClientInterface;
use Xabbuh\XApi\Client\Api\AgentProfileApiClientInterface;
use Xabbuh\XApi\Client\Api\StateApiClientInterface;
use Xabbuh\XApi\Client\Api\StatementsApiClientInterface;
use Xabbuh\XApi\Client\Request\HandlerInterface;
use Xabbuh\XApi\Serializer\ActorSerializerInterface;
use Xabbuh\XApi\Serializer\DocumentDataSerializerInterface;
use Xabbuh\XApi\Serializer\SerializerRegistryInterface;
use Xabbuh\XApi\Serializer\StatementResultSerializerInterface;
use Xabbuh\XApi\Serializer\StatementSerializerInterface;
class XApiClientSpec extends ObjectBehavior
{
function let(
HandlerInterface $requestHandler,
SerializerRegistryInterface $serializerRegistry,
ActorSerializerInterface $actorSerializer,
DocumentDataSerializerInterface $documentDataSerializer,
StatementSerializerInterface $statementSerializer,
StatementResultSerializerInterface $statementResultSerializer
) {
$serializerRegistry->getActorSerializer()->willReturn($actorSerializer);
$serializerRegistry->getDocumentDataSerializer()->willReturn($documentDataSerializer);
$serializerRegistry->getStatementSerializer()->willReturn($statementSerializer);
$serializerRegistry->getStatementResultSerializer()->willReturn($statementResultSerializer);
$this->beConstructedWith($requestHandler, $serializerRegistry, '1.0.1');
}
function it_returns_a_statements_api_client_instance()
{
$this->getStatementsApiClient()->shouldBeAnInstanceOf(StatementsApiClientInterface::class);
}
function it_returns_an_activity_profile_api_client_instance()
{
$this->getActivityProfileApiClient()->shouldBeAnInstanceOf(ActivityProfileApiClientInterface::class);
}
function it_returns_an_agent_profile_api_client_instance()
{
$this->getAgentProfileApiClient()->shouldBeAnInstanceOf(AgentProfileApiClientInterface::class);
}
function it_returns_a_state_api_client_instance()
{
$this->getStateApiClient()->shouldBeAnInstanceOf(StateApiClientInterface::class);
}
}