Skip to content

test(proxy/proxy_server): pin control-plane routes (PR3)#28850

Merged
yuneng-berri merged 8 commits into
litellm_yj_may29from
claude/optimistic-wozniak-zhILd
May 29, 2026
Merged

test(proxy/proxy_server): pin control-plane routes (PR3)#28850
yuneng-berri merged 8 commits into
litellm_yj_may29from
claude/optimistic-wozniak-zhILd

Conversation

@yuneng-berri

Copy link
Copy Markdown
Collaborator

Summary

PR3 of the proxy_server.py behavior-pinning project — fills the 7 PR3 placeholder files left empty by the harness PR (#28827) with happy + error tests for the 34 control-plane routes in the pin list. Pins HTTP-boundary behavior of admin, login/SSO, onboarding, invitation, config CRUD, model-cost-map reload, anthropic-beta-headers reload, and misc routes via dict-equality assertions, so future refactors of litellm/proxy/proxy_server.py can't silently change response shapes.

What's covered

File Routes Tests
test_routes_login_sso.py 5 14
test_routes_onboarding.py 2 10
test_routes_invitation.py 4 14
test_routes_config.py 8 22
test_routes_model_cost_map.py 5 16
test_routes_anthropic_beta.py 4 15
test_routes_misc.py 6 16
Total 34 107

Includes both premium_user-true and -false paths for admin-gated routes that branch on premium status, per the PR3 prompt.

Test plan

  • uv run pytest tests/test_litellm/proxy/proxy_server/ -n 4126 passed in 13.2s (the 19 extra come from the harness's test_harness_smoke.py and a few placeholder no-op cases).
  • python tests/test_litellm/proxy/proxy_server/_pin_check.py --list .pin_list.txtPASS (34 pins, 107 tests, zero status-only failures).
  • python tests/test_litellm/proxy/proxy_server/_coverage_check.py (CI mode, self-detected target) → PASS (24.5% line, 10.4% branch — exceeds the PR0 baseline; the 70% / 55% PR3 gate is additive on top of PR1+PR2 and self-activates once their files are filled).
  • Runtime well under the 3-min PR3 budget.

Notes for reviewers

  • All tests use only fixtures from tests/test_litellm/proxy/proxy_server/conftest.py (no new conftests, no fixtures defined inline).
  • A few routes use prisma_client.db.litellm_config, which is not in the default _PRISMA_TABLES list in conftest (litellm_configtable is the one stubbed). Each affected test file installs litellm_config on the mock locally to avoid touching shared fixtures.
  • Mocked Pydantic models / scheduler globals / external reload functions where the routes call out; no network calls fire from this suite.
  • No deletion of existing scattered tests (cleanup deferred per plan).

Out of scope

  • MCP forwarding routes (dynamic_mcp_route, toolset_mcp_route) — deferred to the MCP refactor workstream noted in the parent plan.

Generated by Claude Code

claude added 7 commits May 26, 2026 06:48
Adds happy + error tests for the misc control-plane routes:
GET /, /routes, /adaptive_router/state, /get_logo_url,
/get_image, /get_favicon.

Also gitignores .pin_list.txt (used by the pin gate).
Adds happy + error tests for the 5 login/SSO control-plane routes:
GET /fallback/login, POST /login, POST /v2/login, POST /v3/login,
POST /v3/login/exchange. Mocks authenticate_user and
create_ui_token_object at their imported location.
Adds happy + error tests for the 2 onboarding control-plane routes:
GET /onboarding/get_token, POST /onboarding/claim_token. Wires a
MagicMock async context manager for prisma_client.db.tx() and
signs the onboarding JWT with the patched master_key.
…ial)

Adds happy + error tests for the 5 model-cost-map control-plane routes:
POST /reload/model_cost_map, POST|DELETE|GET
/schedule/model_cost_map_reload(/status), GET /model/cost_map/source.
Attaches litellm_config to mock_prisma per-test (the table is not in
the default _PRISMA_TABLES fixture).
…R3, partial)

