django-esi 5.3.0b1__py3-none-any.whl → 6.0.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.

Potentially problematic release.


This version of django-esi might be problematic. Click here for more details.

@@ -1,22 +1,20 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: django-esi
3
- Version: 5.3.0b1
3
+ Version: 6.0.0
4
4
  Summary: Django app for accessing the EVE Swagger Interface (ESI).
5
5
  Author-email: Alliance Auth <adarnof@gmail.com>
6
6
  Requires-Python: >=3.8
7
7
  Description-Content-Type: text/markdown
8
8
  Classifier: Environment :: Web Environment
9
9
  Classifier: Framework :: Django
10
- Classifier: Framework :: Django :: 3.2
11
- Classifier: Framework :: Django :: 4.0
12
- Classifier: Framework :: Django :: 4.1
13
10
  Classifier: Framework :: Django :: 4.2
14
11
  Classifier: Framework :: Django :: 5.0
12
+ Classifier: Framework :: Django :: 5.1
15
13
  Classifier: Intended Audience :: Developers
16
14
  Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
17
15
  Classifier: Operating System :: OS Independent
18
16
  Classifier: Programming Language :: Python
19
- Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3 :: Only
20
18
  Classifier: Programming Language :: Python :: 3.8
21
19
  Classifier: Programming Language :: Python :: 3.9
22
20
  Classifier: Programming Language :: Python :: 3.10
@@ -24,21 +22,30 @@ Classifier: Programming Language :: Python :: 3.11
24
22
  Classifier: Programming Language :: Python :: 3.12
25
23
  Classifier: Topic :: Internet :: WWW/HTTP
26
24
  Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
27
- Requires-Dist: bravado>=10.6.0,<11.0
25
+ Requires-Dist: bravado>=10.6,<11
26
+ Requires-Dist: brotli
28
27
  Requires-Dist: celery>=4.0.2
29
- Requires-Dist: django>=2.2,<5.1
30
- Requires-Dist: jsonschema<4.0.0
31
- Requires-Dist: python-jose>=3.3.0
32
- Requires-Dist: requests>=2.26.0
33
- Requires-Dist: requests_oauthlib>=0.8.0
28
+ Requires-Dist: django>=4.2,<5.2
29
+ Requires-Dist: jsonschema<4
30
+ Requires-Dist: python-jose>=3.3
31
+ Requires-Dist: requests>=2.26
32
+ Requires-Dist: requests-oauthlib>=0.8
34
33
  Requires-Dist: tqdm>=4.62.3
35
- Requires-Dist: brotli
36
- Requires-Dist: sphinx ; extra == "docs"
37
34
  Requires-Dist: myst-parser ; extra == "docs"
38
- Requires-Dist: sphinx_rtd_theme ; extra == "docs"
39
- Requires-Dist: sphinxcontrib-django2 ; extra == "docs"
35
+ Requires-Dist: sphinx ; extra == "docs"
36
+ Requires-Dist: sphinx-copybutton ; extra == "docs"
37
+ Requires-Dist: sphinx-rtd-theme<3,>=2 ; extra == "docs"
38
+ Requires-Dist: sphinx-tabs ; extra == "docs"
39
+ Requires-Dist: sphinxcontrib-django ; extra == "docs"
40
+ Requires-Dist: coverage ; extra == "test"
41
+ Requires-Dist: factory-boy ; extra == "test"
42
+ Requires-Dist: requests-mock ; extra == "test"
43
+ Project-URL: Documentation, https://django-esi.readthedocs.io/en/latest/
40
44
  Project-URL: Homepage, https://gitlab.com/allianceauth/django-esi
45
+ Project-URL: Source, https://gitlab.com/allianceauth/django-esi
46
+ Project-URL: Tracker, https://gitlab.com/allianceauth/django-esi/-/issues
41
47
  Provides-Extra: docs
48
+ Provides-Extra: test
42
49
 
43
50
  # django-esi
44
51
 
@@ -1,15 +1,15 @@
1
- esi/__init__.py,sha256=e2a8pk9JZ2i5PGZ9dauTYBgJCKnI8w7ldFspjYDhS30,157
2
- esi/admin.py,sha256=vfpTW1WOLmAxQKAAW8d_Nrkn1MvVRO9raQrHGXpW2l4,1100
1
+ esi/__init__.py,sha256=NtkIRztRvZcWgRF9JOeRXIdygDh6Yy5at20njzh1b5g,113
2
+ esi/admin.py,sha256=Cr9cMMS9WA64-OqVcw-jpes1hTnMnqrhK9eyfz6QwC4,1111
3
3
  esi/app_settings.py,sha256=O8TkKonK2zdF7RjMem1vMhEMulAtjvksxKgchrI8jME,3783
4
4
  esi/apps.py,sha256=RXDeRh62DO8NcKEzpiQovOay9wmb7MoVyC1W-cc-Aqc,272
5
5
  esi/checks.py,sha256=o3ka-Ux3QqTaf0u-oFGCPxwuG7DNJ3XYXiC7_2rQ1Ic,1154
6
6
  esi/clients.py,sha256=gkkJVZ9xqcd0TOI-5VduqYLaave1LjI16ucckr3UX9o,21303
7
7
  esi/decorators.py,sha256=USqGaIrVoyMpKlUB_ddZPe7QK0fBrFqAnoZDj8MMlSI,8081
8
8
  esi/errors.py,sha256=KfFtgX8Mys4uMoQtco0n_pQeaM83yVrRSyW6StXuUjo,308
9
- esi/managers.py,sha256=VEob7SGDq1AMn8i8Rw5zLQrHSmi_rHN9KNHq2nA-mgo,11455
9
+ esi/managers.py,sha256=0g3J2jgoX-BviisjDEEAypkTayVBY-G2I_ZuskTDUqg,11350
10
10
  esi/models.py,sha256=fJJu8rLDMGW3ChxwFAZtFBWKB7PgMuDBatTuT06gWiA,11412
11
11
  esi/tasks.py,sha256=6wOqlANbQ83uvOt0L4_QHaLz0YZe1jtrQyr7zmxKY6g,1516
12
- esi/urls.py,sha256=RV_ZirfB3oEElPGXfj33m6FqwVdFRADDW9bN1WwJU2E,161
12
+ esi/urls.py,sha256=23dY6ciekJ5wfwzo5LzLp0LFvWudrEAGICpDrscTeD8,152
13
13
  esi/views.py,sha256=ytfCILjz1rzITGgAGPyCY9bkFpE3KUfnii2UpHu6Bmc,3916
14
14
  esi/locale/de/LC_MESSAGES/django.mo,sha256=9_Fc_R8oZpT_CojH8gBxdSqj2K84EMEMn4wkvmOr7Dg,820
