Skip to content

Commit 4b524de

Browse files
committed
fix: tests based on updated implementation
1 parent 8a13303 commit 4b524de

File tree

5 files changed

+148
-131
lines changed

5 files changed

+148
-131
lines changed

.github/workflows/test.yml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,10 @@ jobs:
1212
env:
1313
MONGODB_URI: mongodb://db:27017
1414
DB_NAME: todo-app
15-
GOOGLE_JWT_SECRET_KEY: "test-secret-key-for-jwt"
1615
GOOGLE_JWT_ACCESS_LIFETIME: "3600"
1716
GOOGLE_JWT_REFRESH_LIFETIME: "604800"
1817
GOOGLE_OAUTH_CLIENT_ID: "test-client-id"
1918
GOOGLE_OAUTH_CLIENT_SECRET: "test-client-secret"
20-
GOOGLE_OAUTH_REDIRECT_URI: "http://localhost:3000/auth/callback"
2119
COOKIE_SECURE: "False"
2220
COOKIE_SAMESITE: "Lax"
2321

todo/tests/integration/base_mongo_test.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ def setUpClass(cls):
2222
cls.override = override_settings(
2323
MONGODB_URI=cls.mongo_url,
2424
DB_NAME="testdb",
25+
FRONTEND_URL="http://localhost:4000"
2526
)
2627
cls.override.enable()
2728
DatabaseManager.reset()
@@ -76,4 +77,4 @@ def get_user_model(self) -> UserModel:
7677
name=self.user_data["name"],
7778
createdAt=datetime.now(timezone.utc),
7879
updatedAt=datetime.now(timezone.utc),
79-
)
80+
)

todo/tests/unit/middlewares/test_jwt_auth.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,6 @@ def setUp(self):
1717
self.request.path = "/v1/tasks"
1818
self.request.headers = {}
1919
self.request.COOKIES = {}
20-
self._original_public_paths = settings.PUBLIC_PATHS
21-
settings.PUBLIC_PATHS = ["/v1/auth/google/login"]
22-
self.addCleanup(setattr, settings, "PUBLIC_PATHS", self._original_public_paths)
2320

2421
def test_public_path_authentication_bypass(self):
2522
"""Test that requests to public paths bypass authentication"""

todo/tests/unit/views/test_auth.py

Lines changed: 113 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,10 @@
44
from unittest.mock import patch, Mock, PropertyMock
55
from bson.objectid import ObjectId
66

7-
from todo.views.auth import (
8-
GoogleCallbackView,
9-
)
10-
11-
from todo.utils.google_jwt_utils import (
12-
generate_google_token_pair,
13-
)
14-
from todo.constants.messages import AppMessages, AuthErrorMessages
7+
from todo.views.auth import GoogleCallbackView
8+
from todo.utils.google_jwt_utils import generate_google_token_pair
9+
from todo.constants.messages import AppMessages
10+
from todo.tests.fixtures.user import google_auth_user_payload, users_db_data
1511

1612

1713
class GoogleLoginViewTests(APITestCase):
@@ -21,7 +17,7 @@ def setUp(self):
2117
self.url = reverse("google_login")
2218

2319
@patch("todo.services.google_oauth_service.GoogleOAuthService.get_authorization_url")
24-
def test_get_returns_redirect_url_for_html_request(self, mock_get_auth_url):
20+
def test_get_returns_redirect_for_html_request(self, mock_get_auth_url):
2521
mock_auth_url = "https://accounts.google.com/o/oauth2/auth"
2622
mock_state = "test_state"
2723
mock_get_auth_url.return_value = (mock_auth_url, mock_state)
@@ -41,12 +37,31 @@ def test_get_returns_json_for_json_request(self, mock_get_auth_url):
4137
response = self.client.get(self.url, HTTP_ACCEPT="application/json")
4238

4339
self.assertEqual(response.status_code, status.HTTP_200_OK)
40+
self.assertEqual(response.data["statusCode"], status.HTTP_200_OK)
41+
self.assertEqual(response.data["message"], "Google OAuth URL generated successfully")
4442
self.assertEqual(response.data["data"]["authUrl"], mock_auth_url)
4543
self.assertEqual(response.data["data"]["state"], mock_state)
4644
mock_get_auth_url.assert_called_once_with(None)
4745

4846
@patch("todo.services.google_oauth_service.GoogleOAuthService.get_authorization_url")
49-
def test_get_with_redirect_url(self, mock_get_auth_url):
47+
def test_get_returns_json_with_format_parameter(self, mock_get_auth_url):
48+
"""Test that format=json parameter returns JSON response"""
49+
mock_auth_url = "https://accounts.google.com/o/oauth2/auth"
50+
mock_state = "test_state"
51+
mock_get_auth_url.return_value = (mock_auth_url, mock_state)
52+
53+
response = self.client.get(f"{self.url}?format=json")
54+
55+
self.assertEqual(response.status_code, status.HTTP_200_OK)
56+
self.assertEqual(response.data["statusCode"], status.HTTP_200_OK)
57+
self.assertEqual(response.data["message"], "Google OAuth URL generated successfully")
58+
self.assertEqual(response.data["data"]["authUrl"], mock_auth_url)
59+
self.assertEqual(response.data["data"]["state"], mock_state)
60+
mock_get_auth_url.assert_called_once_with(None)
61+
62+
@patch("todo.services.google_oauth_service.GoogleOAuthService.get_authorization_url")
63+
def test_get_with_redirect_url_html_request(self, mock_get_auth_url):
64+
"""Test HTML request with redirect URL"""
5065
mock_auth_url = "https://accounts.google.com/o/oauth2/auth"
5166
mock_state = "test_state"
5267
mock_get_auth_url.return_value = (mock_auth_url, mock_state)
@@ -58,6 +73,33 @@ def test_get_with_redirect_url(self, mock_get_auth_url):
5873
self.assertEqual(response.url, mock_auth_url)
5974
mock_get_auth_url.assert_called_once_with(redirect_url)
6075

76+
@patch("todo.services.google_oauth_service.GoogleOAuthService.get_authorization_url")
77+
def test_get_with_redirect_url_json_request(self, mock_get_auth_url):
78+
"""Test JSON request with redirect URL"""
79+
mock_auth_url = "https://accounts.google.com/o/oauth2/auth"
80+
mock_state = "test_state"
81+
mock_get_auth_url.return_value = (mock_auth_url, mock_state)
82+
redirect_url = "http://localhost:3000/callback"
83+
84+
response = self.client.get(f"{self.url}?redirectURL={redirect_url}", HTTP_ACCEPT="application/json")
85+
86+
self.assertEqual(response.status_code, status.HTTP_200_OK)
87+
self.assertEqual(response.data["data"]["authUrl"], mock_auth_url)
88+
self.assertEqual(response.data["data"]["state"], mock_state)
89+
mock_get_auth_url.assert_called_once_with(redirect_url)
90+
91+
@patch("todo.services.google_oauth_service.GoogleOAuthService.get_authorization_url")
92+
def test_stores_state_in_session(self, mock_get_auth_url):
93+
"""Test that state is stored in session for both request types"""
94+
mock_auth_url = "https://accounts.google.com/o/oauth2/auth"
95+
mock_state = "test_state"
96+
mock_get_auth_url.return_value = (mock_auth_url, mock_state)
97+
98+
response = self.client.get(self.url, HTTP_ACCEPT="application/json")
99+
100+
self.assertEqual(response.status_code, status.HTTP_200_OK)
101+
self.assertEqual(self.client.session.get("oauth_state"), mock_state)
102+
61103

62104
class GoogleCallbackViewTests(APITestCase):
63105
def setUp(self):
@@ -66,6 +108,8 @@ def setUp(self):
66108
self.url = reverse("google_callback")
67109
self.factory = APIRequestFactory()
68110
self.view = GoogleCallbackView.as_view()
111+
112+
self.test_user_data = users_db_data[0]
69113

