@@ -82,6 +82,8 @@ def _mock_context():
8282 run_agent_stream ,
8383 stop_agent_tasks ,
8484 _resolve_user_tenant_language ,
85+ _apply_duplicate_name_availability_rules ,
86+ _check_single_model_availability ,
8587 )
8688 from consts .model import ExportAndImportAgentInfo , ExportAndImportDataFormat , MCPInfo , AgentRequest
8789
@@ -3968,6 +3970,67 @@ async def test_list_all_agent_info_impl_all_disabled_agents():
39683970 mock_check_tools .assert_not_called ()
39693971
39703972
3973+ def test_apply_duplicate_name_availability_rules_handles_missing_fields ():
3974+ """
3975+ Ensure duplicate detection gracefully handles agents without name/display_name.
3976+ """
3977+ enriched_agents = [
3978+ {
3979+ "raw_agent" : {
3980+ "agent_id" : 1 ,
3981+ "name" : None ,
3982+ "display_name" : None ,
3983+ "create_time" : "2024-01-01T00:00:00" ,
3984+ },
3985+ "unavailable_reasons" : [],
3986+ },
3987+ {
3988+ "raw_agent" : {
3989+ "agent_id" : 2 ,
3990+ "name" : "dup" ,
3991+ "display_name" : None ,
3992+ "create_time" : "2024-01-01T00:00:00" ,
3993+ },
3994+ "unavailable_reasons" : [],
3995+ },
3996+ {
3997+ "raw_agent" : {
3998+ "agent_id" : 3 ,
3999+ "name" : "dup" ,
4000+ "display_name" : None ,
4001+ "create_time" : "2024-02-01T00:00:00" ,
4002+ },
4003+ "unavailable_reasons" : [],
4004+ },
4005+ {
4006+ "raw_agent" : {
4007+ "agent_id" : 4 ,
4008+ "name" : None ,
4009+ "display_name" : "display-dup" ,
4010+ "create_time" : "2024-01-01T00:00:00" ,
4011+ },
4012+ "unavailable_reasons" : [],
4013+ },
4014+ {
4015+ "raw_agent" : {
4016+ "agent_id" : 5 ,
4017+ "name" : None ,
4018+ "display_name" : "display-dup" ,
4019+ "create_time" : "2024-02-01T00:00:00" ,
4020+ },
4021+ "unavailable_reasons" : [],
4022+ },
4023+ ]
4024+
4025+ _apply_duplicate_name_availability_rules (enriched_agents )
4026+
4027+ assert enriched_agents [0 ]["unavailable_reasons" ] == []
4028+ assert "duplicate_name" not in enriched_agents [1 ]["unavailable_reasons" ]
4029+ assert "duplicate_name" in enriched_agents [2 ]["unavailable_reasons" ]
4030+ assert "duplicate_display_name" not in enriched_agents [3 ]["unavailable_reasons" ]
4031+ assert "duplicate_display_name" in enriched_agents [4 ]["unavailable_reasons" ]
4032+
4033+
39714034# ============================================================================
39724035# Tests for Agent Export/Import Integration with model_name fields
39734036# ============================================================================
@@ -5420,3 +5483,60 @@ async def test_resolve_model_quick_config_exception(
54205483 model_label = "Model" ,
54215484 tenant_id = "tenant_011"
54225485 )
5486+
5487+
5488+ def test_check_single_model_availability_no_model_id ():
5489+ reasons = _check_single_model_availability (
5490+ model_id = None ,
5491+ tenant_id = "tenant" ,
5492+ model_cache = {},
5493+ reason_key = "model_unavailable" ,
5494+ )
5495+ assert reasons == []
5496+
5497+
5498+ @patch ("backend.services.agent_service.get_model_by_model_id" )
5499+ def test_check_single_model_availability_fetches_and_handles_missing_model (mock_get_model ):
5500+ model_cache = {}
5501+ mock_get_model .return_value = None
5502+
5503+ reasons = _check_single_model_availability (
5504+ model_id = 123 ,
5505+ tenant_id = "tenant" ,
5506+ model_cache = model_cache ,
5507+ reason_key = "model_unavailable" ,
5508+ )
5509+
5510+ assert reasons == ["model_unavailable" ]
5511+ assert 123 in model_cache
5512+ mock_get_model .assert_called_once_with (123 , "tenant" )
5513+
5514+
5515+ def test_check_single_model_availability_uses_cached_unavailable_model ():
5516+ model_cache = {
5517+ 456 : {"connect_status" : agent_service .ModelConnectStatusEnum .UNAVAILABLE .value }
5518+ }
5519+
5520+ reasons = _check_single_model_availability (
5521+ model_id = 456 ,
5522+ tenant_id = "tenant" ,
5523+ model_cache = model_cache ,
5524+ reason_key = "model_unavailable" ,
5525+ )
5526+
5527+ assert reasons == ["model_unavailable" ]
5528+
5529+
5530+ def test_check_single_model_availability_returns_empty_for_available_model ():
5531+ model_cache = {
5532+ 789 : {"connect_status" : agent_service .ModelConnectStatusEnum .AVAILABLE .value }
5533+ }
5534+
5535+ reasons = _check_single_model_availability (
5536+ model_id = 789 ,
5537+ tenant_id = "tenant" ,
5538+ model_cache = model_cache ,
5539+ reason_key = "model_unavailable" ,
5540+ )
5541+
5542+ assert reasons == []
0 commit comments