Repository: ietf-tools/datatracker

Issue:
"Show location" toggle for meeting time slots not having intended effect
### Describe the issue

Reported by @flynnliz,

> The function to hide a particular session’s location isn’t working. 

Demonstration / workaround:
* Create a "break" timeslot with a location (required) and uncheck the "show location" box
* create session request, drag and drop into timeslot
* *observe that the agenda shows the location*
* edit the timeslot to change location to "--" and save
* *observe that the agenda shows a blank location*
With this workaround, the timeslot edit grid (`meeting/<num>/timeslots/edit`) no longer shows the timeslot. This makes editing the timeslot impossible/inconvenient.

### Code of Conduct

- [X] I agree to follow the [IETF's Code of Conduct](https://github.com/ietf-tools/.github/blob/main/CODE_OF_CONDUCT.md)


Discussion:

Resolving patch:
diff --git a/ietf/meeting/views.py b/ietf/meeting/views.py
--- a/ietf/meeting/views.py
+++ b/ietf/meeting/views.py
@@ -1701,11 +1701,11 @@ def agenda_extract_schedule (item):
     return {
         "id": item.id,
         "sessionId": item.session.id,
-        "room": item.room_name,
+        "room": item.room_name if item.timeslot.show_location else None,
         "location": {
             "short": item.timeslot.location.floorplan.short,
             "name": item.timeslot.location.floorplan.name,
-        } if (item.timeslot.location and item.timeslot.location.floorplan) else {},
+        } if (item.timeslot.show_location and item.timeslot.location and item.timeslot.location.floorplan) else {},
         "acronym": item.acronym,
         "duration": item.timeslot.duration.seconds,
         "name": item.timeslot.name,


Test patch:
diff --git a/ietf/meeting/tests_views.py b/ietf/meeting/tests_views.py
--- a/ietf/meeting/tests_views.py
+++ b/ietf/meeting/tests_views.py
@@ -39,15 +39,15 @@
 from ietf.group.models import Group, Role, GroupFeatures
 from ietf.group.utils import can_manage_group
 from ietf.person.models import Person
-from ietf.meeting.helpers import can_approve_interim_request, can_view_interim_request
-from ietf.meeting.helpers import send_interim_approval_request
+from ietf.meeting.helpers import can_approve_interim_request, can_view_interim_request, preprocess_assignments_for_agenda
+from ietf.meeting.helpers import send_interim_approval_request, AgendaKeywordTagger
 from ietf.meeting.helpers import send_interim_meeting_cancellation_notice, send_interim_session_cancellation_notice
 from ietf.meeting.helpers import send_interim_minutes_reminder, populate_important_dates, update_important_dates
 from ietf.meeting.models import Session, TimeSlot, Meeting, SchedTimeSessAssignment, Schedule, SessionPresentation, SlideSubmission, SchedulingEvent, Room, Constraint, ConstraintName
 from ietf.meeting.test_data import make_meeting_test_data, make_interim_meeting, make_interim_test_data
 from ietf.meeting.utils import finalize, condition_slide_order
 from ietf.meeting.utils import add_event_info_to_session_qs
-from ietf.meeting.views import session_draft_list, parse_agenda_filter_params, sessions_post_save
+from ietf.meeting.views import session_draft_list, parse_agenda_filter_params, sessions_post_save, agenda_extract_schedule
 from ietf.name.models import SessionStatusName, ImportantDateName, RoleName, ProceedingsMaterialTypeName
 from ietf.utils.decorators import skip_coverage
 from ietf.utils.mail import outbox, empty_outbox, get_payload_text
@@ -147,6 +147,31 @@ def write_materials_files(self, meeting, session):
                                   "This is a slideshow")
 
 
+class AgendaApiTests(TestCase):
+    def test_agenda_extract_schedule_location(self):
+        meeting = MeetingFactory(type_id='ietf')
+        room = RoomFactory(meeting=meeting, floorplan=FloorPlanFactory(meeting=meeting))
+        hidden_ts = TimeSlotFactory(meeting=meeting, location=room, show_location=False)
+        shown_ts = TimeSlotFactory(meeting=meeting, location=room, show_location=True)
+        hidden_sess = SessionFactory(meeting=meeting, add_to_schedule=False)
+        shown_sess = SessionFactory(meeting=meeting, add_to_schedule=False)
+        meeting.schedule.assignments.create(timeslot=hidden_ts, session=hidden_sess)
+        meeting.schedule.assignments.create(timeslot=shown_ts, session=shown_sess)
+        processed = preprocess_assignments_for_agenda(
+            SchedTimeSessAssignment.objects.filter(session__in=[hidden_sess, shown_sess]),
+            meeting
+        )
+        AgendaKeywordTagger(assignments=processed).apply()
+        extracted = {item.pk: agenda_extract_schedule(item) for item in processed}
+
+        hidden = extracted[hidden_sess.pk]
+        self.assertIsNone(hidden['room'])
+        self.assertEqual(hidden['location'], {})
+
+        shown = extracted[shown_sess.pk]
+        self.assertEqual(shown['room'], room.name)
+        self.assertEqual(shown['location'], {'name': room.floorplan.name, 'short': room.floorplan.short})
+
 
 class MeetingTests(BaseMeetingTestCase):
     def test_meeting_agenda(self):