diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index fdafbbedbe147a87acd9a0d138230b756f873c1c..1afa771b38392d91c5f070aadaaa520609937906 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -10,6 +10,7 @@ variables: stages: - build - test + - coverage - deploy build_web_backend: @@ -60,7 +61,7 @@ test_web_backend_database: - vendor/bin/phpunit --testsuite Database generate_api_docs: - stage: test + stage: coverage script: - cd src/backend - "if (php artisan apidoc:generate | grep \"Exception\") then echo \"Failed to generate API docs.\" && false; else true; fi" @@ -69,6 +70,16 @@ generate_api_docs: - src/backend/public/docs expire_in: 1 day +generate_code_coverage: + stage: coverage + script: + - cd src/backend + - phpdbg -qrr -d memory_limit=256M vendor/bin/phpunit --coverage-html cov + artifacts: + paths: + - src/backend/cov + expire_in: 30 days + deploy_backend_production: stage: deploy before_script: diff --git a/php/dev.ini b/php/dev.ini index 66192d154a4db333ad7187e8f2934d1598912552..a1a02ec9c1f1a98f7215760852ac823aefd3d2ac 100644 --- a/php/dev.ini +++ b/php/dev.ini @@ -12,3 +12,4 @@ xdebug.remote.mode=req xdebug.remote.handler=dbgp date.timezone = "America/Los_Angeles" +memory_limit = 256M diff --git a/php/prod.ini b/php/prod.ini index 52e86d2a8d26b15155522cac92da87fdc8805e65..02e4b50eeb6c09185cf06c58605ce6f144dee538 100644 --- a/php/prod.ini +++ b/php/prod.ini @@ -1 +1,2 @@ date.timezone = "America/Los_Angeles" +memory_limit = 256M diff --git a/src/backend/app/Http/Controllers/ApiController.php b/src/backend/app/Http/Controllers/ApiController.php index c0454b11ddc1a1e6e15792ac024bea0e49476d73..9727e7e19f500f38d58c0ac6c1b42cdef07c0458 100644 --- a/src/backend/app/Http/Controllers/ApiController.php +++ b/src/backend/app/Http/Controllers/ApiController.php @@ -38,17 +38,6 @@ abstract class ApiController extends Controller $this->status = $code; } - /** - * @return \Illuminate\Http\JsonResponse - */ - public function respondSuccess(): JsonResponse - { - return new JsonResponse([ - 'status' => 'success', - 'code' => $this->status, - ], $this->status); - } - /** * @param array $data * @return JsonResponse @@ -56,7 +45,7 @@ abstract class ApiController extends Controller public function respondWithData(array $data): JsonResponse { return new JsonResponse(array_merge($data, [ - 'status' => 'success', + 'status' => $this->status === 200 ? 'success' : 'error', 'code' => $this->status, ]), $this->status); } @@ -65,7 +54,7 @@ abstract class ApiController extends Controller { return new JsonResponse([ 'message' => $message, - 'status' => 'success', + 'status' => $this->status === 200 ? 'success' : 'error', 'code' => $this->status, ], $this->status); } diff --git a/src/backend/app/Http/Controllers/DoorsController.php b/src/backend/app/Http/Controllers/DoorsController.php index 985f38f423bc017575eaacb9f31a807928d34c59..f8830f6e17885a75226d46a3e2d83ba6b28155fb 100644 --- a/src/backend/app/Http/Controllers/DoorsController.php +++ b/src/backend/app/Http/Controllers/DoorsController.php @@ -51,7 +51,7 @@ class DoorsController extends ApiController $this->authorizer->protect(Permissions::MANAGE_DOORS); $this->validate($this->request, [ - 'query' => 'string', + 'query' => 'nullable|string', ]); $presenter = new GetAllDoorsAPIPresenter(); diff --git a/src/backend/app/Http/Controllers/OverridesController.php b/src/backend/app/Http/Controllers/OverridesController.php index aa66668a7536d08e3736ebd5296e3f62ee42dc4f..5fbcae5a86dfbbc4f4d27ad27492699dd50edeef 100644 --- a/src/backend/app/Http/Controllers/OverridesController.php +++ b/src/backend/app/Http/Controllers/OverridesController.php @@ -153,10 +153,10 @@ class OverridesController extends ApiController $this->authorizer->protect(Permissions::LOGS_READ); $this->validate($this->request, [ - 'start' => 'date', - 'end' => 'date', - 'door_id' => 'integer', - 'user_id' => 'integer', + 'start' => 'nullable|date', + 'end' => 'nullable|date', + 'door_id' => 'nullable|integer', + 'user_id' => 'nullable|integer', ]); $presenter = new ApiPresenter(); diff --git a/src/backend/app/Http/Controllers/SchedulesController.php b/src/backend/app/Http/Controllers/SchedulesController.php index 962836f016939bc9138ddcddc85a90fc5fa6425c..d7442c3ae08771ddaf8f9b9bdd8e4f9bbfd1e85d 100644 --- a/src/backend/app/Http/Controllers/SchedulesController.php +++ b/src/backend/app/Http/Controllers/SchedulesController.php @@ -32,7 +32,7 @@ class SchedulesController extends ApiController * * * @authenticated - * @bodyParam duration integer required The duration in minutes that the event lasts for. Example: 120 + * @bodyParam duration integer required The duration in seconds that the event lasts for. Example: 120 * @bodyParam group_id integer required The group to apply the schedule for. Example: 8 * @bodyParam type integer required The type of schedule. Example: 0 * @bodyParam rset string required The RFC 5545 compliant string representing the set. Example: RRULE:FREQ=MINUTELY @@ -49,10 +49,10 @@ class SchedulesController extends ApiController $this->authorizer->protect(Permissions::MANAGE_DOORS); $this->validate($this->request, [ - 'duration' => 'required|integer', /* miliseconds */ + 'duration' => 'required|integer', 'group_id' => 'required|integer', - 'type' => 'required|integer', /* 0 = Open, 1 = UserAccess */ - 'rset' => 'required|string', /* RFC RSet (NOT FULLY COMPLIANT!) */ + 'type' => 'required|integer', + 'rset' => 'required|string', 'description' => 'required|string|max:1024', ]); @@ -115,10 +115,10 @@ class SchedulesController extends ApiController $this->authorizer->protect(Permissions::MANAGE_DOORS); $this->validate($this->request, [ - 'start' => 'date', - 'end' => 'date', - 'type' => 'integer', - 'group_id' => 'integer', + 'start' => 'nullable|date', + 'end' => 'nullable|date', + 'type' => 'nullable|integer', + 'group_id' => 'nullable|integer', ]); $presenter = new SchedulesGetApiPresenter(); @@ -147,7 +147,7 @@ class SchedulesController extends ApiController * * @authenticated * @urlParam scheduleId required The schedule to update. Example: 1 - * @bodyParam duration integer The duration in minutes that the event lasts for. Example: 120 + * @bodyParam duration integer The duration in seconds that the event lasts for. Example: 120 * @bodyParam group_id integer The group to apply the schedule for. Example: 8 * @bodyParam type integer The type of schedule. Example: 0 * @bodyParam rset string The RFC 5545 compliant string representing the set. Example: RRULE:FREQ=MINUTELY @@ -165,11 +165,11 @@ class SchedulesController extends ApiController $this->authorizer->protect(Permissions::MANAGE_DOORS); $this->validate($this->request, [ - 'duration' => 'integer', - 'group_id' => 'integer', - 'type' => 'integer', - 'rset' => 'string', - 'description' => 'string|max:1024', + 'duration' => 'nullable|integer', + 'group_id' => 'nullable|integer', + 'type' => 'nullable|integer', + 'rset' => 'nullable|string', + 'description' => 'nullable|string|max:1024', ]); $presenter = new ScheduleApiPresenter(); diff --git a/src/backend/app/Http/Controllers/TokensController.php b/src/backend/app/Http/Controllers/TokensController.php index b2b7af9b773c782393bbabbcdadc20afc92f9de4..ab5301005c7d15086698a737d07d8c8e3902ba18 100644 --- a/src/backend/app/Http/Controllers/TokensController.php +++ b/src/backend/app/Http/Controllers/TokensController.php @@ -46,8 +46,8 @@ class TokensController extends ApiController $this->authorizer->protect(Permissions::MANAGE_USERS); $this->validate($this->request, [ - 'user_id' => 'integer', - 'valid_at' => 'date', + 'user_id' => 'nullable|integer', + 'valid_at' => 'nullable|date', ]); $presenter = new AllTokensAPIPresenter(); diff --git a/src/backend/phpunit.xml b/src/backend/phpunit.xml index 85c670a30f34521dd8637059319a374653cca5b0..9f457c90c6c32079d7ae110f594c9b46125c4ba5 100644 --- a/src/backend/phpunit.xml +++ b/src/backend/phpunit.xml @@ -31,6 +31,7 @@ ./app/Console ./src ./src + ./app/Documentation/Strategies diff --git a/src/backend/src/Entities/Schedule.php b/src/backend/src/Entities/Schedule.php index 3a846b6e5d8aa1e751427154d030c9ed54b07e15..3bf8ca9cd90263102603825ee0b5be2291c5fa1f 100644 --- a/src/backend/src/Entities/Schedule.php +++ b/src/backend/src/Entities/Schedule.php @@ -194,4 +194,32 @@ class Schedule { return $this->description; } + + /** + * @param \Carbon\Carbon $carbon + * @return \Carbon\Carbon + */ + public function addDuration(Carbon $carbon): Carbon + { + return $carbon->addRealSeconds($this->duration); + } + + /** + * @param \Carbon\Carbon $carbon + * @return \Carbon\Carbon + */ + public function subDuration(Carbon $carbon): Carbon + { + return $carbon->subRealSeconds($this->duration); + } + + /** + * @param \Carbon\Carbon $carbon + * @param int $duration + * @return \Carbon\Carbon + */ + public static function calculateEventEnd(Carbon $carbon, int $duration): Carbon + { + return $carbon->addRealSeconds($duration); + } } diff --git a/src/backend/src/Entities/User.php b/src/backend/src/Entities/User.php index eb8cf189341194d0cb14f3b4c89ba8bdf828680a..1728164dcb80f97f3c0ccd422ad1e27e21da9558 100644 --- a/src/backend/src/Entities/User.php +++ b/src/backend/src/Entities/User.php @@ -186,20 +186,6 @@ class User $this->id = $id; } - /** - * @param string|null $email - * @param string|null $password - * @return bool - */ - public function matchCredentials(?string $email, ?string $password): bool - { - if (!$this->password) { - return false; - } - - return $this->hasEmailOf($email) && $this->password->matches($password); - } - /** * @return string */ @@ -276,19 +262,6 @@ class User return $this->getFirstName() === $name; } - /** - * @param \Source\Entities\User|null $user - * @return bool - */ - public function is(?User $user): bool - { - if (!$user) { - return false; - } - - return $this->hasEmailOf($user); - } - /** * @param \Carbon\Carbon|null $date * @return bool diff --git a/src/backend/src/Exceptions/NotImplementedException.php b/src/backend/src/Exceptions/NotImplementedException.php deleted file mode 100644 index a4e23cc30678a57bec7e5f763b90d934647adecf..0000000000000000000000000000000000000000 --- a/src/backend/src/Exceptions/NotImplementedException.php +++ /dev/null @@ -1,15 +0,0 @@ -find($this->castToInt($doorId)); if (!$dbDoor) { - return null; + throw new EntityNotFoundException('Could not update door. Door not found.'); } if ($dbDoor->getAttribute('name') !== $door->getName() && $this->findByName($door->getName())) { @@ -192,7 +193,7 @@ class DatabaseDoorsRepository implements DoorsRepository /** * @inheritDoc */ - public function delete(string $doorId): bool + public function delete(string $doorId): int { return \App\Door::destroy($this->castToInt($doorId)); } diff --git a/src/backend/src/Gateways/Doors/DoorsRepository.php b/src/backend/src/Gateways/Doors/DoorsRepository.php index c1e60cb7dcac2ec2134a9f839a7e5f980e244564..cf1851acc332e2651cd25d092d9e904b0d860c40 100644 --- a/src/backend/src/Gateways/Doors/DoorsRepository.php +++ b/src/backend/src/Gateways/Doors/DoorsRepository.php @@ -16,7 +16,7 @@ interface DoorsRepository * @return \Source\Entities\Door|null * @throws \Source\Exceptions\EntityExistsException */ - public function create(Door $door): ?Door; + public function create(Door $door): Door; /** * Queries doors, if query is empty or null it gets all doors. @@ -58,18 +58,19 @@ interface DoorsRepository /** * @param string $doorId * @param \Source\Entities\Door $door - * @return \Source\Entities\Door|null + * @return \Source\Entities\Door * @throws \Source\Exceptions\EntityExistsException + * @throws \Source\Exceptions\EntityNotFoundException */ - public function update(string $doorId, Door $door): ?Door; + public function update(string $doorId, Door $door): Door; /** * Deletes a door * * @param string $doorId - * @return bool + * @return int number of doors deleted */ - public function delete(string $doorId): bool; + public function delete(string $doorId): int; /** * Checks a door for existence. diff --git a/src/backend/src/Gateways/Doors/InMemoryDoorsRepository.php b/src/backend/src/Gateways/Doors/InMemoryDoorsRepository.php index 79339e546092b106f2070761a1cbbc64e60cdb30..6582372e07a6a51f5e3a6b8a39348b4e439510f5 100644 --- a/src/backend/src/Gateways/Doors/InMemoryDoorsRepository.php +++ b/src/backend/src/Gateways/Doors/InMemoryDoorsRepository.php @@ -7,6 +7,7 @@ use Carbon\Carbon; use Source\Entities\Door; use Source\Entities\HashedSearchable; use Source\Exceptions\EntityExistsException; +use Source\Exceptions\EntityNotFoundException; class InMemoryDoorsRepository implements DoorsRepository { @@ -16,7 +17,7 @@ class InMemoryDoorsRepository implements DoorsRepository /** * @inheritDoc */ - public function create(Door $door): ?Door + public function create(Door $door): Door { if ($this->findByName($door->getName())) { throw new EntityExistsException(); @@ -103,7 +104,7 @@ class InMemoryDoorsRepository implements DoorsRepository /** * @inheritDoc */ - public function update(string $doorId, Door $door): ?Door + public function update(string $doorId, Door $door): Door { foreach ($this->doors as &$doorBase) { if ($doorBase->hasIdOf($doorId)) { @@ -115,19 +116,21 @@ class InMemoryDoorsRepository implements DoorsRepository } } - return null; + throw new EntityNotFoundException('Door not found.'); } /** * @inheritDoc */ - public function delete(string $doorId): bool + public function delete(string $doorId): int { - $this->doors = array_values(array_filter($this->doors, static function (Door $door) use ($doorId) { + $doors = 0; + $this->doors = array_values(array_filter($this->doors, static function (Door $door) use ($doorId, &$doors) { + $doors++; return !$door->hasIdOf($doorId); })); - return true; + return $doors; } /** diff --git a/src/backend/src/Gateways/Overrides/DatabaseOverridesRepository.php b/src/backend/src/Gateways/Overrides/DatabaseOverridesRepository.php index 8d7b9ffdd120530e3d23da72f4bbd4b0a4ec4686..4727c9ad2b2796d1a0fde16881a2fa2dc5caa7a7 100644 --- a/src/backend/src/Gateways/Overrides/DatabaseOverridesRepository.php +++ b/src/backend/src/Gateways/Overrides/DatabaseOverridesRepository.php @@ -6,11 +6,15 @@ namespace Source\Gateways\Overrides; use Carbon\Carbon; use Source\Sanitize\CastsTo; use Source\Entities\Override; +use Illuminate\Support\Facades\Log; +use Illuminate\Database\QueryException; use Illuminate\Database\ConnectionInterface; use Source\Exceptions\EntityNotFoundException; class DatabaseOverridesRepository implements OverridesRepository { + protected const FOREIGN_KEY_VIOLATION = '23503'; + use CastsTo; /** @@ -117,11 +121,12 @@ QUERY; } /** - * @inheritDoc + * @param \App\Override $o + * @param \Source\Entities\Override $override + * @throws \Source\Exceptions\EntityNotFoundException */ - public function addOverride(Override $override): ?Override + protected function saveOverride(\App\Override $o, Override $override): void { - $o = new \App\Override(); $o->setAttribute('user_id', $override->getUserId()); $o->setAttribute('door_id', $override->getDoorId()); $o->setAttribute('type', $override->getType()); @@ -129,13 +134,31 @@ QUERY; $o->setAttribute('end', $override->getEnd()); $o->setAttribute('reason', $override->getReason()); + try { + $o->save(); + } catch (QueryException $e) { + if ($e->getCode() === self::FOREIGN_KEY_VIOLATION) { + throw new EntityNotFoundException('Cannot save override because the specified user or door does not exist.'); + } + + Log::error('Failed saving override: ' . $e); + + throw $e; + } + } + + /** + * @inheritDoc + */ + public function addOverride(Override $override): Override + { + $o = new \App\Override(); + if ($override->getCreatedAt()) { $o->setCreatedAt($override->getCreatedAt()); } - if (!$o->save()) { - return null; - } + $this->saveOverride($o, $override); return self::toOverride($o); } @@ -143,7 +166,7 @@ QUERY; /** * @inheritDoc */ - public function updateOverride(string $overrideId, Override $override): ?Override + public function updateOverride(string $overrideId, Override $override): Override { /** @var \App\Override $o */ $o = \App\Override::query()->find($this->castToInt($overrideId)); @@ -152,16 +175,7 @@ QUERY; throw new EntityNotFoundException('Override with id "' . $overrideId . '" does not exist.'); } - $o->setAttribute('user_id', $override->getUserId()); - $o->setAttribute('door_id', $override->getDoorId()); - $o->setAttribute('type', $override->getType()); - $o->setAttribute('start', $override->getStart()); - $o->setAttribute('end', $override->getEnd()); - $o->setAttribute('reason', $override->getReason()); - - if (!$o->save()) { - return null; - } + $this->saveOverride($o, $override); return self::toOverride($o); } diff --git a/src/backend/src/Gateways/Overrides/InMemoryOverridesRepository.php b/src/backend/src/Gateways/Overrides/InMemoryOverridesRepository.php index b211f76a241512e8107a71ebb6f3cd73961b6c78..2557a1654132c2f12f746cab327f3484ba833935 100644 --- a/src/backend/src/Gateways/Overrides/InMemoryOverridesRepository.php +++ b/src/backend/src/Gateways/Overrides/InMemoryOverridesRepository.php @@ -60,7 +60,7 @@ class InMemoryOverridesRepository implements OverridesRepository /** * @inheritDoc */ - public function addOverride(Override $override): ?Override + public function addOverride(Override $override): Override { $override = new Override( $override->getId(), @@ -82,7 +82,7 @@ class InMemoryOverridesRepository implements OverridesRepository /** * @inheritDoc */ - public function updateOverride(string $overrideId, Override $override): ?Override + public function updateOverride(string $overrideId, Override $override): Override { $this->overrides = array_filter($this->overrides, static function (Override $o) use ($overrideId) { return !$o->hasIdOf($overrideId); diff --git a/src/backend/src/Gateways/Overrides/OverridesRepository.php b/src/backend/src/Gateways/Overrides/OverridesRepository.php index 5c49e831a581d486ece7eee92f823f4aabf40bb2..3425fa86f64a80357086426205826ebb90bee087 100644 --- a/src/backend/src/Gateways/Overrides/OverridesRepository.php +++ b/src/backend/src/Gateways/Overrides/OverridesRepository.php @@ -30,20 +30,23 @@ interface OverridesRepository public function activeOverrideForDoorBetween(string $doorId, Carbon $begin, Carbon $end): ?Override; /** + * Persists an override to the application. Only the latest override is ever looked at for scheduling + * * @param \Source\Entities\Override $override - * @return \Source\Entities\Override|null + * @return \Source\Entities\Override + * @throws \Source\Exceptions\EntityNotFoundException */ - public function addOverride(Override $override): ?Override; + public function addOverride(Override $override): Override; /** * Update an override * * @param string $overrideId * @param \Source\Entities\Override $override - * @return \Source\Entities\Override|null + * @return \Source\Entities\Override * @throws \Source\Exceptions\EntityNotFoundException */ - public function updateOverride(string $overrideId, Override $override): ?Override; + public function updateOverride(string $overrideId, Override $override): Override; /** * Retrieves an override diff --git a/src/backend/src/Gateways/RecurrenceSet/PhpRruleRecurrenceSet.php b/src/backend/src/Gateways/RecurrenceSet/PhpRruleRecurrenceSet.php index 8f155479b3ece4f3ea8583acda211e71dac27abf..ab967259750f79adfba8d8fb62048cb2915ad5da 100644 --- a/src/backend/src/Gateways/RecurrenceSet/PhpRruleRecurrenceSet.php +++ b/src/backend/src/Gateways/RecurrenceSet/PhpRruleRecurrenceSet.php @@ -67,8 +67,8 @@ class PhpRruleRecurrenceSet implements RecurrenceSetRepository /** * @inheritDoc */ - public function occurrenceHappeningAtDate(Carbon $date, int $duration): bool + public function occurrenceHappeningAtDate(Carbon $date, int $durationSeconds): bool { - return count($this->occurrencesBetween($date->clone()->subRealSeconds($duration), $date)) > 0; + return count($this->occurrencesBetween($date->clone()->subRealSeconds($durationSeconds), $date)) > 0; } } diff --git a/src/backend/src/Gateways/RecurrenceSet/RecurrenceSetRepository.php b/src/backend/src/Gateways/RecurrenceSet/RecurrenceSetRepository.php index 5ec3986a1047ce01553289e5a8e9fe27453e7099..5c423a494249ef0cb9fc6d52cc927fd1ca6e59b3 100644 --- a/src/backend/src/Gateways/RecurrenceSet/RecurrenceSetRepository.php +++ b/src/backend/src/Gateways/RecurrenceSet/RecurrenceSetRepository.php @@ -40,8 +40,8 @@ interface RecurrenceSetRepository * Determines if an instance is happening at the given date given the duration in seconds * * @param \Carbon\Carbon $date - * @param int $duration + * @param int $durationSeconds * @return bool */ - public function occurrenceHappeningAtDate(Carbon $date, int $duration): bool; + public function occurrenceHappeningAtDate(Carbon $date, int $durationSeconds): bool; } diff --git a/src/backend/src/Gateways/Schedules/DatabaseSchedulesRepository.php b/src/backend/src/Gateways/Schedules/DatabaseSchedulesRepository.php index e8f378bc1ff60e7924a929c73600327f9dfcb2af..574b0443b5ca44edd5dc6d4a627fd88a7b233d11 100644 --- a/src/backend/src/Gateways/Schedules/DatabaseSchedulesRepository.php +++ b/src/backend/src/Gateways/Schedules/DatabaseSchedulesRepository.php @@ -6,10 +6,15 @@ namespace Source\Gateways\Schedules; use Carbon\Carbon; use Source\Sanitize\CastsTo; use Source\Entities\Schedule; +use Illuminate\Support\Facades\Log; +use Illuminate\Database\QueryException; use Illuminate\Database\Eloquent\Builder; +use Source\Exceptions\EntityNotFoundException; class DatabaseSchedulesRepository implements SchedulesRepository { + protected const FOREIGN_KEY_VIOLATION = '23503'; + use CastsTo; /** @@ -46,16 +51,37 @@ class DatabaseSchedulesRepository implements SchedulesRepository } /** - * @inheritDoc + * @param \App\Schedule $dbSchedule + * @param \Source\Entities\Schedule $schedule + * @throws \Source\Exceptions\EntityNotFoundException */ - public function create(Schedule $schedule): ?Schedule + public function saveSchedule(\App\Schedule $dbSchedule, Schedule $schedule): void { - $dbSchedule = new \App\Schedule(); $this->setAttributesOnDbSchedule($dbSchedule, $schedule); - if (!$dbSchedule->save()) { - return null; + try { + $dbSchedule->save(); + } catch (QueryException $e) { + if ($e->getCode() === self::FOREIGN_KEY_VIOLATION) { + throw new EntityNotFoundException('Cannot save schedule because the group does not exist'); + } + + Log::error('Failed saving schedule: ' . $e); + + throw $e; } + } + + /** + * @inheritDoc + */ + public function create(Schedule $schedule): Schedule + { + $dbSchedule = new \App\Schedule(); + + $this->saveSchedule($dbSchedule, $schedule); + + $dbSchedule->save(); return self::toSchedule($dbSchedule); } @@ -140,20 +166,16 @@ class DatabaseSchedulesRepository implements SchedulesRepository /** * @inheritDoc */ - public function update(string $scheduleId, Schedule $schedule): ?Schedule + public function update(string $scheduleId, Schedule $schedule): Schedule { /** @var \App\Schedule|null $dbSchedule */ $dbSchedule = \App\Schedule::query()->find($this->castToInt($scheduleId)); if (!$scheduleId) { - return null; + throw new EntityNotFoundException('Schedule does not exist.'); } - $this->setAttributesOnDbSchedule($dbSchedule, $schedule); - - if (!$dbSchedule->save()) { - return null; - } + $this->saveSchedule($dbSchedule, $schedule); return self::toSchedule($dbSchedule); } diff --git a/src/backend/src/Gateways/Schedules/InMemorySchedulesRepository.php b/src/backend/src/Gateways/Schedules/InMemorySchedulesRepository.php index 2949e7fb5ae306906f60f8d60cf00e0919af4157..af72d7b88e47c097444f7938b3b9e1e00f346ec5 100644 --- a/src/backend/src/Gateways/Schedules/InMemorySchedulesRepository.php +++ b/src/backend/src/Gateways/Schedules/InMemorySchedulesRepository.php @@ -5,6 +5,7 @@ namespace Source\Gateways\Schedules; use Carbon\Carbon; use Source\Entities\Schedule; +use Source\Exceptions\EntityNotFoundException; class InMemorySchedulesRepository implements SchedulesRepository { @@ -16,9 +17,10 @@ class InMemorySchedulesRepository implements SchedulesRepository /** * @inheritDoc */ - public function create(Schedule $schedule): ?Schedule + public function create(Schedule $schedule): Schedule { $this->schedules[] = $schedule; + return $schedule; } @@ -68,8 +70,25 @@ class InMemorySchedulesRepository implements SchedulesRepository $include = $include && $schedule->hasGroupIdOf($groupId); } - if ($begin || $end) { - $include = $schedule->isActiveForDate($begin) || $schedule->isActiveForDate($end); + if ($schedule->getEnd()) { + if ($begin && $end) { + $include = $include && + ($begin->lessThanOrEqualTo($schedule->getEnd()) && + $end->greaterThanOrEqualTo($schedule->getStart())); + } elseif ($begin) { + $include = $include && $begin->lessThanOrEqualTo($schedule->getEnd()); + } elseif ($end) { + $include = $include && $end->greaterThanOrEqualTo($schedule->getStart()); + } + } elseif ($begin && $end) { + $include = $include && + (($begin->lessThanOrEqualTo($schedule->getStart()) && + $end->greaterThanOrEqualTo($schedule->getStart())) || + $begin->greaterThanOrEqualTo($schedule->getStart())); + } elseif ($begin) { + $include = $include && $begin->greaterThanOrEqualTo($schedule->getStart()); + } elseif ($end) { + $include = $include && $end->greaterThanOrEqualTo($schedule->getStart()); } return $include; @@ -79,15 +98,16 @@ class InMemorySchedulesRepository implements SchedulesRepository /** * @inheritDoc */ - public function update(string $scheduleId, Schedule $schedule): ?Schedule + public function update(string $scheduleId, Schedule $schedule): Schedule { - foreach ($this->schedules as $k=>$s) { + foreach ($this->schedules as $k => $s) { if ($s->hasIdOf($scheduleId)) { $this->schedules[$k] = $schedule; + return $schedule; } } - return null; + throw new EntityNotFoundException('Schedule not found.'); } } diff --git a/src/backend/src/Gateways/Schedules/SchedulesRepository.php b/src/backend/src/Gateways/Schedules/SchedulesRepository.php index 2fb511913945bab184eeffb94c9b73b62aaf755a..4fc0cb5120a086cb51c86ac9f683bfba2136e104 100644 --- a/src/backend/src/Gateways/Schedules/SchedulesRepository.php +++ b/src/backend/src/Gateways/Schedules/SchedulesRepository.php @@ -12,9 +12,10 @@ interface SchedulesRepository * Creates a schedule entry * * @param \Source\Entities\Schedule $schedule - * @return \Source\Entities\Schedule|null + * @return \Source\Entities\Schedule + * @throws \Source\Exceptions\EntityNotFoundException */ - public function create(Schedule $schedule): ?Schedule; + public function create(Schedule $schedule): Schedule; /** * Get a schedule @@ -48,7 +49,8 @@ interface SchedulesRepository * * @param string $scheduleId * @param \Source\Entities\Schedule $schedule - * @return \Source\Entities\Schedule|null + * @return \Source\Entities\Schedule + * @throws \Source\Exceptions\EntityNotFoundException */ - public function update(string $scheduleId, Schedule $schedule): ?Schedule; + public function update(string $scheduleId, Schedule $schedule): Schedule; } diff --git a/src/backend/src/Gateways/Tokens/DatabaseTokensRepository.php b/src/backend/src/Gateways/Tokens/DatabaseTokensRepository.php index 8889cf9fe46dc5f06ca07785c5dcd40a0d832923..ff8d62a9eef1a6f991e13bd3ab2ccdb921b78486 100644 --- a/src/backend/src/Gateways/Tokens/DatabaseTokensRepository.php +++ b/src/backend/src/Gateways/Tokens/DatabaseTokensRepository.php @@ -3,38 +3,56 @@ namespace Source\Gateways\Tokens; -use App\User; use Carbon\Carbon; use Source\Entities\Token; use Illuminate\Support\Str; use Source\Sanitize\CastsTo; use Source\Entities\RawToken; +use Illuminate\Support\Facades\Log; use Source\Entities\HashedSearchable; +use Illuminate\Database\QueryException; use Illuminate\Database\Eloquent\Builder; use Source\Exceptions\EntityNotFoundException; class DatabaseTokensRepository implements TokensRepository { + protected const FOREIGN_KEY_VIOLATION = '23503'; + use CastsTo; /** - * @inheritDoc + * @param \App\Token $dbToken + * @param \Source\Entities\Token $token + * @throws \Source\Exceptions\EntityNotFoundException */ - public function create(Token $token): Token + protected function saveToken(\App\Token $dbToken, Token $token): void { - /** @var \App\User|null $user */ - $user = User::query()->find($token->getUserId()); - - if (!$user) { - throw new EntityNotFoundException('Cannot create token for non existent user'); - } - - $dbToken = new \App\Token(); $dbToken->setAttribute('name', $token->getName()); $dbToken->setAttribute('user_id', $token->getUserId()); $dbToken->setAttribute('api_token', $token->getToken()->getHash()); $dbToken->setAttribute('expires_at', $token->getExpiresAt()); - $dbToken->save(); + + try { + $dbToken->save(); + } catch (QueryException $e) { + if ($e->getCode() === self::FOREIGN_KEY_VIOLATION) { + throw new EntityNotFoundException('Cannot save token for non existent user'); + } + + Log::error('Cannot save token: ' . $e); + + throw $e; + } + } + + /** + * @inheritDoc + */ + public function create(Token $token): Token + { + $dbToken = new \App\Token(); + + $this->saveToken($dbToken, $token); return self::dbTokenToToken($dbToken); } @@ -63,13 +81,10 @@ class DatabaseTokensRepository implements TokensRepository $dbToken = \App\Token::query()->find($this->castToInt($tokenId)); if (!$dbToken) { - throw new EntityNotFoundException(); + throw new EntityNotFoundException('Token with id "' . $tokenId . '" not found.'); } - $dbToken->setAttribute('name', $token->getName()); - $dbToken->setAttribute('expired_at', $token->getExpiresAt()); - $dbToken->setAttribute('api_token', $token->getToken()->getHash()); - $dbToken->save(); + $this->saveToken($dbToken, $token); return self::dbTokenToToken($dbToken); } @@ -169,7 +184,7 @@ class DatabaseTokensRepository implements TokensRepository $dbToken = \App\Token::query()->find($this->castToInt($tokenId)); if (!$dbToken) { - throw new EntityNotFoundException(); + throw new EntityNotFoundException('Token not found.'); } $token = self::dbTokenToToken($dbToken); diff --git a/src/backend/src/Gateways/Tokens/InMemoryTokensRepository.php b/src/backend/src/Gateways/Tokens/InMemoryTokensRepository.php index e088785f2f8c0789c774e014a1ac0c8d8cdb4f1b..ecef1e61cd111fc7ce6dcaf91b22be267701dfdb 100644 --- a/src/backend/src/Gateways/Tokens/InMemoryTokensRepository.php +++ b/src/backend/src/Gateways/Tokens/InMemoryTokensRepository.php @@ -36,6 +36,7 @@ class InMemoryTokensRepository implements TokensRepository public function createLoginToken(string $userId, string $salt): RawToken { $raw = self::generateTokenString(); + return new RawToken($raw, $this->create(new Token( 0, $userId, @@ -50,7 +51,7 @@ class InMemoryTokensRepository implements TokensRepository */ public function update(string $tokenId, Token $token): Token { - foreach ($this->tokens as $key=>$tok) { + foreach ($this->tokens as $key => $tok) { if ($tok->hasIdOf($tokenId)) { $this->tokens[$key] = $token; @@ -69,10 +70,10 @@ class InMemoryTokensRepository implements TokensRepository public function filter(?string $userId = null, ?Carbon $validAt = null): array { return array_values(array_filter($this->tokens, static function (Token $token) use ($userId, $validAt) { - $include = true; + $include = $token->getName() !== null; if ($validAt) { - $include = $token->isValidAtTime($validAt); + $include = $include && $token->isValidAtTime($validAt); } if ($userId !== null) { @@ -125,8 +126,11 @@ class InMemoryTokensRepository implements TokensRepository foreach ($this->tokens as $token) { if ($token->hasIdOf($tokenId) && $token->isValid()) { $token->setExpiresAt(Carbon::now()); + return; } } + + throw new EntityNotFoundException(); } /** @@ -142,4 +146,12 @@ class InMemoryTokensRepository implements TokensRepository return null; } + + /** + * @return \Source\Entities\Token[] + */ + public function getAll(): array + { + return $this->tokens; + } } diff --git a/src/backend/src/UseCases/Door/Commands/OverrideCommand.php b/src/backend/src/UseCases/Door/Commands/OverrideCommand.php index 38cc75d209222138782c26625a651d2351457cc2..dffd9f31d81d4fbd0cb6f3cfe4509a734521fde9 100644 --- a/src/backend/src/UseCases/Door/Commands/OverrideCommand.php +++ b/src/backend/src/UseCases/Door/Commands/OverrideCommand.php @@ -53,7 +53,7 @@ class OverrideCommand extends Command $length = (int)substr($args, 1); if ($length > 0) { - return $this->overrides->addOverride(new Override( + $this->overrides->addOverride(new Override( 0, "Open mode override created at keypad by {$user->getDisplayName()}.", $user->getId(), @@ -61,7 +61,8 @@ class OverrideCommand extends Command Override::TYPE_OPEN, Carbon::now(), Carbon::now()->addRealMinutes($length) - )) !== null; + )); + return true; } return false; @@ -69,7 +70,7 @@ class OverrideCommand extends Command $length = (int)substr($args, 1); if ($length > 0) { - return $this->overrides->addOverride(new Override( + $this->overrides->addOverride(new Override( 0, "Closed mode override created at keypad by {$user->getDisplayName()}.", $user->getId(), @@ -77,7 +78,8 @@ class OverrideCommand extends Command Override::TYPE_LOCKED, Carbon::now(), Carbon::now()->addRealMinutes($length) - )) !== null; + )); + return true; } return false; @@ -86,7 +88,7 @@ class OverrideCommand extends Command if ($override) { try { - return $this->overrides->updateOverride($override->getId(), new Override( + $this->overrides->updateOverride($override->getId(), new Override( $override->getId(), $override->getReason() . "\nCancelled at keypad by {$user->getDisplayName()}.", $override->getUserId(), @@ -94,7 +96,7 @@ class OverrideCommand extends Command $override->getType(), $override->getStart(), Carbon::now()->subSecond() - )) !== null; + )); } catch (EntityNotFoundException $e) { return false; } diff --git a/src/backend/src/UseCases/Door/StatusResponse/StatusResponse.php b/src/backend/src/UseCases/Door/StatusResponse/StatusResponse.php index fa2103f7e1182478ea34f1160a9d01e5ef87f241..8426e50b95b4352c9600ab7c4cdffcf299416f34 100644 --- a/src/backend/src/UseCases/Door/StatusResponse/StatusResponse.php +++ b/src/backend/src/UseCases/Door/StatusResponse/StatusResponse.php @@ -93,10 +93,10 @@ class StatusResponse implements StatusResponseUseCase } // Subtract off duration to make sure we get any currently running schedules - $b = $begin->subSeconds($schedule->getDuration()); + $b = $schedule->subDuration($begin); foreach ($this->rset->occurrencesBetween($b, $end) as $eventStart) { - $eventEnd = $eventStart->clone()->addRealSeconds($schedule->getDuration()); + $eventEnd = $schedule->addDuration($eventStart->clone()); $override = $this->overrides->activeOverrideForDoorBetween($doorId, $eventStart, $eventEnd); if ($override && $override->hasTypeOf(Override::TYPE_LOCKED)) { // If the beginning of the schedule overlaps with the override diff --git a/src/backend/src/UseCases/Doors/CreateDoor/CreateDoor.php b/src/backend/src/UseCases/Doors/CreateDoor/CreateDoor.php index 60920f6137f14e420d1e9ee7729386a47e7d405e..6e710925e0e447ba6f177297e4f06789b1092d9c 100644 --- a/src/backend/src/UseCases/Doors/CreateDoor/CreateDoor.php +++ b/src/backend/src/UseCases/Doors/CreateDoor/CreateDoor.php @@ -5,7 +5,6 @@ namespace Source\UseCases\Doors\CreateDoor; use Source\Entities\Door; use Source\Entities\HashedSearchable; use Source\Gateways\Doors\DoorsRepository; -use Source\Exceptions\EntityExistsException; use Source\Gateways\Tokens\TokensRepository; class CreateDoor implements CreateDoorUseCase @@ -48,9 +47,7 @@ class CreateDoor implements CreateDoorUseCase HashedSearchable::hash($this->salt, $token) ); - if (!($door = $this->doors->create($door))) { - throw new EntityExistsException(); - } + $door = $this->doors->create($door); $response = new ResponseModel($door, $token); diff --git a/src/backend/src/UseCases/Doors/CreateDoor/CreateDoorUseCase.php b/src/backend/src/UseCases/Doors/CreateDoor/CreateDoorUseCase.php index 6bcbafcd9b5deb89a351c139f0291444cf229579..34998f59745e99df3226559205167b53efb3cd1e 100644 --- a/src/backend/src/UseCases/Doors/CreateDoor/CreateDoorUseCase.php +++ b/src/backend/src/UseCases/Doors/CreateDoor/CreateDoorUseCase.php @@ -11,7 +11,6 @@ interface CreateDoorUseCase * Required attributes: * location * name - * salt (For hashing api key, application key is a good choice) * * @param array $attributes * @param Presenter $presenter diff --git a/src/backend/src/UseCases/Doors/DeleteDoor/DeleteDoor.php b/src/backend/src/UseCases/Doors/DeleteDoor/DeleteDoor.php index ac0bea78a6c31d8820a092ce685f76ab99da211f..098e7ef26e06f653f11cbf40397b4c20bae68973 100644 --- a/src/backend/src/UseCases/Doors/DeleteDoor/DeleteDoor.php +++ b/src/backend/src/UseCases/Doors/DeleteDoor/DeleteDoor.php @@ -25,14 +25,10 @@ class DeleteDoor implements DeleteDoorUseCase */ public function delete(string $doorId, Presenter $presenter) { - if (!($door = $this->doors->get($doorId))) { - throw new EntityNotFoundException(); - } - - if (!$this->doors->delete($door->getId())) { - $text = 'Unable to delete door'; - } else { + if ($this->doors->delete($doorId) > 0) { $text = 'Door deleted.'; + } else { + throw new EntityNotFoundException(); } $response = new ResponseModel($text); diff --git a/src/backend/src/UseCases/Doors/GenerateDoorToken/GenerateDoorToken.php b/src/backend/src/UseCases/Doors/GenerateDoorToken/GenerateDoorToken.php index d714bede75f57330b9f70024192c1a4915a267ba..fd7f96d6c37b6c74712b6fdbe462ac6e5aaf4604 100644 --- a/src/backend/src/UseCases/Doors/GenerateDoorToken/GenerateDoorToken.php +++ b/src/backend/src/UseCases/Doors/GenerateDoorToken/GenerateDoorToken.php @@ -53,9 +53,7 @@ class GenerateDoorToken implements GenerateDoorTokenUseCase ); $returnedDoor = $this->doors->update($doorId, $door); - $response = new ResponseModel($returnedDoor, $token); - $presenter->present($response); } } diff --git a/src/backend/src/UseCases/Doors/UpdateDoor/ResponseModel.php b/src/backend/src/UseCases/Doors/UpdateDoor/ResponseModel.php index c1e60b5796a6b8ee63579f0549759cfe79e3b0d5..8c2b6ad377963c6f1d4b1f8d6668ecde38ef900b 100644 --- a/src/backend/src/UseCases/Doors/UpdateDoor/ResponseModel.php +++ b/src/backend/src/UseCases/Doors/UpdateDoor/ResponseModel.php @@ -7,9 +7,9 @@ use Source\Entities\Door; class ResponseModel { /** - * @var \Source\Entities\Door|null + * @var \Source\Entities\Door */ - protected ?Door $door = null; + protected Door $door; /** * @var string @@ -17,17 +17,17 @@ class ResponseModel protected string $message = ''; /** - * @param \Source\Entities\Door|null $door + * @param \Source\Entities\Door $door */ - public function __construct(?Door $door) + public function __construct(Door $door) { $this->door = $door; } /** - * @return \Source\Entities\Door|null + * @return \Source\Entities\Door */ - public function getDoor(): ?Door + public function getDoor(): Door { return $this->door; } diff --git a/src/backend/src/UseCases/Doors/UpdateDoor/UpdateDoor.php b/src/backend/src/UseCases/Doors/UpdateDoor/UpdateDoor.php index 028057cecd8593d374c85523904b6baba76d99e4..b2c9aaac94916633a5d8efa36f5ac3a2e3957926 100644 --- a/src/backend/src/UseCases/Doors/UpdateDoor/UpdateDoor.php +++ b/src/backend/src/UseCases/Doors/UpdateDoor/UpdateDoor.php @@ -44,13 +44,7 @@ class UpdateDoor implements UpdateDoorUseCase $returnedDoor = $this->doors->update($door->getId(), $newDoor); $response = new ResponseModel($returnedDoor); - - if (!$returnedDoor) { - $response->setMessage('Unable to update door.'); - } else { - $response->setMessage('Successfully updated door.'); - } - + $response->setMessage('Successfully updated door.'); $presenter->present($response); } } diff --git a/src/backend/src/UseCases/Overrides/OverrideCreate/OverrideCreate.php b/src/backend/src/UseCases/Overrides/OverrideCreate/OverrideCreate.php index 79232ef874266b3254242ee97049078a1e7bc49c..9d3a5e1efcf9a0365f798b1c313149081cf18652 100644 --- a/src/backend/src/UseCases/Overrides/OverrideCreate/OverrideCreate.php +++ b/src/backend/src/UseCases/Overrides/OverrideCreate/OverrideCreate.php @@ -53,26 +53,24 @@ class OverrideCreate implements OverrideCreateUseCase $response->addError('Door does not exist!'); } - try { - $override = $this->overrides->addOverride( - new Override( - 0, - $attributes['reason'], - $userId, - $doorId, - $attributes['type'], - new Carbon($attributes['start']), - new Carbon($attributes['end']) - ) - ); + if (!$response->hasError()) { + try { + $override = $this->overrides->addOverride( + new Override( + 0, + $attributes['reason'], + $userId, + $doorId, + $attributes['type'], + new Carbon($attributes['start']), + new Carbon($attributes['end']) + ) + ); - if (!$override) { - $response->addError('Something went wrong when adding the override'); - } else { $response->setOverride($override); + } catch (InvalidArgumentException $e) { + $response->addError($e->getMessage()); } - } catch (InvalidArgumentException $e) { - $response->addError($e->getMessage()); } if ($response->hasError()) { diff --git a/src/backend/src/UseCases/Overrides/OverrideUpdate/OverrideUpdate.php b/src/backend/src/UseCases/Overrides/OverrideUpdate/OverrideUpdate.php index d84d431b2a4db7a201c7882d5927b85405937483..09b6221b465a4647f34aa504fb3570218a548d1a 100644 --- a/src/backend/src/UseCases/Overrides/OverrideUpdate/OverrideUpdate.php +++ b/src/backend/src/UseCases/Overrides/OverrideUpdate/OverrideUpdate.php @@ -48,11 +48,13 @@ class OverrideUpdate implements OverrideUpdateUseCase $reason = $attributes['reason'] ?? $override->getReason(); $start = $attributes['start'] ?? null; $end = $attributes['end'] ?? null; + if ($start) { $start = new Carbon($start); } else { $start = $override->getStart(); } + if ($end) { $end = new Carbon($end); } else { @@ -70,17 +72,7 @@ class OverrideUpdate implements OverrideUpdateUseCase )); $response = new ResponseModel(); - - if (!$override) { - $response->addError('Something went wrong when adding the override'); - } else { - $response->setOverride($override); - } - - if ($response->hasError()) { - $presenter->presentError($response); - } else { - $presenter->present($response); - } + $response->setOverride($override); + $presenter->present($response); } } diff --git a/src/backend/src/UseCases/Schedules/ScheduleCreate/ScheduleCreate.php b/src/backend/src/UseCases/Schedules/ScheduleCreate/ScheduleCreate.php index 07d95d6be90dd8240c6629d2dc251a7a2c19cff9..4f38ca014d08b2adfb235f9dcc4dbf0aa416352f 100644 --- a/src/backend/src/UseCases/Schedules/ScheduleCreate/ScheduleCreate.php +++ b/src/backend/src/UseCases/Schedules/ScheduleCreate/ScheduleCreate.php @@ -58,7 +58,7 @@ class ScheduleCreate implements ScheduleCreateUseCase $this->rset->parse($attributes['rset']); $end = $this->rset->endDate(); if ($end) { - $end->addRealSeconds($attributes['duration']); + $end = Schedule::calculateEventEnd($end, $attributes['duration']); } $schedule = new Schedule( 0, @@ -74,11 +74,7 @@ class ScheduleCreate implements ScheduleCreateUseCase if (!$response->hasError()) { $schedule = $this->schedules->create($schedule); - if (!$schedule) { - $response->addError('Unable to create the schedule.'); - } else { - $response->setSchedule($schedule); - } + $response->setSchedule($schedule); } } catch (InvalidArgumentException $e) { // error: invalid rfc string or invalid type given diff --git a/src/backend/src/UseCases/Schedules/ScheduleCreate/ScheduleCreateUseCase.php b/src/backend/src/UseCases/Schedules/ScheduleCreate/ScheduleCreateUseCase.php index b82270c1067c160bf4176c3682c6e1b903fa15d7..8c0d72cdfd36be49110e1e6f71933bb1d547adbf 100644 --- a/src/backend/src/UseCases/Schedules/ScheduleCreate/ScheduleCreateUseCase.php +++ b/src/backend/src/UseCases/Schedules/ScheduleCreate/ScheduleCreateUseCase.php @@ -11,12 +11,13 @@ interface ScheduleCreateUseCase * Required Attributes * - type: int or string (0 = open mode schedule, 1 = access time schedule) * - rset: string (valid as defined by rfc 5321) - * - duration: int or string (number of ms for the event to last) + * - duration: int or string (number of seconds for the event to last) * - group_id: int or string (group id to attach the schedule to) * - description: string (user entered description of the schedule) * * @param array $attributes * @param \Source\UseCases\Schedules\Presenter $presenter + * @throws \Source\Exceptions\EntityNotFoundException */ public function create(array $attributes, Presenter $presenter): void; } diff --git a/src/backend/src/UseCases/Schedules/ScheduleUpdate/ScheduleUpdate.php b/src/backend/src/UseCases/Schedules/ScheduleUpdate/ScheduleUpdate.php index 9a0b797d225fb3a91c1c57dbdefb873b43bc2a4d..a875d3fea3ec9d11a3da3a5cc20b9f8114e88da3 100644 --- a/src/backend/src/UseCases/Schedules/ScheduleUpdate/ScheduleUpdate.php +++ b/src/backend/src/UseCases/Schedules/ScheduleUpdate/ScheduleUpdate.php @@ -66,7 +66,7 @@ class ScheduleUpdate implements ScheduleUpdateUseCase $this->rset->parse($rset); $end = $this->rset->endDate(); if ($end) { - $end->addRealSeconds($duration); + $end = Schedule::calculateEventEnd($end, $duration); } $schedule = new Schedule( 0, @@ -82,11 +82,7 @@ class ScheduleUpdate implements ScheduleUpdateUseCase if (!$response->hasError()) { $schedule = $this->schedules->update($oldSchedule->getId(), $schedule); - if (!$schedule) { - $response->addError('Unable to update the schedule.'); - } else { - $response->setSchedule($schedule); - } + $response->setSchedule($schedule); } } catch (InvalidArgumentException $e) { // error: invalid rfc string or invalid type given diff --git a/src/backend/src/UseCases/Tokens/CreateToken/CreateToken.php b/src/backend/src/UseCases/Tokens/CreateToken/CreateToken.php index d5cda97c99d2f4cc3578edde08096d0166ff1d8b..f14279f13a3de14c1ac4102b002a9e8e26e4daae 100644 --- a/src/backend/src/UseCases/Tokens/CreateToken/CreateToken.php +++ b/src/backend/src/UseCases/Tokens/CreateToken/CreateToken.php @@ -36,7 +36,7 @@ class CreateToken implements CreateTokenUseCase { $name = $attributes['name'] ?? null; if (!$name) { - throw new InvalidArgumentException('Name cannot be null'); + throw new InvalidArgumentException('Name cannot be empty'); } $tokenString = $this->tokens::generateTokenString(); diff --git a/src/backend/src/UseCases/Tokens/UpdateToken/UpdateToken.php b/src/backend/src/UseCases/Tokens/UpdateToken/UpdateToken.php index 650d81a834bfb0376cb481814919c13f9b1e0e0d..22f2249bf4f6175ea99032de9f44b85276851641 100644 --- a/src/backend/src/UseCases/Tokens/UpdateToken/UpdateToken.php +++ b/src/backend/src/UseCases/Tokens/UpdateToken/UpdateToken.php @@ -33,7 +33,7 @@ class UpdateToken implements UpdateTokenUseCase } $expiresAt = null; - if (isset($attributes['expires_at'])) { + if (array_key_exists('expires_at', $attributes)) { $expiresAt = $this->liberalCastToCarbon($expiresAt); } else { $expiresAt = $token->getExpiresAt(); diff --git a/src/backend/tests/Database/AttemptDatabaseTest.php b/src/backend/tests/Database/AttemptDatabaseTest.php index 73594b3600a40ad2c4686438da728f95a22a7bfc..f2ccdbfe7525effcba06718b17c9a5749944de71 100644 --- a/src/backend/tests/Database/AttemptDatabaseTest.php +++ b/src/backend/tests/Database/AttemptDatabaseTest.php @@ -22,7 +22,7 @@ class AttemptDatabaseTest extends DatabaseTestCase */ protected DatabaseDoorsRepository $doors; - public function setUp(): void + protected function setUp(): void { parent::setUp(); $this->repository = new DatabaseAttemptsRepository(); diff --git a/src/backend/tests/Database/DoorDatabaseTest.php b/src/backend/tests/Database/DoorDatabaseTest.php index b33de8b1dc9c70268201084123b6cf9d54f98252..e187666d8640fcb911a8ebdfea1f9f93af9b6d3a 100644 --- a/src/backend/tests/Database/DoorDatabaseTest.php +++ b/src/backend/tests/Database/DoorDatabaseTest.php @@ -14,7 +14,7 @@ class DoorDatabaseTest extends DatabaseTestCase { protected DatabaseDoorsRepository $doors; - public function setUp(): void + protected function setUp(): void { parent::setUp(); @@ -50,9 +50,9 @@ class DoorDatabaseTest extends DatabaseTestCase public function it_deletes_doors(): void { $d = $this->doors->create(new Door(0, 'loc', 'name', new HashedSearchable('token'))); - $this->assertFalse($this->doors->delete('ah idk if im gonna finish this project. Im sorry')); + $this->assertEquals(0, $this->doors->delete('ah idk if im gonna finish this project. Im sorry')); $this->assertCount(1, $this->doors->search()); - $this->assertTrue($this->doors->delete($d->getId())); + $this->assertEquals(1, $this->doors->delete($d->getId())); $this->assertCount(0, $this->doors->search()); } diff --git a/src/backend/tests/Database/DoorGroupDatabaseTest.php b/src/backend/tests/Database/DoorGroupDatabaseTest.php index ed20b55884d1ade4a7b0d8c101ffc56cd6ae5e1d..eb73a3266b92f7dba2cd8e141cbae40ef1ea1192 100644 --- a/src/backend/tests/Database/DoorGroupDatabaseTest.php +++ b/src/backend/tests/Database/DoorGroupDatabaseTest.php @@ -29,7 +29,7 @@ class DoorGroupDatabaseTest extends DatabaseTestCase */ protected DatabaseGroupsRepository $groups; - public function setUp(): void + protected function setUp(): void { parent::setUp(); $this->doors = new DatabaseDoorsRepository(); diff --git a/src/backend/tests/Database/DoorScheduleDatabaseTest.php b/src/backend/tests/Database/DoorScheduleDatabaseTest.php index 52d7dd26cee59ba04b837697c66acde8323e09b6..006c5f8a17ed06eba87075fc226f7da2a4a5aa41 100644 --- a/src/backend/tests/Database/DoorScheduleDatabaseTest.php +++ b/src/backend/tests/Database/DoorScheduleDatabaseTest.php @@ -49,7 +49,7 @@ class DoorScheduleDatabaseTest extends DatabaseTestCase */ protected DatabaseDoorScheduleRepository $doorSchedules; - public function setUp(): void + protected function setUp(): void { parent::setUp(); $this->doors = new DatabaseDoorsRepository(); diff --git a/src/backend/tests/Database/DoorUserDatabaseTest.php b/src/backend/tests/Database/DoorUserDatabaseTest.php index 6d57b117763aa72ac10f70678e5943d1dbfa7a00..5dcccb12e07e8a1d1c6342e11b48d6e078c62c6f 100644 --- a/src/backend/tests/Database/DoorUserDatabaseTest.php +++ b/src/backend/tests/Database/DoorUserDatabaseTest.php @@ -48,7 +48,7 @@ class DoorUserDatabaseTest extends DatabaseTestCase */ protected DatabaseGroupUserRepository $groupUsers; - public function setUp(): void + protected function setUp(): void { parent::setUp(); diff --git a/src/backend/tests/Database/EntriesDatabaseTest.php b/src/backend/tests/Database/EntriesDatabaseTest.php index 05f642768e660c00c355500a4ca441a5ff0c6828..0020733b176a1caaf68bfcff5eb646eeafc4d2f9 100644 --- a/src/backend/tests/Database/EntriesDatabaseTest.php +++ b/src/backend/tests/Database/EntriesDatabaseTest.php @@ -30,7 +30,7 @@ class EntriesDatabaseTest extends DatabaseTestCase */ protected DatabaseEntriesRepository $repository; - public function setUp(): void + protected function setUp(): void { parent::setUp(); diff --git a/src/backend/tests/Database/GroupDatabaseTest.php b/src/backend/tests/Database/GroupDatabaseTest.php index b63f34aaef4d5e3e60287a5c14b3826f4e2b7430..d901b5b2e8e44ef2b6f8db430c32e9bfa52c5915 100644 --- a/src/backend/tests/Database/GroupDatabaseTest.php +++ b/src/backend/tests/Database/GroupDatabaseTest.php @@ -15,7 +15,7 @@ class GroupDatabaseTest extends DatabaseTestCase */ protected DatabaseGroupsRepository $groups; - public function setUp(): void + protected function setUp(): void { parent::setUp(); diff --git a/src/backend/tests/Database/GroupUserDatabaseTest.php b/src/backend/tests/Database/GroupUserDatabaseTest.php index b4950725a0ac6f601b6038c2a834933c93057126..f993f0cd106ec51a02afbe3dffdd768e917ae4b8 100644 --- a/src/backend/tests/Database/GroupUserDatabaseTest.php +++ b/src/backend/tests/Database/GroupUserDatabaseTest.php @@ -38,7 +38,7 @@ class GroupUserDatabaseTest extends DatabaseTestCase */ protected Group $group; - public function setUp(): void + protected function setUp(): void { parent::setUp(); diff --git a/src/backend/tests/Database/OverrideDatabaseTest.php b/src/backend/tests/Database/OverrideDatabaseTest.php index 60ffdc8159b28064712d0124a7b4bc69fc5df262..adb7546a1bd7d9c1c34d5ab5063463de252bfef2 100644 --- a/src/backend/tests/Database/OverrideDatabaseTest.php +++ b/src/backend/tests/Database/OverrideDatabaseTest.php @@ -10,6 +10,7 @@ use Tests\DatabaseTestCase; use Source\Entities\Override; use Illuminate\Support\Facades\DB; use Source\Entities\HashedSearchable; +use Source\Exceptions\EntityNotFoundException; use Source\Gateways\Doors\DatabaseDoorsRepository; use Source\Gateways\Users\DatabaseUsersRepository; use Source\Gateways\Overrides\DatabaseOverridesRepository; @@ -31,7 +32,7 @@ class OverrideDatabaseTest extends DatabaseTestCase */ protected DatabaseDoorsRepository $doors; - public function setUp(): void + protected function setUp(): void { parent::setUp(); @@ -69,6 +70,7 @@ class OverrideDatabaseTest extends DatabaseTestCase /** * @test * @throws \Source\Exceptions\EntityExistsException + * @throws \Source\Exceptions\EntityNotFoundException */ public function it_can_create_and_find_overrides(): void { @@ -102,6 +104,7 @@ class OverrideDatabaseTest extends DatabaseTestCase /** * @test * @throws \Source\Exceptions\EntityExistsException + * @throws \Source\Exceptions\EntityNotFoundException */ public function it_gets_active_override_for_door(): void { @@ -131,4 +134,56 @@ class OverrideDatabaseTest extends DatabaseTestCase // It picks the latest override $this->assertEquals(Override::TYPE_OPEN, $this->repository->activeOverrideForDoorBetween($d1->getId(), Carbon::now(), Carbon::now()->addHours(3))->getType()); } + + /** + * @test + * @throws \Source\Exceptions\EntityExistsException + * @throws \Source\Exceptions\EntityNotFoundException + */ + public function it_throws_an_exception_on_insert_of_row_referencing_invalid_user(): void + { + $d = $this->createDoor('d1'); + $this->expectException(EntityNotFoundException::class); + $this->repository->addOverride(new Override(0, 'the reason', 269141, $d->getId(), Override::TYPE_OPEN, Carbon::now(), Carbon::now())); + } + + /** + * @test + * @throws \Source\Exceptions\EntityExistsException + * @throws \Source\Exceptions\EntityNotFoundException + */ + public function it_throws_an_exception_on_insert_of_row_referencing_invalid_door(): void + { + $u = $this->createUser(); + $this->expectException(EntityNotFoundException::class); + $this->repository->addOverride(new Override(0, 'the reason', $u->getId(), 270370, Override::TYPE_OPEN, Carbon::now(), Carbon::now())); + } + + /** + * @test + * @throws \Source\Exceptions\EntityExistsException + * @throws \Source\Exceptions\EntityNotFoundException + */ + public function it_throws_exception_on_update_with_invalid_door(): void + { + $d = $this->createDoor('d1'); + $u = $this->createUser('u1'); + $id = $this->repository->addOverride(new Override(0, 'the reason', $u->getId(), $d->getId(), Override::TYPE_OPEN, Carbon::now(), Carbon::now()))->getId(); + $this->expectException(EntityNotFoundException::class); + $this->repository->updateOverride($id, new Override(0, 'the reason', $u->getId(), 268467, Override::TYPE_OPEN, Carbon::now(), Carbon::now())); + } + + /** + * @test + * @throws \Source\Exceptions\EntityExistsException + * @throws \Source\Exceptions\EntityNotFoundException + */ + public function it_throws_exception_on_update_with_invalid_user(): void + { + $d = $this->createDoor('d1'); + $u = $this->createUser('u1'); + $id = $this->repository->addOverride(new Override(0, 'the reason', $u->getId(), $d->getId(), Override::TYPE_OPEN, Carbon::now(), Carbon::now()))->getId(); + $this->expectException(EntityNotFoundException::class); + $this->repository->updateOverride($id, new Override(0, 'the reason', 267270, $d->getId(), Override::TYPE_OPEN, Carbon::now(), Carbon::now())); + } } diff --git a/src/backend/tests/Database/ScheduleDatabaseTest.php b/src/backend/tests/Database/ScheduleDatabaseTest.php index 57e20c74834f96f93c5f072afc070802d88b2f8b..3a048adc25de50b0ce6863e0851c411018c4ce38 100644 --- a/src/backend/tests/Database/ScheduleDatabaseTest.php +++ b/src/backend/tests/Database/ScheduleDatabaseTest.php @@ -22,7 +22,7 @@ class ScheduleDatabaseTest extends DatabaseTestCase */ protected DatabaseGroupsRepository $groups; - public function setUp(): void + protected function setUp(): void { parent::setUp(); diff --git a/src/backend/tests/Database/TokenDatabaseTest.php b/src/backend/tests/Database/TokenDatabaseTest.php index 9096365c55bd7ebce69659b80e2c300e4b51694e..aada9b665c2be3b52778f23fc8a4d282ea993e80 100644 --- a/src/backend/tests/Database/TokenDatabaseTest.php +++ b/src/backend/tests/Database/TokenDatabaseTest.php @@ -37,7 +37,7 @@ class TokenDatabaseTest extends DatabaseTestCase /** * @throws \Source\Exceptions\EntityExistsException */ - public function setUp(): void + protected function setUp(): void { parent::setUp(); diff --git a/src/backend/tests/Database/UserDatabaseTest.php b/src/backend/tests/Database/UserDatabaseTest.php index 8f22e5581cb126ec6a186367998f914f0827e3f9..b0883d0379b7373f72862f5f2434dc02ce28ba34 100644 --- a/src/backend/tests/Database/UserDatabaseTest.php +++ b/src/backend/tests/Database/UserDatabaseTest.php @@ -17,7 +17,7 @@ class UserDatabaseTest extends DatabaseTestCase */ protected DatabaseUsersRepository $users; - public function setUp(): void + protected function setUp(): void { parent::setUp(); diff --git a/src/backend/tests/Doubles/AuthorizerStub.php b/src/backend/tests/Doubles/AuthorizerStub.php index 51926b4282f7fac3be0be4fb65e1c3db6ba8bb17..bd7789f3d0d3b50f2991a18d187a696f8122332f 100644 --- a/src/backend/tests/Doubles/AuthorizerStub.php +++ b/src/backend/tests/Doubles/AuthorizerStub.php @@ -14,6 +14,11 @@ class AuthorizerStub implements Authorizer protected ?string $id = null; + /** + * @var string[] + */ + protected array $perms = []; + /** * @param string|null $id */ @@ -100,12 +105,17 @@ class AuthorizerStub implements Authorizer } } + public function setPermissions(array $permssions): void + { + $this->perms = $permssions; + } + /** * @inheritDoc */ public function getPermissions(): array { - return []; + return $this->perms; } /** diff --git a/src/backend/tests/Doubles/RecurrenceSetStub.php b/src/backend/tests/Doubles/RecurrenceSetStub.php index 2a50d42e0c48c2c6b55f52339244a8da13fb85b8..0826aaf7e7a5ccb8488f6a0d64ec7f7466765f2f 100644 --- a/src/backend/tests/Doubles/RecurrenceSetStub.php +++ b/src/backend/tests/Doubles/RecurrenceSetStub.php @@ -58,7 +58,7 @@ class RecurrenceSetStub implements RecurrenceSetRepository /** * @inheritDoc */ - public function occurrenceHappeningAtDate(Carbon $date, int $duration): bool + public function occurrenceHappeningAtDate(Carbon $date, int $durationSeconds): bool { return $this->occurrenceHappeningAtDate; } diff --git a/src/backend/tests/Feature/Api/Attempts/AttemptsGetApiTest.php b/src/backend/tests/Feature/Api/Attempts/AttemptsGetApiTest.php new file mode 100644 index 0000000000000000000000000000000000000000..209446516e19702331de77d7d0e1f9ec3fb189cb --- /dev/null +++ b/src/backend/tests/Feature/Api/Attempts/AttemptsGetApiTest.php @@ -0,0 +1,91 @@ +attempts = new InMemoryAttemptsRepository(); + $this->instance(AttemptsRepository::class, $this->attempts); + + $this->authenticate(); + } + + protected function handleTest(?string $door_id = null, ?string $start = null, ?string $end = null): void + { + $this->response = $this->getJson( + 'api/attempts?api_token=' . $this->authToken + . '&door_id=' . $door_id + . '&start=' . $start + . '&end=' . $end + ); + } + + /** + * @test + */ + public function it_scopes_to_start_date(): void + { + $this->attempts->add(new Attempt(1, 1, new Carbon('2020-05-13'))); + $this->attempts->add(new Attempt(1, 2, new Carbon('2020-05-15'))); + + $this->handleTest(null, '2020-05-14', null); + + $this->response->assertJsonCount(1, 'data'); + $this->assertEquals(2, $this->response->json('data')[0]['door_id']); + } + + /** + * @test + */ + public function it_scopes_to_end_date(): void + { + $this->attempts->add(new Attempt(1, 1, new Carbon('2020-05-13'))); + $this->attempts->add(new Attempt(1, 2, new Carbon('2020-05-15'))); + + $this->handleTest(null, null, '2020-05-14'); + + $this->response->assertJsonCount(1, 'data'); + $this->assertEquals(1, $this->response->json('data')[0]['door_id']); + } + + /** + * @test + */ + public function it_scopes_to_door_id(): void + { + $this->attempts->add(new Attempt(1, 1, new Carbon('2020-05-13'))); + $this->attempts->add(new Attempt(1, 2, new Carbon('2020-05-15'))); + + $this->handleTest(1); + + $this->response->assertJsonCount(1, 'data'); + $this->assertEquals(1, $this->response->json('data')[0]['door_id']); + } +} diff --git a/src/backend/tests/Feature/Api/Auth/AuthControllerTest.php b/src/backend/tests/Feature/Api/Auth/AuthControllerTest.php index 872d8dbb98ceb30e95c42d208c31a855ee57f298..af6bddfd0f23e54d10f25e00b70985a4caea3e3a 100644 --- a/src/backend/tests/Feature/Api/Auth/AuthControllerTest.php +++ b/src/backend/tests/Feature/Api/Auth/AuthControllerTest.php @@ -21,7 +21,7 @@ class AuthControllerTest extends TestCase public const VALID_TOKEN = '267270'; - public function setUp(): void + protected function setUp(): void { parent::setUp(); diff --git a/src/backend/tests/Feature/Api/DoorGroup/AddDoorToGroupApiTest.php b/src/backend/tests/Feature/Api/DoorGroup/AddDoorToGroupApiTest.php new file mode 100644 index 0000000000000000000000000000000000000000..28122d79db79b4a3654cc043a267f90f7675e35a --- /dev/null +++ b/src/backend/tests/Feature/Api/DoorGroup/AddDoorToGroupApiTest.php @@ -0,0 +1,73 @@ +groups = new InMemoryGroupsRepository(); + $this->doorGroup = new InMemoryDoorGroupRepository($this->doorsRepository, $this->groups); + + $this->instance(GroupsRepository::class, $this->groups); + $this->instance(DoorGroupRepository::class, $this->doorGroup); + + $this->authenticate(); + } + + protected function handleTest(string $doorId, string $groupId): void + { + $this->response = $this->postJson('api/doors/' . $doorId . '/group/' . $groupId, [ + 'api_token' => $this->authToken, + ]); + } + + /** + * @test + * @throws \Source\Exceptions\EntityExistsException + * @throws \Source\Exceptions\EntityNotFoundException + */ + public function it_adds_a_door_to_a_group(): void + { + $this->groups->create(new Group(1, '', '')); + $this->doorsRepository->create(new Door(1, '', '', new HashedSearchable(''))); + + $this->handleTest(1, 1); + + $this->response->assertStatus(200); + $this->assertCount(1, $this->doorGroup->getDoorsForGroup(1)); + } +} diff --git a/src/backend/tests/Feature/Api/DoorGroup/GetGroupsForDoorApiTest.php b/src/backend/tests/Feature/Api/DoorGroup/GetGroupsForDoorApiTest.php new file mode 100644 index 0000000000000000000000000000000000000000..9de54a01380e782d6fd13bd2c044d8e0e79fb33b --- /dev/null +++ b/src/backend/tests/Feature/Api/DoorGroup/GetGroupsForDoorApiTest.php @@ -0,0 +1,88 @@ +groups = new InMemoryGroupsRepository(); + $this->doorGroup = new InMemoryDoorGroupRepository($this->doorsRepository, $this->groups); + + $this->instance(GroupsRepository::class, $this->groups); + $this->instance(DoorGroupRepository::class, $this->doorGroup); + + $this->authenticate(); + } + + protected function handleTest(string $doorId): void + { + $this->response = $this->getJson('api/doors/' . $doorId . '/groups?api_token=' . $this->authToken); + } + + /** + * @test + * @throws \Source\Exceptions\EntityExistsException + * @throws \Source\Exceptions\EntityNotFoundException + */ + public function it_gets_groups_for_a_door(): void + { + $this->groups->create(new Group(1, '', '')); + $this->doorsRepository->create(new Door(1, '', '', new HashedSearchable(''))); + $this->doorGroup->addDoorToGroup(1, 1); + + $this->handleTest(1); + + $this->response->assertStatus(200); + $this->response->assertJsonCount(1, 'data'); + } + + /** + * @test + * @throws \Source\Exceptions\EntityExistsException + * @throws \Source\Exceptions\EntityNotFoundException + */ + public function it_cannot_get_groups_for_non_existent_door(): void + { + $this->groups->create(new Group(1, '', '')); + $this->doorsRepository->create(new Door(1, '', '', new HashedSearchable(''))); + $this->doorGroup->addDoorToGroup(1, 1); + + $this->handleTest(2); + + $this->response->assertStatus(404); + } +} diff --git a/src/backend/tests/Feature/Api/DoorGroup/RemoveDoorFromGroupApiTest.php b/src/backend/tests/Feature/Api/DoorGroup/RemoveDoorFromGroupApiTest.php new file mode 100644 index 0000000000000000000000000000000000000000..8d25a05c5a4886bdccc8f83143f220979fd72fd3 --- /dev/null +++ b/src/backend/tests/Feature/Api/DoorGroup/RemoveDoorFromGroupApiTest.php @@ -0,0 +1,74 @@ +groups = new InMemoryGroupsRepository(); + $this->doorGroup = new InMemoryDoorGroupRepository($this->doorsRepository, $this->groups); + + $this->instance(GroupsRepository::class, $this->groups); + $this->instance(DoorGroupRepository::class, $this->doorGroup); + + $this->authenticate(); + } + + protected function handleTest(string $doorId, string $groupId): void + { + $this->response = $this->deleteJson('api/doors/' . $doorId . '/group/' . $groupId, [ + 'api_token' => $this->authToken, + ]); + } + + /** + * @test + * @throws \Source\Exceptions\EntityExistsException + * @throws \Source\Exceptions\EntityNotFoundException + */ + public function it_removes_a_door_from_a_group(): void + { + $this->groups->create(new Group(1, '', '')); + $this->doorsRepository->create(new Door(1, '', '', new HashedSearchable(''))); + $this->doorGroup->addDoorToGroup(1, 1); + + $this->handleTest(1, 1); + + $this->response->assertStatus(200); + $this->assertCount(0, $this->doorGroup->getDoorsForGroup(1)); + } +} diff --git a/src/backend/tests/Feature/Api/DoorUser/DoorUserAccessApiTest.php b/src/backend/tests/Feature/Api/DoorUser/DoorUserAccessApiTest.php new file mode 100644 index 0000000000000000000000000000000000000000..347c98dff765d7fef7880cd1bd5477c88509ede3 --- /dev/null +++ b/src/backend/tests/Feature/Api/DoorUser/DoorUserAccessApiTest.php @@ -0,0 +1,112 @@ +groups = new InMemoryGroupsRepository(); + $this->schedules = new InMemorySchedulesRepository(); + $this->doorGroup = new InMemoryDoorGroupRepository($this->doorsRepository, $this->groups); + $this->groupUser = new InMemoryGroupUserRepository($this->usersRepository, $this->groups); + $this->instance(GroupUserRepository::class, $this->groupUser); + $this->instance(DoorGroupRepository::class, $this->doorGroup); + $this->instance(GroupsRepository::class, $this->groups); + $this->instance(SchedulesRepository::class, $this->schedules); + + $this->authenticate(); + } + + protected function handleTest(string $userId): void + { + $this->response = $this->getJson('api/users/' . $userId . '/doors?api_token=' . $this->authToken); + } + + /** + * @test + * @throws \Source\Exceptions\EntityExistsException + * @throws \Source\Exceptions\EntityNotFoundException + */ + public function it_gets_doors_a_user_has_access_to(): void + { + $this->doorsRepository->create(new Door(1, '', '', new HashedSearchable(''))); + $this->doorsRepository->create(new Door(2, '', '', new HashedSearchable(''))); + $this->groups->create(new Group(1, '', '')); + $this->doorGroup->addDoorToGroup(1, 1); + $this->doorGroup->addDoorToGroup(2, 1); + $this->groupUser->addUserToGroup(1, 1); + $this->schedules->create(new Schedule(1, 1, Schedule::TYPE_USER_ACCESS, '', 1234, '', new Carbon('2020-06-09'))); + $this->schedules->create(new Schedule(2, 1, Schedule::TYPE_USER_ACCESS, '', 1235, '', new Carbon('2020-06-09'))); + + $this->handleTest(1); + + $this->response->assertStatus(200); + $this->response->assertJson([ + 'groups' => [ + ['id' => 1, 'title' => '', 'description' => ''], + ], + 'doors' => [ + 1 => [ + ['id' => 1, 'name' => '', 'location' => ''], + ['id' => 2, 'name' => '', 'location' => ''], + ], + ], + 'schedules' => [ + 1 => [ + ['id' => 1, 'description' => '', 'rset' => '', 'duration' => 1234, 'end_date' => null], + ['id' => 2, 'description' => '', 'rset' => '', 'duration' => 1235, 'end_date' => null], + ], + ], + ]); + } +} diff --git a/src/backend/tests/Feature/Api/Doors/DoorGetApiTest.php b/src/backend/tests/Feature/Api/Doors/DoorGetApiTest.php new file mode 100644 index 0000000000000000000000000000000000000000..07a5d86d513f12f5a99cd5e552fa9e4e7d3ecd7f --- /dev/null +++ b/src/backend/tests/Feature/Api/Doors/DoorGetApiTest.php @@ -0,0 +1,61 @@ +authenticate(); + } + + protected function handleTest(string $id): void + { + $this->response = $this->getJson('api/doors/' . $id . '?api_token=' . $this->authToken); + } + + /** + * @test + * @throws \Source\Exceptions\EntityExistsException + */ + public function it_gets_a_door(): void + { + $this->doorsRepository->create(new Door(0, '', '', new HashedSearchable(''))); + + $this->handleTest('0'); + + $this->response->assertJson(['door' => [ + 'id' => 0, + 'location' => '', + 'name' => '', + ]]); + } + + /** + * @test + */ + public function it_handles_non_existent_doors(): void + { + $this->handleTest('asdf'); + + $this->response->assertStatus(404); + } +} diff --git a/src/backend/tests/Feature/Api/Doors/DoorsCreateApiTest.php b/src/backend/tests/Feature/Api/Doors/DoorsCreateApiTest.php new file mode 100644 index 0000000000000000000000000000000000000000..e3590791e1f2d8bb10fd809ae12d1e53f8ed035f --- /dev/null +++ b/src/backend/tests/Feature/Api/Doors/DoorsCreateApiTest.php @@ -0,0 +1,59 @@ +authenticate(); + } + + /** + * @param array $data + */ + protected function handleTest(array $data): void + { + $this->response = $this->postJson( + 'api/doors', + array_merge( + ['api_token' => $this->authToken], + $data + ) + ); + } + + /** + * @test + */ + public function it_creates_a_door(): void + { + $this->handleTest(['name' => 'new door', 'location' => 'your moms house']); + + $this->response->assertStatus(200); + $door = $this->doorsRepository->findByName('new door'); + $this->assertNotNull($door); + $this->response->assertJson(['door' => ['name' => 'new door', 'location' => 'your moms house']]); + $this->assertEquals( + HashedSearchable::hash(config('app.key'), $this->response->json('door_token')), + $door->getToken() + ); + } +} diff --git a/src/backend/tests/Feature/Api/Doors/DoorsDeleteApiTest.php b/src/backend/tests/Feature/Api/Doors/DoorsDeleteApiTest.php new file mode 100644 index 0000000000000000000000000000000000000000..8507ac42544ca4f965bad1e1d89472efc1ed31ed --- /dev/null +++ b/src/backend/tests/Feature/Api/Doors/DoorsDeleteApiTest.php @@ -0,0 +1,59 @@ +authenticate(); + } + + protected function handleTest(string $id): void + { + $this->response = $this->deleteJson('api/doors/' . $id . '?api_token=' . $this->authToken); + } + + /** + * @test + */ + public function it_cannot_delete_non_existent_door(): void + { + $this->handleTest('asdf'); + + $this->response->assertStatus(404); + } + + /** + * @test + * @throws \Source\Exceptions\EntityExistsException + */ + public function it_can_delete_a_door(): void + { + $this->doorsRepository->create(new Door(0, '', '', new HashedSearchable(''))); + + $this->handleTest('0'); + + $this->response->assertStatus(200); + $this->response->assertJson(['message' => 'Door deleted.']); + $this->assertCount(0, $this->doorsRepository->search()); + } +} diff --git a/src/backend/tests/Feature/Api/Doors/DoorsGetApiTest.php b/src/backend/tests/Feature/Api/Doors/DoorsGetApiTest.php new file mode 100644 index 0000000000000000000000000000000000000000..ed3229dfb95dc714114fd8fd414a9ce805c2bd39 --- /dev/null +++ b/src/backend/tests/Feature/Api/Doors/DoorsGetApiTest.php @@ -0,0 +1,62 @@ +authenticate(); + } + + protected function handleTest(string $query = ''): void + { + $this->response = $this->getJson('api/doors?api_token=' . $this->authToken . '&query=' . $query); + } + + /** + * @test + * @throws \Source\Exceptions\EntityExistsException + */ + public function it_paginates_all_doors(): void + { + for ($i = 0; $i < 100; $i++) { + $this->doorsRepository->create(new Door($i, '', '', new HashedSearchable(''))); + } + + $this->handleTest(); + $this->response->assertJson(['total' => 100]); + } + + /** + * @test + * @throws \Source\Exceptions\EntityExistsException + */ + public function it_filters_doors(): void + { + $this->doorsRepository->create(new Door(1, 'location', 'name', new HashedSearchable(''))); + $this->doorsRepository->create(new Door(2, 'hue hue', 'nan', new HashedSearchable(''))); + + $this->handleTest('location'); + + $this->response->assertJsonCount(1, 'data'); + } +} diff --git a/src/backend/tests/Feature/Api/Doors/DoorsTokenRegenerateApiTest.php b/src/backend/tests/Feature/Api/Doors/DoorsTokenRegenerateApiTest.php new file mode 100644 index 0000000000000000000000000000000000000000..18b1835c2ece4ad3ef63d018c35d192563e498f6 --- /dev/null +++ b/src/backend/tests/Feature/Api/Doors/DoorsTokenRegenerateApiTest.php @@ -0,0 +1,57 @@ +authenticate(); + } + + protected function handleTest(string $id): void + { + $this->response = $this->postJson('api/doors/' . $id . '/regenerate-token', ['api_token' => $this->authToken]); + } + + /** + * @test + */ + public function it_cannot_regenerate_tokens_of_nonexistent_doors(): void + { + $this->handleTest('lol'); + + $this->response->assertStatus(404); + } + + /** + * @test + * @throws \Source\Exceptions\EntityExistsException + */ + public function it_regenerates_door_tokens(): void + { + $this->doorsRepository->create(new Door(1, 'loc', 'yey', new HashedSearchable(''))); + $this->handleTest('1'); + $this->response->assertStatus(200); + $door = $this->doorsRepository->get(1); + $this->assertEquals( + HashedSearchable::hash(config('app.key'), $this->response->json('door_token')), + $door->getToken() + ); + } +} diff --git a/src/backend/tests/Feature/Api/Doors/DoorsUpdateApiTest.php b/src/backend/tests/Feature/Api/Doors/DoorsUpdateApiTest.php new file mode 100644 index 0000000000000000000000000000000000000000..28d98197b81ab6c70cbb625fb5bd2e21d12671be --- /dev/null +++ b/src/backend/tests/Feature/Api/Doors/DoorsUpdateApiTest.php @@ -0,0 +1,69 @@ +authenticate(); + } + + /** + * @param string $doorId + * @param array $data + */ + protected function handleTest(string $doorId, array $data): void + { + $this->response = $this->patchJson( + 'api/doors/' . $doorId, + array_merge(['api_token' => $this->authToken], $data) + ); + } + + /** + * @test + * @throws \Source\Exceptions\EntityExistsException + */ + public function it_updates_a_door(): void + { + $door = new Door(self::VALID_DOOR_ID, 'loc', 'name', new HashedSearchable('')); + + $this->doorsRepository->create($door); + + $this->handleTest(self::VALID_DOOR_ID, ['location' => 'new', 'name' => 'also new']); + $this->response->assertStatus(200); + $d = $this->doorsRepository->findByName('also new'); + $this->assertNotNull($d); + $this->assertEquals('also new', $d->getName()); + $this->assertEquals('new', $d->getLocation()); + $this->response->assertJson(['door' => ['name' => 'also new', 'location' => 'new']]); + } + + /** + * @test + */ + public function it_cannot_update_invalid_door(): void + { + $this->handleTest('asdfasd', []); + + $this->response->assertStatus(404); + } +} diff --git a/src/backend/tests/Feature/Api/Entries/EntriesGetApiTest.php b/src/backend/tests/Feature/Api/Entries/EntriesGetApiTest.php new file mode 100644 index 0000000000000000000000000000000000000000..3585eb0ee024699ee07acb73d86a3bf15de73440 --- /dev/null +++ b/src/backend/tests/Feature/Api/Entries/EntriesGetApiTest.php @@ -0,0 +1,109 @@ +entries = new InMemoryEntriesRepository(); + $this->instance(EntriesRepository::class, $this->entries); + + $this->authenticate(); + } + + protected function handleTest(?string $start, ?string $end, ?string $doorId, ?string $userId): void + { + $this->response = $this->getJson( + 'api/entries?api_token=' . $this->authToken + . '&start=' . $start + . '&end=' . $end + . '&door_id=' . $doorId + . '&user_id=' . $userId + ); + } + + /** + * @test + */ + public function it_can_get_none(): void + { + $this->handleTest(null, null, null, null); + + $this->response->assertJsonCount(0, 'data'); + } + + /** + * @test + */ + public function it_filters_by_start(): void + { + $this->entries->add(new Entry(1, 1, 2, true, new Carbon('2020-01-02'))); + $this->entries->add(new Entry(2, 1, 2, true, new Carbon('2020-04-02'))); + + $this->handleTest('2020-02-05', null, null, null); + $this->response->assertJsonCount(1, 'data'); + $this->response->assertJson(['data' => [['id' => 2]]]); + } + + /** + * @test + */ + public function it_filters_by_end(): void + { + $this->entries->add(new Entry(1, 1, 2, true, new Carbon('2020-01-02'))); + $this->entries->add(new Entry(2, 1, 2, true, new Carbon('2020-04-02'))); + $this->handleTest(null, '2020-02-05', null, null); + $this->response->assertJsonCount(1, 'data'); + $this->response->assertJson(['data' => [['id' => 1]]]); + } + + /** + * @test + */ + public function it_filters_by_user_id(): void + { + $this->entries->add(new Entry(1, 1, 2, true)); + $this->entries->add(new Entry(2, 2, 1, true)); + $this->handleTest(null, null, null, 1); + $this->response->assertJsonCount(1, 'data'); + $this->response->assertJson(['data' => [['id' => 1]]]); + } + + /** + * @test + */ + public function it_filters_by_door_id(): void + { + $this->entries->add(new Entry(1, 1, 2, true)); + $this->entries->add(new Entry(2, 2, 1, true)); + $this->handleTest(null, null, 1, null); + $this->response->assertJsonCount(1, 'data'); + $this->response->assertJson(['data' => [['id' => 2]]]); + } +} diff --git a/src/backend/tests/Feature/Api/Groups/CreateGroupApiTest.php b/src/backend/tests/Feature/Api/Groups/CreateGroupApiTest.php index d8e8b8670a1638e1d484b3bdb181b88c74029c4d..d89c03c522fbffe0f6f08a2478affed3c3ef84b2 100644 --- a/src/backend/tests/Feature/Api/Groups/CreateGroupApiTest.php +++ b/src/backend/tests/Feature/Api/Groups/CreateGroupApiTest.php @@ -16,7 +16,7 @@ class CreateGroupApiTest extends AuthenticatesWithApplicationTestCase protected InMemoryGroupsRepository $groups; - public function setUp(): void + protected function setUp(): void { parent::setUp(); diff --git a/src/backend/tests/Feature/Api/Groups/DeleteGroupApiTest.php b/src/backend/tests/Feature/Api/Groups/DeleteGroupApiTest.php index cfd8949c9f536924f37bad093256fdc610e88809..3ff80f4964b05c19ff2c85246a7d60e70d1cdaa9 100644 --- a/src/backend/tests/Feature/Api/Groups/DeleteGroupApiTest.php +++ b/src/backend/tests/Feature/Api/Groups/DeleteGroupApiTest.php @@ -23,7 +23,7 @@ class DeleteGroupApiTest extends AuthenticatesWithApplicationTestCase */ protected GroupsRepository $groups; - public function setUp(): void + protected function setUp(): void { parent::setUp(); diff --git a/src/backend/tests/Feature/Api/Groups/GetAllGroupsApiTest.php b/src/backend/tests/Feature/Api/Groups/GetAllGroupsApiTest.php index 1acc3bb0e2127267e478776627d0d55f9b5901c9..a4e193feee2370e6c5e41a682ea0c713ae676b13 100644 --- a/src/backend/tests/Feature/Api/Groups/GetAllGroupsApiTest.php +++ b/src/backend/tests/Feature/Api/Groups/GetAllGroupsApiTest.php @@ -22,7 +22,7 @@ class GetAllGroupsApiTest extends AuthenticatesWithApplicationTestCase */ protected GroupsRepository $groups; - public function setUp(): void + protected function setUp(): void { parent::setUp(); diff --git a/src/backend/tests/Feature/Api/Groups/GetGroupApiTest.php b/src/backend/tests/Feature/Api/Groups/GetGroupApiTest.php index 96b714d151b470c2d9746f2decceeddc77c3e193..05baa9aefb62c050e1bebb8ac3a4e223b405a0ca 100644 --- a/src/backend/tests/Feature/Api/Groups/GetGroupApiTest.php +++ b/src/backend/tests/Feature/Api/Groups/GetGroupApiTest.php @@ -18,7 +18,7 @@ class GetGroupApiTest extends AuthenticatesWithApplicationTestCase protected InMemoryGroupsRepository $groups; - public function setUp(): void + protected function setUp(): void { parent::setUp(); diff --git a/src/backend/tests/Feature/Api/Groups/GetUsersForGroupApiTest.php b/src/backend/tests/Feature/Api/Groups/GetUsersForGroupApiTest.php index 4f589741b5ea248cc069593e815a571c9022a016..a9084a008a8b6e234b9b419d8eecf7b604e172d4 100644 --- a/src/backend/tests/Feature/Api/Groups/GetUsersForGroupApiTest.php +++ b/src/backend/tests/Feature/Api/Groups/GetUsersForGroupApiTest.php @@ -29,7 +29,7 @@ class GetUsersForGroupApiTest extends AuthenticatesWithApplicationTestCase */ protected InMemoryGroupUserRepository $repository; - public function setUp(): void + protected function setUp(): void { parent::setUp(); diff --git a/src/backend/tests/Feature/Api/Groups/UpdateGroupApiTest.php b/src/backend/tests/Feature/Api/Groups/UpdateGroupApiTest.php index 4f337763b041d43ef91c882376768a9fbb9ef8e6..854eb1f45c4b175b9e13137884f8de457669f7ca 100644 --- a/src/backend/tests/Feature/Api/Groups/UpdateGroupApiTest.php +++ b/src/backend/tests/Feature/Api/Groups/UpdateGroupApiTest.php @@ -13,7 +13,7 @@ use Tests\Feature\AuthenticatesWithApplicationTestCase; class UpdateGroupApiTest extends AuthenticatesWithApplicationTestCase { /** - * @var \Illuminate\Foundation\Testing\TestResponse + * @var \Illuminate\Testing\TestResponse */ protected TestResponse $response; @@ -22,7 +22,7 @@ class UpdateGroupApiTest extends AuthenticatesWithApplicationTestCase */ protected GroupsRepository $groups; - public function setUp(): void + protected function setUp(): void { parent::setUp(); @@ -53,6 +53,7 @@ class UpdateGroupApiTest extends AuthenticatesWithApplicationTestCase /** * @test + * @throws \Source\Exceptions\EntityExistsException * @throws \Source\Exceptions\EntityNotFoundException */ public function it_protects_the_route(): void @@ -91,6 +92,8 @@ class UpdateGroupApiTest extends AuthenticatesWithApplicationTestCase * @param array $message * @dataProvider invalidGroupProvider * @throws EntityNotFoundException + * @throws \Source\Exceptions\EntityExistsException + * @throws \Source\Exceptions\EntityNotFoundException */ public function it_tests_the_validation_rules(array $data, array $message): void { @@ -101,7 +104,8 @@ class UpdateGroupApiTest extends AuthenticatesWithApplicationTestCase /** * @test - * @throws EntityNotFoundException + * @throws \Source\Exceptions\EntityExistsException + * @throws \Source\Exceptions\EntityNotFoundException */ public function it_updates_a_group(): void { @@ -125,7 +129,8 @@ class UpdateGroupApiTest extends AuthenticatesWithApplicationTestCase /** * @test - * @throws EntityNotFoundException + * @throws \Source\Exceptions\EntityExistsException + * @throws \Source\Exceptions\EntityNotFoundException */ public function it_cannot_update_non_existent_group(): void { @@ -140,6 +145,7 @@ class UpdateGroupApiTest extends AuthenticatesWithApplicationTestCase /** * @test + * @throws \Source\Exceptions\EntityExistsException * @throws \Source\Exceptions\EntityNotFoundException */ public function it_presents_error(): void diff --git a/src/backend/tests/Feature/Api/Me/GetCurrentUserDoorAccessApiTest.php b/src/backend/tests/Feature/Api/Me/GetCurrentUserDoorAccessApiTest.php new file mode 100644 index 0000000000000000000000000000000000000000..f442fb85b6612564861c0d9aa1c6644b2937f10a --- /dev/null +++ b/src/backend/tests/Feature/Api/Me/GetCurrentUserDoorAccessApiTest.php @@ -0,0 +1,112 @@ +groups = new InMemoryGroupsRepository(); + $this->schedules = new InMemorySchedulesRepository(); + $this->doorGroup = new InMemoryDoorGroupRepository($this->doorsRepository, $this->groups); + $this->groupUser = new InMemoryGroupUserRepository($this->usersRepository, $this->groups); + $this->instance(GroupUserRepository::class, $this->groupUser); + $this->instance(DoorGroupRepository::class, $this->doorGroup); + $this->instance(GroupsRepository::class, $this->groups); + $this->instance(SchedulesRepository::class, $this->schedules); + + $this->authenticate(); + } + + protected function handleTest(): void + { + $this->response = $this->getJson('api/me/access?api_token=' . $this->authToken); + } + + /** + * @test + * @throws \Source\Exceptions\EntityExistsException + * @throws \Source\Exceptions\EntityNotFoundException + */ + public function it_gets_doors_a_user_has_access_to(): void + { + $this->doorsRepository->create(new Door(1, '', '', new HashedSearchable(''))); + $this->doorsRepository->create(new Door(2, '', '', new HashedSearchable(''))); + $this->groups->create(new Group(1, '', '')); + $this->doorGroup->addDoorToGroup(1, 1); + $this->doorGroup->addDoorToGroup(2, 1); + $this->groupUser->addUserToGroup(1, 1); + $this->schedules->create(new Schedule(1, 1, Schedule::TYPE_USER_ACCESS, '', 1234, '', new Carbon('2020-06-09'))); + $this->schedules->create(new Schedule(2, 1, Schedule::TYPE_USER_ACCESS, '', 1235, '', new Carbon('2020-06-09'))); + + $this->handleTest(); + + $this->response->assertStatus(200); + $this->response->assertJson([ + 'groups' => [ + ['id' => 1, 'title' => '', 'description' => ''], + ], + 'doors' => [ + 1 => [ + ['id' => 1, 'name' => '', 'location' => ''], + ['id' => 2, 'name' => '', 'location' => ''], + ], + ], + 'schedules' => [ + 1 => [ + ['id' => 1, 'description' => '', 'rset' => '', 'duration' => 1234, 'end_date' => null], + ['id' => 2, 'description' => '', 'rset' => '', 'duration' => 1235, 'end_date' => null], + ], + ], + ]); + } +} diff --git a/src/backend/tests/Feature/Api/Me/GetCurrentUserGroupsApiTest.php b/src/backend/tests/Feature/Api/Me/GetCurrentUserGroupsApiTest.php index 7bc5e7a13f29b599b411f304fc6cc028d1685464..2722a36f83c658d44c93abef096267445a722d5b 100644 --- a/src/backend/tests/Feature/Api/Me/GetCurrentUserGroupsApiTest.php +++ b/src/backend/tests/Feature/Api/Me/GetCurrentUserGroupsApiTest.php @@ -28,7 +28,7 @@ class GetCurrentUserGroupsApiTest extends AuthenticatesWithApplicationTestCase */ protected InMemoryGroupsRepository $groups; - public function setUp(): void + protected function setUp(): void { parent::setUp(); diff --git a/src/backend/tests/Feature/Api/Me/GetCurrentUserPermissionsApiTest.php b/src/backend/tests/Feature/Api/Me/GetCurrentUserPermissionsApiTest.php new file mode 100644 index 0000000000000000000000000000000000000000..b5350fce187d88efc6971bd13de84904abfaf4f7 --- /dev/null +++ b/src/backend/tests/Feature/Api/Me/GetCurrentUserPermissionsApiTest.php @@ -0,0 +1,45 @@ +authorizer->setPermissions(['perm1', 'perm2']); + + $this->authenticate(); + } + + protected function handleTest(): void + { + $this->response = $this->getJson('api/me/permissions?api_token='. $this->authToken); + } + + /** + * @test + */ + public function it_gets_current_user_permissions(): void + { + $this->handleTest(); + + $this->response->assertStatus(200); + $this->response->assertJson(['permissions' => ['perm1', 'perm2']]); + } +} diff --git a/src/backend/tests/Feature/Api/Me/GetCurrentUserTokensApiTest.php b/src/backend/tests/Feature/Api/Me/GetCurrentUserTokensApiTest.php new file mode 100644 index 0000000000000000000000000000000000000000..ef5a77dc151ce34e49026fb0f5a301686c7ddacf --- /dev/null +++ b/src/backend/tests/Feature/Api/Me/GetCurrentUserTokensApiTest.php @@ -0,0 +1,49 @@ +authenticate(); + } + + protected function handleTest(): void + { + $this->response = $this->getJson('api/me/tokens?api_token=' . $this->authToken); + } + + /** + * @test + * @throws \Source\Exceptions\EntityNotFoundException + */ + public function it_gets_current_user_tokens(): void + { + $this->tokens->create(new Token(10, 1, new HashedSearchable(''), 'token 1')); + + $this->handleTest(); + + $this->response->assertStatus(200); + + $this->response->assertJson(['data' => [['id' => 10, 'name' => 'token 1']]]); + } +} diff --git a/src/backend/tests/Feature/Api/Me/UpdateCurrentUserApiTest.php b/src/backend/tests/Feature/Api/Me/UpdateCurrentUserApiTest.php index 990d8c7ccd5c3618eca9d4db94a45ad72b729a06..927ab9e9aa574131819606d68081ce3e3ce4d877 100644 --- a/src/backend/tests/Feature/Api/Me/UpdateCurrentUserApiTest.php +++ b/src/backend/tests/Feature/Api/Me/UpdateCurrentUserApiTest.php @@ -33,7 +33,7 @@ class UpdateCurrentUserApiTest extends AuthenticatesWithApplicationTestCase */ protected InMemoryGroupsRepository $groups; - public function setUp(): void + protected function setUp(): void { parent::setUp(); diff --git a/src/backend/tests/Feature/Api/Overrides/OverrideGetApiTest.php b/src/backend/tests/Feature/Api/Overrides/OverrideGetApiTest.php new file mode 100644 index 0000000000000000000000000000000000000000..6fa41b71b5377a2c8e8ce1ddfe1893568c4aa1f5 --- /dev/null +++ b/src/backend/tests/Feature/Api/Overrides/OverrideGetApiTest.php @@ -0,0 +1,67 @@ +overrides = new InMemoryOverridesRepository(); + $this->instance(OverridesRepository::class, $this->overrides); + + $this->authenticate(); + } + + protected function handleTest(string $id): void + { + $this->response = $this->getJson('api/overrides/' . $id . '?api_token=' . $this->authToken); + } + + /** + * @test + */ + public function it_gets_override(): void + { + $o = $this->overrides->addOverride(new Override(0, 'hi', 1, 1, Override::TYPE_OPEN, Carbon::now(), Carbon::now()->addDay())); + + $this->handleTest($o->getId()); + $this->response->assertStatus(200); + + $this->response->assertJson(['override' => ['reason' => 'hi']]); + } + + /** + * @test + */ + public function it_handles_non_existent_override(): void + { + $this->handleTest('non-existent'); + + $this->response->assertStatus(404); + } +} diff --git a/src/backend/tests/Feature/Api/Overrides/OverridesCreateApiTest.php b/src/backend/tests/Feature/Api/Overrides/OverridesCreateApiTest.php new file mode 100644 index 0000000000000000000000000000000000000000..b1a5cd8a1387ee7e7305406c7f5ba913517035e7 --- /dev/null +++ b/src/backend/tests/Feature/Api/Overrides/OverridesCreateApiTest.php @@ -0,0 +1,94 @@ +overrides = new InMemoryOverridesRepository(); + $this->instance(OverridesRepository::class, $this->overrides); + + $this->authenticate(); + } + + /** + * @param array $data + */ + protected function handleTest(array $data): void + { + $this->response = $this->postJson( + 'api/overrides', + array_merge( + ['api_token' => $this->authToken], + $data + ) + ); + } + + /** + * @test + * @throws \Source\Exceptions\EntityExistsException + */ + public function it_creates_an_override(): void + { + $this->doorsRepository->create(new Door(1, '', '', new HashedSearchable(''))); + $overrides = $this->overrides->filterHistory(null, null, null, null); + $this->assertCount(0, $overrides); + $this->handleTest([ + 'reason' => 'idk', + 'door_id' => '1', + 'type' => 1, + 'start' => '2020-04-14', + 'end' => '2020-04-15', + ]); + + $overrides = $this->overrides->filterHistory(null, null, null, null); + $this->response->assertStatus(200); + $this->assertCount(1, $overrides); + $this->assertEquals($this->authUser->getId(), $overrides[0]->getUserId()); + } + + /** + * @test + */ + public function it_fails_creating_an_override_if_door_is_not_found(): void + { + $this->handleTest([ + 'reason' => 'idk', + 'door_id' => '1', + 'type' => 1, + 'start' => '2020-04-14', + 'end' => '2020-04-15', + ]); + + $overrides = $this->overrides->filterHistory(null, null, null, null); + $this->response->assertStatus(422); + $this->assertCount(0, $overrides); + } +} diff --git a/src/backend/tests/Feature/Api/Overrides/OverridesGetApiTest.php b/src/backend/tests/Feature/Api/Overrides/OverridesGetApiTest.php new file mode 100644 index 0000000000000000000000000000000000000000..321612404e9ce78170bca7cc7e3b9cd8071d5722 --- /dev/null +++ b/src/backend/tests/Feature/Api/Overrides/OverridesGetApiTest.php @@ -0,0 +1,138 @@ +overrides = new InMemoryOverridesRepository(); + $this->instance(OverridesRepository::class, $this->overrides); + + $this->authenticate(); + } + + /** + * @param string|null $start + * @param string|null $end + * @param string|null $doorId + * @param string|null $userId + */ + protected function handleTest(?string $start, ?string $end, ?string $doorId, ?string $userId): void + { + $this->response = $this->getJson( + 'api/overrides?api_token=' . $this->authToken + . '&start=' . $start + . '&end=' . $end + . '&door_id=' . $doorId + . '&user_id=' . $userId + ); + } + + protected function createBasicOverrides(): void + { + $this->overrides->addOverride(new Override( + 1, + 'reason 1', + 2, + 3, + Override::TYPE_OPEN, + new Carbon('2020-03-22'), + new Carbon('2020-03-23') + )); + $this->overrides->addOverride(new Override( + 2, + 'reason 2', + 3, + 2, + Override::TYPE_OPEN, + new Carbon('2020-03-25'), + new Carbon('2020-03-26') + )); + } + + /** + * @test + */ + public function overrides_filter_by_start(): void + { + $this->createBasicOverrides(); + + $this->handleTest('2020-03-24', null, null, null); + + $this->response->assertStatus(200); + + $this->response->assertJsonCount(1, 'data'); + $this->assertEquals(2, $this->response->json('data')[0]['id']); + } + + /** + * @test + */ + public function overrides_filter_by_end(): void + { + $this->createBasicOverrides(); + + $this->handleTest(null, '2020-03-24', null, null); + + $this->response->assertStatus(200); + + $this->response->assertJsonCount(1, 'data'); + $this->assertEquals(1, $this->response->json('data')[0]['id']); + } + + /** + * @test + */ + public function overrides_filter_by_user(): void + { + $this->createBasicOverrides(); + + $this->handleTest(null, null, null, 3); + + $this->response->assertStatus(200); + + $this->response->assertJsonCount(1, 'data'); + $this->assertEquals(2, $this->response->json('data')[0]['id']); + } + + /** + * @test + */ + public function overrides_filter_by_door(): void + { + $this->createBasicOverrides(); + + $this->handleTest(null, null, 3, null); + + $this->response->assertStatus(200); + + $this->response->assertJsonCount(1, 'data'); + $this->assertEquals(1, $this->response->json('data')[0]['id']); + } +} diff --git a/src/backend/tests/Feature/Api/Overrides/OverridesUpdateApiTest.php b/src/backend/tests/Feature/Api/Overrides/OverridesUpdateApiTest.php new file mode 100644 index 0000000000000000000000000000000000000000..e14ed496ca972498621950446d5cebb3d5ff30a3 --- /dev/null +++ b/src/backend/tests/Feature/Api/Overrides/OverridesUpdateApiTest.php @@ -0,0 +1,93 @@ +overrides = new InMemoryOverridesRepository(); + $this->instance(OverridesRepository::class, $this->overrides); + + $this->authenticate(); + } + + protected function handleTest(string $id, array $data): void + { + $this->response = $this->patchJson( + 'api/overrides/' . $id, + array_merge(['api_token' => $this->authToken], $data) + ); + } + + /** + * @test + */ + public function it_updates_an_override(): void + { + $o = $this->overrides->addOverride(new Override(0, 'hi', 1, 1, Override::TYPE_OPEN, Carbon::now(), Carbon::now()->addDay())); + + $this->handleTest($o->getId(), ['reason' => 'new reason boio']); + + $this->response->assertStatus(200); + + $overrides = $this->overrides->filterHistory(null, null, null, null); + $this->assertCount(1, $overrides); + + $this->assertEquals('new reason boio', $overrides[0]->getReason()); + $this->response->assertJson(['override' => ['reason' => 'new reason boio', 'user_id' => 1]]); + } + + /** + * @test + */ + public function it_updates_many_attributes(): void + { + $o = $this->overrides->addOverride(new Override(0, 'hi', 1, 1, Override::TYPE_OPEN, Carbon::now(), Carbon::now()->addDay())); + + $this->handleTest($o->getId(), ['reason' => 'new reason boio', 'start' => '2020-01-02', 'end' => '2020-02-03']); + + $this->response->assertStatus(200); + + $overrides = $this->overrides->filterHistory(null, null, null, null); + $this->assertCount(1, $overrides); + + $this->assertEquals('new reason boio', $overrides[0]->getReason()); + $this->response->assertJson(['override' => ['reason' => 'new reason boio', 'user_id' => 1, 'start' => '2020-01-02T00:00:00-08:00', 'end' => '2020-02-03T00:00:00-08:00']]); + } + + /** + * @test + */ + public function it_cannot_update_non_existent_overrides(): void + { + $this->handleTest('lol', []); + + $this->response->assertStatus(404); + } +} diff --git a/src/backend/tests/Feature/Api/Schedules/ScheduleGetApiTest.php b/src/backend/tests/Feature/Api/Schedules/ScheduleGetApiTest.php new file mode 100644 index 0000000000000000000000000000000000000000..6ba495e876e85392fca50ad3f8568278d2656fed --- /dev/null +++ b/src/backend/tests/Feature/Api/Schedules/ScheduleGetApiTest.php @@ -0,0 +1,69 @@ +schedules = new InMemorySchedulesRepository(); + $this->instance(SchedulesRepository::class, $this->schedules); + + $this->authenticate(); + } + + protected function handleTest(string $id): void + { + $this->response = $this->getJson('api/schedules/' . $id . '?api_token=' . $this->authToken); + } + + /** + * @test + */ + public function it_cannot_get_a_schedule_that_is_not_there(): void + { + $this->handleTest('bad id'); + + $this->response->assertStatus(404); + } + + /** + * @test + * @throws \Source\Exceptions\EntityNotFoundException + */ + public function it_can_get_a_schedule(): void + { + $this->schedules->create(new Schedule(1, 1, Schedule::TYPE_OPEN_MODE, 'r set', 1234, 'desc', Carbon::now())); + + $this->handleTest(1); + + $this->response->assertStatus(200); + + $this->response->assertJson(['schedule' => ['id' => 1, 'description' => 'desc']]); + } +} diff --git a/src/backend/tests/Feature/Api/Schedules/SchedulesCreateApiTest.php b/src/backend/tests/Feature/Api/Schedules/SchedulesCreateApiTest.php new file mode 100644 index 0000000000000000000000000000000000000000..2f3d329017015ded33d56ecd7ecf13eb9a88666f --- /dev/null +++ b/src/backend/tests/Feature/Api/Schedules/SchedulesCreateApiTest.php @@ -0,0 +1,114 @@ +rset = new RecurrenceSetStub(); + $this->rset->beginDate = Carbon::now(); + $this->rset->endDate = Carbon::now()->addDay(); + $this->schedules = new InMemorySchedulesRepository(); + $this->groups = new InMemoryGroupsRepository(); + $this->instance(GroupsRepository::class, $this->groups); + $this->instance(RecurrenceSetRepository::class, $this->rset); + $this->instance(SchedulesRepository::class, $this->schedules); + + $this->authenticate(); + } + + protected function handleTest(array $data): void + { + $this->response = $this->postJson('api/schedules', array_merge( + ['api_token' => $this->authToken], + $data + )); + } + + /** + * @test + * @throws \Source\Exceptions\EntityExistsException + */ + public function it_creates_a_schedule(): void + { + $this->groups->create(new Group(1, '', '')); + + $this->handleTest([ + 'duration' => 1234, + 'group_id' => 1, + 'type' => Schedule::TYPE_OPEN_MODE, + 'rset' => 'rset', + 'description' => 'desc' + ]); + $this->response->assertStatus(200); + + $this->assertCount(1, $this->schedules->filter()); + $this->assertEquals('desc', $this->schedules->filter()[0]->getDescription()); + $this->response->assertJson(['schedule' => ['group_id' => 1, 'type' => Schedule::TYPE_OPEN_MODE]]); + } + + /** + * @test + */ + public function it_can_fail_to_create_a_schedule(): void + { + $this->rset->failParse = true; + $this->handleTest([ + 'duration' => -1, + 'group_id' => 1, + 'type' => 1234, + 'rset' => 'rset', + 'description' => 'desc' + ]); + + $this->response->assertStatus(422); + + $this->assertCount(0, $this->schedules->filter()); + $this->response->assertJson(['errors' => [ + 'Invalid group specified.', + 'Duration cannot be negative.', + 'Invalid rset string.', + ]]); + } +} diff --git a/src/backend/tests/Feature/Api/Schedules/SchedulesGetApiTest.php b/src/backend/tests/Feature/Api/Schedules/SchedulesGetApiTest.php new file mode 100644 index 0000000000000000000000000000000000000000..cd236ea18a6710e0ccd7c95f71fb19ba224101f5 --- /dev/null +++ b/src/backend/tests/Feature/Api/Schedules/SchedulesGetApiTest.php @@ -0,0 +1,113 @@ +schedules = new InMemorySchedulesRepository(); + $this->instance(SchedulesRepository::class, $this->schedules); + + $this->authenticate(); + } + + protected function handleTest(?string $start, ?string $end, ?string $type, ?string $groupId): void + { + $this->response = $this->getJson( + 'api/schedules?api_token=' . $this->authToken + . '&start=' . $start + . '&end=' . $end + . '&type=' . $type + . '&group_id=' . $groupId + ); + } + + /** + * @test + * @throws \Source\Exceptions\EntityNotFoundException + */ + public function it_filters_schedules_by_begin(): void + { + $this->schedules->create(new Schedule(1, 1, Schedule::TYPE_OPEN_MODE, 'r set', 1234, 'desc', new Carbon('2020-03-30'))); + $this->schedules->create(new Schedule(2, 1, Schedule::TYPE_OPEN_MODE, 'r set', 1234, 'desc', new Carbon('2020-04-30'))); + + $this->handleTest('2020-04-01', null, null, null); + + $this->response->assertStatus(200); + $this->response->assertJsonCount(1, 'data'); + $this->response->assertJson(['data' => [['id' => 1]]]); + } + + /** + * @test + * @throws \Source\Exceptions\EntityNotFoundException + */ + public function it_filters_schedules_by_end(): void + { + $this->schedules->create(new Schedule(1, 1, Schedule::TYPE_OPEN_MODE, 'r set', 1234, 'desc', new Carbon('2020-03-30'))); + $this->schedules->create(new Schedule(2, 1, Schedule::TYPE_OPEN_MODE, 'r set', 1234, 'desc', new Carbon('2020-04-30'))); + + $this->handleTest(null, '2020-05-01', null, null); + + $this->response->assertStatus(200); + $this->response->assertJsonCount(2, 'data'); + } + + /** + * @test + * @throws \Source\Exceptions\EntityNotFoundException + */ + public function it_filters_schedules_by_type(): void + { + $this->schedules->create(new Schedule(1, 1, Schedule::TYPE_USER_ACCESS, 'r set', 1234, 'desc', new Carbon('2020-03-30'))); + $this->schedules->create(new Schedule(2, 1, Schedule::TYPE_OPEN_MODE, 'r set', 1234, 'desc', new Carbon('2020-04-30'))); + + $this->handleTest(null, null, Schedule::TYPE_USER_ACCESS, null); + + $this->response->assertStatus(200); + $this->response->assertJsonCount(1, 'data'); + $this->response->assertJson(['data' => [['id' => 1]]]); + } + + /** + * @test + * @throws \Source\Exceptions\EntityNotFoundException + */ + public function it_filters_schedules_by_groupe(): void + { + $this->schedules->create(new Schedule(1, 2, Schedule::TYPE_USER_ACCESS, 'r set', 1234, 'desc', new Carbon('2020-03-30'))); + $this->schedules->create(new Schedule(2, 1, Schedule::TYPE_OPEN_MODE, 'r set', 1234, 'desc', new Carbon('2020-04-30'))); + + $this->handleTest(null, null, null, 1); + + $this->response->assertStatus(200); + $this->response->assertJsonCount(1, 'data'); + $this->response->assertJson(['data' => [['id' => 2]]]); + } +} diff --git a/src/backend/tests/Feature/Api/Schedules/SchedulesUpdateApiTest.php b/src/backend/tests/Feature/Api/Schedules/SchedulesUpdateApiTest.php new file mode 100644 index 0000000000000000000000000000000000000000..3e26aab07120f8f777c40b3c8562829dfbb137db --- /dev/null +++ b/src/backend/tests/Feature/Api/Schedules/SchedulesUpdateApiTest.php @@ -0,0 +1,118 @@ +rset = new RecurrenceSetStub(); + $this->rset->beginDate = Carbon::now(); + $this->rset->endDate = Carbon::now()->addDay(); + $this->schedules = new InMemorySchedulesRepository(); + $this->groups = new InMemoryGroupsRepository(); + $this->instance(GroupsRepository::class, $this->groups); + $this->instance(RecurrenceSetRepository::class, $this->rset); + $this->instance(SchedulesRepository::class, $this->schedules); + + $this->authenticate(); + } + + protected function handleTest(string $id, array $data): void + { + $this->response = $this->patchJson('api/schedules/' . $id, array_merge( + ['api_token' => $this->authToken], + $data + )); + } + + /** + * @test + * @throws \Source\Exceptions\EntityExistsException + * @throws \Source\Exceptions\EntityNotFoundException + */ + public function it_updates_a_schedule(): void + { + $this->groups->create(new Group(1, '', '')); + $this->schedules->create(new Schedule(1, 1, Schedule::TYPE_USER_ACCESS, '', 1234, 'old', Carbon::now())); + + $this->handleTest(1, [ + 'type' => Schedule::TYPE_OPEN_MODE, + 'rset' => 'rset', + 'description' => 'new' + ]); + $this->response->assertStatus(200); + + $this->assertCount(1, $this->schedules->filter()); + $this->assertEquals('new', $this->schedules->filter()[0]->getDescription()); + $this->assertEquals(Schedule::TYPE_OPEN_MODE, $this->schedules->filter()[0]->getType()); + $this->assertEquals('rset', $this->schedules->filter()[0]->getRset()); + $this->response->assertJson(['schedule' => ['group_id' => 1, 'type' => Schedule::TYPE_OPEN_MODE]]); + } + + /** + * @test + * @throws \Source\Exceptions\EntityNotFoundException + */ + public function it_can_fail_to_create_a_schedule(): void + { + $this->rset->failParse = true; + $this->schedules->create(new Schedule(1, 1, Schedule::TYPE_USER_ACCESS, '', 1234, 'old', Carbon::now())); + $this->handleTest(1, [ + 'type' => Schedule::TYPE_OPEN_MODE, + 'rset' => 'rset', + 'description' => 'new', + 'duration' => -1, + 'group_id' => 1, + ]); + + $this->response->assertStatus(422); + + $this->assertEquals('old', $this->schedules->filter()[0]->getDescription()); + $this->response->assertJson(['errors' => [ + 'Invalid group specified.', + 'Duration cannot be negative.', + 'Invalid rset string.', + ]]); + } +} diff --git a/src/backend/tests/Feature/Api/Tokens/TokenGetApiTest.php b/src/backend/tests/Feature/Api/Tokens/TokenGetApiTest.php new file mode 100644 index 0000000000000000000000000000000000000000..007615378c5642d777591c50648c9bae5c3b641d --- /dev/null +++ b/src/backend/tests/Feature/Api/Tokens/TokenGetApiTest.php @@ -0,0 +1,56 @@ +authenticate(); + } + + protected function handleTest(string $id): void + { + $this->response = $this->getJson('api/tokens/' . $id . '?api_token=' . $this->authToken); + } + + /** + * @test + */ + public function it_errors_on_invalid_token(): void + { + $this->handleTest('hello there'); + + $this->response->assertStatus(404); + } + + /** + * @test + * @throws \Source\Exceptions\EntityNotFoundException + */ + public function it_gets_a_valid_token(): void + { + $token = $this->tokens->create(new Token(0, 1, new HashedSearchable(''))); + $this->handleTest($token->getId()); + $this->assertEquals($token->getName(), $this->response->json('token')['name']); + $this->assertEquals($token->getId(), $this->response->json('token')['id']); + } +} diff --git a/src/backend/tests/Feature/Api/Tokens/TokensCreateApiTest.php b/src/backend/tests/Feature/Api/Tokens/TokensCreateApiTest.php new file mode 100644 index 0000000000000000000000000000000000000000..5ce433d41838beb1930437732d9c6ed912d8ee87 --- /dev/null +++ b/src/backend/tests/Feature/Api/Tokens/TokensCreateApiTest.php @@ -0,0 +1,56 @@ +authenticate(); + } + + /** + * @param array $data + */ + protected function handleTest(array $data): void + { + $this->response = $this->postJson('api/tokens', array_merge( + ['api_token' => $this->authToken], + $data + )); + } + + /** + * @test + */ + public function it_creates_a_token(): void + { + $this->handleTest(['name' => 'general kenobi', 'user_id' => 1]); + $this->response->assertStatus(200); + $this->response->assertJson(['token' => ['name' => 'general kenobi', 'user_id' => 1]]); + $tokens = $this->tokens->filter(); + $this->assertCount(1, $tokens); + $token = $tokens[0]; + $this->assertEquals( + HashedSearchable::hash(config('app.key'), $this->response->json('token_string')), + $token->getToken() + ); + } +} diff --git a/src/backend/tests/Feature/Api/Tokens/TokensExpireApiTest.php b/src/backend/tests/Feature/Api/Tokens/TokensExpireApiTest.php new file mode 100644 index 0000000000000000000000000000000000000000..0540837f2958f764104cb5511f11e7584bfe9202 --- /dev/null +++ b/src/backend/tests/Feature/Api/Tokens/TokensExpireApiTest.php @@ -0,0 +1,62 @@ +authenticate(); + } + + /** + * @param string $id + */ + protected function handleTest(string $id): void + { + $this->response = $this->postJson('api/tokens/' . $id . '/expire', ['api_token' => $this->authToken]); + } + + /** + * @test + */ + public function it_cannot_expire_non_existent_tokens(): void + { + $this->handleTest('bad id'); + + $this->response->assertStatus(404); + } + + /** + * @test + * @throws \Source\Exceptions\EntityNotFoundException + */ + public function it_expires_tokens(): void + { + $token = $this->tokens->create(new Token(0, 1, new HashedSearchable(''), 'name')); + + $this->assertNull($token->getExpiresAt()); + + $this->handleTest($token->getId()); + + $this->assertNotNull($this->tokens->filter()[0]->getExpiresAt()); + } +} diff --git a/src/backend/tests/Feature/Api/Tokens/TokensGetApiTest.php b/src/backend/tests/Feature/Api/Tokens/TokensGetApiTest.php new file mode 100644 index 0000000000000000000000000000000000000000..4ba9fe5b76e1d5e78187e28f59683b50ff9ceb19 --- /dev/null +++ b/src/backend/tests/Feature/Api/Tokens/TokensGetApiTest.php @@ -0,0 +1,115 @@ +authenticate(); + } + + protected function handleTest(?string $userId, ?string $validAt): void + { + $this->response = $this->getJson( + 'api/tokens?api_token=' . $this->authToken + . '&user_id=' . $userId + . '&valid_at=' . $validAt + ); + } + + /** + * @test + */ + public function it_gets_no_tokens(): void + { + $this->handleTest(null, null); + $this->response->assertJsonCount(0, 'data'); + } + + /** + * @test + * @throws \Source\Exceptions\EntityNotFoundException + */ + public function it_scopes_to_user_id(): void + { + $this->tokens->create(new Token(0, 1, new HashedSearchable(''), 'name', null)); + $this->tokens->create(new Token(10, 2, new HashedSearchable(''), 'name 2', null)); + + $this->handleTest(2, null); + + $this->response->assertStatus(200); + + $this->response->assertJsonCount(1, 'data'); + $this->assertEquals(10, $this->response->json('data')[0]['id']); + } + + /** + * @test + * @throws \Source\Exceptions\EntityNotFoundException + */ + public function it_scopes_to_valid_date(): void + { + $this->tokens->create(new Token(0, 1, new HashedSearchable(''), 'name', new Carbon('2019-11-12'))); + $this->tokens->create(new Token(10, 2, new HashedSearchable(''), 'name 2', new Carbon('2020-10-10'))); + + $this->handleTest(null, '2020-05-29'); + + $this->response->assertStatus(200); + + $this->response->assertJsonCount(1, 'data'); + $this->assertEquals(10, $this->response->json('data')[0]['id']); + } + + /** + * @test + * @throws \Source\Exceptions\EntityNotFoundException + */ + public function it_scopes_to_date_and_user_id(): void + { + $id = $this->tokens->create(new Token(0, 1, new HashedSearchable(''), 'name', new Carbon('2019-11-12')))->getId(); + $this->tokens->create(new Token(10, 2, new HashedSearchable(''), 'name 2', new Carbon('2020-10-10'))); + + $this->handleTest(1, '2019-05-29'); + + $this->response->assertStatus(200); + + $this->response->assertJsonCount(1, 'data'); + $this->assertEquals($id, $this->response->json('data')[0]['id']); + } + + /** + * @test + * @throws \Source\Exceptions\EntityNotFoundException + */ + public function it_does_not_have_to_scop(): void + { + $this->tokens->create(new Token(0, 1, new HashedSearchable(''), 'name', new Carbon('2019-11-12'))); + $this->tokens->create(new Token(10, 2, new HashedSearchable(''), 'name 2', new Carbon('2020-10-10'))); + + $this->handleTest(null, null); + + $this->response->assertStatus(200); + + $this->response->assertJsonCount(2, 'data'); + } +} diff --git a/src/backend/tests/Feature/Api/Tokens/TokensUpdateApiTest.php b/src/backend/tests/Feature/Api/Tokens/TokensUpdateApiTest.php new file mode 100644 index 0000000000000000000000000000000000000000..7889481455bd3f8b5623a839890fa655c874b8ed --- /dev/null +++ b/src/backend/tests/Feature/Api/Tokens/TokensUpdateApiTest.php @@ -0,0 +1,82 @@ +authenticate(); + } + + protected function handleTest(string $id, array $data): void + { + $this->response = $this->patchJson( + 'api/tokens/' . $id, + array_merge(['api_token' => $this->authToken], $data) + ); + } + + /** + * @test + * @throws \Source\Exceptions\EntityNotFoundException + */ + public function it_updates_a_token(): void + { + $token = $this->tokens->create(new Token(0, 1, new HashedSearchable(''), 'name')); + + $this->handleTest($token->getId(), ['name' => 'new name']); + + $this->response->assertStatus(200); + + $new = $this->tokens->get($token->getId()); + $this->assertEquals('new name', $new->getName()); + $this->response->assertJson(['token' => ['name' => 'new name']]); + } + + /** + * @test + */ + public function it_cannot_update_non_existent_token(): void + { + $this->handleTest('hi', []); + + $this->response->assertStatus(404); + } + + /** + * @test + * @throws \Source\Exceptions\EntityNotFoundException + */ + public function it_can_clear_expires(): void + { + $token = $this->tokens->create(new Token(0, 1, new HashedSearchable(''), 'name', Carbon::now())); + + $this->handleTest($token->getId(), ['expires_at' => null]); + + $this->response->assertStatus(200); + $this->response->assertJson(['token' => ['expires_at' => null]]); + $this->assertCount(1, $this->tokens->filter()); + $token = $this->tokens->filter()[0]; + $this->assertNull($token->getExpiresAt()); + } +} diff --git a/src/backend/tests/Feature/Api/Users/AddUserToGroupApiTest.php b/src/backend/tests/Feature/Api/Users/AddUserToGroupApiTest.php index 78e24ef20e8a306701183552b1210b7a0190ac18..670df8d1076447c584832c50886b62d1afd7078e 100644 --- a/src/backend/tests/Feature/Api/Users/AddUserToGroupApiTest.php +++ b/src/backend/tests/Feature/Api/Users/AddUserToGroupApiTest.php @@ -20,7 +20,7 @@ class AddUserToGroupApiTest extends AuthenticatesWithApplicationTestCase protected GroupUserRepository $repository; - public function setUp(): void + protected function setUp(): void { parent::setUp(); diff --git a/src/backend/tests/Feature/Api/Users/GetGroupsForUserApiTest.php b/src/backend/tests/Feature/Api/Users/GetGroupsForUserApiTest.php index 51d286c39c0a624bb4f913ab93c32180fa299d28..9eb8e2022b372311a8e1cdd58bec6f48fa22b148 100644 --- a/src/backend/tests/Feature/Api/Users/GetGroupsForUserApiTest.php +++ b/src/backend/tests/Feature/Api/Users/GetGroupsForUserApiTest.php @@ -20,7 +20,7 @@ class GetGroupsForUserApiTest extends AuthenticatesWithApplicationTestCase protected GroupUserRepository $repository; - public function setUp(): void + protected function setUp(): void { parent::setUp(); diff --git a/src/backend/tests/Feature/Api/Users/RemoveUserFromGroupApiTest.php b/src/backend/tests/Feature/Api/Users/RemoveUserFromGroupApiTest.php index 574efdeab68dfc3466ccaf3d83d9a2a9a8ecb5f7..dae921f8dff9eba5b40b7bc7914460853ddbd84e 100644 --- a/src/backend/tests/Feature/Api/Users/RemoveUserFromGroupApiTest.php +++ b/src/backend/tests/Feature/Api/Users/RemoveUserFromGroupApiTest.php @@ -20,7 +20,7 @@ class RemoveUserFromGroupApiTest extends AuthenticatesWithApplicationTestCase protected GroupUserRepository $repository; - public function setUp(): void + protected function setUp(): void { parent::setUp(); diff --git a/src/backend/tests/Feature/AuthenticatesWithApplicationTestCase.php b/src/backend/tests/Feature/AuthenticatesWithApplicationTestCase.php index fa05c1dd2a2175a79f7ab1ebb10343a5b839be8b..b2917655793a7f66a8f633af51b26c5af1b3db9d 100644 --- a/src/backend/tests/Feature/AuthenticatesWithApplicationTestCase.php +++ b/src/backend/tests/Feature/AuthenticatesWithApplicationTestCase.php @@ -42,7 +42,7 @@ class AuthenticatesWithApplicationTestCase extends TestCase /** * @throws BindingResolutionException */ - public function setUp(): void + protected function setUp(): void { parent::setUp(); @@ -69,7 +69,7 @@ class AuthenticatesWithApplicationTestCase extends TestCase $this->usersRepository->create($this->authUser); $this->authorizer->setCurrentUserId($this->authUser->getId()); - $this->tokens->create(new Token(1, 1, HashedSearchable::hash(config('app.key'), self::VALID_TOKEN), 'name')); + $this->tokens->create(new Token(1, 1, HashedSearchable::hash(config('app.key'), self::VALID_TOKEN))); $this->authToken = self::VALID_TOKEN; } diff --git a/src/backend/tests/Feature/Door/DoorAccessTest.php b/src/backend/tests/Feature/Door/DoorAccessTest.php index 55f2033454d2cc70582712819240bfa32ede306c..89e22d479e6a2f607e0a23036d35cf6724dc1466 100644 --- a/src/backend/tests/Feature/Door/DoorAccessTest.php +++ b/src/backend/tests/Feature/Door/DoorAccessTest.php @@ -16,7 +16,7 @@ class DoorAccessTest extends AuthenticatesWithApplicationTestCase protected InMemoryDoorScheduleRepository $doorSchedules; - public function setUp(): void + protected function setUp(): void { parent::setUp(); $this->doorSchedules = $this->app->make(DoorScheduleRepository::class); diff --git a/src/backend/tests/Feature/Door/DoorStatusTest.php b/src/backend/tests/Feature/Door/DoorStatusTest.php index 9365609b536a8afa4de6ed62cc686b7a6f8f30ae..db75534f2e598da29501f7d135c219bfd194a320 100644 --- a/src/backend/tests/Feature/Door/DoorStatusTest.php +++ b/src/backend/tests/Feature/Door/DoorStatusTest.php @@ -19,7 +19,7 @@ class DoorStatusTest extends AuthenticatesWithApplicationTestCase protected TestResponse $response; - public function setUp(): void + protected function setUp(): void { parent::setUp(); diff --git a/src/backend/tests/Feature/Door/DoorUpdateTest.php b/src/backend/tests/Feature/Door/DoorUpdateTest.php index 539fc17b08760e3ee84e2bdeef24056d9a184acf..837184152afb640bab8e7cfee9f96bf3b380e3ce 100644 --- a/src/backend/tests/Feature/Door/DoorUpdateTest.php +++ b/src/backend/tests/Feature/Door/DoorUpdateTest.php @@ -25,7 +25,7 @@ class DoorUpdateTest extends AuthenticatesWithApplicationTestCase */ protected Filesystem $disk; - public function setUp(): void + protected function setUp(): void { parent::setUp(); diff --git a/src/backend/tests/Unit/Guards/ApiGuardTest.php b/src/backend/tests/Unit/Guards/ApiGuardTest.php index c280b64156be545a723ed11b0aee0022882a07ab..be5cd9713d99a3a971b50bd0281619a568d1453f 100644 --- a/src/backend/tests/Unit/Guards/ApiGuardTest.php +++ b/src/backend/tests/Unit/Guards/ApiGuardTest.php @@ -38,7 +38,7 @@ class ApiGuardTest extends TestCase */ protected TokenPresenterStub $presenter; - public function setUp(): void + protected function setUp(): void { parent::setUp(); diff --git a/src/backend/tests/Unit/Guards/DoorGuardTest.php b/src/backend/tests/Unit/Guards/DoorGuardTest.php index d2467b57b0ea9cd2097eae9079c166ed9019fe76..834c37719f78b527d627d8443d7aa8d2d71ea067 100644 --- a/src/backend/tests/Unit/Guards/DoorGuardTest.php +++ b/src/backend/tests/Unit/Guards/DoorGuardTest.php @@ -39,7 +39,7 @@ class DoorGuardTest extends TestCase */ protected DoorPresenterStub $presenter; - public function setUp(): void + protected function setUp(): void { parent::setUp(); diff --git a/src/backend/tests/Unit/Repository/RecurrenceSetLibraryConnectorTest.php b/src/backend/tests/Unit/Repository/RecurrenceSetLibraryConnectorTest.php index d9f8b5ca9968322fc17f2ad5dde10fad2a99e593..c238a0a7ec27d549bcadad725123120878b3ba00 100644 --- a/src/backend/tests/Unit/Repository/RecurrenceSetLibraryConnectorTest.php +++ b/src/backend/tests/Unit/Repository/RecurrenceSetLibraryConnectorTest.php @@ -19,7 +19,7 @@ class RecurrenceSetLibraryConnectorTest extends TestCase protected string $beginString; - public function setUp(): void + protected function setUp(): void { parent::setUp(); $this->begin = Carbon::parse('2020-05-17 17:49:10', 'America/Los_Angeles'); diff --git a/src/backend/tests/Unit/Repository/SimpleSamlIntegrationTest.php b/src/backend/tests/Unit/Repository/SimpleSamlIntegrationTest.php index ecd574bc69f9e6d7342943021dbd4aadb01bd6bc..0d92d87a54f76b1121e54f1109e2e318d21189ff 100644 --- a/src/backend/tests/Unit/Repository/SimpleSamlIntegrationTest.php +++ b/src/backend/tests/Unit/Repository/SimpleSamlIntegrationTest.php @@ -18,7 +18,7 @@ class SimpleSamlIntegrationTest extends TestCase */ protected SimpleSamlPhpSamlRepository $saml; - public function setUp(): void + protected function setUp(): void { parent::setUp(); diff --git a/src/backend/tests/Unit/Source/Authorizer/AuthorizerTest.php b/src/backend/tests/Unit/Source/Authorizer/AuthorizerTest.php index b03c55f096fd3d0b35137165a4e5ad7a432bbdf4..6d9737e6d4d12d05f1ba827675e2f34f67ba47a0 100644 --- a/src/backend/tests/Unit/Source/Authorizer/AuthorizerTest.php +++ b/src/backend/tests/Unit/Source/Authorizer/AuthorizerTest.php @@ -41,7 +41,7 @@ class AuthorizerTest extends TestCase */ protected ?string $currentUserId; - public function setUp(): void + protected function setUp(): void { parent::setUp(); diff --git a/src/backend/tests/Unit/Source/UseCases/Door/Access/Authorizers/CommandAuthorizerTest.php b/src/backend/tests/Unit/Source/UseCases/Door/Access/Authorizers/CommandAuthorizerTest.php index 0d1600a23adc5bfc0d409e61b1b4415e658f68ab..690a41e97cf0381cb230364510cc1fb20b511b53 100644 --- a/src/backend/tests/Unit/Source/UseCases/Door/Access/Authorizers/CommandAuthorizerTest.php +++ b/src/backend/tests/Unit/Source/UseCases/Door/Access/Authorizers/CommandAuthorizerTest.php @@ -30,7 +30,7 @@ class CommandAuthorizerTest extends TestCase protected int $status; - public function setUp(): void + protected function setUp(): void { parent::setUp(); diff --git a/src/backend/tests/Unit/Source/UseCases/Door/Access/Authorizers/CommanderAuthorizerTest.php b/src/backend/tests/Unit/Source/UseCases/Door/Access/Authorizers/CommanderAuthorizerTest.php index b284a777b36f80f1ce7f356bca662d9eb986422d..e5bf2b2bdf5b4913baa08a5053b3f9daf95376da 100644 --- a/src/backend/tests/Unit/Source/UseCases/Door/Access/Authorizers/CommanderAuthorizerTest.php +++ b/src/backend/tests/Unit/Source/UseCases/Door/Access/Authorizers/CommanderAuthorizerTest.php @@ -24,7 +24,7 @@ class CommanderAuthorizerTest extends TestCase protected int $status; - public function setUp(): void + protected function setUp(): void { parent::setUp(); diff --git a/src/backend/tests/Unit/Source/UseCases/Door/Access/Authorizers/OpenModeAuthorizerTest.php b/src/backend/tests/Unit/Source/UseCases/Door/Access/Authorizers/OpenModeAuthorizerTest.php index 6e645b68cdcb2e838684ce2b124d743610e7b308..85649fac9ea19ee1369045d43985e5d913355f49 100644 --- a/src/backend/tests/Unit/Source/UseCases/Door/Access/Authorizers/OpenModeAuthorizerTest.php +++ b/src/backend/tests/Unit/Source/UseCases/Door/Access/Authorizers/OpenModeAuthorizerTest.php @@ -34,7 +34,7 @@ class OpenModeAuthorizerTest extends TestCase */ protected RecurrenceSetStub $recurrenceSet; - public function setUp(): void + protected function setUp(): void { parent::setUp(); $this->date = new Carbon('2020-05-15 14:46:25'); diff --git a/src/backend/tests/Unit/Source/UseCases/Door/Access/Authorizers/OverrideAuthorizerTest.php b/src/backend/tests/Unit/Source/UseCases/Door/Access/Authorizers/OverrideAuthorizerTest.php index ec0a432dd474a5bafc09bc7e7902012d07d7d228..234bd62b31fc5b0edcec5de38068db9d703d2b8f 100644 --- a/src/backend/tests/Unit/Source/UseCases/Door/Access/Authorizers/OverrideAuthorizerTest.php +++ b/src/backend/tests/Unit/Source/UseCases/Door/Access/Authorizers/OverrideAuthorizerTest.php @@ -24,7 +24,7 @@ class OverrideAuthorizerTest extends TestCase protected int $status; - public function setUp(): void + protected function setUp(): void { parent::setUp(); $this->overrides = new InMemoryOverridesRepository(); diff --git a/src/backend/tests/Unit/Source/UseCases/Door/Access/Authorizers/ScheduleAuthorizerTest.php b/src/backend/tests/Unit/Source/UseCases/Door/Access/Authorizers/ScheduleAuthorizerTest.php index d9f2b9c9421969649635ee1f16f5e0fa99d35a95..586914e87689327edee97cf25dceba2067cb3371 100644 --- a/src/backend/tests/Unit/Source/UseCases/Door/Access/Authorizers/ScheduleAuthorizerTest.php +++ b/src/backend/tests/Unit/Source/UseCases/Door/Access/Authorizers/ScheduleAuthorizerTest.php @@ -43,7 +43,7 @@ class ScheduleAuthorizerTest extends TestCase */ protected InMemoryDoorUserRepository $doorUsers; - public function setUp(): void + protected function setUp(): void { parent::setUp(); $this->date = new Carbon('2020-05-15 14:46:25'); diff --git a/src/backend/tests/Unit/Source/UseCases/Door/Access/UseCaseTest.php b/src/backend/tests/Unit/Source/UseCases/Door/Access/UseCaseTest.php index 7bdf8d276a9e149aa5afb2ab8ab603e6cd2796b8..1a870878e8104f2749645a9937c04a081e039ced 100644 --- a/src/backend/tests/Unit/Source/UseCases/Door/Access/UseCaseTest.php +++ b/src/backend/tests/Unit/Source/UseCases/Door/Access/UseCaseTest.php @@ -47,7 +47,7 @@ class UseCaseTest extends TestCase */ protected InMemoryUsersRepository $users; - public function setUp(): void + protected function setUp(): void { parent::setUp(); diff --git a/src/backend/tests/Unit/Source/UseCases/Door/Authenticate/PresenterTest.php b/src/backend/tests/Unit/Source/UseCases/Door/Authenticate/PresenterTest.php index 07124fac7a84a46e3e32199f40f958b2fee7693d..4992211a99ce6c75b73c9ea3851bce1628fd2f10 100644 --- a/src/backend/tests/Unit/Source/UseCases/Door/Authenticate/PresenterTest.php +++ b/src/backend/tests/Unit/Source/UseCases/Door/Authenticate/PresenterTest.php @@ -26,7 +26,7 @@ class PresenterTest extends TestCase */ protected ?\App\Door $response; - public function setUp(): void + protected function setUp(): void { parent::setUp(); diff --git a/src/backend/tests/Unit/Source/UseCases/Door/Authenticate/UseCaseTest.php b/src/backend/tests/Unit/Source/UseCases/Door/Authenticate/UseCaseTest.php index 1edf19f56eaa7bc8767252b34edfae2715d3013f..fd9952653405b4bb1e2fb26f62b623985d1c7071 100644 --- a/src/backend/tests/Unit/Source/UseCases/Door/Authenticate/UseCaseTest.php +++ b/src/backend/tests/Unit/Source/UseCases/Door/Authenticate/UseCaseTest.php @@ -29,7 +29,7 @@ class UseCaseTest extends TestCase protected Authenticate $useCase; - public function setUp(): void + protected function setUp(): void { parent::setUp(); diff --git a/src/backend/tests/Unit/Source/UseCases/Door/Commands/DoorCommandHandlerTest.php b/src/backend/tests/Unit/Source/UseCases/Door/Commands/DoorCommandHandlerTest.php index 9541088b02a40d1dc24abe71c10893272cca9d33..ad6512cfdd230237995693fdb9673cd710db872b 100644 --- a/src/backend/tests/Unit/Source/UseCases/Door/Commands/DoorCommandHandlerTest.php +++ b/src/backend/tests/Unit/Source/UseCases/Door/Commands/DoorCommandHandlerTest.php @@ -22,7 +22,7 @@ class DoorCommandHandlerTest extends TestCase protected bool $success = false; - public function setUp(): void + protected function setUp(): void { parent::setUp(); diff --git a/src/backend/tests/Unit/Source/UseCases/Door/Commands/OverrideCommandTest.php b/src/backend/tests/Unit/Source/UseCases/Door/Commands/OverrideCommandTest.php index 9d0050db7c69732ff958e63461fcb27bc17f1bda..203d6f35bdaada9d59b9a48a55d780f7f08afa35 100644 --- a/src/backend/tests/Unit/Source/UseCases/Door/Commands/OverrideCommandTest.php +++ b/src/backend/tests/Unit/Source/UseCases/Door/Commands/OverrideCommandTest.php @@ -27,7 +27,7 @@ class OverrideCommandTest extends TestCase protected bool $success = false; - public function setUp(): void + protected function setUp(): void { parent::setUp(); diff --git a/src/backend/tests/Unit/Source/UseCases/Door/StatusResponse/StatusResponsePresenterTest.php b/src/backend/tests/Unit/Source/UseCases/Door/StatusResponse/StatusResponsePresenterTest.php index 779e607c153d231bf048af98f2b53bbe98961442..d1836f9a53ddfb0e9111a0531e76497441d3eb31 100644 --- a/src/backend/tests/Unit/Source/UseCases/Door/StatusResponse/StatusResponsePresenterTest.php +++ b/src/backend/tests/Unit/Source/UseCases/Door/StatusResponse/StatusResponsePresenterTest.php @@ -26,7 +26,7 @@ class StatusResponsePresenterTest extends TestCase */ protected array $response; - public function setUp(): void + protected function setUp(): void { parent::setUp(); $this->responseModel = new ResponseModel(); diff --git a/src/backend/tests/Unit/Source/UseCases/Door/StatusResponse/StatusResponseTest.php b/src/backend/tests/Unit/Source/UseCases/Door/StatusResponse/StatusResponseTest.php index 7b021671d2c146c02c1f3bdb14f89e1aa42b713d..f77cf07847bc8a2b44668cc5b01f63c1fedc5bb8 100644 --- a/src/backend/tests/Unit/Source/UseCases/Door/StatusResponse/StatusResponseTest.php +++ b/src/backend/tests/Unit/Source/UseCases/Door/StatusResponse/StatusResponseTest.php @@ -45,7 +45,7 @@ class StatusResponseTest extends TestCase */ protected RecurrenceSetStub $rset; - public function setUp(): void + protected function setUp(): void { parent::setUp(); diff --git a/src/backend/tests/Unit/Source/UseCases/Door/UpdateBinary/UpdateBinaryTest.php b/src/backend/tests/Unit/Source/UseCases/Door/UpdateBinary/UpdateBinaryTest.php index d4e34807de12518d11ea1ce5ac5664ee1f8bdc72..5d57f5a33b87fc526d0efd1454a832f675132d4c 100644 --- a/src/backend/tests/Unit/Source/UseCases/Door/UpdateBinary/UpdateBinaryTest.php +++ b/src/backend/tests/Unit/Source/UseCases/Door/UpdateBinary/UpdateBinaryTest.php @@ -26,7 +26,7 @@ class UpdateBinaryTest extends TestCase protected string $returnedPath; - public function setUp(): void + protected function setUp(): void { parent::setUp(); diff --git a/src/backend/tests/Unit/Source/UseCases/Doors/GetDoor/PresenterTest.php b/src/backend/tests/Unit/Source/UseCases/Doors/GetDoor/PresenterTest.php index 17a5db8c92cdd671ee767ded5ebe3f885d0d7488..b7deca82d89d117c734710e7bfe73dc25a2ed6ab 100644 --- a/src/backend/tests/Unit/Source/UseCases/Doors/GetDoor/PresenterTest.php +++ b/src/backend/tests/Unit/Source/UseCases/Doors/GetDoor/PresenterTest.php @@ -27,7 +27,7 @@ class PresenterTest extends TestCase */ protected array $response; - public function setUp(): void + protected function setUp(): void { parent::setUp(); diff --git a/src/backend/tests/Unit/Source/UseCases/Doors/GetDoor/UseCaseTest.php b/src/backend/tests/Unit/Source/UseCases/Doors/GetDoor/UseCaseTest.php index 4cf7fbd0e1b76f33689bab2f1540099793447452..96d6aee3eb57880e10870a70dc0e25043e339180 100644 --- a/src/backend/tests/Unit/Source/UseCases/Doors/GetDoor/UseCaseTest.php +++ b/src/backend/tests/Unit/Source/UseCases/Doors/GetDoor/UseCaseTest.php @@ -33,7 +33,7 @@ class UseCaseTest extends TestCase */ protected PresenterStub $presenter; - public function setUp(): void + protected function setUp(): void { parent::setUp(); diff --git a/src/backend/tests/Unit/Source/UseCases/GroupUser/AddUserToGroup/PresenterTest.php b/src/backend/tests/Unit/Source/UseCases/GroupUser/AddUserToGroup/PresenterTest.php index 239208b9cb5da25496c70d46c4b61b3957398e20..17fbc6529296aa09dcf7cefea1167613f95db017 100644 --- a/src/backend/tests/Unit/Source/UseCases/GroupUser/AddUserToGroup/PresenterTest.php +++ b/src/backend/tests/Unit/Source/UseCases/GroupUser/AddUserToGroup/PresenterTest.php @@ -15,7 +15,7 @@ class PresenterTest extends TestCase protected array $response; - public function setUp(): void + protected function setUp(): void { parent::setUp(); diff --git a/src/backend/tests/Unit/Source/UseCases/GroupUser/AddUserToGroup/UseCaseTest.php b/src/backend/tests/Unit/Source/UseCases/GroupUser/AddUserToGroup/UseCaseTest.php index 5eccef72d04be7b2434bc482ec9b2af3c94517c2..691c328b0f4dfe783976b9df5fe576f7db084a54 100644 --- a/src/backend/tests/Unit/Source/UseCases/GroupUser/AddUserToGroup/UseCaseTest.php +++ b/src/backend/tests/Unit/Source/UseCases/GroupUser/AddUserToGroup/UseCaseTest.php @@ -50,7 +50,7 @@ class UseCaseTest extends TestCase protected AuthorizerStub $authorizer; - public function setUp(): void + protected function setUp(): void { parent::setUp(); diff --git a/src/backend/tests/Unit/Source/UseCases/GroupUser/GetGroupUsers/PresenterTest.php b/src/backend/tests/Unit/Source/UseCases/GroupUser/GetGroupUsers/PresenterTest.php index 1aa1fdef6585f512036bb713dd931ce71eeb77c9..1ae99723982ffadb340dba069622f67502e72d88 100644 --- a/src/backend/tests/Unit/Source/UseCases/GroupUser/GetGroupUsers/PresenterTest.php +++ b/src/backend/tests/Unit/Source/UseCases/GroupUser/GetGroupUsers/PresenterTest.php @@ -16,7 +16,7 @@ class PresenterTest extends TestCase protected array $response; - public function setUp(): void + protected function setUp(): void { parent::setUp(); diff --git a/src/backend/tests/Unit/Source/UseCases/GroupUser/GetGroupUsers/UseCaseTest.php b/src/backend/tests/Unit/Source/UseCases/GroupUser/GetGroupUsers/UseCaseTest.php index 8a708fa93ec1627751051fc894e26c2c78ea29f9..a22a523576f2602be832eba45a4256ab49343df7 100644 --- a/src/backend/tests/Unit/Source/UseCases/GroupUser/GetGroupUsers/UseCaseTest.php +++ b/src/backend/tests/Unit/Source/UseCases/GroupUser/GetGroupUsers/UseCaseTest.php @@ -30,7 +30,7 @@ class UseCaseTest extends TestCase protected GroupsRepository $groups; - public function setUp(): void + protected function setUp(): void { parent::setUp(); diff --git a/src/backend/tests/Unit/Source/UseCases/GroupUser/GetUserGroups/PresenterTest.php b/src/backend/tests/Unit/Source/UseCases/GroupUser/GetUserGroups/PresenterTest.php index 503e985b0e3a296bf0b94b1aba2c02e1ddaf3a61..a32d8abb77845466bbe6b6b3b1a7a0e27942170a 100644 --- a/src/backend/tests/Unit/Source/UseCases/GroupUser/GetUserGroups/PresenterTest.php +++ b/src/backend/tests/Unit/Source/UseCases/GroupUser/GetUserGroups/PresenterTest.php @@ -16,7 +16,7 @@ class PresenterTest extends TestCase protected array $response; - public function setUp(): void + protected function setUp(): void { parent::setUp(); diff --git a/src/backend/tests/Unit/Source/UseCases/GroupUser/GetUserGroups/UseCaseTest.php b/src/backend/tests/Unit/Source/UseCases/GroupUser/GetUserGroups/UseCaseTest.php index 5f6031812af9c5962f16ff115785bec022961369..e05c8382e9460d6cdf4e8644108d90eefe50e7d6 100644 --- a/src/backend/tests/Unit/Source/UseCases/GroupUser/GetUserGroups/UseCaseTest.php +++ b/src/backend/tests/Unit/Source/UseCases/GroupUser/GetUserGroups/UseCaseTest.php @@ -30,7 +30,7 @@ class UseCaseTest extends TestCase protected GroupsRepository $groups; - public function setUp(): void + protected function setUp(): void { parent::setUp(); diff --git a/src/backend/tests/Unit/Source/UseCases/GroupUser/RemoveUserFromGroup/PresenterTest.php b/src/backend/tests/Unit/Source/UseCases/GroupUser/RemoveUserFromGroup/PresenterTest.php index 8e3508c56de4630154ae62e544a05b296522f89e..c48f1315cddc8603e850657618c52760c5c1829c 100644 --- a/src/backend/tests/Unit/Source/UseCases/GroupUser/RemoveUserFromGroup/PresenterTest.php +++ b/src/backend/tests/Unit/Source/UseCases/GroupUser/RemoveUserFromGroup/PresenterTest.php @@ -15,7 +15,7 @@ class PresenterTest extends TestCase protected array $response; - public function setUp(): void + protected function setUp(): void { parent::setUp(); diff --git a/src/backend/tests/Unit/Source/UseCases/GroupUser/RemoveUserFromGroup/UseCaseTest.php b/src/backend/tests/Unit/Source/UseCases/GroupUser/RemoveUserFromGroup/UseCaseTest.php index 1418eaecf91e1045e68c0d1fc0fbbb86ea1d014d..fae2bba5e77111996719119d0fad7d7b51578256 100644 --- a/src/backend/tests/Unit/Source/UseCases/GroupUser/RemoveUserFromGroup/UseCaseTest.php +++ b/src/backend/tests/Unit/Source/UseCases/GroupUser/RemoveUserFromGroup/UseCaseTest.php @@ -50,7 +50,7 @@ class UseCaseTest extends TestCase */ protected AuthorizerStub $authorizer; - public function setUp(): void + protected function setUp(): void { parent::setUp(); diff --git a/src/backend/tests/Unit/Source/UseCases/Groups/CreateGroup/PresenterTest.php b/src/backend/tests/Unit/Source/UseCases/Groups/CreateGroup/PresenterTest.php index 4404b63dc31db95f926dfdfe4b9b59d77ae31493..b527981579ffabb56906206c96fbe0162d29cff3 100644 --- a/src/backend/tests/Unit/Source/UseCases/Groups/CreateGroup/PresenterTest.php +++ b/src/backend/tests/Unit/Source/UseCases/Groups/CreateGroup/PresenterTest.php @@ -17,7 +17,7 @@ class PresenterTest extends TestCase protected array $response; - public function setUp(): void + protected function setUp(): void { parent::setUp(); diff --git a/src/backend/tests/Unit/Source/UseCases/Groups/CreateGroup/UseCaseTest.php b/src/backend/tests/Unit/Source/UseCases/Groups/CreateGroup/UseCaseTest.php index 26b9720933061ee9a8c8eeca10dc3d546ce1e462..9f9b758b603e8b92cff09252abe69bbc7e8d225e 100644 --- a/src/backend/tests/Unit/Source/UseCases/Groups/CreateGroup/UseCaseTest.php +++ b/src/backend/tests/Unit/Source/UseCases/Groups/CreateGroup/UseCaseTest.php @@ -33,7 +33,7 @@ class UseCaseTest extends TestCase */ protected PresenterStub $presenter; - public function setUp(): void + protected function setUp(): void { parent::setUp(); diff --git a/src/backend/tests/Unit/Source/UseCases/Groups/DeleteGroup/PresenterTest.php b/src/backend/tests/Unit/Source/UseCases/Groups/DeleteGroup/PresenterTest.php index 337771137f0f319933000d0e0869206439c1775b..6a1fbf64e239995e986300e3512c0f47a7912626 100644 --- a/src/backend/tests/Unit/Source/UseCases/Groups/DeleteGroup/PresenterTest.php +++ b/src/backend/tests/Unit/Source/UseCases/Groups/DeleteGroup/PresenterTest.php @@ -15,7 +15,7 @@ class PresenterTest extends TestCase protected array $response; - public function setUp(): void + protected function setUp(): void { parent::setUp(); diff --git a/src/backend/tests/Unit/Source/UseCases/Groups/DeleteGroup/UseCaseTest.php b/src/backend/tests/Unit/Source/UseCases/Groups/DeleteGroup/UseCaseTest.php index 90e1182038eeade1ae8e0db77dfa58193cd0c5f1..2b8539f4fab1415fbe0954aad80caa9c0443e503 100644 --- a/src/backend/tests/Unit/Source/UseCases/Groups/DeleteGroup/UseCaseTest.php +++ b/src/backend/tests/Unit/Source/UseCases/Groups/DeleteGroup/UseCaseTest.php @@ -22,7 +22,7 @@ class UseCaseTest extends TestCase protected PresenterStub $presenter; - public function setUp(): void + protected function setUp(): void { parent::setUp(); diff --git a/src/backend/tests/Unit/Source/UseCases/Groups/GetAllGroups/PresenterTest.php b/src/backend/tests/Unit/Source/UseCases/Groups/GetAllGroups/PresenterTest.php index 49c950d2ba12cec8e74e0d9706cb404dd72d2caa..736a86b2afe89ad8bfd7c9c62c1a365081a770c6 100644 --- a/src/backend/tests/Unit/Source/UseCases/Groups/GetAllGroups/PresenterTest.php +++ b/src/backend/tests/Unit/Source/UseCases/Groups/GetAllGroups/PresenterTest.php @@ -17,7 +17,7 @@ class PresenterTest extends TestCase protected array $response; - public function setUp(): void + protected function setUp(): void { parent::setUp(); diff --git a/src/backend/tests/Unit/Source/UseCases/Groups/GetAllGroups/UseCaseTest.php b/src/backend/tests/Unit/Source/UseCases/Groups/GetAllGroups/UseCaseTest.php index a5801904f6e086f89a5ae3938594650fe9b13561..8d3a5576a4ba08e6fd5d9e06ce800b172817d554 100644 --- a/src/backend/tests/Unit/Source/UseCases/Groups/GetAllGroups/UseCaseTest.php +++ b/src/backend/tests/Unit/Source/UseCases/Groups/GetAllGroups/UseCaseTest.php @@ -31,7 +31,7 @@ class UseCaseTest extends TestCase */ protected PresenterStub $presenter; - public function setUp(): void + protected function setUp(): void { parent::setUp(); diff --git a/src/backend/tests/Unit/Source/UseCases/Groups/GetGroup/PresenterTest.php b/src/backend/tests/Unit/Source/UseCases/Groups/GetGroup/PresenterTest.php index 998057c44ca50670229b39c65494a781b4f75b3a..93923ceef06d309f80a1bdf3d5bd35d71fff9fe5 100644 --- a/src/backend/tests/Unit/Source/UseCases/Groups/GetGroup/PresenterTest.php +++ b/src/backend/tests/Unit/Source/UseCases/Groups/GetGroup/PresenterTest.php @@ -17,7 +17,7 @@ class PresenterTest extends TestCase protected array $response; - public function setUp(): void + protected function setUp(): void { parent::setUp(); diff --git a/src/backend/tests/Unit/Source/UseCases/Groups/GetGroup/UseCaseTest.php b/src/backend/tests/Unit/Source/UseCases/Groups/GetGroup/UseCaseTest.php index 9f5e8cda8d902b2c3ad526ee0571e2b7bef0e9c2..98e980d45a98e66f6187ee0c2b07dfbbdcb9f0b4 100644 --- a/src/backend/tests/Unit/Source/UseCases/Groups/GetGroup/UseCaseTest.php +++ b/src/backend/tests/Unit/Source/UseCases/Groups/GetGroup/UseCaseTest.php @@ -20,7 +20,7 @@ class UseCaseTest extends TestCase protected PresenterStub $presenter; - public function setUp(): void + protected function setUp(): void { parent::setUp(); diff --git a/src/backend/tests/Unit/Source/UseCases/Groups/UpdateGroup/PresenterTest.php b/src/backend/tests/Unit/Source/UseCases/Groups/UpdateGroup/PresenterTest.php index c58c809b5c979ac6a3456bfba45425ea8e413a09..14904aad64a3c081a23beb8504df10c00c3dc07e 100644 --- a/src/backend/tests/Unit/Source/UseCases/Groups/UpdateGroup/PresenterTest.php +++ b/src/backend/tests/Unit/Source/UseCases/Groups/UpdateGroup/PresenterTest.php @@ -17,7 +17,7 @@ class PresenterTest extends TestCase protected array $response; - public function setUp(): void + protected function setUp(): void { parent::setUp(); diff --git a/src/backend/tests/Unit/Source/UseCases/Groups/UpdateGroup/UseCaseTest.php b/src/backend/tests/Unit/Source/UseCases/Groups/UpdateGroup/UseCaseTest.php index 28be9ce3e53962cf6533e64348c5523d01db94b6..73bdbef7f04a66d7a5de06d1a6f9ed3f1eb8a969 100644 --- a/src/backend/tests/Unit/Source/UseCases/Groups/UpdateGroup/UseCaseTest.php +++ b/src/backend/tests/Unit/Source/UseCases/Groups/UpdateGroup/UseCaseTest.php @@ -22,7 +22,7 @@ class UseCaseTest extends TestCase protected PresenterStub $presenter; - public function setUp(): void + protected function setUp(): void { parent::setUp(); diff --git a/src/backend/tests/Unit/Source/UseCases/Schedules/ScheduleCreateTest.php b/src/backend/tests/Unit/Source/UseCases/Schedules/ScheduleCreateTest.php index 855d5bfdb94a1cc164482db4e5eccaa89f087689..7a6f89fe870e392b1748acca2c04ec3a095336cc 100644 --- a/src/backend/tests/Unit/Source/UseCases/Schedules/ScheduleCreateTest.php +++ b/src/backend/tests/Unit/Source/UseCases/Schedules/ScheduleCreateTest.php @@ -44,7 +44,7 @@ class ScheduleCreateTest extends TestCase */ protected ResponseModel $response; - public function setUp(): void + protected function setUp(): void { parent::setUp(); diff --git a/src/backend/tests/Unit/Source/UseCases/Schedules/ScheduleGetTest.php b/src/backend/tests/Unit/Source/UseCases/Schedules/ScheduleGetTest.php index a5f8b5c3863619fb10ac3e2454465db8972ff5ed..21d033d041bdfbc8421fcfdebaa6142b08a017c0 100644 --- a/src/backend/tests/Unit/Source/UseCases/Schedules/ScheduleGetTest.php +++ b/src/backend/tests/Unit/Source/UseCases/Schedules/ScheduleGetTest.php @@ -32,7 +32,7 @@ class ScheduleGetTest extends TestCase */ protected ResponseModel $response; - public function setUp(): void + protected function setUp(): void { parent::setUp(); diff --git a/src/backend/tests/Unit/Source/UseCases/Schedules/ScheduleUpdateTest.php b/src/backend/tests/Unit/Source/UseCases/Schedules/ScheduleUpdateTest.php index fc8fb220592b134983bfde70bb4954490fbc5e17..f23348cf344161676088f7d63e28c4ed9064c030 100644 --- a/src/backend/tests/Unit/Source/UseCases/Schedules/ScheduleUpdateTest.php +++ b/src/backend/tests/Unit/Source/UseCases/Schedules/ScheduleUpdateTest.php @@ -49,7 +49,7 @@ class ScheduleUpdateTest extends TestCase */ protected ScheduleUpdate $useCase; - public function setUp(): void + protected function setUp(): void { parent::setUp(); diff --git a/src/backend/tests/Unit/Source/UseCases/Schedules/SchedulesGet/SchedulesGetTest.php b/src/backend/tests/Unit/Source/UseCases/Schedules/SchedulesGet/SchedulesGetTest.php index 84e9337f2a6f24e0d940347a1a17d3bf7e432c2d..e8c3337d46c129e13cec01766862c9010be651b2 100644 --- a/src/backend/tests/Unit/Source/UseCases/Schedules/SchedulesGet/SchedulesGetTest.php +++ b/src/backend/tests/Unit/Source/UseCases/Schedules/SchedulesGet/SchedulesGetTest.php @@ -32,7 +32,7 @@ class SchedulesGetTest extends TestCase */ protected ResponseModel $response; - public function setUp(): void + protected function setUp(): void { parent::setUp(); diff --git a/src/backend/tests/Unit/Source/UseCases/Users/Authenticate/AttemptUseCaseTest.php b/src/backend/tests/Unit/Source/UseCases/Users/Authenticate/AttemptUseCaseTest.php index e8012d81a9011a9ae65361d2356b76643779361e..cbd8495aafad13f9d40b657040ae25afd0629a80 100644 --- a/src/backend/tests/Unit/Source/UseCases/Users/Authenticate/AttemptUseCaseTest.php +++ b/src/backend/tests/Unit/Source/UseCases/Users/Authenticate/AttemptUseCaseTest.php @@ -107,8 +107,8 @@ class AttemptUseCaseTest extends UseCaseBaseTest $this->handleTest(); - $this->assertCount(1, $this->tokens->filter()); - $token = $this->tokens->filter()[0]; + $this->assertCount(1, $this->tokens->getAll()); + $token = $this->tokens->getAll()[0]; $this->assertLessThan(Carbon::now()->addHours(25), $token->getExpiresAt()); $this->assertGreaterThan(Carbon::now()->subHours(23), $token->getExpiresAt()); $this->assertEquals($user->getId(), $token->getUserId()); diff --git a/src/backend/tests/Unit/Source/UseCases/Users/Authenticate/PresenterTest.php b/src/backend/tests/Unit/Source/UseCases/Users/Authenticate/PresenterTest.php index f590e7f874c37e37329400db49318f4eb3edb610..83ee81a3faad4944ebe68e20d734f50189c8b298 100644 --- a/src/backend/tests/Unit/Source/UseCases/Users/Authenticate/PresenterTest.php +++ b/src/backend/tests/Unit/Source/UseCases/Users/Authenticate/PresenterTest.php @@ -29,7 +29,7 @@ class PresenterTest extends TestCase */ protected array $response; - public function setUp(): void + protected function setUp(): void { parent::setUp(); diff --git a/src/backend/tests/Unit/Source/UseCases/Users/Authenticate/SamlUseCaseTest.php b/src/backend/tests/Unit/Source/UseCases/Users/Authenticate/SamlUseCaseTest.php index f220f657ed24537bbadb304469a6218f561f8f10..1629126bfd1ecc5c60b50b2e424199471a382cec 100644 --- a/src/backend/tests/Unit/Source/UseCases/Users/Authenticate/SamlUseCaseTest.php +++ b/src/backend/tests/Unit/Source/UseCases/Users/Authenticate/SamlUseCaseTest.php @@ -111,7 +111,7 @@ class SamlUseCaseTest extends UseCaseBaseTest $token = HashedSearchable::hash(self::SALT, self::VALID_TOKEN); $this->tokens->create(new Token(0, $user->getId(), $token)); $this->useCase->samlLogout(self::VALID_TOKEN); - $tok = $this->tokens->filter()[0]; + $tok = $this->tokens->getAll()[0]; $this->assertTrue($tok->isInvalid()); } @@ -185,8 +185,8 @@ class SamlUseCaseTest extends UseCaseBaseTest $this->handleLoginTest($samlUser); - $this->assertCount(1, $this->tokens->filter()); - $token = $this->tokens->filter()[0]; + $this->assertCount(1, $this->tokens->getAll()); + $token = $this->tokens->getAll()[0]; $this->assertLessThan(Carbon::now()->addHours(25), $token->getExpiresAt()); $this->assertGreaterThan(Carbon::now()->subHours(23), $token->getExpiresAt()); $this->assertEquals($user->getId(), $token->getUserId()); diff --git a/src/backend/tests/Unit/Source/UseCases/Users/Authenticate/UseCaseBaseTest.php b/src/backend/tests/Unit/Source/UseCases/Users/Authenticate/UseCaseBaseTest.php index d4292b95b338019da85e423147389f41051d671a..9be4d40ce7c3d730266cc93106cd44ade5e34622 100644 --- a/src/backend/tests/Unit/Source/UseCases/Users/Authenticate/UseCaseBaseTest.php +++ b/src/backend/tests/Unit/Source/UseCases/Users/Authenticate/UseCaseBaseTest.php @@ -57,7 +57,7 @@ abstract class UseCaseBaseTest extends TestCase public const VALID_TOKEN = '97055'; - public function setUp(): void + protected function setUp(): void { parent::setUp(); diff --git a/src/backend/tests/Unit/Source/UseCases/Users/CreateUser/PresenterTest.php b/src/backend/tests/Unit/Source/UseCases/Users/CreateUser/PresenterTest.php index e522f59d7447801c820b79bb8f7f3c31a49f7632..5b9b5a2d2595453ec2d04bd9f45ff16138e0411d 100644 --- a/src/backend/tests/Unit/Source/UseCases/Users/CreateUser/PresenterTest.php +++ b/src/backend/tests/Unit/Source/UseCases/Users/CreateUser/PresenterTest.php @@ -19,7 +19,7 @@ class PresenterTest extends TestCase protected array $response; - public function setUp(): void + protected function setUp(): void { parent::setUp(); diff --git a/src/backend/tests/Unit/Source/UseCases/Users/CreateUser/UseCaseTest.php b/src/backend/tests/Unit/Source/UseCases/Users/CreateUser/UseCaseTest.php index 131c38d02a485fd9c9a2b4d6be0caeb18be70bb1..6d4f52964f191343491206ac5273558fb1e18a60 100644 --- a/src/backend/tests/Unit/Source/UseCases/Users/CreateUser/UseCaseTest.php +++ b/src/backend/tests/Unit/Source/UseCases/Users/CreateUser/UseCaseTest.php @@ -21,7 +21,7 @@ class UseCaseTest extends TestCase protected PresenterStub $presenter; - public function setUp(): void + protected function setUp(): void { parent::setUp(); diff --git a/src/backend/tests/Unit/Source/UseCases/Users/DeleteUser/PresenterTest.php b/src/backend/tests/Unit/Source/UseCases/Users/DeleteUser/PresenterTest.php index 7af62b821cbf21f93b91110d913dd37e6e354b4b..b4c6acd0e4908b744a64158690a297b97aebeb9f 100644 --- a/src/backend/tests/Unit/Source/UseCases/Users/DeleteUser/PresenterTest.php +++ b/src/backend/tests/Unit/Source/UseCases/Users/DeleteUser/PresenterTest.php @@ -15,7 +15,7 @@ class PresenterTest extends TestCase protected array $response; - public function setUp(): void + protected function setUp(): void { parent::setUp(); diff --git a/src/backend/tests/Unit/Source/UseCases/Users/DeleteUser/UseCaseTest.php b/src/backend/tests/Unit/Source/UseCases/Users/DeleteUser/UseCaseTest.php index d853e7a30f13e4c15b48399f7e7bc911499cb37c..59ff3b9bfefcc9bd35a49f1edee6bc42180af2c4 100644 --- a/src/backend/tests/Unit/Source/UseCases/Users/DeleteUser/UseCaseTest.php +++ b/src/backend/tests/Unit/Source/UseCases/Users/DeleteUser/UseCaseTest.php @@ -24,7 +24,7 @@ class UseCaseTest extends TestCase protected AuthorizerStub $authorizer; - public function setUp(): void + protected function setUp(): void { parent::setUp(); diff --git a/src/backend/tests/Unit/Source/UseCases/Users/GetAllUsers/PresenterTest.php b/src/backend/tests/Unit/Source/UseCases/Users/GetAllUsers/PresenterTest.php index 8fe72f0b957ebfa13d47a9211d4ee00ae58b116e..8bb98164a4c3f057bf388be8468c8c45ce9a81e6 100644 --- a/src/backend/tests/Unit/Source/UseCases/Users/GetAllUsers/PresenterTest.php +++ b/src/backend/tests/Unit/Source/UseCases/Users/GetAllUsers/PresenterTest.php @@ -19,7 +19,7 @@ class PresenterTest extends TestCase protected array $response; - public function setUp(): void + protected function setUp(): void { parent::setUp(); diff --git a/src/backend/tests/Unit/Source/UseCases/Users/GetAllUsers/UseCaseTest.php b/src/backend/tests/Unit/Source/UseCases/Users/GetAllUsers/UseCaseTest.php index d3ae459b7e1987fe4f5a6d265750f8f3e1f32c9a..36f911d84a1d341cf2983c8cb3ccbd8dcc3d8e5e 100644 --- a/src/backend/tests/Unit/Source/UseCases/Users/GetAllUsers/UseCaseTest.php +++ b/src/backend/tests/Unit/Source/UseCases/Users/GetAllUsers/UseCaseTest.php @@ -28,7 +28,7 @@ class UseCaseTest extends TestCase protected PresenterStub $presenter; - public function setUp(): void + protected function setUp(): void { parent::setUp(); diff --git a/src/backend/tests/Unit/Source/UseCases/Users/GetUser/PresenterTest.php b/src/backend/tests/Unit/Source/UseCases/Users/GetUser/PresenterTest.php index 4bfde978f34e9521bb2e62214d833acc969ea8ba..faa02700c9c908fba3536ad618b27a26e0d6dba0 100644 --- a/src/backend/tests/Unit/Source/UseCases/Users/GetUser/PresenterTest.php +++ b/src/backend/tests/Unit/Source/UseCases/Users/GetUser/PresenterTest.php @@ -28,7 +28,7 @@ class PresenterTest extends TestCase */ protected array $response; - public function setUp(): void + protected function setUp(): void { parent::setUp(); diff --git a/src/backend/tests/Unit/Source/UseCases/Users/GetUser/UseCaseTest.php b/src/backend/tests/Unit/Source/UseCases/Users/GetUser/UseCaseTest.php index ec412bad99216b8f587b6ea49aa144cde6cdf73e..3650ec5482f51ccee4672d15e96a2045960a657d 100644 --- a/src/backend/tests/Unit/Source/UseCases/Users/GetUser/UseCaseTest.php +++ b/src/backend/tests/Unit/Source/UseCases/Users/GetUser/UseCaseTest.php @@ -20,7 +20,7 @@ class UseCaseTest extends TestCase protected PresenterStub $presenter; - public function setUp(): void + protected function setUp(): void { parent::setUp(); diff --git a/src/backend/tests/Unit/Source/UseCases/Users/UpdateUser/CurrentUserUpdateUseCaseTest.php b/src/backend/tests/Unit/Source/UseCases/Users/UpdateUser/CurrentUserUpdateUseCaseTest.php index 63b89399181b208fc9fa300770beef6e849dfb87..f292920f7cdd76064d0fe37e155ad5253f6438e7 100644 --- a/src/backend/tests/Unit/Source/UseCases/Users/UpdateUser/CurrentUserUpdateUseCaseTest.php +++ b/src/backend/tests/Unit/Source/UseCases/Users/UpdateUser/CurrentUserUpdateUseCaseTest.php @@ -41,7 +41,7 @@ class CurrentUserUpdateUseCaseTest extends TestCase */ protected AuthorizerStub $authorizer; - public function setUp(): void + protected function setUp(): void { parent::setUp(); diff --git a/src/backend/tests/Unit/Source/UseCases/Users/UpdateUser/PresenterTest.php b/src/backend/tests/Unit/Source/UseCases/Users/UpdateUser/PresenterTest.php index e9fb23bf2c2327914888dbeb7063f367055c53bd..75019845175ee0563c84a4956159b6be03bd7588 100644 --- a/src/backend/tests/Unit/Source/UseCases/Users/UpdateUser/PresenterTest.php +++ b/src/backend/tests/Unit/Source/UseCases/Users/UpdateUser/PresenterTest.php @@ -19,7 +19,7 @@ class PresenterTest extends TestCase protected array $response; - public function setUp(): void + protected function setUp(): void { parent::setUp(); diff --git a/src/backend/tests/Unit/Source/UseCases/Users/UpdateUser/UseCaseTest.php b/src/backend/tests/Unit/Source/UseCases/Users/UpdateUser/UseCaseTest.php index a60f5268d0fc16a47a1cc62d95f2ff0b34cb531b..eeaf6f5b5a4a2b68260bf6ad417bc886260fe728 100644 --- a/src/backend/tests/Unit/Source/UseCases/Users/UpdateUser/UseCaseTest.php +++ b/src/backend/tests/Unit/Source/UseCases/Users/UpdateUser/UseCaseTest.php @@ -27,7 +27,7 @@ class UseCaseTest extends TestCase protected AuthorizerStub $authorizer; - public function setUp(): void + protected function setUp(): void { parent::setUp();