Skip to content

Commit

Permalink
Adjust link serialization logic to match current map display (#193)
Browse files Browse the repository at this point in the history
  • Loading branch information
Andrew-Dickinson authored Feb 16, 2024
1 parent 023ff06 commit 6b33005
Show file tree
Hide file tree
Showing 4 changed files with 199 additions and 15 deletions.
18 changes: 14 additions & 4 deletions src/meshapi/serializers/map.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@

from meshapi.models import Install, Link, Sector

EXCLUDED_INSTALL_STATUSES = {
Install.InstallStatus.CLOSED,
Install.InstallStatus.NN_REASSIGNED,
}
ALLOWED_INSTALL_STATUSES = set(Install.InstallStatus.values) - EXCLUDED_INSTALL_STATUSES


class JavascriptDateField(serializers.IntegerField):
def to_internal_value(self, date_int_val: int):
Expand All @@ -27,17 +33,21 @@ def to_representation(self, date_val: datetime.date):


def get_install_number_from_building(building):
installs = building.installs.all()
installs = building.installs.exclude(install_status__in=EXCLUDED_INSTALL_STATUSES).order_by("install_number")
active_installs = [install for install in installs if install.install_status == Install.InstallStatus.ACTIVE]
if len(active_installs):
return active_installs[0].install_number

if len(installs) == 0:
if building.primary_nn:
return building.primary_nn
else:
raise ValueError(
f"Building with ID {building} is invalid for install "
f"number conversion, no attached installs or NN assigned"
f"Building {building} with ID {building.id} is invalid for install "
f"number conversion, no attached installs with or NN assigned to building"
)
else:
return min(install.install_number for install in installs)
return installs.first().install_number


class MapDataInstallSerializer(serializers.ModelSerializer):
Expand Down
169 changes: 169 additions & 0 deletions src/meshapi/tests/test_map_endpoints.py
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,16 @@ def test_link_data(self):
)
random.save()

inactive = Building(
building_status=Building.BuildingStatus.INACTIVE,
address_truth_sources="",
latitude=0,
longitude=0,
altitude=0,
primary_nn=123456,
)
inactive.save()

links.append(
Link(
from_building=sn1,
Expand Down Expand Up @@ -471,6 +481,24 @@ def test_link_data(self):
)
)

links.append(
Link(
from_building=sn1,
to_building=random,
status=Link.LinkStatus.DEAD,
type=Link.LinkType.STANDARD,
)
)

links.append(
Link(
from_building=sn1,
to_building=inactive,
status=Link.LinkStatus.ACTIVE,
type=Link.LinkType.STANDARD,
)
)

for link in links:
link.save()

Expand Down Expand Up @@ -508,3 +536,144 @@ def test_link_data(self):
},
],
)

def test_link_install_number_resolution(self):
links = []

# Use the same member for everything since it doesn't matter
member = Member(name="Fake Name")
member.save()

building_1 = Building(
building_status=Building.BuildingStatus.ACTIVE,
address_truth_sources="",
latitude=0,
longitude=0,
altitude=0,
primary_nn=555,
)
building_1.save()

Install(
install_number=5,
install_status=Install.InstallStatus.INACTIVE,
request_date=datetime.date(2015, 3, 15),
building=building_1,
member=member,
).save()
Install(
install_number=6,
install_status=Install.InstallStatus.CLOSED,
request_date=datetime.date(2015, 3, 15),
building=building_1,
member=member,
).save()
Install(
install_number=7,
install_status=Install.InstallStatus.ACTIVE,
request_date=datetime.date(2015, 3, 15),
building=building_1,
member=member,
).save()

building_2 = Building(
building_status=Building.BuildingStatus.ACTIVE,
address_truth_sources="",
latitude=0,
longitude=0,
altitude=0,
primary_nn=99,
)
building_2.save()
Install(
install_number=90,
install_status=Install.InstallStatus.CLOSED,
request_date=datetime.date(2015, 3, 15),
building=building_2,
member=member,
).save()
Install(
install_number=91,
install_status=Install.InstallStatus.NN_REASSIGNED,
request_date=datetime.date(2015, 3, 15),
building=building_2,
member=member,
).save()

