from fastapi import FastAPI from fastapi.testclient import TestClient from api.endpoints import router class StubMessageStorage: def __init__(self, updated=True): self.updated = updated self.calls = [] def update_feedback_by_message_id(self, message_id, feedback, feedback_content=None): self.calls.append( { "message_id": message_id, "feedback": feedback, "feedback_content": feedback_content, } ) return self.updated def _build_client(monkeypatch, storage): app = FastAPI() app.include_router(router) monkeypatch.setattr("api.endpoints.get_message_storage", lambda: storage) return TestClient(app) def test_feedback_endpoint_writes_like(monkeypatch): storage = StubMessageStorage(updated=True) client = _build_client(monkeypatch, storage) response = client.post( "/api/messages/feedback", json={"message_id": "mid-1", "feedback": "like"}, ) assert response.status_code == 200 assert response.json() == {"ok": True, "message_id": "mid-1"} assert storage.calls[0] == { "message_id": "mid-1", "feedback": "like", "feedback_content": None, } def test_feedback_endpoint_requires_feedback_content_for_dislike(monkeypatch): storage = StubMessageStorage(updated=True) client = _build_client(monkeypatch, storage) response = client.post( "/api/messages/feedback", json={"message_id": "mid-2", "feedback": "dislike"}, ) assert response.status_code == 422 def test_feedback_endpoint_returns_400_when_message_not_found(monkeypatch): storage = StubMessageStorage(updated=False) client = _build_client(monkeypatch, storage) response = client.post( "/api/messages/feedback", json={ "message_id": "missing-mid", "feedback": "dislike", "feedback_content": "not useful", }, ) assert response.status_code == 400 body = response.json() assert body["detail"]["code"] == "INVALID_REQUEST" assert body["detail"]["detail"]["field"] == "message_id"