15
15
  esi/locale/de/LC_MESSAGES/django.po,sha256=2NQVGYzLroHPPrWgmACSnb2d3nwlkMBLxA1uWU3K0FA,1503
@@ -61,7 +61,7 @@ esi/tests/test_checks.py,sha256=ntq2ijuJ-6pxGruNh21rM4GlXDLVm-o3sy8DrFbjwEM,1846
61
61
  esi/tests/test_clients.py,sha256=eaB0DniNrpaQiAQGokLMmcwWYq0H1iswz3fdKvuf3E4,36037
62
62
  esi/tests/test_decorators.py,sha256=I5MhcLKhN5xD4PxgEQqOWQ2kiXquDqQIEve9dbTOsho,15069
63
63
  esi/tests/test_management_command.py,sha256=mtxfBtG6CHP1bTy1tJEO-djX4SQwMT3T_mqGnUIM6qs,9863
64
- esi/tests/test_managers.py,sha256=V9KAnVnyXk2oHyy26aVm5FN5UTSG6Y63fU3FSGt7IHE,24548
64
+ esi/tests/test_managers.py,sha256=CEpjXSXyVY6xxgrs0f9FnEh-KY9JPaKjKYiutXLLShE,24309
65
65
  esi/tests/test_models.py,sha256=lDj5IcYgXHeOFTHXTsWGg13CSooFaxD0c51kJn_ytAc,13748
66
66
  esi/tests/test_swagger.json,sha256=HOrPgbvwm5N521QNcE3baWcZJkSjmuN_VWrR06wEQoo,17241
67
67
  esi/tests/test_swagger_full.json,sha256=JCEAZNMFhkdZhquTx4lDhrqGgCrzzzlYU64HdbEv8E4,2548369
@@ -69,7 +69,7 @@ esi/tests/test_tasks.py,sha256=P3vtqSno92DywNYu38nIo-_UiSicRAbun1AAsav0EBo,2104
69
69
  esi/tests/test_templatetags.py,sha256=b68JWE3HvOlr2aUisJHsTsDS4e7IMjDeqTuzMqC7Re4,517
70
70
  esi/tests/test_views.py,sha256=Kj_f2yIpmPG0kx-lAX_sfkaHlIpgbkm02ieA1V3o-k4,13073
71
71
  esi/tests/threading_pilot.py,sha256=ax_dEdnTNibA-UQHqbZle_2dh_3jcHKRyrYSOKuE_6U,1931
72
- django_esi-5.3.0b1.dist-info/LICENSE,sha256=WJ7YI-moTFb-uVrFjnzzhGJrnL9P2iqQe8NuED3hutI,35141
73
- django_esi-5.3.0b1.dist-info/WHEEL,sha256=EZbGkh7Ie4PoZfRQ8I0ZuP9VklN_TvcZ6DSE5Uar4z4,81
74
- django_esi-5.3.0b1.dist-info/METADATA,sha256=jgQw9_H0egqTGExUm43ipgEKgVcv4w_tHt7e5zWvVY4,4275
75
- django_esi-5.3.0b1.dist-info/RECORD,,
72
+ django_esi-6.0.0.dist-info/LICENSE,sha256=WJ7YI-moTFb-uVrFjnzzhGJrnL9P2iqQe8NuED3hutI,35141
73
+ django_esi-6.0.0.dist-info/WHEEL,sha256=EZbGkh7Ie4PoZfRQ8I0ZuP9VklN_TvcZ6DSE5Uar4z4,81
74
+ django_esi-6.0.0.dist-info/METADATA,sha256=0WMNumAVhCwNIO4tWXLmV3RU6ovU1VHRKmbhTlfOGhk,4656
75
+ django_esi-6.0.0.dist-info/RECORD,,
esi/__init__.py CHANGED
@@ -1,6 +1,5 @@
1
1
  """Django app for accessing the EVE Swagger Interface (ESI)."""
2
2
 
3
- default_app_config = 'esi.apps.EsiConfig'
4
3
 
5
- __version__ = '5.3.0b1'
4
+ __version__ = '6.0.0'
6
5
  __title__ = 'django-esi'
esi/admin.py CHANGED
@@ -17,10 +17,12 @@ class TokenAdmin(admin.ModelAdmin):
17
17
  qs = super().get_queryset(request)
18
18
  return qs.select_related('user').prefetch_related('scopes')
19
19
 
20
+ @admin.display(
21
+ description='Scopes'
22
+ )
20
23
  def get_scopes(self, obj):
21
24
  return ", ".join([x.name for x in obj.scopes.all()])
22
25
 
23
- get_scopes.short_description = 'Scopes'
24
26
 
25
27
  User = get_user_model()
26
28
  list_display = ('user', 'character_name', 'get_scopes')
esi/managers.py CHANGED
@@ -1,18 +1,16 @@
1
- from datetime import timedelta
2
1
  import logging
3
- from typing import Union, Any
2
+ from datetime import timedelta
3
+ from typing import Any, Union
4
4
 
5
5
  import requests
6
- from requests_oauthlib import OAuth2Session
7
-
8
6
  from django.db import models
9
7
  from django.utils import timezone
10
-
11
- from .errors import TokenError, IncompleteResponseError
12
- from . import app_settings
13
-
14
8
  from jose import jwt
15
9
  from jose.exceptions import ExpiredSignatureError, JWTError
10
+ from requests_oauthlib import OAuth2Session
11
+
12
+ from . import app_settings
13
+ from .errors import IncompleteResponseError, TokenError
16
14
 
17
15
  logger = logging.getLogger(__name__)
18
16
 
@@ -75,26 +73,12 @@ class TokenQueryset(models.QuerySet):
75
73
  Returns:
76
74
  All tokens which are still valid.
77
75
  """
78
- expired = self.get_expired()
79
- valid = list(
80
- self.exclude(
81
- pk__in=expired
82
- ).values_list(
83
- "pk",
84
- flat=True
85
- )
86
- )
87
- valid_expired = list(
88
- expired.bulk_refresh(
89
- ).values_list(
90
- "pk",
91
- flat=True
92
- )
93
- )
94
- _qs = self.filter(
95
- pk__in=(valid + valid_expired)
96
- )
97
- return _qs
76
+ expired_pks = set(self.get_expired().values_list("pk", flat=True))
77
+ fresh_pks = set(self.exclude(pk__in=expired_pks).values_list("pk", flat=True))
78
+ refreshed = self.filter(pk__in=expired_pks).bulk_refresh()
79
+ refreshed_pks = set(refreshed.values_list("pk", flat=True))
80
+ qs = self.filter(pk__in=fresh_pks | refreshed_pks)
81
+ return qs
98
82
 
99
83
  def require_scopes(self, scope_string: Union[str, list]) -> models.QuerySet:
100
84
  """Filter tokens which have at least a subset of given scopes.