Adds happy + error tests for the 4 anthropic-beta-headers control-plane
routes: POST /reload/anthropic_beta_headers, POST|DELETE|GET
/schedule/anthropic_beta_headers_reload(/status). Stubs
db.litellm_config (not in default _PRISMA_TABLES) and monkeypatches
reload_beta_headers_config so no network calls fire.
Adds happy + error tests for the 4 invitation control-plane routes:
POST /invitation/new, GET /invitation/info, POST /invitation/update,
POST /invitation/delete. Patches _user_has_admin_privileges /
_user_has_admin_view to avoid extensive get_user_object mocking.
Adds happy + error tests for the 8 config-CRUD control-plane routes:
POST /config/update, POST|GET /config/field/update|info, GET /config/list,
POST /config/field/delete, POST /config/callback/delete,
GET /get/config/callbacks, GET /config/yaml. Attaches litellm_config
to mock_prisma per-test.
@CLAassistant

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@codecov

codecov Bot commented May 26, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@greptile-apps

greptile-apps Bot commented May 26, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fills in the 7 placeholder test files from the PR3 harness, adding 107 behavior-pinning tests for 34 control-plane routes across login/SSO, onboarding, invitation, config CRUD, model-cost-map reload, Anthropic-beta-headers reload, and misc routes. All tests use only the shared conftest.py fixtures with no real network calls.

  • Two trivially-true assertions (b\"\" in response.content and len(response.content) >= 0) will never catch a regression and need to be tightened to > 0 checks.
  • One test in test_routes_anthropic_beta.py matches a serialized JSON string with hard-coded spacing, which is brittle against alternate serializer call-sites; deserializing and comparing the dict directly is more robust.
  • One config callback "not-found" test accepts both 404 and 500, which may be masking an underlying error-handling gap in the route itself.

Confidence Score: 4/5

This is a purely additive test-only PR with no production code changes; the main risk is a small number of assertions that are too weak to catch the regressions they appear to guard against.

The two trivially-true assertions mean two tests will pass unconditionally and never detect a regression on those error paths, defeating the purpose of pinning them. The rest of the 107 tests are well-structured with tight dict-equality checks via normalize(), proper volatile-key handling, and good role/auth coverage.

tests/test_litellm/proxy/proxy_server/test_routes_misc.py and test_routes_login_sso.py contain the non-failing assertions; test_routes_anthropic_beta.py has the brittle JSON string check.

Important Files Changed

Filename Overview
tests/test_litellm/proxy/proxy_server/test_routes_misc.py Pins 6 misc routes. Contains a trivially-true assertion (b"" in response.content) that never fails and provides no regression protection.
tests/test_litellm/proxy/proxy_server/test_routes_login_sso.py Pins 5 login/SSO routes. One 500-error test uses len(response.content) >= 0 which is always True and gives no signal on whether an error body is actually returned.
tests/test_litellm/proxy/proxy_server/test_routes_anthropic_beta.py Pins 4 Anthropic-beta reload/schedule routes. One test uses brittle string-literal JSON assertions that depend on exact serialization spacing.
tests/test_litellm/proxy/proxy_server/test_routes_config.py Pins 8 config routes. One error-path test accepts both 404 and 500, weakening the pin; all other assertions are tight dict-equality checks.
tests/test_litellm/proxy/proxy_server/test_routes_invitation.py Pins 4 invitation CRUD routes with solid dict-equality assertions and proper volatile-key handling; no issues found.
tests/test_litellm/proxy/proxy_server/test_routes_model_cost_map.py Pins 5 model-cost-map reload/schedule routes with tight dict-equality assertions and proper mock isolation; no issues found.
tests/test_litellm/proxy/proxy_server/test_routes_onboarding.py Pins 2 onboarding routes including JWT decode assertion; thorough edge-case coverage (expired invite, user_id mismatch, missing fields).

Reviews (1): Last reviewed commit: "test(proxy/proxy_server): pin config CRU..." | Re-trigger Greptile

Comment on lines +43 to +44
assert response.status_code == 405
assert b"" in response.content or response.headers.get("content-type")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Trivially-true assertion — b"" in response.content is always True (the empty bytes literal is a substring of every bytes object), so this check can never fail and provides zero regression protection. The guard also short-circuits the or, meaning the content-type side is never even evaluated. The test's stated intent is to verify a non-empty body is returned.

Suggested change
assert response.status_code == 405
assert b"" in response.content or response.headers.get("content-type")
assert response.status_code == 405
assert len(response.content) > 0 and response.headers.get("content-type")

Comment on lines +156 to +160
# raise_server_exceptions=False -> TestClient returns 500 with body
assert response.status_code == 500
# Some non-status assertion — body should be present
assert len(response.content) >= 0
assert response.headers.get("content-type") is not None

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 len(response.content) >= 0 is trivially true — the length of a bytes object is always non-negative, so this assertion never fails regardless of what the server returns. A future refactor that produces an empty body on a 500 would silently pass. The intent is clearly to verify the response carries a body.

Suggested change
# raise_server_exceptions=False -> TestClient returns 500 with body
assert response.status_code == 500
# Some non-status assertion — body should be present
assert len(response.content) >= 0
assert response.headers.get("content-type") is not None
# raise_server_exceptions=False -> TestClient returns 500 with body
assert response.status_code == 500
# Some non-status assertion — body should be present
assert len(response.content) > 0
assert response.headers.get("content-type") is not None

Comment on lines +126 to +130
call_kwargs = prisma.db.litellm_config.upsert.await_args.kwargs
data = call_kwargs["data"]
update_payload = data["update"]["param_value"]
assert '"interval_hours": 12' in update_payload
assert '"force_reload": true' in update_payload

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 These string-literal checks on a JSON-serialized payload are brittle: they rely on json.dumps always emitting a space after the colon (e.g. "interval_hours": 12 vs "interval_hours":12). Python's default serializer does add that space, but any call-site that passes separators or uses a different serializer would break this assertion even though the data is correct. Prefer inspecting the deserialized dict directly.

Suggested change
call_kwargs = prisma.db.litellm_config.upsert.await_args.kwargs
data = call_kwargs["data"]
update_payload = data["update"]["param_value"]
assert '"interval_hours": 12' in update_payload
assert '"force_reload": true' in update_payload
call_kwargs = prisma.db.litellm_config.upsert.await_args.kwargs
data = call_kwargs["data"]
update_payload = data["update"]["param_value"]
import json as _json
parsed = _json.loads(update_payload) if isinstance(update_payload, str) else update_payload
assert parsed["interval_hours"] == 12
assert parsed["force_reload"] is True

Comment on lines +404 to +413


# ---------------------------------------------------------------------------
# POST /config/callback/delete
# ---------------------------------------------------------------------------


def test_config_callback_delete_happy_admin(client, auth_as, mock_prisma, monkeypatch):
"""Admin deletes a configured success callback — handler returns the
success message + remaining callbacks + a timestamp."""

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Overly-permissive status-code assertion weakens the pin

Accepting both 404 and 500 means the test will not catch a regression where the route starts returning a generic 500 instead of a proper 404. The comment explains this accommodates a known ProxyException wrapping issue, but that means the production error-handling path is currently broken for this case. Consider pinning to the actually-observed code, or asserting only 404 and fixing the underlying wrapping.

- test_routes_misc.py: `b"" in response.content` is trivially true;
  replace with `len(response.content) > 0` so an empty 405 body trips
  the gate.
- test_routes_login_sso.py: `len(response.content) >= 0` is trivially
  true; tighten to `> 0`.
- test_routes_anthropic_beta.py: replace brittle string-literal checks
  on the serialized JSON (`'"interval_hours": 12' in payload`) with
  `json.loads` + dict access so the assertion survives any serializer
  spacing.
- test_routes_config.py: `assert status_code in (404, 500)` was too
  permissive; the handler re-raises HTTPException(404) verbatim, so
  pin 404 strictly.
yuneng-berri pushed a commit that referenced this pull request May 26, 2026
Apply the same review feedback Greptile gave on PR1 (#28856) and PR3
(#28850) to PR2's forwarding-route tests:

- Replace permissive `>= 400` / `in (X, Y)` status assertions with the
  exact 500/405 the handler actually returns, so a regression that
  silently shifts the code now fails the pin.
- Add a body-presence check alongside each tightened status assertion
  to satisfy _pin_check.py's no-status-only rule.
yuneng-berri added a commit that referenced this pull request May 29, 2026
* test(proxy): pin proxy_server.py forwarding-route behavior

PR2 of the proxy_server.py behavior-pinning project: fills the 12
forwarding-route test files added by the harness PR with happy + error
pins for all 52 LLM-facing routes (models, chat/completions, completions,
embeddings, moderations, audio, assistants, threads, utils, model-info,
model-metrics, queue). Every happy-path test asserts the full response
dict via normalize() so the gate enforces real shape pinning rather
than status codes.

* test(proxy): drop task-plumbing comments from PR2 test files

* test(proxy): tighten PR2 error-path status-code pins

Apply the same review feedback Greptile gave on PR1 (#28856) and PR3
(#28850) to PR2's forwarding-route tests:

- Replace permissive `>= 400` / `in (X, Y)` status assertions with the
  exact 500/405 the handler actually returns, so a regression that
  silently shifts the code now fails the pin.
- Add a body-presence check alongside each tightened status assertion
  to satisfy _pin_check.py's no-status-only rule.

---------

Co-authored-by: Claude <[email protected]>
@yuneng-berri yuneng-berri changed the base branch from litellm_internal_staging to litellm_yj_may29 May 29, 2026 22:41
@yuneng-berri yuneng-berri merged commit 01ed202 into litellm_yj_may29 May 29, 2026
46 checks passed
@yuneng-berri yuneng-berri deleted the claude/optimistic-wozniak-zhILd branch May 29, 2026 22:41
yuneng-berri added a commit that referenced this pull request May 30, 2026
* test(proxy/proxy_server): pin forwarding routes (PR2) (#28887)

* test(proxy): pin proxy_server.py forwarding-route behavior

PR2 of the proxy_server.py behavior-pinning project: fills the 12
forwarding-route test files added by the harness PR with happy + error
pins for all 52 LLM-facing routes (models, chat/completions, completions,
embeddings, moderations, audio, assistants, threads, utils, model-info,
model-metrics, queue). Every happy-path test asserts the full response
dict via normalize() so the gate enforces real shape pinning rather
than status codes.

* test(proxy): drop task-plumbing comments from PR2 test files

* test(proxy): tighten PR2 error-path status-code pins

Apply the same review feedback Greptile gave on PR1 (#28856) and PR3
(#28850) to PR2's forwarding-route tests:

- Replace permissive `>= 400` / `in (X, Y)` status assertions with the
  exact 500/405 the handler actually returns, so a regression that
  silently shifts the code now fails the pin.
- Add a body-presence check alongside each tightened status assertion
  to satisfy _pin_check.py's no-status-only rule.

---------

Co-authored-by: Claude <[email protected]>

* test(proxy): pin proxy_server.py non-route surface behavior (PR1) (#28856)

* test(proxy): pin proxy_server.py non-route surface behavior (PR1)

Fills the 7 PR1 placeholder files under tests/test_litellm/proxy/proxy_server/
with behavior pins for the non-route surface of proxy_server.py:
lifecycle/init/shutdown, ProxyConfig class methods, DB-overlay config scrubbers,
spend counters, background-health helpers, OpenAPI customization, exception
handlers, and streaming-generator helpers.

233 tests cover 101 pin-list symbols (1+ happy + 1+ error each). New-tests-only
coverage on litellm/proxy/proxy_server.py: 32.80% line / 20.91% branch (PR1
gate: 25% line / 18% branch). Full directory runs in ~22s with -n 4.

Plan: https://www.notion.so/Plan-Pin-proxy_server-py-behavior-2026-05-25-36c43b8acdab81ee845fd5365128a2fc

* test(proxy): address Greptile review comments on test_lifecycle.py

- test_initialize_signature_is_async_with_expected_params: hard-code
  expected_param_count so a signature change actually trips the gate
  (previously both sides of the comparison were len(sig.parameters)).
- test_check_request_disconnection_invalid_when_connected_times_out:
  patch asyncio.sleep so the test no longer spins for ~1.2 s of real
  wall-clock; timeout lowered to 0.05 s.

---------

Co-authored-by: Claude <[email protected]>

* test(proxy/proxy_server): pin control-plane routes (PR3) (#28850)

* test(proxy/proxy_server): pin misc routes (PR3, partial)

Adds happy + error tests for the misc control-plane routes:
GET /, /routes, /adaptive_router/state, /get_logo_url,
/get_image, /get_favicon.

Also gitignores .pin_list.txt (used by the pin gate).

* test(proxy/proxy_server): pin login/SSO routes (PR3, partial)

Adds happy + error tests for the 5 login/SSO control-plane routes:
GET /fallback/login, POST /login, POST /v2/login, POST /v3/login,
POST /v3/login/exchange. Mocks authenticate_user and
create_ui_token_object at their imported location.

* test(proxy/proxy_server): pin onboarding routes (PR3, partial)

Adds happy + error tests for the 2 onboarding control-plane routes:
GET /onboarding/get_token, POST /onboarding/claim_token. Wires a
MagicMock async context manager for prisma_client.db.tx() and
signs the onboarding JWT with the patched master_key.

* test(proxy/proxy_server): pin model_cost_map reload routes (PR3, partial)

Adds happy + error tests for the 5 model-cost-map control-plane routes:
POST /reload/model_cost_map, POST|DELETE|GET
/schedule/model_cost_map_reload(/status), GET /model/cost_map/source.
Attaches litellm_config to mock_prisma per-test (the table is not in
the default _PRISMA_TABLES fixture).

* test(proxy/proxy_server): pin anthropic_beta_headers reload routes (PR3, partial)

Adds happy + error tests for the 4 anthropic-beta-headers control-plane
routes: POST /reload/anthropic_beta_headers, POST|DELETE|GET
/schedule/anthropic_beta_headers_reload(/status). Stubs
db.litellm_config (not in default _PRISMA_TABLES) and monkeypatches
reload_beta_headers_config so no network calls fire.

* test(proxy/proxy_server): pin invitation routes (PR3, partial)

Adds happy + error tests for the 4 invitation control-plane routes:
POST /invitation/new, GET /invitation/info, POST /invitation/update,
POST /invitation/delete. Patches _user_has_admin_privileges /
_user_has_admin_view to avoid extensive get_user_object mocking.

* test(proxy/proxy_server): pin config CRUD routes (PR3, partial)

Adds happy + error tests for the 8 config-CRUD control-plane routes:
POST /config/update, POST|GET /config/field/update|info, GET /config/list,
POST /config/field/delete, POST /config/callback/delete,
GET /get/config/callbacks, GET /config/yaml. Attaches litellm_config
to mock_prisma per-test.

* test(proxy/proxy_server): tighten pin assertions per review

- test_routes_misc.py: `b"" in response.content` is trivially true;
  replace with `len(response.content) > 0` so an empty 405 body trips
  the gate.
- test_routes_login_sso.py: `len(response.content) >= 0` is trivially
  true; tighten to `> 0`.
- test_routes_anthropic_beta.py: replace brittle string-literal checks
  on the serialized JSON (`'"interval_hours": 12' in payload`) with
  `json.loads` + dict access so the assertion survives any serializer
  spacing.
- test_routes_config.py: `assert status_code in (404, 500)` was too
  permissive; the handler re-raises HTTPException(404) verbatim, so
  pin 404 strictly.

---------

Co-authored-by: Claude <[email protected]>

---------

Co-authored-by: Claude <[email protected]>
fzowl pushed a commit to fzowl/litellm that referenced this pull request Jun 24, 2026
* test(proxy/proxy_server): pin forwarding routes (PR2) (BerriAI#28887)

* test(proxy): pin proxy_server.py forwarding-route behavior

PR2 of the proxy_server.py behavior-pinning project: fills the 12
forwarding-route test files added by the harness PR with happy + error
pins for all 52 LLM-facing routes (models, chat/completions, completions,
embeddings, moderations, audio, assistants, threads, utils, model-info,
model-metrics, queue). Every happy-path test asserts the full response
dict via normalize() so the gate enforces real shape pinning rather
than status codes.

* test(proxy): drop task-plumbing comments from PR2 test files

* test(proxy): tighten PR2 error-path status-code pins

Apply the same review feedback Greptile gave on PR1 (BerriAI#28856) and PR3
(BerriAI#28850) to PR2's forwarding-route tests:

- Replace permissive `>= 400` / `in (X, Y)` status assertions with the
  exact 500/405 the handler actually returns, so a regression that
  silently shifts the code now fails the pin.
- Add a body-presence check alongside each tightened status assertion
  to satisfy _pin_check.py's no-status-only rule.

---------


* test(proxy): pin proxy_server.py non-route surface behavior (PR1) (BerriAI#28856)

* test(proxy): pin proxy_server.py non-route surface behavior (PR1)

Fills the 7 PR1 placeholder files under tests/test_litellm/proxy/proxy_server/
with behavior pins for the non-route surface of proxy_server.py:
lifecycle/init/shutdown, ProxyConfig class methods, DB-overlay config scrubbers,
spend counters, background-health helpers, OpenAPI customization, exception
handlers, and streaming-generator helpers.

233 tests cover 101 pin-list symbols (1+ happy + 1+ error each). New-tests-only
coverage on litellm/proxy/proxy_server.py: 32.80% line / 20.91% branch (PR1
gate: 25% line / 18% branch). Full directory runs in ~22s with -n 4.

Plan: https://www.notion.so/Plan-Pin-proxy_server-py-behavior-2026-05-25-36c43b8acdab81ee845fd5365128a2fc

* test(proxy): address Greptile review comments on test_lifecycle.py

- test_initialize_signature_is_async_with_expected_params: hard-code
  expected_param_count so a signature change actually trips the gate
  (previously both sides of the comparison were len(sig.parameters)).
- test_check_request_disconnection_invalid_when_connected_times_out:
  patch asyncio.sleep so the test no longer spins for ~1.2 s of real
  wall-clock; timeout lowered to 0.05 s.

---------


* test(proxy/proxy_server): pin control-plane routes (PR3) (BerriAI#28850)

* test(proxy/proxy_server): pin misc routes (PR3, partial)

Adds happy + error tests for the misc control-plane routes:
GET /, /routes, /adaptive_router/state, /get_logo_url,
/get_image, /get_favicon.

Also gitignores .pin_list.txt (used by the pin gate).

* test(proxy/proxy_server): pin login/SSO routes (PR3, partial)

Adds happy + error tests for the 5 login/SSO control-plane routes:
GET /fallback/login, POST /login, POST /v2/login, POST /v3/login,
POST /v3/login/exchange. Mocks authenticate_user and
create_ui_token_object at their imported location.

* test(proxy/proxy_server): pin onboarding routes (PR3, partial)

Adds happy + error tests for the 2 onboarding control-plane routes:
GET /onboarding/get_token, POST /onboarding/claim_token. Wires a
MagicMock async context manager for prisma_client.db.tx() and
signs the onboarding JWT with the patched master_key.

* test(proxy/proxy_server): pin model_cost_map reload routes (PR3, partial)

Adds happy + error tests for the 5 model-cost-map control-plane routes:
POST /reload/model_cost_map, POST|DELETE|GET
/schedule/model_cost_map_reload(/status), GET /model/cost_map/source.
Attaches litellm_config to mock_prisma per-test (the table is not in
the default _PRISMA_TABLES fixture).

* test(proxy/proxy_server): pin anthropic_beta_headers reload routes (PR3, partial)

Adds happy + error tests for the 4 anthropic-beta-headers control-plane
routes: POST /reload/anthropic_beta_headers, POST|DELETE|GET
/schedule/anthropic_beta_headers_reload(/status). Stubs
db.litellm_config (not in default _PRISMA_TABLES) and monkeypatches
reload_beta_headers_config so no network calls fire.

* test(proxy/proxy_server): pin invitation routes (PR3, partial)

Adds happy + error tests for the 4 invitation control-plane routes:
POST /invitation/new, GET /invitation/info, POST /invitation/update,
POST /invitation/delete. Patches _user_has_admin_privileges /
_user_has_admin_view to avoid extensive get_user_object mocking.

* test(proxy/proxy_server): pin config CRUD routes (PR3, partial)

Adds happy + error tests for the 8 config-CRUD control-plane routes:
POST /config/update, POST|GET /config/field/update|info, GET /config/list,
POST /config/field/delete, POST /config/callback/delete,
GET /get/config/callbacks, GET /config/yaml. Attaches litellm_config
to mock_prisma per-test.

* test(proxy/proxy_server): tighten pin assertions per review

- test_routes_misc.py: `b"" in response.content` is trivially true;
  replace with `len(response.content) > 0` so an empty 405 body trips
  the gate.
- test_routes_login_sso.py: `len(response.content) >= 0` is trivially
  true; tighten to `> 0`.
- test_routes_anthropic_beta.py: replace brittle string-literal checks
  on the serialized JSON (`'"interval_hours": 12' in payload`) with
  `json.loads` + dict access so the assertion survives any serializer
  spacing.
- test_routes_config.py: `assert status_code in (404, 500)` was too
  permissive; the handler re-raises HTTPException(404) verbatim, so
  pin 404 strictly.

---------


---------
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants