Skip to content

Commit a2e39a1

Browse files
refactored google auth callback (#101)
* refactored google auth callback * fix: failing tests
1 parent 01be215 commit a2e39a1

File tree

3 files changed

+92
-305
lines changed

3 files changed

+92
-305
lines changed

todo/tests/unit/views/test_auth.py

Lines changed: 39 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from rest_framework.test import APISimpleTestCase, APIClient, APIRequestFactory
1+
from rest_framework.test import APITestCase, APIClient, APIRequestFactory
22
from rest_framework.reverse import reverse
33
from rest_framework import status
44
from unittest.mock import patch, Mock, PropertyMock
@@ -14,7 +14,7 @@
1414
from todo.constants.messages import AppMessages, AuthErrorMessages
1515

1616

17-
class GoogleLoginViewTests(APISimpleTestCase):
17+
class GoogleLoginViewTests(APITestCase):
1818
def setUp(self):
1919
super().setUp()
2020
self.client = APIClient()
@@ -59,46 +59,54 @@ def test_get_with_redirect_url(self, mock_get_auth_url):
5959
mock_get_auth_url.assert_called_once_with(redirect_url)
6060

6161

62-
class GoogleCallbackViewTests(APISimpleTestCase):
62+
class GoogleCallbackViewTests(APITestCase):
6363
def setUp(self):
6464
super().setUp()
6565
self.client = APIClient()
6666
self.url = reverse("google_callback")
6767
self.factory = APIRequestFactory()
6868
self.view = GoogleCallbackView.as_view()
6969

70-
def test_get_returns_error_for_oauth_error(self):
70+
def test_get_redirects_for_oauth_error(self):
7171
error = "access_denied"
72-
request = self.factory.get(f"{self.url}?error={error}")
72+
response = self.client.get(f"{self.url}?error={error}")
7373

74-
response = self.view(request)
74+
self.assertEqual(response.status_code, status.HTTP_302_FOUND)
75+
self.assertIn("error=access_denied", response.url)
7576

76-
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
77-
self.assertEqual(response.data["message"], error)
78-
self.assertEqual(response.data["errors"][0]["detail"], error)
77+
def test_get_redirects_for_missing_code(self):
78+
response = self.client.get(self.url)
79+
80+
self.assertEqual(response.status_code, status.HTTP_302_FOUND)
81+
self.assertIn("error=missing_parameters", response.url)
82+
83+
def test_get_redirects_for_valid_code_and_state(self):
84+
response = self.client.get(f"{self.url}?code=test_code&state=test_state")
7985

80-
def test_get_returns_error_for_missing_code(self):
81-
request = self.factory.get(self.url)
86+
self.assertEqual(response.status_code, status.HTTP_302_FOUND)
87+
self.assertIn("code=test_code", response.url)
88+
self.assertIn("state=test_state", response.url)
8289

83-
response = self.view(request)
90+
def test_post_returns_error_for_missing_code(self):
91+
response = self.client.post(self.url, {})
8492

8593
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
8694
self.assertEqual(response.data["message"], "No authorization code received from Google")
87-
self.assertEqual(response.data["errors"][0]["detail"], "No authorization code received from Google")
8895

89-
def test_get_returns_error_for_invalid_state(self):
90-
request = self.factory.get(f"{self.url}?code=test_code&state=invalid_state")
91-
request.session = {"oauth_state": "different_state"}
96+
def test_post_returns_error_for_invalid_state(self):
97+
98+
session = self.client.session
99+
session["oauth_state"] = "different_state"
100+
session.save()
92101

93-
response = self.view(request)
102+
response = self.client.post(self.url, {"code": "test_code", "state": "invalid_state"})
94103

95104
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
96105
self.assertEqual(response.data["message"], "Invalid state parameter")
97-
self.assertEqual(response.data["errors"][0]["detail"], "Invalid state parameter")
98106

99107
@patch("todo.services.google_oauth_service.GoogleOAuthService.handle_callback")
100108
@patch("todo.services.user_service.UserService.create_or_update_user")
101-
def test_get_handles_callback_successfully(self, mock_create_user, mock_handle_callback):
109+
def test_post_handles_callback_successfully(self, mock_create_user, mock_handle_callback):
102110
mock_google_data = {
103111
"id": "test_google_id",
104112
"email": "[email protected]",
@@ -115,70 +123,26 @@ def test_get_handles_callback_successfully(self, mock_create_user, mock_handle_c
115123
mock_handle_callback.return_value = mock_google_data
116124
mock_create_user.return_value = mock_user
117125

118-
request = self.factory.get(f"{self.url}?code=test_code&state=test_state")
119-
request.session = {"oauth_state": "test_state"}
126+
session = self.client.session
127+
session["oauth_state"] = "test_state"
128+
session.save()
120129

121-
response = self.view(request)
130+
response = self.client.post(self.url, {"code": "test_code", "state": "test_state"})
122131

123132
self.assertEqual(response.status_code, status.HTTP_200_OK)
124-
self.assertIn("✅ Google OAuth Login Successful!", response.content.decode())
125-
self.assertIn(str(mock_user.id), response.content.decode())
126-
self.assertIn(mock_user.name, response.content.decode())
127-
self.assertIn(mock_user.email_id, response.content.decode())
128-
self.assertIn(mock_user.google_id, response.content.decode())
133+
self.assertEqual(response.data["data"]["user"]["id"], user_id)
134+
self.assertEqual(response.data["data"]["user"]["name"], mock_user.name)
135+
self.assertEqual(response.data["data"]["user"]["email"], mock_user.email_id)
136+
self.assertEqual(response.data["data"]["user"]["google_id"], mock_user.google_id)
129137
self.assertIn("ext-access", response.cookies)
130138
self.assertIn("ext-refresh", response.cookies)
131-
self.assertNotIn("oauth_state", request.session)
139+
self.assertNotIn("oauth_state", self.client.session)
132140

133141

134-
class GoogleAuthStatusViewTests(APISimpleTestCase):
135-
def setUp(self):
136-
super().setUp()
137-
self.client = APIClient()
138-
self.url = reverse("google_status")
139142

140-
def test_get_returns_401_when_no_access_token(self):
141-
response = self.client.get(self.url)
142143

143-
self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)
144-
self.assertEqual(response.data["message"], AuthErrorMessages.NO_ACCESS_TOKEN)
145-
self.assertEqual(response.data["authenticated"], False)
146-
self.assertEqual(response.data["statusCode"], status.HTTP_401_UNAUTHORIZED)
147144

148-
@patch("todo.utils.google_jwt_utils.validate_google_access_token")
149-
@patch("todo.services.user_service.UserService.get_user_by_id")
150-
def test_get_returns_user_info_when_authenticated(self, mock_get_user, mock_validate_token):
151-
user_id = str(ObjectId())
152-
user_data = {
153-
"user_id": user_id,
154-
"google_id": "test_google_id",
155-
"email": "[email protected]",
156-
"name": "Test User",
157-
}
158-
mock_validate_token.return_value = user_data
159-
160-
mock_user = Mock()
161-
mock_user.id = ObjectId(user_id)
162-
mock_user.google_id = "test_google_id"
163-
mock_user.email_id = "[email protected]"
164-
mock_user.name = "Test User"
165-
type(mock_user).id = PropertyMock(return_value=ObjectId(user_id))
166-
167-
mock_get_user.return_value = mock_user
168-
169-
tokens = generate_google_token_pair(user_data)
170-
self.client.cookies["ext-access"] = tokens["access_token"]
171-
172-
response = self.client.get(self.url, HTTP_ACCEPT="application/json")
173-
174-
self.assertEqual(response.status_code, status.HTTP_200_OK)
175-
self.assertEqual(response.data["data"]["user"]["id"], user_id)
176-
self.assertEqual(response.data["data"]["user"]["email"], mock_user.email_id)
177-
self.assertEqual(response.data["data"]["user"]["name"], mock_user.name)
178-
self.assertEqual(response.data["data"]["user"]["google_id"], mock_user.google_id)
179-
180-
181-
class GoogleRefreshViewTests(APISimpleTestCase):
145+
class GoogleRefreshViewTests(APITestCase):
182146
def setUp(self):
183147
super().setUp()
184148
self.client = APIClient()
@@ -213,7 +177,7 @@ def test_get_refreshes_token_successfully(self, mock_validate_token):
213177
self.assertIn("ext-access", response.cookies)
214178

215179

216-
class GoogleLogoutViewTests(APISimpleTestCase):
180+
class GoogleLogoutViewTests(APITestCase):
217181
def setUp(self):
218182
super().setUp()
219183
self.client = APIClient()
@@ -231,7 +195,7 @@ def test_get_returns_success_and_clears_cookies(self):
231195
self.client.cookies["ext-refresh"] = tokens["refresh_token"]
232196

233197
response = self.client.get(self.url, HTTP_ACCEPT="application/json")
234-
198+
235199
self.assertEqual(response.status_code, status.HTTP_200_OK)
236200
self.assertEqual(response.data["data"]["success"], True)
237201
self.assertEqual(response.data["message"], AppMessages.GOOGLE_LOGOUT_SUCCESS)

todo/urls.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
GoogleCallbackView,
88
GoogleRefreshView,
99
GoogleLogoutView,
10-
GoogleAuthStatusView,
1110
)
1211

1312
urlpatterns = [
@@ -17,7 +16,6 @@
1716
path("labels", LabelListView.as_view(), name="labels"),
1817
path("auth/google/login/", GoogleLoginView.as_view(), name="google_login"),
1918
path("auth/google/callback/", GoogleCallbackView.as_view(), name="google_callback"),
20-
path("auth/google/status/", GoogleAuthStatusView.as_view(), name="google_status"),
2119
path("auth/google/refresh/", GoogleRefreshView.as_view(), name="google_refresh"),
2220
path("auth/google/logout/", GoogleLogoutView.as_view(), name="google_logout"),
2321
]

0 commit comments

Comments
 (0)