django-pfx 1.2.dev97__tar.gz → 1.2.dev101__tar.gz

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 (122) hide show
  1. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/PKG-INFO +1 -1
  2. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/django_pfx.egg-info/PKG-INFO +1 -1
  3. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/django_pfx.egg-info/SOURCES.txt +1 -1
  4. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/doc/conf.py +11 -1
  5. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/doc/index.rst +1 -1
  6. django-pfx-1.2.dev97/doc/source/pfxcore.views.rst → django-pfx-1.2.dev101/doc/source/api.views.rst +15 -1
  7. django-pfx-1.2.dev101/doc/source/internationalisation.md +41 -0
  8. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/doc/source/testing.md +98 -22
  9. django-pfx-1.2.dev97/doc/source/internationalisation.md +0 -5
  10. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/.gitignore +0 -0
  11. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/.gitlab-ci.yml +0 -0
  12. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/.pre-commit-config.yaml +0 -0
  13. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/LICENSE +0 -0
  14. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/MANIFEST.in +0 -0
  15. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/README.md +0 -0
  16. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/django_pfx.egg-info/dependency_links.txt +0 -0
  17. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/django_pfx.egg-info/requires.txt +0 -0
  18. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/django_pfx.egg-info/top_level.txt +0 -0
  19. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/doc/Makefile +0 -0
  20. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/doc/source/authentication.md +0 -0
  21. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/doc/source/cookbook.md +0 -0
  22. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/doc/source/decorator.md +0 -0
  23. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/doc/source/getting_started.md +0 -0
  24. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/doc/source/model.md +0 -0
  25. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/doc/source/pfx_views.md +0 -0
  26. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/img/pfx.png +0 -0
  27. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/img/pfx.svg +0 -0
  28. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/pfx/__init__.py +0 -0
  29. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/pfx/pfxcore/__init__.py +0 -0
  30. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/pfx/pfxcore/apidoc/__init__.py +0 -0
  31. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/pfx/pfxcore/apidoc/parameters.py +0 -0
  32. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/pfx/pfxcore/apidoc/schema.py +0 -0
  33. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/pfx/pfxcore/apidoc/tags.py +0 -0
  34. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/pfx/pfxcore/apps.py +0 -0
  35. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/pfx/pfxcore/decorator/__init__.py +0 -0
  36. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/pfx/pfxcore/decorator/rest.py +0 -0
  37. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/pfx/pfxcore/default_settings.py +0 -0
  38. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/pfx/pfxcore/exceptions.py +0 -0
  39. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/pfx/pfxcore/fields.py +0 -0
  40. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/pfx/pfxcore/http/__init__.py +0 -0
  41. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/pfx/pfxcore/http/json_response.py +0 -0
  42. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/pfx/pfxcore/locale/fr/LC_MESSAGES/django.mo +0 -0
  43. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/pfx/pfxcore/locale/fr/LC_MESSAGES/django.po +0 -0
  44. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/pfx/pfxcore/management/__init__.py +0 -0
  45. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/pfx/pfxcore/management/commands/__init__.py +0 -0
  46. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/pfx/pfxcore/management/commands/makeapidoc.py +0 -0
  47. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/pfx/pfxcore/middleware/__init__.py +0 -0
  48. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/pfx/pfxcore/middleware/authentication.py +0 -0
  49. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/pfx/pfxcore/middleware/locale.py +0 -0
  50. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/pfx/pfxcore/models/__init__.py +0 -0
  51. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/pfx/pfxcore/models/cache_mixins.py +0 -0
  52. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/pfx/pfxcore/models/not_null_fields.py +0 -0
  53. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/pfx/pfxcore/models/pfx_models.py +0 -0
  54. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/pfx/pfxcore/models/user_filtered_queryset_mixin.py +0 -0
  55. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/pfx/pfxcore/serializers/__init__.py +0 -0
  56. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/pfx/pfxcore/serializers/json.py +0 -0
  57. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/pfx/pfxcore/settings.py +0 -0
  58. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/pfx/pfxcore/shortcuts.py +0 -0
  59. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/pfx/pfxcore/storage/__init__.py +0 -0
  60. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/pfx/pfxcore/storage/s3_storage.py +0 -0
  61. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/pfx/pfxcore/templates/registration/password_reset_email.txt +0 -0
  62. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/pfx/pfxcore/templates/registration/password_reset_subject.txt +0 -0
  63. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/pfx/pfxcore/templates/registration/welcome_email.txt +0 -0
  64. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/pfx/pfxcore/templates/registration/welcome_subject.txt +0 -0
  65. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/pfx/pfxcore/test.py +0 -0
  66. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/pfx/pfxcore/urls.py +0 -0
  67. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/pfx/pfxcore/views/__init__.py +0 -0
  68. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/pfx/pfxcore/views/authentication_views.py +0 -0
  69. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/pfx/pfxcore/views/fields.py +0 -0
  70. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/pfx/pfxcore/views/filters_views.py +0 -0
  71. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/pfx/pfxcore/views/locale_views.py +0 -0
  72. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/pfx/pfxcore/views/parameters/__init__.py +0 -0
  73. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/pfx/pfxcore/views/parameters/date_format.py +0 -0
  74. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/pfx/pfxcore/views/parameters/groups.py +0 -0
  75. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/pfx/pfxcore/views/parameters/list_count.py +0 -0
  76. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/pfx/pfxcore/views/parameters/list_items.py +0 -0
  77. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/pfx/pfxcore/views/parameters/list_mode.py +0 -0
  78. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/pfx/pfxcore/views/parameters/list_order.py +0 -0
  79. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/pfx/pfxcore/views/parameters/list_search.py +0 -0
  80. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/pfx/pfxcore/views/parameters/media_redirect.py +0 -0
  81. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/pfx/pfxcore/views/parameters/meta_fields.py +0 -0
  82. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/pfx/pfxcore/views/parameters/meta_filters.py +0 -0
  83. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/pfx/pfxcore/views/parameters/meta_orders.py +0 -0
  84. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/pfx/pfxcore/views/parameters/subset.py +0 -0
  85. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/pfx/pfxcore/views/parameters/subset_limit.py +0 -0
  86. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/pfx/pfxcore/views/parameters/subset_offset.py +0 -0
  87. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/pfx/pfxcore/views/parameters/subset_page.py +0 -0
  88. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/pfx/pfxcore/views/parameters/subset_page_size.py +0 -0
  89. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/pfx/pfxcore/views/parameters/subset_page_subset.py +0 -0
  90. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/pfx/pfxcore/views/rest_views.py +0 -0
  91. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/pyproject.toml +0 -0
  92. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/requirements.txt +0 -0
  93. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/runtest.py +0 -0
  94. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/setup.cfg +0 -0
  95. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/setup.py +0 -0
  96. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/tests/__init__.py +0 -0
  97. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/tests/models.py +0 -0
  98. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/tests/settings/__init__.py +0 -0
  99. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/tests/settings/ci.py +0 -0
  100. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/tests/settings/common.py +0 -0
  101. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/tests/settings/dev.py +0 -0
  102. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/tests/settings/dev_custom_example.py +0 -0
  103. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/tests/settings/dev_default.py +0 -0
  104. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/tests/tests/__init__.py +0 -0
  105. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/tests/tests/basic_api_errors.py +0 -0
  106. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/tests/tests/basic_api_test.py +0 -0
  107. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/tests/tests/test_api_doc.py +0 -0
  108. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/tests/tests/test_auth_api.py +0 -0
  109. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/tests/tests/test_cache.py +0 -0
  110. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/tests/tests/test_fields.py +0 -0
  111. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/tests/tests/test_filters.py +0 -0
  112. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/tests/tests/test_locale_api.py +0 -0
  113. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/tests/tests/test_perm_tests.py +0 -0
  114. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/tests/tests/test_perms_api.py +0 -0
  115. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/tests/tests/test_shortcuts.py +0 -0
  116. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/tests/tests/test_timezone_middleware.py +0 -0
  117. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/tests/tests/test_tools.py +0 -0
  118. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/tests/tests/test_user_queryset.py +0 -0
  119. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/tests/tests/test_view_decorators.py +0 -0
  120. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/tests/tests/test_view_fields.py +0 -0
  121. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/tests/urls.py +0 -0
  122. {django-pfx-1.2.dev97 → django-pfx-1.2.dev101}/tests/views.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: django-pfx
