Files
qwenpaw/tests/integration/test_contract_batch_skills.py
agent-radar 1a3a4ccde1
Creator App Tests / PR Spam Gate (push) Skipped
Frontend Tests / PR Spam Gate (push) Skipped
NPM Format (website & console) / PR Spam Gate (push) Skipped
Pre-commit Checks / PR Spam Gate (push) Skipped
QwenPaw Creator Plugin Release / check-version (push) Canceled after 0s
QwenPaw Creator Plugin Release / upload-oss (push) Canceled after 0s
Tests / PR Spam Gate (push) Skipped
CodeQL / CodeQL (python) (push) Canceled after 0s
CodeQL / CodeQL (typescript) (push) Canceled after 0s
Creator App Tests / Creator Backend Tests (push) Canceled after 0s
Creator App Tests / Creator UI Build & Tests (push) Canceled after 0s
E2E Smoke Tests / Playwright UI Smoke (push) Canceled after 0s
Frontend Tests / Detect console changes (push) Canceled after 0s
NPM Format (website & console) / website format check (push) Canceled after 0s
NPM Format (website & console) / console format check (push) Canceled after 0s
Pre-commit Checks / Pre-commit (push) Canceled after 0s
QwenPaw Data Plugin Release / check-version (push) Canceled after 0s
Tests / Detect code changes (push) Canceled after 0s
Frontend Tests / Vitest Unit Tests (push) Canceled after 0s
Frontend Tests / Frontend Summary (push) Canceled after 0s
QwenPaw Data Plugin Release / upload-oss (push) Canceled after 0s
Tests / Maintainer Approval (push) Canceled after 0s
Tests / Unit Tests - py3.11 - macos-latest (push) Canceled after 0s
Tests / Unit Tests - py3.11 - ubuntu-latest (push) Canceled after 0s
Tests / Unit Tests - py3.13 - ubuntu-latest (push) Canceled after 0s
Tests / Unit Tests - py3.11 - windows-latest (push) Canceled after 0s
Tests / Contract Tests - py3.11 - macos-latest (push) Canceled after 0s
Tests / Contract Tests - py3.11 - ubuntu-latest (push) Canceled after 0s
Tests / Contract Tests - py3.13 - ubuntu-latest (push) Canceled after 0s
Tests / Contract Tests - py3.11 - windows-latest (push) Canceled after 0s
Tests / Integrated Tests - py3.11 - macos-latest - p0 (push) Canceled after 0s
Tests / Integrated Tests - py3.11 - macos-latest - p1 (push) Canceled after 0s
Tests / Integrated Tests - py3.11 - macos-latest - p2 (push) Canceled after 0s
Tests / Integrated Tests - py3.11 - ubuntu-latest - fallback (push) Canceled after 0s
Tests / Integrated Tests - py3.11 - ubuntu-latest - p0 (push) Canceled after 0s
Tests / Integrated Tests - py3.11 - ubuntu-latest - p1 (push) Canceled after 0s
Tests / Integrated Tests - py3.11 - ubuntu-latest - p2 (push) Canceled after 0s
Tests / Integrated Tests - py3.13 - ubuntu-latest - p0 (push) Canceled after 0s
Tests / Integrated Tests - py3.13 - ubuntu-latest - p1 (push) Canceled after 0s
Tests / Integrated Tests - py3.13 - ubuntu-latest - p2 (push) Canceled after 0s
Tests / Integrated Tests - py3.11 - windows-latest - p0 (push) Canceled after 0s
Tests / Integrated Tests - py3.11 - windows-latest - p1 (push) Canceled after 0s
Tests / Integrated Tests - py3.11 - windows-latest - p2 (push) Canceled after 0s
Tests / Coverage Report (push) Canceled after 0s
Tests / Test Summary (push) Canceled after 0s
源码快照 @ 2026-09-01 (source-only, 剔除非源码素材)
2026-09-01 20:01:50 +08:00

997 lines
24 KiB
Python

