Version 5.1 - All the GraphQL #32

Closed
timw4mail wants to merge 1160 commits from develop into master
20 changed files with 348 additions and 491 deletions
Showing only changes of commit dfe0b3a6cf - Show all commits

View File

@ -39,7 +39,7 @@ A self-hosted client that allows custom formatting of data from the hummingbird
1. Install dependencies via composer: `composer install` 1. Install dependencies via composer: `composer install`
2. Change the `WHOSE` constant declaration in `index.php` to your name 2. Change the `WHOSE` constant declaration in `index.php` to your name
3. Configure settings in `app/config/config.php` to your liking 3. Configure settings in `app/config/config.php` and `app/config/routing.php` to your liking
4. Create the following directories if they don't exist, and make sure they are world writable 4. Create the following directories if they don't exist, and make sure they are world writable
* app/cache * app/cache
* public/images/manga * public/images/manga

View File

@ -64,6 +64,8 @@ $container->set('response', $web_factory->newResponse());
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Router // Router
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
$container->set('url-generator', new Base\UrlGenerator($container));
$router = new Base\Router($container); $router = new Base\Router($container);
$router->dispatch(); $router->dispatch();

View File

@ -10,6 +10,6 @@ $base_config = [
'img_cache_path' => _dir(ROOT_DIR, 'public/images'), 'img_cache_path' => _dir(ROOT_DIR, 'public/images'),
// Included config files // Included config files
'routes' => require _dir(CONF_DIR, 'routes.php'), 'routes' => require __DIR__ . '/routes.php',
'database' => require _dir(CONF_DIR, 'database.php'), 'database' => require __DIR__ . '/database.php',
]; ];

View File

@ -1,4 +1,4 @@
<?php <?php
$config = [ $config = [
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Username for anime and manga lists // Username for anime and manga lists
@ -13,50 +13,12 @@ $config = [
'show_anime_collection' => TRUE, 'show_anime_collection' => TRUE,
// path to public directory on the server // path to public directory on the server
'asset_dir' => __DIR__ . '/../../public', 'asset_dir' => realpath(__DIR__ . '/../../public'),
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Routing // Included config files
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
'routing' => [ // Routing paths and options
// Subfolder prefix for url 'routing' => require __DIR__ . '/routing.php',
'subfolder_prefix' => '',
// Path to public directory, where images/css/javascript are located,
// appended to the url
'asset_path' => '/public',
// Url paths to each content type
'anime_path' => 'anime',
'manga_path' => 'manga',
'collection_path' => 'collection',
'stats_path' => 'stats',
// Which list should be the default?
'default_list' => 'anime', // anime or manga
// Default pages for anime/manga
'default_anime_path' => "/anime/watching",
'default_manga_path' => '/manga/all',
// Default to list view?
'default_to_list_view' => FALSE,
],
// Url paths to each
'anime_path' => 'anime',
'manga_path' => 'manga',
'collection_path' => 'collection',
'stats_path' => 'stats',
// Which list should be the default?
'default_list' => 'anime', // anime or manga
// Default pages for anime/manga
'default_anime_path' => "/anime/watching",
'default_manga_path' => '/manga/all',
// Default to list view?
'default_to_list_view' => FALSE,
]; ];

View File

@ -14,8 +14,6 @@
/* $config = */require 'config.php'; /* $config = */require 'config.php';
$config = (object)$config;
// Should we use myth to preprocess? // Should we use myth to preprocess?
$use_myth = FALSE; $use_myth = FALSE;
@ -27,7 +25,7 @@ $use_myth = FALSE;
| The folder where css files exist, in relation to the document root | The folder where css files exist, in relation to the document root
| |
*/ */
$css_root = $config->asset_dir. '/css/'; $css_root = $config['asset_dir'] . '/css/';
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
@ -57,4 +55,4 @@ $path_to = '';
| The folder where javascript files exist, in relation to the document root | The folder where javascript files exist, in relation to the document root
| |
*/ */
$js_root = $config->asset_dir. '/js/'; $js_root = $config['asset_dir'] . '/js/';

24
app/config/routing.php Normal file
View File

@ -0,0 +1,24 @@
<?php
// ----------------------------------------------------------------------------
// Routing
// ----------------------------------------------------------------------------
return [
// Subfolder prefix for url
'subfolder_prefix' => '',
// Path to public directory, where images/css/javascript are located,
// appended to the url
'asset_path' => '/public',
// Which list should be the default?
'default_list' => 'anime', // anime or manga
// Default pages for anime/manga
'default_anime_path' => "/anime/watching",
'default_manga_path' => '/manga/all',
// Default to list view?
'default_to_list_view' => FALSE,
];

View File

@ -53,112 +53,5 @@ class Config {
return NULL; return NULL;
} }
/**
* Get the base url for css/js/images
*
* @return string
*/
public function asset_url(/*...*/)
{
$args = func_get_args();
$base_url = rtrim($this->url(""), '/');
$routing_config = $this->__get("routing");
$base_url = "{$base_url}" . $routing_config['asset_path'];
array_unshift($args, $base_url);
return implode("/", $args);
}
/**
* Get the base url from the config
*
* @param string $type - (optional) The controller
* @return string
*/
public function base_url($type="anime")
{
$config_path = trim($this->__get("{$type}_path"), "/");
// Set the appropriate HTTP host
$host = $_SERVER['HTTP_HOST'];
$path = ($config_path !== '') ? $config_path : "";
return implode("/", ['/', $host, $path]);
}
/**
* Generate a proper url from the path
*
* @param string $path
* @return string
*/
public function url($path)
{
$path = trim($path, '/');
// Remove any optional parameters from the route
$path = preg_replace('`{/.*?}`i', '', $path);
// Set the appropriate HTTP host
$host = $_SERVER['HTTP_HOST'];
return "//{$host}/{$path}";
}
public function default_url($type)
{
$type = trim($type);
$default_path = $this->__get("default_{$type}_path");
if ( ! is_null($default_path))
{
return $this->url($default_path);
}
return "";
}
/**
* Generate full url path from the route path based on config
*
* @param string $path - (optional) The route path
* @param string $type - (optional) The controller (anime or manga), defaults to anime
* @return string
*/
public function full_url($path="", $type="anime")
{
$config_path = trim($this->__get("{$type}_path"), "/");
$config_default_route = $this->__get("default_{$type}_path");
// Remove beginning/trailing slashes
$config_path = trim($config_path, '/');
$path = trim($path, '/');
// Remove any optional parameters from the route
$path = preg_replace('`{/.*?}`i', '', $path);
// Set the appropriate HTTP host
$host = $_SERVER['HTTP_HOST'];
// Set the default view
if ($path === '')
{
$path .= trim($config_default_route, '/');
if ($this->__get('default_to_list_view')) $path .= '/list';
}
// Set an leading folder
/*if ($config_path !== '')
{
$path = "{$config_path}/{$path}";
}*/
return "//{$host}/{$path}";
}
} }
// End of config.php // End of config.php

