aa-structures 2.8.0__py3-none-any.whl → 2.9.1__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 (62) hide show
  1. {aa_structures-2.8.0.dist-info → aa_structures-2.9.1.dist-info}/METADATA +2 -2
  2. {aa_structures-2.8.0.dist-info → aa_structures-2.9.1.dist-info}/RECORD +62 -61
  3. structures/__init__.py +1 -1
  4. structures/admin.py +3 -3
  5. structures/app_settings.py +88 -69
  6. structures/core/notification_embeds/billing_embeds.py +40 -7
  7. structures/core/notification_embeds/{character_embeds.py → corporate_embeds.py} +23 -13
  8. structures/core/notification_embeds/main.py +76 -38
  9. structures/core/notification_embeds/moonmining_embeds.py +12 -17
  10. structures/core/notification_embeds/orbital_embeds.py +3 -8
  11. structures/core/notification_embeds/sov_embeds.py +21 -19
  12. structures/core/notification_embeds/structures_embeds.py +19 -26
  13. structures/core/notification_embeds/tower_embeds.py +2 -2
  14. structures/core/notification_embeds/war_embeds.py +298 -92
  15. structures/core/notification_types.py +63 -44
  16. structures/forms.py +0 -1
  17. structures/helpers.py +13 -0
  18. structures/locale/de/LC_MESSAGES/django.po +488 -302
  19. structures/locale/django.pot +494 -308
  20. structures/locale/en/LC_MESSAGES/django.po +494 -308
  21. structures/locale/es/LC_MESSAGES/django.po +488 -302
  22. structures/locale/fr_FR/LC_MESSAGES/django.po +494 -308
  23. structures/locale/it_IT/LC_MESSAGES/django.po +494 -308
  24. structures/locale/ja/LC_MESSAGES/django.po +494 -308
  25. structures/locale/ko_KR/LC_MESSAGES/django.po +488 -302
  26. structures/locale/ru/LC_MESSAGES/django.mo +0 -0
  27. structures/locale/ru/LC_MESSAGES/django.po +532 -349
  28. structures/locale/uk/LC_MESSAGES/django.po +488 -302
  29. structures/locale/zh_Hans/LC_MESSAGES/django.po +488 -302
  30. structures/migrations/0005_add_notification_types.py +135 -0
  31. structures/models/eveuniverse.py +0 -1
  32. structures/models/notifications.py +1 -1
  33. structures/models/owners.py +3 -1
  34. structures/tests/core/notification_embeds/test_main.py +29 -27
  35. structures/tests/core/test_notification_structuretimers.py +2 -1
  36. structures/tests/core/test_notifications_timerboard.py +2 -1
  37. structures/tests/core/test_serializers.py +4 -2
  38. structures/tests/core/test_starbases.py +4 -2
  39. structures/tests/integration/test_tasks.py +2 -1
  40. structures/tests/integration/test_views.py +6 -3
  41. structures/tests/models/test_eveuniverse.py +2 -1
  42. structures/tests/models/test_notifications_1.py +16 -21
  43. structures/tests/models/test_notifications_2.py +4 -2
  44. structures/tests/models/test_notifications_3.py +6 -3
  45. structures/tests/models/test_notifications_discord.py +2 -1
  46. structures/tests/models/test_owners_1.py +28 -4
  47. structures/tests/models/test_owners_2.py +2 -1
  48. structures/tests/models/test_owners_3.py +2 -1
  49. structures/tests/models/test_owners_4.py +2 -1
  50. structures/tests/models/test_owners_5.py +8 -4
  51. structures/tests/models/test_structures.py +16 -8
  52. structures/tests/test_helpers.py +23 -3
  53. structures/tests/test_managers_1.py +16 -8
  54. structures/tests/test_managers_2.py +2 -1
  55. structures/tests/test_tasks.py +12 -6
  56. structures/tests/testdata/entities.json +150 -0
  57. structures/tests/testdata/helpers.py +1 -0
  58. structures/tests/views/test_public.py +2 -1
  59. structures/tests/views/test_statistics.py +2 -1
  60. structures/tests/views/test_structures.py +20 -10
  61. {aa_structures-2.8.0.dist-info → aa_structures-2.9.1.dist-info}/LICENSE +0 -0
  62. {aa_structures-2.8.0.dist-info → aa_structures-2.9.1.dist-info}/WHEEL +0 -0
