Add order and order request classes

References #3
This commit is contained in:
Oliver Davies 2020-05-31 01:02:21 +01:00
parent e83c6e59e4
commit 532dfd43a1
10 changed files with 342 additions and 8 deletions

View file

@ -0,0 +1,9 @@
<?php
namespace Opdavies\Glassboxx\Enum;
final class InteractionType
{
public const LOAN = 'loan';
public const PURCHASE = 'purchase';
}

View file

@ -0,0 +1,62 @@
<?php
declare(strict_types=1);
namespace Opdavies\Glassboxx\Request;
use Opdavies\Glassboxx\Enum\InteractionType;
use Opdavies\Glassboxx\Traits\UsesAuthTokenTrait;
use Opdavies\Glassboxx\Traits\UsesCreatedAtTrait;
use Opdavies\Glassboxx\ValueObject\OrderInterface;
class OrderRequest extends AbstractRequest implements OrderRequestInterface
{
use UsesCreatedAtTrait;
use UsesAuthTokenTrait;
/** @var OrderInterface */
private $order;
public function forOrder(OrderInterface $order): AbstractRequest
{
$this->order = $order;
return $this;
}
public function execute(): string
{
$body = [
'items' => [
[
'created_at' => $this->getCreatedAtDate(),
'currency_code' => $this->order->getCurrencyCode(),
'customer_email' => $this->order->getCustomer()->getEmailAddress(),
'customer_firstname' => $this->order->getCustomer()->getFirstName(),
'customer_lastname' => $this->order->getCustomer()->getLastName(),
'discount_amount' => 0,
'duration_for_loan' => 0,
'hostname' => $this->config->getVendorId(),
'original_order_number' => $this->order->getOrderNumber(),
'price_incl_tax' => $this->order->getPrice(),
'sku' => $this->order->getSku(),
'type_of_interaction' => InteractionType::PURCHASE,
],
],
];
$response = $this->client->request(
'POST',
self::BASE_URL . self::ENDPOINT,
[
'auth_bearer' => $this->authToken,
'headers' => [
'Content-Type' => 'application/json',
],
'body' => json_encode($body),
]
);
return $response->getContent(false);
}
}

View file

@ -0,0 +1,16 @@
<?php
declare(strict_types=1);
namespace Opdavies\Glassboxx\Request;
use Opdavies\Glassboxx\ValueObject\OrderInterface;
interface OrderRequestInterface
{
public const ENDPOINT = '/glassboxxorder/toglassboxx';
public function forOrder(OrderInterface $order): AbstractRequest;
public function execute(): string;
}

View file

@ -0,0 +1,25 @@
<?php
declare(strict_types=1);
namespace Opdavies\Glassboxx\Traits;
use DateTime;
trait UsesCreatedAtTrait
{
/** @var string */
private $time = 'now';
public function getCreatedAtDate(): string
{
return (new DateTime($this->time))->format('Y-m-d H:i:s');
}
public function setCreatedDate(string $dateString): self
{
$this->time = $dateString;
return $this;
}
}

View file

@ -0,0 +1,62 @@
<?php
declare(strict_types=1);
namespace Opdavies\Glassboxx\ValueObject;
final class Order implements OrderInterface
{
/** @var CustomerInterface */
private $customer;
/** @var string */
private $sku;
/** @var string */
private $orderNumber;
/** @var string */
private $currencyCode;
/** @var float */
private $price;
public function __construct(
CustomerInterface $customer,
string $sku,
string $orderNumber,
string $currencyCode,
float $price
) {
$this->customer = $customer;
$this->sku = $sku;
$this->orderNumber = $orderNumber;
$this->currencyCode = $currencyCode;
$this->price = $price;
}
public function getCurrencyCode(): string
{
return $this->currencyCode;
}
public function getCustomer(): CustomerInterface
{
return $this->customer;
}
public function getOrderNumber(): string
{
return $this->orderNumber;
}
public function getPrice(): float
{
return $this->price;
}
public function getSku(): string
{
return $this->sku;
}
}

View file

@ -0,0 +1,24 @@
<?php
namespace Opdavies\Glassboxx\ValueObject;
interface OrderInterface
{
public function __construct(
CustomerInterface $customer,
string $sku,
string $orderNumber,
string $currencyCode,
float $price
);
public function getCurrencyCode(): string;
public function getCustomer(): CustomerInterface;
public function getOrderNumber(): string;
public function getPrice(): float;
public function getSku(): string;
}

View file

@ -7,6 +7,7 @@ namespace Opdavies\Glassboxx\Tests\Glassboxx\Request;
use Opdavies\Glassboxx\Request\AuthTokenRequestInterface;
use Opdavies\Glassboxx\Request\CustomerRequest;
use Opdavies\Glassboxx\Tests\Glassboxx\TestCase;
use Opdavies\Glassboxx\Traits\UsesCreatedAtTrait;
use Opdavies\Glassboxx\ValueObject\CustomerInterface;
use Symfony\Component\HttpClient\MockHttpClient;
use Symfony\Contracts\HttpClient\ResponseInterface;
@ -49,15 +50,8 @@ final class CustomerRequestTest extends TestCase
)
->willReturn($response);
$customer = $this->getMockBuilder(CustomerInterface::class)
->disableOriginalConstructor()
->getMock();
$customer->method('getFirstName')->willReturn('Oliver');
$customer->method('getLastName')->willReturn('Davies');
$customer->method('getEmailAddress')->willReturn('oliver@oliverdavies.uk');
$request = (new CustomerRequest($client))
->forCustomer($customer)
->forCustomer($this->getMockCustomer())
->withAuthToken($authTokenRequest->getToken())
->withConfig($this->config);

