Added user id to logs, implemented filter by user
This commit is contained in:
parent
162116998c
commit
8185a74edc
|
@ -0,0 +1,38 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Engelsystem\Migrations;
|
||||||
|
|
||||||
|
use Engelsystem\Database\Migration\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
|
||||||
|
class AddUserIdToLogEntries extends Migration
|
||||||
|
{
|
||||||
|
use Reference;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run the migration
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
$this->schema->table('log_entries', function (Blueprint $table): void {
|
||||||
|
$table->unsignedInteger('user_id')->after('id')->nullable()->default(null);
|
||||||
|
$table->foreign('user_id')
|
||||||
|
->references('id')->on('users')
|
||||||
|
->onUpdate('cascade')
|
||||||
|
->nullOnDelete();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migration
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
$this->schema->table('log_entries', function (Blueprint $table): void {
|
||||||
|
$table->dropForeign('log_entries_user_id_foreign');
|
||||||
|
$table->dropColumn('user_id');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Engelsystem\Migrations;
|
||||||
|
|
||||||
|
use Engelsystem\Database\Migration\Migration;
|
||||||
|
|
||||||
|
class AddLogsAllPermission extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migration
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
$db = $this->schema->getConnection();
|
||||||
|
$db->table('privileges')
|
||||||
|
->insert([
|
||||||
|
['name' => 'logs.all', 'description' => 'View all logs'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
$logsAll = $db->table('privileges')
|
||||||
|
->where('name', 'logs.all')
|
||||||
|
->get(['id'])
|
||||||
|
->first();
|
||||||
|
|
||||||
|
$bureaucrat = 80;
|
||||||
|
$db->table('group_privileges')
|
||||||
|
->insertOrIgnore([
|
||||||
|
['group_id' => $bureaucrat, 'privilege_id' => $logsAll->id],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migration
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
$db = $this->schema->getConnection();
|
||||||
|
$db->table('privileges')
|
||||||
|
->where('name', 'logs.all')
|
||||||
|
->delete();
|
||||||
|
}
|
||||||
|
}
|
|
@ -30,7 +30,7 @@ trait Reference
|
||||||
$table->primary($fromColumn);
|
$table->primary($fromColumn);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->addReference($table, $fromColumn, $targetTable, $targetColumn ?: 'id');
|
$this->addReference($table, $fromColumn, $targetTable, $targetColumn);
|
||||||
|
|
||||||
return $col;
|
return $col;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1407,6 +1407,9 @@ msgstr "Du kannst hier Markdown verwenden"
|
||||||
msgid "form.required"
|
msgid "form.required"
|
||||||
msgstr "Pflichtfeld"
|
msgstr "Pflichtfeld"
|
||||||
|
|
||||||
|
msgid "form.user_select"
|
||||||
|
msgstr "Wähle einen User"
|
||||||
|
|
||||||
msgid "schedule.import"
|
msgid "schedule.import"
|
||||||
msgstr "Programm importieren"
|
msgstr "Programm importieren"
|
||||||
|
|
||||||
|
@ -1531,6 +1534,9 @@ msgstr "Suchen"
|
||||||
msgid "log.log"
|
msgid "log.log"
|
||||||
msgstr "Logs"
|
msgstr "Logs"
|
||||||
|
|
||||||
|
msgid "log.only_own"
|
||||||
|
msgstr "Du siehst hier deine eigenen Logs. Die logs anderer User können nur Bürokraten sehen."
|
||||||
|
|
||||||
msgid "log.time"
|
msgid "log.time"
|
||||||
msgstr "Zeit"
|
msgstr "Zeit"
|
||||||
|
|
||||||
|
|
|
@ -115,6 +115,9 @@ msgstr "Required"
|
||||||
msgid "form.markdown"
|
msgid "form.markdown"
|
||||||
msgstr "You can use Markdown here"
|
msgstr "You can use Markdown here"
|
||||||
|
|
||||||
|
msgid "form.user_select"
|
||||||
|
msgstr "Select a user"
|
||||||
|
|
||||||
msgid "schedule.import"
|
msgid "schedule.import"
|
||||||
msgstr "Import schedule"
|
msgstr "Import schedule"
|
||||||
|
|
||||||
|
@ -244,6 +247,9 @@ msgstr "Search"
|
||||||
msgid "log.log"
|
msgid "log.log"
|
||||||
msgstr "Logs"
|
msgstr "Logs"
|
||||||
|
|
||||||
|
msgid "log.only_own"
|
||||||
|
msgstr "You can view your own logs. The logs of other users can be checked by bureaucrats."
|
||||||
|
|
||||||
msgid "log.time"
|
msgid "log.time"
|
||||||
msgstr "Time"
|
msgstr "Time"
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="col-md-12">
|
<div class="col-md-12">
|
||||||
<h1>{{ block('title') }}</h1>
|
<h1>{{ block('title') }} <small>({{ entries|length }})</small></h1>
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-12">
|
<div class="col-md-12">
|
||||||
|
@ -14,19 +14,39 @@
|
||||||
<form method="post" action="{{ url('/admin/logs') }}" class="form-inline">
|
<form method="post" action="{{ url('/admin/logs') }}" class="form-inline">
|
||||||
{{ csrf() }}
|
{{ csrf() }}
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-8">
|
||||||
{{ f.input('search', __('form.search'), {
|
{{ f.input('search', __('form.search'), {
|
||||||
'value': search,
|
'value': search,
|
||||||
'hide_label': true,
|
'hide_label': true,
|
||||||
}) }}
|
}) }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% if has_permission_to('logs.all') %}
|
||||||
|
<div class="col-md-4">
|
||||||
|
{{ f.select('search_user_id', __('general.user'), users, {
|
||||||
|
'default_option': __('form.user_select'),
|
||||||
|
'selected': search_user_id,
|
||||||
|
}) }}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
|
||||||
{{ f.submit(__('form.search'), {'icon_left': 'search'}) }}
|
{{ f.submit(__('form.search'), {'icon_left': 'search'}) }}
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{% if not has_permission_to('logs.all') %}
|
||||||
|
<div class="mb-3">
|
||||||
|
{{ m.alert(__('log.only_own')) }}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
<table class="table table-striped">
|
<table class="table table-striped">
|
||||||
<tr>
|
<tr>
|
||||||
<th>{{ __('log.time') }}</th>
|
<th>{{ __('log.time') }}</th>
|
||||||
<th>{{ __('log.level') }}</th>
|
<th>{{ __('log.level') }}</th>
|
||||||
|
<th>{{ __('general.user') }}</th>
|
||||||
<th>{{ __('log.message') }}</th>
|
<th>{{ __('log.message') }}</th>
|
||||||
</tr>
|
</tr>
|
||||||
{% for entry in entries %}
|
{% for entry in entries %}
|
||||||
|
@ -47,10 +67,11 @@
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
<td class="table-{{ td_type }}">{{ entry.created_at.format(__('general.datetime')) }}</td>
|
<td class="table-{{ td_type }} text-nowrap">{{ entry.created_at.format(__('general.datetime')) }}</td>
|
||||||
<td class="table-{{ td_type }}">
|
<td class="table-{{ td_type }} text-nowrap">
|
||||||
<span class="badge bg-{{ type }}">{{ entry.level|capitalize }}</span> <!-- //todo bs5 -->
|
<span class="badge bg-{{ type }}">{{ entry.level|capitalize }}</span> <!-- //todo bs5 -->
|
||||||
</td>
|
</td>
|
||||||
|
<td class="text-nowrap">{% if entry.user %}{{ m.user(entry.user) }}{% endif %}</td>
|
||||||
<td>{{ entry.message|nl2br }}</td>
|
<td>{{ entry.message|nl2br }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
|
@ -5,9 +5,12 @@ declare(strict_types=1);
|
||||||
namespace Engelsystem\Controllers\Admin;
|
namespace Engelsystem\Controllers\Admin;
|
||||||
|
|
||||||
use Engelsystem\Controllers\BaseController;
|
use Engelsystem\Controllers\BaseController;
|
||||||
|
use Engelsystem\Helpers\Authenticator;
|
||||||
use Engelsystem\Http\Request;
|
use Engelsystem\Http\Request;
|
||||||
use Engelsystem\Http\Response;
|
use Engelsystem\Http\Response;
|
||||||
use Engelsystem\Models\LogEntry;
|
use Engelsystem\Models\LogEntry;
|
||||||
|
use Engelsystem\Models\User\User;
|
||||||
|
use Illuminate\Support\Collection;
|
||||||
|
|
||||||
class LogsController extends BaseController
|
class LogsController extends BaseController
|
||||||
{
|
{
|
||||||
|
@ -16,18 +19,33 @@ class LogsController extends BaseController
|
||||||
'admin_log',
|
'admin_log',
|
||||||
];
|
];
|
||||||
|
|
||||||
public function __construct(protected LogEntry $log, protected Response $response)
|
public function __construct(protected LogEntry $log, protected Response $response, protected Authenticator $auth)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public function index(Request $request): Response
|
public function index(Request $request): Response
|
||||||
{
|
{
|
||||||
|
$searchUserId = (int) $request->input('search_user_id') ?: null;
|
||||||
$search = $request->input('search');
|
$search = $request->input('search');
|
||||||
$entries = $this->log->filter($search);
|
$userId = $this->auth->user()?->id;
|
||||||
|
|
||||||
|
if ($this->auth->can('logs.all')) {
|
||||||
|
$userId = $searchUserId;
|
||||||
|
}
|
||||||
|
|
||||||
|
$entries = $this->log->filter($search, $userId);
|
||||||
|
|
||||||
|
/** @var Collection $users */
|
||||||
|
$users = User::with('personalData')
|
||||||
|
->orderBy('name')
|
||||||
|
->get()
|
||||||
|
->mapWithKeys(function (User $u) {
|
||||||
|
return [$u->id => $u->displayName];
|
||||||
|
});
|
||||||
|
|
||||||
return $this->response->withView(
|
return $this->response->withView(
|
||||||
'admin/log.twig',
|
'admin/log.twig',
|
||||||
['entries' => $entries, 'search' => $search]
|
['entries' => $entries, 'search' => $search, 'users' => $users, 'search_user_id' => $searchUserId]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,7 +44,7 @@ class Logger extends AbstractLogger
|
||||||
$message .= $this->formatException($context['exception']);
|
$message .= $this->formatException($context['exception']);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->log->create(['level' => $level, 'message' => $message]);
|
$this->createEntry(['level' => $level, 'message' => $message]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -81,4 +81,9 @@ class Logger extends AbstractLogger
|
||||||
{
|
{
|
||||||
return in_array($level, $this->allowedLevels);
|
return in_array($level, $this->allowedLevels);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function createEntry(array $data): void
|
||||||
|
{
|
||||||
|
$this->log->create($data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,24 +5,21 @@ declare(strict_types=1);
|
||||||
namespace Engelsystem\Logger;
|
namespace Engelsystem\Logger;
|
||||||
|
|
||||||
use Engelsystem\Helpers\Authenticator;
|
use Engelsystem\Helpers\Authenticator;
|
||||||
use Psr\Log\InvalidArgumentException;
|
|
||||||
use Stringable;
|
|
||||||
|
|
||||||
class UserAwareLogger extends Logger
|
class UserAwareLogger extends Logger
|
||||||
{
|
{
|
||||||
protected Authenticator $auth;
|
protected ?Authenticator $auth;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logs with an arbitrary level and prepends the user
|
* Adds the authenticated user to the log message
|
||||||
* @throws InvalidArgumentException
|
|
||||||
*/
|
*/
|
||||||
public function log(mixed $level, string|Stringable $message, array $context = []): void
|
public function createEntry(array $data): void
|
||||||
{
|
{
|
||||||
if ($this->auth && ($user = $this->auth->user())) {
|
if ($this->auth && ($user = $this->auth->user())) {
|
||||||
$message = sprintf('%s (%u): %s', $user->name, $user->id, $message);
|
$data['user_id'] = $user->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
parent::log($level, $message, $context);
|
parent::createEntry($data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setAuth(Authenticator $auth): void
|
public function setAuth(Authenticator $auth): void
|
||||||
|
|
|
@ -5,6 +5,7 @@ declare(strict_types=1);
|
||||||
namespace Engelsystem\Models;
|
namespace Engelsystem\Models;
|
||||||
|
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
|
use Engelsystem\Models\User\UsesUserModel;
|
||||||
use Illuminate\Database\Eloquent\Builder;
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
use Illuminate\Database\Eloquent\Collection;
|
use Illuminate\Database\Eloquent\Collection;
|
||||||
use Illuminate\Database\Query\Builder as QueryBuilder;
|
use Illuminate\Database\Query\Builder as QueryBuilder;
|
||||||
|
@ -23,35 +24,48 @@ use Illuminate\Support\Collection as SupportCollection;
|
||||||
*/
|
*/
|
||||||
class LogEntry extends BaseModel
|
class LogEntry extends BaseModel
|
||||||
{
|
{
|
||||||
|
use UsesUserModel;
|
||||||
|
|
||||||
/** @var bool enable timestamps for created_at */
|
/** @var bool enable timestamps for created_at */
|
||||||
public $timestamps = true; // phpcs:ignore
|
public $timestamps = true; // phpcs:ignore
|
||||||
|
|
||||||
/** @var null Disable updated_at */
|
/** @var null Disable updated_at */
|
||||||
public const UPDATED_AT = null;
|
public const UPDATED_AT = null;
|
||||||
|
|
||||||
|
/** @var array<string, string> */
|
||||||
|
protected $casts = [ // phpcs:ignore
|
||||||
|
'user_id' => 'integer',
|
||||||
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The attributes that are mass assignable.
|
* The attributes that are mass assignable.
|
||||||
*/
|
*/
|
||||||
protected $fillable = [ // phpcs:ignore
|
protected $fillable = [ // phpcs:ignore
|
||||||
'level',
|
'level',
|
||||||
'message',
|
'message',
|
||||||
|
'user_id',
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Builder[]|Collection|SupportCollection|LogEntry[]
|
* @return Builder[]|Collection|SupportCollection|LogEntry[]
|
||||||
*/
|
*/
|
||||||
public static function filter(string $keyword = null): array|Collection|SupportCollection
|
public static function filter(?string $keyword = null, ?int $userId = null): array|Collection|SupportCollection
|
||||||
{
|
{
|
||||||
$query = self::query()
|
$query = self::with(['user', 'user.personalData', 'user.state'])
|
||||||
->select()
|
|
||||||
->orderByDesc('created_at')
|
->orderByDesc('created_at')
|
||||||
->orderByDesc('id')
|
->orderByDesc('id')
|
||||||
->limit(10000);
|
->limit(10000);
|
||||||
|
|
||||||
|
if (!empty($userId)) {
|
||||||
|
$query->where('user_id', $userId);
|
||||||
|
}
|
||||||
|
|
||||||
if (!empty($keyword)) {
|
if (!empty($keyword)) {
|
||||||
$query
|
$query
|
||||||
->where('level', '=', $keyword)
|
->where(function (Builder $query) use ($keyword): void {
|
||||||
|
$query->where('level', '=', $keyword)
|
||||||
->orWhere('message', 'LIKE', '%' . $keyword . '%');
|
->orWhere('message', 'LIKE', '%' . $keyword . '%');
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return $query->get();
|
return $query->get();
|
||||||
|
|
|
@ -4,10 +4,13 @@ declare(strict_types=1);
|
||||||
|
|
||||||
namespace Engelsystem\Test\Unit\Controllers\Admin;
|
namespace Engelsystem\Test\Unit\Controllers\Admin;
|
||||||
|
|
||||||
|
use Engelsystem\Config\Config;
|
||||||
use Engelsystem\Controllers\Admin\LogsController;
|
use Engelsystem\Controllers\Admin\LogsController;
|
||||||
|
use Engelsystem\Helpers\Authenticator;
|
||||||
use Engelsystem\Http\Request;
|
use Engelsystem\Http\Request;
|
||||||
use Engelsystem\Http\Response;
|
use Engelsystem\Http\Response;
|
||||||
use Engelsystem\Models\LogEntry;
|
use Engelsystem\Models\LogEntry;
|
||||||
|
use Engelsystem\Models\User\User;
|
||||||
use Engelsystem\Test\Unit\HasDatabase;
|
use Engelsystem\Test\Unit\HasDatabase;
|
||||||
use Engelsystem\Test\Unit\TestCase;
|
use Engelsystem\Test\Unit\TestCase;
|
||||||
use Illuminate\Database\Eloquent\Collection;
|
use Illuminate\Database\Eloquent\Collection;
|
||||||
|
@ -25,22 +28,36 @@ class LogsControllerTest extends TestCase
|
||||||
{
|
{
|
||||||
$log = new LogEntry();
|
$log = new LogEntry();
|
||||||
$alert = $log->create(['level' => LogLevel::ALERT, 'message' => 'Alert test']);
|
$alert = $log->create(['level' => LogLevel::ALERT, 'message' => 'Alert test']);
|
||||||
$alert = $log->find($alert)->first();
|
$alert = $log->with('user')->find($alert)->first();
|
||||||
$error = $log->create(['level' => LogLevel::ERROR, 'message' => 'Error test']);
|
$error = $log->create(['level' => LogLevel::ERROR, 'message' => 'Error test']);
|
||||||
$error = $log->find($error)->first();
|
$error = $log->with('user')->find($error)->first();
|
||||||
|
|
||||||
|
$auth = $this->createMock(Authenticator::class);
|
||||||
|
$this->setExpects($auth, 'user', null, null, 2);
|
||||||
|
$this->setExpects($auth, 'can', ['logs.all'], true, 2);
|
||||||
|
|
||||||
$response = $this->createMock(Response::class);
|
$response = $this->createMock(Response::class);
|
||||||
$response->expects($this->exactly(2))
|
$response->expects($this->exactly(2))
|
||||||
->method('withView')
|
->method('withView')
|
||||||
->withConsecutive(
|
->withConsecutive(
|
||||||
['admin/log.twig', ['entries' => new Collection([$error, $alert]), 'search' => null]],
|
['admin/log.twig', [
|
||||||
['admin/log.twig', ['entries' => new Collection([$error]), 'search' => 'error']]
|
'entries' => new Collection([$error, $alert]),
|
||||||
|
'search' => null,
|
||||||
|
'users' => new Collection(),
|
||||||
|
'search_user_id' => null,
|
||||||
|
]],
|
||||||
|
['admin/log.twig', [
|
||||||
|
'entries' => new Collection([$error]),
|
||||||
|
'search' => 'error',
|
||||||
|
'users' => new Collection(),
|
||||||
|
'search_user_id' => null,
|
||||||
|
]]
|
||||||
)
|
)
|
||||||
->willReturn($response);
|
->willReturn($response);
|
||||||
|
|
||||||
$request = Request::create('/');
|
$request = Request::create('/');
|
||||||
|
|
||||||
$controller = new LogsController($log, $response);
|
$controller = new LogsController($log, $response, $auth);
|
||||||
$controller->index($request);
|
$controller->index($request);
|
||||||
|
|
||||||
$request->request->set('search', 'error');
|
$request->request->set('search', 'error');
|
||||||
|
@ -48,12 +65,48 @@ class LogsControllerTest extends TestCase
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Setup the DB
|
* @covers \Engelsystem\Controllers\Admin\LogsController::index
|
||||||
|
*/
|
||||||
|
public function testIndexUser(): void
|
||||||
|
{
|
||||||
|
User::factory()->create();
|
||||||
|
$user = User::with(['personalData', 'state'])->first();
|
||||||
|
|
||||||
|
$log = new LogEntry();
|
||||||
|
$alert = $log->create(['level' => LogLevel::ALERT, 'message' => 'Users message', 'user_id' => $user->id]);
|
||||||
|
/** @var LogEntry $alert */
|
||||||
|
$alert = $log->with('user')->find($alert)->first();
|
||||||
|
$log->create(['level' => LogLevel::ERROR, 'message' => 'Error test']);
|
||||||
|
|
||||||
|
$auth = $this->createMock(Authenticator::class);
|
||||||
|
$this->setExpects($auth, 'user', null, $user);
|
||||||
|
$this->setExpects($auth, 'can', ['logs.all'], false);
|
||||||
|
|
||||||
|
$response = $this->createMock(Response::class);
|
||||||
|
$response->expects($this->once())
|
||||||
|
->method('withView')
|
||||||
|
->willReturnCallback(function (string $view, array $data) use ($alert, $response) {
|
||||||
|
$this->assertEquals('admin/log.twig', $view);
|
||||||
|
$this->assertArrayHasKey('entries', $data);
|
||||||
|
$this->assertCount(1, $data['entries']);
|
||||||
|
$this->assertEquals($alert->message, $data['entries'][0]['message']);
|
||||||
|
return $response;
|
||||||
|
});
|
||||||
|
|
||||||
|
$request = Request::create('/');
|
||||||
|
|
||||||
|
$controller = new LogsController($log, $response, $auth);
|
||||||
|
$controller->index($request);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up the DB
|
||||||
*/
|
*/
|
||||||
public function setUp(): void
|
public function setUp(): void
|
||||||
{
|
{
|
||||||
parent::setUp();
|
parent::setUp();
|
||||||
|
|
||||||
$this->initDatabase();
|
$this->initDatabase();
|
||||||
|
$this->app->instance('config', new Config([]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,6 +45,7 @@ class LoggerTest extends ServiceProviderTest
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @covers \Engelsystem\Logger\Logger::log
|
* @covers \Engelsystem\Logger\Logger::log
|
||||||
|
* @covers \Engelsystem\Logger\Logger::createEntry
|
||||||
* @dataProvider provideLogLevels
|
* @dataProvider provideLogLevels
|
||||||
*/
|
*/
|
||||||
public function testAllLevels(string $level): void
|
public function testAllLevels(string $level): void
|
||||||
|
|
|
@ -8,18 +8,23 @@ use Engelsystem\Helpers\Authenticator;
|
||||||
use Engelsystem\Logger\UserAwareLogger;
|
use Engelsystem\Logger\UserAwareLogger;
|
||||||
use Engelsystem\Models\LogEntry;
|
use Engelsystem\Models\LogEntry;
|
||||||
use Engelsystem\Models\User\User;
|
use Engelsystem\Models\User\User;
|
||||||
use Engelsystem\Test\Unit\ServiceProviderTest;
|
use Engelsystem\Test\Unit\HasDatabase;
|
||||||
|
use Engelsystem\Test\Unit\TestCase;
|
||||||
use PHPUnit\Framework\MockObject\MockObject;
|
use PHPUnit\Framework\MockObject\MockObject;
|
||||||
use Psr\Log\LogLevel;
|
use Psr\Log\LogLevel;
|
||||||
|
|
||||||
class UserAwareLoggerTest extends ServiceProviderTest
|
class UserAwareLoggerTest extends TestCase
|
||||||
{
|
{
|
||||||
|
use HasDatabase;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @covers \Engelsystem\Logger\UserAwareLogger::log
|
* @covers \Engelsystem\Logger\UserAwareLogger::createEntry
|
||||||
* @covers \Engelsystem\Logger\UserAwareLogger::setAuth
|
* @covers \Engelsystem\Logger\UserAwareLogger::setAuth
|
||||||
*/
|
*/
|
||||||
public function testLog(): void
|
public function testLog(): void
|
||||||
{
|
{
|
||||||
|
$this->initDatabase(); // To be able to run the test by itself
|
||||||
|
|
||||||
$user = User::factory(['id' => 1, 'name' => 'admin'])->make();
|
$user = User::factory(['id' => 1, 'name' => 'admin'])->make();
|
||||||
|
|
||||||
/** @var LogEntry|MockObject $logEntry */
|
/** @var LogEntry|MockObject $logEntry */
|
||||||
|
@ -30,7 +35,7 @@ class UserAwareLoggerTest extends ServiceProviderTest
|
||||||
->method('create')
|
->method('create')
|
||||||
->withConsecutive(
|
->withConsecutive(
|
||||||
[['level' => LogLevel::INFO, 'message' => 'Some more informational foo']],
|
[['level' => LogLevel::INFO, 'message' => 'Some more informational foo']],
|
||||||
[['level' => LogLevel::INFO, 'message' => 'admin (1): Some even more informational bar']]
|
[['level' => LogLevel::INFO, 'message' => 'Some even more informational bar', 'user_id' => 1]]
|
||||||
);
|
);
|
||||||
|
|
||||||
/** @var Authenticator|MockObject $auth */
|
/** @var Authenticator|MockObject $auth */
|
||||||
|
|
|
@ -5,6 +5,7 @@ declare(strict_types=1);
|
||||||
namespace Engelsystem\Test\Unit\Models;
|
namespace Engelsystem\Test\Unit\Models;
|
||||||
|
|
||||||
use Engelsystem\Models\LogEntry;
|
use Engelsystem\Models\LogEntry;
|
||||||
|
use Engelsystem\Models\User\User;
|
||||||
use Psr\Log\LogLevel;
|
use Psr\Log\LogLevel;
|
||||||
|
|
||||||
class LogEntryTest extends ModelTest
|
class LogEntryTest extends ModelTest
|
||||||
|
@ -14,6 +15,8 @@ class LogEntryTest extends ModelTest
|
||||||
*/
|
*/
|
||||||
public function testFilter(): void
|
public function testFilter(): void
|
||||||
{
|
{
|
||||||
|
$user = User::factory()->create();
|
||||||
|
(new LogEntry(['level' => LogLevel::DEBUG, 'message' => 'Some users fault', 'user_id' => $user->id]))->save();
|
||||||
foreach (
|
foreach (
|
||||||
[
|
[
|
||||||
'I\'m an info' => LogLevel::INFO,
|
'I\'m an info' => LogLevel::INFO,
|
||||||
|
@ -31,9 +34,10 @@ class LogEntryTest extends ModelTest
|
||||||
(new LogEntry(['level' => $level, 'message' => $message]))->save();
|
(new LogEntry(['level' => $level, 'message' => $message]))->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->assertCount(10, LogEntry::filter());
|
$this->assertCount(11, LogEntry::filter());
|
||||||
$this->assertCount(3, LogEntry::filter(LogLevel::INFO));
|
$this->assertCount(3, LogEntry::filter(LogLevel::INFO));
|
||||||
$this->assertCount(1, LogEntry::filter('Oops'));
|
$this->assertCount(1, LogEntry::filter('Oops'));
|
||||||
|
$this->assertCount(1, LogEntry::filter(null, $user->id));
|
||||||
|
|
||||||
/** @var LogEntry $first */
|
/** @var LogEntry $first */
|
||||||
$first = LogEntry::filter()->first();
|
$first = LogEntry::filter()->first();
|
||||||
|
|
Loading…
Reference in New Issue