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

221 lines
7.8 KiB
PHP

<?php
declare(strict_types=1);
namespace Engelsystem\Test\Unit\Controllers\Admin;
use Engelsystem\Controllers\Admin\RoomsController;
use Engelsystem\Events\EventDispatcher;
use Engelsystem\Helpers\Carbon;
use Engelsystem\Http\Exceptions\ValidationException;
use Engelsystem\Http\Redirector;
use Engelsystem\Http\Validation\Validator;
use Engelsystem\Models\AngelType;
use Engelsystem\Models\Room;
use Engelsystem\Models\Shifts\NeededAngelType;
use Engelsystem\Models\Shifts\Shift;
use Engelsystem\Models\Shifts\ShiftEntry;
use Engelsystem\Models\User\User;
use Engelsystem\Test\Unit\Controllers\ControllerTest;
use PHPUnit\Framework\MockObject\MockObject;
class RoomsControllerTest extends ControllerTest
{
protected Redirector|MockObject $redirect;
/**
* @covers \Engelsystem\Controllers\Admin\RoomsController::__construct
* @covers \Engelsystem\Controllers\Admin\RoomsController::index
*/
public function testIndex(): void
{
/** @var RoomsController $controller */
$controller = $this->app->make(RoomsController::class);
Room::factory(5)->create();
$this->response->expects($this->once())
->method('withView')
->willReturnCallback(function (string $view, array $data) {
$this->assertEquals('admin/rooms/index', $view);
$this->assertTrue($data['is_index'] ?? false);
$this->assertCount(5, $data['rooms'] ?? []);
return $this->response;
});
$controller->index();
}
/**
* @covers \Engelsystem\Controllers\Admin\RoomsController::edit
* @covers \Engelsystem\Controllers\Admin\RoomsController::showEdit
*/
public function testEdit(): void
{
/** @var RoomsController $controller */
$controller = $this->app->make(RoomsController::class);
/** @var Room $room */
$room = Room::factory()->create();
$angelTypes = AngelType::factory(3)->create();
(new NeededAngelType(['room_id' => $room->id, 'angel_type_id' => $angelTypes[0]->id, 'count' => 3]))->save();
$this->response->expects($this->once())
->method('withView')
->willReturnCallback(function (string $view, array $data) use ($room) {
$this->assertEquals('admin/rooms/edit', $view);
$this->assertEquals($room->id, $data['room']?->id);
$this->assertCount(3, $data['angel_types'] ?? []);
$this->assertCount(1, $data['needed_angel_types'] ?? []);
return $this->response;
});
$this->request = $this->request->withAttribute('room_id', 1);
$controller->edit($this->request);
}
/**
* @covers \Engelsystem\Controllers\Admin\RoomsController::edit
* @covers \Engelsystem\Controllers\Admin\RoomsController::showEdit
*/
public function testEditNew(): void
{
/** @var RoomsController $controller */
$controller = $this->app->make(RoomsController::class);
AngelType::factory(3)->create();
$this->response->expects($this->once())
->method('withView')
->willReturnCallback(function (string $view, array $data) {
$this->assertEquals('admin/rooms/edit', $view);
$this->assertEmpty($data['room'] ?? []);
$this->assertCount(3, $data['angel_types'] ?? []);
$this->assertEmpty($data['needed_angel_types'] ?? []);
return $this->response;
});
$controller->edit($this->request);
}
/**
* @covers \Engelsystem\Controllers\Admin\RoomsController::save
*/
public function testSave(): void
{
/** @var RoomsController $controller */
$controller = $this->app->make(RoomsController::class);
$controller->setValidator(new Validator());
AngelType::factory(3)->create();
$this->setExpects($this->redirect, 'to', ['/admin/rooms']);
$this->request = $this->request->withParsedBody([
'name' => 'Testroom',
'description' => 'Something',
'dect' => 'DECTNR',
'map_url' => 'https://osm.url/#map=h/x/y',
'angel_type_1' => '0',
'angel_type_2' => '3',
]);
$controller->save($this->request);
$this->assertTrue($this->log->hasInfoThatContains('Updated room'));
$this->assertHasNotification('room.edit.success');
$this->assertCount(1, Room::whereName('Testroom')->get());
$neededAngelType = NeededAngelType::whereRoomId(1)
->where('angel_type_id', 2)
->where('count', 3)
->get();
$this->assertCount(1, $neededAngelType);
}
/**
* @covers \Engelsystem\Controllers\Admin\RoomsController::save
*/
public function testSaveUniqueName(): void
{
/** @var RoomsController $controller */
$controller = $this->app->make(RoomsController::class);
$controller->setValidator(new Validator());
Room::factory()->create(['name' => 'Testroom']);
$this->request = $this->request->withParsedBody([
'name' => 'Testroom',
]);
$this->expectException(ValidationException::class);
$controller->save($this->request);
}
/**
* @covers \Engelsystem\Controllers\Admin\RoomsController::save
* @covers \Engelsystem\Controllers\Admin\RoomsController::delete
*/
public function testSaveDelete(): void
{
/** @var RoomsController $controller */
$controller = $this->app->make(RoomsController::class);
$controller->setValidator(new Validator());
/** @var Room $room */
$room = Room::factory()->create();
$this->request = $this->request->withParsedBody([
'id' => '1',
'delete' => '1',
]);
$controller->save($this->request);
$this->assertEmpty(Room::find($room->id));
}
/**
* @covers \Engelsystem\Controllers\Admin\RoomsController::delete
*/
public function testDelete(): void
{
/** @var EventDispatcher|MockObject $dispatcher */
$dispatcher = $this->createMock(EventDispatcher::class);
$this->app->instance('events.dispatcher', $dispatcher);
/** @var RoomsController $controller */
$controller = $this->app->make(RoomsController::class);
$controller->setValidator(new Validator());
/** @var Room $room */
$room = Room::factory()->create();
/** @var Shift $shift */
$shift = Shift::factory()->create(['room_id' => $room->id, 'start' => Carbon::create()->subHour()]);
/** @var User $user */
$user = User::factory()->create(['name' => 'foo', 'email' => 'lorem@ipsum']);
/** @var ShiftEntry $shiftEntry */
ShiftEntry::factory()->create(['shift_id' => $shift->id, 'user_id' => $user->id]);
$this->setExpects($this->redirect, 'to', ['/admin/rooms'], $this->response);
$dispatcher->expects($this->once())
->method('dispatch')
->willReturnCallback(function (string $event, array $data) use ($room, $user) {
$this->assertEquals('shift.entry.deleting', $event);
$this->assertEquals($room->id, $data['room']->id);
$this->assertEquals($user->id, $data['user']->id);
return [];
});
$this->request = $this->request->withParsedBody(['id' => 1, 'delete' => '1']);
$controller->delete($this->request);
$this->assertNull(Room::find($room->id));
$this->assertTrue($this->log->hasInfoThatContains('Deleted room'));
$this->assertHasNotification('room.delete.success');
}
public function setUp(): void
{
parent::setUp();
$this->redirect = $this->createMock(Redirector::class);
$this->app->instance(Redirector::class, $this->redirect);
}
}