aa-structures 2.3.0__py3-none-any.whl → 2.3.1b1__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: aa-structures
3
- Version: 2.3.0
3
+ Version: 2.3.1b1
4
4
  Summary: App for managing Eve Online structures with Alliance Auth
5
5
  Project-URL: Homepage, https://gitlab.com/ErikKalkoken/aa-structures
6
6
  Project-URL: Documentation, https://aa-structures.readthedocs.io/en/latest/
@@ -1,4 +1,4 @@
1
- structures/__init__.py,sha256=1RZykJ8KDupKof3pl0_1nk1EzfoL7Pn44T9SgOIxINA,104
1
+ structures/__init__.py,sha256=9GX_0x7w1T8qGTZtM8aB70qyhAOu8S1HmvNWarR-CXE,106
2
2
  structures/admin.py,sha256=C83NxL0kGX5cOePUD53Xj5mVdgDEEQM_x14w_9Sisrg,36110
3
3
  structures/app_settings.py,sha256=mhEr3RtTJrrgb50ZPZNQWd_Sls7yyFKQfnb0oVocap4,6228
4
4
  structures/apps.py,sha256=TSbhF_vhCupKlxhVZnMHIF-Gh18MozBrc4WprT3IXd4,268
@@ -47,7 +47,7 @@ structures/migrations/0003_add_localization_and_unique_key.py,sha256=ZxJMfUtgUH2
47
47
  structures/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
48
48
  structures/models/__init__.py,sha256=T712-e_T-Fp44tFO-cpf-F2ngehxoDSQlDqoKs6pV2s,505
49
49
  structures/models/eveuniverse.py,sha256=iQlZC6zMueg0F-a6iOgacHrIa9ZBvl0utpIhoCoL920,2073
50
- structures/models/notifications.py,sha256=4TEkILbHrszoKjZqX8QwmVC30DztQTW75PHosGQstkk,42691
50
+ structures/models/notifications.py,sha256=zPwsUO_nwmmlB2c4t7Hn1cRXVmQeFdjwSuY8378gd7g,42745
51
51
  structures/models/owners.py,sha256=GJTn74pE-ZMSYPUSimclnSLIJ1r9UPnORFUEv4_m0Lc,53967
52
52
  structures/models/structures.py,sha256=u6XGozfc3Sngm2BRAS7z4dHsMmEVUWLxogo8knZtFmw,37256
53
53
  structures/static/structures/css/global.css,sha256=R4LEH9PwLoN77qkqBK7u2y_vzRC3fq8X_zKnAW7yhiA,1165
@@ -126,7 +126,7 @@ structures/tests/__init__.py,sha256=9MrJzKr8DdsQY3-79v188pTpwqT4TDQ46vKnBJAGqic,
126
126
  structures/tests/test_admin.py,sha256=57eFbtevnBQ_oTGJHUYweJzRp9BID6ylWUXHO6F-LI8,21127
127
127
  structures/tests/test_checks.py,sha256=bqM9fOZDybHp7Emp8CJUt2PXKvde7B22AaQW2pH-dqg,1242
128
128
  structures/tests/test_helpers.py,sha256=YNJC5in0H6Mb2qsW4nznP2PFGkrgmdjfT93AVLtH00I,1861
129
- structures/tests/test_integration.py,sha256=2ysd5txGxWz598pOAv5XNugK0lHShPiQ9EX9hT2jRkY,20151
129
+ structures/tests/test_integration.py,sha256=dxvg8htNnwl6lzPeTAgRWe15fgf7NGELWWgETskUT3U,23524
130
130
  structures/tests/test_managers_1.py,sha256=gQFaUZPg7iLWNyzYkE0HTNGqE5quB2eT9aQzk2436JU,26102
131
131
  structures/tests/test_managers_3.py,sha256=MMAJp6m3C_LsE8vK2udW17RLFx2W6_0dKwsSKWCl384,1567
132
132
  structures/tests/test_tasks.py,sha256=hzcRbiHI0fsfUIp2376yRZPLOpg_H-mtXKM0cBRha8c,18409
@@ -140,7 +140,7 @@ structures/tests/core/test_sovereignty.py,sha256=jR7AX3j35DeHhKPN846QMJp5g6koyGg
140
140
  structures/tests/core/test_starbases.py,sha256=qVzE1Yk_P0yN6U0uyeaYr08sqD07kTkyXYQwUFWSahI,3163
