diff --git a/app/Http/Controllers/PublicWikiController.php b/app/Http/Controllers/PublicWikiController.php index 15224b37..2cc4d5b6 100644 --- a/app/Http/Controllers/PublicWikiController.php +++ b/app/Http/Controllers/PublicWikiController.php @@ -11,6 +11,7 @@ class PublicWikiController extends Controller { private static $defaultParams = [ 'sort' => 'sitename', 'direction' => 'asc', + 'per_page' => 15, ]; private static $activeThresholdPageCount = 2; @@ -24,8 +25,8 @@ public function index(Request $request) { 'direction' => 'in:desc,asc', 'is_featured' => 'boolean', 'is_active' => 'boolean', - 'per_page' => 'numeric', - 'page' => 'numeric', + 'per_page' => 'int|min:1|max:100', + 'page' => 'int|min:1', ]); $params = array_merge(self::$defaultParams, $request->input()); @@ -61,12 +62,7 @@ public function index(Request $request) { break; } - $perPage = null; - if (array_key_exists('per_page', $params)) { - $perPage = intval($params['per_page']); - } - - return PublicWikiResource::collection($query->paginate($perPage)); + return PublicWikiResource::collection($query->paginate($params['per_page'])); } /** diff --git a/tests/Http/Controllers/PublicWikiControllerTest.php b/tests/Http/Controllers/PublicWikiControllerTest.php index 5ec79487..f5748ff8 100644 --- a/tests/Http/Controllers/PublicWikiControllerTest.php +++ b/tests/Http/Controllers/PublicWikiControllerTest.php @@ -6,10 +6,13 @@ use App\Http\Resources\PublicWikiResource; use App\Wiki; use App\WikiProfile; +use Generator; use Illuminate\Database\Events\QueryExecuted; use Illuminate\Foundation\Testing\DatabaseTransactions; use Illuminate\Http\Request; +use Illuminate\Http\Resources\Json\AnonymousResourceCollection; use Illuminate\Support\Facades\DB; +use Illuminate\Validation\ValidationException; use Tests\TestCase; class PublicWikiControllerTest extends TestCase { @@ -35,6 +38,44 @@ public function testShowLoadsWikiLatestProfileForResource(): void { $this->assertSame(true, $resource->toArray(new Request())['reuse_prototype']); } + public static function provideQueryParamsAndErrorExpected(): Generator { + yield 'default params' => [[], false]; + yield 'sort by sitename ascending' => [['sort' => 'sitename', 'direction' => 'asc'], false]; + yield 'sort by pages descending' => [['sort' => 'pages', 'direction' => 'desc'], false]; + yield 'sort by invalid value' => [['sort' => 'invalid'], true]; + yield 'sort by invalid direction' => [['direction' => 'invalid'], true]; + yield 'is_featured is boolean true' => [['is_featured' => true], false]; + yield 'is_featured is boolean 0' => [['is_featured' => 0], false]; + yield 'is_featured is invalid' => [['is_featured' => 'invalid'], true]; + yield 'is_active is boolean false' => [['is_active' => false], false]; + yield 'is_active is boolean 1' => [['is_active' => 1], false]; + yield 'is_active is invalid' => [['is_active' => 'invalid'], true]; + yield 'per_page is not int' => [['per_page' => 1.2], true]; + yield 'per_page is too low' => [['per_page' => 0], true]; + yield 'per_page is min value' => [['per_page' => 1], false]; + yield 'per_page is max value' => [['per_page' => 100], false]; + yield 'per_page is too high' => [['per_page' => 101], true]; + yield 'page is not int' => [['page' => 2.3], true]; + yield 'page is too low' => [['page' => 0], true]; + yield 'page is min value' => [['page' => 1], false]; + } + + /** + * @dataProvider provideQueryParamsAndErrorExpected + */ + public function testIndexQueryParamValidation(array $queryParams, bool $errorExpected): void { + $controller = new PublicWikiController(); + $request = new Request($queryParams); + + if ($errorExpected) { + $this->expectException(ValidationException::class); + } + + $response = $controller->index($request); + + $this->assertInstanceOf(AnonymousResourceCollection::class, $response); + } + public function testIndexReusePrototypeOnlyRequiresOneAdditionalDatabaseQuery(): void { for ($i = 1; $i <= 3; $i++) { $wiki = Wiki::factory()->create([