fixed tests part1

This commit is contained in:
pushrbx 2023-01-27 21:51:39 +00:00
parent 1e302fb62c
commit 5e922f7cd9
20 changed files with 210 additions and 145 deletions

View File

@ -1,7 +1,7 @@
[![Jikan](https://i.imgur.com/ccx3pxo.png)](#jikan-rest-api-v4---unofficial-myanimelistnet-rest-api)
# Jikan REST API v4 - Unofficial MyAnimeList.net REST API
[![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/jikan-me/jikan-rest.svg)](http://isitmaintained.com/project/jikan-me/jikan-rest "Average time to resolve an issue") [![Percentage of issues still open](http://isitmaintained.com/badge/open/jikan-me/jikan-rest.svg)](http://isitmaintained.com/project/jikan-me/jikan-rest "Percentage of issues still open") [![stable](https://img.shields.io/badge/PHP-^8.0-blue.svg?style=flat)]() [![Discord Server](https://img.shields.io/discord/460491088004907029.svg?style=flat&logo=discord)](https://discordapp.com/invite/4tvCr36)
[![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/jikan-me/jikan-rest.svg)](http://isitmaintained.com/project/jikan-me/jikan-rest "Average time to resolve an issue") [![Percentage of issues still open](http://isitmaintained.com/badge/open/jikan-me/jikan-rest.svg)](http://isitmaintained.com/project/jikan-me/jikan-rest "Percentage of issues still open") [![stable](https://img.shields.io/badge/PHP-^8.1-blue.svg?style=flat)]() [![Discord Server](https://img.shields.io/discord/460491088004907029.svg?style=flat&logo=discord)](https://discordapp.com/invite/4tvCr36)
Jikan is a REST API for [MyAnimeList.net](https://myanimelist.net). It scrapes the website to satisfy the need for API functionality that MyAnimeList.net lacks.
@ -25,7 +25,7 @@ Please read the [manual installation guide](https://github.com/jikan-me/jikan-re
For any additional help, join our [Discord server](http://discord.jikan.moe/).
### 🐳 Docker Installation
We distribute the app as a container image so you can just run it:
We distribute the app as a container image, so you can just run it:
```bash
docker run -d --name=jikan-rest -p 8080:8080 -v ./.env:/app/.env jikanme/jikan-rest:latest
```

View File

@ -18,7 +18,7 @@ class Anime extends JikanApiSearchableModel
{
use HasFactory, MediaFilters, FilteredByLetter;
protected array $filters = ["order_by", "status", "type", "sort", "max_score", "min_score", "score", "rating", "start_date", "end_date", "producer", "producers", "letter"];
protected array $filters = ["order_by", "status", "type", "sort", "max_score", "min_score", "score", "rating", "start_date", "end_date", "producer", "producers", "letter", "genres", "genres_exclude"];
/**
* The attributes that are mass assignable.
*
@ -133,12 +133,6 @@ class Anime extends JikanApiSearchableModel
];
}
/** @noinspection PhpUnused */
public function filterByLetter(\Laravel\Scout\Builder|\Illuminate\Database\Eloquent\Builder $query, string $value): \Laravel\Scout\Builder|\Illuminate\Database\Eloquent\Builder
{
return $query->where("title", "like", "{$value}%");
}
/** @noinspection PhpUnused */
public function filterByType(\Laravel\Scout\Builder|\Illuminate\Database\Eloquent\Builder $query, AnimeTypeEnum $value): \Laravel\Scout\Builder|\Illuminate\Database\Eloquent\Builder
{
@ -152,15 +146,15 @@ class Anime extends JikanApiSearchableModel
}
/** @noinspection PhpUnused */
public function filterByStartDate(\Laravel\Scout\Builder|\Illuminate\Database\Eloquent\Builder $query, CarbonImmutable $date): \Laravel\Scout\Builder|\Illuminate\Database\Eloquent\Builder
public function filterByStartDate(\Laravel\Scout\Builder|\Illuminate\Database\Eloquent\Builder $query, CarbonImmutable $value): \Laravel\Scout\Builder|\Illuminate\Database\Eloquent\Builder
{
return $query->where("aired.from", $date->setTime(0, 0)->toAtomString());
return $query->where("aired.from", ">=", $value->setTime(0, 0)->toAtomString());
}
/** @noinspection PhpUnused */
public function filterByEndDate(\Laravel\Scout\Builder|\Illuminate\Database\Eloquent\Builder $query, CarbonImmutable $date): \Laravel\Scout\Builder|\Illuminate\Database\Eloquent\Builder
public function filterByEndDate(\Laravel\Scout\Builder|\Illuminate\Database\Eloquent\Builder $query, CarbonImmutable $value): \Laravel\Scout\Builder|\Illuminate\Database\Eloquent\Builder
{
return $query->where("aired.to", $date->setTime(0, 0)->toAtomString());
return $query->where("aired.to", "<=", $value->setTime(0, 0)->toAtomString());
}
public function filterByProducer(\Laravel\Scout\Builder|\Illuminate\Database\Eloquent\Builder $query, string $value): \Laravel\Scout\Builder|\Illuminate\Database\Eloquent\Builder

View File

@ -8,11 +8,21 @@ trait MediaFilters
{
public function filterByMaxScore(\Laravel\Scout\Builder|\Illuminate\Database\Eloquent\Builder $query, mixed $value): \Laravel\Scout\Builder|\Illuminate\Database\Eloquent\Builder
{
// if the client specifies the "max" possible value, ignore it, in that case they want everything included
// https://github.com/jikan-me/jikan-rest/issues/309
if (floatval($value) == 10) {
return $query;
}
return $query->where("score", "<=", floatval($value));
}
public function filterByMinScore(\Laravel\Scout\Builder|\Illuminate\Database\Eloquent\Builder $query, mixed $value): \Laravel\Scout\Builder|\Illuminate\Database\Eloquent\Builder
{
// if the client specifies the "max" possible value, ignore it, in that case they want everything included
// https://github.com/jikan-me/jikan-rest/issues/309
if (floatval($value) == 0) {
return $query;
}
return $query->where("score", ">=", floatval($value));
}

View File

@ -10,6 +10,6 @@ trait ResolvesPaginatorParams
$limit = $limit ?? $default_max_results_per_page;
$page = $page ?? 1;
return compact($limit, $page);
return compact("limit", "page");
}
}

View File

@ -7,6 +7,7 @@ use App\Enums\AnimeOrderByEnum;
use App\Enums\AnimeRatingEnum;
use App\Enums\AnimeStatusEnum;
use App\Http\Resources\V4\AnimeCollection;
use App\Rules\Attributes\EnumValidation;
use Spatie\Enum\Laravel\Rules\EnumRule;
use Spatie\LaravelData\Attributes\MapInputName;
use Spatie\LaravelData\Attributes\MapOutputName;
@ -23,10 +24,10 @@ use Spatie\LaravelData\Optional;
*/
final class AnimeSearchCommand extends MediaSearchCommand implements DataRequest
{
#[WithCast(EnumCast::class, AnimeStatusEnum::class)]
#[WithCast(EnumCast::class, AnimeStatusEnum::class), EnumValidation(AnimeStatusEnum::class)]
public AnimeStatusEnum|Optional $status;
#[WithCast(EnumCast::class, AnimeRatingEnum::class)]
#[WithCast(EnumCast::class, AnimeRatingEnum::class), EnumValidation(AnimeRatingEnum::class)]
public AnimeRatingEnum|Optional $rating;
#[IntegerType, Min(1)]
@ -35,16 +36,11 @@ final class AnimeSearchCommand extends MediaSearchCommand implements DataRequest
#[Prohibits("producer"), StringType]
public string|Optional $producers;
#[MapInputName("order_by"), MapOutputName("order_by"), WithCast(EnumCast::class, AnimeOrderByEnum::class)]
#[
MapInputName("order_by"),
MapOutputName("order_by"),
WithCast(EnumCast::class, AnimeOrderByEnum::class),
EnumValidation(AnimeOrderByEnum::class)
]
public AnimeOrderByEnum|Optional $orderBy;
public static function rules(): array
{
return [
...parent::rules(),
"status" => [new EnumRule(AnimeStatusEnum::class)],
"rating" => [new EnumRule(AnimeRatingEnum::class)],
"order_by" => [new EnumRule(AnimeOrderByEnum::class)]
];
}
}

View File

@ -7,6 +7,7 @@ use App\Contracts\DataRequest;
use App\Enums\MangaOrderByEnum;
use App\Enums\MangaStatusEnum;
use App\Http\Resources\V4\MangaCollection;
use App\Rules\Attributes\EnumValidation;
use Spatie\Enum\Laravel\Rules\EnumRule;
use Spatie\LaravelData\Attributes\MapInputName;
use Spatie\LaravelData\Attributes\MapOutputName;
@ -19,21 +20,17 @@ use Spatie\LaravelData\Optional;
*/
final class MangaSearchCommand extends MediaSearchCommand implements DataRequest
{
#[WithCast(EnumCast::class, MangaStatusEnum::class)]
#[WithCast(EnumCast::class, MangaStatusEnum::class), EnumValidation(MangaStatusEnum::class)]
public MangaStatusEnum|Optional $status;
#[StringType]
public string|Optional $magazines;
#[MapInputName("order_by"), MapOutputName("order_by"), WithCast(EnumCast::class, MangaOrderByEnum::class)]
#[
MapInputName("order_by"),
MapOutputName("order_by"),
EnumValidation(MangaOrderByEnum::class),
WithCast(EnumCast::class, MangaOrderByEnum::class)
]
public MangaOrderByEnum|Optional $orderBy;
public static function rules(): array
{
return [
...parent::rules(),
"status" => new EnumRule(MangaStatusEnum::class),
"order_by" => new EnumRule(MangaOrderByEnum::class)
];
}
}

View File

@ -3,16 +3,17 @@
namespace App\Dto;
use Carbon\CarbonImmutable;
use Illuminate\Validation\Validator;
use Spatie\LaravelData\Attributes\MapInputName;
use Spatie\LaravelData\Attributes\MapOutputName;
use Spatie\LaravelData\Attributes\Validation\AfterOrEqual;
use Spatie\LaravelData\Attributes\Validation\BeforeOrEqual;
use Spatie\LaravelData\Attributes\Validation\Between;
use Spatie\LaravelData\Attributes\Validation\DateFormat;
use Spatie\LaravelData\Attributes\Validation\GreaterThanOrEqualTo;
use Spatie\LaravelData\Attributes\Validation\LessThanOrEqualTo;
use Spatie\LaravelData\Attributes\Validation\Numeric;
use Spatie\LaravelData\Attributes\Validation\Prohibits;
use Spatie\LaravelData\Attributes\Validation\Required;
use Spatie\LaravelData\Attributes\Validation\Sometimes;
use Spatie\LaravelData\Attributes\WithCast;
use Spatie\LaravelData\Attributes\WithTransformer;
use Spatie\LaravelData\Casts\DateTimeInterfaceCast;
@ -21,10 +22,10 @@ use Spatie\LaravelData\Transformers\DateTimeInterfaceTransformer;
class MediaSearchCommand extends SearchCommand
{
#[MapInputName("min_score"), MapOutputName("min_score"), Between(1.00, 9.99), Numeric]
#[MapInputName("min_score"), MapOutputName("min_score"), Between(0.00, 10.00), Numeric]
public float|Optional $minScore;
#[MapInputName("max_score"), MapOutputName("max_score"), Between(1.00, 9.99), Numeric]
#[MapInputName("max_score"), MapOutputName("max_score"), Between(1.00, 10.00), Numeric]
public float|Optional $maxScore;
#[Between(1.00, 9.99), Numeric, Prohibits(["min_score", "max_score"])]
@ -37,11 +38,29 @@ class MediaSearchCommand extends SearchCommand
#[MapInputName("genres_exclude"), MapOutputName("genres_exclude")]
public string|Optional $genresExclude;
#[WithCast(DateTimeInterfaceCast::class), WithTransformer(DateTimeInterfaceTransformer::class)]
#[BeforeOrEqual("end_date"), DateFormat("Y-m-d")]
#[
BeforeOrEqual("end_date"),
DateFormat("Y-m-d"),
Sometimes,
Required,
WithCast(DateTimeInterfaceCast::class),
WithTransformer(DateTimeInterfaceTransformer::class)
]
public CarbonImmutable|Optional $start_date;
#[WithCast(DateTimeInterfaceCast::class), WithTransformer(DateTimeInterfaceTransformer::class)]
#[AfterOrEqual("start_date"), DateFormat("Y-m-d")]
#[
AfterOrEqual("start_date"),
DateFormat("Y-m-d"),
Sometimes,
Required,
WithCast(DateTimeInterfaceCast::class),
WithTransformer(DateTimeInterfaceTransformer::class)
]
public CarbonImmutable|Optional $end_date;
public static function withValidator(Validator $validator): void
{
$validator->sometimes("min_score", "lte:max_score", fn ($input) => !empty($input->max_score));
$validator->sometimes("max_score", "gte:min_score", fn ($input) => !empty($input->min_score));
}
}

View File

@ -6,6 +6,7 @@ use App\Casts\EnumCast;
use App\Dto\Concerns\HasLimitParameter;
use App\Dto\Concerns\HasPageParameter;
use App\Enums\SortDirection;
use App\Rules\Attributes\EnumValidation;
use Spatie\Enum\Laravel\Rules\EnumRule;
use Spatie\LaravelData\Attributes\Validation\Alpha;
use Spatie\LaravelData\Attributes\Validation\Max;
@ -26,16 +27,9 @@ class SearchCommand extends Data
#[Max(255), StringType]
public string|Optional $q;
#[WithCast(EnumCast::class, SortDirection::class)]
#[WithCast(EnumCast::class, SortDirection::class), EnumValidation(SortDirection::class)]
public SortDirection|Optional $sort;
#[Size(1), StringType, Alpha]
public string|Optional $letter;
public static function rules(): array
{
return [
"sort" => [new EnumRule(SortDirection::class)]
];
}
}

View File

@ -7,6 +7,7 @@ use App\Concerns\HasRequestFingerprint;
use App\Contracts\DataRequest;
use App\Enums\GenderEnum;
use App\Http\Resources\V4\UserCollection;
use App\Rules\Attributes\EnumValidation;
use Spatie\Enum\Laravel\Rules\EnumRule;
use Spatie\LaravelData\Attributes\Validation\StringType;
use Spatie\LaravelData\Attributes\WithCast;
@ -23,17 +24,9 @@ final class UsersSearchCommand extends SearchCommand implements DataRequest
public int|Optional $maxAge;
#[WithCast(EnumCast::class, GenderEnum::class)]
#[WithCast(EnumCast::class, GenderEnum::class), EnumValidation(GenderEnum::class)]
public GenderEnum|Optional $gender;
#[StringType]
public string|Optional $location;
public static function rules(): array
{
return [
...parent::rules(),
"gender" => [new EnumRule(GenderEnum::class)]
];
}
}

View File

@ -115,6 +115,7 @@ class GithubReport
"Please fill out the details below.\n\n**Summary:**\n\n**Steps to reproduce:**\n\n\n\n ### Additional Details \n **Jikan Parser Version**: ```{$this->jikanVersion}```\n**PHP:** ```{$this->phpVersion}```\n**Redis**: ```{$this->redisRunning}```\n**Exception:** ```{$this->name}```\n**Code:** ```{$this->code}```\n**Message:** ```{$this->error}```\n**Trace:** ```{$this->trace}```\n**Request:** `{$this->requestMethod} {$this->requestUri}`\n"
);
// https://github.com/jikan-me/jikan-rest/issues/new?assignees=&labels=i%3A+bug%2C+i%3A+needs+triage&template=bug.md&title=
return "https://github.com/{$this->repo}/issues/new?title={$title}&body={$body}";
}

View File

@ -113,9 +113,9 @@ class Handler extends ExceptionHandler
return response()
->json([
'status' => 400,
'type' => 'BadRequestException',
'message' => $e->getMessage(),
'error' => null
'type' => 'ValidationException',
'messages' => $e->validator->getMessageBag()->getMessages(),
'error' => 'Invalid or incomplete request. Make sure your request is correct. https://docs.api.jikan.moe/'
], 400);
}

View File

@ -18,6 +18,10 @@ trait FilterResolver
private function resolveCustomFilter($filterName, $values)
{
$filterMethodName = "filterBy" . ucfirst(Str::camel($filterName));
if (method_exists($this, $filterMethodName)) {
$filterName = $filterMethodName;
}
return $this->getClosure($this->makeCallable($filterName), $values);
}

View File

@ -16,7 +16,7 @@ class Manga extends JikanApiSearchableModel
{
use HasFactory, MediaFilters, FilteredByLetter;
protected array $filters = ["order_by", "status", "type", "sort", "max_score", "min_score", "score", "start_date", "end_date", "magazine", "magazines", "letter"];
protected array $filters = ["order_by", "status", "type", "sort", "max_score", "min_score", "score", "start_date", "end_date", "magazine", "magazines", "letter", "genres", "genres_exclude"];
/**
* The attributes that are mass assignable.
@ -58,15 +58,15 @@ class Manga extends JikanApiSearchableModel
}
/** @noinspection PhpUnused */
public function filterByStartDate(\Laravel\Scout\Builder|\Illuminate\Database\Eloquent\Builder $query, CarbonImmutable $date): \Laravel\Scout\Builder|\Illuminate\Database\Eloquent\Builder
public function filterByStartDate(\Laravel\Scout\Builder|\Illuminate\Database\Eloquent\Builder $query, CarbonImmutable $value): \Laravel\Scout\Builder|\Illuminate\Database\Eloquent\Builder
{
return $query->where("published.from", $date->setTime(0, 0)->toAtomString());
return $query->where("published.from", ">=", $value->setTime(0, 0)->toAtomString());
}
/** @noinspection PhpUnused */
public function filterByEndDate(\Laravel\Scout\Builder|\Illuminate\Database\Eloquent\Builder $query, CarbonImmutable $date): \Laravel\Scout\Builder|\Illuminate\Database\Eloquent\Builder
public function filterByEndDate(\Laravel\Scout\Builder|\Illuminate\Database\Eloquent\Builder $query, CarbonImmutable $value): \Laravel\Scout\Builder|\Illuminate\Database\Eloquent\Builder
{
return $query->where("published.to", $date->setTime(0, 0)->toAtomString());
return $query->where("published.to", "<=", $value->setTime(0, 0)->toAtomString());
}
public function filterByMagazine(\Laravel\Scout\Builder|\Illuminate\Database\Eloquent\Builder $query, string $value): \Laravel\Scout\Builder|\Illuminate\Database\Eloquent\Builder

View File

@ -15,7 +15,6 @@ use App\Contracts\Repository;
use App\Contracts\RequestHandler;
use App\Contracts\UnitOfWork;
use App\Contracts\UserRepository;
use App\Http\Middleware\EndpointCacheTtlMiddleware;
use App\Macros\CollectionOffsetGetFirst;
use App\Macros\ResponseJikanCacheFlags;
use App\Macros\To2dArrayWithDottedKeys;
@ -30,6 +29,7 @@ use App\Repositories\DefaultPeopleRepository;
use App\Repositories\DefaultProducerRepository;
use App\Repositories\DefaultUserRepository;
use App\Repositories\MangaGenresRepository;
use App\Services\DefaultBuilderPaginatorService;
use App\Services\DefaultCachedScraperService;
use App\Services\DefaultQueryBuilderService;
use App\Services\DefaultScoutSearchService;
@ -82,11 +82,7 @@ class AppServiceProvider extends ServiceProvider
// cache options class is used to share the request scope level cache settings
$this->app->singleton(CacheOptions::class);
$this->app->singleton(CachedScraperService::class, DefaultCachedScraperService::class);
if ($this->getSearchIndexesEnabledConfig($this->app)) {
$this->app->bind(QueryBuilderPaginatorService::class, ScoutBuilderPaginatorService::class);
} else {
$this->app->bind(QueryBuilderPaginatorService::class, EloquentBuilderPaginatorService::class);
}
$this->app->bind(QueryBuilderPaginatorService::class, DefaultBuilderPaginatorService::class);
$this->registerModelRepositories();
$this->registerRequestHandlers();
}