70114
def test_get_redirects_for_oauth_error(self):
71115
error = "access_denied"
@@ -80,67 +124,37 @@ def test_get_redirects_for_missing_code(self):
80124
self.assertEqual(response.status_code, status.HTTP_302_FOUND)
81125
self.assertIn("error=missing_code", response.url)
82126

83-
@patch("todo.services.google_oauth_service.GoogleOAuthService.handle_callback")
84-
@patch("todo.services.user_service.UserService.create_or_update_user")
85-
def test_get_redirects_for_valid_code_and_state(self, mock_create_user, mock_handle_callback):
86-
mock_google_data = {
87-
"id": "test_google_id",
88-
"email": "[email protected]",
89-
"name": "Test User",
90-
}
91-
user_id = str(ObjectId())
92-
mock_user = Mock()
93-
mock_user.id = ObjectId(user_id)
94-
mock_user.google_id = mock_google_data["id"]
95-
mock_user.email_id = mock_google_data["email"]
96-
mock_user.name = mock_google_data["name"]
97-
type(mock_user).id = PropertyMock(return_value=ObjectId(user_id))
98-
99-
mock_handle_callback.return_value = mock_google_data
100-
mock_create_user.return_value = mock_user
101-
102-
session = self.client.session
103-
session["oauth_state"] = "test_state"
104-
session.save()
105-
106-
response = self.client.get(f"{self.url}?code=test_code&state=test_state")
127+
def test_get_redirects_for_missing_state(self):
128+
response = self.client.get(f"{self.url}?code=test_code")
107129

108130
self.assertEqual(response.status_code, status.HTTP_302_FOUND)
109-
self.assertIn("success=true", response.url)
110-
self.assertIn("ext-access", response.cookies)
111-
self.assertIn("ext-refresh", response.cookies)
112-
self.assertNotIn("oauth_state", self.client.session)
131+
self.assertIn("error=missing_state", response.url)
113132

114-
def test_post_returns_error_for_missing_code(self):
115-
response = self.client.post(self.url, {})
116-
117-
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
118-
self.assertEqual(response.data["message"], "No authorization code received from Google")
119-
120-
def test_post_returns_error_for_invalid_state(self):
133+
def test_get_redirects_for_invalid_state(self):
121134
session = self.client.session
122-
session["oauth_state"] = "different_state"
135+
session["oauth_state"] = "correct_state"
123136
session.save()
124137

125-
response = self.client.post(self.url, {"code": "test_code", "state": "invalid_state"})
138+
response = self.client.get(f"{self.url}?code=test_code&state=wrong_state")
126139

127-
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
128-
self.assertEqual(response.data["message"], "Invalid state parameter")
140+
self.assertEqual(response.status_code, status.HTTP_302_FOUND)
141+
self.assertIn("error=invalid_state", response.url)
129142

130143
@patch("todo.services.google_oauth_service.GoogleOAuthService.handle_callback")
131144
@patch("todo.services.user_service.UserService.create_or_update_user")
132-
def test_post_handles_callback_successfully(self, mock_create_user, mock_handle_callback):
145+
def test_get_redirects_for_valid_code_and_state(self, mock_create_user, mock_handle_callback):
133146
mock_google_data = {
134-
"id": "test_google_id",
135-
"email": "[email protected]",
136-
"name": "Test User",
147+
"id": self.test_user_data["google_id"],
148+
"email": self.test_user_data["email_id"],
149+
"name": self.test_user_data["name"],
137150
}
151+
138152
user_id = str(ObjectId())
139153
mock_user = Mock()
140154
mock_user.id = ObjectId(user_id)
141-
mock_user.google_id = mock_google_data["id"]
142-
mock_user.email_id = mock_google_data["email"]
143-
mock_user.name = mock_google_data["name"]
155+
mock_user.google_id = self.test_user_data["google_id"]
156+
mock_user.email_id = self.test_user_data["email_id"]
157+
mock_user.name = self.test_user_data["name"]
144158
type(mock_user).id = PropertyMock(return_value=ObjectId(user_id))
145159

