aboutsummaryrefslogtreecommitdiff
path: root/tests/test_contributions_api.py
diff options
context:
space:
mode:
Diffstat (limited to 'tests/test_contributions_api.py')
-rw-r--r--tests/test_contributions_api.py120
1 files changed, 120 insertions, 0 deletions
diff --git a/tests/test_contributions_api.py b/tests/test_contributions_api.py
new file mode 100644
index 0000000..d90aceb
--- /dev/null
+++ b/tests/test_contributions_api.py
@@ -0,0 +1,120 @@
+from datetime import UTC, datetime
+
+from fastapi.testclient import TestClient
+
+from srht_contrib.main import create_app
+from srht_contrib.models import ContributionEvent
+
+
+def test_api_routes_require_api_key(settings, db_engine, session_factory) -> None:
+ app = create_app(settings, engine=db_engine, session_factory=session_factory)
+ with TestClient(app) as open_client:
+ response = open_client.get("/health")
+ assert response.status_code == 200
+
+ with TestClient(app) as unauthorized:
+ unauthorized_response = unauthorized.get("/api/contributions/~ccleberg?from=2026-03-28&to=2026-03-30")
+ assert unauthorized_response.status_code == 401
+
+ with TestClient(app) as invalid:
+ invalid.headers.update({"X-API-Key": "wrong-key"})
+ invalid_response = invalid.get("/api/repositories")
+ assert invalid_response.status_code == 401
+
+
+def test_contributions_api_returns_zero_filled_range(client: TestClient, db_session) -> None:
+ db_session.add(
+ ContributionEvent(
+ service="todo",
+ event_type="ticket_created",
+ actor="~ccleberg",
+ repo_name=None,
+ resource_id="1",
+ external_uid="todo:ticket:1:created",
+ occurred_at=datetime(2026, 3, 30, 10, 0, tzinfo=UTC),
+ weight=1.0,
+ raw_payload_json=None,
+ )
+ )
+ db_session.commit()
+
+ response = client.get("/api/contributions/~ccleberg?from=2026-03-28&to=2026-03-30")
+
+ assert response.status_code == 200
+ assert response.json()["days"] == [
+ {"date": "2026-03-28", "count": 0, "score": 0.0},
+ {"date": "2026-03-29", "count": 0, "score": 0.0},
+ {"date": "2026-03-30", "count": 1, "score": 1.0},
+ ]
+
+
+def test_contribution_stats_api(client: TestClient, db_session) -> None:
+ db_session.add_all(
+ [
+ ContributionEvent(
+ service="todo",
+ event_type="ticket_created",
+ actor="~ccleberg",
+ repo_name=None,
+ resource_id="1",
+ external_uid="todo:ticket:1:created",
+ occurred_at=datetime(2026, 3, 29, 10, 0, tzinfo=UTC),
+ weight=1.0,
+ raw_payload_json=None,
+ ),
+ ContributionEvent(
+ service="todo",
+ event_type="ticket_comment",
+ actor="~ccleberg",
+ repo_name=None,
+ resource_id="1",
+ external_uid="todo:ticket:1:comment:2",
+ occurred_at=datetime(2026, 3, 30, 11, 0, tzinfo=UTC),
+ weight=0.5,
+ raw_payload_json=None,
+ ),
+ ]
+ )
+ db_session.commit()
+
+ response = client.get("/api/contributions/~ccleberg/stats?from=2026-03-28&to=2026-03-30")
+
+ assert response.status_code == 200
+ assert response.json()["total_events"] == 2
+ assert response.json()["total_score"] == 1.5
+ assert response.json()["longest_streak"] == 2
+ assert response.json()["current_streak"] == 2
+
+
+def test_invalid_date_input_returns_400(client: TestClient) -> None:
+ response = client.get("/api/contributions/~ccleberg?from=2026-13-01&to=2026-03-30")
+
+ assert response.status_code == 400
+ assert "Invalid date format" in response.json()["detail"]
+
+
+def test_contribution_routes_use_settings_backed_alias_resolution(settings, db_engine, session_factory) -> None:
+ alias_settings = settings.model_copy(update={"actor_aliases_json": {"~ccleberg": ["[email protected]"]}})
+ app = create_app(alias_settings, engine=db_engine, session_factory=session_factory)
+ with session_factory() as session:
+ session.add(
+ ContributionEvent(
+ service="todo",
+ event_type="ticket_created",
+ actor="~ccleberg",
+ repo_name=None,
+ resource_id="1",
+ external_uid="todo:alias:1",
+ occurred_at=datetime(2026, 3, 30, 10, 0, tzinfo=UTC),
+ weight=1.0,
+ raw_payload_json=None,
+ )
+ )
+ session.commit()
+
+ with TestClient(app) as client:
+ client.headers.update({"X-API-Key": alias_settings.api_key})
+ response = client.get("/api/contributions/[email protected]?from=2026-03-30&to=2026-03-30")
+
+ assert response.status_code == 200
+ assert response.json()["actor"] == "~ccleberg"