View File

@ -0,0 +1,16 @@
<?php
namespace App\Rules\Attributes;
use Attribute;
use Spatie\Enum\Laravel\Rules\EnumRule;
use Spatie\LaravelData\Attributes\Validation\Rule;
#[Attribute(Attribute::TARGET_PROPERTY)]
final class EnumValidation extends Rule
{
public function __construct(string $enumClass)
{
parent::__construct(new EnumRule($enumClass));
}
}

View File

@ -0,0 +1,23 @@
<?php
namespace App\Services;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
final class DefaultBuilderPaginatorService implements QueryBuilderPaginatorService
{
public function __construct(
private readonly EloquentBuilderPaginatorService $eloquentBuilderPaginatorService,
private readonly ScoutBuilderPaginatorService $scoutBuilderPaginatorService)
{
}
public function paginate(\Illuminate\Database\Eloquent\Builder|\Laravel\Scout\Builder $builder, ?int $limit = null, ?int $page = null): LengthAwarePaginator
{
if ($builder instanceof \Laravel\Scout\Builder) {
return $this->scoutBuilderPaginatorService->paginate($builder, $limit, $page);
}
return $this->eloquentBuilderPaginatorService->paginate($builder, $limit, $page);
}
}

View File

@ -5,7 +5,7 @@ namespace App\Services;
use App\Concerns\ResolvesPaginatorParams;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
class ScoutBuilderPaginatorService implements QueryBuilderPaginatorService
final class ScoutBuilderPaginatorService implements QueryBuilderPaginatorService
{
use ResolvesPaginatorParams;

View File

@ -3,7 +3,9 @@
namespace Database\Factories;
use App\CarbonDateRange;
use App\Http\QueryBuilder\AnimeSearchQueryBuilder;
use App\Enums\AnimeRatingEnum;
use App\Enums\AnimeTypeEnum;
use App\Enums\MangaTypeEnum;
use App\Testing\JikanDataGenerator;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Carbon;
@ -88,7 +90,7 @@ abstract class JikanMediaModelFactory extends JikanModelFactory implements Media
return fn($i) => $randomDate->copy()->addDays($i);
})()),
"rating" => ((function() {
$validRatingItems = array_values(AnimeSearchQueryBuilder::MAP_RATING);
$validRatingItems = AnimeRatingEnum::toValues();
$validRatingItemsCount = count($validRatingItems);
return fn($i) => $validRatingItems[$i % $validRatingItemsCount];
})()),
@ -98,7 +100,7 @@ abstract class JikanMediaModelFactory extends JikanModelFactory implements Media
return fn($i) => $alphabet[$i % $alphabetCount];
})()),
"type" => ((function() {
$types = array_values(AnimeSearchQueryBuilder::MAP_TYPES);
$types = $this->modelName() === "App\Anime" ? AnimeTypeEnum::toValues() : MangaTypeEnum::toValues();
$typesCount = count($types);
return fn($i) => $types[$i % $typesCount];
})()),

