Skip to content

Commit 2b0f400

Browse files
Test of password reset endpoint is now working, with the resend.send call mocked
1 parent 8dbda40 commit 2b0f400

File tree

1 file changed

+70
-34
lines changed

1 file changed

+70
-34
lines changed

tests/test_authentication.py

Lines changed: 70 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
from fastapi.testclient import TestClient
33
from sqlmodel import Session, select
44
from datetime import timedelta
5+
from unittest.mock import patch
6+
import resend
57

68
from main import app
79
from utils.models import User, PasswordResetToken
@@ -51,6 +53,24 @@ def test_user_fixture(session: Session):
5153
return user
5254

5355

56+
# Mock email response fixture
57+
@pytest.fixture
58+
def mock_email_response():
59+
"""
60+
Returns a mock Email response object
61+
"""
62+
return resend.Email(id="6229f547-f3f6-4eb8-b0dc-82c1b09121b6")
63+
64+
65+
@pytest.fixture
66+
def mock_resend_send(mock_email_response):
67+
"""
68+
Patches resend.Emails.send to return a mock response
69+
"""
70+
with patch('resend.Emails.send', return_value=mock_email_response) as mock:
71+
yield mock
72+
73+
5474
# --- Authentication Helper Function Tests ---
5575

5676

@@ -166,40 +186,56 @@ def test_refresh_token_endpoint(client: TestClient, test_user: User):
166186
assert decoded["sub"] == test_user.email
167187

168188

169-
# # TODO: Mock email sending
170-
# def test_password_reset_flow(client: TestClient, session: Session, test_user: User):
171-
# # Test forgot password request
172-
# response = client.post(
173-
# "/auth/forgot_password",
174-
# data={"email": test_user.email},
175-
# follow_redirects=False
176-
# )
177-
# assert response.status_code == 303
178-
179-
# # Verify reset token was created
180-
# reset_token = session.exec(select(PasswordResetToken)
181-
# .where(PasswordResetToken.user_id == test_user.id)).first()
182-
# assert reset_token is not None
183-
# assert not reset_token.used
184-
185-
# # Test password reset
186-
# response = client.post(
187-
# "/auth/reset_password",
188-
# data={
189-
# "email": test_user.email,
190-
# "token": reset_token.token,
191-
# "new_password": "NewPass123!@#",
192-
# "confirm_new_password": "NewPass123!@#"
193-
# },
194-
# follow_redirects=False
195-
# )
196-
# assert response.status_code == 303
197-
198-
# # Verify password was updated and token was marked as used
199-
# session.refresh(test_user)
200-
# session.refresh(reset_token)
201-
# assert verify_password("NewPass123!@#", test_user.hashed_password)
202-
# assert reset_token.used
189+
def test_password_reset_flow(client: TestClient, session: Session, test_user: User, mock_resend_send):
190+
# Test forgot password request
191+
response = client.post(
192+
"/auth/forgot_password",
193+
data={"email": test_user.email},
194+
follow_redirects=False
195+
)
196+
assert response.status_code == 303
197+
198+
# Verify the email was "sent" with correct parameters
199+
mock_resend_send.assert_called_once()
200+
call_args = mock_resend_send.call_args[0][0] # Get the SendParams argument
201+
202+
# Verify SendParams structure and required fields
203+
assert isinstance(call_args, dict)
204+
assert isinstance(call_args["from"], str)
205+
assert isinstance(call_args["to"], list)
206+
assert isinstance(call_args["subject"], str)
207+
assert isinstance(call_args["html"], str)
208+
209+
# Verify content
210+
assert call_args["to"] == [test_user.email]
211+
assert call_args["from"] == "[email protected]"
212+
assert "Password Reset Request" in call_args["subject"]
213+
assert "reset_password" in call_args["html"]
214+
215+
# Verify reset token was created
216+
reset_token = session.exec(select(PasswordResetToken)
217+
.where(PasswordResetToken.user_id == test_user.id)).first()
218+
assert reset_token is not None
219+
assert not reset_token.used
220+
221+
# Test password reset
222+
response = client.post(
223+
"/auth/reset_password",
224+
data={
225+
"email": test_user.email,
226+
"token": reset_token.token,
227+
"new_password": "NewPass123!@#",
228+
"confirm_new_password": "NewPass123!@#"
229+
},
230+
follow_redirects=False
231+
)
232+
assert response.status_code == 303
233+
234+
# Verify password was updated and token was marked as used
235+
session.refresh(test_user)
236+
session.refresh(reset_token)
237+
assert verify_password("NewPass123!@#", test_user.hashed_password)
238+
assert reset_token.used
203239

204240

205241
def test_logout_endpoint(client: TestClient):

0 commit comments

Comments
 (0)