django-pfx 1.2.dev97__tar.gz → 1.2.dev99__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 (121) hide show
  1. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/PKG-INFO +1 -1
  2. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/django_pfx.egg-info/PKG-INFO +1 -1
  3. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/doc/source/testing.md +98 -22
  4. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/.gitignore +0 -0
  5. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/.gitlab-ci.yml +0 -0
  6. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/.pre-commit-config.yaml +0 -0
  7. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/LICENSE +0 -0
  8. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/MANIFEST.in +0 -0
  9. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/README.md +0 -0
  10. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/django_pfx.egg-info/SOURCES.txt +0 -0
  11. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/django_pfx.egg-info/dependency_links.txt +0 -0
  12. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/django_pfx.egg-info/requires.txt +0 -0
  13. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/django_pfx.egg-info/top_level.txt +0 -0
  14. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/doc/Makefile +0 -0
  15. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/doc/conf.py +0 -0
  16. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/doc/index.rst +0 -0
  17. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/doc/source/authentication.md +0 -0
  18. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/doc/source/cookbook.md +0 -0
  19. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/doc/source/decorator.md +0 -0
  20. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/doc/source/getting_started.md +0 -0
  21. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/doc/source/internationalisation.md +0 -0
  22. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/doc/source/model.md +0 -0
  23. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/doc/source/pfx_views.md +0 -0
  24. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/doc/source/pfxcore.views.rst +0 -0
  25. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/img/pfx.png +0 -0
  26. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/img/pfx.svg +0 -0
  27. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/pfx/__init__.py +0 -0
  28. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/pfx/pfxcore/__init__.py +0 -0
  29. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/pfx/pfxcore/apidoc/__init__.py +0 -0
  30. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/pfx/pfxcore/apidoc/parameters.py +0 -0
  31. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/pfx/pfxcore/apidoc/schema.py +0 -0
  32. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/pfx/pfxcore/apidoc/tags.py +0 -0
  33. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/pfx/pfxcore/apps.py +0 -0
  34. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/pfx/pfxcore/decorator/__init__.py +0 -0
  35. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/pfx/pfxcore/decorator/rest.py +0 -0
  36. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/pfx/pfxcore/default_settings.py +0 -0
  37. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/pfx/pfxcore/exceptions.py +0 -0
  38. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/pfx/pfxcore/fields.py +0 -0
  39. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/pfx/pfxcore/http/__init__.py +0 -0
  40. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/pfx/pfxcore/http/json_response.py +0 -0
  41. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/pfx/pfxcore/locale/fr/LC_MESSAGES/django.mo +0 -0
  42. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/pfx/pfxcore/locale/fr/LC_MESSAGES/django.po +0 -0
  43. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/pfx/pfxcore/management/__init__.py +0 -0
  44. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/pfx/pfxcore/management/commands/__init__.py +0 -0
  45. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/pfx/pfxcore/management/commands/makeapidoc.py +0 -0
  46. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/pfx/pfxcore/middleware/__init__.py +0 -0
  47. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/pfx/pfxcore/middleware/authentication.py +0 -0
  48. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/pfx/pfxcore/middleware/locale.py +0 -0
  49. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/pfx/pfxcore/models/__init__.py +0 -0
  50. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/pfx/pfxcore/models/cache_mixins.py +0 -0
  51. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/pfx/pfxcore/models/not_null_fields.py +0 -0
  52. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/pfx/pfxcore/models/pfx_models.py +0 -0
  53. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/pfx/pfxcore/models/user_filtered_queryset_mixin.py +0 -0
  54. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/pfx/pfxcore/serializers/__init__.py +0 -0
  55. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/pfx/pfxcore/serializers/json.py +0 -0
  56. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/pfx/pfxcore/settings.py +0 -0
  57. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/pfx/pfxcore/shortcuts.py +0 -0
  58. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/pfx/pfxcore/storage/__init__.py +0 -0
  59. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/pfx/pfxcore/storage/s3_storage.py +0 -0
  60. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/pfx/pfxcore/templates/registration/password_reset_email.txt +0 -0
  61. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/pfx/pfxcore/templates/registration/password_reset_subject.txt +0 -0
  62. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/pfx/pfxcore/templates/registration/welcome_email.txt +0 -0
  63. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/pfx/pfxcore/templates/registration/welcome_subject.txt +0 -0
  64. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/pfx/pfxcore/test.py +0 -0
  65. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/pfx/pfxcore/urls.py +0 -0
  66. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/pfx/pfxcore/views/__init__.py +0 -0
  67. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/pfx/pfxcore/views/authentication_views.py +0 -0
  68. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/pfx/pfxcore/views/fields.py +0 -0
  69. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/pfx/pfxcore/views/filters_views.py +0 -0
  70. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/pfx/pfxcore/views/locale_views.py +0 -0
  71. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/pfx/pfxcore/views/parameters/__init__.py +0 -0
  72. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/pfx/pfxcore/views/parameters/date_format.py +0 -0
  73. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/pfx/pfxcore/views/parameters/groups.py +0 -0
  74. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/pfx/pfxcore/views/parameters/list_count.py +0 -0
  75. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/pfx/pfxcore/views/parameters/list_items.py +0 -0
  76. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/pfx/pfxcore/views/parameters/list_mode.py +0 -0
  77. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/pfx/pfxcore/views/parameters/list_order.py +0 -0
  78. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/pfx/pfxcore/views/parameters/list_search.py +0 -0
  79. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/pfx/pfxcore/views/parameters/media_redirect.py +0 -0
  80. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/pfx/pfxcore/views/parameters/meta_fields.py +0 -0
  81. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/pfx/pfxcore/views/parameters/meta_filters.py +0 -0
  82. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/pfx/pfxcore/views/parameters/meta_orders.py +0 -0
  83. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/pfx/pfxcore/views/parameters/subset.py +0 -0
  84. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/pfx/pfxcore/views/parameters/subset_limit.py +0 -0
  85. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/pfx/pfxcore/views/parameters/subset_offset.py +0 -0
  86. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/pfx/pfxcore/views/parameters/subset_page.py +0 -0
  87. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/pfx/pfxcore/views/parameters/subset_page_size.py +0 -0
  88. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/pfx/pfxcore/views/parameters/subset_page_subset.py +0 -0
  89. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/pfx/pfxcore/views/rest_views.py +0 -0
  90. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/pyproject.toml +0 -0
  91. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/requirements.txt +0 -0
  92. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/runtest.py +0 -0
  93. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/setup.cfg +0 -0
  94. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/setup.py +0 -0
  95. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/tests/__init__.py +0 -0
  96. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/tests/models.py +0 -0
  97. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/tests/settings/__init__.py +0 -0
  98. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/tests/settings/ci.py +0 -0
  99. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/tests/settings/common.py +0 -0
  100. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/tests/settings/dev.py +0 -0
  101. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/tests/settings/dev_custom_example.py +0 -0
  102. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/tests/settings/dev_default.py +0 -0
  103. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/tests/tests/__init__.py +0 -0
  104. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/tests/tests/basic_api_errors.py +0 -0
  105. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/tests/tests/basic_api_test.py +0 -0
  106. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/tests/tests/test_api_doc.py +0 -0
  107. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/tests/tests/test_auth_api.py +0 -0
  108. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/tests/tests/test_cache.py +0 -0
  109. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/tests/tests/test_fields.py +0 -0
  110. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/tests/tests/test_filters.py +0 -0
  111. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/tests/tests/test_locale_api.py +0 -0
  112. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/tests/tests/test_perm_tests.py +0 -0
  113. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/tests/tests/test_perms_api.py +0 -0
  114. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/tests/tests/test_shortcuts.py +0 -0
  115. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/tests/tests/test_timezone_middleware.py +0 -0
  116. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/tests/tests/test_tools.py +0 -0
  117. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/tests/tests/test_user_queryset.py +0 -0
  118. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/tests/tests/test_view_decorators.py +0 -0
  119. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/tests/tests/test_view_fields.py +0 -0
  120. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/tests/urls.py +0 -0
  121. {django-pfx-1.2.dev97 → django-pfx-1.2.dev99}/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.dev99
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.dev99
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
@@ -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
+ ```
File without changes
File without changes
File without changes
File without changes