92 lines
3.2 KiB
Python
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)]
|