Added book export and created export tests to cover
In reference to #177
Showing
11 changed files
with
306 additions
and
15 deletions
| ... | @@ -3,6 +3,7 @@ | ... | @@ -3,6 +3,7 @@ |
| 3 | use Activity; | 3 | use Activity; |
| 4 | use BookStack\Repos\EntityRepo; | 4 | use BookStack\Repos\EntityRepo; |
| 5 | use BookStack\Repos\UserRepo; | 5 | use BookStack\Repos\UserRepo; |
| 6 | +use BookStack\Services\ExportService; | ||
| 6 | use Illuminate\Http\Request; | 7 | use Illuminate\Http\Request; |
| 7 | use Illuminate\Http\Response; | 8 | use Illuminate\Http\Response; |
| 8 | use Views; | 9 | use Views; |
| ... | @@ -12,16 +13,19 @@ class BookController extends Controller | ... | @@ -12,16 +13,19 @@ class BookController extends Controller |
| 12 | 13 | ||
| 13 | protected $entityRepo; | 14 | protected $entityRepo; |
| 14 | protected $userRepo; | 15 | protected $userRepo; |
| 16 | + protected $exportService; | ||
| 15 | 17 | ||
| 16 | /** | 18 | /** |
| 17 | * BookController constructor. | 19 | * BookController constructor. |
| 18 | * @param EntityRepo $entityRepo | 20 | * @param EntityRepo $entityRepo |
| 19 | * @param UserRepo $userRepo | 21 | * @param UserRepo $userRepo |
| 22 | + * @param ExportService $exportService | ||
| 20 | */ | 23 | */ |
| 21 | - public function __construct(EntityRepo $entityRepo, UserRepo $userRepo) | 24 | + public function __construct(EntityRepo $entityRepo, UserRepo $userRepo, ExportService $exportService) |
| 22 | { | 25 | { |
| 23 | $this->entityRepo = $entityRepo; | 26 | $this->entityRepo = $entityRepo; |
| 24 | $this->userRepo = $userRepo; | 27 | $this->userRepo = $userRepo; |
| 28 | + $this->exportService = $exportService; | ||
| 25 | parent::__construct(); | 29 | parent::__construct(); |
| 26 | } | 30 | } |
| 27 | 31 | ||
| ... | @@ -258,4 +262,49 @@ class BookController extends Controller | ... | @@ -258,4 +262,49 @@ class BookController extends Controller |
| 258 | session()->flash('success', trans('entities.books_permissions_updated')); | 262 | session()->flash('success', trans('entities.books_permissions_updated')); |
| 259 | return redirect($book->getUrl()); | 263 | return redirect($book->getUrl()); |
| 260 | } | 264 | } |
| 265 | + | ||
| 266 | + /** | ||
| 267 | + * Export a book as a PDF file. | ||
| 268 | + * @param string $bookSlug | ||
| 269 | + * @return mixed | ||
| 270 | + */ | ||
| 271 | + public function exportPdf($bookSlug) | ||
| 272 | + { | ||
| 273 | + $book = $this->entityRepo->getBySlug('book', $bookSlug); | ||
| 274 | + $pdfContent = $this->exportService->bookToPdf($book); | ||
| 275 | + return response()->make($pdfContent, 200, [ | ||
| 276 | + 'Content-Type' => 'application/octet-stream', | ||
| 277 | + 'Content-Disposition' => 'attachment; filename="' . $bookSlug . '.pdf' | ||
| 278 | + ]); | ||
| 279 | + } | ||
| 280 | + | ||
| 281 | + /** | ||
| 282 | + * Export a book as a contained HTML file. | ||
| 283 | + * @param string $bookSlug | ||
| 284 | + * @return mixed | ||
| 285 | + */ | ||
| 286 | + public function exportHtml($bookSlug) | ||
| 287 | + { | ||
| 288 | + $book = $this->entityRepo->getBySlug('book', $bookSlug); | ||
| 289 | + $htmlContent = $this->exportService->bookToContainedHtml($book); | ||
| 290 | + return response()->make($htmlContent, 200, [ | ||
| 291 | + 'Content-Type' => 'application/octet-stream', | ||
| 292 | + 'Content-Disposition' => 'attachment; filename="' . $bookSlug . '.html' | ||
| 293 | + ]); | ||
| 294 | + } | ||
| 295 | + | ||
| 296 | + /** | ||
| 297 | + * Export a book as a plain text file. | ||
| 298 | + * @param $bookSlug | ||
| 299 | + * @return mixed | ||
| 300 | + */ | ||
| 301 | + public function exportPlainText($bookSlug) | ||
| 302 | + { | ||
| 303 | + $book = $this->entityRepo->getBySlug('book', $bookSlug); | ||
| 304 | + $htmlContent = $this->exportService->bookToPlainText($book); | ||
| 305 | + return response()->make($htmlContent, 200, [ | ||
| 306 | + 'Content-Type' => 'application/octet-stream', | ||
| 307 | + 'Content-Disposition' => 'attachment; filename="' . $bookSlug . '.txt' | ||
| 308 | + ]); | ||
| 309 | + } | ||
| 261 | } | 310 | } | ... | ... |
| ... | @@ -439,7 +439,6 @@ class PageController extends Controller | ... | @@ -439,7 +439,6 @@ class PageController extends Controller |
| 439 | { | 439 | { |
| 440 | $page = $this->entityRepo->getBySlug('page', $pageSlug, $bookSlug); | 440 | $page = $this->entityRepo->getBySlug('page', $pageSlug, $bookSlug); |
| 441 | $pdfContent = $this->exportService->pageToPdf($page); | 441 | $pdfContent = $this->exportService->pageToPdf($page); |
| 442 | -// return $pdfContent; | ||
| 443 | return response()->make($pdfContent, 200, [ | 442 | return response()->make($pdfContent, 200, [ |
| 444 | 'Content-Type' => 'application/octet-stream', | 443 | 'Content-Type' => 'application/octet-stream', |
| 445 | 'Content-Disposition' => 'attachment; filename="' . $pageSlug . '.pdf' | 444 | 'Content-Disposition' => 'attachment; filename="' . $pageSlug . '.pdf' | ... | ... |
| ... | @@ -313,11 +313,12 @@ class EntityRepo | ... | @@ -313,11 +313,12 @@ class EntityRepo |
| 313 | * Loads the book slug onto child elements to prevent access database access for getting the slug. | 313 | * Loads the book slug onto child elements to prevent access database access for getting the slug. |
| 314 | * @param Book $book | 314 | * @param Book $book |
| 315 | * @param bool $filterDrafts | 315 | * @param bool $filterDrafts |
| 316 | + * @param bool $renderPages | ||
| 316 | * @return mixed | 317 | * @return mixed |
| 317 | */ | 318 | */ |
| 318 | - public function getBookChildren(Book $book, $filterDrafts = false) | 319 | + public function getBookChildren(Book $book, $filterDrafts = false, $renderPages = false) |
| 319 | { | 320 | { |
| 320 | - $q = $this->permissionService->bookChildrenQuery($book->id, $filterDrafts)->get(); | 321 | + $q = $this->permissionService->bookChildrenQuery($book->id, $filterDrafts, $renderPages)->get(); |
| 321 | $entities = []; | 322 | $entities = []; |
| 322 | $parents = []; | 323 | $parents = []; |
| 323 | $tree = []; | 324 | $tree = []; |
| ... | @@ -325,6 +326,10 @@ class EntityRepo | ... | @@ -325,6 +326,10 @@ class EntityRepo |
| 325 | foreach ($q as $index => $rawEntity) { | 326 | foreach ($q as $index => $rawEntity) { |
| 326 | if ($rawEntity->entity_type === 'BookStack\\Page') { | 327 | if ($rawEntity->entity_type === 'BookStack\\Page') { |
| 327 | $entities[$index] = $this->page->newFromBuilder($rawEntity); | 328 | $entities[$index] = $this->page->newFromBuilder($rawEntity); |
| 329 | + if ($renderPages) { | ||
| 330 | + $entities[$index]->html = $rawEntity->description; | ||
| 331 | + $entities[$index]->html = $this->renderPage($entities[$index]); | ||
| 332 | + }; | ||
| 328 | } else if ($rawEntity->entity_type === 'BookStack\\Chapter') { | 333 | } else if ($rawEntity->entity_type === 'BookStack\\Chapter') { |
| 329 | $entities[$index] = $this->chapter->newFromBuilder($rawEntity); | 334 | $entities[$index] = $this->chapter->newFromBuilder($rawEntity); |
| 330 | $key = $entities[$index]->entity_type . ':' . $entities[$index]->id; | 335 | $key = $entities[$index]->entity_type . ':' . $entities[$index]->id; | ... | ... |
| 1 | <?php namespace BookStack\Services; | 1 | <?php namespace BookStack\Services; |
| 2 | 2 | ||
| 3 | +use BookStack\Book; | ||
| 3 | use BookStack\Page; | 4 | use BookStack\Page; |
| 4 | use BookStack\Repos\EntityRepo; | 5 | use BookStack\Repos\EntityRepo; |
| 5 | 6 | ||
| ... | @@ -25,24 +26,69 @@ class ExportService | ... | @@ -25,24 +26,69 @@ class ExportService |
| 25 | */ | 26 | */ |
| 26 | public function pageToContainedHtml(Page $page) | 27 | public function pageToContainedHtml(Page $page) |
| 27 | { | 28 | { |
| 28 | - $cssContent = file_get_contents(public_path('/css/export-styles.css')); | 29 | + $pageHtml = view('pages/export', [ |
| 29 | - $pageHtml = view('pages/export', ['page' => $page, 'pageContent' => $this->entityRepo->renderPage($page), 'css' => $cssContent])->render(); | 30 | + 'page' => $page, |
| 31 | + 'pageContent' => $this->entityRepo->renderPage($page) | ||
| 32 | + ])->render(); | ||
| 30 | return $this->containHtml($pageHtml); | 33 | return $this->containHtml($pageHtml); |
| 31 | } | 34 | } |
| 32 | 35 | ||
| 33 | /** | 36 | /** |
| 34 | - * Convert a page to a pdf file. | 37 | + * Convert a book to a self-contained HTML file. |
| 38 | + * @param Book $book | ||
| 39 | + * @return mixed|string | ||
| 40 | + */ | ||
| 41 | + public function bookToContainedHtml(Book $book) | ||
| 42 | + { | ||
| 43 | + $bookTree = $this->entityRepo->getBookChildren($book, true, true); | ||
| 44 | + $html = view('books/export', [ | ||
| 45 | + 'book' => $book, | ||
| 46 | + 'bookChildren' => $bookTree | ||
| 47 | + ])->render(); | ||
| 48 | + return $this->containHtml($html); | ||
| 49 | + } | ||
| 50 | + | ||
| 51 | + /** | ||
| 52 | + * Convert a page to a PDF file. | ||
| 35 | * @param Page $page | 53 | * @param Page $page |
| 36 | * @return mixed|string | 54 | * @return mixed|string |
| 37 | */ | 55 | */ |
| 38 | public function pageToPdf(Page $page) | 56 | public function pageToPdf(Page $page) |
| 39 | { | 57 | { |
| 40 | - $cssContent = file_get_contents(public_path('/css/export-styles.css')); | 58 | + $html = view('pages/pdf', [ |
| 41 | - $pageHtml = view('pages/pdf', ['page' => $page, 'pageContent' => $this->entityRepo->renderPage($page), 'css' => $cssContent])->render(); | 59 | + 'page' => $page, |
| 60 | + 'pageContent' => $this->entityRepo->renderPage($page) | ||
| 61 | + ])->render(); | ||
| 62 | + return $this->htmlToPdf($html); | ||
| 63 | + } | ||
| 64 | + | ||
| 65 | + /** | ||
| 66 | + * Convert a book to a PDF file | ||
| 67 | + * @param Book $book | ||
| 68 | + * @return string | ||
| 69 | + */ | ||
| 70 | + public function bookToPdf(Book $book) | ||
| 71 | + { | ||
| 72 | + $bookTree = $this->entityRepo->getBookChildren($book, true, true); | ||
| 73 | + $html = view('books/export', [ | ||
| 74 | + 'book' => $book, | ||
| 75 | + 'bookChildren' => $bookTree | ||
| 76 | + ])->render(); | ||
| 77 | + return $this->htmlToPdf($html); | ||
| 78 | + } | ||
| 79 | + | ||
| 80 | + /** | ||
| 81 | + * Convert normal webpage HTML to a PDF. | ||
| 82 | + * @param $html | ||
| 83 | + * @return string | ||
| 84 | + */ | ||
| 85 | + protected function htmlToPdf($html) | ||
| 86 | + { | ||
| 87 | + $containedHtml = $this->containHtml($html); | ||
| 42 | $useWKHTML = config('snappy.pdf.binary') !== false; | 88 | $useWKHTML = config('snappy.pdf.binary') !== false; |
| 43 | - $containedHtml = $this->containHtml($pageHtml); | ||
| 44 | if ($useWKHTML) { | 89 | if ($useWKHTML) { |
| 45 | $pdf = \SnappyPDF::loadHTML($containedHtml); | 90 | $pdf = \SnappyPDF::loadHTML($containedHtml); |
| 91 | + $pdf->setOption('print-media-type', true); | ||
| 46 | } else { | 92 | } else { |
| 47 | $pdf = \PDF::loadHTML($containedHtml); | 93 | $pdf = \PDF::loadHTML($containedHtml); |
| 48 | } | 94 | } |
| ... | @@ -122,6 +168,29 @@ class ExportService | ... | @@ -122,6 +168,29 @@ class ExportService |
| 122 | return $text; | 168 | return $text; |
| 123 | } | 169 | } |
| 124 | 170 | ||
| 171 | + /** | ||
| 172 | + * Convert a book into a plain text string. | ||
| 173 | + * @param Book $book | ||
| 174 | + * @return string | ||
| 175 | + */ | ||
| 176 | + public function bookToPlainText(Book $book) | ||
| 177 | + { | ||
| 178 | + $bookTree = $this->entityRepo->getBookChildren($book, true, true); | ||
| 179 | + $text = $book->name . "\n\n"; | ||
| 180 | + foreach ($bookTree as $bookChild) { | ||
| 181 | + if ($bookChild->isA('chapter')) { | ||
| 182 | + $text .= $bookChild->name . "\n\n"; | ||
| 183 | + $text .= $bookChild->description . "\n\n"; | ||
| 184 | + foreach ($bookChild->pages as $page) { | ||
| 185 | + $text .= $this->pageToPlainText($page); | ||
| 186 | + } | ||
| 187 | + } else { | ||
| 188 | + $text .= $this->pageToPlainText($bookChild); | ||
| 189 | + } | ||
| 190 | + } | ||
| 191 | + return $text; | ||
| 192 | + } | ||
| 193 | + | ||
| 125 | } | 194 | } |
| 126 | 195 | ||
| 127 | 196 | ... | ... |
| ... | @@ -474,11 +474,13 @@ class PermissionService | ... | @@ -474,11 +474,13 @@ class PermissionService |
| 474 | /** | 474 | /** |
| 475 | * Get the children of a book in an efficient single query, Filtered by the permission system. | 475 | * Get the children of a book in an efficient single query, Filtered by the permission system. |
| 476 | * @param integer $book_id | 476 | * @param integer $book_id |
| 477 | - * @param bool $filterDrafts | 477 | + * @param bool $filterDrafts |
| 478 | + * @param bool $fetchPageContent | ||
| 478 | * @return \Illuminate\Database\Query\Builder | 479 | * @return \Illuminate\Database\Query\Builder |
| 479 | */ | 480 | */ |
| 480 | - public function bookChildrenQuery($book_id, $filterDrafts = false) { | 481 | + public function bookChildrenQuery($book_id, $filterDrafts = false, $fetchPageContent = false) { |
| 481 | - $pageSelect = $this->db->table('pages')->selectRaw("'BookStack\\\\Page' as entity_type, id, slug, name, text, '' as description, book_id, priority, chapter_id, draft")->where('book_id', '=', $book_id)->where(function($query) use ($filterDrafts) { | 482 | + $pageContentSelect = $fetchPageContent ? 'html' : "''"; |
| 483 | + $pageSelect = $this->db->table('pages')->selectRaw("'BookStack\\\\Page' as entity_type, id, slug, name, text, {$pageContentSelect} as description, book_id, priority, chapter_id, draft")->where('book_id', '=', $book_id)->where(function($query) use ($filterDrafts) { | ||
| 482 | $query->where('draft', '=', 0); | 484 | $query->where('draft', '=', 0); |
| 483 | if (!$filterDrafts) { | 485 | if (!$filterDrafts) { |
| 484 | $query->orWhere(function($query) { | 486 | $query->orWhere(function($query) { | ... | ... |
| ... | @@ -143,7 +143,7 @@ return [ | ... | @@ -143,7 +143,7 @@ return [ |
| 143 | * the desired content might be different (e.g. screen or projection view of html file). | 143 | * the desired content might be different (e.g. screen or projection view of html file). |
| 144 | * Therefore allow specification of content here. | 144 | * Therefore allow specification of content here. |
| 145 | */ | 145 | */ |
| 146 | - "DOMPDF_DEFAULT_MEDIA_TYPE" => "screen", | 146 | + "DOMPDF_DEFAULT_MEDIA_TYPE" => "print", |
| 147 | 147 | ||
| 148 | /** | 148 | /** |
| 149 | * The default paper size. | 149 | * The default paper size. | ... | ... |
resources/views/books/export.blade.php
0 → 100644
| 1 | +<!doctype html> | ||
| 2 | +<html lang="en"> | ||
| 3 | +<head> | ||
| 4 | + <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> | ||
| 5 | + <title>{{ $book->name }}</title> | ||
| 6 | + | ||
| 7 | + <style> | ||
| 8 | + {!! file_get_contents(public_path('/css/export-styles.css')) !!} | ||
| 9 | + .page-break { | ||
| 10 | + page-break-after: always; | ||
| 11 | + } | ||
| 12 | + .chapter-hint { | ||
| 13 | + color: #888; | ||
| 14 | + margin-top: 32px; | ||
| 15 | + } | ||
| 16 | + .chapter-hint + h1 { | ||
| 17 | + margin-top: 0; | ||
| 18 | + } | ||
| 19 | + ul.contents ul li { | ||
| 20 | + list-style: circle; | ||
| 21 | + } | ||
| 22 | + @media screen { | ||
| 23 | + .page-break { | ||
| 24 | + border-top: 1px solid #DDD; | ||
| 25 | + } | ||
| 26 | + } | ||
| 27 | + </style> | ||
| 28 | + @yield('head') | ||
| 29 | +</head> | ||
| 30 | +<body> | ||
| 31 | +<div class="container"> | ||
| 32 | + <div class="row"> | ||
| 33 | + <div class="col-md-8 col-md-offset-2"> | ||
| 34 | + <div class="page-content"> | ||
| 35 | + | ||
| 36 | + <h1 style="font-size: 4.8em">{{$book->name}}</h1> | ||
| 37 | + | ||
| 38 | + <p>{{ $book->description }}</p> | ||
| 39 | + | ||
| 40 | + @if(count($bookChildren) > 0) | ||
| 41 | + <ul class="contents"> | ||
| 42 | + @foreach($bookChildren as $bookChild) | ||
| 43 | + <li><a href="#{{$bookChild->getType()}}-{{$bookChild->id}}">{{ $bookChild->name }}</a></li> | ||
| 44 | + @if($bookChild->isA('chapter') && count($bookChild->pages) > 0) | ||
| 45 | + <ul> | ||
| 46 | + @foreach($bookChild->pages as $page) | ||
| 47 | + <li><a href="#page-{{$page->id}}">{{ $page->name }}</a></li> | ||
| 48 | + @endforeach | ||
| 49 | + </ul> | ||
| 50 | + @endif | ||
| 51 | + @endforeach | ||
| 52 | + </ul> | ||
| 53 | + @endif | ||
| 54 | + | ||
| 55 | + @foreach($bookChildren as $bookChild) | ||
| 56 | + <div class="page-break"></div> | ||
| 57 | + <h1 id="{{$bookChild->getType()}}-{{$bookChild->id}}">{{ $bookChild->name }}</h1> | ||
| 58 | + @if($bookChild->isA('chapter')) | ||
| 59 | + <p>{{ $bookChild->description }}</p> | ||
| 60 | + @if(count($bookChild->pages) > 0) | ||
| 61 | + @foreach($bookChild->pages as $page) | ||
| 62 | + <div class="page-break"></div> | ||
| 63 | + <div class="chapter-hint">{{$bookChild->name}}</div> | ||
| 64 | + <h1 id="page-{{$page->id}}">{{ $page->name }}</h1> | ||
| 65 | + {!! $page->html !!} | ||
| 66 | + @endforeach | ||
| 67 | + @endif | ||
| 68 | + @else | ||
| 69 | + {!! $bookChild->html !!} | ||
| 70 | + @endif | ||
| 71 | + @endforeach | ||
| 72 | + | ||
| 73 | + </div> | ||
| 74 | + </div> | ||
| 75 | + </div> | ||
| 76 | +</div> | ||
| 77 | +</body> | ||
| 78 | +</html> |
| ... | @@ -10,6 +10,14 @@ | ... | @@ -10,6 +10,14 @@ |
| 10 | </div> | 10 | </div> |
| 11 | <div class="col-sm-6"> | 11 | <div class="col-sm-6"> |
| 12 | <div class="action-buttons faded"> | 12 | <div class="action-buttons faded"> |
| 13 | + <span dropdown class="dropdown-container"> | ||
| 14 | + <div dropdown-toggle class="text-button text-primary"><i class="zmdi zmdi-open-in-new"></i>{{ trans('entities.pages_export') }}</div> | ||
| 15 | + <ul class="wide"> | ||
| 16 | + <li><a href="{{ $book->getUrl('/export/html') }}" target="_blank">{{ trans('entities.pages_export_html') }} <span class="text-muted float right">.html</span></a></li> | ||
| 17 | + <li><a href="{{ $book->getUrl('/export/pdf') }}" target="_blank">{{ trans('entities.pages_export_pdf') }} <span class="text-muted float right">.pdf</span></a></li> | ||
| 18 | + <li><a href="{{ $book->getUrl('/export/plaintext') }}" target="_blank">{{ trans('entities.pages_export_text') }} <span class="text-muted float right">.txt</span></a></li> | ||
| 19 | + </ul> | ||
| 20 | + </span> | ||
| 13 | @if(userCan('page-create', $book)) | 21 | @if(userCan('page-create', $book)) |
| 14 | <a href="{{ $book->getUrl('/page/create') }}" class="text-pos text-button"><i class="zmdi zmdi-plus"></i>{{ trans('entities.pages_new') }}</a> | 22 | <a href="{{ $book->getUrl('/page/create') }}" class="text-pos text-button"><i class="zmdi zmdi-plus"></i>{{ trans('entities.pages_new') }}</a> |
| 15 | @endif | 23 | @endif | ... | ... |
| ... | @@ -5,7 +5,7 @@ | ... | @@ -5,7 +5,7 @@ |
| 5 | <title>{{ $page->name }}</title> | 5 | <title>{{ $page->name }}</title> |
| 6 | 6 | ||
| 7 | <style> | 7 | <style> |
| 8 | - {!! $css !!} | 8 | + {!! file_get_contents(public_path('/css/export-styles.css')) !!} |
| 9 | </style> | 9 | </style> |
| 10 | @yield('head') | 10 | @yield('head') |
| 11 | </head> | 11 | </head> | ... | ... |
| ... | @@ -26,6 +26,9 @@ Route::group(['middleware' => 'auth'], function () { | ... | @@ -26,6 +26,9 @@ Route::group(['middleware' => 'auth'], function () { |
| 26 | Route::get('/{slug}/delete', 'BookController@showDelete'); | 26 | Route::get('/{slug}/delete', 'BookController@showDelete'); |
| 27 | Route::get('/{bookSlug}/sort', 'BookController@sort'); | 27 | Route::get('/{bookSlug}/sort', 'BookController@sort'); |
| 28 | Route::put('/{bookSlug}/sort', 'BookController@saveSort'); | 28 | Route::put('/{bookSlug}/sort', 'BookController@saveSort'); |
| 29 | + Route::get('/{bookSlug}/export/html', 'BookController@exportHtml'); | ||
| 30 | + Route::get('/{bookSlug}/export/pdf', 'BookController@exportPdf'); | ||
| 31 | + Route::get('/{bookSlug}/export/plaintext', 'BookController@exportPlainText'); | ||
| 29 | 32 | ||
| 30 | // Pages | 33 | // Pages |
| 31 | Route::get('/{bookSlug}/page/create', 'PageController@create'); | 34 | Route::get('/{bookSlug}/page/create', 'PageController@create'); | ... | ... |
tests/Entity/ExportTest.php
0 → 100644
| 1 | +<?php namespace Tests; | ||
| 2 | + | ||
| 3 | + | ||
| 4 | +use BookStack\Page; | ||
| 5 | + | ||
| 6 | +class ExportTest extends TestCase | ||
| 7 | +{ | ||
| 8 | + | ||
| 9 | + public function test_page_text_export() | ||
| 10 | + { | ||
| 11 | + $page = Page::first(); | ||
| 12 | + $this->asEditor(); | ||
| 13 | + | ||
| 14 | + $resp = $this->get($page->getUrl('/export/plaintext')); | ||
| 15 | + $resp->assertStatus(200); | ||
| 16 | + $resp->assertSee($page->name); | ||
| 17 | + $resp->assertHeader('Content-Disposition', 'attachment; filename="' . $page->slug . '.txt'); | ||
| 18 | + } | ||
| 19 | + | ||
| 20 | + public function test_page_pdf_export() | ||
| 21 | + { | ||
| 22 | + $page = Page::first(); | ||
| 23 | + $this->asEditor(); | ||
| 24 | + | ||
| 25 | + $resp = $this->get($page->getUrl('/export/pdf')); | ||
| 26 | + $resp->assertStatus(200); | ||
| 27 | + $resp->assertHeader('Content-Disposition', 'attachment; filename="' . $page->slug . '.pdf'); | ||
| 28 | + } | ||
| 29 | + | ||
| 30 | + public function test_page_html_export() | ||
| 31 | + { | ||
| 32 | + $page = Page::first(); | ||
| 33 | + $this->asEditor(); | ||
| 34 | + | ||
| 35 | + $resp = $this->get($page->getUrl('/export/html')); | ||
| 36 | + $resp->assertStatus(200); | ||
| 37 | + $resp->assertSee($page->name); | ||
| 38 | + $resp->assertHeader('Content-Disposition', 'attachment; filename="' . $page->slug . '.html'); | ||
| 39 | + } | ||
| 40 | + | ||
| 41 | + public function test_book_text_export() | ||
| 42 | + { | ||
| 43 | + $page = Page::first(); | ||
| 44 | + $book = $page->book; | ||
| 45 | + $this->asEditor(); | ||
| 46 | + | ||
| 47 | + $resp = $this->get($book->getUrl('/export/plaintext')); | ||
| 48 | + $resp->assertStatus(200); | ||
| 49 | + $resp->assertSee($book->name); | ||
| 50 | + $resp->assertSee($page->name); | ||
| 51 | + $resp->assertHeader('Content-Disposition', 'attachment; filename="' . $book->slug . '.txt'); | ||
| 52 | + } | ||
| 53 | + | ||
| 54 | + public function test_book_pdf_export() | ||
| 55 | + { | ||
| 56 | + $page = Page::first(); | ||
| 57 | + $book = $page->book; | ||
| 58 | + $this->asEditor(); | ||
| 59 | + | ||
| 60 | + $resp = $this->get($book->getUrl('/export/pdf')); | ||
| 61 | + $resp->assertStatus(200); | ||
| 62 | + $resp->assertHeader('Content-Disposition', 'attachment; filename="' . $book->slug . '.pdf'); | ||
| 63 | + } | ||
| 64 | + | ||
| 65 | + public function test_book_html_export() | ||
| 66 | + { | ||
| 67 | + $page = Page::first(); | ||
| 68 | + $book = $page->book; | ||
| 69 | + $this->asEditor(); | ||
| 70 | + | ||
| 71 | + $resp = $this->get($book->getUrl('/export/html')); | ||
| 72 | + $resp->assertStatus(200); | ||
| 73 | + $resp->assertSee($book->name); | ||
| 74 | + $resp->assertSee($page->name); | ||
| 75 | + $resp->assertHeader('Content-Disposition', 'attachment; filename="' . $book->slug . '.html'); | ||
| 76 | + } | ||
| 77 | + | ||
| 78 | +} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
-
Please register or sign in to post a comment