141
141
  structures/tests/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
142
142
  structures/tests/models/test_eveuniverse.py,sha256=6o1im7H4lB26xnVBo58jl0Y57oNVElQ4L4E7dVE_uv0,1600
143
- structures/tests/models/test_notifications_1.py,sha256=JOjejNjfx4jfrz_9wnrxHo9F2EVWliQJdm5uDKgv2FM,38429
143
+ structures/tests/models/test_notifications_1.py,sha256=vziy9QWLTPc2z6k0cT7Z7CmORlfn-Ib7rxUkRY9sL_s,39346
144
144
  structures/tests/models/test_notifications_2.py,sha256=ZsQcJ5pbi8tJHDnCUfqZsyOGNsbERdkO6n7qGt-cW_Y,31553
145
145
  structures/tests/models/test_notifications_3.py,sha256=_s2Qj7nZIObFW_sOPFtC8k3WaTIYuCiQIqA6FAnocRk,6004
146
146
  structures/tests/models/test_notifications_discord.py,sha256=snykVVAtQQ9xfHpk8X8pDrlle266ZpfcT3itE8AUaCo,5318
@@ -154,7 +154,7 @@ structures/tests/testdata/entities.json,sha256=EPla7cAARMIMjiwO4rZELyyDSeZv3V5Wn
154
154
  structures/tests/testdata/esi_data.json,sha256=DX47oSlRZIPxlPueMfiNElbZbAip2cp3LAUmv8GAPJ0,13864
155
155
  structures/tests/testdata/eveuniverse.json,sha256=dPI-aBrHsMBW2XpE6C827bSQEYqC0tCsIF7qy6n1n2w,979813
156
156
  structures/tests/testdata/factories.py,sha256=IUKm-Kud2lTOFFnznJjXwquTVlavOpIIyq78GWVPDXs,7827
157
- structures/tests/testdata/factories_2.py,sha256=mVROR_3yKdcPaZO9QpFhwBjEjmtr8vyAj5GVCwsN2BI,9910
157
+ structures/tests/testdata/factories_2.py,sha256=p9reEVY8LeYHIJC_9d2kAk2zwYeRJn37XEe_-NYY4F4,10857
158
158
  structures/tests/testdata/generate_notifications.py,sha256=nE077mVHVmOVudKIGMtHUfBIcV5Ch5Z0IngD1gp5yQk,5746
159
159
  structures/tests/testdata/generate_notifications_2.py,sha256=K5Bs5Xs08GkgA8BjCciopAbX0RR58Tsscs2MkOjblpk,1415
160
160
  structures/tests/testdata/generate_structures.py,sha256=wzuLjsTZrmErB7664YoTdSsqjy6Q5Z26LAKXKgy_ZTA,6238
@@ -169,7 +169,7 @@ structures/webhooks/models.py,sha256=3J51A2EXIpxoH5iOWJcFGaPTtaaPQTo0zl-yyl6wwHQ
169
169
  structures/webhooks/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
170
170
  structures/webhooks/tests/test_core.py,sha256=VHzfA2GQPlhA7trsIOUBA5U8kfsvzH81Nt6iJjELFIk,6395
171
171
  structures/webhooks/tests/test_utils.py,sha256=ekADFv0JOEtXeqdiejbeqrABO__Q1flJHzVieQ7L9e0,459
172
- aa_structures-2.3.0.dist-info/METADATA,sha256=mmKWmxJCl0aWhtcUAhW-ogP-n0gsdM6vzJbiHBYP6lk,5927
173
- aa_structures-2.3.0.dist-info/WHEEL,sha256=9MIigYJ7D5sOqAPqr0-o6tSMY_nQ7c6kvtvyeUB99YQ,87
174
- aa_structures-2.3.0.dist-info/licenses/LICENSE,sha256=XZiwB_S_40_HhnvLg5xvtBb3g1oGjPrk0rpFwk8iInE,1070
175
- aa_structures-2.3.0.dist-info/RECORD,,
172
+ aa_structures-2.3.1b1.dist-info/METADATA,sha256=zSW6E4hrOdu0rjMfLZxOKQqDrIxYm3IrsW4FS19ey9A,5929
173
+ aa_structures-2.3.1b1.dist-info/WHEEL,sha256=y1bSCq4r5i4nMmpXeUJMqs3ipKvkZObrIXSvJHm1qCI,87
174
+ aa_structures-2.3.1b1.dist-info/licenses/LICENSE,sha256=XZiwB_S_40_HhnvLg5xvtBb3g1oGjPrk0rpFwk8iInE,1070
175
+ aa_structures-2.3.1b1.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: hatchling 1.14.1
2
+ Generator: hatchling 1.17.0
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
structures/__init__.py CHANGED
@@ -1,4 +1,4 @@
1
1
  default_app_config = "structures.apps.StructuresConfig"