View File

@ -1,6 +1,6 @@
<?php <?php
namespace Animeclient\Base; namespace AnimeClient\Base;
/** /**
* Wrapper of Aura container to be in the anime client namespace * Wrapper of Aura container to be in the anime client namespace

View File

@ -33,6 +33,12 @@ class Controller {
*/ */
protected $model; protected $model;
/**
* Url generatation class
* @var UrlGenerator
*/
protected $urlGenerator;
/** /**
* Common data to be sent to views * Common data to be sent to views
* @var array * @var array
@ -46,16 +52,19 @@ class Controller {
/** /**
* Constructor * Constructor
* *
* @param Config $config * @param Container $container
* @param array $web * @param array $web
*/ */
public function __construct(Container $container) public function __construct(Container $container)
{ {
$this->config = $container->get('config'); $this->config = $container->get('config');
$this->base_data['config'] = $this->config; $this->base_data['config'] = $this->config;
$this->base_data['urlGenerator'] = $container->get('url-generator');
$this->request = $container->get('request'); $this->request = $container->get('request');
$this->response = $container->get('response'); $this->response = $container->get('response');
$this->urlGenerator = $container->get('url-generator');
} }
/** /**
@ -169,7 +178,7 @@ class Controller {
*/ */
public function redirect($url, $code, $type="anime") public function redirect($url, $code, $type="anime")
{ {
$url = $this->config->full_url($url, $type); $url = $this->urlGenerator->full_url($url, $type);
$this->response->redirect->to($url, $code); $this->response->redirect->to($url, $code);
} }
@ -199,7 +208,7 @@ class Controller {
public function logout() public function logout()
{ {
session_destroy(); session_destroy();
$this->response->redirect->seeOther($this->config->full_url('')); $this->response->redirect->seeOther($this->urlGenerator->full_url(''));
} }
/** /**
@ -238,7 +247,7 @@ class Controller {
) )
) )
{ {
$this->response->redirect->afterPost($this->config->full_url('', $this->base_data['url_type'])); $this->response->redirect->afterPost($this->urlGenerator->full_url('', $this->base_data['url_type']));
return; return;
} }

View File

@ -10,7 +10,7 @@ use \Aura\Web\Response;
/** /**
* Basic routing/ dispatch * Basic routing/ dispatch
*/ */
class Router { class Router extends RoutingBase {
/** /**
* The route-matching object * The route-matching object
@ -18,12 +18,6 @@ class Router {
*/ */
protected $router; protected $router;
/**
* The global configuration object
* @var object $config
*/
protected $config;
/** /**
* Class wrapper for input superglobals * Class wrapper for input superglobals
* @var object * @var object
@ -42,12 +36,6 @@ class Router {
*/ */
protected $output_routes; protected $output_routes;
/**
* Injection Container
* @var Container $container
*/
protected $container;
/** /**
* Constructor * Constructor
* *
@ -58,14 +46,12 @@ class Router {
*/ */
public function __construct(Container $container) public function __construct(Container $container)
{ {
$this->config = $container->get('config'); parent::__construct($container);
$this->router = $container->get('aura-router'); $this->router = $container->get('aura-router');
$this->request = $container->get('request'); $this->request = $container->get('request');
$this->web = [$this->request, $container->get('response')]; $this->web = [$this->request, $container->get('response')];
$this->output_routes = $this->_setup_routes(); $this->output_routes = $this->_setup_routes();
$this->container = $container;
} }
/** /**
@ -141,7 +127,6 @@ class Router {
$controller = new $controller_name($this->container); $controller = new $controller_name($this->container);
// Run the appropriate controller method // Run the appropriate controller method
$error_handler->addDataTable('controller_args', $params); $error_handler->addDataTable('controller_args', $params);
call_user_func_array([$controller, $action_method], $params); call_user_func_array([$controller, $action_method], $params);
} }
@ -153,29 +138,20 @@ class Router {
*/ */
public function get_controller() public function get_controller()
{ {
$route_type = $this->config->default_list; $error_handler = $this->container->get('error-handler');
$route_type = $this->__get('default_list');
$host = $this->request->server->get("HTTP_HOST"); $host = $this->request->server->get("HTTP_HOST");
$request_uri = $this->request->server->get('PATH_INFO'); $request_uri = $this->request->server->get('PATH_INFO');
$path = trim($request_uri, '/'); $path = trim($request_uri, '/');
$route_type_map = [
$this->config->anime_path => 'anime',
$this->config->manga_path => 'manga',
$this->config->collection_path => 'collection',
$this->config->stats_path => 'stats'
];
$segments = explode('/', $path); $segments = explode('/', $path);
$controller = array_shift($segments); $controller = reset($segments);
if (array_key_exists($controller, array_keys($route_type_map))) //$controller_class = '\\AnimeClient\\Controller\\' . ucfirst($controller);
{
return $route_type_map[$controller];
}
return $route_type; return $controller;
} }
/** /**
@ -190,9 +166,9 @@ class Router {
$route_type = $this->get_controller(); $route_type = $this->get_controller();
// Return early if invalid route array // Return early if invalid route array
if ( ! array_key_exists($route_type, $this->config->routes)) return []; if ( ! array_key_exists($route_type, $this->routes)) return [];
$applied_routes = array_merge($this->config->routes[$route_type], $this->config->routes['common']); $applied_routes = array_merge($this->routes[$route_type], $this->routes['common']);
// Add routes // Add routes
foreach($applied_routes as $name => &$route) foreach($applied_routes as $name => &$route)

52
src/Base/RoutingBase.php Normal file
View File

@ -0,0 +1,52 @@
<?php
namespace AnimeClient\Base;
class RoutingBase {
/**
* Injection Container
* @var Container $container
*/
protected $container;
/**
* Config Object
* @var Config
*/
protected $config;
/**
* Routing array
* @var array
*/
protected $routes;
/**
* Constructor
*
* @param Container $container
*/
public function __construct(Container $container)
{
$this->container = $container;
$this->config = $container->get('config');
$this->routes = $this->config->__get('routes');
}
/**
* Retreive the appropriate value for the routing key
*
* @param string $key
* @return mixed
*/
public function __get($key)
{
$routing_config = $this->config->routing;
if (array_key_exists($key, $routing_config))
{
return $routing_config[$key];
}
}
}
// End of RoutingBase.php

View File

@ -5,44 +5,7 @@ namespace AnimeClient\Base;
/** /**
* UrlGenerator class. * UrlGenerator class.
*/ */
class UrlGenerator { class UrlGenerator extends RoutingBase {
/**
* Config Object
* @var Config
*/
protected $config;
/**
* Constructor
*
* @param Container $container
*/
public function __construct(Container $container)
{
$this->config = $container->get('config');
}
/**
* Retreive the appropriate value for the routing key
*
* @param string $key
* @return mixed
*/
protected function __get($key)
{
$routing_config = $this->config->__get('routing');
if (array_key_exists($key, $routing_config))
{
return $routing_config[$key];
}
}
public function __invoke()
{
$args = func_get_args();
}
/** /**
* Get the base url for css/js/images * Get the base url for css/js/images
@ -52,7 +15,9 @@ class UrlGenerator {
public function asset_url(/*...*/) public function asset_url(/*...*/)
{ {
$args = func_get_args(); $args = func_get_args();
$base_url = rtrim($this->__get('asset_path'), '/'); $base_url = rtrim($this->url(""), '/');
$base_url = "{$base_url}" . $this->__get("asset_path");
array_unshift($args, $base_url); array_unshift($args, $base_url);
@ -95,6 +60,12 @@ class UrlGenerator {
return "//{$host}/{$path}"; return "//{$host}/{$path}";
} }
/**
* Full default path for the list pages
*
* @param string $type
* @return string
*/
public function default_url($type) public function default_url($type)
{ {
$type = trim($type); $type = trim($type);

View File

@ -64,13 +64,13 @@ class Anime extends BaseController {
$this->model = new AnimeModel($container); $this->model = new AnimeModel($container);
$this->collection_model = new AnimeCollectionModel($container); $this->collection_model = new AnimeCollectionModel($container);
$this->base_data = [ $this->base_data = array_merge($this->base_data, [
'message' => '', 'message' => '',
'url_type' => 'anime', 'url_type' => 'anime',
'other_type' => 'manga', 'other_type' => 'manga',
'nav_routes' => $this->nav_routes, 'nav_routes' => $this->nav_routes,
'config' => $this->config, 'config' => $this->config,
]; ]);
} }
/** /**
@ -108,82 +108,6 @@ class Anime extends BaseController {
]); ]);
} }
/**
* Show the anime collection page
*
* @return void
*/
public function collection($view)
{
$view_map = [
'' => 'collection',
'list' => 'collection_list'
];
$data = $this->collection_model->get_collection();
$this->outputHTML('anime/' . $view_map[$view], [
'title' => WHOSE . " Anime Collection",
'sections' => $data,
'genres' => $this->collection_model->get_genre_list()
]);
}
/**
* Show the anime collection add/edit form
*
* @param int $id
* @return void
*/
public function collection_form($id=NULL)
{
$action = (is_null($id)) ? "Add" : "Edit";
$this->outputHTML('anime/collection_' . strtolower($action), [
'action' => $action,
'action_url' => $this->config->full_url("collection/" . strtolower($action)),
'title' => WHOSE . " Anime Collection &middot; {$action}",
'media_items' => $this->collection_model->get_media_type_list(),
'item' => ($action === "Edit") ? $this->collection_model->get($id) : []
]);
}
/**
* Update a collection item
*
* @return void
*/
public function collection_edit()
{
$data = $this->request->post->get();
if ( ! array_key_exists('hummingbird_id', $data))
{
$this->redirect("collection/view", 303, "anime");
}
$this->collection_model->update($data);
$this->redirect("collection/view", 303, "anime");
}
/**
* Add a collection item
*
* @return void
*/
public function collection_add()
{
$data = $this->request->post->get();
if ( ! array_key_exists('id', $data))
{
$this->redirect("collection/view", 303, "anime");
}
$this->collection_model->add($data);
$this->redirect("collection/view", 303, "anime");
}
/** /**
* Update an anime item * Update an anime item
* *

View File

@ -54,14 +54,14 @@ class Collection extends BaseController {
unset($this->nav_routes['Collection']); unset($this->nav_routes['Collection']);
} }
$this->collection_model = new AnimeCollectionModel($this->config); $this->collection_model = new AnimeCollectionModel($container);
$this->base_data = [ $this->base_data = array_merge($this->base_data, [
'message' => '', 'message' => '',
'url_type' => 'anime', 'url_type' => 'anime',
'other_type' => 'manga', 'other_type' => 'manga',
'nav_routes' => $this->nav_routes, 'nav_routes' => $this->nav_routes,
'config' => $this->config, 'config' => $this->config,
]; ]);
} }
/** /**

View File

@ -48,12 +48,12 @@ class Manga extends Controller {
parent::__construct($container); parent::__construct($container);
$config = $container->get('config'); $config = $container->get('config');
$this->model = new MangaModel($container); $this->model = new MangaModel($container);
$this->base_data = [ $this->base_data = array_merge($this->base_data, [
'config' => $this->config, 'config' => $this->config,
'url_type' => 'manga', 'url_type' => 'manga',
'other_type' => 'anime', 'other_type' => 'anime',
'nav_routes' => $this->nav_routes 'nav_routes' => $this->nav_routes
]; ]);
} }
/** /**

View File

@ -11,7 +11,7 @@
<section class="media-wrap"> <section class="media-wrap">
<?php foreach($items as $item): ?> <?php foreach($items as $item): ?>
<article class="media" id="a-<?= $item['hummingbird_id'] ?>"> <article class="media" id="a-<?= $item['hummingbird_id'] ?>">
<img src="<?= $config->asset_url('images', 'anime', basename($item['cover_image'])) ?>" /> <img src="<?= $urlGenerator->asset_url('images', 'anime', basename($item['cover_image'])) ?>" />
<div class="name"> <div class="name">
<a href="https://hummingbird.me/anime/<?= $item['slug'] ?>"> <a href="https://hummingbird.me/anime/<?= $item['slug'] ?>">
<?= $item['title'] ?> <?= $item['title'] ?>
@ -28,7 +28,7 @@
</article> </article>
<?php if (is_logged_in()): ?> <?php if (is_logged_in()): ?>
<span>[<a href="<?= $config->full_url("collection/edit/{$item['hummingbird_id']}", "anime") ?>">Edit</a>]</span> <span>[<a href="<?= $urlGenerator->full_url("collection/edit/{$item['hummingbird_id']}", "anime") ?>">Edit</a>]</span>
<?php endif ?> <?php endif ?>
<?php endforeach ?> <?php endforeach ?>
</section> </section>

View File

@ -3,24 +3,24 @@
<head> <head>
<title><?= $title ?></title> <title><?= $title ?></title>
<meta charset="utf-8" /> <meta charset="utf-8" />
<link rel="stylesheet" href="<?= $config->asset_url('css.php?g=base') ?>" /> <link rel="stylesheet" href="<?= $urlGenerator->asset_url('css.php?g=base') ?>" />
<script> <script>
var BASE_URL = "<?= $config->base_url($url_type) ?>"; var BASE_URL = "<?= $urlGenerator->base_url($url_type) ?>";
var CONTROLLER = "<?= $url_type ?>"; var CONTROLLER = "<?= $url_type ?>";
</script> </script>
</head> </head>
<body class="<?= $url_type ?> list"> <body class="<?= $url_type ?> list">
<h1 class="flex flex-align-end flex-wrap"> <h1 class="flex flex-align-end flex-wrap">
<span class="flex-no-wrap grow-1"> <span class="flex-no-wrap grow-1">
<a href="<?= $config->default_url($url_type) ?>"> <a href="<?= $urlGenerator->default_url($url_type) ?>">
<?= WHOSE ?> <?= ucfirst($url_type) ?> <?= (strpos($route_path, 'collection') !== FALSE) ? 'Collection' : 'List' ?> <?= WHOSE ?> <?= ucfirst($url_type) ?> <?= (strpos($route_path, 'collection') !== FALSE) ? 'Collection' : 'List' ?>
</a> [<a href="<?= $config->default_url($other_type) ?>"><?= ucfirst($other_type) ?> List</a>] </a> [<a href="<?= $urlGenerator->default_url($other_type) ?>"><?= ucfirst($other_type) ?> List</a>]
</span> </span>
<span class="flex-no-wrap small-font"> <span class="flex-no-wrap small-font">
<?php if (is_logged_in()): ?> <?php if (is_logged_in()): ?>
[<a href="<?= $config->full_url("/logout", $url_type) ?>">Logout</a>] [<a href="<?= $urlGenerator->full_url("/logout", $url_type) ?>">Logout</a>]
<?php else: ?> <?php else: ?>
[<a href="<?= $config->full_url("/login", $url_type) ?>"><?= WHOSE ?> Login</a>] [<a href="<?= $urlGenerator->full_url("/login", $url_type) ?>"><?= WHOSE ?> Login</a>]
<?php endif ?> <?php endif ?>
</span> </span>
</h1> </h1>
@ -28,14 +28,14 @@
<nav> <nav>
<ul> <ul>
<?php foreach($nav_routes as $title => $nav_path): ?> <?php foreach($nav_routes as $title => $nav_path): ?>
<li class="<?= is_selected($nav_path, $route_path) ?>"><a href="<?= $config->url($nav_path) ?>"><?= $title ?></a></li> <li class="<?= is_selected($nav_path, $route_path) ?>"><a href="<?= $urlGenerator->url($nav_path) ?>"><?= $title ?></a></li>
<?php endforeach ?> <?php endforeach ?>
</ul> </ul>
<?php if (is_view_page()): ?> <?php if (is_view_page()): ?>
<br /> <br />
<ul> <ul>
<li class="<?= is_not_selected('list', last_segment()) ?>"><a href="<?= $config->url($route_path) ?>">Cover View</a></li> <li class="<?= is_not_selected('list', last_segment()) ?>"><a href="<?= $urlGenerator->url($route_path) ?>">Cover View</a></li>
<li class="<?= is_selected('list', last_segment()) ?>"><a href="<?= $config->url("{$route_path}/list") ?>">List View</a></li> <li class="<?= is_selected('list', last_segment()) ?>"><a href="<?= $urlGenerator->url("{$route_path}/list") ?>">List View</a></li>
</ul> </ul>
<?php endif ?> <?php endif ?>
</nav> </nav>

View File

@ -8,7 +8,7 @@ class ConfigTest extends AnimeClient_TestCase {
{ {
$this->config = new Config([ $this->config = new Config([
'foo' => 'bar', 'foo' => 'bar',
'asset_path' => '//localhost/assets/', 'asset_path' => '/assets',
'bar' => 'baz' 'bar' => 'baz'
]); ]);
} }
@ -24,118 +24,4 @@ class ConfigTest extends AnimeClient_TestCase {
{ {
$this->assertEquals(NULL, $this->config->foobar); $this->assertEquals(NULL, $this->config->foobar);
} }
public function assetUrlProvider()
{
return [
'single argument' => [
'args' => [
'images'
],
'expected' => '//localhost/assets/images',
],
'multiple arguments' => [
'args' => [
'images', 'anime', 'foo.png'
],
'expected' => '//localhost/assets/images/anime/foo.png'
]
];
}
/**
* @dataProvider assetUrlProvider
*/
public function testAssetUrl($args, $expected)
{
$result = call_user_func_array([$this->config, 'asset_url'], $args);
$this->assertEquals($expected, $result);
}
public function dataFullUrl()
{
return [
'default_view' => [
'config' => [
'routing' => [
'anime_path' => 'anime',
'manga_path' => 'manga',
'default_list' => 'manga',
'default_anime_path' => '/anime/watching',
'default_manga_path' => '/manga/all',
'default_to_list_view' => FALSE,
],
],
'path' => '',
'type' => 'manga',
'expected' => '//localhost/manga/all',
],
'default_view_list' => [
'config' => [
'routing' => [
'anime_path' => 'anime',
'manga_path' => 'manga',
'default_list' => 'manga',
'default_anime_path' => '/anime/watching',
'default_manga_path' => '/manga/all',
'default_to_list_view' => TRUE,
],
],
'path' => '',
'type' => 'manga',
'expected' => '//localhost/manga/all/list',
]
];
}
/**
* @dataProvider dataFullUrl
*/
public function testFullUrl($config, $path, $type, $expected)
{
$this->config = new Config($config);
$result = $this->config->full_url($path, $type);
$this->assertEquals($expected, $result);
}
public function dataBaseUrl()
{
$config = [
'routing' => [
'anime_path' => 'anime',
'manga_path' => 'manga',
'default_list' => 'manga',
'default_anime_path' => '/watching',
'default_manga_path' => '/all',
'default_to_list_view' => TRUE,
],
];
return [
'path_based_routing_anime' => [
'config' => $config,
'type' => 'anime',
'expected' => '//localhost/anime'
],
'path_based_routing_manga' => [
'config' => $config,
'type' => 'manga',
'expected' => '//localhost/manga'
]
];
}
/**
* @dataProvider dataBaseUrl
*/
public function testBaseUrl($config, $type, $expected)
{
$this->config = new Config($config);
$result = $this->config->base_url($type);
$this->assertEquals($expected, $result);
}
} }

View File

@ -3,6 +3,7 @@
use AnimeClient\Base\Router; use AnimeClient\Base\Router;
use AnimeClient\Base\Config; use AnimeClient\Base\Config;
use AnimeClient\Base\Container; use AnimeClient\Base\Container;
use AnimeClient\Base\UrlGenerator;
use Aura\Web\WebFactory; use Aura\Web\WebFactory;
use Aura\Router\RouterFactory; use Aura\Router\RouterFactory;
@ -43,6 +44,8 @@ class RouterTest extends AnimeClient_TestCase {
$this->router = new Router($this->container); $this->router = new Router($this->container);
$this->config = $this->container->get('config'); $this->config = $this->container->get('config');
$this->urlGenerator = new UrlGenerator($this->container);
$this->container->set('url-generator', $this->urlGenerator);
} }
public function testRouterSanity() public function testRouterSanity()
@ -54,6 +57,41 @@ class RouterTest extends AnimeClient_TestCase {
public function dataRoute() public function dataRoute()
{ {
$default_config = array( $default_config = array(
'routes' => [
'common' => [
'login_form' => [
'path' => '/login',
'action' => ['login'],
'verb' => 'get'
],
],
'anime' => [
'watching' => [
'path' => '/anime/watching{/view}',
'action' => ['anime_list'],
'params' => [
'type' => 'currently-watching',
'title' => WHOSE . " Anime List &middot; Watching"
],
'tokens' => [
'view' => '[a-z_]+'
]
],
],
'manga' => [
'plan_to_read' => [
'path' => '/manga/plan_to_read{/view}',
'action' => ['manga_list'],
'params' => [
'type' => 'Plan to Read',
'title' => WHOSE . " Manga List &middot; Plan to Read"
],
'tokens' => [
'view' => '[a-z_]+'
]
],
]
],
'routing' => [ 'routing' => [
'anime_path' => 'anime', 'anime_path' => 'anime',
'manga_path' => 'manga', 'manga_path' => 'manga',
@ -62,21 +100,34 @@ class RouterTest extends AnimeClient_TestCase {
); );
$data = [ $data = [
'manga_path_routing' => array( 'anime_default_routing_manga' => array(
'config' => $default_config, 'config' => $default_config,
'type' => 'manga', 'controller' => 'manga',
'host' => "localhost", 'host' => "localhost",
'uri' => "/manga/plan_to_read", 'uri' => "/manga/plan_to_read",
), ),
'anime_path_routing' => array( 'manga_default_routing_anime' => array(
'config' => $default_config, 'config' => $default_config,
'type' => 'anime', 'controller' => 'anime',
'host' => "localhost", 'host' => "localhost",
'uri' => "/anime/watching", 'uri' => "/anime/watching",
),
'anime_default_routing_anime' => array(
'config' => $default_config,
'controller' => 'anime',
'host' => 'localhost',
'uri' => '/anime/watching',
),
'manga_default_routing_manga' => array(
'config' => $default_config,
'controller' => 'manga',
'host' => 'localhost',
'uri' => '/manga/plan_to_read'
) )
]; ];
$data['anime_path_routing']['config']['routing']['default_list'] = 'manga'; $data['manga_default_routing_anime']['config']['routing']['default_list'] = 'manga';
$data['manga_default_routing_manga']['config']['routing']['default_list'] = 'manga';
return $data; return $data;
} }
@ -84,52 +135,16 @@ class RouterTest extends AnimeClient_TestCase {
/** /**
* @dataProvider dataRoute * @dataProvider dataRoute
*/ */
public function testRoute($config, $type, $host, $uri) public function testRoute($config, $controller, $host, $uri)
{ {
$check_var = "{$type}_path";
$config['base_config']['routes'] = [
'common' => [
'login_form' => [
'path' => '/login',
'action' => ['login'],
'verb' => 'get'
],
],
'anime' => [
'watching' => [
'path' => '/anime/watching{/view}',
'action' => ['anime_list'],
'params' => [
'type' => 'currently-watching',
'title' => WHOSE . " Anime List &middot; Watching"
],
'tokens' => [
'view' => '[a-z_]+'
]
],
],
'manga' => [
'plan_to_read' => [
'path' => '/manga/plan_to_read{/view}',
'action' => ['manga_list'],
'params' => [
'type' => 'Plan to Read',
'title' => WHOSE . " Manga List &middot; Plan to Read"
],
'tokens' => [
'view' => '[a-z_]+'
]
],
]
];
$this->_set_up($config, $uri, $host); $this->_set_up($config, $uri, $host);
$request = $this->container->get('request'); $request = $this->container->get('request');
$aura_router = $this->container->get('aura-router'); $aura_router = $this->container->get('aura-router');
// Check route setup // Check route setup
$this->assertEquals($config['base_config']['routes'], $this->config->routes, "Incorrect route path"); $this->assertEquals($config['routes'], $this->config->routes, "Incorrect route path");
$this->assertTrue(is_array($this->router->get_output_routes())); $this->assertTrue(is_array($this->router->get_output_routes()));
// Check environment variables // Check environment variables
@ -138,8 +153,7 @@ class RouterTest extends AnimeClient_TestCase {
// Make sure the route is an anime type // Make sure the route is an anime type
$this->assertTrue($aura_router->count() > 0, "0 routes"); $this->assertTrue($aura_router->count() > 0, "0 routes");
$this->assertTrue($this->config->$check_var !== '', "Check variable is empty"); $this->assertEquals($controller, $this->router->get_controller(), "Incorrect Route type");
$this->assertEquals($type, $this->router->get_controller(), "Incorrect Route type");
// Make sure the route matches, by checking that it is actually an object // Make sure the route matches, by checking that it is actually an object
$route = $this->router->get_route(); $route = $this->router->get_route();
@ -152,6 +166,8 @@ class RouterTest extends AnimeClient_TestCase {
'routing' => [ 'routing' => [
'anime_path' => 'anime', 'anime_path' => 'anime',
'manga_path' => 'manga', 'manga_path' => 'manga',
'default_anime_path' => "/anime/watching",
'default_manga_path' => '/manga/all',
'default_list' => 'manga' 'default_list' => 'manga'
], ],
'routes' => [ 'routes' => [
@ -187,7 +203,7 @@ class RouterTest extends AnimeClient_TestCase {
]; ];
$this->_set_up($config, "/", "localhost"); $this->_set_up($config, "/", "localhost");
//$this->assertEquals($this->config->full_url('', 'manga'), $this->response->headers->get('location')); $this->assertEquals('//localhost/manga/all', $this->urlGenerator->default_url('manga'), "Incorrect default url");
$this->assertEquals('//localhost/manga/', $this->config->full_url('', 'manga'), "Incorrect default url"); $this->assertEquals('//localhost/anime/watching', $this->urlGenerator->default_url('anime'), "Incorrect default url");
} }
} }

View File

@ -0,0 +1,144 @@
<?php
use AnimeClient\Base\Config;
use AnimeClient\Base\Container;
use AnimeClient\Base\UrlGenerator;
class UrlGeneratorTest extends AnimeClient_TestCase {
public function setUp()
{
$this->container = new Container([
'config' => new Config([
'foo' => 'bar',
'routing' => [
'asset_path' => '/assets',
],
'bar' => 'baz'
])
]);
$this->config = $this->container->get('config');
}
public function assetUrlProvider()
{
return [
'single argument' => [
'args' => [
'images'
],
'expected' => '//localhost/assets/images',
],
'multiple arguments' => [
'args' => [
'images', 'anime', 'foo.png'
],
'expected' => '//localhost/assets/images/anime/foo.png'
]
];
}
/**
* @dataProvider assetUrlProvider
*/
public function testAssetUrl($args, $expected)
{
$urlGenerator = new UrlGenerator($this->container);
$result = call_user_func_array([$urlGenerator, 'asset_url'], $args);
$this->assertEquals($expected, $result);
}
public function dataFullUrl()
{
return [
'default_view' => [
'config' => [
'routing' => [
'anime_path' => 'anime',
'manga_path' => 'manga',
'default_list' => 'manga',
'default_anime_path' => '/anime/watching',
'default_manga_path' => '/manga/all',
'default_to_list_view' => FALSE,
],
],
'path' => '',
'type' => 'manga',
'expected' => '//localhost/manga/all',
],
'default_view_list' => [
'config' => [
'routing' => [
'anime_path' => 'anime',
'manga_path' => 'manga',
'default_list' => 'manga',
'default_anime_path' => '/anime/watching',
'default_manga_path' => '/manga/all',
'default_to_list_view' => TRUE,
],
],
'path' => '',
'type' => 'manga',
'expected' => '//localhost/manga/all/list',
]
];
}
/**
* @dataProvider dataFullUrl
*/
public function testFullUrl($config, $path, $type, $expected)
{
$config = new Config($config);
$this->container->set('config', $config);
$urlGenerator = new UrlGenerator($this->container);
$result = $urlGenerator->full_url($path, $type);
$this->assertEquals($expected, $result);
}
public function dataBaseUrl()
{
$config = [
'routing' => [
'anime_path' => 'anime',
'manga_path' => 'manga',
'default_list' => 'manga',
'default_anime_path' => '/watching',
'default_manga_path' => '/all',
'default_to_list_view' => TRUE,
],
];
return [
'path_based_routing_anime' => [
'config' => $config,
'type' => 'anime',
'expected' => '//localhost/anime'
],
'path_based_routing_manga' => [
'config' => $config,
'type' => 'manga',
'expected' => '//localhost/manga'
]
];
}
/**
* @dataProvider dataBaseUrl
*/
public function testBaseUrl($config, $type, $expected)
{
$config = new Config($config);
$this->container->set('config', $config);
$urlGenerator = new UrlGenerator($this->container);
$result = $urlGenerator->base_url($type);
$this->assertEquals($expected, $result);
}
}