mirror of
https://github.com/BookStackApp/BookStack.git
synced 2024-10-01 01:36:00 -04:00
Added testing to favourite system
- Also removed some old view service references. - Updated TopFavourites query to be based on favourites table and join in the views instead of the other way around, so that favourites still show even if they have no views.
This commit is contained in:
parent
c2069f37cc
commit
ba8ba5c634
@ -588,7 +588,7 @@ class PermissionService
|
|||||||
|
|
||||||
$q = $query->where(function ($query) use ($tableDetails, $action) {
|
$q = $query->where(function ($query) use ($tableDetails, $action) {
|
||||||
$query->whereExists(function ($permissionQuery) use (&$tableDetails, $action) {
|
$query->whereExists(function ($permissionQuery) use (&$tableDetails, $action) {
|
||||||
$permissionQuery->select('id')->from('joint_permissions')
|
$permissionQuery->select(['role_id'])->from('joint_permissions')
|
||||||
->whereRaw('joint_permissions.entity_id=' . $tableDetails['tableName'] . '.' . $tableDetails['entityIdColumn'])
|
->whereRaw('joint_permissions.entity_id=' . $tableDetails['tableName'] . '.' . $tableDetails['entityIdColumn'])
|
||||||
->whereRaw('joint_permissions.entity_type=' . $tableDetails['tableName'] . '.' . $tableDetails['entityTypeColumn'])
|
->whereRaw('joint_permissions.entity_type=' . $tableDetails['tableName'] . '.' . $tableDetails['entityTypeColumn'])
|
||||||
->where('action', '=', $action)
|
->where('action', '=', $action)
|
||||||
|
@ -1,34 +1,33 @@
|
|||||||
<?php namespace BookStack\Entities\Queries;
|
<?php namespace BookStack\Entities\Queries;
|
||||||
|
|
||||||
use BookStack\Actions\View;
|
use BookStack\Actions\Favourite;
|
||||||
use Illuminate\Database\Query\JoinClause;
|
use Illuminate\Database\Query\JoinClause;
|
||||||
use Illuminate\Support\Facades\DB;
|
|
||||||
|
|
||||||
class TopFavourites extends EntityQuery
|
class TopFavourites extends EntityQuery
|
||||||
{
|
{
|
||||||
public function run(int $count, int $skip = 0)
|
public function run(int $count, int $skip = 0)
|
||||||
{
|
{
|
||||||
$user = user();
|
$user = user();
|
||||||
if ($user === null || $user->isDefault()) {
|
if (is_null($user) || $user->isDefault()) {
|
||||||
return collect();
|
return collect();
|
||||||
}
|
}
|
||||||
|
|
||||||
$query = $this->permissionService()
|
$query = $this->permissionService()
|
||||||
->filterRestrictedEntityRelations(View::query(), 'views', 'viewable_id', 'viewable_type', 'view')
|
->filterRestrictedEntityRelations(Favourite::query(), 'favourites', 'favouritable_id', 'favouritable_type', 'view')
|
||||||
->select('*', 'viewable_id', 'viewable_type', DB::raw('SUM(views) as view_count'))
|
->select('favourites.*')
|
||||||
->groupBy('viewable_id', 'viewable_type')
|
->leftJoin('views', function (JoinClause $join) {
|
||||||
->rightJoin('favourites', function (JoinClause $join) {
|
$join->on('favourites.favouritable_id', '=', 'views.viewable_id');
|
||||||
$join->on('views.viewable_id', '=', 'favourites.favouritable_id');
|
$join->on('favourites.favouritable_type', '=', 'views.viewable_type');
|
||||||
$join->on('views.viewable_type', '=', 'favourites.favouritable_type');
|
$join->where('views.user_id', '=', user()->id);
|
||||||
$join->where('favourites.user_id', '=', user()->id);
|
|
||||||
})
|
})
|
||||||
->orderBy('view_count', 'desc');
|
->orderBy('views.views', 'desc')
|
||||||
|
->where('favourites.user_id', '=', user()->id);
|
||||||
|
|
||||||
return $query->with('viewable')
|
return $query->with('favouritable')
|
||||||
->skip($skip)
|
->skip($skip)
|
||||||
->take($count)
|
->take($count)
|
||||||
->get()
|
->get()
|
||||||
->pluck('viewable')
|
->pluck('favouritable')
|
||||||
->filter();
|
->filter();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
<?php namespace BookStack\Http\Controllers;
|
<?php namespace BookStack\Http\Controllers;
|
||||||
|
|
||||||
use BookStack\Actions\ViewService;
|
|
||||||
use BookStack\Entities\Queries\Popular;
|
use BookStack\Entities\Queries\Popular;
|
||||||
use BookStack\Entities\Tools\SearchRunner;
|
use BookStack\Entities\Tools\SearchRunner;
|
||||||
use BookStack\Entities\Tools\ShelfContext;
|
use BookStack\Entities\Tools\ShelfContext;
|
||||||
@ -10,16 +9,13 @@ use Illuminate\Http\Request;
|
|||||||
|
|
||||||
class SearchController extends Controller
|
class SearchController extends Controller
|
||||||
{
|
{
|
||||||
protected $viewService;
|
|
||||||
protected $searchRunner;
|
protected $searchRunner;
|
||||||
protected $entityContextManager;
|
protected $entityContextManager;
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
ViewService $viewService,
|
|
||||||
SearchRunner $searchRunner,
|
SearchRunner $searchRunner,
|
||||||
ShelfContext $entityContextManager
|
ShelfContext $entityContextManager
|
||||||
) {
|
) {
|
||||||
$this->viewService = $viewService;
|
|
||||||
$this->searchRunner = $searchRunner;
|
$this->searchRunner = $searchRunner;
|
||||||
$this->entityContextManager = $entityContextManager;
|
$this->entityContextManager = $entityContextManager;
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
namespace BookStack\Providers;
|
namespace BookStack\Providers;
|
||||||
|
|
||||||
use BookStack\Actions\ActivityService;
|
use BookStack\Actions\ActivityService;
|
||||||
use BookStack\Actions\ViewService;
|
|
||||||
use BookStack\Auth\Permissions\PermissionService;
|
use BookStack\Auth\Permissions\PermissionService;
|
||||||
use BookStack\Theming\ThemeService;
|
use BookStack\Theming\ThemeService;
|
||||||
use BookStack\Uploads\ImageService;
|
use BookStack\Uploads\ImageService;
|
||||||
@ -32,10 +31,6 @@ class CustomFacadeProvider extends ServiceProvider
|
|||||||
return $this->app->make(ActivityService::class);
|
return $this->app->make(ActivityService::class);
|
||||||
});
|
});
|
||||||
|
|
||||||
$this->app->singleton('views', function () {
|
|
||||||
return $this->app->make(ViewService::class);
|
|
||||||
});
|
|
||||||
|
|
||||||
$this->app->singleton('images', function () {
|
$this->app->singleton('images', function () {
|
||||||
return $this->app->make(ImageService::class);
|
return $this->app->make(ImageService::class);
|
||||||
});
|
});
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
use BookStack\Actions\Favourite;
|
use BookStack\Actions\Favourite;
|
||||||
|
use BookStack\Entities\Models\Book;
|
||||||
|
use BookStack\Entities\Models\Bookshelf;
|
||||||
|
use BookStack\Entities\Models\Chapter;
|
||||||
use BookStack\Entities\Models\Page;
|
use BookStack\Entities\Models\Page;
|
||||||
use Tests\TestCase;
|
use Tests\TestCase;
|
||||||
|
|
||||||
@ -56,4 +59,60 @@ class FavouriteTest extends TestCase
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function test_book_chapter_shelf_pages_contain_favourite_button()
|
||||||
|
{
|
||||||
|
$entities = [
|
||||||
|
Bookshelf::query()->first(),
|
||||||
|
Book::query()->first(),
|
||||||
|
Chapter::query()->first(),
|
||||||
|
];
|
||||||
|
$this->actingAs($this->getEditor());
|
||||||
|
|
||||||
|
foreach ($entities as $entity) {
|
||||||
|
$resp = $this->get($entity->getUrl());
|
||||||
|
$resp->assertElementExists('form[method="POST"][action$="/favourites/add"]');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_header_contains_link_to_favourites_page_when_logged_in()
|
||||||
|
{
|
||||||
|
$this->setSettings(['app-public' => 'true']);
|
||||||
|
$this->get('/')->assertElementNotContains('header', 'My Favourites');
|
||||||
|
$this->actingAs($this->getViewer())->get('/')->assertElementContains('header a', 'My Favourites');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_favourites_shown_on_homepage()
|
||||||
|
{
|
||||||
|
$editor = $this->getEditor();
|
||||||
|
|
||||||
|
$resp = $this->actingAs($editor)->get('/');
|
||||||
|
$resp->assertElementNotExists('#top-favourites');
|
||||||
|
|
||||||
|
/** @var Page $page */
|
||||||
|
$page = Page::query()->first();
|
||||||
|
$page->favourites()->save((new Favourite)->forceFill(['user_id' => $editor->id]));
|
||||||
|
|
||||||
|
$resp = $this->get('/');
|
||||||
|
$resp->assertElementExists('#top-favourites');
|
||||||
|
$resp->assertElementContains('#top-favourites', $page->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_favourites_list_page_shows_favourites_and_has_working_pagination()
|
||||||
|
{
|
||||||
|
/** @var Page $page */
|
||||||
|
$page = Page::query()->first();
|
||||||
|
$editor = $this->getEditor();
|
||||||
|
|
||||||
|
$resp = $this->actingAs($editor)->get('/favourites');
|
||||||
|
$resp->assertDontSee($page->name);
|
||||||
|
|
||||||
|
$page->favourites()->save((new Favourite)->forceFill(['user_id' => $editor->id]));
|
||||||
|
|
||||||
|
$resp = $this->get('/favourites');
|
||||||
|
$resp->assertSee($page->name);
|
||||||
|
|
||||||
|
$resp = $this->get('/favourites?page=2');
|
||||||
|
$resp->assertDontSee($page->name);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user