@@ -0,0 +1,135 @@
1
+ # Generated by Django 4.0.10 on 2024-03-21 13:45
2
+
3
+ import multiselectfield.db.fields
4
+
5
+ from django.db import migrations
6
+
7
+
8
+ class Migration(migrations.Migration):
9
+ dependencies = [
10
+ ("structures", "0004_improve_localization"),
11
+ ]
12
+
13
+ operations = [
14
+ migrations.AlterField(
15
+ model_name="webhook",
16
+ name="notification_types",
17
+ field=multiselectfield.db.fields.MultiSelectField(
18
+ choices=[
19
+ ("OwnershipTransferred", "Upwell structure ownership transferred"),
20
+ ("StructureAnchoring", "Upwell structure anchoring"),
21
+ ("StructureDestroyed", "Upwell structure destroyed"),
22
+ ("StructureFuelAlert", "Upwell structure fuel alert"),
23
+ ("StructureJumpFuelAlert", "Upwell structure jump fuel alert"),
24
+ ("StructureLostArmor", "Upwell structure lost armor"),
25
+ ("StructureLostShields", "Upwell structure lost shields"),
26
+ ("StructureOnline", "Upwell structure went online"),
27
+ ("StructureRefueledExtra", "Upwell structure refueled"),
28
+ (
29
+ "StructuresReinforcementChanged",
30
+ "Upwell structure reinforcement time changed",
31
+ ),
32
+ (
33
+ "StructureServicesOffline",
34
+ "Upwell structure services went offline",
35
+ ),
36
+ ("StructureUnanchoring", "Upwell structure unanchoring"),
37
+ ("StructureUnderAttack", "Upwell structure is under attack"),
38
+ ("StructureWentHighPower", "Upwell structure went high power"),
39
+ ("StructureWentLowPower", "Upwell structure went low power"),
40
+ ("OrbitalAttacked", "Customs office attacked"),
41
+ ("OrbitalReinforced", "Customs office reinforced"),
42
+ ("TowerAlertMsg", "Starbase attacked"),
43
+ ("TowerResourceAlertMsg", "Starbase fuel alert"),
44
+ ("TowerRefueledExtra", "Starbase refueled (BETA)"),
45
+ ("TowerReinforcedExtra", "Starbase reinforced (BETA)"),
46
+ (
47
+ "MoonminingAutomaticFracture",
48
+ "Moon mining automatic fracture triggered",
49
+ ),
50
+ (
51
+ "MoonminingExtractionCancelled",
52
+ "Moon mining extraction cancelled",
53
+ ),
54
+ ("MoonminingExtractionFinished", "Moon mining extraction finished"),
55
+ ("MoonminingExtractionStarted", "Moon mining extraction started"),
56
+ ("MoonminingLaserFired", "Moonmining laser fired"),
57
+ ("SovAllClaimAquiredMsg", "Sovereignty claim acknowledgment"),
58
+ ("SovAllClaimLostMsg", "Sovereignty lost"),
59
+ ("AllAnchoringMsg", "Structure anchoring in alliance space"),
60
+ ("EntosisCaptureStarted", "Sovereignty entosis capture started"),
61
+ ("SovStructureDestroyed", "Sovereignty structure destroyed"),
62
+ ("SovStructureReinforced", "Sovereignty structure reinforced"),
63
+ (
64
+ "SovCommandNodeEventStarted",
65
+ "Sovereignty command node event started",
66
+ ),
67
+ ("AcceptedAlly", "War accepted ally"),
68
+ (
69
+ "AllWarCorpJoinedAllianceMsg",
70
+ "Alliance war corporation joined alliance message",
71
+ ),
72
+ ("AllWarSurrenderMsg", "Alliance war surrender message"),
73
+ ("AllyJoinedWarAggressorMsg", "War ally joined aggressor"),
74
+ ("AllyJoinedWarAllyMsg", "War ally joined ally"),
75
+ ("AllyJoinedWarDefenderMsg", "War ally joined defender"),
76
+ ("CorpWarSurrenderMsg", "War party surrendered"),
77
+ ("CorpBecameWarEligible", "War corporation became eligible"),
78
+ ("CorpNoLongerWarEligible", "War corporation no longer eligible"),
79
+ ("DeclareWar", "War declared"),
80
+ ("WarHQRemovedFromSpace", "War HQ removed from space"),
81
+ ("WarInvalid", "War invalid"),
82
+ (
83
+ "MercOfferedNegotiationMsg",
84
+ "War mercenary offered negotiation message",
85
+ ),
86
+ ("MercOfferRetractedMsg", "War mercenary offer retracted message"),
87
+ ("OfferedSurrender", "War offered surrender"),
88
+ ("OfferedToAlly", "War offered to become ally"),
89
+ ("WarAdopted", "War adopted"),
90
+ ("WarDeclared", "War declared"),
91
+ ("WarInherited", "War inherited"),
92
+ ("WarRetractedByConcord", "War retracted by Concord"),
93
+ ("WarSurrenderOfferMsg", "War surrender offered"),
94
+ ("CharAppAcceptMsg", "Character joins corporation"),
95
+ ("CorpAppInvitedMsg", "Character invited to join corporation"),
96
+ ("CorpAppNewMsg", "Character submitted application"),
97
+ ("CharAppRejectMsg", "Corp application rejected message"),
98
+ (
99
+ "CorpAppRejectCustomMsg",
100
+ "Corp application rejected custom message",
101
+ ),
102
+ ("CharAppWithdrawMsg", "Character withdrew application"),
103
+ ("CharLeftCorpMsg", "Character leaves corporation"),
104
+ ("CorpAllBillMsg", "Corp alliance billing message"),
105
+ ("BillOutOfMoneyMsg", "Bill out of money"),
106
+ (
107
+ "InfrastructureHubBillAboutToExpire",
108
+ "I-HUB bill about to expire",
109
+ ),
110
+ ("IHubDestroyedByBillFailure", "I_HUB destroyed by bill failure"),
111
+ ],
112
+ default=[
113
+ "StructureAnchoring",
114
+ "StructureDestroyed",
115
+ "StructureFuelAlert",
116
+ "StructureLostArmor",
117
+ "StructureLostShields",
118
+ "StructureOnline",
119
+ "StructureServicesOffline",
120
+ "StructureUnderAttack",
121
+ "StructureWentHighPower",
122
+ "StructureWentLowPower",
123
+ "OrbitalAttacked",
124
+ "OrbitalReinforced",
125
+ "TowerAlertMsg",
126
+ "TowerResourceAlertMsg",
127
+ "SovStructureReinforced",
128
+ "SovStructureDestroyed",
129
+ ],
130
+ help_text="Select which type of notifications should be forwarded to this webhook",
131
+ max_length=1338,
132
+ verbose_name="notification types",
133
+ ),
134
+ ),
135
+ ]
@@ -1,6 +1,5 @@
1
1
  """Eve Universe models for Structures."""