3
- Version: 1.2.dev97
3
+ Version: 1.2.dev101
4
4
  Summary: Django PFX is a toolkit to build web APIs dedicated to be used by React progressive web app.
5
5
  Author: Hervé Martinet
6
6
  Author-email: herve.martinet@gmail.com
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: django-pfx
3
- Version: 1.2.dev97
3
+ Version: 1.2.dev101
4
4
  Summary: Django PFX is a toolkit to build web APIs dedicated to be used by React progressive web app.
5
5
  Author: Hervé Martinet
6
6
  Author-email: herve.martinet@gmail.com
@@ -17,6 +17,7 @@ django_pfx.egg-info/top_level.txt
17
17
  doc/Makefile
18
18
  doc/conf.py
19
19
  doc/index.rst
20
+ doc/source/api.views.rst
20
21
  doc/source/authentication.md
21
22
  doc/source/cookbook.md
22
23
  doc/source/decorator.md
@@ -24,7 +25,6 @@ doc/source/getting_started.md
24
25
  doc/source/internationalisation.md
25
26
  doc/source/model.md
26
27
  doc/source/pfx_views.md
27
- doc/source/pfxcore.views.rst
28
28
  doc/source/testing.md
29
29
  img/pfx.png
30
30
  img/pfx.svg
@@ -16,6 +16,8 @@ import sys
16
16
  import django
