django-cfg 1.1.61__py3-none-any.whl → 1.1.62__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. django_cfg/__init__.py +1 -1
  2. django_cfg/management/commands/rundramatiq.py +174 -202
  3. django_cfg/modules/django_tasks.py +54 -428
  4. django_cfg/modules/dramatiq_setup.py +16 -0
  5. {django_cfg-1.1.61.dist-info → django_cfg-1.1.62.dist-info}/METADATA +1 -1
  6. {django_cfg-1.1.61.dist-info → django_cfg-1.1.62.dist-info}/RECORD +9 -27
  7. django_cfg/apps/accounts/tests/__init__.py +0 -1
  8. django_cfg/apps/accounts/tests/test_models.py +0 -412
  9. django_cfg/apps/accounts/tests/test_otp_views.py +0 -143
  10. django_cfg/apps/accounts/tests/test_serializers.py +0 -331
  11. django_cfg/apps/accounts/tests/test_services.py +0 -401
  12. django_cfg/apps/accounts/tests/test_signals.py +0 -110
  13. django_cfg/apps/accounts/tests/test_views.py +0 -255
  14. django_cfg/apps/newsletter/tests/__init__.py +0 -1
  15. django_cfg/apps/newsletter/tests/run_tests.py +0 -47
  16. django_cfg/apps/newsletter/tests/test_email_integration.py +0 -256
  17. django_cfg/apps/newsletter/tests/test_email_tracking.py +0 -332
  18. django_cfg/apps/newsletter/tests/test_newsletter_manager.py +0 -83
  19. django_cfg/apps/newsletter/tests/test_newsletter_models.py +0 -157
  20. django_cfg/apps/support/tests/__init__.py +0 -0
  21. django_cfg/apps/support/tests/test_models.py +0 -106
  22. django_cfg/apps/tasks/@docs/CONFIGURATION.md +0 -663
  23. django_cfg/apps/tasks/@docs/README.md +0 -195
  24. django_cfg/apps/tasks/@docs/TASKS_QUEUES.md +0 -423
  25. django_cfg/apps/tasks/@docs/TROUBLESHOOTING.md +0 -506
  26. {django_cfg-1.1.61.dist-info → django_cfg-1.1.62.dist-info}/WHEEL +0 -0
  27. {django_cfg-1.1.61.dist-info → django_cfg-1.1.62.dist-info}/entry_points.txt +0 -0
  28. {django_cfg-1.1.61.dist-info → django_cfg-1.1.62.dist-info}/licenses/LICENSE +0 -0
