Skip to content
This repository has been archived by the owner on Oct 10, 2018. It is now read-only.

Commit

Permalink
Merge pull request #11 from kontenta/event
Browse files Browse the repository at this point in the history
Visit events and visit widgets
  • Loading branch information
bjuppa authored Sep 21, 2018
2 parents 1fab199 + 63788a1 commit b738871
Show file tree
Hide file tree
Showing 9 changed files with 218 additions and 5 deletions.
1 change: 1 addition & 0 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,6 @@
<php>
<env name="APP_KEY" value="AckfSECXIvnK5r28GVIWUAxmbBSjTsmF"/>
<env name="APP_URL" value="http://127.0.0.1:8000"/>
<env name="CACHE_DRIVER" value="array"/>
</php>
</phpunit>
8 changes: 7 additions & 1 deletion src/Auth/AdminUser.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,14 @@

use Illuminate\Notifications\Notifiable;
use Kontenta\KontourSupport\Auth\Passwords\CanResetPassword;
use Kontenta\Kontour\Contracts\AdminUser as AdminUserContract;

class AdminUser extends \Illuminate\Foundation\Auth\User
class AdminUser extends \Illuminate\Foundation\Auth\User implements AdminUserContract
{
use Notifiable, CanResetPassword;

public function getDisplayName() : string
{
return $this->getEmailForPasswordReset();
}
}
40 changes: 40 additions & 0 deletions src/PersonalRecentVisitsWidget.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php

namespace Kontenta\KontourSupport;

use Illuminate\Contracts\Auth\Access\Authorizable;
use Illuminate\Support\Facades\Auth;
use Kontenta\Kontour\Contracts\PersonalRecentVisitsWidget as PersonalRecentVisitsWidgetContract;

class PersonalRecentVisitsWidget implements PersonalRecentVisitsWidgetContract
{
protected $repository;

public function __construct(RecentVisitsRepository $repository)
{
$this->repository = $repository;
}

public function toHtml()
{
return '<ul>' . $this->getVisits()->map(function ($visit) {
return '<li data-kontour-visit-type="' . $visit->getType() . '">' . $visit->getLink()->toHtml() . '</li>';
})->implode("\n") . '</ul>';
}

public function isAuthorized(Authorizable $user = null): bool
{
return true;
}

private function getVisits()
{
return $this->repository->getShowVisits()->merge($this->repository->getEditVisits())->filter(function ($visit) {
return $visit->getUser()->is(Auth::guard(config('kontour.guard'))->user());
})->unique(function ($visit) {
return $visit->getLink()->getUrl();
})->sortByDesc(function ($visit) {
return $visit->getDateTime();
});
}
}
30 changes: 28 additions & 2 deletions src/Providers/KontourServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,14 @@
use Kontenta\KontourSupport\AdminViewManager;
use Kontenta\KontourSupport\AdminWidgetManager;
use Kontenta\KontourSupport\MenuWidget;
use Kontenta\KontourSupport\RecentVisitsRepository;
use Kontenta\KontourSupport\PersonalRecentVisitsWidget;
use Kontenta\KontourSupport\TeamRecentVisitsWidget;
use Kontenta\KontourSupport\Http\Middleware\AuthenticateAdmin;
use Kontenta\KontourSupport\Http\Middleware\RedirectIfAuthenticated;
use Kontenta\Kontour\Concerns\RegistersAdminRoutes;
use Kontenta\Kontour\Concerns\RegistersAdminWidgets;
use Illuminate\Support\Facades\Event;

class KontourServiceProvider extends ServiceProvider
{
Expand Down Expand Up @@ -71,6 +75,24 @@ function ($app) {
MenuWidget::class,
true
);

$this->app->bindIf(
\Kontenta\Kontour\Contracts\RecentVisitsRepository::class,
RecentVisitsRepository::class,
true
);

$this->app->bindIf(
\Kontenta\Kontour\Contracts\PersonalRecentVisitsWidget::class,
PersonalRecentVisitsWidget::class,
true
);

$this->app->bindIf(
\Kontenta\Kontour\Contracts\TeamRecentVisitsWidget::class,
TeamRecentVisitsWidget::class,
true
);
}

