-
Notifications
You must be signed in to change notification settings - Fork 14
test: adds test cases for authentication #83
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 17 commits
44b6410
13051de
54418c5
500f0b6
9060369
8ea44e6
5a4c210
48c3546
5915f74
8936274
9e0a411
89b65db
4101eb4
a18d700
114f5fe
6e84d9f
1689c8c
da7abf9
a2a8c41
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
from datetime import datetime, timezone | ||
|
||
users_db_data = [ | ||
{ | ||
"google_id": "123456789", | ||
"email_id": "[email protected]", | ||
"name": "Test User", | ||
"created_at": datetime.now(timezone.utc), | ||
"updated_at": datetime.now(timezone.utc), | ||
}, | ||
{ | ||
"google_id": "987654321", | ||
"email_id": "[email protected]", | ||
"name": "Another User", | ||
"created_at": datetime.now(timezone.utc), | ||
"updated_at": datetime.now(timezone.utc), | ||
}, | ||
] | ||
VaibhavSingh8 marked this conversation as resolved.
Show resolved
Hide resolved
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,31 @@ | ||
from http import HTTPStatus | ||
from bson import ObjectId | ||
from django.urls import reverse | ||
from rest_framework.test import APIClient | ||
from bson import ObjectId | ||
|
||
from todo.tests.fixtures.task import tasks_db_data | ||
from todo.tests.integration.base_mongo_test import BaseMongoTestCase | ||
from todo.constants.messages import ApiErrors, ValidationErrors | ||
from todo.utils.google_jwt_utils import generate_google_token_pair | ||
|
||
|
||
class AuthenticatedMongoTestCase(BaseMongoTestCase): | ||
def setUp(self): | ||
super().setUp() | ||
self._setup_auth_cookies() | ||
|
||
def _setup_auth_cookies(self): | ||
user_data = { | ||
"user_id": str(ObjectId()), | ||
"google_id": "test_google_id", | ||
"email": "[email protected]", | ||
"name": "Test User", | ||
} | ||
tokens = generate_google_token_pair(user_data) | ||
self.client.cookies["ext-access"] = tokens["access_token"] | ||
self.client.cookies["ext-refresh"] = tokens["refresh_token"] | ||
|
||
VaibhavSingh8 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
class TaskDetailAPIIntegrationTest(BaseMongoTestCase): | ||
class TaskDetailAPIIntegrationTest(AuthenticatedMongoTestCase): | ||
def setUp(self): | ||
super().setUp() | ||
self.db.tasks.delete_many({}) # Clear tasks to avoid DuplicateKeyError | ||
|
@@ -17,7 +35,6 @@ def setUp(self): | |
self.existing_task_id = str(self.task_doc["_id"]) | ||
self.non_existent_id = str(ObjectId()) | ||
self.invalid_task_id = "invalid-task-id" | ||
self.client = APIClient() | ||
|
||
def test_get_task_by_id_success(self): | ||
url = reverse("task_detail", args=[self.existing_task_id]) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,31 @@ | ||
from http import HTTPStatus | ||
from bson import ObjectId | ||
from django.urls import reverse | ||
from rest_framework.test import APIClient | ||
from bson import ObjectId | ||
|
||
from todo.tests.fixtures.task import tasks_db_data | ||
from todo.tests.integration.base_mongo_test import BaseMongoTestCase | ||
from todo.constants.messages import ValidationErrors, ApiErrors | ||
from todo.utils.google_jwt_utils import generate_google_token_pair | ||
|
||
|
||
class AuthenticatedMongoTestCase(BaseMongoTestCase): | ||
def setUp(self): | ||
super().setUp() | ||
self._setup_auth_cookies() | ||
|
||
def _setup_auth_cookies(self): | ||
user_data = { | ||
"user_id": str(ObjectId()), | ||
"google_id": "test_google_id", | ||
"email": "[email protected]", | ||
"name": "Test User", | ||
} | ||
tokens = generate_google_token_pair(user_data) | ||
self.client.cookies["ext-access"] = tokens["access_token"] | ||
self.client.cookies["ext-refresh"] = tokens["refresh_token"] | ||
VaibhavSingh8 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
|
||
class TaskDeleteAPIIntegrationTest(BaseMongoTestCase): | ||
class TaskDeleteAPIIntegrationTest(AuthenticatedMongoTestCase): | ||
def setUp(self): | ||
super().setUp() | ||
self.db.tasks.delete_many({}) | ||
|
@@ -17,7 +35,6 @@ def setUp(self): | |
self.existing_task_id = str(task_doc["_id"]) | ||
self.non_existent_id = str(ObjectId()) | ||
self.invalid_task_id = "invalid-task-id" | ||
self.client = APIClient() | ||
|
||
def test_delete_task_success(self): | ||
url = reverse("task_detail", args=[self.existing_task_id]) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
# This file is required for Python to recognize this directory as a package |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
from unittest import TestCase | ||
from unittest.mock import Mock, patch | ||
from django.http import HttpRequest, JsonResponse | ||
from django.conf import settings | ||
from rest_framework import status | ||
import json | ||
|
||
from todo.middlewares.jwt_auth import JWTAuthenticationMiddleware, is_google_user, is_rds_user, get_current_user_info | ||
from todo.constants.messages import AuthErrorMessages | ||
|
||
|
||
class JWTAuthenticationMiddlewareTests(TestCase): | ||
def setUp(self): | ||
self.get_response = Mock(return_value=JsonResponse({"data": "test"})) | ||
self.middleware = JWTAuthenticationMiddleware(self.get_response) | ||
self.request = Mock(spec=HttpRequest) | ||
self.request.path = "/v1/tasks" | ||
self.request.headers = {} | ||
self.request.COOKIES = {} | ||
settings.PUBLIC_PATHS = ["/v1/auth/google/login"] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This works, but the best practice is to use Django's reverse() utility. Hardcoding URL paths makes our tests brittle. If we ever decide to refactor our API routes (e.g., change /v1/ to /v2/), we would have to manually find and replace these strings in every single test file, which is error-prone. |
||
|
||
VaibhavSingh8 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
def test_public_path_authentication_bypass(self): | ||
"""Test that requests to public paths bypass authentication""" | ||
self.request.path = "/v1/auth/google/login" | ||
response = self.middleware(self.request) | ||
self.get_response.assert_called_once_with(self.request) | ||
self.assertEqual(response.status_code, 200) | ||
|
||
@patch("todo.middlewares.jwt_auth.JWTAuthenticationMiddleware._try_google_auth") | ||
def test_google_auth_success(self, mock_google_auth): | ||
"""Test successful Google authentication""" | ||
mock_google_auth.return_value = True | ||
self.request.COOKIES = {"ext-access": "google_token"} | ||
response = self.middleware(self.request) | ||
mock_google_auth.assert_called_once_with(self.request) | ||
self.get_response.assert_called_once_with(self.request) | ||
self.assertEqual(response.status_code, 200) | ||
|
||
@patch("todo.middlewares.jwt_auth.JWTAuthenticationMiddleware._try_rds_auth") | ||
def test_rds_auth_success(self, mock_rds_auth): | ||
"""Test successful RDS authentication""" | ||
mock_rds_auth.return_value = True | ||
self.request.COOKIES = {"rds_session_v2": "valid_token"} | ||
response = self.middleware(self.request) | ||
mock_rds_auth.assert_called_once_with(self.request) | ||
self.get_response.assert_called_once_with(self.request) | ||
self.assertEqual(response.status_code, 200) | ||
|
||
@patch("todo.middlewares.jwt_auth.JWTAuthenticationMiddleware._try_google_auth") | ||
def test_google_token_expired(self, mock_google_auth): | ||
"""Test handling of expired Google token""" | ||
mock_google_auth.return_value = False | ||
self.request.COOKIES = {"ext-access": "expired_token"} | ||
response = self.middleware(self.request) | ||
self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) | ||
response_data = json.loads(response.content) | ||
VaibhavSingh8 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
self.assertEqual(response_data["message"], AuthErrorMessages.AUTHENTICATION_REQUIRED) | ||
|
||
@patch("todo.middlewares.jwt_auth.JWTAuthenticationMiddleware._try_rds_auth") | ||
def test_rds_token_invalid(self, mock_rds_auth): | ||
"""Test handling of invalid RDS token""" | ||
mock_rds_auth.return_value = False | ||
self.request.COOKIES = {"rds_session_v2": "invalid_token"} | ||
response = self.middleware(self.request) | ||
self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) | ||
response_data = json.loads(response.content) | ||
self.assertEqual(response_data["message"], AuthErrorMessages.AUTHENTICATION_REQUIRED) | ||
|
||
def test_no_tokens_provided(self): | ||
"""Test handling of request with no tokens""" | ||
response = self.middleware(self.request) | ||
self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) | ||
response_data = json.loads(response.content) | ||
self.assertEqual(response_data["message"], AuthErrorMessages.AUTHENTICATION_REQUIRED) | ||
|
||
|
||
class AuthUtilityFunctionsTests(TestCase): | ||
def setUp(self): | ||
self.request = Mock(spec=HttpRequest) | ||
|
||
def test_is_google_user(self): | ||
"""Test checking if request is from Google user""" | ||
self.request.auth_type = "google" | ||
self.assertTrue(is_google_user(self.request)) | ||
|
||
self.request.auth_type = None | ||
self.assertFalse(is_google_user(self.request)) | ||
|
||
self.request.auth_type = "rds" | ||
self.assertFalse(is_google_user(self.request)) | ||
|
||
def test_is_rds_user(self): | ||
"""Test checking if request is from RDS user""" | ||
self.request.auth_type = "rds" | ||
self.assertTrue(is_rds_user(self.request)) | ||
|
||
self.request.auth_type = None | ||
self.assertFalse(is_rds_user(self.request)) | ||
|
||
self.request.auth_type = "google" | ||
self.assertFalse(is_rds_user(self.request)) | ||
|
||
def test_get_current_user_info_google(self): | ||
"""Test getting user info for Google user""" | ||
self.request.user_id = "google_user_123" | ||
self.request.auth_type = "google" | ||
self.request.google_id = "google_123" | ||
self.request.user_email = "[email protected]" | ||
self.request.user_name = "Test User" | ||
user_info = get_current_user_info(self.request) | ||
self.assertEqual(user_info["user_id"], "google_user_123") | ||
self.assertEqual(user_info["auth_type"], "google") | ||
self.assertEqual(user_info["google_id"], "google_123") | ||
self.assertEqual(user_info["email"], "[email protected]") | ||
self.assertEqual(user_info["name"], "Test User") | ||
|
||
def test_get_current_user_info_rds(self): | ||
"""Test getting user info for RDS user""" | ||
self.request.user_id = "rds_user_123" | ||
self.request.auth_type = "rds" | ||
self.request.user_role = "admin" | ||
user_info = get_current_user_info(self.request) | ||
self.assertEqual(user_info["user_id"], "rds_user_123") | ||
self.assertEqual(user_info["auth_type"], "rds") | ||
self.assertEqual(user_info["role"], "admin") | ||
|
||
def test_get_current_user_info_no_user_id(self): | ||
"""Test getting user info when no user ID is present""" | ||
user_info = get_current_user_info(self.request) | ||
self.assertIsNone(user_info) |
Uh oh!
There was an error while loading. Please reload this page.