1
|
|
|
<?php |
2
|
|
|
declare(strict_types=1); |
3
|
|
|
|
4
|
|
|
namespace Tfboe\FmLib\Tests\Integration; |
5
|
|
|
|
6
|
|
|
use LaravelDoctrine\ORM\Facades\EntityManager; |
7
|
|
|
use Tfboe\FmLib\Entity\UserInterface; |
8
|
|
|
use Tfboe\FmLib\TestHelpers\DatabaseTestCase; |
9
|
|
|
use Tfboe\FmLib\Tests\Entity\User; |
10
|
|
|
use Tfboe\FmLib\Tests\Helpers\ApplicationGetter; |
11
|
|
|
|
12
|
|
|
/** |
13
|
|
|
* Class UserUnauthenticatedTest |
14
|
|
|
* @SuppressWarnings(PHPMD.TooManyPublicMethods) |
15
|
|
|
*/ |
16
|
|
|
class UserUnauthenticatedTest extends DatabaseTestCase |
17
|
|
|
{ |
18
|
|
|
use ApplicationGetter; |
19
|
|
|
|
20
|
|
|
//<editor-fold desc="Public Methods"> |
21
|
|
|
public function testAuthenticationError() |
22
|
|
|
{ |
23
|
|
|
$this->json('GET', '/userId')->seeStatusCode(401)->seeJsonEquals( |
24
|
|
|
["status" => 401, "message" => "Not logged in!", |
25
|
|
|
"name" => "AuthenticationException"]); |
26
|
|
|
} |
27
|
|
|
|
28
|
|
|
public function testCannotRecognizeExistingUsername() |
29
|
|
|
{ |
30
|
|
|
$password = $this->newPassword(); |
31
|
|
|
/** @var UserInterface $user */ |
32
|
|
|
$user = entity(User::class)->create(['originalPassword' => $password]); |
33
|
|
|
$this->json('POST', '/login', [ |
34
|
|
|
'email' => $user->getEmail(), |
35
|
|
|
'password' => $password . "wrong-password" |
36
|
|
|
]); |
37
|
|
|
$headers1 = $this->response->headers->all(); |
38
|
|
|
if (array_key_exists("date", $headers1)) { |
39
|
|
|
unset($headers1["date"]); |
40
|
|
|
} |
41
|
|
|
$content1 = $this->response->content(); |
42
|
|
|
|
43
|
|
|
$this->json('POST', '/login', [ |
44
|
|
|
'email' => $user->getEmail() . "wrong-email", |
45
|
|
|
'password' => $password . "wrong-password" |
46
|
|
|
]); |
47
|
|
|
|
48
|
|
|
$headers2 = $this->response->headers->all(); |
49
|
|
|
if (array_key_exists("date", $headers2)) { |
50
|
|
|
unset($headers2["date"]); |
51
|
|
|
} |
52
|
|
|
$content2 = $this->response->content(); |
53
|
|
|
self::assertEquals(json_encode($headers1), json_encode($headers2)); |
54
|
|
|
self::assertEquals($content1, $content2); |
55
|
|
|
} |
56
|
|
|
|
57
|
|
View Code Duplication |
public function testDoubleEmail() |
|
|
|
|
58
|
|
|
{ |
59
|
|
|
$user = entity(User::class)->create(['originalPassword' => 'testPassword']); |
60
|
|
|
$this->json('POST', '/register', [ |
61
|
|
|
'email' => $user->getEmail(), |
62
|
|
|
'password' => 'testPassword2' |
63
|
|
|
])->seeStatusCode(422)->seeJsonEquals(["errors" => ["email" => ["The email has already been taken."]], |
64
|
|
|
"message" => "The given data was invalid.", "name" => "ValidationException", "status" => 422]); |
65
|
|
|
} |
66
|
|
|
|
67
|
|
|
public function testEmailRequiredValidation() |
68
|
|
|
{ |
69
|
|
|
$this->json('POST', '/register', [ |
70
|
|
|
'password' => 'testPassword' |
71
|
|
|
])->seeStatusCode(422)->seeJsonEquals(["errors" => ["email" => ["The email field is required."]], |
72
|
|
|
"message" => "The given data was invalid.", "name" => "ValidationException", "status" => 422]); |
73
|
|
|
} |
74
|
|
|
|
75
|
|
View Code Duplication |
public function testEmailRequiredValidationLogin() |
|
|
|
|
76
|
|
|
{ |
77
|
|
|
entity(User::class)->create(['originalPassword' => 'testPassword']); |
78
|
|
|
$this->json('POST', '/login', [ |
79
|
|
|
'password' => 'testPassword' |
80
|
|
|
])->seeStatusCode(422)->seeJsonEquals(["errors" => ["email" => ["The email field is required."]], |
81
|
|
|
"message" => "The given data was invalid.", "name" => "ValidationException", "status" => 422]); |
82
|
|
|
} |
83
|
|
|
|
84
|
|
View Code Duplication |
public function testInvalidCredentials() |
|
|
|
|
85
|
|
|
{ |
86
|
|
|
$password = $this->newPassword(); |
87
|
|
|
/** @var UserInterface $user */ |
88
|
|
|
$user = entity(User::class)->create(['originalPassword' => $password]); |
89
|
|
|
/** @noinspection PhpUnhandledExceptionInspection */ |
90
|
|
|
$property = self::getProperty(User::class, 'id'); |
91
|
|
|
$property->setValue($user, "\x84invalid"); |
92
|
|
|
$this->json('POST', '/login', [ |
93
|
|
|
'email' => $user->getEmail(), |
94
|
|
|
'password' => $password . "wrong-password" |
95
|
|
|
])->seeStatusCode(401); |
96
|
|
|
self::assertNull($this->response->headers->get('jwt-token')); |
97
|
|
|
} |
98
|
|
|
|
99
|
|
View Code Duplication |
public function testInvalidEmailValidation() |
|
|
|
|
100
|
|
|
{ |
101
|
|
|
$this->json('POST', '/register', [ |
102
|
|
|
'email' => 'invalidEmail', |
103
|
|
|
'password' => 'testPassword' |
104
|
|
|
])->seeStatusCode(422)->seeJsonEquals(["errors" => ["email" => ["The email must be a valid email address."]], |
105
|
|
|
"message" => "The given data was invalid.", "name" => "ValidationException", "status" => 422]); |
106
|
|
|
} |
107
|
|
|
|
108
|
|
View Code Duplication |
public function testInvalidEmailValidationLogin() |
|
|
|
|
109
|
|
|
{ |
110
|
|
|
entity(User::class)->create(['originalPassword' => 'testPassword']); |
111
|
|
|
$this->json('POST', '/login', [ |
112
|
|
|
'email' => 'invalidEmail', |
113
|
|
|
'password' => 'testPassword' |
114
|
|
|
])->seeStatusCode(422)->seeJsonEquals(["errors" => ["email" => ["The email must be a valid email address."]], |
115
|
|
|
"message" => "The given data was invalid.", "name" => "ValidationException", "status" => 422]); |
116
|
|
|
} |
117
|
|
|
|
118
|
|
View Code Duplication |
public function testInvalidId() |
|
|
|
|
119
|
|
|
{ |
120
|
|
|
$password = $this->newPassword(); |
121
|
|
|
/** @var UserInterface $user */ |
122
|
|
|
$user = entity(User::class)->create(['originalPassword' => $password]); |
123
|
|
|
/** @noinspection PhpUnhandledExceptionInspection */ |
124
|
|
|
$property = self::getProperty(User::class, 'id'); |
125
|
|
|
$property->setValue($user, "\x84invalid"); |
126
|
|
|
$this->json('POST', '/login', [ |
127
|
|
|
'email' => $user->getEmail(), |
128
|
|
|
'password' => $password |
129
|
|
|
])->seeStatusCode(401); |
130
|
|
|
self::assertNull($this->response->headers->get('jwt-token')); |
131
|
|
|
} |
132
|
|
|
|
133
|
|
View Code Duplication |
public function testInvalidLastConfirmedAGBVersion() |
|
|
|
|
134
|
|
|
{ |
135
|
|
|
$this->json('POST', '/register', [ |
136
|
|
|
'email' => '[email protected]', |
137
|
|
|
'password' => 'testPassword', |
138
|
|
|
'confirmedAGBVersion' => 'noInt', |
139
|
|
|
])->seeStatusCode(422)->seeJsonEquals(["errors" => ["confirmedAGBVersion" => |
140
|
|
|
["The confirmed a g b version must be an integer."]], |
141
|
|
|
"message" => "The given data was invalid.", "name" => "ValidationException", "status" => 422]); |
142
|
|
|
} |
143
|
|
|
|
144
|
|
View Code Duplication |
public function testLogin() |
|
|
|
|
145
|
|
|
{ |
146
|
|
|
$password = $this->newPassword(); |
147
|
|
|
/** @var UserInterface $user */ |
148
|
|
|
$user = entity(User::class)->create(['originalPassword' => $password]); |
149
|
|
|
$this->json('POST', '/login', [ |
150
|
|
|
'email' => $user->getEmail(), |
151
|
|
|
'password' => $password |
152
|
|
|
])->seeJsonEquals(['id' => $user->getId()])->seeHeader('jwt-token'); |
153
|
|
|
self::assertNotNull($this->response->headers->get('jwt-token')); |
154
|
|
|
} |
155
|
|
|
|
156
|
|
View Code Duplication |
public function testMultipleValidationErrors() |
|
|
|
|
157
|
|
|
{ |
158
|
|
|
$this->json('POST', '/register', [ |
159
|
|
|
'password' => 5 |
160
|
|
|
])->seeStatusCode(422)->seeJsonEquals( |
161
|
|
|
["errors" => [ |
162
|
|
|
"email" => ["The email field is required."], |
163
|
|
|
"password" => ["The password must be a string.", "The password must be at least 8 characters."] |
164
|
|
|
], "message" => "The given data was invalid.", "name" => "ValidationException", "status" => 422]); |
165
|
|
|
} |
166
|
|
|
|
167
|
|
View Code Duplication |
public function testNegativeLastConfirmedAGBVersion() |
|
|
|
|
168
|
|
|
{ |
169
|
|
|
$this->json('POST', '/register', [ |
170
|
|
|
'email' => '[email protected]', |
171
|
|
|
'password' => 'testPassword', |
172
|
|
|
'confirmedAGBVersion' => -1, |
173
|
|
|
])->seeStatusCode(422)->seeJsonEquals(["errors" => ["confirmedAGBVersion" => |
174
|
|
|
["The confirmed a g b version must be at least 0."]], |
175
|
|
|
"message" => "The given data was invalid.", "name" => "ValidationException", "status" => 422]); |
176
|
|
|
} |
177
|
|
|
|
178
|
|
View Code Duplication |
public function testNoStringPassword() |
|
|
|
|
179
|
|
|
{ |
180
|
|
|
$this->json('POST', '/register', [ |
181
|
|
|
'email' => '[email protected]', |
182
|
|
|
'password' => 16511233 |
183
|
|
|
])->seeStatusCode(422)->seeJsonEquals(["errors" => ["password" => ["The password must be a string."]], |
184
|
|
|
"message" => "The given data was invalid.", "name" => "ValidationException", "status" => 422]); |
185
|
|
|
} |
186
|
|
|
|
187
|
|
View Code Duplication |
public function testNoStringPasswordLogin() |
|
|
|
|
188
|
|
|
{ |
189
|
|
|
/** @var UserInterface $user */ |
190
|
|
|
$user = entity(User::class)->create(['originalPassword' => 'testPassword']); |
191
|
|
|
$this->json('POST', '/login', [ |
192
|
|
|
'email' => $user->getEmail(), |
193
|
|
|
'password' => 16511233 |
194
|
|
|
])->seeStatusCode(422)->seeJsonEquals(["errors" => ["password" => ["The password must be a string."]], |
195
|
|
|
"message" => "The given data was invalid.", "name" => "ValidationException", "status" => 422]); |
196
|
|
|
} |
197
|
|
|
|
198
|
|
|
public function testPasswordRequiredValidation() |
199
|
|
|
{ |
200
|
|
|
$this->json('POST', '/register', [ |
201
|
|
|
'email' => '[email protected]' |
202
|
|
|
])->seeStatusCode(422)->seeJsonEquals(["errors" => ["password" => ["The password field is required."]], |
203
|
|
|
"message" => "The given data was invalid.", "name" => "ValidationException", "status" => 422]); |
204
|
|
|
} |
205
|
|
|
|
206
|
|
View Code Duplication |
public function testPasswordRequiredValidationLogin() |
|
|
|
|
207
|
|
|
{ |
208
|
|
|
/** @var UserInterface $user */ |
209
|
|
|
$user = entity(User::class)->create(['originalPassword' => 'testPassword']); |
210
|
|
|
$this->json('POST', '/login', [ |
211
|
|
|
'email' => $user->getEmail() |
212
|
|
|
])->seeStatusCode(422)->seeJsonEquals(["errors" => ["password" => ["The password field is required."]], |
213
|
|
|
"message" => "The given data was invalid.", "name" => "ValidationException", "status" => 422]); |
214
|
|
|
} |
215
|
|
|
|
216
|
|
|
public function testRegisterUser() |
217
|
|
|
{ |
218
|
|
|
$this->json('POST', '/register', [ |
219
|
|
|
'email' => '[email protected]', |
220
|
|
|
'password' => 'testPassword' |
221
|
|
|
])->seeJsonStructure(['id']); |
222
|
|
|
} |
223
|
|
|
|
224
|
|
|
public function testRegistrationWithLastConfirmedAGBVersion() |
225
|
|
|
{ |
226
|
|
|
$this->json('POST', '/register', [ |
227
|
|
|
'email' => '[email protected]', |
228
|
|
|
'password' => 'testPassword', |
229
|
|
|
'confirmedAGBVersion' => 5 |
230
|
|
|
])->seeJsonStructure(['id']); |
231
|
|
|
$result = json_decode($this->response->getContent(), true); |
232
|
|
|
/** @var UserInterface $user */ |
233
|
|
|
/** @noinspection PhpUndefinedMethodInspection */ |
234
|
|
|
$user = EntityManager::find(User::class, $result['id']); |
235
|
|
|
self::assertEquals(5, $user->getConfirmedAGBVersion()); |
236
|
|
|
} |
237
|
|
|
|
238
|
|
|
public function testRegistrationWithStringAsLastConfirmedAGBVersion() |
239
|
|
|
{ |
240
|
|
|
$this->json('POST', '/register', [ |
241
|
|
|
'email' => '[email protected]', |
242
|
|
|
'password' => 'testPassword', |
243
|
|
|
'confirmedAGBVersion' => "5" |
244
|
|
|
])->seeStatusCode(422)->seeJsonEquals(["errors" => |
245
|
|
|
["confirmedAGBVersion" => ["The confirmed a g b version must be an integer."]], |
246
|
|
|
"message" => "The given data was invalid.", "name" => "ValidationException", "status" => 422]); |
247
|
|
|
} |
248
|
|
|
|
249
|
|
View Code Duplication |
public function testTooShortPassword() |
|
|
|
|
250
|
|
|
{ |
251
|
|
|
$this->json('POST', '/register', [ |
252
|
|
|
'email' => '[email protected]', |
253
|
|
|
'password' => 'short' |
254
|
|
|
])->seeStatusCode(422)->seeJsonEquals(["errors" => |
255
|
|
|
["password" => ["The password must be at least 8 characters."]], |
256
|
|
|
"message" => "The given data was invalid.", "name" => "ValidationException", "status" => 422]); |
257
|
|
|
} |
258
|
|
|
|
259
|
|
View Code Duplication |
public function testTooShortPasswordLogin() |
|
|
|
|
260
|
|
|
{ |
261
|
|
|
/** @var UserInterface $user */ |
262
|
|
|
$user = entity(User::class)->create(['originalPassword' => 'testPassword']); |
263
|
|
|
$this->json('POST', '/login', [ |
264
|
|
|
'email' => $user->getEmail(), |
265
|
|
|
'password' => 'short' |
266
|
|
|
])->seeStatusCode(422)->seeJsonEquals(["errors" => [ |
267
|
|
|
"password" => ["The password must be at least 8 characters."]], |
268
|
|
|
"message" => "The given data was invalid.", "name" => "ValidationException", "status" => 422]); |
269
|
|
|
} |
270
|
|
|
|
271
|
|
View Code Duplication |
public function testWrongPassword() |
|
|
|
|
272
|
|
|
{ |
273
|
|
|
$password = $this->newPassword(); |
274
|
|
|
/** @var UserInterface $user */ |
275
|
|
|
$user = entity(User::class)->create(['originalPassword' => $password]); |
276
|
|
|
$this->json('POST', '/login', [ |
277
|
|
|
'email' => $user->getEmail(), |
278
|
|
|
'password' => $password . "wrong-password" |
279
|
|
|
])->seeStatusCode(401); |
280
|
|
|
self::assertNull($this->response->headers->get('jwt-token')); |
281
|
|
|
} |
282
|
|
|
|
283
|
|
View Code Duplication |
public function testWrongUsername() |
|
|
|
|
284
|
|
|
{ |
285
|
|
|
$password = $this->newPassword(); |
286
|
|
|
/** @var UserInterface $user */ |
287
|
|
|
$user = entity(User::class)->create(['originalPassword' => $password]); |
288
|
|
|
$this->json('POST', '/login', [ |
289
|
|
|
'email' => $user->getEmail() . "wrong-email", |
290
|
|
|
'password' => $password |
291
|
|
|
])->seeStatusCode(401); |
292
|
|
|
self::assertNull($this->response->headers->get('jwt-token')); |
293
|
|
|
} |
294
|
|
|
//</editor-fold desc="Public Methods"> |
295
|
|
|
} |
296
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.