diff --git a/app/Exceptions/Handler.php b/app/Exceptions/Handler.php index 72dbe24..60f30ef 100755 --- a/app/Exceptions/Handler.php +++ b/app/Exceptions/Handler.php @@ -14,6 +14,7 @@ use Jikan\Exception\ParserException; use Laravel\Lumen\Exceptions\Handler as ExceptionHandler; use Predis\Connection\ConnectionException; use Symfony\Component\HttpClient\Exception\TimeoutException; +use Symfony\Component\HttpFoundation\Exception\BadRequestException; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Exception\HttpException; @@ -95,6 +96,27 @@ class Handler extends ExceptionHandler ], 500); } + // BadRequestException from Controllers + if ($e instanceof BadRequestException) { + return response() + ->json([ + 'status' => 400, + 'type' => 'BadRequestException', + 'message' => $e->getMessage(), + 'error' => null + ], 400); + } + + if ($e instanceof ValidationException) { + return response() + ->json([ + 'status' => 400, + 'type' => 'BadRequestException', + 'message' => $e->getMessage(), + 'error' => null + ], 400); + } + // BadResponseException from Jikan PHP API // This is basically the response MyAnimeList returns to Jikan if ($e instanceof BadResponseException) { diff --git a/app/Helpers/ScraperHelper.php b/app/Helpers/ScraperHelper.php new file mode 100644 index 0000000..2962df3 --- /dev/null +++ b/app/Helpers/ScraperHelper.php @@ -0,0 +1,22 @@ +serialize($response, 'json'), + true + ); + } +} diff --git a/app/Http/Controllers/V4DB/AnimeController.php b/app/Http/Controllers/V4DB/AnimeController.php index fa06323..ac23a32 100644 --- a/app/Http/Controllers/V4DB/AnimeController.php +++ b/app/Http/Controllers/V4DB/AnimeController.php @@ -22,6 +22,7 @@ use App\Http\Resources\V4\AnimeVideosResource; use App\Http\Resources\V4\ForumResource; use Illuminate\Http\Request; use Illuminate\Support\Facades\DB; +use Jikan\Helper\Constants; use Jikan\Request\Anime\AnimeCharactersAndStaffRequest; use Jikan\Request\Anime\AnimeEpisodeRequest; use Jikan\Request\Anime\AnimeEpisodesRequest; @@ -38,6 +39,7 @@ use Jikan\Request\Anime\AnimeVideosEpisodesRequest; use Jikan\Request\Anime\AnimeVideosRequest; use Laravel\Lumen\Http\ResponseFactory; use MongoDB\BSON\UTCDateTime; +use Symfony\Component\HttpFoundation\Exception\BadRequestException; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; class AnimeController extends Controller @@ -1110,9 +1112,27 @@ class AnimeController extends Controller || $this->isExpired($request, $results) ) { $page = $request->get('page') ?? 1; - $anime = $this->jikan->getAnimeReviews(new AnimeReviewsRequest($id, $page)); - $response = \json_decode($this->serializer->serialize($anime, 'json'), true); + $sort = $request->get('sort') ?? Constants::REVIEWS_SORT_MOST_VOTED; + if (!in_array($sort, [Constants::REVIEWS_SORT_MOST_VOTED, Constants::REVIEWS_SORT_NEWEST, Constants::REVIEWS_SORT_OLDEST])) { + throw new BadRequestException('Invalid sort for reviews. Please refer to the documentation: https://docs.api.jikan.moe/'); + } + + $spoilers = $request->get('spoilers') ?? false; + $preliminary = $request->get('preliminary') ?? false; + + $anime = $this->jikan + ->getAnimeReviews( + new AnimeReviewsRequest( + $id, + $page, + $sort, + $spoilers, + $preliminary + ) + ); + + $response = \json_decode($this->serializer->serialize($anime, 'json'), true); $results = $this->updateCache($request, $results, $response); } diff --git a/app/Http/Controllers/V4DB/Controller.php b/app/Http/Controllers/V4DB/Controller.php index cc6f287..07846d9 100644 --- a/app/Http/Controllers/V4DB/Controller.php +++ b/app/Http/Controllers/V4DB/Controller.php @@ -36,7 +36,7 @@ class Controller extends BaseController * ) * ), * @OA\Server( - * description="Jikan REST API Beta", + * description="Jikan REST API", * url="https://api.jikan.moe/v4", * ), * @OA\ExternalDocumentation( @@ -49,12 +49,12 @@ class Controller extends BaseController /** * @var Serializer */ - protected $serializer; + protected Serializer $serializer; /** * @var MalClient */ - protected $jikan; + protected MalClient $jikan; /** * @var Request @@ -64,16 +64,16 @@ class Controller extends BaseController /** * @var array */ - private $response; + private array $response; - protected $expired = false; + protected bool $expired = false; - protected $fingerprint; + protected string $fingerprint; /** * AnimeController constructor. * - * @param Serializer $serializer + * @param Request $request * @param MalClient $jikan */ public function __construct(Request $request, MalClient $jikan) diff --git a/app/Http/Controllers/V4DB/MangaController.php b/app/Http/Controllers/V4DB/MangaController.php index b53b519..ec17a2f 100644 --- a/app/Http/Controllers/V4DB/MangaController.php +++ b/app/Http/Controllers/V4DB/MangaController.php @@ -2,38 +2,28 @@ namespace App\Http\Controllers\V4DB; -use App\Anime; +use App\Helpers\ScraperHelper; use App\Http\HttpHelper; use App\Http\HttpResponse; -use App\Http\Resources\V4\AnimeCharactersResource; -use App\Http\Resources\V4\AnimeForumResource; +use App\Http\QueryBuilder\Scraper\Query; +use App\Http\QueryBuilder\Scraper\QueryResolver; +use App\Http\QueryBuilder\Scraper\ScraperHandler; use App\Http\Resources\V4\ExternalLinksResource; use App\Http\Resources\V4\MangaRelationsResource; use App\Http\Resources\V4\ResultsResource; use App\Http\Resources\V4\ReviewsResource; -use App\Http\Resources\V4\UserUpdatesResource; use App\Http\Resources\V4\RecommendationsResource; use App\Http\Resources\V4\MoreInfoResource; -use App\Http\Resources\V4\AnimeNewsResource; -use App\Http\Resources\V4\AnimeStatisticsResource; use App\Http\Resources\V4\ForumResource; use App\Http\Resources\V4\MangaCharactersResource; use App\Http\Resources\V4\MangaStatisticsResource; -use App\Http\Resources\V4\NewsResource; use App\Http\Resources\V4\PicturesResource; +use App\Http\Validation\ValidationTypeEnum; use App\Manga; use Illuminate\Http\Request; -use Illuminate\Http\Resources\Json\JsonResource; use Illuminate\Support\Facades\DB; -use Jikan\Request\Anime\AnimeCharactersAndStaffRequest; -use Jikan\Request\Anime\AnimeForumRequest; -use Jikan\Request\Anime\AnimeMoreInfoRequest; -use Jikan\Request\Anime\AnimeNewsRequest; -use Jikan\Request\Anime\AnimePicturesRequest; -use Jikan\Request\Anime\AnimeRecentlyUpdatedByUsersRequest; -use Jikan\Request\Anime\AnimeRecommendationsRequest; -use Jikan\Request\Anime\AnimeReviewsRequest; -use Jikan\Request\Anime\AnimeStatsRequest; +use Jikan\Exception\BadResponseException; +use Jikan\Helper\Constants; use Jikan\Request\Manga\MangaCharactersRequest; use Jikan\Request\Manga\MangaForumRequest; use Jikan\Request\Manga\MangaMoreInfoRequest; @@ -41,11 +31,10 @@ use Jikan\Request\Manga\MangaNewsRequest; use Jikan\Request\Manga\MangaPicturesRequest; use Jikan\Request\Manga\MangaRecentlyUpdatedByUsersRequest; use Jikan\Request\Manga\MangaRecommendationsRequest; -use Jikan\Request\Manga\MangaRequest; use Jikan\Request\Manga\MangaReviewsRequest; use Jikan\Request\Manga\MangaStatsRequest; use MongoDB\BSON\UTCDateTime; -use mysql_xdevapi\Result; +use Symfony\Component\HttpFoundation\Exception\BadRequestException; class MangaController extends Controller { @@ -442,7 +431,7 @@ class MangaController extends Controller * @OA\Property( * property="data", * type="array", - * + * * @OA\Items( * type="object", * ref="#/components/schemas/manga_images" @@ -693,7 +682,7 @@ class MangaController extends Controller } /** - * @OA\Get( + * @OA\Get( * path="/manga/{id}/reviews", * operationId="getMangaReviews", * tags={"manga"}, @@ -719,9 +708,20 @@ class MangaController extends Controller * description="Error: Bad request. When required parameters were not supplied.", * ), * ) + * @throws \Exception */ public function reviews(Request $request, int $id) { + $validation = $this->validate($request, [ + 'page' => 'nullable|numeric', + 'sort' => 'nullable|string' + ]); + + $page = $request->get('page') ?? 1; + $spoilers = $request->get('spoilers') ?? false; + $preliminary = $request->get('preliminary') ?? false; + $sort = $request->get('sort'); + $results = DB::table($this->getRouteTable($request)) ->where('request_hash', $this->fingerprint) ->get(); @@ -730,9 +730,19 @@ class MangaController extends Controller $results->isEmpty() || $this->isExpired($request, $results) ) { - $page = $request->get('page') ?? 1; - $manga = $this->jikan->getMangaReviews(new MangaReviewsRequest($id, $page)); - $response = \json_decode($this->serializer->serialize($manga, 'json'), true); + + $response = ScraperHelper::getSerializedJSON( + app('JikanParser') + ->getMangaReviews( + new MangaReviewsRequest( + $id, + $page, + in_array($sort, [Constants::REVIEWS_SORT_MOST_VOTED, Constants::REVIEWS_SORT_NEWEST, Constants::REVIEWS_SORT_OLDEST]) ? $sort : Constants::REVIEWS_SORT_MOST_VOTED, + $spoilers, + $preliminary + ) + ) + ); $results = $this->updateCache($request, $results, $response); } diff --git a/app/Http/Controllers/V4DB/ReviewsController.php b/app/Http/Controllers/V4DB/ReviewsController.php index 5471a6e..34a214f 100644 --- a/app/Http/Controllers/V4DB/ReviewsController.php +++ b/app/Http/Controllers/V4DB/ReviewsController.php @@ -9,7 +9,9 @@ use Illuminate\Http\Request; use Illuminate\Support\Facades\DB; use Jikan\Helper\Constants; use Jikan\Request\Reviews\RecentReviewsRequest; +use Jikan\Request\Reviews\ReviewsRequest; use MongoDB\BSON\UTCDateTime; +use Symfony\Component\HttpFoundation\Exception\BadRequestException; class ReviewsController extends Controller { @@ -73,7 +75,26 @@ class ReviewsController extends Controller || $this->isExpired($request, $results) ) { $page = $request->get('page') ?? 1; - $anime = $this->jikan->getRecentReviews(new RecentReviewsRequest(Constants::RECENT_REVIEW_ANIME, $page)); + $sort = $request->get('sort') ?? Constants::REVIEWS_SORT_MOST_VOTED; + + if (!in_array($sort, [Constants::REVIEWS_SORT_MOST_VOTED, Constants::REVIEWS_SORT_NEWEST, Constants::REVIEWS_SORT_OLDEST])) { + throw new BadRequestException('Invalid sort for reviews. Please refer to the documentation: https://docs.api.jikan.moe/'); + } + + $spoilers = $request->get('spoilers') ?? false; + $preliminary = $request->get('preliminary') ?? false; + + $anime = $this->jikan + ->getReviews( + new ReviewsRequest( + Constants::ANIME, + $page, + $sort, + $spoilers, + $preliminary + ) + ); + $response = \json_decode($this->serializer->serialize($anime, 'json'), true); $results = $this->updateCache($request, $results, $response); @@ -149,9 +170,27 @@ class ReviewsController extends Controller || $this->isExpired($request, $results) ) { $page = $request->get('page') ?? 1; - $anime = $this->jikan->getRecentReviews(new RecentReviewsRequest(Constants::RECENT_REVIEW_MANGA, $page)); - $response = \json_decode($this->serializer->serialize($anime, 'json'), true); + $sort = $request->get('sort') ?? Constants::REVIEWS_SORT_MOST_VOTED; + if (!in_array($sort, [Constants::REVIEWS_SORT_MOST_VOTED, Constants::REVIEWS_SORT_NEWEST, Constants::REVIEWS_SORT_OLDEST])) { + throw new BadRequestException('Invalid sort for reviews. Please refer to the documentation: https://docs.api.jikan.moe/'); + } + + $spoilers = $request->get('spoilers') ?? false; + $preliminary = $request->get('preliminary') ?? false; + + $anime = $this->jikan + ->getReviews( + new ReviewsRequest( + Constants::MANGA, + $page, + $sort, + $spoilers, + $preliminary + ) + ); + + $response = \json_decode($this->serializer->serialize($anime, 'json'), true); $results = $this->updateCache($request, $results, $response); } diff --git a/app/Http/Controllers/V4DB/SearchController.php b/app/Http/Controllers/V4DB/SearchController.php index 62a8eb7..875d445 100644 --- a/app/Http/Controllers/V4DB/SearchController.php +++ b/app/Http/Controllers/V4DB/SearchController.php @@ -641,6 +641,14 @@ class SearchController extends ControllerWithQueryBuilderProvider } /** + * + * @OA\Schema( + * schema="producers_query_orderby", + * description="Producers Search Query Order By", + * type="string", + * enum={"mal_id", "count", "favorites", "established"} + * ) + * * @OA\Get( * path="/producers", * operationId="getProducers", diff --git a/app/Http/Controllers/V4DB/UserController.php b/app/Http/Controllers/V4DB/UserController.php index 5cf3b3e..5a90f75 100644 --- a/app/Http/Controllers/V4DB/UserController.php +++ b/app/Http/Controllers/V4DB/UserController.php @@ -14,6 +14,7 @@ use App\Http\Resources\V4\UserProfileMangaListResource; use App\Profile; use Illuminate\Http\Request; use Illuminate\Support\Facades\DB; +use Jikan\Helper\Constants; use Jikan\Request\User\RecentlyOnlineUsersRequest; use Jikan\Request\User\UserAnimeListRequest; use Jikan\Request\User\UserClubsRequest; @@ -23,6 +24,7 @@ use Jikan\Request\User\UserMangaListRequest; use Jikan\Request\User\UserRecommendationsRequest; use Jikan\Request\User\UserReviewsRequest; use MongoDB\BSON\UTCDateTime; +use Symfony\Component\HttpFoundation\Exception\BadRequestException; /** * Class Controller @@ -964,9 +966,16 @@ class UserController extends Controller || $this->isExpired($request, $results) ) { $page = $request->get('page') ?? 1; - $data = $this->jikan->getUserReviews(new UserReviewsRequest($username, $page)); - $response = \json_decode($this->serializer->serialize($data, 'json'), true); + $data = $this->jikan + ->getUserReviews( + new UserReviewsRequest( + $username, + $page, + ) + ); + + $response = \json_decode($this->serializer->serialize($data, 'json'), true); $results = $this->updateCache($request, $results, $response); } diff --git a/app/Http/Resources/V4/ReviewsResource.php b/app/Http/Resources/V4/ReviewsResource.php index 9fcb03d..d6a64cb 100644 --- a/app/Http/Resources/V4/ReviewsResource.php +++ b/app/Http/Resources/V4/ReviewsResource.php @@ -19,17 +19,57 @@ class ReviewsResource extends JsonResource * @OA\Property( * property="url", * type="string", - * description="MyAnimeList URL" + * description="MyAnimeList review URL" * ), * @OA\Property( * property="type", * type="string", - * description="Entry Type" + * description="Entry type" * ), * @OA\Property( - * property="votes", - * type="integer", - * description="Number of user votes on the Review" + * property="reactions", + * type="object", + * description="User reaction count on the review", + * @OA\Property( + * property="overall", + * type="integer", + * description="Overall reaction count" + * ), + * @OA\Property( + * property="nice", + * type="integer", + * description="Nice reaction count" + * ), + * @OA\Property( + * property="love_it", + * type="integer", + * description="Love it reaction count" + * ), + * @OA\Property( + * property="funny", + * type="integer", + * description="Funny reaction count" + * ), + * @OA\Property( + * property="confusing", + * type="integer", + * description="Confusing reaction count" + * ), + * @OA\Property( + * property="informative", + * type="integer", + * description="Informative reaction count" + * ), + * @OA\Property( + * property="well_written", + * type="integer", + * description="Well written reaction count" + * ), + * @OA\Property( + * property="creative", + * type="integer", + * description="Creative reaction count" + * ) * ), * @OA\Property( * property="date", @@ -37,44 +77,30 @@ class ReviewsResource extends JsonResource * description="Review created date ISO8601" * ), * @OA\Property( - * property="chapters_read", - * type="integer", - * description="Number of chapters read by the reviewer" - * ), - * @OA\Property( * property="review", * type="string", * description="Review content" * ), * @OA\Property( - * property="scores", - * type="object", - * description="Review Scores breakdown", - * @OA\Property( - * property="overall", - * type="integer", - * description="Overall Score" - * ), - * @OA\Property( - * property="story", - * type="integer", - * description="Story Score" - * ), - * @OA\Property( - * property="art", - * type="integer", - * description="Art Score" - * ), - * @OA\Property( - * property="character", - * type="integer", - * description="Character Score" - * ), - * @OA\Property( - * property="enjoyment", - * type="integer", - * description="Enjoyment Score" - * ), + * property="score", + * type="integer", + * description="Number of user votes on the Review" + * ), + * @OA\Property ( + * property="tags", + * type="array", + * description="Review tags", + * @OA\Items(type="string"), + * ), + * @OA\Property ( + * property="is_spoiler", + * type="bool", + * description="The review contains spoiler" + * ), + * @OA\Property ( + * property="is_preliminary", + * type="bool", + * description="The review was made before the entry was completed" * ), * ), * @@ -89,17 +115,57 @@ class ReviewsResource extends JsonResource * @OA\Property( * property="url", * type="string", - * description="MyAnimeList URL" + * description="MyAnimeList review URL" * ), * @OA\Property( * property="type", * type="string", - * description="Entry Type" + * description="Entry type" * ), * @OA\Property( - * property="votes", - * type="integer", - * description="Number of user votes on the Review" + * property="reactions", + * type="object", + * description="User reaction count on the review", + * @OA\Property( + * property="overall", + * type="integer", + * description="Overall reaction count" + * ), + * @OA\Property( + * property="nice", + * type="integer", + * description="Nice reaction count" + * ), + * @OA\Property( + * property="love_it", + * type="integer", + * description="Love it reaction count" + * ), + * @OA\Property( + * property="funny", + * type="integer", + * description="Funny reaction count" + * ), + * @OA\Property( + * property="confusing", + * type="integer", + * description="Confusing reaction count" + * ), + * @OA\Property( + * property="informative", + * type="integer", + * description="Informative reaction count" + * ), + * @OA\Property( + * property="well_written", + * type="integer", + * description="Well written reaction count" + * ), + * @OA\Property( + * property="creative", + * type="integer", + * description="Creative reaction count" + * ) * ), * @OA\Property( * property="date", @@ -112,45 +178,31 @@ class ReviewsResource extends JsonResource * description="Review content" * ), * @OA\Property( + * property="score", + * type="integer", + * description="Number of user votes on the Review" + * ), + * @OA\Property ( + * property="tags", + * type="array", + * description="Review tags", + * @OA\Items(type="string"), + * ), + * @OA\Property ( + * property="is_spoiler", + * type="bool", + * description="The review contains spoiler" + * ), + * @OA\Property ( + * property="is_preliminary", + * type="bool", + * description="The review was made before the entry was completed" + * ), + * @OA\Property( * property="episodes_watched", * type="integer", * description="Number of episodes watched" * ), - * @OA\Property( - * property="scores", - * type="object", - * description="Review Scores breakdown", - * @OA\Property( - * property="overall", - * type="integer", - * description="Overall Score" - * ), - * @OA\Property( - * property="story", - * type="integer", - * description="Story Score" - * ), - * @OA\Property( - * property="animation", - * type="integer", - * description="Animation Score" - * ), - * @OA\Property( - * property="sound", - * type="integer", - * description="Sound Score" - * ), - * @OA\Property( - * property="character", - * type="integer", - * description="Character Score" - * ), - * @OA\Property( - * property="enjoyment", - * type="integer", - * description="Enjoyment Score" - * ), - * ), * ), * * @@ -233,4 +285,4 @@ class ReviewsResource extends JsonResource 'data' => $this['results'], ]; } -} \ No newline at end of file +} diff --git a/storage/api-docs/api-docs.json b/storage/api-docs/api-docs.json index a03a0b7..6c3d6d4 100644 --- a/storage/api-docs/api-docs.json +++ b/storage/api-docs/api-docs.json @@ -4199,6 +4199,15 @@ }, "type": "object" }, + "magazines_query_orderby": { + "description": "Order by magazine data", + "type": "string", + "enum": [ + "mal_id", + "name", + "count" + ] + }, "manga_news": { "description": "Manga News Resource", "allOf": [ @@ -4323,6 +4332,16 @@ } ] }, + "producers_query_orderby": { + "description": "Producers Search Query Order By", + "type": "string", + "enum": [ + "mal_id", + "count", + "favorites", + "established" + ] + }, "seasons": { "description": "List of available seasons", "properties": { @@ -4638,15 +4657,6 @@ "created" ] }, - "magazines_query_orderby": { - "description": "Order by magazine data", - "type": "string", - "enum": [ - "mal_id", - "name", - "count" - ] - }, "manga_search_query_type": { "description": "Available Manga types", "type": "string", @@ -4699,17 +4709,6 @@ "favorites" ] }, - "producers_query_orderby": { - "description": "Order by producers data", - "type": "string", - "enum": [ - "mal_id", - "name", - "count", - "favorites", - "established" - ] - }, "users_search_query_gender": { "description": "Users Search Query Gender", "type": "string", @@ -8467,54 +8466,77 @@ "type": "integer" }, "url": { - "description": "MyAnimeList URL", + "description": "MyAnimeList review URL", "type": "string" }, "type": { - "description": "Entry Type", + "description": "Entry type", "type": "string" }, - "votes": { - "description": "Number of user votes on the Review", - "type": "integer" + "reactions": { + "description": "User reaction count on the review", + "properties": { + "overall": { + "description": "Overall reaction count", + "type": "integer" + }, + "nice": { + "description": "Nice reaction count", + "type": "integer" + }, + "love_it": { + "description": "Love it reaction count", + "type": "integer" + }, + "funny": { + "description": "Funny reaction count", + "type": "integer" + }, + "confusing": { + "description": "Confusing reaction count", + "type": "integer" + }, + "informative": { + "description": "Informative reaction count", + "type": "integer" + }, + "well_written": { + "description": "Well written reaction count", + "type": "integer" + }, + "creative": { + "description": "Creative reaction count", + "type": "integer" + } + }, + "type": "object" }, "date": { "description": "Review created date ISO8601", "type": "string" }, - "chapters_read": { - "description": "Number of chapters read by the reviewer", - "type": "integer" - }, "review": { "description": "Review content", "type": "string" }, - "scores": { - "description": "Review Scores breakdown", - "properties": { - "overall": { - "description": "Overall Score", - "type": "integer" - }, - "story": { - "description": "Story Score", - "type": "integer" - }, - "art": { - "description": "Art Score", - "type": "integer" - }, - "character": { - "description": "Character Score", - "type": "integer" - }, - "enjoyment": { - "description": "Enjoyment Score", - "type": "integer" - } - }, - "type": "object" + "score": { + "description": "Number of user votes on the Review", + "type": "integer" + }, + "tags": { + "description": "Review tags", + "type": "array", + "items": { + "type": "string" + } + }, + "is_spoiler": { + "description": "The review contains spoiler", + "type": "bool" + }, + "is_preliminary": { + "description": "The review was made before the entry was completed", + "type": "bool" } }, "type": "object" @@ -8526,16 +8548,50 @@ "type": "integer" }, "url": { - "description": "MyAnimeList URL", + "description": "MyAnimeList review URL", "type": "string" }, "type": { - "description": "Entry Type", + "description": "Entry type", "type": "string" }, - "votes": { - "description": "Number of user votes on the Review", - "type": "integer" + "reactions": { + "description": "User reaction count on the review", + "properties": { + "overall": { + "description": "Overall reaction count", + "type": "integer" + }, + "nice": { + "description": "Nice reaction count", + "type": "integer" + }, + "love_it": { + "description": "Love it reaction count", + "type": "integer" + }, + "funny": { + "description": "Funny reaction count", + "type": "integer" + }, + "confusing": { + "description": "Confusing reaction count", + "type": "integer" + }, + "informative": { + "description": "Informative reaction count", + "type": "integer" + }, + "well_written": { + "description": "Well written reaction count", + "type": "integer" + }, + "creative": { + "description": "Creative reaction count", + "type": "integer" + } + }, + "type": "object" }, "date": { "description": "Review created date ISO8601", @@ -8545,39 +8601,28 @@ "description": "Review content", "type": "string" }, + "score": { + "description": "Number of user votes on the Review", + "type": "integer" + }, + "tags": { + "description": "Review tags", + "type": "array", + "items": { + "type": "string" + } + }, + "is_spoiler": { + "description": "The review contains spoiler", + "type": "bool" + }, + "is_preliminary": { + "description": "The review was made before the entry was completed", + "type": "bool" + }, "episodes_watched": { "description": "Number of episodes watched", "type": "integer" - }, - "scores": { - "description": "Review Scores breakdown", - "properties": { - "overall": { - "description": "Overall Score", - "type": "integer" - }, - "story": { - "description": "Story Score", - "type": "integer" - }, - "animation": { - "description": "Animation Score", - "type": "integer" - }, - "sound": { - "description": "Sound Score", - "type": "integer" - }, - "character": { - "description": "Character Score", - "type": "integer" - }, - "enjoyment": { - "description": "Enjoyment Score", - "type": "integer" - } - }, - "type": "object" } }, "type": "object" diff --git a/tests/HttpV4/Controllers/AnimeControllerTest.php b/tests/HttpV4/Controllers/AnimeControllerTest.php index 732d92e..fb6cf9d 100644 --- a/tests/HttpV4/Controllers/AnimeControllerTest.php +++ b/tests/HttpV4/Controllers/AnimeControllerTest.php @@ -406,9 +406,14 @@ class AnimeControllerV4Test extends TestCase [ 'mal_id', 'url', - 'votes', + 'type', + 'reactions', 'date', 'review', + 'score', + 'tags', + 'is_spoiler', + 'is_preliminary', 'episodes_watched', 'scores' => [ 'overall', @@ -508,7 +513,7 @@ class AnimeControllerV4Test extends TestCase ] ]); - $this->get('/v4/anime/1/userupdates?page=100') + $this->get('/v4/anime/1/userupdates?page=200') ->seeStatusCode(404); } diff --git a/tests/HttpV4/Controllers/MangaControllerTest.php b/tests/HttpV4/Controllers/MangaControllerTest.php index 0967e53..589b158 100644 --- a/tests/HttpV4/Controllers/MangaControllerTest.php +++ b/tests/HttpV4/Controllers/MangaControllerTest.php @@ -228,9 +228,14 @@ class MangaControllerV4Test extends TestCase [ 'mal_id', 'url', - 'votes', + 'type', + 'reactions', 'date', 'review', + 'score', + 'tags', + 'is_spoiler', + 'is_preliminary', 'chapters_read', 'scores' => [ 'overall', @@ -331,7 +336,7 @@ class MangaControllerV4Test extends TestCase ] ]); - $this->get('/v4/manga/1/userupdates?page=100') + $this->get('/v4/manga/1/userupdates?page=200') ->seeStatusCode(404); } diff --git a/tests/HttpV4/Controllers/PersonControllerTest.php b/tests/HttpV4/Controllers/PersonControllerTest.php index e7e64e1..3f80a09 100644 --- a/tests/HttpV4/Controllers/PersonControllerTest.php +++ b/tests/HttpV4/Controllers/PersonControllerTest.php @@ -112,7 +112,6 @@ class PersonControllerTest extends TestCase 'images' => [ 'jpg' => [ 'image_url', - 'small_image_url', ], 'webp' => [ 'image_url', diff --git a/tests/HttpV4/Controllers/ReviewsControllerTest.php b/tests/HttpV4/Controllers/ReviewsControllerTest.php index d6ce5c8..8c2b2f9 100644 --- a/tests/HttpV4/Controllers/ReviewsControllerTest.php +++ b/tests/HttpV4/Controllers/ReviewsControllerTest.php @@ -17,18 +17,14 @@ class ReviewsControllerTest extends TestCase 'mal_id', 'url', 'type', - 'votes', + 'reactions', 'date', 'review', + 'score', + 'tags', + 'is_spoiler', + 'is_preliminary', 'episodes_watched', - 'scores' => [ - 'overall', - 'story', - 'animation', - 'sound', - 'character', - 'enjoyment', - ], 'entry' => [ 'mal_id', 'url', @@ -77,17 +73,14 @@ class ReviewsControllerTest extends TestCase 'mal_id', 'url', 'type', - 'votes', + 'reactions', 'date', 'review', + 'score', + 'tags', + 'is_spoiler', + 'is_preliminary', 'chapters_read', - 'scores' => [ - 'overall', - 'story', - 'art', - 'character', - 'enjoyment', - ], 'entry' => [ 'mal_id', 'url', @@ -121,4 +114,4 @@ class ReviewsControllerTest extends TestCase ] ]); } -} \ No newline at end of file +} diff --git a/tests/HttpV4/Controllers/UserControllerTest.php b/tests/HttpV4/Controllers/UserControllerTest.php index 85a4316..6695a98 100644 --- a/tests/HttpV4/Controllers/UserControllerTest.php +++ b/tests/HttpV4/Controllers/UserControllerTest.php @@ -274,9 +274,13 @@ class UserControllerTest extends TestCase 'mal_id', 'url', 'type', - 'votes', + 'reactions', 'date', 'review', + 'score', + 'tags', + 'is_spoiler', + 'is_preliminary', 'entry' => [ 'mal_id', 'url',