146160
mock_handle_callback.return_value = mock_google_data
@@ -150,50 +164,26 @@ def test_post_handles_callback_successfully(self, mock_create_user, mock_handle_
150164
session["oauth_state"] = "test_state"
151165
session.save()
152166

153-
response = self.client.post(self.url, {"code": "test_code", "state": "test_state"})
167+
response = self.client.get(f"{self.url}?code=test_code&state=test_state")
154168

155-
self.assertEqual(response.status_code, status.HTTP_200_OK)
156-
self.assertEqual(response.data["data"]["user"]["id"], user_id)
157-
self.assertEqual(response.data["data"]["user"]["name"], mock_user.name)
158-
self.assertEqual(response.data["data"]["user"]["email"], mock_user.email_id)
159-
self.assertEqual(response.data["data"]["user"]["google_id"], mock_user.google_id)
169+
self.assertEqual(response.status_code, status.HTTP_302_FOUND)
170+
self.assertIn("success=true", response.url)
160171
self.assertIn("ext-access", response.cookies)
161172
self.assertIn("ext-refresh", response.cookies)
162173
self.assertNotIn("oauth_state", self.client.session)
163174

164-
class GoogleRefreshViewTests(APITestCase):
165-
def setUp(self):
166-
super().setUp()
167-
self.client = APIClient()
168-
self.url = reverse("google_refresh")
169-
170-
def test_get_returns_401_when_no_refresh_token(self):
171-
response = self.client.get(self.url)
172-
173-
self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)
174-
self.assertEqual(response.data["message"], AuthErrorMessages.NO_REFRESH_TOKEN)
175-
self.assertEqual(response.data["authenticated"], False)
176-
self.assertEqual(response.data["statusCode"], status.HTTP_401_UNAUTHORIZED)
177-
178-
@patch("todo.utils.google_jwt_utils.validate_google_refresh_token")
179-
def test_get_refreshes_token_successfully(self, mock_validate_token):
180-
user_data = {
181-
"user_id": str(ObjectId()),
182-
"google_id": "test_google_id",
183-
"email": "[email protected]",
184-
"name": "Test User",
185-
}
186-
tokens = generate_google_token_pair(user_data)
187-
mock_validate_token.return_value = user_data
175+
@patch("todo.services.google_oauth_service.GoogleOAuthService.handle_callback")
176+
def test_get_redirects_for_callback_exception(self, mock_handle_callback):
177+
mock_handle_callback.side_effect = Exception("OAuth service error")
188178

189-
self.client.cookies["ext-refresh"] = tokens["refresh_token"]
179+
session = self.client.session
180+
session["oauth_state"] = "test_state"
181+
session.save()
190182

191-
response = self.client.get(self.url, HTTP_ACCEPT="application/json")
183+
response = self.client.get(f"{self.url}?code=test_code&state=test_state")
192184

193-
self.assertEqual(response.status_code, status.HTTP_200_OK)
194-
self.assertEqual(response.data["data"]["success"], True)
195-
self.assertEqual(response.data["message"], AppMessages.TOKEN_REFRESHED)
196-
self.assertIn("ext-access", response.cookies)
185+
self.assertEqual(response.status_code, status.HTTP_302_FOUND)
186+
self.assertIn("error=auth_failed", response.url)
197187

198188

199189
class GoogleLogoutViewTests(APITestCase):
@@ -202,52 +192,57 @@ def setUp(self):
202192
self.client = APIClient()
203193
self.url = reverse("google_logout")
204194