@@ -16,74 +16,49 @@ from .jwt_factory import generate_jwk, generate_token
16
16
 
17
17
 
18
18
  class TestProcessScopes(TestCase):
19
-
20
19
  def test_none(self):
21
- self.assertSetEqual(
22
- _process_scopes(None), set()
23
- )
20
+ self.assertSetEqual(_process_scopes(None), set())
24
21
 
25
22
  def test_empty_list(self):
26
- self.assertSetEqual(
27
- _process_scopes([]), set()
28
- )
23
+ self.assertSetEqual(_process_scopes([]), set())
29
24
 
30
25
  def test_single_string_1(self):
31
- self.assertSetEqual(
32
- _process_scopes(['one']),
33
- {'one'}
34
- )
26
+ self.assertSetEqual(_process_scopes(["one"]), {"one"})
35
27
 
36
28
  def test_single_string_2(self):
37
- self.assertSetEqual(
38
- _process_scopes(['one two three']),
39
- {'one', 'two', 'three'}
40
- )
29
+ self.assertSetEqual(_process_scopes(["one two three"]), {"one", "two", "three"})
41
30
 
42
31
  def test_list(self):
43
32
  self.assertSetEqual(
44
- _process_scopes(['one', 'two', 'three']),
45
- {'one', 'two', 'three'}
33
+ _process_scopes(["one", "two", "three"]), {"one", "two", "three"}
46
34
  )
47
35
 
48
36
  def test_tuple(self):
49
37
  self.assertSetEqual(
50
- _process_scopes(('one', 'two', 'three')),
51
- {'one', 'two', 'three'}
38
+ _process_scopes(("one", "two", "three")), {"one", "two", "three"}
52
39
  )
53
40
 
54
41
 
55
- class TestTokenQuerySet(TestCase):
56
-
57
- def setUp(self):
42
+ class TestTokenGetExpired(TestCase):
43
+ @patch("esi.models.app_settings.ESI_TOKEN_VALID_DURATION", 120)
44
+ def test_get_expired(self):
58
45
  self.user1 = User.objects.create_user(
59
- 'Bruce Wayne',
60
- 'abc@example.com',
61
- 'password'
46
+ "Bruce Wayne", "abc@example.com", "password"
62
47
  )
63
48
  self.user2 = User.objects.create_user(
64
- 'Peter Parker',
65
- 'abc@example.com',
66
- 'password'
49
+ "Peter Parker", "abc@example.com", "password"
67
50
  )
68
- Token.objects.all().delete()
69
-
70
- @patch('esi.models.app_settings.ESI_TOKEN_VALID_DURATION', 120)
71
- def test_get_expired(self):
72
51
  _store_as_Token(
73
52
  _generate_token(
74
- character_id=101,
75
- character_name=self.user1.username,
76
- scopes=['abc']
53
+ character_id=101, character_name=self.user1.username, scopes=["abc"]
77
54
  ),
78
- self.user1
55
+ self.user1,
79
56
  )
80
57
  t2 = _store_as_Token(
81
58
  _generate_token(
82
- character_id=102,
83
- character_name=self.user2.username,
84
- scopes=['xyz']
59
+ character_id=102, character_name=self.user2.username, scopes=["xyz"]
85
60
  ),
86
- self.user2
61
+ self.user2,
87
62
  )
88
63
  self.assertEqual(list(Token.objects.get_queryset().get_expired()), [])
89
64
 
@@ -91,44 +66,46 @@ class TestTokenQuerySet(TestCase):
91
66
  t2.save()
92
67
  self.assertEqual(list(Token.objects.get_queryset().get_expired()), [t2])
93
68
 
94
- @patch('esi.managers.app_settings.ESI_SSO_CLIENT_ID', 'abc')
95
- @patch('esi.managers.app_settings.ESI_SSO_CLIENT_SECRET', 'xyz')
96
- @patch('esi.models.Token.delete', autospec=True)
97
- @patch('esi.models.Token.refresh', autospec=True)
98
- @patch('esi.managers.requests.auth.HTTPBasicAuth', autospec=True)
99
- @patch('esi.managers.OAuth2Session', autospec=True)
69
+
70
+ @patch("esi.managers.app_settings.ESI_SSO_CLIENT_ID", "abc")
71
+ @patch("esi.managers.app_settings.ESI_SSO_CLIENT_SECRET", "xyz")
72
+ @patch("esi.models.Token.delete", autospec=True)
73
+ @patch("esi.models.Token.refresh", autospec=True)
74
+ @patch("esi.managers.requests.auth.HTTPBasicAuth", autospec=True)
75
+ @patch("esi.managers.OAuth2Session", autospec=True)
76
+ class TestTokenBulkRefresh(TestCase):
77
+ @classmethod
78
+ def setUpClass(cls) -> None:
79
+ super().setUpClass()
80
+ cls.user = User.objects.create_user(
81
+ "Bruce Wayne", "abc@example.com", "password"
82
+ )
83
+
100
84
  def test_bulk_refresh_normal(
101
85
  self,
102
86
  mock_OAuth2Session,
103
87
  mock_HTTPBasicAuth,
104
88
  mock_Token_refresh,
105
- mock_Token_delete
89
+ mock_Token_delete,
106
90
  ):
107
91
  character_id = 99
108
- character_name = 'Bruce Wayne'
92
+ character_name = "Bruce Wayne"
109
93
  t1 = _store_as_Token(
110
94
  _generate_token(
111
- character_id=character_id,
112
- character_name=character_name,
113
- scopes=['abc']
95
+ character_id=character_id, character_name=character_name, scopes=["abc"]
114
96
  ),
115
- self.user1
97
+ self.user,
116
98
  )
117
99
  t2 = _store_as_Token(
118
100
  _generate_token(
119
- character_id=character_id,
120
- character_name=character_name,
121
- scopes=['xyz']
101
+ character_id=character_id, character_name=character_name, scopes=["xyz"]
122
102
  ),
123
- self.user1
103
+ self.user,
124
104
  )
125
105
  incomplete_qs = Token.objects.get_queryset().bulk_refresh()
126
106
  self.assertEqual(mock_Token_refresh.call_count, 2)
127
107
  self.assertEqual(mock_Token_delete.call_count, 0)
128
- self.assertSetEqual(
129
- set(incomplete_qs),
130
- {t1, t2}
131
- )
108
+ self.assertSetEqual(set(incomplete_qs), {t1, t2})
132
109
 
133
110
  # Note
134
111
  # looks like a bug in bulk_refresh():
@@ -136,340 +113,337 @@ class TestTokenQuerySet(TestCase):
136
113
  # can not be null:
137
114
  # self.filter(refresh_token__isnull=True).get_expired().delete()
138
115
 