2
2
 
3
-
4
3
  from django.db import models
5
4
  from django.utils.translation import gettext_lazy as _
6
5
  from eveuniverse.models import EveSolarSystem
@@ -409,7 +409,7 @@ class NotificationBase(models.Model):
409
409
  logger.info("%s: Trying to sent to webhook: %s", self, webhook)
410
410
  try:
411
411
  embed, ping_type = self._generate_embed(webhook.language_code)
412
- except (OSError, NotImplementedError) as ex:
412
+ except OSError as ex:
413
413
  logger.warning("%s: Failed to generate embed: %s", self, ex, exc_info=True)
414
414
  return False
415
415
 
@@ -235,7 +235,9 @@ class Owner(models.Model):
235
235
  is_alliance_main=False
236
236
  )
237
237
  if "update_fields" in kwargs:
238
- kwargs["update_fields"].append("is_alliance_main")
238
+ u = set(kwargs["update_fields"])
239
+ u.add("is_alliance_main")
240
+ kwargs["update_fields"] = u
239
241
  super().save(*args, **kwargs)
240
242
 
241
243
  @property
@@ -51,7 +51,8 @@ class TestBilType(TestCase):
51
51
 
52
52
  class TestNotificationEmbeds(TestCase):
53
53
  @classmethod
54
- def setUpTestData(cls):
54
+ def setUpClass(cls):
55
+ super().setUpClass()
55
56
  cls.owner = OwnerFactory()
56
57
 
57
58
  def test_should_create_obj_from_notification(self):
@@ -69,15 +70,6 @@ class TestNotificationEmbeds(TestCase):
69
70
  )
70
71
  self.assertEqual(str(notification_embed), "1000000999:CorpBecameWarEligible")
71
72
 
72
- def test_should_raise_exception_for_unsupported_notif_types(self):
73
- # given
74
- notification = NotificationFactory(
75
- owner=self.owner, notif_type="XXXUnsupportedNotificationTypeXXX"
76
- )
77
- # when / then
78
- with self.assertRaises(NotImplementedError):
79
- NotificationBaseEmbed.create(notification)
80
-
81
73
  def test_should_require_notification_for_init(self):
82
74
  with self.assertRaises(TypeError):
