- tests/test_auth.py: enable/disable via env, valid/invalid creds - tests/test_rate_limit.py: bucket math + window expiry - tests/test_router_media.py: path traversal (file/thumb), paginated subreddits/authors, blacklist preview shape, DELETE flow, cleanup-by-type 400 paths - tests/test_router_stats.py: cache TTL, .json exclusion, missing dir - tests/test_router_favorites.py: paginated favorites/authors, no N+1 (query count), favorites_only filter - tests/test_router_config.py: CRUD subreddits/users/blacklist - tests/test_config_manager.py: case-insensitive dedupe, blacklist removes from collection, domain normalization - tests/test_extractors_imgur.py: i.imgur direct, gifv->mp4, albums/galleries -> None src/database.py: resolve RMC_DB_PATH lazily in Database() so tests can monkeypatch the env per case (no more module-import capture) Result: 135 passed (was 77). Coverage 55% global; 100% on auth/imgur, 96% rate_limit, 84% stats router, 80% config_manager.
57 lines
2.1 KiB
Python
57 lines
2.1 KiB
Python
"""Tests for /api/subreddits, /api/users, /api/blacklist CRUD endpoints."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import pytest
|
|
from fastapi.testclient import TestClient
|
|
|
|
from src.web import config_manager
|
|
from src.web.app import app
|
|
|
|
|
|
@pytest.fixture
|
|
def client(tmp_path, monkeypatch):
|
|
monkeypatch.setattr(config_manager, "CONFIG_PATH", tmp_path / "config.yaml")
|
|
return TestClient(app)
|
|
|
|
|
|
class TestSubredditsCRUD:
|
|
def test_post_then_delete(self, client):
|
|
response = client.post("/api/subreddits", json={"name": "pics", "limit": 50, "sort": "hot"})
|
|
assert response.status_code in (200, 201)
|
|
response = client.get("/api/subreddits")
|
|
assert any(s["name"] == "pics" for s in response.json())
|
|
response = client.delete("/api/subreddits/pics")
|
|
assert response.status_code == 200
|
|
|
|
def test_duplicate_returns_409(self, client):
|
|
client.post("/api/subreddits", json={"name": "pics"})
|
|
response = client.post("/api/subreddits", json={"name": "pics"})
|
|
assert response.status_code == 409
|
|
|
|
def test_delete_missing_returns_404(self, client):
|
|
response = client.delete("/api/subreddits/ghost")
|
|
assert response.status_code == 404
|
|
|
|
|
|
class TestUsersCRUD:
|
|
def test_post_then_delete(self, client):
|
|
response = client.post("/api/users", json={"name": "alice"})
|
|
assert response.status_code in (200, 201)
|
|
response = client.delete("/api/users/alice")
|
|
assert response.status_code == 200
|
|
|
|
|
|
class TestBlacklistCRUD:
|
|
def test_authors_add_remove(self, client):
|
|
client.post("/api/blacklist/authors", json={"value": "spammer"})
|
|
response = client.get("/api/blacklist")
|
|
assert "spammer" in response.json().get("authors", [])
|
|
response = client.delete("/api/blacklist/authors/spammer")
|
|
assert response.status_code == 200
|
|
|
|
def test_keywords_add(self, client):
|
|
response = client.post("/api/blacklist/keywords", json={"value": "buy now"})
|
|
assert response.status_code in (200, 201)
|
|
response = client.get("/api/blacklist")
|
|
assert "buy now" in response.json().get("title_keywords", [])
|