From 97d3bb1f5ca9d27dec669450bfc23dc092bdb429 Mon Sep 17 00:00:00 2001
From: Felix Blanke <info@fblanke.de>
Date: Sun, 9 Feb 2025 23:52:03 +0100
Subject: [PATCH] Store IDs as integer in JSON export

---
 AKModel/models.py                 | 12 +++---
 AKModel/tests/test_json_export.py | 67 +++++++++++++++++--------------
 AKModel/views/ak.py               |  2 +-
 3 files changed, 43 insertions(+), 38 deletions(-)

diff --git a/AKModel/models.py b/AKModel/models.py
index f11c66e2..5bd570dc 100644
--- a/AKModel/models.py
+++ b/AKModel/models.py
@@ -871,7 +871,7 @@ class Room(models.Model):
             time_constraints = [f"availability-room-{self.pk}"]
 
         data = {
-            "id": str(self.pk),
+            "id": self.pk,
             "info": {
                 "name": self.name,
             },
@@ -1018,13 +1018,13 @@ class AKSlot(models.Model):
         ceil_offet_eps = decimal.Decimal(1e-4)
 
         data = {
-            "id": str(self.pk),
+            "id": self.pk,
             "duration": math.ceil(self.duration / self.event.export_slot - ceil_offet_eps),
             "properties": {
                 "conflicts":
-                    [str(conflict.pk) for conflict in conflict_slots.all()]
-                  + [str(second_slot.pk) for second_slot in other_ak_slots.all()],
-                "dependencies": [str(dep.pk) for dep in dependency_slots.all()],
+                    [conflict.pk for conflict in conflict_slots.all()]
+                  + [second_slot.pk for second_slot in other_ak_slots.all()],
+                "dependencies": [dep.pk for dep in dependency_slots.all()],
             },
             "room_constraints": [constraint.name
                                  for constraint in self.ak.requirements.all()],
@@ -1036,7 +1036,7 @@ class AKSlot(models.Model):
                 "description": self.ak.description,
                 "reso": self.ak.reso,
                 "duration_in_hours": float(self.duration),
-                "django_ak_id": str(self.ak.pk),
+                "django_ak_id": self.ak.pk,
                 },
             }
 
diff --git a/AKModel/tests/test_json_export.py b/AKModel/tests/test_json_export.py
index 5a604dc7..ee3774be 100644
--- a/AKModel/tests/test_json_export.py
+++ b/AKModel/tests/test_json_export.py
@@ -89,7 +89,7 @@ class JSONExportTest(TestCase):
             with self.subTest(event=event):
                 self.set_up_event(event=event)
                 self.assertEqual(
-                    {str(slot.pk) for slot in self.ak_slots},
+                    {slot.pk for slot in self.ak_slots},
                     self.export_objects["aks"].keys(),
                     "Exported AKs does not match the AKSlots of the event",
                 )
@@ -152,7 +152,7 @@ class JSONExportTest(TestCase):
                         f"{item} properties keys not as expected",
                     )
 
-                    self._check_type(ak["id"], str, "id", item=item)
+                    self._check_type(ak["id"], int, "id", item=item)
                     self._check_type(ak["duration"], int, "duration", item=item)
                     self._check_type(ak["info"]["name"], str, "info/name", item=item)
                     self._check_type(ak["info"]["head"], str, "info/head", item=item)
@@ -168,16 +168,22 @@ class JSONExportTest(TestCase):
                     )
                     self._check_type(
                         ak["info"]["django_ak_id"],
-                        str,
+                        int,
                         "info/django_ak_id",
                         item=item,
                     )
 
                     self._check_lst(
-                        ak["properties"]["conflicts"], "conflicts", item=item
+                        ak["properties"]["conflicts"],
+                        "conflicts",
+                        item=item,
+                        contained_type=int,
                     )
                     self._check_lst(
-                        ak["properties"]["dependencies"], "dependencies", item=item
+                        ak["properties"]["dependencies"],
+                        "dependencies",
+                        item=item,
+                        contained_type=int,
                     )
                     self._check_lst(
                         ak["time_constraints"], "time_constraints", item=item
@@ -212,7 +218,7 @@ class JSONExportTest(TestCase):
                         f"{item} info keys not as expected",
                     )
 
