Version 5.1 - All the GraphQL #32
@ -54,19 +54,21 @@ final class FormGenerator {
|
||||
public function generate(string $name, array $form): string
|
||||
{
|
||||
$type = $form['type'];
|
||||
$display = $form['display'] ?? TRUE;
|
||||
$value = $form['value'] ?? '';
|
||||
|
||||
if ($form['display'] === FALSE)
|
||||
if ($display === FALSE)
|
||||
{
|
||||
return $this->helper->input([
|
||||
'type' => 'hidden',
|
||||
'name' => $name,
|
||||
'value' => $form['value'],
|
||||
'value' => $value,
|
||||
]);
|
||||
}
|
||||
|
||||
$params = [
|
||||
'name' => $name,
|
||||
'value' => $form['value'],
|
||||
'value' => $value,
|
||||
'attribs' => [
|
||||
'id' => $name,
|
||||
],
|
||||
@ -95,7 +97,7 @@ final class FormGenerator {
|
||||
|
||||
foreach (['readonly', 'disabled'] as $key)
|
||||
{
|
||||
if ($form[$key] !== FALSE)
|
||||
if (array_key_exists($key, $form) && $form[$key] !== FALSE)
|
||||
{
|
||||
$params['attribs'][$key] = $form[$key];
|
||||
}
|
||||
|
275
tests/AnimeClient/FormGeneratorTest.php
Normal file
275
tests/AnimeClient/FormGeneratorTest.php
Normal file
@ -0,0 +1,275 @@
|
||||
<?php declare(strict_types=1);
|
||||
/**
|
||||
* Hummingbird Anime List Client
|
||||
*
|
||||
* An API client for Kitsu to manage anime and manga watch lists
|
||||
*
|
||||
* PHP version 7.3
|
||||
*
|
||||
* @package HummingbirdAnimeClient
|
||||
* @author Timothy J. Warren <tim@timshomepage.net>
|
||||
* @copyright 2015 - 2020 Timothy J. Warren
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
* @version 4.2
|
||||
* @link https://git.timshomepage.net/timw4mail/HummingBirdAnimeClient
|
||||
*/
|
||||
|
||||
namespace Aviat\AnimeClient\Tests;
|
||||
|
||||
use Aviat\AnimeClient\FormGenerator;
|
||||
|
||||
/**
|
||||
* Map config settings to form fields
|
||||
*/
|
||||
const SETTINGS_MAP = [
|
||||
'anilist' => [
|
||||
'enabled' => [
|
||||
'type' => 'boolean',
|
||||
'title' => 'Enable Anilist Integration',
|
||||
'default' => FALSE,
|
||||
'description' => 'Enable syncing data between Kitsu and Anilist. Requires appropriate API keys to be set in config',
|
||||
],
|
||||
'client_id' => [
|
||||
'type' => 'string',
|
||||
'title' => 'Anilist API Client ID',
|
||||
'default' => '',
|
||||
'description' => 'The client id for your Anilist API application',
|
||||
],
|
||||
'client_secret' => [
|
||||
'type' => 'string',
|
||||
'title' => 'Anilist API Client Secret',
|
||||
'default' => '',
|
||||
'description' => 'The client secret for your Anilist API application',
|
||||
],
|
||||
'username' => [
|
||||
'type' => 'string',
|
||||
'title' => 'Anilist Username',
|
||||
'default' => '',
|
||||
'description' => 'Login username for Anilist account to integrate with',
|
||||
],
|
||||
'access_token' => [
|
||||
'type' => 'hidden',
|
||||
'title' => 'API Access Token',
|
||||
'default' => '',
|
||||
'description' => 'The Access code for accessing the Anilist API',
|
||||
'readonly' => TRUE,
|
||||
],
|
||||
'access_token_expires' => [
|
||||
'type' => 'string',
|
||||
'title' => 'Expiration timestamp of the access token',
|
||||
'default' => '0',
|
||||
'description' => 'The unix timestamp of when the access token expires.',
|
||||
'readonly' => TRUE,
|
||||
],
|
||||
'refresh_token' => [
|
||||
'type' => 'string',
|
||||
'title' => 'API Refresh Token',
|
||||
'default' => '',
|
||||
'description' => 'Token to refresh the access token before it expires',
|
||||
'readonly' => TRUE,
|
||||
],
|
||||
],
|
||||
|
||||
'cache' => [
|
||||
'driver' => [
|
||||
'type' => 'select',
|
||||
'title' => 'Cache Type',
|
||||
'description' => 'The Cache backend',
|
||||
'options' => [
|
||||
'APCu' => 'apcu',
|
||||
'Memcached' => 'memcached',
|
||||
'Redis' => 'redis',
|
||||
'No Cache' => 'null'
|
||||
],
|
||||
],
|
||||
'connection' => [
|
||||
'type' => 'subfield',
|
||||
'title' => 'Connection',
|
||||
'fields' => [
|
||||
'host' => [
|
||||
'type' => 'string',
|
||||
'title' => 'Cache Host',
|
||||
'description' => 'Host of the cache backend to connect to',
|
||||
],
|
||||
'port' => [
|
||||
'type' => 'string',
|
||||
'title' => 'Cache Port',
|
||||
'description' => 'Port of the cache backend to connect to',
|
||||
'default' => NULL,
|
||||
],
|
||||
'password' => [
|
||||
'type' => 'string',
|
||||
'title' => 'Cache Password',
|
||||
'description' => 'Password to connect to cache backend',
|
||||
'default' => NULL,
|
||||
],
|
||||
'persistent' => [
|
||||
'type' => 'boolean',
|
||||
'title' => 'Persistent Cache Connection',
|
||||
'description' => 'Whether to have a persistent connection to the cache',
|
||||
'default' => FALSE,
|
||||
],
|
||||
'database' => [
|
||||
'type' => 'string',
|
||||
'title' => 'Cache Database',
|
||||
'default' => '1',
|
||||
'description' => 'Cache database number for Redis',
|
||||
],
|
||||
],
|
||||
],
|
||||
/* 'options' => [
|
||||
'type' => 'subfield',
|
||||
'title' => 'Options',
|
||||
'fields' => [],
|
||||
] */
|
||||
],
|
||||
'config' => [
|
||||
'kitsu_username' => [
|
||||
'type' => 'string',
|
||||
'title' => 'Kitsu Username',
|
||||
'default' => '',
|
||||
'description' => 'Username of the account to pull list data from.',
|
||||
],
|
||||
'whose_list' => [
|
||||
'type' => 'string',
|
||||
'title' => 'Whose List',
|
||||
'default' => 'Somebody',
|
||||
'description' => 'Name of the owner of the list data.',
|
||||
],
|
||||
'theme' => [
|
||||
'type' => 'select',
|
||||
'title' => 'Theme',
|
||||
'default' => 'auto',
|
||||
'description' => 'Which color scheme to use?',
|
||||
'options' => [
|
||||
'Automatically match OS theme' => 'auto',
|
||||
'Original Light Theme' => 'light',
|
||||
'Dark Theme' => 'dark',
|
||||
]
|
||||
],
|
||||
'show_anime_collection' => [
|
||||
'type' => 'boolean',
|
||||
'title' => 'Show Anime Collection',
|
||||
'default' => FALSE,
|
||||
'description' => 'Should the anime collection be shown?',
|
||||
],
|
||||
'show_manga_collection' => [
|
||||
'type' => 'boolean',
|
||||
'title' => 'Show Manga Collection',
|
||||
'default' => FALSE,
|
||||
'description' => 'Should the manga collection be shown?',
|
||||
],
|
||||
'default_list' => [
|
||||
'type' => 'select',
|
||||
'title' => 'Default List',
|
||||
'description' => 'Which list to show by default.',
|
||||
'options' => [
|
||||
'Anime' => 'anime',
|
||||
'Manga' => 'manga',
|
||||
],
|
||||
],
|
||||
'default_anime_list_path' => [ //watching|plan_to_watch|on_hold|dropped|completed|all
|
||||
'type' => 'select',
|
||||
'title' => 'Default Anime List Section',
|
||||
'description' => 'Which part of the anime list to show by default.',
|
||||
'options' => [
|
||||
'Watching' => 'watching',
|
||||
'Plan to Watch' => 'plan_to_watch',
|
||||
'On Hold' => 'on_hold',
|
||||
'Dropped' => 'dropped',
|
||||
'Completed' => 'completed',
|
||||
'All' => 'all',
|
||||
]
|
||||
],
|
||||
'default_manga_list_path' => [ //reading|plan_to_read|on_hold|dropped|completed|all
|
||||
'type' => 'select',
|
||||
'title' => 'Default Manga List Section',
|
||||
'description' => 'Which part of the manga list to show by default.',
|
||||
'options' => [
|
||||
'Reading' => 'reading',
|
||||
'Plan to Read' => 'plan_to_read',
|
||||
'On Hold' => 'on_hold',
|
||||
'Dropped' => 'dropped',
|
||||
'Completed' => 'completed',
|
||||
'All' => 'all',
|
||||
]
|
||||
]
|
||||
],
|
||||
'database' => [
|
||||
'type' => [
|
||||
'type' => 'select',
|
||||
'title' => 'Database Type',
|
||||
'options' => [
|
||||
'MySQL' => 'mysql',
|
||||
'PostgreSQL' => 'pgsql',
|
||||
'SQLite' => 'sqlite',
|
||||
],
|
||||
'default' => 'sqlite',
|
||||
'description' => 'Type of database to connect to',
|
||||
],
|
||||
'host' => [
|
||||
'type' => 'string',
|
||||
'title' => 'Host',
|
||||
'description' => 'The host of the database server',
|
||||
],
|
||||
'user' => [
|
||||
'type' => 'string',
|
||||
'title' => 'User',
|
||||
'description' => 'Database connection user',
|
||||
],
|
||||
'pass' => [
|
||||
'type' => 'string',
|
||||
'title' => 'Password',
|
||||
'description' => 'Database connection password'
|
||||
],
|
||||
'port' => [
|
||||
'type' => 'string',
|
||||
'title' => 'Port',
|
||||
'description' => 'Database connection port',
|
||||
'default' => NULL,
|
||||
],
|
||||
'database' => [
|
||||
'type' => 'string',
|
||||
'title' => 'Database Name',
|
||||
'description' => 'Name of the database/schema to connect to',
|
||||
],
|
||||
'file' => [
|
||||
'type' => 'string',
|
||||
'title' => 'Database File',
|
||||
'description' => 'Path to the database file, if required by the current database type.',
|
||||
'default' => 'anime_collection.sqlite',
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
|
||||
class FormGeneratorTest extends AnimeClientTestCase {
|
||||
protected $generator;
|
||||
|
||||
public function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->generator = new FormGenerator($this->container);
|
||||
}
|
||||
|
||||
public function testSanity(): void
|
||||
{
|
||||
$generator = new FormGenerator($this->container);
|
||||
$this->assertInstanceOf(FormGenerator::class, $generator);
|
||||
}
|
||||
|
||||
public function testGeneration(): void
|
||||
{
|
||||
// $html = $this->generator->generate('database', SETTINGS_MAP);
|
||||
// $this->assertMatchesHtmlSnapshot($html);
|
||||
foreach (SETTINGS_MAP as $section => $fields)
|
||||
{
|
||||
foreach ($fields as $name => $config)
|
||||
{
|
||||
$html = $this->generator->generate($name, $config);
|
||||
$this->assertMatchesHtmlSnapshot($html);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
|
||||
<html><body>
|
||||
<label><input type="radio" name="enabled" value="1"> Yes</label>
|
||||
<label><input type="radio" name="enabled" value="0" checked> No</label>
|
||||
</body></html>
|
@ -0,0 +1,4 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
|
||||
<html><body>
|
||||
<input id="kitsu_username" type="text" name="kitsu_username" value="">
|
||||
</body></html>
|
@ -0,0 +1,4 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
|
||||
<html><body>
|
||||
<input id="whose_list" type="text" name="whose_list" value="">
|
||||
</body></html>
|
@ -0,0 +1,8 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
|
||||
<html><body>
|
||||
<select id="theme" name="theme">
|
||||
<option value="auto">Automatically match OS theme</option>
|
||||
<option value="light">Original Light Theme</option>
|
||||
<option value="dark">Dark Theme</option>
|
||||
</select>
|
||||
</body></html>
|
@ -0,0 +1,5 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
|
||||
<html><body>
|
||||
<label><input type="radio" name="show_anime_collection" value="1"> Yes</label>
|
||||
<label><input type="radio" name="show_anime_collection" value="0" checked> No</label>
|
||||
</body></html>
|
@ -0,0 +1,5 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
|
||||
<html><body>
|
||||
<label><input type="radio" name="show_manga_collection" value="1"> Yes</label>
|
||||
<label><input type="radio" name="show_manga_collection" value="0" checked> No</label>
|
||||
</body></html>
|
@ -0,0 +1,7 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
|
||||
<html><body>
|
||||
<select id="default_list" name="default_list">
|
||||
<option value="anime">Anime</option>
|
||||
<option value="manga">Manga</option>
|
||||
</select>
|
||||
</body></html>
|
@ -0,0 +1,11 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
|
||||
<html><body>
|
||||
<select id="default_anime_list_path" name="default_anime_list_path">
|
||||
<option value="watching">Watching</option>
|
||||
<option value="plan_to_watch">Plan to Watch</option>
|
||||
<option value="on_hold">On Hold</option>
|
||||
<option value="dropped">Dropped</option>
|
||||
<option value="completed">Completed</option>
|
||||
<option value="all">All</option>
|
||||
</select>
|
||||
</body></html>
|
@ -0,0 +1,11 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
|
||||
<html><body>
|
||||
<select id="default_manga_list_path" name="default_manga_list_path">
|
||||
<option value="reading">Reading</option>
|
||||
<option value="plan_to_read">Plan to Read</option>
|
||||
<option value="on_hold">On Hold</option>
|
||||
<option value="dropped">Dropped</option>
|
||||
<option value="completed">Completed</option>
|
||||
<option value="all">All</option>
|
||||
</select>
|
||||
</body></html>
|
@ -0,0 +1,8 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
|
||||
<html><body>
|
||||
<select id="type" name="type">
|
||||
<option value="mysql">MySQL</option>
|
||||
<option value="pgsql">PostgreSQL</option>
|
||||
<option value="sqlite">SQLite</option>
|
||||
</select>
|
||||
</body></html>
|
@ -0,0 +1,4 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
|
||||
<html><body>
|
||||
<input id="host" type="text" name="host" value="">
|
||||
</body></html>
|
@ -0,0 +1,4 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
|
||||
<html><body>
|
||||
<input id="client_id" type="text" name="client_id" value="">
|
||||
</body></html>
|
@ -0,0 +1,4 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
|
||||
<html><body>
|
||||
<input id="user" type="text" name="user" value="">
|
||||
</body></html>
|
@ -0,0 +1,4 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
|
||||
<html><body>
|
||||
<input id="pass" type="text" name="pass" value="">
|
||||
</body></html>
|
@ -0,0 +1,4 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
|
||||
<html><body>
|
||||
<input id="port" type="text" name="port" value="">
|
||||
</body></html>
|
@ -0,0 +1,4 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
|
||||
<html><body>
|
||||
<input id="database" type="text" name="database" value="">
|
||||
</body></html>
|
@ -0,0 +1,4 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
|
||||
<html><body>
|
||||
<input id="file" type="text" name="file" value="">
|
||||
</body></html>
|
@ -0,0 +1,4 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
|
||||
<html><body>
|
||||
<input id="client_secret" type="text" name="client_secret" value="">
|
||||
</body></html>
|
@ -0,0 +1,4 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
|
||||
<html><body>
|
||||
<input id="username" type="text" name="username" value="">
|
||||
</body></html>
|
@ -0,0 +1,4 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
|
||||
<html><body>
|
||||
<input id="access_token" type="text" name="access_token" readonly value="">
|
||||
</body></html>
|
@ -0,0 +1,4 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
|
||||
<html><body>
|
||||
<input id="access_token_expires" type="text" name="access_token_expires" readonly value="">
|
||||
</body></html>
|
@ -0,0 +1,4 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
|
||||
<html><body>
|
||||
<input id="refresh_token" type="text" name="refresh_token" readonly value="">
|
||||
</body></html>
|
@ -0,0 +1,9 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
|
||||
<html><body>
|
||||
<select id="driver" name="driver">
|
||||
<option value="apcu">APCu</option>
|
||||
<option value="memcached">Memcached</option>
|
||||
<option value="redis">Redis</option>
|
||||
<option value="null">No Cache</option>
|
||||
</select>
|
||||
</body></html>
|
@ -0,0 +1,4 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
|
||||
<html><body>
|
||||
<input id="connection" type="text" name="connection" value="">
|
||||
</body></html>
|
@ -1,41 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Global setup for unit tests
|
||||
*/
|
||||
|
||||
// Work around the silly timezone error
|
||||
$timezone = ini_get('date.timezone');
|
||||
if ($timezone === '' || $timezone === FALSE)
|
||||
{
|
||||
ini_set('date.timezone', 'GMT');
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Autoloading
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
require_once __DIR__ . '/AnimeClientTestCase.php';
|
||||
require_once __DIR__ . '/../vendor/autoload.php';
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Ini Settings
|
||||
// -----------------------------------------------------------------------------
|
||||
ini_set('session.use_cookies', 0);
|
||||
ini_set("session.use_only_cookies", 0);
|
||||
ini_set("session.use_trans_sid", 1);
|
||||
// Start session here to supress error about headers not sent
|
||||
session_start();
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Load base test case and mocks
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// Pre-define some superglobals
|
||||
$_SESSION = [];
|
||||
$_COOKIE = [];
|
||||
|
||||
// Request base test case and mocks
|
||||
require_once __DIR__ . '/TestSessionHandler.php';
|
||||
require_once __DIR__ . '/mocks.php';
|
||||
|
||||
// End of bootstrap.php
|
@ -1,41 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Global setup for unit tests
|
||||
*/
|
||||
|
||||
// Work around the silly timezone error
|
||||
$timezone = ini_get('date.timezone');
|
||||
if ($timezone === '' || $timezone === FALSE)
|
||||
{
|
||||
ini_set('date.timezone', 'GMT');
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Autoloading
|
||||
// -----------------------------------------------------------------------------
|
||||
// Composer autoload
|
||||
require realpath(__DIR__ . '/../vendor/autoload.php');
|
||||
require 'IonTestCase.php';
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Ini Settings
|
||||
// -----------------------------------------------------------------------------
|
||||
ini_set('session.use_cookies', 0);
|
||||
ini_set('session.use_only_cookies',0);
|
||||
ini_set('session.use_trans_sid',1);
|
||||
// Start session here to surpress error about headers not sent
|
||||
session_start();
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Load base test case and mocks
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// Pre-define some superglobals
|
||||
$_SESSION = [];
|
||||
$_COOKIE = [];
|
||||
|
||||
// Request base test case and mocks
|
||||
require 'TestSessionHandler.php';
|
||||
require 'mocks.php';
|
||||
|
||||
// End of bootstrap.php
|
Loading…
Reference in New Issue
Block a user