mirror of
https://github.com/BookStackApp/BookStack.git
synced 2024-10-01 01:36:00 -04:00
Added testing coverage for Bookshelves
Created modified TestResponse so we can use DOM operations in new Testcases as we move away from the BrowserKit tests.
This commit is contained in:
parent
8ff969dd17
commit
b59e5942c8
@ -1288,6 +1288,7 @@ class EntityRepo
|
||||
* Returns the number of books that had permissions updated.
|
||||
* @param Bookshelf $bookshelf
|
||||
* @return int
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function copyBookshelfPermissions(Bookshelf $bookshelf)
|
||||
{
|
||||
|
@ -49,6 +49,7 @@ return [
|
||||
|
||||
// Entities
|
||||
'entity_not_found' => 'Entity not found',
|
||||
'bookshelf_not_found' => 'Bookshelf not found',
|
||||
'book_not_found' => 'Book not found',
|
||||
'page_not_found' => 'Page not found',
|
||||
'chapter_not_found' => 'Chapter not found',
|
||||
|
170
tests/Entity/BookShelfTest.php
Normal file
170
tests/Entity/BookShelfTest.php
Normal file
@ -0,0 +1,170 @@
|
||||
<?php namespace Tests;
|
||||
|
||||
use BookStack\Book;
|
||||
use BookStack\Bookshelf;
|
||||
|
||||
class BookShelfTest extends TestCase
|
||||
{
|
||||
|
||||
public function test_shelves_shows_in_header_if_have_view_permissions()
|
||||
{
|
||||
$viewer = $this->getViewer();
|
||||
$resp = $this->actingAs($viewer)->get('/');
|
||||
$resp->assertElementContains('header', 'Shelves');
|
||||
|
||||
$viewer->roles()->delete();
|
||||
$this->giveUserPermissions($viewer);
|
||||
$resp = $this->actingAs($viewer)->get('/');
|
||||
$resp->assertElementNotContains('header', 'Shelves');
|
||||
|
||||
$this->giveUserPermissions($viewer, ['bookshelf-view-all']);
|
||||
$resp = $this->actingAs($viewer)->get('/');
|
||||
$resp->assertElementContains('header', 'Shelves');
|
||||
|
||||
$viewer->roles()->delete();
|
||||
$this->giveUserPermissions($viewer, ['bookshelf-view-own']);
|
||||
$resp = $this->actingAs($viewer)->get('/');
|
||||
$resp->assertElementContains('header', 'Shelves');
|
||||
}
|
||||
|
||||
public function test_shelves_page_contains_create_link()
|
||||
{
|
||||
$resp = $this->asEditor()->get('/shelves');
|
||||
$resp->assertElementContains('a', 'Create New Shelf');
|
||||
}
|
||||
|
||||
public function test_shelves_create()
|
||||
{
|
||||
$booksToInclude = Book::take(2)->get();
|
||||
$shelfInfo = [
|
||||
'name' => 'My test book' . str_random(4),
|
||||
'description' => 'Test book description ' . str_random(10)
|
||||
];
|
||||
$resp = $this->asEditor()->post('/shelves', array_merge($shelfInfo, [
|
||||
'books' => $booksToInclude->implode('id', ','),
|
||||
'tags' => [
|
||||
[
|
||||
'name' => 'Test Category',
|
||||
'value' => 'Test Tag Value',
|
||||
]
|
||||
],
|
||||
]));
|
||||
$resp->assertRedirect();
|
||||
$editorId = $this->getEditor()->id;
|
||||
$this->assertDatabaseHas('bookshelves', array_merge($shelfInfo, ['created_by' => $editorId, 'updated_by' => $editorId]));
|
||||
|
||||
$shelf = Bookshelf::where('name', '=', $shelfInfo['name'])->first();
|
||||
$shelfPage = $this->get($shelf->getUrl());
|
||||
$shelfPage->assertSee($shelfInfo['name']);
|
||||
$shelfPage->assertSee($shelfInfo['description']);
|
||||
$shelfPage->assertElementContains('.tag-item', 'Test Category');
|
||||
$shelfPage->assertElementContains('.tag-item', 'Test Tag Value');
|
||||
|
||||
$this->assertDatabaseHas('bookshelves_books', ['bookshelf_id' => $shelf->id, 'book_id' => $booksToInclude[0]->id]);
|
||||
$this->assertDatabaseHas('bookshelves_books', ['bookshelf_id' => $shelf->id, 'book_id' => $booksToInclude[1]->id]);
|
||||
}
|
||||
|
||||
public function test_shelf_view()
|
||||
{
|
||||
$shelf = Bookshelf::first();
|
||||
$resp = $this->asEditor()->get($shelf->getUrl());
|
||||
$resp->assertStatus(200);
|
||||
$resp->assertSeeText($shelf->name);
|
||||
$resp->assertSeeText($shelf->description);
|
||||
|
||||
foreach ($shelf->books as $book) {
|
||||
$resp->assertSee($book->name);
|
||||
}
|
||||
}
|
||||
|
||||
public function test_shelf_view_shows_action_buttons()
|
||||
{
|
||||
$shelf = Bookshelf::first();
|
||||
$resp = $this->asAdmin()->get($shelf->getUrl());
|
||||
$resp->assertSee($shelf->getUrl('/edit'));
|
||||
$resp->assertSee($shelf->getUrl('/permissions'));
|
||||
$resp->assertSee($shelf->getUrl('/delete'));
|
||||
$resp->assertElementContains('a', 'Edit');
|
||||
$resp->assertElementContains('a', 'Permissions');
|
||||
$resp->assertElementContains('a', 'Delete');
|
||||
|
||||
$resp = $this->asEditor()->get($shelf->getUrl());
|
||||
$resp->assertDontSee($shelf->getUrl('/permissions'));
|
||||
}
|
||||
|
||||
public function test_shelf_edit()
|
||||
{
|
||||
$shelf = Bookshelf::first();
|
||||
$resp = $this->asEditor()->get($shelf->getUrl('/edit'));
|
||||
$resp->assertSeeText('Edit Bookshelf');
|
||||
|
||||
$booksToInclude = Book::take(2)->get();
|
||||
$shelfInfo = [
|
||||
'name' => 'My test book' . str_random(4),
|
||||
'description' => 'Test book description ' . str_random(10)
|
||||
];
|
||||
|
||||
$resp = $this->asEditor()->put($shelf->getUrl(), array_merge($shelfInfo, [
|
||||
'books' => $booksToInclude->implode('id', ','),
|
||||
'tags' => [
|
||||
[
|
||||
'name' => 'Test Category',
|
||||
'value' => 'Test Tag Value',
|
||||
]
|
||||
],
|
||||
]));
|
||||
$shelf = Bookshelf::find($shelf->id);
|
||||
$resp->assertRedirect($shelf->getUrl());
|
||||
$this->assertSessionHas('success');
|
||||
|
||||
$editorId = $this->getEditor()->id;
|
||||
$this->assertDatabaseHas('bookshelves', array_merge($shelfInfo, ['id' => $shelf->id, 'created_by' => $editorId, 'updated_by' => $editorId]));
|
||||
|
||||
$shelfPage = $this->get($shelf->getUrl());
|
||||
$shelfPage->assertSee($shelfInfo['name']);
|
||||
$shelfPage->assertSee($shelfInfo['description']);
|
||||
$shelfPage->assertElementContains('.tag-item', 'Test Category');
|
||||
$shelfPage->assertElementContains('.tag-item', 'Test Tag Value');
|
||||
|
||||
$this->assertDatabaseHas('bookshelves_books', ['bookshelf_id' => $shelf->id, 'book_id' => $booksToInclude[0]->id]);
|
||||
$this->assertDatabaseHas('bookshelves_books', ['bookshelf_id' => $shelf->id, 'book_id' => $booksToInclude[1]->id]);
|
||||
}
|
||||
|
||||
public function test_shelf_delete()
|
||||
{
|
||||
$shelf = Bookshelf::first();
|
||||
$resp = $this->asEditor()->get($shelf->getUrl('/delete'));
|
||||
$resp->assertSeeText('Delete Bookshelf');
|
||||
$resp->assertSee("action=\"{$shelf->getUrl()}\"");
|
||||
|
||||
$resp = $this->delete($shelf->getUrl());
|
||||
$resp->assertRedirect('/shelves');
|
||||
$this->assertDatabaseMissing('bookshelves', ['id' => $shelf->id]);
|
||||
$this->assertDatabaseMissing('bookshelves_books', ['bookshelf_id' => $shelf->id]);
|
||||
$this->assertSessionHas('success');
|
||||
}
|
||||
|
||||
public function test_shelf_copy_permissions()
|
||||
{
|
||||
$shelf = Bookshelf::first();
|
||||
$resp = $this->asAdmin()->get($shelf->getUrl('/permissions'));
|
||||
$resp->assertSeeText('Copy Permissions');
|
||||
$resp->assertSee("action=\"{$shelf->getUrl('/copy-permissions')}\"");
|
||||
|
||||
$child = $shelf->books()->first();
|
||||
$editorRole = $this->getEditor()->roles()->first();
|
||||
$this->assertFalse(boolval($child->restricted), "Child book should not be restricted by default");
|
||||
$this->assertTrue($child->permissions()->count() === 0, "Child book should have no permissions by default");
|
||||
|
||||
$this->setEntityRestrictions($shelf, ['view', 'update'], [$editorRole]);
|
||||
$resp = $this->post($shelf->getUrl('/copy-permissions'));
|
||||
$child = $shelf->books()->first();
|
||||
|
||||
$resp->assertRedirect($shelf->getUrl());
|
||||
$this->assertTrue(boolval($child->restricted), "Child book should now be restricted");
|
||||
$this->assertTrue($child->permissions()->count() === 2, "Child book should have copied permissions");
|
||||
$this->assertDatabaseHas('entity_permissions', ['restrictable_id' => $child->id, 'action' => 'view', 'role_id' => $editorRole->id]);
|
||||
$this->assertDatabaseHas('entity_permissions', ['restrictable_id' => $child->id, 'action' => 'update', 'role_id' => $editorRole->id]);
|
||||
}
|
||||
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
<?php namespace Tests;
|
||||
|
||||
use BookStack\Book;
|
||||
use BookStack\Bookshelf;
|
||||
use BookStack\Entity;
|
||||
use BookStack\User;
|
||||
use BookStack\Repos\EntityRepo;
|
||||
@ -34,6 +35,63 @@ class RestrictionsTest extends BrowserKitTest
|
||||
parent::setEntityRestrictions($entity, $actions, $roles);
|
||||
}
|
||||
|
||||
public function test_bookshelf_view_restriction()
|
||||
{
|
||||
$shelf = Bookshelf::first();
|
||||
|
||||
$this->actingAs($this->user)
|
||||
->visit($shelf->getUrl())
|
||||
->seePageIs($shelf->getUrl());
|
||||
|
||||
$this->setEntityRestrictions($shelf, []);
|
||||
|
||||
$this->forceVisit($shelf->getUrl())
|
||||
->see('Bookshelf not found');
|
||||
|
||||
$this->setEntityRestrictions($shelf, ['view']);
|
||||
|
||||
$this->visit($shelf->getUrl())
|
||||
->see($shelf->name);
|
||||
}
|
||||
|
||||
public function test_bookshelf_update_restriction()
|
||||
{
|
||||
$shelf = BookShelf::first();
|
||||
|
||||
$this->actingAs($this->user)
|
||||
->visit($shelf->getUrl('/edit'))
|
||||
->see('Edit Book');
|
||||
|
||||
$this->setEntityRestrictions($shelf, ['view', 'delete']);
|
||||
|
||||
$this->forceVisit($shelf->getUrl('/edit'))
|
||||
->see('You do not have permission')->seePageIs('/');
|
||||
|
||||
$this->setEntityRestrictions($shelf, ['view', 'update']);
|
||||
|
||||
$this->visit($shelf->getUrl('/edit'))
|
||||
->seePageIs($shelf->getUrl('/edit'));
|
||||
}
|
||||
|
||||
public function test_bookshelf_delete_restriction()
|
||||
{
|
||||
$shelf = Book::first();
|
||||
|
||||
$this->actingAs($this->user)
|
||||
->visit($shelf->getUrl('/delete'))
|
||||
->see('Delete Book');
|
||||
|
||||
$this->setEntityRestrictions($shelf, ['view', 'update']);
|
||||
|
||||
$this->forceVisit($shelf->getUrl('/delete'))
|
||||
->see('You do not have permission')->seePageIs('/');
|
||||
|
||||
$this->setEntityRestrictions($shelf, ['view', 'delete']);
|
||||
|
||||
$this->visit($shelf->getUrl('/delete'))
|
||||
->seePageIs($shelf->getUrl('/delete'))->see('Delete Book');
|
||||
}
|
||||
|
||||
public function test_book_view_restriction()
|
||||
{
|
||||
$book = Book::first();
|
||||
@ -325,6 +383,23 @@ class RestrictionsTest extends BrowserKitTest
|
||||
->seePageIs($pageUrl . '/delete')->see('Delete Page');
|
||||
}
|
||||
|
||||
public function test_bookshelf_restriction_form()
|
||||
{
|
||||
$shelf = Bookshelf::first();
|
||||
$this->asAdmin()->visit($shelf->getUrl('/permissions'))
|
||||
->see('Bookshelf Permissions')
|
||||
->check('restricted')
|
||||
->check('restrictions[2][view]')
|
||||
->press('Save Permissions')
|
||||
->seeInDatabase('bookshelves', ['id' => $shelf->id, 'restricted' => true])
|
||||
->seeInDatabase('entity_permissions', [
|
||||
'restrictable_id' => $shelf->id,
|
||||
'restrictable_type' => 'BookStack\Bookshelf',
|
||||
'role_id' => '2',
|
||||
'action' => 'view'
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_book_restriction_form()
|
||||
{
|
||||
$book = Book::first();
|
||||
@ -413,6 +488,44 @@ class RestrictionsTest extends BrowserKitTest
|
||||
->dontSee($page->name);
|
||||
}
|
||||
|
||||
public function test_bookshelf_update_restriction_override()
|
||||
{
|
||||
$shelf = Bookshelf::first();
|
||||
|
||||
$this->actingAs($this->viewer)
|
||||
->visit($shelf->getUrl('/edit'))
|
||||
->dontSee('Edit Book');
|
||||
|
||||
$this->setEntityRestrictions($shelf, ['view', 'delete']);
|
||||
|
||||
$this->forceVisit($shelf->getUrl('/edit'))
|
||||
->see('You do not have permission')->seePageIs('/');
|
||||
|
||||
$this->setEntityRestrictions($shelf, ['view', 'update']);
|
||||
|
||||
$this->visit($shelf->getUrl('/edit'))
|
||||
->seePageIs($shelf->getUrl('/edit'));
|
||||
}
|
||||
|
||||
public function test_bookshelf_delete_restriction_override()
|
||||
{
|
||||
$shelf = Bookshelf::first();
|
||||
|
||||
$this->actingAs($this->viewer)
|
||||
->visit($shelf->getUrl('/delete'))
|
||||
->dontSee('Delete Book');
|
||||
|
||||
$this->setEntityRestrictions($shelf, ['view', 'update']);
|
||||
|
||||
$this->forceVisit($shelf->getUrl('/delete'))
|
||||
->see('You do not have permission')->seePageIs('/');
|
||||
|
||||
$this->setEntityRestrictions($shelf, ['view', 'delete']);
|
||||
|
||||
$this->visit($shelf->getUrl('/delete'))
|
||||
->seePageIs($shelf->getUrl('/delete'))->see('Delete Book');
|
||||
}
|
||||
|
||||
public function test_book_create_restriction_override()
|
||||
{
|
||||
$book = Book::first();
|
||||
|
@ -1,5 +1,6 @@
|
||||
<?php namespace Tests;
|
||||
|
||||
use BookStack\Bookshelf;
|
||||
use BookStack\Page;
|
||||
use BookStack\Repos\PermissionsRepo;
|
||||
use BookStack\Role;
|
||||
@ -16,32 +17,6 @@ class RolesTest extends BrowserKitTest
|
||||
$this->user = $this->getViewer();
|
||||
}
|
||||
|
||||
/**
|
||||
* Give the given user some permissions.
|
||||
* @param \BookStack\User $user
|
||||
* @param array $permissions
|
||||
*/
|
||||
protected function giveUserPermissions(\BookStack\User $user, $permissions = [])
|
||||
{
|
||||
$newRole = $this->createNewRole($permissions);
|
||||
$user->attachRole($newRole);
|
||||
$user->load('roles');
|
||||
$user->permissions(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new basic role for testing purposes.
|
||||
* @param array $permissions
|
||||
* @return Role
|
||||
*/
|
||||
protected function createNewRole($permissions = [])
|
||||
{
|
||||
$permissionRepo = app(PermissionsRepo::class);
|
||||
$roleData = factory(\BookStack\Role::class)->make()->toArray();
|
||||
$roleData['permissions'] = array_flip($permissions);
|
||||
return $permissionRepo->saveNewRole($roleData);
|
||||
}
|
||||
|
||||
public function test_admin_can_see_settings()
|
||||
{
|
||||
$this->asAdmin()->visit('/settings')->see('Settings');
|
||||
@ -203,6 +178,90 @@ class RolesTest extends BrowserKitTest
|
||||
}
|
||||
}
|
||||
|
||||
public function test_bookshelves_create_all_permissions()
|
||||
{
|
||||
$this->checkAccessPermission('bookshelf-create-all', [
|
||||
'/create-shelf'
|
||||
], [
|
||||
'/shelves' => 'Create New Shelf'
|
||||
]);
|
||||
|
||||
$this->visit('/create-shelf')
|
||||
->type('test shelf', 'name')
|
||||
->type('shelf desc', 'description')
|
||||
->press('Save Shelf')
|
||||
->seePageIs('/shelves/test-shelf');
|
||||
}
|
||||
|
||||
public function test_bookshelves_edit_own_permission()
|
||||
{
|
||||
$otherShelf = Bookshelf::first();
|
||||
$ownShelf = $this->newShelf(['name' => 'test-shelf', 'slug' => 'test-shelf']);
|
||||
$ownShelf->forceFill(['created_by' => $this->user->id, 'updated_by' => $this->user->id])->save();
|
||||
$this->regenEntityPermissions($ownShelf);
|
||||
|
||||
$this->checkAccessPermission('bookshelf-update-own', [
|
||||
$ownShelf->getUrl('/edit')
|
||||
], [
|
||||
$ownShelf->getUrl() => 'Edit'
|
||||
]);
|
||||
|
||||
$this->visit($otherShelf->getUrl())
|
||||
->dontSeeInElement('.action-buttons', 'Edit')
|
||||
->visit($otherShelf->getUrl('/edit'))
|
||||
->seePageIs('/');
|
||||
}
|
||||
|
||||
public function test_bookshelves_edit_all_permission()
|
||||
{
|
||||
$otherShelf = \BookStack\Bookshelf::first();
|
||||
$this->checkAccessPermission('bookshelf-update-all', [
|
||||
$otherShelf->getUrl('/edit')
|
||||
], [
|
||||
$otherShelf->getUrl() => 'Edit'
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_bookshelves_delete_own_permission()
|
||||
{
|
||||
$this->giveUserPermissions($this->user, ['bookshelf-update-all']);
|
||||
$otherShelf = \BookStack\Bookshelf::first();
|
||||
$ownShelf = $this->newShelf(['name' => 'test-shelf', 'slug' => 'test-shelf']);
|
||||
$ownShelf->forceFill(['created_by' => $this->user->id, 'updated_by' => $this->user->id])->save();
|
||||
$this->regenEntityPermissions($ownShelf);
|
||||
|
||||
$this->checkAccessPermission('bookshelf-delete-own', [
|
||||
$ownShelf->getUrl('/delete')
|
||||
], [
|
||||
$ownShelf->getUrl() => 'Delete'
|
||||
]);
|
||||
|
||||
$this->visit($otherShelf->getUrl())
|
||||
->dontSeeInElement('.action-buttons', 'Delete')
|
||||
->visit($otherShelf->getUrl('/delete'))
|
||||
->seePageIs('/');
|
||||
$this->visit($ownShelf->getUrl())->visit($ownShelf->getUrl('/delete'))
|
||||
->press('Confirm')
|
||||
->seePageIs('/shelves')
|
||||
->dontSee($ownShelf->name);
|
||||
}
|
||||
|
||||
public function test_bookshelves_delete_all_permission()
|
||||
{
|
||||
$this->giveUserPermissions($this->user, ['bookshelf-update-all']);
|
||||
$otherShelf = \BookStack\Bookshelf::first();
|
||||
$this->checkAccessPermission('bookshelf-delete-all', [
|
||||
$otherShelf->getUrl('/delete')
|
||||
], [
|
||||
$otherShelf->getUrl() => 'Delete'
|
||||
]);
|
||||
|
||||
$this->visit($otherShelf->getUrl())->visit($otherShelf->getUrl('/delete'))
|
||||
->press('Confirm')
|
||||
->seePageIs('/shelves')
|
||||
->dontSee($otherShelf->name);
|
||||
}
|
||||
|
||||
public function test_books_create_all_permissions()
|
||||
{
|
||||
$this->checkAccessPermission('book-create-all', [
|
||||
|
@ -1,9 +1,11 @@
|
||||
<?php namespace Tests;
|
||||
|
||||
use BookStack\Book;
|
||||
use BookStack\Bookshelf;
|
||||
use BookStack\Chapter;
|
||||
use BookStack\Entity;
|
||||
use BookStack\Repos\EntityRepo;
|
||||
use BookStack\Repos\PermissionsRepo;
|
||||
use BookStack\Role;
|
||||
use BookStack\Services\PermissionService;
|
||||
use BookStack\Services\SettingService;
|
||||
@ -69,6 +71,25 @@ trait SharedTestHelpers
|
||||
return $user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Regenerate the permission for an entity.
|
||||
* @param Entity $entity
|
||||
*/
|
||||
protected function regenEntityPermissions(Entity $entity)
|
||||
{
|
||||
$this->app[PermissionService::class]->buildJointPermissionsForEntity($entity);
|
||||
$entity->load('jointPermissions');
|
||||
}
|
||||
|
||||
/**
|
||||
* Create and return a new bookshelf.
|
||||
* @param array $input
|
||||
* @return Bookshelf
|
||||
*/
|
||||
public function newShelf($input = ['name' => 'test shelf', 'description' => 'My new test shelf']) {
|
||||
return $this->app[EntityRepo::class]->createFromInput('bookshelf', $input, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create and return a new book.
|
||||
* @param array $input
|
||||
@ -140,4 +161,30 @@ trait SharedTestHelpers
|
||||
$entity->load('jointPermissions');
|
||||
}
|
||||
|
||||
/**
|
||||
* Give the given user some permissions.
|
||||
* @param \BookStack\User $user
|
||||
* @param array $permissions
|
||||
*/
|
||||
protected function giveUserPermissions(\BookStack\User $user, $permissions = [])
|
||||
{
|
||||
$newRole = $this->createNewRole($permissions);
|
||||
$user->attachRole($newRole);
|
||||
$user->load('roles');
|
||||
$user->permissions(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new basic role for testing purposes.
|
||||
* @param array $permissions
|
||||
* @return Role
|
||||
*/
|
||||
protected function createNewRole($permissions = [])
|
||||
{
|
||||
$permissionRepo = app(PermissionsRepo::class);
|
||||
$roleData = factory(Role::class)->make()->toArray();
|
||||
$roleData['permissions'] = array_flip($permissions);
|
||||
return $permissionRepo->saveNewRole($roleData);
|
||||
}
|
||||
|
||||
}
|
@ -2,13 +2,13 @@
|
||||
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
use Illuminate\Foundation\Testing\TestCase as BaseTestCase;
|
||||
use Illuminate\Foundation\Testing\TestResponse;
|
||||
|
||||
abstract class TestCase extends BaseTestCase
|
||||
{
|
||||
use CreatesApplication;
|
||||
use DatabaseTransactions;
|
||||
use SharedTestHelpers;
|
||||
|
||||
/**
|
||||
* The base URL to use while testing the application.
|
||||
* @var string
|
||||
@ -18,11 +18,46 @@ abstract class TestCase extends BaseTestCase
|
||||
/**
|
||||
* Assert a permission error has occurred.
|
||||
* @param TestResponse $response
|
||||
* @return TestCase
|
||||
*/
|
||||
protected function assertPermissionError(TestResponse $response)
|
||||
{
|
||||
$response->assertRedirect('/');
|
||||
$this->assertTrue(session()->has('error'));
|
||||
$this->assertSessionHas('error');
|
||||
session()->remove('error');
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert the session contains a specific entry.
|
||||
* @param string $key
|
||||
* @return $this
|
||||
*/
|
||||
protected function assertSessionHas(string $key)
|
||||
{
|
||||
$this->assertTrue(session()->has($key), "Session does not contain a [{$key}] entry");
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Override of the get method so we can get visibility of custom TestResponse methods.
|
||||
* @param string $uri
|
||||
* @param array $headers
|
||||
* @return TestResponse
|
||||
*/
|
||||
public function get($uri, array $headers = [])
|
||||
{
|
||||
return parent::get($uri, $headers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the test response instance from the given response.
|
||||
*
|
||||
* @param \Illuminate\Http\Response $response
|
||||
* @return TestResponse
|
||||
*/
|
||||
protected function createTestResponse($response)
|
||||
{
|
||||
return TestResponse::fromBaseResponse($response);
|
||||
}
|
||||
}
|
141
tests/TestResponse.php
Normal file
141
tests/TestResponse.php
Normal file
@ -0,0 +1,141 @@
|
||||
<?php namespace Tests;
|
||||
|
||||
use \Illuminate\Foundation\Testing\TestResponse as BaseTestResponse;
|
||||
use Symfony\Component\DomCrawler\Crawler;
|
||||
use PHPUnit\Framework\Assert as PHPUnit;
|
||||
|
||||
/**
|
||||
* Class TestResponse
|
||||
* Custom extension of the default Laravel TestResponse class.
|
||||
* @package Tests
|
||||
*/
|
||||
class TestResponse extends BaseTestResponse {
|
||||
|
||||
protected $crawlerInstance;
|
||||
|
||||
/**
|
||||
* Get the DOM Crawler for the response content.
|
||||
* @return Crawler
|
||||
*/
|
||||
protected function crawler()
|
||||
{
|
||||
if (!is_object($this->crawlerInstance)) {
|
||||
$this->crawlerInstance = new Crawler($this->getContent());
|
||||
}
|
||||
return $this->crawlerInstance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert the response contains the specified element.
|
||||
* @param string $selector
|
||||
* @return $this
|
||||
*/
|
||||
public function assertElementExists(string $selector)
|
||||
{
|
||||
$elements = $this->crawler()->filter($selector);
|
||||
PHPUnit::assertTrue(
|
||||
$elements->count() > 0,
|
||||
'Unable to find element matching the selector: '.PHP_EOL.PHP_EOL.
|
||||
"[{$selector}]".PHP_EOL.PHP_EOL.
|
||||
'within'.PHP_EOL.PHP_EOL.
|
||||
"[{$this->getContent()}]."
|
||||
);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert the response does not contain the specified element.
|
||||
* @param string $selector
|
||||
* @return $this
|
||||
*/
|
||||
public function assertElementNotExists(string $selector)
|
||||
{
|
||||
$elements = $this->crawler()->filter($selector);
|
||||
PHPUnit::assertTrue(
|
||||
$elements->count() === 0,
|
||||
'Found elements matching the selector: '.PHP_EOL.PHP_EOL.
|
||||
"[{$selector}]".PHP_EOL.PHP_EOL.
|
||||
'within'.PHP_EOL.PHP_EOL.
|
||||
"[{$this->getContent()}]."
|
||||
);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert the response includes a specific element containing the given text.
|
||||
* @param string $selector
|
||||
* @param string $text
|
||||
* @return $this
|
||||
*/
|
||||
public function assertElementContains(string $selector, string $text)
|
||||
{
|
||||
$elements = $this->crawler()->filter($selector);
|
||||
$matched = false;
|
||||
$pattern = $this->getEscapedPattern($text);
|
||||
foreach ($elements as $element) {
|
||||
$element = new Crawler($element);
|
||||
if (preg_match("/$pattern/i", $element->html())) {
|
||||
$matched = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
PHPUnit::assertTrue(
|
||||
$matched,
|
||||
'Unable to find element of selector: '.PHP_EOL.PHP_EOL.
|
||||
"[{$selector}]".PHP_EOL.PHP_EOL.
|
||||
'containing text'.PHP_EOL.PHP_EOL.
|
||||
"[{$text}]".PHP_EOL.PHP_EOL.
|
||||
'within'.PHP_EOL.PHP_EOL.
|
||||
"[{$this->getContent()}]."
|
||||
);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert the response does not include a specific element containing the given text.
|
||||
* @param string $selector
|
||||
* @param string $text
|
||||
* @return $this
|
||||
*/
|
||||
public function assertElementNotContains(string $selector, string $text)
|
||||
{
|
||||
$elements = $this->crawler()->filter($selector);
|
||||
$matched = false;
|
||||
$pattern = $this->getEscapedPattern($text);
|
||||
foreach ($elements as $element) {
|
||||
$element = new Crawler($element);
|
||||
if (preg_match("/$pattern/i", $element->html())) {
|
||||
$matched = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
PHPUnit::assertTrue(
|
||||
!$matched,
|
||||
'Found element of selector: '.PHP_EOL.PHP_EOL.
|
||||
"[{$selector}]".PHP_EOL.PHP_EOL.
|
||||
'containing text'.PHP_EOL.PHP_EOL.
|
||||
"[{$text}]".PHP_EOL.PHP_EOL.
|
||||
'within'.PHP_EOL.PHP_EOL.
|
||||
"[{$this->getContent()}]."
|
||||
);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the escaped text pattern for the constraint.
|
||||
* @param string $text
|
||||
* @return string
|
||||
*/
|
||||
protected function getEscapedPattern($text)
|
||||
{
|
||||
$rawPattern = preg_quote($text, '/');
|
||||
$escapedPattern = preg_quote(e($text), '/');
|
||||
return $rawPattern == $escapedPattern
|
||||
? $rawPattern : "({$rawPattern}|{$escapedPattern})";
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user