@@ -340,6 +340,102 @@ def test_update_tool_table_from_scan_tool_list_success(monkeypatch, mock_session
340340
341341 # Function executes successfully without throwing exceptions
342342
343+ def test_update_tool_table_from_scan_tool_list_create_new_tool (monkeypatch , mock_session ):
344+ """Test creating new tool when tool doesn't exist in database"""
345+ session , query = mock_session
346+
347+ # Mock existing tools with different name&source combination
348+ existing_tool = MockToolInfo ()
349+ existing_tool .name = "existing_tool"
350+ existing_tool .source = "existing_source"
351+
352+ mock_all = MagicMock ()
353+ mock_all .return_value = [existing_tool ]
354+ mock_filter = MagicMock ()
355+ mock_filter .all = mock_all
356+ query .filter .return_value = mock_filter
357+
358+ session .add = MagicMock ()
359+
360+ mock_ctx = MagicMock ()
361+ mock_ctx .__enter__ .return_value = session
362+ mock_ctx .__exit__ .return_value = None
363+ monkeypatch .setattr ("backend.database.tool_db.get_db_session" , lambda : mock_ctx )
364+ monkeypatch .setattr ("backend.database.tool_db.filter_property" , lambda data , model : data )
365+
366+ # Create a mock for ToolInfo class constructor
367+ mock_tool_info_instance = MagicMock ()
368+ mock_tool_info_class = MagicMock (return_value = mock_tool_info_instance )
369+ monkeypatch .setattr ("backend.database.tool_db.ToolInfo" , mock_tool_info_class )
370+
371+ # Create a new tool with different name&source that doesn't exist in database
372+ new_tool = MockToolInfo ()
373+ new_tool .name = "new_tool"
374+ new_tool .source = "new_source"
375+ tool_list = [new_tool ]
376+
377+ update_tool_table_from_scan_tool_list ("tenant1" , "user1" , tool_list )
378+
379+ # Verify that session.add was called to add the new tool
380+ session .add .assert_called_once_with (mock_tool_info_instance )
381+ # Verify that ToolInfo constructor was called with correct parameters
382+ expected_call_args = new_tool .__dict__ .copy ()
383+ expected_call_args .update ({
384+ "created_by" : "user1" ,
385+ "updated_by" : "user1" ,
386+ "author" : "tenant1" ,
387+ "is_available" : True
388+ })
389+ mock_tool_info_class .assert_called_once_with (** expected_call_args )
390+
391+ def test_update_tool_table_from_scan_tool_list_create_new_tool_invalid_name (monkeypatch , mock_session ):
392+ """Test creating new tool with invalid name (is_available=False)"""
393+ session , query = mock_session
394+
395+ # Mock existing tools with different name&source combination
396+ existing_tool = MockToolInfo ()
397+ existing_tool .name = "existing_tool"
398+ existing_tool .source = "existing_source"
399+
400+ mock_all = MagicMock ()
401+ mock_all .return_value = [existing_tool ]
402+ mock_filter = MagicMock ()
403+ mock_filter .all = mock_all
404+ query .filter .return_value = mock_filter
405+
406+ session .add = MagicMock ()
407+
408+ mock_ctx = MagicMock ()
409+ mock_ctx .__enter__ .return_value = session
410+ mock_ctx .__exit__ .return_value = None
411+ monkeypatch .setattr ("backend.database.tool_db.get_db_session" , lambda : mock_ctx )
412+ monkeypatch .setattr ("backend.database.tool_db.filter_property" , lambda data , model : data )
413+
414+ # Create a mock for ToolInfo class constructor
415+ mock_tool_info_instance = MagicMock ()
416+ mock_tool_info_class = MagicMock (return_value = mock_tool_info_instance )
417+ monkeypatch .setattr ("backend.database.tool_db.ToolInfo" , mock_tool_info_class )
418+
419+ # Create a new tool with invalid name (contains special characters)
420+ new_tool = MockToolInfo ()
421+ new_tool .name = "invalid-tool-name!" # Contains dash and exclamation mark
422+ new_tool .source = "new_source"
423+ tool_list = [new_tool ]
424+
425+ update_tool_table_from_scan_tool_list ("tenant1" , "user1" , tool_list )
426+
427+ # Verify that session.add was called to add the new tool
428+ session .add .assert_called_once_with (mock_tool_info_instance )
429+ # Verify that ToolInfo constructor was called with is_available=False for invalid name
430+ expected_call_args = new_tool .__dict__ .copy ()
431+ expected_call_args .update ({
432+ "created_by" : "user1" ,
433+ "updated_by" : "user1" ,
434+ "author" : "tenant1" ,
435+ "is_available" : False # Should be False for invalid tool name
436+ })
437+ mock_tool_info_class .assert_called_once_with (** expected_call_args )
438+
343439def test_add_tool_field (monkeypatch , mock_session ):
344440 """Test adding tool field"""
345441 session , query = mock_session
0 commit comments