feat: 新增接口22生发控制与测试页
This commit is contained in:
+20
-29
@@ -8,11 +8,7 @@ from conftest import fixture
|
||||
|
||||
import app as app_module
|
||||
|
||||
# 测试自带固定密码,避免依赖 worker_config.json 的实际值(中间件运行期读模块全局)
|
||||
app_module.ACCEPT_PASSWORDS = ["testpass"]
|
||||
|
||||
URL = "/api/v1/face/measure"
|
||||
H = {"X-Internal-Token": "testpass"}
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
@@ -22,18 +18,13 @@ def client():
|
||||
yield c
|
||||
|
||||
|
||||
def _post(client, fixture_name=None, headers=H, data=None, extra_files=None):
|
||||
def _post(client, fixture_name=None, data=None, extra_files=None):
|
||||
files = {}
|
||||
if fixture_name:
|
||||
files["image_file"] = (fixture_name, open(fixture(fixture_name), "rb"), "application/octet-stream")
|
||||
if extra_files:
|
||||
files.update(extra_files)
|
||||
return client.post(URL, headers=headers, files=files or None, data=data)
|
||||
|
||||
|
||||
def test_auth_missing_token_401(client):
|
||||
r = _post(client, "frontal.jpg", headers={})
|
||||
assert r.status_code == 401
|
||||
return client.post(URL, files=files or None, data=data)
|
||||
|
||||
|
||||
def _patch_health_ok(monkeypatch):
|
||||
@@ -107,7 +98,7 @@ def test_tcp_probe_real_socket():
|
||||
|
||||
|
||||
def test_param_none_provided_1007(client):
|
||||
r = client.post(URL, headers=H)
|
||||
r = client.post(URL)
|
||||
assert r.json()["code"] == 1007
|
||||
|
||||
|
||||
@@ -131,7 +122,7 @@ GROW = "/api/v1/hair/grow"
|
||||
|
||||
def test_grow_missing_gender_1004(client):
|
||||
files = {"image_file": ("frontal.jpg", open(fixture("frontal.jpg"), "rb"), "application/octet-stream")}
|
||||
r = client.post(GROW, headers=H, files=files)
|
||||
r = client.post(GROW, files=files)
|
||||
assert r.json()["code"] == 1004
|
||||
|
||||
|
||||
@@ -148,7 +139,7 @@ def test_grow_female_returns_5(client, monkeypatch):
|
||||
|
||||
files = {"image_file": ("frontal.jpg", open(fixture("frontal.jpg"), "rb"), "application/octet-stream")}
|
||||
# hair_style 必填(cb1989c 起):指定全部 5 种发型以验证完整管线
|
||||
r = client.post(GROW, headers=H, files=files, data={"gender": "female", "hair_style": "1,2,3,4,5"})
|
||||
r = client.post(GROW, files=files, data={"gender": "female", "hair_style": "1,2,3,4,5"})
|
||||
body = r.json()
|
||||
assert body["code"] == 0, body
|
||||
results = body["data"]["results"]
|
||||
@@ -163,13 +154,13 @@ GROWB = "/api/v1/hair/grow-b"
|
||||
|
||||
|
||||
def test_growb_missing_marked_1007(client):
|
||||
r = client.post(GROWB, headers=H) # 一张图都没传
|
||||
r = client.post(GROWB) # 一张图都没传
|
||||
assert r.json()["code"] == 1007
|
||||
|
||||
|
||||
def test_growb_no_line_1001(client):
|
||||
files = {"marked_image_file": ("m.jpg", open(fixture("frontal.jpg"), "rb"), "application/octet-stream")}
|
||||
r = client.post(GROWB, headers=H, files=files) # 无划线 → 拒识
|
||||
r = client.post(GROWB, files=files) # 无划线 → 拒识
|
||||
assert r.json()["code"] == 1001
|
||||
|
||||
|
||||
@@ -177,7 +168,7 @@ def test_growb_success(client, monkeypatch):
|
||||
import hairline.comfyui as comfy
|
||||
monkeypatch.setattr(comfy, "run", lambda *a, **k: _PNG_1x1)
|
||||
files = {"marked_image_file": ("m.jpg", open(fixture("marked_hairline.jpg"), "rb"), "application/octet-stream")}
|
||||
body = client.post(GROWB, headers=H, files=files).json() # 只传划线图一张
|
||||
body = client.post(GROWB, files=files).json() # 只传划线图一张
|
||||
assert body["code"] == 0, body
|
||||
d = body["data"]
|
||||
assert d["hairline_type"] == "custom"
|
||||
@@ -190,7 +181,7 @@ HLGEN = "/api/v1/hairline/generate"
|
||||
|
||||
|
||||
def test_hairline5_restored_schema_has_only_historical_parameters(client):
|
||||
schema = client.get("/openapi.json", headers=H).json()
|
||||
schema = client.get("/openapi.json").json()
|
||||
ref = schema["paths"][HLGEN]["post"]["requestBody"]["content"]["multipart/form-data"]["schema"]["$ref"]
|
||||
fields = schema["components"]["schemas"][ref.rsplit("/", 1)[-1]]["properties"]
|
||||
assert set(fields) == {"image_file", "image_url", "image_base64", "gender", "hair_style",
|
||||
@@ -204,7 +195,7 @@ def test_hairline5_restored_schema_has_only_historical_parameters(client):
|
||||
def test_hairline5_restored_three_levels_and_original_coordinate_contract(client, gender):
|
||||
from pathlib import Path
|
||||
photo = Path(fixture("frontal.jpg")).read_bytes()
|
||||
body = client.post(HLGEN, headers=H, files={"image_file": ("frontal.jpg", photo, "image/jpeg")},
|
||||
body = client.post(HLGEN, files={"image_file": ("frontal.jpg", photo, "image/jpeg")},
|
||||
data={"gender": gender, "hair_style": "1,3", "generate_grow_image": "false"}).json()
|
||||
assert body["code"] == 0, body
|
||||
data = body["data"]
|
||||
@@ -225,13 +216,13 @@ def test_hairline5_restored_three_levels_and_original_coordinate_contract(client
|
||||
|
||||
def test_hairline_gen_missing_gender_1004(client):
|
||||
files = {"image_file": ("frontal.jpg", open(fixture("frontal.jpg"), "rb"), "application/octet-stream")}
|
||||
assert client.post(HLGEN, headers=H, files=files).json()["code"] == 1004
|
||||
assert client.post(HLGEN, files=files).json()["code"] == 1004
|
||||
|
||||
|
||||
def test_hairline_gen_missing_hairstyle_1007(client):
|
||||
# hair_style 已改为必填(同接口2):只给 gender、不给 hair_style → 1007
|
||||
files = {"image_file": ("frontal.jpg", open(fixture("frontal.jpg"), "rb"), "application/octet-stream")}
|
||||
assert client.post(HLGEN, headers=H, files=files, data={"gender": "female"}).json()["code"] == 1007
|
||||
assert client.post(HLGEN, files=files, data={"gender": "female"}).json()["code"] == 1007
|
||||
|
||||
|
||||
def test_hairline_gen_female(client, monkeypatch):
|
||||
@@ -240,7 +231,7 @@ def test_hairline_gen_female(client, monkeypatch):
|
||||
monkeypatch.setattr(comfy, "run", lambda *a, **k: _PNG_1x1)
|
||||
|
||||
files = {"image_file": ("frontal.jpg", open(fixture("frontal.jpg"), "rb"), "application/octet-stream")}
|
||||
body = client.post(HLGEN, headers=H, files=files, data={"gender": "female", "hair_style": "1,3"}).json()
|
||||
body = client.post(HLGEN, files=files, data={"gender": "female", "hair_style": "1,3"}).json()
|
||||
assert body["code"] == 0, body
|
||||
d = body["data"]
|
||||
imgs = d["hairline_images"]
|
||||
@@ -279,7 +270,7 @@ HLGEN52 = "/api/v1/hairline/generate-52"
|
||||
|
||||
|
||||
def test_hairline52_legacy_form_parameters_and_defaults_are_preserved(client):
|
||||
schema = client.get("/openapi.json", headers=H).json()
|
||||
schema = client.get("/openapi.json").json()
|
||||
body = schema["paths"][HLGEN52]["post"]["requestBody"]["content"]["multipart/form-data"]["schema"]
|
||||
body = schema["components"]["schemas"][body["$ref"].rsplit("/", 1)[-1]]
|
||||
fields = body["properties"]
|
||||
@@ -310,7 +301,7 @@ def test_hairline52_legacy_request_keeps_fields_and_original_coordinates(client,
|
||||
return _PNG_1x1
|
||||
monkeypatch.setattr(comfy, "run", generate)
|
||||
form = {"gender": "male", "hair_style": "1", "use_mask": "false", "prompt": "legacy prompt"}
|
||||
kwargs = {"headers": H, "data": form}
|
||||
kwargs = {"data": form}
|
||||
if image_kind == "file":
|
||||
kwargs["files"] = {"image_file": ("frontal.jpg", raw, "image/jpeg")}
|
||||
elif image_kind == "base64":
|
||||
@@ -385,13 +376,13 @@ def test_hairline52_height_compare_uses_same_new_rule(client, monkeypatch, norma
|
||||
|
||||
def test_hairline52_gen_missing_gender_1004(client):
|
||||
files = {"image_file": ("frontal.jpg", open(fixture("frontal.jpg"), "rb"), "application/octet-stream")}
|
||||
assert client.post(HLGEN52, headers=H, files=files).json()["code"] == 1004
|
||||
assert client.post(HLGEN52, files=files).json()["code"] == 1004
|
||||
|
||||
|
||||
def test_hairline52_gen_missing_hairstyle_1007(client):
|
||||
# hair_style 已改为必填(同接口2):只给 gender、不给 hair_style → 1007
|
||||
files = {"image_file": ("frontal.jpg", open(fixture("frontal.jpg"), "rb"), "application/octet-stream")}
|
||||
assert client.post(HLGEN52, headers=H, files=files, data={"gender": "female"}).json()["code"] == 1007
|
||||
assert client.post(HLGEN52, files=files, data={"gender": "female"}).json()["code"] == 1007
|
||||
|
||||
|
||||
def test_hairline52_gen_female(client, monkeypatch):
|
||||
@@ -400,7 +391,7 @@ def test_hairline52_gen_female(client, monkeypatch):
|
||||
monkeypatch.setattr(comfy, "run", lambda *a, **k: _PNG_1x1)
|
||||
|
||||
files = {"image_file": ("frontal.jpg", open(fixture("frontal.jpg"), "rb"), "application/octet-stream")}
|
||||
body = client.post(HLGEN52, headers=H, files=files,
|
||||
body = client.post(HLGEN52, files=files,
|
||||
data={"gender": "female", "hair_style": "1,3", "normalize_image": "true"}).json()
|
||||
assert body["code"] == 0, body
|
||||
d = body["data"]
|
||||
@@ -422,7 +413,7 @@ def test_hairline52_gen_female(client, monkeypatch):
|
||||
assert d["high_hairline_center_point"] is None and d["low_hairline_center_point"] is None
|
||||
rule = d["height_rule"]
|
||||
assert rule["target_upper_height_px"] == pytest.approx(
|
||||
(rule["middle_height_px"] + rule["lower_height_px"]) / 2)
|
||||
(rule["middle_height_px"] + rule["lower_height_px"]) * 0.45)
|
||||
for x in imgs:
|
||||
assert x["height_placement"]["new_center"]["y"] == pytest.approx(rule["target_center"]["y"], abs=1)
|
||||
assert base64.b64decode(imgs[0]["grown_image_base64"])[:3] == b"\xff\xd8\xff"
|
||||
@@ -512,6 +503,6 @@ def _assert_vertical_lines(data, variant):
|
||||
|
||||
def test_measure_v2_vertical_lines_have_no_head_edges(client):
|
||||
files = {"image_file": ("frontal.jpg", open(fixture("frontal.jpg"), "rb"), "application/octet-stream")}
|
||||
body = client.post("/api/v1/face/measure-v2", headers=H, files=files).json()
|
||||
body = client.post("/api/v1/face/measure-v2", files=files).json()
|
||||
assert body["code"] == 0, body
|
||||
_assert_vertical_lines(body["data"], "v6")
|
||||
|
||||
Reference in New Issue
Block a user