namespace Tests\Api;
-use BookStack\Activity\Models\Tag;
use BookStack\Entities\Models\Book;
use BookStack\Entities\Models\Bookshelf;
use BookStack\Entities\Models\Chapter;
{
use TestsApi;
- protected $baseEndpoint = '/api/search';
+ protected string $baseEndpoint = '/api/search';
public function test_all_endpoint_returns_search_filtered_results_with_query()
{
$resp->assertOk();
}
- public function test_all_endpoint_includes_book_and_chapter_titles_when_requested()
+ public function test_all_endpoint_includes_parent_details_where_visible()
{
- $this->actingAsApiEditor();
-
- $book = $this->entities->book();
- $chapter = $this->entities->chapter();
- $page = $this->entities->newPage();
-
- $book->name = 'My Test Book';
- $book->save();
-
- $chapter->name = 'My Test Chapter';
- $chapter->book_id = $book->id;
- $chapter->save();
-
- $page->name = 'My Test Page With UniqueSearchTerm';
- $page->book_id = $book->id;
- $page->chapter_id = $chapter->id;
- $page->save();
+ $page = $this->entities->pageWithinChapter();
+ $chapter = $page->chapter;
+ $book = $page->book;
+ $page->update(['name' => 'name with superextrauniquevalue within']);
$page->indexForSearch();
- // Test without include parameter
- $resp = $this->getJson($this->baseEndpoint . '?query=UniqueSearchTerm');
- $resp->assertOk();
- $resp->assertDontSee('book_title');
- $resp->assertDontSee('chapter_title');
-
- // Test with include parameter
- $resp = $this->getJson($this->baseEndpoint . '?query=UniqueSearchTerm&include=titles');
- $resp->assertOk();
+ $editor = $this->users->editor();
+ $this->actingAsApiEditor();
+ $resp = $this->getJson($this->baseEndpoint . '?query=superextrauniquevalue');
$resp->assertJsonFragment([
- 'name' => 'My Test Page With UniqueSearchTerm',
- 'book_title' => 'My Test Book',
- 'chapter_title' => 'My Test Chapter',
- 'type' => 'page'
+ 'id' => $page->id,
+ 'type' => 'page',
+ 'book' => [
+ 'id' => $book->id,
+ 'name' => $book->name,
+ 'slug' => $book->slug,
+ ],
+ 'chapter' => [
+ 'id' => $chapter->id,
+ 'name' => $chapter->name,
+ 'slug' => $chapter->slug,
+ ],
]);
- }
- public function test_all_endpoint_validates_include_parameter()
- {
- $this->actingAsApiEditor();
+ $this->permissions->disableEntityInheritedPermissions($chapter);
+ $this->permissions->setEntityPermissions($page, ['view'], [$editor->roles()->first()]);
- // Test invalid include value
- $resp = $this->getJson($this->baseEndpoint . '?query=test&include=invalid');
- $resp->assertOk();
- $resp->assertDontSee('book_title');
+ $resp = $this->getJson($this->baseEndpoint . '?query=superextrauniquevalue');
+ $resp->assertJsonPath('data.0.id', $page->id);
+ $resp->assertJsonPath('data.0.book.name', $book->name);
+ $resp->assertJsonMissingPath('data.0.chapter');
- // Test SQL injection attempt
- $resp = $this->getJson($this->baseEndpoint . '?query=test&include=titles;DROP TABLE users');
- $resp->assertStatus(422);
+ $this->permissions->disableEntityInheritedPermissions($book);
- // Test multiple includes
- $resp = $this->getJson($this->baseEndpoint . '?query=test&include=titles,tags');
- $resp->assertOk();
+ $resp = $this->getJson($this->baseEndpoint . '?query=superextrauniquevalue');
+ $resp->assertJsonPath('data.0.id', $page->id);
+ $resp->assertJsonMissingPath('data.0.book.name');
}
-
- public function test_all_endpoint_includes_tags_when_requested()
- {
- $this->actingAsApiEditor();
-
- // Create a page and give it a unique name for search
- $page = $this->entities->page();
- $page->name = 'Page With UniqueSearchTerm';
- $page->save();
-
- // Save tags to the page using the existing saveTagsToEntity method
- $tags = [
- ['name' => 'SampleTag', 'value' => 'SampleValue']
- ];
- app(\BookStack\Activity\TagRepo::class)->saveTagsToEntity($page, $tags);
-
- // Ensure the page is indexed for search
- $page->indexForSearch();
-
- // Test without the "tags" include
- $resp = $this->getJson($this->baseEndpoint . '?query=UniqueSearchTerm');
- $resp->assertOk();
- $resp->assertDontSee('tags');
-
- // Test with the "tags" include
- $resp = $this->getJson($this->baseEndpoint . '?query=UniqueSearchTerm&include=tags');
- $resp->assertOk();
-
- // Assert that tags are included in the response
- $resp->assertJsonFragment([
- 'name' => 'SampleTag',
- 'value' => 'SampleValue',
- ]);
-
- // Optionally: check the structure to match the tag order as well
- $resp->assertJsonStructure([
- 'data' => [
- '*' => [
- 'tags' => [
- '*' => [
- 'name',
- 'value',
- 'order',
- ],
- ],
- ],
- ],
- ]);
- }
-
-
}