snipe/tests/test_feedback.py

134 lines
4.9 KiB
Python

"""Tests for the shared feedback router (circuitforge-core) mounted in snipe."""
from __future__ import annotations
from collections.abc import Callable
from unittest.mock import MagicMock, patch
from fastapi import FastAPI
from fastapi.testclient import TestClient
from circuitforge_core.api.feedback import make_feedback_router
# ── Test app factory ──────────────────────────────────────────────────────────
def _make_client(demo_mode_fn: Callable[[], bool] | None = None) -> TestClient:
app = FastAPI()
router = make_feedback_router(
repo="Circuit-Forge/snipe",
product="snipe",
demo_mode_fn=demo_mode_fn,
)
app.include_router(router, prefix="/api/feedback")
return TestClient(app)
# ── GET /api/feedback/status ──────────────────────────────────────────────────
def test_status_disabled_when_no_token(monkeypatch):
monkeypatch.delenv("FORGEJO_API_TOKEN", raising=False)
monkeypatch.delenv("DEMO_MODE", raising=False)
client = _make_client(demo_mode_fn=lambda: False)
res = client.get("/api/feedback/status")
assert res.status_code == 200
assert res.json() == {"enabled": False}
def test_status_enabled_when_token_set(monkeypatch):
monkeypatch.setenv("FORGEJO_API_TOKEN", "test-token")
client = _make_client(demo_mode_fn=lambda: False)
res = client.get("/api/feedback/status")
assert res.status_code == 200
assert res.json() == {"enabled": True}
def test_status_disabled_in_demo_mode(monkeypatch):
monkeypatch.setenv("FORGEJO_API_TOKEN", "test-token")
demo = True
client = _make_client(demo_mode_fn=lambda: demo)
res = client.get("/api/feedback/status")
assert res.status_code == 200
assert res.json() == {"enabled": False}
# ── POST /api/feedback ────────────────────────────────────────────────────────
def test_submit_returns_503_when_no_token(monkeypatch):
monkeypatch.delenv("FORGEJO_API_TOKEN", raising=False)
client = _make_client(demo_mode_fn=lambda: False)
res = client.post("/api/feedback", json={
"title": "Test", "description": "desc", "type": "bug",
})
assert res.status_code == 503
def test_submit_returns_403_in_demo_mode(monkeypatch):
monkeypatch.setenv("FORGEJO_API_TOKEN", "test-token")
demo = True
client = _make_client(demo_mode_fn=lambda: demo)
res = client.post("/api/feedback", json={
"title": "Test", "description": "desc", "type": "bug",
})
assert res.status_code == 403
def test_submit_creates_issue(monkeypatch):
monkeypatch.setenv("FORGEJO_API_TOKEN", "test-token")
label_response = MagicMock()
label_response.ok = True
label_response.json.return_value = [
{"id": 1, "name": "beta-feedback"},
{"id": 2, "name": "needs-triage"},
{"id": 3, "name": "bug"},
]
issue_response = MagicMock()
issue_response.ok = True
issue_response.json.return_value = {
"number": 7,
"html_url": "https://git.opensourcesolarpunk.com/Circuit-Forge/snipe/issues/7",
}
client = _make_client(demo_mode_fn=lambda: False)
with patch("circuitforge_core.api.feedback.requests.get", return_value=label_response), \
patch("circuitforge_core.api.feedback.requests.post", return_value=issue_response):
res = client.post("/api/feedback", json={
"title": "Listing scores wrong",
"description": "Trust score shows 0 when seller has 1000 feedback",
"type": "bug",
"repro": "1. Search for anything\n2. Check trust score",
"tab": "search",
})
assert res.status_code == 200
data = res.json()
assert data["issue_number"] == 7
assert data["issue_url"] == "https://git.opensourcesolarpunk.com/Circuit-Forge/snipe/issues/7"
def test_submit_returns_502_on_forgejo_error(monkeypatch):
monkeypatch.setenv("FORGEJO_API_TOKEN", "test-token")
label_response = MagicMock()
label_response.ok = True
label_response.json.return_value = [
{"id": 1, "name": "beta-feedback"},
{"id": 2, "name": "needs-triage"},
{"id": 3, "name": "question"},
]
bad_response = MagicMock()
bad_response.ok = False
bad_response.text = "internal server error"
client = _make_client(demo_mode_fn=lambda: False)
with patch("circuitforge_core.api.feedback.requests.get", return_value=label_response), \
patch("circuitforge_core.api.feedback.requests.post", return_value=bad_response):
res = client.post("/api/feedback", json={
"title": "Oops", "description": "desc", "type": "other",
})
assert res.status_code == 502