Skip to content

Commit

Permalink
Merge pull request #17 from chadicus/develop
Browse files Browse the repository at this point in the history
Add __call() to Client
  • Loading branch information
chadicus committed Dec 18, 2015
2 parents eeafa0f + 874be08 commit 0784ee7
Show file tree
Hide file tree
Showing 8 changed files with 212 additions and 22 deletions.
6 changes: 1 addition & 5 deletions examples/get.php
Expand Up @@ -8,11 +8,7 @@

$client = new Client($privateApiKey, $publicApiKey);

$response = $client->get('characters', 1009351);

$wrapper = $response->getDataWrapper();

$character = $wrapper->getData()->getResults()[0];
$character = $client->characters(1009351);

echo "{$character->getName()}\n";
echo "{$character->getDescription()}\n";
Expand Down
23 changes: 23 additions & 0 deletions examples/get_character_by_id.php
@@ -0,0 +1,23 @@
<?php
require_once dirname(__DIR__) . '/vendor/autoload.php';

use Chadicus\Marvel\Api\Client;

$publicApiKey = getenv('PUBLIC_KEY');
$privateApiKey = getenv('PRIVATE_KEY');

$client = new Client($privateApiKey, $publicApiKey);

$response = $client->get('characters', 1009351);

$wrapper = $response->getDataWrapper();

$character = $wrapper->getData()->getResults()[0];

echo "{$character->getName()}\n";
echo "{$character->getDescription()}\n";

foreach ($character->getEvents()->getItems() as $event) {
echo "\t{$event->getName()}\n";
}

16 changes: 16 additions & 0 deletions examples/search.php
@@ -0,0 +1,16 @@
<?php
require_once dirname(__DIR__) . '/vendor/autoload.php';

use Chadicus\Marvel\Api\Client;

$publicApiKey = getenv('PUBLIC_KEY');
$privateApiKey = getenv('PRIVATE_KEY');

$client = new Client($privateApiKey, $publicApiKey);

//1009165 is the character id for the Avangers
$comics = $client->comics(['characters' => 1009165]);

foreach ($comics as $comic) {
echo "{$comic->getTitle()}\n";
}
25 changes: 25 additions & 0 deletions src/Client.php
Expand Up @@ -153,4 +153,29 @@ final private function getFromCache(RequestInterface $request)

return $this->cache->get($request);
}

