Files
049-snack-and-lift/tests/unit/test_application_verification.py
Tirsvad 8c6cc148f5 Add My Bookings verification and date-independent booking (steps 7 and 8)
Booking entries parsed from the My Bookings page, comparison of expected
and found bookings with the lecture's output, NoBookingsFoundError as the
counterpart of NoSuchElementException, exit code 3 on a mismatch, tests for
every starting weekday of the 8-day window, container tests against local
fixtures.

Task: MIL-006#1
Task: MIL-006#2
Task: MIL-006#3
Task: MIL-006#4
2026-10-28 18:02:44 +08:00

82 lines
2.8 KiB
Python

"""@file test_application_verification.py
@brief Reading the My Bookings page and verifying the bookings, against a fake gym.
"""
import pytest
from tests.unit.fakes import FakeGym
from tests.unit.test_booking_entry import make_entry
from tests.unit.test_models import make_card
from snack_and_lift.application.booking import book_target_classes
from snack_and_lift.application.verification import get_my_bookings, verify_bookings
from snack_and_lift.domain.errors import GymError, NoBookingsFoundError
from snack_and_lift.domain.models import ClassResult, Outcome
def test_get_my_bookings_opens_the_page_and_returns_all_entries() -> None:
entries = [make_entry("Wed, Aug 13, 7:00 AM"), make_entry(waitlisted=True)]
gym = FakeGym(bookings=entries)
assert get_my_bookings(gym) == entries
assert gym.calls == ["open_my_bookings", "list_my_bookings"]
def test_get_my_bookings_raises_when_the_page_has_no_entry() -> None:
with pytest.raises(NoBookingsFoundError):
get_my_bookings(FakeGym(bookings=[]))
def test_get_my_bookings_propagates_the_page_error() -> None:
with pytest.raises(GymError, match="Failed to load"):
get_my_bookings(FakeGym(bookings_error="Failed to load bookings"))
def test_verify_bookings_succeeds_for_the_booked_classes() -> None:
gym = FakeGym(
cards=[
make_card("Tue, Aug 12", card_id="1"),
make_card("Thu, Aug 14", card_id="2", button_text="Join Waitlist"),
]
)
results = book_target_classes(gym)
verification = verify_bookings(gym, results)
assert verification.is_success
assert verification.verified == ["Spin Class", "Spin Class (Waitlist)"]
def test_verify_bookings_ignores_entries_that_are_not_target_classes() -> None:
gym = FakeGym(bookings=[make_entry(), make_entry("Wed, Aug 13, 6:00 PM")])
results = [ClassResult(make_card("Tue, Aug 12"), Outcome.NEW_BOOKING)]
assert verify_bookings(gym, results).is_success
def test_verify_bookings_reports_a_missing_booking() -> None:
gym = FakeGym(bookings=[make_entry("Wed, Aug 13, 7:00 AM")])
results = [ClassResult(make_card("Tue, Aug 12"), Outcome.NEW_BOOKING)]
verification = verify_bookings(gym, results)
assert not verification.is_success
assert verification.missing == ["Spin Class on Tue, Aug 12"]
def test_verify_bookings_raises_when_classes_were_booked_but_the_page_is_empty() -> None:
gym = FakeGym(bookings=[])
results = [ClassResult(make_card("Tue, Aug 12"), Outcome.NEW_BOOKING)]
with pytest.raises(NoBookingsFoundError):
verify_bookings(gym, results)
def test_verify_bookings_skips_the_page_when_nothing_is_expected() -> None:
gym = FakeGym()
verification = verify_bookings(gym, [])
assert verification.is_success
assert verification.expected == 0
assert gym.calls == []