17
17
  from django.conf import settings
18
18
 
19
+ from sphinx.ext.autodoc import between
20
+
19
21
  sys.path.insert(0, os.path.abspath('../'))
20
22
  settings.configure(
21
23
  SECRET_KEY='something to make Django happy',
@@ -26,8 +28,16 @@ settings.configure(
26
28
  'pfx.pfxcore'])
27
29
  django.setup()
28
30
 
29
- # -- Project information -----------------------------------------------------
30
31
 
32
+ def setup(app):
33
+ # Register a sphinx.ext.autodoc.between listener to ignore everything
34
+ # between lines that contain --- and """ (yaml from apispec)
35
+ app.connect('autodoc-process-docstring',
36
+ between('^.*(---|""")$', exclude=True))
37
+ return app
38
+
39
+
40
+ # -- Project information -----------------------------------------------------
31
41
  project = 'Django PFX'
32
42
  copyright = '2021, Hervé Martinet, Nicolas Béraneck'
33
43
  author = 'Hervé Martinet, Nicolas Béraneck'
@@ -24,12 +24,12 @@ Topics
24
24
  source/getting_started
25
25
  source/decorator
26
26
  source/pfx_views
27
- source/pfxcore.views
28
27
  source/model
29
28
  source/internationalisation
30
29
  source/authentication
31
30
  source/cookbook
32
31
  source/testing
32
+ source/api.views
33
33
 
34
34
  Indices and tables
35
35
  ==================
@@ -1,4 +1,4 @@
1
- Django PFX views
1
+ API
2
2
  =====================
3
3
 
4
4
  The ``DetailRestViewMixin`` class
@@ -10,6 +10,20 @@ The ``DetailRestViewMixin`` class
10
10
 
11
11
  .. :inherited-members:
12
12
 
13
+ The ``LocaleMiddleware`` class
14
+ *********************************
15
+ .. autoclass:: pfx.pfxcore.middleware.LocaleMiddleware
16
+ :members:
17
+ :undoc-members:
18
+ :show-inheritance:
19
+
20
+ The ``LocaleRestView`` class
21
+ *********************************
22
+ .. autoclass:: pfx.pfxcore.views.LocaleRestView
23
+ :members:
24
+ :undoc-members:
25
+ :show-inheritance:
26
+
13
27
  The ``ModelMixin`` class
14
28
  *********************************
15
29
  .. autoclass:: pfx.pfxcore.views.ModelMixin
