django-esi 8.0.0a3__py3-none-any.whl → 8.0.0a4__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.
- {django_esi-8.0.0a3.dist-info → django_esi-8.0.0a4.dist-info}/METADATA +1 -1
- {django_esi-8.0.0a3.dist-info → django_esi-8.0.0a4.dist-info}/RECORD +40 -29
- esi/__init__.py +2 -2
- esi/aiopenapi3/plugins.py +13 -2
- esi/locale/cs_CZ/LC_MESSAGES/django.mo +0 -0
- esi/locale/cs_CZ/LC_MESSAGES/django.po +53 -0
- esi/locale/de/LC_MESSAGES/django.mo +0 -0
- esi/locale/de/LC_MESSAGES/django.po +10 -9
- esi/locale/en/LC_MESSAGES/django.mo +0 -0
- esi/locale/en/LC_MESSAGES/django.po +3 -3
- esi/locale/es/LC_MESSAGES/django.mo +0 -0
- esi/locale/es/LC_MESSAGES/django.po +12 -10
- esi/locale/fr_FR/LC_MESSAGES/django.mo +0 -0
- esi/locale/fr_FR/LC_MESSAGES/django.po +18 -10
- esi/locale/it_IT/LC_MESSAGES/django.mo +0 -0
- esi/locale/it_IT/LC_MESSAGES/django.po +12 -10
- esi/locale/ja/LC_MESSAGES/django.mo +0 -0
- esi/locale/ja/LC_MESSAGES/django.po +10 -9
- esi/locale/ko_KR/LC_MESSAGES/django.mo +0 -0
- esi/locale/ko_KR/LC_MESSAGES/django.po +10 -9
- esi/locale/nl_NL/LC_MESSAGES/django.mo +0 -0
- esi/locale/nl_NL/LC_MESSAGES/django.po +53 -0
- esi/locale/pl_PL/LC_MESSAGES/django.mo +0 -0
- esi/locale/pl_PL/LC_MESSAGES/django.po +53 -0
- esi/locale/ru/LC_MESSAGES/django.mo +0 -0
- esi/locale/ru/LC_MESSAGES/django.po +13 -10
- esi/locale/sk/LC_MESSAGES/django.mo +0 -0
- esi/locale/sk/LC_MESSAGES/django.po +55 -0
- esi/locale/uk/LC_MESSAGES/django.mo +0 -0
- esi/locale/uk/LC_MESSAGES/django.po +57 -0
- esi/locale/zh_Hans/LC_MESSAGES/django.mo +0 -0
- esi/locale/zh_Hans/LC_MESSAGES/django.po +10 -9
- esi/management/commands/generate_esi_stubs.py +11 -31
- esi/models.py +1 -1
- esi/openapi_clients.py +161 -44
- esi/stubs.pyi +388 -388
- esi/tests/test_openapi.json +264 -0
- esi/tests/test_openapi.py +248 -1
- {django_esi-8.0.0a3.dist-info → django_esi-8.0.0a4.dist-info}/WHEEL +0 -0
- {django_esi-8.0.0a3.dist-info → django_esi-8.0.0a4.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
{
|
|
2
|
+
"components": {
|
|
3
|
+
"headers": {
|
|
4
|
+
"CacheControl": {
|
|
5
|
+
"description": "Directives for caching mechanisms. It controls how the response can be cached, by whom, and for how long.",
|
|
6
|
+
"schema": { "type": "string" }
|
|
7
|
+
},
|
|
8
|
+
"ContentLanguage": {
|
|
9
|
+
"description": "The language used in the response.",
|
|
10
|
+
"schema": {
|
|
11
|
+
"enum": ["en", "de", "fr", "ja", "ru", "zh", "ko", "es"],
|
|
12
|
+
"type": "string"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"ETag": {
|
|
16
|
+
"description": "The ETag value of the response body. Use this with If-None-Match to check whether the resource has changed.",
|
|
17
|
+
"schema": { "type": "string" }
|
|
18
|
+
},
|
|
19
|
+
"LastModified": {
|
|
20
|
+
"description": "The last modified date of the response. Use this with If-Modified-Since to check whether the resource has changed.",
|
|
21
|
+
"schema": { "type": "string" }
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"parameters": {
|
|
25
|
+
"AcceptLanguage": {
|
|
26
|
+
"description": "The language to use for the response.",
|
|
27
|
+
"in": "header",
|
|
28
|
+
"name": "Accept-Language",
|
|
29
|
+
"schema": {
|
|
30
|
+
"default": "en",
|
|
31
|
+
"enum": ["en", "de", "fr", "ja", "ru", "zh", "ko", "es"],
|
|
32
|
+
"type": "string"
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
"CompatibilityDate": {
|
|
36
|
+
"description": "The compatibility date for the request.",
|
|
37
|
+
"in": "header",
|
|
38
|
+
"name": "X-Compatibility-Date",
|
|
39
|
+
"required": true,
|
|
40
|
+
"schema": { "enum": ["2025-08-26"], "format": "date", "type": "string" }
|
|
41
|
+
},
|
|
42
|
+
"IfModifiedSince": {
|
|
43
|
+
"description": "The date the resource was last modified. A 304 will be returned if the resource has not been modified since this date.",
|
|
44
|
+
"in": "header",
|
|
45
|
+
"name": "If-Modified-Since",
|
|
46
|
+
"schema": { "type": "string" }
|
|
47
|
+
},
|
|
48
|
+
"IfNoneMatch": {
|
|
49
|
+
"description": "The ETag of the previous request. A 304 will be returned if this matches the current ETag.",
|
|
50
|
+
"in": "header",
|
|
51
|
+
"name": "If-None-Match",
|
|
52
|
+
"schema": { "type": "string" }
|
|
53
|
+
},
|
|
54
|
+
"Tenant": {
|
|
55
|
+
"description": "The tenant ID for the request.",
|
|
56
|
+
"example": "",
|
|
57
|
+
"in": "header",
|
|
58
|
+
"name": "X-Tenant",
|
|
59
|
+
"schema": { "default": "tranquility", "type": "string" }
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
"schemas": {
|
|
63
|
+
"StatusGet": {
|
|
64
|
+
"properties": {
|
|
65
|
+
"players": {
|
|
66
|
+
"description": "Current online player count",
|
|
67
|
+
"type": "integer"
|
|
68
|
+
},
|
|
69
|
+
"server_version": {
|
|
70
|
+
"description": "Running version as string",
|
|
71
|
+
"type": "string"
|
|
72
|
+
},
|
|
73
|
+
"start_time": {
|
|
74
|
+
"description": "Server start timestamp",
|
|
75
|
+
"format": "date-time",
|
|
76
|
+
"type": "string"
|
|
77
|
+
},
|
|
78
|
+
"vip": {
|
|
79
|
+
"description": "If the server is in VIP mode",
|
|
80
|
+
"type": "boolean"
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
"required": ["start_time", "players", "server_version"],
|
|
84
|
+
"type": "object"
|
|
85
|
+
},
|
|
86
|
+
"Error": {
|
|
87
|
+
"additionalProperties": false,
|
|
88
|
+
"properties": {
|
|
89
|
+
"details": {
|
|
90
|
+
"description": "List of individual error details.",
|
|
91
|
+
"items": {
|
|
92
|
+
"$ref": "#/components/schemas/ErrorDetail"
|
|
93
|
+
},
|
|
94
|
+
"type": [
|
|
95
|
+
"array",
|
|
96
|
+
"null"
|
|
97
|
+
]
|
|
98
|
+
},
|
|
99
|
+
"error": {
|
|
100
|
+
"description": "Error message.",
|
|
101
|
+
"type": "string"
|
|
102
|
+
}
|
|
103
|
+
},
|
|
104
|
+
"required": [
|
|
105
|
+
"error"
|
|
106
|
+
],
|
|
107
|
+
"type": "object"
|
|
108
|
+
},
|
|
109
|
+
"ErrorDetail": {
|
|
110
|
+
"additionalProperties": false,
|
|
111
|
+
"properties": {
|
|
112
|
+
"location": {
|
|
113
|
+
"description": "Where the error occurred, e.g. 'body.items[3].tags' or 'path.thing-id'",
|
|
114
|
+
"type": "string"
|
|
115
|
+
},
|
|
116
|
+
"message": {
|
|
117
|
+
"description": "Error message text",
|
|
118
|
+
"type": "string"
|
|
119
|
+
},
|
|
120
|
+
"value": {
|
|
121
|
+
"description": "The value at the given location"
|
|
122
|
+
}
|
|
123
|
+
},
|
|
124
|
+
"type": "object"
|
|
125
|
+
}
|
|
126
|
+
},
|
|
127
|
+
"securitySchemes": {
|
|
128
|
+
"OAuth2": {
|
|
129
|
+
"flows": {
|
|
130
|
+
"authorizationCode": {
|
|
131
|
+
"authorizationUrl": "https://login.eveonline.com/v2/oauth/authorize",
|
|
132
|
+
"scopes": {
|
|
133
|
+
"esi-alliances.read_contacts.v1": "esi-alliances.read_contacts.v1",
|
|
134
|
+
"esi-assets.read_assets.v1": "esi-assets.read_assets.v1",
|
|
135
|
+
"esi-assets.read_corporation_assets.v1": "esi-assets.read_corporation_assets.v1",
|
|
136
|
+
"esi-calendar.read_calendar_events.v1": "esi-calendar.read_calendar_events.v1",
|
|
137
|
+
"esi-calendar.respond_calendar_events.v1": "esi-calendar.respond_calendar_events.v1",
|
|
138
|
+
"esi-characters.read_agents_research.v1": "esi-characters.read_agents_research.v1",
|
|
139
|
+
"esi-characters.read_blueprints.v1": "esi-characters.read_blueprints.v1",
|
|
140
|
+
"esi-characters.read_contacts.v1": "esi-characters.read_contacts.v1",
|
|
141
|
+
"esi-characters.read_corporation_roles.v1": "esi-characters.read_corporation_roles.v1",
|
|
142
|
+
"esi-characters.read_fatigue.v1": "esi-characters.read_fatigue.v1",
|
|
143
|
+
"esi-characters.read_fw_stats.v1": "esi-characters.read_fw_stats.v1",
|
|
144
|
+
"esi-characters.read_loyalty.v1": "esi-characters.read_loyalty.v1",
|
|
145
|
+
"esi-characters.read_medals.v1": "esi-characters.read_medals.v1",
|
|
146
|
+
"esi-characters.read_notifications.v1": "esi-characters.read_notifications.v1",
|
|
147
|
+
"esi-characters.read_standings.v1": "esi-characters.read_standings.v1",
|
|
148
|
+
"esi-characters.read_titles.v1": "esi-characters.read_titles.v1",
|
|
149
|
+
"esi-characters.write_contacts.v1": "esi-characters.write_contacts.v1",
|
|
150
|
+
"esi-clones.read_clones.v1": "esi-clones.read_clones.v1",
|
|
151
|
+
"esi-clones.read_implants.v1": "esi-clones.read_implants.v1",
|
|
152
|
+
"esi-contracts.read_character_contracts.v1": "esi-contracts.read_character_contracts.v1",
|
|
153
|
+
"esi-contracts.read_corporation_contracts.v1": "esi-contracts.read_corporation_contracts.v1",
|
|
154
|
+
"esi-corporations.read_blueprints.v1": "esi-corporations.read_blueprints.v1",
|
|
155
|
+
"esi-corporations.read_contacts.v1": "esi-corporations.read_contacts.v1",
|
|
156
|
+
"esi-corporations.read_container_logs.v1": "esi-corporations.read_container_logs.v1",
|
|
157
|
+
"esi-corporations.read_corporation_membership.v1": "esi-corporations.read_corporation_membership.v1",
|
|
158
|
+
"esi-corporations.read_divisions.v1": "esi-corporations.read_divisions.v1",
|
|
159
|
+
"esi-corporations.read_facilities.v1": "esi-corporations.read_facilities.v1",
|
|
160
|
+
"esi-corporations.read_fw_stats.v1": "esi-corporations.read_fw_stats.v1",
|
|
161
|
+
"esi-corporations.read_medals.v1": "esi-corporations.read_medals.v1",
|
|
162
|
+
"esi-corporations.read_projects.v1": "esi-corporations.read_projects.v1",
|
|
163
|
+
"esi-corporations.read_standings.v1": "esi-corporations.read_standings.v1",
|
|
164
|
+
"esi-corporations.read_starbases.v1": "esi-corporations.read_starbases.v1",
|
|
165
|
+
"esi-corporations.read_structures.v1": "esi-corporations.read_structures.v1",
|
|
166
|
+
"esi-corporations.read_titles.v1": "esi-corporations.read_titles.v1",
|
|
167
|
+
"esi-corporations.track_members.v1": "esi-corporations.track_members.v1",
|
|
168
|
+
"esi-fittings.read_fittings.v1": "esi-fittings.read_fittings.v1",
|
|
169
|
+
"esi-fittings.write_fittings.v1": "esi-fittings.write_fittings.v1",
|
|
170
|
+
"esi-fleets.read_fleet.v1": "esi-fleets.read_fleet.v1",
|
|
171
|
+
"esi-fleets.write_fleet.v1": "esi-fleets.write_fleet.v1",
|
|
172
|
+
"esi-industry.read_character_jobs.v1": "esi-industry.read_character_jobs.v1",
|
|
173
|
+
"esi-industry.read_character_mining.v1": "esi-industry.read_character_mining.v1",
|
|
174
|
+
"esi-industry.read_corporation_jobs.v1": "esi-industry.read_corporation_jobs.v1",
|
|
175
|
+
"esi-industry.read_corporation_mining.v1": "esi-industry.read_corporation_mining.v1",
|
|
176
|
+
"esi-killmails.read_corporation_killmails.v1": "esi-killmails.read_corporation_killmails.v1",
|
|
177
|
+
"esi-killmails.read_killmails.v1": "esi-killmails.read_killmails.v1",
|
|
178
|
+
"esi-location.read_location.v1": "esi-location.read_location.v1",
|
|
179
|
+
"esi-location.read_online.v1": "esi-location.read_online.v1",
|
|
180
|
+
"esi-location.read_ship_type.v1": "esi-location.read_ship_type.v1",
|
|
181
|
+
"esi-mail.organize_mail.v1": "esi-mail.organize_mail.v1",
|
|
182
|
+
"esi-mail.read_mail.v1": "esi-mail.read_mail.v1",
|
|
183
|
+
"esi-mail.send_mail.v1": "esi-mail.send_mail.v1",
|
|
184
|
+
"esi-markets.read_character_orders.v1": "esi-markets.read_character_orders.v1",
|
|
185
|
+
"esi-markets.read_corporation_orders.v1": "esi-markets.read_corporation_orders.v1",
|
|
186
|
+
"esi-markets.structure_markets.v1": "esi-markets.structure_markets.v1",
|
|
187
|
+
"esi-planets.manage_planets.v1": "esi-planets.manage_planets.v1",
|
|
188
|
+
"esi-planets.read_customs_offices.v1": "esi-planets.read_customs_offices.v1",
|
|
189
|
+
"esi-search.search_structures.v1": "esi-search.search_structures.v1",
|
|
190
|
+
"esi-skills.read_skillqueue.v1": "esi-skills.read_skillqueue.v1",
|
|
191
|
+
"esi-skills.read_skills.v1": "esi-skills.read_skills.v1",
|
|
192
|
+
"esi-ui.open_window.v1": "esi-ui.open_window.v1",
|
|
193
|
+
"esi-ui.write_waypoint.v1": "esi-ui.write_waypoint.v1",
|
|
194
|
+
"esi-universe.read_structures.v1": "esi-universe.read_structures.v1",
|
|
195
|
+
"esi-wallet.read_character_wallet.v1": "esi-wallet.read_character_wallet.v1",
|
|
196
|
+
"esi-wallet.read_corporation_wallets.v1": "esi-wallet.read_corporation_wallets.v1"
|
|
197
|
+
},
|
|
198
|
+
"tokenUrl": "https://login.eveonline.com/v2/oauth/token"
|
|
199
|
+
}
|
|
200
|
+
},
|
|
201
|
+
"type": "oauth2"
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
},
|
|
205
|
+
"info": {
|
|
206
|
+
"contact": {
|
|
207
|
+
"name": "ESI Support",
|
|
208
|
+
"url": "https://developers.eveonline.com/docs/support/"
|
|
209
|
+
},
|
|
210
|
+
"license": {
|
|
211
|
+
"name": "EVE Developer License",
|
|
212
|
+
"url": "https://developers.eveonline.com/license-agreement"
|
|
213
|
+
},
|
|
214
|
+
"termsOfService": "https://support.eveonline.com/hc/en-us/articles/8414770561948-EVE-Online-Terms-of-Service",
|
|
215
|
+
"title": "EVE Stable Infrastructure (ESI) - tranquility",
|
|
216
|
+
"version": "2025-08-26"
|
|
217
|
+
},
|
|
218
|
+
"openapi": "3.1.0",
|
|
219
|
+
"paths": {
|
|
220
|
+
"/status": {
|
|
221
|
+
"get": {
|
|
222
|
+
"description": "EVE Server status",
|
|
223
|
+
"operationId": "GetStatus",
|
|
224
|
+
"parameters": [
|
|
225
|
+
{ "$ref": "#/components/parameters/AcceptLanguage" },
|
|
226
|
+
{ "$ref": "#/components/parameters/IfNoneMatch" },
|
|
227
|
+
{ "$ref": "#/components/parameters/CompatibilityDate" },
|
|
228
|
+
{ "$ref": "#/components/parameters/Tenant" }
|
|
229
|
+
],
|
|
230
|
+
"responses": {
|
|
231
|
+
"200": {
|
|
232
|
+
"content": {
|
|
233
|
+
"application/json": {
|
|
234
|
+
"schema": { "$ref": "#/components/schemas/StatusGet" }
|
|
235
|
+
}
|
|
236
|
+
},
|
|
237
|
+
"description": "OK",
|
|
238
|
+
"headers": {
|
|
239
|
+
"Cache-Control": { "$ref": "#/components/headers/CacheControl" },
|
|
240
|
+
"ETag": { "$ref": "#/components/headers/ETag" },
|
|
241
|
+
"Last-Modified": { "$ref": "#/components/headers/LastModified" }
|
|
242
|
+
}
|
|
243
|
+
},
|
|
244
|
+
"default": {
|
|
245
|
+
"content": {
|
|
246
|
+
"application/json": {
|
|
247
|
+
"schema": { "$ref": "#/components/schemas/Error" }
|
|
248
|
+
}
|
|
249
|
+
},
|
|
250
|
+
"description": "Error"
|
|
251
|
+
}
|
|
252
|
+
},
|
|
253
|
+
"summary": "Retrieve the uptime and player counts",
|
|
254
|
+
"tags": ["Status"],
|
|
255
|
+
"x-cache-age": 30,
|
|
256
|
+
"x-compatibility-date": "2020-01-01"
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
},
|
|
260
|
+
"servers": [{ "url": "https://esi.evetech.net" }],
|
|
261
|
+
"tags": [
|
|
262
|
+
{ "name": "Status" }
|
|
263
|
+
]
|
|
264
|
+
}
|
esi/tests/test_openapi.py
CHANGED
|
@@ -1,7 +1,219 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from unittest import mock
|
|
3
|
+
from unittest.mock import MagicMock, patch
|
|
1
4
|
from django.test import TestCase
|
|
2
|
-
from datetime import date
|
|
5
|
+
from datetime import date, timedelta
|
|
3
6
|
|
|
4
7
|
from esi.openapi_clients import ESIClientProvider
|
|
8
|
+
from django.utils import timezone
|
|
9
|
+
from httpx import RequestError, HTTPStatusError
|
|
10
|
+
from esi.exceptions import ESIErrorLimitException
|
|
11
|
+
from esi import app_settings
|
|
12
|
+
from esi import __title__, __url__, __version__
|
|
13
|
+
import httpx
|
|
14
|
+
|
|
15
|
+
from .. import openapi_clients as oc
|
|
16
|
+
|
|
17
|
+
SPEC_PATH = os.path.join(
|
|
18
|
+
os.path.dirname(os.path.abspath(__file__)), "test_openapi.json"
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class TestClientFunctions(TestCase):
|
|
23
|
+
def test_time_to_expiry_valid(self):
|
|
24
|
+
expires = (
|
|
25
|
+
timezone.now() + timedelta(seconds=120)
|
|
26
|
+
).strftime('%a, %d %b %Y %H:%M:%S %Z')
|
|
27
|
+
ttl = oc._time_to_expiry(expires)
|
|
28
|
+
|
|
29
|
+
# this shouldnt take more that 10 seconds
|
|
30
|
+
self.assertGreater(ttl, 110)
|
|
31
|
+
|
|
32
|
+
def test_time_to_expiry_invalid(self):
|
|
33
|
+
# invalid format returns 0
|
|
34
|
+
self.assertEqual(oc._time_to_expiry("not-a-date"), 0)
|
|
35
|
+
|
|
36
|
+
def test_httpx_exceptions_valids(self):
|
|
37
|
+
self.assertTrue(
|
|
38
|
+
oc._httpx_exceptions(
|
|
39
|
+
RequestError("Bad Request")
|
|
40
|
+
)
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
response = MagicMock(status_code=502)
|
|
44
|
+
exc = HTTPStatusError("msg", request=None, response=response)
|
|
45
|
+
|
|
46
|
+
self.assertTrue(
|
|
47
|
+
oc._httpx_exceptions(exc)
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
response.status_code = 400
|
|
51
|
+
exc = HTTPStatusError("msg", request=None, response=response)
|
|
52
|
+
|
|
53
|
+
self.assertFalse(
|
|
54
|
+
oc._httpx_exceptions(exc)
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
self.assertFalse(
|
|
58
|
+
oc._httpx_exceptions(
|
|
59
|
+
ESIErrorLimitException(reset=10)
|
|
60
|
+
)
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
def test_httpx_exceptions_invalid(self):
|
|
64
|
+
self.assertFalse(
|
|
65
|
+
oc._httpx_exceptions(
|
|
66
|
+
"this is not an exception!"
|
|
67
|
+
)
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
class BuildUserAgentTests(TestCase):
|
|
72
|
+
app_name = "TestsApp"
|
|
73
|
+
app_ver = "1.2.3"
|
|
74
|
+
app_url = "https://tests.pass"
|
|
75
|
+
|
|
76
|
+
def test_build_user_agent_with_url(self):
|
|
77
|
+
ua = oc._build_user_agent(self.app_name, self.app_ver, self.app_url)
|
|
78
|
+
self.assertEqual(
|
|
79
|
+
(
|
|
80
|
+
f"{self.app_name}/{self.app_ver} "
|
|
81
|
+
f"({app_settings.ESI_USER_CONTACT_EMAIL}{f'; +{self.app_url})'} "
|
|
82
|
+
f"{__title__}/{__version__} (+{__url__})"
|
|
83
|
+
),
|
|
84
|
+
ua
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
def test_build_user_agent_without_url(self):
|
|
88
|
+
ua = oc._build_user_agent(self.app_name, self.app_ver)
|
|
89
|
+
self.assertEqual(
|
|
90
|
+
(
|
|
91
|
+
f"{self.app_name}/{self.app_ver} "
|
|
92
|
+
f"({app_settings.ESI_USER_CONTACT_EMAIL}) "
|
|
93
|
+
f"{__title__}/{__version__} (+{__url__})"
|
|
94
|
+
),
|
|
95
|
+
ua
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
class BaseEsiOperationTests(TestCase):
|
|
100
|
+
def setUp(self):
|
|
101
|
+
self.page_param = MagicMock()
|
|
102
|
+
self.page_param.name = "page"
|
|
103
|
+
|
|
104
|
+
self.after_param = MagicMock()
|
|
105
|
+
self.after_param.name = "after"
|
|
106
|
+
|
|
107
|
+
self.before_param = MagicMock()
|
|
108
|
+
self.before_param.name = "before"
|
|
109
|
+
|
|
110
|
+
self.data_param = MagicMock()
|
|
111
|
+
self.data_param.name = "data"
|
|
112
|
+
|
|
113
|
+
self.lang_param = MagicMock()
|
|
114
|
+
self.lang_param.name = "Accept-Language"
|
|
115
|
+
|
|
116
|
+
self.body_param = MagicMock()
|
|
117
|
+
self.body_param.name = "body"
|
|
118
|
+
|
|
119
|
+
self.fake_op = MagicMock()
|
|
120
|
+
self.fake_op.parameters = [
|
|
121
|
+
self.data_param,
|
|
122
|
+
self.lang_param
|
|
123
|
+
]
|
|
124
|
+
self.fake_op.tags = ["test"]
|
|
125
|
+
self.fake_op.operationId = "fake_op"
|
|
126
|
+
self.api = MagicMock(app_name="TestApp")
|
|
127
|
+
self.op = oc.BaseEsiOperation(
|
|
128
|
+
("GET", "/fake_op", self.fake_op, {}),
|
|
129
|
+
self.api
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
def test_non_unique_kwargs(self):
|
|
133
|
+
op_1 = self.op(data="bar")
|
|
134
|
+
key_1 = op_1._cache_key()
|
|
135
|
+
op_2 = self.op(data="foo")
|
|
136
|
+
key_2 = op_2._cache_key()
|
|
137
|
+
self.assertNotEqual(key_1, key_2)
|
|
138
|
+
|
|
139
|
+
def test_unique_kwargs(self):
|
|
140
|
+
op_1 = self.op(data="foo")
|
|
141
|
+
key_1 = op_1._cache_key()
|
|
142
|
+
op_2 = self.op(data="foo")
|
|
143
|
+
key_2 = op_2._cache_key()
|
|
144
|
+
self.assertEqual(key_1, key_2)
|
|
145
|
+
|
|
146
|
+
def test_extract_body(self):
|
|
147
|
+
test_body = "something somethng something..."
|
|
148
|
+
op = self.op(body=test_body)
|
|
149
|
+
body = op._extract_body_param()
|
|
150
|
+
self.assertEqual(test_body, body)
|
|
151
|
+
|
|
152
|
+
def test_extract_body_exception(self):
|
|
153
|
+
test_body = "something somethng something..."
|
|
154
|
+
self.fake_op.requestBody = False
|
|
155
|
+
op = self.op(body=test_body)
|
|
156
|
+
with self.assertRaises(ValueError):
|
|
157
|
+
op._extract_body_param()
|
|
158
|
+
|
|
159
|
+
def test_extract_token(self):
|
|
160
|
+
test_tkn = {"token": "token model goes here"}
|
|
161
|
+
op = self.op(token=test_tkn)
|
|
162
|
+
token = op._extract_token_param()
|
|
163
|
+
self.assertEqual(test_tkn, token)
|
|
164
|
+
|
|
165
|
+
def test_extract_token_exception_no_token_needed(self):
|
|
166
|
+
self.op._kwargs = {"token": "token"}
|
|
167
|
+
self.fake_op.security = None
|
|
168
|
+
with self.assertRaises(ValueError):
|
|
169
|
+
self.op._extract_token_param()
|
|
170
|
+
|
|
171
|
+
def test_not_page_or_cursor_param(self):
|
|
172
|
+
self.assertFalse(self.op._has_page_param())
|
|
173
|
+
self.assertFalse(self.op._has_cursor_param())
|
|
174
|
+
|
|
175
|
+
def test_has_page_param(self):
|
|
176
|
+
self.fake_op.parameters += [self.page_param]
|
|
177
|
+
op = self.op()
|
|
178
|
+
self.assertTrue(op._has_page_param())
|
|
179
|
+
|
|
180
|
+
def test_has_cursor_params(self):
|
|
181
|
+
self.fake_op.parameters = [self.after_param]
|
|
182
|
+
op = self.op()
|
|
183
|
+
self.assertTrue(op._has_cursor_param())
|
|
184
|
+
|
|
185
|
+
self.fake_op.parameters = [self.before_param]
|
|
186
|
+
op = self.op()
|
|
187
|
+
self.assertTrue(op._has_cursor_param())
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
class EsiOperationTests(TestCase):
|
|
191
|
+
def setUp(self):
|
|
192
|
+
self.op_mock = MagicMock()
|
|
193
|
+
self.op_mock.parameters = []
|
|
194
|
+
self.op_mock.tags = ["tag"]
|
|
195
|
+
self.op_mock.operationId = "opid"
|
|
196
|
+
|
|
197
|
+
self.api_mock = MagicMock()
|
|
198
|
+
self.api_mock.app_name = "TestApp"
|
|
199
|
+
|
|
200
|
+
self.op = oc.EsiOperation(
|
|
201
|
+
(
|
|
202
|
+
"GET",
|
|
203
|
+
"/url",
|
|
204
|
+
self.op_mock,
|
|
205
|
+
{}
|
|
206
|
+
),
|
|
207
|
+
self.api_mock
|
|
208
|
+
)
|
|
209
|
+
|
|
210
|
+
@patch.object(oc.EsiOperation, "_make_request")
|
|
211
|
+
def test_result_and_results(self, mock_make_request):
|
|
212
|
+
data = {"data": "stuff"}
|
|
213
|
+
mock_resp = MagicMock(status_code=200, headers={"Expires": "Wed, 1 July 2099 11:00:00 GMT"})
|
|
214
|
+
mock_make_request.return_value = ({"Expires": "date"}, data, mock_resp)
|
|
215
|
+
data_resp = self.op(foo="bar").result()
|
|
216
|
+
self.assertEqual(data, data_resp)
|
|
5
217
|
|
|
6
218
|
|
|
7
219
|
class TestOpenapiClientProvider(TestCase):
|
|
@@ -12,3 +224,38 @@ class TestOpenapiClientProvider(TestCase):
|
|
|
12
224
|
|
|
13
225
|
self.assertEqual("2024-01-01", ESIClientProvider._date_to_string(testdate_1))
|
|
14
226
|
self.assertEqual("2025-08-26", ESIClientProvider._date_to_string(testdate_2))
|
|
227
|
+
|
|
228
|
+
@patch.object(httpx.Client, "send")
|
|
229
|
+
def test_ua(self, send: MagicMock):
|
|
230
|
+
app_name = "TestsApp"
|
|
231
|
+
app_ver = "1.2.3"
|
|
232
|
+
app_url = "https://tests.pass"
|
|
233
|
+
esi = ESIClientProvider(
|
|
234
|
+
ua_appname=app_name,
|
|
235
|
+
ua_url=app_url,
|
|
236
|
+
ua_version=app_ver,
|
|
237
|
+
compatibility_date="2020-01-01",
|
|
238
|
+
spec_file=SPEC_PATH
|
|
239
|
+
)
|
|
240
|
+
|
|
241
|
+
send.return_value = httpx.Response(
|
|
242
|
+
200,
|
|
243
|
+
json={
|
|
244
|
+
"players": 1234,
|
|
245
|
+
"server_version": "1234",
|
|
246
|
+
"start_time": "2029-09-19T11:02:08Z"
|
|
247
|
+
},
|
|
248
|
+
request=httpx.Request("GET", "test"),
|
|
249
|
+
)
|
|
250
|
+
|
|
251
|
+
status = esi.client.Status.GetStatus().result()
|
|
252
|
+
call_args, call_kwargs = send.call_args
|
|
253
|
+
self.assertEqual(
|
|
254
|
+
call_args[0].headers["user-agent"],
|
|
255
|
+
(
|
|
256
|
+
f"{app_name}/{app_ver} "
|
|
257
|
+
f"({app_settings.ESI_USER_CONTACT_EMAIL}{f'; +{app_url})'} "
|
|
258
|
+
f"{__title__}/{__version__} (+{__url__})"
|
|
259
|
+
)
|
|
260
|
+
)
|
|
261
|
+
self.assertEqual(status.players, 1234)
|
|
File without changes
|
|
File without changes
|