mirror of
https://github.com/jikan-me/jikan-rest.git
synced 2025-02-20 11:23:35 +08:00
added the foundations for fixture based tests
This commit is contained in:
parent
2254ef7bf2
commit
8f102d2b56
@ -7,7 +7,6 @@ indent_style = space
|
|||||||
indent_size = 2
|
indent_size = 2
|
||||||
insert_final_newline = true
|
insert_final_newline = true
|
||||||
trim_trailing_whitespace = true
|
trim_trailing_whitespace = true
|
||||||
end_of_line = lf
|
|
||||||
|
|
||||||
[*.md]
|
[*.md]
|
||||||
max_line_length = off
|
max_line_length = off
|
||||||
|
@ -5,9 +5,12 @@ namespace App;
|
|||||||
use App\Http\HttpHelper;
|
use App\Http\HttpHelper;
|
||||||
use Jikan\Jikan;
|
use Jikan\Jikan;
|
||||||
use Jikan\Request\Anime\AnimeRequest;
|
use Jikan\Request\Anime\AnimeRequest;
|
||||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
|
|
||||||
class Anime extends JikanApiSearchableModel
|
class Anime extends JikanApiSearchableModel
|
||||||
{
|
{
|
||||||
|
use HasFactory;
|
||||||
|
|
||||||
// note that here we skip "score", "min_score", "max_score", "rating" and others because they need special logic
|
// note that here we skip "score", "min_score", "max_score", "rating" and others because they need special logic
|
||||||
// to set the correct filtering on the ORM.
|
// to set the correct filtering on the ORM.
|
||||||
protected array $filters = ["order_by", "status", "type", "sort"];
|
protected array $filters = ["order_by", "status", "type", "sort"];
|
||||||
|
@ -4,9 +4,12 @@ namespace App;
|
|||||||
|
|
||||||
use Jikan\Jikan;
|
use Jikan\Jikan;
|
||||||
use Jikan\Request\Character\CharacterRequest;
|
use Jikan\Request\Character\CharacterRequest;
|
||||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
|
|
||||||
class Character extends JikanApiSearchableModel
|
class Character extends JikanApiSearchableModel
|
||||||
{
|
{
|
||||||
|
use HasFactory;
|
||||||
|
|
||||||
protected array $filters = ["order_by", "sort"];
|
protected array $filters = ["order_by", "sort"];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -4,6 +4,7 @@ namespace App;
|
|||||||
|
|
||||||
use Jenssegers\Mongodb\Eloquent\Model;
|
use Jenssegers\Mongodb\Eloquent\Model;
|
||||||
use Jikan\Request\Genre\AnimeGenresRequest;
|
use Jikan\Request\Genre\AnimeGenresRequest;
|
||||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class Magazine
|
* Class Magazine
|
||||||
@ -11,6 +12,8 @@ use Jikan\Request\Genre\AnimeGenresRequest;
|
|||||||
*/
|
*/
|
||||||
class GenreAnime extends JikanApiSearchableModel
|
class GenreAnime extends JikanApiSearchableModel
|
||||||
{
|
{
|
||||||
|
use HasFactory;
|
||||||
|
|
||||||
protected array $filters = ["order_by", "sort"];
|
protected array $filters = ["order_by", "sort"];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -4,6 +4,7 @@ namespace App;
|
|||||||
|
|
||||||
use Jenssegers\Mongodb\Eloquent\Model;
|
use Jenssegers\Mongodb\Eloquent\Model;
|
||||||
use Jikan\Request\Genre\AnimeGenresRequest;
|
use Jikan\Request\Genre\AnimeGenresRequest;
|
||||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class Magazine
|
* Class Magazine
|
||||||
@ -11,6 +12,8 @@ use Jikan\Request\Genre\AnimeGenresRequest;
|
|||||||
*/
|
*/
|
||||||
class GenreManga extends JikanApiSearchableModel
|
class GenreManga extends JikanApiSearchableModel
|
||||||
{
|
{
|
||||||
|
use HasFactory;
|
||||||
|
|
||||||
protected array $filters = ["order_by", "sort"];
|
protected array $filters = ["order_by", "sort"];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -5,9 +5,12 @@ namespace App;
|
|||||||
use App\Http\HttpHelper;
|
use App\Http\HttpHelper;
|
||||||
use Jikan\Jikan;
|
use Jikan\Jikan;
|
||||||
use Jikan\Request\Manga\MangaRequest;
|
use Jikan\Request\Manga\MangaRequest;
|
||||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
|
|
||||||
class Manga extends JikanApiSearchableModel
|
class Manga extends JikanApiSearchableModel
|
||||||
{
|
{
|
||||||
|
use HasFactory;
|
||||||
|
|
||||||
// note that here we skip "score", "min_score", "max_score", "rating" and others because they need special logic
|
// note that here we skip "score", "min_score", "max_score", "rating" and others because they need special logic
|
||||||
// to set the correct filtering on the ORM.
|
// to set the correct filtering on the ORM.
|
||||||
protected array $filters = ["order_by", "status", "type", "sort"];
|
protected array $filters = ["order_by", "status", "type", "sort"];
|
||||||
|
@ -5,9 +5,11 @@ namespace App;
|
|||||||
use Jikan\Jikan;
|
use Jikan\Jikan;
|
||||||
use Jikan\Request\Person\PersonRequest;
|
use Jikan\Request\Person\PersonRequest;
|
||||||
use function Symfony\Component\Translation\t;
|
use function Symfony\Component\Translation\t;
|
||||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
|
|
||||||
class Person extends JikanApiSearchableModel
|
class Person extends JikanApiSearchableModel
|
||||||
{
|
{
|
||||||
|
use HasFactory;
|
||||||
protected array $filters = ["order_by", "sort"];
|
protected array $filters = ["order_by", "sort"];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -39,6 +39,7 @@
|
|||||||
"zircote/swagger-php": "3.*"
|
"zircote/swagger-php": "3.*"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
|
"fakerphp/faker": "^1.20",
|
||||||
"mockery/mockery": "^1.3.1",
|
"mockery/mockery": "^1.3.1",
|
||||||
"phpunit/phpunit": "^8.5"
|
"phpunit/phpunit": "^8.5"
|
||||||
},
|
},
|
||||||
|
71
composer.lock
generated
71
composer.lock
generated
@ -4,7 +4,7 @@
|
|||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "cf4c0d150bce75398ce4300c27d1cdf6",
|
"content-hash": "3471a91d2125954a5be97999b1c3ce12",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "amphp/amp",
|
"name": "amphp/amp",
|
||||||
@ -10945,6 +10945,73 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"packages-dev": [
|
"packages-dev": [
|
||||||
|
{
|
||||||
|
"name": "fakerphp/faker",
|
||||||
|
"version": "v1.20.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/FakerPHP/Faker.git",
|
||||||
|
"reference": "37f751c67a5372d4e26353bd9384bc03744ec77b"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/FakerPHP/Faker/zipball/37f751c67a5372d4e26353bd9384bc03744ec77b",
|
||||||
|
"reference": "37f751c67a5372d4e26353bd9384bc03744ec77b",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": "^7.1 || ^8.0",
|
||||||
|
"psr/container": "^1.0 || ^2.0",
|
||||||
|
"symfony/deprecation-contracts": "^2.2 || ^3.0"
|
||||||
|
},
|
||||||
|
"conflict": {
|
||||||
|
"fzaninotto/faker": "*"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"bamarni/composer-bin-plugin": "^1.4.1",
|
||||||
|
"doctrine/persistence": "^1.3 || ^2.0",
|
||||||
|
"ext-intl": "*",
|
||||||
|
"symfony/phpunit-bridge": "^4.4 || ^5.2"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"doctrine/orm": "Required to use Faker\\ORM\\Doctrine",
|
||||||
|
"ext-curl": "Required by Faker\\Provider\\Image to download images.",
|
||||||
|
"ext-dom": "Required by Faker\\Provider\\HtmlLorem for generating random HTML.",
|
||||||
|
"ext-iconv": "Required by Faker\\Provider\\ru_RU\\Text::realText() for generating real Russian text.",
|
||||||
|
"ext-mbstring": "Required for multibyte Unicode string functionality."
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-main": "v1.20-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Faker\\": "src/Faker/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "François Zaninotto"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Faker is a PHP library that generates fake data for you.",
|
||||||
|
"keywords": [
|
||||||
|
"data",
|
||||||
|
"faker",
|
||||||
|
"fixtures"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/FakerPHP/Faker/issues",
|
||||||
|
"source": "https://github.com/FakerPHP/Faker/tree/v1.20.0"
|
||||||
|
},
|
||||||
|
"time": "2022-07-20T13:12:54+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "hamcrest/hamcrest-php",
|
"name": "hamcrest/hamcrest-php",
|
||||||
"version": "v2.0.1",
|
"version": "v2.0.1",
|
||||||
@ -12426,5 +12493,5 @@
|
|||||||
"ext-mongodb": "*"
|
"ext-mongodb": "*"
|
||||||
},
|
},
|
||||||
"platform-dev": [],
|
"platform-dev": [],
|
||||||
"plugin-api-version": "2.2.0"
|
"plugin-api-version": "2.3.0"
|
||||||
}
|
}
|
||||||
|
102
database/factories/AnimeFactory.php
Normal file
102
database/factories/AnimeFactory.php
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
<?php
|
||||||
|
namespace Database\Factories;
|
||||||
|
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||||
|
use App\Anime;
|
||||||
|
|
||||||
|
|
||||||
|
class AnimeFactory extends Factory
|
||||||
|
{
|
||||||
|
use JikanDataGenerator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The name of the factory's corresponding model.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $model = Anime::class;
|
||||||
|
|
||||||
|
|
||||||
|
public function definition(): array
|
||||||
|
{
|
||||||
|
$mal_id = $this->createMalId();
|
||||||
|
$title = $this->createTitle();
|
||||||
|
$status = $this->faker->randomElement(["Currently Airing", "Completed", "Upcoming"]);
|
||||||
|
[$aired_from, $aired_to] = $this->createActiveDateRange($status, "Currently Airing");
|
||||||
|
|
||||||
|
return [
|
||||||
|
"mal_id" => $mal_id,
|
||||||
|
"url" => $this->createUrl($mal_id, "anime"),
|
||||||
|
"titles" => [
|
||||||
|
[
|
||||||
|
"type" => "Default",
|
||||||
|
"title" => $title
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"title" => $title,
|
||||||
|
"title_english" => $title,
|
||||||
|
"title_japanese" => $title,
|
||||||
|
"title_synonyms" => [$title],
|
||||||
|
"type" => $this->faker->randomElement(["TV", "Movie", "OVA"]),
|
||||||
|
"source" => $this->faker->randomElement(["Manga", "Original", "Novel"]),
|
||||||
|
"episodes" => $this->faker->randomElement([1, 12, 13, 16, 24, 48, 96, 128, 366]),
|
||||||
|
"status" => $status,
|
||||||
|
"airing" => $status == "Currently Airing",
|
||||||
|
"aired" => [
|
||||||
|
"from" => $aired_from->toAtomString(),
|
||||||
|
"to" => $aired_to,
|
||||||
|
],
|
||||||
|
"duration" => "",
|
||||||
|
"rating" => $this->faker->randomElement(["R - 17+ (violence & profanity)", "PG"]),
|
||||||
|
"score" => $this->faker->randomFloat(2, 1.00, 9.99),
|
||||||
|
"scored_by" => $this->faker->randomDigitNotNull(),
|
||||||
|
"rank" => $this->faker->randomDigitNotNull(),
|
||||||
|
"popularity" => $this->faker->randomDigitNotNull(),
|
||||||
|
"members" => $this->faker->randomDigitNotNull(),
|
||||||
|
"favorites" => $this->faker->randomDigitNotNull(),
|
||||||
|
"synopsis" => "test",
|
||||||
|
"background" => "test",
|
||||||
|
"season" => $this->faker->randomElement(["winter", "spring", "fall", "summer"]),
|
||||||
|
"broadcast" => [
|
||||||
|
"day" => "",
|
||||||
|
"time" => "",
|
||||||
|
"timezone" => "Asia/Tokyo",
|
||||||
|
"string" => "Tuesdays at 00:00 (JST)"
|
||||||
|
],
|
||||||
|
"producers" => [
|
||||||
|
[
|
||||||
|
"mal_id" => 16,
|
||||||
|
"type" => "anime",
|
||||||
|
"name" => "TV Tokyo",
|
||||||
|
"url" => "https://myanimelist.net/anime/producer/16/TV_Tokyo"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"lincesors" => [
|
||||||
|
[
|
||||||
|
"mal_id" => 119,
|
||||||
|
"type" => "anime",
|
||||||
|
"name" => "VIZ Media",
|
||||||
|
"url" => "https://myanimelist.net/anime/producer/119/VIZ_Media"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"studios" => [],
|
||||||
|
"genres" => [
|
||||||
|
[
|
||||||
|
"mal_id" => 1,
|
||||||
|
"type" => "anime",
|
||||||
|
"name" => "Action",
|
||||||
|
"url" => "https://myanimelist.net/anime/genre/1/Action"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"explicit_genres" => [],
|
||||||
|
"themes" => [],
|
||||||
|
"demographics" => [
|
||||||
|
[
|
||||||
|
"mal_id" => 27,
|
||||||
|
"type" => "anime",
|
||||||
|
"name" => "Shounen",
|
||||||
|
"url" => "https://myanimelist.net/anime/genre/27/Shounen"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
31
database/factories/CharacterFactory.php
Normal file
31
database/factories/CharacterFactory.php
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Database\Factories;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||||
|
use App\Character;
|
||||||
|
|
||||||
|
|
||||||
|
class CharacterFactory extends Factory
|
||||||
|
{
|
||||||
|
use JikanDataGenerator;
|
||||||
|
|
||||||
|
protected $model = Character::class;
|
||||||
|
|
||||||
|
public function definition()
|
||||||
|
{
|
||||||
|
$mal_id = $this->createMalId();
|
||||||
|
$url = $this->createUrl($mal_id, "character");
|
||||||
|
|
||||||
|
return [
|
||||||
|
"mal_id" => $mal_id,
|
||||||
|
"url" => $url,
|
||||||
|
"images" => [],
|
||||||
|
"name" => $this->faker->name(),
|
||||||
|
"name_kanji" => "岡",
|
||||||
|
"nicknames" => [],
|
||||||
|
"favorites" => $this->faker->randomDigitNotNull(),
|
||||||
|
"about" => "test"
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
9
database/factories/GenreAnimeFactory.php
Normal file
9
database/factories/GenreAnimeFactory.php
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<?php
|
||||||
|
namespace Database\Factories;
|
||||||
|
use App\GenreAnime;
|
||||||
|
|
||||||
|
class GenreAnimeFactory extends GenreFactory
|
||||||
|
{
|
||||||
|
protected $model = GenreAnime::class;
|
||||||
|
protected string $mediaType = "anime";
|
||||||
|
}
|
24
database/factories/GenreFactory.php
Normal file
24
database/factories/GenreFactory.php
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<?php
|
||||||
|
namespace Database\Factories;
|
||||||
|
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||||
|
|
||||||
|
abstract class GenreFactory extends Factory
|
||||||
|
{
|
||||||
|
use JikanDataGenerator;
|
||||||
|
|
||||||
|
protected string $mediaType = "";
|
||||||
|
|
||||||
|
public function definition(): array
|
||||||
|
{
|
||||||
|
$mal_id = $this->createMalId();
|
||||||
|
$name = $this->getRandomGenreName();
|
||||||
|
$url = $this->createUrl($mal_id, $this->mediaType . "/genre");
|
||||||
|
|
||||||
|
return [
|
||||||
|
"mal_id" => $mal_id,
|
||||||
|
"name" => $name,
|
||||||
|
"url" => $url,
|
||||||
|
"count" => $this->faker->randomDigit()
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
9
database/factories/GenreMangaFactory.php
Normal file
9
database/factories/GenreMangaFactory.php
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<?php
|
||||||
|
namespace Database\Factories;
|
||||||
|
use App\GenreManga;
|
||||||
|
|
||||||
|
class GenreMangaFactory extends GenreFactory
|
||||||
|
{
|
||||||
|
protected $model = GenreManga::class;
|
||||||
|
protected string $mediaType = "manga";
|
||||||
|
}
|
129
database/factories/JikanDataGenerator.php
Normal file
129
database/factories/JikanDataGenerator.php
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
<?php
|
||||||
|
namespace Database\Factories;
|
||||||
|
use Faker\Generator;
|
||||||
|
use Illuminate\Support\Carbon;
|
||||||
|
|
||||||
|
trait JikanDataGenerator
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The current Faker instance.
|
||||||
|
*
|
||||||
|
* @var Generator
|
||||||
|
*/
|
||||||
|
protected $faker;
|
||||||
|
private array $dummyGenres = [
|
||||||
|
"Action",
|
||||||
|
"Adventure",
|
||||||
|
"Avant Garde",
|
||||||
|
"Award Winning",
|
||||||
|
"Boys Love",
|
||||||
|
"Comedy",
|
||||||
|
"Drama",
|
||||||
|
"Fantasy",
|
||||||
|
"Girls Love",
|
||||||
|
"Gourmet",
|
||||||
|
"Horror",
|
||||||
|
"Mystery",
|
||||||
|
"Romance",
|
||||||
|
"Sci-Fi",
|
||||||
|
"Slice of Life",
|
||||||
|
"Sports",
|
||||||
|
"Supernatural",
|
||||||
|
"Suspense",
|
||||||
|
"Ecchi",
|
||||||
|
"Erotica",
|
||||||
|
"Hentai",
|
||||||
|
"Adult Cast",
|
||||||
|
"Anthropomorphic",
|
||||||
|
"CGDCT",
|
||||||
|
"Childcare",
|
||||||
|
"Combat Sports",
|
||||||
|
"Crossdressing",
|
||||||
|
"Delinquents",
|
||||||
|
"Detective",
|
||||||
|
"Educational",
|
||||||
|
"Gag Humor",
|
||||||
|
"Gore",
|
||||||
|
"Harem",
|
||||||
|
"High Stakes Game",
|
||||||
|
"Historical",
|
||||||
|
"Idols (Female)",
|
||||||
|
"Idols (Male)",
|
||||||
|
"Isekai",
|
||||||
|
"Iyashikei",
|
||||||
|
"Love Polygon",
|
||||||
|
"Magical Sex Shift",
|
||||||
|
"Mahou Shoujo",
|
||||||
|
"Martial Arts",
|
||||||
|
"Mecha",
|
||||||
|
"Medical",
|
||||||
|
"Military",
|
||||||
|
"Music",
|
||||||
|
"Mythology",
|
||||||
|
"Organized Crime",
|
||||||
|
"Otaku Culture",
|
||||||
|
"Parody",
|
||||||
|
"Performing Arts",
|
||||||
|
"Pets",
|
||||||
|
"Psychological",
|
||||||
|
"Racing",
|
||||||
|
"Reincarnation",
|
||||||
|
"Reverse Harem",
|
||||||
|
"Romantic Subtext",
|
||||||
|
"Samurai",
|
||||||
|
"School",
|
||||||
|
"Showbiz",
|
||||||
|
"Space",
|
||||||
|
"Strategy Game",
|
||||||
|
"Super Power",
|
||||||
|
"Survival",
|
||||||
|
"Team Sports",
|
||||||
|
"Time Travel",
|
||||||
|
"Vampire",
|
||||||
|
"Video Game",
|
||||||
|
"Visual Arts",
|
||||||
|
"Workplace",
|
||||||
|
"Josei",
|
||||||
|
"Kids",
|
||||||
|
"Seinen",
|
||||||
|
"Shoujo",
|
||||||
|
"Shounen"
|
||||||
|
];
|
||||||
|
|
||||||
|
private function createUrl($malId, $type): string
|
||||||
|
{
|
||||||
|
return "https://myanimelist.net/" . $type . "/" . $malId . "/x";
|
||||||
|
}
|
||||||
|
|
||||||
|
private function createMalId(): int
|
||||||
|
{
|
||||||
|
return $this->faker->numberBetween(1, 99999);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function createTitle(): string
|
||||||
|
{
|
||||||
|
return $this->faker->name();
|
||||||
|
}
|
||||||
|
|
||||||
|
private function createRandomDateTime($startDate = "-30 years"): Carbon
|
||||||
|
{
|
||||||
|
return Carbon::createFromTimestamp($this->faker->dateTimeBetween($startDate)->getTimestamp());
|
||||||
|
}
|
||||||
|
|
||||||
|
private function createActiveDateRange($status, $activeStatus): array
|
||||||
|
{
|
||||||
|
$from = $this->createRandomDateTime("-15 years");
|
||||||
|
$to = $status != $activeStatus ? $from->addDays($this->faker->numberBetween(1, 368))->toAtomString() : null;
|
||||||
|
return [$from, $to];
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getRandomGenreName(): string
|
||||||
|
{
|
||||||
|
return $this->faker->randomElement($this->dummyGenres);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getRandomGenreNames($count = 1): array
|
||||||
|
{
|
||||||
|
return $this->faker->randomElements($this->dummyGenres, $count);
|
||||||
|
}
|
||||||
|
}
|
85
database/factories/MangaFactory.php
Normal file
85
database/factories/MangaFactory.php
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
<?php
|
||||||
|
namespace Database\Factories;
|
||||||
|
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||||
|
use App\Manga;
|
||||||
|
|
||||||
|
class MangaFactory extends Factory
|
||||||
|
{
|
||||||
|
use JikanDataGenerator;
|
||||||
|
|
||||||
|
protected $model = Manga::class;
|
||||||
|
|
||||||
|
public function definition()
|
||||||
|
{
|
||||||
|
$mal_id = $this->createMalId();
|
||||||
|
$title = $this->createTitle();
|
||||||
|
$status = $this->faker->randomElement(["Finished", "Publishing", "Upcoming"]);
|
||||||
|
[$published_from, $published_to] = $this->createActiveDateRange($status, "Publishing");
|
||||||
|
|
||||||
|
return [
|
||||||
|
"mal_id" => $mal_id,
|
||||||
|
"url" => $this->createUrl($mal_id, "manga"),
|
||||||
|
"titles" => [
|
||||||
|
[
|
||||||
|
"type" => "Default",
|
||||||
|
"title" => $title
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"title" => $title,
|
||||||
|
"title_english" => $title,
|
||||||
|
"title_japanese" => $title,
|
||||||
|
"title_synonyms" => [$title],
|
||||||
|
"type" => $this->faker->randomElement(["Manga", "Light Novel", "Web Novel"]),
|
||||||
|
"chapters" => $this->faker->numberBetween(1, 255),
|
||||||
|
"volumes" => $this->faker->numberBetween(0, 55),
|
||||||
|
"status" => $status,
|
||||||
|
"publishing" => $status === "Finished",
|
||||||
|
"published" => [
|
||||||
|
"from" => $published_from->toAtomString(),
|
||||||
|
"to" => $published_to
|
||||||
|
],
|
||||||
|
"score" => $this->faker->randomFloat(2, 1.00, 9.99),
|
||||||
|
"scored_by" => $this->faker->randomDigitNotNull(),
|
||||||
|
"rank" => $this->faker->randomDigitNotNull(),
|
||||||
|
"popularity" => $this->faker->randomDigitNotNull(),
|
||||||
|
"members" => $this->faker->randomDigitNotNull(),
|
||||||
|
"favorites" => $this->faker->randomDigitNotNull(),
|
||||||
|
"synopsis" => "test",
|
||||||
|
"background" => "test",
|
||||||
|
"authors" => [
|
||||||
|
[
|
||||||
|
"mal_id" => 1874,
|
||||||
|
"type" => "people",
|
||||||
|
"name" => "Arakawa, Hiromu",
|
||||||
|
"url" => "https://myanimelist.net/people/1847/Hiromu_Arakawa"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"serializations" => [
|
||||||
|
[
|
||||||
|
"mal_id" => 13,
|
||||||
|
"type" => "manga",
|
||||||
|
"name" => "Shounen Gangan",
|
||||||
|
"url" => "https://myanimelist.net/manga/magazine/13/Shounen_Gangan"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"genres" => [
|
||||||
|
[
|
||||||
|
"mal_id" => 1,
|
||||||
|
"type" => "anime",
|
||||||
|
"name" => "Action",
|
||||||
|
"url" => "https://myanimelist.net/anime/genre/1/Action"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"explicit_genres" => [],
|
||||||
|
"themes" => [],
|
||||||
|
"demographics" => [
|
||||||
|
[
|
||||||
|
"mal_id" => 27,
|
||||||
|
"type" => "manga",
|
||||||
|
"name" => "Shounen",
|
||||||
|
"url" => "https://myanimelist.net/manga/genre/27/Shounen"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
39
database/factories/PersonFactory.php
Normal file
39
database/factories/PersonFactory.php
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
<?php
|
||||||
|
namespace Database\Factories;
|
||||||
|
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||||
|
use App\Person;
|
||||||
|
|
||||||
|
|
||||||
|
class PersonFactory extends Factory
|
||||||
|
{
|
||||||
|
use JikanDataGenerator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The name of the factory's corresponding model.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $model = Person::class;
|
||||||
|
|
||||||
|
public function definition(): array
|
||||||
|
{
|
||||||
|
$mal_id = $this->createMalId();
|
||||||
|
$name = $this->faker->name();
|
||||||
|
$given_name = $this->faker->firstName();
|
||||||
|
$family_name = $this->faker->lastName();
|
||||||
|
|
||||||
|
return [
|
||||||
|
"mal_id" => $mal_id,
|
||||||
|
"url" => $this->createUrl($mal_id, "people"),
|
||||||
|
"website_url" => "https://webiste.example",
|
||||||
|
"images" => [],
|
||||||
|
"name" => $name,
|
||||||
|
"given_name" => $given_name,
|
||||||
|
"family_name" => $family_name,
|
||||||
|
"alternate_names" => [],
|
||||||
|
"birthday" => $this->createRandomDateTime("-80 years")->toAtomString(),
|
||||||
|
"favorites" => $this->faker->randomDigitNotNull(),
|
||||||
|
"about" => "test"
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
57
tests/AnimeSearchEndpointTest.php
Normal file
57
tests/AnimeSearchEndpointTest.php
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
<?php
|
||||||
|
use Laravel\Lumen\Testing\DatabaseMigrations;
|
||||||
|
use App\Anime;
|
||||||
|
|
||||||
|
class AnimeSearchEndpointTest extends TestCase
|
||||||
|
{
|
||||||
|
use DatabaseMigrations;
|
||||||
|
|
||||||
|
public function limitParameterCombinationsProvider(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
[5, []],
|
||||||
|
[5, ["type" => "tv"]],
|
||||||
|
[5, ["type" => "tv", "min_score" => 7]],
|
||||||
|
[5, ["type" => "tv", "max_score" => 6]],
|
||||||
|
[5, ["type" => "tv", "status" => "complete", "max_score" => 8]],
|
||||||
|
[5, ["type" => "movie", "status" => "complete", "max_score" => 8]]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
public function shouldReturnMethodNotAllowedResponseIfMethodNotAllowed()
|
||||||
|
{
|
||||||
|
$this->json("POST", "/v4/anime", ["title" => "Dum"])
|
||||||
|
->seeStatusCode(405);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider limitParameterCombinationsProvider
|
||||||
|
*/
|
||||||
|
public function testLimitParameter(int $limitCount, array $additionalParams)
|
||||||
|
{
|
||||||
|
$f = Anime::factory()->count(25);
|
||||||
|
$overrides = [];
|
||||||
|
// let's make all database items the same type
|
||||||
|
if (array_key_exists("type", $additionalParams)) {
|
||||||
|
$overrides["type"] = $additionalParams["type"];
|
||||||
|
}
|
||||||
|
$f->make($overrides);
|
||||||
|
$parameters = http_build_query([
|
||||||
|
"limit" => $limitCount,
|
||||||
|
...$additionalParams
|
||||||
|
]);
|
||||||
|
$uri = "/v4/anime?" . $parameters;
|
||||||
|
$sut = $this->getJson($uri);
|
||||||
|
$content = $sut->response->json();
|
||||||
|
|
||||||
|
$sut->seeStatusCode(200);
|
||||||
|
$sut->response->assertJsonPath("pagination.items.count", $limitCount);
|
||||||
|
$sut->response->assertJsonPath("pagination.items.total", 25);
|
||||||
|
$sut->response->assertJsonPath("pagination.items.per_page", $limitCount);
|
||||||
|
$this->assertIsArray($content["data"]);
|
||||||
|
$this->assertCount($limitCount, $content["data"]);
|
||||||
|
}
|
||||||
|
}
|
15
tests/MakesHttpRequestsEx.php
Normal file
15
tests/MakesHttpRequestsEx.php
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
trait MakesHttpRequestsEx
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Visit the given URI with a JSON GET request.
|
||||||
|
* @param string $uri
|
||||||
|
* @param array $headers
|
||||||
|
* @return TestCase
|
||||||
|
*/
|
||||||
|
public function getJson(string $uri, array $headers = []): TestCase
|
||||||
|
{
|
||||||
|
return $this->json('GET', $uri, [], $headers);
|
||||||
|
}
|
||||||
|
}
|
@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
abstract class TestCase extends Laravel\Lumen\Testing\TestCase
|
abstract class TestCase extends Laravel\Lumen\Testing\TestCase
|
||||||
{
|
{
|
||||||
|
use MakesHttpRequestsEx;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates the application.
|
* Creates the application.
|
||||||
*
|
*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user