Skip to content

Commit 9adc854

Browse files
Merge pull request #8 from piyush-jaiswal/feature/improve_jwt_tests
Improve JWT tests
2 parents 4c4f815 + eaff7aa commit 9adc854

File tree

1 file changed

+40
-2
lines changed

1 file changed

+40
-2
lines changed

tests/test_auth.py

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
1+
import math
2+
13
import pytest
24

35
from app.models import User
46
from tests import utils
7+
from flask_jwt_extended import decode_token
58

69

710
class TestAuth:
811
TEST_EMAIL = "[email protected]"
912
TEST_PASSWORD = "testpassword"
13+
ACCESS_TOKEN_DELTA = 10800 # 3 hours in seconds
14+
REFRESH_TOKEN_DELTA = 259200 # 3 days in seconds
1015

1116
@pytest.fixture(autouse=True)
1217
def setup(self, client):
@@ -41,6 +46,34 @@ def _test_invalid_request_data(self, endpoint, expected_status=400):
4146
response = self.client.post(endpoint, data="not json data")
4247
assert response.status_code == 415
4348

49+
def _decode_token(self, token):
50+
# Needs Flask app context for secret/algorithms from current_app.config
51+
with self.client.application.app_context():
52+
return decode_token(token, allow_expired=False)
53+
def _assert_jwt_structure(self, token, expected_sub, expected_type, fresh=False):
54+
assert token.count(".") == 2, f"Token does not have three segments: {token}"
55+
payload = self._decode_token(token)
56+
assert payload["sub"] == expected_sub
57+
assert payload["type"] == expected_type
58+
assert "iat" in payload
59+
assert "exp" in payload
60+
assert "jti" in payload
61+
assert payload["fresh"] is fresh
62+
63+
# Expiry check
64+
expected_delta = None
65+
if expected_type == "access":
66+
expected_delta = self.ACCESS_TOKEN_DELTA
67+
elif expected_type == "refresh":
68+
expected_delta = self.REFRESH_TOKEN_DELTA
69+
70+
if expected_delta is not None:
71+
actual_delta = payload["exp"] - payload["iat"]
72+
# Allow a small margin (e.g., 0-2 seconds) for processing time
73+
assert math.isclose(actual_delta, expected_delta, abs_tol=2), (
74+
f"Token expiry delta {actual_delta} != expected {expected_delta}"
75+
)
76+
4477
def test_register_success(self, register_user):
4578
response = register_user(self.TEST_EMAIL, self.TEST_PASSWORD)
4679

@@ -81,8 +114,10 @@ def test_login_success(self, register_user, login_user):
81114
data = response.get_json()
82115
assert "access_token" in data
83116
assert "refresh_token" in data
84-
assert len(data["access_token"]) > 0
85-
assert len(data["refresh_token"]) > 0
117+
118+
user = self._verify_user_in_db(self.TEST_EMAIL)
119+
self._assert_jwt_structure(data["access_token"], expected_sub=str(user.id), expected_type="access", fresh=True)
120+
self._assert_jwt_structure(data["refresh_token"], expected_sub=str(user.id), expected_type="refresh")
86121

87122
def test_login_invalid_password(self, register_user, login_user):
88123
register_user(self.TEST_EMAIL, self.TEST_PASSWORD)
@@ -109,6 +144,9 @@ def test_refresh_token(self, register_user, login_user):
109144
assert data["access_token"] != original_access_token
110145
assert "refresh_token" not in data
111146

147+
user = self._verify_user_in_db(self.TEST_EMAIL)
148+
self._assert_jwt_structure(data["access_token"], expected_sub=str(user.id), expected_type="access")
149+
112150
def test_refresh_token_invalid(self, register_user, login_user):
113151
# Access token test
114152
register_user(self.TEST_EMAIL, self.TEST_PASSWORD)

0 commit comments

Comments
 (0)