Skip to content

Commit

Permalink
EA-3353: Add multipart request ability (#7)
Browse files Browse the repository at this point in the history
  • Loading branch information
sleipi committed Jan 6, 2021
1 parent 6577035 commit 4ece3ea
Show file tree
Hide file tree
Showing 8 changed files with 165 additions and 46 deletions.
38 changes: 26 additions & 12 deletions src/Api/ApiClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
use JTL\SCX\Client\Exception\RequestFailedException;
use JTL\SCX\Client\Model\ErrorList;
use JTL\SCX\Client\ObjectSerializer;
use JTL\SCX\Client\Request\Multipart\MultipartFormDataRequest;
use JTL\SCX\Client\Request\RequestFactory;
use JTL\SCX\Client\Request\ScxApiRequest;
use JTL\SCX\Client\Request\UrlFactory;
Expand All @@ -28,13 +29,6 @@ class ApiClient
private RequestFactory $requestFactory;
private UrlFactory $urlFactory;

/**
* AbstractApi constructor.
* @param ClientInterface $client
* @param Configuration $configuration
* @param RequestFactory $requestFactory
* @param UrlFactory $urlFactory
*/
public function __construct(
Configuration $configuration,
ClientInterface $client = null,
Expand Down Expand Up @@ -63,14 +57,20 @@ public function request(ScxApiRequest $request): ResponseInterface
$request->getUrl(),
$request->getParams()
);
$request = $this->requestFactory->create(
$apiRequest = $this->requestFactory->create(
$request->getHttpMethod(),
$url,
$this->createHeaders($request),
$request->getBody()
);
return $this->client->send($request);
} catch (ClientException|ServerException $exception) {

$options = [];
if ($request instanceof MultipartFormDataRequest) {
$options['multipart'] = $this->buildMultipartBody($request);
}

return $this->client->send($apiRequest, $options);
} catch (ClientException | ServerException $exception) {
$response = $exception->getResponse();
$errorList = null;
$responseBody = null;
Expand All @@ -96,8 +96,22 @@ public function request(ScxApiRequest $request): ResponseInterface
protected function createHeaders(ScxApiRequest $request): array
{
$headers = $request->getAdditionalHeaders();
$headers['Content-Type'] = $request->getContentType();

if (!$request instanceof MultipartFormDataRequest) {
$headers['Content-Type'] = $request->getContentType();
}
return $headers;
}

/**
* @param MultipartFormDataRequest $request
* @return array
*/
private function buildMultipartBody(MultipartFormDataRequest $request): array
{
$parameters = [];
foreach ($request->buildMultipartBody() as $parameter) {
$parameters[] = ['name' => $parameter->getName(), 'contents' => $parameter->getContent()];
}
return $parameters;
}
}
17 changes: 17 additions & 0 deletions src/Request/Multipart/MultipartFormDataRequest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php declare(strict_types=1);
/**
* This File is part of JTL-Software
*
* User: rherrgesell
* Date: 1/6/21
*/

namespace JTL\SCX\Client\Request\Multipart;

interface MultipartFormDataRequest
{
/**
* @return array<MultipartParameter>
*/
public function buildMultipartBody(): array;
}
48 changes: 48 additions & 0 deletions src/Request/Multipart/MultipartParameter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?php declare(strict_types=1);
/**
* This File is part of JTL-Software
*
* User: rherrgesell
* Date: 1/6/21
*/

namespace JTL\SCX\Client\Request\Multipart;

use Psr\Http\Message\StreamInterface;

class MultipartParameter
{
private string $name;

/**
* @var string|StreamInterface|resource
*/
private $content;

/**
* Parameter constructor.
* @param string $name
* @param string|StreamInterface|resource $content
*/
public function __construct(string $name, $content)
{
$this->name = $name;
$this->content = $content;
}

/**
* @return string
*/
public function getName(): string
{
return $this->name;
}

/**
* @return string|StreamInterface|resource
*/
public function getContent()
{
return $this->content;
}
}
15 changes: 0 additions & 15 deletions tests/AbstractTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,21 +38,6 @@ protected function createConfigurationMock()
return $configuration;
}

