aa-intel-tool 2.6.1__py3-none-any.whl → 2.6.2__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.
- aa_intel_tool/__init__.py +1 -1
- aa_intel_tool/helper/eve_character.py +24 -36
- aa_intel_tool/helper/static_files.py +2 -2
- aa_intel_tool/locale/cs_CZ/LC_MESSAGES/django.po +9 -9
- aa_intel_tool/locale/de/LC_MESSAGES/django.mo +0 -0
- aa_intel_tool/locale/de/LC_MESSAGES/django.po +13 -13
- aa_intel_tool/locale/django.pot +10 -10
- aa_intel_tool/locale/es/LC_MESSAGES/django.po +9 -9
- aa_intel_tool/locale/fr_FR/LC_MESSAGES/django.mo +0 -0
- aa_intel_tool/locale/fr_FR/LC_MESSAGES/django.po +13 -13
- aa_intel_tool/locale/it_IT/LC_MESSAGES/django.po +9 -9
- aa_intel_tool/locale/ja/LC_MESSAGES/django.po +9 -9
- aa_intel_tool/locale/ko_KR/LC_MESSAGES/django.po +9 -9
- aa_intel_tool/locale/nl_NL/LC_MESSAGES/django.po +9 -9
- aa_intel_tool/locale/pl_PL/LC_MESSAGES/django.po +9 -9
- aa_intel_tool/locale/ru/LC_MESSAGES/django.mo +0 -0
- aa_intel_tool/locale/ru/LC_MESSAGES/django.po +13 -13
- aa_intel_tool/locale/sk/LC_MESSAGES/django.po +9 -9
- aa_intel_tool/locale/uk/LC_MESSAGES/django.mo +0 -0
- aa_intel_tool/locale/uk/LC_MESSAGES/django.po +15 -15
- aa_intel_tool/locale/zh_Hans/LC_MESSAGES/django.po +9 -9
- aa_intel_tool/parser/general.py +11 -16
- aa_intel_tool/parser/helper/db.py +8 -11
- aa_intel_tool/parser/module/chatlist.py +97 -126
- aa_intel_tool/parser/module/dscan.py +115 -147
- aa_intel_tool/parser/module/fleetcomp.py +85 -102
- aa_intel_tool/static/aa_intel_tool/css/aa-intel-tool.css +6 -19
- aa_intel_tool/static/aa_intel_tool/css/aa-intel-tool.min.css +1 -1
- aa_intel_tool/static/aa_intel_tool/css/aa-intel-tool.min.css.map +1 -1
- aa_intel_tool/static/aa_intel_tool/javascript/aa-intel-tool-chatscan-highlight.js +104 -64
- aa_intel_tool/static/aa_intel_tool/javascript/aa-intel-tool-chatscan-highlight.min.js.map +1 -1
- aa_intel_tool/static/aa_intel_tool/javascript/aa-intel-tool-chatscan.js +2 -2
- aa_intel_tool/static/aa_intel_tool/javascript/aa-intel-tool-chatscan.min.js +1 -1
- aa_intel_tool/static/aa_intel_tool/javascript/aa-intel-tool-dscan-highlight.js +43 -43
- aa_intel_tool/static/aa_intel_tool/javascript/aa-intel-tool-dscan-highlight.min.js.map +1 -1
- aa_intel_tool/static/aa_intel_tool/javascript/aa-intel-tool-dscan.js +31 -7
- aa_intel_tool/static/aa_intel_tool/javascript/aa-intel-tool-dscan.min.js +1 -1
- aa_intel_tool/static/aa_intel_tool/javascript/aa-intel-tool-dscan.min.js.map +1 -1
- aa_intel_tool/static/aa_intel_tool/javascript/aa-intel-tool-fleetcomposition-highlight.js +51 -51
- aa_intel_tool/static/aa_intel_tool/javascript/aa-intel-tool-fleetcomposition-highlight.min.js.map +1 -1
- aa_intel_tool/static/aa_intel_tool/javascript/aa-intel-tool-fleetcomposition.js +9 -3
- aa_intel_tool/static/aa_intel_tool/javascript/aa-intel-tool-fleetcomposition.min.js +1 -1
- aa_intel_tool/static/aa_intel_tool/javascript/aa-intel-tool-fleetcomposition.min.js.map +1 -1
- aa_intel_tool/static/aa_intel_tool/javascript/aa-intel-tool-scan-result-common.js +53 -31
- aa_intel_tool/static/aa_intel_tool/javascript/aa-intel-tool-scan-result-common.min.js +1 -1
- aa_intel_tool/static/aa_intel_tool/javascript/aa-intel-tool-scan-result-common.min.js.map +1 -1
- aa_intel_tool/templates/aa_intel_tool/partials/scan/evetime.html +1 -1
- aa_intel_tool/tests/test-data/dscan.txt +250 -0
- aa_intel_tool/tests/test_admin.py +50 -38
- aa_intel_tool/tests/test_helper_eve_character.py +405 -0
- aa_intel_tool/tests/test_models.py +188 -4
- aa_intel_tool/tests/test_parser_general.py +771 -0
- aa_intel_tool/tests/test_parser_module_chatlist.py +154 -0
- {aa_intel_tool-2.6.1.dist-info → aa_intel_tool-2.6.2.dist-info}/METADATA +1 -1
- {aa_intel_tool-2.6.1.dist-info → aa_intel_tool-2.6.2.dist-info}/RECORD +57 -55
- aa_intel_tool/tests/test_parser.py +0 -135
- {aa_intel_tool-2.6.1.dist-info → aa_intel_tool-2.6.2.dist-info}/WHEEL +0 -0
- {aa_intel_tool-2.6.1.dist-info → aa_intel_tool-2.6.2.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,771 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Testing the parsers
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
# Standard Library
|
|
6
|
+
from unittest.mock import MagicMock, patch
|
|
7
|
+
|
|
8
|
+
# Django
|
|
9
|
+
from django.test import TestCase
|
|
10
|
+
|
|
11
|
+
# Alliance Auth (External Libs)
|
|
12
|
+
from eveuniverse.models import EveEntity
|
|
13
|
+
|
|
14
|
+
# AA Intel Tool
|
|
15
|
+
from aa_intel_tool.exceptions import ParserError
|
|
16
|
+
from aa_intel_tool.parser.general import check_intel_type, parse_intel
|
|
17
|
+
from aa_intel_tool.parser.module.chatlist import (
|
|
18
|
+
_get_character_info,
|
|
19
|
+
_get_unaffiliated_alliance_info,
|
|
20
|
+
_parse_alliance_info,
|
|
21
|
+
_parse_character_info,
|
|
22
|
+
_parse_chatscan_data,
|
|
23
|
+
_parse_corporation_info,
|
|
24
|
+
)
|
|
25
|
+
from aa_intel_tool.tests.utils import (
|
|
26
|
+
load_chatscan_faulty_txt,
|
|
27
|
+
load_chatscan_txt,
|
|
28
|
+
load_dscan_txt,
|
|
29
|
+
load_fleetcomp_txt,
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class TestCheckIntelType(TestCase):
|
|
34
|
+
"""
|
|
35
|
+
Test the check_intel_type function
|
|
36
|
+
"""
|
|
37
|
+
|
|
38
|
+
def test_check_intel_type_dscan(self):
|
|
39
|
+
"""
|
|
40
|
+
Test should return 'dscan' as the expected intel type
|
|
41
|
+
|
|
42
|
+
:return:
|
|
43
|
+
:rtype:
|
|
44
|
+
"""
|
|
45
|
+
|
|
46
|
+
form_data = load_dscan_txt()
|
|
47
|
+
scan_data = str(form_data).splitlines()
|
|
48
|
+
|
|
49
|
+
intel_type = check_intel_type(scan_data=scan_data)
|
|
50
|
+
expected_intel_type = "dscan"
|
|
51
|
+
|
|
52
|
+
self.assertEqual(first=intel_type, second=expected_intel_type)
|
|
53
|
+
|
|
54
|
+
def test_check_intel_type_chatlist(self):
|
|
55
|
+
"""
|
|
56
|
+
Test should return 'chatlist' as the expected intel type
|
|
57
|
+
|
|
58
|
+
:return:
|
|
59
|
+
:rtype:
|
|
60
|
+
"""
|
|
61
|
+
|
|
62
|
+
form_data = load_chatscan_txt()
|
|
63
|
+
scan_data = str(form_data).splitlines()
|
|
64
|
+
|
|
65
|
+
intel_type = check_intel_type(scan_data=scan_data)
|
|
66
|
+
expected_intel_type = "chatlist"
|
|
67
|
+
|
|
68
|
+
self.assertEqual(first=intel_type, second=expected_intel_type)
|
|
69
|
+
|
|
70
|
+
def test_check_intel_type_fleetcomp(self):
|
|
71
|
+
"""
|
|
72
|
+
Test should return 'fleetcomp' as the expected intel type
|
|
73
|
+
|
|
74
|
+
:return:
|
|
75
|
+
:rtype:
|
|
76
|
+
"""
|
|
77
|
+
|
|
78
|
+
form_data = load_fleetcomp_txt()
|
|
79
|
+
scan_data = str(form_data).splitlines()
|
|
80
|
+
|
|
81
|
+
intel_type = check_intel_type(scan_data=scan_data)
|
|
82
|
+
expected_intel_type = "fleetcomp"
|
|
83
|
+
|
|
84
|
+
self.assertEqual(first=intel_type, second=expected_intel_type)
|
|
85
|
+
|
|
86
|
+
def test_check_intel_type_malformed_data(self):
|
|
87
|
+
"""
|
|
88
|
+
Test should throw a ParserError as the expected intel type
|
|
89
|
+
This happens when invalid data has been posted
|
|
90
|
+
|
|
91
|
+
:return:
|
|
92
|
+
:rtype:
|
|
93
|
+
"""
|
|
94
|
+
|
|
95
|
+
form_data = load_chatscan_faulty_txt()
|
|
96
|
+
scan_data = str(form_data).splitlines()
|
|
97
|
+
|
|
98
|
+
expected_exception = ParserError
|
|
99
|
+
expected_message = "A parser error occurred » No suitable parser found. Input is not a supported intel type or malformed …" # pylint: disable=line-too-long
|
|
100
|
+
|
|
101
|
+
with self.assertRaises(expected_exception=expected_exception):
|
|
102
|
+
check_intel_type(scan_data=scan_data)
|
|
103
|
+
|
|
104
|
+
with self.assertRaisesMessage(
|
|
105
|
+
expected_exception=expected_exception, expected_message=expected_message
|
|
106
|
+
):
|
|
107
|
+
check_intel_type(scan_data=scan_data)
|
|
108
|
+
|
|
109
|
+
def test_parse_intel_with_invalid_form_data(self):
|
|
110
|
+
"""
|
|
111
|
+
Test should return a ParserError as parsed intel data for invalid form data
|
|
112
|
+
|
|
113
|
+
:return:
|
|
114
|
+
:rtype:
|
|
115
|
+
"""
|
|
116
|
+
|
|
117
|
+
form_data = load_chatscan_faulty_txt()
|
|
118
|
+
|
|
119
|
+
expected_exception = ParserError
|
|
120
|
+
expected_message = "A parser error occurred » No suitable parser found. Input is not a supported intel type or malformed …" # pylint: disable=line-too-long
|
|
121
|
+
|
|
122
|
+
with self.assertRaises(ParserError):
|
|
123
|
+
parse_intel(form_data=form_data)
|
|
124
|
+
|
|
125
|
+
with self.assertRaisesMessage(
|
|
126
|
+
expected_exception=expected_exception, expected_message=expected_message
|
|
127
|
+
):
|
|
128
|
+
parse_intel(form_data=form_data)
|
|
129
|
+
|
|
130
|
+
def test_parse_intel_empty_form_data(self):
|
|
131
|
+
"""
|
|
132
|
+
Test should throw a ParserError as parsed intel data for empty form data
|
|
133
|
+
|
|
134
|
+
:return:
|
|
135
|
+
:rtype:
|
|
136
|
+
"""
|
|
137
|
+
|
|
138
|
+
form_data = ""
|
|
139
|
+
|
|
140
|
+
expected_exception = ParserError
|
|
141
|
+
expected_message = "A parser error occurred » No data to parse …"
|
|
142
|
+
|
|
143
|
+
with self.assertRaises(expected_exception=expected_exception):
|
|
144
|
+
parse_intel(form_data=form_data)
|
|
145
|
+
|
|
146
|
+
with self.assertRaisesMessage(
|
|
147
|
+
expected_exception=expected_exception, expected_message=expected_message
|
|
148
|
+
):
|
|
149
|
+
parse_intel(form_data=form_data)
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
class TestParseIntel(TestCase):
|
|
153
|
+
"""
|
|
154
|
+
Test the parse_intel function
|
|
155
|
+
"""
|
|
156
|
+
|
|
157
|
+
@patch("aa_intel_tool.parser.general.check_intel_type")
|
|
158
|
+
@patch(
|
|
159
|
+
"aa_intel_tool.parser.general.SUPPORTED_INTEL_TYPES",
|
|
160
|
+
{"dscan": {"parser": MagicMock(return_value=MagicMock(hash="hash1"))}},
|
|
161
|
+
)
|
|
162
|
+
def test_parses_valid_dscan_data(self, mock_check_intel_type):
|
|
163
|
+
"""
|
|
164
|
+
Test should return the hash of the parsed intel data for valid dscan data
|
|
165
|
+
|
|
166
|
+
:param mock_check_intel_type:
|
|
167
|
+
:type mock_check_intel_type:
|
|
168
|
+
:return:
|
|
169
|
+
:rtype:
|
|
170
|
+
"""
|
|
171
|
+
|
|
172
|
+
mock_check_intel_type.return_value = "dscan"
|
|
173
|
+
form_data = load_dscan_txt()
|
|
174
|
+
result = parse_intel(form_data)
|
|
175
|
+
|
|
176
|
+
self.assertEqual(result, "hash1")
|
|
177
|
+
|
|
178
|
+
@patch("aa_intel_tool.parser.general.check_intel_type")
|
|
179
|
+
@patch(
|
|
180
|
+
"aa_intel_tool.parser.general.SUPPORTED_INTEL_TYPES",
|
|
181
|
+
{"fleetcomp": {"parser": MagicMock(return_value=MagicMock(hash="hash2"))}},
|
|
182
|
+
)
|
|
183
|
+
def test_parses_valid_fleetcomp_data(self, mock_check_intel_type):
|
|
184
|
+
"""
|
|
185
|
+
Test should return the hash of the parsed intel data for valid fleetcomp data
|
|
186
|
+
|
|
187
|
+
:param mock_check_intel_type:
|
|
188
|
+
:type mock_check_intel_type:
|
|
189
|
+
:return:
|
|
190
|
+
:rtype:
|
|
191
|
+
"""
|
|
192
|
+
|
|
193
|
+
mock_check_intel_type.return_value = "fleetcomp"
|
|
194
|
+
form_data = load_fleetcomp_txt()
|
|
195
|
+
result = parse_intel(form_data)
|
|
196
|
+
|
|
197
|
+
self.assertEqual(result, "hash2")
|
|
198
|
+
|
|
199
|
+
@patch("aa_intel_tool.parser.general.check_intel_type")
|
|
200
|
+
@patch(
|
|
201
|
+
"aa_intel_tool.parser.general.SUPPORTED_INTEL_TYPES",
|
|
202
|
+
{"chatscan": {"parser": MagicMock(return_value=MagicMock(hash="hash3"))}},
|
|
203
|
+
)
|
|
204
|
+
def test_parses_valid_chatscan_data(self, mock_check_intel_type):
|
|
205
|
+
"""
|
|
206
|
+
Test should return the hash of the parsed intel data for valid chatscan data
|
|
207
|
+
|
|
208
|
+
:param mock_check_intel_type:
|
|
209
|
+
:type mock_check_intel_type:
|
|
210
|
+
:return:
|
|
211
|
+
:rtype:
|
|
212
|
+
"""
|
|
213
|
+
|
|
214
|
+
mock_check_intel_type.return_value = "chatscan"
|
|
215
|
+
form_data = load_chatscan_txt()
|
|
216
|
+
result = parse_intel(form_data)
|
|
217
|
+
|
|
218
|
+
self.assertEqual(result, "hash3")
|
|
219
|
+
|
|
220
|
+
@patch("aa_intel_tool.parser.general.check_intel_type")
|
|
221
|
+
def test_raises_error_for_invalid_data(self, mock_check_intel_type):
|
|
222
|
+
"""
|
|
223
|
+
Test should throw a ParserError as parsed intel data for invalid data
|
|
224
|
+
|
|
225
|
+
:param mock_check_intel_type:
|
|
226
|
+
:type mock_check_intel_type:
|
|
227
|
+
:return:
|
|
228
|
+
:rtype:
|
|
229
|
+
"""
|
|
230
|
+
|
|
231
|
+
mock_check_intel_type.side_effect = ParserError("Invalid data")
|
|
232
|
+
form_data = load_chatscan_faulty_txt()
|
|
233
|
+
|
|
234
|
+
with self.assertRaises(ParserError):
|
|
235
|
+
parse_intel(form_data)
|
|
236
|
+
|
|
237
|
+
def test_raises_error_for_empty_data(self):
|
|
238
|
+
"""
|
|
239
|
+
Test should throw a ParserError as parsed intel data for empty form data
|
|
240
|
+
|
|
241
|
+
:return:
|
|
242
|
+
:rtype:
|
|
243
|
+
"""
|
|
244
|
+
|
|
245
|
+
form_data = ""
|
|
246
|
+
|
|
247
|
+
with self.assertRaises(ParserError):
|
|
248
|
+
parse_intel(form_data)
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
class TestParseChatScanData(TestCase):
|
|
252
|
+
"""
|
|
253
|
+
Test the _parse_chatscan_data function
|
|
254
|
+
"""
|
|
255
|
+
|
|
256
|
+
@patch("aa_intel_tool.parser.module.chatlist._parse_alliance_info")
|
|
257
|
+
@patch("aa_intel_tool.parser.module.chatlist._parse_corporation_info")
|
|
258
|
+
@patch("aa_intel_tool.parser.module.chatlist._parse_character_info")
|
|
259
|
+
def test_parses_valid_characters(
|
|
260
|
+
self,
|
|
261
|
+
mock_parse_character_info,
|
|
262
|
+
mock_parse_corporation_info,
|
|
263
|
+
mock_parse_alliance_info,
|
|
264
|
+
):
|
|
265
|
+
"""
|
|
266
|
+
Test should parse valid chatscan data and return a dictionary
|
|
267
|
+
|
|
268
|
+
:param mock_parse_character_info:
|
|
269
|
+
:type mock_parse_character_info:
|
|
270
|
+
:param mock_parse_corporation_info:
|
|
271
|
+
:type mock_parse_corporation_info:
|
|
272
|
+
:param mock_parse_alliance_info:
|
|
273
|
+
:type mock_parse_alliance_info:
|
|
274
|
+
:return:
|
|
275
|
+
:rtype:
|
|
276
|
+
"""
|
|
277
|
+
|
|
278
|
+
eve_characters = MagicMock()
|
|
279
|
+
eve_characters.__iter__.return_value = [
|
|
280
|
+
MagicMock(
|
|
281
|
+
character_name="Character1",
|
|
282
|
+
alliance_name="Alliance1",
|
|
283
|
+
corporation_name="Corp1",
|
|
284
|
+
),
|
|
285
|
+
MagicMock(
|
|
286
|
+
character_name="Character2",
|
|
287
|
+
alliance_name="Alliance2",
|
|
288
|
+
corporation_name="Corp2",
|
|
289
|
+
),
|
|
290
|
+
]
|
|
291
|
+
mock_parse_character_info.side_effect = lambda eve_character: {
|
|
292
|
+
"name": eve_character.character_name
|
|
293
|
+
}
|
|
294
|
+
mock_parse_corporation_info.side_effect = lambda eve_character: {
|
|
295
|
+
"name": eve_character.corporation_name
|
|
296
|
+
}
|
|
297
|
+
mock_parse_alliance_info.side_effect = lambda eve_character: {
|
|
298
|
+
"name": eve_character.alliance_name
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
result = _parse_chatscan_data(eve_characters)
|
|
302
|
+
|
|
303
|
+
self.assertEqual(len(result["pilots"]), 2)
|
|
304
|
+
self.assertEqual(len(result["corporations"]), 2)
|
|
305
|
+
self.assertEqual(len(result["alliances"]), 2)
|
|
306
|
+
|
|
307
|
+
@patch("aa_intel_tool.parser.module.chatlist._parse_alliance_info")
|
|
308
|
+
@patch("aa_intel_tool.parser.module.chatlist._parse_corporation_info")
|
|
309
|
+
@patch("aa_intel_tool.parser.module.chatlist._parse_character_info")
|
|
310
|
+
def test_handles_unaffiliated_characters(
|
|
311
|
+
self,
|
|
312
|
+
mock_parse_character_info,
|
|
313
|
+
mock_parse_corporation_info,
|
|
314
|
+
mock_parse_alliance_info,
|
|
315
|
+
):
|
|
316
|
+
"""
|
|
317
|
+
Test should handle unaffiliated characters and return "Unaffiliated" as the alliance name
|
|
318
|
+
|
|
319
|
+
:param mock_parse_character_info:
|
|
320
|
+
:type mock_parse_character_info:
|
|
321
|
+
:param mock_parse_corporation_info:
|
|
322
|
+
:type mock_parse_corporation_info:
|
|
323
|
+
:param mock_parse_alliance_info:
|
|
324
|
+
:type mock_parse_alliance_info:
|
|
325
|
+
:return:
|
|
326
|
+
:rtype:
|
|
327
|
+
"""
|
|
328
|
+
|
|
329
|
+
eve_characters = MagicMock()
|
|
330
|
+
eve_characters.__iter__.return_value = [
|
|
331
|
+
MagicMock(
|
|
332
|
+
character_name="Character1",
|
|
333
|
+
alliance_name=None,
|
|
334
|
+
corporation_name="Corp1",
|
|
335
|
+
)
|
|
336
|
+
]
|
|
337
|
+
mock_parse_character_info.side_effect = lambda eve_character: {
|
|
338
|
+
"name": eve_character.character_name
|
|
339
|
+
}
|
|
340
|
+
mock_parse_corporation_info.side_effect = lambda eve_character: {
|
|
341
|
+
"name": eve_character.corporation_name
|
|
342
|
+
}
|
|
343
|
+
mock_parse_alliance_info.side_effect = lambda eve_character: {
|
|
344
|
+
"name": "Unaffiliated"
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
result = _parse_chatscan_data(eve_characters)
|
|
348
|
+
|
|
349
|
+
self.assertEqual(result["alliances"][0]["name"], "Unaffiliated")
|
|
350
|
+
|
|
351
|
+
@patch("aa_intel_tool.parser.module.chatlist._parse_alliance_info")
|
|
352
|
+
@patch("aa_intel_tool.parser.module.chatlist._parse_corporation_info")
|
|
353
|
+
@patch("aa_intel_tool.parser.module.chatlist._parse_character_info")
|
|
354
|
+
def test_counts_characters_correctly(
|
|
355
|
+
self,
|
|
356
|
+
mock_parse_character_info,
|
|
357
|
+
mock_parse_corporation_info,
|
|
358
|
+
mock_parse_alliance_info,
|
|
359
|
+
):
|
|
360
|
+
"""
|
|
361
|
+
Test should count characters correctly and return the correct counts for alliances and corporations
|
|
362
|
+
|
|
363
|
+
:param mock_parse_character_info:
|
|
364
|
+
:type mock_parse_character_info:
|
|
365
|
+
:param mock_parse_corporation_info:
|
|
366
|
+
:type mock_parse_corporation_info:
|
|
367
|
+
:param mock_parse_alliance_info:
|
|
368
|
+
:type mock_parse_alliance_info:
|
|
369
|
+
:return:
|
|
370
|
+
:rtype:
|
|
371
|
+
"""
|
|
372
|
+
|
|
373
|
+
eve_characters = MagicMock()
|
|
374
|
+
eve_characters.__iter__.return_value = [
|
|
375
|
+
MagicMock(
|
|
376
|
+
character_name="Character1",
|
|
377
|
+
alliance_name="Alliance1",
|
|
378
|
+
corporation_name="Corp1",
|
|
379
|
+
),
|
|
380
|
+
MagicMock(
|
|
381
|
+
character_name="Character2",
|
|
382
|
+
alliance_name="Alliance1",
|
|
383
|
+
corporation_name="Corp1",
|
|
384
|
+
),
|
|
385
|
+
MagicMock(
|
|
386
|
+
character_name="Character3",
|
|
387
|
+
alliance_name="Alliance2",
|
|
388
|
+
corporation_name="Corp2",
|
|
389
|
+
),
|
|
390
|
+
]
|
|
391
|
+
mock_parse_character_info.side_effect = lambda eve_character: {
|
|
392
|
+
"name": eve_character.character_name
|
|
393
|
+
}
|
|
394
|
+
mock_parse_corporation_info.side_effect = lambda eve_character: {
|
|
395
|
+
"name": eve_character.corporation_name
|
|
396
|
+
}
|
|
397
|
+
mock_parse_alliance_info.side_effect = lambda eve_character: {
|
|
398
|
+
"name": eve_character.alliance_name
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
result = _parse_chatscan_data(eve_characters)
|
|
402
|
+
|
|
403
|
+
self.assertEqual(result["alliances"][0]["count"], 2)
|
|
404
|
+
self.assertEqual(result["corporations"][0]["count"], 2)
|
|
405
|
+
self.assertEqual(result["alliances"][1]["count"], 1)
|
|
406
|
+
self.assertEqual(result["corporations"][1]["count"], 1)
|
|
407
|
+
|
|
408
|
+
|
|
409
|
+
class TestParseCharacterInfo(TestCase):
|
|
410
|
+
"""
|
|
411
|
+
Test the _parse_character_info function
|
|
412
|
+
"""
|
|
413
|
+
|
|
414
|
+
@patch("aa_intel_tool.parser.module.chatlist._parse_alliance_info")
|
|
415
|
+
@patch("aa_intel_tool.parser.module.chatlist._parse_corporation_info")
|
|
416
|
+
def test_parses_valid_character_info(
|
|
417
|
+
self, mock_parse_corporation_info, mock_parse_alliance_info
|
|
418
|
+
):
|
|
419
|
+
"""
|
|
420
|
+
Test should parse valid character info and return a dictionary
|
|
421
|
+
|
|
422
|
+
:param mock_parse_corporation_info:
|
|
423
|
+
:type mock_parse_corporation_info:
|
|
424
|
+
:param mock_parse_alliance_info:
|
|
425
|
+
:type mock_parse_alliance_info:
|
|
426
|
+
:return:
|
|
427
|
+
:rtype:
|
|
428
|
+
"""
|
|
429
|
+
|
|
430
|
+
eve_character = MagicMock(
|
|
431
|
+
character_id=123,
|
|
432
|
+
character_name="Character1",
|
|
433
|
+
portrait_url_32="portrait_url",
|
|
434
|
+
)
|
|
435
|
+
mock_parse_corporation_info.return_value = {"name": "Corp1"}
|
|
436
|
+
mock_parse_alliance_info.return_value = {"name": "Alliance1"}
|
|
437
|
+
|
|
438
|
+
result = _parse_character_info(eve_character)
|
|
439
|
+
|
|
440
|
+
self.assertEqual(result["id"], 123)
|
|
441
|
+
self.assertEqual(result["name"], "Character1")
|
|
442
|
+
self.assertEqual(result["portrait"], "portrait_url")
|
|
443
|
+
self.assertEqual(result["corporation"]["name"], "Corp1")
|
|
444
|
+
self.assertEqual(result["alliance"]["name"], "Alliance1")
|
|
445
|
+
|
|
446
|
+
@patch("aa_intel_tool.parser.module.chatlist._parse_alliance_info")
|
|
447
|
+
@patch("aa_intel_tool.parser.module.chatlist._parse_corporation_info")
|
|
448
|
+
def test_handles_missing_alliance_info(
|
|
449
|
+
self, mock_parse_corporation_info, mock_parse_alliance_info
|
|
450
|
+
):
|
|
451
|
+
"""
|
|
452
|
+
Test should handle missing alliance info and return "Unaffiliated" as the alliance name
|
|
453
|
+
|
|
454
|
+
:param mock_parse_corporation_info:
|
|
455
|
+
:type mock_parse_corporation_info:
|
|
456
|
+
:param mock_parse_alliance_info:
|
|
457
|
+
:type mock_parse_alliance_info:
|
|
458
|
+
:return:
|
|
459
|
+
:rtype:
|
|
460
|
+
"""
|
|
461
|
+
|
|
462
|
+
eve_character = MagicMock(
|
|
463
|
+
character_id=123,
|
|
464
|
+
character_name="Character1",
|
|
465
|
+
portrait_url_32="portrait_url",
|
|
466
|
+
)
|
|
467
|
+
mock_parse_corporation_info.return_value = {"name": "Corp1"}
|
|
468
|
+
mock_parse_alliance_info.return_value = {"name": "Unaffiliated"}
|
|
469
|
+
|
|
470
|
+
result = _parse_character_info(eve_character)
|
|
471
|
+
|
|
472
|
+
self.assertEqual(result["alliance"]["name"], "Unaffiliated")
|
|
473
|
+
|
|
474
|
+
|
|
475
|
+
class TestParseCorporationInfo(TestCase):
|
|
476
|
+
"""
|
|
477
|
+
Test the _parse_corporation_info function
|
|
478
|
+
"""
|
|
479
|
+
|
|
480
|
+
@patch("aa_intel_tool.parser.module.chatlist._parse_alliance_info")
|
|
481
|
+
def test_parses_valid_corporation_info(self, mock_parse_alliance_info):
|
|
482
|
+
"""
|
|
483
|
+
Test should parse valid corporation info and return a dictionary
|
|
484
|
+
|
|
485
|
+
:param mock_parse_alliance_info:
|
|
486
|
+
:type mock_parse_alliance_info:
|
|
487
|
+
:return:
|
|
488
|
+
:rtype:
|
|
489
|
+
"""
|
|
490
|
+
|
|
491
|
+
eve_character = MagicMock(
|
|
492
|
+
corporation_id=456,
|
|
493
|
+
corporation_name="Corp1",
|
|
494
|
+
corporation_ticker="C1",
|
|
495
|
+
corporation_logo_url_32="corp_logo_url",
|
|
496
|
+
)
|
|
497
|
+
mock_parse_alliance_info.return_value = {"name": "Alliance1"}
|
|
498
|
+
|
|
499
|
+
result = _parse_corporation_info(eve_character)
|
|
500
|
+
|
|
501
|
+
self.assertEqual(result["id"], 456)
|
|
502
|
+
self.assertEqual(result["name"], "Corp1")
|
|
503
|
+
self.assertEqual(result["ticker"], "C1")
|
|
504
|
+
self.assertEqual(result["logo"], "corp_logo_url")
|
|
505
|
+
self.assertEqual(result["alliance"]["name"], "Alliance1")
|
|
506
|
+
|
|
507
|
+
@patch("aa_intel_tool.parser.module.chatlist._parse_alliance_info")
|
|
508
|
+
def test_handles_missing_alliance_info(self, mock_parse_alliance_info):
|
|
509
|
+
"""
|
|
510
|
+
Test should handle missing alliance info and return "Unaffiliated" as the alliance name
|
|
511
|
+
|
|
512
|
+
:param mock_parse_alliance_info:
|
|
513
|
+
:type mock_parse_alliance_info:
|
|
514
|
+
:return:
|
|
515
|
+
:rtype:
|
|
516
|
+
"""
|
|
517
|
+
|
|
518
|
+
eve_character = MagicMock(
|
|
519
|
+
corporation_id=456,
|
|
520
|
+
corporation_name="Corp1",
|
|
521
|
+
corporation_ticker="C1",
|
|
522
|
+
corporation_logo_url_32="corp_logo_url",
|
|
523
|
+
)
|
|
524
|
+
mock_parse_alliance_info.return_value = {"name": "Unaffiliated"}
|
|
525
|
+
|
|
526
|
+
result = _parse_corporation_info(eve_character, with_alliance_info=False)
|
|
527
|
+
|
|
528
|
+
self.assertNotIn("alliance", result)
|
|
529
|
+
|
|
530
|
+
|
|
531
|
+
class TestParseAllianceInfo(TestCase):
|
|
532
|
+
"""
|
|
533
|
+
Test the _parse_alliance_info function
|
|
534
|
+
"""
|
|
535
|
+
|
|
536
|
+
def test_parses_valid_alliance_info(self):
|
|
537
|
+
"""
|
|
538
|
+
Test should parse valid alliance info and return a dictionary
|
|
539
|
+
|
|
540
|
+
:return:
|
|
541
|
+
:rtype:
|
|
542
|
+
"""
|
|
543
|
+
|
|
544
|
+
eve_character = MagicMock(
|
|
545
|
+
alliance_id=789,
|
|
546
|
+
alliance_name="Alliance1",
|
|
547
|
+
alliance_ticker="A1",
|
|
548
|
+
alliance_logo_url_32="alliance_logo_url",
|
|
549
|
+
)
|
|
550
|
+
|
|
551
|
+
result = _parse_alliance_info(eve_character)
|
|
552
|
+
|
|
553
|
+
self.assertEqual(result["id"], 789)
|
|
554
|
+
self.assertEqual(result["name"], "Alliance1")
|
|
555
|
+
self.assertEqual(result["ticker"], "A1")
|
|
556
|
+
self.assertEqual(result["logo"], "alliance_logo_url")
|
|
557
|
+
self.assertIn("dotlan", result)
|
|
558
|
+
self.assertIn("zkillboard", result)
|
|
559
|
+
|
|
560
|
+
def test_handles_unaffiliated_alliance(self):
|
|
561
|
+
"""
|
|
562
|
+
Test should handle unaffiliated alliance info and return "Unaffiliated" as the alliance name
|
|
563
|
+
|
|
564
|
+
:return:
|
|
565
|
+
:rtype:
|
|
566
|
+
"""
|
|
567
|
+
|
|
568
|
+
eve_character = MagicMock(alliance_id=None)
|
|
569
|
+
|
|
570
|
+
result = _parse_alliance_info(eve_character)
|
|
571
|
+
|
|
572
|
+
self.assertEqual(result["id"], 1)
|
|
573
|
+
self.assertEqual(result["name"], "")
|
|
574
|
+
self.assertEqual(result["ticker"], "")
|
|
575
|
+
self.assertIn("logo", result)
|
|
576
|
+
|
|
577
|
+
@patch("aa_intel_tool.parser.module.chatlist.dotlan.alliance_url")
|
|
578
|
+
@patch("aa_intel_tool.parser.module.chatlist.zkillboard.alliance_url")
|
|
579
|
+
def test_includes_evelinks(self, mock_zkillboard, mock_dotlan):
|
|
580
|
+
"""
|
|
581
|
+
Test should include zkillboard and dotlan links in the result
|
|
582
|
+
|
|
583
|
+
:param mock_zkillboard:
|
|
584
|
+
:type mock_zkillboard:
|
|
585
|
+
:param mock_dotlan:
|
|
586
|
+
:type mock_dotlan:
|
|
587
|
+
:return:
|
|
588
|
+
:rtype:
|
|
589
|
+
"""
|
|
590
|
+
|
|
591
|
+
eve_character = MagicMock(
|
|
592
|
+
alliance_id=789,
|
|
593
|
+
alliance_name="Alliance1",
|
|
594
|
+
alliance_ticker="A1",
|
|
595
|
+
alliance_logo_url_32="alliance_logo_url",
|
|
596
|
+
)
|
|
597
|
+
mock_dotlan.return_value = "dotlan_url"
|
|
598
|
+
mock_zkillboard.return_value = "zkillboard_url"
|
|
599
|
+
|
|
600
|
+
result = _parse_alliance_info(eve_character, with_evelinks=True)
|
|
601
|
+
|
|
602
|
+
self.assertEqual(result["dotlan"], "dotlan_url")
|
|
603
|
+
self.assertEqual(result["zkillboard"], "zkillboard_url")
|
|
604
|
+
|
|
605
|
+
def test_excludes_evelinks(self):
|
|
606
|
+
"""
|
|
607
|
+
Test should exclude zkillboard and dotlan links from the result
|
|
608
|
+
|
|
609
|
+
:return:
|
|
610
|
+
:rtype:
|
|
611
|
+
"""
|
|
612
|
+
|
|
613
|
+
eve_character = MagicMock(
|
|
614
|
+
alliance_id=789,
|
|
615
|
+
alliance_name="Alliance1",
|
|
616
|
+
alliance_ticker="A1",
|
|
617
|
+
alliance_logo_url_32="alliance_logo_url",
|
|
618
|
+
)
|
|
619
|
+
|
|
620
|
+
result = _parse_alliance_info(eve_character, with_evelinks=False)
|
|
621
|
+
|
|
622
|
+
self.assertNotIn("dotlan", result)
|
|
623
|
+
self.assertNotIn("zkillboard", result)
|
|
624
|
+
|
|
625
|
+
|
|
626
|
+
class TestGetUnaffiliatedAllianceInfo(TestCase):
|
|
627
|
+
"""
|
|
628
|
+
Test the _get_unaffiliated_alliance_info function
|
|
629
|
+
"""
|
|
630
|
+
|
|
631
|
+
@patch("aa_intel_tool.parser.module.chatlist.eveimageserver.alliance_logo_url")
|
|
632
|
+
def test_returns_correct_alliance_info(self, mock_alliance_logo_url):
|
|
633
|
+
"""
|
|
634
|
+
Test should return the correct information for the unaffiliated alliance
|
|
635
|
+
|
|
636
|
+
:param mock_alliance_logo_url:
|
|
637
|
+
:type mock_alliance_logo_url:
|
|
638
|
+
:return:
|
|
639
|
+
:rtype:
|
|
640
|
+
"""
|
|
641
|
+
|
|
642
|
+
mock_alliance_logo_url.return_value = "mock_logo_url"
|
|
643
|
+
|
|
644
|
+
result = _get_unaffiliated_alliance_info()
|
|
645
|
+
|
|
646
|
+
self.assertEqual(result["id"], 1)
|
|
647
|
+
self.assertEqual(result["name"], "")
|
|
648
|
+
self.assertEqual(result["ticker"], "")
|
|
649
|
+
self.assertEqual(result["logo"], "mock_logo_url")
|
|
650
|
+
|
|
651
|
+
@patch("aa_intel_tool.parser.module.chatlist.eveimageserver.alliance_logo_url")
|
|
652
|
+
def handles_logo_url_generation(self, mock_alliance_logo_url):
|
|
653
|
+
"""
|
|
654
|
+
Test should generate the correct logo URL for the unaffiliated alliance
|
|
655
|
+
|
|
656
|
+
:param mock_alliance_logo_url:
|
|
657
|
+
:type mock_alliance_logo_url:
|
|
658
|
+
:return:
|
|
659
|
+
:rtype:
|
|
660
|
+
"""
|
|
661
|
+
|
|
662
|
+
mock_alliance_logo_url.return_value = "mock_logo_url"
|
|
663
|
+
|
|
664
|
+
result = _get_unaffiliated_alliance_info()
|
|
665
|
+
|
|
666
|
+
mock_alliance_logo_url.assert_called_once_with(alliance_id=1, size=32)
|
|
667
|
+
self.assertEqual(result["logo"], "mock_logo_url")
|
|
668
|
+
|
|
669
|
+
|
|
670
|
+
class TestGetCharacterInfo(TestCase):
|
|
671
|
+
"""
|
|
672
|
+
Test the _get_character_info function
|
|
673
|
+
"""
|
|
674
|
+
|
|
675
|
+
@patch("aa_intel_tool.parser.module.chatlist.EveCharacter.objects.filter")
|
|
676
|
+
@patch("aa_intel_tool.parser.module.chatlist.get_or_create_character")
|
|
677
|
+
def test_returns_existing_characters(self, mock_get_or_create, mock_filter):
|
|
678
|
+
"""
|
|
679
|
+
Test should return existing characters from the database
|
|
680
|
+
|
|
681
|
+
:param mock_get_or_create:
|
|
682
|
+
:type mock_get_or_create:
|
|
683
|
+
:param mock_filter:
|
|
684
|
+
:type mock_filter:
|
|
685
|
+
:return:
|
|
686
|
+
:rtype:
|
|
687
|
+
"""
|
|
688
|
+
|
|
689
|
+
# Mock the QuerySet returned by filter
|
|
690
|
+
mock_queryset = MagicMock()
|
|
691
|
+
mock_queryset.exclude.return_value = mock_queryset
|
|
692
|
+
mock_queryset.count.return_value = 0
|
|
693
|
+
mock_queryset.__iter__.return_value = iter([])
|
|
694
|
+
mock_filter.return_value = mock_queryset
|
|
695
|
+
|
|
696
|
+
# Mock the creation of a new character
|
|
697
|
+
mock_get_or_create.return_value = [MagicMock(character_name="Character1")]
|
|
698
|
+
|
|
699
|
+
result = _get_character_info(["Character1", "Character2"])
|
|
700
|
+
|
|
701
|
+
self.assertEqual(len(result), 1)
|
|
702
|
+
self.assertEqual(result[0].character_name, "Character1")
|
|
703
|
+
|
|
704
|
+
@patch("aa_intel_tool.parser.module.chatlist.EveCharacter.objects.filter")
|
|
705
|
+
def test_fetches_characters_from_eveuniverse(self, mock_filter):
|
|
706
|
+
"""
|
|
707
|
+
Test should fetch characters from the Eve Universe API
|
|
708
|
+
|
|
709
|
+
:param mock_filter:
|
|
710
|
+
:type mock_filter:
|
|
711
|
+
:return:
|
|
712
|
+
:rtype:
|
|
713
|
+
"""
|
|
714
|
+
|
|
715
|
+
mock_filter.return_value.exclude.return_value.count.return_value = 0
|
|
716
|
+
|
|
717
|
+
with patch(
|
|
718
|
+
"aa_intel_tool.parser.module.chatlist.EveEntity.objects.fetch_by_names_esi"
|
|
719
|
+
) as mock_fetch:
|
|
720
|
+
mock_fetch.return_value.filter.return_value.values_list.return_value = [1]
|
|
721
|
+
with patch(
|
|
722
|
+
"aa_intel_tool.parser.module.chatlist.get_or_create_character"
|
|
723
|
+
) as mock_get_or_create:
|
|
724
|
+
mock_get_or_create.return_value = [
|
|
725
|
+
MagicMock(character_name="Character1")
|
|
726
|
+
]
|
|
727
|
+
|
|
728
|
+
result = _get_character_info(["Character1"])
|
|
729
|
+
|
|
730
|
+
self.assertEqual(len(result), 1)
|
|
731
|
+
self.assertEqual(result[0].character_name, "Character1")
|
|
732
|
+
|
|
733
|
+
@patch("aa_intel_tool.parser.module.chatlist.EveCharacter.objects.filter")
|
|
734
|
+
def test_handles_no_characters_found(self, mock_filter):
|
|
735
|
+
"""
|
|
736
|
+
Test should raise a ParserError when no characters are found
|
|
737
|
+
|
|
738
|
+
:param mock_filter:
|
|
739
|
+
:type mock_filter:
|
|
740
|
+
:return:
|
|
741
|
+
:rtype:
|
|
742
|
+
"""
|
|
743
|
+
|
|
744
|
+
mock_filter.return_value.exclude.return_value.count.return_value = 0
|
|
745
|
+
|
|
746
|
+
with patch(
|
|
747
|
+
"aa_intel_tool.parser.module.chatlist.EveEntity.objects.fetch_by_names_esi"
|
|
748
|
+
) as mock_fetch:
|
|
749
|
+
mock_fetch.return_value.filter.return_value.values_list.return_value = []
|
|
750
|
+
with self.assertRaises(ParserError):
|
|
751
|
+
_get_character_info(["UnknownCharacter"])
|
|
752
|
+
|
|
753
|
+
@patch("aa_intel_tool.parser.module.chatlist.EveCharacter.objects.filter")
|
|
754
|
+
def test_handles_eveuniverse_fetch_error(self, mock_filter):
|
|
755
|
+
"""
|
|
756
|
+
Test should raise a ParserError when there is an error fetching from the Eve Universe API
|
|
757
|
+
|
|
758
|
+
:param mock_filter:
|
|
759
|
+
:type mock_filter:
|
|
760
|
+
:return:
|
|
761
|
+
:rtype:
|
|
762
|
+
"""
|
|
763
|
+
|
|
764
|
+
mock_filter.return_value.exclude.return_value.count.return_value = 0
|
|
765
|
+
|
|
766
|
+
with patch(
|
|
767
|
+
"aa_intel_tool.parser.module.chatlist.EveEntity.objects.fetch_by_names_esi"
|
|
768
|
+
) as mock_fetch:
|
|
769
|
+
mock_fetch.side_effect = EveEntity.DoesNotExist
|
|
770
|
+
with self.assertRaises(ParserError):
|
|
771
|
+
_get_character_info(["Character1"])
|