django-camomilla-cms 6.0.0b16__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.
Files changed (62) hide show
  1. camomilla/__init__.py +1 -1
  2. camomilla/contrib/modeltranslation/hvad_migration.py +9 -9
  3. camomilla/dynamic_pages_urls.py +6 -2
  4. camomilla/managers/pages.py +87 -2
  5. camomilla/model_api.py +6 -4
  6. camomilla/models/menu.py +9 -4
  7. camomilla/models/page.py +178 -117
  8. camomilla/openapi/schema.py +15 -10
  9. camomilla/redirects.py +10 -0
  10. camomilla/serializers/base/__init__.py +4 -4
  11. camomilla/serializers/fields/__init__.py +5 -17
  12. camomilla/serializers/fields/related.py +5 -3
  13. camomilla/serializers/mixins/__init__.py +23 -240
  14. camomilla/serializers/mixins/fields.py +20 -0
  15. camomilla/serializers/mixins/filter_fields.py +9 -8
  16. camomilla/serializers/mixins/json.py +34 -0
  17. camomilla/serializers/mixins/language.py +32 -0
  18. camomilla/serializers/mixins/nesting.py +35 -0
  19. camomilla/serializers/mixins/optimize.py +91 -0
  20. camomilla/serializers/mixins/ordering.py +34 -0
  21. camomilla/serializers/mixins/page.py +58 -0
  22. camomilla/{contrib/rest_framework/serializer.py → serializers/mixins/translation.py} +16 -56
  23. camomilla/serializers/utils.py +3 -3
  24. camomilla/serializers/validators.py +6 -2
  25. camomilla/settings.py +10 -2
  26. camomilla/storages/default.py +7 -1
  27. camomilla/templates/defaults/parts/menu.html +1 -1
  28. camomilla/templatetags/menus.py +3 -0
  29. camomilla/theme/__init__.py +1 -1
  30. camomilla/theme/{admin.py → admin/__init__.py} +22 -20
  31. camomilla/theme/admin/pages.py +46 -0
  32. camomilla/theme/admin/translations.py +13 -0
  33. camomilla/theme/apps.py +1 -5
  34. camomilla/translation.py +7 -1
  35. camomilla/urls.py +2 -5
  36. camomilla/utils/query_parser.py +42 -23
  37. camomilla/utils/translation.py +47 -5
  38. camomilla/views/base/__init__.py +35 -5
  39. camomilla/views/medias.py +1 -1
  40. camomilla/views/mixins/__init__.py +17 -76
  41. camomilla/views/mixins/bulk_actions.py +22 -0
  42. camomilla/views/mixins/language.py +33 -0
  43. camomilla/views/mixins/optimize.py +18 -0
  44. camomilla/views/mixins/pagination.py +11 -8
  45. camomilla/views/mixins/permissions.py +6 -0
  46. camomilla/views/pages.py +12 -2
  47. {django_camomilla_cms-6.0.0b16.dist-info → django_camomilla_cms-6.0.0b17.dist-info}/METADATA +23 -16
  48. {django_camomilla_cms-6.0.0b16.dist-info → django_camomilla_cms-6.0.0b17.dist-info}/RECORD +60 -43
  49. {django_camomilla_cms-6.0.0b16.dist-info → django_camomilla_cms-6.0.0b17.dist-info}/WHEEL +1 -1
  50. tests/test_camomilla_filters.py +1 -1
  51. tests/test_media.py +98 -65
  52. tests/test_menu.py +97 -0
  53. tests/test_model_api_register.py +393 -0
  54. tests/test_pages.py +343 -0
  55. tests/test_query_parser.py +1 -2
  56. tests/test_templates_context.py +111 -0
  57. tests/utils/api.py +0 -1
  58. tests/utils/media.py +9 -0
  59. camomilla/contrib/rest_framework/__init__.py +0 -0
  60. camomilla/serializers/fields/json.py +0 -48
  61. {django_camomilla_cms-6.0.0b16.dist-info → django_camomilla_cms-6.0.0b17.dist-info/licenses}/LICENSE +0 -0
  62. {django_camomilla_cms-6.0.0b16.dist-info → django_camomilla_cms-6.0.0b17.dist-info}/top_level.txt +0 -0
