--- /dev/null
+<?php
+
+namespace Tests;
+
+use BookStack\Auth\Permissions\RolePermission;
+use Carbon\Carbon;
+
+class ApiAuthTest extends TestCase
+{
+ use TestsApi;
+
+ protected $endpoint = '/api/books';
+
+ public function test_default_item_count_reflected_in_listing_requests()
+ {
+ $this->actingAsApiEditor();
+
+ config()->set(['api.default_item_count' => 5]);
+ $resp = $this->get($this->endpoint);
+ $resp->assertJsonCount(5, 'data');
+
+ config()->set(['api.default_item_count' => 1]);
+ $resp = $this->get($this->endpoint);
+ $resp->assertJsonCount(1, 'data');
+ }
+
+ public function test_default_item_count_does_not_limit_count_param()
+ {
+ $this->actingAsApiEditor();
+ config()->set(['api.default_item_count' => 1]);
+ $resp = $this->get($this->endpoint . '?count=5');
+ $resp->assertJsonCount(5, 'data');
+ }
+
+ public function test_max_item_count_limits_listing_requests()
+ {
+ $this->actingAsApiEditor();
+
+ config()->set(['api.max_item_count' => 2]);
+ $resp = $this->get($this->endpoint);
+ $resp->assertJsonCount(2, 'data');
+
+ $resp = $this->get($this->endpoint . '?count=5');
+ $resp->assertJsonCount(2, 'data');
+ }
+
+}
\ No newline at end of file
--- /dev/null
+<?php
+
+namespace Tests;
+
+use BookStack\Auth\Permissions\RolePermission;
+use BookStack\Entities\Book;
+use Carbon\Carbon;
+
+class ApiAuthTest extends TestCase
+{
+ use TestsApi;
+
+ protected $endpoint = '/api/books';
+
+ public function test_count_parameter_limits_responses()
+ {
+ $this->actingAsApiEditor();
+ $bookCount = min(Book::visible()->count(), 100);
+
+ $resp = $this->get($this->endpoint);
+ $resp->assertJsonCount($bookCount, 'data');
+
+ $resp = $this->get($this->endpoint . '?count=1');
+ $resp->assertJsonCount(1, 'data');
+ }
+
+ public function test_offset_parameter()
+ {
+ $this->actingAsApiEditor();
+ $books = Book::visible()->orderBy('id')->take(3)->get();
+
+ $resp = $this->get($this->endpoint . '?count=1');
+ $resp->assertJsonMissing(['name' => $books[1]->name ]);
+
+ $resp = $this->get($this->endpoint . '?count=1&offset=1000');
+ $resp->assertJsonCount(0, 'data');
+ }
+
+ public function test_sort_parameter()
+ {
+ $this->actingAsApiEditor();
+
+ $sortChecks = [
+ '-id' => Book::visible()->orderBy('id', 'desc')->first(),
+ '+name' => Book::visible()->orderBy('name', 'asc')->first(),
+ 'name' => Book::visible()->orderBy('name', 'asc')->first(),
+ '-name' => Book::visible()->orderBy('name', 'desc')->first()
+ ];
+
+ foreach ($sortChecks as $sortOption => $result) {
+ $resp = $this->get($this->endpoint . '?count=1&sort=' . $sortOption);
+ $resp->assertJson(['data' => [
+ [
+ 'id' => $result->id,
+ 'name' => $result->name,
+ ]
+ ]]);
+ }
+ }
+
+}
\ No newline at end of file
protected $apiTokenId = 'apitoken';
protected $apiTokenSecret = 'password';
- protected function errorResponse(string $messge, int $code)
+ /**
+ * Set the API editor role as the current user via the API driver.
+ */
+ protected function actingAsApiEditor()
{
- return ["error" => ["code" => $code, "message" => $messge]];
+ $this->actingAs($this->getEditor(), 'api');
+ return $this;
}
- protected function apiAuthHeader()
+ /**
+ * Format the given items into a standardised error format.
+ */
+ protected function errorResponse(string $message, int $code): array
+ {
+ return ["error" => ["code" => $code, "message" => $message]];
+ }
+
+ /**
+ * Get an approved API auth header.
+ */
+ protected function apiAuthHeader(): array
{
return [
"Authorization" => "Token {$this->apiTokenId}:{$this->apiTokenSecret}"