engelsystem/tests/Unit/Controllers/Admin/UserWorkLogControllerTest.php

396 lines
15 KiB
PHP
Raw Normal View History

2022-12-08 17:40:24 +01:00
<?php
declare(strict_types=1);
2022-12-08 17:40:24 +01:00
namespace Engelsystem\Test\Unit\Controllers\Admin;
use Carbon\Carbon;
use Engelsystem\Controllers\Admin\UserWorkLogController;
use Engelsystem\Helpers\Authenticator;
use Engelsystem\Http\Exceptions\HttpNotFound;
use Engelsystem\Http\Exceptions\ValidationException;
use Engelsystem\Http\Redirector;
use Engelsystem\Http\UrlGenerator;
use Engelsystem\Http\Validation\Validator;
use Engelsystem\Models\User\User;
use Engelsystem\Models\Worklog;
use Engelsystem\Test\Unit\Controllers\ControllerTest;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use PHPUnit\Framework\MockObject\MockObject;
class UserWorkLogControllerTest extends ControllerTest
{
protected Authenticator|MockObject $auth;
2022-12-08 17:40:24 +01:00
protected Redirector|MockObject $redirect;
2022-12-08 17:40:24 +01:00
protected User $user;
2022-12-08 17:40:24 +01:00
protected UserWorkLogController $controller;
2022-12-08 17:40:24 +01:00
/**
* @covers \Engelsystem\Controllers\Admin\UserWorkLogController::editWorklog
*/
public function testShowAddWorklogWithUnknownUserIdThrows(): void
2022-12-08 17:40:24 +01:00
{
$request = $this->request->withAttribute('user_id', 1234);
2022-12-08 17:40:24 +01:00
$this->expectException(ModelNotFoundException::class);
$this->controller->editWorklog($request);
}
/**
* @covers \Engelsystem\Controllers\Admin\UserWorkLogController::editWorklog
* @covers \Engelsystem\Controllers\Admin\UserWorkLogController::__construct
* @covers \Engelsystem\Controllers\Admin\UserWorkLogController::showEditWorklog
*/
public function testShowAddWorklog(): void
2022-12-08 17:40:24 +01:00
{
$request = $this->request->withAttribute('user_id', $this->user->id);
2022-12-08 17:40:24 +01:00
$this->response->expects($this->once())
->method('withView')
->willReturnCallback(function (string $view, array $data) {
$this->assertEquals('admin/user/edit-worklog.twig', $view);
$this->assertEquals($this->user->id, $data['user']->id);
$this->assertEquals(Carbon::today(), $data['work_date']);
$this->assertEquals(0, $data['work_hours']);
$this->assertEquals('', $data['comment']);
$this->assertFalse($data['is_edit']);
return $this->response;
});
$this->controller->editWorklog($request);
}
/**
* @covers \Engelsystem\Controllers\Admin\UserWorkLogController::editWorklog
* @covers \Engelsystem\Controllers\Admin\UserWorkLogController::getWorkDateSuggestion
*
* @dataProvider buildupConfigsAndWorkDates
*/
public function testShowAddWorklogWithSuggestedWorkDate(
Carbon|null $buildup_start,
Carbon|null $event_start,
Carbon $suggested_work_date
): void {
$request = $this->request->withAttribute('user_id', $this->user->id);
2022-12-08 17:40:24 +01:00
config(['buildup_start' => $buildup_start]);
config(['event_start' => $event_start]);
$this->response->expects($this->once())
->method('withView')
->willReturnCallback(function (string $view, array $data) use ($suggested_work_date) {
$this->assertEquals($suggested_work_date, $data['work_date']);
return $this->response;
});
$this->controller->editWorklog($request);
}
/**
* @covers \Engelsystem\Controllers\Admin\UserWorkLogController::editWorklog
*/
public function testShowEditWorklogWithWorkLogNotAssociatedToUserThrows(): void
2022-12-08 17:40:24 +01:00
{
/** @var User $user2 */
$user2 = User::factory()->create();
/** @var Worklog $worklog */
$worklog = Worklog::factory(['user_id' => $user2->id])->create();
$request = $this->request
->withAttribute('user_id', $this->user->id)
2022-12-08 17:40:24 +01:00
->withAttribute('worklog_id', $worklog->id);
$this->expectException(HttpNotFound::class);
$this->controller->editWorklog($request);
}
/**
* @covers \Engelsystem\Controllers\Admin\UserWorkLogController::editWorklog
*/
public function testShowEditWorklog(): void
2022-12-08 17:40:24 +01:00
{
/** @var Worklog $worklog */
$worklog = Worklog::factory([
'user_id' => $this->user->id,
'worked_at' => new Carbon('2022-01-01'),
'hours' => 3.14,
'comment' => 'a comment'
])->create();
$request = $this->request
->withAttribute('user_id', $this->user->id)
2022-12-08 17:40:24 +01:00
->withAttribute('worklog_id', $worklog->id);
$this->response->expects($this->once())
->method('withView')
->willReturnCallback(function (string $view, array $data) {
$this->assertEquals($this->user->id, $data['user']->id);
$this->assertEquals(new Carbon('2022-01-01'), $data['work_date']);
$this->assertEquals(3.14, $data['work_hours']);
$this->assertEquals('a comment', $data['comment']);
$this->assertTrue($data['is_edit']);
return $this->response;
});
$this->controller->editWorklog($request);
}
/**
* @covers \Engelsystem\Controllers\Admin\UserWorkLogController::saveWorklog
*/
public function testSaveWorklogWithUnkownUserIdThrows(): void
2022-12-08 17:40:24 +01:00
{
$request = $this->request->withAttribute('user_id', 1234)->withParsedBody([]);
2022-12-08 17:40:24 +01:00
$this->expectException(ModelNotFoundException::class);
$this->controller->saveWorklog($request);
}
/**
* @covers \Engelsystem\Controllers\Admin\UserWorkLogController::saveWorklog
*
* @dataProvider invalidSaveWorkLogParams
*/
public function testSaveWorklogWithInvalidParamsThrows(array $body): void
2022-12-08 17:40:24 +01:00
{
$request = $this->request->withAttribute('user_id', $this->user->id)->withParsedBody($body);
2022-12-08 17:40:24 +01:00
$this->expectException(ValidationException::class);
$this->controller->saveWorklog($request);
}
/**
* @covers \Engelsystem\Controllers\Admin\UserWorkLogController::saveWorklog
*/
public function testSaveNewWorklog(): void
2022-12-08 17:40:24 +01:00
{
$work_date = Carbon::today();
$work_hours = 3.14;
$comment = str_repeat('X', 200);
$body = ['work_date' => $work_date, 'work_hours' => $work_hours, 'comment' => $comment];
$request = $this->request->withAttribute('user_id', $this->user->id)->withParsedBody($body);
2022-12-08 17:40:24 +01:00
$this->setExpects($this->auth, 'user', null, $this->user, $this->any());
$this->redirect->expects($this->once())
->method('to')
->with('/users?action=view&user_id=' . $this->user->id)
->willReturn($this->response);
$this->controller->saveWorklog($request);
$this->assertHasNotification('worklog.add.success');
$this->assertEquals(1, $this->user->worklogs->count());
$new_worklog = $this->user->worklogs[0];
$this->assertEquals($this->user->id, $new_worklog->user->id);
$this->assertEquals($work_date, $new_worklog->worked_at);
$this->assertEquals($work_hours, $new_worklog->hours);
$this->assertEquals($comment, $new_worklog->comment);
}
/**
* @covers \Engelsystem\Controllers\Admin\UserWorkLogController::saveWorklog
*/
public function testOverwriteWorklogWithUnknownWorkLogIdThrows(): void
2022-12-08 17:40:24 +01:00
{
$body = ['work_date' => Carbon::today(), 'work_hours' => 3.14, 'comment' => 'a comment'];
$request = $this->request
->withAttribute('user_id', $this->user->id)
2022-12-08 17:40:24 +01:00
->withAttribute('worklog_id', 1234)
->withParsedBody($body);
$this->expectException(ModelNotFoundException::class);
$this->controller->saveWorklog($request);
}
/**
* @covers \Engelsystem\Controllers\Admin\UserWorkLogController::saveWorklog
*/
public function testOverwriteWorklogWithWorkLogNotAssociatedToUserThrows(): void
2022-12-08 17:40:24 +01:00
{
/** @var User $user2 */
$user2 = User::factory()->create();
/** @var Worklog $worklog */
$worklog = Worklog::factory(['user_id' => $user2->id])->create();
$body = ['work_date' => Carbon::today(), 'work_hours' => 3.14, 'comment' => 'a comment'];
$request = $this->request
->withAttribute('user_id', $this->user->id)
2022-12-08 17:40:24 +01:00
->withAttribute('worklog_id', $worklog->id)
->withParsedBody($body);
$this->expectException(HttpNotFound::class);
$this->controller->saveWorklog($request);
}
/**
* @covers \Engelsystem\Controllers\Admin\UserWorkLogController::saveWorklog
*/
public function testOverwriteWorklog(): void
2022-12-08 17:40:24 +01:00
{
/** @var Worklog $worklog */
$worklog = Worklog::factory(['user_id' => $this->user->id])->create();
$work_date = Carbon::today();
$work_hours = 3.14;
$comment = str_repeat('X', 200);
$body = ['work_date' => $work_date, 'work_hours' => $work_hours, 'comment' => $comment];
$request = $this->request
->withAttribute('user_id', $this->user->id)
2022-12-08 17:40:24 +01:00
->withAttribute('worklog_id', $worklog->id)
->withParsedBody($body);
$this->setExpects($this->auth, 'user', null, $this->user, $this->any());
$this->redirect->expects($this->once())
->method('to')
->with('/users?action=view&user_id=' . $this->user->id)
->willReturn($this->response);
$this->controller->saveWorklog($request);
$this->assertHasNotification('worklog.edit.success');
$worklog = Worklog::find($worklog->id);
$this->assertEquals($work_date, $worklog->worked_at);
$this->assertEquals($work_hours, $worklog->hours);
$this->assertEquals($comment, $worklog->comment);
}
/**
* @covers \Engelsystem\Controllers\Admin\UserWorkLogController::showDeleteWorklog
*/
public function testShowDeleteWorklogWithWorkLogNotAssociatedToUserThrows(): void
2022-12-08 17:40:24 +01:00
{
/** @var User $user2 */
$user2 = User::factory()->create();
/** @var Worklog $worklog */
$worklog = Worklog::factory(['user_id' => $user2->id])->create();
$request = $this->request
->withAttribute('user_id', $this->user->id)
2022-12-08 17:40:24 +01:00
->withAttribute('worklog_id', $worklog->id);
$this->expectException(HttpNotFound::class);
$this->controller->showDeleteWorklog($request);
}
/**
* @covers \Engelsystem\Controllers\Admin\UserWorkLogController::showDeleteWorklog
*/
public function testShowDeleteWorklog(): void
2022-12-08 17:40:24 +01:00
{
/** @var Worklog $worklog */
$worklog = Worklog::factory(['user_id' => $this->user->id])->create();
$request = $this->request
->withAttribute('user_id', $this->user->id)
2022-12-08 17:40:24 +01:00
->withAttribute('worklog_id', $worklog->id);
$this->response->expects($this->once())
->method('withView')
->willReturnCallback(function (string $view, array $data) {
$this->assertEquals($this->user->id, $data['user']->id);
return $this->response;
});
$this->controller->showDeleteWorklog($request);
}
/**
* @covers \Engelsystem\Controllers\Admin\UserWorkLogController::deleteWorklog
*/
public function testDeleteWorklogWithUnknownWorkLogIdThrows(): void
2022-12-08 17:40:24 +01:00
{
$request = $this->request
->withAttribute('user_id', $this->user->id)
2022-12-08 17:40:24 +01:00
->withAttribute('worklog_id', 1234);
$this->expectException(ModelNotFoundException::class);
$this->controller->deleteWorklog($request);
}
/**
* @covers \Engelsystem\Controllers\Admin\UserWorkLogController::deleteWorklog
*/
public function testDeleteWorklogWithWorkLogNotAssociatedToUserThrows(): void
2022-12-08 17:40:24 +01:00
{
/** @var User $user2 */
$user2 = User::factory()->create();
/** @var Worklog $worklog */
$worklog = Worklog::factory(['user_id' => $user2->id])->create();
$request = $this->request
->withAttribute('user_id', $this->user->id)
2022-12-08 17:40:24 +01:00
->withAttribute('worklog_id', $worklog->id);
$this->expectException(HttpNotFound::class);
$this->controller->deleteWorklog($request);
}
/**
* @covers \Engelsystem\Controllers\Admin\UserWorkLogController::deleteWorklog
*/
public function testDeleteWorklog(): void
2022-12-08 17:40:24 +01:00
{
/** @var Worklog $worklog */
$worklog = Worklog::factory(['user_id' => $this->user->id])->create();
$request = $this->request
->withAttribute('user_id', $this->user->id)
2022-12-08 17:40:24 +01:00
->withAttribute('worklog_id', $worklog->id);
$this->setExpects($this->auth, 'user', null, $this->user, $this->any());
$this->redirect->expects($this->once())
->method('to')
->with('/users?action=view&user_id=' . $this->user->id)
->willReturn($this->response);
$this->controller->deleteWorklog($request);
$this->assertHasNotification('worklog.delete.success');
$worklog = Worklog::find($worklog->id);
$this->assertNull($worklog);
}
/**
* @return array[]
*/
public function invalidSaveWorkLogParams(): array
{
$today = Carbon::today();
return [
// missing work_date
[['work_hours' => 3.14, 'comment' => 'com']],
// missing work_hours
[['work_date' => $today, 'comment' => 'com']],
// missing comment
[['work_date' => $today, 'work_hours' => 3.14]],
// too low work_hours
[['work_date' => $today, 'work_hours' => -.1, 'comment' => 'com']],
// too low work_hours
[['work_date' => $today, 'work_hours' => 3.14, 'comment' => str_repeat('X', 201)]],
];
}
/**
* @return array[]
*/
public function buildupConfigsAndWorkDates(): array
{
$day_before_yesterday = Carbon::today()->subDays(2);
$yesterday = Carbon::yesterday();
$today = Carbon::today();
$tomorrow = Carbon::tomorrow();
// buildup_start, event_start, suggested work date
return [
[null, null, $today],
[$yesterday, null, $yesterday],
[$yesterday, $tomorrow, $today],
[$day_before_yesterday, $yesterday, $day_before_yesterday],
];
}
/**
* Setup environment
*/
public function setUp(): void
{
parent::setUp();
$this->app->bind('http.urlGenerator', UrlGenerator::class);
$this->auth = $this->createMock(Authenticator::class);
$this->app->instance(Authenticator::class, $this->auth);
$this->redirect = $this->createMock(Redirector::class);
$this->app->instance(Redirector::class, $this->redirect);
$this->user = User::factory()->create();
$this->setExpects($this->auth, 'user', null, $this->user, $this->any());
$this->controller = $this->app->make(UserWorkLogController::class);
$this->controller->setValidator(new Validator());
}
}