mirror of
https://github.com/BookStackApp/BookStack.git
synced 2024-11-25 17:57:28 +08:00
Added ability to copy a page
In 'More' menu alongside move. Allows you to move if you have permission to create within the new target parent. Closes #673
This commit is contained in:
parent
d34b91f2c9
commit
0f7b0ad45a
|
@ -197,8 +197,8 @@ class Entity extends Ownable
|
|||
* @param $path
|
||||
* @return string
|
||||
*/
|
||||
public function getUrl($path)
|
||||
public function getUrl($path = '/')
|
||||
{
|
||||
return '/';
|
||||
return $path;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -592,12 +592,70 @@ class PageController extends Controller
|
|||
return redirect($page->getUrl());
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the view to copy a page.
|
||||
* @param string $bookSlug
|
||||
* @param string $pageSlug
|
||||
* @return mixed
|
||||
* @throws NotFoundException
|
||||
*/
|
||||
public function showCopy($bookSlug, $pageSlug)
|
||||
{
|
||||
$page = $this->entityRepo->getBySlug('page', $pageSlug, $bookSlug);
|
||||
$this->checkOwnablePermission('page-update', $page);
|
||||
session()->flashInput(['name' => $page->name]);
|
||||
return view('pages/copy', [
|
||||
'book' => $page->book,
|
||||
'page' => $page
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a copy of a page within the requested target destination.
|
||||
* @param string $bookSlug
|
||||
* @param string $pageSlug
|
||||
* @param Request $request
|
||||
* @return mixed
|
||||
* @throws NotFoundException
|
||||
*/
|
||||
public function copy($bookSlug, $pageSlug, Request $request)
|
||||
{
|
||||
$page = $this->entityRepo->getBySlug('page', $pageSlug, $bookSlug);
|
||||
$this->checkOwnablePermission('page-update', $page);
|
||||
|
||||
$entitySelection = $request->get('entity_selection', null);
|
||||
if ($entitySelection === null || $entitySelection === '') {
|
||||
$parent = $page->chapter ? $page->chapter : $page->book;
|
||||
} else {
|
||||
$stringExploded = explode(':', $entitySelection);
|
||||
$entityType = $stringExploded[0];
|
||||
$entityId = intval($stringExploded[1]);
|
||||
|
||||
try {
|
||||
$parent = $this->entityRepo->getById($entityType, $entityId);
|
||||
} catch (\Exception $e) {
|
||||
session()->flash(trans('entities.selected_book_chapter_not_found'));
|
||||
return redirect()->back();
|
||||
}
|
||||
}
|
||||
|
||||
$this->checkOwnablePermission('page-create', $parent);
|
||||
|
||||
$pageCopy = $this->entityRepo->copyPage($page, $parent, $request->get('name', ''));
|
||||
|
||||
Activity::add($pageCopy, 'page_create', $pageCopy->book->id);
|
||||
session()->flash('success', trans('entities.pages_copy_success'));
|
||||
|
||||
return redirect($pageCopy->getUrl());
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the permissions for this page.
|
||||
* @param string $bookSlug
|
||||
* @param string $pageSlug
|
||||
* @param Request $request
|
||||
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
|
||||
* @throws NotFoundException
|
||||
*/
|
||||
public function restrict($bookSlug, $pageSlug, Request $request)
|
||||
{
|
||||
|
|
|
@ -89,16 +89,17 @@ class SearchController extends Controller
|
|||
{
|
||||
$entityTypes = $request->filled('types') ? collect(explode(',', $request->get('types'))) : collect(['page', 'chapter', 'book']);
|
||||
$searchTerm = $request->get('term', false);
|
||||
$permission = $request->get('permission', 'view');
|
||||
|
||||
// Search for entities otherwise show most popular
|
||||
if ($searchTerm !== false) {
|
||||
$searchTerm .= ' {type:'. implode('|', $entityTypes->toArray()) .'}';
|
||||
$entities = $this->searchService->searchEntities($searchTerm)['results'];
|
||||
$entities = $this->searchService->searchEntities($searchTerm, 'all', 1, 20, $permission)['results'];
|
||||
} else {
|
||||
$entityNames = $entityTypes->map(function ($type) {
|
||||
return 'BookStack\\' . ucfirst($type);
|
||||
})->toArray();
|
||||
$entities = $this->viewService->getPopular(20, 0, $entityNames);
|
||||
$entities = $this->viewService->getPopular(20, 0, $entityNames, $permission);
|
||||
}
|
||||
|
||||
return view('search/entity-ajax-list', ['entities' => $entities]);
|
||||
|
|
|
@ -593,6 +593,30 @@ class EntityRepo
|
|||
return $slug;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a new draft page instance.
|
||||
* @param Book $book
|
||||
* @param Chapter|bool $chapter
|
||||
* @return Page
|
||||
*/
|
||||
public function getDraftPage(Book $book, $chapter = false)
|
||||
{
|
||||
$page = $this->page->newInstance();
|
||||
$page->name = trans('entities.pages_initial_name');
|
||||
$page->created_by = user()->id;
|
||||
$page->updated_by = user()->id;
|
||||
$page->draft = true;
|
||||
|
||||
if ($chapter) {
|
||||
$page->chapter_id = $chapter->id;
|
||||
}
|
||||
|
||||
$book->pages()->save($page);
|
||||
$page = $this->page->find($page->id);
|
||||
$this->permissionService->buildJointPermissionsForEntity($page);
|
||||
return $page;
|
||||
}
|
||||
|
||||
/**
|
||||
* Publish a draft page to make it a normal page.
|
||||
* Sets the slug and updates the content.
|
||||
|
@ -621,6 +645,43 @@ class EntityRepo
|
|||
return $draftPage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a copy of a page in a new location with a new name.
|
||||
* @param Page $page
|
||||
* @param Entity $newParent
|
||||
* @param string $newName
|
||||
* @return Page
|
||||
*/
|
||||
public function copyPage(Page $page, Entity $newParent, $newName = '')
|
||||
{
|
||||
$newBook = $newParent->isA('book') ? $newParent : $newParent->book;
|
||||
$newChapter = $newParent->isA('chapter') ? $newParent : null;
|
||||
$copyPage = $this->getDraftPage($newBook, $newChapter);
|
||||
$pageData = $page->getAttributes();
|
||||
|
||||
// Update name
|
||||
if (!empty($newName)) {
|
||||
$pageData['name'] = $newName;
|
||||
}
|
||||
|
||||
// Copy tags from previous page if set
|
||||
if ($page->tags) {
|
||||
$pageData['tags'] = [];
|
||||
foreach ($page->tags as $tag) {
|
||||
$pageData['tags'][] = ['name' => $tag->name, 'value' => $tag->value];
|
||||
}
|
||||
}
|
||||
|
||||
// Set priority
|
||||
if ($newParent->isA('chapter')) {
|
||||
$pageData['priority'] = $this->getNewChapterPriority($newParent);
|
||||
} else {
|
||||
$pageData['priority'] = $this->getNewBookPriority($newParent);
|
||||
}
|
||||
|
||||
return $this->publishPageDraft($copyPage, $pageData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves a page revision into the system.
|
||||
* @param Page $page
|
||||
|
@ -805,30 +866,6 @@ class EntityRepo
|
|||
return strip_tags($html);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a new draft page instance.
|
||||
* @param Book $book
|
||||
* @param Chapter|bool $chapter
|
||||
* @return Page
|
||||
*/
|
||||
public function getDraftPage(Book $book, $chapter = false)
|
||||
{
|
||||
$page = $this->page->newInstance();
|
||||
$page->name = trans('entities.pages_initial_name');
|
||||
$page->created_by = user()->id;
|
||||
$page->updated_by = user()->id;
|
||||
$page->draft = true;
|
||||
|
||||
if ($chapter) {
|
||||
$page->chapter_id = $chapter->id;
|
||||
}
|
||||
|
||||
$book->pages()->save($page);
|
||||
$page = $this->page->find($page->id);
|
||||
$this->permissionService->buildJointPermissionsForEntity($page);
|
||||
return $page;
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for image usage within page content.
|
||||
* @param $imageString
|
||||
|
|
|
@ -630,16 +630,17 @@ class PermissionService
|
|||
* @param string $tableName
|
||||
* @param string $entityIdColumn
|
||||
* @param string $entityTypeColumn
|
||||
* @param string $action
|
||||
* @return mixed
|
||||
*/
|
||||
public function filterRestrictedEntityRelations($query, $tableName, $entityIdColumn, $entityTypeColumn)
|
||||
public function filterRestrictedEntityRelations($query, $tableName, $entityIdColumn, $entityTypeColumn, $action = 'view')
|
||||
{
|
||||
if ($this->isAdmin()) {
|
||||
$this->clean();
|
||||
return $query;
|
||||
}
|
||||
|
||||
$this->currentAction = 'view';
|
||||
$this->currentAction = $action;
|
||||
$tableDetails = ['tableName' => $tableName, 'entityIdColumn' => $entityIdColumn, 'entityTypeColumn' => $entityTypeColumn];
|
||||
|
||||
$q = $query->where(function ($query) use ($tableDetails) {
|
||||
|
|
|
@ -67,7 +67,7 @@ class SearchService
|
|||
* @param int $count - Count of each entity to search, Total returned could can be larger and not guaranteed.
|
||||
* @return array[int, Collection];
|
||||
*/
|
||||
public function searchEntities($searchString, $entityType = 'all', $page = 1, $count = 20)
|
||||
public function searchEntities($searchString, $entityType = 'all', $page = 1, $count = 20, $action = 'view')
|
||||
{
|
||||
$terms = $this->parseSearchString($searchString);
|
||||
$entityTypes = array_keys($this->entities);
|
||||
|
@ -87,8 +87,8 @@ class SearchService
|
|||
if (!in_array($entityType, $entityTypes)) {
|
||||
continue;
|
||||
}
|
||||
$search = $this->searchEntityTable($terms, $entityType, $page, $count);
|
||||
$entityTotal = $this->searchEntityTable($terms, $entityType, $page, $count, true);
|
||||
$search = $this->searchEntityTable($terms, $entityType, $page, $count, $action);
|
||||
$entityTotal = $this->searchEntityTable($terms, $entityType, $page, $count, $action, true);
|
||||
if ($entityTotal > $page * $count) {
|
||||
$hasMore = true;
|
||||
}
|
||||
|
@ -147,12 +147,13 @@ class SearchService
|
|||
* @param string $entityType
|
||||
* @param int $page
|
||||
* @param int $count
|
||||
* @param string $action
|
||||
* @param bool $getCount Return the total count of the search
|
||||
* @return \Illuminate\Database\Eloquent\Collection|int|static[]
|
||||
*/
|
||||
public function searchEntityTable($terms, $entityType = 'page', $page = 1, $count = 20, $getCount = false)
|
||||
public function searchEntityTable($terms, $entityType = 'page', $page = 1, $count = 20, $action = 'view', $getCount = false)
|
||||
{
|
||||
$query = $this->buildEntitySearchQuery($terms, $entityType);
|
||||
$query = $this->buildEntitySearchQuery($terms, $entityType, $action);
|
||||
if ($getCount) {
|
||||
return $query->count();
|
||||
}
|
||||
|
@ -165,9 +166,10 @@ class SearchService
|
|||
* Create a search query for an entity
|
||||
* @param array $terms
|
||||
* @param string $entityType
|
||||
* @param string $action
|
||||
* @return \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
protected function buildEntitySearchQuery($terms, $entityType = 'page')
|
||||
protected function buildEntitySearchQuery($terms, $entityType = 'page', $action = 'view')
|
||||
{
|
||||
$entity = $this->getEntity($entityType);
|
||||
$entitySelect = $entity->newQuery();
|
||||
|
@ -212,7 +214,7 @@ class SearchService
|
|||
}
|
||||
}
|
||||
|
||||
return $this->permissionService->enforceEntityRestrictions($entityType, $entitySelect, 'view');
|
||||
return $this->permissionService->enforceEntityRestrictions($entityType, $entitySelect, $action);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -51,11 +51,13 @@ class ViewService
|
|||
* @param int $count
|
||||
* @param int $page
|
||||
* @param bool|false|array $filterModel
|
||||
* @param string $action - used for permission checking
|
||||
* @return
|
||||
*/
|
||||
public function getPopular($count = 10, $page = 0, $filterModel = false)
|
||||
public function getPopular($count = 10, $page = 0, $filterModel = false, $action = 'view')
|
||||
{
|
||||
$skipCount = $count * $page;
|
||||
$query = $this->permissionService->filterRestrictedEntityRelations($this->view, 'views', 'viewable_id', 'viewable_type')
|
||||
$query = $this->permissionService->filterRestrictedEntityRelations($this->view, 'views', 'viewable_id', 'viewable_type', $action)
|
||||
->select('*', 'viewable_id', 'viewable_type', \DB::raw('SUM(views) as view_count'))
|
||||
->groupBy('viewable_id', 'viewable_type')
|
||||
->orderBy('view_count', 'desc');
|
||||
|
|
5
package-lock.json
generated
5
package-lock.json
generated
|
@ -6825,11 +6825,6 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"moment": {
|
||||
"version": "2.21.0",
|
||||
"resolved": "https://registry.npmjs.org/moment/-/moment-2.21.0.tgz",
|
||||
"integrity": "sha512-TCZ36BjURTeFTM/CwRcViQlfkMvL1/vFISuNLO5GkcVm1+QHfbSiNqZuWeMFjj1/3+uAjXswgRk30j1kkLYJBQ=="
|
||||
},
|
||||
"move-concurrently": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz",
|
||||
|
|
|
@ -7,7 +7,8 @@ class EntitySelector {
|
|||
this.lastClick = 0;
|
||||
|
||||
let entityTypes = elem.hasAttribute('entity-types') ? elem.getAttribute('entity-types') : 'page,book,chapter';
|
||||
this.searchUrl = window.baseUrl(`/ajax/search/entities?types=${encodeURIComponent(entityTypes)}`);
|
||||
let entityPermission = elem.hasAttribute('entity-permission') ? elem.getAttribute('entity-permission') : 'view';
|
||||
this.searchUrl = window.baseUrl(`/ajax/search/entities?types=${encodeURIComponent(entityTypes)}&permission=${encodeURIComponent(entityPermission)}`);
|
||||
|
||||
this.input = elem.querySelector('[entity-selector-input]');
|
||||
this.searchInput = elem.querySelector('[entity-selector-search]');
|
||||
|
@ -68,7 +69,6 @@ class EntitySelector {
|
|||
|
||||
onClick(event) {
|
||||
let t = event.target;
|
||||
console.log('click', t);
|
||||
|
||||
if (t.matches('.entity-list-item *')) {
|
||||
event.preventDefault();
|
||||
|
|
|
@ -31,6 +31,7 @@ return [
|
|||
'edit' => 'Edit',
|
||||
'sort' => 'Sort',
|
||||
'move' => 'Move',
|
||||
'copy' => 'Copy',
|
||||
'reply' => 'Reply',
|
||||
'delete' => 'Delete',
|
||||
'search' => 'Search',
|
||||
|
|
|
@ -166,6 +166,9 @@ return [
|
|||
'pages_not_in_chapter' => 'Page is not in a chapter',
|
||||
'pages_move' => 'Move Page',
|
||||
'pages_move_success' => 'Page moved to ":parentName"',
|
||||
'pages_copy' => 'Copy Page',
|
||||
'pages_copy_desination' => 'Copy Destination',
|
||||
'pages_copy_success' => 'Page successfully copied',
|
||||
'pages_permissions' => 'Page Permissions',
|
||||
'pages_permissions_success' => 'Page permissions updated',
|
||||
'pages_revision' => 'Revision',
|
||||
|
|
|
@ -30,9 +30,9 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group" collapsible id="logo-control">
|
||||
<div class="form-group" collapsible id="tags-control">
|
||||
<div class="collapse-title text-primary" collapsible-trigger>
|
||||
<label for="user-avatar">{{ trans('entities.book_tags') }}</label>
|
||||
<label for="tag-manager">{{ trans('entities.book_tags') }}</label>
|
||||
</div>
|
||||
<div class="collapse-content" collapsible-content>
|
||||
@include('components.tag-manager', ['entity' => isset($book)?$book:null, 'entityType' => 'chapter'])
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<div class="form-group">
|
||||
<div entity-selector class="entity-selector {{$selectorSize or ''}}" entity-types="{{ $entityTypes or 'book,chapter,page' }}">
|
||||
<div entity-selector class="entity-selector {{$selectorSize or ''}}" entity-types="{{ $entityTypes or 'book,chapter,page' }}" entity-permission="{{ $entityPermission or 'view' }}">
|
||||
<input type="hidden" entity-selector-input name="{{$name}}" value="">
|
||||
<input type="text" placeholder="{{ trans('common.search') }}" entity-selector-search>
|
||||
<div class="text-center loading" entity-selector-loading>@include('partials.loading-icon')</div>
|
||||
|
|
43
resources/views/pages/copy.blade.php
Normal file
43
resources/views/pages/copy.blade.php
Normal file
|
@ -0,0 +1,43 @@
|
|||
@extends('simple-layout')
|
||||
|
||||
@section('toolbar')
|
||||
<div class="col-sm-12 faded">
|
||||
@include('pages._breadcrumbs', ['page' => $page])
|
||||
</div>
|
||||
@stop
|
||||
|
||||
@section('body')
|
||||
|
||||
<div class="container small">
|
||||
<p> </p>
|
||||
<div class="card">
|
||||
<h3>@icon('copy') {{ trans('entities.pages_copy') }}</h3>
|
||||
<div class="body">
|
||||
<form action="{{ $page->getUrl('/copy') }}" method="POST">
|
||||
{!! csrf_field() !!}
|
||||
|
||||
<div class="form-group title-input">
|
||||
<label for="name">{{ trans('common.name') }}</label>
|
||||
@include('form/text', ['name' => 'name'])
|
||||
</div>
|
||||
|
||||
<div class="form-group" collapsible>
|
||||
<div class="collapse-title text-primary" collapsible-trigger>
|
||||
<label for="entity_selection">{{ trans('entities.pages_copy_desination') }}</label>
|
||||
</div>
|
||||
<div class="collapse-content" collapsible-content>
|
||||
@include('components.entity-selector', ['name' => 'entity_selection', 'selectorSize' => 'large', 'entityTypes' => 'book,chapter', 'entityPermission' => 'page-create'])
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="form-group text-right">
|
||||
<a href="{{ $page->getUrl() }}" class="button outline">{{ trans('common.cancel') }}</a>
|
||||
<button type="submit" class="button pos">{{ trans('entities.pages_copy') }}</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@stop
|
|
@ -22,6 +22,7 @@
|
|||
<a dropdown-toggle class="text-primary text-button">@icon('more') {{ trans('common.more') }}</a>
|
||||
<ul>
|
||||
@if(userCan('page-update', $page))
|
||||
<li><a href="{{ $page->getUrl('/copy') }}" class="text-primary" >@icon('copy'){{ trans('common.copy') }}</a></li>
|
||||
<li><a href="{{ $page->getUrl('/move') }}" class="text-primary" >@icon('folder'){{ trans('common.move') }}</a></li>
|
||||
<li><a href="{{ $page->getUrl('/revisions') }}" class="text-primary">@icon('history'){{ trans('entities.revisions') }}</a></li>
|
||||
@endif
|
||||
|
|
|
@ -47,6 +47,8 @@ Route::group(['middleware' => 'auth'], function () {
|
|||
Route::get('/{bookSlug}/page/{pageSlug}/edit', 'PageController@edit');
|
||||
Route::get('/{bookSlug}/page/{pageSlug}/move', 'PageController@showMove');
|
||||
Route::put('/{bookSlug}/page/{pageSlug}/move', 'PageController@move');
|
||||
Route::get('/{bookSlug}/page/{pageSlug}/copy', 'PageController@showCopy');
|
||||
Route::post('/{bookSlug}/page/{pageSlug}/copy', 'PageController@copy');
|
||||
Route::get('/{bookSlug}/page/{pageSlug}/delete', 'PageController@showDelete');
|
||||
Route::get('/{bookSlug}/draft/{pageId}/delete', 'PageController@showDeleteDraft');
|
||||
Route::get('/{bookSlug}/page/{pageSlug}/permissions', 'PageController@showRestrict');
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<?php namespace Tests;
|
||||
|
||||
use BookStack\Book;
|
||||
use BookStack\Chapter;
|
||||
use BookStack\Page;
|
||||
use BookStack\Repos\EntityRepo;
|
||||
|
||||
|
@ -11,7 +12,7 @@ class SortTest extends TestCase
|
|||
public function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
$this->book = \BookStack\Book::first();
|
||||
$this->book = Book::first();
|
||||
}
|
||||
|
||||
public function test_drafts_do_not_show_up()
|
||||
|
@ -29,9 +30,9 @@ class SortTest extends TestCase
|
|||
|
||||
public function test_page_move()
|
||||
{
|
||||
$page = \BookStack\Page::first();
|
||||
$page = Page::first();
|
||||
$currentBook = $page->book;
|
||||
$newBook = \BookStack\Book::where('id', '!=', $currentBook->id)->first();
|
||||
$newBook = Book::where('id', '!=', $currentBook->id)->first();
|
||||
|
||||
$resp = $this->asAdmin()->get($page->getUrl() . '/move');
|
||||
$resp->assertSee('Move Page');
|
||||
|
@ -39,7 +40,7 @@ class SortTest extends TestCase
|
|||
$movePageResp = $this->put($page->getUrl() . '/move', [
|
||||
'entity_selection' => 'book:' . $newBook->id
|
||||
]);
|
||||
$page = \BookStack\Page::find($page->id);
|
||||
$page = Page::find($page->id);
|
||||
|
||||
$movePageResp->assertRedirect($page->getUrl());
|
||||
$this->assertTrue($page->book->id == $newBook->id, 'Page book is now the new book');
|
||||
|
@ -51,10 +52,10 @@ class SortTest extends TestCase
|
|||
|
||||
public function test_chapter_move()
|
||||
{
|
||||
$chapter = \BookStack\Chapter::first();
|
||||
$chapter = Chapter::first();
|
||||
$currentBook = $chapter->book;
|
||||
$pageToCheck = $chapter->pages->first();
|
||||
$newBook = \BookStack\Book::where('id', '!=', $currentBook->id)->first();
|
||||
$newBook = Book::where('id', '!=', $currentBook->id)->first();
|
||||
|
||||
$chapterMoveResp = $this->asAdmin()->get($chapter->getUrl() . '/move');
|
||||
$chapterMoveResp->assertSee('Move Chapter');
|
||||
|
@ -63,7 +64,7 @@ class SortTest extends TestCase
|
|||
'entity_selection' => 'book:' . $newBook->id
|
||||
]);
|
||||
|
||||
$chapter = \BookStack\Chapter::find($chapter->id);
|
||||
$chapter = Chapter::find($chapter->id);
|
||||
$moveChapterResp->assertRedirect($chapter->getUrl());
|
||||
$this->assertTrue($chapter->book->id === $newBook->id, 'Chapter Book is now the new book');
|
||||
|
||||
|
@ -71,7 +72,7 @@ class SortTest extends TestCase
|
|||
$newBookResp->assertSee('moved chapter');
|
||||
$newBookResp->assertSee($chapter->name);
|
||||
|
||||
$pageToCheck = \BookStack\Page::find($pageToCheck->id);
|
||||
$pageToCheck = Page::find($pageToCheck->id);
|
||||
$this->assertTrue($pageToCheck->book_id === $newBook->id, 'Chapter child page\'s book id has changed to the new book');
|
||||
$pageCheckResp = $this->get($pageToCheck->getUrl());
|
||||
$pageCheckResp->assertSee($newBook->name);
|
||||
|
@ -120,4 +121,43 @@ class SortTest extends TestCase
|
|||
$checkResp->assertSee($newBook->name);
|
||||
}
|
||||
|
||||
public function test_page_copy()
|
||||
{
|
||||
$page = Page::first();
|
||||
$currentBook = $page->book;
|
||||
$newBook = Book::where('id', '!=', $currentBook->id)->first();
|
||||
|
||||
$resp = $this->asEditor()->get($page->getUrl('/copy'));
|
||||
$resp->assertSee('Copy Page');
|
||||
|
||||
$movePageResp = $this->post($page->getUrl('/copy'), [
|
||||
'entity_selection' => 'book:' . $newBook->id,
|
||||
'name' => 'My copied test page'
|
||||
]);
|
||||
|
||||
$pageCopy = Page::where('name', '=', 'My copied test page')->first();
|
||||
|
||||
$movePageResp->assertRedirect($pageCopy->getUrl());
|
||||
$this->assertTrue($pageCopy->book->id == $newBook->id, 'Page was copied to correct book');
|
||||
}
|
||||
|
||||
public function test_page_copy_with_no_destination()
|
||||
{
|
||||
$page = Page::first();
|
||||
$currentBook = $page->book;
|
||||
|
||||
$resp = $this->asEditor()->get($page->getUrl('/copy'));
|
||||
$resp->assertSee('Copy Page');
|
||||
|
||||
$movePageResp = $this->post($page->getUrl('/copy'), [
|
||||
'name' => 'My copied test page'
|
||||
]);
|
||||
|
||||
$pageCopy = Page::where('name', '=', 'My copied test page')->first();
|
||||
|
||||
$movePageResp->assertRedirect($pageCopy->getUrl());
|
||||
$this->assertTrue($pageCopy->book->id == $currentBook->id, 'Page was copied to correct book');
|
||||
$this->assertTrue($pageCopy->id !== $page->id, 'Page copy is not the same instance');
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user