"""Tests for the admin Block Kit modals — opening (views.open), submitting (view_submission), shared validation, and non-admin rejection (the IDOR case: a modal can be opened from Home, so the surface is never trusted).""" from unittest.mock import MagicMock import pytest from freezegun import freeze_time ADMIN = "U_ADMIN" INTRUDER = "U_INTRUDER" # 2026-06-01 is a Monday → night shift; 18:00 ET is inside the night window. MON_NIGHT = "2026-06-01 18:00:00" @pytest.fixture def admin_schedule(schedule, seed): seed.config(admin_users=[ADMIN]) return schedule @pytest.fixture def ack(): return MagicMock(name="ack") def _override_view(date="2026-12-25", ext="114", shift="night"): return { "state": { "values": { "date": {"date": {"selected_date": date}}, "extension": {"extension": {"selected_option": {"value": ext}}}, "shift_type": {"shift_type": {"selected_option": {"value": shift}}}, } } } def _holiday_view(date="2026-12-25", slots="2", multiplier="", label="Christmas"): return { "state": { "values": { "date": {"date": {"selected_date": date}}, "slots": {"slots": {"value": slots}}, "multiplier": {"multiplier": {"value": multiplier or None}}, "label": {"label": {"value": label}}, } } } def _body(user_id=ADMIN, trigger_id="T123"): return {"user": {"id": user_id}, "trigger_id": trigger_id} class TestOpenModals: def test_admin_opens_override_modal( self, slackbot_app, admin_schedule, seed, client ): seed.roster("114", "Alice") slackbot_app.open_override_modal(_body(), client, admin_schedule) view = client.views_open.call_args.kwargs["view"] assert view["callback_id"] == "admin_override_submit" def test_admin_opens_holiday_modal(self, slackbot_app, admin_schedule, client): slackbot_app.open_holiday_add_modal(_body(), client, admin_schedule) view = client.views_open.call_args.kwargs["view"] assert view["callback_id"] == "admin_holiday_add_submit" def test_non_admin_cannot_open_override(self, slackbot_app, admin_schedule, client): slackbot_app.open_override_modal(_body(INTRUDER), client, admin_schedule) client.views_open.assert_not_called() def test_non_admin_cannot_open_holiday(self, slackbot_app, admin_schedule, client): slackbot_app.open_holiday_add_modal(_body(INTRUDER), client, admin_schedule) client.views_open.assert_not_called() class TestOverrideSubmission: def test_happy_path(self, slackbot_app, admin_schedule, seed, ack, client): seed.roster("114", "Alice") slackbot_app.handle_override_submission( ack, _body(), _override_view(), client, admin_schedule, None ) assert admin_schedule.get_override("2026-12-25")["extension"] == "114" ack.assert_called_once_with() assert client.chat_postMessage.call_args.kwargs["channel"] == ADMIN @freeze_time(MON_NIGHT) def test_same_day_repoints_and_confirms( self, slackbot_app, admin_schedule, seed, ack, client, routing_spy ): seed.roster("114", "Alice") slackbot_app.handle_override_submission( ack, _body(), _override_view(date="2026-06-01"), client, admin_schedule, None, ) routing_spy.assert_called_once_with("114") assert "repointed" in client.chat_postMessage.call_args.kwargs["text"].lower() def test_unknown_extension_surfaces_field_error( self, slackbot_app, admin_schedule, ack, client ): slackbot_app.handle_override_submission( ack, _body(), _override_view(ext="999"), client, admin_schedule, None ) kwargs = ack.call_args.kwargs assert kwargs["response_action"] == "errors" assert "extension" in kwargs["errors"] assert admin_schedule.get_override("2026-12-25") is None def test_non_admin_rejected(self, slackbot_app, admin_schedule, seed, ack, client): seed.roster("114", "Alice") slackbot_app.handle_override_submission( ack, _body(INTRUDER), _override_view(), client, admin_schedule, None ) assert ack.call_args.kwargs["response_action"] == "errors" assert admin_schedule.get_override("2026-12-25") is None @freeze_time("2026-06-01 12:00:00") class TestHolidaySubmission: def test_happy_path(self, slackbot_app, admin_schedule, ack, client, monkeypatch): monkeypatch.setattr(slackbot_app, "_activate_holiday_inline", MagicMock()) slackbot_app.handle_holiday_add_submission( ack, _body(), _holiday_view(multiplier="2"), client, admin_schedule, "C_T" ) holiday = admin_schedule.get_holiday("2026-12-25") assert holiday["slots"] == 2 assert holiday["label"] == "Christmas" assert float(holiday["multiplier"]) == 2.0 ack.assert_called_once_with() assert client.chat_postMessage.call_args.kwargs["channel"] == ADMIN def test_default_multiplier_when_blank( self, slackbot_app, admin_schedule, ack, client, monkeypatch ): monkeypatch.setattr(slackbot_app, "_activate_holiday_inline", MagicMock()) slackbot_app.handle_holiday_add_submission( ack, _body(), _holiday_view(), client, admin_schedule, None ) assert float(admin_schedule.get_holiday("2026-12-25")["multiplier"]) == 1.5 def test_past_date_surfaces_field_error( self, slackbot_app, admin_schedule, ack, client ): slackbot_app.handle_holiday_add_submission( ack, _body(), _holiday_view(date="2026-01-01"), client, admin_schedule, None ) errors = ack.call_args.kwargs["errors"] assert "date" in errors and "past" in errors["date"].lower() assert admin_schedule.get_holiday("2026-01-01") is None def test_bad_slots_surfaces_field_error( self, slackbot_app, admin_schedule, ack, client ): slackbot_app.handle_holiday_add_submission( ack, _body(), _holiday_view(slots="lots"), client, admin_schedule, None ) assert "slots" in ack.call_args.kwargs["errors"] assert admin_schedule.get_holiday("2026-12-25") is None def test_missing_label_surfaces_field_error( self, slackbot_app, admin_schedule, ack, client ): slackbot_app.handle_holiday_add_submission( ack, _body(), _holiday_view(label=""), client, admin_schedule, None ) assert "label" in ack.call_args.kwargs["errors"] def test_bad_multiplier_surfaces_field_error( self, slackbot_app, admin_schedule, ack, client ): slackbot_app.handle_holiday_add_submission( ack, _body(), _holiday_view(multiplier="huge"), client, admin_schedule, None ) assert "multiplier" in ack.call_args.kwargs["errors"] def test_non_admin_rejected(self, slackbot_app, admin_schedule, ack, client): slackbot_app.handle_holiday_add_submission( ack, _body(INTRUDER), _holiday_view(), client, admin_schedule, None ) assert ack.call_args.kwargs["response_action"] == "errors" assert admin_schedule.get_holiday("2026-12-25") is None