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 @@ + \ No newline at end of file