From a8e3c594e3d79196d6746083c57c7e82fb227bb4 Mon Sep 17 00:00:00 2001 From: "Timothy J. Warren" Date: Fri, 9 Oct 2015 14:34:55 -0400 Subject: [PATCH] Basic Menu generation --- app/bootstrap.php | 40 ++---- app/config/menus.php | 28 ----- app/views/anime/list.php | 9 +- app/views/header.php | 14 +-- index.php | 37 +++++- .../AnimeClient/Auth/HummingbirdAuth.php | 22 +++- src/Aviat/AnimeClient/Config.php | 23 +--- src/Aviat/AnimeClient/Controller.php | 10 +- src/Aviat/AnimeClient/Controller/Anime.php | 16 +-- .../AnimeClient/Controller/Collection.php | 39 ++---- src/Aviat/AnimeClient/Controller/Manga.php | 18 +-- .../{Router.php => Dispatcher.php} | 6 +- src/Aviat/AnimeClient/Helper/Menu.php | 4 +- src/Aviat/AnimeClient/Helper/UrlHelper.php | 19 --- src/Aviat/AnimeClient/MenuGenerator.php | 59 +++++---- src/Aviat/AnimeClient/RoutingBase.php | 56 +++++++++ src/Aviat/Ion/Type/ArrayType.php | 11 +- src/functions.php | 12 -- .../{RouterTest.php => DispatcherTest.php} | 16 ++- tests/AnimeClient/MenuGeneratorTest.php | 59 +++++++++ tests/AnimeClient/RoutingBaseTest.php | 51 ++++++++ tests/bootstrap.php | 115 +++++++++++------- 22 files changed, 391 insertions(+), 273 deletions(-) rename src/Aviat/AnimeClient/{Router.php => Dispatcher.php} (98%) delete mode 100644 src/Aviat/AnimeClient/Helper/UrlHelper.php rename tests/AnimeClient/{RouterTest.php => DispatcherTest.php} (95%) create mode 100644 tests/AnimeClient/MenuGeneratorTest.php create mode 100644 tests/AnimeClient/RoutingBaseTest.php diff --git a/app/bootstrap.php b/app/bootstrap.php index dfbc39ce..df93e1c0 100644 --- a/app/bootstrap.php +++ b/app/bootstrap.php @@ -5,47 +5,24 @@ namespace Aviat\AnimeClient; -use \Whoops\Handler\PrettyPageHandler; -use \Whoops\Handler\JsonResponseHandler; use Aura\Html\HelperLocatorFactory; -use \Aura\Web\WebFactory; -use \Aura\Router\RouterFactory; -use \Aura\Session\SessionFactory; - +use Aura\Web\WebFactory; +use Aura\Router\RouterFactory; +use Aura\Session\SessionFactory; use Aviat\Ion\Di\Container; -require _dir(SRC_DIR, '/functions.php'); - // ----------------------------------------------------------------------------- // Setup DI container // ----------------------------------------------------------------------------- -$di = function() { +return function(array $config_array = []) { $container = new Container(); - // ------------------------------------------------------------------------- - // Setup error handling - // ------------------------------------------------------------------------- - $whoops = new \Whoops\Run(); - - // Set up default handler for general errors - $defaultHandler = new PrettyPageHandler(); - $whoops->pushHandler($defaultHandler); - - // Set up json handler for ajax errors - $jsonHandler = new JsonResponseHandler(); - $jsonHandler->onlyForAjaxRequests(TRUE); - $whoops->pushHandler($jsonHandler); - - $whoops->register(); - - $container->set('error-handler', $defaultHandler); - // ------------------------------------------------------------------------- // Injected Objects // ------------------------------------------------------------------------- // Create Config Object - $config = new Config(); + $config = new Config($config_array); $container->set('config', $config); // Create Aura Router Object @@ -79,14 +56,11 @@ $di = function() { $container->set('url-generator', new UrlGenerator($container)); // ------------------------------------------------------------------------- - // Router + // Dispatcher // ------------------------------------------------------------------------- - $router = new Router($container); - $container->set('router', $router); + $container->set('dispatcher', new Dispatcher($container)); return $container; }; -$di()->get('router')->dispatch(); - // End of bootstrap.php \ No newline at end of file diff --git a/app/config/menus.php b/app/config/menus.php index 1d4ce011..788509b6 100644 --- a/app/config/menus.php +++ b/app/config/menus.php @@ -1,24 +1,7 @@ [ - 'default' => '', - 'items' => [ - 'anime_list' => '{anime_list}', - 'manga_list' => '{manga_list}', - 'collection' => '{collection}' - ] - ], - 'view_type' => [ - 'is_parent' => FALSE, - 'default' => 'cover_view', - 'items' => [ - 'cover_view' => '{parent}', - 'list_view' => '{parent}/list' - ] - ], 'anime_list' => [ - 'default' => '', 'route_prefix' => '/anime', 'items' => [ 'watching' => '/watching', @@ -27,13 +10,9 @@ return [ 'dropped' => '/dropped', 'completed' => '/completed', 'all' => '/all' - ], - 'children' => [ - 'view_type' ] ], 'manga_list' => [ - 'default' => '', 'route_prefix' => '/manga', 'items' => [ 'reading' => '/reading', @@ -42,20 +21,13 @@ return [ 'dropped' => '/dropped', 'completed' => '/completed', 'all' => '/all' - ], - 'children' => [ - 'view_type' ] ], 'collection' => [ - 'default' => '', 'route_prefix' => '/collection', 'items' => [ 'anime' => '/anime', 'manga' => '/manga', - ], - 'children' => [ - 'view_type' ] ] ]; \ No newline at end of file diff --git a/app/views/anime/list.php b/app/views/anime/list.php index 1a7fdd14..e8b0343e 100644 --- a/app/views/anime/list.php +++ b/app/views/anime/list.php @@ -8,7 +8,6 @@ Title - Alternate Title Airing Status Score Type @@ -25,19 +24,21 @@ + " . $item['anime']['alternate_title'] : "" ?> - / 10 Episodes: / - + + diff --git a/app/views/header.php b/app/views/header.php index b17a858d..ea30df67 100644 --- a/app/views/header.php +++ b/app/views/header.php @@ -24,20 +24,14 @@ -
- diff --git a/index.php b/index.php index 26bff907..2edf4b35 100644 --- a/index.php +++ b/index.php @@ -2,6 +2,10 @@ /** * Here begins everything! */ +use Whoops\Handler\PrettyPageHandler; +use Whoops\Handler\JsonResponseHandler; + +use Aviat\AnimeClient\Config; // Work around the silly timezone error $timezone = ini_get('date.timezone'); @@ -47,6 +51,37 @@ spl_autoload_register(function($class) { // Dependency setup require _dir(ROOT_DIR, '/vendor/autoload.php'); -require _dir(APP_DIR, 'bootstrap.php'); +require _dir(SRC_DIR, '/functions.php'); + +// ------------------------------------------------------------------------- +// Setup error handling +// ------------------------------------------------------------------------- +$whoops = new \Whoops\Run(); + +// Set up default handler for general errors +$defaultHandler = new PrettyPageHandler(); +$whoops->pushHandler($defaultHandler); + +// Set up json handler for ajax errors +$jsonHandler = new JsonResponseHandler(); +$jsonHandler->onlyForAjaxRequests(TRUE); +$whoops->pushHandler($jsonHandler); + +//$whoops->register(); + +// ----------------------------------------------------------------------------- +// Dependency Injection setup +// ----------------------------------------------------------------------------- +require _dir(CONF_DIR, 'base_config.php'); // $base_config +require _dir(CONF_DIR, 'config.php'); // $config +$config_array = array_merge($base_config, $config); +$di = require _dir(APP_DIR, 'bootstrap.php'); +$container = $di($config_array); +$container->set('error-handler', $defaultHandler); + +// ----------------------------------------------------------------------------- +// Dispatch to the current route +// ----------------------------------------------------------------------------- +$container->get('dispatcher')(); // End of index.php \ No newline at end of file diff --git a/src/Aviat/AnimeClient/Auth/HummingbirdAuth.php b/src/Aviat/AnimeClient/Auth/HummingbirdAuth.php index c3562755..2e24e643 100644 --- a/src/Aviat/AnimeClient/Auth/HummingbirdAuth.php +++ b/src/Aviat/AnimeClient/Auth/HummingbirdAuth.php @@ -5,6 +5,9 @@ namespace Aviat\AnimeClient\Auth; use Aviat\Ion\Di\ContainerInterface; use Aviat\AnimeClient\Model\Anime as AnimeModel; +/** + * Hummingbird API Authentication + */ class HummingbirdAuth { use \Aviat\Ion\Di\ContainerAware; @@ -31,19 +34,32 @@ class HummingbirdAuth { public function __construct(ContainerInterface $container) { $this->setContainer($container); - $this->session = $container->get('sesion') + $this->session = $container->get('session') ->getSegment(__NAMESPACE__); $this->model = new AnimeModel($container); } + /** + * Make the appropriate authentication call, + * and save the resulting auth token if successful + * + * @param string $username + * @param string $password + * @return boolean + */ public function authenticate($username, $password) { - + return $this->model->authenticate(); } + /** + * Retrieve the authentication token from the session + * + * @return string + */ public function get_auth_token() { - + return $this->session->get('auth_token'); } } diff --git a/src/Aviat/AnimeClient/Config.php b/src/Aviat/AnimeClient/Config.php index 3d535bf3..10d35ee6 100644 --- a/src/Aviat/AnimeClient/Config.php +++ b/src/Aviat/AnimeClient/Config.php @@ -15,27 +15,16 @@ class Config { * * @var array */ - protected $config = []; + protected $map = []; /** * Constructor * * @param array $config_files */ - public function __construct(array $config_files = []) + public function __construct(array $config_array = []) { - // @codeCoverageIgnoreStart - if (empty($config_files)) - { - require_once \_dir(CONF_DIR, 'config.php'); // $config - require_once \_dir(CONF_DIR, 'base_config.php'); // $base_config - - $this->config = array_merge($config, $base_config); - } - else // @codeCoverageIgnoreEnd - { - $this->config = $config_files; - } + $this->map = $config_array; } /** @@ -46,9 +35,9 @@ class Config { */ public function get($key) { - if (isset($this->config[$key])) + if (array_key_exists($key, $this->map)) { - return $this->config[$key]; + return $this->map[$key]; } return NULL; @@ -63,7 +52,7 @@ class Config { */ public function set($key, $value) { - $this->config[$key] = $value; + $this->map[$key] = $value; return $this; } } diff --git a/src/Aviat/AnimeClient/Controller.php b/src/Aviat/AnimeClient/Controller.php index b3f65acf..a4419e8d 100644 --- a/src/Aviat/AnimeClient/Controller.php +++ b/src/Aviat/AnimeClient/Controller.php @@ -56,7 +56,7 @@ class Controller { protected $base_data = [ 'url_type' => 'anime', 'other_type' => 'manga', - 'nav_routes' => [] + 'menu_name' => '' ]; /** @@ -105,7 +105,7 @@ class Controller { { $errorHandler = $this->container->get('error-handler'); $errorHandler->addDataTable('Template Data', $data); - $router = $this->container->get('router'); + $router = $this->container->get('dispatcher'); if (isset($this->base_data)) { @@ -131,7 +131,7 @@ class Controller { * * @param HtmlView $view * @param string $template - * @param array|object $data + * @param array $data * @return void */ public function render_full_page($view, $template, array $data) @@ -145,10 +145,10 @@ class Controller { * Output a template to HTML, using the provided data * * @param string $template - * @param array|object $data + * @param array $data * @return void */ - public function outputHTML($template, $data = []) + public function outputHTML($template, array $data = []) { $view = new HtmlView($this->container); $this->render_full_page($view, $template, $data); diff --git a/src/Aviat/AnimeClient/Controller/Anime.php b/src/Aviat/AnimeClient/Controller/Anime.php index 9416fb7a..0fe9afe5 100644 --- a/src/Aviat/AnimeClient/Controller/Anime.php +++ b/src/Aviat/AnimeClient/Controller/Anime.php @@ -34,20 +34,6 @@ class Anime extends BaseController { */ protected $base_data; - /** - * Route mapping for main navigation - * @var array $nav_routes - */ - private $nav_routes = [ - 'Watching' => '/anime/watching{/view}', - 'Plan to Watch' => '/anime/plan_to_watch{/view}', - 'On Hold' => '/anime/on_hold{/view}', - 'Dropped' => '/anime/dropped{/view}', - 'Completed' => '/anime/completed{/view}', - 'Collection' => '/collection/view{/view}', - 'All' => '/anime/all{/view}' - ]; - /** * Constructor * @@ -65,10 +51,10 @@ class Anime extends BaseController { $this->model = new AnimeModel($container); $this->collection_model = new AnimeCollectionModel($container); $this->base_data = array_merge($this->base_data, [ + 'menu_name' => 'anime_list', 'message' => '', 'url_type' => 'anime', 'other_type' => 'manga', - 'nav_routes' => $this->nav_routes, 'config' => $this->config, ]); } diff --git a/src/Aviat/AnimeClient/Controller/Collection.php b/src/Aviat/AnimeClient/Controller/Collection.php index 341bf61d..a57cb33c 100644 --- a/src/Aviat/AnimeClient/Controller/Collection.php +++ b/src/Aviat/AnimeClient/Controller/Collection.php @@ -19,9 +19,9 @@ class Collection extends BaseController { /** * The anime collection model - * @var object $collection_model + * @var object $anime_collection_model */ - private $collection_model; + private $anime_collection_model; /** * Data to ve sent to all routes in this controller @@ -35,20 +35,6 @@ class Collection extends BaseController { */ protected $urlGenerator; - /** - * Route mapping for main navigation - * @var array $nav_routes - */ - private $nav_routes = [ - 'Watching' => '/anime/watching{/view}', - 'Plan to Watch' => '/anime/plan_to_watch{/view}', - 'On Hold' => '/anime/on_hold{/view}', - 'Dropped' => '/anime/dropped{/view}', - 'Completed' => '/anime/completed{/view}', - 'Collection' => '/collection/view{/view}', - 'All' => '/anime/all{/view}' - ]; - /** * Constructor * @@ -58,18 +44,13 @@ class Collection extends BaseController { { parent::__construct($container); - if ($this->config->get('show_anime_collection') === FALSE) - { - unset($this->nav_routes['Collection']); - } - $this->urlGenerator = $container->get('url-generator'); - $this->collection_model = new AnimeCollectionModel($container); + $this->anime_anime_collection_model = new AnimeCollectionModel($container); $this->base_data = array_merge($this->base_data, [ + 'menu_name' => 'collection', 'message' => '', 'url_type' => 'anime', 'other_type' => 'manga', - 'nav_routes' => $this->nav_routes, 'config' => $this->config, ]); } @@ -98,12 +79,12 @@ class Collection extends BaseController { 'list' => 'list' ]; - $data = $this->collection_model->get_collection(); + $data = $this->anime_collection_model->get_collection(); $this->outputHTML('collection/' . $view_map[$view], [ 'title' => $this->config->get('whose_list') . "'s Anime Collection", 'sections' => $data, - 'genres' => $this->collection_model->get_genre_list() + 'genres' => $this->anime_collection_model->get_genre_list() ]); } @@ -121,8 +102,8 @@ class Collection extends BaseController { 'action' => $action, 'action_url' => $this->urlGenerator->full_url("collection/" . strtolower($action)), 'title' => $this->config->whose_list . " Anime Collection · {$action}", - 'media_items' => $this->collection_model->get_media_type_list(), - 'item' => ($action === "Edit") ? $this->collection_model->get($id) : [] + 'media_items' => $this->anime_collection_model->get_media_type_list(), + 'item' => ($action === "Edit") ? $this->anime_collection_model->get($id) : [] ]); } @@ -139,7 +120,7 @@ class Collection extends BaseController { $this->redirect("collection/view", 303, "anime"); } - $this->collection_model->update($data); + $this->anime_collection_model->update($data); $this->redirect("collection/view", 303, "anime"); } @@ -157,7 +138,7 @@ class Collection extends BaseController { $this->redirect("collection/view", 303, "anime"); } - $this->collection_model->add($data); + $this->anime_collection_model->add($data); $this->redirect("collection/view", 303, "anime"); } diff --git a/src/Aviat/AnimeClient/Controller/Manga.php b/src/Aviat/AnimeClient/Controller/Manga.php index d49328b6..620b9846 100644 --- a/src/Aviat/AnimeClient/Controller/Manga.php +++ b/src/Aviat/AnimeClient/Controller/Manga.php @@ -26,20 +26,6 @@ class Manga extends Controller { */ protected $base_data; - - /** - * Route mapping for main navigation - * @var array $nav_routes - */ - private $nav_routes = [ - 'Reading' => '/manga/reading{/view}', - 'Plan to Read' => '/manga/plan_to_read{/view}', - 'On Hold' => '/manga/on_hold{/view}', - 'Dropped' => '/manga/dropped{/view}', - 'Completed' => '/manga/completed{/view}', - 'All' => '/manga/all{/view}' - ]; - /** * Constructor * @@ -51,10 +37,10 @@ class Manga extends Controller { $config = $container->get('config'); $this->model = new MangaModel($container); $this->base_data = array_merge($this->base_data, [ + 'menu_name' => 'manga_list', 'config' => $this->config, 'url_type' => 'manga', - 'other_type' => 'anime', - 'nav_routes' => $this->nav_routes + 'other_type' => 'anime' ]); } diff --git a/src/Aviat/AnimeClient/Router.php b/src/Aviat/AnimeClient/Dispatcher.php similarity index 98% rename from src/Aviat/AnimeClient/Router.php rename to src/Aviat/AnimeClient/Dispatcher.php index c09e6294..82ab1f44 100644 --- a/src/Aviat/AnimeClient/Router.php +++ b/src/Aviat/AnimeClient/Dispatcher.php @@ -12,7 +12,7 @@ use Aviat\Ion\Di\ContainerInterface; /** * Basic routing/ dispatch */ -class Router extends RoutingBase { +class Dispatcher extends RoutingBase { /** * The route-matching object @@ -109,7 +109,7 @@ class Router extends RoutingBase { * @param object $route * @return void */ - public function dispatch($route = NULL) + public function __invoke($route = NULL) { $error_handler = $this->container->get('error-handler'); @@ -264,4 +264,4 @@ class Router extends RoutingBase { return $output_routes; } } -// End of Router.php \ No newline at end of file +// End of Dispatcher.php \ No newline at end of file diff --git a/src/Aviat/AnimeClient/Helper/Menu.php b/src/Aviat/AnimeClient/Helper/Menu.php index 536ac7d0..c68e0492 100644 --- a/src/Aviat/AnimeClient/Helper/Menu.php +++ b/src/Aviat/AnimeClient/Helper/Menu.php @@ -2,11 +2,9 @@ namespace Aviat\AnimeClient\Helper; -use Aura\Html\Helper\AbstractHelper; - use Aviat\AnimeClient\MenuGenerator; -class Menu extends AbstractHelper { +class Menu { use \Aviat\Ion\Di\ContainerAware; diff --git a/src/Aviat/AnimeClient/Helper/UrlHelper.php b/src/Aviat/AnimeClient/Helper/UrlHelper.php deleted file mode 100644 index 6c92a874..00000000 --- a/src/Aviat/AnimeClient/Helper/UrlHelper.php +++ /dev/null @@ -1,19 +0,0 @@ -menus = $this->config->get('menus'); $this->helper = $container->get('html-helper'); + $this->request = $container->get('request'); } /** @@ -49,16 +56,11 @@ class MenuGenerator extends RoutingBase { // Note: Children menus have urls based on the // current url path /* - $parsed = [ - 'menu_name' => [ - 'items' => [ - 'title' => 'full_url_path', - ], - 'children' => [ - 'title' => 'full_url_path' - ] - ] - ] + parsed = { + menu_name: { + title: 'full_url_path' + } + } */ $parsed = []; @@ -68,14 +70,8 @@ class MenuGenerator extends RoutingBase { $parsed[$name] = []; foreach ($menu['items'] as $path_name => $partial_path) { - $title = $this->string($path_name)->humanize()->titleize(); - $parsed[$name]['items'][$title] = $this->string($menu['route_prefix'])->append($partial_path); - } - - // @TODO: Handle child menu(s) - if (count($menu['children']) > 0) - { - + $title = (string) $this->string($path_name)->humanize()->titleize(); + $parsed[$name][$title] = (string) $this->string($menu['route_prefix'])->append($partial_path); } } @@ -91,16 +87,29 @@ class MenuGenerator extends RoutingBase { public function generate($menu) { $parsed_config = $this->parse_config(); + + // Bail out early on invalid menu + if ( ! $this->arr($parsed_config)->has_key($menu)) + { + return ''; + } + $menu_config = $parsed_config[$menu]; - // Array of list items to add to the main menu - $main_menu = []; + foreach($menu_config as $title => $path) + { + $selected = $this->string($path)->contains($this->path()); + $link = $this->helper->a($this->url($path), $title); + $attrs = ($selected) + ? ['class' => 'selected'] + : []; - // Start the menu list - $helper->ul(); - + $this->helper->ul()->rawItem($link, $attrs); + } + // Create the menu html + return $this->helper->ul(); } } // End of MenuGenerator.php \ No newline at end of file diff --git a/src/Aviat/AnimeClient/RoutingBase.php b/src/Aviat/AnimeClient/RoutingBase.php index e063c594..7a5742c5 100644 --- a/src/Aviat/AnimeClient/RoutingBase.php +++ b/src/Aviat/AnimeClient/RoutingBase.php @@ -11,6 +11,9 @@ use Aviat\Ion\Di\ContainerInterface; * Base for routing/url classes */ class RoutingBase { + + use \Aviat\Ion\StringWrapper; + /** * Injection Container * @var Container $container @@ -56,5 +59,58 @@ class RoutingBase { return $routing_config[$key]; } } + + /** + * Get the current url path + * + * @return string + */ + public function path() + { + $request = $this->container->get('request'); + $path = $request->server->get('REQUEST_URI'); + $cleaned_path = $this->string($path) + ->trim() + ->trimRight('/') + ->ensureLeft('/'); + + return (string) $cleaned_path; + } + + /** + * Get the url segments + * + * @return array + */ + public function segments() + { + $path = $this->path(); + $segments = explode('/', $path); + + return $segments; + } + + /** + * Get a segment of the current url + * + * @param int $num + * @return string|null + */ + public function get_segment($num) + { + $segments = $this->segments(); + return (array_key_exists($num, $segments)) ? $segments[$num] : NULL; + } + + /** + * Retrieve the last url segment + * + * @return string + */ + public function last_segment() + { + $segments = $this->segments(); + return end($segments); + } } // End of RoutingBase.php \ No newline at end of file diff --git a/src/Aviat/Ion/Type/ArrayType.php b/src/Aviat/Ion/Type/ArrayType.php index 40f928b2..09bfd4c7 100644 --- a/src/Aviat/Ion/Type/ArrayType.php +++ b/src/Aviat/Ion/Type/ArrayType.php @@ -28,7 +28,6 @@ class ArrayType { 'filter' => 'array_filter', 'flip' => 'array_flip', 'intersect' => 'array_intersect', - 'has_key' => 'array_key_exists', 'keys' => 'array_keys', 'merge' => 'array_merge', 'pad' => 'array_pad', @@ -90,6 +89,16 @@ class ArrayType { return $this->arr; } } + + /** + * Does the passed key exist in the current array? + * + * @return bool + */ + public function has_key($key) + { + return array_key_exists($key, $this->arr); + } /** * Fill an array with the specified value diff --git a/src/functions.php b/src/functions.php index 25ed65f7..2e85bd79 100644 --- a/src/functions.php +++ b/src/functions.php @@ -28,18 +28,6 @@ function is_not_selected($a, $b) return ($a !== $b) ? 'selected' : ''; } -/** - * Get the last segment of the current url - * - * @return string - */ -function last_segment() -{ - $path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH); - $segments = explode('/', $path); - return end($segments); -} - /** * Determine whether to show the sub-menu * diff --git a/tests/AnimeClient/RouterTest.php b/tests/AnimeClient/DispatcherTest.php similarity index 95% rename from tests/AnimeClient/RouterTest.php rename to tests/AnimeClient/DispatcherTest.php index 1d0e8e6e..432a35b9 100644 --- a/tests/AnimeClient/RouterTest.php +++ b/tests/AnimeClient/DispatcherTest.php @@ -1,13 +1,13 @@ [] ]); + $old_config = $this->container->get('config'); + // Add the appropriate objects to the container $this->container = new Container([ - 'config' => new Config($config), + 'config' => $old_config, 'request' => $web_factory->newRequest(), 'response' => $web_factory->newResponse(), 'aura-router' => $router_factory->newInstance(), 'error-handler' => new MockErrorHandler() ]); - $this->router = new Router($this->container); + if ( ! empty($config)) + { + $config = new Config($config); + $this->container->set('config', $config); + } + + $this->router = new Dispatcher($this->container); $this->config = $this->container->get('config'); $this->urlGenerator = new UrlGenerator($this->container); $this->container->set('url-generator', $this->urlGenerator); diff --git a/tests/AnimeClient/MenuGeneratorTest.php b/tests/AnimeClient/MenuGeneratorTest.php new file mode 100644 index 00000000..6eda8dc0 --- /dev/null +++ b/tests/AnimeClient/MenuGeneratorTest.php @@ -0,0 +1,59 @@ +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() + { + $generator = new MenuGenerator($this->container); + $this->assertInstanceOf('Aviat\AnimeClient\MenuGenerator', $generator); + } + + public function testParseConfig() + { + $friend = new Friend($this->generator); + $expected = [ + 'anime_list' => [ + 'Watching' => '/anime/watching', + 'Plan To Watch' => '/anime/plan_to_watch', + 'On Hold' => '/anime/on_hold', + 'Dropped' => '/anime/dropped', + 'Completed' => '/anime/completed', + 'All' => '/anime/all' + ] + ]; + $this->assertEquals($expected, $friend->parse_config()); + } +} \ No newline at end of file diff --git a/tests/AnimeClient/RoutingBaseTest.php b/tests/AnimeClient/RoutingBaseTest.php new file mode 100644 index 00000000..657072be --- /dev/null +++ b/tests/AnimeClient/RoutingBaseTest.php @@ -0,0 +1,51 @@ +routingBase = new RoutingBase($this->container); + } + + public function dataSegments() + { + return [ + 'empty_segment' => [ + 'request_uri' => ' // ', + 'path' => '/', + 'segments' => ['', ''], + 'last_segment' => NULL + ], + 'three_segments' => [ + 'request_uri' => '/anime/watching/list ', + 'path' => '/anime/watching/list', + 'segments' => ['', 'anime', 'watching', 'list'], + 'last_segment' => 'list' + ] + ]; + } + + /** + * @dataProvider dataSegments + */ + public function testSegments($request_uri, $path, $segments, $last_segment) + { + $this->setSuperGlobals([ + '_SERVER' => [ + 'REQUEST_URI' => $request_uri + ] + ]); + + $this->assertEquals($path, $this->routingBase->path(), "Path is invalid"); + $this->assertEquals($segments, $this->routingBase->segments(), "Segments array is invalid"); + $this->assertEquals($last_segment, $this->routingBase->last_segment(), "Last segment is invalid"); + + foreach($segments as $i => $value) + { + $this->assertEquals($value, $this->routingBase->get_segment($i), "Segment {$i} is invalid"); + } + } +} \ No newline at end of file diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 65095077..49ecc102 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -2,54 +2,12 @@ /** * Global setup for unit tests */ +use Aura\Web\WebFactory; use Aviat\AnimeClient\Config; use Aviat\Ion\Di\Container; use Aviat\AnimeClient\UrlGenerator; -// ----------------------------------------------------------------------------- -// Mock the default error handler -// ----------------------------------------------------------------------------- - -class MockErrorHandler { - public function addDataTable($name, Array $values) {} -} - -// ----------------------------------------------------------------------------- -// Define a base testcase class -// ----------------------------------------------------------------------------- - -/** - * Base class for TestCases - */ -class AnimeClient_TestCase extends PHPUnit_Framework_TestCase { - protected $container; - - public function setUp() - { - parent::setUp(); - - $config = new Config([ - 'asset_path' => '//localhost/assets/', - 'databaase' => [], - 'routes' => [ - 'common' => [], - 'anime' => [], - 'manga' => [] - ] - ]); - - $container = new Container([ - 'config' => $config, - 'error-handler' => new MockErrorHandler() - ]); - - $container->set('url-generator', new UrlGenerator($container)); - - $this->container = $container; - } -} - // ----------------------------------------------------------------------------- // Autoloaders // ----------------------------------------------------------------------------- @@ -72,7 +30,7 @@ define('CONF_DIR', _dir(APP_DIR, 'config')); define('SRC_DIR', _dir(ROOT_DIR, 'src')); define('BASE_DIR', _dir(SRC_DIR, 'Base')); require _dir(ROOT_DIR, '/vendor/autoload.php'); -require _dir(SRC_DIR, 'functions.php'); +require _dir(SRC_DIR, '/functions.php'); /** * Set up autoloaders @@ -95,4 +53,71 @@ spl_autoload_register(function ($class) { $_SESSION = []; $_COOKIE = []; -// End of bootstrap.php +// ----------------------------------------------------------------------------- +// Mock the default error handler +// ----------------------------------------------------------------------------- + +class MockErrorHandler { + public function addDataTable($name, array $values=[]) {} +} + +// ----------------------------------------------------------------------------- +// Define a base testcase class +// ----------------------------------------------------------------------------- + +/** + * Base class for TestCases + */ +class AnimeClient_TestCase extends PHPUnit_Framework_TestCase { + protected $container; + + public function setUp() + { + parent::setUp(); + + $config_array = [ + 'asset_path' => '//localhost/assets/', + 'databaase' => [], + 'routing' => [ + + ], + 'routes' => [ + 'convention' => [ + 'default_controller' => '', + 'default_method' => '', + ], + 'common' => [], + 'anime' => [], + 'manga' => [] + ] + ]; + + $di = require _dir(APP_DIR, 'bootstrap.php'); + $container = $di($config_array); + $container->set('error-handler', new MockErrorHandler()); + + $this->container = $container; + } + + /** + * Set arbitrary superglobal values for testing purposes + * + * @param array $supers + * @return void + */ + public function setSuperGlobals($supers = []) + { + $default = [ + '_GET' => $_GET, + '_POST' => $_POST, + '_COOKIE' => $_COOKIE, + '_SERVER' => $_SERVER, + '_FILES' => $_FILES + ]; + $web_factory = new WebFactory(array_merge($default,$supers)); + $this->container->set('request', $web_factory->newRequest()); + $this->container->set('response', $web_factory->newResponse()); + } +} + +// End of bootstrap.php \ No newline at end of file