175 lines
5.7 KiB
PHP
175 lines
5.7 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Tests\Controller;
|
|
|
|
use App\Booking\TimeRange;
|
|
use App\Entity\Booking;
|
|
use App\Entity\Resource;
|
|
use App\Entity\ResourceType;
|
|
use App\Entity\User;
|
|
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();
|
|
$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', svgElementId: 'desk-01');
|
|
$this->resource('P1', ResourceType::PARKING, 'parking-01');
|
|
|
|
$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, ?string $svgElementId = null): Resource
|
|
{
|
|
$resource = new Resource($type, $label, $svgElementId);
|
|
$this->em->persist($resource);
|
|
$this->em->flush();
|
|
|
|
return $resource;
|
|
}
|
|
}
|