Added HasUserNotifications trait to show messages to the user

This commit is contained in:
Igor Scheller 2020-03-01 18:21:16 +01:00 committed by msquare
parent e42284deca
commit 72f4839130
10 changed files with 154 additions and 30 deletions

View File

@ -0,0 +1,19 @@
{% import 'macros/base.twig' as m %}
{{ msg() }}
{% for message in errors|default([]) %}
{{ m.alert(__(message), 'danger') }}
{% endfor %}
{% for message in warnings|default([]) %}
{{ m.alert(__(message), 'warning') }}
{% endfor %}
{% for message in information|default([]) %}
{{ m.alert(__(message), 'info') }}
{% endfor %}
{% for message in messages|default([]) %}
{{ m.alert(__(message), 'success') }}
{% endfor %}

View File

@ -32,10 +32,7 @@
<div class="col-sm-6 col-sm-offset-3 col-md-4 col-md-offset-4">
<div class="panel panel-primary first">
<div class="panel-body">
{{ msg() }}
{% for message in errors|default([]) %}
{{ m.alert(__(message), 'danger') }}
{% endfor %}
{% include 'layouts/parts/messages.twig' %}
<form action="" enctype="multipart/form-data" method="post">
{{ csrf() }}

View File

@ -8,9 +8,7 @@
<div class="container">
<h1>{{ __('Password recovery') }}</h1>
{% for message in errors|default([]) %}
{{ m.alert(__(message), 'danger') }}
{% endfor %}
{% include 'layouts/parts/messages.twig' %}
<div class="row">
{% block row_content %}

View File

@ -9,12 +9,12 @@ use Engelsystem\Http\Request;
use Engelsystem\Http\Response;
use Engelsystem\Http\UrlGeneratorInterface;
use Engelsystem\Models\User\User;
use Illuminate\Support\Arr;
use Illuminate\Support\Collection;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
class AuthController extends BaseController
{
use HasUserNotifications;
/** @var Response */
protected $response;
@ -70,12 +70,9 @@ class AuthController extends BaseController
*/
protected function showLogin(): Response
{
$errors = Collection::make(Arr::flatten($this->session->get('errors', [])));
$this->session->remove('errors');
return $this->response->withView(
'pages/login',
['errors' => $errors]
$this->getNotifications()
);
}
@ -95,7 +92,7 @@ class AuthController extends BaseController
$user = $this->auth->authenticate($data['login'], $data['password']);
if (!$user instanceof User) {
$this->session->set('errors', array_merge($this->session->get('errors', []), ['auth.not-found']));
$this->addNotification('auth.not-found', 'errors');
return $this->showLogin();
}

View File

@ -0,0 +1,35 @@
<?php
namespace Engelsystem\Controllers;
use Illuminate\Support\Arr;
use Illuminate\Support\Collection;
trait HasUserNotifications
{
/**
* @param string|array $value
* @param string $type
*/
protected function addNotification($value, $type = 'messages')
{
session()->set(
$type,
array_merge(session()->get($type, []), [$value])
);
}
/**
* @return array
*/
protected function getNotifications(): array
{
$return = [];
foreach (['errors', 'warnings', 'information', 'messages'] as $type) {
$return[$type] = Collection::make(Arr::flatten(session()->get($type, [])));
session()->remove($type);
}
return $return;
}
}

View File

@ -8,13 +8,13 @@ use Engelsystem\Http\Response;
use Engelsystem\Mail\EngelsystemMailer;
use Engelsystem\Models\User\PasswordReset;
use Engelsystem\Models\User\User;
use Illuminate\Support\Arr;
use Illuminate\Support\Collection;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
class PasswordResetController extends BaseController
{
use HasUserNotifications;
/** @var LoggerInterface */
protected $log;
@ -120,10 +120,7 @@ class PasswordResetController extends BaseController
]);
if ($data['password'] !== $data['password_confirmation']) {
$this->session->set(
'errors',
array_merge($this->session->get('errors', []), ['validation.password.confirmed'])
);
$this->addNotification('validation.password.confirmed', 'errors');
return $this->showView('pages/password/reset-form');
}
@ -141,12 +138,9 @@ class PasswordResetController extends BaseController
*/
protected function showView($view = 'pages/password/reset', $data = []): Response
{
$errors = Collection::make(Arr::flatten($this->session->get('errors', [])));
$this->session->remove('errors');
return $this->response->withView(
$view,
array_merge_recursive(['errors' => $errors], $data)
array_merge_recursive($this->getNotifications(), $data)
);
}

View File

