mirror of
https://github.com/KohakuBlueleaf/KohakuHub.git
synced 2026-07-10 16:20:59 -05:00
test(hf-e2e): move visibility coverage tests under huggingface_hub flow
The previous coverage commit added raw-HTTP tests in test_crud.py for the visibility="public" + 400 unknown-visibility branches. Per the HF compatibility rule (AGENTS.md §5.1: prefer verification through the real huggingface_hub Python client), reshape so the public branch is exercised by HfApi.create_repo(repo_id, private=False) — v0 cells take the explicit-private path, v1 cells take the visibility="public" path, both observably collapse to a public repo. The 400 branch keeps using raw HTTP because huggingface_hub validates visibility client-side (RepoVisibility_T Literal) and refuses to send unknown values; that branch is documented in the test docstring. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -24,41 +24,6 @@ async def test_create_repository_and_reject_normalized_duplicate(owner_client):
|
||||
assert body["repo_id"] == "owner/sandbox-repo"
|
||||
|
||||
|
||||
async def test_create_repo_visibility_public_creates_public_repo(owner_client):
|
||||
"""``visibility="public"`` (huggingface_hub>=1.x shape with
|
||||
``private=False``) must round-trip as a public repo. Pairs with the
|
||||
``visibility="private"`` path covered through the live hf-client e2e
|
||||
test in ``test_huggingface_hub_deep.py`` — together they exercise
|
||||
both branches of the visibility resolver in ``crud.py`` so the
|
||||
patch-coverage gate stays clean."""
|
||||
response = await owner_client.post(
|
||||
"/api/repos/create",
|
||||
json={"type": "model", "name": "visibility-public-repo", "visibility": "public"},
|
||||
)
|
||||
assert response.status_code == 200
|
||||
assert response.json()["repo_id"] == "owner/visibility-public-repo"
|
||||
|
||||
info = await owner_client.get("/api/models/owner/visibility-public-repo")
|
||||
assert info.status_code == 200
|
||||
assert info.json()["private"] is False
|
||||
|
||||
|
||||
async def test_create_repo_unknown_visibility_returns_400(owner_client):
|
||||
"""The resolver must reject visibility values it cannot map to a
|
||||
private bool. Without this guard a typo like ``"hidden"`` would be
|
||||
silently treated as public — masking client-side bugs and breaking
|
||||
HF API symmetry with ``update_repo_settings``."""
|
||||
response = await owner_client.post(
|
||||
"/api/repos/create",
|
||||
json={"type": "model", "name": "visibility-bogus-repo", "visibility": "hidden"},
|
||||
)
|
||||
assert response.status_code == 400
|
||||
body = response.json()
|
||||
error_text = body.get("detail", {}).get("error", "") if isinstance(body.get("detail"), dict) else str(body)
|
||||
assert "visibility" in error_text.lower()
|
||||
assert "public" in error_text and "private" in error_text
|
||||
|
||||
|
||||
async def test_admin_can_delete_empty_org_repository(admin_client, owner_client):
|
||||
create_response = await owner_client.post(
|
||||
"/api/repos/create",
|
||||
|
||||
@@ -836,6 +836,72 @@ async def test_create_repo_private_flag_is_honored_across_hf_versions(
|
||||
await _run(outsider_api.repo_info, repo_id)
|
||||
|
||||
|
||||
async def test_create_repo_private_false_round_trips_as_public(
|
||||
live_server_url, hf_api_token
|
||||
):
|
||||
"""``HfApi.create_repo(repo_id, private=False)`` must produce a
|
||||
public repo on every client version.
|
||||
|
||||
The two on-the-wire shapes are also asymmetric on the public side:
|
||||
|
||||
* ``huggingface_hub<1`` sends ``{"private": false}`` directly,
|
||||
hitting the explicit-``private`` branch of the backend resolver.
|
||||
* ``huggingface_hub>=1.x`` resolves ``private=False`` into
|
||||
``{"visibility": "public"}`` (see ``_resolve_repo_visibility`` in
|
||||
``hf_api.py``), hitting the ``visibility=="public"`` branch
|
||||
instead.
|
||||
|
||||
Routing through the real client on the matrix exercises *both*
|
||||
branches across the CI matrix — v0 cells cover ``private``
|
||||
resolution and v1 cells cover ``visibility`` resolution — so a
|
||||
regression in either branch surfaces here.
|
||||
"""
|
||||
api = _api(live_server_url, hf_api_token)
|
||||
repo_id = "owner/hf-deep-create-public"
|
||||
await _run(api.create_repo, repo_id, private=False)
|
||||
|
||||
info = await _run(api.repo_info, repo_id)
|
||||
assert info.private is False, (
|
||||
"create_repo(private=False) produced a private repo — the "
|
||||
"backend mis-resolved the public path. v0 sends 'private=False' "
|
||||
"and v1 sends 'visibility=public'; both must collapse to public."
|
||||
)
|
||||
|
||||
|
||||
async def test_create_repo_rejects_unknown_visibility_value(
|
||||
live_server_url, hf_api_token
|
||||
):
|
||||
"""The visibility resolver must reject values it cannot map to a
|
||||
private bool with a 400 (and a stable error message).
|
||||
|
||||
The real ``huggingface_hub`` client validates ``visibility``
|
||||
client-side (``RepoVisibility_T = Literal["public", "private",
|
||||
"protected"]`` in ``hf_api.py``) and refuses to send a typo like
|
||||
``"hidden"`` over the wire — so the only way to drive this
|
||||
server-side branch is a direct HTTP request alongside the
|
||||
hf-client e2e flow. Without this guard a typo would silently
|
||||
produce a public repo, masking client-side bugs and breaking
|
||||
symmetry with the same guard in ``update_repo_settings``.
|
||||
"""
|
||||
async with httpx.AsyncClient(timeout=10) as client:
|
||||
response = await client.post(
|
||||
f"{live_server_url}/api/repos/create",
|
||||
json={
|
||||
"type": "model",
|
||||
"name": "hf-deep-create-bogus-visibility",
|
||||
"visibility": "hidden",
|
||||
},
|
||||
headers={"Authorization": f"Bearer {hf_api_token}"},
|
||||
)
|
||||
|
||||
assert response.status_code == 400, response.text
|
||||
body = response.json()
|
||||
detail = body.get("detail") if isinstance(body, dict) else None
|
||||
error_text = detail.get("error", "") if isinstance(detail, dict) else str(body)
|
||||
assert "visibility" in error_text.lower()
|
||||
assert "public" in error_text and "private" in error_text
|
||||
|
||||
|
||||
async def test_update_repo_settings_visibility_field_is_honored(
|
||||
live_server_url, hf_api_token
|
||||
):
|
||||
|
||||
Reference in New Issue
Block a user