View File

@ -53,11 +53,19 @@ class AnimeSearchEndpointTest extends TestCase
];
}
public function partialDatesParameterProvider(): array
{
return [
[["start_date" => "2012"]],
[["start_date" => "2012-05"]],
[["end_date" => "2015"]],
[["end_date" => "2015-05"]]
];
}
public function startDatesParameterProvider(): array
{
return [
[["start_date" => "2022"]],
[["start_date" => "2012-05"]],
[["start_date" => "2012-05-12"]],
[["start_date" => "2012-04-01"]],
[["start_date" => "2012-04-28"]],
@ -68,8 +76,6 @@ class AnimeSearchEndpointTest extends TestCase
public function endDatesParameterProvider(): array
{
return [
[["end_date" => "2022"]],
[["end_date" => "2012-05"]],
[["end_date" => "2012-05-12"]],
[["end_date" => "2012-05-12", "page" => 1]],
];
@ -78,8 +84,6 @@ class AnimeSearchEndpointTest extends TestCase
public function startAndEndDatesParameterProvider(): array
{
return [
[["start_date" => "2021", "end_date" => "2022"]],
[["start_date" => "2021-01", "end_date" => "2021-02"]],
[["start_date" => "2021-01-01", "end_date" => "2021-03-22"]],
[["start_date" => "2021-01-01", "end_date" => "2021-03-22", "page" => 1]],
];
@ -127,10 +131,10 @@ class AnimeSearchEndpointTest extends TestCase
public function invalidScoreParameterProvider(): array
{
return [
[["max_score" => "634638"], 15],
[["min_score" => "673473"], 0],
[["max_score" => "72344", "min_score" => "3532325"], 0],
[["max_score" => 1, "min_score" => 5], 0],
[["max_score" => "634638"]],
[["min_score" => "673473"]],
[["max_score" => "72344", "min_score" => "3532325"]],
[["max_score" => 1, "min_score" => 5]],
];
}
@ -198,15 +202,26 @@ class AnimeSearchEndpointTest extends TestCase
/**
* @dataProvider emptyDateRangeProvider
*/
public function testSearchByEmptyDatesShouldDoNothing($params)
public function testSearchByEmptyDatesShouldRaiseValidationError($params)
{
$this->generateFiveSpecificAndTenRandomElementsInDb($params);
$content = $this->getJsonResponse($params);
$this->seeStatusCode(200);
$this->assertPaginationData(15);
$this->assertCount(15, $content["data"]);
$this->seeStatusCode(400);
$this->assertEquals("ValidationException", data_get($content, "type"));
}
/**
* @dataProvider partialDatesParameterProvider
*/
public function testSearchByStartDateShouldRaiseIfPartialDate($params)
{
$this->generateFiveSpecificAndTenRandomElementsInDb($params);
$content = $this->getJsonResponse($params);
$this->seeStatusCode(400);
$this->assertEquals("ValidationException", data_get($content, "type"));
}
/**
@ -345,25 +360,20 @@ class AnimeSearchEndpointTest extends TestCase
$this->generateFiveSpecificAndTenRandomElementsInDb($params);
$content = $this->getJsonResponse($params);
$this->seeStatusCode(200);
$this->assertPaginationData(15);
$this->assertIsArray($content["data"]);
// it should return all, and disregard the gibberish filter
$this->assertCount(15, $content["data"]);
$this->seeStatusCode(400);
$this->assertEquals("ValidationException", data_get($content, "type"));
}
/**
* @dataProvider invalidScoreParameterProvider
*/
public function testSearchByInvalidScoreParameters($params, $expectedCount)
public function testSearchByInvalidScoreParameters($params)
{
$this->generateFiveSpecificAndTenRandomElementsInDb($params);
$content = $this->getJsonResponse($params);
$this->seeStatusCode(200);
$this->assertPaginationData($expectedCount);
$this->assertIsArray($content["data"]);
$this->assertCount($expectedCount, $content["data"]);
$this->seeStatusCode(400);
$this->assertEquals("ValidationException", data_get($content, "type"));
}
/**
@ -489,10 +499,8 @@ class AnimeSearchEndpointTest extends TestCase
$this->generateFiveSpecificAndTenRandomElementsInDb($params);
$content = $this->getJsonResponse($params);
$this->seeStatusCode(200);
$this->assertPaginationData($expectedCount);
$this->assertIsArray($content["data"]);
$this->assertCount($expectedCount, $content["data"]);
$this->seeStatusCode(400);
$this->assertEquals("ValidationException", data_get($content, "type"));
}
/**
@ -511,7 +519,6 @@ class AnimeSearchEndpointTest extends TestCase
public function testSearchByInvalidLetterParameter()
{
$expectedCount = 0;
$this->generateFiveSpecificAndTenRandomElementsInDb([
"letter" => "a"
]);
@ -519,10 +526,8 @@ class AnimeSearchEndpointTest extends TestCase
"letter" => "asd"
]);
$this->seeStatusCode(200);
$this->assertPaginationData($expectedCount);
$this->assertIsArray($content["data"]);
$this->assertCount($expectedCount, $content["data"]);
$this->seeStatusCode(400);
$this->assertEquals("ValidationException", data_get($content, "type"));
}
public function testTypeSenseSearchPagination()

View File

@ -55,11 +55,19 @@ class MangaSearchEndpointTest extends TestCase
];
}
public function partialDatesParameterProvider(): array
{
return [
[["start_date" => "2012"]],
[["start_date" => "2012-05"]],
[["end_date" => "2015"]],
[["end_date" => "2015-05"]]
];
}
public function startDatesParameterProvider(): array
{
return [
[["start_date" => "2022"]],
[["start_date" => "2012-05"]],
[["start_date" => "2012-05-12"]],
[["start_date" => "2012-04-01"]],
[["start_date" => "2012-04-28"]],
@ -70,8 +78,6 @@ class MangaSearchEndpointTest extends TestCase
public function endDatesParameterProvider(): array
{
return [
[["end_date" => "2022"]],
[["end_date" => "2012-05"]],
[["end_date" => "2012-05-12"]],
[["end_date" => "2012-05-12", "page" => 1]],
];
@ -80,8 +86,6 @@ class MangaSearchEndpointTest extends TestCase
public function startAndEndDatesParameterProvider(): array
{
return [
[["start_date" => "2021", "end_date" => "2022"]],
[["start_date" => "2021-01", "end_date" => "2021-02"]],
[["start_date" => "2021-01-01", "end_date" => "2021-03-22"]],
[["start_date" => "2021-01-01", "end_date" => "2021-03-22", "page" => 1]],
];
@ -123,10 +127,10 @@ class MangaSearchEndpointTest extends TestCase
public function invalidScoreParameterProvider(): array
{
return [
[["max_score" => "634638"], 15],
[["min_score" => "673473"], 0],
[["max_score" => "72344", "min_score" => "3532325"], 0],
[["max_score" => 1, "min_score" => 5], 0],
[["max_score" => "634638"]],
[["min_score" => "673473"]],
[["max_score" => "72344", "min_score" => "3532325"]],
[["max_score" => 1, "min_score" => 5]],
];
}
@ -185,17 +189,29 @@ class MangaSearchEndpointTest extends TestCase
/**
* @dataProvider emptyDateRangeProvider
*/
public function testSearchByEmptyDatesShouldDoNothing($params)
public function testSearchByEmptyDatesShouldRaiseValidationError($params)
{
$this->generateFiveSpecificAndTenRandomElementsInDb($params);
$content = $this->getJsonResponse($params);
$this->seeStatusCode(200);
$this->assertPaginationData(15);
$this->assertCount(15, $content["data"]);
$this->seeStatusCode(400);
$this->assertEquals("ValidationException", data_get($content, "type"));
}
/**
* @dataProvider partialDatesParameterProvider
*/
public function testSearchByStartDateShouldRaiseIfPartialDate($params)
{
$this->generateFiveSpecificAndTenRandomElementsInDb($params);
$content = $this->getJsonResponse($params);
$this->seeStatusCode(400);
$this->assertEquals("ValidationException", data_get($content, "type"));
}
/**
* @dataProvider startDatesParameterProvider
*/
@ -264,7 +280,10 @@ class MangaSearchEndpointTest extends TestCase
// this is mainly focused on mongodb features
$startDate = "2015-02-01";
$carbonStartDate = Carbon::parse($startDate);
Manga::factory(5)->create();
$fo = Manga::factory(5);
$fo->create($fo->serializeStateDefinition([
"published" => new CarbonDateRange(Carbon::parse("2002-01-01"), Carbon::parse("2002-02-02"))
]));
$f = Manga::factory(1);
$f->create($f->serializeStateDefinition([
"published" => new CarbonDateRange($carbonStartDate, null)
@ -282,12 +301,15 @@ class MangaSearchEndpointTest extends TestCase
public function testSearchWithEndDateEqualToParam()
{
// we test here whether the filtering works by start date
// if the start date parameter's value exactly matches
// if the end date parameter's value exactly matches
// with one item in the database.
// this is mainly focused on mongodb features
$endDate = "2015-03-28";
$carbonEndDate = Carbon::parse($endDate);
Manga::factory(5)->create();
$fo = Manga::factory(5);
$fo->create($fo->serializeStateDefinition([
"published" => new CarbonDateRange(Carbon::parse("2022-01-01"), Carbon::parse("2022-02-02"))
]));
$f = Manga::factory(1);
$f->create($f->serializeStateDefinition([
"published" => new CarbonDateRange(Carbon::parse("2015-01-05"), $carbonEndDate)
@ -326,25 +348,20 @@ class MangaSearchEndpointTest extends TestCase
$this->generateFiveSpecificAndTenRandomElementsInDb($params);
$content = $this->getJsonResponse($params);
$this->seeStatusCode(200);
$this->assertPaginationData(15);
$this->assertIsArray($content["data"]);
// it should return all, and disregard the gibberish filter
$this->assertCount(15, $content["data"]);
$this->seeStatusCode(400);
$this->assertEquals("ValidationException", data_get($content, "type"));
}
/**
* @dataProvider invalidScoreParameterProvider
*/
public function testSearchByInvalidScoreParameters($params, $expectedCount)
public function testSearchByInvalidScoreParameters($params)
{
$this->generateFiveSpecificAndTenRandomElementsInDb($params);
$content = $this->getJsonResponse($params);
$this->seeStatusCode(200);
$this->assertPaginationData($expectedCount);
$this->assertIsArray($content["data"]);
$this->assertCount($expectedCount, $content["data"]);
$this->seeStatusCode(400);
$this->assertEquals("ValidationException", data_get($content, "type"));
}
/**
@ -487,10 +504,8 @@ class MangaSearchEndpointTest extends TestCase
"letter" => "asd"
]);
$this->seeStatusCode(200);
$this->assertPaginationData($expectedCount);
$this->assertIsArray($content["data"]);
$this->assertCount($expectedCount, $content["data"]);
$this->seeStatusCode(400);
$this->assertEquals("ValidationException", data_get($content, "type"));
}
public function testTypeSenseSearchPagination()