test_models.py 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. from datetime import timedelta
  2. from django.core.exceptions import ValidationError
  3. from django.test import TestCase, override_settings
  4. from django.utils import timezone
  5. from users.choices import TokenVersionChoices
  6. from users.models import User, Token
  7. from utilities.testing import create_test_user
  8. class TokenTest(TestCase):
  9. """
  10. Test class for testing the functionality of the Token model.
  11. """
  12. @classmethod
  13. def setUpTestData(cls):
  14. """
  15. Set up test data for the Token model.
  16. """
  17. cls.user = create_test_user('User 1')
  18. def test_is_active(self):
  19. """
  20. Test the is_active property.
  21. """
  22. # Token with enabled status and no expiration date
  23. token = Token(user=self.user, enabled=True, expires=None)
  24. self.assertTrue(token.is_active)
  25. # Token with disabled status
  26. token.enabled = False
  27. self.assertFalse(token.is_active)
  28. # Token with enabled status and future expiration
  29. future_date = timezone.now() + timedelta(days=1)
  30. token = Token(user=self.user, enabled=True, expires=future_date)
  31. self.assertTrue(token.is_active)
  32. # Token with past expiration
  33. token.expires = timezone.now() - timedelta(days=1)
  34. self.assertFalse(token.is_active)
  35. # Token with disabled status and past expiration
  36. past_date = timezone.now() - timedelta(days=1)
  37. token = Token(user=self.user, enabled=False, expires=past_date)
  38. self.assertFalse(token.is_active)
  39. def test_is_expired(self):
  40. """
  41. Test the is_expired property.
  42. """
  43. # Token with no expiration
  44. token = Token(user=self.user, expires=None)
  45. self.assertFalse(token.is_expired)
  46. # Token with future expiration
  47. token.expires = timezone.now() + timedelta(days=1)
  48. self.assertFalse(token.is_expired)
  49. # Token with past expiration
  50. token.expires = timezone.now() - timedelta(days=1)
  51. self.assertTrue(token.is_expired)
  52. def test_cannot_create_token_with_past_expiration(self):
  53. """
  54. Test that creating a token with an expiration date in the past raises a ValidationError.
  55. """
  56. past_date = timezone.now() - timedelta(days=1)
  57. token = Token(user=self.user, expires=past_date)
  58. with self.assertRaises(ValidationError) as cm:
  59. token.clean()
  60. self.assertIn('expires', cm.exception.error_dict)
  61. def test_can_update_existing_expired_token(self):
  62. """
  63. Test that updating an already expired token does NOT raise a ValidationError.
  64. """
  65. # Create a valid token first with an expiration date in the past
  66. # bypasses the clean() method
  67. token = Token.objects.create(user=self.user)
  68. token.expires = timezone.now() - timedelta(days=1)
  69. token.save()
  70. # Try to update the description
  71. token.description = 'New Description'
  72. try:
  73. token.clean()
  74. token.save()
  75. except ValidationError:
  76. self.fail('Updating an expired token should not raise ValidationError')
  77. token.refresh_from_db()
  78. self.assertEqual(token.description, 'New Description')
  79. @override_settings(API_TOKEN_PEPPERS={})
  80. def test_v2_without_peppers_configured(self):
  81. """
  82. Attempting to save a v2 token without API_TOKEN_PEPPERS defined should raise a ValidationError.
  83. """
  84. token = Token(version=TokenVersionChoices.V2)
  85. with self.assertRaises(ValidationError):
  86. token.clean()
  87. class UserConfigTest(TestCase):
  88. @classmethod
  89. def setUpTestData(cls):
  90. user = User.objects.create_user(username='testuser')
  91. user.config.data = {
  92. 'a': True,
  93. 'b': {
  94. 'foo': 101,
  95. 'bar': 102,
  96. },
  97. 'c': {
  98. 'foo': {
  99. 'x': 201,
  100. },
  101. 'bar': {
  102. 'y': 202,
  103. },
  104. 'baz': {
  105. 'z': 203,
  106. }
  107. }
  108. }
  109. user.config.save()
  110. def test_get(self):
  111. userconfig = User.objects.get(username='testuser').config
  112. # Retrieve root and nested values
  113. self.assertEqual(userconfig.get('a'), True)
  114. self.assertEqual(userconfig.get('b.foo'), 101)
  115. self.assertEqual(userconfig.get('c.baz.z'), 203)
  116. # Invalid values should return None
  117. self.assertIsNone(userconfig.get('invalid'))
  118. self.assertIsNone(userconfig.get('a.invalid'))
  119. self.assertIsNone(userconfig.get('b.foo.invalid'))
  120. self.assertIsNone(userconfig.get('b.foo.x.invalid'))
  121. # Invalid values with a provided default should return the default
  122. self.assertEqual(userconfig.get('invalid', 'DEFAULT'), 'DEFAULT')
  123. self.assertEqual(userconfig.get('a.invalid', 'DEFAULT'), 'DEFAULT')
  124. self.assertEqual(userconfig.get('b.foo.invalid', 'DEFAULT'), 'DEFAULT')
  125. self.assertEqual(userconfig.get('b.foo.x.invalid', 'DEFAULT'), 'DEFAULT')
  126. def test_all(self):
  127. userconfig = User.objects.get(username='testuser').config
  128. flattened_data = {
  129. 'a': True,
  130. 'b.foo': 101,
  131. 'b.bar': 102,
  132. 'c.foo.x': 201,
  133. 'c.bar.y': 202,
  134. 'c.baz.z': 203,
  135. }
  136. # Retrieve a flattened dictionary containing all config data
  137. self.assertEqual(userconfig.all(), flattened_data)
  138. def test_set(self):
  139. userconfig = User.objects.get(username='testuser').config
  140. # Overwrite existing values
  141. userconfig.set('a', 'abc')
  142. userconfig.set('c.foo.x', 'abc')
  143. self.assertEqual(userconfig.data['a'], 'abc')
  144. self.assertEqual(userconfig.data['c']['foo']['x'], 'abc')
  145. # Create new values
  146. userconfig.set('d', 'abc')
  147. userconfig.set('b.baz', 'abc')
  148. self.assertEqual(userconfig.data['d'], 'abc')
  149. self.assertEqual(userconfig.data['b']['baz'], 'abc')
  150. # Set a value and commit to the database
  151. userconfig.set('a', 'def', commit=True)
  152. userconfig.refresh_from_db()
  153. self.assertEqual(userconfig.data['a'], 'def')
  154. # Attempt to change a branch node to a leaf node
  155. with self.assertRaises(TypeError):
  156. userconfig.set('b', 1)
  157. # Attempt to change a leaf node to a branch node
  158. with self.assertRaises(TypeError):
  159. userconfig.set('a.x', 1)
  160. def test_clear(self):
  161. userconfig = User.objects.get(username='testuser').config
  162. # Clear existing values
  163. userconfig.clear('a')
  164. userconfig.clear('b.foo')
  165. self.assertTrue('a' not in userconfig.data)
  166. self.assertTrue('foo' not in userconfig.data['b'])
  167. self.assertEqual(userconfig.data['b']['bar'], 102)
  168. # Clear a non-existing value; should fail silently
  169. userconfig.clear('invalid')