building_3 = Building(
building_status=Building.BuildingStatus.ACTIVE,
address_truth_sources="",
latitude=0,
longitude=0,
altitude=0,
primary_nn=731,
)
building_3.save()
Install(
install_number=104,
install_status=Install.InstallStatus.PENDING,
request_date=datetime.date(2015, 3, 15),
building=building_3,
member=member,
).save()
Install(
install_number=105,
install_status=Install.InstallStatus.REQUEST_RECEIVED,
request_date=datetime.date(2015, 3, 15),
building=building_3,
member=member,
).save()

links.append(
Link(
from_building=building_1,
to_building=building_2,
status=Link.LinkStatus.ACTIVE,
type=Link.LinkType.STANDARD,
)
)

links.append(
Link(
from_building=building_2,
to_building=building_3,
status=Link.LinkStatus.ACTIVE,
type=Link.LinkType.STANDARD,
)
)

links.append(
Link(
from_building=building_3,
to_building=building_1,
status=Link.LinkStatus.ACTIVE,
type=Link.LinkType.STANDARD,
)
)

for link in links:
link.save()

self.maxDiff = None
response = self.c.get("/api/v1/mapdata/links/")

self.assertEqual(
json.loads(response.content.decode("UTF8")),
[
{
"from": 7,
"to": 99,
"status": "active",
},
{
"from": 99,
"to": 104,
"status": "active",
},
{
"from": 104,
"to": 7,
"status": "active",
},
],
)
2 changes: 1 addition & 1 deletion src/meshapi/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
path("query/install/", views.QueryInstall.as_view(), name="meshapi-v1-query-install"),
path("mapdata/installs/", views.MapDataInstallList.as_view(), name="meshapi-v1-map-data-installs"),
path("mapdata/links/", views.MapDataLinkList.as_view(), name="meshapi-v1-map-data-links"),
path("mapdata/sectors/", views.MapDataSectorlList.as_view(), name="meshapi-v1-map-data-sectors"),
path("mapdata/sectors/", views.MapDataSectorList.as_view(), name="meshapi-v1-map-data-sectors"),
path("geography/whole-mesh.kml", views.map_kml, name="meshapi-v1-geography-whole-mesh-kml"),
]

Expand Down
25 changes: 15 additions & 10 deletions src/meshapi/views/map.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,13 @@
from rest_framework import generics, permissions

from meshapi.models import Building, Install, Link, Sector
from meshapi.serializers import MapDataInstallSerializer, MapDataLinkSerializer, MapDataSectorSerializer
from meshapi.serializers import (
ALLOWED_INSTALL_STATUSES,
EXCLUDED_INSTALL_STATUSES,
MapDataInstallSerializer,
MapDataLinkSerializer,
MapDataSectorSerializer,
)


class MapDataInstallList(generics.ListAPIView):
Expand All @@ -13,12 +19,7 @@ class MapDataInstallList(generics.ListAPIView):
def get_queryset(self):
all_installs = []

excluded_statuses = {
Install.InstallStatus.CLOSED,
Install.InstallStatus.NN_REASSIGNED,
}

queryset = Install.objects.filter(~Q(install_status__in=excluded_statuses))
queryset = Install.objects.filter(~Q(install_status__in=EXCLUDED_INSTALL_STATUSES))

for install in queryset:
all_installs.append(install)
Expand All @@ -34,7 +35,7 @@ def get_queryset(self):
primary_nn__isnull=False,
building_status=Building.BuildingStatus.ACTIVE,
)
& Q(installs__install_status__in=set(Install.InstallStatus.values) - excluded_statuses)
& Q(installs__install_status__in=ALLOWED_INSTALL_STATUSES)
):
if building.primary_nn not in covered_nns:
representative_install = building.installs.all()[0]
Expand All @@ -57,10 +58,14 @@ class MapDataLinkList(generics.ListAPIView):
permission_classes = [permissions.AllowAny]
serializer_class = MapDataLinkSerializer
pagination_class = None
queryset = Link.objects.filter(~Q(status__in=[Link.LinkStatus.DEAD]))
queryset = (
Link.objects.exclude(status__in=[Link.LinkStatus.DEAD])
.exclude(from_building__building_status=Building.BuildingStatus.INACTIVE)
.exclude(to_building__building_status=Building.BuildingStatus.INACTIVE)
)


class MapDataSectorlList(generics.ListAPIView):
class MapDataSectorList(generics.ListAPIView):
permission_classes = [permissions.AllowAny]
serializer_class = MapDataSectorSerializer
pagination_class = None
Expand Down

0 comments on commit 6b33005

Please sign in to comment.