aa-structures 2.9.1__py3-none-any.whl → 2.11.0__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_structures-2.9.1.dist-info → aa_structures-2.11.0.dist-info}/METADATA +1 -1
- {aa_structures-2.9.1.dist-info → aa_structures-2.11.0.dist-info}/RECORD +24 -20
- structures/__init__.py +1 -1
- structures/admin.py +43 -4
- structures/app_settings.py +1 -1
- structures/auth_hooks.py +6 -1
- structures/managers.py +17 -4
- structures/migrations/0006_add_ownercharacter_disabled.py +27 -0
- structures/models/owners.py +104 -51
- structures/tests/integration/test_tasks.py +2 -3
- structures/tests/integration/test_views.py +2 -2
- structures/tests/models/test_owners_1.py +95 -52
- structures/tests/models/test_owners_4.py +21 -5
- structures/tests/models/test_owners_6.py +31 -0
- structures/tests/test_admin.py +65 -0
- structures/tests/test_managers_2.py +3 -2
- structures/tests/testdata/factories.py +3 -4
- structures/tests/views/test_service_status.py +113 -0
- structures/tests/views/test_structures.py +52 -80
- structures/urls.py +3 -2
- structures/views/status.py +22 -0
- structures/views/structures.py +3 -19
- {aa_structures-2.9.1.dist-info → aa_structures-2.11.0.dist-info}/LICENSE +0 -0
- {aa_structures-2.9.1.dist-info → aa_structures-2.11.0.dist-info}/WHEEL +0 -0
@@ -8,13 +8,13 @@ from django.urls import reverse
|
|
8
8
|
from django.utils.dateparse import parse_datetime
|
9
9
|
from django.utils.timezone import now
|
10
10
|
|
11
|
+
from allianceauth.eveonline.models import EveCharacter
|
11
12
|
from app_utils.testdata_factories import UserMainFactory
|
12
13
|
from app_utils.testing import json_response_to_python
|
13
14
|
|
15
|
+
import structures.views.status
|
14
16
|
from structures.models import Owner, Structure
|
15
|
-
from structures.
|
16
|
-
|
17
|
-
from ..testdata.factories import (
|
17
|
+
from structures.tests.testdata.factories import (
|
18
18
|
EveCharacterFactory,
|
19
19
|
JumpGateFactory,
|
20
20
|
OwnerFactory,
|
@@ -26,7 +26,9 @@ from ..testdata.factories import (
|
|
26
26
|
UserMainDefaultOwnerFactory,
|
27
27
|
WebhookFactory,
|
28
28
|
)
|
29
|
-
from
|
29
|
+
from structures.tests.testdata.load_eveuniverse import load_eveuniverse
|
30
|
+
from structures.views import structures
|
31
|
+
|
30
32
|
from .utils import json_response_to_dict
|
31
33
|
|
32
34
|
VIEWS_PATH = "structures.views.structures"
|
@@ -526,7 +528,7 @@ class TestAddStructureOwner(TestCase):
|
|
526
528
|
cls.factory = RequestFactory()
|
527
529
|
load_eveuniverse()
|
528
530
|
cls.user = UserMainDefaultOwnerFactory()
|
529
|
-
cls.character = cls.user.profile.main_character
|
531
|
+
cls.character: EveCharacter = cls.user.profile.main_character
|
530
532
|
cls.character_ownership = cls.character.character_ownership
|
531
533
|
|
532
534
|
def _add_structure_owner_view(self, token=None, user=None):
|
@@ -655,87 +657,57 @@ class TestAddStructureOwner(TestCase):
|
|
655
657
|
)
|
656
658
|
self.assertTrue(owner.is_active)
|
657
659
|
|
658
|
-
|
659
|
-
|
660
|
-
@
|
661
|
-
|
662
|
-
|
663
|
-
|
664
|
-
|
665
|
-
|
666
|
-
def test_view_service_status_ok(self):
|
667
|
-
# given
|
668
|
-
OwnerFactory(
|
669
|
-
structures_last_update_at=now(),
|
670
|
-
notifications_last_update_at=now(),
|
671
|
-
forwarding_last_update_at=now(),
|
672
|
-
assets_last_update_at=now(),
|
673
|
-
)
|
674
|
-
request = self.factory.get(reverse("structures:service_status"))
|
675
|
-
# when
|
676
|
-
response = structures.service_status(request)
|
677
|
-
# then
|
678
|
-
self.assertEqual(response.status_code, 200)
|
679
|
-
|
680
|
-
@patch(OWNERS_PATH + ".STRUCTURES_STRUCTURE_SYNC_GRACE_MINUTES", 30)
|
681
|
-
def test_view_service_status_fail_structures(self):
|
660
|
+
@patch(VIEWS_PATH + ".STRUCTURES_ADMIN_NOTIFICATIONS_ENABLED", False)
|
661
|
+
@patch(VIEWS_PATH + ".tasks.update_all_for_owner")
|
662
|
+
@patch(VIEWS_PATH + ".notify_admins")
|
663
|
+
@patch(VIEWS_PATH + ".messages")
|
664
|
+
def test_can_readd_same_character(
|
665
|
+
self, mock_messages, mock_notify_admins, mock_update_all_for_owner
|
666
|
+
):
|
682
667
|
# given
|
683
|
-
OwnerFactory(
|
684
|
-
|
685
|
-
notifications_last_update_at=now(),
|
686
|
-
forwarding_last_update_at=now(),
|
687
|
-
assets_last_update_at=now(),
|
688
|
-
)
|
689
|
-
request = self.factory.get(reverse("structures:service_status"))
|
668
|
+
owner = OwnerFactory(characters=[self.character])
|
669
|
+
owner_character = owner.characters.first()
|
690
670
|
# when
|
691
|
-
response =
|
671
|
+
response = self._add_structure_owner_view(user=self.user)
|
692
672
|
# then
|
693
|
-
self.assertEqual(response.status_code,
|
694
|
-
|
695
|
-
|
696
|
-
|
697
|
-
|
698
|
-
OwnerFactory(
|
699
|
-
structures_last_update_at=now(),
|
700
|
-
notifications_last_update_at=now() - dt.timedelta(minutes=31),
|
701
|
-
forwarding_last_update_at=now(),
|
702
|
-
assets_last_update_at=now(),
|
673
|
+
self.assertEqual(response.status_code, 302)
|
674
|
+
self.assertEqual(response.url, reverse("structures:index"))
|
675
|
+
owner.refresh_from_db()
|
676
|
+
character_ownerships = set(
|
677
|
+
owner.characters.values_list("character_ownership", flat=True)
|
703
678
|
)
|
704
|
-
|
705
|
-
|
706
|
-
|
707
|
-
# then
|
708
|
-
self.assertEqual(response.status_code, 500)
|
709
|
-
|
710
|
-
@patch(OWNERS_PATH + ".STRUCTURES_NOTIFICATION_SYNC_GRACE_MINUTES", 30)
|
711
|
-
def test_view_service_status_fail_forwarding(self):
|
712
|
-
# given
|
713
|
-
OwnerFactory(
|
714
|
-
structures_last_update_at=now(),
|
715
|
-
notifications_last_update_at=now(),
|
716
|
-
forwarding_last_update_at=now() - dt.timedelta(minutes=31),
|
717
|
-
assets_last_update_at=now(),
|
679
|
+
self.assertSetEqual(
|
680
|
+
{self.character_ownership.pk, owner_character.character_ownership.pk},
|
681
|
+
character_ownerships,
|
718
682
|
)
|
719
|
-
request = self.factory.get(reverse("structures:service_status"))
|
720
|
-
# when
|
721
|
-
response = structures.service_status(request)
|
722
|
-
# then
|
723
|
-
self.assertEqual(response.status_code, 500)
|
724
683
|
|
725
|
-
@patch(
|
726
|
-
|
727
|
-
|
728
|
-
|
729
|
-
|
730
|
-
|
731
|
-
|
732
|
-
|
733
|
-
|
734
|
-
|
735
|
-
|
736
|
-
|
737
|
-
|
738
|
-
|
684
|
+
# @patch(VIEWS_PATH + ".STRUCTURES_ADMIN_NOTIFICATIONS_ENABLED", False)
|
685
|
+
# @patch(VIEWS_PATH + ".tasks.update_all_for_owner")
|
686
|
+
# @patch(VIEWS_PATH + ".notify_admins")
|
687
|
+
# @patch(VIEWS_PATH + ".messages")
|
688
|
+
# def test_should_reenable_character_when_re_adding(
|
689
|
+
# self, mock_messages, mock_notify_admins, mock_update_all_for_owner
|
690
|
+
# ):
|
691
|
+
# # given
|
692
|
+
# owner = OwnerFactory(characters=[self.character])
|
693
|
+
# owner_character: OwnerCharacter = owner.characters.first()
|
694
|
+
# owner_character.is_enabled = False
|
695
|
+
# owner_character.save()
|
696
|
+
# # when
|
697
|
+
# response = self._add_structure_owner_view(user=self.user)
|
698
|
+
# # then
|
699
|
+
# self.assertEqual(response.status_code, 302)
|
700
|
+
# self.assertEqual(response.url, reverse("structures:index"))
|
701
|
+
# owner.refresh_from_db()
|
702
|
+
# character_ownerships = set(
|
703
|
+
# owner.characters.values_list("character_ownership", flat=True)
|
704
|
+
# )
|
705
|
+
# self.assertSetEqual(
|
706
|
+
# {self.character_ownership.pk, owner_character.character_ownership.pk},
|
707
|
+
# character_ownerships,
|
708
|
+
# )
|
709
|
+
# owner_character.refresh_from_db()
|
710
|
+
# self.assertTrue(owner_character.is_enabled)
|
739
711
|
|
740
712
|
|
741
713
|
class TestStructureFittingModal(TestCase):
|
structures/urls.py
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
"""Tasks for Structures."""
|
2
2
|
|
3
3
|
from django.urls import path
|
4
|
+
from django.views.decorators.cache import never_cache
|
4
5
|
|
5
|
-
from .views import public, statistics, structures
|
6
|
+
from .views import public, statistics, status, structures
|
6
7
|
|
7
8
|
app_name = "structures"
|
8
9
|
|
@@ -19,7 +20,7 @@ urlpatterns = [
|
|
19
20
|
structures.add_structure_owner,
|
20
21
|
name="add_structure_owner",
|
21
22
|
),
|
22
|
-
path("service_status",
|
23
|
+
path("service_status", never_cache(status.service_status), name="service_status"),
|
23
24
|
path(
|
24
25
|
"<int:structure_id>/structure_details",
|
25
26
|
structures.structure_details,
|
@@ -0,0 +1,22 @@
|
|
1
|
+
"""Status views."""
|
2
|
+
|
3
|
+
from django.http import HttpRequest, HttpResponse, HttpResponseServerError
|
4
|
+
|
5
|
+
from structures.models import Owner
|
6
|
+
|
7
|
+
|
8
|
+
def service_status(request: HttpRequest):
|
9
|
+
"""Public view to 3rd party monitoring.
|
10
|
+
|
11
|
+
This is view allows running a 3rd party monitoring on the status
|
12
|
+
of this services. Service will be reported as down if any of the
|
13
|
+
configured structure or notifications syncs fails or is delayed
|
14
|
+
"""
|
15
|
+
active_owners = Owner.objects.filter(
|
16
|
+
is_included_in_service_status=True, is_active=True
|
17
|
+
)
|
18
|
+
for owner in active_owners:
|
19
|
+
if not owner.are_all_syncs_ok:
|
20
|
+
return HttpResponseServerError("service is down")
|
21
|
+
|
22
|
+
return HttpResponse("service is up")
|
structures/views/structures.py
CHANGED
@@ -10,7 +10,7 @@ from django.contrib import messages
|
|
10
10
|
from django.contrib.auth.decorators import login_required, permission_required
|
11
11
|
from django.contrib.auth.models import User
|
12
12
|
from django.db.models import Prefetch
|
13
|
-
from django.http import HttpRequest,
|
13
|
+
from django.http import HttpRequest, JsonResponse
|
14
14
|
from django.shortcuts import get_object_or_404, redirect, render
|
15
15
|
from django.templatetags.static import static
|
16
16
|
from django.urls import reverse
|
@@ -630,7 +630,7 @@ def add_structure_owner(request: HttpRequest, token: Token):
|
|
630
630
|
% {
|
631
631
|
"corporation": owner,
|
632
632
|
"character": token_char,
|
633
|
-
"characters_count": owner.
|
633
|
+
"characters_count": owner.valid_characters_count(),
|
634
634
|
}
|
635
635
|
),
|
636
636
|
)
|
@@ -646,24 +646,8 @@ def add_structure_owner(request: HttpRequest, token: Token):
|
|
646
646
|
"character": token_char,
|
647
647
|
"corporation": owner,
|
648
648
|
"user": request.user.username,
|
649
|
-
"characters_count": owner.
|
649
|
+
"characters_count": owner.valid_characters_count(),
|
650
650
|
},
|
651
651
|
title=_("%s: Character added to: %s") % (__title__, owner),
|
652
652
|
)
|
653
653
|
return redirect("structures:index")
|
654
|
-
|
655
|
-
|
656
|
-
def service_status(request: HttpRequest):
|
657
|
-
"""Public view to 3rd party monitoring.
|
658
|
-
|
659
|
-
This is view allows running a 3rd party monitoring on the status
|
660
|
-
of this services. Service will be reported as down if any of the
|
661
|
-
configured structure or notifications syncs fails or is delayed
|
662
|
-
"""
|
663
|
-
status_ok = True
|
664
|
-
for owner in Owner.objects.filter(is_included_in_service_status=True):
|
665
|
-
status_ok = status_ok and owner.are_all_syncs_ok
|
666
|
-
|
667
|
-
if status_ok:
|
668
|
-
return HttpResponse(_("service is up"))
|
669
|
-
return HttpResponseServerError(_("service is down"))
|
File without changes
|
File without changes
|