Skip to content

Commit c7b7b44

Browse files
committed
✨ User management: Model list needs tenant isolation (unit test)
1 parent f968d98 commit c7b7b44

1 file changed

Lines changed: 7 additions & 21 deletions

File tree

test/backend/services/test_model_management_service.py

Lines changed: 7 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -287,27 +287,18 @@ async def _clear_model_memories(**kwargs):
287287
nexent_memory_mod.clear_model_memories = _clear_model_memories
288288
sys.modules["nexent.memory.memory_service"] = nexent_memory_mod
289289

290-
# Stub services.tenant_service required by list_models_for_admin
290+
# Stub services.tenant_service required by list_models_for_admin BEFORE any imports
291291
services_tenant_mod = types.ModuleType("services.tenant_service")
292292

293293

294294
def _get_tenant_info(tenant_id):
295+
"""Mock implementation of get_tenant_info for testing."""
295296
return {"tenant_name": "Test Tenant"}
296297

297298

298299
services_tenant_mod.get_tenant_info = _get_tenant_info
299300
sys.modules["services.tenant_service"] = services_tenant_mod
300301

301-
# Also stub the backend-level import path
302-
backend_services_tenant_mod = types.ModuleType("backend.services.tenant_service")
303-
backend_services_tenant_mod.get_tenant_info = _get_tenant_info
304-
sys.modules["backend.services.tenant_service"] = backend_services_tenant_mod
305-
306-
# Stub parent 'services' package to prevent attribute access error
307-
services_pkg = types.ModuleType("services")
308-
services_pkg.tenant_service = services_tenant_mod
309-
sys.modules["services"] = services_pkg
310-
311302

312303
def import_svc():
313304
"""Import service under MinioClient patch to avoid real initialization."""
@@ -1130,8 +1121,7 @@ async def test_list_models_for_admin_success():
11301121

11311122
with mock.patch.object(svc, "get_model_records", return_value=records), \
11321123
mock.patch.object(svc, "add_repo_to_name", side_effect=lambda model_repo, model_name: f"{model_repo}/{model_name}" if model_repo else model_name), \
1133-
mock.patch.object(svc.ModelConnectStatusEnum, "get_value", side_effect=lambda s: s or "not_detected"), \
1134-
mock.patch.object(svc, "get_tenant_info", return_value={"tenant_name": "Test Tenant"}):
1124+
mock.patch.object(svc.ModelConnectStatusEnum, "get_value", side_effect=lambda s: s or "not_detected"):
11351125
out = await svc.list_models_for_admin("t1")
11361126
assert out["tenant_id"] == "t1"
11371127
assert out["tenant_name"] == "Test Tenant"
@@ -1155,8 +1145,7 @@ async def test_list_models_for_admin_with_pagination():
11551145

11561146
with mock.patch.object(svc, "get_model_records", return_value=records), \
11571147
mock.patch.object(svc, "add_repo_to_name", side_effect=lambda model_repo, model_name: f"{model_repo}/{model_name}" if model_repo else model_name), \
1158-
mock.patch.object(svc.ModelConnectStatusEnum, "get_value", side_effect=lambda s: s or "not_detected"), \
1159-
mock.patch.object(svc, "get_tenant_info", return_value={"tenant_name": "Test Tenant"}):
1148+
mock.patch.object(svc.ModelConnectStatusEnum, "get_value", side_effect=lambda s: s or "not_detected"):
11601149
# Page 1, page_size 10
11611150
out = await svc.list_models_for_admin("t1", page=1, page_size=10)
11621151
assert out["page"] == 1
@@ -1191,8 +1180,7 @@ async def test_list_models_for_admin_with_model_type_filter():
11911180

11921181
with mock.patch.object(svc, "get_model_records", return_value=records) as mock_get_records, \
11931182
mock.patch.object(svc, "add_repo_to_name", side_effect=lambda model_repo, model_name: f"{model_repo}/{model_name}" if model_repo else model_name), \
1194-
mock.patch.object(svc.ModelConnectStatusEnum, "get_value", side_effect=lambda s: s or "not_detected"), \
1195-
mock.patch.object(svc, "get_tenant_info", return_value={"tenant_name": "Test Tenant"}):
1183+
mock.patch.object(svc.ModelConnectStatusEnum, "get_value", side_effect=lambda s: s or "not_detected"):
11961184
# Filter by llm
11971185
out = await svc.list_models_for_admin("t1", model_type="llm")
11981186
mock_get_records.assert_called_once_with({"model_type": "llm"}, "t1")
@@ -1204,8 +1192,7 @@ async def test_list_models_for_admin_empty_tenant():
12041192
"""Test list_models_for_tenant handles empty tenant gracefully."""
12051193
svc = import_svc()
12061194

1207-
with mock.patch.object(svc, "get_model_records", return_value=[]), \
1208-
mock.patch.object(svc, "get_tenant_info", return_value={"tenant_name": ""}):
1195+
with mock.patch.object(svc, "get_model_records", return_value=[]):
12091196
out = await svc.list_models_for_admin("t1")
12101197
assert out["tenant_id"] == "t1"
12111198
assert out["tenant_name"] == ""
@@ -1241,8 +1228,7 @@ async def test_list_models_for_admin_type_mapping():
12411228

12421229
with mock.patch.object(svc, "get_model_records", return_value=records), \
12431230
mock.patch.object(svc, "add_repo_to_name", side_effect=lambda model_repo, model_name: f"{model_repo}/{model_name}" if model_repo else model_name), \
1244-
mock.patch.object(svc.ModelConnectStatusEnum, "get_value", side_effect=lambda s: s or "not_detected"), \
1245-
mock.patch.object(svc, "get_tenant_info", return_value={"tenant_name": "Test Tenant"}):
1231+
mock.patch.object(svc.ModelConnectStatusEnum, "get_value", side_effect=lambda s: s or "not_detected"):
12461232
out = await svc.list_models_for_admin("t1")
12471233

12481234
assert len(out["models"]) == 1

0 commit comments

Comments
 (0)