"""Tests for slack-bot _handle_swap — now creates a pending swap + DMs the target instead of reassigning immediately.""" from freezegun import freeze_time MON = "2026-06-01 12:00:00" def _setup(seed): seed.roster("114", "Alice", slack_user_id="U_ALICE") seed.roster("115", "Bob", slack_user_id="U_BOB") seed.weekly("Monday", "114", "Alice") # Alice is on the Monday shift @freeze_time(MON) def test_request_creates_pending_and_dms_target( slackbot_app, schedule, seed, respond, client, routing_spy, text_of ): _setup(seed) slackbot_app._handle_swap( respond, schedule, "U_ALICE", "swap today <@U_BOB>", "C1", client, "C_TEST" ) swap = schedule.get_swap("2026-06-01") assert swap["status"] == "pending" and swap["target_ext"] == "115" # Not applied yet — the shift still belongs to Alice. assert schedule.get_override("2026-06-01") is None routing_spy.assert_not_called() # DM'd the target, told the requester. assert client.chat_postMessage.call_args.kwargs["channel"] == "U_BOB" assert "Swap request sent" in text_of(respond) @freeze_time(MON) def test_request_by_extension( slackbot_app, schedule, seed, respond, client, routing_spy ): _setup(seed) slackbot_app._handle_swap( respond, schedule, "U_ALICE", "swap today 115", "C1", client, "C_TEST" ) assert schedule.get_swap("2026-06-01")["target_ext"] == "115" @freeze_time(MON) def test_later_request_supersedes(slackbot_app, schedule, seed, respond, client): _setup(seed) seed.roster("116", "Carol", slack_user_id="U_CAROL") slackbot_app._handle_swap( respond, schedule, "U_ALICE", "swap today <@U_BOB>", "C1", client, "C_TEST" ) slackbot_app._handle_swap( respond, schedule, "U_ALICE", "swap today <@U_CAROL>", "C1", client, "C_TEST" ) assert schedule.get_swap("2026-06-01")["target_ext"] == "116" @freeze_time(MON) def test_target_not_linked_to_slack( slackbot_app, schedule, seed, respond, client, text_of ): seed.roster("114", "Alice", slack_user_id="U_ALICE") seed.roster("115", "Bob") # registered but never linked Slack seed.weekly("Monday", "114", "Alice") slackbot_app._handle_swap( respond, schedule, "U_ALICE", "swap today 115", "C1", client, "C_TEST" ) assert "isn't linked to Slack" in text_of(respond) assert schedule.get_swap("2026-06-01") is None @freeze_time(MON) def test_swap_to_self_rejected(slackbot_app, schedule, seed, respond, client, text_of): _setup(seed) slackbot_app._handle_swap( respond, schedule, "U_ALICE", "swap today 114", "C1", client, "C_TEST" ) assert "already yours" in text_of(respond).lower() @freeze_time(MON) def test_not_your_shift(slackbot_app, schedule, seed, respond, client, text_of): seed.roster("114", "Alice", slack_user_id="U_ALICE") seed.roster("115", "Bob", slack_user_id="U_BOB") seed.weekly("Monday", "115", "Bob") # Bob's shift, not Alice's slackbot_app._handle_swap( respond, schedule, "U_ALICE", "swap today <@U_BOB>", "C1", client, "C_TEST" ) assert "not your shift" in text_of(respond).lower() assert schedule.get_swap("2026-06-01") is None @freeze_time(MON) def test_target_mention_unregistered( slackbot_app, schedule, seed, respond, client, text_of ): seed.roster("114", "Alice", slack_user_id="U_ALICE") seed.weekly("Monday", "114", "Alice") slackbot_app._handle_swap( respond, schedule, "U_ALICE", "swap today <@U_GHOST>", "C1", client, "C_TEST" ) assert "isn't registered" in text_of(respond) @freeze_time(MON) def test_target_extension_not_found( slackbot_app, schedule, seed, respond, client, text_of ): seed.roster("114", "Alice", slack_user_id="U_ALICE") seed.weekly("Monday", "114", "Alice") slackbot_app._handle_swap( respond, schedule, "U_ALICE", "swap today 999", "C1", client, "C_TEST" ) assert "not found" in text_of(respond).lower() @freeze_time(MON) def test_past_date(slackbot_app, schedule, seed, respond, client, text_of): _setup(seed) slackbot_app._handle_swap( respond, schedule, "U_ALICE", "swap 2026-05-01 <@U_BOB>", "C1", client, "C_TEST" ) assert "past" in text_of(respond).lower() @freeze_time(MON) def test_unregistered_requester(slackbot_app, schedule, respond, client, text_of): slackbot_app._handle_swap( respond, schedule, "U_NOBODY", "swap today 115", "C1", client, "C_TEST" ) assert "not registered" in text_of(respond).lower() @freeze_time(MON) def test_usage(slackbot_app, schedule, respond, client, text_of): slackbot_app._handle_swap( respond, schedule, "U_ALICE", "swap today", "C1", client, "C_TEST" ) assert "Usage" in text_of(respond)