From 1babe78d9eb79c6b73007aea882d4f3ca5ec6a2b Mon Sep 17 00:00:00 2001 From: WajahatKanju Date: Sun, 3 Mar 2024 15:38:18 +0500 Subject: [PATCH 1/2] added test for accounts, decorators --- accounts/tests.py | 3 - accounts/tests.pys | 42 +++++++ accounts/tests/__init__.py | 2 + accounts/tests/test_decorators.py | 187 ++++++++++++++++++++++++++++++ 4 files changed, 231 insertions(+), 3 deletions(-) delete mode 100644 accounts/tests.py create mode 100644 accounts/tests.pys create mode 100644 accounts/tests/__init__.py create mode 100644 accounts/tests/test_decorators.py diff --git a/accounts/tests.py b/accounts/tests.py deleted file mode 100644 index 7ce503c..0000000 --- a/accounts/tests.py +++ /dev/null @@ -1,3 +0,0 @@ -from django.test import TestCase - -# Create your tests here. diff --git a/accounts/tests.pys b/accounts/tests.pys new file mode 100644 index 0000000..9d1ecae --- /dev/null +++ b/accounts/tests.pys @@ -0,0 +1,42 @@ +from django.contrib.auth import get_user_model +from django.http import HttpResponse +from django.test import TestCase, RequestFactory +from accounts.decorators import admin_required + +User = get_user_model() + +class AdminRequiredDecoratorTests(TestCase): + def setUp(self): + self.superuser = User.objects.create_superuser( + username='admin', email='admin@example.com', password='password' + ) + self.user = User.objects.create_user( + username='user', email='user@example.com', password='password' + ) + self.factory = RequestFactory() + + def admin_view(self, request): + return HttpResponse() + + def test_admin_required_decorator(self): + # Apply the admin_required decorator to the view function + decorated_view = admin_required(self.admin_view) + + request = self.factory.get("/") + request.user = self.user + response = decorated_view(request) + self.assertEqual(response.status_code, 302) + + + def test_admin_required_decorator_with_redirect(self): + # Apply the admin_required decorator to the view function + decorated_view = admin_required(function=self.admin_view,redirect_to="/login/") + + request = self.factory.get("/") + request.user = self.user + response = decorated_view(request) + + # Assert redirection to login page + self.assertEqual(response.status_code, 302) + self.assertEqual(response.url, '/login/') + diff --git a/accounts/tests/__init__.py b/accounts/tests/__init__.py new file mode 100644 index 0000000..bc271df --- /dev/null +++ b/accounts/tests/__init__.py @@ -0,0 +1,2 @@ +# from .test_decorators import AdminRequiredDecoratorTests +# __all__ = [""] \ No newline at end of file diff --git a/accounts/tests/test_decorators.py b/accounts/tests/test_decorators.py new file mode 100644 index 0000000..06e7b10 --- /dev/null +++ b/accounts/tests/test_decorators.py @@ -0,0 +1,187 @@ +from django.contrib.auth import get_user_model +from django.http import HttpResponse +from django.test import TestCase, RequestFactory +from accounts.decorators import admin_required, lecturer_required, student_required + +User = get_user_model() + +class AdminRequiredDecoratorTests(TestCase): + def setUp(self): + self.superuser = User.objects.create_superuser( + username='admin', email='admin@example.com', password='password' + ) + self.user = User.objects.create_user( + username='user', email='user@example.com', password='password' + ) + self.factory = RequestFactory() + + def admin_view(self, request): + return HttpResponse("Admin View Content") + + def test_admin_required_decorator_redirects(self): + decorated_view = admin_required(self.admin_view) + + request = self.factory.get("/restricted-view") + request.user = self.user + response = decorated_view(request) + self.assertEqual(response.status_code, 302) + self.assertEqual(response.url, "/") + + + def test_admin_required_decorator_redirects_to_correct_path(self): + decorated_view = admin_required(function=self.admin_view,redirect_to="/login/") + + request = self.factory.get("restricted-view") + request.user = self.user + response = decorated_view(request) + + self.assertEqual(response.status_code, 302) + self.assertEqual(response.url, '/login/') + + def test_admin_required_decorator_does_not_redirect_superuser(self): + decorated_view = admin_required(self.admin_view) + + request = self.factory.get("/restricted-view") + request.user = self.superuser + response = decorated_view(request) + self.assertEqual(response.status_code, 200) + self.assertEqual(response.content, b"Admin View Content") + + def test_admin_redirect_decorator_return_correct_response(self): + decorated_view = admin_required(self.admin_view) + + request = self.factory.get("/restricted-view") + request.user = self.superuser + response = decorated_view(request) + self.assertIsInstance(response, HttpResponse) + + +class LecturerRequiredDecoratorTests(TestCase): + def setUp(self): + self.lecturer = User.objects.create_user( + username='lecturer', email='lecturer@example.com', password='password', is_lecturer=True + ) + self.user = User.objects.create_user( + username='user', email='user@example.com', password='password' + ) + self.factory = RequestFactory() + + def lecturer_view(self, request): + return HttpResponse("Lecturer View Content") + + def test_lecturer_required_decorator_redirects(self): + decorated_view = lecturer_required(self.lecturer_view) + + request = self.factory.get("/restricted-view") + request.user = self.user + + response = decorated_view(request) + + self.assertEqual(response.status_code, 302) + self.assertEqual(response.url, "/") + + def test_lecturer_required_decorator_redirects_to_correct_path(self): + decorated_view = lecturer_required(function=self.lecturer_view, redirect_to="/login/") + + request = self.factory.get("/restricted-view") + request.user = self.user + + response = decorated_view(request) + + self.assertEqual(response.status_code, 302) + self.assertEqual(response.url, '/login/') + + def test_lecturer_required_decorator_does_not_redirect_lecturer(self): + decorated_view = lecturer_required(self.lecturer_view) + + request = self.factory.get("/restricted-view") + request.user = self.lecturer + + response = decorated_view(request) + + self.assertEqual(response.status_code, 200) + self.assertEqual(response.content, b"Lecturer View Content") + + def test_lecturer_redirect_decorator_return_correct_response(self): + decorated_view = lecturer_required(self.lecturer_view) + + request = self.factory.get("/restricted-view") + request.user = self.lecturer + + response = decorated_view(request) + + self.assertIsInstance(response, HttpResponse) + +class StudentRequiredDecoratorTests(TestCase): + def setUp(self): + self.student = User.objects.create_user( + username='student', email='student@example.com', password='password', is_student=True + ) + self.user = User.objects.create_user( + username='user', email='user@example.com', password='password' + ) + self.factory = RequestFactory() + + def student_view(self, request): + return HttpResponse("Student View Content") + + def test_student_required_decorator_redirects(self): + # Apply the student_required decorator to the view function + decorated_view = student_required(self.student_view) + + # Create a mock request object with a non-student user + request = self.factory.get("/restricted-view") + request.user = self.user + + # Call the decorated view + response = decorated_view(request) + + # Assert that the response is a redirect (status code 302) + self.assertEqual(response.status_code, 302) + # Assert that the response redirects to the default URL ("/") + self.assertEqual(response.url, "/") + + def test_student_required_decorator_redirects_to_correct_path(self): + # Apply the student_required decorator to the view function + decorated_view = student_required(function=self.student_view, redirect_to="/login/") + + # Create a mock request object with a non-student user + request = self.factory.get("/restricted-view") + request.user = self.user + + # Call the decorated view + response = decorated_view(request) + + # Assert redirection to login page + self.assertEqual(response.status_code, 302) + self.assertEqual(response.url, '/login/') + + def test_student_required_decorator_does_not_redirect_student(self): + # Apply the student_required decorator to the view function + decorated_view = student_required(self.student_view) + + # Create a mock request object with a student user + request = self.factory.get("/restricted-view") + request.user = self.student + + # Call the decorated view + response = decorated_view(request) + + # Assert that the response is not a redirect (status code 200) + self.assertEqual(response.status_code, 200) + # Assert that the response contains the view content + self.assertEqual(response.content, b"Student View Content") + + def test_student_redirect_decorator_return_correct_response(self): + # Apply the student_required decorator to the view function + decorated_view = student_required(self.student_view) + + # Create a mock request object with a student user + request = self.factory.get("/restricted-view") + request.user = self.student + + # Call the decorated view + response = decorated_view(request) + + # Assert that the response is an instance of HttpResponse + self.assertIsInstance(response, HttpResponse) \ No newline at end of file From 425cdcba648fda80fbeca240584822cefa184e6f Mon Sep 17 00:00:00 2001 From: WajahatKanju Date: Sun, 3 Mar 2024 16:39:48 +0500 Subject: [PATCH 2/2] added test accounts_filters --- accounts/filters.py | 2 +- accounts/tests/test_decorators.py | 18 ---------- accounts/tests/test_filters.py | 55 +++++++++++++++++++++++++++++++ 3 files changed, 56 insertions(+), 19 deletions(-) create mode 100644 accounts/tests/test_filters.py diff --git a/accounts/filters.py b/accounts/filters.py index d24fd85..710820e 100644 --- a/accounts/filters.py +++ b/accounts/filters.py @@ -7,7 +7,7 @@ class LecturerFilter(django_filters.FilterSet): username = django_filters.CharFilter(lookup_expr="exact", label="") name = django_filters.CharFilter(method="filter_by_name", label="") email = django_filters.CharFilter(lookup_expr="icontains", label="") - + class Meta: model = User fields = ["username", "email"] diff --git a/accounts/tests/test_decorators.py b/accounts/tests/test_decorators.py index 06e7b10..9326626 100644 --- a/accounts/tests/test_decorators.py +++ b/accounts/tests/test_decorators.py @@ -126,62 +126,44 @@ class StudentRequiredDecoratorTests(TestCase): return HttpResponse("Student View Content") def test_student_required_decorator_redirects(self): - # Apply the student_required decorator to the view function decorated_view = student_required(self.student_view) - # Create a mock request object with a non-student user request = self.factory.get("/restricted-view") request.user = self.user - # Call the decorated view response = decorated_view(request) - # Assert that the response is a redirect (status code 302) self.assertEqual(response.status_code, 302) - # Assert that the response redirects to the default URL ("/") self.assertEqual(response.url, "/") def test_student_required_decorator_redirects_to_correct_path(self): - # Apply the student_required decorator to the view function decorated_view = student_required(function=self.student_view, redirect_to="/login/") - # Create a mock request object with a non-student user request = self.factory.get("/restricted-view") request.user = self.user - # Call the decorated view response = decorated_view(request) - # Assert redirection to login page self.assertEqual(response.status_code, 302) self.assertEqual(response.url, '/login/') def test_student_required_decorator_does_not_redirect_student(self): - # Apply the student_required decorator to the view function decorated_view = student_required(self.student_view) - # Create a mock request object with a student user request = self.factory.get("/restricted-view") request.user = self.student - # Call the decorated view response = decorated_view(request) - # Assert that the response is not a redirect (status code 200) self.assertEqual(response.status_code, 200) - # Assert that the response contains the view content self.assertEqual(response.content, b"Student View Content") def test_student_redirect_decorator_return_correct_response(self): - # Apply the student_required decorator to the view function decorated_view = student_required(self.student_view) - # Create a mock request object with a student user request = self.factory.get("/restricted-view") request.user = self.student - # Call the decorated view response = decorated_view(request) - # Assert that the response is an instance of HttpResponse self.assertIsInstance(response, HttpResponse) \ No newline at end of file diff --git a/accounts/tests/test_filters.py b/accounts/tests/test_filters.py new file mode 100644 index 0000000..fa16cf8 --- /dev/null +++ b/accounts/tests/test_filters.py @@ -0,0 +1,55 @@ +from django.test import TestCase +from accounts.filters import LecturerFilter, StudentFilter +from accounts.models import User, Student +from course.models import Program + +class LecturerFilterTestCase(TestCase): + def setUp(self): + User.objects.create(username="user1", first_name="John", last_name="Doe", email="john@example.com") + User.objects.create(username="user2", first_name="Jane", last_name="Doe", email="jane@example.com") + User.objects.create(username="user3", first_name="Alice", last_name="Smith", email="alice@example.com") + + def test_username_filter(self): + filter_set = LecturerFilter(data={"username": "user1"}) + self.assertEqual(len(filter_set.qs), 1) + + def test_name_filter(self): + filter_set = LecturerFilter(data={"name": "John"}) + self.assertEqual(len(filter_set.qs), 1) + + def test_email_filter(self): + filter_set = LecturerFilter(data={"email": "example.com"}) + self.assertEqual(len(filter_set.qs), 3) # All users should be returned since all have email addresses with "example.com" + + def test_combined_filters(self): + filter_set = LecturerFilter(data={"name": "Doe", "email": "example.com"}) + self.assertEqual(len(filter_set.qs), 2) # Both John Doe and Jane Doe should be returned + + filter_set = LecturerFilter(data={"name": "Alice", "email": "example.com"}) + self.assertEqual(len(filter_set.qs), 1) # 1 user matches Alice with "example.com" in the email + + def test_no_filters(self): + filter_set = LecturerFilter(data={}) + self.assertEqual(len(filter_set.qs), 3) # All users should be returned since no filters are applied + +class StudentFilterTestCase(TestCase): + def setUp(self): + program1 = Program.objects.create(title="Computer Science", summary="Program for computer science students") + program2 = Program.objects.create(title="Mathematics", summary="Program for mathematics students") + program3 = Program.objects.create(title="Computer Engineering", summary="Program for computer engineering students") + + Student.objects.create(student=User.objects.create(username="student1", first_name="John", last_name="Doe", email="john@example.com"), program=program1) + Student.objects.create(student=User.objects.create(username="student2", first_name="Jane", last_name="Williams", email="jane@example.com"), program=program2) + Student.objects.create(student=User.objects.create(username="student3", first_name="Alice", last_name="Smith", email="alice@example.com"), program=program3) + + def test_name_filter(self): + filtered_students = StudentFilter(data = {'name': 'John'}, queryset=Student.objects.all()).qs + self.assertEqual(filtered_students.count(), 1) + + def test_email_filter(self): + filter_set = StudentFilter(data={"email": "example.com"}) + self.assertEqual(len(filter_set.qs), 3) # All students should be returned since all have email addresses with "example.com" + + def test_program_filter(self): + filter_set = StudentFilter(data={"program__title": "Computer Science"}) + self.assertEqual(len(filter_set.qs), 1)