fix(api): group create read product from multipart form (bug: 'provide product info' when no file attached)
The GroupBuilder sends the create form as multipart/form-data (FormData). The code decided JSON vs form by checking — when no file was attached, request.files was empty/falsy, so it tried get_json() on a multipart body and lost the product field -> 400 'provide product info' even though the user filled the product name. Fix: branch on the Content-Type (multipart/form-data -> request.form) instead of request.files. Added a regression test (multipart create with product only -> 201). Verified live: multipart product-only create now returns 201.
This commit is contained in:
@@ -88,7 +88,10 @@ def create_group():
|
|||||||
file.save(dest)
|
file.save(dest)
|
||||||
saved_files.append(dest.name)
|
saved_files.append(dest.name)
|
||||||
|
|
||||||
data = request.form.to_dict() if request.files else (request.get_json(silent=True) or {})
|
if request.content_type and "multipart/form-data" in request.content_type:
|
||||||
|
data = request.form.to_dict()
|
||||||
|
else:
|
||||||
|
data = request.get_json(silent=True) or {}
|
||||||
|
|
||||||
from ..services.file_parser import parse_document
|
from ..services.file_parser import parse_document
|
||||||
|
|
||||||
|
|||||||
@@ -47,6 +47,18 @@ def main():
|
|||||||
assert r.get_json()["group"]["status"] == "draft"
|
assert r.get_json()["group"]["status"] == "draft"
|
||||||
print("[ok] group created (draft)")
|
print("[ok] group created (draft)")
|
||||||
|
|
||||||
|
# Regression: multipart (like the frontend FormData) with product field but NO file
|
||||||
|
# attached must still create the group (was 400 'provide product info' before fix).
|
||||||
|
r = client.post(
|
||||||
|
"/api/groups",
|
||||||
|
data={"product": "Multipart Product"},
|
||||||
|
content_type="multipart/form-data",
|
||||||
|
headers=H,
|
||||||
|
)
|
||||||
|
assert r.status_code == 201, f"multipart create failed: {r.get_json()}"
|
||||||
|
assert r.get_json()["group"]["title"] == "Multipart Product"
|
||||||
|
print("[ok] group created via multipart (product only) — regression fixed")
|
||||||
|
|
||||||
# analyze should fail cleanly (LLM None)
|
# analyze should fail cleanly (LLM None)
|
||||||
r = client.post(f"/api/groups/{gid}/analyze", headers=H)
|
r = client.post(f"/api/groups/{gid}/analyze", headers=H)
|
||||||
assert r.status_code == 500, r.get_json()
|
assert r.status_code == 500, r.get_json()
|
||||||
@@ -54,8 +66,9 @@ def main():
|
|||||||
|
|
||||||
# list groups as admin
|
# list groups as admin
|
||||||
r = client.get("/api/groups", headers=H)
|
r = client.get("/api/groups", headers=H)
|
||||||
assert r.status_code == 200 and len(r.get_json()["groups"]) == 1
|
assert r.status_code == 200 and len(r.get_json()["groups"]) >= 1
|
||||||
print("[ok] admin lists 1 group")
|
assert all(g["status"] == "draft" for g in r.get_json()["groups"])
|
||||||
|
print("[ok] admin lists groups")
|
||||||
|
|
||||||
# personas empty until analyze
|
# personas empty until analyze
|
||||||
r = client.get(f"/api/groups/{gid}", headers=H)
|
r = client.get(f"/api/groups/{gid}", headers=H)
|
||||||
|
|||||||
Reference in New Issue
Block a user