Files
040-personal-flight-club/tests/test_notification_manager.py
Tirsvad 2f3bdd41e2
Quality checks / quality-checks (pull_request) Successful in 27s
Quality / quality (pull_request) Successful in 27s
English comments / english-comments (pull_request) Successful in 26s
Tests / pytest (pull_request) Successful in 49s
Carry over the Day 39 code, tests, CI workflows, Doxyfile and env template
Task: MIL-001#1
Task: MIL-001#2
Task: MIL-001#3
Task: MIL-001#4
Task: MIL-001#5
2026-10-24 23:38:25 +08:00

92 lines
3.2 KiB
Python

import builtins
import sys
import types
from typing import Any
import pytest
from flight_club.constants import ENV_WHATSAPP_NUMBER
from flight_club.flight_data import FlightData
from flight_club.notification_manager import NotificationManager
NUMBER = "+441234567890"
def _flight() -> FlightData:
return FlightData(54, "LHR", "CDG", "2026-10-25", "2027-04-20")
def test_build_message_contains_price_airports_and_dates() -> None:
message = NotificationManager().build_message(_flight())
assert message == (
"Low price alert! Only GBP 54 to fly from LHR to CDG, from 2026-10-25 to 2027-04-20."
)
def test_send_whatsapp_returns_false_when_number_missing(
monkeypatch: pytest.MonkeyPatch, capsys: pytest.CaptureFixture[str]
) -> None:
monkeypatch.delenv(ENV_WHATSAPP_NUMBER, raising=False)
assert NotificationManager().send_whatsapp("hello") is False
output = capsys.readouterr().out
assert "hello" in output
assert ENV_WHATSAPP_NUMBER in output
def test_send_whatsapp_uses_injected_sender(monkeypatch: pytest.MonkeyPatch) -> None:
monkeypatch.setenv(ENV_WHATSAPP_NUMBER, NUMBER)
calls: list[tuple[str, str]] = []
manager = NotificationManager(sender=lambda number, message: calls.append((number, message)))
assert manager.send_whatsapp("hello") is True
assert calls == [(NUMBER, "hello")]
def test_send_whatsapp_returns_false_when_pywhatkit_missing(
monkeypatch: pytest.MonkeyPatch, capsys: pytest.CaptureFixture[str]
) -> None:
monkeypatch.setenv(ENV_WHATSAPP_NUMBER, NUMBER)
monkeypatch.delitem(sys.modules, "pywhatkit", raising=False)
real_import = builtins.__import__
def fake_import(name: str, *args: Any, **kwargs: Any) -> Any:
if name == "pywhatkit":
raise ImportError(name)
return real_import(name, *args, **kwargs)
monkeypatch.setattr(builtins, "__import__", fake_import)
assert NotificationManager().send_whatsapp("hello") is False
output = capsys.readouterr().out
assert "whatsapp" in output
assert "hello" in output
assert NUMBER not in output
def test_send_whatsapp_never_prints_number_when_pywhatkit_fails(
monkeypatch: pytest.MonkeyPatch, capsys: pytest.CaptureFixture[str]
) -> None:
monkeypatch.setenv(ENV_WHATSAPP_NUMBER, NUMBER)
fake = types.ModuleType("pywhatkit")
def fail(*args: Any) -> None:
raise RuntimeError(f"cannot reach {args[0]}")
fake.sendwhatmsg_instantly = fail # type: ignore[attr-defined]
monkeypatch.setitem(sys.modules, "pywhatkit", fake)
assert NotificationManager().send_whatsapp("hello") is False
output = capsys.readouterr().out
assert "RuntimeError" in output
assert "hello" in output
assert NUMBER not in output
def test_send_whatsapp_calls_pywhatkit_with_documented_arguments(
monkeypatch: pytest.MonkeyPatch,
) -> None:
monkeypatch.setenv(ENV_WHATSAPP_NUMBER, NUMBER)
received: list[tuple[Any, ...]] = []
fake = types.ModuleType("pywhatkit")
fake.sendwhatmsg_instantly = lambda *args: received.append(args) # type: ignore[attr-defined]
monkeypatch.setitem(sys.modules, "pywhatkit", fake)
assert NotificationManager().send_whatsapp("hello") is True
assert received == [(NUMBER, "hello", 15, True, 3)]