2
2
 
3
- __version__ = "2.3.0"
3
+ __version__ = "2.3.1b1"
4
4
  __title__ = "Structures"
@@ -239,7 +239,7 @@ class NotificationType(models.TextChoices):
239
239
  cls.SOV_STRUCTURE_REINFORCED,
240
240
  cls.SOV_STRUCTURE_DESTROYED,
241
241
  cls.SOV_ALL_CLAIM_LOST_MSG,
242
- cls.SOV_ALL_ANCHORING_MSG,
242
+ # cls.SOV_ALL_ANCHORING_MSG, # This notif is not broadcasted to all corporations
243
243
  # wars
244
244
  cls.WAR_ALLY_JOINED_WAR_AGGRESSOR_MSG,
245
245
  cls.WAR_ALLY_JOINED_WAR_AllY_MSG,
@@ -121,47 +121,73 @@ class TestNotificationFilterForAllianceLevel(NoSocketsTestCase):
121
121
  # given
122
122
  self.owner.is_alliance_main = False
123
123
  self.owner.save()
124
- notif = self.owner.notification_set.get(notification_id=1000000509)
124
+ notifs = self.owner.notification_set.exclude(
125
+ notif_type__in=NotificationType.relevant_for_alliance_level
126
+ )
125
127
  # when/then
126
- self.assertFalse(notif.filter_for_alliance_level())
128
+ for notif in notifs:
129
+ with self.subTest(notif=str(notif)):
130
+ self.assertFalse(notif.filter_for_alliance_level())
127
131
 
128
132
  def test_should_not_filter_non_alliance_notifications_2(self):
129
133
  # given
130
134
  self.owner.is_alliance_main = True
131
135
  self.owner.save()
132
- notif = self.owner.notification_set.get(notification_id=1000000509)
136
+ notifs = self.owner.notification_set.exclude(
137
+ notif_type__in=NotificationType.relevant_for_alliance_level
138
+ )
133
139
  # when/then
134
- self.assertFalse(notif.filter_for_alliance_level())
140
+ for notif in notifs:
141
+ with self.subTest(notif=str(notif)):
142
+ self.assertFalse(notif.filter_for_alliance_level())
135
143
 
136
144
  def test_should_filter_alliance_notifications(self):
137
145
  # given
138
146
  self.owner.is_alliance_main = False
139
147
  self.owner.save()
140
- notif = self.owner.notification_set.get(notification_id=1000000803)
148
+ notifs = self.owner.notification_set.filter(
149
+ notif_type__in=NotificationType.relevant_for_alliance_level
150
+ )
141
151
  # when/then
142
- self.assertTrue(notif.filter_for_alliance_level())
152
+ for notif in notifs:
153
+ with self.subTest(notif=str(notif)):
154
+ self.assertTrue(notif.filter_for_alliance_level())
143
155
 
144
156
  def test_should_not_filter_alliance_notifications_1(self):
145
157
  # given
146
158
  self.owner.is_alliance_main = True
147
159
  self.owner.save()
160
+ notifs = self.owner.notification_set.filter(
161
+ notif_type__in=NotificationType.relevant_for_alliance_level
162
+ )
148
163
  # when/then
149
- notif = self.owner.notification_set.get(notification_id=1000000803)
150
- self.assertFalse(notif.filter_for_alliance_level())
164
+ for notif in notifs:
165
+ with self.subTest(notif=str(notif)):
166
+ self.assertFalse(notif.filter_for_alliance_level())
151
167
 
152
168
  def test_should_not_filter_alliance_notifications_2(self):