/**
Expand All @@ -79,9 +101,8 @@ function ($app) {
public function boot()
{
$this->registerResources();

$this->registerRoutes();

$this->registerEventListeners();
$this->registerWidgets();

if ($this->app->runningInConsole()) {
Expand Down Expand Up @@ -117,6 +138,11 @@ protected function registerRoutes()
}
}

protected function registerEventListeners()
{
Event::subscribe(RecentVisitsRepository::class);
}

protected function registerWidgets()
{
$this->registerAdminWidget($this->app->make(\Kontenta\Kontour\Contracts\MenuWidget::class), $this->app->make(\Kontenta\Kontour\Contracts\AdminViewManager::class)->navSection());
Expand Down
41 changes: 41 additions & 0 deletions src/RecentVisitsRepository.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

namespace Kontenta\KontourSupport;

use Illuminate\Contracts\Auth\Access\Authorizable;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Cache;
use Kontenta\Kontour\Events\AdminToolVisited;
use Kontenta\Kontour\Contracts\RecentVisitsRepository as RecentVisitsRepositoryContract;

class RecentVisitsRepository implements RecentVisitsRepositoryContract
{
private $keyPrefix = 'kontour-recent';

public function getShowVisits(): Collection
{
return Cache::get($this->generateCacheKey('show'), new Collection());
}

public function getEditVisits(): Collection
{
return Cache::get($this->generateCacheKey('edit'), new Collection());
}

public function subscribe($events)
{
$events->listen(AdminToolVisited::class, [$this, 'handle']);
}

public function handle(AdminToolVisited $event)
{
$key = $this->generateCacheKey($event->visit->getType());
$visits = Cache::get($key, new Collection());
$visits->push($event->visit);
Cache::forever($key, $visits);
}

protected function generateCacheKey($type) {
return 'kontour-recent-visits-'.$type;
}
}
40 changes: 40 additions & 0 deletions src/TeamRecentVisitsWidget.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php

namespace Kontenta\KontourSupport;

use Illuminate\Contracts\Auth\Access\Authorizable;
use Illuminate\Support\Facades\Auth;
use Kontenta\Kontour\Contracts\TeamRecentVisitsWidget as TeamRecentVisitsWidgetContract;

class TeamRecentVisitsWidget implements TeamRecentVisitsWidgetContract
{
protected $repository;

public function __construct(RecentVisitsRepository $repository)
{
$this->repository = $repository;
}

public function toHtml()
{
return '<ul>' . $this->getVisits()->map(function ($visit) {
return '<li data-kontour-visit-type="' . $visit->getType() . '" data-kontour-username="' . $visit->getUser()->getDisplayName() . '">' . $visit->getLink()->toHtml() . '</li>';
})->implode("\n") . '</ul>';
}

public function isAuthorized(Authorizable $user = null): bool
{
return true;
}

private function getVisits()
{
return $this->repository->getEditVisits()->filter(function ($visit) {
return !$visit->getUser()->is(Auth::guard(config('kontour.guard'))->user());
})->unique(function ($visit) {
return $visit->getLink()->getUrl();
})->sortByDesc(function ($visit) {
return $visit->getDateTime();
});
}
}
8 changes: 8 additions & 0 deletions tests/Feature/Fakes/UserlandController.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,19 @@
namespace Kontenta\KontourSupport\Tests\Feature\Fakes;

use Illuminate\Routing\Controller as BaseController;
use Illuminate\Support\Facades\Auth;
use Kontenta\Kontour\Events\AdminToolVisited;
use Kontenta\KontourSupport\AdminLink;
use Kontenta\Kontour\ShowAdminVisit;

class UserlandController extends BaseController
{
public function index()
{
$link = new AdminLink(url()->full(), 'Recent Userland Tool');
$user = Auth::guard(config('kontour.guard'))->user();
$visit = new ShowAdminVisit($link, $user);
event(new AdminToolVisited($visit));
return view('userland::index');
}

Expand Down
5 changes: 5 additions & 0 deletions tests/Feature/Fakes/UserlandServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
use Illuminate\Support\ServiceProvider;
use Kontenta\Kontour\Concerns\RegistersAdminRoutes;
use Kontenta\Kontour\Concerns\RegistersAdminWidgets;
use Kontenta\Kontour\Contracts\PersonalRecentVisitsWidget;
use Kontenta\Kontour\Contracts\TeamRecentVisitsWidget;

class UserlandServiceProvider extends ServiceProvider
{
Expand Down Expand Up @@ -39,6 +41,7 @@ protected function registerRoutes()
'namespace' => 'Kontenta\KontourSupport\Tests\Feature\Fakes',
], function ($router) {
$router->get('/', 'UserlandController@index')->name('userland.index');
$router->get('edit', 'UserlandController@edit')->name('userland.edit');
});
});
}
Expand All @@ -55,6 +58,8 @@ protected function registerWidgets()
{
$this->registerAdminWidget(new UserlandAdminWidget());
$this->registerAdminWidget(new UnauthorizedWidget());
$this->registerAdminWidget($this->app->make(PersonalRecentVisitsWidget::class));
$this->registerAdminWidget($this->app->make(TeamRecentVisitsWidget::class));
}

protected function addMenuLink()
Expand Down
50 changes: 48 additions & 2 deletions tests/Feature/UserlandControllerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,13 @@

namespace Kontenta\KontourSupport\Tests\Feature;

use Kontenta\KontourSupport\Tests\UserlandAdminToolTest;
use Illuminate\Support\Facades\Event;
use Kontenta\KontourSupport\AdminLink;
use Kontenta\KontourSupport\Tests\Feature\Fakes\User;
use Kontenta\KontourSupport\Tests\UserlandAdminToolTest;
use Kontenta\Kontour\EditAdminVisit;
use Kontenta\Kontour\Events\AdminToolVisited;
use Kontenta\Kontour\ShowAdminVisit;

class UserlandControllerTest extends UserlandAdminToolTest
{
Expand All @@ -21,12 +26,53 @@ public function setUp()

public function test_index_route()
{
Event::fake();

$response = $this->actingAs($this->user)->get(route('userland.index'));

$response->assertSee('<main');
$response->assertSee('UserlandAdminWidget');
$response->assertDontSee('UnauthorizedWidget');
$response->assertSee(route('userland.index'));
$response->assertSee('<a href="' . route('userland.index') . '">Userland Tool</a>');
$response->assertSee('>main<');
Event::assertDispatched(AdminToolVisited::class, function ($e) {
$now = new \DateTimeImmutable();
return $e->visit->getLink()->getUrl() == route('userland.index') and
$this->user->is($e->visit->getUser()) and
$now->getTimestamp() - $e->visit->getDateTime()->getTimestamp() >= 0;
});
}

public function test_recent_visits_widgets()
{
$otherUser = factory(User::class)->create();
$link = new AdminLink(route('userland.edit'), 'Recent Userland Tool');
$visit = new EditAdminVisit($link, $this->user);
event(new AdminToolVisited($visit));
event(new AdminToolVisited($visit));
$link = new AdminLink(route('userland.index'), 'Other Recent Userland Tool');
$visit = new ShowAdminVisit($link, $otherUser);
event(new AdminToolVisited($visit));
$link = new AdminLink(route('userland.edit'), 'Other Recent Userland Tool');
$visit = new EditAdminVisit($link, $otherUser);
event(new AdminToolVisited($visit));
event(new AdminToolVisited($visit));

$response = $this->actingAs($this->user)->get(route('userland.index'));

$response->assertOk();

// Check personal links
$numberOfMatches = substr_count($response->content(), '<li data-kontour-visit-type="show"><a href="' . route('userland.index') . '">Recent Userland Tool</a>');
$this->assertEquals(1, $numberOfMatches);

$numberOfMatches = substr_count($response->content(), '<li data-kontour-visit-type="edit"><a href="' . route('userland.edit') . '">Recent Userland Tool</a>');
$this->assertEquals(1, $numberOfMatches);

// Check team links
$numberOfMatches = substr_count($response->content(), '<li data-kontour-visit-type="edit" data-kontour-username="' . $otherUser->getDisplayName() . '"><a href="' . route('userland.edit') . '">Other Recent Userland Tool</a>');
$this->assertEquals(1, $numberOfMatches);

$response->assertDontSee('<a href="' . route('userland.index') . '">Other Recent Userland Tool</a>');
}
}

0 comments on commit b738871

Please sign in to comment.