authentik.api.tests.test_ordering
1from django.db.models import OrderBy 2from django.test import TestCase 3from rest_framework.request import Request 4from rest_framework.test import APIRequestFactory 5 6from authentik.api.ordering import NullsAwareOrderingFilter 7from authentik.core.models import Token, User 8 9 10class MockView: 11 ordering_fields = "__all__" 12 ordering = None 13 14 15class TestNullsAwareOrderingFilter(TestCase): 16 17 def setUp(self): 18 self.filter = NullsAwareOrderingFilter() 19 self.view = MockView() 20 factory = APIRequestFactory() 21 self._req = lambda ordering: Request(factory.get("/", {"ordering": ordering})) 22 23 def _order_by(self, model, ordering): 24 qs = model.objects.all() 25 return self.filter.filter_queryset(self._req(ordering), qs, self.view).query.order_by 26 27 def test_nullable_asc_nulls_first(self): 28 """Ascending sort on a nullable field rewrites to nulls_first=True.""" 29 (expr,) = self._order_by(User, "last_login") 30 self.assertIsInstance(expr, OrderBy) 31 self.assertFalse(expr.descending) 32 self.assertTrue(expr.nulls_first) 33 34 def test_nullable_desc_nulls_last(self): 35 """Descending sort on a nullable field rewrites to nulls_last=True.""" 36 (expr,) = self._order_by(User, "-last_login") 37 self.assertIsInstance(expr, OrderBy) 38 self.assertTrue(expr.descending) 39 self.assertTrue(expr.nulls_last) 40 41 def test_non_nullable_passes_through(self): 42 """Non-nullable fields are left as plain string terms.""" 43 (expr,) = self._order_by(User, "username") 44 self.assertEqual(expr, "username") 45 46 def test_mixed_ordering(self): 47 """Only nullable terms are rewritten; non-nullable terms pass through unchanged.""" 48 first, second = self._order_by(User, "username,-last_login") 49 self.assertEqual(first, "username") 50 self.assertIsInstance(second, OrderBy) 51 self.assertTrue(second.descending) 52 self.assertTrue(second.nulls_last) 53 54 def test_expires_nullable(self): 55 """expires on ExpiringModel is nullable and is rewritten correctly.""" 56 (expr,) = self._order_by(Token, "-expires") 57 self.assertIsInstance(expr, OrderBy) 58 self.assertTrue(expr.descending) 59 self.assertTrue(expr.nulls_last)
16class TestNullsAwareOrderingFilter(TestCase): 17 18 def setUp(self): 19 self.filter = NullsAwareOrderingFilter() 20 self.view = MockView() 21 factory = APIRequestFactory() 22 self._req = lambda ordering: Request(factory.get("/", {"ordering": ordering})) 23 24 def _order_by(self, model, ordering): 25 qs = model.objects.all() 26 return self.filter.filter_queryset(self._req(ordering), qs, self.view).query.order_by 27 28 def test_nullable_asc_nulls_first(self): 29 """Ascending sort on a nullable field rewrites to nulls_first=True.""" 30 (expr,) = self._order_by(User, "last_login") 31 self.assertIsInstance(expr, OrderBy) 32 self.assertFalse(expr.descending) 33 self.assertTrue(expr.nulls_first) 34 35 def test_nullable_desc_nulls_last(self): 36 """Descending sort on a nullable field rewrites to nulls_last=True.""" 37 (expr,) = self._order_by(User, "-last_login") 38 self.assertIsInstance(expr, OrderBy) 39 self.assertTrue(expr.descending) 40 self.assertTrue(expr.nulls_last) 41 42 def test_non_nullable_passes_through(self): 43 """Non-nullable fields are left as plain string terms.""" 44 (expr,) = self._order_by(User, "username") 45 self.assertEqual(expr, "username") 46 47 def test_mixed_ordering(self): 48 """Only nullable terms are rewritten; non-nullable terms pass through unchanged.""" 49 first, second = self._order_by(User, "username,-last_login") 50 self.assertEqual(first, "username") 51 self.assertIsInstance(second, OrderBy) 52 self.assertTrue(second.descending) 53 self.assertTrue(second.nulls_last) 54 55 def test_expires_nullable(self): 56 """expires on ExpiringModel is nullable and is rewritten correctly.""" 57 (expr,) = self._order_by(Token, "-expires") 58 self.assertIsInstance(expr, OrderBy) 59 self.assertTrue(expr.descending) 60 self.assertTrue(expr.nulls_last)
Similar to TransactionTestCase, but use transaction.atomic() to achieve
test isolation.
In most situations, TestCase should be preferred to TransactionTestCase as it allows faster execution. However, there are some situations where using TransactionTestCase might be necessary (e.g. testing some transactional behavior).
On database backends with no transaction support, TestCase behaves as TransactionTestCase.
18 def setUp(self): 19 self.filter = NullsAwareOrderingFilter() 20 self.view = MockView() 21 factory = APIRequestFactory() 22 self._req = lambda ordering: Request(factory.get("/", {"ordering": ordering}))
Hook method for setting up the test fixture before exercising it.
28 def test_nullable_asc_nulls_first(self): 29 """Ascending sort on a nullable field rewrites to nulls_first=True.""" 30 (expr,) = self._order_by(User, "last_login") 31 self.assertIsInstance(expr, OrderBy) 32 self.assertFalse(expr.descending) 33 self.assertTrue(expr.nulls_first)
Ascending sort on a nullable field rewrites to nulls_first=True.
35 def test_nullable_desc_nulls_last(self): 36 """Descending sort on a nullable field rewrites to nulls_last=True.""" 37 (expr,) = self._order_by(User, "-last_login") 38 self.assertIsInstance(expr, OrderBy) 39 self.assertTrue(expr.descending) 40 self.assertTrue(expr.nulls_last)
Descending sort on a nullable field rewrites to nulls_last=True.
42 def test_non_nullable_passes_through(self): 43 """Non-nullable fields are left as plain string terms.""" 44 (expr,) = self._order_by(User, "username") 45 self.assertEqual(expr, "username")
Non-nullable fields are left as plain string terms.
47 def test_mixed_ordering(self): 48 """Only nullable terms are rewritten; non-nullable terms pass through unchanged.""" 49 first, second = self._order_by(User, "username,-last_login") 50 self.assertEqual(first, "username") 51 self.assertIsInstance(second, OrderBy) 52 self.assertTrue(second.descending) 53 self.assertTrue(second.nulls_last)
Only nullable terms are rewritten; non-nullable terms pass through unchanged.
55 def test_expires_nullable(self): 56 """expires on ExpiringModel is nullable and is rewritten correctly.""" 57 (expr,) = self._order_by(Token, "-expires") 58 self.assertIsInstance(expr, OrderBy) 59 self.assertTrue(expr.descending) 60 self.assertTrue(expr.nulls_last)
expires on ExpiringModel is nullable and is rewritten correctly.