Commit 8adeed43 authored by Jacob Priddy's avatar Jacob Priddy 👌
Browse files

Use database transactions to make tests faster and add last_seen_at for

doors
parent 3dfa5514
Pipeline #5781 failed with stages
in 3 minutes and 43 seconds
...@@ -8,7 +8,9 @@ use Illuminate\Database\Eloquent\Relations\BelongsToMany; ...@@ -8,7 +8,9 @@ use Illuminate\Database\Eloquent\Relations\BelongsToMany;
class Door extends Authenticatable class Door extends Authenticatable
{ {
protected $fillable = ['id', 'name', 'location', 'created_at', 'updated_at']; protected $fillable = ['id', 'name', 'location', 'created_at', 'updated_at', 'last_seen_at'];
protected $dates = ['last_seen_at'];
/** /**
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
......
...@@ -21,6 +21,7 @@ class CreateDoorsTable extends Migration ...@@ -21,6 +21,7 @@ class CreateDoorsTable extends Migration
// hashed // hashed
$table->string('api_token')->unique(); $table->string('api_token')->unique();
$table->timestamps(); $table->timestamps();
$table->timestamp('last_seen_at')->nullable();
}); });
} }
......
...@@ -37,6 +37,11 @@ class Door ...@@ -37,6 +37,11 @@ class Door
*/ */
protected ?Carbon $updatedAt; protected ?Carbon $updatedAt;
/**
* @var \Carbon\Carbon|null
*/
protected ?Carbon $lastSeenAt;
/** /**
* @param int $id * @param int $id
* @param string $location * @param string $location
...@@ -44,6 +49,7 @@ class Door ...@@ -44,6 +49,7 @@ class Door
* @param \Source\Entities\HashedSearchable $token * @param \Source\Entities\HashedSearchable $token
* @param Carbon|null $createdAt * @param Carbon|null $createdAt
* @param Carbon|null $updatedAt * @param Carbon|null $updatedAt
* @param \Carbon\Carbon|null $lastSeenAt
*/ */
public function __construct( public function __construct(
int $id, int $id,
...@@ -51,7 +57,8 @@ class Door ...@@ -51,7 +57,8 @@ class Door
string $name, string $name,
HashedSearchable $token, HashedSearchable $token,
?Carbon $createdAt = null, ?Carbon $createdAt = null,
?Carbon $updatedAt = null ?Carbon $updatedAt = null,
?Carbon $lastSeenAt = null
) { ) {
$this->id = $id; $this->id = $id;
$this->location = $location; $this->location = $location;
...@@ -59,6 +66,7 @@ class Door ...@@ -59,6 +66,7 @@ class Door
$this->token = $token; $this->token = $token;
$this->createdAt = $createdAt; $this->createdAt = $createdAt;
$this->updatedAt = $updatedAt; $this->updatedAt = $updatedAt;
$this->lastSeenAt = $lastSeenAt;
} }
/** /**
...@@ -101,6 +109,14 @@ class Door ...@@ -101,6 +109,14 @@ class Door
return $this->updatedAt; return $this->updatedAt;
} }
/**
* @return \Carbon\Carbon|null
*/
public function getLastSeenAt(): ?Carbon
{
return $this->lastSeenAt;
}
/** /**
* @param \Source\Entities\HashedSearchable|null $token * @param \Source\Entities\HashedSearchable|null $token
* @return bool * @return bool
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
namespace Source\Gateways\Doors; namespace Source\Gateways\Doors;
use Carbon\Carbon;
use Source\Entities\Door; use Source\Entities\Door;
use Source\Sanitize\CastsTo; use Source\Sanitize\CastsTo;
use Source\Entities\HashedSearchable; use Source\Entities\HashedSearchable;
...@@ -42,7 +43,8 @@ class DatabaseDoorsRepository implements DoorsRepository ...@@ -42,7 +43,8 @@ class DatabaseDoorsRepository implements DoorsRepository
$door->name, $door->name,
new HashedSearchable($door->api_token), new HashedSearchable($door->api_token),
$door->created_at, $door->created_at,
$door->updated_at $door->updated_at,
$door->last_seen_at
); );
} }
...@@ -55,13 +57,17 @@ class DatabaseDoorsRepository implements DoorsRepository ...@@ -55,13 +57,17 @@ class DatabaseDoorsRepository implements DoorsRepository
return null; return null;
} }
$dbDoor = \App\Door::where('api_token', $token->getHash())->first(); $door = \App\Door::where('api_token', $token->getHash())->first();
if (!$dbDoor) { if (!$door) {
return null; return null;
} }
return self::makeDoorFromDb($dbDoor); // Anytime a door is matched update last_seen_at
$door->last_seen_at = Carbon::now();
$door->save();
return self::makeDoorFromDb($door);
} }
/** /**
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
namespace Source\Gateways\Doors; namespace Source\Gateways\Doors;
use Carbon\Carbon;
use Source\Entities\Door; use Source\Entities\Door;
use Source\Entities\HashedSearchable; use Source\Entities\HashedSearchable;
use Source\Exceptions\EntityExistsException; use Source\Exceptions\EntityExistsException;
......
...@@ -98,6 +98,7 @@ abstract class BasePresenter ...@@ -98,6 +98,7 @@ abstract class BasePresenter
'location' => $door->getLocation(), 'location' => $door->getLocation(),
'created_at' => $this->formatDateTime($door->getCreatedAt()), 'created_at' => $this->formatDateTime($door->getCreatedAt()),
'updated_at' => $this->formatDateTime($door->getUpdatedAt()), 'updated_at' => $this->formatDateTime($door->getUpdatedAt()),
'last_seen_at' => $this->formatDateTime($door->getLastSeenAt()),
]; ];
} }
......
...@@ -25,11 +25,7 @@ class Authenticate implements AuthenticateUseCase ...@@ -25,11 +25,7 @@ class Authenticate implements AuthenticateUseCase
*/ */
public function check(Presenter $presenter, string $salt, ?string $token): void public function check(Presenter $presenter, string $salt, ?string $token): void
{ {
$found = null;
if ($token) {
$found = $this->doors->getByToken(HashedSearchable::hash($salt, $token)); $found = $this->doors->getByToken(HashedSearchable::hash($salt, $token));
}
$response = new ResponseModel(); $response = new ResponseModel();
......
...@@ -27,7 +27,11 @@ class DoorDatabaseTest extends DatabaseTestCase ...@@ -27,7 +27,11 @@ class DoorDatabaseTest extends DatabaseTestCase
{ {
$door = $this->doors->create(new Door(0, 'loc', 'name', new HashedSearchable('token'))); $door = $this->doors->create(new Door(0, 'loc', 'name', new HashedSearchable('token')));
$this->assertEquals($door, $this->doors->getByToken(new HashedSearchable('token'))); $found = $this->doors->getByToken(new HashedSearchable('token'));
$this->assertEquals('loc', $found->getLocation());
$this->assertEquals('name', $found->getName());
$this->assertNotNull($found->getLastSeenAt());
$this->assertNull($this->doors->getByToken(new HashedSearchable('i am autistic'))); $this->assertNull($this->doors->getByToken(new HashedSearchable('i am autistic')));
} }
......
...@@ -74,25 +74,25 @@ class DoorUserDatabaseTest extends DatabaseTestCase ...@@ -74,25 +74,25 @@ class DoorUserDatabaseTest extends DatabaseTestCase
*/ */
public function it_selects_the_group_intersection_of_doors_and_users(): void public function it_selects_the_group_intersection_of_doors_and_users(): void
{ {
$this->groups->create(new Group( $g1 = $this->groups->create(new Group(
0, 0,
'title', 'title',
'description' 'description'
)); ));
$this->groups->create(new Group( $g2 = $this->groups->create(new Group(
0, 0,
'title2', 'title2',
'description2' 'description2'
)); ));
$this->users->create(new User( $u1 = $this->users->create(new User(
0, 0,
'first', 'first',
'last', 'last',
'display', 'display',
'email' 'email'
)); ));
$this->users->create(new User( $u2 = $this->users->create(new User(
0, 0,
'first2', 'first2',
'last2', 'last2',
...@@ -100,24 +100,24 @@ class DoorUserDatabaseTest extends DatabaseTestCase ...@@ -100,24 +100,24 @@ class DoorUserDatabaseTest extends DatabaseTestCase
'email2' 'email2'
)); ));
$this->doors->create(new Door( $d1 = $this->doors->create(new Door(
0, 0,
'location', 'location',
'name', 'name',
new HashedSearchable('hash') new HashedSearchable('hash')
)); ));
$this->doors->create(new Door( $d2 = $this->doors->create(new Door(
0, 0,
'location2', 'location2',
'name2', 'name2',
new HashedSearchable('hash2') new HashedSearchable('hash2')
)); ));
$this->doorGroups->addDoorToGroup(1, 1); $this->doorGroups->addDoorToGroup($d1->getId(), $g1->getId());
$this->doorGroups->addDoorToGroup(2, 2); $this->doorGroups->addDoorToGroup($d2->getId(), $g2->getId());
$this->groupUsers->addUserToGroup(1, 1); $this->groupUsers->addUserToGroup($u1->getId(), $g1->getId());
$this->groupUsers->addUserToGroup(2, 2); $this->groupUsers->addUserToGroup($u1->getId(), $g2->getId());
$groups = $this->db->getDoorUserGroupIntersection('1', '1'); $groups = $this->db->getDoorUserGroupIntersection($d1->getId(), $u1->getId());
$this->assertCount(1, $groups); $this->assertCount(1, $groups);
$this->assertEquals('title', $groups[0]->getTitle()); $this->assertEquals('title', $groups[0]->getTitle());
$this->assertEquals('description', $groups[0]->getDescription()); $this->assertEquals('description', $groups[0]->getDescription());
......
...@@ -49,7 +49,7 @@ class GroupDatabaseTest extends DatabaseTestCase ...@@ -49,7 +49,7 @@ class GroupDatabaseTest extends DatabaseTestCase
$group = $this->groups->create(new Group(0, '', '')); $group = $this->groups->create(new Group(0, '', ''));
$this->assertEquals($group, $this->groups->get(1)); $this->assertEquals($group, $this->groups->get($group->getId()));
} }
/** /**
...@@ -67,7 +67,7 @@ class GroupDatabaseTest extends DatabaseTestCase ...@@ -67,7 +67,7 @@ class GroupDatabaseTest extends DatabaseTestCase
{ {
$group = $this->groups->create(new Group(0, '', '')); $group = $this->groups->create(new Group(0, '', ''));
$this->assertEquals($group, $this->groups->get(1)); $this->assertEquals($group, $this->groups->get($group->getId()));
} }
/** /**
...@@ -75,11 +75,11 @@ class GroupDatabaseTest extends DatabaseTestCase ...@@ -75,11 +75,11 @@ class GroupDatabaseTest extends DatabaseTestCase
*/ */
public function it_deletes_a_group(): void public function it_deletes_a_group(): void
{ {
$this->groups->create(new Group(0, '', '')); $group = $this->groups->create(new Group(0, '', ''));
$this->assertTrue($this->groups->delete(1)); $this->assertTrue($this->groups->delete($group->getId()));
$this->assertFalse($this->groups->exists(new Group(2, '', ''))); $this->assertFalse($this->groups->exists(new Group(9999999, '', '')));
$this->assertFalse($this->groups->delete(2)); $this->assertFalse($this->groups->delete(2));
...@@ -91,11 +91,10 @@ class GroupDatabaseTest extends DatabaseTestCase ...@@ -91,11 +91,10 @@ class GroupDatabaseTest extends DatabaseTestCase
*/ */
public function it_checks_existence_of_groups(): void public function it_checks_existence_of_groups(): void
{ {
$this->groups->create(new Group(0, '', '')); $g = $this->groups->create(new Group(0, '', ''));
$this->assertTrue($this->groups->exists(new Group(1, 'asdf', 'asdf'))); $this->assertFalse($this->groups->exists(new Group(0, 'asdf', 'asdf')));
$this->assertFalse($this->groups->exists(new Group(2, 'asdf', 'asdf'))); $this->assertTrue($this->groups->exists(new Group(0, '', '')));
$this->assertTrue($this->groups->exists(new Group(3, '', '')));
} }
/** /**
...@@ -103,11 +102,11 @@ class GroupDatabaseTest extends DatabaseTestCase ...@@ -103,11 +102,11 @@ class GroupDatabaseTest extends DatabaseTestCase
*/ */
public function it_updates_a_group(): void public function it_updates_a_group(): void
{ {
$this->groups->create(new Group(0, 'title', 'description')); $g = $this->groups->create(new Group(0, 'title', 'description'));
$this->groups->update(1, new Group(0, 'new title', 'new desc')); $this->groups->update($g->getId(), new Group(0, 'new title', 'new desc'));
$group = $this->groups->get(1); $group = $this->groups->get($g->getId());
$this->assertEquals('new title', $group->getTitle()); $this->assertEquals('new title', $group->getTitle());
$this->assertEquals('new desc', $group->getDescription()); $this->assertEquals('new desc', $group->getDescription());
......
...@@ -28,6 +28,16 @@ class GroupUserDatabaseTest extends DatabaseTestCase ...@@ -28,6 +28,16 @@ class GroupUserDatabaseTest extends DatabaseTestCase
*/ */
protected DatabaseGroupUserRepository $groupUsers; protected DatabaseGroupUserRepository $groupUsers;
/**
* @var \Source\Entities\User|null
*/
protected User $user;
/**
* @var \Source\Entities\Group
*/
protected Group $group;
public function setUp(): void public function setUp(): void
{ {
parent::setUp(); parent::setUp();
...@@ -35,8 +45,8 @@ class GroupUserDatabaseTest extends DatabaseTestCase ...@@ -35,8 +45,8 @@ class GroupUserDatabaseTest extends DatabaseTestCase
$this->users = new DatabaseUsersRepository(); $this->users = new DatabaseUsersRepository();
$this->groups = new DatabaseGroupsRepository(); $this->groups = new DatabaseGroupsRepository();
$this->groupUsers = new DatabaseGroupUserRepository(); $this->groupUsers = new DatabaseGroupUserRepository();
$this->users->create(new User(0, '', '', '', '', null, null, null)); $this->user = $this->users->create(new User(0, '', '', '', '', null, null, null));
$this->groups->create(new Group(0, '', '')); $this->group = $this->groups->create(new Group(0, '', ''));
} }
/** /**
...@@ -69,7 +79,7 @@ class GroupUserDatabaseTest extends DatabaseTestCase ...@@ -69,7 +79,7 @@ class GroupUserDatabaseTest extends DatabaseTestCase
{ {
$this->expectException(EntityNotFoundException::class); $this->expectException(EntityNotFoundException::class);
$this->groupUsers->addUserToGroup('1', 'ree'); $this->groupUsers->addUserToGroup($this->user->getId(), 'ree');
} }
/** /**
...@@ -80,7 +90,7 @@ class GroupUserDatabaseTest extends DatabaseTestCase ...@@ -80,7 +90,7 @@ class GroupUserDatabaseTest extends DatabaseTestCase
{ {
$this->expectException(EntityNotFoundException::class); $this->expectException(EntityNotFoundException::class);
$this->groupUsers->addUserToGroup('re', '1'); $this->groupUsers->addUserToGroup('re', $this->group->getId());
} }
...@@ -92,7 +102,7 @@ class GroupUserDatabaseTest extends DatabaseTestCase ...@@ -92,7 +102,7 @@ class GroupUserDatabaseTest extends DatabaseTestCase
{ {
$this->expectException(EntityNotFoundException::class); $this->expectException(EntityNotFoundException::class);
$this->groupUsers->removeUserFromGroup('1', 'ree'); $this->groupUsers->removeUserFromGroup($this->user->getId(), 'ree');
} }
/** /**
...@@ -103,7 +113,7 @@ class GroupUserDatabaseTest extends DatabaseTestCase ...@@ -103,7 +113,7 @@ class GroupUserDatabaseTest extends DatabaseTestCase
{ {
$this->expectException(EntityNotFoundException::class); $this->expectException(EntityNotFoundException::class);
$this->groupUsers->removeUserFromGroup('re', '1'); $this->groupUsers->removeUserFromGroup('re', $this->group->getId());
} }
/** /**
...@@ -112,13 +122,13 @@ class GroupUserDatabaseTest extends DatabaseTestCase ...@@ -112,13 +122,13 @@ class GroupUserDatabaseTest extends DatabaseTestCase
*/ */
public function it_can_add_remove_and_get_groups_for_users(): void public function it_can_add_remove_and_get_groups_for_users(): void
{ {
$this->groupUsers->addUserToGroup('1', '1'); $this->groupUsers->addUserToGroup($this->user->getId(), $this->group->getId());
$this->assertCount(1, $this->groupUsers->getGroupsForUser('1')); $this->assertCount(1, $this->groupUsers->getGroupsForUser($this->user->getId()));
$this->groupUsers->removeUserFromGroup('1', '1'); $this->groupUsers->removeUserFromGroup($this->user->getId(), $this->group->getId());
$this->assertCount(0, $this->groupUsers->getGroupsForUser('1')); $this->assertCount(0, $this->groupUsers->getGroupsForUser($this->user->getId()));
} }
/** /**
...@@ -127,8 +137,8 @@ class GroupUserDatabaseTest extends DatabaseTestCase ...@@ -127,8 +137,8 @@ class GroupUserDatabaseTest extends DatabaseTestCase
*/ */
public function it_can_get_users_for_a_group(): void public function it_can_get_users_for_a_group(): void
{ {
$this->groupUsers->addUserToGroup('1', '1'); $this->groupUsers->addUserToGroup($this->user->getId(), $this->group->getId());
$this->assertCount(1, $this->groupUsers->getUsersForGroup('1')); $this->assertCount(1, $this->groupUsers->getUsersForGroup($this->group->getId()));
} }
} }
...@@ -23,13 +23,18 @@ class TokenDatabaseTest extends DatabaseTestCase ...@@ -23,13 +23,18 @@ class TokenDatabaseTest extends DatabaseTestCase
*/ */
protected DatabaseUsersRepository $users; protected DatabaseUsersRepository $users;
/**
* @var \Source\Entities\User
*/
protected User $user;
public function setUp(): void public function setUp(): void
{ {
parent::setUp(); parent::setUp();
$this->tokens = new DatabaseTokensRepository(); $this->tokens = new DatabaseTokensRepository();
$this->users = new DatabaseUsersRepository(); $this->users = new DatabaseUsersRepository();
$this->users->create(new User(0, '', '', '', '', null, null, null)); $this->user = $this->users->create(new User(0, '', '', '', '', null, null, null));
} }
/** /**
...@@ -38,12 +43,11 @@ class TokenDatabaseTest extends DatabaseTestCase ...@@ -38,12 +43,11 @@ class TokenDatabaseTest extends DatabaseTestCase
*/ */
public function it_creates_and_finds_tokens(): void public function it_creates_and_finds_tokens(): void
{ {
$token = $this->tokens->create(new Token(0, 1, 'token')); $token = $this->tokens->create(new Token(0, $this->user->getId(), 'token'));
$dbToken = $this->tokens->findValidToken('token'); $dbToken = $this->tokens->findValidToken('token');
$this->assertEquals($token, $dbToken); $this->assertEquals($token, $dbToken);
$this->assertEquals(1, $dbToken->getUserId());
$nullToken = $this->tokens->findValidToken('reeee'); $nullToken = $this->tokens->findValidToken('reeee');