/**
* Allow calls such as $client->characters();
*
* @param string $name The name of the api resource
* @param array $arguments The parameters to pass to get() or search()
*
* @return Collection|EntityInterface
*/
final public function __call($name, array $arguments)
{
$resource = strtolower($name);
$parameters = array_shift($arguments);
if ($parameters === null || is_array($parameters)) {
return new Collection($this, $resource, $parameters ?: []);
}

$response = $this->get($resource, $parameters);
$results = $response->getDataWrapper()->getData()->getResults();
if (empty($results)) {
return null;
}

return $results[0];
}
}
2 changes: 1 addition & 1 deletion src/Response.php
Expand Up @@ -92,7 +92,7 @@ final public function getHeaders()
*/
final public function getDataWrapper()
{
if ($this->dataWrapper === null && $this->httpCode === 200) {
if ($this->dataWrapper === null) {
$this->dataWrapper = new DataWrapper($this->body);
}

Expand Down
13 changes: 12 additions & 1 deletion tests/Assets/ComicAdapter.php
Expand Up @@ -29,10 +29,21 @@ final class ComicAdapter implements AdapterInterface
public function send(RequestInterface $request)
{
$allResults = self::getAllResults();
$total = count($allResults);

$queryString = parse_url($request->getUrl(), PHP_URL_QUERY);
$queryParams = [];
parse_str($queryString, $queryParams);

$path = parse_url($request->getUrl(), PHP_URL_PATH);
if (substr($path, -6) !== 'comics') {
$parts = explode('/', $request->getUrl());
$id = array_pop($parts);
$queryParams['offset'] = $id - 1;
$queryParams['limit'] = 1;
$total = 1;
}

$this->parameters = $queryParams;

$offset = (int)$queryParams['offset'];
Expand All @@ -49,7 +60,7 @@ public function send(RequestInterface $request)
'data' => [
'offset' => $offset,
'limit' => $limit,
'total' => 5,
'total' => $total,
'count' => $count,
'results' => $results,
],
Expand Down
54 changes: 54 additions & 0 deletions tests/Assets/ErrorAdapter.php
@@ -0,0 +1,54 @@
<?php
namespace Chadicus\Marvel\Api\Assets;

use Chadicus\Marvel\Api\Adapter\AdapterInterface;
use Chadicus\Marvel\Api\RequestInterface;
use Chadicus\Marvel\Api\Response;

/**
* Adapter implementation that only returns empty responses.
*/
final class ErrorAdapter implements AdapterInterface
{
/**
* The last request given to this adapter.
*
* @var Request
*/
private $request = null;

/**
* Returns an empty Response.
*
* @param RequestInterface $request The request to send.
*
* @return ResponseInterface
*/
public function send(RequestInterface $request)
{
$this->request = $request;

return new Response(
404,
[
'code' => 'ResourceNotFound',
'message' => "{$request->getUrl()} was not found",
],
[
'Response Code' => 404,
'Response Status' => 'Not Found',
'Content-Type' => 'application/json',
]
);
}

/**
* Return the last request given to this Adapter.
*
* @return RequestInterface
*/
public function getRequest()
{
return $this->request;
}
}
95 changes: 80 additions & 15 deletions tests/ClientTest.php
Expand Up @@ -2,7 +2,7 @@

namespace Chadicus\Marvel\Api;

use Chadicus\Marvel\Api\Assets\FakeAdapter;
use Chadicus\Marvel\Api\Assets;
use Chadicus\Marvel\Api\Adapter\AdapterInterface;

/**
Expand Down Expand Up @@ -42,7 +42,7 @@ function () {
}
);

$adapter = new FakeAdapter();
$adapter = new Assets\FakeAdapter();
$client = new Client('aPrivateKey', 'aPublicKey', $adapter);
$client->search('a Resource', ['key' => 'value']);
$request = $adapter->getRequest();
Expand Down Expand Up @@ -82,15 +82,15 @@ public function badConstructorData()
{
return [
// privateApiKey
'privateApiKey is null' => [null, 'a public key', new FakeAdapter()],
'privateApiKey is empty' => ['', 'a public key', new FakeAdapter()],
'privateApiKey is whitespace' => [" \n\t", 'a public key', new FakeAdapter()],
'privateApiKey is not a string' => [true, 'a public key', new FakeAdapter()],
'privateApiKey is null' => [null, 'a public key', new Assets\FakeAdapter()],
'privateApiKey is empty' => ['', 'a public key', new Assets\FakeAdapter()],
'privateApiKey is whitespace' => [" \n\t", 'a public key', new Assets\FakeAdapter()],
'privateApiKey is not a string' => [true, 'a public key', new Assets\FakeAdapter()],
// publicApiKey
'publicApiKey is null' => ['a private key', null, new FakeAdapter()],
'publicApiKey is empty' => ['a private key', '', new FakeAdapter()],
'publicApiKey is whitespace' => ['a private key', "\n \t", new FakeAdapter()],
'publicApiKey is not a string' => ['a private key', false, new FakeAdapter()],
'publicApiKey is null' => ['a private key', null, new Assets\FakeAdapter()],
'publicApiKey is empty' => ['a private key', '', new Assets\FakeAdapter()],
'publicApiKey is whitespace' => ['a private key', "\n \t", new Assets\FakeAdapter()],
'publicApiKey is not a string' => ['a private key', false, new Assets\FakeAdapter()],
];
}

Expand All @@ -109,7 +109,7 @@ public function badConstructorData()
*/
public function searchtWithBadData($resource, array $filters)
{
(new Client('not under test', 'not under test', new FakeAdapter()))->search($resource, $filters);
(new Client('not under test', 'not under test', new Assets\FakeAdapter()))->search($resource, $filters);
}

/**
Expand Down Expand Up @@ -147,7 +147,7 @@ function () {
}
);

$adapter = new FakeAdapter();
$adapter = new Assets\FakeAdapter();
$client = new Client('aPrivateKey', 'aPublicKey', $adapter);
$client->get('a Resource', 1);
$request = $adapter->getRequest();
Expand All @@ -174,7 +174,7 @@ function () {
*/
public function gettWithBadData($resource, $id)
{
(new Client('not under test', 'not under test', new FakeAdapter()))->get($resource, $id);
(new Client('not under test', 'not under test', new Assets\FakeAdapter()))->get($resource, $id);
}

/**
Expand Down Expand Up @@ -220,7 +220,7 @@ function () {
new Request(Client::BASE_URL . "a+Resource/1?apikey=aPublicKey&ts=1&hash={$hash}", 'GET'),
new Response(599, ['custom' => 'header'], ['key' => 'value'])
);
$adapter = new FakeAdapter();
$adapter = new Assets\FakeAdapter();
$client = new Client('aPrivateKey', 'aPublicKey', $adapter, $cache);
$response = $client->get('a Resource', 1);
$this->assertSame(599, $response->getHttpCode());
Expand Down Expand Up @@ -253,7 +253,7 @@ function () {
$request = new Request(Client::BASE_URL . "a+Resource/1?apikey=aPublicKey&ts=1&hash={$hash}", 'GET');

$cache = new Cache\ArrayCache();
$adapter = new FakeAdapter();
$adapter = new Assets\FakeAdapter();
$client = new Client('aPrivateKey', 'aPublicKey', $adapter, $cache);
$response = $client->get('a Resource', 1);

Expand All @@ -262,4 +262,69 @@ function () {
$this->assertSame($response->getHeaders(), $cachedResponse->getHeaders());
$this->assertSame($response->getBody(), $cachedResponse->getBody());
}

/**
* Verify bahvior of __call() for single entity.
*
* @test
* @covers ::__call
*
* @return void
*/
public function callEntity()
{
$client = new Client('not under test', 'not under test', new Assets\ComicAdapter());
$comic = $client->comics(2);
$this->assertInstanceOf('Chadicus\Marvel\Api\Entities\Comic', $comic);
$this->assertSame(2, $comic->getId());
}

/**
* Verify bahvior of __call() for entity that is not found.
*
* @test
* @covers ::__call
*
* @return void
*/
public function callEntityNotFound()
{
$client = new Client('not under test', 'not under test', new Assets\EmptyAdapter());
$comic = $client->comics(1);
$this->assertNull($comic);
}

/**
* Verify bahvior of __call() for entity that is invalid.
*
* @test
* @covers ::__call
*
* @return void
*/
public function callInvalidEntity()
{
$client = new Client('not under test', 'not under test', new Assets\ErrorAdapter());
$result = $client->batman(1);
$this->assertNull($result);
}

/**
* Verify basic bahvior of __call() for entity collection.
*
* @test
* @covers ::__call
*
* @return void
*/
public function callCollection()
{
$client = new Client('not under test', 'not under test', new Assets\ComicAdapter());
$comics = $client->comics();
$this->assertInstanceOf('Chadicus\Marvel\Api\Collection', $comics);
$this->assertSame(5, $comics->count());
foreach ($comics as $key => $comic) {
$this->assertSame($key + 1, $comic->getId());
}
}
}

0 comments on commit 0784ee7

Please sign in to comment.