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.
- django_cfg/__init__.py +1 -1
- django_cfg/management/commands/rundramatiq.py +174 -202
- django_cfg/modules/django_tasks.py +54 -428
- django_cfg/modules/dramatiq_setup.py +16 -0
- {django_cfg-1.1.61.dist-info → django_cfg-1.1.62.dist-info}/METADATA +1 -1
- {django_cfg-1.1.61.dist-info → django_cfg-1.1.62.dist-info}/RECORD +9 -27
- django_cfg/apps/accounts/tests/__init__.py +0 -1
- django_cfg/apps/accounts/tests/test_models.py +0 -412
- django_cfg/apps/accounts/tests/test_otp_views.py +0 -143
- django_cfg/apps/accounts/tests/test_serializers.py +0 -331
- django_cfg/apps/accounts/tests/test_services.py +0 -401
- django_cfg/apps/accounts/tests/test_signals.py +0 -110
- django_cfg/apps/accounts/tests/test_views.py +0 -255
- django_cfg/apps/newsletter/tests/__init__.py +0 -1
- django_cfg/apps/newsletter/tests/run_tests.py +0 -47
- django_cfg/apps/newsletter/tests/test_email_integration.py +0 -256
- django_cfg/apps/newsletter/tests/test_email_tracking.py +0 -332
- django_cfg/apps/newsletter/tests/test_newsletter_manager.py +0 -83
- django_cfg/apps/newsletter/tests/test_newsletter_models.py +0 -157
- django_cfg/apps/support/tests/__init__.py +0 -0
- django_cfg/apps/support/tests/test_models.py +0 -106
- django_cfg/apps/tasks/@docs/CONFIGURATION.md +0 -663
- django_cfg/apps/tasks/@docs/README.md +0 -195
- django_cfg/apps/tasks/@docs/TASKS_QUEUES.md +0 -423
- django_cfg/apps/tasks/@docs/TROUBLESHOOTING.md +0 -506
- {django_cfg-1.1.61.dist-info → django_cfg-1.1.62.dist-info}/WHEEL +0 -0
- {django_cfg-1.1.61.dist-info → django_cfg-1.1.62.dist-info}/entry_points.txt +0 -0
- {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)
|