@@ -1,331 +0,0 @@
1
- import os
2
- from django.test import TestCase
3
- from django.contrib.auth import get_user_model
4
- from django_cfg.apps.accounts.serializers.profile import (
5
- UserProfileUpdateSerializer,
6
- RegistrationSourceSerializer,
7
- UserRegistrationSourceSerializer,
8
- UserWithSourcesSerializer,
9
- )
10
- from django_cfg.apps.accounts.serializers.otp import OTPRequestSerializer, OTPVerifySerializer
11
- from django_cfg.apps.accounts.models import RegistrationSource, UserRegistrationSource
12
-
13
- User = get_user_model()
14
-
15
- # Disable Telegram notifications in tests
16
- os.environ["TELEGRAM_DISABLED"] = "true"
17
-
18
-
19
- class UserProfileUpdateSerializerTest(TestCase):
20
- def setUp(self):
21
- self.user = User.objects.create(
22
- username="testuser",
23
- email="test@example.com",
24
- first_name="John",
25
- last_name="Doe",
26
- )
27
-
28
- def test_valid_first_name_update(self):
29
- """Test valid first name update."""
30
- data = {"first_name": "Jane"}
31
- serializer = UserProfileUpdateSerializer(self.user, data=data, partial=True)
32
- self.assertTrue(serializer.is_valid())
33
- self.assertEqual(serializer.validated_data["first_name"], "Jane")
34
-
35
- def test_first_name_too_short(self):
36
- """Test first name validation - too short."""
37
- data = {"first_name": "J"}
38
- serializer = UserProfileUpdateSerializer(self.user, data=data, partial=True)
39
- self.assertFalse(serializer.is_valid())
40
- self.assertIn("first_name", serializer.errors)
41
-
42
- def test_valid_last_name_update(self):
43
- """Test valid last name update."""
44
- data = {"last_name": "Smith"}
45
- serializer = UserProfileUpdateSerializer(self.user, data=data, partial=True)
46
- self.assertTrue(serializer.is_valid())
47
- self.assertEqual(serializer.validated_data["last_name"], "Smith")
48
-
49
- def test_last_name_too_short(self):
50
- """Test last name validation - too short."""
51
- data = {"last_name": "S"}
52
- serializer = UserProfileUpdateSerializer(self.user, data=data, partial=True)
53
- self.assertFalse(serializer.is_valid())
54
- self.assertIn("last_name", serializer.errors)
55
-
56
- def test_valid_phone_update(self):
57
- """Test valid phone update."""
58
- data = {"phone": "+1 (555) 123-4567"}
59
- serializer = UserProfileUpdateSerializer(self.user, data=data, partial=True)
60
- self.assertTrue(serializer.is_valid())
61
- self.assertEqual(serializer.validated_data["phone"], "+1 (555) 123-4567")
62
-
63
- def test_invalid_phone(self):
64
- """Test phone validation - invalid format."""
65
- data = {"phone": "invalid-phone"}
66
- serializer = UserProfileUpdateSerializer(self.user, data=data, partial=True)
67
- self.assertFalse(serializer.is_valid())
68
- self.assertIn("phone", serializer.errors)
69
-
70
- def test_multiple_fields_update(self):
71
- """Test updating multiple fields at once."""
72
- data = {
73
- "first_name": "Jane",
74
- "last_name": "Smith",
75
- "company": "Tech Corp",
76
- "position": "Developer",
77
- }
78
- serializer = UserProfileUpdateSerializer(self.user, data=data, partial=True)
79
- self.assertTrue(serializer.is_valid())
80
- self.assertEqual(serializer.validated_data["first_name"], "Jane")
81
- self.assertEqual(serializer.validated_data["last_name"], "Smith")
82
- self.assertEqual(serializer.validated_data["company"], "Tech Corp")
83
- self.assertEqual(serializer.validated_data["position"], "Developer")
84
-
85
-
86
- class RegistrationSourceSerializerTest(TestCase):
87
- def setUp(self):
88
- self.source = RegistrationSource.objects.create(
89
- url="https://reforms.ai",
90
- name="Unreal Dashboard",
91
- description="Main dashboard for Unreal project",
92
- is_active=True,
93
- )
94
-
95
- def test_source_serializer_fields(self):
96
- """Test RegistrationSource serializer includes all required fields."""
97
- serializer = RegistrationSourceSerializer(self.source)
98
- data = serializer.data
99
-
100
- self.assertIn("id", data)
101
- self.assertIn("url", data)
102
- self.assertIn("name", data)
103
- self.assertIn("description", data)
104
- self.assertIn("is_active", data)
105
- self.assertIn("created_at", data)
106
- self.assertIn("updated_at", data)
107
-
108
- self.assertEqual(data["url"], "https://reforms.ai")
109
- self.assertEqual(data["name"], "Unreal Dashboard")
110
- self.assertEqual(data["description"], "Main dashboard for Unreal project")
111
- self.assertTrue(data["is_active"])
112
-
113
- def test_source_serializer_validation(self):
114
- """Test RegistrationSource serializer validation."""
115
- data = {
116
- "url": "https://test.example.com",
117
- "name": "Test Source",
118
- "description": "Test description",
119
- "is_active": True,
120
- }
121
- serializer = RegistrationSourceSerializer(data=data)
122
- self.assertTrue(serializer.is_valid())
123
-
124
-
125
- class UserRegistrationSourceSerializerTest(TestCase):
126
- def setUp(self):
127
- self.user = User.objects.create(username="testuser", email="test@example.com")
128
- self.source = RegistrationSource.objects.create(
129
- url="https://reforms.ai", name="Unreal Dashboard"
130
- )
131
- self.user_source = UserRegistrationSource.objects.create(
132
- user=self.user, source=self.source, first_registration=True
133
- )
134
-
135
- def test_user_source_serializer_fields(self):
136
- """Test UserRegistrationSource serializer includes all required fields."""
137
- serializer = UserRegistrationSourceSerializer(self.user_source)
138
- data = serializer.data
139
-
140
- self.assertIn("id", data)
141
- self.assertIn("user", data)
142
- self.assertIn("source", data)
143
- self.assertIn("first_registration", data)
144
- self.assertIn("registration_date", data)
145
-
146
- self.assertEqual(data["user"], self.user.id)
147
- self.assertTrue(data["first_registration"])
148
-
149
- # Check nested source data
150
- source_data = data["source"]
151
- self.assertEqual(source_data["url"], "https://reforms.ai")
152
- self.assertEqual(source_data["name"], "Unreal Dashboard")
153
-
154
- def test_user_source_serializer_validation(self):
155
- """Test UserRegistrationSource serializer validation."""
156
- data = {
157
- "user": self.user.id,
158
- "source": self.source.id,
159
- "first_registration": False,
160
- }
161
- serializer = UserRegistrationSourceSerializer(data=data)
162
- self.assertTrue(serializer.is_valid())
163
-
164
-
165
- class UserWithSourcesSerializerTest(TestCase):
166
- def setUp(self):
167
- self.user = User.objects.create(
168
- username="testuser",
169
- email="test@example.com",
170
- first_name="John",
171
- last_name="Doe",
172
- )
173
- self.source1 = RegistrationSource.objects.create(
174
- url="https://reforms.ai", name="Unreal Dashboard"
175
- )
176
- self.source2 = RegistrationSource.objects.create(
177
- url="https://app.example.com", name="Example App"
178
- )
179
- self.user_source1 = UserRegistrationSource.objects.create(
180
- user=self.user, source=self.source1, first_registration=True
181
- )
182
- self.user_source2 = UserRegistrationSource.objects.create(
183
- user=self.user, source=self.source2, first_registration=False
184
- )
185
-
186
- def test_user_with_sources_serializer_fields(self):
187
- """Test UserWithSources serializer includes sources information."""
188
- serializer = UserWithSourcesSerializer(self.user)
189
- data = serializer.data
190
-
191
- # Check basic user fields
192
- self.assertIn("id", data)
193
- self.assertIn("email", data)
194
- self.assertIn("first_name", data)
195
- self.assertIn("last_name", data)
196
-
197
- # Check sources fields
198
- self.assertIn("sources", data)
199
- self.assertIn("primary_source", data)
200
-
201
- # Check sources data
202
- sources = data["sources"]
203
- self.assertEqual(len(sources), 2)
204
-
205
- # Check primary source
206
- primary_source = data["primary_source"]
207
- self.assertIsNotNone(primary_source)
208
- self.assertEqual(primary_source["url"], "https://reforms.ai")
209
- self.assertEqual(primary_source["name"], "Unreal Dashboard")
210
-
211
- def test_user_with_sources_no_sources(self):
212
- """Test UserWithSources serializer for user without sources."""
213
- user_without_sources = User.objects.create(
214
- username="nosources", email="nosources@example.com"
215
- )
216
- serializer = UserWithSourcesSerializer(user_without_sources)
217
- data = serializer.data
218
-
219
- self.assertEqual(len(data["sources"]), 0)
220
- self.assertIsNone(data["primary_source"])
221
-
222
-
223
- class OTPRequestSerializerTest(TestCase):
224
- def test_valid_otp_request(self):
225
- """Test valid OTP request with source_url."""
226
- data = {
227
- "email": "test@example.com",
228
- "source_url": "https://reforms.ai",
229
- }
230
- serializer = OTPRequestSerializer(data=data)
231
- self.assertTrue(serializer.is_valid())
232
- self.assertEqual(serializer.validated_data["email"], "test@example.com")
233
- self.assertEqual(
234
- serializer.validated_data["source_url"], "https://reforms.ai"
235
- )
236
-
237
- def test_valid_otp_request_without_source_url(self):
238
- """Test valid OTP request without source_url."""
239
- data = {"email": "test@example.com"}
240
- serializer = OTPRequestSerializer(data=data)
241
- self.assertTrue(serializer.is_valid())
242
- self.assertEqual(serializer.validated_data["email"], "test@example.com")
243
- self.assertNotIn("source_url", serializer.validated_data)
244
-
245
- def test_valid_otp_request_empty_source_url(self):
246
- """Test valid OTP request with empty source_url."""
247
- data = {"email": "test@example.com", "source_url": ""}
248
- serializer = OTPRequestSerializer(data=data)
249
- self.assertTrue(serializer.is_valid())
250
- self.assertEqual(serializer.validated_data["email"], "test@example.com")
251
- self.assertIsNone(serializer.validated_data.get("source_url"))
252
-
253
- def test_invalid_email(self):
254
- """Test invalid email in OTP request."""
255
- data = {
256
- "email": "invalid-email",
257
- "source_url": "https://reforms.ai",
258
- }
259
- serializer = OTPRequestSerializer(data=data)
260
- self.assertFalse(serializer.is_valid())
261
- self.assertIn("email", serializer.errors)
262
-
263
- def test_missing_email(self):
264
- """Test missing email in OTP request."""
265
- data = {"source_url": "https://reforms.ai"}
266
- serializer = OTPRequestSerializer(data=data)
267
- self.assertFalse(serializer.is_valid())
268
- self.assertIn("email", serializer.errors)
269
-
270
- def test_invalid_source_url(self):
271
- """Test invalid source_url in OTP request."""
272
- data = {"email": "test@example.com", "source_url": "not-a-url"}
273
- serializer = OTPRequestSerializer(data=data)
274
- self.assertFalse(serializer.is_valid())
275
- self.assertIn("source_url", serializer.errors)
276
-
277
-
278
- class OTPVerifySerializerTest(TestCase):
279
- def test_valid_otp_verify(self):
280
- """Test valid OTP verification with source_url."""
281
- data = {
282
- "email": "test@example.com",
283
- "otp": "123456",
284
- "source_url": "https://reforms.ai",
285
- }
286
- serializer = OTPVerifySerializer(data=data)
287
- self.assertTrue(serializer.is_valid())
288
- self.assertEqual(serializer.validated_data["email"], "test@example.com")
289
- self.assertEqual(serializer.validated_data["otp"], "123456")
290
- self.assertEqual(
291
- serializer.validated_data["source_url"], "https://reforms.ai"
292
- )
293
-
294
- def test_valid_otp_verify_without_source_url(self):
295
- """Test valid OTP verification without source_url."""
296
- data = {"email": "test@example.com", "otp": "123456"}
297
- serializer = OTPVerifySerializer(data=data)
298
- self.assertTrue(serializer.is_valid())
299
- self.assertEqual(serializer.validated_data["email"], "test@example.com")
300
- self.assertEqual(serializer.validated_data["otp"], "123456")
301
- self.assertNotIn("source_url", serializer.validated_data)
302
-
303
- def test_invalid_otp_format(self):
304
- """Test invalid OTP format."""
305
- data = {
306
- "email": "test@example.com",
307
- "otp": "12345", # Too short
308
- "source_url": "https://reforms.ai",
309
- }
310
- serializer = OTPVerifySerializer(data=data)
311
- self.assertFalse(serializer.is_valid())
312
- self.assertIn("otp", serializer.errors)
313
-
314
- def test_invalid_otp_characters(self):
315
- """Test invalid OTP characters."""
316
- data = {
317
- "email": "test@example.com",
318
- "otp": "12345a", # Contains letter
319
- "source_url": "https://reforms.ai",
320
- }
321
- serializer = OTPVerifySerializer(data=data)
322
- self.assertFalse(serializer.is_valid())
323
- self.assertIn("otp", serializer.errors)
324
-
325
- def test_missing_required_fields(self):
326
- """Test missing required fields."""
327
- data = {"source_url": "https://reforms.ai"}
328
- serializer = OTPVerifySerializer(data=data)
329
- self.assertFalse(serializer.is_valid())
330
- self.assertIn("email", serializer.errors)
331
- self.assertIn("otp", serializer.errors)