1010use PHPUnit \Framework \Attributes \Small ;
1111use PHPUnit \Framework \MockObject \MockObject ;
1212use PHPUnit \Framework \TestCase ;
13- use stdClass ;
13+ use Symfony \ Component \ Console \ Application ;
1414use Symfony \Component \Console \Command \Command ;
1515use Symfony \Component \Console \Input \InputInterface ;
1616use Symfony \Component \Console \Output \OutputInterface ;
@@ -38,15 +38,15 @@ protected function setUp(): void
3838 $ this ->ioMock = $ this ->createMock (SymfonyStyle::class);
3939
4040 $ this ->command = new TestMcpToolCommand ($ this ->containerMock );
41- $ this ->command ->setApplication ($ this ->createMock (\ Symfony \ Component \ Console \ Application::class));
41+ $ this ->command ->setApplication ($ this ->createMock (Application::class));
4242 $ this ->injectPrivateProperty ($ this ->command , 'input ' , $ this ->inputMock );
4343 $ this ->injectPrivateProperty ($ this ->command , 'io ' , $ this ->ioMock );
4444 }
4545
4646 /**
4747 * Tests that an exception is thrown when no tool is provided
4848 */
49- public function test_get_tool_instance_no_tool_provided_throws_exception (): void
49+ public function test_get_tool_instance_no_tool_provided_and_no_tool_configured_throws_exception (): void
5050 {
5151 $ this ->inputMock
5252 ->method ('getArgument ' )
@@ -59,6 +59,32 @@ public function test_get_tool_instance_no_tool_provided_throws_exception(): void
5959 $ this ->invokeGetToolInstanceMethod ();
6060 }
6161
62+ /**
63+ * Tests that an exception is thrown when no tool is provided
64+ */
65+ public function test_get_tool_instance_no_tool_provided_ask_choice_from_configured_tools (): void
66+ {
67+ $ this ->containerMock
68+ ->method ('getParameter ' )
69+ ->with ('klp_mcp_server.tools ' )
70+ ->willReturn ([HelloWorldTool::class]);
71+ $ this ->containerMock
72+ ->method ('get ' )
73+ ->with (HelloWorldTool::class)
74+ ->willReturn (new HelloWorldTool );
75+ $ this ->inputMock
76+ ->method ('getArgument ' )
77+ ->with ('tool ' )
78+ ->willReturn (null );
79+
80+ $ this ->ioMock
81+ ->expects ($ this ->once ())
82+ ->method ('choice ' )
83+ ->with ('Select a tool to test ' , ['hello-world ( ' .HelloWorldTool::class.') ' ]);
84+
85+ $ this ->invokeGetToolInstanceMethod ();
86+ }
87+
6288 /**
6389 * Tests that a tool instance is returned when a valid class name is provided
6490 */
@@ -412,6 +438,12 @@ private function invokePrivateMethod(string $methodName, array $args = []): mixe
412438 */
413439 public function test_list_all_tools_when_no_tools_are_configured_displays_warning (): void
414440 {
441+ $ this ->inputMock
442+ ->expects ($ this ->once ())
443+ ->method ('getOption ' )
444+ ->with ('list ' )
445+ ->willReturn ('list ' );
446+
415447 $ this ->containerMock
416448 ->method ('getParameter ' )
417449 ->with ('klp_mcp_server.tools ' )
@@ -422,14 +454,19 @@ public function test_list_all_tools_when_no_tools_are_configured_displays_warnin
422454 ->method ('warning ' )
423455 ->with ('No MCP tools are configured. Add tools in config/package/klp-mcp-server.yaml ' );
424456
425- $ this ->assertEquals (Command::SUCCESS , $ this ->command ->listAllTools ()) ;
457+ $ this ->assertEquals (Command::SUCCESS , $ this ->command ->execute ( $ this -> inputMock , $ this -> outputMock )); ;
426458 }
427459
428460 /**
429461 * Tests that when valid tools are present, they are displayed in a table.
430462 */
431463 public function test_list_all_tools_when_valid_tools_present_displays_table (): void
432464 {
465+ $ this ->inputMock
466+ ->expects ($ this ->once ())
467+ ->method ('getOption ' )
468+ ->with ('list ' )
469+ ->willReturn ('list ' );
433470 $ tools = [HelloWorldTool::class, VersionCheckTool::class];
434471 $ toolMocks = [
435472 ['name ' => 'Tool1 ' , 'class ' => HelloWorldTool::class, 'description ' => 'This is tool 1 ' ],
@@ -453,14 +490,19 @@ public function test_list_all_tools_when_valid_tools_present_displays_table(): v
453490 ->method ('table ' )
454491 ->with (['Name ' , 'Class ' , 'Description ' ], $ toolMocks );
455492
456- $ this ->assertEquals (Command::SUCCESS , $ this ->command ->listAllTools ( ));
493+ $ this ->assertEquals (Command::SUCCESS , $ this ->command ->execute ( $ this -> inputMock , $ this -> outputMock ));
457494 }
458495
459496 /**
460497 * Tests that when a tool class cannot be loaded, it is gracefully handled.
461498 */
462499 public function test_list_all_tools_handles_tool_loading_exceptions_gracefully (): void
463500 {
501+ $ this ->inputMock
502+ ->expects ($ this ->once ())
503+ ->method ('getOption ' )
504+ ->with ('list ' )
505+ ->willReturn ('list ' );
464506 $ tools = [HelloWorldTool::class];
465507
466508 $ this ->containerMock
@@ -477,7 +519,7 @@ public function test_list_all_tools_handles_tool_loading_exceptions_gracefully()
477519 ->method ('warning ' )
478520 ->with ("Couldn't load tool class: " . HelloWorldTool::class);;
479521
480- $ this ->assertEquals (Command::SUCCESS , $ this ->command ->listAllTools ( ));
522+ $ this ->assertEquals (Command::SUCCESS , $ this ->command ->execute ( $ this -> inputMock , $ this -> outputMock ));
481523 }
482524
483525 /**
@@ -713,4 +755,32 @@ public function test_ask_for_input_data_handle_alpha_for_integer(): void
713755
714756 $ this ->assertEquals ([], $ result );
715757 }
758+
759+ /**
760+ * Tests that askForInputData handles invalid JSON for object property.
761+ */
762+ public function test_ask_for_input_data_handle_alpha_for_required_integer (): void
763+ {
764+ $ schema = [
765+ 'properties ' => [
766+ 'age ' => [
767+ 'type ' => 'integer ' ,
768+ 'description ' => 'How old are you? ' ,
769+ ],
770+ ],
771+ 'required ' => ['age ' ],
772+ ];
773+ $ this ->ioMock
774+ ->method ('ask ' )
775+ ->with ('Value ' , false )
776+ ->willReturn ('twenty ' );
777+ $ this ->ioMock
778+ ->expects ($ this ->once ())
779+ ->method ('warning ' )
780+ ->with ('Required field skipped. Using 0. ' );
781+
782+ $ result = $ this ->command ->askForInputData ($ schema );
783+
784+ $ this ->assertEquals (['age ' => 0 ], $ result );
785+ }
716786}
0 commit comments