139
- @patch('esi.managers.app_settings.ESI_SSO_CLIENT_ID', 'abc')
140
- @patch('esi.managers.app_settings.ESI_SSO_CLIENT_SECRET', 'xyz')
141
- @patch('esi.models.Token.delete', autospec=True)
142
- @patch('esi.models.Token.refresh', autospec=True)
143
- @patch('esi.managers.requests.auth.HTTPBasicAuth', autospec=True)
144
- @patch('esi.managers.OAuth2Session', autospec=True)
145
116
  def test_bulk_refresh_token_error(
146
117
  self,
147
118
  mock_OAuth2Session,
148
119
  mock_HTTPBasicAuth,
149
120
  mock_Token_refresh,
150
- mock_Token_delete
121
+ mock_Token_delete,
151
122
  ):
152
123
  mock_Token_refresh.side_effect = TokenError
153
124
 
154
125
  character_id = 99
155
- character_name = 'Bruce Wayne'
126
+ character_name = "Bruce Wayne"
156
127
  t1 = _store_as_Token(
157
128
  _generate_token(
158
- character_id=character_id,
159
- character_name=character_name,
160
- scopes=['abc']
129
+ character_id=character_id, character_name=character_name, scopes=["abc"]
161
130
  ),
162
- self.user1
131
+ self.user,
163
132
  )
164
133
  t2 = _store_as_Token(
165
134
  _generate_token(
166
- character_id=character_id,
167
- character_name=character_name,
168
- scopes=['xyz']
135
+ character_id=character_id, character_name=character_name, scopes=["xyz"]
169
136
  ),
170
- self.user1
137
+ self.user,
171
138
  )
172
139
  incomplete_qs = Token.objects.get_queryset().bulk_refresh()
173
140
  self.assertEqual(mock_Token_refresh.call_count, 2)
174
141
  self.assertEqual(mock_Token_delete.call_count, 2)
175
- self.assertSetEqual(
176
- set(incomplete_qs),
177
- {t1, t2}
178
- )
142
+ self.assertSetEqual(set(incomplete_qs), {t1, t2})
179
143
 
180
- @patch('esi.managers.app_settings.ESI_SSO_CLIENT_ID', 'abc')
181
- @patch('esi.managers.app_settings.ESI_SSO_CLIENT_SECRET', 'xyz')
182
- @patch('esi.models.Token.delete', autospec=True)
183
- @patch('esi.models.Token.refresh', autospec=True)
184
- @patch('esi.managers.requests.auth.HTTPBasicAuth', autospec=True)
185
- @patch('esi.managers.OAuth2Session', autospec=True)
186
144
  def test_bulk_refresh_incomplete_response_error(
187
145
  self,
188
146
  mock_OAuth2Session,
189
147
  mock_HTTPBasicAuth,
190
148
  mock_Token_refresh,
191
- mock_Token_delete
149
+ mock_Token_delete,
192
150
  ):
193
151
  mock_Token_refresh.side_effect = IncompleteResponseError
194
152
 
195
153
  character_id = 99
196
- character_name = 'Bruce Wayne'
154
+ character_name = "Bruce Wayne"
197
155
  _store_as_Token(
198
156
  _generate_token(
199
- character_id=character_id,
200
- character_name=character_name,
201
- scopes=['abc']
157
+ character_id=character_id, character_name=character_name, scopes=["abc"]
202
158
  ),
203
- self.user1
159
+ self.user,
204
160
  )
205
161
  _store_as_Token(
206
162
  _generate_token(
207
- character_id=character_id,
208
- character_name=character_name,
209
- scopes=['xyz']
163
+ character_id=character_id, character_name=character_name, scopes=["xyz"]
210
164
  ),
211
- self.user1
165
+ self.user,
212
166
  )
213
167
  incomplete_qs = Token.objects.get_queryset().bulk_refresh()
214
168
  self.assertEqual(mock_Token_refresh.call_count, 2)
215
169
  self.assertEqual(mock_Token_delete.call_count, 0)