153
169
  # given
154
170
  self.owner.is_alliance_main = True
155
171
  self.owner.save()
156
- notif = self.owner.notification_set.get(notification_id=1000000803)
157
- self.assertFalse(notif.filter_for_alliance_level())
172
+ notifs = self.owner.notification_set.filter(
173
+ notif_type__in=NotificationType.relevant_for_alliance_level
174
+ )
175
+ # when/then
176
+ for notif in notifs:
177
+ with self.subTest(notif=str(notif)):
178
+ self.assertFalse(notif.filter_for_alliance_level())
158
179
 
159
180
  def test_should_not_filter_alliance_notifications_3(self):
160
181
  # given
161
182
  _, owner = set_owner_character(character_id=1102) # corp with no alliance
162
183
  load_notification_entities(owner)
163
- notif = owner.notification_set.get(notification_id=1000000803)
164
- self.assertFalse(notif.filter_for_alliance_level())
184
+ notifs = self.owner.notification_set.filter(
185
+ notif_type__in=NotificationType.relevant_for_alliance_level
186
+ )
187
+ # when/then
188
+ for notif in notifs:
189
+ with self.subTest(notif=str(notif)):
190
+ self.assertFalse(notif.filter_for_alliance_level())
165
191
 
166
192
 
167
193
  class TestNotificationCreateFromStructure(NoSocketsTestCase):
@@ -16,9 +16,11 @@ from app_utils.esi_testing import EsiClientStub, EsiEndpoint
16
16
  from .. import tasks
17
17
  from ..models import NotificationType, Structure
18
18
  from .testdata.factories_2 import (
19
+ EveEntityAllianceFactory,
19
20
  EveEntityCorporationFactory,
20
21
  NotificationFactory,
21
22
  OwnerFactory,
23
+ RawNotificationFactory,
22
24
  StarbaseFactory,
23
25
  StructureFactory,
24
26
  WebhookFactory,
@@ -431,6 +433,91 @@ class TestTasks(TestCase):
431
433
  if AuthTimer:
432
434
  self.assertTrue(AuthTimer.objects.exists())
433
435
 
436
+ def test_should_fetch_and_send_notification_when_enabled_for_webhook(
437
+ self, mock_esi_2, mock_esi, mock_execute
438
+ ):
439
+ # given
440
+ webhook = WebhookFactory(
441
+ notification_types=[NotificationType.WAR_CORPORATION_BECAME_ELIGIBLE]
442
+ )
443
+ owner = OwnerFactory(webhooks=[webhook], is_alliance_main=True)
444
+ eve_character = owner.characters.first().character_ownership.character
445
+ # corporation_id = owner.corporation.corporation_id
446
+ notif = RawNotificationFactory()
447
+ endpoints = [
448
+ EsiEndpoint(
449
+ "Character",
450
+ "get_characters_character_id_notifications",
451
+ "character_id",
452
+ needs_token=True,
453
+ data={
454
+ str(eve_character.character_id): [notif],
455
+ },
456
+ ),
457
+ ]
458
+ mock_esi.client = mock_esi_2.client = EsiClientStub.create_from_endpoints(
459
+ endpoints
460
+ )
461
+ # when
462
+ tasks.fetch_all_notifications.delay()
463
+ # then
464
+ self.assertTrue(mock_execute.called)
465
+ embed = mock_execute.call_args[1]["embeds"][0]
466
+ self.assertIn("now eligible", embed.description)
467
+
468
+ def test_should_fetch_and_send_notification_when_enabled_for_webhook_all_anchoring(
469
+ self, mock_esi_2, mock_esi, mock_execute
470
+ ):
471
+ # given
472
+ webhook = WebhookFactory(
473
+ notification_types=[NotificationType.SOV_ALL_ANCHORING_MSG]
474
+ )
475
+ owner = OwnerFactory(webhooks=[webhook], is_alliance_main=False)
476
+ eve_character = owner.characters.first().character_ownership.character
477
+ alliance = EveEntityAllianceFactory(
478
+ id=owner.corporation.alliance_id,
479
+ name=owner.corporation.alliance.alliance_name,
480
+ )
481
+ corporation = EveEntityCorporationFactory(
482
+ id=owner.corporation.corporation_id, name=owner.corporation.corporation_name
483
+ )
484
+ starbase = StarbaseFactory(owner=owner)
485
+ notif = RawNotificationFactory(
486
+ type="AllAnchoringMsg",
487
+ sender=corporation,
488
+ data={
489
+ "allianceID": alliance.id,
490
+ "corpID": corporation.id,
491
+ "corpsPresent": [{"allianceID": alliance.id, "corpID": corporation.id}],
492
+ "moonID": starbase.eve_moon.id,
493
+ "solarSystemID": starbase.eve_solar_system.id,
494
+ "towers": [
495
+ {"moonID": starbase.eve_moon.id, "typeID": starbase.eve_type.id}
496
+ ],
497
+ "typeID": starbase.eve_type.id,
498
+ },
499
+ )
500
+ endpoints = [
501
+ EsiEndpoint(
502
+ "Character",
503
+ "get_characters_character_id_notifications",
504
+ "character_id",
505
+ needs_token=True,
506
+ data={
507
+ str(eve_character.character_id): [notif],
508
+ },
509
+ ),
510
+ ]
511
+ mock_esi.client = mock_esi_2.client = EsiClientStub.create_from_endpoints(
512
+ endpoints
513
+ )
514
+ # when
515
+ tasks.fetch_all_notifications.delay()
516
+ # then
517
+ self.assertTrue(mock_execute.called)
518
+ embed = mock_execute.call_args[1]["embeds"][0]
519
+ self.assertIn("has anchored in", embed.description)
520
+
434
521
  @patch(NOTIFICATIONS_PATH + ".STRUCTURES_ADD_TIMERS", True)
435
522
  def test_should_fetch_new_notification_from_esi_and_send_to_webhook_and_create_timers(
436
523
  self, mock_esi_2, mock_esi, mock_execute
@@ -508,7 +595,7 @@ class TestTasks(TestCase):
508
595
  NotificationType.SOV_ALL_CLAIM_LOST_MSG,
509
596
  ]
510
597
  )