205-
def test_get_returns_success_and_clears_cookies(self):
206-
user_data = {
207-
"user_id": str(ObjectId()),
208-
"google_id": "test_google_id",
209-
"email": "[email protected]",
210-
"name": "Test User",
211-
}
212-
tokens = generate_google_token_pair(user_data)
213-
self.client.cookies["ext-access"] = tokens["access_token"]
214-
self.client.cookies["ext-refresh"] = tokens["refresh_token"]
215-
216-
response = self.client.get(self.url, HTTP_ACCEPT="application/json")
217-
218-
self.assertEqual(response.status_code, status.HTTP_200_OK)
219-
self.assertEqual(response.data["data"]["success"], True)
220-
self.assertEqual(response.data["message"], AppMessages.GOOGLE_LOGOUT_SUCCESS)
221-
self.assertEqual(response.cookies.get("ext-access").value, "")
222-
self.assertEqual(response.cookies.get("ext-refresh").value, "")
223-
224-
def test_get_redirects_when_not_json_request(self):
195+
def test_get_returns_json_response(self):
225196
redirect_url = "http://localhost:3000"
226197
self.client.cookies["ext-access"] = "test_access_token"
227198
self.client.cookies["ext-refresh"] = "test_refresh_token"
228199

229200
response = self.client.get(f"{self.url}?redirectURL={redirect_url}")
230201

231-
self.assertEqual(response.status_code, status.HTTP_302_FOUND)
232-
self.assertEqual(response.url, redirect_url)
202+
self.assertEqual(response.status_code, status.HTTP_200_OK)
203+
self.assertEqual(response.data["data"]["success"], True)
204+
self.assertEqual(response.data["message"], AppMessages.GOOGLE_LOGOUT_SUCCESS)
233205
self.assertEqual(response.cookies.get("ext-access").value, "")
234206
self.assertEqual(response.cookies.get("ext-refresh").value, "")
235207

236208
def test_post_returns_success_and_clears_cookies(self):
209+
"""Test that POST requests return JSON"""
237210
user_data = {
238211
"user_id": str(ObjectId()),
239-
"google_id": "test_google_id",
240-
"email": "[email protected]",
241-
"name": "Test User",
212+
"google_id": google_auth_user_payload["google_id"],
213+
"email": google_auth_user_payload["email"],
214+
"name": google_auth_user_payload["name"],
242215
}
243216
tokens = generate_google_token_pair(user_data)
244217
self.client.cookies["ext-access"] = tokens["access_token"]
245218
self.client.cookies["ext-refresh"] = tokens["refresh_token"]
246219

247-
response = self.client.post(self.url, HTTP_ACCEPT="application/json")
220+
response = self.client.post(self.url)
248221

249222
self.assertEqual(response.status_code, status.HTTP_200_OK)
250223
self.assertEqual(response.data["data"]["success"], True)
251224
self.assertEqual(response.data["message"], AppMessages.GOOGLE_LOGOUT_SUCCESS)
252225
self.assertEqual(response.cookies.get("ext-access").value, "")
253226
self.assertEqual(response.cookies.get("ext-refresh").value, "")
227+
228+
def test_logout_clears_session(self):
229+
"""Test that logout clears session data"""
230+
session = self.client.session
231+
session["oauth_state"] = "test_state"
232+
session["some_other_data"] = "test_data"
233+
session.save()
234+
235+
response = self.client.post(self.url)
236+
237+
self.assertEqual(response.status_code, status.HTTP_200_OK)
238+
self.assertNotIn("oauth_state", self.client.session)
239+
self.assertNotIn("some_other_data", self.client.session)
240+
241+
def test_logout_clears_sessionid_cookie(self):
242+
"""Test that logout clears sessionid cookie"""
243+
self.client.cookies["sessionid"] = "test_session_id"
244+
245+
response = self.client.post(self.url)
246+
247+
self.assertEqual(response.status_code, status.HTTP_200_OK)
248+
self.assertEqual(response.cookies.get("sessionid").value, "")

0 commit comments

Comments
 (0)