tests/test_media.py CHANGED
@@ -1,80 +1,113 @@
1
1
  import pytest
2
2
  import json
3
- import os
3
+ from django.test import TestCase
4
4
  from camomilla.models import Media
5
- from .fixtures import load_asset
6
5
  from .utils.api import login_superuser
6
+ from .utils.media import load_asset_and_remove_media
7
7
  from rest_framework.test import APIClient
8
- from django.conf import settings
9
8
 
10
9
  client = APIClient()
11
10
 
11
+ class MediaTestCase(TestCase):
12
+ def setUp(self):
13
+ self.client = APIClient()
14
+ token = login_superuser()
15
+ self.client.credentials(HTTP_AUTHORIZATION='Token ' + token)
12
16
 
13
- def load_asset_and_remove_media(filename):
14
- asset = load_asset(filename)
15
- if os.path.exists(f"{settings.MEDIA_ROOT}/{filename}"):
16
- os.remove(f"{settings.MEDIA_ROOT}/{filename}")
17
- return asset
17
+ @pytest.mark.django_db
18
+ def test_media_api_crud(self):
19
+ # Create media 1
20
+ asset = load_asset_and_remove_media("10595073.png")
21
+ response = self.client.post(
22
+ "/api/camomilla/media/",
23
+ {
24
+ "file": asset,
25
+ "data": json.dumps({"translations": {"en": {"alt_text": "Test 1", "title": "Test 1", "description": "Test 1"}}}),
26
+ },
27
+ format="multipart",
28
+ )
29
+ assert response.status_code == 201
30
+ assert Media.objects.count() == 1
31
+ media = Media.objects.first()
32
+ assert media.alt_text == "Test 1"
33
+ assert media.title == "Test 1"
34
+ assert media.description == "Test 1"
35
+ assert media.file.name == "10595073.png"
18
36
 
37
+ # Create media 2
38
+ asset = load_asset_and_remove_media("37059501.png")
39
+ response = self.client.post(
40
+ "/api/camomilla/media/",
41
+ {
42
+ "file": asset,
43
+ "data": json.dumps({"translations": {"en": {"alt_text": "Test 2", "title": "Test 2", "description": "Test 2"}}}),
44
+ },
45
+ format="multipart",
46
+ )
47
+ assert response.status_code == 201
48
+ assert Media.objects.count() == 2
49
+ media = Media.objects.first() # Ordering in model is descending -pk
50
+ assert media.alt_text == "Test 2"
51
+ assert media.title == "Test 2"
52
+ assert media.description == "Test 2"
53
+ assert media.file.name == "37059501.png"
19
54
 
20
- @pytest.mark.django_db
21
- def test_media_api_creation():
22
- token = login_superuser()
23
- client.credentials(HTTP_AUTHORIZATION='Token ' + token)
24
- asset = load_asset_and_remove_media("10595073.png")
25
- response = client.post(
26
- "/api/camomilla/media/",
27
- {
28
- "file": asset,
29
- "data": json.dumps({"translations": {"en": {"alt_text": "Test", "title": "Test", "description": "Test"}}}),
30
- },
31
- format="multipart",
32
- )
33
- assert response.status_code == 201
34
- assert Media.objects.count() == 1
35
- media = Media.objects.first()
36
- assert media.alt_text == "Test"
37
- assert media.title == "Test"
38
- assert media.description == "Test"
39
- assert media.file.name == "10595073.png"
55
+ # Read media
56
+ response = self.client.get("/api/camomilla/media/2/")
57
+ assert response.status_code == 200
58
+ assert response.json()['id'] == 2
59
+ assert response.json()['title'] == "Test 2"
60
+ assert response.json()['file'] == "http://testserver/media/37059501.png"
40
61
 
