mirror of
https://github.com/BookStackApp/BookStack.git
synced 2026-05-04 18:08:46 +03:00
From testing, don't think this could exploited directly, as the response would error instead of allowing control characters, but this adds an extra layer of sanitization, and switches to encoded disposition filenames for better UTF8 support.
144 lines
5.0 KiB
PHP
144 lines
5.0 KiB
PHP
<?php
|
|
|
|
namespace Tests\Exports;
|
|
|
|
use BookStack\Entities\Models\Book;
|
|
use Tests\TestCase;
|
|
|
|
class MarkdownExportTest extends TestCase
|
|
{
|
|
public function test_page_markdown_export()
|
|
{
|
|
$page = $this->entities->page();
|
|
|
|
$resp = $this->asEditor()->get($page->getUrl('/export/markdown'));
|
|
$resp->assertStatus(200);
|
|
$resp->assertSee($page->name);
|
|
$resp->assertHeader('Content-Disposition', 'attachment; filename*=UTF-8\'\'' . $page->slug . '.md');
|
|
}
|
|
|
|
public function test_page_markdown_export_uses_existing_markdown_if_apparent()
|
|
{
|
|
$page = $this->entities->page()->forceFill([
|
|
'markdown' => '# A header',
|
|
'html' => '<h1>Dogcat</h1>',
|
|
]);
|
|
$page->save();
|
|
|
|
$resp = $this->asEditor()->get($page->getUrl('/export/markdown'));
|
|
$resp->assertSee('A header');
|
|
$resp->assertDontSee('Dogcat');
|
|
}
|
|
|
|
public function test_page_markdown_export_converts_html_where_no_markdown()
|
|
{
|
|
$page = $this->entities->page()->forceFill([
|
|
'markdown' => '',
|
|
'html' => '<h1>Dogcat</h1><p>Some <strong>bold</strong> text</p>',
|
|
]);
|
|
$page->save();
|
|
|
|
$resp = $this->asEditor()->get($page->getUrl('/export/markdown'));
|
|
$resp->assertSee("# Dogcat\n\nSome **bold** text");
|
|
}
|
|
|
|
public function test_chapter_markdown_export()
|
|
{
|
|
$chapter = $this->entities->chapter();
|
|
$chapter->description_html = '<p>My <strong>chapter</strong> description</p>';
|
|
$chapter->save();
|
|
$page = $chapter->pages()->first();
|
|
|
|
$resp = $this->asEditor()->get($chapter->getUrl('/export/markdown'));
|
|
|
|
$resp->assertSee('# ' . $chapter->name);
|
|
$resp->assertSee('# ' . $page->name);
|
|
$resp->assertSee('My **chapter** description');
|
|
}
|
|
|
|
public function test_chapter_markdown_export_pages_are_permission_controlled()
|
|
{
|
|
$chapter = $this->entities->chapterHasPages();
|
|
$page = $chapter->pages()->first();
|
|
$page->name = 'MyPageWhichShouldNotBeFound';
|
|
$page->save();
|
|
$this->permissions->disableEntityInheritedPermissions($page);
|
|
|
|
$resp = $this->asEditor()->get($chapter->getUrl('/export/markdown'));
|
|
|
|
$resp->assertSee('# ' . $chapter->name);
|
|
$resp->assertDontSee('MyPageWhichShouldNotBeFound');
|
|
}
|
|
|
|
public function test_book_markdown_export()
|
|
{
|
|
$book = Book::query()->whereHas('pages')->whereHas('chapters')->first();
|
|
$book->description_html = '<p>My <strong>book</strong> description</p>';
|
|
$book->save();
|
|
|
|
$chapter = $book->chapters()->first();
|
|
$chapter->description_html = '<p>My <strong>chapter</strong> description</p>';
|
|
$chapter->save();
|
|
|
|
$page = $chapter->pages()->first();
|
|
$resp = $this->asEditor()->get($book->getUrl('/export/markdown'));
|
|
|
|
$resp->assertSee('# ' . $book->name);
|
|
$resp->assertSee('# ' . $chapter->name);
|
|
$resp->assertSee('# ' . $page->name);
|
|
$resp->assertSee('My **book** description');
|
|
$resp->assertSee('My **chapter** description');
|
|
}
|
|
|
|
public function test_book_markdown_export_chapters_are_permission_controlled()
|
|
{
|
|
$book = $this->entities->bookHasChaptersAndPages();
|
|
$chapter = $book->chapters()->first();
|
|
$page = $chapter->pages()->first();
|
|
$page->name = 'MyPageWhichShouldNotBeFound';
|
|
$page->save();
|
|
$chapter->name = 'MyChapterWhichShouldNotBeFound';
|
|
$chapter->save();
|
|
$this->permissions->disableEntityInheritedPermissions($chapter);
|
|
|
|
$resp = $this->asEditor()->get($book->getUrl('/export/markdown'));
|
|
|
|
$resp->assertSee('# ' . $book->name);
|
|
$resp->assertDontSee('MyChapterWhichShouldNotBeFound');
|
|
$resp->assertDontSee('MyPageWhichShouldNotBeFound');
|
|
}
|
|
|
|
public function test_book_markdown_export_direct_pages_are_permission_controlled()
|
|
{
|
|
$book = $this->entities->bookHasChaptersAndPages();
|
|
$page = $book->directPages()->first();
|
|
$page->name = 'MyPageWhichShouldNotBeFound';
|
|
$page->save();
|
|
$this->permissions->disableEntityInheritedPermissions($page);
|
|
|
|
$resp = $this->asEditor()->get($book->getUrl('/export/markdown'));
|
|
|
|
$resp->assertSee('# ' . $book->name);
|
|
$resp->assertDontSee('MyPageWhichShouldNotBeFound');
|
|
}
|
|
|
|
public function test_book_markdown_export_concats_immediate_pages_with_newlines()
|
|
{
|
|
/** @var Book $book */
|
|
$book = Book::query()->whereHas('pages')->first();
|
|
|
|
$this->asEditor()->get($book->getUrl('/create-page'));
|
|
$this->get($book->getUrl('/create-page'));
|
|
|
|
[$pageA, $pageB] = $book->pages()->whereNull('chapter_id')->get();
|
|
$pageA->html = '<p>hello tester</p>';
|
|
$pageA->save();
|
|
$pageB->name = 'The second page in this test';
|
|
$pageB->save();
|
|
|
|
$resp = $this->get($book->getUrl('/export/markdown'));
|
|
$resp->assertDontSee('hello tester# The second page in this test');
|
|
$resp->assertSee("hello tester\n\n# The second page in this test");
|
|
}
|
|
}
|