feat: Implement recent chats feature with API endpoint and UI integration
This commit is contained in:
@@ -57,6 +57,7 @@ def client(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> TestClient:
|
||||
|
||||
importlib.reload(importlib.import_module("app.storage"))
|
||||
telegram_service_module = importlib.reload(importlib.import_module("app.telegram_service"))
|
||||
models_module = importlib.reload(importlib.import_module("app.models"))
|
||||
main_module = importlib.reload(importlib.import_module("app.main"))
|
||||
|
||||
# Stub out Telegram interactions
|
||||
@@ -74,6 +75,11 @@ def client(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> TestClient:
|
||||
async def fake_send_message(chat_id: str, message: str) -> None:
|
||||
call_log.append((chat_id, message))
|
||||
|
||||
recent_chats_state: List[models_module.RecentChat] = []
|
||||
|
||||
async def fake_fetch_recent_chats(limit: int = 50) -> List[models_module.RecentChat]:
|
||||
return recent_chats_state[:limit]
|
||||
|
||||
async def fake_disconnect() -> None:
|
||||
return None
|
||||
|
||||
@@ -86,10 +92,13 @@ def client(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> TestClient:
|
||||
monkeypatch.setattr(main_module.telegram_service, "send_message", fake_send_message)
|
||||
monkeypatch.setattr(main_module.telegram_service, "disconnect", fake_disconnect)
|
||||
monkeypatch.setattr(main_module.telegram_service, "verify_code", fake_verify_code)
|
||||
monkeypatch.setattr(main_module.telegram_service, "fetch_recent_chats", fake_fetch_recent_chats)
|
||||
monkeypatch.setattr(main_module.telegram_service, "is_connected", lambda: True)
|
||||
|
||||
test_client = TestClient(main_module.app)
|
||||
test_client.call_log = call_log # type: ignore[attr-defined]
|
||||
test_client.recent_chats_state = recent_chats_state # type: ignore[attr-defined]
|
||||
test_client.RecentChatModel = models_module.RecentChat # type: ignore[attr-defined]
|
||||
return test_client
|
||||
|
||||
|
||||
@@ -124,6 +133,26 @@ def test_create_list_and_trigger_hook(client: TestClient) -> None:
|
||||
assert last_triggered_value is not None
|
||||
first_triggered_at = datetime.fromisoformat(last_triggered_value)
|
||||
|
||||
client.recent_chats_state[:] = [
|
||||
client.RecentChatModel(
|
||||
chat_id=payload["chat_id"],
|
||||
display_name=f"Chat {payload['chat_id']}",
|
||||
chat_type="user",
|
||||
username="exampleuser",
|
||||
phone_number="123456",
|
||||
last_used_at=datetime.now(),
|
||||
)
|
||||
]
|
||||
|
||||
recent_resp = client.get("/api/recent-chats")
|
||||
assert recent_resp.status_code == 200
|
||||
recent_data = recent_resp.json()
|
||||
assert len(recent_data) == 1
|
||||
assert recent_data[0]["chat_id"] == payload["chat_id"]
|
||||
assert recent_data[0]["display_name"] == f"Chat {payload['chat_id']}"
|
||||
assert recent_data[0]["username"] == "exampleuser"
|
||||
assert recent_data[0]["phone_number"] == "123456"
|
||||
|
||||
new_id = "customid123"
|
||||
patch_resp = client.patch(f"/api/hooks/{data['hook_id']}", json={"hook_id": new_id})
|
||||
assert patch_resp.status_code == 200
|
||||
@@ -164,6 +193,25 @@ def test_create_list_and_trigger_hook(client: TestClient) -> None:
|
||||
second_triggered_at = datetime.fromisoformat(second_triggered_value)
|
||||
assert second_triggered_at >= first_triggered_at
|
||||
|
||||
client.recent_chats_state[:] = [
|
||||
client.RecentChatModel(
|
||||
chat_id=update_payload["chat_id"],
|
||||
display_name=f"Chat {update_payload['chat_id']}",
|
||||
chat_type="group",
|
||||
username="updateduser",
|
||||
phone_number=None,
|
||||
last_used_at=datetime.now(),
|
||||
)
|
||||
]
|
||||
|
||||
history_resp = client.get("/api/recent-chats")
|
||||
assert history_resp.status_code == 200
|
||||
history_data = history_resp.json()
|
||||
assert history_data[0]["chat_id"] == update_payload["chat_id"]
|
||||
assert history_data[0]["display_name"] == f"Chat {update_payload['chat_id']}"
|
||||
assert history_data[0]["username"] == "updateduser"
|
||||
assert history_data[0]["phone_number"] is None
|
||||
|
||||
|
||||
def test_login_verify_without_phone_number(client: TestClient) -> None:
|
||||
response = client.post("/api/login/verify", json={"code": "123456"})
|
||||
@@ -171,3 +219,15 @@ def test_login_verify_without_phone_number(client: TestClient) -> None:
|
||||
payload = response.json()
|
||||
assert payload["authorized"] is True
|
||||
assert payload["user"] == "Test User"
|
||||
|
||||
|
||||
def test_recent_chats_requires_authorization(client: TestClient, monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
from app import main as main_module
|
||||
|
||||
async def not_authorized() -> bool:
|
||||
return False
|
||||
|
||||
monkeypatch.setattr(main_module.telegram_service, "is_authorized", not_authorized)
|
||||
|
||||
response = client.get("/api/recent-chats")
|
||||
assert response.status_code == 401
|
||||
|
||||
Reference in New Issue
Block a user