Files
ephub/tests/Controller/DashboardControllerTest.php
T

175 lines
5.6 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Tests\Controller;
use App\Entity\Booking;
use App\Entity\Resource;
use App\Entity\User;
use App\Enum\ResourceType;
use App\Model\TimeRange;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\KernelBrowser;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
class DashboardControllerTest extends WebTestCase
{
private KernelBrowser $client;
private EntityManagerInterface $em;
protected function setUp(): void
{
$this->client = self::createClient(server: ['HTTPS' => true]);
$this->client->disableReboot();
$this->em = self::getContainer()->get(EntityManagerInterface::class);
$this->em->getConnection()->beginTransaction();
}
protected function tearDown(): void
{
$this->em->getConnection()->rollBack();
parent::tearDown();
}
/**
* The extensibility guarantee, asserted against the enum rather than against a fixed list:
* a new ResourceType case must produce a working tile without anyone editing a template.
*/
public function testThereIsATileForEveryBookableKind(): void
{
$this->client->loginUser($this->user());
$crawler = $this->client->request('GET', '/');
self::assertResponseIsSuccessful();
foreach (ResourceType::cases() as $type) {
self::assertCount(
1,
$crawler->filter(\sprintf('a[href="/book/%s"]', $type->value)),
\sprintf('no dashboard tile links to the %s board', $type->value),
);
self::assertStringContainsString($type->plural(), $crawler->html());
}
}
/**
* The bookings list is only reachable from here now that the sidebar is gone.
*/
public function testTheDashboardLinksToTheBookingsList(): void
{
$this->client->loginUser($this->user());
$crawler = $this->client->request('GET', '/');
self::assertCount(1, $crawler->filter('a[href="/bookings"]'));
}
public function testTheNavigationIsGone(): void
{
$this->client->loginUser($this->user());
$crawler = $this->client->request('GET', '/');
self::assertCount(0, $crawler->filter('#mobilenav'));
self::assertCount(1, $crawler->filter('a[href="/logout"]'));
}
public function testATileCountsWhatIsStillFreeToday(): void
{
$user = $this->user();
$today = new \DateTimeImmutable('today');
$this->resource('D1');
$taken = $this->resource('D2');
$this->em->persist(new Booking($this->user('[email protected]'), $taken, $today));
$this->em->flush();
$this->client->loginUser($user);
$crawler = $this->client->request('GET', '/');
$tile = $crawler->filter('a[href="/book/desk"]')->text();
self::assertStringContainsString('von 2 heute frei', $tile);
self::assertStringContainsString('1', $tile);
}
/**
* A part-day booking still makes the resource "not free today" -- the dashboard has no span
* to qualify the answer with, so it takes the whole day.
*/
public function testAPartDayBookingCountsAsTakenForTheDay(): void
{
$desk = $this->resource('D1');
$this->em->persist(new Booking($this->user('[email protected]'), $desk, new \DateTimeImmutable('today'), TimeRange::fromMinutes(540, 780)));
$this->em->flush();
$this->client->loginUser($this->user());
$crawler = $this->client->request('GET', '/');
self::assertStringContainsString('heute alles belegt', $crawler->filter('a[href="/book/desk"]')->text());
}
public function testYourOwnBookingIsCalledOutOnTheTile(): void
{
$user = $this->user();
$this->em->persist(new Booking($user, $this->resource('D1'), new \DateTimeImmutable('today')));
$this->em->flush();
$this->client->loginUser($user);
$crawler = $this->client->request('GET', '/');
self::assertStringContainsString('D1', $crawler->filter('a[href="/book/desk"]')->text());
}
public function testABoardOnlyShowsItsOwnKindOfResource(): void
{
$this->resource('D1');
$this->resource('P1', ResourceType::PARKING);
$this->client->loginUser($this->user());
$desks = $this->client->request('GET', '/book/desk')->html();
self::assertStringContainsString('D1', $desks);
self::assertStringNotContainsString('P1', $desks);
$parking = $this->client->request('GET', '/book/parking')->html();
self::assertStringContainsString('P1', $parking);
self::assertStringNotContainsString('D1', $parking);
}
public function testAnUnknownBookingAreaIsNotFound(): void
{
$this->client->loginUser($this->user());
$this->client->request('GET', '/book/bikes');
self::assertResponseStatusCodeSame(404);
}
public function testABoardWithNothingSetUpSaysSo(): void
{
$this->client->loginUser($this->user());
self::assertStringContainsString(
'noch nichts eingerichtet',
$this->client->request('GET', '/book/parking')->html(),
);
}
private function user(string $email = '[email protected]'): User
{
$user = new User($email, 'Test');
$user->setRoles(['ROLE_EMPLOYEE']);
$this->em->persist($user);
$this->em->flush();
return $user;
}
private function resource(string $label, ResourceType $type = ResourceType::DESK): Resource
{
$resource = new Resource($type, $label);
$this->em->persist($resource);
$this->em->flush();
return $resource;
}
}