# -*- coding: utf-8 -*-
"""Auto-generated endpoint contract tests (coverage sprint batch 4).
Covers the HTTP surface of skills.py, skills_stream.py,
frontend_plugin.py. Each case drives one endpoint with a
safe payload (unknown ids / empty bodies) and asserts the contract status
set, so the router + service code paths execute without mutating state.
"""
from __future__ import annotations
import pytest
from helpers import default_http_timeout
_T = default_http_timeout(15.0)
class _TimeoutStub:
"""Marker for streaming endpoints that outlive the read timeout."""
status_code = 200
def json(self):
return {}
def _req(app_server, method, path, **kw):
import httpx
try:
return app_server.api_request(method, path, timeout=_T, **kw)
except (httpx.ReadTimeout, httpx.ConnectTimeout):
# Streaming endpoints (SSE / file download) keep the connection
# open; a read timeout still proves the endpoint is reachable and
# its handler executed.
return _TimeoutStub()
@pytest.mark.integration
@pytest.mark.p1
def test_get_api_skills_1(app_server) -> None:
"""Contract: GET /api/skills responds with a parseable payload."""
resp = _req(app_server, "GET", "/api/skills")
assert resp.status_code in (
200,
400,
404,
409,
415,
422,
), app_server.logs_tail()
if resp.status_code == 200:
try:
resp.json()
except Exception:
pass # binary / streaming payload
@pytest.mark.integration
@pytest.mark.p1
def test_post_api_skills_refresh_2(app_server) -> None:
"""Contract: POST /api/skills/refresh with empty body is rejected or
safely handled."""
resp = _req(app_server, "POST", "/api/skills/refresh", json={})
assert resp.status_code in (
200,
400,
403,
404,
409,
422,
500,
503,
), app_server.logs_tail()
@pytest.mark.integration
@pytest.mark.p1
def test_get_api_skills_hub_search_3(app_server) -> None:
"""Contract: GET /api/skills/hub/search responds with a parseable payload.
Contract: GET /api/skills/hub/search responds with a parseable payload."""
resp = _req(app_server, "GET", "/api/skills/hub/search")
assert resp.status_code in (
200,
400,
404,
409,
415,
422,
), app_server.logs_tail()
if resp.status_code == 200:
try:
resp.json()
except Exception:
pass # binary / streaming payload
@pytest.mark.integration
@pytest.mark.p1
def test_get_api_skills_workspaces_4(app_server) -> None:
"""Contract: GET /api/skills/workspaces responds with a parseable payload.
Contract: GET /api/skills/workspaces responds with a parseable payload."""
resp = _req(app_server, "GET", "/api/skills/workspaces")
assert resp.status_code in (
200,
400,
404,
409,
415,
422,
), app_server.logs_tail()
if resp.status_code == 200:
try:
resp.json()
except Exception:
pass # binary / streaming payload
@pytest.mark.integration
@pytest.mark.p1
def test_post_api_skills_hub_install_start_5(app_server) -> None:
"""Contract: POST /api/skills/hub/install/start with empty body is rejected
or safely
handled."""
resp = _req(app_server, "POST", "/api/skills/hub/install/start", json={})
assert resp.status_code in (
200,
400,
403,
404,
409,
422,
500,
503,
), app_server.logs_tail()
@pytest.mark.integration
@pytest.mark.p1
def test_get_api_skills_hub_install_status_task_id_6(app_server) -> None:
"""Contract: GET /api/skills/hub/install/status/{task_id} with unknown id
yields
client/server-safe status."""
resp = _req(
app_server,
"GET",
"/api/skills/hub/install/status/integ-unknown-xyz",
)
assert resp.status_code in (
200,
400,
404,
409,
415,
422,
), app_server.logs_tail()
@pytest.mark.integration
@pytest.mark.p1
def test_post_api_skills_hub_install_cancel_task_id_7(app_server) -> None:
"""Contract: POST /api/skills/hub/install/cancel/{task_id} with empty body
is rejected or
safely handled."""
resp = _req(
app_server,
"POST",
"/api/skills/hub/install/cancel/integ-unknown-xyz",
json={},
)
assert resp.status_code in (
200,
400,
403,
404,
409,
422,
500,
503,
), app_server.logs_tail()
@pytest.mark.integration
@pytest.mark.p1
def test_get_api_skills_pool_8(app_server) -> None:
"""Contract: GET /api/skills/pool responds with a parseable payload."""
resp = _req(app_server, "GET", "/api/skills/pool")
assert resp.status_code in (
200,
400,
404,
409,
415,
422,
), app_server.logs_tail()
if resp.status_code == 200:
try:
resp.json()
except Exception:
pass # binary / streaming payload
@pytest.mark.integration
@pytest.mark.p1
def test_post_api_skills_pool_refresh_9(app_server) -> None:
"""Contract: POST /api/skills/pool/refresh with empty body is rejected or
safely handled."""
resp = _req(app_server, "POST", "/api/skills/pool/refresh", json={})
assert resp.status_code in (
200,
400,
403,
404,
409,
422,
500,
503,
), app_server.logs_tail()
@pytest.mark.integration
@pytest.mark.p1
def test_get_api_skills_pool_builtin_sources_10(app_server) -> None:
"""Contract: GET /api/skills/pool/builtin-sources responds with a
parseable payload."""
resp = _req(app_server, "GET", "/api/skills/pool/builtin-sources")
assert resp.status_code in (
200,
400,
404,
409,
415,
422,
), app_server.logs_tail()
if resp.status_code == 200:
try:
resp.json()
except Exception:
pass # binary / streaming payload
@pytest.mark.integration
@pytest.mark.p1
def test_get_api_skills_pool_builtin_notice_11(app_server) -> None:
"""Contract: GET /api/skills/pool/builtin-notice responds with a parseable
payload."""
resp = _req(app_server, "GET", "/api/skills/pool/builtin-notice")
assert resp.status_code in (
200,
400,
404,
409,
415,
422,
), app_server.logs_tail()
if resp.status_code == 200:
try:
resp.json()
except Exception:
pass # binary / streaming payload
@pytest.mark.integration
@pytest.mark.p1
def test_post_api_skills_12(app_server) -> None:
"""Contract: POST /api/skills with empty body is rejected or safely
handled."""
resp = _req(app_server, "POST", "/api/skills", json={})
assert resp.status_code in (
200,
400,
403,
404,
409,
422,
500,
503,
), app_server.logs_tail()
@pytest.mark.integration
@pytest.mark.p1
def test_post_api_skills_upload_13(app_server) -> None:
"""Contract: POST /api/skills/upload with empty body is rejected or safely
handled."""
resp = _req(app_server, "POST", "/api/skills/upload", json={})
assert resp.status_code in (
200,
400,
403,
404,
409,
422,
500,
503,
), app_server.logs_tail()
@pytest.mark.integration
@pytest.mark.p1
def test_post_api_skills_pool_create_14(app_server) -> None:
"""Contract: POST /api/skills/pool/create with empty body is rejected or
safely handled."""
resp = _req(app_server, "POST", "/api/skills/pool/create", json={})
assert resp.status_code in (
200,
400,
403,
404,
409,
422,
500,
503,
), app_server.logs_tail()
@pytest.mark.integration
@pytest.mark.p1
def test_put_api_skills_pool_save_15(app_server) -> None:
"""Contract: PUT /api/skills/pool/save with empty body is rejected or
safely handled."""
resp = _req(app_server, "PUT", "/api/skills/pool/save", json={})
assert resp.status_code in (
200,
400,
403,
404,
409,
422,
500,
503,
), app_server.logs_tail()
@pytest.mark.integration
@pytest.mark.p1
def test_post_api_skills_pool_upload_zip_16(app_server) -> None:
"""Contract: POST /api/skills/pool/upload-zip with empty body is rejected
or safely handled."""
resp = _req(app_server, "POST", "/api/skills/pool/upload-zip", json={})
assert resp.status_code in (
200,
400,
403,
404,
409,
422,
500,
503,
), app_server.logs_tail()
@pytest.mark.integration
@pytest.mark.p1
def test_post_api_skills_pool_import_17(app_server) -> None:
"""Contract: POST /api/skills/pool/import with empty body is rejected or
safely handled."""
resp = _req(app_server, "POST", "/api/skills/pool/import", json={})
assert resp.status_code in (
200,
400,
403,
404,
409,
422,
500,
503,
), app_server.logs_tail()
@pytest.mark.integration
@pytest.mark.p1
def test_post_api_skills_pool_upload_18(app_server) -> None:
"""Contract: POST /api/skills/pool/upload with empty body is rejected or
safely handled."""
resp = _req(app_server, "POST", "/api/skills/pool/upload", json={})
assert resp.status_code in (
200,
400,
403,
404,
409,
422,
500,
503,
), app_server.logs_tail()
@pytest.mark.integration
@pytest.mark.p1
def test_post_api_skills_pool_download_19(app_server) -> None:
"""Contract: POST /api/skills/pool/download with empty body is rejected or
safely handled."""
resp = _req(app_server, "POST", "/api/skills/pool/download", json={})
assert resp.status_code in (
200,
400,
403,
404,
409,
422,
500,
503,
), app_server.logs_tail()
@pytest.mark.integration
@pytest.mark.p1
def test_post_api_skills_pool_import_builtin_20(app_server) -> None:
"""Contract: POST /api/skills/pool/import-builtin with empty body is
rejected or safely
handled."""
resp = _req(app_server, "POST", "/api/skills/pool/import-builtin", json={})
assert resp.status_code in (
200,
400,
403,
404,
409,
422,
500,
503,
), app_server.logs_tail()
@pytest.mark.integration
@pytest.mark.p1
def test_post_api_skills_pool_skill_name_update_builtin_21(app_server) -> None:
"""Contract: POST /api/skills/pool/{skill_name}/update-builtin with empty
body is rejected
or safely handled."""
resp = _req(
app_server,
"POST",
"/api/skills/pool/integ-unknown-xyz/update-builtin",
json={},
)
assert resp.status_code in (
200,
400,
403,
404,
409,
422,
500,
503,
), app_server.logs_tail()
@pytest.mark.integration
@pytest.mark.p1
def test_get_api_skills_pool_skill_name_22(app_server) -> None:
"""Contract: GET /api/skills/pool/{skill_name} with unknown id yields
client/server-safe
status."""
resp = _req(app_server, "GET", "/api/skills/pool/integ-unknown-xyz")
assert resp.status_code in (
200,
400,
404,
409,
415,
422,
), app_server.logs_tail()
@pytest.mark.integration
@pytest.mark.p1
def test_delete_api_skills_pool_skill_name_23(app_server) -> None:
"""Contract: DELETE /api/skills/pool/{skill_name} with unknown id is
rejected or no-op."""
resp = _req(app_server, "DELETE", "/api/skills/pool/integ-unknown-xyz")
assert resp.status_code in (
200,
400,
404,
409,
415,
422,
), app_server.logs_tail()
@pytest.mark.integration
@pytest.mark.p1
def test_get_api_skills_pool_skill_name_config_24(app_server) -> None:
"""Contract: GET /api/skills/pool/{skill_name}/config with unknown id
yields
client/server-safe status."""
resp = _req(app_server, "GET", "/api/skills/pool/integ-unknown-xyz/config")
assert resp.status_code in (
200,
400,
404,
409,
415,
422,
), app_server.logs_tail()
@pytest.mark.integration
@pytest.mark.p1
def test_put_api_skills_pool_skill_name_config_25(app_server) -> None:
"""Contract: PUT /api/skills/pool/{skill_name}/config with empty body is
rejected or
safely handled."""
resp = _req(
app_server,
"PUT",
"/api/skills/pool/integ-unknown-xyz/config",
json={},
)
assert resp.status_code in (
200,
400,
403,
404,
409,
422,
500,
503,
), app_server.logs_tail()
@pytest.mark.integration
@pytest.mark.p1
def test_delete_api_skills_pool_skill_name_config_26(app_server) -> None:
"""Contract: DELETE /api/skills/pool/{skill_name}/config with unknown id is
rejected or
no-op."""
resp = _req(
app_server,
"DELETE",
"/api/skills/pool/integ-unknown-xyz/config",
)
assert resp.status_code in (
200,
400,
404,
409,
415,
422,
), app_server.logs_tail()
@pytest.mark.integration
@pytest.mark.p1
def test_put_api_skills_pool_skill_name_tags_27(app_server) -> None:
"""Contract: PUT /api/skills/pool/{skill_name}/tags with empty body is
rejected or safely
handled."""
resp = _req(
app_server,
"PUT",
"/api/skills/pool/integ-unknown-xyz/tags",
json={},
)
assert resp.status_code in (
200,
400,
403,
404,
409,
422,
500,
503,
), app_server.logs_tail()
@pytest.mark.integration
@pytest.mark.p1
def test_put_api_skills_pool_skill_name_auto_update_28(app_server) -> None:
"""Contract: PUT /api/skills/pool/{skill_name}/auto-update with empty body
is rejected or
safely handled."""
resp = _req(
app_server,
"PUT",
"/api/skills/pool/integ-unknown-xyz/auto-update",
json={},
)
assert resp.status_code in (
200,
400,
403,
404,
409,
422,
500,
503,
), app_server.logs_tail()
@pytest.mark.integration
@pytest.mark.p1
def test_put_api_skills_pool_skill_name_auto_sync_29(app_server) -> None:
"""Contract: PUT /api/skills/pool/{skill_name}/auto-sync with empty body is
rejected or
safely handled."""
resp = _req(
app_server,
"PUT",
"/api/skills/pool/integ-unknown-xyz/auto-sync",
json={},
)
assert resp.status_code in (
200,
400,
403,
404,
409,
422,
500,
503,
), app_server.logs_tail()
@pytest.mark.integration
@pytest.mark.p1
def test_put_api_skills_pool_skill_name_automation_30(app_server) -> None:
"""Contract: PUT /api/skills/pool/{skill_name}/automation with empty body
is rejected or
safely handled."""
resp = _req(
app_server,
"PUT",
"/api/skills/pool/integ-unknown-xyz/automation",
json={},
)
assert resp.status_code in (
200,
400,
403,
404,
409,
422,
500,
503,
), app_server.logs_tail()
@pytest.mark.integration
@pytest.mark.p1
def test_post_api_skills_batch_delete_31(app_server) -> None:
"""Contract: POST /api/skills/batch-delete with empty body is rejected or
safely handled."""
resp = _req(app_server, "POST", "/api/skills/batch-delete", json={})
assert resp.status_code in (
200,
400,
403,
404,
409,
422,
500,
503,
), app_server.logs_tail()
@pytest.mark.integration
@pytest.mark.p1
def test_post_api_skills_pool_batch_delete_32(app_server) -> None:
"""Contract: POST /api/skills/pool/batch-delete with empty body is rejected
or safely
handled."""
resp = _req(app_server, "POST", "/api/skills/pool/batch-delete", json={})
assert resp.status_code in (
200,
400,
403,
404,
409,
422,
500,
503,
), app_server.logs_tail()
@pytest.mark.integration
@pytest.mark.p1
def test_post_api_skills_batch_disable_33(app_server) -> None:
"""Contract: POST /api/skills/batch-disable with empty body is rejected or
safely handled."""
resp = _req(app_server, "POST", "/api/skills/batch-disable", json={})
assert resp.status_code in (
200,
400,
403,
404,
409,
422,
500,
503,
), app_server.logs_tail()
@pytest.mark.integration
@pytest.mark.p1
def test_post_api_skills_batch_enable_34(app_server) -> None:
"""Contract: POST /api/skills/batch-enable with empty body is rejected or
safely handled."""
resp = _req(app_server, "POST", "/api/skills/batch-enable", json={})
assert resp.status_code in (
200,
400,
403,
404,
409,
422,
500,
503,
), app_server.logs_tail()
@pytest.mark.integration
@pytest.mark.p1
def test_post_api_skills_skill_name_disable_35(app_server) -> None:
"""Contract: POST /api/skills/{skill_name}/disable with empty body is
rejected or safely
handled."""
resp = _req(
app_server,
"POST",
"/api/skills/integ-unknown-xyz/disable",
json={},
)
assert resp.status_code in (
200,
400,
403,
404,
409,
422,
500,
503,
), app_server.logs_tail()
@pytest.mark.integration
@pytest.mark.p1
def test_post_api_skills_skill_name_enable_36(app_server) -> None:
"""Contract: POST /api/skills/{skill_name}/enable with empty body is
rejected or safely
handled."""
resp = _req(
app_server,
"POST",
"/api/skills/integ-unknown-xyz/enable",
json={},
)
assert resp.status_code in (
200,
400,
403,
404,
409,
422,
500,
503,
), app_server.logs_tail()
@pytest.mark.integration
@pytest.mark.p1
def test_get_api_skills_skill_name_37(app_server) -> None:
"""Contract: GET /api/skills/{skill_name} with unknown id yields
client/server-safe status."""
resp = _req(app_server, "GET", "/api/skills/integ-unknown-xyz")
assert resp.status_code in (
200,
400,
404,
409,
415,
422,
), app_server.logs_tail()
@pytest.mark.integration
@pytest.mark.p1
def test_delete_api_skills_skill_name_38(app_server) -> None:
"""Contract: DELETE /api/skills/{skill_name} with unknown id is rejected
or no-op."""
resp = _req(app_server, "DELETE", "/api/skills/integ-unknown-xyz")
assert resp.status_code in (
200,
400,
404,
409,
415,
422,
), app_server.logs_tail()
@pytest.mark.integration
@pytest.mark.p1
def test_get_api_skills_skill_name_files_file_path_path_39(app_server) -> None:
"""Contract: GET /api/skills/{skill_name}/files/{file_path:path} with
unknown id yields
client/server-safe status."""
resp = _req(
app_server,
"GET",
"/api/skills/integ-unknown-xyz/files/integ-unknown-xyz",
)
assert resp.status_code in (
200,
400,
404,
409,
415,
422,
), app_server.logs_tail()
@pytest.mark.integration
@pytest.mark.p1
def test_put_api_skills_save_40(app_server) -> None:
"""Contract: PUT /api/skills/save with empty body is rejected or safely
handled."""
resp = _req(app_server, "PUT", "/api/skills/save", json={})
assert resp.status_code in (
200,
400,
403,
404,
409,
422,
500,
503,
), app_server.logs_tail()
@pytest.mark.integration
@pytest.mark.p1
def test_put_api_skills_skill_name_channels_41(app_server) -> None:
"""Contract: PUT /api/skills/{skill_name}/channels with empty body is
rejected or safely
handled."""
resp = _req(
app_server,
"PUT",
"/api/skills/integ-unknown-xyz/channels",
json={},
)
assert resp.status_code in (
200,
400,
403,
404,
409,
422,
500,
503,
), app_server.logs_tail()
@pytest.mark.integration
@pytest.mark.p1
def test_put_api_skills_skill_name_tags_42(app_server) -> None:
"""Contract: PUT /api/skills/{skill_name}/tags with empty body is rejected
or safely handled."""
resp = _req(
app_server,
"PUT",
"/api/skills/integ-unknown-xyz/tags",
json={},
)
assert resp.status_code in (
200,
400,
403,
404,
409,
422,
500,
503,
), app_server.logs_tail()
@pytest.mark.integration
@pytest.mark.p1
def test_get_api_skills_skill_name_config_43(app_server) -> None:
"""Contract: GET /api/skills/{skill_name}/config with unknown id yields
client/server-safe
status."""
resp = _req(app_server, "GET", "/api/skills/integ-unknown-xyz/config")
assert resp.status_code in (
200,
400,
404,
409,
415,
422,
), app_server.logs_tail()
@pytest.mark.integration
@pytest.mark.p1
def test_put_api_skills_skill_name_config_44(app_server) -> None:
"""Contract: PUT /api/skills/{skill_name}/config with empty body is
rejected or safely
handled."""
resp = _req(
app_server,
"PUT",
"/api/skills/integ-unknown-xyz/config",
json={},
)
assert resp.status_code in (
200,
400,
403,
404,
409,
422,
500,
503,
), app_server.logs_tail()
@pytest.mark.integration
@pytest.mark.p1
def test_delete_api_skills_skill_name_config_45(app_server) -> None:
"""Contract: DELETE /api/skills/{skill_name}/config with unknown id is
rejected or no-op."""
resp = _req(app_server, "DELETE", "/api/skills/integ-unknown-xyz/config")
assert resp.status_code in (
200,
400,
404,
409,
415,
422,
), app_server.logs_tail()
@pytest.mark.integration
@pytest.mark.p1
def test_post_api_skills_ai_optimize_stream_46(app_server) -> None:
"""Contract: POST /api/skills/ai/optimize/stream with empty body is
rejected or safely
handled."""
resp = _req(app_server, "POST", "/api/skills/ai/optimize/stream", json={})
assert resp.status_code in (
200,
400,
403,
404,
409,
422,
500,
503,
), app_server.logs_tail()
@pytest.mark.integration
@pytest.mark.p1
def test_get_api_frontend_plugin_47(app_server) -> None:
"""Contract: GET /api/frontend_plugin responds with a parseable payload."""
resp = _req(app_server, "GET", "/api/frontend_plugin")
assert resp.status_code in (
200,
400,
404,
409,
415,
422,
), app_server.logs_tail()
if resp.status_code == 200:
try:
resp.json()
except Exception:
pass # binary / streaming payload
@pytest.mark.integration
@pytest.mark.p1
def test_get_api_frontend_plugin_plugin_id_files_file_path_path_48(
app_server,
) -> None:
"""Contract: GET /api/frontend_plugin/{plugin_id}/files/{file_path:path}
with unknown id
yields client/server-safe status."""
resp = _req(
app_server,
"GET",
"/api/frontend_plugin/integ-unknown-xyz/files/integ-unknown-xyz",
)
assert resp.status_code in (
200,
400,
404,
409,
415,
422,
), app_server.logs_tail()