83
75
  NotificationBaseEmbed(notification="dummy")
@@ -89,7 +81,8 @@ class TestNotificationEmbeds(TestCase):
89
81
 
90
82
  class TestNotificationEmbedsGenerate(TestCase):
91
83
  @classmethod
92
- def setUpTestData(cls):
84
+ def setUpClass(cls):
85
+ super().setUpClass()
93
86
  load_eveuniverse()
94
87
  load_eve_entities()
95
88
  alliance = EveAllianceInfoFactory(alliance_id=3001)
@@ -145,38 +138,44 @@ class TestNotificationEmbedsGenerate(TestCase):
145
138
  for notif_type in NotificationType.esi_notifications():
146
139
  with self.subTest(notif_type=notif_type):
147
140
  # given
148
- notification = (
141
+ notif = (
149
142
  Notification.objects.select_related("owner", "sender")
150
143
  .filter(notif_type=notif_type)
151
144
  .first()
152
145
  )
153
- self.assertIsInstance(notification, Notification)
154
- notification_embed = NotificationBaseEmbed.create(notification)
146
+ self.assertIsInstance(notif, Notification)
147
+ notif_embed = NotificationBaseEmbed.create(notif)
148
+
155
149
  # when
156
- discord_embed = notification_embed.generate_embed()
150
+ obj = notif_embed.generate_embed()
151
+
157
152
  # then
158
- self.assertIsInstance(discord_embed, dhooks_lite.Embed)
153
+ self.assertIsInstance(obj, dhooks_lite.Embed)
159
154
 
160
155
  def test_should_generate_embed_for_all_supported_esi_notification_types_normal(
161
156
  self,
162
157
  ):
163
- # Structures references in notifications are pre-generated
158
+ # Pre-generate structures referenced in notifications
164
159
  StructureFactory(owner=self.owner, id=1000000000001, eve_type_name="Astrahus")
165
160
  StructureFactory(owner=self.owner, id=1000000000002, eve_type_name="Athanor")
161
+
166
162
  for notif_type in NotificationType.esi_notifications():
167
163
  with self.subTest(notif_type=notif_type):
168
164
  # given
169
- notification = (
165
+ notif = (
170
166
  Notification.objects.select_related("owner", "sender")
171
167
  .filter(notif_type=notif_type)
172
168
  .first()
173
169
  )
174
- self.assertIsInstance(notification, Notification)
175
- notification_embed = NotificationBaseEmbed.create(notification)
170
+ self.assertIsInstance(notif, Notification)
171
+ notif_embed = NotificationBaseEmbed.create(notif)
172
+
176
173
  # when
177
- discord_embed = notification_embed.generate_embed()
174
+ obj = notif_embed.generate_embed()
175
+
178
176
  # then
179
- self.assertIsInstance(discord_embed, dhooks_lite.Embed)
177
+ self.assertIsInstance(obj, dhooks_lite.Embed)
178
+ self.assertTrue(obj.description)
180
179
 
181
180
  def test_should_set_ping_everyone_for_color_danger(self):
182
181
  # given
@@ -244,7 +243,8 @@ class TestNotificationEmbedsGenerate(TestCase):
244
243
 
245
244
  class TestNotificationEmbedsClasses(NoSocketsTestCase):
246
245
  @classmethod
247
- def setUpTestData(cls):
246
+ def setUpClass(cls):
247
+ super().setUpClass()
248
248
  load_eveuniverse()
249
249
  user = UserMainDefaultOwnerFactory()
250
250
  cls.owner = OwnerFactory(user=user)
@@ -302,7 +302,8 @@ class TestNotificationEmbedsClasses(NoSocketsTestCase):
302
302
 
303
303
  class TestGeneratedNotification(NoSocketsTestCase):
304
304
  @classmethod
305
- def setUpTestData(cls):
305
+ def setUpClass(cls):
306
+ super().setUpClass()
306
307
  load_eveuniverse()
307
308
 
308
309
  def test_should_create_tower_reinforced_embed(self):
@@ -327,7 +328,8 @@ class TestGeneratedNotification(NoSocketsTestCase):
327
328
 
328
329
  class TestEveNotificationEmbeds(NoSocketsTestCase):
329
330
  @classmethod
330
- def setUpTestData(cls):
331
+ def setUpClass(cls):
332
+ super().setUpClass()
331
333
  load_eveuniverse()
332
334
  cls.owner = OwnerFactory()
333
335
 
@@ -343,7 +345,7 @@ class TestEveNotificationEmbeds(NoSocketsTestCase):
343
345
  # when
344
346
  obj = embed.generate_embed()
345
347
  # then
346
- self.assertIsInstance(obj, dhooks_lite.Embed)
348
+ self.assertTrue(obj.description)
347
349
 
348
350
  def test_should_create_sov_embed_without_sender(self):
349
351
  # given
@@ -357,4 +359,4 @@ class TestEveNotificationEmbeds(NoSocketsTestCase):
357
359
  # when
358
360
  obj = embed.generate_embed()
359
361
  # then
360
- self.assertIsInstance(obj, dhooks_lite.Embed)
362
+ self.assertTrue(obj.description)
@@ -43,7 +43,8 @@ if "structuretimers" in app_labels():
43
43
  @patch(MODULE_PATH + ".STRUCTURES_MOON_EXTRACTION_TIMERS_ENABLED", True)
44
44
  class TestTimersForStructureTimers(NoSocketsTestCase):
45
45
  @classmethod
46
- def setUpTestData(cls):
46
+ def setUpClass(cls):
47
+ super().setUpClass()
47
48
  load_eveuniverse()
48
49
 
49
50
  def test_should_create_timer_for_reinforced_structure(self):
@@ -29,7 +29,8 @@ if "timerboard" in app_labels():
29
29
  @patch("structuretimers.models.STRUCTURETIMERS_NOTIFICATIONS_ENABLED", False)
30
30
  class TestNotificationAddToTimerboard(NoSocketsTestCase):
31
31
  @classmethod
32
- def setUpTestData(cls):
32
+ def setUpClass(cls):
33
+ super().setUpClass()
33
34
  load_eveuniverse()
34
35
  load_eve_entities()
35
36
  cls.owner = OwnerFactory(is_alliance_main=True)
@@ -28,7 +28,8 @@ def to_dict(lst: List[dict], key="id"):
28
28
 
29
29
  class TestStructureListSerializer(NoSocketsTestCase):
30
30
  @classmethod
31
- def setUpTestData(cls):
31
+ def setUpClass(cls):
32
+ super().setUpClass()
32
33
  cls.factory = RequestFactory()
33
34
  load_eveuniverse()
34
35
  cls.user = UserMainDefaultFactory()
@@ -138,7 +139,8 @@ class TestStructureListSerializer(NoSocketsTestCase):
138
139
 
139
140
  class TestPocoListSerializer(NoSocketsTestCase):
140
141
  @classmethod
141
- def setUpTestData(cls):
142
+ def setUpClass(cls):
143
+ super().setUpClass()
142
144
  cls.factory = RequestFactory()
143
145
  load_eveuniverse()
144
146
  alliance = EveAllianceInfoFactory(
@@ -8,7 +8,8 @@ from structures.tests.testdata.load_eveuniverse import load_eveuniverse
8
8
 
9
9
  class TestStarbases(NoSocketsTestCase):
10
10
  @classmethod
11
- def setUpTestData(cls):
11
+ def setUpClass(cls):
12
+ super().setUpClass()
12
13
  load_eveuniverse()
13
14
  cls.type_astrahus = EveType.objects.get(id=35832)
14
15
  cls.type_poco = EveType.objects.get(id=2233)
@@ -58,7 +59,8 @@ class TestStarbases(NoSocketsTestCase):
58
59
 
59
60
  class TestStarbasesFuelDuration(NoSocketsTestCase):
60
61
  @classmethod
61
- def setUpTestData(cls):
62
+ def setUpClass(cls):
63
+ super().setUpClass()
62
64
  load_eveuniverse()
63
65
 
64
66
  def test_can_calculate_for_large_tower(self):
@@ -58,7 +58,8 @@ TASKS_PATH = "structures.tasks"
58
58
  @patch(OWNERS_PATH + ".esi")
59
59
  class TestTasks(TestCase):
60
60
  @classmethod
61
- def setUpTestData(cls):
61
+ def setUpClass(cls):
62
+ super().setUpClass()
62
63
  load_eveuniverse()
63
64
 
64
65
  def test_should_fetch_new_upwell_structure_from_esi(
@@ -25,7 +25,8 @@ COMMON_PATH = "structures.views.common"
25
25
 
26
26
  class TestStructureListView(TestCase):
27
27
  @classmethod
28
- def setUpTestData(cls):
28
+ def setUpClass(cls):
29
+ super().setUpClass()
29
30
  load_eveuniverse()
30
31
  cls.user = UserMainDefaultFactory()
31
32
  cls.owner = OwnerFactory(user=cls.user)
@@ -56,7 +57,8 @@ class TestStructureListView(TestCase):
56
57
 
57
58
  class TestStatisticsView(TestCase):
58
59
  @classmethod
59
- def setUpTestData(cls):
60
+ def setUpClass(cls):
61
+ super().setUpClass()
60
62
  load_eveuniverse()
61
63
  cls.user = UserMainDefaultFactory()
62
64
  cls.owner = OwnerFactory(user=cls.user)
@@ -80,7 +82,8 @@ class TestStatisticsView(TestCase):
80
82
 
81
83
  class TestPocoView(TestCase):
82
84
  @classmethod
83
- def setUpTestData(cls):
85
+ def setUpClass(cls):
86
+ super().setUpClass()
84
87
  load_eveuniverse()
85
88
  character = EveCharacterFactory(character_name="Bruce Wayne")
86
89
  cls.user = UserMainBasicFactory(main_character__character=character)
@@ -22,7 +22,8 @@ class TestEveSovereigntyMap(NoSocketsTestCase):
22
22
 
23
23
  class TestEveSpaceType(NoSocketsTestCase):
24
24
  @classmethod
25
- def setUpTestData(cls):
25
+ def setUpClass(cls):
26
+ super().setUpClass()
26
27
  load_eveuniverse()
27
28
 
28
29
  def test_space_type_highsec(self):
@@ -28,7 +28,8 @@ MODULE_PATH = "structures.models.notifications"
28
28
 
29
29
  class TestNotification(NoSocketsTestCase):
30
30
  @classmethod
31
- def setUpTestData(cls):
31
+ def setUpClass(cls):
32
+ super().setUpClass()
32
33
  load_eveuniverse()
33
34
  load_eve_entities()
34
35
  cls.owner = OwnerFactory()
@@ -99,7 +100,7 @@ class TestNotification(NoSocketsTestCase):
99
100
  self.assertTrue(notif.can_be_rendered)
100
101
 
101
102
  def test_can_be_rendered_3(self):
102
- for notif_type in ["DeclareWar"]:
103
+ for notif_type in ["UnknownNotificationType"]:
103
104
  with self.subTest(notification_type=notif_type):
104
105
  notif = Notification.objects.filter(notif_type=notif_type).first()
105
106
  if notif:
@@ -191,7 +192,8 @@ class TestNotificationFilterForAllianceLevel(NoSocketsTestCase):
191
192
 
192
193
  class TestNotificationCreateFromStructure(NoSocketsTestCase):
193
194
  @classmethod
194
- def setUpTestData(cls):
195
+ def setUpClass(cls):
196
+ super().setUpClass()
195
197
  load_eveuniverse()
196
198
  EveEntityCorporationFactory(id=1000137, name="DED")
197
199
  cls.owner = OwnerFactory()
@@ -256,7 +258,8 @@ class TestNotificationCreateFromStructure(NoSocketsTestCase):
256
258
 
257
259
  class TestNotificationRelevantWebhooks(NoSocketsTestCase):
258
260
  @classmethod
259
- def setUpTestData(cls):
261
+ def setUpClass(cls):
262
+ super().setUpClass()
260
263
  load_eveuniverse()
261
264
  load_eve_entities()
262
265
 
@@ -407,7 +410,8 @@ class TestNotificationRelevantWebhooks(NoSocketsTestCase):
407
410
 
408
411
  class TestNotificationSendToConfiguredWebhooks(NoSocketsTestCase):
409
412
  @classmethod
410
- def setUpTestData(cls):
413
+ def setUpClass(cls):
414
+ super().setUpClass()
411
415
  load_eveuniverse()
412
416
 
413
417
  @patch(MODULE_PATH + ".Notification.send_to_webhook")
@@ -546,7 +550,8 @@ class TestNotificationSendToConfiguredWebhooks(NoSocketsTestCase):
546
550
  @patch(MODULE_PATH + ".Webhook.send_message")
547
551
  class TestNotificationSendToWebhook(NoSocketsTestCase):
548
552
  @classmethod
549
- def setUpTestData(cls):
553
+ def setUpClass(cls):
554
+ super().setUpClass()
550
555
  load_eveuniverse()
551
556
  EveEntityCorporationFactory(id=1000137, name="DED")
552
557
 
@@ -612,18 +617,7 @@ class TestNotificationSendMessage(NoSocketsTestCase):
612
617
  self.assertIsNotNone(kwargs["content"])
613
618
  self.assertIsNotNone(kwargs["embeds"])
614
619
 
615
- def test_should_ignore_unsupported_notif_types(self, mock_send_message):
616
- # given
617
- mock_send_message.return_value = 1
618
- obj = NotificationFactory(
619
- owner=self.owner, notif_type="XXXUnsupportedNotificationTypeXXX"
620
- )
621
- # when
622
- result = obj.send_to_webhook(self.webhook)
623
- # then
624
- self.assertFalse(result)
625
-
626
- def test_mark_notification_as_sent_when_successful(self, mock_send_message):
620
+ def test_should_mark_notification_as_sent_when_successful(self, mock_send_message):
627
621
  # given
628
622
  mock_send_message.return_value = True
629
623
  obj = NotificationFactory(owner=self.owner)
@@ -633,7 +627,7 @@ class TestNotificationSendMessage(NoSocketsTestCase):
633
627
  obj.refresh_from_db()
634
628
  self.assertTrue(obj.is_sent)
635
629
 
636
- def test_dont_mark_notification_as_sent_when_error(self, mock_send_message):
630
+ def test_should_not_mark_notification_as_sent_when_error(self, mock_send_message):
637
631
  # given
638
632
  mock_send_message.return_value = 0
639
633
  obj = NotificationFactory(owner=self.owner)
@@ -643,7 +637,7 @@ class TestNotificationSendMessage(NoSocketsTestCase):
643
637
  obj.refresh_from_db()
644
638
  self.assertFalse(obj.is_sent)
645
639
 
646
- def test_send_to_webhook_all_notification_types(self, mock_send_message):
640
+ def test_can_send_all_notification_types(self, mock_send_message):
647
641
  # given
648
642
  mock_send_message.return_value = 1
649
643
  types_tested = set()
@@ -736,7 +730,8 @@ class TestNotificationSendMessage(NoSocketsTestCase):
736
730
  @patch(MODULE_PATH + ".Webhook.send_message", spec=True)
737
731
  class TestNotificationPings(NoSocketsTestCase):
738
732
  @classmethod
739
- def setUpTestData(cls):
733
+ def setUpClass(cls):
734
+ super().setUpClass()
740
735
  load_eveuniverse()
741
736
  corporation = EveEntityCorporationFactory()
742
737
  cls.notif_params = {
@@ -363,7 +363,8 @@ class TestStructureFuelAlerts(NoSocketsTestCase):
363
363
  @patch(MODULE_PATH + ".Webhook.send_message", spec=True)
364
364
  class TestJumpFuelAlerts(NoSocketsTestCase):
365
365
  @classmethod
366
- def setUpTestData(cls):
366
+ def setUpClass(cls):
367
+ super().setUpClass()
367
368
  load_eveuniverse()
368
369
  EveEntityCorporationFactory(id=1000137, name="DED")
369
370
 
@@ -592,7 +593,8 @@ class TestJumpFuelAlerts(NoSocketsTestCase):
592
593
 
593
594
  class TestNotificationRelatedStructures(NoSocketsTestCase):
594
595
  @classmethod
595
- def setUpTestData(cls):
596
+ def setUpClass(cls):
597
+ super().setUpClass()
596
598
  load_eveuniverse()
597
599
  load_eve_entities()
598
600
  cls.owner = OwnerFactory()
@@ -22,7 +22,8 @@ MODULE_PATH = "structures.models.notifications"
22
22
 
23
23
  class TestGeneratedNotification(NoSocketsTestCase):
24
24
  @classmethod
25
- def setUpTestData(cls):
25
+ def setUpClass(cls):
26
+ super().setUpClass()
26
27
  load_eveuniverse()
27
28
 
28
29
  def test_should_have_str(self):
@@ -53,7 +54,8 @@ class TestGeneratedNotification(NoSocketsTestCase):
53
54
 
54
55
  class TestGeneratedNotificationManagerCreatePosReinforced(NoSocketsTestCase):
55
56
  @classmethod
56
- def setUpTestData(cls):
57
+ def setUpClass(cls):
58
+ super().setUpClass()
57
59
  load_eveuniverse()
58
60
  cls.owner = OwnerFactory()
59
61
 
@@ -149,7 +151,8 @@ class TestGeneratedNotificationManagerCreatePosReinforced(NoSocketsTestCase):
149
151
  @mock.patch("structures.core.notification_timers.add_or_remove_timer")
150
152
  class TestProcessTimers(NoSocketsTestCase):
151
153
  @classmethod
152
- def setUpTestData(cls):
154
+ def setUpClass(cls):
155
+ super().setUpClass()
153
156
  cls.owner = OwnerFactory()
154
157
 
155
158
  @mock.patch(MODULE_PATH + ".STRUCTURES_ADD_TIMERS", True)
@@ -29,7 +29,8 @@ if "discord" in app_labels():
29
29
  @patch(MODULE_PATH + ".Webhook.send_message", spec=True)
30
30
  class TestGroupPings(NoSocketsTestCase):
31
31
  @classmethod
32
- def setUpTestData(cls):
32
+ def setUpClass(cls):
33
+ super().setUpClass()
33
34
  load_eveuniverse()
34
35
  load_eve_entities()
35
36
  cls.group_1 = Group.objects.create(name="Dummy Group 1")
@@ -27,7 +27,8 @@ MODULE_PATH = "structures.models.owners"
27
27
 
28
28
  class TestOwner(NoSocketsTestCase):
29
29
  @classmethod
30
- def setUpTestData(cls):
30
+ def setUpClass(cls):
31
+ super().setUpClass()
31
32
  cls.alliance = EveAllianceInfoFactory(
32
33
  alliance_name="Wayne Enterprises", alliance_ticker="WYE"
33
34
  )
@@ -189,6 +190,26 @@ class TestOwner(NoSocketsTestCase):
189
190
  self.owner.refresh_from_db()
190
191
  self.assertFalse(self.owner.is_alliance_main)
191
192
 
193
+ def test_should_ensure_is_alliance_main_is_set_for_update_fields_1(self):
194
+ # given
195
+ corporation = EveCorporationInfoFactory(alliance=self.alliance)
196
+ owner = OwnerFactory(corporation=corporation, is_alliance_main=True)
197
+ # when
198
+ owner.save(update_fields={"is_active"})
199
+ # then
200
+ owner.refresh_from_db()
201
+ self.assertTrue(owner.is_alliance_main)
202
+
203
+ def test_should_ensure_is_alliance_main_is_set_for_update_fields_2(self):
204
+ # given
205
+ corporation = EveCorporationInfoFactory(alliance=self.alliance)
206
+ owner = OwnerFactory(corporation=corporation, is_alliance_main=True)
207
+ # when
208
+ owner.save(update_fields=["is_active"])
209
+ # then
210
+ owner.refresh_from_db()
211
+ self.assertTrue(owner.is_alliance_main)
212
+
192
213
  def test_should_allow_mains_from_other_alliances(self):
193
214
  # given
194
215
  self.owner.is_alliance_main = True
@@ -223,7 +244,8 @@ class TestOwner(NoSocketsTestCase):
223
244
 
224
245
  class TestOwnerHasSov(NoSocketsTestCase):
225
246
  @classmethod
226
- def setUpTestData(cls):
247
+ def setUpClass(cls):
248
+ super().setUpClass()
227
249
  load_eveuniverse()
228
250
  cls.owner = OwnerFactory()
229
251
  EveSovereigntyMapFactory(
@@ -474,7 +496,8 @@ class TestOwnerFetchToken(NoSocketsTestCase):
474
496
 
475
497
  class TestOwnerCharacters(NoSocketsTestCase):
476
498
  @classmethod
477
- def setUpTestData(cls):
499
+ def setUpClass(cls):
500
+ super().setUpClass()
478
501
  cls.owner = OwnerFactory()
479
502
 
480
503
  def test_should_return_str(self):
@@ -544,7 +567,8 @@ class TestOwnerCharacters(NoSocketsTestCase):
544
567
  @patch(MODULE_PATH + ".notify_admins", spec=True)
545
568
  class TestOwnerDeleteCharacter(NoSocketsTestCase):
546
569
  @classmethod
547
- def setUpTestData(cls):
570
+ def setUpClass(cls):
571
+ super().setUpClass()
548
572
  cls.owner = OwnerFactory(characters=False)
549
573
 
550
574
  def test_should_delete_character_and_notify(self, mock_notify_admins, mock_notify):
@@ -30,7 +30,8 @@ MODULE_PATH = "structures.models.owners"
30
30
  @patch(MODULE_PATH + ".esi")
31
31
  class TestUpdateStructuresEsi(NoSocketsTestCase):
32
32
  @classmethod
33
- def setUpTestData(cls):
33
+ def setUpClass(cls):
34
+ super().setUpClass()
34
35
  load_eveuniverse()
35
36
  cls.user = UserMainDefaultOwnerFactory()
36
37
  cls.owner = OwnerFactory(user=cls.user, structures_last_update_at=None)