From 9de8ffc9db0ca4aa2934c79c6181892a0b5c3a32 Mon Sep 17 00:00:00 2001 From: pushrbx Date: Wed, 10 Apr 2024 18:59:30 +0100 Subject: [PATCH] fixed filtering by producer/magazine on anime/manga search endpoints - additionally improved model factories for tests --- app/Anime.php | 41 +++++++++-------- app/Manga.php | 8 +--- database/factories/AnimeFactory.php | 44 ++++++++++++++++++ database/factories/JikanMediaModelFactory.php | 26 ++++++++++- database/factories/MangaFactory.php | 45 +++++++++++++++++++ tests/Integration/AnimeSearchEndpointTest.php | 1 + tests/Integration/MangaSearchEndpointTest.php | 1 + 7 files changed, 141 insertions(+), 25 deletions(-) diff --git a/app/Anime.php b/app/Anime.php index daa54e0..54d53e3 100644 --- a/app/Anime.php +++ b/app/Anime.php @@ -181,14 +181,11 @@ class Anime extends JikanApiSearchableModel } $producer = (int)$value; - /** @noinspection PhpParamsInspection */ - return $query->whereRaw([ - '$or' => [ - ['producers.mal_id' => $producer], - ['licensors.mal_id' => $producer], - ['studios.mal_id' => $producer] - ] - ]); + return $query->where(function (\Jenssegers\Mongodb\Eloquent\Builder $query) use ($producer) { + return $query->where('producers.mal_id', $producer) + ->orWhere('licensors.mal_id', $producer) + ->orWhere('studios.mal_id', $producer); + }); } /** @noinspection PhpUnused */ @@ -198,16 +195,24 @@ class Anime extends JikanApiSearchableModel return $query; } - $producers = collect(explode(',', $value))->filter()->toArray(); - $orFilters = []; - foreach ($producers as $producer) { - $producer = (int)$producer; - $orFilters[] = ['producers.mal_id' => $producer]; - $orFilters[] = ['licensors.mal_id' => $producer]; - $orFilters[] = ['studios.mal_id' => $producer]; - } - /** @noinspection PhpParamsInspection */ - return $query->whereRaw(['$or' => $orFilters]); + /* @var \Illuminate\Support\Collection $producers */ + $producers = collect(explode(',', $value))->filter(); + + return $query->where(function (\Jenssegers\Mongodb\Eloquent\Builder $query) use ($producers) { + $firstProducer = (int)$producers->first(); + $query = $query->where('producers.mal_id', $firstProducer) + ->orWhere('licensors.mal_id', $firstProducer) + ->orWhere('studios.mal_id', $firstProducer); + + foreach ($producers->skip(1) as $producer) { + $producer = (int)$producer; + $query = $query->orWhere('producers.mal_id', $producer) + ->orWhere('licensors.mal_id', $producer) + ->orWhere('studios.mal_id', $producer); + } + + return $query; + }); } /** @noinspection PhpUnused */ diff --git a/app/Manga.php b/app/Manga.php index 08e2409..eb983a8 100644 --- a/app/Manga.php +++ b/app/Manga.php @@ -111,14 +111,10 @@ class Manga extends JikanApiSearchableModel return $query; } + /** @var \Illuminate\Support\Collection $magazines */ $magazines = collect(explode(',', $value))->filter()->map(fn($x) => (int)$x)->toArray(); - /** @noinspection PhpParamsInspection */ - return $query->whereRaw([ - "serializations.mal_id" => [ - '$in' => $magazines - ] - ]); + return $query->whereIn("serializations.mal_id", $magazines); } /** @noinspection PhpUnused */ diff --git a/database/factories/AnimeFactory.php b/database/factories/AnimeFactory.php index 202d753..aaa59a4 100644 --- a/database/factories/AnimeFactory.php +++ b/database/factories/AnimeFactory.php @@ -4,6 +4,7 @@ namespace Database\Factories; use App\CarbonDateRange; use App\Anime; use App\Testing\JikanDataGenerator; +use Illuminate\Support\Collection; use MongoDB\BSON\UTCDateTime; @@ -139,4 +140,47 @@ class AnimeFactory extends JikanMediaModelFactory "request_hash" => sprintf("request:%s:%s", "v4", $this->getItemTestUrl("anime", $mal_id)) ]; } + + protected function getOverridesFromQueryStringParameters(Collection $additionalParams): array + { + $overrides = parent::getOverridesFromQueryStringParameters($additionalParams); + + if ($additionalParams->has("producers")) { + $overrides["producers"] = []; + $producerIds = explode(",", $additionalParams["producers"]); + foreach ($producerIds as $producerId) { + $overrides["producers"][] = [ + "mal_id" => (int)$producerId, + "type" => "anime", + "name" => "Producer ${producerId}", + "url" => "https://myanimelist.net/anime/producer/${producerId}/x" + ]; + } + } + + return $overrides; + } + + protected function getOppositeOverridesFromQueryStringParameters(Collection $additionalParams): array + { + $overrides = parent::getOppositeOverridesFromQueryStringParameters($additionalParams); + + if ($additionalParams->has("producers")) { + $overrides["producers"] = []; + $producerIds = explode(",", $additionalParams["producers"]); + do { + $randomEls = $this->faker->randomElements([11, 60, 89, 54, 32, 22, 108, 65], $this->faker->numberBetween(1, 3)); + } while (count(array_intersect($randomEls, $producerIds)) > 0); + foreach ($randomEls as $producerId) { + $overrides["produces"][] = [ + "mal_id" => (int)$producerId, + "type" => "anime", + "name" => "Producer ${producerId}", + "url" => "https://myanimelist.net/anime/producer/${producerId}/x" + ]; + } + } + + return $overrides; + } } diff --git a/database/factories/JikanMediaModelFactory.php b/database/factories/JikanMediaModelFactory.php index 66e839a..9b41962 100644 --- a/database/factories/JikanMediaModelFactory.php +++ b/database/factories/JikanMediaModelFactory.php @@ -7,6 +7,7 @@ use App\Enums\AnimeRatingEnum; use App\Enums\AnimeTypeEnum; use App\Enums\MangaTypeEnum; use App\Testing\JikanDataGenerator; +use Illuminate\Database\Eloquent\Factories\Sequence; use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Carbon; use Illuminate\Support\Collection; @@ -56,6 +57,16 @@ abstract class JikanMediaModelFactory extends JikanModelFactory implements Media * @return self */ public function overrideFromQueryStringParameters(array $additionalParams, bool $doOpposite = false): self + { + if ($this->count === 1) { + return $this->state($this->serializeStateDefinition($this->getStateOverrides($additionalParams, $doOpposite))); + } + + /** @noinspection PhpParamsInspection */ + return $this->state(new Sequence(fn(Sequence $_) => $this->serializeStateDefinition($this->getStateOverrides($additionalParams, $doOpposite)))); + } + + private function getStateOverrides(array $additionalParams, bool $doOpposite = false): array { $additionalParams = collect($additionalParams); @@ -66,7 +77,7 @@ abstract class JikanMediaModelFactory extends JikanModelFactory implements Media $overrides = $this->getOverridesFromQueryStringParameters($additionalParams); } - return $this->state($this->serializeStateDefinition($overrides)); + return $overrides; } /** @@ -158,6 +169,10 @@ abstract class JikanMediaModelFactory extends JikanModelFactory implements Media $overrides = [...$overrides, ...$a]; } + if ($additionalParams->has("score")) { + $overrides["score"] = floatval($additionalParams["score"]); + } + if ($additionalParams->has("min_score") && !$additionalParams->has("max_score")) { $min_score = floatval($additionalParams["min_score"]); if ($this->isScoreValueValid($min_score)) { @@ -283,6 +298,15 @@ abstract class JikanMediaModelFactory extends JikanModelFactory implements Media $overrides = [...$overrides, ...$a]; } + if ($additionalParams->has("score")) { + $specifiedScore = floatval($additionalParams["score"]); + do { + $randomScore = $this->faker->randomFloat(2, 1.00, 9.99); + } while ($randomScore === $specifiedScore); + + $overrides["score"] = $randomScore; + } + if ($additionalParams->has("min_score") && !$additionalParams->has("max_score")) { $min_score = floatval($additionalParams["min_score"]); if ($this->isScoreValueValid($min_score)) { diff --git a/database/factories/MangaFactory.php b/database/factories/MangaFactory.php index f8b2c66..6ae3665 100644 --- a/database/factories/MangaFactory.php +++ b/database/factories/MangaFactory.php @@ -4,6 +4,7 @@ namespace Database\Factories; use App\CarbonDateRange; use App\Testing\JikanDataGenerator; use App\Manga; +use Illuminate\Support\Collection; use MongoDB\BSON\UTCDateTime; class MangaFactory extends JikanMediaModelFactory @@ -98,4 +99,48 @@ class MangaFactory extends JikanMediaModelFactory "request_hash" => sprintf("request:%s:%s", "v4", $this->getItemTestUrl("manga", $mal_id)) ]; } + + protected function getOverridesFromQueryStringParameters(Collection $additionalParams): array + { + $overrides = parent::getOverridesFromQueryStringParameters($additionalParams); + + if ($additionalParams->has("magazines")) { + $overrides["serializations"] = []; + $magazineIds = explode(",", $additionalParams["magazines"]); + foreach ($magazineIds as $magazineId) { + $overrides["serializations"][] = [ + "mal_id" => (int)$magazineId, + "type" => "manga", + "name" => "Magazine {$magazineId}", + "url" => "https://myanimelist.net/manga/magazine/{$magazineId}/x" + ]; + } + } + + return $overrides; + } + + protected function getOppositeOverridesFromQueryStringParameters(Collection $additionalParams): array + { + $overrides = parent::getOppositeOverridesFromQueryStringParameters($additionalParams); + + if ($additionalParams->has("magazines")) { + $overrides["serializations"] = []; + $magazineIds = explode(",", $additionalParams["magazines"]); + do { + $randomEls = $this->faker->randomElements([11, 60, 89, 54, 32, 22, 108, 65], $this->faker->numberBetween(1, 3)); + } while (count(array_intersect($randomEls, $magazineIds)) > 0); + + foreach ($randomEls as $magazineId) { + $overrides["serializations"][] = [ + "mal_id" => (int)$magazineId, + "type" => "manga", + "name" => "Magazine {$magazineId}", + "url" => "https://myanimelist.net/manga/magazine/{$magazineId}/x" + ]; + } + } + + return $overrides; + } } diff --git a/tests/Integration/AnimeSearchEndpointTest.php b/tests/Integration/AnimeSearchEndpointTest.php index 7100478..eb0314c 100644 --- a/tests/Integration/AnimeSearchEndpointTest.php +++ b/tests/Integration/AnimeSearchEndpointTest.php @@ -138,6 +138,7 @@ class AnimeSearchEndpointTest extends TestCase "type = movie" => [["type" => "movie"]], "type = ova" => [["type" => "ova"]], "type = special" => [["type" => "special"]], + "score = 8 and producers = 11" => [["score" => "8", "producers" => "11"]], ]; } diff --git a/tests/Integration/MangaSearchEndpointTest.php b/tests/Integration/MangaSearchEndpointTest.php index 6ab0738..0c5ff4c 100644 --- a/tests/Integration/MangaSearchEndpointTest.php +++ b/tests/Integration/MangaSearchEndpointTest.php @@ -128,6 +128,7 @@ class MangaSearchEndpointTest extends TestCase [["type" => "novel"]], [["type" => "lightnovel"]], [["type" => "oneshot"]], + [["score" => "8", "magazines" => "83"]] ]; }