62
+ # Read medias
63
+ response = self.client.get("/api/camomilla/media/")
64
+ assert response.status_code == 200
65
+ assert response.json()[0]['id'] == 2 # Ordering in model is descending -pk
66
+ assert response.json()[0]['title'] == "Test 2"
67
+ assert response.json()[1]['id'] == 1
68
+ assert response.json()[1]['title'] == "Test 1"
41
69
 
42
- @pytest.mark.django_db
43
- def test_media_compression():
44
- token = login_superuser()
45
- client.credentials(HTTP_AUTHORIZATION='Token ' + token)
46
- asset = load_asset_and_remove_media("Sample-jpg-image-10mb.jpg")
47
- asset_size = asset.size
48
- response = client.post(
49
- "/api/camomilla/media/",
50
- {
51
- "file": asset,
52
- "data": json.dumps({"translations": {"en": {"alt_text": "Test", "title": "Test", "description": "Test"}}}),
53
- },
54
- format="multipart",
55
- )
56
- assert response.status_code == 201
57
- assert Media.objects.count() == 1
58
- media = Media.objects.first()
59
- assert media.file.size < asset_size
60
- assert media.file.size < 1000000 # 1MB
70
+ # Delete media
71
+ response = self.client.delete("/api/camomilla/media/2/")
72
+ assert response.status_code == 204
73
+ assert len(Media.objects.all()) == 1
74
+ media = Media.objects.last()
75
+ assert media.id == 1
76
+ assert media.title == "Test 1"
61
77
 
62
78
 
