Version 5.1 - All the GraphQL #32
169
build.xml
169
build.xml
@ -1,169 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project default="full-build" name="animeclient" basedir=".">
|
|
||||||
<autoloader autoloaderpath="${project.basedir}/vendor/autoload.php" />
|
|
||||||
<!-- By default, we assume all tools to be on the $PATH -->
|
|
||||||
<property name="pdepend" value="pdepend" />
|
|
||||||
<property name="phpcpd" value="phpcpd" />
|
|
||||||
<property name="phpdox" value="phpdox" />
|
|
||||||
<property name="phploc" value="phploc" />
|
|
||||||
<property name="phpmd" value="phpmd" />
|
|
||||||
<property name="phpunit" value="phpunit" />
|
|
||||||
<property name="sonar" value="sonar-runner" />
|
|
||||||
|
|
||||||
<target name="full-build"
|
|
||||||
depends="prepare,static-analysis,phpunit,phpdox"
|
|
||||||
description="Performs static analysis, runs the tests, and generates project documentation"
|
|
||||||
/>
|
|
||||||
<target name="quick-build"
|
|
||||||
depends="prepare,lint,phpunit-no-coverage"
|
|
||||||
description="Performs a lint check and runs the tests (without generating code coverage reports)"
|
|
||||||
/>
|
|
||||||
<target name="static-analysis"
|
|
||||||
depends="lint,phploc-ci,pdepend,phpcpd-ci"
|
|
||||||
description="Performs static analysis"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<target name="clean" unless="clean.done" description="Cleanup build artifacts">
|
|
||||||
<delete dir="build/api" />
|
|
||||||
<delete dir="build/coverage" />
|
|
||||||
<delete dir="build/logs" />
|
|
||||||
<delete dir="build/pdepend" />
|
|
||||||
<delete dir="build/phpdox" />
|
|
||||||
<property name="clean.done" value="true" />
|
|
||||||
</target>
|
|
||||||
|
|
||||||
<target name="prepare" depends="clean" unless="prepare.done" description="Prepare for build">
|
|
||||||
<mkdir dir="build/api" />
|
|
||||||
<mkdir dir="build/coverage" />
|
|
||||||
<mkdir dir="build/logs" />
|
|
||||||
<mkdir dir="build/pdepend" />
|
|
||||||
<mkdir dir="build/phpdox" />
|
|
||||||
<property name="prepare.done" value="true" />
|
|
||||||
</target>
|
|
||||||
|
|
||||||
<target name="lint" unless="lint.done" description="Perform syntax check of sourcecode files">
|
|
||||||
<parallel threadcount="6">
|
|
||||||
<apply executable="php" passthru="true" taskname="lint">
|
|
||||||
<arg value="-l" />
|
|
||||||
<fileset dir=".">
|
|
||||||
<include name="src/Aviat/AnimeClient/**/*.php" />
|
|
||||||
</fileset>
|
|
||||||
</apply>
|
|
||||||
<apply executable="php" passthru="true" taskname="lint">
|
|
||||||
<arg value="-l" />
|
|
||||||
<fileset dir=".">
|
|
||||||
<include name="src/Aviat/Ion/**/*.php" />
|
|
||||||
</fileset>
|
|
||||||
</apply>
|
|
||||||
<apply executable="php" passthru="true" taskname="lint">
|
|
||||||
<arg value="-l" />
|
|
||||||
<fileset dir=".">
|
|
||||||
<include name="tests/AnimeClient/**/*.php" />
|
|
||||||
</fileset>
|
|
||||||
</apply>
|
|
||||||
<apply executable="php" passthru="true" taskname="lint">
|
|
||||||
<arg value="-l" />
|
|
||||||
<fileset dir=".">
|
|
||||||
<include name="tests/Ion/**/*.php" />
|
|
||||||
</fileset>
|
|
||||||
</apply>
|
|
||||||
</parallel>
|
|
||||||
|
|
||||||
<property name="lint.done" value="true" />
|
|
||||||
</target>
|
|
||||||
|
|
||||||
<target name="phploc" unless="phploc.done" description="Measure project size using PHPLOC and print human readable output. Intended for usage on the command line.">
|
|
||||||
<exec executable="${phploc}" passthru="true" taskname="phploc">
|
|
||||||
<arg value="--count-tests" />
|
|
||||||
<arg path="src" />
|
|
||||||
<arg path="tests" />
|
|
||||||
</exec>
|
|
||||||
|
|
||||||
<property name="phploc.done" value="true" />
|
|
||||||
</target>
|
|
||||||
|
|
||||||
<target name="phploc-ci" depends="prepare" unless="phploc.done" description="Measure project size using PHPLOC and log result in CSV and XML format. Intended for usage within a continuous integration environment.">
|
|
||||||
<parallel threadcount="2">
|
|
||||||
<phploc countTests="true" reportType="csv" reportDirectory="build/logs" reportName="phploc" taskname="csv report">
|
|
||||||
<fileset dir=".">
|
|
||||||
<include name="src/**/*.php" />
|
|
||||||
<include name="tests/**/*.php" />
|
|
||||||
</fileset>
|
|
||||||
</phploc>
|
|
||||||
<phploc countTests="true" reportType="xml" reportDirectory="build/logs" reportName="phploc" taskname="xml report">
|
|
||||||
<fileset dir=".">
|
|
||||||
<include name="src/**/*.php" />
|
|
||||||
<include name="tests/**/*.php" />
|
|
||||||
</fileset>
|
|
||||||
</phploc>
|
|
||||||
</parallel>
|
|
||||||
|
|
||||||
<property name="phploc.done" value="true" />
|
|
||||||
</target>
|
|
||||||
|
|
||||||
<target name="pdepend" depends="prepare" unless="pdepend.done" description="Calculate software metrics using PHP_Depend and log result in XML format. Intended for usage within a continuous integration environment.">
|
|
||||||
<phpdepend>
|
|
||||||
<fileset dir=".">
|
|
||||||
<include name="src/**/*.php" />
|
|
||||||
</fileset>
|
|
||||||
<logger type="jdepend-xml" outfile="build/logs/jdepend.xml" />
|
|
||||||
<logger type="jdepend-chart" outfile="build/pdepend/dependencies.svg" />
|
|
||||||
<logger type="overview-pyramid" outfile="build/pdepend/overview-pyramid.svg" />
|
|
||||||
</phpdepend>
|
|
||||||
|
|
||||||
<property name="pdepend.done" value="true" />
|
|
||||||
</target>
|
|
||||||
|
|
||||||
<target name="phpcpd" unless="phpcpd.done" description="Find duplicate code using PHPCPD and print human readable output. Intended for usage on the command line before committing.">
|
|
||||||
<phpcpd>
|
|
||||||
<formatter type="default" usefile="false" />
|
|
||||||
<fileset dir=".">
|
|
||||||
<include name="src/**/*.php" />
|
|
||||||
</fileset>
|
|
||||||
</phpcpd>
|
|
||||||
|
|
||||||
<property name="phpcpd.done" value="true" />
|
|
||||||
</target>
|
|
||||||
|
|
||||||
<target name="phpcpd-ci" depends="prepare" unless="phpcpd.done" description="Find duplicate code using PHPCPD and log result in XML format. Intended for usage within a continuous integration environment.">
|
|
||||||
<phpcpd>
|
|
||||||
<formatter type="pmd" outfile="build/logs/pmd-cpd.xml" />
|
|
||||||
<fileset dir=".">
|
|
||||||
<include name="src/**/*.php" />
|
|
||||||
</fileset>
|
|
||||||
</phpcpd>
|
|
||||||
|
|
||||||
<property name="phpcpd.done" value="true" />
|
|
||||||
</target>
|
|
||||||
|
|
||||||
<target name="phpunit" unless="phpunit.done" depends="prepare" description="Run unit tests with PHPUnit">
|
|
||||||
<exec executable="${phpunit}" logoutput="true" passthru="true" checkreturn="true" taskname="phpunit">
|
|
||||||
<arg value="--configuration" />
|
|
||||||
<arg path="build/phpunit.xml" />
|
|
||||||
</exec>
|
|
||||||
|
|
||||||
<property name="phpunit.done" value="true" />
|
|
||||||
</target>
|
|
||||||
|
|
||||||
<target name="phpunit-no-coverage" depends="prepare" unless="phpunit.done" description="Run unit tests with PHPUnit (without generating code coverage reports)">
|
|
||||||
<exec executable="${phpunit}" passthru="true" taskname="phpunit">
|
|
||||||
<arg value="--configuration" />
|
|
||||||
<arg path="build/phpunit.xml" />
|
|
||||||
<arg value="--no-coverage" />
|
|
||||||
</exec>
|
|
||||||
|
|
||||||
<property name="phpunit.done" value="true" />
|
|
||||||
</target>
|
|
||||||
|
|
||||||
<target name="phpdox" depends="phploc-ci,phpunit" unless="phpdox.done" description="Generate project documentation using phpDox">
|
|
||||||
<exec dir="build" executable="${phpdox}" passthru="true" taskname="phpdox" />
|
|
||||||
|
|
||||||
<property name="phpdox.done" value="true" />
|
|
||||||
</target>
|
|
||||||
|
|
||||||
<target name="sonar" depends="phpunit" unless="sonar.done" description="Generate code analysis with sonarqube">
|
|
||||||
<exec executable="${sonar}" passthru="true" taskname="sonar" />
|
|
||||||
|
|
||||||
<property name="sonar.done" value="true" />
|
|
||||||
</target>
|
|
||||||
</project>
|
|
@ -1,108 +0,0 @@
|
|||||||
<?php declare(strict_types=1);
|
|
||||||
/**
|
|
||||||
* Hummingbird Anime Client
|
|
||||||
*
|
|
||||||
* An API client for Hummingbird to manage anime and manga watch lists
|
|
||||||
*
|
|
||||||
* PHP version 7
|
|
||||||
*
|
|
||||||
* @package HummingbirdAnimeClient
|
|
||||||
* @author Timothy J. Warren <tim@timshomepage.net>
|
|
||||||
* @copyright 2015 - 2016 Timothy J. Warren
|
|
||||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
|
||||||
* @version 3.1
|
|
||||||
* @link https://github.com/timw4mail/HummingBirdAnimeClient
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace Aviat\AnimeClient\Auth;
|
|
||||||
|
|
||||||
use Aviat\AnimeClient\AnimeClient;
|
|
||||||
use Aviat\Ion\Di\ContainerInterface;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Hummingbird API Authentication
|
|
||||||
*/
|
|
||||||
class HummingbirdAuth {
|
|
||||||
|
|
||||||
use \Aviat\Ion\Di\ContainerAware;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Anime API Model
|
|
||||||
*
|
|
||||||
* @var \Aviat\AnimeClient\Model\API
|
|
||||||
*/
|
|
||||||
protected $model;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Session object
|
|
||||||
*
|
|
||||||
* @var Aura\Session\Segment
|
|
||||||
*/
|
|
||||||
protected $segment;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor
|
|
||||||
*
|
|
||||||
* @param ContainerInterface $container
|
|
||||||
*/
|
|
||||||
public function __construct(ContainerInterface $container)
|
|
||||||
{
|
|
||||||
$this->setContainer($container);
|
|
||||||
$this->segment = $container->get('session')
|
|
||||||
->getSegment(AnimeClient::SESSION_SEGMENT);
|
|
||||||
$this->model = $container->get('api-model');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Make the appropriate authentication call,
|
|
||||||
* and save the resulting auth token if successful
|
|
||||||
*
|
|
||||||
* @param string $password
|
|
||||||
* @return boolean
|
|
||||||
*/
|
|
||||||
public function authenticate($password)
|
|
||||||
{
|
|
||||||
$username = $this->container->get('config')
|
|
||||||
->get('hummingbird_username');
|
|
||||||
$auth_token = $this->model->authenticate($username, $password);
|
|
||||||
|
|
||||||
if (FALSE !== $auth_token)
|
|
||||||
{
|
|
||||||
$this->segment->set('auth_token', $auth_token);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check whether the current user is authenticated
|
|
||||||
*
|
|
||||||
* @return boolean
|
|
||||||
*/
|
|
||||||
public function is_authenticated()
|
|
||||||
{
|
|
||||||
return ($this->get_auth_token() !== FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Clear authentication values
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function logout()
|
|
||||||
{
|
|
||||||
$this->segment->clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve the authentication token from the session
|
|
||||||
*
|
|
||||||
* @return string|false
|
|
||||||
*/
|
|
||||||
public function get_auth_token()
|
|
||||||
{
|
|
||||||
return $this->segment->get('auth_token', FALSE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// End of HummingbirdAuth.php
|
|
@ -1,29 +0,0 @@
|
|||||||
<?php declare(strict_types=1);
|
|
||||||
/**
|
|
||||||
* Hummingbird Anime Client
|
|
||||||
*
|
|
||||||
* An API client for Hummingbird to manage anime and manga watch lists
|
|
||||||
*
|
|
||||||
* PHP version 7
|
|
||||||
*
|
|
||||||
* @package HummingbirdAnimeClient
|
|
||||||
* @author Timothy J. Warren <tim@timshomepage.net>
|
|
||||||
* @copyright 2015 - 2016 Timothy J. Warren
|
|
||||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
|
||||||
* @version 3.1
|
|
||||||
* @link https://github.com/timw4mail/HummingBirdAnimeClient
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace Aviat\AnimeClient\Hummingbird\Enum;
|
|
||||||
|
|
||||||
use Aviat\Ion\Enum as BaseEnum;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Status of when anime is being/was/will be aired
|
|
||||||
*/
|
|
||||||
class AnimeAiringStatus extends BaseEnum {
|
|
||||||
const NOT_YET_AIRED = 'Not Yet Aired';
|
|
||||||
const AIRING = 'Currently Airing';
|
|
||||||
const FINISHED_AIRING = 'Finished Airing';
|
|
||||||
}
|
|
||||||
// End of AnimeAiringStatus.php
|
|
@ -1,32 +0,0 @@
|
|||||||
<?php declare(strict_types=1);
|
|
||||||
/**
|
|
||||||
* Hummingbird Anime Client
|
|
||||||
*
|
|
||||||
* An API client for Hummingbird to manage anime and manga watch lists
|
|
||||||
*
|
|
||||||
* PHP version 7
|
|
||||||
*
|
|
||||||
* @package HummingbirdAnimeClient
|
|
||||||
* @author Timothy J. Warren <tim@timshomepage.net>
|
|
||||||
* @copyright 2015 - 2016 Timothy J. Warren
|
|
||||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
|
||||||
* @version 3.1
|
|
||||||
* @link https://github.com/timw4mail/HummingBirdAnimeClient
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace Aviat\AnimeClient\Hummingbird\Enum;
|
|
||||||
|
|
||||||
use Aviat\Ion\Enum as BaseEnum;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Type of Anime
|
|
||||||
*/
|
|
||||||
class AnimeShowType extends BaseEnum {
|
|
||||||
const TV = 'TV';
|
|
||||||
const MOVIE = 'Movie';
|
|
||||||
const OVA = 'OVA';
|
|
||||||
const ONA = 'ONA';
|
|
||||||
const SPECIAL = 'Special';
|
|
||||||
const MUSIC = 'Music';
|
|
||||||
}
|
|
||||||
// End of AnimeShowType.php
|
|
@ -1,31 +0,0 @@
|
|||||||
<?php declare(strict_types=1);
|
|
||||||
/**
|
|
||||||
* Hummingbird Anime Client
|
|
||||||
*
|
|
||||||
* An API client for Hummingbird to manage anime and manga watch lists
|
|
||||||
*
|
|
||||||
* PHP version 7
|
|
||||||
*
|
|
||||||
* @package HummingbirdAnimeClient
|
|
||||||
* @author Timothy J. Warren <tim@timshomepage.net>
|
|
||||||
* @copyright 2015 - 2016 Timothy J. Warren
|
|
||||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
|
||||||
* @version 3.1
|
|
||||||
* @link https://github.com/timw4mail/HummingBirdAnimeClient
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace Aviat\AnimeClient\Hummingbird\Enum;
|
|
||||||
|
|
||||||
use Aviat\Ion\Enum as BaseEnum;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Possible values for watching status for the current anime
|
|
||||||
*/
|
|
||||||
class AnimeWatchingStatus extends BaseEnum {
|
|
||||||
const WATCHING = 'currently-watching';
|
|
||||||
const PLAN_TO_WATCH = 'plan-to-watch';
|
|
||||||
const COMPLETED = 'completed';
|
|
||||||
const ON_HOLD = 'on-hold';
|
|
||||||
const DROPPED = 'dropped';
|
|
||||||
}
|
|
||||||
// End of AnimeWatchingStatus.php
|
|
@ -1,31 +0,0 @@
|
|||||||
<?php declare(strict_types=1);
|
|
||||||
/**
|
|
||||||
* Hummingbird Anime Client
|
|
||||||
*
|
|
||||||
* An API client for Hummingbird to manage anime and manga watch lists
|
|
||||||
*
|
|
||||||
* PHP version 7
|
|
||||||
*
|
|
||||||
* @package HummingbirdAnimeClient
|
|
||||||
* @author Timothy J. Warren <tim@timshomepage.net>
|
|
||||||
* @copyright 2015 - 2016 Timothy J. Warren
|
|
||||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
|
||||||
* @version 3.1
|
|
||||||
* @link https://github.com/timw4mail/HummingBirdAnimeClient
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace Aviat\AnimeClient\Hummingbird\Enum;
|
|
||||||
|
|
||||||
use Aviat\Ion\Enum as BaseEnum;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Possible values for current reading status of manga
|
|
||||||
*/
|
|
||||||
class MangaReadingStatus extends BaseEnum {
|
|
||||||
const READING = 'Currently Reading';
|
|
||||||
const PLAN_TO_READ = 'Plan to Read';
|
|
||||||
const DROPPED = 'Dropped';
|
|
||||||
const ON_HOLD = 'On Hold';
|
|
||||||
const COMPLETED = 'Completed';
|
|
||||||
}
|
|
||||||
// End of MangaReadingStatus.php
|
|
@ -1,147 +0,0 @@
|
|||||||
<?php declare(strict_types=1);
|
|
||||||
/**
|
|
||||||
* Hummingbird Anime Client
|
|
||||||
*
|
|
||||||
* An API client for Hummingbird to manage anime and manga watch lists
|
|
||||||
*
|
|
||||||
* PHP version 7
|
|
||||||
*
|
|
||||||
* @package HummingbirdAnimeClient
|
|
||||||
* @author Timothy J. Warren <tim@timshomepage.net>
|
|
||||||
* @copyright 2015 - 2016 Timothy J. Warren
|
|
||||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
|
||||||
* @version 3.1
|
|
||||||
* @link https://github.com/timw4mail/HummingBirdAnimeClient
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace Aviat\AnimeClient\Hummingbird\Transformer;
|
|
||||||
|
|
||||||
use Aviat\Ion\Transformer\AbstractTransformer;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Transformer for anime list
|
|
||||||
*/
|
|
||||||
class AnimeListTransformer extends AbstractTransformer {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert raw api response to a more
|
|
||||||
* logical and workable structure
|
|
||||||
*
|
|
||||||
* @param array $item API library item
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function transform($item)
|
|
||||||
{
|
|
||||||
$anime =& $item['anime'];
|
|
||||||
$genres = $this->linearizeGenres($item['anime']['genres']);
|
|
||||||
|
|
||||||
$rating = NULL;
|
|
||||||
if ($item['rating']['type'] === 'advanced')
|
|
||||||
{
|
|
||||||
$rating = is_numeric($item['rating']['value'])
|
|
||||||
? (int) 2 * $item['rating']['value']
|
|
||||||
: '-';
|
|
||||||
}
|
|
||||||
|
|
||||||
$total_episodes = is_numeric($anime['episode_count'])
|
|
||||||
? $anime['episode_count']
|
|
||||||
: '-';
|
|
||||||
|
|
||||||
$alternate_title = NULL;
|
|
||||||
if (array_key_exists('alternate_title', $anime))
|
|
||||||
{
|
|
||||||
// If the alternate title is very similar, or
|
|
||||||
// a subset of the main title, don't list the
|
|
||||||
// alternate title
|
|
||||||
$not_subset = stripos($anime['title'], $anime['alternate_title']) === FALSE;
|
|
||||||
$diff = levenshtein($anime['title'], $anime['alternate_title'] ?? '');
|
|
||||||
if ($not_subset && $diff >= 5)
|
|
||||||
{
|
|
||||||
$alternate_title = $anime['alternate_title'];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return [
|
|
||||||
'id' => $item['id'],
|
|
||||||
'episodes' => [
|
|
||||||
'watched' => $item['episodes_watched'],
|
|
||||||
'total' => $total_episodes,
|
|
||||||
'length' => $anime['episode_length'],
|
|
||||||
],
|
|
||||||
'airing' => [
|
|
||||||
'status' => $anime['status'],
|
|
||||||
'started' => $anime['started_airing'],
|
|
||||||
'ended' => $anime['finished_airing']
|
|
||||||
],
|
|
||||||
'anime' => [
|
|
||||||
'age_rating' => $anime['age_rating'],
|
|
||||||
'title' => $anime['title'],
|
|
||||||
'alternate_title' => $alternate_title,
|
|
||||||
'slug' => $anime['slug'],
|
|
||||||
'url' => $anime['url'],
|
|
||||||
'type' => $anime['show_type'],
|
|
||||||
'image' => $anime['cover_image'],
|
|
||||||
'genres' => $genres,
|
|
||||||
],
|
|
||||||
'watching_status' => $item['status'],
|
|
||||||
'notes' => $item['notes'],
|
|
||||||
'rewatching' => (bool) $item['rewatching'],
|
|
||||||
'rewatched' => $item['rewatched_times'],
|
|
||||||
'user_rating' => $rating,
|
|
||||||
'private' => (bool) $item['private'],
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert transformed data to
|
|
||||||
* api response format
|
|
||||||
*
|
|
||||||
* @param array $item Transformed library item
|
|
||||||
* @return array API library item
|
|
||||||
*/
|
|
||||||
public function untransform($item)
|
|
||||||
{
|
|
||||||
// Messy mapping of boolean values to their API string equivalents
|
|
||||||
$privacy = 'public';
|
|
||||||
if (array_key_exists('private', $item) && $item['private'])
|
|
||||||
{
|
|
||||||
$privacy = 'private';
|
|
||||||
}
|
|
||||||
|
|
||||||
$rewatching = 'false';
|
|
||||||
if (array_key_exists('rewatching', $item) && $item['rewatching'])
|
|
||||||
{
|
|
||||||
$rewatching = 'true';
|
|
||||||
}
|
|
||||||
|
|
||||||
return [
|
|
||||||
'id' => $item['id'],
|
|
||||||
'status' => $item['watching_status'],
|
|
||||||
'sane_rating_update' => $item['user_rating'] / 2,
|
|
||||||
'rewatching' => $rewatching,
|
|
||||||
'rewatched_times' => $item['rewatched'],
|
|
||||||
'notes' => $item['notes'],
|
|
||||||
'episodes_watched' => $item['episodes_watched'],
|
|
||||||
'privacy' => $privacy
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Simplify structure of genre list
|
|
||||||
*
|
|
||||||
* @param array $rawGenres
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
protected function linearizeGenres(array $rawGenres): array
|
|
||||||
{
|
|
||||||
$genres = [];
|
|
||||||
|
|
||||||
foreach ($rawGenres as $genre)
|
|
||||||
{
|
|
||||||
$genres[] = $genre['name'];
|
|
||||||
}
|
|
||||||
|
|
||||||
return $genres;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// End of AnimeListTransformer.php
|
|
@ -1,121 +0,0 @@
|
|||||||
<?php declare(strict_types=1);
|
|
||||||
/**
|
|
||||||
* Hummingbird Anime Client
|
|
||||||
*
|
|
||||||
* An API client for Hummingbird to manage anime and manga watch lists
|
|
||||||
*
|
|
||||||
* PHP version 7
|
|
||||||
*
|
|
||||||
* @package HummingbirdAnimeClient
|
|
||||||
* @author Timothy J. Warren <tim@timshomepage.net>
|
|
||||||
* @copyright 2015 - 2016 Timothy J. Warren
|
|
||||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
|
||||||
* @version 3.1
|
|
||||||
* @link https://github.com/timw4mail/HummingBirdAnimeClient
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace Aviat\AnimeClient\Hummingbird\Transformer;
|
|
||||||
|
|
||||||
use Aviat\Ion\Transformer\AbstractTransformer;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Data transformation class for zippered Hummingbird manga
|
|
||||||
*/
|
|
||||||
class MangaListTransformer extends AbstractTransformer {
|
|
||||||
|
|
||||||
use \Aviat\Ion\StringWrapper;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remap zipped anime data to a more logical form
|
|
||||||
*
|
|
||||||
* @param array $item manga entry item
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function transform($item)
|
|
||||||
{
|
|
||||||
$manga =& $item['manga'];
|
|
||||||
|
|
||||||
$rating = (is_numeric($item['rating']))
|
|
||||||
? intval(2 * $item['rating'])
|
|
||||||
: '-';
|
|
||||||
|
|
||||||
$total_chapters = ($manga['chapter_count'] > 0)
|
|
||||||
? $manga['chapter_count']
|
|
||||||
: '-';
|
|
||||||
|
|
||||||
$total_volumes = ($manga['volume_count'] > 0)
|
|
||||||
? $manga['volume_count']
|
|
||||||
: '-';
|
|
||||||
|
|
||||||
$map = [
|
|
||||||
'id' => $item['id'],
|
|
||||||
'chapters' => [
|
|
||||||
'read' => $item['chapters_read'],
|
|
||||||
'total' => $total_chapters
|
|
||||||
],
|
|
||||||
'volumes' => [
|
|
||||||
'read' => $item['volumes_read'],
|
|
||||||
'total' => $total_volumes
|
|
||||||
],
|
|
||||||
'manga' => [
|
|
||||||
'title' => $manga['romaji_title'],
|
|
||||||
'alternate_title' => NULL,
|
|
||||||
'slug' => $manga['id'],
|
|
||||||
'url' => 'https://hummingbird.me/manga/' . $manga['id'],
|
|
||||||
'type' => $manga['manga_type'],
|
|
||||||
'image' => $manga['poster_image_thumb'],
|
|
||||||
'genres' => $manga['genres'],
|
|
||||||
],
|
|
||||||
'reading_status' => $item['status'],
|
|
||||||
'notes' => $item['notes'],
|
|
||||||
'rereading' => (bool)$item['rereading'],
|
|
||||||
'reread' => $item['reread_count'],
|
|
||||||
'user_rating' => $rating,
|
|
||||||
];
|
|
||||||
|
|
||||||
if (array_key_exists('english_title', $manga))
|
|
||||||
{
|
|
||||||
$diff = levenshtein($manga['romaji_title'], $manga['english_title']);
|
|
||||||
|
|
||||||
// If the titles are REALLY similar, don't bother showing both
|
|
||||||
if ($diff >= 5)
|
|
||||||
{
|
|
||||||
$map['manga']['alternate_title'] = $manga['english_title'];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $map;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Untransform data to update the api
|
|
||||||
*
|
|
||||||
* @param array $item
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function untransform($item)
|
|
||||||
{
|
|
||||||
$rereading = (array_key_exists('rereading', $item)) && (bool)$item['rereading'];
|
|
||||||
|
|
||||||
$map = [
|
|
||||||
'id' => $item['id'],
|
|
||||||
'manga_id' => $item['manga_id'],
|
|
||||||
'status' => $item['status'],
|
|
||||||
'chapters_read' => (int)$item['chapters_read'],
|
|
||||||
'volumes_read' => (int)$item['volumes_read'],
|
|
||||||
'rereading' => $rereading,
|
|
||||||
'reread_count' => (int)$item['reread_count'],
|
|
||||||
'notes' => $item['notes'],
|
|
||||||
];
|
|
||||||
|
|
||||||
if ($item['new_rating'] !== $item['old_rating'] && $item['new_rating'] !== "")
|
|
||||||
{
|
|
||||||
$map['rating'] = ($item['new_rating'] > 0)
|
|
||||||
? $item['new_rating'] / 2
|
|
||||||
: $item['old_rating'] / 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $map;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// End of MangaListTransformer.php
|
|
@ -1,92 +0,0 @@
|
|||||||
<?php declare(strict_types=1);
|
|
||||||
/**
|
|
||||||
* Hummingbird Anime Client
|
|
||||||
*
|
|
||||||
* An API client for Hummingbird to manage anime and manga watch lists
|
|
||||||
*
|
|
||||||
* PHP version 7
|
|
||||||
*
|
|
||||||
* @package HummingbirdAnimeClient
|
|
||||||
* @author Timothy J. Warren <tim@timshomepage.net>
|
|
||||||
* @copyright 2015 - 2016 Timothy J. Warren
|
|
||||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
|
||||||
* @version 3.1
|
|
||||||
* @link https://github.com/timw4mail/HummingBirdAnimeClient
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace Aviat\AnimeClient\Hummingbird\Transformer;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Merges the two separate manga lists together
|
|
||||||
*/
|
|
||||||
class MangaListsZipper {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* List of manga information
|
|
||||||
*
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
protected $manga_series_list = [];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* List of manga tracking information
|
|
||||||
*
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
protected $manga_tracking_list = [];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create the transformer
|
|
||||||
*
|
|
||||||
* @param array $merge_lists The raw manga data
|
|
||||||
*/
|
|
||||||
public function __construct(array $merge_lists)
|
|
||||||
{
|
|
||||||
$this->manga_series_list = $merge_lists['manga'];
|
|
||||||
$this->manga_tracking_list = $merge_lists['manga_library_entries'];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Do the transformation, and return the output
|
|
||||||
*
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function transform()
|
|
||||||
{
|
|
||||||
$this->index_manga_entries();
|
|
||||||
|
|
||||||
$output = [];
|
|
||||||
|
|
||||||
foreach ($this->manga_tracking_list as &$entry)
|
|
||||||
{
|
|
||||||
$id = $entry['manga_id'];
|
|
||||||
$entry['manga'] = $this->manga_series_list[$id];
|
|
||||||
unset($entry['manga_id']);
|
|
||||||
|
|
||||||
$output[] = $entry;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $output;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Index manga series by the id
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
protected function index_manga_entries()
|
|
||||||
{
|
|
||||||
$orig_list = $this->manga_series_list;
|
|
||||||
$indexed_list = [];
|
|
||||||
|
|
||||||
foreach ($orig_list as $manga)
|
|
||||||
{
|
|
||||||
$id = $manga['id'];
|
|
||||||
$indexed_list[$id] = $manga;
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->manga_series_list = $indexed_list;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
// End of ManagListsZipper.php
|
|
@ -1,88 +0,0 @@
|
|||||||
<?php
|
|
||||||
use Aura\Session\SessionFactory;
|
|
||||||
use Aviat\AnimeClient\Auth\HummingbirdAuth;
|
|
||||||
use Aviat\Ion\Friend;
|
|
||||||
use GuzzleHttp\Client;
|
|
||||||
use GuzzleHttp\Handler\MockHandler;
|
|
||||||
use GuzzleHttp\HandlerStack;
|
|
||||||
use GuzzleHttp\Psr7\Response;
|
|
||||||
|
|
||||||
class HummingbirdAuthTest extends AnimeClient_TestCase {
|
|
||||||
|
|
||||||
static $session;
|
|
||||||
static $sessionHandler;
|
|
||||||
|
|
||||||
public static function setUpBeforeClass()
|
|
||||||
{
|
|
||||||
self::$session = (new SessionFactory)->newInstance([]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setUp()
|
|
||||||
{
|
|
||||||
parent::setUp();
|
|
||||||
$auth = new HummingbirdAuth($this->container);
|
|
||||||
$friend = new Friend($auth);
|
|
||||||
$this->auth = $friend;
|
|
||||||
$this->container->setInstance('session', self::$session);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function dataAuthenticate()
|
|
||||||
{
|
|
||||||
$testToken = 'notReallyAValidTokenButThisIsATest';
|
|
||||||
|
|
||||||
return [
|
|
||||||
'successful auth call' => [
|
|
||||||
'username' => 'timw4mailtest',
|
|
||||||
'password' => 'password',
|
|
||||||
'response_data' => [
|
|
||||||
'code' => 201,
|
|
||||||
'body' => json_encode($testToken)
|
|
||||||
],
|
|
||||||
'session_value' => $testToken,
|
|
||||||
'expected' => TRUE,
|
|
||||||
],
|
|
||||||
'unsuccessful auth call' => [
|
|
||||||
'username' => 'foo',
|
|
||||||
'password' => 'foobarbaz',
|
|
||||||
'response_data' => [
|
|
||||||
'code' => 401,
|
|
||||||
'body' => '{"error":"Invalid credentials"}',
|
|
||||||
],
|
|
||||||
'session_value' => FALSE,
|
|
||||||
'expected' => FALSE,
|
|
||||||
]
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @dataProvider dataAuthenticate
|
|
||||||
*/
|
|
||||||
public function testAuthenticate($username, $password, $response_data, $session_value, $expected)
|
|
||||||
{
|
|
||||||
$this->container->get('config')
|
|
||||||
->set('hummingbird_username', $username);
|
|
||||||
$model = new MockBaseApiModel($this->container);
|
|
||||||
$mock = new MockHandler([
|
|
||||||
new Response($response_data['code'], [], $response_data['body'])
|
|
||||||
]);
|
|
||||||
$handler = HandlerStack::create($mock);
|
|
||||||
$client = new Client([
|
|
||||||
'handler' => $handler,
|
|
||||||
'http_errors' => FALSE // Don't throw an exception for 400/500 class status codes
|
|
||||||
]);
|
|
||||||
$model->__set('client', $client);
|
|
||||||
$this->auth->__set('model', $model);
|
|
||||||
|
|
||||||
$actual = $this->auth->authenticate($password);
|
|
||||||
$this->assertEquals($expected, $actual);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testIsAuthenticated()
|
|
||||||
{
|
|
||||||
$data = $this->dataAuthenticate();
|
|
||||||
call_user_func_array([$this, 'testAuthenticate'], $data['successful auth call']);
|
|
||||||
$this->assertTrue($this->auth->is_authenticated());
|
|
||||||
$this->auth->logout();
|
|
||||||
$this->assertFalse($this->auth->is_authenticated());
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,76 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
use Aviat\AnimeClient\Model\AnimeCollection as AnimeCollectionModel;
|
|
||||||
use Aviat\Ion\Config;
|
|
||||||
use Aviat\Ion\Friend;
|
|
||||||
|
|
||||||
class AnimeCollectionModelTest extends AnimeClient_TestCase {
|
|
||||||
|
|
||||||
public function setUp()
|
|
||||||
{
|
|
||||||
parent::setUp();
|
|
||||||
$this->container->setInstance('config', new Config([
|
|
||||||
'database' => [
|
|
||||||
'collection' => [
|
|
||||||
'type' => 'sqlite',
|
|
||||||
'host' => '',
|
|
||||||
'user' => '',
|
|
||||||
'pass' => '',
|
|
||||||
'port' => '',
|
|
||||||
'name' => 'default',
|
|
||||||
'database' => '',
|
|
||||||
'file' => ':memory:',
|
|
||||||
]
|
|
||||||
]
|
|
||||||
]));
|
|
||||||
$this->config = $this->container->get('config');
|
|
||||||
$this->collectionModel = new AnimeCollectionModel($this->container);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testSanity()
|
|
||||||
{
|
|
||||||
$friend = new Friend($this->collectionModel);
|
|
||||||
$this->assertInstanceOf('Aviat\Ion\Model\DB', $this->collectionModel);
|
|
||||||
$this->assertInstanceOf('Aviat\AnimeClient\Model\Anime', $friend->anime_model);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testInvalidDatabase()
|
|
||||||
{
|
|
||||||
$this->container->setInstance('config', new Config([
|
|
||||||
'database' => [
|
|
||||||
'collection' => [
|
|
||||||
'type' => 'sqlite',
|
|
||||||
'host' => '',
|
|
||||||
'user' => '',
|
|
||||||
'pass' => '',
|
|
||||||
'port' => '',
|
|
||||||
'name' => 'default',
|
|
||||||
'database' => '',
|
|
||||||
'file' => __FILE__,
|
|
||||||
]
|
|
||||||
]
|
|
||||||
]));
|
|
||||||
$collectionModel = new Friend(new AnimeCollectionModel($this->container));
|
|
||||||
$this->assertFalse($collectionModel->valid_database);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testNonExistentDatabase()
|
|
||||||
{
|
|
||||||
$this->container->setInstance('config', new Config([
|
|
||||||
'database' => [
|
|
||||||
'collection' => [
|
|
||||||
'type' => 'sqlite',
|
|
||||||
'host' => '',
|
|
||||||
'user' => '',
|
|
||||||
'pass' => '',
|
|
||||||
'port' => '',
|
|
||||||
'name' => 'default',
|
|
||||||
'database' => '',
|
|
||||||
'file' => '/foo/bar/baz/foobazbar.db',
|
|
||||||
]
|
|
||||||
]
|
|
||||||
]));
|
|
||||||
$collectionModel = new Friend(new AnimeCollectionModel($this->container));
|
|
||||||
$this->assertFalse($collectionModel->valid_database);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,55 +0,0 @@
|
|||||||
<?php
|
|
||||||
use Aviat\Ion\Friend;
|
|
||||||
|
|
||||||
class AnimeModelTest extends AnimeClient_TestCase {
|
|
||||||
|
|
||||||
public function setUp()
|
|
||||||
{
|
|
||||||
parent::setUp();
|
|
||||||
$this->animeModel = new Friend(new TestAnimeModel($this->container));
|
|
||||||
$this->mockDir = __DIR__ . '/../test_data/anime_list/search_mocks';
|
|
||||||
}
|
|
||||||
|
|
||||||
public function dataSearch()
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
'nonsense search' => [
|
|
||||||
'search' => 'foo',
|
|
||||||
],
|
|
||||||
'search for common series' => [
|
|
||||||
'search' => 'Fate',
|
|
||||||
],
|
|
||||||
'search for weird series' => [
|
|
||||||
'search' => 'Twintails',
|
|
||||||
]
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @dataProvider dataSearch
|
|
||||||
*/
|
|
||||||
public function testSearch($search)
|
|
||||||
{
|
|
||||||
// Mock requests
|
|
||||||
$json = file_get_contents(_dir($this->mockDir, "{$search}.json"));
|
|
||||||
$client = $this->getMockClient(200, [
|
|
||||||
'Content-Type' => 'application/json'
|
|
||||||
], $json);
|
|
||||||
$this->animeModel->__set('client', $client);
|
|
||||||
|
|
||||||
$actual = $this->animeModel->search($search);
|
|
||||||
$this->assertEquals(json_decode($json, TRUE), $actual);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testSearchBadResponse()
|
|
||||||
{
|
|
||||||
$client = $this->getMockClient(400, [
|
|
||||||
'Content-Type' => 'application/json'
|
|
||||||
], "[]");
|
|
||||||
$this->animeModel->__set('client', $client);
|
|
||||||
|
|
||||||
$this->expectException('RuntimeException');
|
|
||||||
|
|
||||||
$this->animeModel->search('');
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,252 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
use Aviat\AnimeClient\Container;
|
|
||||||
use GuzzleHttp\Client;
|
|
||||||
use GuzzleHttp\Handler\MockHandler;
|
|
||||||
use GuzzleHttp\HandlerStack;
|
|
||||||
use GuzzleHttp\Psr7\Response;
|
|
||||||
|
|
||||||
class BaseApiModelTest extends AnimeClient_TestCase {
|
|
||||||
|
|
||||||
public function setUp()
|
|
||||||
{
|
|
||||||
parent::setUp();
|
|
||||||
$this->model = new MockBaseApiModel($this->container);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function getIp()
|
|
||||||
{
|
|
||||||
$response = $this->model->get('/ip');
|
|
||||||
$json = json_decode($response->getBody(), TRUE);
|
|
||||||
$ip = $json['origin'];
|
|
||||||
return $ip;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function dataClient()
|
|
||||||
{
|
|
||||||
$user_agent = "Tim's Anime Client/2.0";
|
|
||||||
$headers = [
|
|
||||||
'User-Agent' => $user_agent
|
|
||||||
];
|
|
||||||
|
|
||||||
return [
|
|
||||||
'invalid method' => [
|
|
||||||
'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
|
|
||||||
],
|
|
||||||
'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,
|
|
||||||
'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,
|
|
||||||
'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,
|
|
||||||
'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,
|
|
||||||
'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;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Because you have to make another api call to get the origin ip
|
|
||||||
// address, it needs to be retreived outside of the dataProvider method
|
|
||||||
$expected['origin'] = $this->getIp();
|
|
||||||
$actual = ($is_json)
|
|
||||||
? json_decode($result->getBody(), TRUE)
|
|
||||||
: (string) $result->getBody();
|
|
||||||
|
|
||||||
$this->assertEquals($expected, $actual);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function dataAuthenticate()
|
|
||||||
{
|
|
||||||
$test_token = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJqdGkiOiI4YTA5ZDk4Ny1iZWQxLTQyMTktYWVmOS0wMTcxYWVjYTE3ZWUiLCJzY29wZSI6WyJhbGwiXSwic3ViIjoxMDgwMTIsImlzcyI6MTQ0NTAxNzczNSwiZXhwIjoxNDUyOTY2NTM1fQ.fpha1ZDN9dSFAuHeJesfOP9pCk5-ZnZk4uv3zumRMY0';
|
|
||||||
|
|
||||||
return [
|
|
||||||
'successful authentication' => [
|
|
||||||
'username' => 'timw4mailtest',
|
|
||||||
'password' => 'password',
|
|
||||||
'response_data' => [
|
|
||||||
'code' => 201,
|
|
||||||
'body' => json_encode($test_token)
|
|
||||||
],
|
|
||||||
'expected' => $test_token
|
|
||||||
],
|
|
||||||
'failed authentication' => [
|
|
||||||
'username' => 'foo',
|
|
||||||
'password' => 'foobarbaz',
|
|
||||||
'response_data' => [
|
|
||||||
'code' => 401,
|
|
||||||
'body' => '{"error":"Invalid credentials"}',
|
|
||||||
],
|
|
||||||
'expected' => FALSE
|
|
||||||
]
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @dataProvider dataAuthenticate
|
|
||||||
*/
|
|
||||||
public function testAuthenticate($username, $password, $response_data, $expected)
|
|
||||||
{
|
|
||||||
$mock = new MockHandler([
|
|
||||||
new Response($response_data['code'], [], $response_data['body'])
|
|
||||||
]);
|
|
||||||
$handler = HandlerStack::create($mock);
|
|
||||||
$client = new Client([
|
|
||||||
'handler' => $handler,
|
|
||||||
'http_errors' => FALSE // Don't throw an exception for 400/500 class status codes
|
|
||||||
]);
|
|
||||||
|
|
||||||
// Set the mock client
|
|
||||||
$this->model->__set('client', $client);
|
|
||||||
|
|
||||||
// Check results based on mock data
|
|
||||||
$actual = $this->model->authenticate($username, $password);
|
|
||||||
$this->assertEquals($expected, $actual, "Incorrect method return value");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,71 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
use Aviat\Ion\Friend;
|
|
||||||
use Aviat\Ion\Json;
|
|
||||||
|
|
||||||
class MangaModelTest extends AnimeClient_TestCase {
|
|
||||||
|
|
||||||
public function setUp()
|
|
||||||
{
|
|
||||||
parent::setUp();
|
|
||||||
$this->container->setInstance('util', new MockUtil($this->container));
|
|
||||||
$this->model = new Friend(new TestMangaModel($this->container));
|
|
||||||
$this->mockDir = __DIR__ . '/../test_data/manga_list';
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testZipperLists()
|
|
||||||
{
|
|
||||||
$raw_data = Json::decodeFile($this->mockDir . '/manga.json');
|
|
||||||
$expected = Json::decodeFile($this->mockDir . '/manga-zippered.json');
|
|
||||||
|
|
||||||
$this->assertEquals($expected, $this->model->zipperLists($raw_data));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testMapByStatus()
|
|
||||||
{
|
|
||||||
$original = Json::decodeFile($this->mockDir . '/manga-transformed.json');
|
|
||||||
$expected = Json::decodeFile($this->mockDir . '/manga-mapped.json');
|
|
||||||
$actual = $this->model->map_by_status($original);
|
|
||||||
|
|
||||||
$this->assertEquals($expected, $actual);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testGetListFromApi()
|
|
||||||
{
|
|
||||||
$data = file_get_contents($this->mockDir . '/manga.json');
|
|
||||||
$client = $this->getMockClient(200, [
|
|
||||||
'Content-type' => 'application/json'
|
|
||||||
], $data);
|
|
||||||
$this->model->__set('client', $client);
|
|
||||||
|
|
||||||
$reflect = new ReflectionClass($this->model);
|
|
||||||
$constants = $reflect->getConstants();
|
|
||||||
|
|
||||||
$expected_all = Json::decodeFile($this->mockDir . '/manga-mapped.json');
|
|
||||||
|
|
||||||
$this->assertEquals($expected_all, $this->model->_get_list_from_api());
|
|
||||||
|
|
||||||
foreach($constants as $name => $value)
|
|
||||||
{
|
|
||||||
$key = $reflect->getConstant($name);
|
|
||||||
$this->assertEquals($expected_all[$key], $this->model->_get_list_from_api($key));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testGetList()
|
|
||||||
{
|
|
||||||
if (($var = getenv('CI')))
|
|
||||||
{
|
|
||||||
$this->markTestSkipped();
|
|
||||||
}
|
|
||||||
|
|
||||||
$data = file_get_contents($this->mockDir . '/manga.json');
|
|
||||||
$client = $this->getMockClient(200, [
|
|
||||||
'Content-type' => 'application/json'
|
|
||||||
], $data);
|
|
||||||
$this->model->__set('client', $client);
|
|
||||||
|
|
||||||
$expected = Json::decodeFile($this->mockDir . '/get-all-lists.json');
|
|
||||||
$this->assertEquals($expected['Reading'], $this->model->get_list('Reading'));
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,50 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
use Aviat\AnimeClient\Hummingbird\Transformer\AnimeListTransformer;
|
|
||||||
use Aviat\Ion\Friend;
|
|
||||||
use Aviat\Ion\Json;
|
|
||||||
|
|
||||||
class AnimeListTransformerTest extends AnimeClient_TestCase {
|
|
||||||
|
|
||||||
public function setUp()
|
|
||||||
{
|
|
||||||
parent::setUp();
|
|
||||||
$this->start_file = __DIR__ . '/../test_data/anime_list/anime-completed.json';
|
|
||||||
$this->res_file = __DIR__ . '/../test_data/anime_list/anime-completed-transformed.json';
|
|
||||||
$this->transformer = new AnimeListTransformer();
|
|
||||||
$this->transformerFriend = new Friend($this->transformer);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function dataLinearizeGenres()
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
[
|
|
||||||
'original' => [
|
|
||||||
['name' => 'Action'],
|
|
||||||
['name' => 'Comedy'],
|
|
||||||
['name' => 'Magic'],
|
|
||||||
['name' => 'Fantasy'],
|
|
||||||
['name' => 'Mahou Shoujo']
|
|
||||||
],
|
|
||||||
'expected' => ['Action', 'Comedy', 'Magic', 'Fantasy', 'Mahou Shoujo']
|
|
||||||
]
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @dataProvider dataLinearizeGenres
|
|
||||||
*/
|
|
||||||
public function testLinearizeGenres($original, $expected)
|
|
||||||
{
|
|
||||||
$actual = $this->transformerFriend->linearizeGenres($original);
|
|
||||||
$this->assertEquals($expected, $actual);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testTransform()
|
|
||||||
{
|
|
||||||
$json = Json::decodeFile($this->start_file);
|
|
||||||
$expected = Json::decodeFile($this->res_file);
|
|
||||||
$actual = $this->transformer->transformCollection($json);
|
|
||||||
$this->assertEquals($expected, $actual);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,114 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
use Aviat\AnimeClient\Hummingbird\Transformer\MangaListTransformer;
|
|
||||||
use Aviat\Ion\Json;
|
|
||||||
|
|
||||||
class MangaListTransformerTest extends AnimeClient_TestCase {
|
|
||||||
|
|
||||||
public function setUp()
|
|
||||||
{
|
|
||||||
parent::setUp();
|
|
||||||
$this->start_file = __DIR__ . '/../test_data/manga_list/manga-zippered.json';
|
|
||||||
$this->res_file = __DIR__ . '/../test_data/manga_list/manga-transformed.json';
|
|
||||||
$this->transformer = new MangaListTransformer();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public function testTransform()
|
|
||||||
{
|
|
||||||
$orig_json = Json::decodeFile($this->start_file);
|
|
||||||
$expected = Json::decodeFile($this->res_file);
|
|
||||||
|
|
||||||
$actual = $this->transformer->transformCollection($orig_json);
|
|
||||||
$this->assertEquals($expected, $actual);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function dataUntransform()
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
'same_rating' => [
|
|
||||||
'orig' => [
|
|
||||||
'id' => 401735,
|
|
||||||
'manga_id' => "love-hina",
|
|
||||||
'status' => "Plan to Read",
|
|
||||||
'chapters_read' => 16,
|
|
||||||
'volumes_read' => 2,
|
|
||||||
'rereading' => true,
|
|
||||||
'reread_count' => 1,
|
|
||||||
'notes' => "Some text notes",
|
|
||||||
'old_rating' => 7,
|
|
||||||
'new_rating' => 7,
|
|
||||||
],
|
|
||||||
'expected' => [
|
|
||||||
'id' => 401735,
|
|
||||||
'manga_id' => "love-hina",
|
|
||||||
'status' => "Plan to Read",
|
|
||||||
'chapters_read' => 16,
|
|
||||||
'volumes_read' => 2,
|
|
||||||
'rereading' => true,
|
|
||||||
'reread_count' => 1,
|
|
||||||
'notes' => "Some text notes",
|
|
||||||
]
|
|
||||||
],
|
|
||||||
'update_rating' => [
|
|
||||||
'orig' => [
|
|
||||||
'id' => 401735,
|
|
||||||
'manga_id' => "love-hina",
|
|
||||||
'status' => "Plan to Read",
|
|
||||||
'chapters_read' => 16,
|
|
||||||
'volumes_read' => 2,
|
|
||||||
'rereading' => true,
|
|
||||||
'reread_count' => 1,
|
|
||||||
'notes' => "Some text notes",
|
|
||||||
'old_rating' => 7,
|
|
||||||
'new_rating' => 8,
|
|
||||||
],
|
|
||||||
'expected' => [
|
|
||||||
'id' => 401735,
|
|
||||||
'manga_id' => "love-hina",
|
|
||||||
'status' => "Plan to Read",
|
|
||||||
'chapters_read' => 16,
|
|
||||||
'volumes_read' => 2,
|
|
||||||
'rereading' => true,
|
|
||||||
'reread_count' => 1,
|
|
||||||
'notes' => "Some text notes",
|
|
||||||
'rating' => 4,
|
|
||||||
]
|
|
||||||
],
|
|
||||||
'remove_rating' => [
|
|
||||||
'orig' => [
|
|
||||||
'id' => 401735,
|
|
||||||
'manga_id' => "love-hina",
|
|
||||||
'status' => "Plan to Read",
|
|
||||||
'chapters_read' => 16,
|
|
||||||
'volumes_read' => 2,
|
|
||||||
'rereading' => true,
|
|
||||||
'reread_count' => 1,
|
|
||||||
'notes' => "Some text notes",
|
|
||||||
'old_rating' => 7,
|
|
||||||
'new_rating' => 0,
|
|
||||||
],
|
|
||||||
'expected' => [
|
|
||||||
'id' => 401735,
|
|
||||||
'manga_id' => "love-hina",
|
|
||||||
'status' => "Plan to Read",
|
|
||||||
'chapters_read' => 16,
|
|
||||||
'volumes_read' => 2,
|
|
||||||
'rereading' => true,
|
|
||||||
'reread_count' => 1,
|
|
||||||
'notes' => "Some text notes",
|
|
||||||
'rating' => 3.5,
|
|
||||||
]
|
|
||||||
]
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @dataProvider dataUntransform
|
|
||||||
*/
|
|
||||||
public function testUntransform($orig, $expected)
|
|
||||||
{
|
|
||||||
$actual = $this->transformer->untransform($orig);
|
|
||||||
$this->assertEquals($expected, $actual);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,28 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
use Aviat\AnimeClient\Hummingbird\Transformer\MangaListsZipper;
|
|
||||||
use Aviat\Ion\Json;
|
|
||||||
|
|
||||||
class MangaListsZipperTest extends AnimeClient_TestCase {
|
|
||||||
|
|
||||||
protected $start_file = '';
|
|
||||||
protected $res_file = '';
|
|
||||||
|
|
||||||
public function setUp()
|
|
||||||
{
|
|
||||||
$this->start_file = __DIR__ . '/../test_data/manga_list/manga.json';
|
|
||||||
$this->res_file = __DIR__ . '/../test_data/manga_list/manga-zippered.json';
|
|
||||||
|
|
||||||
$json = Json::decodeFile($this->start_file);
|
|
||||||
$this->mangaListsZipper = new MangaListsZipper($json);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testTransform()
|
|
||||||
{
|
|
||||||
$zippered_json = Json::decodeFile($this->res_file);
|
|
||||||
$transformed = $this->mangaListsZipper->transform();
|
|
||||||
|
|
||||||
$this->assertEquals($zippered_json, $transformed);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user