From f5f42b14d4581725d31e1c21cc12ac73a7837a7e Mon Sep 17 00:00:00 2001 From: pushrbx Date: Tue, 13 Feb 2024 18:38:00 +0000 Subject: [PATCH 01/30] fixed issues around the season endpoint --- app/Repositories/DefaultAnimeRepository.php | 32 ++++---- app/Support/RepositoryQueryBase.php | 3 +- tests/Integration/SeasonControllerTest.php | 89 ++++++++++++++++++++- 3 files changed, 107 insertions(+), 17 deletions(-) diff --git a/app/Repositories/DefaultAnimeRepository.php b/app/Repositories/DefaultAnimeRepository.php index e337182..4a29a48 100644 --- a/app/Repositories/DefaultAnimeRepository.php +++ b/app/Repositories/DefaultAnimeRepository.php @@ -5,15 +5,12 @@ namespace App\Repositories; use App\Anime; use App\Contracts\AnimeRepository; use App\Contracts\Repository; -use App\Enums\AnimeRatingEnum; use App\Enums\AnimeScheduleFilterEnum; -use App\Enums\AnimeSeasonEnum; use App\Enums\AnimeStatusEnum; use App\Enums\AnimeTypeEnum; use Illuminate\Contracts\Database\Query\Builder as EloquentBuilder; use Illuminate\Database\Eloquent\Collection; use Illuminate\Support\Carbon; -use Jikan\Helper\Constants; use Laravel\Scout\Builder as ScoutBuilder; /** @@ -120,44 +117,49 @@ final class DefaultAnimeRepository extends DatabaseRepository implements AnimeRe ?string $premiered = null ): EloquentBuilder { - /** @noinspection PhpParamsInspection */ $queryable = $this->queryable(true); - $airedFilter = ["aired.from" => [ + $airedFilter = ['aired.from' => [ '$gte' => $from->toAtomString(), - '$lte' => $to->modify("last day of this month")->toAtomString() + '$lte' => $to->modify('last day of this month')->toAtomString() ]]; $finalFilter = []; // if the premiered parameter for the filter is not null, look for those items which have a premiered attribute set, // and equals to the parameter value, OR look for those items which doesn't have premired attribute set, - // they don't have a garbled aired string and their aired.from date is within the from-to parameters range + // they don't have a garbled aired string and their aired.from date is within the from-to parameters range. + // Additionally, we want to include all those items which are carry overs from previous seasons. if ($premiered !== null) { $finalFilter['$or'] = [ - ["premiered" => $premiered], + ['premiered' => $premiered], [ - "premiered" => null, - "aired.string" => [ - '$not' => ['$regex' => "{$from->year} to ?"] + 'premiered' => null, + 'aired.string' => [ + '$nin' => ["{$from->year} to ?"] ], ...$airedFilter + ], + // this condition will include "continuing" items from previous seasons + [ + 'aired.from' => ['$lte' => $from->toAtomString()], + 'airing' => true ] ]; } else { $finalFilter = array_merge($finalFilter, $airedFilter); - $finalFilter["aired.string"] = [ - '$not' => ['$regex' => "{$from->year} to ?"] + $finalFilter['aired.string'] = [ + '$nin' => ["{$from->year} to ?"] ]; } if (!is_null($type)) { - $finalFilter["type"] = $type->label; + $finalFilter['type'] = $type->label; } $queryable = $queryable->whereRaw($finalFilter); - return $queryable->orderBy("members", "desc"); + return $queryable->orderBy('members', 'desc'); } public function getUpcomingSeasonItems( diff --git a/app/Support/RepositoryQueryBase.php b/app/Support/RepositoryQueryBase.php index 0463586..17fcd19 100644 --- a/app/Support/RepositoryQueryBase.php +++ b/app/Support/RepositoryQueryBase.php @@ -3,6 +3,7 @@ namespace App\Support; use Laravel\Scout\Builder as ScoutBuilder; use Illuminate\Contracts\Database\Query\Builder; +use Jenssegers\Mongodb\Eloquent\Builder as MongoDbBuilder; class RepositoryQueryBase { @@ -15,7 +16,7 @@ class RepositoryQueryBase { } - protected function queryable(bool $createNew = false): Builder + protected function queryable(bool $createNew = false): Builder|MongoDbBuilder { if ($createNew) { $callback = $this->getQueryable; diff --git a/tests/Integration/SeasonControllerTest.php b/tests/Integration/SeasonControllerTest.php index 2879209..44a71db 100644 --- a/tests/Integration/SeasonControllerTest.php +++ b/tests/Integration/SeasonControllerTest.php @@ -25,7 +25,7 @@ class SeasonControllerTest extends TestCase $state = $f->serializeStateDefinition([ "aired" => new CarbonDateRange($carbonStartDate, null) ]); - $state["aired"]["string"] = "Jan 1, 2024 to ?"; + $state["aired"]["string"] = "2024 to ?"; $state["premiered"] = null; $state["status"] = "Not yet aired"; $state["airing"] = false; @@ -49,4 +49,91 @@ class SeasonControllerTest extends TestCase $this->assertIsArray($content["data"]); $this->assertCount(1, $content["data"]); } + + public function testShouldNotFilterOutFutureAiringDates() + { + Carbon::setTestNow(Carbon::parse("2024-01-11")); + // an item in the future airing + $f = Anime::factory(1); + $startDate = "2024-02-24"; + $carbonStartDate = Carbon::parse($startDate); + $state = $f->serializeStateDefinition([ + "aired" => new CarbonDateRange($carbonStartDate, null) + ]); + $state["aired"]["string"] = "Feb 24, 2024 to ?"; + $state["premiered"] = null; + $state["status"] = "Not yet aired"; + $state["airing"] = false; + $f->create($state); + + // the "garbled" wrong item + $f = Anime::factory(1); + $startDate = "2024-01-01"; + $carbonStartDate = Carbon::parse($startDate); + $state = $f->serializeStateDefinition([ + "aired" => new CarbonDateRange($carbonStartDate, null) + ]); + $state["aired"]["string"] = "2024 to ?"; + $state["premiered"] = null; + $state["status"] = "Not yet aired"; + $state["airing"] = false; + $f->create($state); + + // the absolutely correct item + $f = Anime::factory(1); + $state = $f->serializeStateDefinition([ + "aired" => new CarbonDateRange(Carbon::parse("2024-01-10"), Carbon::parse("2024-02-15")) + ]); + $state["premiered"] = "Winter 2024"; + $state["status"] = "Currently Airing"; + $state["airing"] = true; + $f->create($state); + + $content = $this->getJsonResponse([], "/v4/seasons/2024/winter"); + $this->seeStatusCode(200); + $this->assertIsArray($content["data"]); + $this->assertCount(2, $content["data"]); + } + + public function testShouldNotFilterOutContinuingItemsFromPreviousSeasons() + { + Carbon::setTestNow(Carbon::parse("2024-01-11")); + // an item in the future airing + $f = Anime::factory(1); + $startDate = "2024-02-24"; + $carbonStartDate = Carbon::parse($startDate); + $state = $f->serializeStateDefinition([ + "aired" => new CarbonDateRange($carbonStartDate, null) + ]); + $state["aired"]["string"] = "Feb 24, 2024 to ?"; + $state["premiered"] = null; + $state["status"] = "Not yet aired"; + $state["airing"] = false; + $f->create($state); + + // the absolutely correct item + $f = Anime::factory(1); + $state = $f->serializeStateDefinition([ + "aired" => new CarbonDateRange(Carbon::parse("2024-01-10"), Carbon::parse("2024-02-15")) + ]); + $state["premiered"] = "Winter 2024"; + $state["status"] = "Currently Airing"; + $state["airing"] = true; + $f->create($state); + + // the continuing item + $f = Anime::factory(1); + $state = $f->serializeStateDefinition([ + "aired" => new CarbonDateRange(Carbon::parse("2023-10-10"), null) + ]); + $state["premiered"] = "Fall 2023"; + $state["status"] = "Currently Airing"; + $state["airing"] = true; + $f->create($state); + + $content = $this->getJsonResponse([], "/v4/seasons/2024/winter"); + $this->seeStatusCode(200); + $this->assertIsArray($content["data"]); + $this->assertCount(3, $content["data"]); + } } From 8948dc1053ed40d4bb2790522999e926dd933cfb Mon Sep 17 00:00:00 2001 From: pushrbx Date: Tue, 13 Feb 2024 21:15:36 +0000 Subject: [PATCH 02/30] fixed buggy tests --- app/Support/CachedData.php | 2 +- .../Unit/DefaultCachedScraperServiceTest.php | 28 +++++++++---------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/app/Support/CachedData.php b/app/Support/CachedData.php index 898009c..33c0db7 100644 --- a/app/Support/CachedData.php +++ b/app/Support/CachedData.php @@ -65,7 +65,7 @@ final class CachedData implements ArrayAccess $expiry = $this->expiry(); - return time() > $expiry; + return Carbon::now()->unix() > $expiry; } public function toArray(): array diff --git a/tests/Unit/DefaultCachedScraperServiceTest.php b/tests/Unit/DefaultCachedScraperServiceTest.php index 46f5e5e..6d8ca5e 100644 --- a/tests/Unit/DefaultCachedScraperServiceTest.php +++ b/tests/Unit/DefaultCachedScraperServiceTest.php @@ -51,7 +51,7 @@ final class DefaultCachedScraperServiceTest extends TestCase public function testIfFindListReturnsNotExpiredItems() { $testRequestHash = $this->requestHash(); - $now = Carbon::now(); + $now = Carbon::createFromDate(2022, 1, 11, "UTC")->addHours(8)->addMinutes(12); Carbon::setTestNow($now); // the cached data in the database // this should be an array of arrays as builder->get() returns multiple items @@ -76,14 +76,14 @@ final class DefaultCachedScraperServiceTest extends TestCase public function testIfFindListUpdatesCacheIfItemsExpired() { $testRequestHash = $this->requestHash(); - $now = Carbon::now(); + $now = Carbon::createFromDate(2022, 1, 11, "UTC")->addHours(8)->addMinutes(12); Carbon::setTestNow($now); // the cached data in the database // this should be an array of arrays as builder->get() returns multiple items $dummyResults = collect([[ "request_hash" => $testRequestHash, - "modifiedAt" => new UTCDateTime($now->sub("2 days")->getPreciseTimestamp(3)), + "modifiedAt" => new UTCDateTime($now->copy()->subDays(2)->getPreciseTimestamp(3)), "results" => [ ["dummy" => "dummy1"], ["dummy" => "dummy2"] @@ -128,7 +128,7 @@ final class DefaultCachedScraperServiceTest extends TestCase public function testIfFindListUpdatesCacheIfCacheIsEmpty() { $testRequestHash = $this->requestHash(); - $now = Carbon::now(); + $now = Carbon::createFromDate(2022, 1, 11, "UTC")->addHours(8)->addMinutes(12); Carbon::setTestNow($now); // the data returned by the scraper @@ -175,7 +175,7 @@ final class DefaultCachedScraperServiceTest extends TestCase { $malId = 1; $testRequestHash = $this->requestHash(); - $now = Carbon::now(); + $now = Carbon::createFromDate(2022, 1, 11, "UTC")->addHours(8)->addMinutes(12); Carbon::setTestNow($now); $mockModel = Anime::factory()->makeOne([ "mal_id" => $malId, @@ -197,7 +197,7 @@ final class DefaultCachedScraperServiceTest extends TestCase { $malId = 1; $testRequestHash = $this->requestHash(); - $now = Carbon::now(); + $now = Carbon::createFromDate(2022, 1, 11, "UTC")->addHours(8)->addMinutes(12); Carbon::setTestNow($now); $mockModel = Anime::factory()->makeOne([ "mal_id" => $malId, @@ -224,11 +224,11 @@ final class DefaultCachedScraperServiceTest extends TestCase { $malId = 1; $testRequestHash = $this->requestHash(); - $now = Carbon::now(); + $now = Carbon::createFromDate(2022, 1, 11, "UTC")->addHours(8)->addMinutes(12); $mockModel = Anime::factory()->makeOne([ "mal_id" => $malId, - "modifiedAt" => new UTCDateTime($now->sub("3 days")->getPreciseTimestamp(3)), - "createdAt" => new UTCDateTime($now->sub("3 days")->getPreciseTimestamp(3)) + "modifiedAt" => new UTCDateTime($now->copy()->sub("3 days")->getPreciseTimestamp(3)), + "createdAt" => new UTCDateTime($now->copy()->sub("3 days")->getPreciseTimestamp(3)) ]); $now = Carbon::now(); Carbon::setTestNow($now); @@ -264,7 +264,7 @@ final class DefaultCachedScraperServiceTest extends TestCase { $username = "kompot"; $testRequestHash = $this->requestHash(); - $now = Carbon::now(); + $now = Carbon::createFromDate(2022, 1, 11, "UTC")->addHours(8)->addMinutes(12); Carbon::setTestNow($now); $mockModel = Profile::factory()->makeOne([ "username" => $username, @@ -287,7 +287,7 @@ final class DefaultCachedScraperServiceTest extends TestCase { $username = "kompot"; $testRequestHash = $this->requestHash(); - $now = Carbon::now(); + $now = Carbon::createFromDate(2022, 1, 11, "UTC")->addHours(8)->addMinutes(12); Carbon::setTestNow($now); $mockModel = Profile::factory()->makeOne([ "username" => $username, @@ -319,12 +319,12 @@ final class DefaultCachedScraperServiceTest extends TestCase $malId = 1; $username = "kompot"; $testRequestHash = $this->requestHash(); - $now = Carbon::now(); + $now = Carbon::createFromDate(2022, 1, 11, "UTC")->addHours(8)->addMinutes(12); $mockModel = Profile::factory()->makeOne([ "mal_id" => $malId, "username" => $username, - "modifiedAt" => new UTCDateTime($now->sub("3 days")->getPreciseTimestamp(3)), - "createdAt" => new UTCDateTime($now->sub("3 days")->getPreciseTimestamp(3)) + "modifiedAt" => new UTCDateTime($now->copy()->sub("3 days")->getPreciseTimestamp(3)), + "createdAt" => new UTCDateTime($now->copy()->sub("3 days")->getPreciseTimestamp(3)) ]); $now = Carbon::now(); Carbon::setTestNow($now); From d32cc5603f08cd1ab8f6b60cc52c82f6666f2996 Mon Sep 17 00:00:00 2001 From: BarraFiqaulihi <102664471+BarraFiqaulihi@users.noreply.github.com> Date: Sat, 24 Feb 2024 19:44:23 +0200 Subject: [PATCH 03/30] Remove duplicate parameter from "/schedules" path --- storage/api-docs/api-docs.json | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/storage/api-docs/api-docs.json b/storage/api-docs/api-docs.json index 4a295e4..c32616f 100644 --- a/storage/api-docs/api-docs.json +++ b/storage/api-docs/api-docs.json @@ -2283,9 +2283,6 @@ ], "operationId": "getSchedules", "parameters": [ - { - "$ref": "#/components/parameters/page" - }, { "name": "filter", "in": "query", @@ -9104,4 +9101,4 @@ "description": "About", "url": "https://jikan.moe" } -} \ No newline at end of file +} From e4263d1c913ed1ba9aa31a9fc02f1deb28fbcf7c Mon Sep 17 00:00:00 2001 From: BarraFiqaulihi <102664471+BarraFiqaulihi@users.noreply.github.com> Date: Sat, 24 Feb 2024 23:47:15 +0200 Subject: [PATCH 04/30] Remove duplicate OA parameter from ScheduleController --- app/Http/Controllers/V4DB/ScheduleController.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/Http/Controllers/V4DB/ScheduleController.php b/app/Http/Controllers/V4DB/ScheduleController.php index 8ad4b18..143deb0 100644 --- a/app/Http/Controllers/V4DB/ScheduleController.php +++ b/app/Http/Controllers/V4DB/ScheduleController.php @@ -13,8 +13,6 @@ class ScheduleController extends Controller * operationId="getSchedules", * tags={"schedules"}, * - * @OA\Parameter(ref="#/components/parameters/page"), - * * @OA\Parameter( * name="filter", * in="query", From f9616f88c01ec584177a3d211c542fb41f9c970f Mon Sep 17 00:00:00 2001 From: Irfan Date: Tue, 5 Mar 2024 18:01:25 +0500 Subject: [PATCH 05/30] Update .env.dist --- .env.dist | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.env.dist b/.env.dist index a7e07ed..2e57f4e 100644 --- a/.env.dist +++ b/.env.dist @@ -6,7 +6,7 @@ APP_DEBUG=false APP_KEY= APP_TIMEZONE=UTC APP_URL=http://localhost -APP_VERSION="4.2.1" +APP_VERSION="4.2.2" ### # Logging From a415418ebf95830992b07ccc8cb51bfd8b1a4758 Mon Sep 17 00:00:00 2001 From: Irfan Date: Tue, 5 Mar 2024 18:02:09 +0500 Subject: [PATCH 06/30] Update api-docs.json --- storage/api-docs/api-docs.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/api-docs/api-docs.json b/storage/api-docs/api-docs.json index c32616f..75d5875 100644 --- a/storage/api-docs/api-docs.json +++ b/storage/api-docs/api-docs.json @@ -9101,4 +9101,4 @@ "description": "About", "url": "https://jikan.moe" } -} +} \ No newline at end of file From 53eeaf6a13b9c2a8cdd6e87f6ebf7c36559aa7af Mon Sep 17 00:00:00 2001 From: Anand Prakash Sharma <31429879+tbkj98@users.noreply.github.com> Date: Sun, 17 Mar 2024 11:01:08 +0530 Subject: [PATCH 07/30] Update api-docs.json Removed duplicate request parameter reference "sfw" --- storage/api-docs/api-docs.json | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/storage/api-docs/api-docs.json b/storage/api-docs/api-docs.json index 75d5875..c9108d3 100644 --- a/storage/api-docs/api-docs.json +++ b/storage/api-docs/api-docs.json @@ -2329,9 +2329,6 @@ ] } }, - { - "$ref": "#/components/parameters/sfw" - }, { "$ref": "#/components/parameters/unapproved" }, @@ -2366,9 +2363,6 @@ ], "operationId": "getAnimeSearch", "parameters": [ - { - "$ref": "#/components/parameters/sfw" - }, { "$ref": "#/components/parameters/unapproved" }, @@ -2524,9 +2518,6 @@ ], "operationId": "getMangaSearch", "parameters": [ - { - "$ref": "#/components/parameters/sfw" - }, { "$ref": "#/components/parameters/unapproved" }, @@ -9101,4 +9092,4 @@ "description": "About", "url": "https://jikan.moe" } -} \ No newline at end of file +} From b66834084ca2fd3446ad259459425be89e033474 Mon Sep 17 00:00:00 2001 From: Anand Prakash Sharma <31429879+tbkj98@users.noreply.github.com> Date: Sat, 23 Mar 2024 14:02:31 +0530 Subject: [PATCH 08/30] Removed duplicate reference to sfw param in comments for anime and manga GET search endpoints --- app/Http/Controllers/V4DB/SearchController.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/Http/Controllers/V4DB/SearchController.php b/app/Http/Controllers/V4DB/SearchController.php index 40b3626..087b26f 100644 --- a/app/Http/Controllers/V4DB/SearchController.php +++ b/app/Http/Controllers/V4DB/SearchController.php @@ -25,7 +25,6 @@ class SearchController extends Controller * operationId="getAnimeSearch", * tags={"anime"}, * - * @OA\Parameter(ref="#/components/parameters/sfw"), * @OA\Parameter(ref="#/components/parameters/unapproved"), * @OA\Parameter(ref="#/components/parameters/page"), * @OA\Parameter(ref="#/components/parameters/limit"), @@ -159,7 +158,6 @@ class SearchController extends Controller * operationId="getMangaSearch", * tags={"manga"}, * - * @OA\Parameter(ref="#/components/parameters/sfw"), * @OA\Parameter(ref="#/components/parameters/unapproved"), * @OA\Parameter(ref="#/components/parameters/page"), * @OA\Parameter(ref="#/components/parameters/limit"), From 5b656b4d2b8384ff44a0e5a145e4e3437f2147bd Mon Sep 17 00:00:00 2001 From: Anand Prakash Sharma <31429879+tbkj98@users.noreply.github.com> Date: Sat, 23 Mar 2024 14:05:21 +0530 Subject: [PATCH 09/30] Removed duplicate parameter reference "sfw" --- app/Http/Controllers/V4DB/ScheduleController.php | 1 - 1 file changed, 1 deletion(-) diff --git a/app/Http/Controllers/V4DB/ScheduleController.php b/app/Http/Controllers/V4DB/ScheduleController.php index 143deb0..4b31e5b 100644 --- a/app/Http/Controllers/V4DB/ScheduleController.php +++ b/app/Http/Controllers/V4DB/ScheduleController.php @@ -37,7 +37,6 @@ class ScheduleController extends Controller * @OA\Schema(type="string",enum={"true", "false"}) * ), * - * @OA\Parameter(ref="#/components/parameters/sfw"), * @OA\Parameter(ref="#/components/parameters/unapproved"), * @OA\Parameter(ref="#/components/parameters/page"), * @OA\Parameter(ref="#/components/parameters/limit"), From 6794ac4e8029c3fbb2cc298a794d3eca5782e1b3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 2 Apr 2024 04:14:29 +0000 Subject: [PATCH 10/30] Bump jikan-me/jikan from 4.0.8 to 4.0.9 Bumps [jikan-me/jikan](https://github.com/jikan-me/jikan) from 4.0.8 to 4.0.9. - [Release notes](https://github.com/jikan-me/jikan/releases) - [Commits](https://github.com/jikan-me/jikan/compare/v4.0.8...v4.0.9) --- updated-dependencies: - dependency-name: jikan-me/jikan dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- composer.lock | 385 ++++++++++++++++++++++++-------------------------- 1 file changed, 181 insertions(+), 204 deletions(-) diff --git a/composer.lock b/composer.lock index a9802f3..fd737c4 100644 --- a/composer.lock +++ b/composer.lock @@ -1513,25 +1513,29 @@ }, { "name": "doctrine/deprecations", - "version": "v1.0.0", + "version": "1.1.3", "source": { "type": "git", "url": "https://github.com/doctrine/deprecations.git", - "reference": "0e2a4f1f8cdfc7a92ec3b01c9334898c806b30de" + "reference": "dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/deprecations/zipball/0e2a4f1f8cdfc7a92ec3b01c9334898c806b30de", - "reference": "0e2a4f1f8cdfc7a92ec3b01c9334898c806b30de", + "url": "https://api.github.com/repos/doctrine/deprecations/zipball/dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab", + "reference": "dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab", "shasum": "" }, "require": { - "php": "^7.1|^8.0" + "php": "^7.1 || ^8.0" }, "require-dev": { "doctrine/coding-standard": "^9", - "phpunit/phpunit": "^7.5|^8.5|^9.5", - "psr/log": "^1|^2|^3" + "phpstan/phpstan": "1.4.10 || 1.10.15", + "phpstan/phpstan-phpunit": "^1.0", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "psalm/plugin-phpunit": "0.18.4", + "psr/log": "^1 || ^2 || ^3", + "vimeo/psalm": "4.30.0 || 5.12.0" }, "suggest": { "psr/log": "Allows logging deprecations via PSR-3 logger implementation" @@ -1550,9 +1554,9 @@ "homepage": "https://www.doctrine-project.org/", "support": { "issues": "https://github.com/doctrine/deprecations/issues", - "source": "https://github.com/doctrine/deprecations/tree/v1.0.0" + "source": "https://github.com/doctrine/deprecations/tree/1.1.3" }, - "time": "2022-05-02T15:47:09+00:00" + "time": "2024-01-30T19:34:25+00:00" }, { "name": "doctrine/inflector", @@ -2026,28 +2030,29 @@ }, { "name": "fabpot/goutte", - "version": "v4.0.2", + "version": "v4.0.3", "source": { "type": "git", "url": "https://github.com/FriendsOfPHP/Goutte.git", - "reference": "f51940fbe0db060bc4fc0b3f1d19bc4ff3054b17" + "reference": "e3f28671c87a48a0f13ada1baea0d95acc2138c3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/FriendsOfPHP/Goutte/zipball/f51940fbe0db060bc4fc0b3f1d19bc4ff3054b17", - "reference": "f51940fbe0db060bc4fc0b3f1d19bc4ff3054b17", + "url": "https://api.github.com/repos/FriendsOfPHP/Goutte/zipball/e3f28671c87a48a0f13ada1baea0d95acc2138c3", + "reference": "e3f28671c87a48a0f13ada1baea0d95acc2138c3", "shasum": "" }, "require": { "php": ">=7.1.3", "symfony/browser-kit": "^4.4|^5.0|^6.0", "symfony/css-selector": "^4.4|^5.0|^6.0", + "symfony/deprecation-contracts": "^2.1|^3", "symfony/dom-crawler": "^4.4|^5.0|^6.0", "symfony/http-client": "^4.4|^5.0|^6.0", "symfony/mime": "^4.4|^5.0|^6.0" }, "require-dev": { - "symfony/phpunit-bridge": "^5.0|^6.0" + "symfony/phpunit-bridge": "^6.0" }, "type": "application", "autoload": { @@ -2075,9 +2080,10 @@ ], "support": { "issues": "https://github.com/FriendsOfPHP/Goutte/issues", - "source": "https://github.com/FriendsOfPHP/Goutte/tree/v4.0.2" + "source": "https://github.com/FriendsOfPHP/Goutte/tree/v4.0.3" }, - "time": "2021-12-17T17:15:01+00:00" + "abandoned": "symfony/browser-kit", + "time": "2023-04-01T09:05:33+00:00" }, { "name": "flipbox/lumen-generator", @@ -4548,16 +4554,16 @@ }, { "name": "jikan-me/jikan", - "version": "v4.0.8", + "version": "v4.0.9", "source": { "type": "git", "url": "https://github.com/jikan-me/jikan.git", - "reference": "db7c2d2e940c028ba3bdfac71d66e39daf74952a" + "reference": "eac008510873c9ef4a61d6a7b684153be14269df" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/jikan-me/jikan/zipball/db7c2d2e940c028ba3bdfac71d66e39daf74952a", - "reference": "db7c2d2e940c028ba3bdfac71d66e39daf74952a", + "url": "https://api.github.com/repos/jikan-me/jikan/zipball/eac008510873c9ef4a61d6a7b684153be14269df", + "reference": "eac008510873c9ef4a61d6a7b684153be14269df", "shasum": "" }, "require": { @@ -4596,7 +4602,7 @@ "description": "Jikan is an unofficial MyAnimeList API", "support": { "issues": "https://github.com/jikan-me/jikan/issues", - "source": "https://github.com/jikan-me/jikan/tree/v4.0.8" + "source": "https://github.com/jikan-me/jikan/tree/v4.0.9" }, "funding": [ { @@ -4604,7 +4610,7 @@ "type": "patreon" } ], - "time": "2023-10-28T10:21:22+00:00" + "time": "2024-04-01T21:41:29+00:00" }, { "name": "jms/metadata", @@ -5500,26 +5506,24 @@ }, { "name": "masterminds/html5", - "version": "2.7.6", + "version": "2.8.1", "source": { "type": "git", "url": "https://github.com/Masterminds/html5-php.git", - "reference": "897eb517a343a2281f11bc5556d6548db7d93947" + "reference": "f47dcf3c70c584de14f21143c55d9939631bc6cf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Masterminds/html5-php/zipball/897eb517a343a2281f11bc5556d6548db7d93947", - "reference": "897eb517a343a2281f11bc5556d6548db7d93947", + "url": "https://api.github.com/repos/Masterminds/html5-php/zipball/f47dcf3c70c584de14f21143c55d9939631bc6cf", + "reference": "f47dcf3c70c584de14f21143c55d9939631bc6cf", "shasum": "" }, "require": { - "ext-ctype": "*", "ext-dom": "*", - "ext-libxml": "*", "php": ">=5.3.0" }, "require-dev": { - "phpunit/phpunit": "^4.8.35 || ^5.7.21 || ^6 || ^7" + "phpunit/phpunit": "^4.8.35 || ^5.7.21 || ^6 || ^7 || ^8" }, "type": "library", "extra": { @@ -5563,9 +5567,9 @@ ], "support": { "issues": "https://github.com/Masterminds/html5-php/issues", - "source": "https://github.com/Masterminds/html5-php/tree/2.7.6" + "source": "https://github.com/Masterminds/html5-php/tree/2.8.1" }, - "time": "2022-08-18T16:18:26+00:00" + "time": "2023-05-10T11:58:31+00:00" }, { "name": "matchish/laravel-scout-elasticsearch", @@ -6746,24 +6750,27 @@ }, { "name": "phpdocumentor/type-resolver", - "version": "1.6.2", + "version": "1.8.2", "source": { "type": "git", "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "48f445a408c131e38cab1c235aa6d2bb7a0bb20d" + "reference": "153ae662783729388a584b4361f2545e4d841e3c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/48f445a408c131e38cab1c235aa6d2bb7a0bb20d", - "reference": "48f445a408c131e38cab1c235aa6d2bb7a0bb20d", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/153ae662783729388a584b4361f2545e4d841e3c", + "reference": "153ae662783729388a584b4361f2545e4d841e3c", "shasum": "" }, "require": { - "php": "^7.4 || ^8.0", - "phpdocumentor/reflection-common": "^2.0" + "doctrine/deprecations": "^1.0", + "php": "^7.3 || ^8.0", + "phpdocumentor/reflection-common": "^2.0", + "phpstan/phpdoc-parser": "^1.13" }, "require-dev": { "ext-tokenizer": "*", + "phpbench/phpbench": "^1.2", "phpstan/extension-installer": "^1.1", "phpstan/phpstan": "^1.8", "phpstan/phpstan-phpunit": "^1.1", @@ -6795,9 +6802,9 @@ "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", "support": { "issues": "https://github.com/phpDocumentor/TypeResolver/issues", - "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.6.2" + "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.8.2" }, - "time": "2022-10-14T12:47:21+00:00" + "time": "2024-02-23T11:10:43+00:00" }, { "name": "phpoption/phpoption", @@ -6876,22 +6883,24 @@ }, { "name": "phpstan/phpdoc-parser", - "version": "1.16.1", + "version": "1.27.0", "source": { "type": "git", "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "e27e92d939e2e3636f0a1f0afaba59692c0bf571" + "reference": "86e4d5a4b036f8f0be1464522f4c6b584c452757" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/e27e92d939e2e3636f0a1f0afaba59692c0bf571", - "reference": "e27e92d939e2e3636f0a1f0afaba59692c0bf571", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/86e4d5a4b036f8f0be1464522f4c6b584c452757", + "reference": "86e4d5a4b036f8f0be1464522f4c6b584c452757", "shasum": "" }, "require": { "php": "^7.2 || ^8.0" }, "require-dev": { + "doctrine/annotations": "^2.0", + "nikic/php-parser": "^4.15", "php-parallel-lint/php-parallel-lint": "^1.2", "phpstan/extension-installer": "^1.0", "phpstan/phpstan": "^1.5", @@ -6915,9 +6924,9 @@ "description": "PHPDoc parser with support for nullable, intersection and generic types", "support": { "issues": "https://github.com/phpstan/phpdoc-parser/issues", - "source": "https://github.com/phpstan/phpdoc-parser/tree/1.16.1" + "source": "https://github.com/phpstan/phpdoc-parser/tree/1.27.0" }, - "time": "2023-02-07T18:11:17+00:00" + "time": "2024-03-21T13:14:53+00:00" }, { "name": "predis/predis", @@ -8815,30 +8824,27 @@ }, { "name": "symfony/browser-kit", - "version": "v6.2.5", + "version": "v6.4.3", "source": { "type": "git", "url": "https://github.com/symfony/browser-kit.git", - "reference": "ea591a69d714216d29cb67b519b509bd32b735a2" + "reference": "495ffa2e6d17e199213f93768efa01af32bbf70e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/browser-kit/zipball/ea591a69d714216d29cb67b519b509bd32b735a2", - "reference": "ea591a69d714216d29cb67b519b509bd32b735a2", + "url": "https://api.github.com/repos/symfony/browser-kit/zipball/495ffa2e6d17e199213f93768efa01af32bbf70e", + "reference": "495ffa2e6d17e199213f93768efa01af32bbf70e", "shasum": "" }, "require": { "php": ">=8.1", - "symfony/dom-crawler": "^5.4|^6.0" + "symfony/dom-crawler": "^5.4|^6.0|^7.0" }, "require-dev": { - "symfony/css-selector": "^5.4|^6.0", - "symfony/http-client": "^5.4|^6.0", - "symfony/mime": "^5.4|^6.0", - "symfony/process": "^5.4|^6.0" - }, - "suggest": { - "symfony/process": "" + "symfony/css-selector": "^5.4|^6.0|^7.0", + "symfony/http-client": "^5.4|^6.0|^7.0", + "symfony/mime": "^5.4|^6.0|^7.0", + "symfony/process": "^5.4|^6.0|^7.0" }, "type": "library", "autoload": { @@ -8866,7 +8872,7 @@ "description": "Simulates the behavior of a web browser, allowing you to make requests, click on links and submit forms programmatically", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/browser-kit/tree/v6.2.5" + "source": "https://github.com/symfony/browser-kit/tree/v6.4.3" }, "funding": [ { @@ -8882,7 +8888,7 @@ "type": "tidelift" } ], - "time": "2023-01-01T08:38:09+00:00" + "time": "2024-01-23T14:51:35+00:00" }, { "name": "symfony/console", @@ -8982,16 +8988,16 @@ }, { "name": "symfony/css-selector", - "version": "v6.2.5", + "version": "v6.4.3", "source": { "type": "git", "url": "https://github.com/symfony/css-selector.git", - "reference": "bf1b9d4ad8b1cf0dbde8b08e0135a2f6259b9ba1" + "reference": "ee0f7ed5cf298cc019431bb3b3977ebc52b86229" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/css-selector/zipball/bf1b9d4ad8b1cf0dbde8b08e0135a2f6259b9ba1", - "reference": "bf1b9d4ad8b1cf0dbde8b08e0135a2f6259b9ba1", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/ee0f7ed5cf298cc019431bb3b3977ebc52b86229", + "reference": "ee0f7ed5cf298cc019431bb3b3977ebc52b86229", "shasum": "" }, "require": { @@ -9027,7 +9033,7 @@ "description": "Converts CSS selectors to XPath expressions", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/css-selector/tree/v6.2.5" + "source": "https://github.com/symfony/css-selector/tree/v6.4.3" }, "funding": [ { @@ -9043,20 +9049,20 @@ "type": "tidelift" } ], - "time": "2023-01-01T08:38:09+00:00" + "time": "2024-01-23T14:51:35+00:00" }, { "name": "symfony/deprecation-contracts", - "version": "v3.2.0", + "version": "v3.4.0", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "1ee04c65529dea5d8744774d474e7cbd2f1206d3" + "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/1ee04c65529dea5d8744774d474e7cbd2f1206d3", - "reference": "1ee04c65529dea5d8744774d474e7cbd2f1206d3", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/7c3aff79d10325257a001fcf92d991f24fc967cf", + "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf", "shasum": "" }, "require": { @@ -9065,7 +9071,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "3.3-dev" + "dev-main": "3.4-dev" }, "thanks": { "name": "symfony/contracts", @@ -9094,7 +9100,7 @@ "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v3.2.0" + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.4.0" }, "funding": [ { @@ -9110,20 +9116,20 @@ "type": "tidelift" } ], - "time": "2022-11-25T10:21:52+00:00" + "time": "2023-05-23T14:45:45+00:00" }, { "name": "symfony/dom-crawler", - "version": "v6.2.5", + "version": "v6.4.4", "source": { "type": "git", "url": "https://github.com/symfony/dom-crawler.git", - "reference": "19aa4962a0687e96941f0bdb27b794c5b73e2394" + "reference": "f0e7ec3fa17000e2d0cb4557b4b47c88a6a63531" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/19aa4962a0687e96941f0bdb27b794c5b73e2394", - "reference": "19aa4962a0687e96941f0bdb27b794c5b73e2394", + "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/f0e7ec3fa17000e2d0cb4557b4b47c88a6a63531", + "reference": "f0e7ec3fa17000e2d0cb4557b4b47c88a6a63531", "shasum": "" }, "require": { @@ -9133,10 +9139,7 @@ "symfony/polyfill-mbstring": "~1.0" }, "require-dev": { - "symfony/css-selector": "^5.4|^6.0" - }, - "suggest": { - "symfony/css-selector": "" + "symfony/css-selector": "^5.4|^6.0|^7.0" }, "type": "library", "autoload": { @@ -9164,7 +9167,7 @@ "description": "Eases DOM navigation for HTML and XML documents", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/dom-crawler/tree/v6.2.5" + "source": "https://github.com/symfony/dom-crawler/tree/v6.4.4" }, "funding": [ { @@ -9180,7 +9183,7 @@ "type": "tidelift" } ], - "time": "2023-01-20T17:45:48+00:00" + "time": "2024-02-07T09:17:57+00:00" }, { "name": "symfony/error-handler", @@ -9338,29 +9341,26 @@ }, { "name": "symfony/event-dispatcher-contracts", - "version": "v3.2.0", + "version": "v3.4.0", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher-contracts.git", - "reference": "0782b0b52a737a05b4383d0df35a474303cabdae" + "reference": "a76aed96a42d2b521153fb382d418e30d18b59df" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/0782b0b52a737a05b4383d0df35a474303cabdae", - "reference": "0782b0b52a737a05b4383d0df35a474303cabdae", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/a76aed96a42d2b521153fb382d418e30d18b59df", + "reference": "a76aed96a42d2b521153fb382d418e30d18b59df", "shasum": "" }, "require": { "php": ">=8.1", "psr/event-dispatcher": "^1" }, - "suggest": { - "symfony/event-dispatcher-implementation": "" - }, "type": "library", "extra": { "branch-alias": { - "dev-main": "3.3-dev" + "dev-main": "3.4-dev" }, "thanks": { "name": "symfony/contracts", @@ -9397,7 +9397,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.2.0" + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.4.0" }, "funding": [ { @@ -9413,7 +9413,7 @@ "type": "tidelift" } ], - "time": "2022-11-25T10:21:52+00:00" + "time": "2023-05-23T14:45:45+00:00" }, { "name": "symfony/finder", @@ -9481,16 +9481,16 @@ }, { "name": "symfony/http-client", - "version": "v6.2.6", + "version": "v6.2.13", "source": { "type": "git", "url": "https://github.com/symfony/http-client.git", - "reference": "6efa9a7521ab7d031a82cf0a759484d1b02a6ad9" + "reference": "297374a399ce6852d5905d92a1351df00bb9dd10" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client/zipball/6efa9a7521ab7d031a82cf0a759484d1b02a6ad9", - "reference": "6efa9a7521ab7d031a82cf0a759484d1b02a6ad9", + "url": "https://api.github.com/repos/symfony/http-client/zipball/297374a399ce6852d5905d92a1351df00bb9dd10", + "reference": "297374a399ce6852d5905d92a1351df00bb9dd10", "shasum": "" }, "require": { @@ -9514,6 +9514,7 @@ "guzzlehttp/promises": "^1.4", "nyholm/psr7": "^1.0", "php-http/httplug": "^1.0|^2.0", + "php-http/message-factory": "^1.0", "psr/http-client": "^1.0", "symfony/dependency-injection": "^5.4|^6.0", "symfony/http-kernel": "^5.4|^6.0", @@ -9545,8 +9546,11 @@ ], "description": "Provides powerful methods to fetch HTTP resources synchronously or asynchronously", "homepage": "https://symfony.com", + "keywords": [ + "http" + ], "support": { - "source": "https://github.com/symfony/http-client/tree/v6.2.6" + "source": "https://github.com/symfony/http-client/tree/v6.2.13" }, "funding": [ { @@ -9562,32 +9566,29 @@ "type": "tidelift" } ], - "time": "2023-01-30T15:46:28+00:00" + "time": "2023-07-03T12:13:45+00:00" }, { "name": "symfony/http-client-contracts", - "version": "v3.2.0", + "version": "v3.4.0", "source": { "type": "git", "url": "https://github.com/symfony/http-client-contracts.git", - "reference": "c5f587eb445224ddfeb05b5ee703476742d730bf" + "reference": "1ee70e699b41909c209a0c930f11034b93578654" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/c5f587eb445224ddfeb05b5ee703476742d730bf", - "reference": "c5f587eb445224ddfeb05b5ee703476742d730bf", + "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/1ee70e699b41909c209a0c930f11034b93578654", + "reference": "1ee70e699b41909c209a0c930f11034b93578654", "shasum": "" }, "require": { "php": ">=8.1" }, - "suggest": { - "symfony/http-client-implementation": "" - }, "type": "library", "extra": { "branch-alias": { - "dev-main": "3.3-dev" + "dev-main": "3.4-dev" }, "thanks": { "name": "symfony/contracts", @@ -9627,7 +9628,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/http-client-contracts/tree/v3.2.0" + "source": "https://github.com/symfony/http-client-contracts/tree/v3.4.0" }, "funding": [ { @@ -9643,7 +9644,7 @@ "type": "tidelift" } ], - "time": "2022-11-25T10:21:52+00:00" + "time": "2023-07-30T20:28:31+00:00" }, { "name": "symfony/http-foundation", @@ -9984,16 +9985,16 @@ }, { "name": "symfony/polyfill-ctype", - "version": "v1.27.0", + "version": "v1.29.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "5bbc823adecdae860bb64756d639ecfec17b050a" + "reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/5bbc823adecdae860bb64756d639ecfec17b050a", - "reference": "5bbc823adecdae860bb64756d639ecfec17b050a", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ef4d7e442ca910c4764bce785146269b30cb5fc4", + "reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4", "shasum": "" }, "require": { @@ -10007,9 +10008,6 @@ }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.27-dev" - }, "thanks": { "name": "symfony/polyfill", "url": "https://github.com/symfony/polyfill" @@ -10046,7 +10044,7 @@ "portable" ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.27.0" + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.29.0" }, "funding": [ { @@ -10062,20 +10060,20 @@ "type": "tidelift" } ], - "time": "2022-11-03T14:55:06+00:00" + "time": "2024-01-29T20:11:03+00:00" }, { "name": "symfony/polyfill-intl-grapheme", - "version": "v1.27.0", + "version": "v1.29.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference": "511a08c03c1960e08a883f4cffcacd219b758354" + "reference": "32a9da87d7b3245e09ac426c83d334ae9f06f80f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/511a08c03c1960e08a883f4cffcacd219b758354", - "reference": "511a08c03c1960e08a883f4cffcacd219b758354", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/32a9da87d7b3245e09ac426c83d334ae9f06f80f", + "reference": "32a9da87d7b3245e09ac426c83d334ae9f06f80f", "shasum": "" }, "require": { @@ -10086,9 +10084,6 @@ }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.27-dev" - }, "thanks": { "name": "symfony/polyfill", "url": "https://github.com/symfony/polyfill" @@ -10127,7 +10122,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.27.0" + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.29.0" }, "funding": [ { @@ -10143,20 +10138,20 @@ "type": "tidelift" } ], - "time": "2022-11-03T14:55:06+00:00" + "time": "2024-01-29T20:11:03+00:00" }, { "name": "symfony/polyfill-intl-idn", - "version": "v1.27.0", + "version": "v1.29.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-idn.git", - "reference": "639084e360537a19f9ee352433b84ce831f3d2da" + "reference": "a287ed7475f85bf6f61890146edbc932c0fff919" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/639084e360537a19f9ee352433b84ce831f3d2da", - "reference": "639084e360537a19f9ee352433b84ce831f3d2da", + "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/a287ed7475f85bf6f61890146edbc932c0fff919", + "reference": "a287ed7475f85bf6f61890146edbc932c0fff919", "shasum": "" }, "require": { @@ -10169,9 +10164,6 @@ }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.27-dev" - }, "thanks": { "name": "symfony/polyfill", "url": "https://github.com/symfony/polyfill" @@ -10214,7 +10206,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.27.0" + "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.29.0" }, "funding": [ { @@ -10230,20 +10222,20 @@ "type": "tidelift" } ], - "time": "2022-11-03T14:55:06+00:00" + "time": "2024-01-29T20:11:03+00:00" }, { "name": "symfony/polyfill-intl-normalizer", - "version": "v1.27.0", + "version": "v1.29.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "19bd1e4fcd5b91116f14d8533c57831ed00571b6" + "reference": "bc45c394692b948b4d383a08d7753968bed9a83d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/19bd1e4fcd5b91116f14d8533c57831ed00571b6", - "reference": "19bd1e4fcd5b91116f14d8533c57831ed00571b6", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/bc45c394692b948b4d383a08d7753968bed9a83d", + "reference": "bc45c394692b948b4d383a08d7753968bed9a83d", "shasum": "" }, "require": { @@ -10254,9 +10246,6 @@ }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.27-dev" - }, "thanks": { "name": "symfony/polyfill", "url": "https://github.com/symfony/polyfill" @@ -10298,7 +10287,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.27.0" + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.29.0" }, "funding": [ { @@ -10314,20 +10303,20 @@ "type": "tidelift" } ], - "time": "2022-11-03T14:55:06+00:00" + "time": "2024-01-29T20:11:03+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.27.0", + "version": "v1.29.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534" + "reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/8ad114f6b39e2c98a8b0e3bd907732c207c2b534", - "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9773676c8a1bb1f8d4340a62efe641cf76eda7ec", + "reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec", "shasum": "" }, "require": { @@ -10341,9 +10330,6 @@ }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.27-dev" - }, "thanks": { "name": "symfony/polyfill", "url": "https://github.com/symfony/polyfill" @@ -10381,7 +10367,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.27.0" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.29.0" }, "funding": [ { @@ -10397,20 +10383,20 @@ "type": "tidelift" } ], - "time": "2022-11-03T14:55:06+00:00" + "time": "2024-01-29T20:11:03+00:00" }, { "name": "symfony/polyfill-php72", - "version": "v1.27.0", + "version": "v1.29.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php72.git", - "reference": "869329b1e9894268a8a61dabb69153029b7a8c97" + "reference": "861391a8da9a04cbad2d232ddd9e4893220d6e25" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/869329b1e9894268a8a61dabb69153029b7a8c97", - "reference": "869329b1e9894268a8a61dabb69153029b7a8c97", + "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/861391a8da9a04cbad2d232ddd9e4893220d6e25", + "reference": "861391a8da9a04cbad2d232ddd9e4893220d6e25", "shasum": "" }, "require": { @@ -10418,9 +10404,6 @@ }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.27-dev" - }, "thanks": { "name": "symfony/polyfill", "url": "https://github.com/symfony/polyfill" @@ -10457,7 +10440,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php72/tree/v1.27.0" + "source": "https://github.com/symfony/polyfill-php72/tree/v1.29.0" }, "funding": [ { @@ -10473,20 +10456,20 @@ "type": "tidelift" } ], - "time": "2022-11-03T14:55:06+00:00" + "time": "2024-01-29T20:11:03+00:00" }, { "name": "symfony/polyfill-php80", - "version": "v1.27.0", + "version": "v1.29.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936" + "reference": "87b68208d5c1188808dd7839ee1e6c8ec3b02f1b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936", - "reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/87b68208d5c1188808dd7839ee1e6c8ec3b02f1b", + "reference": "87b68208d5c1188808dd7839ee1e6c8ec3b02f1b", "shasum": "" }, "require": { @@ -10494,9 +10477,6 @@ }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.27-dev" - }, "thanks": { "name": "symfony/polyfill", "url": "https://github.com/symfony/polyfill" @@ -10540,7 +10520,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.27.0" + "source": "https://github.com/symfony/polyfill-php80/tree/v1.29.0" }, "funding": [ { @@ -10556,7 +10536,7 @@ "type": "tidelift" } ], - "time": "2022-11-03T14:55:06+00:00" + "time": "2024-01-29T20:11:03+00:00" }, { "name": "symfony/process", @@ -10709,16 +10689,16 @@ }, { "name": "symfony/serializer", - "version": "v5.4.19", + "version": "v5.4.36", "source": { "type": "git", "url": "https://github.com/symfony/serializer.git", - "reference": "2139fa01c19a764af81191d635b2b9302f4bafd8" + "reference": "05137a513f4c5a5e56ffbcf53847a93284b49f67" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/serializer/zipball/2139fa01c19a764af81191d635b2b9302f4bafd8", - "reference": "2139fa01c19a764af81191d635b2b9302f4bafd8", + "url": "https://api.github.com/repos/symfony/serializer/zipball/05137a513f4c5a5e56ffbcf53847a93284b49f67", + "reference": "05137a513f4c5a5e56ffbcf53847a93284b49f67", "shasum": "" }, "require": { @@ -10730,10 +10710,10 @@ "conflict": { "doctrine/annotations": "<1.12", "phpdocumentor/reflection-docblock": "<3.2.2", - "phpdocumentor/type-resolver": "<1.4.0|>=1.7.0", + "phpdocumentor/type-resolver": "<1.4.0", "symfony/dependency-injection": "<4.4", "symfony/property-access": "<5.4", - "symfony/property-info": "<5.3.13", + "symfony/property-info": "<5.4.24|>=6,<6.2.11", "symfony/uid": "<5.3", "symfony/yaml": "<4.4" }, @@ -10749,8 +10729,8 @@ "symfony/http-foundation": "^4.4|^5.0|^6.0", "symfony/http-kernel": "^4.4|^5.0|^6.0", "symfony/mime": "^4.4|^5.0|^6.0", - "symfony/property-access": "^5.4|^6.0", - "symfony/property-info": "^5.3.13|^6.0", + "symfony/property-access": "^5.4.26|^6.3", + "symfony/property-info": "^5.4.24|^6.2.11", "symfony/uid": "^5.3|^6.0", "symfony/validator": "^4.4|^5.0|^6.0", "symfony/var-dumper": "^4.4|^5.0|^6.0", @@ -10792,7 +10772,7 @@ "description": "Handles serializing and deserializing data structures, including object graphs, into array structures or other formats like XML and JSON.", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/serializer/tree/v5.4.19" + "source": "https://github.com/symfony/serializer/tree/v5.4.36" }, "funding": [ { @@ -10808,36 +10788,33 @@ "type": "tidelift" } ], - "time": "2023-01-14T08:18:46+00:00" + "time": "2024-02-22T18:40:43+00:00" }, { "name": "symfony/service-contracts", - "version": "v3.2.0", + "version": "v3.4.1", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "aac98028c69df04ee77eb69b96b86ee51fbf4b75" + "reference": "fe07cbc8d837f60caf7018068e350cc5163681a0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/aac98028c69df04ee77eb69b96b86ee51fbf4b75", - "reference": "aac98028c69df04ee77eb69b96b86ee51fbf4b75", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/fe07cbc8d837f60caf7018068e350cc5163681a0", + "reference": "fe07cbc8d837f60caf7018068e350cc5163681a0", "shasum": "" }, "require": { "php": ">=8.1", - "psr/container": "^2.0" + "psr/container": "^1.1|^2.0" }, "conflict": { "ext-psr": "<1.1|>=2" }, - "suggest": { - "symfony/service-implementation": "" - }, "type": "library", "extra": { "branch-alias": { - "dev-main": "3.3-dev" + "dev-main": "3.4-dev" }, "thanks": { "name": "symfony/contracts", @@ -10877,7 +10854,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/service-contracts/tree/v3.2.0" + "source": "https://github.com/symfony/service-contracts/tree/v3.4.1" }, "funding": [ { @@ -10893,20 +10870,20 @@ "type": "tidelift" } ], - "time": "2022-11-25T10:21:52+00:00" + "time": "2023-12-26T14:02:43+00:00" }, { "name": "symfony/string", - "version": "v6.2.5", + "version": "v6.4.4", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "b2dac0fa27b1ac0f9c0c0b23b43977f12308d0b0" + "reference": "4e465a95bdc32f49cf4c7f07f751b843bbd6dcd9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/b2dac0fa27b1ac0f9c0c0b23b43977f12308d0b0", - "reference": "b2dac0fa27b1ac0f9c0c0b23b43977f12308d0b0", + "url": "https://api.github.com/repos/symfony/string/zipball/4e465a95bdc32f49cf4c7f07f751b843bbd6dcd9", + "reference": "4e465a95bdc32f49cf4c7f07f751b843bbd6dcd9", "shasum": "" }, "require": { @@ -10917,14 +10894,14 @@ "symfony/polyfill-mbstring": "~1.0" }, "conflict": { - "symfony/translation-contracts": "<2.0" + "symfony/translation-contracts": "<2.5" }, "require-dev": { - "symfony/error-handler": "^5.4|^6.0", - "symfony/http-client": "^5.4|^6.0", - "symfony/intl": "^6.2", - "symfony/translation-contracts": "^2.0|^3.0", - "symfony/var-exporter": "^5.4|^6.0" + "symfony/error-handler": "^5.4|^6.0|^7.0", + "symfony/http-client": "^5.4|^6.0|^7.0", + "symfony/intl": "^6.2|^7.0", + "symfony/translation-contracts": "^2.5|^3.0", + "symfony/var-exporter": "^5.4|^6.0|^7.0" }, "type": "library", "autoload": { @@ -10963,7 +10940,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v6.2.5" + "source": "https://github.com/symfony/string/tree/v6.4.4" }, "funding": [ { @@ -10979,7 +10956,7 @@ "type": "tidelift" } ], - "time": "2023-01-01T08:38:09+00:00" + "time": "2024-02-01T13:16:41+00:00" }, { "name": "symfony/translation", From 2a7fcff3292e200f0ff7756a9da6f559b1cd1890 Mon Sep 17 00:00:00 2001 From: pushrbx Date: Wed, 10 Apr 2024 18:57:10 +0100 Subject: [PATCH 11/30] removed annoying warning log --- app/Anime.php | 1 - 1 file changed, 1 deletion(-) diff --git a/app/Anime.php b/app/Anime.php index 61df1e1..daa54e0 100644 --- a/app/Anime.php +++ b/app/Anime.php @@ -103,7 +103,6 @@ class Anime extends JikanApiSearchableModel || !is_string($premiered) || !preg_match('~(Winter|Spring|Summer|Fall|)\s([\d+]{4})~', $premiered) ) { - Log::warning("Invalid premiered value in Anime model[$this->mal_id]: " . $premiered); return null; } From 9de8ffc9db0ca4aa2934c79c6181892a0b5c3a32 Mon Sep 17 00:00:00 2001 From: pushrbx Date: Wed, 10 Apr 2024 18:59:30 +0100 Subject: [PATCH 12/30] 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"]] ]; } From 9342407bef741d58c6d8efd71afe29d99ba7df35 Mon Sep 17 00:00:00 2001 From: pushrbx Date: Thu, 11 Apr 2024 00:01:40 +0100 Subject: [PATCH 13/30] fixed tests according to the recent factory changes --- database/factories/JikanMediaModelFactory.php | 2 ++ tests/Integration/AnimeSearchEndpointTest.php | 6 +++--- tests/Integration/MangaSearchEndpointTest.php | 6 +++--- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/database/factories/JikanMediaModelFactory.php b/database/factories/JikanMediaModelFactory.php index 9b41962..78aa748 100644 --- a/database/factories/JikanMediaModelFactory.php +++ b/database/factories/JikanMediaModelFactory.php @@ -62,6 +62,8 @@ abstract class JikanMediaModelFactory extends JikanModelFactory implements Media return $this->state($this->serializeStateDefinition($this->getStateOverrides($additionalParams, $doOpposite))); } + // we want to generate overrides for each manufactured item, so all of them will call the faker for values, + // and they should have their own values, increasing the randomness of the generated data /** @noinspection PhpParamsInspection */ return $this->state(new Sequence(fn(Sequence $_) => $this->serializeStateDefinition($this->getStateOverrides($additionalParams, $doOpposite)))); } diff --git a/tests/Integration/AnimeSearchEndpointTest.php b/tests/Integration/AnimeSearchEndpointTest.php index eb0314c..7184146 100644 --- a/tests/Integration/AnimeSearchEndpointTest.php +++ b/tests/Integration/AnimeSearchEndpointTest.php @@ -261,16 +261,16 @@ class AnimeSearchEndpointTest extends TestCase */ public function testSearchByEndDate($params) { - $overrides = $this->generateFiveSpecificAndTenRandomElementsInDb($params); + $this->generateFiveSpecificAndTenRandomElementsInDb($params); $content = $this->getJsonResponse($params); $actualEndDate = Carbon::parse(data_get($content, "data.0.aired.to")); - $paramEndDate = Carbon::parse($overrides["aired"]["to"]); + $paramEndDate = Carbon::parse($params['end_date']); $this->seeStatusCode(200); $this->assertPaginationData(5); - $this->assertLessThanOrEqual(0, $actualEndDate->diff($paramEndDate)->days); + $this->assertGreaterThanOrEqual(1, $actualEndDate->diff($paramEndDate)->days); // we created 5 elements according to parameters, so we expect 5 of them. $this->assertCount(5, $content["data"]); } diff --git a/tests/Integration/MangaSearchEndpointTest.php b/tests/Integration/MangaSearchEndpointTest.php index 0c5ff4c..fbc9d5b 100644 --- a/tests/Integration/MangaSearchEndpointTest.php +++ b/tests/Integration/MangaSearchEndpointTest.php @@ -243,16 +243,16 @@ class MangaSearchEndpointTest extends TestCase */ public function testSearchByEndDate($params) { - $overrides = $this->generateFiveSpecificAndTenRandomElementsInDb($params); + $this->generateFiveSpecificAndTenRandomElementsInDb($params); $content = $this->getJsonResponse($params); $actualEndDate = Carbon::parse(data_get($content, "data.0.published.to")); - $paramEndDate = Carbon::parse($overrides["published"]["to"]); + $paramEndDate = Carbon::parse($params["end_date"]); $this->seeStatusCode(200); $this->assertPaginationData(5); - $this->assertLessThanOrEqual(0, $actualEndDate->diff($paramEndDate)->days); + $this->assertGreaterThanOrEqual(1, $actualEndDate->diff($paramEndDate)->days); // we created 5 elements according to parameters, so we expect 5 of them. $this->assertCount(5, $content["data"]); } From c44949ed21e1a78e0a1a319ff2f0b38d7fff6d6c Mon Sep 17 00:00:00 2001 From: pushrbx Date: Sun, 26 May 2024 14:44:00 +0200 Subject: [PATCH 14/30] bumped gh actions versions --- .github/workflows/container-image-release.yml | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/.github/workflows/container-image-release.yml b/.github/workflows/container-image-release.yml index b9d0f9d..5ebe0de 100644 --- a/.github/workflows/container-image-release.yml +++ b/.github/workflows/container-image-release.yml @@ -86,10 +86,14 @@ jobs: digest="${{ steps.build.outputs.digest }}" touch "/tmp/digests/${digest#sha256:}" + - name: Transform platform value + id: platform_transform + run: echo "platform=$(echo '${{ matrix.platform }}' | sed 's/\//_/g')" >> $GITHUB_OUTPUT + - name: Upload digest - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: - name: digests + name: digests-${{ steps.platform_transform.outputs.platform }} path: /tmp/digests/* if-no-files-found: error retention-days: 1 @@ -101,9 +105,10 @@ jobs: - build-app-image steps: - name: Download digests - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: - name: digests + name: digests-* + merge-multiple: true path: /tmp/digests - name: Set up Docker Buildx From d25fd7820f46f6c82ddf2ae0105e1017d72a8507 Mon Sep 17 00:00:00 2001 From: Irfan Date: Wed, 29 May 2024 11:18:56 +0500 Subject: [PATCH 15/30] Update composer.lock --- composer.lock | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/composer.lock b/composer.lock index fd737c4..52e93b3 100644 --- a/composer.lock +++ b/composer.lock @@ -4554,16 +4554,16 @@ }, { "name": "jikan-me/jikan", - "version": "v4.0.9", + "version": "v4.0.10", "source": { "type": "git", "url": "https://github.com/jikan-me/jikan.git", - "reference": "eac008510873c9ef4a61d6a7b684153be14269df" + "reference": "6853fac21bfdbb89b1f5bd0f85cc12325a8ed074" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/jikan-me/jikan/zipball/eac008510873c9ef4a61d6a7b684153be14269df", - "reference": "eac008510873c9ef4a61d6a7b684153be14269df", + "url": "https://api.github.com/repos/jikan-me/jikan/zipball/6853fac21bfdbb89b1f5bd0f85cc12325a8ed074", + "reference": "6853fac21bfdbb89b1f5bd0f85cc12325a8ed074", "shasum": "" }, "require": { @@ -4602,7 +4602,7 @@ "description": "Jikan is an unofficial MyAnimeList API", "support": { "issues": "https://github.com/jikan-me/jikan/issues", - "source": "https://github.com/jikan-me/jikan/tree/v4.0.9" + "source": "https://github.com/jikan-me/jikan/tree/v4.0.10" }, "funding": [ { @@ -4610,7 +4610,7 @@ "type": "patreon" } ], - "time": "2024-04-01T21:41:29+00:00" + "time": "2024-05-29T06:11:45+00:00" }, { "name": "jms/metadata", @@ -13590,5 +13590,5 @@ "ext-mongodb": "*" }, "platform-dev": [], - "plugin-api-version": "2.6.0" + "plugin-api-version": "2.3.0" } From 2f2dd8d95c3e6442577f3847ce3cc9a9dac2d614 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 31 May 2024 04:38:18 +0000 Subject: [PATCH 16/30] Bump jikan-me/jikan from 4.0.10 to 4.0.11 Bumps [jikan-me/jikan](https://github.com/jikan-me/jikan) from 4.0.10 to 4.0.11. - [Release notes](https://github.com/jikan-me/jikan/releases) - [Commits](https://github.com/jikan-me/jikan/compare/v4.0.10...v4.0.11) --- updated-dependencies: - dependency-name: jikan-me/jikan dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- composer.lock | 171 +++++++++++++++++++++++++------------------------- 1 file changed, 86 insertions(+), 85 deletions(-) diff --git a/composer.lock b/composer.lock index 52e93b3..b7d9f1a 100644 --- a/composer.lock +++ b/composer.lock @@ -4554,16 +4554,16 @@ }, { "name": "jikan-me/jikan", - "version": "v4.0.10", + "version": "v4.0.11", "source": { "type": "git", "url": "https://github.com/jikan-me/jikan.git", - "reference": "6853fac21bfdbb89b1f5bd0f85cc12325a8ed074" + "reference": "fcc8d20817ce29332b496a21652b9965c6c8196c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/jikan-me/jikan/zipball/6853fac21bfdbb89b1f5bd0f85cc12325a8ed074", - "reference": "6853fac21bfdbb89b1f5bd0f85cc12325a8ed074", + "url": "https://api.github.com/repos/jikan-me/jikan/zipball/fcc8d20817ce29332b496a21652b9965c6c8196c", + "reference": "fcc8d20817ce29332b496a21652b9965c6c8196c", "shasum": "" }, "require": { @@ -4602,7 +4602,7 @@ "description": "Jikan is an unofficial MyAnimeList API", "support": { "issues": "https://github.com/jikan-me/jikan/issues", - "source": "https://github.com/jikan-me/jikan/tree/v4.0.10" + "source": "https://github.com/jikan-me/jikan/tree/v4.0.11" }, "funding": [ { @@ -4610,7 +4610,7 @@ "type": "patreon" } ], - "time": "2024-05-29T06:11:45+00:00" + "time": "2024-05-30T08:15:50+00:00" }, { "name": "jms/metadata", @@ -5506,16 +5506,16 @@ }, { "name": "masterminds/html5", - "version": "2.8.1", + "version": "2.9.0", "source": { "type": "git", "url": "https://github.com/Masterminds/html5-php.git", - "reference": "f47dcf3c70c584de14f21143c55d9939631bc6cf" + "reference": "f5ac2c0b0a2eefca70b2ce32a5809992227e75a6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Masterminds/html5-php/zipball/f47dcf3c70c584de14f21143c55d9939631bc6cf", - "reference": "f47dcf3c70c584de14f21143c55d9939631bc6cf", + "url": "https://api.github.com/repos/Masterminds/html5-php/zipball/f5ac2c0b0a2eefca70b2ce32a5809992227e75a6", + "reference": "f5ac2c0b0a2eefca70b2ce32a5809992227e75a6", "shasum": "" }, "require": { @@ -5523,7 +5523,7 @@ "php": ">=5.3.0" }, "require-dev": { - "phpunit/phpunit": "^4.8.35 || ^5.7.21 || ^6 || ^7 || ^8" + "phpunit/phpunit": "^4.8.35 || ^5.7.21 || ^6 || ^7 || ^8 || ^9" }, "type": "library", "extra": { @@ -5567,9 +5567,9 @@ ], "support": { "issues": "https://github.com/Masterminds/html5-php/issues", - "source": "https://github.com/Masterminds/html5-php/tree/2.8.1" + "source": "https://github.com/Masterminds/html5-php/tree/2.9.0" }, - "time": "2023-05-10T11:58:31+00:00" + "time": "2024-03-31T07:05:07+00:00" }, { "name": "matchish/laravel-scout-elasticsearch", @@ -6883,16 +6883,16 @@ }, { "name": "phpstan/phpdoc-parser", - "version": "1.27.0", + "version": "1.29.0", "source": { "type": "git", "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "86e4d5a4b036f8f0be1464522f4c6b584c452757" + "reference": "536889f2b340489d328f5ffb7b02bb6b183ddedc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/86e4d5a4b036f8f0be1464522f4c6b584c452757", - "reference": "86e4d5a4b036f8f0be1464522f4c6b584c452757", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/536889f2b340489d328f5ffb7b02bb6b183ddedc", + "reference": "536889f2b340489d328f5ffb7b02bb6b183ddedc", "shasum": "" }, "require": { @@ -6924,9 +6924,9 @@ "description": "PHPDoc parser with support for nullable, intersection and generic types", "support": { "issues": "https://github.com/phpstan/phpdoc-parser/issues", - "source": "https://github.com/phpstan/phpdoc-parser/tree/1.27.0" + "source": "https://github.com/phpstan/phpdoc-parser/tree/1.29.0" }, - "time": "2024-03-21T13:14:53+00:00" + "time": "2024-05-06T12:04:23+00:00" }, { "name": "predis/predis", @@ -8824,16 +8824,16 @@ }, { "name": "symfony/browser-kit", - "version": "v6.4.3", + "version": "v6.4.7", "source": { "type": "git", "url": "https://github.com/symfony/browser-kit.git", - "reference": "495ffa2e6d17e199213f93768efa01af32bbf70e" + "reference": "c276856598f70e96f75403fc04841cec1dc56e74" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/browser-kit/zipball/495ffa2e6d17e199213f93768efa01af32bbf70e", - "reference": "495ffa2e6d17e199213f93768efa01af32bbf70e", + "url": "https://api.github.com/repos/symfony/browser-kit/zipball/c276856598f70e96f75403fc04841cec1dc56e74", + "reference": "c276856598f70e96f75403fc04841cec1dc56e74", "shasum": "" }, "require": { @@ -8872,7 +8872,7 @@ "description": "Simulates the behavior of a web browser, allowing you to make requests, click on links and submit forms programmatically", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/browser-kit/tree/v6.4.3" + "source": "https://github.com/symfony/browser-kit/tree/v6.4.7" }, "funding": [ { @@ -8888,7 +8888,7 @@ "type": "tidelift" } ], - "time": "2024-01-23T14:51:35+00:00" + "time": "2024-04-18T09:22:46+00:00" }, { "name": "symfony/console", @@ -8988,16 +8988,16 @@ }, { "name": "symfony/css-selector", - "version": "v6.4.3", + "version": "v6.4.7", "source": { "type": "git", "url": "https://github.com/symfony/css-selector.git", - "reference": "ee0f7ed5cf298cc019431bb3b3977ebc52b86229" + "reference": "1c5d5c2103c3762aff27a27e1e2409e30a79083b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/css-selector/zipball/ee0f7ed5cf298cc019431bb3b3977ebc52b86229", - "reference": "ee0f7ed5cf298cc019431bb3b3977ebc52b86229", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/1c5d5c2103c3762aff27a27e1e2409e30a79083b", + "reference": "1c5d5c2103c3762aff27a27e1e2409e30a79083b", "shasum": "" }, "require": { @@ -9033,7 +9033,7 @@ "description": "Converts CSS selectors to XPath expressions", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/css-selector/tree/v6.4.3" + "source": "https://github.com/symfony/css-selector/tree/v6.4.7" }, "funding": [ { @@ -9049,20 +9049,20 @@ "type": "tidelift" } ], - "time": "2024-01-23T14:51:35+00:00" + "time": "2024-04-18T09:22:46+00:00" }, { "name": "symfony/deprecation-contracts", - "version": "v3.4.0", + "version": "v3.5.0", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf" + "reference": "0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/7c3aff79d10325257a001fcf92d991f24fc967cf", - "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1", + "reference": "0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1", "shasum": "" }, "require": { @@ -9071,7 +9071,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "3.4-dev" + "dev-main": "3.5-dev" }, "thanks": { "name": "symfony/contracts", @@ -9100,7 +9100,7 @@ "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v3.4.0" + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.5.0" }, "funding": [ { @@ -9116,20 +9116,20 @@ "type": "tidelift" } ], - "time": "2023-05-23T14:45:45+00:00" + "time": "2024-04-18T09:32:20+00:00" }, { "name": "symfony/dom-crawler", - "version": "v6.4.4", + "version": "v6.4.7", "source": { "type": "git", "url": "https://github.com/symfony/dom-crawler.git", - "reference": "f0e7ec3fa17000e2d0cb4557b4b47c88a6a63531" + "reference": "2088c5da700b1e7a8689fffc10dda6c1f643deea" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/f0e7ec3fa17000e2d0cb4557b4b47c88a6a63531", - "reference": "f0e7ec3fa17000e2d0cb4557b4b47c88a6a63531", + "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/2088c5da700b1e7a8689fffc10dda6c1f643deea", + "reference": "2088c5da700b1e7a8689fffc10dda6c1f643deea", "shasum": "" }, "require": { @@ -9167,7 +9167,7 @@ "description": "Eases DOM navigation for HTML and XML documents", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/dom-crawler/tree/v6.4.4" + "source": "https://github.com/symfony/dom-crawler/tree/v6.4.7" }, "funding": [ { @@ -9183,7 +9183,7 @@ "type": "tidelift" } ], - "time": "2024-02-07T09:17:57+00:00" + "time": "2024-04-18T09:22:46+00:00" }, { "name": "symfony/error-handler", @@ -9341,16 +9341,16 @@ }, { "name": "symfony/event-dispatcher-contracts", - "version": "v3.4.0", + "version": "v3.5.0", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher-contracts.git", - "reference": "a76aed96a42d2b521153fb382d418e30d18b59df" + "reference": "8f93aec25d41b72493c6ddff14e916177c9efc50" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/a76aed96a42d2b521153fb382d418e30d18b59df", - "reference": "a76aed96a42d2b521153fb382d418e30d18b59df", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/8f93aec25d41b72493c6ddff14e916177c9efc50", + "reference": "8f93aec25d41b72493c6ddff14e916177c9efc50", "shasum": "" }, "require": { @@ -9360,7 +9360,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "3.4-dev" + "dev-main": "3.5-dev" }, "thanks": { "name": "symfony/contracts", @@ -9397,7 +9397,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.4.0" + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.5.0" }, "funding": [ { @@ -9413,7 +9413,7 @@ "type": "tidelift" } ], - "time": "2023-05-23T14:45:45+00:00" + "time": "2024-04-18T09:32:20+00:00" }, { "name": "symfony/finder", @@ -9570,16 +9570,16 @@ }, { "name": "symfony/http-client-contracts", - "version": "v3.4.0", + "version": "v3.5.0", "source": { "type": "git", "url": "https://github.com/symfony/http-client-contracts.git", - "reference": "1ee70e699b41909c209a0c930f11034b93578654" + "reference": "20414d96f391677bf80078aa55baece78b82647d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/1ee70e699b41909c209a0c930f11034b93578654", - "reference": "1ee70e699b41909c209a0c930f11034b93578654", + "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/20414d96f391677bf80078aa55baece78b82647d", + "reference": "20414d96f391677bf80078aa55baece78b82647d", "shasum": "" }, "require": { @@ -9588,7 +9588,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "3.4-dev" + "dev-main": "3.5-dev" }, "thanks": { "name": "symfony/contracts", @@ -9628,7 +9628,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/http-client-contracts/tree/v3.4.0" + "source": "https://github.com/symfony/http-client-contracts/tree/v3.5.0" }, "funding": [ { @@ -9644,7 +9644,7 @@ "type": "tidelift" } ], - "time": "2023-07-30T20:28:31+00:00" + "time": "2024-04-18T09:32:20+00:00" }, { "name": "symfony/http-foundation", @@ -10689,16 +10689,16 @@ }, { "name": "symfony/serializer", - "version": "v5.4.36", + "version": "v5.4.39", "source": { "type": "git", "url": "https://github.com/symfony/serializer.git", - "reference": "05137a513f4c5a5e56ffbcf53847a93284b49f67" + "reference": "107d7e0b67f9295098aa7b29b1daeddd6303c658" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/serializer/zipball/05137a513f4c5a5e56ffbcf53847a93284b49f67", - "reference": "05137a513f4c5a5e56ffbcf53847a93284b49f67", + "url": "https://api.github.com/repos/symfony/serializer/zipball/107d7e0b67f9295098aa7b29b1daeddd6303c658", + "reference": "107d7e0b67f9295098aa7b29b1daeddd6303c658", "shasum": "" }, "require": { @@ -10772,7 +10772,7 @@ "description": "Handles serializing and deserializing data structures, including object graphs, into array structures or other formats like XML and JSON.", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/serializer/tree/v5.4.36" + "source": "https://github.com/symfony/serializer/tree/v5.4.39" }, "funding": [ { @@ -10788,25 +10788,26 @@ "type": "tidelift" } ], - "time": "2024-02-22T18:40:43+00:00" + "time": "2024-04-18T08:26:06+00:00" }, { "name": "symfony/service-contracts", - "version": "v3.4.1", + "version": "v3.5.0", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "fe07cbc8d837f60caf7018068e350cc5163681a0" + "reference": "bd1d9e59a81d8fa4acdcea3f617c581f7475a80f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/fe07cbc8d837f60caf7018068e350cc5163681a0", - "reference": "fe07cbc8d837f60caf7018068e350cc5163681a0", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/bd1d9e59a81d8fa4acdcea3f617c581f7475a80f", + "reference": "bd1d9e59a81d8fa4acdcea3f617c581f7475a80f", "shasum": "" }, "require": { "php": ">=8.1", - "psr/container": "^1.1|^2.0" + "psr/container": "^1.1|^2.0", + "symfony/deprecation-contracts": "^2.5|^3" }, "conflict": { "ext-psr": "<1.1|>=2" @@ -10814,7 +10815,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "3.4-dev" + "dev-main": "3.5-dev" }, "thanks": { "name": "symfony/contracts", @@ -10854,7 +10855,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/service-contracts/tree/v3.4.1" + "source": "https://github.com/symfony/service-contracts/tree/v3.5.0" }, "funding": [ { @@ -10870,20 +10871,20 @@ "type": "tidelift" } ], - "time": "2023-12-26T14:02:43+00:00" + "time": "2024-04-18T09:32:20+00:00" }, { "name": "symfony/string", - "version": "v6.4.4", + "version": "v6.4.7", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "4e465a95bdc32f49cf4c7f07f751b843bbd6dcd9" + "reference": "ffeb9591c61f65a68d47f77d12b83fa530227a69" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/4e465a95bdc32f49cf4c7f07f751b843bbd6dcd9", - "reference": "4e465a95bdc32f49cf4c7f07f751b843bbd6dcd9", + "url": "https://api.github.com/repos/symfony/string/zipball/ffeb9591c61f65a68d47f77d12b83fa530227a69", + "reference": "ffeb9591c61f65a68d47f77d12b83fa530227a69", "shasum": "" }, "require": { @@ -10940,7 +10941,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v6.4.4" + "source": "https://github.com/symfony/string/tree/v6.4.7" }, "funding": [ { @@ -10956,7 +10957,7 @@ "type": "tidelift" } ], - "time": "2024-02-01T13:16:41+00:00" + "time": "2024-04-18T09:22:46+00:00" }, { "name": "symfony/translation", @@ -11057,16 +11058,16 @@ }, { "name": "symfony/translation-contracts", - "version": "v2.5.2", + "version": "v2.5.3", "source": { "type": "git", "url": "https://github.com/symfony/translation-contracts.git", - "reference": "136b19dd05cdf0709db6537d058bcab6dd6e2dbe" + "reference": "b0073a77ac0b7ea55131020e87b1e3af540f4664" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/136b19dd05cdf0709db6537d058bcab6dd6e2dbe", - "reference": "136b19dd05cdf0709db6537d058bcab6dd6e2dbe", + "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/b0073a77ac0b7ea55131020e87b1e3af540f4664", + "reference": "b0073a77ac0b7ea55131020e87b1e3af540f4664", "shasum": "" }, "require": { @@ -11115,7 +11116,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/translation-contracts/tree/v2.5.2" + "source": "https://github.com/symfony/translation-contracts/tree/v2.5.3" }, "funding": [ { @@ -11131,7 +11132,7 @@ "type": "tidelift" } ], - "time": "2022-06-27T16:58:25+00:00" + "time": "2024-01-23T13:51:25+00:00" }, { "name": "symfony/var-dumper", @@ -13590,5 +13591,5 @@ "ext-mongodb": "*" }, "platform-dev": [], - "plugin-api-version": "2.3.0" + "plugin-api-version": "2.6.0" } From 7dd9625588616876d4aa07848effc7ff2c69efb4 Mon Sep 17 00:00:00 2001 From: pushrbx Date: Wed, 5 Jun 2024 14:40:05 +0100 Subject: [PATCH 17/30] Fixed a bug in container-image-release.yml --- .github/workflows/container-image-release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/container-image-release.yml b/.github/workflows/container-image-release.yml index 5ebe0de..bc73b12 100644 --- a/.github/workflows/container-image-release.yml +++ b/.github/workflows/container-image-release.yml @@ -107,7 +107,7 @@ jobs: - name: Download digests uses: actions/download-artifact@v4 with: - name: digests-* + pattern: digests-* merge-multiple: true path: /tmp/digests From 4a122b9a2f6424c5f26612db55c397169cd58ee7 Mon Sep 17 00:00:00 2001 From: pushrbx Date: Tue, 9 Apr 2024 20:31:37 +0100 Subject: [PATCH 18/30] fixed a bug around season endpoints - added a new parameter: "continuing" - continuing items from previous seasons are now excluded by default - should fix #521 --- app/Contracts/AnimeRepository.php | 5 ++- app/Dto/Concerns/HasContinuingParameter.php | 26 +++++++++++ app/Dto/Concerns/PreparesData.php | 3 +- app/Dto/QueryAnimeSeasonCommand.php | 9 +++- app/Features/QueryAnimeSeasonHandlerBase.php | 2 - .../QueryCurrentAnimeSeasonHandler.php | 3 +- .../QuerySpecificAnimeSeasonHandler.php | 4 +- .../Controllers/V4DB/SeasonController.php | 14 ++---- app/Repositories/DefaultAnimeRepository.php | 18 +++++--- storage/api-docs/api-docs.json | 20 ++++++++- tests/Integration/SeasonControllerTest.php | 44 ++++++++++++++++++- 11 files changed, 119 insertions(+), 29 deletions(-) create mode 100644 app/Dto/Concerns/HasContinuingParameter.php diff --git a/app/Contracts/AnimeRepository.php b/app/Contracts/AnimeRepository.php index c0d734a..ee5b484 100644 --- a/app/Contracts/AnimeRepository.php +++ b/app/Contracts/AnimeRepository.php @@ -39,11 +39,12 @@ interface AnimeRepository extends Repository ?AnimeScheduleFilterEnum $filter = null ): EloquentBuilder; - public function getAiredBetween( + public function getItemsBySeason( Carbon $from, Carbon $to, ?AnimeTypeEnum $type = null, - ?string $premiered = null + ?string $premiered = null, + bool $includeContinuingItems = false ): EloquentBuilder; public function getUpcomingSeasonItems(?AnimeTypeEnum $type = null): EloquentBuilder; diff --git a/app/Dto/Concerns/HasContinuingParameter.php b/app/Dto/Concerns/HasContinuingParameter.php new file mode 100644 index 0000000..f6244ad --- /dev/null +++ b/app/Dto/Concerns/HasContinuingParameter.php @@ -0,0 +1,26 @@ +Example usage: `?continuing`", + * @OA\Schema(type="boolean") + * ), + */ +trait HasContinuingParameter +{ + use PreparesData; + + #[BooleanType, WithCast(ContextualBooleanCast::class)] + public bool|Optional $continuing = false; +} diff --git a/app/Dto/Concerns/PreparesData.php b/app/Dto/Concerns/PreparesData.php index 9adc76b..d8c5cb0 100644 --- a/app/Dto/Concerns/PreparesData.php +++ b/app/Dto/Concerns/PreparesData.php @@ -17,7 +17,6 @@ trait PreparesData { // let's always set the limit parameter to the globally configured default value if (property_exists(static::class, "limit") && !$properties->has("limit")) { - /** @noinspection PhpUndefinedFieldInspection */ $properties->put("limit", max_results_per_page( property_exists(static::class, "defaultLimit") ? static::$defaultLimit : null)); } @@ -53,7 +52,7 @@ trait PreparesData } else { $properties->forget($propertyRawName); } - } + } } return $properties; diff --git a/app/Dto/QueryAnimeSeasonCommand.php b/app/Dto/QueryAnimeSeasonCommand.php index 3b7c875..f53c136 100644 --- a/app/Dto/QueryAnimeSeasonCommand.php +++ b/app/Dto/QueryAnimeSeasonCommand.php @@ -11,6 +11,7 @@ use App\Dto\Concerns\HasLimitParameter; use App\Dto\Concerns\HasPageParameter; use App\Dto\Concerns\HasSfwParameter; use App\Dto\Concerns\HasUnapprovedParameter; +use App\Dto\Concerns\HasContinuingParameter; use App\Enums\AnimeTypeEnum; use App\Rules\Attributes\EnumValidation; use Spatie\LaravelData\Attributes\WithCast; @@ -20,7 +21,13 @@ use Spatie\LaravelData\Optional; abstract class QueryAnimeSeasonCommand extends Data implements DataRequest { - use HasSfwParameter, HasKidsParameter, HasUnapprovedParameter, HasLimitParameter, HasRequestFingerprint, HasPageParameter; + use HasSfwParameter, + HasKidsParameter, + HasUnapprovedParameter, + HasLimitParameter, + HasRequestFingerprint, + HasPageParameter, + HasContinuingParameter; #[WithCast(EnumCast::class, AnimeTypeEnum::class), EnumValidation(AnimeTypeEnum::class)] public AnimeTypeEnum|Optional $filter; diff --git a/app/Features/QueryAnimeSeasonHandlerBase.php b/app/Features/QueryAnimeSeasonHandlerBase.php index 778cd07..67a8ced 100644 --- a/app/Features/QueryAnimeSeasonHandlerBase.php +++ b/app/Features/QueryAnimeSeasonHandlerBase.php @@ -32,8 +32,6 @@ abstract class QueryAnimeSeasonHandlerBase implements RequestHandler { $requestParams = collect($request->all()); $type = $requestParams->has("filter") ? $request->filter : null; - $season = $requestParams->has("season") ? $request->season : null; - $year = $requestParams->has("year") ? $request->year : null; $results = $this->getSeasonItems($request, $type); // apply sfw, kids and unapproved filters /** @noinspection PhpUndefinedMethodInspection */ diff --git a/app/Features/QueryCurrentAnimeSeasonHandler.php b/app/Features/QueryCurrentAnimeSeasonHandler.php index da7d427..972d36b 100644 --- a/app/Features/QueryCurrentAnimeSeasonHandler.php +++ b/app/Features/QueryCurrentAnimeSeasonHandler.php @@ -53,7 +53,8 @@ final class QueryCurrentAnimeSeasonHandler extends QueryAnimeSeasonHandlerBase */ [$from, $to] = $this->getSeasonRange($year, $season); $premiered = ucfirst($season)." {$year}"; + $includeContinuingItems = $request->continuing; - return $this->repository->getAiredBetween($from, $to, $type, $premiered); + return $this->repository->getItemsBySeason($from, $to, $type, $premiered, $includeContinuingItems); } } diff --git a/app/Features/QuerySpecificAnimeSeasonHandler.php b/app/Features/QuerySpecificAnimeSeasonHandler.php index f133c30..1ec6821 100644 --- a/app/Features/QuerySpecificAnimeSeasonHandler.php +++ b/app/Features/QuerySpecificAnimeSeasonHandler.php @@ -28,8 +28,8 @@ final class QuerySpecificAnimeSeasonHandler extends QueryAnimeSeasonHandlerBase [$from, $to] = $this->getSeasonRange($request->year, $request->season); $premiered = ucfirst($request->season)." {$request->year}"; + $includeContinuingItems = $request->continuing; - return $this->repository->getAiredBetween($from, $to, $type, $premiered); -// ->where("status", "!=", AnimeStatusEnum::upcoming()->label); + return $this->repository->getItemsBySeason($from, $to, $type, $premiered, $includeContinuingItems); } } diff --git a/app/Http/Controllers/V4DB/SeasonController.php b/app/Http/Controllers/V4DB/SeasonController.php index a70a0cd..aa2c091 100644 --- a/app/Http/Controllers/V4DB/SeasonController.php +++ b/app/Http/Controllers/V4DB/SeasonController.php @@ -2,21 +2,12 @@ namespace App\Http\Controllers\V4DB; -use App\Anime; use App\Dto\QueryAnimeSeasonListCommand; use App\Dto\QueryCurrentAnimeSeasonCommand; use App\Dto\QuerySpecificAnimeSeasonCommand; use App\Dto\QueryUpcomingAnimeSeasonCommand; -use App\Http\HttpResponse; -use App\Http\QueryBuilder\AnimeSearchQueryBuilder; -use App\Http\Resources\V4\AnimeCollection; -use App\Http\Resources\V4\ResultsResource; use Exception; -use Illuminate\Http\Request; -use Illuminate\Support\Carbon; -use Illuminate\Support\Facades\DB; -use Jikan\Request\SeasonList\SeasonListRequest; -use Symfony\Component\HttpFoundation\Exception\BadRequestException; +use OpenApi\Annotations as OA; /** * @@ -38,6 +29,7 @@ class SeasonController extends Controller * * @OA\Parameter(ref="#/components/parameters/sfw"), * @OA\Parameter(ref="#/components/parameters/unapproved"), + * @OA\Parameter(ref="#/components/parameters/continuing"), * @OA\Parameter(ref="#/components/parameters/page"), * @OA\Parameter(ref="#/components/parameters/limit"), * @@ -89,6 +81,7 @@ class SeasonController extends Controller * * @OA\Parameter(ref="#/components/parameters/sfw"), * @OA\Parameter(ref="#/components/parameters/unapproved"), + * @OA\Parameter(ref="#/components/parameters/continuing"), * @OA\Parameter(ref="#/components/parameters/page"), * @OA\Parameter(ref="#/components/parameters/limit"), * @@ -177,6 +170,7 @@ class SeasonController extends Controller * * @OA\Parameter(ref="#/components/parameters/sfw"), * @OA\Parameter(ref="#/components/parameters/unapproved"), + * @OA\Parameter(ref="#/components/parameters/continuing"), * @OA\Parameter(ref="#/components/parameters/page"), * @OA\Parameter(ref="#/components/parameters/limit"), * diff --git a/app/Repositories/DefaultAnimeRepository.php b/app/Repositories/DefaultAnimeRepository.php index 4a29a48..76d9a34 100644 --- a/app/Repositories/DefaultAnimeRepository.php +++ b/app/Repositories/DefaultAnimeRepository.php @@ -110,11 +110,12 @@ final class DefaultAnimeRepository extends DatabaseRepository implements AnimeRe return $queryable; } - public function getAiredBetween( + public function getItemsBySeason( Carbon $from, Carbon $to, ?AnimeTypeEnum $type = null, - ?string $premiered = null + ?string $premiered = null, + bool $includeContinuingItems = false ): EloquentBuilder { $queryable = $this->queryable(true); @@ -127,9 +128,10 @@ final class DefaultAnimeRepository extends DatabaseRepository implements AnimeRe $finalFilter = []; // if the premiered parameter for the filter is not null, look for those items which have a premiered attribute set, - // and equals to the parameter value, OR look for those items which doesn't have premired attribute set, + // and equals to the parameter value, OR look for those items which doesn't have premiered attribute set, // they don't have a garbled aired string and their aired.from date is within the from-to parameters range. - // Additionally, we want to include all those items which are carry overs from previous seasons. + // Additionally, we want to include all those items which are carry overs from previous seasons, + // if the includeContinuingItems argument is set to true. if ($premiered !== null) { $finalFilter['$or'] = [ ['premiered' => $premiered], @@ -140,12 +142,14 @@ final class DefaultAnimeRepository extends DatabaseRepository implements AnimeRe ], ...$airedFilter ], + ]; + if ($includeContinuingItems) { // this condition will include "continuing" items from previous seasons - [ + $finalFilter['$or'][] = [ 'aired.from' => ['$lte' => $from->toAtomString()], 'airing' => true - ] - ]; + ]; + } } else { $finalFilter = array_merge($finalFilter, $airedFilter); $finalFilter['aired.string'] = [ diff --git a/storage/api-docs/api-docs.json b/storage/api-docs/api-docs.json index c9108d3..8ab520a 100644 --- a/storage/api-docs/api-docs.json +++ b/storage/api-docs/api-docs.json @@ -3046,6 +3046,9 @@ { "$ref": "#/components/parameters/unapproved" }, + { + "$ref": "#/components/parameters/continuing" + }, { "$ref": "#/components/parameters/page" }, @@ -3115,6 +3118,9 @@ { "$ref": "#/components/parameters/unapproved" }, + { + "$ref": "#/components/parameters/continuing" + }, { "$ref": "#/components/parameters/page" }, @@ -3191,6 +3197,9 @@ { "$ref": "#/components/parameters/unapproved" }, + { + "$ref": "#/components/parameters/continuing" + }, { "$ref": "#/components/parameters/page" }, @@ -9027,6 +9036,15 @@ } }, "parameters": { + "continuing": { + "name": "continuing", + "in": "query", + "description": "This is a flag. When supplied it will include entries which are continuing from previous seasons. MAL includes these items on the seasons view in the ″TV (continuing)″ section. (Example: https://myanimelist.net/anime/season/2024/winter)
Example usage: `?continuing`", + "required": false, + "schema": { + "type": "boolean" + } + }, "kids": { "name": "kids", "in": "query", @@ -9092,4 +9110,4 @@ "description": "About", "url": "https://jikan.moe" } -} +} \ No newline at end of file diff --git a/tests/Integration/SeasonControllerTest.php b/tests/Integration/SeasonControllerTest.php index 44a71db..e85f77e 100644 --- a/tests/Integration/SeasonControllerTest.php +++ b/tests/Integration/SeasonControllerTest.php @@ -131,9 +131,51 @@ class SeasonControllerTest extends TestCase $state["airing"] = true; $f->create($state); - $content = $this->getJsonResponse([], "/v4/seasons/2024/winter"); + $content = $this->getJsonResponse([], "/v4/seasons/2024/winter?continuing=true"); $this->seeStatusCode(200); $this->assertIsArray($content["data"]); $this->assertCount(3, $content["data"]); } + + public function testShouldNotIncludeContinuingItemsByDefault() + { + Carbon::setTestNow(Carbon::parse("2024-01-11")); + // an item in the future airing + $f = Anime::factory(1); + $startDate = "2024-02-24"; + $carbonStartDate = Carbon::parse($startDate); + $state = $f->serializeStateDefinition([ + "aired" => new CarbonDateRange($carbonStartDate, null) + ]); + $state["aired"]["string"] = "Feb 24, 2024 to ?"; + $state["premiered"] = null; + $state["status"] = "Not yet aired"; + $state["airing"] = false; + $f->create($state); + + // the absolutely correct item + $f = Anime::factory(1); + $state = $f->serializeStateDefinition([ + "aired" => new CarbonDateRange(Carbon::parse("2024-01-10"), Carbon::parse("2024-02-15")) + ]); + $state["premiered"] = "Winter 2024"; + $state["status"] = "Currently Airing"; + $state["airing"] = true; + $f->create($state); + + // the continuing item + $f = Anime::factory(1); + $state = $f->serializeStateDefinition([ + "aired" => new CarbonDateRange(Carbon::parse("2023-10-10"), null) + ]); + $state["premiered"] = "Fall 2023"; + $state["status"] = "Currently Airing"; + $state["airing"] = true; + $f->create($state); + + $content = $this->getJsonResponse([], "/v4/seasons/2024/winter"); + $this->seeStatusCode(200); + $this->assertIsArray($content["data"]); + $this->assertCount(2, $content["data"]); + } } From e042d585b5058194d5b3b34462d7dd86e175d327 Mon Sep 17 00:00:00 2001 From: pushrbx Date: Fri, 31 May 2024 16:52:15 +0100 Subject: [PATCH 19/30] fixed flags in the URL --- app/Dto/Concerns/PreparesData.php | 2 +- tests/Integration/SeasonControllerTest.php | 16 ++++++++++++++-- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/app/Dto/Concerns/PreparesData.php b/app/Dto/Concerns/PreparesData.php index d8c5cb0..10ef1d1 100644 --- a/app/Dto/Concerns/PreparesData.php +++ b/app/Dto/Concerns/PreparesData.php @@ -43,7 +43,7 @@ trait PreparesData } } // if the property is optional and the value is an empty string, we want to ignore it. - if ($property->type->isOptional && $propertyVal === "") { + if ($property->type->isOptional && $propertyVal === "" && !$property->type->acceptsType("bool")) { $propertyVal = null; } diff --git a/tests/Integration/SeasonControllerTest.php b/tests/Integration/SeasonControllerTest.php index e85f77e..6d6a752 100644 --- a/tests/Integration/SeasonControllerTest.php +++ b/tests/Integration/SeasonControllerTest.php @@ -15,6 +15,14 @@ class SeasonControllerTest extends TestCase use SyntheticMongoDbTransaction; use ScoutFlush; + private function continuingUrlProvider(): array + { + return [ + "?continuing=true" => ["/v4/seasons/2024/winter?continuing=true"], + "?continuing" => ["/v4/seasons/2024/winter?continuing"], + ]; + } + public function testShouldFilterOutAnimeWithGarbledAiredString() { Carbon::setTestNow(Carbon::parse("2024-01-11")); @@ -95,7 +103,11 @@ class SeasonControllerTest extends TestCase $this->assertCount(2, $content["data"]); } - public function testShouldNotFilterOutContinuingItemsFromPreviousSeasons() + /** + * @return void + * @dataProvider continuingUrlProvider + */ + public function testShouldNotFilterOutContinuingItemsFromPreviousSeasons($requestUrl) { Carbon::setTestNow(Carbon::parse("2024-01-11")); // an item in the future airing @@ -131,7 +143,7 @@ class SeasonControllerTest extends TestCase $state["airing"] = true; $f->create($state); - $content = $this->getJsonResponse([], "/v4/seasons/2024/winter?continuing=true"); + $content = $this->getJsonResponse([], $requestUrl); $this->seeStatusCode(200); $this->assertIsArray($content["data"]); $this->assertCount(3, $content["data"]); From 63e7996c879f67bbdae37cd139597c38956363e9 Mon Sep 17 00:00:00 2001 From: pushrbx Date: Fri, 31 May 2024 17:51:39 +0100 Subject: [PATCH 20/30] maybe fixed tests --- app/Testing/SyntheticMongoDbTransaction.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/Testing/SyntheticMongoDbTransaction.php b/app/Testing/SyntheticMongoDbTransaction.php index acb357e..224369e 100644 --- a/app/Testing/SyntheticMongoDbTransaction.php +++ b/app/Testing/SyntheticMongoDbTransaction.php @@ -32,6 +32,7 @@ trait SyntheticMongoDbTransaction $tablesWithoutModels = [ "anime_characters_staff", "anime_episodes", + "anime_episode", "anime_forum", "anime_moreinfo", "anime_news", @@ -42,6 +43,7 @@ trait SyntheticMongoDbTransaction "anime_userupdates", "anime_videos", "character_pictures", + "characters_pictures", "clubs_members", "demographics_manga", "demographics_anime", From d7c9d914beeaa9e0346e18280daf22140e0fa80d Mon Sep 17 00:00:00 2001 From: pushrbx Date: Fri, 31 May 2024 17:58:10 +0100 Subject: [PATCH 21/30] maybe fixed tests2 --- app/Testing/SyntheticMongoDbTransaction.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/Testing/SyntheticMongoDbTransaction.php b/app/Testing/SyntheticMongoDbTransaction.php index 224369e..f2c75ac 100644 --- a/app/Testing/SyntheticMongoDbTransaction.php +++ b/app/Testing/SyntheticMongoDbTransaction.php @@ -82,5 +82,6 @@ trait SyntheticMongoDbTransaction { DB::table($tableName)->truncate(); } + usleep(35 * 1000); } } From 719097998008930651aaff7dcffb502e94df93aa Mon Sep 17 00:00:00 2001 From: pushrbx Date: Fri, 31 May 2024 18:10:58 +0100 Subject: [PATCH 22/30] maybe fixed tests3 --- app/Testing/SyntheticMongoDbTransaction.php | 1 - database/factories/JikanMediaModelFactory.php | 8 ++++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/app/Testing/SyntheticMongoDbTransaction.php b/app/Testing/SyntheticMongoDbTransaction.php index f2c75ac..224369e 100644 --- a/app/Testing/SyntheticMongoDbTransaction.php +++ b/app/Testing/SyntheticMongoDbTransaction.php @@ -82,6 +82,5 @@ trait SyntheticMongoDbTransaction { DB::table($tableName)->truncate(); } - usleep(35 * 1000); } } diff --git a/database/factories/JikanMediaModelFactory.php b/database/factories/JikanMediaModelFactory.php index 78aa748..be2e2e1 100644 --- a/database/factories/JikanMediaModelFactory.php +++ b/database/factories/JikanMediaModelFactory.php @@ -312,14 +312,14 @@ abstract class JikanMediaModelFactory extends JikanModelFactory implements Media if ($additionalParams->has("min_score") && !$additionalParams->has("max_score")) { $min_score = floatval($additionalParams["min_score"]); if ($this->isScoreValueValid($min_score)) { - $overrides["score"] = $this->faker->randomFloat(2, 1.00, floatval($additionalParams["min_score"])); + $overrides["score"] = $this->faker->randomFloat(2, 1.00, floatval($additionalParams["min_score"]) - 0.01); } } if (!$additionalParams->has("min_score") && $additionalParams->has("max_score")) { $max_score = $additionalParams["max_score"]; if ($this->isScoreValueValid($max_score)) { - $overrides["score"] = $this->faker->randomFloat(2, floatval($additionalParams["max_score"]), 9.99); + $overrides["score"] = $this->faker->randomFloat(2, floatval($additionalParams["max_score"]) + 0.01, 9.99); } } @@ -330,8 +330,8 @@ abstract class JikanMediaModelFactory extends JikanModelFactory implements Media if ($this->isScoreValueValid($min_score) && $this->isScoreValueValid($max_score)) { $overrides["score"] = $this->faker->randomElement([ - $this->faker->randomFloat(2, 1.00, floatval($additionalParams["min_score"])), - $this->faker->randomFloat(2, floatval($additionalParams["max_score"]), 9.99) + $this->faker->randomFloat(2, 1.00, floatval($additionalParams["min_score"]) - 0.01), + $this->faker->randomFloat(2, floatval($additionalParams["max_score"]) + 0.01, 9.99) ]); } } From aa8d8a6def219e71d7b1e13ad6b50d0246c7baae Mon Sep 17 00:00:00 2001 From: pushrbx Date: Fri, 31 May 2024 18:28:47 +0100 Subject: [PATCH 23/30] maybe fixed tests4 --- database/factories/JikanMediaModelFactory.php | 2 +- database/factories/JikanModelFactory.php | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/database/factories/JikanMediaModelFactory.php b/database/factories/JikanMediaModelFactory.php index be2e2e1..53acb1f 100644 --- a/database/factories/JikanMediaModelFactory.php +++ b/database/factories/JikanMediaModelFactory.php @@ -253,7 +253,7 @@ abstract class JikanMediaModelFactory extends JikanModelFactory implements Media $endDate = $this->adaptDateString($additionalParams["end_date"]); $to = Carbon::parse($endDate); $from = $to->copy()->subDays($this->faker->randomElement([30, 60, 90, 120, 180])); - $overrides[$activityMarkerKeyName] = new CarbonDateRange($from, $to->subDays($this->faker->numberBetween(0, 25))); + $overrides[$activityMarkerKeyName] = new CarbonDateRange($from, $to->subDays($this->faker->numberBetween(1, 25))); } if ($additionalParams->has(["start_date", "end_date"]) diff --git a/database/factories/JikanModelFactory.php b/database/factories/JikanModelFactory.php index 2abd261..b599003 100644 --- a/database/factories/JikanModelFactory.php +++ b/database/factories/JikanModelFactory.php @@ -7,12 +7,18 @@ use Jikan\Model\Common\DateRange; use JMS\Serializer\Serializer; use \Illuminate\Database\Eloquent\Factories\Factory; use Spatie\Enum\Laravel\Faker\FakerEnumProvider; +use Illuminate\Support\Str; abstract class JikanModelFactory extends Factory { public function configure(): JikanModelFactory|static { $this->faker->addProvider(new FakerEnumProvider($this->faker)); + if (array_key_exists("GITHUB_JOB", $_ENV) && $_ENV["GITHUB_JOB"] !== "") { + $this->faker->seed($_ENV["GITHUB_JOB"]); + } else { + $this->faker->seed(Str::random()); + } return $this; } From cb043f49e8280ec0cfc7e701410cf0fd9fcf7b71 Mon Sep 17 00:00:00 2001 From: pushrbx Date: Fri, 31 May 2024 18:36:11 +0100 Subject: [PATCH 24/30] one more tweak to the model factory --- database/factories/JikanMediaModelFactory.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/database/factories/JikanMediaModelFactory.php b/database/factories/JikanMediaModelFactory.php index 53acb1f..289eabd 100644 --- a/database/factories/JikanMediaModelFactory.php +++ b/database/factories/JikanMediaModelFactory.php @@ -244,7 +244,7 @@ abstract class JikanMediaModelFactory extends JikanModelFactory implements Media if ($additionalParams->has("start_date") && !empty($additionalParams["start_date"]) && !$additionalParams->has("end_date")) { $startDate = $this->adaptDateString($additionalParams["start_date"]); - $dt = Carbon::parse($startDate)->addDays($this->faker->numberBetween(0, 25)); + $dt = Carbon::parse($startDate)->addDays($this->faker->numberBetween(1, 25)); $overrides[$activityMarkerKeyName] = new CarbonDateRange($dt, null); } From ec0af72a197cabb4816d8b7309b9e3fc6724093d Mon Sep 17 00:00:00 2001 From: pushrbx Date: Thu, 20 Jun 2024 18:04:38 +0100 Subject: [PATCH 25/30] adjusted the continuing anime filter --- app/Repositories/DefaultAnimeRepository.php | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/app/Repositories/DefaultAnimeRepository.php b/app/Repositories/DefaultAnimeRepository.php index 76d9a34..cf5286f 100644 --- a/app/Repositories/DefaultAnimeRepository.php +++ b/app/Repositories/DefaultAnimeRepository.php @@ -144,9 +144,19 @@ final class DefaultAnimeRepository extends DatabaseRepository implements AnimeRe ], ]; if ($includeContinuingItems) { - // this condition will include "continuing" items from previous seasons + // these conditions will include "continuing" items from previous seasons + // We want to include those which are currently airing, and their aired.to is unknown, and their start + // date is before when the current season began. $finalFilter['$or'][] = [ 'aired.from' => ['$lte' => $from->toAtomString()], + 'aired.to' => null, + 'airing' => true + ]; + // We want to include those which are currently airing, and their aired.to is past the date of the + // current season start. + $finalFilter['$or'][] = [ + 'aired.from' => ['$lte' => $from->toAtomString()], + 'aired.to' => ['$gte' => $from->toAtomString()], 'airing' => true ]; } From 31c7790bef0d66ac9bdca46519c5ed83b5eb0c2b Mon Sep 17 00:00:00 2001 From: pushrbx Date: Thu, 20 Jun 2024 21:56:25 +0100 Subject: [PATCH 26/30] adjusted the continuing anime filter 2 --- app/Repositories/DefaultAnimeRepository.php | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/app/Repositories/DefaultAnimeRepository.php b/app/Repositories/DefaultAnimeRepository.php index cf5286f..786d75b 100644 --- a/app/Repositories/DefaultAnimeRepository.php +++ b/app/Repositories/DefaultAnimeRepository.php @@ -145,11 +145,11 @@ final class DefaultAnimeRepository extends DatabaseRepository implements AnimeRe ]; if ($includeContinuingItems) { // these conditions will include "continuing" items from previous seasons - // We want to include those which are currently airing, and their aired.to is unknown, and their start - // date is before when the current season began. + // long running shows $finalFilter['$or'][] = [ 'aired.from' => ['$lte' => $from->toAtomString()], 'aired.to' => null, + 'episodes' => null, 'airing' => true ]; // We want to include those which are currently airing, and their aired.to is past the date of the @@ -159,6 +159,16 @@ final class DefaultAnimeRepository extends DatabaseRepository implements AnimeRe 'aired.to' => ['$gte' => $from->toAtomString()], 'airing' => true ]; + // In many cases MAL doesn't show the date until an airing show is going to be aired. So we need to get + // clever here. + // We want to include those shows which have started in previous season only (not before) and it's going + // to continue in the current season. + $finalFilter['$or'][] = [ + 'aired.from' => ['$lte' => $from->toAtomString()], + 'aired.to' => null, + 'episodes' => ['$gte' => 14], + 'airing' => true + ]; } } else { $finalFilter = array_merge($finalFilter, $airedFilter); From f775fbce416cc0ff2d085356fbb3d53a01385fb5 Mon Sep 17 00:00:00 2001 From: pushrbx Date: Thu, 20 Jun 2024 23:42:50 +0100 Subject: [PATCH 27/30] adjusted the continuing anime filter 3 --- app/Repositories/DefaultAnimeRepository.php | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/app/Repositories/DefaultAnimeRepository.php b/app/Repositories/DefaultAnimeRepository.php index 786d75b..f2c64eb 100644 --- a/app/Repositories/DefaultAnimeRepository.php +++ b/app/Repositories/DefaultAnimeRepository.php @@ -12,6 +12,7 @@ use Illuminate\Contracts\Database\Query\Builder as EloquentBuilder; use Illuminate\Database\Eloquent\Collection; use Illuminate\Support\Carbon; use Laravel\Scout\Builder as ScoutBuilder; +use MongoDB\BSON\Javascript; /** * @implements Repository @@ -164,7 +165,23 @@ final class DefaultAnimeRepository extends DatabaseRepository implements AnimeRe // We want to include those shows which have started in previous season only (not before) and it's going // to continue in the current season. $finalFilter['$or'][] = [ - 'aired.from' => ['$lte' => $from->toAtomString()], + // note: this expression only works with mongodb version 5.0.0 or higher + '$expr' => [ + '$lte' => [ + [ + '$dateDiff' => [ + 'startDate' => [ + '$dateFromString' => [ + 'dateString' => '$aired.from' + ] + ], + 'endDate' => new Javascript('new Date("' . $from->toAtomString() . '")'), + 'unit' => 'month' + ] + ], + 3 // there are 3 months in a season, so anything that started in 3 months or less will be included + ] + ], 'aired.to' => null, 'episodes' => ['$gte' => 14], 'airing' => true From cc381969a7792c154156ba026e23ba7dddff79a5 Mon Sep 17 00:00:00 2001 From: pushrbx Date: Fri, 21 Jun 2024 00:12:40 +0100 Subject: [PATCH 28/30] adjusted the continuing anime filter 4 --- app/Repositories/DefaultAnimeRepository.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/Repositories/DefaultAnimeRepository.php b/app/Repositories/DefaultAnimeRepository.php index f2c64eb..ffbf103 100644 --- a/app/Repositories/DefaultAnimeRepository.php +++ b/app/Repositories/DefaultAnimeRepository.php @@ -12,7 +12,7 @@ use Illuminate\Contracts\Database\Query\Builder as EloquentBuilder; use Illuminate\Database\Eloquent\Collection; use Illuminate\Support\Carbon; use Laravel\Scout\Builder as ScoutBuilder; -use MongoDB\BSON\Javascript; +use MongoDB\BSON\UTCDateTime; /** * @implements Repository @@ -175,7 +175,7 @@ final class DefaultAnimeRepository extends DatabaseRepository implements AnimeRe 'dateString' => '$aired.from' ] ], - 'endDate' => new Javascript('new Date("' . $from->toAtomString() . '")'), + 'endDate' => new UTCDateTime($from), 'unit' => 'month' ] ], From c62800772956fef6b52dd0bcc8b4420a1ae33add Mon Sep 17 00:00:00 2001 From: pushrbx Date: Sun, 23 Jun 2024 21:29:05 +0100 Subject: [PATCH 29/30] fixed sfw and unapproved filters for random anime and manga endpoint --- app/Features/QueryRandomAnimeHandler.php | 10 +++--- app/Features/QueryRandomMangaHandler.php | 10 +++--- app/JikanApiModel.php | 45 +++++++++++++++++++++--- 3 files changed, 53 insertions(+), 12 deletions(-) diff --git a/app/Features/QueryRandomAnimeHandler.php b/app/Features/QueryRandomAnimeHandler.php index e635ed6..1ad4abb 100644 --- a/app/Features/QueryRandomAnimeHandler.php +++ b/app/Features/QueryRandomAnimeHandler.php @@ -6,6 +6,7 @@ use App\Anime; use App\Contracts\RequestHandler; use App\Dto\QueryRandomAnimeCommand; use App\Http\Resources\V4\AnimeResource; +use Spatie\LaravelData\Optional; /** * @implements RequestHandler @@ -18,12 +19,13 @@ final class QueryRandomAnimeHandler implements RequestHandler public function handle($request): AnimeResource { $queryable = Anime::query(); - // apply sfw, kids and unapproved filters - /** @noinspection PhpUndefinedMethodInspection */ - $queryable = $queryable->filter(collect($request->all())); + + $o = Optional::create(); + $sfwParam = $request->sfw === $o ? false : $request->sfw; + $unapprovedParam = $request->unapproved === $o ? false : $request->unapproved; return new AnimeResource( - $queryable->random()->first() + $queryable->random(1, $sfwParam, $unapprovedParam)->first() ); } diff --git a/app/Features/QueryRandomMangaHandler.php b/app/Features/QueryRandomMangaHandler.php index 56f5832..f486457 100644 --- a/app/Features/QueryRandomMangaHandler.php +++ b/app/Features/QueryRandomMangaHandler.php @@ -6,6 +6,7 @@ use App\Contracts\RequestHandler; use App\Dto\QueryRandomMangaCommand; use App\Http\Resources\V4\MangaResource; use App\Manga; +use Spatie\LaravelData\Optional; /** * @implements RequestHandler @@ -18,12 +19,13 @@ final class QueryRandomMangaHandler implements RequestHandler public function handle($request) { $queryable = Manga::query(); - // apply sfw, kids and unapproved filters - /** @noinspection PhpUndefinedMethodInspection */ - $queryable = $queryable->filter(collect($request->all())); + + $o = Optional::create(); + $sfwParam = $request->sfw === $o ? false : $request->sfw; + $unapprovedParam = $request->unapproved === $o ? false : $request->unapproved; return new MangaResource( - $queryable->random()->first() + $queryable->random(1, $sfwParam, $unapprovedParam)->first() ); } diff --git a/app/JikanApiModel.php b/app/JikanApiModel.php index 9ae0f56..afaf5e1 100644 --- a/app/JikanApiModel.php +++ b/app/JikanApiModel.php @@ -2,9 +2,12 @@ namespace App; +use App\Enums\AnimeRatingEnum; +use App\Enums\MangaTypeEnum; use App\Filters\FilterQueryString; use Illuminate\Support\Collection; use Jenssegers\Mongodb\Eloquent\Builder; +use Jikan\Helper\Constants; class JikanApiModel extends \Jenssegers\Mongodb\Eloquent\Model { @@ -19,10 +22,44 @@ class JikanApiModel extends \Jenssegers\Mongodb\Eloquent\Model protected array $filters = []; /** @noinspection PhpUnused */ - public function scopeRandom(Builder $query, int $numberOfRandomItems = 1): Collection + public function scopeRandom(Builder $query, int $numberOfRandomItems = 1, bool $sfw = false, bool $unapproved = false): Collection { - return $query->raw(fn(\Jenssegers\Mongodb\Collection $collection) => $collection->aggregate([ - ['$sample' => ['size' => $numberOfRandomItems]] - ])); + return $query->raw(function(\Jenssegers\Mongodb\Collection $collection) use ($numberOfRandomItems, $sfw, $unapproved) { + $sfwFilter = [ + 'demographics.mal_id' => [ + '$nin' => [ + Constants::GENRE_ANIME_HENTAI, + Constants::GENRE_ANIME_EROTICA, + Constants::GENRE_MANGA_HENTAI, + Constants::GENRE_MANGA_EROTICA + ] + ], + 'rating' => ['$ne' => AnimeRatingEnum::rx()->label], + 'type' => ['$ne' => MangaTypeEnum::doujin()->label], + 'genres.mal_id' => ['$nin' => [ + Constants::GENRE_ANIME_HENTAI, + Constants::GENRE_MANGA_HENTAI + ]] + ]; + + $pipelineParams = [ + ['$sample' => ['size' => $numberOfRandomItems]] + ]; + + if ($sfw && $unapproved) { + array_unshift($pipelineParams, [ + '$match' => [ + ...$sfwFilter, + 'approved' => false + ] + ]); + } else if ($sfw) { + array_unshift($pipelineParams, ['$match' => $sfwFilter]); + } else if ($unapproved) { + array_unshift($pipelineParams, ['$match' => ['approved' => false]]); + } + + return $collection->aggregate($pipelineParams); + }); } } From 896c68f9b4bfafed1e46a611f4d7be7d7d4775b6 Mon Sep 17 00:00:00 2001 From: pushrbx Date: Sun, 23 Jun 2024 21:29:48 +0100 Subject: [PATCH 30/30] fixed broadcast adapter function in Anime model --- app/Anime.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/app/Anime.php b/app/Anime.php index 54d53e3..a7c39c6 100644 --- a/app/Anime.php +++ b/app/Anime.php @@ -15,6 +15,7 @@ use Jikan\Helper\Constants; use Jikan\Jikan; use Jikan\Request\Anime\AnimeRequest; use Illuminate\Database\Eloquent\Factories\HasFactory; +use MongoDB\Model\BSONDocument; class Anime extends JikanApiSearchableModel { @@ -407,7 +408,7 @@ class Anime extends JikanApiSearchableModel ]; } - private function adaptBroadcastValue(array|string|null $broadcast): array + private function adaptBroadcastValue(array|string|null|BSONDocument $broadcast): array { $null_value = [ 'day' => null, @@ -423,6 +424,10 @@ class Anime extends JikanApiSearchableModel return $broadcast; } + if ($broadcast instanceof BSONDocument) { + return $broadcast->getArrayCopy(); + } + if (!preg_match('~(.*) at (.*) \(~', $broadcast, $matches)) { return [ 'day' => null,