"""验证: 库存看板 BOM 齐套标签页 + BOM 详情页在库/状态列。 不依赖已存在的 app.db, 自建临时库 + 种子数据做断言。 """ import os, sys, tempfile, importlib.util HERE = os.path.dirname(os.path.abspath(__file__)) ROOT = os.path.dirname(HERE) sys.path.insert(0, ROOT) # 用临时库, 不污染正式数据 tmp = tempfile.mktemp(suffix=".db") os.environ["WMS_DB"] = tmp import app as appmod from models import db, Material, Bom, BomItem, Inbound from datetime import date appmod.seed_admin() with appmod.app.app_context(): m = Material(part_number="P0001", manufacturer="测试IC-A", unit="颗", safety_stock=100) db.session.add(m); db.session.flush() b = Bom(code="T03", name="测试产品T03"); db.session.add(b); db.session.flush() db.session.add(BomItem(bom_id=b.id, material_id=m.id, qty_per_unit=2)) # 入库 30, 安全库存 100 -> 在库 30 < 100 -> 偏低(warn) db.session.add(Inbound(material_id=m.id, qty=30, source="测试", occur_date=date.today())) db.session.commit() BID = b.id # 在上下文内取出 id, 避免外部访问 detached 实例 client = appmod.app.test_client() # 登录 admin r = client.post("/login", data={"username": "admin", "password": "admin123"}, follow_redirects=True) assert r.status_code == 200, f"login failed: {r.status_code}" # 1) 看板页应包含 BOM 齐套标签(用 id="tab-bom" 区块判断, 而非注释文本) r = client.get("/dashboard") html = r.get_data(as_text=True) assert "库存预警" in html, "看板缺少库存预警标签" assert 'id="tab-bom"' in html, "看板缺少 BOM 齐套标签页" print("[OK] 管理员看板页含 BOM 齐套标签页") # 2) BOM 详情页应包含 当前在库 / 状态 列, 且 P0001 偏低 r = client.get(f"/bom/{BID}") html = r.get_data(as_text=True) assert "当前在库" in html, "BOM 详情缺少 当前在库 列" assert "状态" in html, "BOM 详情缺少 状态 列" assert "P0001" in html, "BOM 详情未展示组成物料编号" assert "偏低" in html, "P0001 在库30<安全100 应显示偏低, 实际未标黄" assert "30.00" in html, "BOM 详情未显示正确在库数量" print("[OK] BOM 详情页展示 当前在库/状态, P0001 正确标为偏低") # 3) operator 角色不应看到 BOM 标签 (权限隔离) from models import User import hashlib def sha256(s): return hashlib.sha256(s.encode()).hexdigest() with appmod.app.app_context(): if not db.session.scalar(db.select(User).where(User.username == "op1")): db.session.add(User(username="op1", password=sha256("op123"), role="operator", display_name="操作工")) db.session.commit() r = client.post("/logout") r = client.post("/login", data={"username": "op1", "password": "op123"}, follow_redirects=True) r = client.get("/dashboard") html = r.get_data(as_text=True) assert 'id="tab-bom"' not in html, "operator 不应看到 BOM 齐套标签" print("[OK] operator 角色看不到 BOM 齐套标签(权限隔离正确)") os.remove(tmp) print("\nALL PASS ✅")