X-Git-Url: http://source.bookstackapp.com/bookstack/blobdiff_plain/14ea6c9de341a5474210bc8dba862a23c5de7bf0..refs/pull/5280/head:/tests/Api/PagesApiTest.php diff --git a/tests/Api/PagesApiTest.php b/tests/Api/PagesApiTest.php index e08e9b1b7..22659d5bb 100644 --- a/tests/Api/PagesApiTest.php +++ b/tests/Api/PagesApiTest.php @@ -1,15 +1,18 @@ -getJson($this->baseEndpoint . '?count=1&sort=+id'); $resp->assertJson(['data' => [ [ - 'id' => $firstPage->id, - 'name' => $firstPage->name, - 'slug' => $firstPage->slug, - 'book_id' => $firstPage->book->id, + 'id' => $firstPage->id, + 'name' => $firstPage->name, + 'slug' => $firstPage->slug, + 'book_id' => $firstPage->book->id, 'priority' => $firstPage->priority, - ] + 'owned_by' => $firstPage->owned_by, + 'created_by' => $firstPage->created_by, + 'updated_by' => $firstPage->updated_by, + 'revision_count' => $firstPage->revision_count, + ], ]]); } public function test_create_endpoint() { $this->actingAsApiEditor(); - $book = Book::query()->first(); + $book = $this->entities->book(); $details = [ - 'name' => 'My API page', + 'name' => 'My API page', 'book_id' => $book->id, - 'html' => '
My new page content
', - 'tags' => [ + 'html' => 'My new page content
', + 'tags' => [ [ - 'name' => 'tagname', + 'name' => 'tagname', 'value' => 'tagvalue', - ] - ] + ], + ], + 'priority' => 15, ]; $resp = $this->postJson($this->baseEndpoint, $details); @@ -50,10 +58,10 @@ class PagesApiTest extends TestCase $newItem = Page::query()->orderByDesc('id')->where('name', '=', $details['name'])->first(); $resp->assertJson(array_merge($details, ['id' => $newItem->id, 'slug' => $newItem->slug])); $this->assertDatabaseHas('tags', [ - 'entity_id' => $newItem->id, + 'entity_id' => $newItem->id, 'entity_type' => $newItem->getMorphClass(), - 'name' => 'tagname', - 'value' => 'tagvalue', + 'name' => 'tagname', + 'value' => 'tagvalue', ]); $resp->assertSeeText('My new page content'); $resp->assertJsonMissing(['book' => []]); @@ -63,16 +71,16 @@ class PagesApiTest extends TestCase public function test_page_name_needed_to_create() { $this->actingAsApiEditor(); - $book = Book::query()->first(); + $book = $this->entities->book(); $details = [ 'book_id' => $book->id, - 'html' => 'A page created via the API
', + 'html' => 'A page created via the API
', ]; $resp = $this->postJson($this->baseEndpoint, $details); $resp->assertStatus(422); $resp->assertJson($this->validationResponse([ - "name" => ["The name field is required."] + 'name' => ['The name field is required.'], ])); } @@ -87,15 +95,15 @@ class PagesApiTest extends TestCase $resp = $this->postJson($this->baseEndpoint, $details); $resp->assertStatus(422); $resp->assertJson($this->validationResponse([ - "book_id" => ["The book id field is required when chapter id is not present."], - "chapter_id" => ["The chapter id field is required when book id is not present."] + 'book_id' => ['The book id field is required when chapter id is not present.'], + 'chapter_id' => ['The chapter id field is required when book id is not present.'], ])); - $chapter = Chapter::visible()->first(); + $chapter = $this->entities->chapter(); $resp = $this->postJson($this->baseEndpoint, array_merge($details, ['chapter_id' => $chapter->id])); $resp->assertStatus(200); - $book = Book::visible()->first(); + $book = $this->entities->book(); $resp = $this->postJson($this->baseEndpoint, array_merge($details, ['book_id' => $book->id])); $resp->assertStatus(200); } @@ -103,10 +111,10 @@ class PagesApiTest extends TestCase public function test_markdown_can_be_provided_for_create() { $this->actingAsApiEditor(); - $book = Book::visible()->first(); + $book = $this->entities->book(); $details = [ - 'book_id' => $book->id, - 'name' => 'My api page', + 'book_id' => $book->id, + 'name' => 'My api page', 'markdown' => "# A new API page \n[link](https://example.com)", ]; @@ -122,22 +130,22 @@ class PagesApiTest extends TestCase public function test_read_endpoint() { $this->actingAsApiEditor(); - $page = Page::visible()->first(); + $page = $this->entities->page(); $resp = $this->getJson($this->baseEndpoint . "/{$page->id}"); $resp->assertStatus(200); $resp->assertJson([ - 'id' => $page->id, - 'slug' => $page->slug, + 'id' => $page->id, + 'slug' => $page->slug, 'created_by' => [ 'name' => $page->createdBy->name, ], - 'book_id' => $page->book_id, + 'book_id' => $page->book_id, 'updated_by' => [ 'name' => $page->createdBy->name, ], 'owned_by' => [ - 'name' => $page->ownedBy->name + 'name' => $page->ownedBy->name, ], ]); } @@ -145,7 +153,7 @@ class PagesApiTest extends TestCase public function test_read_endpoint_provides_rendered_html() { $this->actingAsApiEditor(); - $page = Page::visible()->first(); + $page = $this->entities->page(); $page->html = "testing
testing
A page created via the API
', 'tags' => [ [ - 'name' => 'freshtag', + 'name' => 'freshtag', 'value' => 'freshtagval', - ] + ], ], + 'priority' => 15, ]; $resp = $this->putJson($this->baseEndpoint . "/{$page->id}", $details); @@ -177,7 +221,7 @@ class PagesApiTest extends TestCase $resp->assertStatus(200); unset($details['html']); $resp->assertJson(array_merge($details, [ - 'id' => $page->id, 'slug' => $page->slug, 'book_id' => $page->book_id + 'id' => $page->id, 'slug' => $page->slug, 'book_id' => $page->book_id, ])); $this->assertActivityExists('page_update', $page); } @@ -185,42 +229,80 @@ class PagesApiTest extends TestCase public function test_providing_new_chapter_id_on_update_will_move_page() { $this->actingAsApiEditor(); - $page = Page::visible()->first(); + $page = $this->entities->page(); $chapter = Chapter::visible()->where('book_id', '!=', $page->book_id)->first(); $details = [ - 'name' => 'My updated API page', + 'name' => 'My updated API page', 'chapter_id' => $chapter->id, - 'html' => 'A page created via the API
', + 'html' => 'A page created via the API
', ]; $resp = $this->putJson($this->baseEndpoint . "/{$page->id}", $details); $resp->assertStatus(200); $resp->assertJson([ 'chapter_id' => $chapter->id, - 'book_id' => $chapter->book_id, + 'book_id' => $chapter->book_id, ]); } public function test_providing_move_via_update_requires_page_create_permission_on_new_parent() { $this->actingAsApiEditor(); - $page = Page::visible()->first(); + $page = $this->entities->page(); $chapter = Chapter::visible()->where('book_id', '!=', $page->book_id)->first(); - $this->setEntityRestrictions($chapter, ['view'], [$this->getEditor()->roles()->first()]); + $this->permissions->setEntityPermissions($chapter, ['view'], [$this->users->editor()->roles()->first()]); $details = [ - 'name' => 'My updated API page', + 'name' => 'My updated API page', 'chapter_id' => $chapter->id, - 'html' => 'A page created via the API
', + 'html' => 'A page created via the API
', ]; $resp = $this->putJson($this->baseEndpoint . "/{$page->id}", $details); $resp->assertStatus(403); } + public function test_update_endpoint_does_not_wipe_content_if_no_html_or_md_provided() + { + $this->actingAsApiEditor(); + $page = $this->entities->page(); + $originalContent = $page->html; + $details = [ + 'name' => 'My updated API page', + 'tags' => [ + [ + 'name' => 'freshtag', + 'value' => 'freshtagval', + ], + ], + ]; + + $this->putJson($this->baseEndpoint . "/{$page->id}", $details); + $page->refresh(); + + $this->assertEquals($originalContent, $page->html); + } + + public function test_update_increments_updated_date_if_only_tags_are_sent() + { + $this->actingAsApiEditor(); + $page = $this->entities->page(); + DB::table('pages')->where('id', '=', $page->id)->update(['updated_at' => Carbon::now()->subWeek()]); + + $details = [ + 'tags' => [['name' => 'Category', 'value' => 'Testing']], + ]; + + $resp = $this->putJson($this->baseEndpoint . "/{$page->id}", $details); + $resp->assertOk(); + + $page->refresh(); + $this->assertGreaterThan(Carbon::now()->subDay()->unix(), $page->updated_at->unix()); + } + public function test_delete_endpoint() { $this->actingAsApiEditor(); - $page = Page::visible()->first(); + $page = $this->entities->page(); $resp = $this->deleteJson($this->baseEndpoint . "/{$page->id}"); $resp->assertStatus(204); @@ -230,7 +312,7 @@ class PagesApiTest extends TestCase public function test_export_html_endpoint() { $this->actingAsApiEditor(); - $page = Page::visible()->first(); + $page = $this->entities->page(); $resp = $this->get($this->baseEndpoint . "/{$page->id}/export/html"); $resp->assertStatus(200); @@ -241,7 +323,7 @@ class PagesApiTest extends TestCase public function test_export_plain_text_endpoint() { $this->actingAsApiEditor(); - $page = Page::visible()->first(); + $page = $this->entities->page(); $resp = $this->get($this->baseEndpoint . "/{$page->id}/export/plaintext"); $resp->assertStatus(200); @@ -252,10 +334,34 @@ class PagesApiTest extends TestCase public function test_export_pdf_endpoint() { $this->actingAsApiEditor(); - $page = Page::visible()->first(); + $page = $this->entities->page(); $resp = $this->get($this->baseEndpoint . "/{$page->id}/export/pdf"); $resp->assertStatus(200); $resp->assertHeader('Content-Disposition', 'attachment; filename="' . $page->slug . '.pdf"'); } -} \ No newline at end of file + + public function test_export_markdown_endpoint() + { + $this->actingAsApiEditor(); + $page = $this->entities->page(); + + $resp = $this->get($this->baseEndpoint . "/{$page->id}/export/markdown"); + $resp->assertStatus(200); + $resp->assertSee('# ' . $page->name); + $resp->assertHeader('Content-Disposition', 'attachment; filename="' . $page->slug . '.md"'); + } + + public function test_cant_export_when_not_have_permission() + { + $types = ['html', 'plaintext', 'pdf', 'markdown']; + $this->actingAsApiEditor(); + $this->permissions->removeUserRolePermissions($this->users->editor(), ['content-export']); + + $page = $this->entities->page(); + foreach ($types as $type) { + $resp = $this->get($this->baseEndpoint . "/{$page->id}/export/{$type}"); + $this->assertPermissionError($resp); + } + } +}