Skip to content

Commit

Permalink
Merge pull request #7 from airtimerewards/refactor/client-interface
Browse files Browse the repository at this point in the history
Refactor client to use interface
  • Loading branch information
Jaik Dean authored Aug 28, 2019
2 parents e00afbd + 40ee089 commit 099c436
Show file tree
Hide file tree
Showing 28 changed files with 418 additions and 488 deletions.
16 changes: 8 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ To instantiate a client, use the factory method and pass in your environment ID
```php
<?php

use AirtimeRewards\ARConnect\Client;
use AirtimeRewards\ARConnect\ARConnectClient;

$client = Client::createClient('api-key', 'environment-id', $logger);
$client = ARConnectClient::createClient('api-key', 'environment-id', $logger);
```

### 3.2 Retrieving Data to Make a Credit
Expand All @@ -49,9 +49,9 @@ applicable to that mobile account.
```php
<?php

use AirtimeRewards\ARConnect\Client;
use AirtimeRewards\ARConnect\ARConnectClient;

$client = Client::createClient('api-key', 'environment-id', $logger);
$client = ARConnectClient::createClient('api-key', 'environment-id', $logger);

$networks = $client->getNetworks(); // returns a collection of networks
$filteredNetworks = $client->getNetworks('447700900000'); // returns a collection of networks for UK mobile number 07700 900 000
Expand All @@ -63,9 +63,9 @@ credit types contain information about the minimum, maximum and increments of cr
```php
<?php

use AirtimeRewards\ARConnect\Client;
use AirtimeRewards\ARConnect\ARConnectClient;

$client = Client::createClient('api-key', 'environment-id', $logger);
$client = ARConnectClient::createClient('api-key', 'environment-id', $logger);
$creditTypes = $client->getCreditTypesForNetwork($network);
```

Expand All @@ -86,12 +86,12 @@ A credit can be applied by calling the `createCredit()` method with the followin
```php
<?php

use AirtimeRewards\ARConnect\Client;
use AirtimeRewards\ARConnect\ARConnectClient;
use AirtimeRewards\ARConnect\Credit;
use Money\Money;
use Money\Currency;

