33namespace Tests \Unit \Controllers ;
44
55use App \Mail \PasswordResetMail ;
6+ use App \Models \PasswordResetToken ;
67use App \Models \User ;
7- use Carbon \CarbonInterface ;
8- use Illuminate \Support \Facades \DB ;
98use Illuminate \Support \Facades \Mail ;
10- use Illuminate \Support \Str ;
119use Illuminate \Testing \TestResponse ;
1210use PHPUnit \Framework \Attributes \Test ;
1311use Tests \TestCase ;
1412
1513class RequestPasswordResetControllerTest extends TestCase
1614{
17- public function settingUp (): void
18- {
19- parent ::settingUp ();
20-
21- $ this ->markTestSkipped ();
22- }
23-
2415 #[Test]
25- public function it_can_show_the_request_page (): void
16+ public function it_can_show_the_request_page ()
2617 {
27- $ this ->showRequestPage ( )->assertStatus (200 );
18+ $ this ->get ( route ( ' login.requestPassword ' ) )->assertStatus (200 );
2819 }
2920
3021 #[Test]
31- public function it_can_show_the_success_page (): void
22+ public function it_can_show_the_success_page ()
3223 {
33- $ this ->showSuccessPage ( )->assertStatus (200 );
24+ $ this ->get ( route ( ' login.requestPassword.success ' ) )->assertStatus (200 );
3425 }
3526
3627 #[Test]
37- public function it_can_request_a_reset (): void
28+ public function it_can_request_a_reset ()
3829 {
3930 Mail::fake ();
4031
41- $ user = factory ()->user ();
32+ $ user = User:: factory ()->create ();
4233
4334 $ this ->postRequestReset ($ user ->email )
4435 ->assertSessionHasNoErrors ()
4536 ->assertRedirect (route ('login.requestPassword.success ' ));
4637
47- $ record = DB ::table ('password_resets ' )->where ('email ' , $ user ->email )->first ();
38+ $ this ->assertSame (1 , PasswordResetToken::count ());
39+ $ token = PasswordResetToken::firstWhere ('user_id ' , $ user ->id );
4840
49- throw_if (! isset ($ record ->token ), '(message for Larastan) ' );
50-
51- $ this ->assertNotNull ($ record ->token );
41+ $ this ->assertTrue ($ token ->expires_at ->isFuture ());
5242
5343 Mail::assertQueued (PasswordResetMail::class, 1 );
5444 Mail::assertQueued (fn (PasswordResetMail $ email ) => $ email ->user ->id === $ user ->id );
5545 }
5646
5747 #[Test]
58- public function you_cant_request_a_reset_if_you_have_not_verified_your_email (): void
59- {
60- $ user = factory ()->user ();
61-
62- $ user ->update (['email_verified_at ' => null ]);
63-
64- $ this ->postRequestReset ($ user ->email )
65- ->assertSessionHasErrors ('email ' )
66- ->assertStatus (302 );
67- }
68-
69- #[Test]
70- public function it_throttles_reset_requests (): void
48+ public function it_throttles_reset_requests ()
7149 {
7250 Mail::fake ();
7351
74- $ user = factory ()->user ();
52+ $ user = User:: factory ()->create ();
7553
76- $ this ->createToken ($ user , now ()->subMinutes (5 ));
54+ $ token = PasswordResetToken::create ([
55+ 'user_id ' => $ user ->id ,
56+ 'hashed_token ' => str_uuid (),
57+ 'expires_at ' => now ()->addHours (4 ),
58+ 'created_at ' => now ()->subMinutes (15 ),
59+ ]);
7760
7861 $ this ->postRequestReset ($ user ->email )
7962 ->assertSessionHasErrors (['email ' => 'You already requested a password reset recently ' ])
8063 ->assertStatus (302 );
8164
65+ $ this ->assertModelExists ($ token );
66+
8267 Mail::assertNothingOutgoing ();
8368 }
8469
8570 #[Test]
86- public function it_updates_existing_tokens (): void
71+ public function it_updates_existing_tokens ()
8772 {
8873 Mail::fake ();
8974
90- $ user = factory ()->user ();
75+ $ user = User:: factory ()->create ();
9176
92- [$ email , $ token ] = $ this ->createToken ($ user , now ()->subHours (2 ));
77+ $ token = PasswordResetToken::create ([
78+ 'user_id ' => $ user ->id ,
79+ 'hashed_token ' => str_uuid (),
80+ 'expires_at ' => now ()->subHours (4 ),
81+ 'created_at ' => now ()->subMinutes (120 ),
82+ ]);
9383
9484 $ this ->postRequestReset ($ user ->email )
9585 ->assertSessionHasNoErrors ()
9686 ->assertRedirect (route ('login.requestPassword.success ' ));
9787
98- $ record = DB :: table ( ' password_resets ' )-> where ( ' email ' , $ user -> email )-> first ( );
88+ $ this -> assertModelMissing ( $ token );
9989
100- throw_if (! isset ($ record ->token ), '(message for Larastan) ' );
101-
102- $ this ->assertNotSame ($ record ->token , $ token );
90+ $ this ->assertNotNull ($ user ->passwordResetToken );
91+ $ this ->assertTrue ($ user ->passwordResetToken ->expires_at ->isFuture ());
10392 }
10493
10594 #[Test]
106- public function it_validates_the_email (): void
95+ public function it_validates_the_email ()
10796 {
108- $ user = factory ()->user ();
97+ $ user = User:: factory ()->create ();
10998
11099 $ this ->postRequestReset ('wrong@example.com ' )
111100 ->assertSessionHasErrors ('email ' )
112101 ->assertStatus (302 );
113102 }
114103
115104 #[Test]
116- public function it_can_render_the_password_reset_email (): void
105+ public function it_can_render_the_password_reset_email ()
117106 {
118- $ user = factory ()->user ();
107+ $ user = User:: factory ()->create ();
119108
120109 $ email = new PasswordResetMail ($ user , 'token ' );
121110
@@ -126,34 +115,8 @@ public function it_can_render_the_password_reset_email(): void
126115 $ email ->render ();
127116 }
128117
129- /** @return array{string, string} */
130- private function createToken (string |User $ email , string |CarbonInterface |null $ createdAt = null ): array
131- {
132- if ($ email instanceof User) {
133- $ email = $ email ->email ;
134- }
135-
136- DB ::table ('password_resets ' )->insert ([
137- 'email ' => $ email ,
138- 'token ' => $ token = sha1 (Str::random ()),
139- 'created_at ' => $ createdAt ?? now (),
140- ]);
141-
142- return [$ email , $ token ];
143- }
144-
145- private function showRequestPage (): TestResponse
146- {
147- return $ this ->get (route ('login.requestPassword ' ));
148- }
149-
150118 private function postRequestReset (string $ email ): TestResponse
151119 {
152120 return $ this ->post (route ('login.requestPassword ' ), ['email ' => $ email ]);
153121 }
154-
155- private function showSuccessPage (): TestResponse
156- {
157- return $ this ->get (route ('login.requestPassword.success ' ));
158- }
159122}
0 commit comments