-                    self._check_type(room["id"], str, "id", item=item)
+                    self._check_type(room["id"], int, "id", item=item)
                     self._check_type(room["capacity"], int, "capacity", item=item)
                     self._check_type(room["info"]["name"], str, "info/name", item=item)
 
@@ -279,7 +285,7 @@ class JSONExportTest(TestCase):
                         {"start", "end"},
                         f"{item} info keys not as expected",
                     )
-                    self._check_type(timeslot["id"], str, "id", item=item)
+                    self._check_type(timeslot["id"], int, "id", item=item)
                     self._check_type(
                         timeslot["info"]["start"], str, "info/start", item=item
                     )
@@ -292,10 +298,10 @@ class JSONExportTest(TestCase):
                     if prev_id is not None:
                         self.assertLess(
                             prev_id,
-                            int(timeslot["id"]),
+                            timeslot["id"],
                             "timeslot ids must be increasing",
                         )
-                    prev_id = int(timeslot["id"])
+                    prev_id = timeslot["id"]
 
     def test_general_conformity_to_spec(self):
         """Test if rest of JSON structure and types conform to standard."""
@@ -332,7 +338,7 @@ class JSONExportTest(TestCase):
                 self.set_up_event(event=event)
 
                 for slot in self.ak_slots:
-                    ak = self.export_objects["aks"][str(slot.pk)]
+                    ak = self.export_objects["aks"][slot.pk]
 
                     self.assertLessEqual(
                         float(slot.duration) * self.slots_in_an_hour - 1e-4,
@@ -359,23 +365,22 @@ class JSONExportTest(TestCase):
                 self.set_up_event(event=event)
 
                 for slot in self.ak_slots:
-                    ak = self.export_objects["aks"][str(slot.pk)]
-                    conflict_slots = self.ak_slots.filter(
-                        ak__in=slot.ak.conflicts.all()
-                    ).values_list("pk", flat=True)
-                    conflict_pks = {str(conflict_pk) for conflict_pk in conflict_slots}
+                    ak = self.export_objects["aks"][slot.pk]
+                    conflict_slots = set(
+                        self.ak_slots.filter(
+                            ak__in=slot.ak.conflicts.all()
+                        ).values_list("pk", flat=True)
+                    )
 
                     other_ak_slots = (
                         self.ak_slots.filter(ak=slot.ak)
                         .exclude(pk=slot.pk)
                         .values_list("pk", flat=True)
                     )
-                    conflict_pks.update(
-                        str(other_slot_pk) for other_slot_pk in other_ak_slots
-                    )
+                    conflict_slots.update(other_ak_slots)
 
                     self.assertEqual(
-                        conflict_pks,
+                        conflict_slots,
                         set(ak["properties"]["conflicts"]),
                         f"Conflicts for slot {slot.pk} not as expected",
                     )
@@ -387,13 +392,13 @@ class JSONExportTest(TestCase):
                 self.set_up_event(event=event)
 
                 for slot in self.ak_slots:
-                    ak = self.export_objects["aks"][str(slot.pk)]
+                    ak = self.export_objects["aks"][slot.pk]
                     dependency_slots = self.ak_slots.filter(
                         ak__in=slot.ak.prerequisites.all()
                     ).values_list("pk", flat=True)
 
                     self.assertEqual(
-                        {str(dep_pk) for dep_pk in dependency_slots},
+                        set(dependency_slots),
                         set(ak["properties"]["dependencies"]),
                         f"Dependencies for slot {slot.pk} not as expected",
                     )
@@ -405,7 +410,7 @@ class JSONExportTest(TestCase):
                 self.set_up_event(event=event)
 
                 for slot in self.ak_slots:
-                    ak = self.export_objects["aks"][str(slot.pk)]
+                    ak = self.export_objects["aks"][slot.pk]
                     self.assertEqual(slot.ak.reso, ak["info"]["reso"])
                     self.assertEqual(
                         slot.ak.reso, "resolution" in ak["time_constraints"]
@@ -418,13 +423,13 @@ class JSONExportTest(TestCase):
                 self.set_up_event(event=event)
 
                 for slot in self.ak_slots:
-                    ak = self.export_objects["aks"][str(slot.pk)]
+                    ak = self.export_objects["aks"][slot.pk]
                     self.assertEqual(ak["info"]["name"], slot.ak.name)
                     self.assertEqual(
                         ak["info"]["head"], ", ".join(map(str, slot.ak.owners.all()))
                     )
                     self.assertEqual(ak["info"]["description"], slot.ak.description)
-                    self.assertEqual(ak["info"]["django_ak_id"], str(slot.ak.pk))
+                    self.assertEqual(ak["info"]["django_ak_id"], slot.ak.pk)
 
     def test_ak_room_constraints(self):
         """Test if AK room constraints are exported as expected."""
@@ -433,7 +438,7 @@ class JSONExportTest(TestCase):
                 self.set_up_event(event=event)
 
                 for slot in self.ak_slots:
-                    ak = self.export_objects["aks"][str(slot.pk)]
+                    ak = self.export_objects["aks"][slot.pk]
                     requirements = list(
                         slot.ak.requirements.values_list("name", flat=True)
                     )
@@ -488,7 +493,7 @@ class JSONExportTest(TestCase):
                         ):
                             time_constraints.add(f"availability-person-{owner.pk}")
 
-                    ak = self.export_objects["aks"][str(slot.pk)]
+                    ak = self.export_objects["aks"][slot.pk]
                     self.assertEqual(
                         set(ak["time_constraints"]),
                         time_constraints,
@@ -502,7 +507,7 @@ class JSONExportTest(TestCase):
                 self.set_up_event(event=event)
 
                 self.assertEqual(
-                    {str(room.pk) for room in self.rooms},
+                    {room.pk for room in self.rooms},
                     self.export_objects["rooms"].keys(),
                     "Exported Rooms do not match the Rooms of the event",
                 )
@@ -514,7 +519,7 @@ class JSONExportTest(TestCase):
                 self.set_up_event(event=event)
 
                 for room in self.rooms:
-                    export_room = self.export_objects["rooms"][str(room.pk)]
+                    export_room = self.export_objects["rooms"][room.pk]
                     self.assertEqual(room.capacity, export_room["capacity"])
 
     def test_room_info(self):
@@ -524,7 +529,7 @@ class JSONExportTest(TestCase):
                 self.set_up_event(event=event)
 
                 for room in self.rooms:
-                    export_room = self.export_objects["rooms"][str(room.pk)]
+                    export_room = self.export_objects["rooms"][room.pk]
                     self.assertEqual(room.name, export_room["info"]["name"])
 
     def test_room_timeconstraints(self):
@@ -542,7 +547,7 @@ class JSONExportTest(TestCase):
                     ):
                         time_constraints.add(f"availability-room-{room.pk}")
 
-                    export_room = self.export_objects["rooms"][str(room.pk)]
+                    export_room = self.export_objects["rooms"][room.pk]
                     self.assertEqual(
                         time_constraints, set(export_room["time_constraints"])
                     )
@@ -568,7 +573,7 @@ class JSONExportTest(TestCase):
 
                     fulfilled_room_constraints.add(f"fixed-room-{room.pk}")
 
-                    export_room = self.export_objects["rooms"][str(room.pk)]
+                    export_room = self.export_objects["rooms"][room.pk]
                     self.assertEqual(
                         fulfilled_room_constraints,
                         set(export_room["fulfilled_room_constraints"]),
diff --git a/AKModel/views/ak.py b/AKModel/views/ak.py
index f6fd7932..d2f17676 100644
--- a/AKModel/views/ak.py
+++ b/AKModel/views/ak.py
@@ -147,7 +147,7 @@ class AKJSONExportView(AdminViewMixin, FilterByEventSlugMixin, ListView):
                 time_constraints.extend(timeslot.constraints)
 
                 current_block.append({
-                    "id": str(timeslot.idx),
+                    "id": timeslot.idx,
                     "info": {
                         "start": timeslot.avail.start.astimezone(self.event.timezone).strftime("%Y-%m-%d %H:%M"),
                         "end": timeslot.avail.end.astimezone(self.event.timezone).strftime("%Y-%m-%d %H:%M"),
-- 
GitLab