diff --git a/ws/templates/trips/medical.html b/ws/templates/trips/medical.html
index 65664bf2..b9178f75 100644
--- a/ws/templates/trips/medical.html
+++ b/ws/templates/trips/medical.html
@@ -15,5 +15,14 @@
{% endif %}
+{% if not has_wimp %}
+
+ No WIMP has been assigned to this trip!
+ {% if is_trip_leader %}
+
Set a WIMP?
+ {% endif %}
+
+{% endif %}
+
{% trip_info trip True %}
{% endblock content %}
diff --git a/ws/templatetags/medical_tags.py b/ws/templatetags/medical_tags.py
index 56b6fde5..af4d8845 100644
--- a/ws/templatetags/medical_tags.py
+++ b/ws/templatetags/medical_tags.py
@@ -38,8 +38,12 @@ def trip_itinerary(trip):
@register.inclusion_tag("for_templatetags/trip_info.html", takes_context=True)
-def trip_info(context, trip, show_participants_if_no_itinerary=False):
- participant = context["viewing_participant"]
+def trip_info(
+ context: dict[str, Any],
+ trip: models.Trip,
+ show_participants_if_no_itinerary: bool = False,
+) -> dict[str, Any]:
+ participant: models.Participant = context["viewing_participant"]
# After a sufficiently long waiting period, hide medical information
# (We could need medical info a day or two after a trip was due back)
diff --git a/ws/tests/views/test_itinerary.py b/ws/tests/views/test_itinerary.py
index 863bf1e0..f9870f82 100644
--- a/ws/tests/views/test_itinerary.py
+++ b/ws/tests/views/test_itinerary.py
@@ -266,8 +266,33 @@ def test_leader_for_another_trip(self):
trip = factories.TripFactory.create()
self._assert_cannot_view(trip)
- def test_view_as_leader(self):
- trip = factories.TripFactory.create(program=enums.Program.HIKING.value)
+ def test_view_as_leader_with_no_wimp(self):
+ trip = factories.TripFactory.create(
+ wimp=None, program=enums.Program.HIKING.value
+ )
+
+ leader = factories.ParticipantFactory.create(user=self.user)
+ factories.LeaderRatingFactory.create(
+ participant=leader, activity=models.LeaderRating.HIKING
+ )
+ trip.leaders.add(leader)
+ response = self.client.get(f"/trips/{trip.pk}/medical/")
+ soup = BeautifulSoup(response.content, "html.parser")
+
+ self.assertIsNone(trip.wimp)
+ self.assertNotEqual(trip.program_enum, enums.Program.WINTER_SCHOOL)
+ missing = soup.find(id="wimp-missing")
+ self.assertEqual(
+ strip_whitespace(missing.text),
+ "No WIMP has been assigned to this trip! Set a WIMP?",
+ )
+ self.assertIsNotNone(missing.find("a", href=f"/trips/{trip.pk}/edit/"))
+
+ def test_view_as_leader_with_wimp_set(self):
+ trip = factories.TripFactory.create(
+ wimp=factories.ParticipantFactory.create(),
+ program=enums.Program.HIKING.value,
+ )
factories.SignUpFactory.create(
participant__emergency_info__allergies="Bee stings", trip=trip, on_trip=True
@@ -281,6 +306,11 @@ def test_view_as_leader(self):
response = self.client.get(f"/trips/{trip.pk}/medical/")
soup = BeautifulSoup(response.content, "html.parser")
+ # This is a non-WS trip with a single WIMP set!
+ self.assertIsNotNone(trip.wimp)
+ self.assertNotEqual(trip.program_enum, enums.Program.WINTER_SCHOOL)
+ self.assertIsNone(soup.find(id="wimp-missing"))
+
# Participant medical info is given
self.assertTrue(soup.find("td", string="Bee stings"))
@@ -293,9 +323,37 @@ def test_view_as_leader(self):
)
)
- def test_view_as_wimp(self):
+ def test_view_ws_trip_as_wimp(self):
+ Group.objects.get(name="WIMP").user_set.add(self.user)
+ trip = factories.TripFactory.create(
+ wimp=None,
+ program=enums.Program.WINTER_SCHOOL.value,
+ )
+
+ factories.SignUpFactory.create(
+ participant__emergency_info__allergies="Bee stings", trip=trip, on_trip=True
+ )
+
+ response = self.client.get(f"/trips/{trip.pk}/medical/")
+ soup = BeautifulSoup(response.content, "html.parser")
+
+ # It's a Winter School trip -- we have one WIMP for *all* trips
+ self.assertIsNone(trip.wimp_id)
+ self.assertIsNone(soup.find(id="wimp-missing"))
+
+ # Participant medical info is given
+ self.assertTrue(soup.find("td", string="Bee stings"))
+
+ # The WIMP cannot provide an itinerary, they're not a leader
+ self.assertFalse(soup.find("a", href=f"/trips/{trip.pk}/itinerary/"))
+
+ def test_view_as_single_trip_wimp(self):
wimp = factories.ParticipantFactory.create(user=self.user)
- trip = factories.TripFactory.create(wimp=wimp)
+ trip = factories.TripFactory.create(
+ wimp=wimp,
+ # It's important that this *not* be a WS trip, since it has a WIMP!
+ program=enums.Program.HIKING.value,
+ )
factories.SignUpFactory.create(
participant__emergency_info__allergies="Bee stings", trip=trip, on_trip=True
@@ -304,6 +362,10 @@ def test_view_as_wimp(self):
response = self.client.get(f"/trips/{trip.pk}/medical/")
soup = BeautifulSoup(response.content, "html.parser")
+ # We of course have a WIMP
+ self.assertIsNotNone(trip.wimp_id)
+ self.assertIsNone(soup.find(id="wimp-missing"))
+
# Participant medical info is given
self.assertTrue(soup.find("td", string="Bee stings"))
diff --git a/ws/views/itinerary.py b/ws/views/itinerary.py
index 80362790..50901229 100644
--- a/ws/views/itinerary.py
+++ b/ws/views/itinerary.py
@@ -5,6 +5,8 @@
what the intended route will be, when to worry, and more.
"""
+from typing import Any
+
from django.contrib.auth.decorators import login_required
from django.core.exceptions import PermissionDenied
from django.db.models import Q
@@ -121,14 +123,19 @@ def dispatch(self, request, *args, **kwargs):
return render(request, "not_your_trip.html", {"trip": trip})
return normal_response
- def get_context_data(self, **kwargs):
+ def get_context_data(self, **kwargs: Any) -> dict[str, Any]:
"""Get a trip info form for display as readonly."""
context_data = super().get_context_data(**kwargs)
trip = self.object
- participant = self.request.participant
- context_data["is_trip_leader"] = perm_utils.leader_on_trip(participant, trip)
-
- return context_data
+ participant = self.request.participant # type: ignore[attr-defined]
+ return {
+ "is_trip_leader": perm_utils.leader_on_trip(participant, trip),
+ "has_wimp": (
+ trip.program_enum == enums.Program.WINTER_SCHOOL
+ or (trip.wimp_id is not None)
+ ),
+ **context_data,
+ }
class ChairTripView(DetailView):