511
- owner = OwnerFactory(webhooks=[webhook])
598
+ owner = OwnerFactory(webhooks=[webhook], is_alliance_main=True)
512
599
  NotificationFactory(
513
600
  owner=owner, notif_type=NotificationType.STRUCTURE_DESTROYED
514
601
  )
@@ -142,7 +142,7 @@ class OwnerFactory(factory.django.DjangoModelFactory):
142
142
  assets_last_update_at = factory.LazyFunction(now)
143
143
  character_ownership = None # no longer used
144
144
  forwarding_last_update_at = factory.LazyFunction(now)
145
- is_alliance_main = True
145
+ is_alliance_main = False
146
146
  is_up = True
147
147
  notifications_last_update_at = factory.LazyFunction(now)
148
148
  structures_last_update_at = factory.LazyFunction(now)
@@ -330,3 +330,36 @@ class GeneratedNotificationFactory(factory.django.DjangoModelFactory):
330
330
  state_timer_end=reinforced_until,
331
331
  )
332
332
  obj.structures.add(starbase)
333
+
334
+
335
+ class RawNotificationFactory(factory.DictFactory):
336
+ """Create a raw notification as received from ESI."""
337
+
338
+ class Meta:
339
+ exclude = ("data", "timestamp_dt", "sender")
340
+
341
+ # excluded
342
+ data = None
343
+ timestamp_dt = None
344
+ sender = factory.SubFactory(EveEntityCorporationFactory, id=2902, name="CONCORD")
345
+
346
+ # included
347
+ notification_id = factory.Sequence(lambda o: 1999000000 + o)
348
+ type = "CorpBecameWarEligible"
349
+ sender_id = factory.LazyAttribute(lambda o: o.sender.id)
350
+ sender_type = factory.LazyAttribute(lambda o: o.sender.category)
351
+ is_read = True
352
+
353
+ @factory.lazy_attribute
354
+ def timestamp(self):
355
+ if not self.timestamp_dt:
356
+ timestamp_dt = now()
357
+ else:
358
+ timestamp_dt = self.timestamp_dt
359
+ return datetime_to_esi(timestamp_dt)
360
+
361
+ @factory.lazy_attribute
362
+ def text(self):
363
+ if not self.data:
364
+ return ""
365
+ return yaml.dump(self.data)