216
- self.assertSetEqual(
217
- set(incomplete_qs),
218
- set()
170
+ self.assertSetEqual(set(incomplete_qs), set())
171
+
172
+
173
+ @patch("esi.models.app_settings.ESI_TOKEN_VALID_DURATION", 120)
174
+ @patch("esi.managers.TokenQueryset.bulk_refresh", autospec=True)
175
+ class TestTokenRequireValid(TestCase):
176
+ @classmethod
177
+ def setUpClass(cls) -> None:
178
+ super().setUpClass()
179
+ cls.user = User.objects.create_user(
180
+ "Bruce Wayne", "abc@example.com", "password"
219
181
  )
220
182
 
221
- @patch('esi.models.app_settings.ESI_TOKEN_VALID_DURATION', 120)
222
- @patch('esi.managers.TokenQueryset.bulk_refresh', autospec=True)
223
- def test_require_valid_none_expired(
224
- self,
225
- mock_bulk_refresh
226
- ):
183
+ def test_require_valid_none_expired(self, mock_bulk_refresh):
227
184
  character_id = 99
228
- character_name = 'Bruce Wayne'
185
+ character_name = "Bruce Wayne"
229
186
  t1 = _store_as_Token(
230
187
  _generate_token(
231
- character_id=character_id,
232
- character_name=character_name,
233
- scopes=['abc']
188
+ character_id=character_id, character_name=character_name, scopes=["abc"]
234
189
  ),
235
- self.user1
190
+ self.user,
236
191
  )
237
192
  t2 = _store_as_Token(
238
193
  _generate_token(
239
- character_id=character_id,
240
- character_name=character_name,
241
- scopes=['xyz']
194
+ character_id=character_id, character_name=character_name, scopes=["xyz"]
242
195
  ),
243
- self.user1
196
+ self.user,
244
197
  )
245
198
  mock_bulk_refresh.return_value = Token.objects.none()
246
199
 
247
- self.assertSetEqual(
248
- set(Token.objects.get_queryset().require_valid()),
249
- {t1, t2}
250
- )
200
+ self.assertSetEqual(set(Token.objects.get_queryset().require_valid()), {t1, t2})
251
201
 
252
- @patch('esi.models.app_settings.ESI_TOKEN_VALID_DURATION', 120)
253
- @patch('esi.managers.TokenQueryset.bulk_refresh', autospec=True)
254
- def test_require_valid_some_expired(
255
- self,
256
- mock_bulk_refresh
257
- ):
202
+ def test_require_valid_some_expired(self, mock_bulk_refresh):
258
203
  character_id = 99
259
- character_name = 'Bruce Wayne'
204
+ character_name = "Bruce Wayne"
260
205
  t1 = _store_as_Token(
261
206
  _generate_token(
262
- character_id=character_id,
263
- character_name=character_name,
264
- scopes=['abc']
207
+ character_id=character_id, character_name=character_name, scopes=["abc"]
265
208
  ),
266
- self.user1
209
+ self.user,
267
210
  )
268
211
  t2 = _store_as_Token(
269
212
  _generate_token(
270
- character_id=character_id,
271
- character_name=character_name,
272
- scopes=['xyz']
213
+ character_id=character_id, character_name=character_name, scopes=["xyz"]
273
214
  ),
274
- self.user1
215
+ self.user,
275
216
  )
276
217
  t2.created -= timedelta(121)
277
218
  t2.save()
278
219
  mock_bulk_refresh.return_value = Token.objects.filter(pk__in=[t2.pk])
279
220
 
280
- self.assertSetEqual(
281
- set(Token.objects.get_queryset().require_valid()),
282
- {t1, t2}
283
- )
221
+ self.assertSetEqual(set(Token.objects.get_queryset().require_valid()), {t1, t2})
284
222
 
285
- @patch('esi.models.app_settings.ESI_TOKEN_VALID_DURATION', 120)
286
- @patch('esi.managers.TokenQueryset.bulk_refresh', autospec=True)
287
- def test_require_valid_one_refresh_error(
288
- self,
289
- mock_bulk_refresh
290
- ):
223
+ def test_require_valid_one_refresh_error(self, mock_bulk_refresh):
291
224
  character_id = 99
292
- character_name = 'Bruce Wayne'
225
+ character_name = "Bruce Wayne"
293
226
  t1 = _store_as_Token(
294
227
  _generate_token(
295
- character_id=character_id,
296
- character_name=character_name,
297
- scopes=['abc']
228
+ character_id=character_id, character_name=character_name, scopes=["abc"]
298
229
  ),
299
- self.user1
230
+ self.user,
300
231
  )
301
232
  t2 = _store_as_Token(
302
233
  _generate_token(
303
- character_id=character_id,
304
- character_name=character_name,
305
- scopes=['xyz']
234
+ character_id=character_id, character_name=character_name, scopes=["xyz"]
306
235
  ),
307
- self.user1
236
+ self.user,
308
237
  )
309
238
  t2.created -= timedelta(121)
310
239
  t2.save()
311
240
  mock_bulk_refresh.return_value = Token.objects.none()
312
241
 
313
- self.assertSetEqual(
314
- set(Token.objects.get_queryset().require_valid()),
315
- {t1}
242
+ self.assertSetEqual(set(Token.objects.get_queryset().require_valid()), {t1})
243
+
244
+
245
+ @patch("esi.models.app_settings.ESI_TOKEN_VALID_DURATION", 120)
246
+ @patch("esi.models.Token.refresh", spec=True)
247
+ class TestTokenBulkRefreshXRequireValid(TestCase):
248
+ @classmethod
249
+ def setUpClass(cls) -> None:
250
+ super().setUpClass()
251
+ cls.user = User.objects.create_user(
252
+ "Bruce Wayne", "abc@example.com", "password"
253
+ )
254
+
255
+ def test_require_valid_all_expired(self, mock_token_refresh):
256
+ """Test demonstrates the bug introduced with 5.3.0b1.
257
+
258
+ bulk_refresh() does not return the token after it has been refreshed.
259
+ Then also require_valid() does not return the refreshed token.
260
+ Apps calling require_valid() will then assume there is no valid token.
261
+ The previous tests did not catch this bug, because it they were testing
262
+ the methods one by one and mocking out responses from other methods.
263
+ """
264
+ def my_refresh(*args, **kwargs):
265
+ t.created = now()
266
+ t.save()
267
+
268
+ # given
269
+ mock_token_refresh.side_effect = my_refresh
270
+ character_id = 99
271
+ character_name = "Bruce Wayne"
272
+ t: Token = _store_as_Token(
273
+ _generate_token(
274
+ character_id=character_id, character_name=character_name, scopes=["abc"]
275
+ ),
276
+ self.user,
277
+ )
278
+ t.created -= timedelta(121)
279
+ t.save()
280
+
281
+ # when
282
+ qs = Token.objects.get_queryset().require_valid()
283
+
284
+ # then
285
+ expected = set(qs.values_list("pk", flat=True))
286
+ self.assertSetEqual(expected, {t.pk})
287
+
288
+
289
+ class TestTokenRequireScopes(TestCase):
290
+ @classmethod
291
+ def setUpClass(cls) -> None:
292
+ super().setUpClass()
293
+ cls.user = User.objects.create_user(
294
+ "Bruce Wayne", "abc@example.com", "password"
316
295
  )
317
296
 
318
297
  def test_require_scopes_normal(self):
319
298
  character_id = 99
320
- character_name = 'Bruce Wayne'
299
+ character_name = "Bruce Wayne"
321
300
  t1 = _store_as_Token(
322
301
  _generate_token(
323
302
  character_id=character_id,
324
303
  character_name=character_name,
325
- scopes=['abc', 'xyz', '123']
304
+ scopes=["abc", "xyz", "123"],
326
305
  ),
327
- self.user1
306
+ self.user,
328
307
  )
329
308
  t2 = _store_as_Token(
330
309
  _generate_token(
331
310
  character_id=character_id,
332
311
  character_name=character_name,
333
- scopes=['abc', 'xyz']
312
+ scopes=["abc", "xyz"],
334
313
  ),
335
- self.user1
314
+ self.user,
336
315
  )
337
316
  t3 = _store_as_Token(
338
317
  _generate_token(
339
318
  character_id=character_id,
340
319
  character_name=character_name,
341
- scopes=['abc', '123']
320
+ scopes=["abc", "123"],
342
321
  ),
343
- self.user1
322
+ self.user,
344
323
  )
345
324
  self.assertSetEqual(
346
- set(Token.objects.get_queryset().require_scopes('abc')), {t1, t2, t3}
325
+ set(Token.objects.get_queryset().require_scopes("abc")), {t1, t2, t3}
347
326
  )
348
327
  self.assertSetEqual(
349
- set(Token.objects.get_queryset().require_scopes('xyz')), {t1, t2}
328
+ set(Token.objects.get_queryset().require_scopes("xyz")), {t1, t2}
350
329
  )
351
330
  self.assertSetEqual(
352
- set(Token.objects.get_queryset().require_scopes('123')), {t1, t3}
331
+ set(Token.objects.get_queryset().require_scopes("123")), {t1, t3}
353
332
  )
354
333
  self.assertSetEqual(
355
- set(Token.objects.get_queryset().require_scopes('555')), set()
334
+ set(Token.objects.get_queryset().require_scopes("555")), set()
356
335
  )
357
336
  self.assertSetEqual(
358
- set(Token.objects.get_queryset().require_scopes('abc xyz 123')), {t1}
337
+ set(Token.objects.get_queryset().require_scopes("abc xyz 123")), {t1}
359
338
  )
360
339
 
361
340
  def test_require_scopes_empty(self):
362
341
  character_id = 99
363
- character_name = 'Bruce Wayne'
342
+ character_name = "Bruce Wayne"
364
343
  _store_as_Token(
365
344
  _generate_token(
366
345
  character_id=character_id,
367
346
  character_name=character_name,
368
- scopes=['abc', 'xyz', '123']
347
+ scopes=["abc", "xyz", "123"],
369
348
  ),
370
- self.user1
349
+ self.user,
371
350
  )
372
351
  t2 = _store_as_Token(
373
- _generate_token(
374
- character_id=character_id,
375
- character_name=character_name
376
- ),
377
- self.user1
352
+ _generate_token(character_id=character_id, character_name=character_name),
353
+ self.user,
378
354
  )
379
355
  t2.scopes.all().delete()
380
356
  _store_as_Token(
381
357
  _generate_token(
382
358
  character_id=character_id,
383
359
  character_name=character_name,
384
- scopes=['abc', '123']
360
+ scopes=["abc", "123"],
385
361
  ),
386
- self.user1
362
+ self.user,
387
363
  )
388
- self.assertSetEqual(set(Token.objects.get_queryset().require_scopes('')), {t2})
364
+ self.assertSetEqual(set(Token.objects.get_queryset().require_scopes("")), {t2})
389
365
 
390
366
  def test_require_scopes_exact(self):
391
367
  character_id = 99
392
- character_name = 'Bruce Wayne'
368
+ character_name = "Bruce Wayne"
393
369
  _store_as_Token(
394
370
  _generate_token(
395
371
  character_id=character_id,
396
372
  character_name=character_name,
397
- scopes=['abc', 'xyz', '123']
373
+ scopes=["abc", "xyz", "123"],
398
374
  ),
399
- self.user1
375
+ self.user,
400
376
  )
401
377
  t2 = _store_as_Token(
402
378
  _generate_token(
403
379
  character_id=character_id,
404
380
  character_name=character_name,
405
- scopes=['abc', 'xyz']
381
+ scopes=["abc", "xyz"],
406
382
  ),
407
- self.user1
383
+ self.user,
408
384
  )
409
385
  t3 = _store_as_Token(
410
386
  _generate_token(
411
387
  character_id=character_id,
412
388
  character_name=character_name,
413
- scopes=['abc', '123']
389
+ scopes=["abc", "123"],
414
390
  ),
415
- self.user1
391
+ self.user,
416
392
  )
417
393
  t4 = _store_as_Token(
418
394
  _generate_token(
419
395
  character_id=character_id,
420
396
  character_name=character_name,
421
- scopes=['abc', '123']
397
+ scopes=["abc", "123"],
422
398
  ),
423
- self.user1
399
+ self.user,
424
400
  )
425
401
  self.assertSetEqual(
426
- set(Token.objects.get_queryset().require_scopes_exact('abc')), set()
402
+ set(Token.objects.get_queryset().require_scopes_exact("abc")), set()
427
403
  )
428
404
  self.assertSetEqual(
429
- set(Token.objects.get_queryset().require_scopes_exact('abc xyz')), {t2}
405
+ set(Token.objects.get_queryset().require_scopes_exact("abc xyz")), {t2}
430
406
  )
431
407
  self.assertSetEqual(
432
- set(Token.objects.get_queryset().require_scopes_exact('abc 123')), {t3, t4}
408
+ set(Token.objects.get_queryset().require_scopes_exact("abc 123")), {t3, t4}
433
409
  )
434
410
 
435
411
  def test_require_scopes_exact_2(self):
436
412
  character_id = 99
437
- character_name = 'Bruce Wayne'
413
+ character_name = "Bruce Wayne"
438
414
  _store_as_Token(
439
415
  _generate_token(
440
416
  character_id=character_id,
441
417
  character_name=character_name,
442
- scopes=['abc', 'xyz', '123']
418
+ scopes=["abc", "xyz", "123"],
443
419
  ),
444
- self.user1
420
+ self.user,
445
421
  )
446
422
  _store_as_Token(
447
423
  _generate_token(
448
424
  character_id=character_id,
449
425
  character_name=character_name,
450
- scopes=['abc', 'xyz']
426
+ scopes=["abc", "xyz"],
451
427
  ),
452
- self.user1
428
+ self.user,
453
429
  )
454
430
  t3 = _store_as_Token(
455
431
  _generate_token(
456
432
  character_id=character_id,
457
433
  character_name=character_name,
458
- scopes=['xyz', '123']
434
+ scopes=["xyz", "123"],
459
435
  ),
460
- self.user1
436
+ self.user,
461
437
  )
462
438
  t4 = _store_as_Token(
463
439
  _generate_token(
464
440
  character_id=character_id,
465
441
  character_name=character_name,
466
- scopes=['xyz', '123']
442
+ scopes=["xyz", "123"],
467
443
  ),
468
- self.user1
469
- )
470
- self.assertSetEqual(
471
- set(Token.objects.get_queryset().equivalent_to(t3)), {t4}
444
+ self.user,
472
445
  )
446
+ self.assertSetEqual(set(Token.objects.get_queryset().equivalent_to(t3)), {t4})
473
447
 
474
448
 
475
449
  class TestTokenManager(TestCase):
@@ -478,173 +452,146 @@ class TestTokenManager(TestCase):
478
452
  self.factory = RequestFactory()
479
453
 
480
454
  self.user1 = User.objects.create_user(
481
- 'Bruce Wayne',
482
- 'abc@example.com',
483
- 'password'
484
- )
485
-
486
- @patch('esi.managers.app_settings.ESI_SSO_CLIENT_ID', 'abc')
487
- @patch('esi.managers.app_settings.ESI_SSO_CLIENT_SECRET', 'xyz')
488
- @patch('esi.managers.app_settings.ESI_SSO_CALLBACK_URL', 'localhost')
489
- @patch('esi.managers.app_settings.ESI_TOKEN_URL', 'localhost')
490
- @patch('esi.managers.app_settings.ESI_TOKEN_VERIFY_URL', 'localhost')
491
- @patch('esi.managers.app_settings.ESI_ALWAYS_CREATE_TOKEN', False)
492
- @patch('esi.managers.TokenManager._decode_jwt')
493
- @patch('esi.managers.OAuth2Session', autospec=True)
455
+ "Bruce Wayne", "abc@example.com", "password"
456
+ )
457
+
458
+ @patch("esi.managers.app_settings.ESI_SSO_CLIENT_ID", "abc")
459
+ @patch("esi.managers.app_settings.ESI_SSO_CLIENT_SECRET", "xyz")
460
+ @patch("esi.managers.app_settings.ESI_SSO_CALLBACK_URL", "localhost")
461
+ @patch("esi.managers.app_settings.ESI_TOKEN_URL", "localhost")
462
+ @patch("esi.managers.app_settings.ESI_TOKEN_VERIFY_URL", "localhost")
463
+ @patch("esi.managers.app_settings.ESI_ALWAYS_CREATE_TOKEN", False)
464
+ @patch("esi.managers.TokenManager._decode_jwt")
465
+ @patch("esi.managers.OAuth2Session", autospec=True)
494
466
  def test_create_from_code_single_scope(self, mock_OAuth2Session, mock_decode_jwt):
495
467
  """Normal case with refresh token"""
496
468
  mock_oauth = Mock()
497
- mock_oauth.request.return_value.json.return_value = \
498
- _generate_token(
499
- 99, 'Bruce Wayne', scopes='publicData'
500
- )
469
+ mock_oauth.request.return_value.json.return_value = _generate_token(
470
+ 99, "Bruce Wayne", scopes="publicData"
471
+ )
501
472
  mock_oauth.fetch_token.return_value = {
502
- 'access_token': 'access_token',
503
- 'refresh_token': 'refresh_token',
504
- 'token_type': 'Bearer',
505
- 'expires_in': 1200,
473
+ "access_token": "access_token",
474
+ "refresh_token": "refresh_token",
475
+ "token_type": "Bearer",
476
+ "expires_in": 1200,
506
477
  }
507
478
  mock_OAuth2Session.return_value = mock_oauth
508
- mock_decode_jwt.return_value = \
509
- _generate_token(
510
- 99, 'Bruce Wayne', scopes='publicData'
511
- )
512
- # create new token from code
513
- token1 = Token.objects.create_from_code('abc123xyz')
514
- self.assertEqual(
515
- token1.character_id,
516
- 99
517
- )
518
- self.assertEqual(
519
- token1.character_name,
520
- 'Bruce Wayne'
521
- )
522
- self.assertEqual(
523
- token1.scopes.all().count(),
524
- 1
479
+ mock_decode_jwt.return_value = _generate_token(
480
+ 99, "Bruce Wayne", scopes="publicData"
525
481
  )
482
+ # create new token from code
483
+ token1 = Token.objects.create_from_code("abc123xyz")
484
+ self.assertEqual(token1.character_id, 99)
485
+ self.assertEqual(token1.character_name, "Bruce Wayne")
486
+ self.assertEqual(token1.scopes.all().count(), 1)
526
487
  # should return existing token instead of creating a new one
527
488
  # since ESI_ALWAYS_CREATE_TOKEN is False
528
- token2 = Token.objects.create_from_code('11abc123xyz')
489
+ token2 = Token.objects.create_from_code("11abc123xyz")
529
490
  self.assertEqual(token1, token2)
530
491
 
531
- @patch('esi.managers.app_settings.ESI_SSO_CLIENT_ID', 'abc')
532
- @patch('esi.managers.app_settings.ESI_SSO_CLIENT_SECRET', 'xyz')
533
- @patch('esi.managers.app_settings.ESI_SSO_CALLBACK_URL', 'localhost')
534
- @patch('esi.managers.app_settings.ESI_TOKEN_URL', 'localhost')
535
- @patch('esi.managers.app_settings.ESI_TOKEN_VERIFY_URL', 'localhost')
536
- @patch('esi.managers.app_settings.ESI_ALWAYS_CREATE_TOKEN', False)
537
- @patch('esi.managers.TokenManager._decode_jwt')
538
- @patch('esi.managers.OAuth2Session', autospec=True)
492
+ @patch("esi.managers.app_settings.ESI_SSO_CLIENT_ID", "abc")
493
+ @patch("esi.managers.app_settings.ESI_SSO_CLIENT_SECRET", "xyz")
494
+ @patch("esi.managers.app_settings.ESI_SSO_CALLBACK_URL", "localhost")
495
+ @patch("esi.managers.app_settings.ESI_TOKEN_URL", "localhost")
496
+ @patch("esi.managers.app_settings.ESI_TOKEN_VERIFY_URL", "localhost")
497
+ @patch("esi.managers.app_settings.ESI_ALWAYS_CREATE_TOKEN", False)
498
+ @patch("esi.managers.TokenManager._decode_jwt")
499
+ @patch("esi.managers.OAuth2Session", autospec=True)
539
500
  def test_create_from_code_1(self, mock_OAuth2Session, mock_decode_jwt):
540
501
  """Normal case with refresh token"""
541
502
  mock_oauth = Mock()
542
- mock_oauth.request.return_value.json.return_value = \
543
- _generate_token(
544
- 99, 'Bruce Wayne', scopes=[
545
- 'esi-calendar.read_calendar_events.v1',
546
- 'esi-location.read_location.v1',
547
- 'esi-location.read_ship_type.v1',
548
- 'esi-unknown-scope'
549
- ]
550
- )
503
+ mock_oauth.request.return_value.json.return_value = _generate_token(
504
+ 99,
505
+ "Bruce Wayne",
506
+ scopes=[
507
+ "esi-calendar.read_calendar_events.v1",
508
+ "esi-location.read_location.v1",
509
+ "esi-location.read_ship_type.v1",
510
+ "esi-unknown-scope",
511
+ ],
512
+ )
551
513
  mock_oauth.fetch_token.return_value = {
552
- 'access_token': 'access_token',
553
- 'refresh_token': 'refresh_token',
554
- 'token_type': 'Bearer',
555
- 'expires_in': 1200,
514
+ "access_token": "access_token",
515
+ "refresh_token": "refresh_token",
516
+ "token_type": "Bearer",
517
+ "expires_in": 1200,
556
518
  }
557
519
  mock_OAuth2Session.return_value = mock_oauth
558
- mock_decode_jwt.return_value = \
559
- _generate_token(
560
- 99, 'Bruce Wayne', scopes=[
561
- 'esi-calendar.read_calendar_events.v1',
562
- 'esi-location.read_location.v1',
563
- 'esi-location.read_ship_type.v1',
564
- 'esi-unknown-scope'
565
- ]
566
- )
567
- # create new token from code
568
- token1 = Token.objects.create_from_code('abc123xyz')
569
- self.assertEqual(
570
- token1.character_id,
571
- 99
572
- )
573
- self.assertEqual(
574
- token1.character_name,
575
- 'Bruce Wayne'
576
- )
577
- self.assertEqual(
578
- token1.scopes.all().count(),
579
- 4
520
+ mock_decode_jwt.return_value = _generate_token(
521
+ 99,
522
+ "Bruce Wayne",
523
+ scopes=[
524
+ "esi-calendar.read_calendar_events.v1",
525
+ "esi-location.read_location.v1",
526
+ "esi-location.read_ship_type.v1",
527
+ "esi-unknown-scope",
528
+ ],
580
529
  )
530
+ # create new token from code
531
+ token1 = Token.objects.create_from_code("abc123xyz")
532
+ self.assertEqual(token1.character_id, 99)
533
+ self.assertEqual(token1.character_name, "Bruce Wayne")
534
+ self.assertEqual(token1.scopes.all().count(), 4)
581
535
 
582
536
  # should return existing token instead of creating a new one
583
537
  # since ESI_ALWAYS_CREATE_TOKEN is False
584
- token2 = Token.objects.create_from_code('11abc123xyz')
538
+ token2 = Token.objects.create_from_code("11abc123xyz")
585
539
  self.assertEqual(token1, token2)
586
540
 
587
- @patch('esi.managers.app_settings.ESI_SSO_CLIENT_ID', 'abc')
588
- @patch('esi.managers.app_settings.ESI_SSO_CLIENT_SECRET', 'xyz')
589
- @patch('esi.managers.app_settings.ESI_SSO_CALLBACK_URL', 'localhost')
590
- @patch('esi.managers.app_settings.ESI_TOKEN_URL', 'localhost')
591
- @patch('esi.managers.app_settings.ESI_TOKEN_VERIFY_URL', 'localhost')
592
- @patch('esi.managers.app_settings.ESI_ALWAYS_CREATE_TOKEN', False)
593
- @patch('esi.managers.TokenManager._decode_jwt')
594
- @patch('esi.managers.OAuth2Session', autospec=True)
541
+ @patch("esi.managers.app_settings.ESI_SSO_CLIENT_ID", "abc")
542
+ @patch("esi.managers.app_settings.ESI_SSO_CLIENT_SECRET", "xyz")
543
+ @patch("esi.managers.app_settings.ESI_SSO_CALLBACK_URL", "localhost")
544
+ @patch("esi.managers.app_settings.ESI_TOKEN_URL", "localhost")
545
+ @patch("esi.managers.app_settings.ESI_TOKEN_VERIFY_URL", "localhost")
546
+ @patch("esi.managers.app_settings.ESI_ALWAYS_CREATE_TOKEN", False)
547
+ @patch("esi.managers.TokenManager._decode_jwt")
548
+ @patch("esi.managers.OAuth2Session", autospec=True)
595
549
  def test_create_from_code_2(self, mock_OAuth2Session, mock_decode_jwt):
596
550
  """Special case w/o refresh token"""
597
551
  mock_oauth = Mock()
598
- mock_oauth.request.return_value.json.return_value = \
599
- _generate_token(
600
- 99, 'Bruce Wayne', scopes=[
601
- 'esi-calendar.read_calendar_events.v1',
602
- 'esi-location.read_location.v1',
603
- 'esi-location.read_ship_type.v1',
604
- 'esi-unknown-scope'
605
- ]
606
- )
552
+ mock_oauth.request.return_value.json.return_value = _generate_token(
553
+ 99,
554
+ "Bruce Wayne",
555
+ scopes=[
556
+ "esi-calendar.read_calendar_events.v1",
557
+ "esi-location.read_location.v1",
558
+ "esi-location.read_ship_type.v1",
559
+ "esi-unknown-scope",
560
+ ],
561
+ )
607
562
  mock_oauth.fetch_token.return_value = {
608
- 'access_token': 'access_token',
609
- 'refresh_token': None,
610
- 'token_type': 'Bearer',
611
- 'expires_in': 1200,
563
+ "access_token": "access_token",
564
+ "refresh_token": None,
565
+ "token_type": "Bearer",
566
+ "expires_in": 1200,
612
567
  }
613
568
  mock_OAuth2Session.return_value = mock_oauth
614
- mock_decode_jwt.return_value = \
615
- _generate_token(
616
- 99, 'Bruce Wayne', scopes=[
617
- 'esi-calendar.read_calendar_events.v1',
618
- 'esi-location.read_location.v1',
619
- 'esi-location.read_ship_type.v1',
620
- 'esi-unknown-scope'
621
- ]
622
- )
623
- # create new token from code
624
- token1 = Token.objects.create_from_code('abc123xyz')
625
- self.assertEqual(
626
- token1.character_id,
627
- 99
628
- )
629
- self.assertEqual(
630
- token1.character_name,
631
- 'Bruce Wayne'
632
- )
633
- self.assertEqual(
634
- token1.scopes.all().count(),
635
- 4
569
+ mock_decode_jwt.return_value = _generate_token(
570
+ 99,
571
+ "Bruce Wayne",
572
+ scopes=[
573
+ "esi-calendar.read_calendar_events.v1",
574
+ "esi-location.read_location.v1",
575
+ "esi-location.read_ship_type.v1",
576
+ "esi-unknown-scope",
577
+ ],
636
578
  )
579
+ # create new token from code
580
+ token1 = Token.objects.create_from_code("abc123xyz")
581
+ self.assertEqual(token1.character_id, 99)
582
+ self.assertEqual(token1.character_name, "Bruce Wayne")
583
+ self.assertEqual(token1.scopes.all().count(), 4)
637
584
 
638
585
  # should return existing token instead of creating a new one
639
586
  # since ESI_ALWAYS_CREATE_TOKEN is False
640
- token2 = Token.objects.create_from_code('11abc123xyz')
587
+ token2 = Token.objects.create_from_code("11abc123xyz")
641
588
  self.assertEqual(token1, token2)
642
589
 
643
- @patch('esi.managers.TokenManager.create_from_code', autospec=True)
590
+ @patch("esi.managers.TokenManager.create_from_code", autospec=True)
644
591
  def test_create_from_request(self, mock_create_from_code):
645
- mock_create_from_code.return_value = 'we got you'
592
+ mock_create_from_code.return_value = "we got you"
646
593
 
647
- request = self.factory.get('https://www.example.com?code=abc123')
594
+ request = self.factory.get("https://www.example.com?code=abc123")
648
595
  request.user = self.user1
649
596
 
650
597
  middleware = SessionMiddleware(HttpResponse)
@@ -652,8 +599,8 @@ class TestTokenManager(TestCase):
652
599
  request.session.save()
653
600
 
654
601
  x = Token.objects.create_from_request(request)
655
- self.assertEqual(x, 'we got you')
656
- self.assertEqual(mock_create_from_code.call_args[0][1], 'abc123')
602
+ self.assertEqual(x, "we got you")
603
+ self.assertEqual(mock_create_from_code.call_args[0][1], "abc123")
657
604
 
658
605
 
659
606
  @requests_mock.Mocker()
esi/urls.py CHANGED
@@ -1,4 +1,4 @@
1
- from django.urls import re_path
1
+ from django.urls import path
2
2
 
3
3
  from . import views
4
4
 
@@ -6,5 +6,5 @@ from . import views
6
6
  app_name = 'esi'
7
7
 
8
8
  urlpatterns = [
9
- re_path(r'^callback/$', views.receive_callback, name='callback'),
9
+ path('callback/', views.receive_callback, name='callback'),
10
10
  ]