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.
- camomilla/__init__.py +1 -1
- camomilla/contrib/modeltranslation/hvad_migration.py +9 -9
- camomilla/dynamic_pages_urls.py +6 -2
- camomilla/managers/pages.py +87 -2
- camomilla/model_api.py +6 -4
- camomilla/models/menu.py +9 -4
- camomilla/models/page.py +178 -117
- camomilla/openapi/schema.py +15 -10
- camomilla/redirects.py +10 -0
- camomilla/serializers/base/__init__.py +4 -4
- camomilla/serializers/fields/__init__.py +5 -17
- camomilla/serializers/fields/related.py +5 -3
- camomilla/serializers/mixins/__init__.py +23 -240
- camomilla/serializers/mixins/fields.py +20 -0
- camomilla/serializers/mixins/filter_fields.py +9 -8
- 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 +3 -3
- camomilla/serializers/validators.py +6 -2
- camomilla/settings.py +10 -2
- camomilla/storages/default.py +7 -1
- 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 +42 -23
- camomilla/utils/translation.py +47 -5
- camomilla/views/base/__init__.py +35 -5
- camomilla/views/medias.py +1 -1
- camomilla/views/mixins/__init__.py +17 -76
- 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 +11 -8
- camomilla/views/mixins/permissions.py +6 -0
- camomilla/views/pages.py +12 -2
- {django_camomilla_cms-6.0.0b16.dist-info → django_camomilla_cms-6.0.0b17.dist-info}/METADATA +23 -16
- {django_camomilla_cms-6.0.0b16.dist-info → django_camomilla_cms-6.0.0b17.dist-info}/RECORD +60 -43
- {django_camomilla_cms-6.0.0b16.dist-info → django_camomilla_cms-6.0.0b17.dist-info}/WHEEL +1 -1
- tests/test_camomilla_filters.py +1 -1
- tests/test_media.py +98 -65
- tests/test_menu.py +97 -0
- tests/test_model_api_register.py +393 -0
- tests/test_pages.py +343 -0
- tests/test_query_parser.py +1 -2
- tests/test_templates_context.py +111 -0
- tests/utils/api.py +0 -1
- tests/utils/media.py +9 -0
- camomilla/contrib/rest_framework/__init__.py +0 -0
- camomilla/serializers/fields/json.py +0 -48
- {django_camomilla_cms-6.0.0b16.dist-info → django_camomilla_cms-6.0.0b17.dist-info/licenses}/LICENSE +0 -0
- {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
|
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
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
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
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
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
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
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
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
"
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
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"
|