aa-intel-tool 2.6.0__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.
Files changed (66) hide show
  1. aa_intel_tool/__init__.py +1 -1
  2. aa_intel_tool/app_settings.py +15 -0
  3. aa_intel_tool/constants.py +6 -5
  4. aa_intel_tool/helper/eve_character.py +24 -36
  5. aa_intel_tool/helper/static_files.py +5 -4
  6. aa_intel_tool/locale/cs_CZ/LC_MESSAGES/django.po +15 -83
  7. aa_intel_tool/locale/de/LC_MESSAGES/django.mo +0 -0
  8. aa_intel_tool/locale/de/LC_MESSAGES/django.po +71 -87
  9. aa_intel_tool/locale/django.pot +16 -84
  10. aa_intel_tool/locale/es/LC_MESSAGES/django.po +19 -83
  11. aa_intel_tool/locale/fr_FR/LC_MESSAGES/django.mo +0 -0
  12. aa_intel_tool/locale/fr_FR/LC_MESSAGES/django.po +72 -88
  13. aa_intel_tool/locale/it_IT/LC_MESSAGES/django.po +15 -83
  14. aa_intel_tool/locale/ja/LC_MESSAGES/django.po +15 -83
  15. aa_intel_tool/locale/ko_KR/LC_MESSAGES/django.po +67 -83
  16. aa_intel_tool/locale/nl_NL/LC_MESSAGES/django.po +15 -83
  17. aa_intel_tool/locale/pl_PL/LC_MESSAGES/django.po +15 -83
  18. aa_intel_tool/locale/ru/LC_MESSAGES/django.mo +0 -0
  19. aa_intel_tool/locale/ru/LC_MESSAGES/django.po +71 -87
  20. aa_intel_tool/locale/sk/LC_MESSAGES/django.po +15 -83
  21. aa_intel_tool/locale/uk/LC_MESSAGES/django.mo +0 -0
  22. aa_intel_tool/locale/uk/LC_MESSAGES/django.po +71 -94
  23. aa_intel_tool/locale/zh_Hans/LC_MESSAGES/django.mo +0 -0
  24. aa_intel_tool/locale/zh_Hans/LC_MESSAGES/django.po +20 -87
  25. aa_intel_tool/parser/general.py +11 -16
  26. aa_intel_tool/parser/helper/db.py +8 -11
  27. aa_intel_tool/parser/module/chatlist.py +97 -126
  28. aa_intel_tool/parser/module/dscan.py +115 -147
  29. aa_intel_tool/parser/module/fleetcomp.py +85 -102
  30. aa_intel_tool/static/aa_intel_tool/css/aa-intel-tool.css +6 -24
  31. aa_intel_tool/static/aa_intel_tool/css/aa-intel-tool.min.css +1 -1
  32. aa_intel_tool/static/aa_intel_tool/css/aa-intel-tool.min.css.map +1 -1
  33. aa_intel_tool/static/aa_intel_tool/javascript/aa-intel-tool-chatscan-highlight.js +104 -64
  34. aa_intel_tool/static/aa_intel_tool/javascript/aa-intel-tool-chatscan-highlight.min.js.map +1 -1
  35. aa_intel_tool/static/aa_intel_tool/javascript/aa-intel-tool-chatscan.js +5 -5
  36. aa_intel_tool/static/aa_intel_tool/javascript/aa-intel-tool-chatscan.min.js +1 -1
  37. aa_intel_tool/static/aa_intel_tool/javascript/aa-intel-tool-chatscan.min.js.map +1 -1
  38. aa_intel_tool/static/aa_intel_tool/javascript/aa-intel-tool-dscan-highlight.js +43 -43
  39. aa_intel_tool/static/aa_intel_tool/javascript/aa-intel-tool-dscan-highlight.min.js.map +1 -1
  40. aa_intel_tool/static/aa_intel_tool/javascript/aa-intel-tool-dscan.js +41 -17
  41. aa_intel_tool/static/aa_intel_tool/javascript/aa-intel-tool-dscan.min.js +1 -1
  42. aa_intel_tool/static/aa_intel_tool/javascript/aa-intel-tool-dscan.min.js.map +1 -1
  43. aa_intel_tool/static/aa_intel_tool/javascript/aa-intel-tool-fleetcomposition-highlight.js +51 -51
  44. aa_intel_tool/static/aa_intel_tool/javascript/aa-intel-tool-fleetcomposition-highlight.min.js.map +1 -1
  45. aa_intel_tool/static/aa_intel_tool/javascript/aa-intel-tool-fleetcomposition.js +13 -7
  46. aa_intel_tool/static/aa_intel_tool/javascript/aa-intel-tool-fleetcomposition.min.js +1 -1
  47. aa_intel_tool/static/aa_intel_tool/javascript/aa-intel-tool-fleetcomposition.min.js.map +1 -1
  48. aa_intel_tool/static/aa_intel_tool/javascript/aa-intel-tool-scan-result-common.js +53 -31
  49. aa_intel_tool/static/aa_intel_tool/javascript/aa-intel-tool-scan-result-common.min.js +1 -1
  50. aa_intel_tool/static/aa_intel_tool/javascript/aa-intel-tool-scan-result-common.min.js.map +1 -1
  51. aa_intel_tool/templates/aa_intel_tool/base.html +7 -42
  52. aa_intel_tool/templates/aa_intel_tool/partials/scan/evetime.html +1 -1
  53. aa_intel_tool/templatetags/aa_intel_tool.py +12 -7
  54. aa_intel_tool/tests/test-data/dscan.txt +250 -0
  55. aa_intel_tool/tests/test_admin.py +50 -38
  56. aa_intel_tool/tests/test_app_settings.py +23 -1
  57. aa_intel_tool/tests/test_helper_eve_character.py +405 -0
  58. aa_intel_tool/tests/test_models.py +188 -4
  59. aa_intel_tool/tests/test_parser_general.py +771 -0
  60. aa_intel_tool/tests/test_parser_module_chatlist.py +154 -0
  61. aa_intel_tool/tests/test_templatetags.py +24 -3
  62. {aa_intel_tool-2.6.0.dist-info → aa_intel_tool-2.6.2.dist-info}/METADATA +4 -4
  63. {aa_intel_tool-2.6.0.dist-info → aa_intel_tool-2.6.2.dist-info}/RECORD +65 -63
  64. aa_intel_tool/tests/test_parser.py +0 -135
  65. {aa_intel_tool-2.6.0.dist-info → aa_intel_tool-2.6.2.dist-info}/WHEEL +0 -0
  66. {aa_intel_tool-2.6.0.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"])