@@ -0,0 +1,41 @@
1
+ # Internationalisation
2
+
3
+ ## Translated strings
4
+
5
+ Use Django's standard way of translating strings (verbose name, choices values, messages, ...).
6
+ PFX will use the translated values according to the requested language.
7
+
8
+ ## Specify available languages
9
+
10
+ In Django, `USE_I18N` must be `True` to use internationalization. Use `LANGUAGE_CODE` to set default locale.
11
+
12
+ You can optionally set `USE_L10N` to `True` (see Django documentation).
13
+
14
+ In Addition, you can set the list of available languages for web services with `LANGUAGES`:
15
+ ```
16
+ LANGUAGES = [
17
+ ('fr', "French"),
18
+ ('en', "English"),
19
+ ]
20
+ ```
21
+
22
+ You can use language only code of language and country.
23
+
24
+ Service responses will use the first language of `Accept-Language` present in `LANGUAGES`.
25
+ Use `X-Custom-Language` to force the use of a specific language.
26
+
27
+ ## LocaleRestView
28
+
29
+ The `LocaleRestView` exposes a service on `/locales/languages` which returns the list of
30
+ available languages.
31
+
32
+ ## LocaleMiddleware
33
+
34
+ To enable internationalization in services, you have to add `'pfx.pfxcore.middleware.LocaleMiddleware'`
35
+ in the `MIDDLEWARE` list.
36
+
37
+ This middleware will use:
38
+ * `LANGUAGES`, `LANGUAGE_CODE`, `Accept-Language` and `X-Custom-Language` to set the language.
39
+ * `TIME_ZONE` and `X-Custom-Timezone` sot set the timezone.
40
+
41
+ You can replace it by a custom middleware if you need another specific behavior.
@@ -18,12 +18,12 @@ so that each request header contains
18
18
  the HTTP_X_CUSTOM_LANGUAGE attribute with the locale.
19
19
 
20
20
  Example :
21
- ```
21
+ ```python
22
22
  client = APIClient(default_locale='en_GB')
23
23
  ```
24
24
  Each request to a service can also override the locale.
25
25
  Example :
26
- ```
26
+ ```python
27
27
  client = APIClient()
28
28
  response = client.get('/api/authors', locale='fr_CH')
29
29
  ```
@@ -33,7 +33,7 @@ response = client.get('/api/authors', locale='fr_CH')
33
33
  Send a get request.
34
34
 
35
35
  Example :
36
- ```
36
+ ```python
37
37
  client = APIClient()
38
38
  response = client.get('/api/authors')
39
39
  ```
@@ -42,7 +42,7 @@ response = client.get('/api/authors')
42
42
  Send a post request with content type 'application/json'.
43
43
 
44
44
  Example :
45
- ```
45
+ ```python
46
46
  client = APIClient()
47
47
  response = client.post(
48
48
  '/api/authors', {
@@ -54,7 +54,7 @@ response = client.post(
54
54
  Send a put request with content type 'application/json'.
55
55
 
56
56
  Example :
57
- ```
57
+ ```python
58
58
  client = APIClient()
59
59
  response = self.client.put(
60
60
  f'/api/authors/{author_pk}',
@@ -67,13 +67,12 @@ response = self.client.put(
67
67
  Send a delete request with content type 'application/json'.
68
68
 
69
69
  Example :
70
- ```
70
+ ```python
71
71
  client = APIClient()
72
72
  response = client.delete(
73
73
  f'/api/authors/{author_pk}')
74
74
  ```
75
75
 
76
-
77
76
  ### Login
78
77
  If you use PFX authentication views you can use this login method.
79
78
 
@@ -81,7 +80,7 @@ Once you called login, you can call any other method
81
80
  listed above, the authentication token will be sent with the requests.
82
81
 
83
82
  Example :
84
- ```
83
+ ```python
85
84
  client = APIClient()
