# retoor from tests.conftest import run_async import pytest from devplacepy.database import get_setting, get_table, init_db, set_setting from devplacepy.services.community.runner import CommunityRunner from devplacepy.services.community.service import DRY_RUN_KEY, CommunityService from devplacepy.services.community.spec import STATUS_FAILING, STATUS_READY from devplacepy.services.community.store import store from tests.unit.services.community.fakes import FakeFetcher, json_community, no_sleep @pytest.fixture def world(): init_db() previous = {key: get_setting(key, "") for key in ("sync_enabled", "sync_origins", DRY_RUN_KEY)} set_setting("sync_enabled", "1") set_setting("sync_origins", "") get_table("communities").delete() get_table("community_runs").delete() get_table("sync_links").delete(origin="forum.test") routes = json_community() runner = CommunityRunner(fetcher_factory=lambda: FakeFetcher(routes), sleep=no_sleep) yield routes, runner for key, value in previous.items(): set_setting(key, value) def seed(runner) -> dict: store.create("forum-test", "https://forum.test/api/posts", "tester", name="forum") run_async(runner.discover("https://forum.test/api/posts", "tester", relearn_slug="forum-test")) return store.get("forum-test") def test_dry_run_service_tick_learns_nothing_and_runs_nothing(world): _, runner = world store.create("forum-test", "https://forum.test/api/posts", "tester", name="forum") set_setting(DRY_RUN_KEY, "1") service = CommunityService(runner) run_async(service.run_once()) assert store.get("forum-test")["status"] == "pending" assert any("DRY RUN" in line for line in service.log_buffer) def test_live_tick_learns_pending_then_runs_due(world): _, runner = world store.create("forum-test", "https://forum.test/api/posts", "tester", name="forum") set_setting(DRY_RUN_KEY, "0") service = CommunityService(runner) run_async(service.run_once()) assert store.get("forum-test")["status"] == STATUS_READY run_async(service.run_once()) row = store.get("forum-test") assert row["run_count"] == 1 assert get_table("sync_links").count(origin="forum.test", kind="posts") == 10 run_async(service.run_once()) assert store.get("forum-test")["run_count"] == 1 def test_repeated_failures_disable_and_flag_the_community(world): routes, runner = world row = seed(runner) routes["https://forum.test/api/posts"] = (500, "down") failing = CommunityRunner(fetcher_factory=lambda: FakeFetcher(routes), sleep=no_sleep) for _ in range(6): current = store.get("forum-test") report = run_async(failing.run(current, dry_run=False, trigger="test")) assert report.status == "failed" final = store.get("forum-test") assert final["status"] == STATUS_FAILING and not final["enabled"] assert "relearn" in "".join(store.runs(row["uid"])[0]["log"]).lower() or final["failure_count"] >= 5 def test_run_history_is_bounded(world): _, runner = world row = seed(runner) for _ in range(35): run_async(runner.run(store.get("forum-test"), dry_run=True, trigger="test")) assert len(store.runs(row["uid"], limit=100)) == 30