View file

@ -0,0 +1,67 @@
<?php
declare(strict_types=1);
namespace Opdavies\Glassboxx\Tests\Glassboxx\Request;
use DateTime;
use Opdavies\Glassboxx\Request\OrderRequest;
use Opdavies\Glassboxx\Tests\Glassboxx\TestCase;
use Symfony\Component\HttpClient\MockHttpClient;
use Symfony\Contracts\HttpClient\ResponseInterface;
final class OrderRequestTest extends TestCase
{
public function testThatItCreatesAnOrder(): void
{
$body = [
'items' => [
[
'created_at' => '2020-06-04 12:00:00',
'currency_code' => 'GBP',
'customer_email' => 'oliver@oliverdavies.uk',
'customer_firstname' => 'Oliver',
'customer_lastname' => 'Davies',
'discount_amount' => 0,
'duration_for_loan' => 0,
'hostname' => 123,
'original_order_number' => 'abc123',
'price_incl_tax' => 100,
'sku' => 'this-is-the-first-sku',
'type_of_interaction' => 'purchase',
],
],
];
$response = $this->getMockBuilder(ResponseInterface::class)->getMock();
$response->method('getContent')->willReturn(json_encode($body));
$authTokenRequest = $this->getMockAuthTokenRequest();
$client = $this->getMockBuilder(MockHttpClient::class)->getMock();
$client->expects($this->once())
->method('request')
->with(
'POST',
OrderRequest::BASE_URL
.OrderRequest::ENDPOINT,
[
'auth_bearer' => $authTokenRequest->getToken(),
'headers' => [
'Content-Type' => 'application/json',
],
'body' => json_encode($body),
]
)
->willReturn($response);
$request = (new OrderRequest($client))
->forOrder($this->getMockOrder())
->withAuthToken($authTokenRequest->getToken())
->withConfig($this->config)
->setCreatedDate('2020-06-04 12:00:00');
// A successful response returns the original body.
$this->assertSame(json_encode($body), $request->execute());
}
}

View file

@ -3,6 +3,9 @@
namespace Opdavies\Glassboxx\Tests\Glassboxx;
use Opdavies\Glassboxx\Config;
use Opdavies\Glassboxx\Request\AuthTokenRequestInterface;
use Opdavies\Glassboxx\ValueObject\CustomerInterface;
use Opdavies\Glassboxx\ValueObject\OrderInterface;
class TestCase extends \PHPUnit\Framework\TestCase
{
@ -24,4 +27,42 @@ class TestCase extends \PHPUnit\Framework\TestCase
)
->getMock();
}
protected function getMockAuthTokenRequest(): AuthTokenRequestInterface
{
$authTokenRequest = $this->getMockBuilder(AuthTokenRequestInterface::class)
->getMock();
$authTokenRequest->expects($this->any())
->method('getToken')
->willReturn('testtoken');
return $authTokenRequest;
}
protected function getMockCustomer(): CustomerInterface
{
$customer = $this->getMockBuilder(CustomerInterface::class)
->disableOriginalConstructor()
->getMock();
$customer->method('getFirstName')->willReturn('Oliver');
$customer->method('getLastName')->willReturn('Davies');
$customer->method('getEmailAddress')->willReturn('oliver@oliverdavies.uk');
return $customer;
}
protected function getMockOrder(): OrderInterface
{
$order = $this->getMockBuilder(OrderInterface::class)
->disableOriginalConstructor()
->getMock();
$order->method('getCurrencyCode')->willReturn('GBP');
$order->method('getCustomer')->willReturn($this->getMockCustomer());
$order->method('getOrderNumber')->willReturn('abc123');
$order->method('getPrice')->willReturn((float) 100);
$order->method('getSku')->willReturn('this-is-the-first-sku');
return $order;
}
}

View file

@ -0,0 +1,34 @@
<?php
declare(strict_types=1);
namespace Opdavies\Glassboxx\Tests\Glassboxx\ValueObject;
use Opdavies\Glassboxx\Tests\Glassboxx\TestCase;
use Opdavies\Glassboxx\ValueObject\Customer;
use Opdavies\Glassboxx\ValueObject\CustomerInterface;
use Opdavies\Glassboxx\ValueObject\Order;
class OrderTest extends TestCase
{
public function testCreatingAnOrder(): void
{
$customer = $this->getMockBuilder(CustomerInterface::class)
->disableOriginalConstructor()
->getMock();
$order = new Order(
$customer,
'this-is-the-sku',
'123',
'GBP',
10.00
);
$this->assertSame('GBP', $order->getCurrencyCode());
$this->assertSame($customer, $order->getCustomer());
$this->assertSame('123', $order->getOrderNumber());
$this->assertSame(10.0, $order->getPrice());
$this->assertSame('this-is-the-sku', $order->getSku());
}
}