@ -2,6 +2,7 @@
namespace Engelsystem\Test\Unit\Controllers;
use DMS\PHPUnitExtensions\ArraySubset\ArraySubsetAsserts;
use Engelsystem\Config\Config;
use Engelsystem\Controllers\AuthController;
use Engelsystem\Helpers\Authenticator;
@ -21,6 +22,7 @@ use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage;
class AuthControllerTest extends TestCase
{
use ArraySubsetAsserts;
use HasDatabase;
/**
@ -38,10 +40,11 @@ class AuthControllerTest extends TestCase
/** @var Authenticator|MockObject $auth */
list(, $session, $url, $config, $auth) = $this->getMocks();
$session->expects($this->once())
$session->expects($this->atLeastOnce())
->method('get')
->with('errors', [])
->willReturn(['foo' => 'bar']);
->willReturnCallback(function ($type) {
return $type == 'errors' ? ['foo' => 'bar'] : [];
});
$response->expects($this->once())
->method('withView')
->with('pages/login')
@ -69,6 +72,7 @@ class AuthControllerTest extends TestCase
/** @var Validator|MockObject $validator */
$validator = new Validator();
$session->set('errors', [['bar' => 'some.bar.error']]);
$this->app->instance('session', $session);
$user = new User([
'name' => 'foo',
@ -92,8 +96,11 @@ class AuthControllerTest extends TestCase
$response->expects($this->once())
->method('withView')
->with('pages/login', ['errors' => collect(['some.bar.error', 'auth.not-found'])])
->willReturn($response);
->willReturnCallback(function ($view, $data = []) use ($response) {
$this->assertEquals('pages/login', $view);
$this->assertArraySubset(['errors' => collect(['some.bar.error', 'auth.not-found'])], $data);
return $response;
});
$response->expects($this->once())
->method('redirectTo')
->with('news')
@ -168,6 +175,8 @@ class AuthControllerTest extends TestCase
/** @var Authenticator|MockObject $auth */
$auth = $this->createMock(Authenticator::class);
$this->app->instance('session', $session);
return [$response, $session, $url, $config, $auth];
}
}

View File

@ -0,0 +1,35 @@
<?php
namespace Engelsystem\Test\Unit\Controllers;
use Engelsystem\Test\Unit\Controllers\Stub\HasUserNotificationsImplementation;
use Engelsystem\Test\Unit\TestCase;
use Illuminate\Support\Collection;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage;
class HasUserNotificationsTest extends TestCase
{
/**
* @covers \Engelsystem\Controllers\HasUserNotifications::getNotifications
* @covers \Engelsystem\Controllers\HasUserNotifications::addNotification
*/
public function testNotifications()
{
$session = new Session(new MockArraySessionStorage());
$this->app->instance('session', $session);
$notify = new HasUserNotificationsImplementation();
$notify->add('Foo', 'errors');
$notify->add('Bar', 'warnings');
$notify->add(['Baz', 'Lorem'], 'information');
$notify->add(['Hm', ['Uff', 'sum']], 'messages');
$this->assertEquals([
'errors' => new Collection(['Foo']),
'warnings' => new Collection(['Bar']),
'information' => new Collection(['Baz', 'Lorem']),
'messages' => new Collection(['Hm', 'Uff', 'sum']),
], $notify->get());
}
}

View File

@ -2,6 +2,7 @@
namespace Engelsystem\Test\Unit\Controllers;
use DMS\PHPUnitExtensions\ArraySubset\ArraySubsetAsserts;
use Engelsystem\Config\Config;
use Engelsystem\Controllers\PasswordResetController;
use Engelsystem\Helpers\Authenticator;
@ -23,6 +24,7 @@ use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage;
class PasswordResetControllerTest extends TestCase
{
use ArraySubsetAsserts;
use HasDatabase;
/** @var array */
@ -199,6 +201,8 @@ class PasswordResetControllerTest extends TestCase
$renderer = $this->createMock(Renderer::class);
$response->setRenderer($renderer);
$this->app->instance('session', $session);
return $this->args = [
'response' => $response,
'session' => $session,
@ -230,7 +234,16 @@ class PasswordResetControllerTest extends TestCase
$args[] = $data;
}
$this->setExpects($renderer, 'render', $args, 'Foo');
$renderer->expects($this->atLeastOnce())
->method('render')
->willReturnCallback(function ($template, $data = []) use ($args) {
$this->assertEquals($args[0], $template);
if (isset($args[1])) {
$this->assertArraySubset($args[1], $data);
}
return 'Foo';
});
}
return $controller;

View File

@ -0,0 +1,27 @@
<?php
namespace Engelsystem\Test\Unit\Controllers\Stub;
use Engelsystem\Controllers\HasUserNotifications;
class HasUserNotificationsImplementation
{
use HasUserNotifications;
/**
* @param string|array $value
* @param string $type
*/
public function add($value, $type = 'messages')
{
$this->addNotification($value, $type);
}
/**
* @return array
*/
public function get(): array
{
return $this->getNotifications();
}
}