django-cms-qe 3.5.0__py3-none-any.whl → 3.6.0__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 (52) hide show
  1. cms_qe/api/constants.py +1 -0
  2. cms_qe/api/permissions.py +12 -0
  3. cms_qe/api/urls.py +32 -0
  4. cms_qe/api/utils.py +14 -0
  5. cms_qe/api/views.py +20 -0
  6. cms_qe/locale/cs/LC_MESSAGES/django.po +12 -0
  7. cms_qe/migrations/0001_api_permissions.py +19 -0
  8. cms_qe/settings/base/app.py +9 -0
  9. cms_qe/templates/admin/index.html +38 -0
  10. cms_qe/urls.py +1 -0
  11. cms_qe_auth/utils.py +6 -2
  12. {django_cms_qe-3.5.0.dist-info → django_cms_qe-3.6.0.dist-info}/METADATA +29 -11
  13. {django_cms_qe-3.5.0.dist-info → django_cms_qe-3.6.0.dist-info}/RECORD +18 -45
  14. {django_cms_qe-3.5.0.dist-info → django_cms_qe-3.6.0.dist-info}/WHEEL +1 -1
  15. cms_qe/static/css/fix-admin.css +0 -14
  16. cms_qe/templates/admin/change_form.html +0 -7
  17. cms_qe/tests/test_errors.py +0 -61
  18. cms_qe/tests/test_export.py +0 -108
  19. cms_qe/tests/test_monitoring.py +0 -15
  20. cms_qe/tests/test_utils.py +0 -77
  21. cms_qe/tests/test_views_security.py +0 -18
  22. cms_qe_analytical/tests/settings.py +0 -24
  23. cms_qe_analytical/tests/templatetags/__init__.py +0 -0
  24. cms_qe_analytical/tests/templatetags/dummy.py +0 -37
  25. cms_qe_analytical/tests/test_tag_google_analytics.py +0 -178
  26. cms_qe_analytical/tests/test_tag_piwik.py +0 -152
  27. cms_qe_analytical/tests/test_utils.py +0 -112
  28. cms_qe_analytical/tests/utils.py +0 -56
  29. cms_qe_auth/tests/__init__.py +0 -0
  30. cms_qe_auth/tests/test_models.py +0 -70
  31. cms_qe_auth/tests/test_utils.py +0 -36
  32. cms_qe_auth/tests/test_view.py +0 -72
  33. cms_qe_auth/tests/utils.py +0 -22
  34. cms_qe_newsletter/tests/__init__.py +0 -0
  35. cms_qe_newsletter/tests/test_mailchimp.py +0 -38
  36. cms_qe_newsletter/tests/test_managment.py +0 -22
  37. cms_qe_newsletter/tests/test_models.py +0 -43
  38. cms_qe_newsletter/tests/test_plugin.py +0 -21
  39. cms_qe_newsletter/tests/test_sync.py +0 -71
  40. cms_qe_newsletter/tests/test_views.py +0 -13
  41. cms_qe_table/tests/__init__.py +0 -0
  42. cms_qe_table/tests/test_models.py +0 -23
  43. cms_qe_table/tests/test_plugin.py +0 -18
  44. cms_qe_table/tests/test_utils.py +0 -90
  45. cms_qe_video/tests/__init__.py +0 -0
  46. cms_qe_video/tests/test_models.py +0 -96
  47. cms_qe_video/tests/test_plugin.py +0 -24
  48. cms_qe_video/tests/test_templatetags.py +0 -20
  49. /cms_qe/{tests → api}/__init__.py +0 -0
  50. {cms_qe_analytical/tests → cms_qe/migrations}/__init__.py +0 -0
  51. {django_cms_qe-3.5.0.dist-info → django_cms_qe-3.6.0.dist-info/licenses}/LICENSE +0 -0
  52. {django_cms_qe-3.5.0.dist-info → django_cms_qe-3.6.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1 @@
1
+ CMS_QE_USER_ACCES_API_PERMISSION = "cms_qe_auth.accessapi_user"
@@ -0,0 +1,12 @@
1
+ # from django.conf import settings
2
+ from rest_framework.permissions import BasePermission
3
+
4
+ from .constants import CMS_QE_USER_ACCES_API_PERMISSION
5
+
6
+
7
+ class CmsQeApiPermission(BasePermission):
8
+ """Permission class checking user type."""
9
+
10
+ def has_permission(self, request, view):
11
+ """Check user access permission to the API."""
12
+ return request.user.has_perm(CMS_QE_USER_ACCES_API_PERMISSION)
cms_qe/api/urls.py ADDED
@@ -0,0 +1,32 @@
1
+ from django.conf import settings
2
+ from django.urls import include, path
3
+ from django.utils.module_loading import import_string
4
+ from drf_spectacular.views import SpectacularAPIView, SpectacularRedocView, SpectacularSwaggerView
5
+ from knox.auth import TokenAuthentication
6
+ from knox.views import LoginView as KnoxLoginView, LogoutView as KnoxLogoutView
7
+ from rest_framework import routers
8
+
9
+ from .permissions import CmsQeApiPermission
10
+ from .views import CmsQeBasicAuthentication
11
+
12
+ ROUTER = routers.DefaultRouter()
13
+
14
+ for url, view_path, name in getattr(settings, "API_VIEWS", []):
15
+ BaseClass = import_string(view_path)
16
+ ApiClass = type(f'Api{BaseClass.__name__}', (BaseClass,), {
17
+ "authentication_classes": BaseClass.authentication_classes + [CmsQeBasicAuthentication, TokenAuthentication],
18
+ "permission_classes": BaseClass.permission_classes + [CmsQeApiPermission],
19
+ })
20
+ ROUTER.register(url, ApiClass, basename=name)
21
+
22
+
23
+ urlpatterns = [
24
+ path("", include(ROUTER.urls)),
25
+ path("login/", KnoxLoginView.as_view(
26
+ authentication_classes=(CmsQeBasicAuthentication,), permission_classes=(CmsQeApiPermission,)),),
27
+ path("logout/", KnoxLogoutView.as_view()),
28
+ # Docs
29
+ path("schema/", SpectacularAPIView.as_view(), name="schema"),
30
+ path("schema/swagger/", SpectacularSwaggerView.as_view(url_name="schema"), name="swagger"),
31
+ path('schema/redoc/', SpectacularRedocView.as_view(url_name='schema'), name='redoc'),
32
+ ]
cms_qe/api/utils.py ADDED
@@ -0,0 +1,14 @@
1
+ """
2
+ REST_FRAMEWORK = {
3
+ 'EXCEPTION_HANDLER': 'cms_qe.api.utils.exception_handler'
4
+ }
5
+ """
6
+ from rest_framework.response import Response
7
+ from rest_framework.views import exception_handler as rest_exception_handler
8
+
9
+
10
+ def exception_handler(exc: Exception, context: dict) -> Response:
11
+ response = rest_exception_handler(exc, context)
12
+ if response is not None:
13
+ response.data["error"] = {"message": response.data.get("detail")}
14
+ return response
cms_qe/api/views.py ADDED
@@ -0,0 +1,20 @@
1
+ from django.contrib.auth import get_user_model
2
+ from django.db.models import Model
3
+ from django.http import HttpRequest
4
+ from django.utils.translation import gettext_lazy as _
5
+ from rest_framework.authentication import BasicAuthentication
6
+ from rest_framework.exceptions import AuthenticationFailed
7
+
8
+
9
+ class CmsQeBasicAuthentication(BasicAuthentication):
10
+
11
+ def authenticate_credentials(self, userid: str, password: str, request: HttpRequest = None) -> tuple[Model, None]:
12
+ """Check credentials against settings and return AnonymousUser or None."""
13
+ class_user = get_user_model()
14
+ try:
15
+ user = class_user.objects.get(username=userid, is_active=True)
16
+ except class_user.DoesNotExist as err:
17
+ raise AuthenticationFailed(_("User inactive or deleted.")) from err
18
+ if user.check_password(password):
19
+ return (user, None)
20
+ raise AuthenticationFailed(_("Invalid username/password."))
@@ -92,6 +92,9 @@ msgstr "Kontejner"
92
92
  msgid "Fluid container"
93
93
  msgstr "Plovoucí kontejner"
94
94
 
95
+ msgid "For example:"
96
+ msgstr "Například:"
97
+
95
98
  #: cms_qe/settings/base/cms.py:64
96
99
  msgid "Full container"
97
100
  msgstr "Plný kontejner"
@@ -120,3 +123,12 @@ msgstr "Obecná chyba"
120
123
  #: cms_qe/templates/cms_qe/internal_error.html:7
121
124
  msgid "Something went very wrong. Please try again later."
122
125
  msgstr ""
126
+
127
+ msgid ""
128
+ "To log into the API, the user needs to have the access permission assigned. "
129
+ "To access other records in the API, the user must have the VIEW permission "
130
+ "set for the model."
131
+ msgstr ""
132
+ "Pro přihlášení do API je potřeba, aby uživatel měl přiděleno oprávnění "
133
+ "ACCESS. Pro přístup k dalším záznamům v API je nutné, aby uživatel měl "
134
+ "nastaveno oprávnění VIEW pro daný model."
@@ -0,0 +1,19 @@
1
+ from django.db import migrations
2
+
3
+ from cms_qe.api.constants import CMS_QE_USER_ACCES_API_PERMISSION
4
+
5
+
6
+ def create_permission(apps, schema_editor):
7
+ ContentType = apps.get_model("contenttypes", "ContentType")
8
+ Permission = apps.get_model("auth", "Permission")
9
+ app_label, model = CMS_QE_USER_ACCES_API_PERMISSION.split(".")
10
+ cms_qe_user, _ = ContentType.objects.get_or_create(app_label=app_label)
11
+ Permission.objects.get_or_create(defaults={ "content_type": cms_qe_user, "codename": model}, name="Can access to the API")
12
+
13
+
14
+ class Migration(migrations.Migration):
15
+ dependencies = []
16
+
17
+ operations = [
18
+ migrations.RunPython(create_permission),
19
+ ]
@@ -95,6 +95,12 @@ INSTALLED_APPS = [
95
95
  'standard_form',
96
96
  'spurl',
97
97
  'aldryn_search',
98
+
99
+ # Site REST API
100
+ 'rest_framework',
101
+ 'knox',
102
+ 'django_filters',
103
+ 'drf_spectacular',
98
104
  ]
99
105
 
100
106
  MIDDLEWARE = [
@@ -135,3 +141,6 @@ MIDDLEWARE = [
135
141
 
136
142
  # Reload site. For example ['uwsgi', '--reload', '/var/run/uwsgi.pid'] or ['touch', 'manage.py'].
137
143
  RELOAD_SITE: list[str] = []
144
+
145
+ # API views: [("path/", "module.api.views.RecordViewSet", "api-records"), ...]
146
+ # API_VIEWS: list[tuple[str, str, str]] = []
@@ -0,0 +1,38 @@
1
+ {% extends "admin/index.html" %}
2
+ {% load i18n %}
3
+
4
+ {% block content %}
5
+ {{ block.super }}
6
+ {% if not app_label %}
7
+ {% if perms.cms_qe_auth.accessapi_user or perms.auth.add_permission %}
8
+ <div class="module">
9
+ <table>
10
+ <caption><h3>REST API</h3></caption>
11
+ <tbody>
12
+ <tr scope="row">
13
+ <td><a href="{% url "api-root" %}">{% url "api-root" %}</a></td>
14
+ </tr>
15
+ <tr scope="row">
16
+ <td><a href="{% url "api-root" %}schema/swagger/">{% url "api-root" %}schema/swagger/</a></td>
17
+ </tr>
18
+ <tr scope="row">
19
+ <td><a href="{% url "api-root" %}schema/redoc/">{% url "api-root" %}schema/redoc/</a></td>
20
+ </tr>
21
+ </tbody>
22
+ </table>
23
+ {% if perms.auth.add_permission %}
24
+ <p>
25
+ {% blocktranslate trimmed %}
26
+ To log into the API, the user needs to have the access permission assigned.
27
+ To access other records in the API, the user must have the VIEW permission set for the model.
28
+ {% endblocktranslate %}
29
+ </p>
30
+ <div>{% translate "For example:" %}</div>
31
+ <div><code>cms_qe_auth | user | Can access to the API</code></div>
32
+ <div><code>aldryn_forms | Form submission | Can view Form submission</code></div>
33
+ <div><code>aldryn_forms | Form plugin | Can view Form plugin</code></div>
34
+ {% endif %}
35
+ </div>
36
+ {% endif %}
37
+ {% endif %}
38
+ {% endblock %}
cms_qe/urls.py CHANGED
@@ -40,6 +40,7 @@ urlpatterns = [
40
40
  path('', include('cms_qe_newsletter.urls')),
41
41
  path('sitemap.xml', sitemap, {'sitemaps': {'cmspages': CMSSitemap}}),
42
42
  path('api/monitoring', views.get_monitoring),
43
+ path('api/v1/', include('cms_qe.api.urls'), name="api-root"),
43
44
  path('.well-known/security.txt', SecurityTxtView.as_view(), name='security-txt'),
44
45
  path('site-search-result/', SiteSearchView.as_view(), name='site-search-result'),
45
46
  path("healthcheck/", HealthCheckView.as_view(), name='healthcheck'), # Used by uwsgi in docker.
cms_qe_auth/utils.py CHANGED
@@ -8,6 +8,7 @@ from django.contrib.auth import get_user_model
8
8
  from django.core.exceptions import ValidationError
9
9
  from django.utils.encoding import force_bytes, force_str
10
10
  from django.utils.http import urlsafe_base64_decode, urlsafe_base64_encode
11
+ from django.utils.module_loading import import_string
11
12
 
12
13
  ACTION_OK = 250 # Requested mail action okay, completed.
13
14
 
@@ -84,5 +85,8 @@ class SMTPCheckRecipient:
84
85
 
85
86
  def smtp_server_accepts_email_address(address: str) -> None:
86
87
  """SMTP server accepts email address. Raise ValidationError if not."""
87
- with SMTPCheckRecipient(settings.EMAIL_HOST) as checker:
88
- checker.check(address)
88
+ backend = import_string(settings.EMAIL_BACKEND)
89
+ if hasattr(backend, "host"):
90
+ # Check only smtp backend.
91
+ with SMTPCheckRecipient(settings.EMAIL_HOST) as checker:
92
+ checker.check(address)
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: django-cms-qe
3
- Version: 3.5.0
3
+ Version: 3.6.0
4
4
  Summary: Django CMS Quick & Easy provides all important modules to run new page withouta lot of coding. Aims to do it very easily and securely.
5
5
  Home-page: https://websites.pages.nic.cz/django-cms-qe
6
6
  Author: CZ.NIC, z.s.p.o.
@@ -46,18 +46,14 @@ Requires-Dist: djangocms-aldryn-search
46
46
  Requires-Dist: django-haystack~=3.2
47
47
  Requires-Dist: pymemcache~=4.0
48
48
  Requires-Dist: whoosh~=2.7
49
- Provides-Extra: build
50
- Requires-Dist: Jinja2<3.1.0; extra == "build"
51
- Requires-Dist: Sphinx==1.8.5; extra == "build"
49
+ Requires-Dist: djangorestframework
50
+ Requires-Dist: markdown
51
+ Requires-Dist: django-filter
52
+ Requires-Dist: django-rest-knox
53
+ Requires-Dist: drf-spectacular
52
54
  Provides-Extra: dev
53
55
  Requires-Dist: django-debug-toolbar~=4.1; extra == "dev"
54
56
  Requires-Dist: django-extensions~=3.2; extra == "dev"
55
- Provides-Extra: mysql
56
- Requires-Dist: mysqlclient~=2.2; extra == "mysql"
57
- Provides-Extra: newsblog
58
- Requires-Dist: djangocms-aldryn-newsblog; extra == "newsblog"
59
- Provides-Extra: psql
60
- Requires-Dist: psycopg2; extra == "psql"
61
57
  Provides-Extra: test
62
58
  Requires-Dist: flake8; extra == "test"
63
59
  Requires-Dist: isort; extra == "test"
@@ -76,6 +72,28 @@ Requires-Dist: webdriverwrapper==2.8.0; extra == "test"
76
72
  Requires-Dist: django-simple-captcha==0.5.14; extra == "test"
77
73
  Requires-Dist: testfixtures; extra == "test"
78
74
  Requires-Dist: tzdata; extra == "test"
75
+ Provides-Extra: build
76
+ Requires-Dist: Jinja2<3.1.0; extra == "build"
77
+ Requires-Dist: Sphinx==1.8.5; extra == "build"
78
+ Provides-Extra: psql
79
+ Requires-Dist: psycopg2; extra == "psql"
80
+ Provides-Extra: mysql
81
+ Requires-Dist: mysqlclient~=2.2; extra == "mysql"
82
+ Provides-Extra: newsblog
83
+ Requires-Dist: djangocms-aldryn-newsblog; extra == "newsblog"
84
+ Dynamic: author
85
+ Dynamic: author-email
86
+ Dynamic: classifier
87
+ Dynamic: description
88
+ Dynamic: description-content-type
89
+ Dynamic: home-page
90
+ Dynamic: keywords
91
+ Dynamic: license
92
+ Dynamic: license-file
93
+ Dynamic: provides-extra
94
+ Dynamic: requires-dist
95
+ Dynamic: requires-python
96
+ Dynamic: summary
79
97
 
80
98
  # Django CMS QE
81
99
 
@@ -7,8 +7,14 @@ cms_qe/fixtures.py,sha256=cq_wnZnqBwPBOHpp_0bHk424iCXKvwmN6ZaKwDvguXk,755
7
7
  cms_qe/monitoring.py,sha256=5t_o7o0htmAAxVjkN2oz0O0v9XdzfePhSfPGcLNPmE8,769
8
8
  cms_qe/signals.py,sha256=MbuLSxPlJA147LEg-lDWDoUNTV1y0OKjwoI3HzgR97g,1253
9
9
  cms_qe/staticfiles.py,sha256=OHkfDfpIxN0B-eCRagZzHDHyBgaulcyYgKhp_3mPZuk,1363
10
- cms_qe/urls.py,sha256=vNiiN7NwFFT48SBNIg6lzjTRMN6BicwH_zz6p-EApsw,3042
10
+ cms_qe/urls.py,sha256=qikE6wfP-JwJ-FiLCw6DRhhA46N0ajI8kABdv0GDjMk,3108
11
11
  cms_qe/utils.py,sha256=gxsWZmS34ZC0Tv1VW8A7VeGlrPyDshodF1ZWXj7xyWE,3057
12
+ cms_qe/api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
+ cms_qe/api/constants.py,sha256=pdSziATRm6yUaaPBYoD07JXcULMvKD0h5RdNTPpG0rM,64
14
+ cms_qe/api/permissions.py,sha256=QKSll8wVOWKNbvX_FsC9CRKbPVcT2s5FM81_fnqeEQg,409
15
+ cms_qe/api/urls.py,sha256=UPd7OUHTJxszNLZo3wu50wyVd7Df2F82PFP-Zr2N_fk,1445
16
+ cms_qe/api/utils.py,sha256=04lsxEkYXlOynCdsz6srdn7-h8Qdpn_lBwmjpJ89OI4,456
17
+ cms_qe/api/views.py,sha256=hTq7jEJ9mzozbYaTPRQW2vfo2EboJ6OyO6Nl0lIsm9I,947
12
18
  cms_qe/boilerplates/bootstrap3/static/cms_qe/css/bootstrap-theme.css,sha256=xOpS-e_dER8z72w-qryCieOGysQI8cELAVt3MHG0phY,26132
13
19
  cms_qe/boilerplates/bootstrap3/static/cms_qe/css/bootstrap-theme.css.map,sha256=cZQbJTuJQjdM1XuKhdRzSJ8hMRQ4up491P76Iq2_D1M,47706
14
20
  cms_qe/boilerplates/bootstrap3/static/cms_qe/css/bootstrap-theme.min.css,sha256=ZT4HPpdCOt2lvDkXokHuhJfdOKSPFLzeAJik5U_Q-l4,23409
@@ -35,7 +41,7 @@ cms_qe/haystack/highlighting.py,sha256=VRECODAO-AGcdon2ggz-Epo41HGmReeUuQFrF_3Pe
35
41
  cms_qe/haystack/inputs.py,sha256=GhgmgKRe74nGJvXSVUBy1_tFxop6NuguriVybddSunA,129
36
42
  cms_qe/haystack/query.py,sha256=bpxIcAOg_LVSa-st0ml-4Oa7gXb_NFMHj8iPCu5jui0,442
37
43
  cms_qe/locale/cs/LC_MESSAGES/django.mo,sha256=lCxKXPDs4MGTmLZZATWFng0_xKcjYrWn5CsHaKjlMIA,2287
38
- cms_qe/locale/cs/LC_MESSAGES/django.po,sha256=bBtnbNTe3pIsre_tNZ8tMdl5ZDfuDZOIwwZRFi33jbA,3545
44
+ cms_qe/locale/cs/LC_MESSAGES/django.po,sha256=mCHLG1Fzo0kInNEuW5HzR9vxgaWs11me7Zh6gDJ2_Rk,4003
39
45
  cms_qe/locale/en/LC_MESSAGES/django.mo,sha256=1Oza0kFTJYv1uLpu51-XbZShcMmsgRMPdKVmSFB0mZk,378
40
46
  cms_qe/locale/en/LC_MESSAGES/django.po,sha256=id9XCp1yVlWOBi37bDGlFVn26ao6mREpGWJI5iTbJH4,1924
41
47
  cms_qe/management/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -43,11 +49,13 @@ cms_qe/management/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJ
43
49
  cms_qe/management/commands/create_superuser_if_not_exists.py,sha256=BUaKwwCx5YmLDLlyq7UTcZTbLjURywiNnsXNYhddaQc,727
44
50
  cms_qe/middleware/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
45
51
  cms_qe/middleware/page_status_code.py,sha256=J-Ezet9ban9rnjWaSuRss9gOz5h7uCCyL46qFlKBd2A,805
52
+ cms_qe/migrations/0001_api_permissions.py,sha256=KPJYBdX3dWYEbUswSiIhkhDV6FcjXG-MPfC2aYwt7Wc,672
53
+ cms_qe/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
46
54
  cms_qe/settings/__init__.py,sha256=GJwHXMHwMuGYE-3ZzePJ-26I2WwE8bAIMUDoiTFr0L8,982
47
55
  cms_qe/settings/dev.py,sha256=51CBwiclE8LLoNB2uioIK_L3JhM1yzukQ0gZimkcFqw,1487
48
56
  cms_qe/settings/unittest.py,sha256=folLIMJb1Arh60_Sn0eNQrvIlx0OsAs6v1tDfyRZVuQ,514
49
57
  cms_qe/settings/base/__init__.py,sha256=5yHfne9gPD_xuTaG3voZP23yzuCwROmif2mmKs-hG_A,446
50
- cms_qe/settings/base/app.py,sha256=pmy_0ThkSDNXmEVrWwFpRQ-mjHCvYFoo8YxmFRLG5bM,3988
58
+ cms_qe/settings/base/app.py,sha256=RGxe4deN_qLGc_aRNKGjmBgsWYYpd-wdm6V47a0VR5I,4213
51
59
  cms_qe/settings/base/auth.py,sha256=OTr1LJ4RSMZm8STs4Q3pwPXmQoURax8OKLJ8eAj7PW4,395
52
60
  cms_qe/settings/base/cache.py,sha256=9p6C5lOz1pG-6k15PyvxlShUjBYIbU0ewpA8AX_YFus,297
53
61
  cms_qe/settings/base/cms.py,sha256=8icCNxcEp_KRDyP8-LXB21UurJL4wNysY39whAyt3I4,1855
@@ -60,9 +68,8 @@ cms_qe/settings/base/path.py,sha256=s0eOmSDOWfjjI5onp28y2S2UKwCYFRDGeoUsZla6-og,
60
68
  cms_qe/settings/base/search.py,sha256=xbO9OFFGLi8PZut_Ngb-27BUI6HPG0ZM4lrO1HXHW-c,618
61
69
  cms_qe/settings/base/security.py,sha256=i6mHb8gv6XPthShL1kFLTwa_vrfoaivzqC9MXLE_YBw,4496
62
70
  cms_qe/settings/base/template.py,sha256=bITmA7XkoqbDpefWWOBsEiPtCREzFfHkUuFvGxJVLK4,1082
63
- cms_qe/static/css/fix-admin.css,sha256=Dv0DZWJ72ZxjhUP9HT7MV-ZPHDwiAC3DgfPE3Fc-WEM,270
64
71
  cms_qe/templates/base.html,sha256=BMd8MbubDB8m1ZzBWfAfzTs4EBQn0oBQUw1GVRA4z6A,972
65
- cms_qe/templates/admin/change_form.html,sha256=YyJmsjepSZTacZE9to5_UwjbTVde0bJuqy6Tiqwk0Dk,201
72
+ cms_qe/templates/admin/index.html,sha256=6CjuqOPQnEYXa7zwyoLyDHt-zzfBwLAf45B0F80ryZ0,1812
66
73
  cms_qe/templates/cms_qe/error.html,sha256=1wNCO-ToNoM-HBnfq0Id_W8m_epmOEYcoozRhhHth5U,322
67
74
  cms_qe/templates/cms_qe/home.html,sha256=XSyChEdMnxcw-OWrm_d_3h2lmXfPyfpCpyYKH6QNG2E,186
68
75
  cms_qe/templates/cms_qe/internal_error.html,sha256=n4JJ80KNHyhiSxGLQadCn9KmctnFABcwLU4KuZly8A4,251
@@ -78,12 +85,6 @@ cms_qe/templates/cmsplugin_filer_folder/plugins/folder/main.html,sha256=8IiTXNU4
78
85
  cms_qe/templatetags/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
79
86
  cms_qe/templatetags/cms_qe_filters.py,sha256=ciYCXLuMVde-f_-B_7a5mHfAJPWPMxYEUMgCHpualRY,784
80
87
  cms_qe/templatetags/kwacros.py,sha256=r2oHLltu8BgKKlrpgzXgvLjbIqwcrH13Lww3zTF-nr8,6275
81
- cms_qe/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
82
- cms_qe/tests/test_errors.py,sha256=sICTfVKbNbqDjpLvT_v485lML8P-MQBIyr9BJUDAKcw,2372
83
- cms_qe/tests/test_export.py,sha256=mh6KO95gVt4Q7CTNDTHvHq4lQH-lFBVI5W4-cHImBto,3456
84
- cms_qe/tests/test_monitoring.py,sha256=xa8mBu-TdBAUIUlnoWQpWtMDa5p8DmD0DCyR82Iu5K8,350
85
- cms_qe/tests/test_utils.py,sha256=iPBDNE4YNsqw-nOfn2J0x74vgDl8xqvDJrFy7Z1U7yo,2535
86
- cms_qe/tests/test_views_security.py,sha256=RvyilVNoAiWApgn3iWJk1t6IaVTn0z6zv5M5sOzyM18,701
87
88
  cms_qe/views/__init__.py,sha256=3b5FCZ5MaqgiWglC7c5mfvP3WYLWTtNp3YpVb9BgYi8,106
88
89
  cms_qe/views/errors.py,sha256=zUbCoyXy_MPsQv3UV1mgq-q2bwqPw9G4KgKU2-oue4w,3169
89
90
  cms_qe/views/maintenance.py,sha256=Q410LCeeihRWhIJ-zzRpFSjfvA6xhgr6NJlNAoTNO2U,1658
@@ -99,14 +100,6 @@ cms_qe_analytical/templates/cms_qe_analytical/google_tag_manager.html,sha256=MJJ
99
100
  cms_qe_analytical/templatetags/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
100
101
  cms_qe_analytical/templatetags/google_analytics.py,sha256=cN87jJzwVcjhqSS2JKTmPt9WntuBLnzxEcwgjrQMJSg,7370
101
102
  cms_qe_analytical/templatetags/piwik.py,sha256=EHOaojmewFpMqHzm_QCtCXGc_HGoiCJ_G-LPc8IfjM4,4131
102
- cms_qe_analytical/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
103
- cms_qe_analytical/tests/settings.py,sha256=o8gNKNCS6Pwqmih2MUxkt3PUpNljta3Xx2_HdZfS6dU,438
104
- cms_qe_analytical/tests/test_tag_google_analytics.py,sha256=n3ocL7rrsS_J2uy-ECObaCV7VJ4BjF_Y2abOPh24Rgs,8227
105
- cms_qe_analytical/tests/test_tag_piwik.py,sha256=CZ9u_3tYVXFvVkH3t5e0vyibzylFIGqPYEWUjqS6z_8,6186
106
- cms_qe_analytical/tests/test_utils.py,sha256=XWaemXx9P8Aab9GJWgx60cH1pfPuZieSvlPJ8z05PCY,4062
107
- cms_qe_analytical/tests/utils.py,sha256=iZgimMaZmzotuRchh7qs5IaxuUUSYg4-ufigR91jyMg,1413
108
- cms_qe_analytical/tests/templatetags/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
109
- cms_qe_analytical/tests/templatetags/dummy.py,sha256=mIRwUFWsdkmvKkUShCFkpVZLunRD7XhdXevpnf5WSB0,920
110
103
  cms_qe_auth/__init__.py,sha256=SZS-CdmFLgIN4WGaUX_780L-vH0lqC7CdxKWjm_EuxE,867
111
104
  cms_qe_auth/admin.py,sha256=PVxb9G_r6R4cyKvZUehENIN-aBSNDpqzA6O2gRbdQeQ,1135
112
105
  cms_qe_auth/apps.py,sha256=YiIgOI3Bxj4-7IZdxUEvHmTK1xS9fR2qMS-fe5AZ-W0,191
@@ -117,7 +110,7 @@ cms_qe_auth/forms.py,sha256=x7sdFoOrKBLTJXqESedpIh6Kc1k5zZhL4vwnmhj1gH8,1137
117
110
  cms_qe_auth/models.py,sha256=Aro43D9y1zrS-3eKHVZEuSkchusDZAcj15B2vYcdt0Q,2713
118
111
  cms_qe_auth/token.py,sha256=DG4Bu8AVV-d1ayL4Oc9DXNnERt1sstrll80RBGrplx0,224
119
112
  cms_qe_auth/urls.py,sha256=RCgr9t1YonE0yR_8gXiXZIGESvQfrwVwlKhBOWmgxkw,2040
120
- cms_qe_auth/utils.py,sha256=94aELOVicanApvKkZ3xw5sFjd2C8AEzyCrHdgpFW8Pc,2790
113
+ cms_qe_auth/utils.py,sha256=JYZUzQhUE_kycVBRBNi-fmGy5WtjIwc3_qsGxOVrNR0,2972
121
114
  cms_qe_auth/views.py,sha256=TG7kwG2xtRUt9S8nG3rUlNOU_BsfvRVybNexGpF_9uI,2233
122
115
  cms_qe_auth/boilerplates/bootstrap3/templates/cms_qe/auth/login_form.html,sha256=nG9X-nvfXA4_9h4lVJGIHdcYFhf7sNEg_rVPa6ze9a4,884
123
116
  cms_qe_auth/boilerplates/bootstrap3/templates/cms_qe/auth/password_change_form.html,sha256=1khb3qibf_YpVV2GyT6W9sgTMtFetNmjs2mbCdCFtIo,599
@@ -159,11 +152,6 @@ cms_qe_auth/templates/cms_qe/auth/email/activation.html,sha256=5KzIsVw-r_3yzi47t
159
152
  cms_qe_auth/templates/cms_qe/auth/email/activation.txt,sha256=rtNkt3bk-RHAWWU8TLS7JbJadHxAuTmW4TjQw6q4Czk,302
160
153
  cms_qe_auth/templates/cms_qe/auth/email/base.html,sha256=PsNYnKORXRZuhhr0Xcg8ebvd-VuJPaBn3ghStCoW8tw,511
161
154
  cms_qe_auth/templates/cms_qe/auth/email/base.txt,sha256=I7CXI7IuUYW_juVJIH1Dlc3asQlEmRMmJDf-thjqObU,142
162
- cms_qe_auth/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
163
- cms_qe_auth/tests/test_models.py,sha256=ps5FsQY9ohHHkxezWFwQn4Qv_XnZKSF6kxXm-fShW8s,2238
164
- cms_qe_auth/tests/test_utils.py,sha256=NjV36oPUUF2eiaTt5SmO2u-dYQgLZiDr64VtpRbdMjI,767
165
- cms_qe_auth/tests/test_view.py,sha256=LpIpWzU8QtjF0pRDkg24AiVM7lRiLSvS-rqVsMbWdsU,2284
166
- cms_qe_auth/tests/utils.py,sha256=7aYvjZofMNBLA7VNwSxa1lp_eHnpURhIdvwaHnPmy_s,581
167
155
  cms_qe_breadcrumb/__init__.py,sha256=RSHANxs85gpPyR2td66syP--Ue6d5AiTv4kbcLWQRRU,344
168
156
  cms_qe_breadcrumb/cms_plugins.py,sha256=3-DFIh-LMn3-IL2UJM8Y8-zD-XuiWHMk1ZBXon1-Vls,387
169
157
  cms_qe_breadcrumb/tests.py,sha256=4eZDHwEMYxRJCvE8XI4M6eJRbGZIaq8PvrzN5eqbBgI,540
@@ -3907,13 +3895,6 @@ cms_qe_newsletter/templates/admin/cms_qe_newsletter/mailinglist/change_list.html
3907
3895
  cms_qe_newsletter/templates/cms_qe/newsletter/form.html,sha256=5YsoZlQsxlBfMStROmK8V9T0-w5akjCu3a75GlpO9bk,385
3908
3896
  cms_qe_newsletter/templates/cms_qe/newsletter/newsletter.html,sha256=0YnNGr4hNhAlkM-7ISeE8y1vRhFi7DdjJI_QH_B_ME4,195
3909
3897
  cms_qe_newsletter/templates/cms_qe/newsletter/submitted.html,sha256=mOgMi56fuo3VFGC7P_uIA0XQQ7qAkG130s-WuvmF-n4,51
3910
- cms_qe_newsletter/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3911
- cms_qe_newsletter/tests/test_mailchimp.py,sha256=_fwNbNjeZA1plUWgFl_NSjly9jqyzG170Bt-mavSQvM,1159
3912
- cms_qe_newsletter/tests/test_managment.py,sha256=mz-ztXPtcVR01V8_mjpBpUgxwa1OrI90UgCShwnW3sA,886
3913
- cms_qe_newsletter/tests/test_models.py,sha256=w428Cl_ZF_GvsGDavb8vIoZlkJLKL5Z7ZN5fK0d76ks,1432
3914
- cms_qe_newsletter/tests/test_plugin.py,sha256=HhSz-QcXAp3KJelQ7r0Z3np_QNHrJY7QbPODv3NI9Pg,523
3915
- cms_qe_newsletter/tests/test_sync.py,sha256=09Cszu3IWvgh6c8m8a-aXtbKWI_yZQbjwkfLT0fdlzI,2269
3916
- cms_qe_newsletter/tests/test_views.py,sha256=IJ621fRok6kK2BfSKfnY-EWVfFXoVRD_rHBpiboZKnk,449
3917
3898
  cms_qe_plugins/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3918
3899
  cms_qe_plugins/attributes.py,sha256=XWLp_Mo3ZQxqUXKOsv1ff-IAX8fnNi2FS_KqdoQT0hQ,760
3919
3900
  cms_qe_plugins/cms_plugins.py,sha256=U1A5oVJNz1uGJL8JT6HYbR1zx7S9B3m6nt4uhGmdK9k,988
@@ -3958,10 +3939,6 @@ cms_qe_table/templates/cms_qe/table/table_value_int.html,sha256=mjmA7u_ENXs3JHza
3958
3939
  cms_qe_table/templates/cms_qe/table/table_widget.html,sha256=tsjlS5Mc_6iALFk0QIexPkFVLEwSb1PlsCkntqfuTwk,1315
3959
3940
  cms_qe_table/templatetags/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3960
3941
  cms_qe_table/templatetags/cms_qe_table_filters.py,sha256=eFBB2FoCcpQRAknMIJLac0ts18w8XIODbouuJlP0ty4,782
3961
- cms_qe_table/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3962
- cms_qe_table/tests/test_models.py,sha256=6DsUUvIwZXIxiys8NUECswb6Laxr3eUsiY1B9nFbolY,728
3963
- cms_qe_table/tests/test_plugin.py,sha256=L66BSM-Yco2hI0ZPIEgx0IZeE3S_Z8DaVANDXKdEsbM,549
3964
- cms_qe_table/tests/test_utils.py,sha256=hORUKMjRman02zW3dLb7f4RDgCL9E-wCtt-gfxifMCY,2857
3965
3942
  cms_qe_test/__init__.py,sha256=-Vc3K2g4JFSE2qw5AvuTGi4rwQGMOXAEycrjgFWk1BQ,121
3966
3943
  cms_qe_test/cms.py,sha256=pspLQxbnwG71PuZKtwfWDu6uVk7RYO86Od1cDXBF108,1796
3967
3944
  cms_qe_video/__init__.py,sha256=2iOdITrw_UvFcQpFA0rhUWBCRe2qvTuDvltp5Q233cc,1070
@@ -3982,10 +3959,7 @@ cms_qe_video/templates/cms_qe/video/video_source_file.html,sha256=QJF5fs88s9Fznp
3982
3959
  cms_qe_video/templates/cms_qe/video/video_widget.html,sha256=Yumciq6bGlAYI1lYx5j9V6IF8QYrncNYygPTkXEz6Wk,925
3983
3960
  cms_qe_video/templatetags/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3984
3961
  cms_qe_video/templatetags/cms_qe_video.py,sha256=NR_mGv91J0rEreZrQjCzaaXSrZsKvrSas12wMJ-Dg24,1168
3985
- cms_qe_video/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3986
- cms_qe_video/tests/test_models.py,sha256=iTTQEFO9D8Shd5-5-EvM-mlvh8etww3c9Kf-DUVwz94,4366
3987
- cms_qe_video/tests/test_plugin.py,sha256=cod8QXTGOLpFgzB105JvzVoyTRq2UOY5Jpqos6GvA9g,1046
3988
- cms_qe_video/tests/test_templatetags.py,sha256=87koyj4w2PD2-bGQCrvE1UwULxDQSA_D_qL-ciM_L8U,1102
3962
+ django_cms_qe-3.6.0.dist-info/licenses/LICENSE,sha256=5wLaeUil0gfU9p8C4zn2Yu_PvZBNieUoYl0z9FcFWdA,1521
3989
3963
  example/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3990
3964
  example/urls.py,sha256=H-IJsRGFVZGw6FD9gvK-0B0dLeSOsduziHvDvcHCQZ0,399
3991
3965
  example/wsgi.py,sha256=lCKhvtFZlorSIA8qYEqc3pZ1Oflrz_Tc696MWJ62ue4,396
@@ -4006,8 +3980,7 @@ test_selenium/pages/cms/__init__.py,sha256=_qe4YZYaQbrXp7Szmmeo4TUSkXlE5Rozu8E3t
4006
3980
  test_selenium/pages/cms/login.py,sha256=UPzJQcYff8NUAT4nvmfQoJQxzOJyPrJ_cKtH35NVfNg,521
4007
3981
  test_selenium/pages/cms/page.py,sha256=YQnpZkopfVnhoyQKpRDGqjNeV6xUl-pEHjEcZ9HRiPk,489
4008
3982
  test_selenium/pages/cms/wizard.py,sha256=yatbXH-rf1ap4O1hY0I13WikM3zkm_NrAiSK6bqENIU,545
4009
- django_cms_qe-3.5.0.dist-info/LICENSE,sha256=5wLaeUil0gfU9p8C4zn2Yu_PvZBNieUoYl0z9FcFWdA,1521
4010
- django_cms_qe-3.5.0.dist-info/METADATA,sha256=QyYycfNdYBbAMxdXvVfvOv4I5ygBW6kWImhmAALWRL4,4651
4011
- django_cms_qe-3.5.0.dist-info/WHEEL,sha256=P9jw-gEje8ByB7_hXoICnHtVCrEwMQh-630tKvQWehc,91
4012
- django_cms_qe-3.5.0.dist-info/top_level.txt,sha256=T4dauFwJy7FmxCy7WoQI3pPwiDessNB2LkfOAP76ssE,172
4013
- django_cms_qe-3.5.0.dist-info/RECORD,,
3983
+ django_cms_qe-3.6.0.dist-info/METADATA,sha256=jAhwwpVT8EnPvK-dAJihBIrz6nHPCtByUhtS_dbG4Yg,5080
3984
+ django_cms_qe-3.6.0.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
3985
+ django_cms_qe-3.6.0.dist-info/top_level.txt,sha256=T4dauFwJy7FmxCy7WoQI3pPwiDessNB2LkfOAP76ssE,172
3986
+ django_cms_qe-3.6.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.3.0)
2
+ Generator: setuptools (78.1.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,14 +0,0 @@
1
- /*
2
- Fix label-value overlap in change form.
3
- */
4
- form .flex-container {
5
- display: flex;
6
- }
7
-
8
- form .aligned label + div.readonly {
9
- margin-top: -0.5em;
10
- }
11
-
12
- .aligned label + p, .aligned .checkbox-row + div.help, .aligned label + div.readonly {
13
- margin-left: 1em;
14
- }
@@ -1,7 +0,0 @@
1
- {% extends "admin/change_form.html" %}
2
- {% load static %}
3
-
4
- {% block extrahead %}
5
- {{ block.super }}
6
- <link rel="stylesheet" type="text/css" href="{% static "css/fix-admin.css" %}">
7
- {% endblock %}
@@ -1,61 +0,0 @@
1
- from unittest.mock import patch
2
-
3
- from django.contrib.auth.models import AnonymousUser
4
- from django.test import RequestFactory, TestCase
5
-
6
- from cms_qe.views import handler500
7
- from cms_qe_test.cms import create_page
8
-
9
-
10
- def test_page_found(client):
11
- create_page('Test page', page_params={'slug': 'test'})
12
- html = client.get('/en/test/').content
13
- assert b'<h1>Generic error</h1>' not in html
14
- assert b'<title>Test page</title>' in html
15
-
16
-
17
- def test_page_not_found(client):
18
- html = client.get('/en/non-existing-page/').content
19
- assert b'<h1>Generic error</h1>' in html
20
- assert b'error404' in html
21
-
22
-
23
- def test_page_not_found_custom_by_cms(client):
24
- create_page('custom page not found', page_params={'slug': 'error404'})
25
- response = client.get('/en/non-existing-page/')
26
- assert response.status_code == 404
27
- html = response.content
28
- assert b'<h1>Generic error</h1>' not in html
29
- assert b'<title>custom page not found</title>' in html
30
-
31
-
32
- def test_page_not_found_cached_custom_by_cms(client):
33
- create_page('custom page not found', page_params={'slug': 'error404'})
34
- # First request store page into the cache
35
- response = client.get('/en/non-existing-page/')
36
- assert response.status_code == 404
37
- # Second request is taken from the cache.
38
- response = client.get('/en/non-existing-page/')
39
- assert response.get('QE-Status-Code') is None
40
- assert response.status_code == 404
41
-
42
-
43
- class Handler500Test(TestCase):
44
- def test_template_rendered(self):
45
- request = RequestFactory().get("/500")
46
- request.current_page = None
47
- request.session = {}
48
- request.user = AnonymousUser()
49
- response = handler500(request)
50
- self.assertContains(response, '<h1>Internal error</h1>', status_code=500)
51
- self.assertContains(response, 'Something went very wrong. Please try again later.', status_code=500)
52
-
53
- @patch('cms_qe.views.errors.render', side_effect=Exception("Fail!"))
54
- def test_template_failure(self, render_mock):
55
- request = RequestFactory().get("/500")
56
- request.current_page = None
57
- request.session = {}
58
- request.user = AnonymousUser()
59
- response = handler500(request)
60
- self.assertContains(response, '<h1>Internal error</h1>', status_code=500)
61
- self.assertContains(response, 'Something went very wrong. Please try again later.', status_code=500)
@@ -1,108 +0,0 @@
1
- import csv
2
- import io
3
- import json
4
- from unittest.mock import patch
5
-
6
- import pytest
7
- from django.contrib.auth import get_user_model
8
- from pytest_data import use_data
9
-
10
- from ..export import export_data, export_file, get_supported_export_types
11
-
12
-
13
- class ModelAdmin:
14
- list_display = ('foo',)
15
-
16
- def foo(self, obj):
17
- return 'foo property'
18
-
19
-
20
- class ExportDataAdmin(ModelAdmin):
21
-
22
- def export_data(self, export_type, queryset):
23
- return 'foo export_data'
24
-
25
-
26
- @pytest.mark.django_db
27
- @use_data(user_data={'username': 'test_export_data_as_csv'})
28
- def test_export_data_as_csv(user):
29
- User = get_user_model()
30
- queryset = User.objects.all()
31
- data = export_data('csv', ModelAdmin(), queryset)
32
- data = list(csv.reader(io.StringIO(data)))
33
- assert len(data) == 2
34
- assert 'test_export_data_as_csv' in data[1]
35
- assert 'foo property' in data[1]
36
-
37
-
38
- @pytest.mark.django_db
39
- @use_data(user_data={'username': 'test_export_data_as_tsv'})
40
- def test_export_data_as_tsv(user):
41
- User = get_user_model()
42
- queryset = User.objects.all()
43
- data = export_data('tsv', ModelAdmin(), queryset)
44
- data = list(csv.reader(io.StringIO(data), delimiter='\t'))
45
- assert len(data) == 2
46
- assert 'test_export_data_as_tsv' in data[1]
47
- assert 'foo property' in data[1]
48
-
49
-
50
- @pytest.mark.django_db
51
- @use_data(user_data={'username': 'test_export_data_as_json'})
52
- def test_export_data_as_json(user):
53
- User = get_user_model()
54
- queryset = User.objects.all()
55
- data = export_data('json', ModelAdmin(), queryset)
56
- data = json.loads(data)
57
- assert len(data) == 1
58
- assert data[0]['username'] == 'test_export_data_as_json'
59
- assert data[0]['foo'] == 'foo property'
60
-
61
-
62
- @pytest.mark.django_db
63
- @use_data(user_data={'username': 'test_export_data_as_json'})
64
- def test_export_data_admin_function(user):
65
- User = get_user_model()
66
- queryset = User.objects.all()
67
- data = export_data('foo', ExportDataAdmin(), queryset)
68
- assert data == 'foo export_data'
69
-
70
-
71
- @pytest.mark.django_db
72
- @use_data(user_data={'username': 'test_export_data_as_json'})
73
- def test_export_file():
74
- User = get_user_model()
75
- queryset = User.objects.all()
76
- response = export_file('csv', ModelAdmin(), queryset)
77
- assert response['content-disposition'] == 'attachment; ' \
78
- 'filename="export.csv"'
79
- assert response.content == b'ID,password,last login,superuser ' \
80
- b'status,username,first name,last name,email address,staff ' \
81
- b'status,active,date joined,groups,user permissions,foo\r\n'
82
-
83
-
84
- def test_get_supported_export_types():
85
- with patch('cms_qe.export.getattr') as mock_getattr:
86
- mock_getattr.side_effect = [
87
- 'csv', 'html', 'json', 'latex', 'ods', 'rst', 'tsv', 'xls',
88
- 'xlsx', 'yaml']
89
- data = get_supported_export_types()
90
- assert sorted(data.keys()) == [
91
- 'csv', 'html', 'json', 'latex', 'ods', 'rst', 'tsv', 'xls', 'xlsx',
92
- 'yaml']
93
- assert data['csv'].mimetype == 'text/csv'
94
- assert data['csv'].label == 'Export selected as CSV'
95
-
96
-
97
- def test_get_supported_export_types_import_error():
98
- with patch('cms_qe.export.getattr') as mock_getattr:
99
- mock_getattr.side_effect = ImportError()
100
- data = get_supported_export_types()
101
- assert data == {}
102
-
103
-
104
- def test_get_supported_export_types_attribute_error():
105
- with patch('cms_qe.export.getattr') as mock_getattr:
106
- mock_getattr.side_effect = AttributeError()
107
- data = get_supported_export_types()
108
- assert data == {}
@@ -1,15 +0,0 @@
1
- import json
2
-
3
- from cms_qe.views import get_monitoring_data
4
-
5
-
6
- def test_get_monitoring_data():
7
- data = get_monitoring_data()
8
- assert data['status']
9
- assert 'cms_qe' in data['app_details']
10
-
11
-
12
- def test_monitoring_view(client):
13
- result = client.get('/api/monitoring').content
14
- data = json.loads(str(result, 'utf8'))
15
- assert data['status']