63
- @pytest.mark.django_db
64
- def test_inflating_prevent():
65
- token = login_superuser()
66
- client.credentials(HTTP_AUTHORIZATION='Token ' + token)
67
- asset = load_asset_and_remove_media("optimized.jpg")
68
- asset_size = asset.size
69
- response = client.post(
70
- "/api/camomilla/media/",
71
- {
72
- "file": asset,
73
- "data": json.dumps({"translations": {"en": {"alt_text": "Test", "title": "Test", "description": "Test"}}}),
74
- },
75
- format="multipart",
76
- )
77
- assert response.status_code == 201
78
- assert Media.objects.count() == 1
79
- media = Media.objects.first()
80
- assert media.file.size < asset_size
79
+ @pytest.mark.django_db
80
+ def test_media_compression(self):
81
+ asset = load_asset_and_remove_media("Sample-jpg-image-10mb.jpg")
82
+ asset_size = asset.size
83
+ response = self.client.post(
84
+ "/api/camomilla/media/",
85
+ {
86
+ "file": asset,
87
+ "data": json.dumps({"translations": {"en": {"alt_text": "Test", "title": "Test", "description": "Test"}}}),
88
+ },
89
+ format="multipart",
90
+ )
91
+ assert response.status_code == 201
92
+ assert Media.objects.count() == 1
93
+ media = Media.objects.first()
94
+ assert media.file.size < asset_size
95
+ assert media.file.size < 1000000 # 1MB
96
+
97
+
98
+ @pytest.mark.django_db
99
+ def test_inflating_prevent(self):
100
+ asset = load_asset_and_remove_media("optimized.jpg")
101
+ asset_size = asset.size
102
+ response = self.client.post(
103
+ "/api/camomilla/media/",
104
+ {
105
+ "file": asset,
106
+ "data": json.dumps({"translations": {"en": {"alt_text": "Test", "title": "Test", "description": "Test"}}}),
107
+ },
108
+ format="multipart",
109
+ )
110
+ assert response.status_code == 201
111
+ assert Media.objects.count() == 1
112
+ media = Media.objects.first()
113
+ assert media.file.size < asset_size
tests/test_menu.py ADDED
@@ -0,0 +1,97 @@
1
+ import pytest
2
+ import html
3
+ from django.test import TestCase
4
+ from rest_framework.test import APIClient
5
+ from .utils.api import login_superuser
6
+ from django.template import Template, Context
7
+ from camomilla.models import Menu
8
+
9
+
10
+ class MenuTestCase(TestCase):
11
+ def setUp(self):
12
+ self.client = APIClient()
13
+ token = login_superuser()
14
+ self.client.credentials(HTTP_AUTHORIZATION='Token ' + token)
15
+
16
+ def renderTemplate(self, template, context = None):
17
+ return Template('{% load menus %}' + template).render(Context(context))
18
+
19
+ @pytest.mark.django_db
20
+ def test_template_render_menu(self):
21
+ assert self.renderTemplate('{% render_menu "key_1" %}') == "\n\n"
22
+ assert len(Menu.objects.all()) == 1
23
+ menu = Menu.objects.first()
24
+ assert menu.id == 1
25
+ assert menu.key == "key_1"
26
+
27
+ assert self.renderTemplate('{% render_menu "key_2" %}') == "\n\n"
28
+ assert len(Menu.objects.all()) == 2
29
+ menu = Menu.objects.last()
30
+ assert menu.id == 2
31
+ assert menu.key == "key_2"
32
+
33
+ @pytest.mark.django_db
34
+ def test_template_get_menus(self):
35
+ self.renderTemplate('{% render_menu "key_3" %}')
36
+ self.renderTemplate('{% render_menu "key_4" %}')
37
+
38
+ rendered = html.unescape(self.renderTemplate('{% get_menus %}'))
39
+ assert rendered == "{'key_3': <Menu: key_3>, 'key_4': <Menu: key_4>}"
40
+
41
+ rendered = html.unescape(self.renderTemplate('{% get_menus "arg" %}'))
42
+ assert rendered == "{}"
43
+
44
+ rendered = html.unescape(self.renderTemplate('{% get_menus "key_3" %}'))
45
+ assert rendered == "{'key_3': <Menu: key_3>}"
46
+
47
+ menus = 'test "menus" in context'
48
+ rendered = html.unescape(self.renderTemplate('{% get_menus %}', {"menus": menus}))
49
+ assert rendered == menus
50
+
51
+ @pytest.mark.django_db
52
+ def test_template_get_menu_node_url(self):
53
+ self.renderTemplate('{% render_menu "key_5" %}')
54
+
55
+ menu = Menu.objects.first()
56
+ menu.nodes = [{"title": "key_5_node_title", "link":{"static": "key_5_url_static"}}]
57
+ menu.save()
58
+
59
+ rendered = html.unescape(self.renderTemplate('{% render_menu "key_5" %}'))
60
+ assert {'<a href="key_5_url_static">key_5_node_title</a>' in rendered}
61
+
62
+ @pytest.mark.django_db
63
+ def test_menu_custom_template(self):
64
+ self.renderTemplate('{% render_menu "key_6_custom" %}')
65
+
66
+ menu = Menu.objects.first()
67
+ menu.nodes = [{"title": "key_6_node_title", "link":{"static": "key_6_url_static"}}]
68
+ menu.save()
69
+
70
+ rendered = html.unescape(self.renderTemplate('{% render_menu "key_6_custom" "website/menu_custom.html" %}'))
71
+ assert {'This is custom menu: key_6_node_title' in rendered}
72
+
73
+ @pytest.mark.django_db
74
+ def test_menu_in_page_template(self):
75
+ self.renderTemplate('{% render_menu "key_7" %}')
76
+
77
+ response = self.client.post(
78
+ "/api/camomilla/pages/",
79
+ {
80
+ "translations": {
81
+ "en": {
82
+ "title": "title_page_menu_1",
83
+ "permalink": "permalink_page_menu_en_1",
84
+ "autopermalink": False
85
+ }
86
+ }
87
+ },
88
+ format='json'
89
+ )
90
+ assert response.status_code == 201
91
+
92
+ menu = Menu.objects.first()
93
+ menu.nodes = [{"title": "key_7_node_title", "link":{"page": { "id": 1, "model":"camomilla.page" }}}]
94
+ menu.save()
95
+
96
+ rendered = html.unescape(self.renderTemplate('{% render_menu "key_7" %}'))
97
+ assert {'href="permalink_page_menu_en_1"' in rendered}
@@ -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"