forked from retoor/devplacepy
feat: add optional ticket selection to planning report generation
Add a `numbers` form field to the planning report endpoint, allowing admins to generate a report for a specific subset of open tickets instead of always planning all open tickets. The selected numbers are parsed from a comma-separated string, deduplicated, and passed to the background job. The job's scope is recorded in the audit log and the Devii tool description is updated to document the new parameter.
This commit is contained in:
@@ -0,0 +1,85 @@
|
||||
# retoor <retoor@molodetz.nl>
|
||||
|
||||
import json
|
||||
|
||||
import pytest
|
||||
import requests
|
||||
|
||||
from devplacepy.database import get_table, refresh_snapshot, set_setting
|
||||
from tests.conftest import BASE_URL
|
||||
|
||||
|
||||
@pytest.fixture(scope="module", autouse=True)
|
||||
def _planning_settings(app_server):
|
||||
set_setting("rate_limit_per_minute", "1000000")
|
||||
set_setting("gitea_base_url", "https://gitea.test")
|
||||
set_setting("gitea_owner", "retoor")
|
||||
set_setting("gitea_repo", "pydevplace")
|
||||
set_setting("gitea_token", "planning-test-token")
|
||||
set_setting("issue_ai_enhance", "0")
|
||||
yield
|
||||
set_setting("gitea_base_url", "")
|
||||
set_setting("gitea_token", "")
|
||||
|
||||
|
||||
def _admin(seeded_db):
|
||||
refresh_snapshot()
|
||||
key = get_table("users").find_one(username="alice_test")["api_key"]
|
||||
session = requests.Session()
|
||||
session.headers.update({"X-API-KEY": key})
|
||||
return session
|
||||
|
||||
|
||||
def _member(seeded_db):
|
||||
refresh_snapshot()
|
||||
key = get_table("users").find_one(username="bob_test")["api_key"]
|
||||
session = requests.Session()
|
||||
session.headers.update({"X-API-KEY": key})
|
||||
return session
|
||||
|
||||
|
||||
def test_planning_requires_admin(seeded_db):
|
||||
member = _member(seeded_db)
|
||||
response = member.post(
|
||||
f"{BASE_URL}/issues/planning", data={"numbers": "1"}, allow_redirects=False
|
||||
)
|
||||
assert response.status_code in (302, 303)
|
||||
|
||||
|
||||
def test_planning_status_unknown_uid_is_404(seeded_db):
|
||||
admin = _admin(seeded_db)
|
||||
response = admin.get(f"{BASE_URL}/issues/planning/does-not-exist")
|
||||
assert response.status_code == 404
|
||||
|
||||
|
||||
def test_planning_enqueue_stores_selected_numbers(seeded_db):
|
||||
admin = _admin(seeded_db)
|
||||
response = admin.post(
|
||||
f"{BASE_URL}/issues/planning", data={"numbers": "4, 7,7, x"}
|
||||
)
|
||||
assert response.status_code == 200, response.text[:300]
|
||||
body = response.json()
|
||||
uid = body["uid"]
|
||||
assert body["status_url"] == f"/issues/planning/{uid}"
|
||||
|
||||
refresh_snapshot()
|
||||
job = get_table("jobs").find_one(uid=uid)
|
||||
assert job is not None
|
||||
assert json.loads(job["payload"])["numbers"] == [4, 7]
|
||||
|
||||
status = admin.get(f"{BASE_URL}/issues/planning/{uid}")
|
||||
assert status.status_code == 200
|
||||
payload = status.json()
|
||||
assert payload["uid"] == uid
|
||||
assert payload["kind"] == "planning"
|
||||
assert payload["status"] in ("pending", "running", "done", "failed")
|
||||
|
||||
|
||||
def test_planning_enqueue_without_numbers_is_all_open(seeded_db):
|
||||
admin = _admin(seeded_db)
|
||||
response = admin.post(f"{BASE_URL}/issues/planning", data={})
|
||||
assert response.status_code == 200, response.text[:300]
|
||||
uid = response.json()["uid"]
|
||||
refresh_snapshot()
|
||||
job = get_table("jobs").find_one(uid=uid)
|
||||
assert json.loads(job["payload"])["numbers"] == []
|
||||
Reference in New Issue
Block a user