Files
factoryOps-v2/tests/test_e2e_integration.py

354 lines
11 KiB
Python
Raw Normal View History

import pytest
from httpx import AsyncClient
from tests.conftest import get_auth_headers
async def _login(
client: AsyncClient, email: str = "super@test.com", pw: str = "pass1234"
):
return await get_auth_headers(client, email, pw)
@pytest.mark.asyncio
async def test_full_lifecycle_flow(client: AsyncClient, seeded_db):
h = await _login(client)
tid = "test-co"
r = await client.post(
f"/api/{tid}/machines",
json={
"name": "E2E 통합 설비",
"equipment_code": "E2E-001",
"model": "Test Model X",
},
headers=h,
)
assert r.status_code == 200
machine = r.json()
machine_id = machine["id"]
assert machine["name"] == "E2E 통합 설비"
r = await client.post(
f"/api/{tid}/machines/{machine_id}/parts",
json={
"name": "E2E 부품",
"part_number": "E2E-P-001",
"category": "소모품",
"lifecycle_type": "count",
"lifecycle_limit": 1000,
"alarm_threshold": 80,
"counter_source": "manual",
},
headers=h,
)
assert r.status_code == 200
part = r.json()
part_id = part["id"]
assert part["counter"]["current_value"] == 0
r = await client.put(
f"/api/{tid}/parts/{part_id}/counter", json={"value": 500}, headers=h
)
assert r.status_code == 200
assert r.json()["counter"]["current_value"] == 500
assert r.json()["counter"]["lifecycle_pct"] == 50.0
r = await client.get(f"/api/{tid}/alarms?is_acknowledged=false", headers=h)
assert r.status_code == 200
assert len(r.json()["alarms"]) == 0
r = await client.put(
f"/api/{tid}/parts/{part_id}/counter", json={"value": 850}, headers=h
)
assert r.status_code == 200
assert r.json()["counter"]["lifecycle_pct"] == 85.0
r = await client.get(f"/api/{tid}/alarms?is_acknowledged=false", headers=h)
assert r.status_code == 200
alarms = r.json()["alarms"]
assert len(alarms) == 1
warning_alarm = alarms[0]
assert warning_alarm["severity"] == "warning"
assert warning_alarm["alarm_type"] == "threshold"
warning_alarm_id = warning_alarm["id"]
r = await client.put(
f"/api/{tid}/parts/{part_id}/counter", json={"value": 1050}, headers=h
)
assert r.status_code == 200
assert r.json()["counter"]["lifecycle_pct"] == 105.0
r = await client.get(f"/api/{tid}/alarms?is_acknowledged=false", headers=h)
assert r.status_code == 200
active = r.json()["alarms"]
assert len(active) == 2
severities = {a["severity"] for a in active}
assert severities == {"warning", "critical"}
r = await client.post(
f"/api/{tid}/alarms/{warning_alarm_id}/acknowledge", headers=h
)
assert r.status_code == 200
assert r.json()["is_acknowledged"] is True
r = await client.get(f"/api/{tid}/alarms/summary", headers=h)
assert r.status_code == 200
summary = r.json()
assert summary["active_count"] == 1
assert summary["critical_count"] == 1
assert summary["warning_count"] == 0
r = await client.post(
f"/api/{tid}/parts/{part_id}/replace",
json={
"reason": "수명 초과",
"notes": "E2E 테스트 교체",
},
headers=h,
)
assert r.status_code == 200
replaced = r.json()
assert replaced["status"] == "success"
assert replaced["part"]["counter"]["current_value"] == 0
assert replaced["part"]["counter"]["lifecycle_pct"] == 0.0
r = await client.get(f"/api/{tid}/parts/{part_id}/replacements", headers=h)
assert r.status_code == 200
logs = r.json()["replacements"]
assert len(logs) == 1
assert logs[0]["counter_at_replacement"] == 1050
assert logs[0]["reason"] == "수명 초과"
r = await client.post(
f"/api/{tid}/templates",
json={
"name": "E2E 설비 점검",
"subject_type": "equipment",
"machine_id": machine_id,
"schedule_type": "daily",
"inspection_mode": "measurement",
"items": [
{
"name": "온도",
"data_type": "numeric",
"unit": "°C",
"spec_min": 10,
"spec_max": 50,
"is_required": True,
},
{"name": "가동 상태", "data_type": "boolean", "is_required": True},
{
"name": "상태",
"data_type": "select",
"select_options": ["정상", "주의", "이상"],
"is_required": True,
},
],
},
headers=h,
)
assert r.status_code == 200
template = r.json()
template_id = template["id"]
assert len(template["items"]) == 3
r = await client.post(
f"/api/{tid}/inspections",
json={
"template_id": template_id,
},
headers=h,
)
assert r.status_code == 200
session = r.json()
session_id = session["id"]
assert session["status"] == "in_progress"
assert len(session["records"]) == 3
detail_r = await client.get(f"/api/{tid}/inspections/{session_id}", headers=h)
assert detail_r.status_code == 200
items_detail = detail_r.json()["items_detail"]
record_data = []
for item_d in items_detail:
item = item_d["item"]
record = item_d["record"]
if item["name"] == "온도":
record_data.append(
{"template_item_id": record["template_item_id"], "value_numeric": 25.5}
)
elif item["name"] == "가동 상태":
record_data.append(
{"template_item_id": record["template_item_id"], "value_boolean": True}
)
elif item["name"] == "상태":
record_data.append(
{"template_item_id": record["template_item_id"], "value_select": "정상"}
)
r = await client.put(
f"/api/{tid}/inspections/{session_id}/records",
json={
"records": record_data,
},
headers=h,
)
assert r.status_code == 200
r = await client.post(f"/api/{tid}/inspections/{session_id}/complete", headers=h)
assert r.status_code == 200
completed = r.json()
assert completed["status"] == "success"
assert completed["summary"]["pass_count"] >= 2
r = await client.get(f"/api/{tid}/machines/{machine_id}", headers=h)
assert r.status_code == 200
assert r.json()["parts_count"] == 1
r = await client.get(f"/api/{tid}/inspections", headers=h)
assert r.status_code == 200
all_sessions = r.json()["inspections"]
completed_sessions = [s for s in all_sessions if s["status"] == "completed"]
assert len(completed_sessions) >= 1
@pytest.mark.asyncio
async def test_tenant_isolation_e2e(client: AsyncClient, seeded_db):
h_super = await _login(client)
h_tenant = await _login(client, "admin@test-co.com", "pass1234")
tid = "test-co"
other = "other-co"
r = await client.post(
f"/api/{tid}/machines",
json={
"name": "격리 테스트 설비",
"equipment_code": "ISO-001",
},
headers=h_super,
)
assert r.status_code == 200
machine_id = r.json()["id"]
r = await client.post(
f"/api/{tid}/machines/{machine_id}/parts",
json={
"name": "격리 부품",
"lifecycle_type": "hours",
"lifecycle_limit": 5000,
},
headers=h_super,
)
assert r.status_code == 200
r = await client.post(
f"/api/{tid}/templates",
json={
"name": "격리 템플릿",
"subject_type": "equipment",
"schedule_type": "daily",
"inspection_mode": "checklist",
"items": [{"name": "체크", "data_type": "boolean", "is_required": True}],
},
headers=h_super,
)
assert r.status_code == 200
r = await client.get(f"/api/{other}/machines", headers=h_super)
assert r.status_code == 200
assert len(r.json()["machines"]) == 0
r = await client.get(f"/api/{other}/templates", headers=h_super)
assert r.status_code == 200
assert len(r.json()["templates"]) == 0
r = await client.get(f"/api/{other}/alarms", headers=h_super)
assert r.status_code == 200
assert len(r.json()["alarms"]) == 0
r = await client.get(f"/api/{other}/inspections", headers=h_super)
assert r.status_code == 200
assert len(r.json()["inspections"]) == 0
@pytest.mark.asyncio
async def test_inspection_with_spec_validation(client: AsyncClient, seeded_db):
h = await _login(client)
tid = "test-co"
r = await client.post(
f"/api/{tid}/machines",
json={
"name": "규격 검증 설비",
"equipment_code": "SPEC-001",
},
headers=h,
)
machine_id = r.json()["id"]
r = await client.post(
f"/api/{tid}/templates",
json={
"name": "규격 검증 점검",
"subject_type": "equipment",
"machine_id": machine_id,
"schedule_type": "ad_hoc",
"inspection_mode": "measurement",
"items": [
{
"name": "치수 A",
"data_type": "numeric",
"unit": "mm",
"spec_min": 10.0,
"spec_max": 20.0,
"is_required": True,
},
{
"name": "치수 B",
"data_type": "numeric",
"unit": "mm",
"spec_min": 5.0,
"spec_max": 8.0,
"is_required": True,
},
],
},
headers=h,
)
template_id = r.json()["id"]
r = await client.post(
f"/api/{tid}/inspections", json={"template_id": template_id}, headers=h
)
session = r.json()
session_id = session["id"]
detail_r = await client.get(f"/api/{tid}/inspections/{session_id}", headers=h)
items_detail = detail_r.json()["items_detail"]
record_data = []
for item_d in items_detail:
item = item_d["item"]
record = item_d["record"]
if item["name"] == "치수 A":
record_data.append(
{"template_item_id": record["template_item_id"], "value_numeric": 15.0}
)
elif item["name"] == "치수 B":
record_data.append(
{"template_item_id": record["template_item_id"], "value_numeric": 9.5}
)
await client.put(
f"/api/{tid}/inspections/{session_id}/records",
json={"records": record_data},
headers=h,
)
r = await client.post(f"/api/{tid}/inspections/{session_id}/complete", headers=h)
assert r.status_code == 200
completed = r.json()
assert completed["status"] == "success"
assert completed["summary"]["pass_count"] == 1
assert completed["summary"]["fail_count"] == 1