from django.test import TestCase, RequestFactory from django.contrib.auth.models import User from django.contrib.gis.geos import Point from .models import CustomUser, Geo, ObjItem from .utils import format_coordinates, parse_pagination_params from .mixins import RoleRequiredMixin, CoordinateProcessingMixin from django.views import View class FormatCoordinatesTestCase(TestCase): """Тесты для функции format_coordinates""" def test_format_positive_coordinates(self): """Тест форматирования положительных координат""" result = format_coordinates(37.62, 55.75) self.assertEqual(result, "55.75N 37.62E") def test_format_negative_longitude(self): """Тест форматирования с отрицательной долготой""" result = format_coordinates(-122.42, 37.77) self.assertEqual(result, "37.77N 122.42W") def test_format_negative_latitude(self): """Тест форматирования с отрицательной широтой""" result = format_coordinates(151.21, -33.87) self.assertEqual(result, "33.87S 151.21E") def test_format_both_negative(self): """Тест форматирования с обеими отрицательными координатами""" result = format_coordinates(-58.38, -34.60) self.assertEqual(result, "34.6S 58.38W") class ParsePaginationParamsTestCase(TestCase): """Тесты для функции parse_pagination_params""" def setUp(self): self.factory = RequestFactory() def test_default_values(self): """Тест значений по умолчанию""" request = self.factory.get("/") page, per_page = parse_pagination_params(request) self.assertEqual(page, 1) self.assertEqual(per_page, 50) def test_custom_values(self): """Тест пользовательских значений""" request = self.factory.get("/?page=3&items_per_page=100") page, per_page = parse_pagination_params(request) self.assertEqual(page, 3) self.assertEqual(per_page, 100) def test_invalid_page_number(self): """Тест невалидного номера страницы""" request = self.factory.get("/?page=invalid") page, per_page = parse_pagination_params(request) self.assertEqual(page, 1) def test_negative_page_number(self): """Тест отрицательного номера страницы""" request = self.factory.get("/?page=-5") page, per_page = parse_pagination_params(request) self.assertEqual(page, 1) def test_max_items_per_page_limit(self): """Тест ограничения максимального количества элементов""" request = self.factory.get("/?items_per_page=20000") page, per_page = parse_pagination_params(request) self.assertEqual(per_page, 10000) class RoleRequiredMixinTestCase(TestCase): """Тесты для RoleRequiredMixin""" def setUp(self): self.factory = RequestFactory() def test_admin_has_access(self): """Тест что администратор имеет доступ""" user = User.objects.create_user(username="testuser", password="12345") # Get the automatically created CustomUser and set role to 'admin' custom_user = CustomUser.objects.get(user=user) custom_user.role = "admin" custom_user.save() # Refresh user to get updated customuser user.refresh_from_db() class TestView(RoleRequiredMixin, View): required_roles = ["admin", "moderator"] view = TestView() request = self.factory.get("/") request.user = user view.request = request self.assertTrue(view.test_func()) def test_user_without_role_denied(self): """Тест что пользователь без роли не имеет доступа""" user_no_role = User.objects.create_user(username="norole", password="12345") # Get the automatically created CustomUser - default role is 'user' custom_user_no_role = CustomUser.objects.get(user=user_no_role) self.assertEqual(custom_user_no_role.role, "user") class TestView(RoleRequiredMixin, View): required_roles = ["admin", "moderator"] view = TestView() request = self.factory.get("/") request.user = user_no_role view.request = request self.assertFalse(view.test_func()) class CoordinateProcessingMixinTestCase(TestCase): """Тесты для CoordinateProcessingMixin""" def setUp(self): self.factory = RequestFactory() def test_extract_geo_coordinates(self): """Тест извлечения координат геолокации""" class TestView(CoordinateProcessingMixin, View): pass view = TestView() request = self.factory.post( "/", {"geo_longitude": "37.62", "geo_latitude": "55.75"} ) view.request = request coords = view._extract_coordinates("geo") self.assertIsNotNone(coords) self.assertEqual(coords, (37.62, 55.75)) def test_extract_invalid_coordinates(self): """Тест извлечения невалидных координат""" class TestView(CoordinateProcessingMixin, View): pass view = TestView() request = self.factory.post( "/", {"geo_longitude": "invalid", "geo_latitude": "55.75"} ) view.request = request coords = view._extract_coordinates("geo") self.assertIsNone(coords) def test_process_coordinates(self): """Тест обработки координат и применения к объекту Geo""" class TestView(CoordinateProcessingMixin, View): pass view = TestView() request = self.factory.post( "/", { "geo_longitude": "37.62", "geo_latitude": "55.75", "kupsat_longitude": "37.63", "kupsat_latitude": "55.76", }, ) view.request = request geo_instance = Geo() view.process_coordinates(geo_instance) self.assertIsNotNone(geo_instance.coords) self.assertEqual(geo_instance.coords.coords, (37.62, 55.75)) self.assertIsNotNone(geo_instance.coords_kupsat) self.assertEqual(geo_instance.coords_kupsat.coords, (37.63, 55.76))