86
85
  client.login(
87
86
  username='jrr.tolkien',
@@ -98,7 +97,7 @@ Test the response code of a response.
98
97
  It takes two parameters, the response and the expected status code.
99
98
 
100
99
  Example :
101
- ```
100
+ ```python
102
101
  class ATestClass(TestAssertMixin, TransactionTestCase):
103
102
 
104
103
  def a_test(self):
@@ -110,12 +109,12 @@ class ATestClass(TestAssertMixin, TransactionTestCase):
110
109
  self.assertRC(response, 200)
111
110
  ```
112
111
 
113
- ### assertJE
114
- Test the value of a json property in the json_content of the response.
115
- It takes 3 parameters, the response, the key and the expected value.
116
- It allows you to specify the path to reach an element in the json structure.
112
+ ### get_val
113
+
114
+ Get a value for a python dictionary or a json HTTP response by a string path key.
115
+ The src parameter can be a Python dictionary or an object with `json_content` attribute.
117
116
  For instance if you have a response like
118
- ```
117
+ ```python
119
118
  {
120
119
  "author": {
121
120
  "pk": 2,
@@ -125,32 +124,58 @@ For instance if you have a response like
125
124
  "pk": 6,
126
125
  }
127
126
  ```
128
- you can reach the author pk by providing "author.pk" as the key.
127
+ you can reach the author pk by providing `"author.pk"` as the key.
129
128
 
130
- AssertJE also allows to specify the index in an array.
131
- The syntax is "@index".
129
+ get_val also allows to specify the index in an array.
130
+ The syntax is `"@index"`.
132
131
 
133
132
  For instance if you want the pk of the author of the
134
- third item in an array of books you can specify "items.@3.author.pk"
133
+ third item in an array of books you can specify `"items.@3.author.pk"`
135
134
 
136
135
  Example :
136
+ ```python
137
+ class ATestClass(TestAssertMixin, TransactionTestCase):
138
+
139
+ def a_test(self):
140
+ client = APIClient()
141
+ response = client.get('/api/books')
142
+ author_pk = self.get_val(response, 'items.@3.author.pk')
137
143
  ```
144
+
145
+ ### assertJE
146
+ Test the value of a dictionary property (using `get_val`).
147
+ It takes 3 parameters, the source, the key and the expected value.
148
+
149
+ Example :
150
+ ```python
138
151
  class ATestClass(TestAssertMixin, TransactionTestCase):
139
152
 
140
153
  def a_test(self):
141
154
  client = APIClient()
142
155
  response = client.get('/api/books')
143
- self.assertJE(response, 'items.@3.author.pk', 6)
156
+ author_pk = self.assertJE(response, 'items.@3.author.pk', 6)
144
157
  ```
145
158
 
146
159
  ### assertNJE
147
- Assert NJE is the same as AssertJE, but it tests that the value is not equal.
160
+ `AssertNJE` is the same as `AssertJE`, but it tests that the value is not equal.
161
+
162
+ ### assertJEExists
163
+ Assert the path exists in the source.
164
+
165
+ ### assertJENotExists
166
+ Assert the path does not exists in the source.
167
+
168
+ ### assertSize
169
+ Test the size of a value (if the value is a collection).
170
+
171
+ ### assertJIn
172
+ Test that an element is part of a collection value.
148
173
 
149
174
  ## Print Response
150
175
  You can use the print_response helper to print a response in the console.
151
176
 
152
177
  Example :
153
- ```
178
+ ```python
154
179
  client = APIClient()
155
180
  response = client.get('/api/books')
156
181
  print_response(response)
@@ -158,7 +183,7 @@ print_response(response)
158
183
 
159
184
  will produce
160
185
 
161
- ```
186
+ ```plain
162
187
  *********************http response*********************
163
188
  Status : 200 OK
164
189
  Headers :
@@ -186,3 +211,54 @@ Content :
186
211
  }
187
212
  *******************************************************
188
213
  ```
214
+
215
+ ## PermsAPITest
216
+
217
+ This test class can be used to test permissions on services with multiple users.
218
+
219
+ Create multiple users in `setUpTestData` and add a method for each service
220
+ you want to test.
221
+
222
+ You can test the response status code or the response list count for items list responses.
223
+
224
+ Example :
225
+ ```python
226
+ class BookPermsAPITest(PermsAPITest):
227
+ def setUp(self):
228
+ self.client = APIClient(with_cookie=True)
229
+
230
+ @classmethod
231
+ def setUpTestData(cls):
232
+ # Create your users here
233
+
234
+ def list(self):
235
+ # Create a book
236
+ return self.client.get('/api/books?items=1&count=1')
237
+
238
+ def get(self):
239
+ # book = … (create a book)
240
+ return self.client.get(f'/api/books/{book.pk}')
241
+
242
+ def post(self):
243
+ return self.client.post('/api/books', dict(
244
+ name="Test new"))
245
+
246
+ def put(self):
247
+ return self.client.put(
248
+ f'/api/books/{self.organization.pk}', dict(
249
+ name="Updated"))
250
+
251
+ def delete(self):
252
+ # book = … (create a book)
253
+ return self.client.delete(f'/api/books/{book.pk}')
254
+
255
+ USER_TESTS = {
256
+ "admin@user.org": dict(
257
+ list=200, list__count=1, get=200
258
+ post=200, put=200, delete=200),
259
+ "user@user.org": dict(
260
+ list=200, list__count=1, get=200,
261
+ post=403, put=403, delete=403),
262
+ }
263
+
264
+ ```
@@ -1,5 +0,0 @@
1
- # Internationalisation
2
-
3
- - parameters
4
- - LocaleMiddleware
5
- - LocaleRestView
File without changes
File without changes