/**
* @param ResponseInterface $response
* @return ClientInterface|Mockery\LegacyMockInterface|Mockery\MockInterface
*/
protected function createClientMock(ResponseInterface $response)
{
$client = Mockery::mock(ClientInterface::class);
$client->shouldReceive('send')
->once()
->with(Mockery::type(Request::class))
->andReturn($response);

return $client;
}

/**
* @param string $method
* @param string|null $body
Expand Down
13 changes: 10 additions & 3 deletions tests/Api/ApiTest.php → tests/Api/ApiClientTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,18 @@
/**
* @covers \JTL\SCX\Client\Api\ApiClient
*/
class ApiTest extends AbstractTestCase
class ApiClientTest extends AbstractTestCase
{
public function testCanCall(): void
{
$response = Mockery::mock(ResponseInterface::class);

$client = $this->createClientMock($response);
$client = $client = Mockery::mock(ClientInterface::class);
$client->shouldReceive('send')
->once()
->with(Mockery::type(Request::class), [])
->andReturn($response);

$configuration = $this->createConfigurationMock();
$requestFactory = $this->createRequestFactoryMock(ScxApiRequest::HTTP_METHOD_POST);
$urlFactory = $this->createUrlFactoryMock('/foo');
Expand All @@ -42,6 +47,7 @@ public function testCanCall(): void
$requestMock->shouldReceive('getAdditionalHeaders')->andReturn([]);
$requestMock->shouldReceive('getContentType')->andReturn('bier');
$requestMock->shouldReceive('getBody')->andReturnNull();
$requestMock->shouldReceive('getOptions')->andReturn([]);
$apiResponse = $api->request($requestMock);

$this->assertSame($response, $apiResponse);
Expand All @@ -65,7 +71,7 @@ public function testCanThrowException(): void
$client = Mockery::mock(ClientInterface::class);
$client->shouldReceive('send')
->once()
->with(Mockery::type(Request::class))
->with(Mockery::type(Request::class), [])
->andThrow(new ClientException('Error', $request, $response));

$configuration = $this->createConfigurationMock();
Expand All @@ -89,6 +95,7 @@ public function testCanThrowException(): void
$requestMock->shouldReceive('getAdditionalHeaders')->andReturn([]);
$requestMock->shouldReceive('getContentType')->andReturn('bier');
$requestMock->shouldReceive('getBody')->andReturnNull();
$requestMock->shouldReceive('getOptions')->andReturn([]);

$this->expectException(RequestFailedException::class);
$api->request($requestMock);
Expand Down
41 changes: 36 additions & 5 deletions tests/Api/Auth/Request/AuthRequestTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,52 @@

namespace JTL\SCX\Client\Api\Auth\Request;

use JTL\SCX\Client\AbstractTestCase;
use PHPUnit\Framework\TestCase;

/**
* Class AuthRequestTest
* @package JTL\SCX\Client\Api\Auth\Request
*
* @covers \JTL\SCX\Client\Api\Auth\Request\AuthRequest
*/
class AuthRequestTest extends AbstractTestCase
class AuthRequestTest extends TestCase
{
public function testCanReadRefreshToken(): void
/**
* @test
*/
public function it_has_correct_refresh_token(): void
{
$refreshToken = uniqid('refreshToken', true);

$request = new AuthRequest($refreshToken);
$this->assertSame($refreshToken, $request->getRefreshToken());
$this->assertEquals($refreshToken, $request->getRefreshToken());
}

/**
* @test
*/
public function it_has_correct_url()
{
$sut = new AuthRequest('foo');
$this->assertEquals('/auth{?refreshToken}', $sut->getUrl());
}

/**
* @test
*/
public function it_has_correct_http_method()
{
$sut = new AuthRequest('foo');
$this->assertEquals(AuthRequest::HTTP_METHOD_POST, $sut->getHttpMethod());
}

/**
* @test
*/
public function it_has_correct_http_parameters()
{
$sut = new AuthRequest('a_refresh_token');
$params = $sut->getParams();
$this->assertArrayHasKey('refreshToken', $params);
$this->assertEquals('a_refresh_token', $params['refreshToken']);
}
}
26 changes: 18 additions & 8 deletions tests/Api/Auth/Response/AuthResponseTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,33 @@
use JTL\SCX\Client\AbstractTestCase;
use JTL\SCX\Client\Model\AuthToken;
use Mockery;
use PHPUnit\Framework\TestCase;

/**
* Class AuthResponseTest
* @package JTL\SCX\Client\Api\Auth\Response
*
* @covers \JTL\SCX\Client\Api\Auth\Response\AuthResponse
*/
class AuthResponseTest extends AbstractTestCase
class AuthResponseTest extends TestCase
{
public function testCanBeCreated(): void
/**
* @test
*/
public function it_has_a_authToken(): void
{
$authToken = Mockery::mock(AuthToken::class);
$statusCode = random_int(1, 100);

$response = new AuthResponse($authToken, $statusCode);

$authToken = $this->createStub(AuthToken::class);
$response = new AuthResponse($authToken, 200);
$this->assertSame($authToken, $response->getAuthToken());
$this->assertSame($statusCode, $response->getStatusCode());
}

/**
* @test
*/
public function request_is_considered_successful_one_http_status_200(): void
{
$statusSuccessful = 200;
$response = new AuthResponse($this->createStub(AuthToken::class), $statusSuccessful);
$this->assertTrue($response->isSuccessful());
}
}
13 changes: 10 additions & 3 deletions tests/Api/AuthAwareApiTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,12 @@ public function testCanRequestWithoutSessionToken(): void
$storageKey = 'key';
$configuration->shouldReceive('hashConfiguration')->andReturn($storageKey);

$client = $this->createClientMock($this->response);
$client = $client = Mockery::mock(ClientInterface::class);
$client->shouldReceive('send')
->once()
->with(Mockery::type(Request::class), [])
->andReturn($this->response);

$requestFactory = $this->createRequestFactoryMock(ScxApiRequest::HTTP_METHOD_POST);
$urlFactory = $this->createUrlFactoryMock('/foo');

Expand Down Expand Up @@ -139,6 +144,7 @@ public function testCanRequestWithoutSessionToken(): void
$requestMock->shouldReceive('getAdditionalHeaders')->andReturn([]);
$requestMock->shouldReceive('getContentType')->andReturn('bier');
$requestMock->shouldReceive('getBody')->andReturnNull();
$requestMock->shouldReceive('getOptions')->andReturn([]);
$response = $testAuthApi->request($requestMock);

$this->assertSame($this->response, $response);
Expand All @@ -150,12 +156,12 @@ public function testCanRequestIfRequestFails(): void

$client->shouldReceive('send')
->once()
->with(Mockery::type(Request::class))
->with(Mockery::type(Request::class), [])
->andThrows(new RequestFailedException('FOO', 401, null, null));

$client->shouldReceive('send')
->once()
->with(Mockery::type(Request::class))
->with(Mockery::type(Request::class), [])
->andReturn($this->response);

$host = 'http://localhost';
Expand Down Expand Up @@ -229,6 +235,7 @@ public function testCanRequestIfRequestFails(): void
$requestMock->shouldReceive('getAdditionalHeaders')->andReturn([]);
$requestMock->shouldReceive('getContentType')->andReturn('bier');
$requestMock->shouldReceive('getBody')->andReturnNull();
$requestMock->shouldReceive('getOptions')->andReturn([]);

$response = $testAuthApi->request($requestMock);
$this->assertSame($this->response, $response);
Expand Down

0 comments on commit 4ece3ea

Please sign in to comment.