Merge pull request #549 from jikan-me/bugfix/548

🐛 Fixed an issue with casting query string params on `/top/reviews` endpoint
This commit is contained in:
pushrbx 2024-10-15 19:01:45 +01:00 committed by GitHub
commit 744bd69aea
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 56 additions and 19 deletions

View File

@ -4,7 +4,6 @@ namespace App\Dto;
use App\Concerns\HasRequestFingerprint;
use App\Contracts\DataRequest;
use App\DataPipes\MapRouteParametersDataPipe;
use App\Dto\Concerns\MapsRouteParameters;
use Illuminate\Http\Resources\Json\JsonResource;
use Illuminate\Http\Resources\Json\ResourceCollection;
@ -13,12 +12,6 @@ use Spatie\LaravelData\Attributes\Validation\Min;
use Spatie\LaravelData\Attributes\Validation\Numeric;
use Spatie\LaravelData\Attributes\Validation\Required;
use Spatie\LaravelData\Data;
use Spatie\LaravelData\DataPipeline;
use Spatie\LaravelData\DataPipes\AuthorizedDataPipe;
use Spatie\LaravelData\DataPipes\CastPropertiesDataPipe;
use Spatie\LaravelData\DataPipes\DefaultValuesDataPipe;
use Spatie\LaravelData\DataPipes\MapPropertiesDataPipe;
use Spatie\LaravelData\DataPipes\ValidatePropertiesDataPipe;
/**
* Base class for all requests/commands which are for looking up things by id.

View File

@ -2,14 +2,12 @@
namespace App\Dto;
use App\Casts\ContextualBooleanCast;
use App\Casts\EnumCast;
use App\Concerns\HasRequestFingerprint;
use App\Contracts\DataRequest;
use App\Dto\Concerns\HasPreliminaryParameter;
use App\Dto\Concerns\HasSpoilersParameter;
use App\Dto\Concerns\PreparesData;
use App\Enums\TopAnimeFilterEnum;
use App\Enums\TopReviewsTypeEnum;
use App\Rules\Attributes\EnumValidation;
use Illuminate\Http\JsonResponse;
@ -23,6 +21,6 @@ final class QueryTopReviewsCommand extends QueryTopItemsCommand implements DataR
{
use HasRequestFingerprint, HasPreliminaryParameter, HasSpoilersParameter, PreparesData;
#[WithCast(EnumCast::class, TopAnimeFilterEnum::class), EnumValidation(TopReviewsTypeEnum::class)]
#[WithCast(EnumCast::class, TopReviewsTypeEnum::class), EnumValidation(TopReviewsTypeEnum::class)]
public TopReviewsTypeEnum|Optional $type;
}

View File

@ -7,7 +7,6 @@ use App\Enums\TopReviewsTypeEnum;
use App\Support\CachedData;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Collection;
use Jikan\Helper\Constants;
use Jikan\MyAnimeList\MalClient;
use Jikan\Request\Reviews\ReviewsRequest;
@ -31,7 +30,7 @@ final class QueryTopReviewsHandler extends RequestHandlerWithScraperCache
$preliminary = $requestParams->get("preliminary", true);
return $this->scraperService->findList(
$requestFingerPrint,
fn (MalClient $jikan, ?int $page = null) => $jikan->getReviews(new ReviewsRequest($type, $page, $spoilers, $preliminary)),
fn (MalClient $jikan, ?int $page = null) => $jikan->getReviews(new ReviewsRequest(ensureEnumPrimitiveValue($type), $page, $spoilers, $preliminary)),
$requestParams->get("page"));
}
}

View File

@ -3,6 +3,7 @@
namespace App\Http\Resources\V4;
use Illuminate\Http\Resources\Json\JsonResource;
use OpenApi\Annotations as OA;
class ReviewsResource extends JsonResource
{

View File

@ -114,3 +114,12 @@ if (! function_exists('cache')) {
return app('cache')->put(key($arguments[0]), reset($arguments[0]), $arguments[1] ?? null);
}
}
if (!function_exists("ensureEnumPrimitiveValue")) {
function ensureEnumPrimitiveValue(int|string|bool|float|null|\Spatie\Enum\Laravel\Enum $value): mixed {
if ($value instanceof \Spatie\Enum\Laravel\Enum) {
return $value->value;
}
return $value;
}
}

14
composer.lock generated
View File

@ -4554,16 +4554,16 @@
},
{
"name": "jikan-me/jikan",
"version": "v4.0.11",
"version": "v4.0.12",
"source": {
"type": "git",
"url": "https://github.com/jikan-me/jikan.git",
"reference": "fcc8d20817ce29332b496a21652b9965c6c8196c"
"reference": "dcb47237a9407473f484bd28a5e44479cdd916fc"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/jikan-me/jikan/zipball/fcc8d20817ce29332b496a21652b9965c6c8196c",
"reference": "fcc8d20817ce29332b496a21652b9965c6c8196c",
"url": "https://api.github.com/repos/jikan-me/jikan/zipball/dcb47237a9407473f484bd28a5e44479cdd916fc",
"reference": "dcb47237a9407473f484bd28a5e44479cdd916fc",
"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.11"
"source": "https://github.com/jikan-me/jikan/tree/v4.0.12"
},
"funding": [
{
@ -4610,7 +4610,7 @@
"type": "patreon"
}
],
"time": "2024-05-30T08:15:50+00:00"
"time": "2024-09-20T22:15:42+00:00"
},
{
"name": "jms/metadata",
@ -13591,5 +13591,5 @@
"ext-mongodb": "*"
},
"platform-dev": [],
"plugin-api-version": "2.6.0"
"plugin-api-version": "2.3.0"
}

View File

@ -7,6 +7,11 @@ use App\Person;
use App\Testing\ScoutFlush;
use App\Testing\SyntheticMongoDbTransaction;
use Illuminate\Database\Eloquent\Factories\Sequence;
use Jikan\Exception\BadResponseException;
use Jikan\Exception\ParserException;
use Jikan\Model\Reviews\Reviews;
use Jikan\MyAnimeList\MalClient;
use Jikan\Parser\Reviews\ReviewsParser;
use Tests\TestCase;
class TopControllerTest extends TestCase
@ -14,6 +19,15 @@ class TopControllerTest extends TestCase
use SyntheticMongoDbTransaction;
use ScoutFlush;
public function topReviewTypeParametersProvider(): array
{
return [
"empty query string" => [[]],
"query string = `?type=anime`" => [["type" => "anime"]],
"query string = `?type=manga`" => [["type" => "manga"]],
];
}
public function testTopAnime()
{
Anime::factory(3)->state(new Sequence(
@ -290,4 +304,27 @@ class TopControllerTest extends TestCase
$this->get('/v4/top/anime/999')
->seeStatusCode(404);
}
/**
* @dataProvider topReviewTypeParametersProvider
* @param $params
* @return void
* @throws BadResponseException
* @throws ParserException
*/
public function testTopReviews($params)
{
$jikanParser = \Mockery::mock(MalClient::class)->makePartial();
$reviewsParser = \Mockery::mock(ReviewsParser::class)->makePartial();
$reviewsParser->allows()->getReviews()->andReturn([]);
$reviewsParser->allows()->hasNextPage()->andReturn(false);
$reviewsFacade = Reviews::fromParser($reviewsParser);
/** @noinspection PhpParamsInspection */
$jikanParser->allows()->getReviews(\Mockery::any())->andReturn($reviewsFacade);
$this->app->instance('JikanParser', $jikanParser);
$this->getJsonResponse($params,"/v4/top/reviews");
$this->seeStatusCode(200);
}
}