$client = Client::createClient('api-key', 'environment-id', $logger);
$client = ARConnectClient::createClient('api-key', 'environment-id', $logger);
$creditValue = new Money(1000, new Currency('GBP')); // £10 of credit
$credit = $client->createCredit(
'447700900000',
Expand Down
8 changes: 8 additions & 0 deletions psalm-baseline.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<files psalm-version="3.4.12@86e5e50c1bb492045e70f2ebe1da3cad06e4e9b2">
<file src="tests/ARConnectClientTest.php">
<TooManyArguments occurrences="1">
<code>append</code>
</TooManyArguments>
</file>
</files>
1 change: 1 addition & 0 deletions psalm.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="https://getpsalm.org/schema/config"
xsi:schemaLocation="https://getpsalm.org/schema/config"
errorBaseline="psalm-baseline.xml"
>
<projectFiles>
<directory name="src"/>
Expand Down
163 changes: 35 additions & 128 deletions src/Client.php → src/ARConnectClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,61 +16,44 @@
use AirtimeRewards\ARConnect\Hateoas\HateoasInterface;
use AirtimeRewards\ARConnect\Hateoas\PaginatedCollection;
use AirtimeRewards\ARConnect\Util\MoneyConverter;
use GuzzleHttp\Client as GuzzleClient;
use GuzzleHttp\Client;
use GuzzleHttp\ClientInterface;
use GuzzleHttp\Exception\GuzzleException;
use Money\Money;
use Psr\Log\LoggerInterface;

/**
* AR Connect API client.
*
* @author Jaik Dean <[email protected]>
* @author Rick Ogden <[email protected]>
*/
class Client
final class ARConnectClient implements ARConnectClientInterface
{
protected const PATH_CREATE_CREDIT = '/v1/environments/{environment}/credits';
protected const PATH_CREATE_QUOTE = '/v1/quote';
protected const PATH_GET_CREDIT = '/v1/credits/{id}';
protected const PATH_GET_ELIGIBILITY = '/v1/environments/{environment}/eligibility/{msisdn}';
protected const PATH_GET_NETWORKS = '/v1/networks';
protected const PATH_GET_CREDIT_TYPES_FOR_NETWORK = '/v1/networks/{network}/credit-types';

protected const LOG_REQUEST_CREATE_CREDIT = '-> POST '.self::PATH_CREATE_CREDIT;
protected const LOG_REQUEST_GET_CREDITS = '-> GET '.self::PATH_CREATE_CREDIT;
protected const LOG_REQUEST_GET_CREDIT = '-> GET '.self::PATH_GET_CREDIT;
protected const LOG_REQUEST_GET_CREDIT_TYPES_FOR_MSISDN = '-> GET '.self::PATH_GET_NETWORKS;
protected const LOG_REQUEST_GET_CREDIT_TYPES_FOR_NETWORK = '-> GET '.self::PATH_GET_CREDIT_TYPES_FOR_NETWORK;
protected const LOG_RESPONSE_ERROR = '<- Error response received from AR Connect';
protected const LOG_RESPONSE_INVALID_JSON = '<- Invalid JSON received from AR Connect';
protected const LOG_RESPONSE_MISSING_DATA = '<- Missing data received from AR Connect';
protected const LOG_RESPONSE_OK = '<- Response OK';

/**
* @var string API URL
*/
protected $endpoint;

/**
* @var string API token
*/
protected $apiKey;

/**
* @var ClientInterface
*/
protected $client;

/**
* @var LoggerInterface
*/
protected $logger;

/**
* @var string
*/
protected $environmentId;
private const PATH_CREATE_CREDIT = '/v1/environments/{environment}/credits';
private const PATH_GET_CREDIT = '/v1/credits/{id}';
private const PATH_GET_ELIGIBILITY = '/v1/environments/{environment}/eligibility/{msisdn}';
private const PATH_GET_NETWORKS = '/v1/networks';
private const PATH_GET_CREDIT_TYPES_FOR_NETWORK = '/v1/networks/{network}/credit-types';

private const LOG_REQUEST_CREATE_CREDIT = '-> POST '.self::PATH_CREATE_CREDIT;
private const LOG_REQUEST_GET_CREDITS = '-> GET '.self::PATH_CREATE_CREDIT;
private const LOG_REQUEST_GET_CREDIT = '-> GET '.self::PATH_GET_CREDIT;
private const LOG_REQUEST_GET_CREDIT_TYPES_FOR_MSISDN = '-> GET '.self::PATH_GET_NETWORKS;
private const LOG_REQUEST_GET_CREDIT_TYPES_FOR_NETWORK = '-> GET '.self::PATH_GET_CREDIT_TYPES_FOR_NETWORK;
private const LOG_RESPONSE_ERROR = '<- Error response received from AR Connect';
private const LOG_RESPONSE_INVALID_JSON = '<- Invalid JSON received from AR Connect';
private const LOG_RESPONSE_MISSING_DATA = '<- Missing data received from AR Connect';
private const LOG_RESPONSE_OK = '<- Response OK';

/** @var string API token */
private $apiKey;

/** @var ClientInterface */
private $client;

/** @var LoggerInterface */
private $logger;

/** @var string */
private $environmentId;

/**
* Intialise the Guzzle client.
Expand All @@ -81,7 +64,7 @@ public static function createClient(
LoggerInterface $logger,
string $endpoint = 'https://api.connect.airtimerewards.co.uk'
): self {
$client = new GuzzleClient(['base_uri' => $endpoint]);
$client = new Client(['base_uri' => $endpoint]);

return new self($client, $apiKey, $environmentId, $logger);
}
Expand All @@ -102,16 +85,6 @@ public function __construct(
$this->environmentId = $environmentId;
}

/**
* Get credit types available for a MSISDN (mobile number).
*
*
* @param string $msisdn
*
* @throws FailedResponseException
* @throws InvalidResponseException
* @throws GuzzleException
*/
public function getNetworks(?string $msisdn = null): NetworkCollection
{
// Log the request
Expand All @@ -129,7 +102,7 @@ public function getNetworks(?string $msisdn = null): NetworkCollection
return new NetworkCollection($data);
}

protected function createLogContext(): array
private function createLogContext(): array
{
return ['request_id' => \uniqid('', true)];
}
Expand All @@ -144,11 +117,11 @@ protected function createLogContext(): array
*
* @throws FailedResponseException if the request failed in an expected way
* @throws InvalidResponseException if the response couldn’t be parsed
* @throws GuzzleException
* @throws \Throwable & GuzzleException
*
* @return array Decoded JSON body
*/
protected function makeRequest(
private function makeRequest(
string $method,
string $uri,
array $options = [],
Expand Down Expand Up @@ -197,30 +170,13 @@ protected function makeRequest(
throw new InvalidResponseException('Cannot parse data as JSON.');
}

/**
* Get credit types available for a network.
*
* @param Network $network The network
*
* @throws FailedResponseException
* @throws InvalidResponseException
* @throws GuzzleException
*/
public function getCreditTypesForNetwork(Network $network): CreditTypeCollection
{
$path = (string) $network->getLink('credit_types');

return $this->getCreditTypesForPath($path);
}

/**
* Get credit types available for a network ID.
*
*
* @throws FailedResponseException
* @throws InvalidResponseException
* @throws GuzzleException
*/
public function getCreditTypesForNetworkId(string $networkId): CreditTypeCollection
{
$path = \str_replace('{network}', $networkId, self::PATH_GET_CREDIT_TYPES_FOR_NETWORK);
Expand All @@ -231,7 +187,7 @@ public function getCreditTypesForNetworkId(string $networkId): CreditTypeCollect
/**
* @throws FailedResponseException
* @throws InvalidResponseException
* @throws GuzzleException
* @throws \Throwable & GuzzleException
*/
private function getCreditTypesForPath(string $path): CreditTypeCollection
{
Expand All @@ -248,15 +204,6 @@ private function getCreditTypesForPath(string $path): CreditTypeCollection
return new CreditTypeCollection($data);
}

/**
* Send credit to a MSISDN (mobile number).
*
* @param Network|string $network Network object or Network ID
*
* @throws FailedResponseException
* @throws InvalidResponseException
* @throws GuzzleException
*/
public function createCredit(
string $msisdn,
$network,
Expand Down Expand Up @@ -307,13 +254,6 @@ public function getCredits(): CreditCollection
return new CreditCollection($data, $this);
}

/**
* Get a credit instance.
*
* @throws FailedResponseException
* @throws InvalidResponseException
* @throws GuzzleException
*/
public function getCredit(string $id): Credit
{
// Log the request
Expand All @@ -333,11 +273,6 @@ public function getCredit(string $id): Credit
return Credit::fromJsonArray($data);
}

/**
* @throws FailedResponseException
* @throws GuzzleException
* @throws InvalidResponseException
*/
public function getPageByRel(string $rel, PaginatedCollection $collection): ?PaginatedCollection
{
$link = $collection->getLink($rel);
Expand All @@ -352,22 +287,12 @@ public function getPageByRel(string $rel, PaginatedCollection $collection): ?Pag

$data = $this->makeRequest('GET', (string) $link, [], $logContext);

/**
* @var class-string<PaginatedCollection>
*/
/** @var class-string<PaginatedCollection> */
$className = \get_class($collection);

return new $className($data, $this);
}

/**
* This will take any resource or collection and get the latest version of it.
*
* @throws FailedResponseException
* @throws InvalidResponseException
* @throws UnrefreshableException
* @throws GuzzleException
*/
public function getRefreshed(HateoasInterface $resource): HateoasInterface
{
if (null === $self = $resource->getLink('self')) {
Expand All @@ -378,15 +303,6 @@ public function getRefreshed(HateoasInterface $resource): HateoasInterface
return $resource::fromJsonArray($data);
}

/**
* @param string[] $networkIds
*
* @throws GuzzleException
* @throws InvalidResponseException
* @throws FailedResponseException
*
* @return Eligibility[]
*/
public function getEligibilityForNetworkIds(string $msisdn, array $networkIds): array
{
$networks = \implode(',', $networkIds);
Expand All @@ -400,15 +316,6 @@ public function getEligibilityForNetworkIds(string $msisdn, array $networkIds):
}, $data['_embedded']['eligibility']);
}

/**
* @param iterable<Network> $networks
*
* @throws GuzzleException
* @throws InvalidResponseException
* @throws FailedResponseException
*
* @return Eligibility[]
*/
public function getEligibilityForNetworks(string $msisdn, iterable $networks): array
{
$networks = (static function (Network ...$networks): array {
Expand Down
Loading

0 comments on commit 099c436

Please sign in to comment.