django-camomilla-cms 6.0.0b15__py2.py3-none-any.whl → 6.0.0b17__py2.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.
- camomilla/__init__.py +1 -1
- camomilla/contrib/modeltranslation/hvad_migration.py +9 -9
- camomilla/dynamic_pages_urls.py +6 -2
- camomilla/managers/pages.py +93 -8
- camomilla/model_api.py +14 -7
- camomilla/models/media.py +1 -1
- camomilla/models/menu.py +10 -4
- camomilla/models/page.py +189 -127
- camomilla/openapi/schema.py +17 -8
- camomilla/redirects.py +10 -0
- camomilla/serializers/base/__init__.py +6 -4
- camomilla/serializers/fields/__init__.py +5 -17
- camomilla/serializers/fields/related.py +10 -4
- camomilla/serializers/mixins/__init__.py +23 -195
- camomilla/serializers/mixins/fields.py +20 -0
- camomilla/serializers/mixins/filter_fields.py +57 -0
- camomilla/serializers/mixins/json.py +34 -0
- camomilla/serializers/mixins/language.py +32 -0
- camomilla/serializers/mixins/nesting.py +35 -0
- camomilla/serializers/mixins/optimize.py +91 -0
- camomilla/serializers/mixins/ordering.py +34 -0
- camomilla/serializers/mixins/page.py +58 -0
- camomilla/{contrib/rest_framework/serializer.py → serializers/mixins/translation.py} +16 -56
- camomilla/serializers/utils.py +5 -3
- camomilla/serializers/validators.py +6 -2
- camomilla/settings.py +10 -2
- camomilla/storages/default.py +12 -0
- camomilla/storages/optimize.py +2 -2
- camomilla/storages/overwrite.py +2 -2
- camomilla/templates/defaults/parts/menu.html +1 -1
- camomilla/templatetags/menus.py +3 -0
- camomilla/theme/__init__.py +1 -1
- camomilla/theme/{admin.py → admin/__init__.py} +22 -20
- camomilla/theme/admin/pages.py +46 -0
- camomilla/theme/admin/translations.py +13 -0
- camomilla/theme/apps.py +1 -5
- camomilla/translation.py +7 -1
- camomilla/urls.py +2 -5
- camomilla/utils/query_parser.py +167 -0
- camomilla/utils/translation.py +47 -5
- camomilla/views/base/__init__.py +35 -5
- camomilla/views/medias.py +1 -1
- camomilla/views/menus.py +0 -2
- camomilla/views/mixins/__init__.py +17 -69
- camomilla/views/mixins/bulk_actions.py +22 -0
- camomilla/views/mixins/language.py +33 -0
- camomilla/views/mixins/optimize.py +18 -0
- camomilla/views/mixins/pagination.py +12 -18
- camomilla/views/mixins/permissions.py +6 -0
- camomilla/views/pages.py +12 -2
- {django_camomilla_cms-6.0.0b15.dist-info → django_camomilla_cms-6.0.0b17.dist-info}/METADATA +23 -16
- django_camomilla_cms-6.0.0b17.dist-info/RECORD +132 -0
- {django_camomilla_cms-6.0.0b15.dist-info → django_camomilla_cms-6.0.0b17.dist-info}/WHEEL +1 -1
- tests/fixtures/__init__.py +17 -0
- tests/test_api.py +2 -11
- tests/test_camomilla_filters.py +7 -13
- tests/test_media.py +113 -0
- tests/test_menu.py +97 -0
- tests/test_model_api.py +68 -0
- tests/test_model_api_permissions.py +39 -0
- tests/test_model_api_register.py +393 -0
- tests/test_pages.py +343 -0
- tests/test_query_parser.py +58 -0
- tests/test_templates_context.py +111 -0
- tests/test_utils.py +64 -64
- tests/utils/api.py +28 -0
- tests/utils/media.py +9 -0
- camomilla/serializers/fields/json.py +0 -49
- django_camomilla_cms-6.0.0b15.dist-info/RECORD +0 -105
- {django_camomilla_cms-6.0.0b15.dist-info → django_camomilla_cms-6.0.0b17.dist-info/licenses}/LICENSE +0 -0
- {django_camomilla_cms-6.0.0b15.dist-info → django_camomilla_cms-6.0.0b17.dist-info}/top_level.txt +0 -0
- {camomilla/contrib/rest_framework → tests/utils}/__init__.py +0 -0
@@ -0,0 +1,393 @@
|
|
1
|
+
import pytest
|
2
|
+
from django.test import TestCase
|
3
|
+
from rest_framework.test import APIClient
|
4
|
+
from .utils.api import login_superuser
|
5
|
+
from example.website.models import TestModel
|
6
|
+
|
7
|
+
|
8
|
+
class ModelAPiRegisterTestCase(TestCase):
|
9
|
+
def setUp(self):
|
10
|
+
self.client = APIClient()
|
11
|
+
token = login_superuser()
|
12
|
+
self.client.credentials(HTTP_AUTHORIZATION='Token ' + token)
|
13
|
+
|
14
|
+
|
15
|
+
@pytest.mark.django_db
|
16
|
+
def test_model_api_register_access(self):
|
17
|
+
client = APIClient()
|
18
|
+
response = client.post("/api/models/test-model/")
|
19
|
+
assert response.status_code == 401
|
20
|
+
|
21
|
+
|
22
|
+
@pytest.mark.django_db
|
23
|
+
def test_model_api_register_crud(self):
|
24
|
+
# Create test model 1
|
25
|
+
response = self.client.post(
|
26
|
+
"/api/models/test-model/",
|
27
|
+
{
|
28
|
+
"title": "title_test_model_1"
|
29
|
+
},
|
30
|
+
format='json'
|
31
|
+
)
|
32
|
+
assert response.status_code == 201
|
33
|
+
assert len(TestModel.objects.all()) == 1
|
34
|
+
test_model = TestModel.objects.first()
|
35
|
+
assert test_model.id == 1
|
36
|
+
assert test_model.title == "title_test_model_1"
|
37
|
+
|
38
|
+
# Create test model 2
|
39
|
+
response = self.client.post(
|
40
|
+
"/api/models/test-model/",
|
41
|
+
{
|
42
|
+
"title": "title_test_model_2"
|
43
|
+
},
|
44
|
+
format='json'
|
45
|
+
)
|
46
|
+
assert response.status_code == 201
|
47
|
+
assert len(TestModel.objects.all()) == 2
|
48
|
+
test_model = TestModel.objects.last()
|
49
|
+
assert test_model.id == 2
|
50
|
+
assert test_model.title == "title_test_model_2"
|
51
|
+
|
52
|
+
# Update test model 2
|
53
|
+
response = self.client.patch(
|
54
|
+
"/api/models/test-model/2/",
|
55
|
+
{
|
56
|
+
"title": "title_test_model_2_updated",
|
57
|
+
},
|
58
|
+
format='json'
|
59
|
+
)
|
60
|
+
assert response.status_code == 200
|
61
|
+
assert len(TestModel.objects.all()) == 2
|
62
|
+
test_model = TestModel.objects.last()
|
63
|
+
assert test_model.id == 2
|
64
|
+
assert test_model.title == "title_test_model_2_updated"
|
65
|
+
|
66
|
+
# Read test model 2
|
67
|
+
response = self.client.get("/api/models/test-model/2/")
|
68
|
+
assert response.status_code == 200
|
69
|
+
assert response.json()['id'] == 2
|
70
|
+
assert response.json()['title'] == "title_test_model_2_updated"
|
71
|
+
|
72
|
+
# Read test models
|
73
|
+
response = self.client.get("/api/models/test-model/")
|
74
|
+
assert response.status_code == 200
|
75
|
+
assert response.json()[0]['id'] == 2
|
76
|
+
assert response.json()[0]['title'] == "title_test_model_2_updated"
|
77
|
+
assert response.json()[1]['id'] == 1
|
78
|
+
assert response.json()[1]['title'] == "title_test_model_1"
|
79
|
+
|
80
|
+
# Delete page
|
81
|
+
response = self.client.delete("/api/models/test-model/2/")
|
82
|
+
assert response.status_code == 204
|
83
|
+
assert len(TestModel.objects.all()) == 1
|
84
|
+
test_model = TestModel.objects.last()
|
85
|
+
assert test_model.id == 1
|
86
|
+
assert test_model.title == "title_test_model_1"
|
87
|
+
|
88
|
+
|
89
|
+
@pytest.mark.django_db
|
90
|
+
def test_model_api_register_listing(self):
|
91
|
+
# Create test model 1
|
92
|
+
response = self.client.post(
|
93
|
+
"/api/models/test-model/",
|
94
|
+
{
|
95
|
+
"title": "title_test_model_1"
|
96
|
+
},
|
97
|
+
format='json'
|
98
|
+
)
|
99
|
+
assert response.status_code == 201
|
100
|
+
|
101
|
+
# Create test model 2
|
102
|
+
response = self.client.post(
|
103
|
+
"/api/models/test-model/",
|
104
|
+
{
|
105
|
+
"title": "title_test_model_2"
|
106
|
+
},
|
107
|
+
format='json'
|
108
|
+
)
|
109
|
+
assert response.status_code == 201
|
110
|
+
|
111
|
+
# Create test model 3
|
112
|
+
response = self.client.post(
|
113
|
+
"/api/models/test-model/",
|
114
|
+
{
|
115
|
+
"title": "title_test_model_3"
|
116
|
+
},
|
117
|
+
format='json'
|
118
|
+
)
|
119
|
+
assert response.status_code == 201
|
120
|
+
|
121
|
+
# Simple Response
|
122
|
+
response = self.client.get("/api/models/test-model/")
|
123
|
+
assert response.status_code == 200
|
124
|
+
assert len(response.json()) == 3
|
125
|
+
assert response.json()[0]['id'] == 3
|
126
|
+
assert response.json()[1]['id'] == 2
|
127
|
+
assert response.json()[2]['id'] == 1
|
128
|
+
|
129
|
+
# Pagination
|
130
|
+
response = self.client.get("/api/models/test-model/?items=2")
|
131
|
+
assert response.status_code == 200
|
132
|
+
assert len(response.json()['items']) == 2
|
133
|
+
assert response.json()['items'][0]['id'] == 3
|
134
|
+
assert response.json()['items'][1]['id'] == 2
|
135
|
+
assert response.json()['paginator']['count'] == 3
|
136
|
+
assert response.json()['paginator']['page'] == 1
|
137
|
+
assert response.json()['paginator']['has_next'] == True
|
138
|
+
assert response.json()['paginator']['has_previous'] == False
|
139
|
+
assert response.json()['paginator']['pages'] == 2
|
140
|
+
assert response.json()['paginator']['page_size'] == 2
|
141
|
+
|
142
|
+
response = self.client.get("/api/models/test-model/?items=2&page=2")
|
143
|
+
assert response.status_code == 200
|
144
|
+
assert len(response.json()['items']) == 1
|
145
|
+
assert response.json()['items'][0]['id'] == 1
|
146
|
+
assert response.json()['paginator']['count'] == 3
|
147
|
+
assert response.json()['paginator']['page'] == 2
|
148
|
+
assert response.json()['paginator']['has_next'] == False
|
149
|
+
assert response.json()['paginator']['has_previous'] == True
|
150
|
+
assert response.json()['paginator']['pages'] == 2
|
151
|
+
assert response.json()['paginator']['page_size'] == 2
|
152
|
+
|
153
|
+
# Filtering
|
154
|
+
response = self.client.get("/api/models/test-model/?fltr=title=title_test_model_2")
|
155
|
+
assert response.status_code == 200
|
156
|
+
assert len(response.json()) == 1
|
157
|
+
assert response.json()[0]['id'] == 2
|
158
|
+
assert response.json()[0]['title'] == "title_test_model_2"
|
159
|
+
|
160
|
+
response = self.client.get("/api/models/test-model/?fltr=title=not_real_title")
|
161
|
+
assert response.status_code == 200
|
162
|
+
assert len(response.json()) == 0
|
163
|
+
|
164
|
+
response = self.client.get("/api/models/test-model/?fltr=title=title_test_model_2&fltr=id=2")
|
165
|
+
assert response.status_code == 200
|
166
|
+
assert len(response.json()) == 1
|
167
|
+
assert response.json()[0]['id'] == 2
|
168
|
+
assert response.json()[0]['title'] == "title_test_model_2"
|
169
|
+
|
170
|
+
response = self.client.get("/api/models/test-model/?fltr=title=title_test_model_2&fltr=id=3")
|
171
|
+
assert response.status_code == 200
|
172
|
+
assert len(response.json()) == 0
|
173
|
+
|
174
|
+
response = self.client.get("/api/models/test-model/?fltr=title__in=[title_test_model_2,title_test_model_3]")
|
175
|
+
assert response.status_code == 200
|
176
|
+
assert len(response.json()) == 2
|
177
|
+
assert response.json()[0]['id'] == 3
|
178
|
+
assert response.json()[0]['title'] == "title_test_model_3"
|
179
|
+
assert response.json()[1]['id'] == 2
|
180
|
+
assert response.json()[1]['title'] == "title_test_model_2"
|
181
|
+
|
182
|
+
response = self.client.get("/api/models/test-model/?fltr=title__in=[title_test_model_4,title_test_model_3]")
|
183
|
+
assert response.status_code == 200
|
184
|
+
assert len(response.json()) == 1
|
185
|
+
assert response.json()[0]['id'] == 3
|
186
|
+
assert response.json()[0]['title'] == "title_test_model_3"
|
187
|
+
|
188
|
+
|
189
|
+
@pytest.mark.django_db
|
190
|
+
def test_model_api_register_listing_filtered_model(self):
|
191
|
+
# Create filter argument register model 1
|
192
|
+
response = self.client.post(
|
193
|
+
"/api/models/filtered-register-model/",
|
194
|
+
{
|
195
|
+
"field_filtered": "test 1"
|
196
|
+
},
|
197
|
+
format='json'
|
198
|
+
)
|
199
|
+
assert response.status_code == 201
|
200
|
+
|
201
|
+
# Create filter argument register model 2
|
202
|
+
response = self.client.post(
|
203
|
+
"/api/models/filtered-register-model/",
|
204
|
+
{
|
205
|
+
"field_filtered": "pippo 2"
|
206
|
+
},
|
207
|
+
format='json'
|
208
|
+
)
|
209
|
+
assert response.status_code == 201
|
210
|
+
|
211
|
+
# Create filter argument register model 3
|
212
|
+
response = self.client.post(
|
213
|
+
"/api/models/filtered-register-model/",
|
214
|
+
{
|
215
|
+
"field_filtered": "3 test"
|
216
|
+
},
|
217
|
+
format='json'
|
218
|
+
)
|
219
|
+
assert response.status_code == 201
|
220
|
+
|
221
|
+
response = self.client.get("/api/models/filtered-register-model/")
|
222
|
+
assert response.status_code == 200
|
223
|
+
assert len(response.json()) == 2
|
224
|
+
assert response.json()[0]['id'] == 3
|
225
|
+
assert response.json()[0]['field_filtered'] == "3 test"
|
226
|
+
assert response.json()[1]['id'] == 1
|
227
|
+
assert response.json()[1]['field_filtered'] == "test 1"
|
228
|
+
|
229
|
+
|
230
|
+
@pytest.mark.django_db
|
231
|
+
def test_model_api_register_base_view_search(self):
|
232
|
+
# Verify search_fields = ["description"]
|
233
|
+
# Create custom arguments register model 1
|
234
|
+
response = self.client.post(
|
235
|
+
"/api/models/custom-base-arguments-register-model/",
|
236
|
+
{
|
237
|
+
"description": "description_1"
|
238
|
+
},
|
239
|
+
format='json'
|
240
|
+
)
|
241
|
+
assert response.status_code == 201
|
242
|
+
|
243
|
+
# Create custom arguments register model 2
|
244
|
+
response = self.client.post(
|
245
|
+
"/api/models/custom-base-arguments-register-model/",
|
246
|
+
{
|
247
|
+
"description": "description_2"
|
248
|
+
},
|
249
|
+
format='json'
|
250
|
+
)
|
251
|
+
assert response.status_code == 201
|
252
|
+
|
253
|
+
# Create custom arguments register model 3
|
254
|
+
response = self.client.post(
|
255
|
+
"/api/models/custom-base-arguments-register-model/",
|
256
|
+
{
|
257
|
+
"description": "description_3"
|
258
|
+
},
|
259
|
+
format='json'
|
260
|
+
)
|
261
|
+
assert response.status_code == 201
|
262
|
+
|
263
|
+
response = self.client.get("/api/models/custom-base-arguments-register-model/?search=not_real_description")
|
264
|
+
assert response.status_code == 200
|
265
|
+
assert len(response.json()) == 0
|
266
|
+
|
267
|
+
response = self.client.get("/api/models/custom-base-arguments-register-model/?search=description_1")
|
268
|
+
assert response.status_code == 200
|
269
|
+
assert len(response.json()) == 1
|
270
|
+
assert response.json()[0]['id'] == 1
|
271
|
+
assert response.json()[0]['description'] == "description_1"
|
272
|
+
|
273
|
+
|
274
|
+
@pytest.mark.django_db
|
275
|
+
def test_model_api_register_base_serializer_search(self):
|
276
|
+
# Verify description = BaseModelSerializer.CharField(min_length=3)
|
277
|
+
# Create custom arguments register model 1
|
278
|
+
response = self.client.post(
|
279
|
+
"/api/models/custom-base-arguments-register-model/",
|
280
|
+
{
|
281
|
+
"description": "12"
|
282
|
+
},
|
283
|
+
format='json'
|
284
|
+
)
|
285
|
+
assert response.status_code == 400
|
286
|
+
|
287
|
+
# Create custom arguments register model 2
|
288
|
+
response = self.client.post(
|
289
|
+
"/api/models/custom-base-arguments-register-model/",
|
290
|
+
{
|
291
|
+
"description": "1234"
|
292
|
+
},
|
293
|
+
format='json'
|
294
|
+
)
|
295
|
+
assert response.status_code == 201
|
296
|
+
|
297
|
+
@pytest.mark.django_db
|
298
|
+
def test_model_api_register_view_search(self):
|
299
|
+
# Verify {"search_fields": ["name"]}
|
300
|
+
# Create custom arguments register model 1
|
301
|
+
response = self.client.post(
|
302
|
+
"/api/models/custom-arguments-register-model/",
|
303
|
+
{
|
304
|
+
"name": "name_1"
|
305
|
+
},
|
306
|
+
format='json'
|
307
|
+
)
|
308
|
+
assert response.status_code == 201
|
309
|
+
|
310
|
+
# Create custom arguments register model 2
|
311
|
+
response = self.client.post(
|
312
|
+
"/api/models/custom-arguments-register-model/",
|
313
|
+
{
|
314
|
+
"name": "name_2"
|
315
|
+
},
|
316
|
+
format='json'
|
317
|
+
)
|
318
|
+
assert response.status_code == 201
|
319
|
+
|
320
|
+
# Create custom arguments register model 3
|
321
|
+
response = self.client.post(
|
322
|
+
"/api/models/custom-arguments-register-model/",
|
323
|
+
{
|
324
|
+
"name": "name_3"
|
325
|
+
},
|
326
|
+
format='json'
|
327
|
+
)
|
328
|
+
assert response.status_code == 201
|
329
|
+
|
330
|
+
response = self.client.get("/api/models/custom-arguments-register-model/?search=not_real_name")
|
331
|
+
assert response.status_code == 200
|
332
|
+
assert len(response.json()) == 0
|
333
|
+
|
334
|
+
response = self.client.get("/api/models/custom-arguments-register-model/?search=name_1")
|
335
|
+
assert response.status_code == 200
|
336
|
+
assert len(response.json()) == 1
|
337
|
+
assert response.json()[0]['name'] == "name_1"
|
338
|
+
|
339
|
+
@pytest.mark.django_db
|
340
|
+
def test_model_api_register_serializer_search(self):
|
341
|
+
# Verify {"fields": ["name"]}
|
342
|
+
# Create custom arguments register model
|
343
|
+
response = self.client.post(
|
344
|
+
"/api/models/custom-arguments-register-model/",
|
345
|
+
{
|
346
|
+
"name": "1234"
|
347
|
+
},
|
348
|
+
format='json'
|
349
|
+
)
|
350
|
+
assert response.status_code == 201
|
351
|
+
assert 'id' not in response.json()
|
352
|
+
assert response.json()['name'] == "1234"
|
353
|
+
|
354
|
+
@pytest.mark.django_db
|
355
|
+
def test_model_api_register_listing_filtered_model(self):
|
356
|
+
# Verify filters={"field_filtered__icontains": "test"}
|
357
|
+
# Create filter argument register model 1
|
358
|
+
response = self.client.post(
|
359
|
+
"/api/models/filtered-register-model/",
|
360
|
+
{
|
361
|
+
"field_filtered": "test 1"
|
362
|
+
},
|
363
|
+
format='json'
|
364
|
+
)
|
365
|
+
assert response.status_code == 201
|
366
|
+
|
367
|
+
# Create filter argument register model 2
|
368
|
+
response = self.client.post(
|
369
|
+
"/api/models/filtered-register-model/",
|
370
|
+
{
|
371
|
+
"field_filtered": "pippo 2"
|
372
|
+
},
|
373
|
+
format='json'
|
374
|
+
)
|
375
|
+
assert response.status_code == 201
|
376
|
+
|
377
|
+
# Create filter argument register model 3
|
378
|
+
response = self.client.post(
|
379
|
+
"/api/models/filtered-register-model/",
|
380
|
+
{
|
381
|
+
"field_filtered": "3 test"
|
382
|
+
},
|
383
|
+
format='json'
|
384
|
+
)
|
385
|
+
assert response.status_code == 201
|
386
|
+
|
387
|
+
response = self.client.get("/api/models/filtered-register-model/")
|
388
|
+
assert response.status_code == 200
|
389
|
+
assert len(response.json()) == 2
|
390
|
+
assert response.json()[0]['id'] == 3
|
391
|
+
assert response.json()[0]['field_filtered'] == "3 test"
|
392
|
+
assert response.json()[1]['id'] == 1
|
393
|
+
assert response.json()[1]['field_filtered'] == "test 1"
|