diff --git a/app/bootstrap.php b/app/bootstrap.php
index df93e1c0..ac7467f0 100644
--- a/app/bootstrap.php
+++ b/app/bootstrap.php
@@ -10,6 +10,7 @@ use Aura\Web\WebFactory;
use Aura\Router\RouterFactory;
use Aura\Session\SessionFactory;
use Aviat\Ion\Di\Container;
+use Aviat\AnimeClient\Auth\HummingbirdAuth;
// -----------------------------------------------------------------------------
// Setup DI container
@@ -54,6 +55,7 @@ return function(array $config_array = []) {
$container->set('session', $session);
$container->set('url-generator', new UrlGenerator($container));
+ $container->set('auth', new HummingbirdAuth($container));
// -------------------------------------------------------------------------
// Dispatcher
diff --git a/src/Aviat/AnimeClient/Config.php b/src/Aviat/AnimeClient/Config.php
index 2b2f6177..d3f40c63 100644
--- a/src/Aviat/AnimeClient/Config.php
+++ b/src/Aviat/AnimeClient/Config.php
@@ -10,6 +10,8 @@ namespace Aviat\AnimeClient;
*/
class Config {
+ use \Aviat\Ion\ArrayWrapper;
+
/**
* Config object
*
@@ -30,11 +32,16 @@ class Config {
/**
* Get a config value
*
- * @param string $key
+ * @param array|string $key
* @return mixed
*/
public function get($key)
{
+ if (is_array($key))
+ {
+ return $this->get_deep_key($key, FALSE);
+ }
+
if (array_key_exists($key, $this->map))
{
return $this->map[$key];
@@ -43,16 +50,84 @@ class Config {
return NULL;
}
+ /**
+ * Return a reference to an arbitrary key on the config map
+ * @param array $key
+ * @param bool $create Whether to create the missing array keys
+ * @return mixed
+ */
+ protected function &get_deep_key(array $key, $create = TRUE)
+ {
+ $pos =& $this->map;
+
+ // Create the start of the array if it doesn't exist
+ if ($create && ! is_array($pos))
+ {
+ $pos = [];
+ }
+ elseif ( ! is_array($pos))
+ {
+ return NULL;
+ }
+
+ // Iterate through the levels of the array,
+ // create the levels if they don't exist
+ foreach($key as $level)
+ {
+ if ($create && empty($pos) && ! is_array($pos))
+ {
+ $pos = [];
+ $pos[$level] = [];
+ }
+ $pos =& $pos[$level];
+ }
+
+ return $pos;
+ }
+
+ /**
+ * Remove a config value
+ *
+ * @param string|array $key
+ * @return void
+ */
+ public function delete($key)
+ {
+ $pos =& $this->map;
+
+ if (is_array($key))
+ {
+ $pos =& $this->arr($this->map)->get_deep_key($key);
+ }
+ else
+ {
+ $pos =& $this->map[$key];
+ }
+
+ unset($pos);
+ }
+
/**
* Set a config value
*
- * @param string $key
+ * @param string|array $key
* @param mixed $value
* @return Config
*/
public function set($key, $value)
{
- $this->map[$key] = $value;
+ $pos =& $this->map;
+
+ if (is_array($key))
+ {
+ $pos =& $this->get_deep_key($key);
+ $pos = $value;
+ }
+ else
+ {
+ $pos[$key] = $value;
+ }
+
return $this;
}
}
diff --git a/src/Aviat/AnimeClient/Controller/Anime.php b/src/Aviat/AnimeClient/Controller/Anime.php
index 1b718bb8..e58289d6 100644
--- a/src/Aviat/AnimeClient/Controller/Anime.php
+++ b/src/Aviat/AnimeClient/Controller/Anime.php
@@ -43,11 +43,6 @@ class Anime extends BaseController {
{
parent::__construct($container);
- if ($this->config->get('show_anime_collection') === FALSE)
- {
- unset($this->nav_routes['Collection']);
- }
-
$this->model = new AnimeModel($container);
$this->collection_model = new AnimeCollectionModel($container);
$this->base_data = array_merge($this->base_data, [
@@ -109,7 +104,8 @@ class Anime extends BaseController {
'completed' => AnimeWatchingStatus::COMPLETED
];
- $title = $this->config->get('whose_list') . "'s Anime List · {$type_title_map[$type]}";
+ $title = $this->config->get('whose_list') .
+ "'s Anime List · {$type_title_map[$type]}";
$view_map = [
'' => 'cover',
diff --git a/src/Aviat/AnimeClient/MenuGenerator.php b/src/Aviat/AnimeClient/MenuGenerator.php
index 7d47221b..f457d4d6 100644
--- a/src/Aviat/AnimeClient/MenuGenerator.php
+++ b/src/Aviat/AnimeClient/MenuGenerator.php
@@ -19,13 +19,6 @@ class MenuGenerator extends UrlGenerator {
*/
protected $helper;
- /**
- * Menu config array
- *
- * @var array
- */
- protected $menus;
-
/**
* Request object
*
@@ -41,7 +34,6 @@ class MenuGenerator extends UrlGenerator {
public function __construct(ContainerInterface $container)
{
parent::__construct($container);
- $this->menus = $this->config->get('menus');
$this->helper = $container->get('html-helper');
$this->request = $container->get('request');
}
@@ -51,11 +43,11 @@ class MenuGenerator extends UrlGenerator {
*
* @return array
*/
- protected function parse_config()
+ protected function parse_config(array $menus)
{
$parsed = [];
- foreach ($this->menus as $name => $menu)
+ foreach ($menus as $name => $menu)
{
$parsed[$name] = [];
foreach ($menu['items'] as $path_name => $partial_path)
@@ -76,7 +68,8 @@ class MenuGenerator extends UrlGenerator {
*/
public function generate($menu)
{
- $parsed_config = $this->parse_config();
+ $menus = $this->config->get('menus');
+ $parsed_config = $this->parse_config($menus);
// Bail out early on invalid menu
if ( ! $this->arr($parsed_config)->has_key($menu))
diff --git a/src/Aviat/AnimeClient/Model/API.php b/src/Aviat/AnimeClient/Model/API.php
index cb53aba1..10e09b0c 100644
--- a/src/Aviat/AnimeClient/Model/API.php
+++ b/src/Aviat/AnimeClient/Model/API.php
@@ -7,12 +7,21 @@ namespace Aviat\AnimeClient\Model;
use GuzzleHttp\Client;
use GuzzleHttp\Cookie\CookieJar;
use GuzzleHttp\Psr7\Request;
+use GuzzleHttp\Psr7\ResponseInterface;
use Aviat\Ion\Di\ContainerInterface;
use Aviat\AnimeClient\Model as BaseModel;
/**
* Base model for api interaction
+ *
+ * @method ResponseInterface get(string $uri, array $options);
+ * @method ResponseInterface delete(string $uri, array $options);
+ * @method ResponseInterface head(string $uri, array $options);
+ * @method ResponseInterface options(string $uri, array $options);
+ * @method ResponseInterface patch(string $uri, array $options);
+ * @method ResponseInterface post(string $uri, array $options);
+ * @method ResponseInterface put(string $uri, array $options);
*/
class API extends BaseModel {
@@ -58,6 +67,35 @@ class API extends BaseModel {
]);
}
+ /**
+ * Magic methods to call guzzle api client
+ *
+ * @param string $method
+ * @param array $args
+ * @return ResponseInterface|null
+ */
+ public function __call($method, $args)
+ {
+ $valid_methods = [
+ 'get',
+ 'delete',
+ 'head',
+ 'options',
+ 'patch',
+ 'post',
+ 'put'
+ ];
+
+ if ( ! in_array($method, $valid_methods))
+ {
+ return NULL;
+ }
+
+ array_unshift($args, strtoupper($method));
+ $response = call_user_func_array([$this->client, 'request'], $args);
+ return $response;
+ }
+
/**
* Attempt login via the api
*
@@ -68,7 +106,7 @@ class API extends BaseModel {
*/
public function authenticate($username, $password)
{
- $result = $this->client->post('https://hummingbird.me/api/v1/users/authenticate', [
+ $result = $this->post('https://hummingbird.me/api/v1/users/authenticate', [
'body' => [
'username' => $username,
'password' => $password
diff --git a/src/Aviat/AnimeClient/Model/Anime.php b/src/Aviat/AnimeClient/Model/Anime.php
index 7fdec7ad..09b25f23 100644
--- a/src/Aviat/AnimeClient/Model/Anime.php
+++ b/src/Aviat/AnimeClient/Model/Anime.php
@@ -5,7 +5,6 @@
namespace Aviat\AnimeClient\Model;
-use Aviat\AnimeClient\Model\API;
use Aviat\AnimeClient\Hummingbird\Enum\AnimeWatchingStatus;
use Aviat\AnimeClient\Hummingbird\Transformer\AnimeListTransformer;
@@ -50,11 +49,11 @@ class Anime extends API {
// @TODO use Hummingbird Auth class
$data['auth_token'] = '';
- $result = $this->client->post("libraries/{$data['id']}", [
+ $response = $this->client->post("libraries/{$data['id']}", [
'body' => $data
]);
- return $result->json();
+ return json_decode($result->getBody(), TRUE);
}
/**
@@ -140,7 +139,7 @@ class Anime extends API {
]
];
- $response = $this->client->get('search/anime', $config);
+ $response = $this->get('search/anime', $config);
$errorHandler->addDataTable('anime_search_response', (array)$response);
if ($response->getStatusCode() != 200)
@@ -148,7 +147,7 @@ class Anime extends API {
throw new RuntimeException($response->getEffectiveUrl());
}
- return $response->json();
+ return json_decode($response->getBody(), TRUE);
}
/**
@@ -170,7 +169,7 @@ class Anime extends API {
}
$username = $this->config->get('hummingbird_username');
- $response = $this->client->get("users/{$username}/library", $config);
+ $response = $this->get("users/{$username}/library", $config);
$output = $this->_check_cache($status, $response);
foreach ($output as &$row)
diff --git a/src/Aviat/AnimeClient/Model/AnimeCollection.php b/src/Aviat/AnimeClient/Model/AnimeCollection.php
index f4c46cfe..1d0303c9 100644
--- a/src/Aviat/AnimeClient/Model/AnimeCollection.php
+++ b/src/Aviat/AnimeClient/Model/AnimeCollection.php
@@ -6,7 +6,6 @@
namespace Aviat\AnimeClient\Model;
use Aviat\Ion\Di\ContainerInterface;
-use Aviat\AnimeClient\Model\DB;
use Aviat\AnimeClient\Model\Anime as AnimeModel;
/**
@@ -43,8 +42,15 @@ class AnimeCollection extends DB {
$db_file_name = $this->db_config['collection']['file'];
if ($db_file_name !== ':memory:')
{
- $db_file = file_get_contents($db_file_name);
- $this->valid_database = (strpos($db_file, 'SQLite format 3') === 0);
+ if ( ! file_exists($db_file_name))
+ {
+ $this->valid_data = FALSE;
+ }
+ else
+ {
+ $db_file = file_get_contents($db_file_name);
+ $this->valid_database = (strpos($db_file, 'SQLite format 3') === 0);
+ }
}
else
{
diff --git a/src/Aviat/AnimeClient/Model/Manga.php b/src/Aviat/AnimeClient/Model/Manga.php
index da84888d..6b688821 100644
--- a/src/Aviat/AnimeClient/Model/Manga.php
+++ b/src/Aviat/AnimeClient/Model/Manga.php
@@ -49,12 +49,12 @@ class Manga extends API {
unset($data['id']);
// @TODO update with auth key from auth class
- $result = $this->client->put("manga_library_entries/{$id}", [
+ $result = $this->put("manga_library_entries/{$id}", [
'cookies' => ['token' => ''],
'json' => ['manga_library_entry' => $data]
]);
- return $result->json();
+ return json_decode($result->getBody(), TRUE);
}
/**
@@ -90,7 +90,7 @@ class Manga extends API {
/**
* Retrieve the list from the hummingbird api
- *
+ *
* @param string $status
* @return array
*/
@@ -104,7 +104,7 @@ class Manga extends API {
'allow_redirects' => FALSE
];
- $response = $this->client->get('manga_library_entries', $config);
+ $response = $this->get('manga_library_entries', $config);
$data = $this->_check_cache($response);
$output = $this->map_by_status($data);
diff --git a/src/Aviat/Ion/Type/ArrayType.php b/src/Aviat/Ion/Type/ArrayType.php
index 666f1d33..b1076b1b 100644
--- a/src/Aviat/Ion/Type/ArrayType.php
+++ b/src/Aviat/Ion/Type/ArrayType.php
@@ -61,7 +61,7 @@ class ArrayType {
*
* @param array $arr
*/
- public function __construct(array $arr)
+ public function __construct(array &$arr)
{
$this->arr =& $arr;
}
@@ -154,5 +154,41 @@ class ArrayType {
{
return in_array($value, $this->arr, $strict);
}
+
+ /**
+ * Return the array
+ *
+ * @return array
+ */
+ public function get()
+ {
+ return $this->arr;
+ }
+
+ /**
+ * Return a reference to the value of an arbitrary key on the array
+ *
+ * @param array $key
+ * @return mixed
+ */
+ public function &get_deep_key(array $key)
+ {
+ $pos =& $this->arr;
+
+ // Create the start of the array if it doesn't exist
+ if ( ! is_array($pos))
+ {
+ return NULL;
+ }
+
+ // Iterate through the levels of the array,
+ // create the levels if they don't exist
+ foreach($key as $level)
+ {
+ $pos =& $pos[$level];
+ }
+
+ return $pos;
+ }
}
// End of ArrayType.php
\ No newline at end of file
diff --git a/src/Aviat/Ion/View/HttpView.php b/src/Aviat/Ion/View/HttpView.php
index 680e6329..6fb18e8c 100644
--- a/src/Aviat/Ion/View/HttpView.php
+++ b/src/Aviat/Ion/View/HttpView.php
@@ -26,6 +26,7 @@ class HttpView extends BaseView {
/**
* Send the appropriate response
*
+ * @codeCoverageIgnore
* @return void
*/
protected function output()
diff --git a/tests/AnimeClient/ConfigTest.php b/tests/AnimeClient/ConfigTest.php
index 4a869e7b..0f338353 100644
--- a/tests/AnimeClient/ConfigTest.php
+++ b/tests/AnimeClient/ConfigTest.php
@@ -20,6 +20,83 @@ class ConfigTest extends AnimeClient_TestCase {
$this->assertNull($this->config->get('baz'));
}
+ public function testConfigSet()
+ {
+ $this->config->set('foo', 'foobar');
+ $this->assertEquals('foobar', $this->config->get('foo'));
+
+ $this->config->set(['apple', 'sauce', 'is'], 'great');
+ $this->assertEquals('great', $this->config->get(['apple', 'sauce', 'is']));
+ }
+
+ public function dataConfigDelete()
+ {
+ return [
+ 'top level delete' => [
+ 'key' => 'apple',
+ 'assertKeys' => [
+ [
+ 'path' => ['apple', 'sauce', 'is'],
+ 'expected' => NULL
+ ],
+ [
+ 'path' => ['apple', 'sauce'],
+ 'expected' => NULL
+ ],
+ [
+ 'path' => 'apple',
+ 'expected' => NULL
+ ]
+ ]
+ ],
+ 'mid level delete' => [
+ 'key' => ['apple', 'sauce'],
+ 'assertKeys' => [
+ [
+ 'path' => ['apple', 'sauce', 'is'],
+ 'expected' => NULL
+ ],
+ [
+ 'path' => ['apple', 'sauce'],
+ 'expected' => NULL
+ ],
+ [
+ 'path' => 'apple',
+ 'expected' => []
+ ]
+ ]
+ ],
+ 'deep delete' => [
+ 'key' => ['apple', 'sauce', 'is'],
+ 'assertKeys' => [
+ [
+ 'path' => ['apple', 'sauce', 'is'],
+ 'expected' => NULL
+ ],
+ [
+ 'path' => ['apple', 'sauce'],
+ 'expected' => NULL
+ ]
+ ]
+ ]
+ ];
+ }
+
+ /**
+ * @dataProvider dataConfigDelete
+ */
+ public function testConfigDelete($key, $assertKeys)
+ {
+$this->markTestIncomplete();
+ $this->config->set(['apple', 'sauce', 'is'], 'great');
+ $this->config->delete($key);
+
+ foreach($assertKeys as $pair)
+ {
+ $this->assertEquals($pair['expected'], $this->config->get($pair['path']));
+ }
+ }
+
public function testGetNonExistentConfigItem()
{
$this->assertNull($this->config->get('foobar'));
diff --git a/tests/AnimeClient/ControllerTest.php b/tests/AnimeClient/ControllerTest.php
index f1b1728b..62f72a63 100644
--- a/tests/AnimeClient/ControllerTest.php
+++ b/tests/AnimeClient/ControllerTest.php
@@ -1,5 +1,8 @@
container->set('request', $web_factory->newRequest());
$this->container->set('response', $web_factory->newResponse());
+
$this->BaseController = new Controller($this->container);
}
+ public function testControllersSanity()
+ {
+ $config = $this->container->get('config');
+ $config->set(['database', 'collection'], [
+ 'type' => 'sqlite',
+ 'database' => '',
+ 'file' => ":memory:"
+ ]);
+ $this->container->set('config', $config);
+
+ $this->assertInstanceOf(
+ 'Aviat\AnimeClient\Controller',
+ new AnimeController($this->container)
+ );
+ $this->assertInstanceOf(
+ 'Aviat\AnimeClient\Controller',
+ new MangaController($this->container)
+ );
+ $this->assertInstanceOf(
+ 'Aviat\AnimeClient\Controller',
+ new CollectionController($this->container)
+ );
+ }
+
public function testBaseControllerSanity()
{
$this->assertTrue(is_object($this->BaseController));
diff --git a/tests/AnimeClient/MenuGeneratorTest.php b/tests/AnimeClient/MenuGeneratorTest.php
index 6eda8dc0..890e1f98 100644
--- a/tests/AnimeClient/MenuGeneratorTest.php
+++ b/tests/AnimeClient/MenuGeneratorTest.php
@@ -16,23 +16,7 @@ class MenuGeneratorTest extends AnimeClient_TestCase {
public function setUp()
{
parent::setUp();
- $config = $this->container->get('config');
- $config->set('menus', [
- 'anime_list' => [
- 'route_prefix' => '/anime',
- 'items' => [
- 'watching' => '/watching',
- 'plan_to_watch' => '/plan_to_watch',
- 'on_hold' => '/on_hold',
- 'dropped' => '/dropped',
- 'completed' => '/completed',
- 'all' => '/all'
- ]
- ],
- ]);
-
$this->generator = new MenuGenerator($this->container);
-
}
public function testSanity()
@@ -44,6 +28,19 @@ class MenuGeneratorTest extends AnimeClient_TestCase {
public function testParseConfig()
{
$friend = new Friend($this->generator);
+ $menus = [
+ 'anime_list' => [
+ 'route_prefix' => '/anime',
+ 'items' => [
+ 'watching' => '/watching',
+ 'plan_to_watch' => '/plan_to_watch',
+ 'on_hold' => '/on_hold',
+ 'dropped' => '/dropped',
+ 'completed' => '/completed',
+ 'all' => '/all'
+ ]
+ ],
+ ];
$expected = [
'anime_list' => [
'Watching' => '/anime/watching',
@@ -54,6 +51,6 @@ class MenuGeneratorTest extends AnimeClient_TestCase {
'All' => '/anime/all'
]
];
- $this->assertEquals($expected, $friend->parse_config());
+ $this->assertEquals($expected, $friend->parse_config($menus));
}
}
\ No newline at end of file
diff --git a/tests/AnimeClient/Model/BaseApiModelTest.php b/tests/AnimeClient/Model/BaseApiModelTest.php
index a67edb6b..1709d684 100644
--- a/tests/AnimeClient/Model/BaseApiModelTest.php
+++ b/tests/AnimeClient/Model/BaseApiModelTest.php
@@ -6,6 +6,8 @@ use Aviat\AnimeClient\Model\API as BaseApiModel;
class MockBaseApiModel extends BaseApiModel {
+ protected $base_url = 'https://httpbin.org/';
+
public function __construct(ContainerInterface $container)
{
parent::__construct($container);
@@ -19,9 +21,15 @@ class MockBaseApiModel extends BaseApiModel {
class BaseApiModelTest extends AnimeClient_TestCase {
+ public function setUp()
+ {
+ parent::setUp();
+ $this->model = new MockBaseApiModel($this->container);
+ }
+
public function testBaseApiModelSanity()
{
- $baseApiModel = new MockBaseApiModel($this->container);
+ $baseApiModel = $this->model;
// Some basic type checks for class memebers
$this->assertInstanceOf('\Aviat\AnimeClient\Model', $baseApiModel);
@@ -34,4 +42,186 @@ class BaseApiModelTest extends AnimeClient_TestCase {
$this->assertTrue(empty($baseApiModel->base_url));
}
+ public function dataClient()
+ {
+ $host = gethostname();
+ $ip = gethostbyname($host);
+ $user_agent = "Tim's Anime Client/2.0";
+ $headers = [
+ 'User-Agent' => $user_agent
+ ];
+
+ return [
+ 'invalid' => [
+ 'method' => 'foo',
+ 'uri' => '',
+ 'options' => [],
+ 'expected' => NULL,
+ 'is_json' => FALSE,
+ ],
+ 'get' => [
+ 'method' => 'get',
+ 'uri' => '/get',
+ 'options' => [
+ 'query' => [
+ 'foo' => 'bar'
+ ],
+ 'headers' => $headers
+ ],
+ 'expected' => [
+ 'args' => [
+ 'foo' => 'bar'
+ ],
+ 'headers' => [
+ 'Host' => 'httpbin.org',
+ 'User-Agent' => $user_agent
+ ],
+ 'origin' => $ip,
+ 'url' => 'https://httpbin.org/get?foo=bar'
+ ],
+ 'is_json' => TRUE
+ ],
+ 'post' => [
+ 'method' => 'post',
+ 'uri' => '/post',
+ 'options' => [
+ 'form_params' => [
+ 'foo' => 'bar',
+ 'baz' => 'foobar'
+ ],
+ 'headers' => $headers
+ ],
+ 'expected' => [
+ 'args' => [],
+ 'data' => '',
+ 'files' => [],
+ 'form' => [
+ 'foo' => 'bar',
+ 'baz' => 'foobar'
+ ],
+ 'headers' => [
+ 'Host' => 'httpbin.org',
+ 'User-Agent' => $user_agent,
+ 'Content-Length' => '18',
+ 'Content-Type' => 'application/x-www-form-urlencoded'
+ ],
+ 'json' => NULL,
+ 'origin' => $ip,
+ 'url' => 'https://httpbin.org/post'
+ ],
+ 'is_json' => TRUE
+ ],
+ 'put' => [
+ 'method' => 'put',
+ 'uri' => '/put',
+ 'options' => [
+ 'form_params' => [
+ 'foo' => 'bar',
+ 'baz' => 'foobar'
+ ],
+ 'headers' => $headers
+ ],
+ 'expected' => [
+ 'args' => [],
+ 'data' => '',
+ 'files' => [],
+ 'form' => [
+ 'foo' => 'bar',
+ 'baz' => 'foobar'
+ ],
+ 'headers' => [
+ 'Host' => 'httpbin.org',
+ 'User-Agent' => $user_agent,
+ 'Content-Length' => '18',
+ 'Content-Type' => 'application/x-www-form-urlencoded'
+ ],
+ 'json' => NULL,
+ 'origin' => $ip,
+ 'url' => 'https://httpbin.org/put'
+ ],
+ 'is_json' => TRUE
+ ],
+ 'patch' => [
+ 'method' => 'patch',
+ 'uri' => '/patch',
+ 'options' => [
+ 'form_params' => [
+ 'foo' => 'bar',
+ 'baz' => 'foobar'
+ ],
+ 'headers' => $headers
+ ],
+ 'expected' => [
+ 'args' => [],
+ 'data' => '',
+ 'files' => [],
+ 'form' => [
+ 'foo' => 'bar',
+ 'baz' => 'foobar'
+ ],
+ 'headers' => [
+ 'Host' => 'httpbin.org',
+ 'User-Agent' => $user_agent,
+ 'Content-Length' => '18',
+ 'Content-Type' => 'application/x-www-form-urlencoded'
+ ],
+ 'json' => NULL,
+ 'origin' => $ip,
+ 'url' => 'https://httpbin.org/patch'
+ ],
+ 'is_json' => TRUE
+ ],
+ 'delete' => [
+ 'method' => 'delete',
+ 'uri' => '/delete',
+ 'options' => [
+ 'form_params' => [
+ 'foo' => 'bar',
+ 'baz' => 'foobar'
+ ],
+ 'headers' => $headers
+ ],
+ 'expected' => [
+ 'args' => [],
+ 'data' => '',
+ 'files' => [],
+ 'form' => [
+ 'foo' => 'bar',
+ 'baz' => 'foobar'
+ ],
+ 'headers' => [
+ 'Host' => 'httpbin.org',
+ 'User-Agent' => $user_agent,
+ 'Content-Length' => '18',
+ 'Content-Type' => 'application/x-www-form-urlencoded'
+ ],
+ 'json' => NULL,
+ 'origin' => $ip,
+ 'url' => 'https://httpbin.org/delete'
+ ],
+ 'is_json' => TRUE
+ ]
+ ];
+ }
+
+ /**
+ * @dataProvider dataClient
+ */
+ public function testClient($method, $uri, $options, $expected, $is_json)
+ {
+ $result = $this->model->$method($uri, $options);
+
+ if (is_null($result))
+ {
+ $this->assertNull($expected);
+ return;
+ }
+
+ $actual = ($is_json)
+ ? json_decode($result->getBody(), TRUE)
+ : (string) $result->getBody();
+
+ $this->assertEquals($expected, $actual);
+ }
+
}
\ No newline at end of file
diff --git a/tests/Ion/View/HtmlViewTest.php b/tests/Ion/View/HtmlViewTest.php
new file mode 100644
index 00000000..8b29dd41
--- /dev/null
+++ b/tests/Ion/View/HtmlViewTest.php
@@ -0,0 +1,52 @@
+getProperties();
+ $props = [];
+
+ foreach($properties as $reflectProp)
+ {
+ $reflectProp->setAccessible(TRUE);
+ $props[$reflectProp->getName()] = $reflectProp->getValue($this);
+ }
+
+ $view = new TestView($this->container);
+ $friend = new Friend($view);
+ foreach($props as $name => $val)
+ {
+ $friend->__set($name, $val);
+ }
+
+ $friend->output();
+ }
+}
+
+class HtmlViewTest extends ViewTest {
+
+ protected $template_path = __DIR__ . "/../../test_views/";
+
+ public function setUp()
+ {
+ parent::setUp();
+ $this->view = new TestHtmlView($this->container);
+ }
+
+ public function testRenderTemplate()
+ {
+ $path = $this->template_path . 'test_view.php';
+ $expected = 'foo';
+ $actual = $this->view->render_template($path, [
+ 'var' => 'foo'
+ ]);
+ $this->assertEquals($expected, $actual);
+ }
+
+}
\ No newline at end of file
diff --git a/tests/Ion/View/HttpViewTest.php b/tests/Ion/View/HttpViewTest.php
new file mode 100644
index 00000000..364c8178
--- /dev/null
+++ b/tests/Ion/View/HttpViewTest.php
@@ -0,0 +1,46 @@
+getProperties();
+ $props = [];
+
+ foreach($properties as $reflectProp)
+ {
+ $reflectProp->setAccessible(TRUE);
+ $props[$reflectProp->getName()] = $reflectProp->getValue($this);
+ }
+
+ $view = new TestView($this->container);
+ $friend = new Friend($view);
+ foreach($props as $name => $val)
+ {
+ $friend->__set($name, $val);
+ }
+
+ $friend->output();
+ }
+}
+
+class HttpViewTest extends ViewTest {
+
+ public function setUp()
+ {
+ parent::setUp();
+ $this->view = new TestHttpView($this->container);
+ $this->friend = new Friend($this->view);
+ }
+
+ public function testRedirect()
+ {
+ $this->friend->redirect('/foo', 303);
+ $this->assertEquals('/foo', $this->friend->response->headers->get('Location'));
+ $this->assertEquals(303, $this->friend->response->status->getCode());
+ }
+}
\ No newline at end of file
diff --git a/tests/Ion/View/JsonViewTest.php b/tests/Ion/View/JsonViewTest.php
new file mode 100644
index 00000000..f2800ec5
--- /dev/null
+++ b/tests/Ion/View/JsonViewTest.php
@@ -0,0 +1,44 @@
+view = new TestJsonView($this->container);
+ $this->friend = new Friend($this->view);
+ }
+
+ public function testSetOutput()
+ {
+ // Extend view class to remove destructor which does output
+ $view = new TestJsonView($this->container);
+
+ // Json encode non-string
+ $content = ['foo' => 'bar'];
+ $expected = json_encode($content);
+ $this->view->setOutput($content);
+ $this->assertEquals($expected, $this->view->getOutput());
+
+ // Directly set string
+ $content = '{}';
+ $expected = '{}';
+ $this->view->setOutput($content);
+ $this->assertEquals($expected, $this->view->getOutput());
+ }
+
+ public function testOutput()
+ {
+ $this->assertEquals('application/json', $this->friend->contentType);
+ }
+}
\ No newline at end of file
diff --git a/tests/Ion/ViewTest.php b/tests/Ion/ViewTest.php
index 425f564b..27c3477e 100644
--- a/tests/Ion/ViewTest.php
+++ b/tests/Ion/ViewTest.php
@@ -3,8 +3,6 @@
use Aura\Web\WebFactory;
use Aviat\Ion\Friend;
use Aviat\Ion\View;
-use Aviat\Ion\Di\Container;
-
class TestView extends View {
@@ -16,16 +14,6 @@ class ViewTest extends AnimeClient_TestCase {
{
parent::setUp();
- $web_factory = new WebFactory([
- '_GET' => $_GET,
- '_POST' => $_POST,
- '_COOKIE' => $_COOKIE,
- '_SERVER' => $_SERVER,
- '_FILES' => $_FILES
- ]);
- $this->container->set('request', $web_factory->newRequest());
- $this->container->set('response', $web_factory->newResponse());
-
$this->view = new TestView($this->container);
$this->friend = new Friend($this->view);
}
@@ -54,8 +42,9 @@ class ViewTest extends AnimeClient_TestCase {
{
$this->friend->contentType = 'text/html';
$this->friend->__destruct();
- $this->assertEquals($this->friend->response->content->getType(), $this->friend->contentType);
- $this->assertEquals($this->friend->response->content->getCharset(), 'utf-8');
- $this->assertEquals($this->friend->response->content->get(), $this->friend->getOutput());
+ $content =& $this->friend->response->content;
+ $this->assertEquals($content->getType(), $this->friend->contentType);
+ $this->assertEquals($content->getCharset(), 'utf-8');
+ $this->assertEquals($content->get(), $this->friend->getOutput());
}
}
\ No newline at end of file
diff --git a/tests/test_views/test_view.php b/tests/test_views/test_view.php
new file mode 100644
index 00000000..3b7e2f71
--- /dev/null
+++ b/tests/test_views/test_view.php
@@ -0,0 +1 @@
+= $var ?>
\ No newline at end of file