# retoor from datetime import timedelta from devplacepy.database import invalidate_admins_cache from devplacepy.services.devii.tasks.guards import ( REASON_BUDGET, REASON_EXPIRED, REASON_FAILURES, REASON_MAX_RUNS, REASON_NOT_ADMIN, automation_allowed, refusal, ) from devplacepy.services.devii.tasks.schedule import now_utc, to_iso from devplacepy.utils import generate_uid def _account(local_db, role): uid = generate_uid() local_db["users"].insert( { "uid": uid, "username": f"guard-{uid[-10:]}", "role": role, "deleted_at": None, } ) invalidate_admins_cache() return uid def _row(owner_uid, **overrides): row = { "uid": generate_uid(), "owner_kind": "user", "owner_id": owner_uid, "run_count": 0, "created_at": to_iso(now_utc()), } row.update(overrides) return row def test_only_administrators_may_automate(local_db): admin = _account(local_db, "Admin") member = _account(local_db, "Member") assert automation_allowed("user", admin) is True assert automation_allowed("user", member) is False assert automation_allowed("guest", "guest-cookie") is False assert automation_allowed("user", "") is False def test_member_owned_task_is_refused(local_db): member = _account(local_db, "Member") assert refusal(_row(member), now_utc()) == REASON_NOT_ADMIN def test_clean_admin_task_is_allowed(local_db): admin = _account(local_db, "Admin") assert refusal(_row(admin), now_utc()) is None def test_exhausted_task_is_refused(local_db): admin = _account(local_db, "Admin") row = _row(admin, max_runs=5, run_count=5) assert refusal(row, now_utc()) == REASON_MAX_RUNS def test_expired_task_is_refused(local_db): admin = _account(local_db, "Admin") now = now_utc() row = _row(admin, expires_at=to_iso(now - timedelta(minutes=1))) assert refusal(row, now) == REASON_EXPIRED def test_task_without_an_expiry_stops_at_the_fallback_ceiling(local_db): admin = _account(local_db, "Admin") now = now_utc() row = _row(admin, created_at=to_iso(now - timedelta(days=40))) assert refusal(row, now) == REASON_EXPIRED def test_repeated_failures_refuse_the_task(local_db): admin = _account(local_db, "Admin") row = _row(admin, failure_count=3) assert refusal(row, now_utc(), max_failures=3) == REASON_FAILURES assert refusal(row, now_utc(), max_failures=0) is None def test_budget_probe_refuses_the_task(local_db): admin = _account(local_db, "Admin") row = _row(admin) assert refusal(row, now_utc(), budget_exceeded=lambda k, i: True) == REASON_BUDGET assert refusal(row, now_utc(), budget_exceeded=lambda k, i: False) is None