76 lines
5.5 KiB
Python
76 lines
5.5 KiB
Python
"""Отчёт по сотрудникам, трудоёмкость задач, возвраты нарядов, фильтры вкладки «Задачи»."""
|
|
import os
|
|
import tempfile
|
|
from datetime import timedelta
|
|
|
|
os.environ.setdefault("DATABASE_URL", os.environ.get("TEST_DATABASE_URL") or "sqlite:///" + os.path.join(tempfile.mkdtemp(), "pp.db").replace("\\", "/"))
|
|
os.environ.setdefault("SCHEDULER_INTERVAL", "3600")
|
|
os.environ.setdefault("SECRET_KEY", "test-secret-key-for-pytest-0123456789abcdef")
|
|
os.environ.setdefault("DATA_DIR", tempfile.mkdtemp())
|
|
|
|
from fastapi.testclient import TestClient # noqa: E402
|
|
|
|
from app import config # noqa: E402
|
|
from app.main import app # noqa: E402
|
|
|
|
V1 = "/api/v1"
|
|
PW = "Pass1234567"
|
|
|
|
|
|
def test_people_report_and_work_filters():
|
|
with TestClient(app) as c:
|
|
login = lambda u, p=PW: {"Authorization": "Bearer " + c.post(f"{V1}/auth/login", json={"username": u, "password": p}).json()["access_token"]}
|
|
adm = login("admin", "admin")
|
|
eng_pos = c.post(f"{V1}/positions", headers=adm, json={"name": "PP-Инженер", "kind": "engineer"}).json()
|
|
dep = c.post(f"{V1}/departments", headers=adm, json={"name": "PP-Служба"}).json()
|
|
a = c.post(f"{V1}/users", headers=adm, json={"username": "pp_a", "full_name": "Альфа Работник", "password": PW, "department_id": dep["id"]}).json()
|
|
c.post(f"{V1}/users", headers=adm, json={"username": "pp_e", "full_name": "Инж Проверяющий", "password": PW, "position_id": eng_pos["id"]})
|
|
ta, te = login("pp_a"), login("pp_e")
|
|
|
|
# задача с нормой трудоёмкости и задача без нормы (фактическое время)
|
|
t1 = c.post(f"{V1}/tasks", headers=te, json={"title": "Норма 2.5 ч", "assignee_id": a["id"], "labor_hours": 2.5}).json()
|
|
assert t1["labor_hours"] == 2.5
|
|
for s, cm in (("in_progress", ""), ("done", "ok")):
|
|
c.post(f"{V1}/tasks/{t1['id']}/status", headers=ta, json={"status": s, "comment": cm})
|
|
t2 = c.post(f"{V1}/tasks", headers=te, json={"title": "Отменённая", "assignee_id": a["id"]}).json()
|
|
c.post(f"{V1}/tasks/{t2['id']}/status", headers=ta, json={"status": "paused", "comment": "жду"})
|
|
c.post(f"{V1}/tasks/{t2['id']}/status", headers=ta, json={"status": "cancelled", "comment": "не нужно"})
|
|
# фильтры вкладки «Задачи»: поставленные мной
|
|
mine_set = c.get(f"{V1}/tasks", headers=te, params={"created_by_me": True}).json()
|
|
assert {x["title"] for x in mine_set} >= {"Норма 2.5 ч", "Отменённая"}
|
|
|
|
# наряд: возврат с проверки и отклонение от нормы
|
|
cl = c.post(f"{V1}/checklists", headers=adm, json={"name": "PP-чек", "items": [{"text": "Давление", "answer_type": "number", "min_value": 1, "max_value": 2}]}).json()
|
|
o = c.post(f"{V1}/orders", headers=te, json={"title": "PP-наряд", "checklist_id": cl["id"], "assignee_user_id": a["id"],
|
|
"reviewer_user_id": c.get(f"{V1}/me", headers=te).json()["id"]}).json()
|
|
item = c.get(f"{V1}/orders/{o['id']}", headers=ta).json()["items"][0]
|
|
c.put(f"{V1}/orders/{o['id']}/items/{item['id']}", headers=ta, json={"value": "5"})
|
|
st = c.post(f"{V1}/orders/{o['id']}/submit", headers=ta).json()["status"]
|
|
if st == "review":
|
|
assert c.post(f"{V1}/orders/{o['id']}/review", headers=te, json={"approve": False, "comment": "Переделать"}).status_code == 200
|
|
c.post(f"{V1}/orders/{o['id']}/submit", headers=ta)
|
|
c.post(f"{V1}/orders/{o['id']}/review", headers=te, json={"approve": True})
|
|
|
|
now = config.now()
|
|
q = {"from": (now - timedelta(days=1)).isoformat(), "to": (now + timedelta(days=1)).isoformat()}
|
|
assert c.get(f"{V1}/reports/people", headers=ta, params=q).status_code == 403
|
|
rep = c.get(f"{V1}/reports/people", headers=te, params={**q, "department_id": dep["id"]}).json()
|
|
assert [r["name"] for r in rep["rows"]] == ["Альфа Работник"]
|
|
r = rep["rows"][0]
|
|
assert r["tasks_done"] == 1 and r["tasks_cancelled"] == 1 and r["tasks_paused"] == 1 and r["orders_done"] == 1
|
|
assert r["deviations"] == 1 and r["hours"] >= 2.5 and r["on_time_pct"] is not None
|
|
day = now.date().isoformat()
|
|
assert r["calendar"][day]["n"] == 2 and r["calendar"][day]["h"] >= 2.5
|
|
assert len(rep["days"]) >= 2
|
|
pdf = c.get(f"{V1}/reports/people", headers=te, params={**q, "format": "pdf"})
|
|
assert pdf.status_code == 200 and pdf.content[:5] == b"%PDF-"
|
|
csv = c.get(f"{V1}/reports/people", headers=te, params={**q, "format": "csv_calendar"}).content.decode("utf-8-sig")
|
|
assert "Альфа Работник" in csv and "Итого ч" in csv
|
|
|
|
# фильтры инцидентов для вкладки «Задачи»
|
|
eq = c.post(f"{V1}/equipment", headers=adm, json={"name": "PP-Станок"}).json()
|
|
c.post(f"{V1}/incidents", headers=ta, json={"equipment_id": eq["id"], "title": "PP-авария"})
|
|
assert [i["title"] for i in c.get(f"{V1}/incidents", headers=ta, params={"mine": True}).json()] == ["PP-авария"]
|
|
assert c.get(f"{V1}/incidents", headers=ta, params={"q": "pp-стан"}).json()[0]["title"] == "PP-авария"
|
|
assert all(i["source"] == "staff" for i in c.get(f"{V1}/incidents", headers=ta, params={"source": "staff"}).json())
|