Skip to content

Commit a40dab3

Browse files
committed
Add tests for Model and AuthUserProvider
1 parent 39a5606 commit a40dab3

File tree

9 files changed

+676
-10
lines changed

9 files changed

+676
-10
lines changed

composer.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,11 @@
2222
"aws/aws-sdk-php": "^3.0"
2323
},
2424
"require-dev": {
25+
"illuminate/auth": "^6.0",
2526
"symfony/var-dumper": "^5.0",
2627
"vlucas/phpdotenv": "^4.1",
27-
"mockery/mockery": "^1.3"
28+
"mockery/mockery": "^1.3",
29+
"phpunit/phpunit": "^9.0"
2830
},
2931
"autoload": {
3032
"psr-4": {
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?php
2+
3+
namespace Kitar\Dynamodb\Model;
4+
5+
use RuntimeException;
6+
7+
class KeyMissingException extends RuntimeException
8+
{
9+
}

src/Kitar/Dynamodb/Model/Model.php

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22

33
namespace Kitar\Dynamodb\Model;
44

5-
use Exception;
65
use Illuminate\Database\Eloquent\Model as BaseModel;
6+
use Kitar\Dynamodb\Model\KeyMissingException;
77

88
class Model extends BaseModel
99
{
@@ -53,6 +53,10 @@ public function __construct(array $attributes = [])
5353
*/
5454
public function getKey()
5555
{
56+
if (empty($this->primaryKey)) {
57+
throw new KeyMissingException("Primary (Partition) key is not defined.");
58+
}
59+
5660
$key = [];
5761

5862
$key[$this->primaryKey] = $this->getAttribute($this->primaryKey);
@@ -61,6 +65,19 @@ public function getKey()
6165
$key[$this->sortKey] = $this->getAttribute($this->sortKey);
6266
}
6367

68+
$missingKeys = [];
69+
70+
foreach ($key as $name => $value) {
71+
if (empty($value)) {
72+
$missingKeys[] = $name;
73+
}
74+
}
75+
76+
if (! empty($missingKeys)) {
77+
$keyNames = implode(', ', $missingKeys);
78+
throw new KeyMissingException("Some required key(s) has no value: {$keyNames}");
79+
}
80+
6481
return $key;
6582
}
6683

@@ -205,16 +222,10 @@ protected function performInsert($query)
205222
* Delete the model from the database.
206223
*
207224
* @return bool|null
208-
*
209-
* @throws \Exception
210225
*/
211226
public function delete()
212227
{
213-
foreach ($this->getKey() as $keyName => $keyValue) {
214-
if (empty($keyValue)) {
215-
throw new Exception("{$keyName} must be defined but missing.");
216-
}
217-
}
228+
$key = $this->getKey();
218229

219230
// If the model doesn't exist, there is nothing to delete so we'll just return
220231
// immediately and not do anything else. Otherwise, we will continue with a
@@ -227,7 +238,7 @@ public function delete()
227238
return false;
228239
}
229240

230-
$this->newQuery()->deleteItem($this->getKey());
241+
$this->newQuery()->deleteItem($key);
231242

232243
$this->exists = false;
233244

tests/Model/AuthUserProviderTest.php

Lines changed: 197 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
<?php
2+
3+
namespace Kitar\Dynamodb\Tests\Model;
4+
5+
use Aws\Result;
6+
use PHPUnit\Framework\TestCase;
7+
use Mockery as m;
8+
use Mockery\Adapter\Phpunit\MockeryPHPUnitIntegration;
9+
use Illuminate\Database\ConnectionResolver;
10+
use Kitar\Dynamodb\Model\KeyMissingException;
11+
use Kitar\Dynamodb\Model\AuthUserProvider;
12+
13+
class AuthUserProviderTest extends TestCase
14+
{
15+
use MockeryPHPUnitIntegration;
16+
17+
protected function tearDown() :void
18+
{
19+
m::close();
20+
}
21+
22+
protected function setConnectionResolver($connection)
23+
{
24+
$connectionResolver = new ConnectionResolver;
25+
$connectionResolver->addConnection('dynamodb', $connection);
26+
$connectionResolver->setDefaultConnection('dynamodb');
27+
UserA::setConnectionResolver($connectionResolver);
28+
UserB::setConnectionResolver($connectionResolver);
29+
UserC::setConnectionResolver($connectionResolver);
30+
}
31+
32+
protected function newConnectionMock()
33+
{
34+
$connection = m::mock('Kitar\Dynamodb\Connection[clientQuery]', [[]]);
35+
36+
return $connection;
37+
}
38+
39+
protected function sampleAwsResult()
40+
{
41+
return new Result([
42+
'Item' => [
43+
'partition' => [
44+
45+
],
46+
'password' => [
47+
'S' => 'foo'
48+
],
49+
'remember_token' => [
50+
'S' => 'valid_token'
51+
]
52+
],
53+
'@metadata' => [
54+
'statuscode' => 200
55+
]
56+
]);
57+
}
58+
59+
/** @test */
60+
public function it_can_retrieve_by_id()
61+
{
62+
$connection = $this->newConnectionMock();
63+
$connection->shouldReceive('getItem')->with([
64+
'TableName' => 'User',
65+
'Key' => [
66+
'partition' => [
67+
68+
]
69+
]
70+
])->andReturn($this->sampleAwsResult());
71+
$this->setConnectionResolver($connection);
72+
73+
$provider = new AuthUserProvider(new UserA);
74+
75+
$res = $provider->retrieveById('[email protected]');
76+
77+
$this->assertInstanceOf(UserA::class, $res);
78+
}
79+
80+
/** @test */
81+
public function it_can_retrieve_by_id_with_default_sort_key()
82+
{
83+
$connection = $this->newConnectionMock();
84+
$connection->shouldReceive('getItem')->with([
85+
'TableName' => 'User',
86+
'Key' => [
87+
'partition' => [
88+
89+
],
90+
'sort' => [
91+
'S' => 'sort_default'
92+
]
93+
]
94+
])->andReturn($this->sampleAwsResult());
95+
$this->setConnectionResolver($connection);
96+
97+
$provider = new AuthUserProvider(new UserC);
98+
99+
$res = $provider->retrieveById('[email protected]');
100+
101+
$this->assertInstanceOf(UserC::class, $res);
102+
}
103+
104+
/** @test */
105+
public function it_cannot_retrieve_by_id_without_default_sort_key()
106+
{
107+
$connection = $this->newConnectionMock();
108+
$this->setConnectionResolver($connection);
109+
110+
$provider = new AuthUserProvider(new UserB);
111+
112+
$this->expectException(KeyMissingException::class);
113+
114+
$provider->retrieveById('[email protected]');
115+
}
116+
117+
/** @test */
118+
public function it_can_retrieve_by_token()
119+
{
120+
$connection = $this->newConnectionMock();
121+
$connection->shouldReceive('getItem')->with([
122+
'TableName' => 'User',
123+
'Key' => [
124+
'partition' => [
125+
126+
]
127+
]
128+
])->andReturn($this->sampleAwsResult());
129+
$this->setConnectionResolver($connection);
130+
131+
$provider = new AuthUserProvider(new UserA);
132+
133+
$res = $provider->retrieveByToken('[email protected]', 'valid_token');
134+
135+
$this->assertInstanceOf(UserA::class, $res);
136+
}
137+
138+
/** @test */
139+
public function it_cannot_retrieve_by_token_with_invalid_token()
140+
{
141+
$connection = $this->newConnectionMock();
142+
$connection->shouldReceive('getItem')->with([
143+
'TableName' => 'User',
144+
'Key' => [
145+
'partition' => [
146+
147+
]
148+
]
149+
])->andReturn($this->sampleAwsResult());
150+
$this->setConnectionResolver($connection);
151+
152+
$provider = new AuthUserProvider(new UserA);
153+
154+
$res = $provider->retrieveByToken('[email protected]', 'invalid_token');
155+
156+
$this->assertNull($res);
157+
}
158+
159+
/** @test */
160+
public function it_can_update_remember_token()
161+
{
162+
$connection = $this->newConnectionMock();
163+
$this->setConnectionResolver($connection);
164+
165+
$provider = new AuthUserProvider(new UserA);
166+
167+
$user = new UserA(['partition' => '[email protected]']);
168+
169+
$provider->updateRememberToken($user, 'new_token');
170+
171+
$this->assertEquals('new_token', $user->getRememberToken());
172+
}
173+
174+
/** @test */
175+
public function it_can_retrieve_by_credentials()
176+
{
177+
$connection = $this->newConnectionMock();
178+
$connection->shouldReceive('getItem')->with([
179+
'TableName' => 'User',
180+
'Key' => [
181+
'partition' => [
182+
183+
]
184+
]
185+
])->andReturn($this->sampleAwsResult());
186+
$this->setConnectionResolver($connection);
187+
188+
$provider = new AuthUserProvider(new UserA);
189+
190+
$user = $provider->retrieveByCredentials([
191+
'email' => '[email protected]',
192+
'password' => 'foo'
193+
]);
194+
195+
$this->assertInstanceOf(UserA::class, $user);
196+
}
197+
}

0 commit comments

Comments
 (0)