1212import typer
1313
1414# First-Party
15- from cforge .commands .resources .plugins import plugins_get , plugins_list , plugins_stats
15+ from cforge .commands .resources .plugins import PluginMode , plugins_get , plugins_list , plugins_stats
1616from cforge .common import AuthenticationError , CLIError
17- from tests .conftest import patch_functions
17+ from tests .conftest import invoke_typer_command , patch_functions
1818
1919
2020class TestPluginCommands :
2121 """Tests for plugins commands."""
2222
23+ def test_plugin_mode_enum_is_case_insensitive (self ) -> None :
24+ """Typer Enum choices should accept case-insensitive values."""
25+ assert PluginMode ("EnFoRcE" ) == PluginMode .ENFORCE
26+
27+ def test_plugin_mode_enum_missing_non_string (self ) -> None :
28+ """Non-string values should not be coerced into Enum members."""
29+ assert PluginMode ._missing_ (123 ) is None
30+
31+ def test_plugin_mode_enum_missing_unknown_value (self ) -> None :
32+ """Unknown strings should not be coerced into Enum members."""
33+ assert PluginMode ._missing_ ("nope" ) is None
34+
2335 def test_plugins_list_success (self , mock_console ) -> None :
2436 """Test plugins list command with table output."""
2537 mock_response = {
@@ -37,7 +49,7 @@ def test_plugins_list_success(self, mock_console) -> None:
3749 make_authenticated_request = {"return_value" : mock_response },
3850 print_table = None ,
3951 ) as mocks :
40- plugins_list ( json_output = False )
52+ invoke_typer_command ( plugins_list )
4153 mocks .print_table .assert_called_once ()
4254
4355 def test_plugins_list_json_output (self , mock_console ) -> None :
@@ -49,14 +61,14 @@ def test_plugins_list_json_output(self, mock_console) -> None:
4961 make_authenticated_request = {"return_value" : mock_response },
5062 print_json = None ,
5163 ) as mocks :
52- plugins_list ( json_output = True )
64+ invoke_typer_command ( plugins_list , json_output = True )
5365 mocks .print_json .assert_called_once ()
5466
5567 def test_plugins_list_no_results (self , mock_console ) -> None :
5668 """Test plugins list with no results."""
5769 mock_response = {"plugins" : [], "total" : 0 , "enabled_count" : 0 , "disabled_count" : 0 }
5870 with patch_functions ("cforge.commands.resources.plugins" , get_console = mock_console , make_authenticated_request = {"return_value" : mock_response }):
59- plugins_list ( json_output = False )
71+ invoke_typer_command ( plugins_list )
6072
6173 assert any ("No plugins found" in str (call ) for call in mock_console .print .call_args_list )
6274
@@ -68,7 +80,7 @@ def test_plugins_list_with_filters(self, mock_console) -> None:
6880 make_authenticated_request = {"return_value" : {"plugins" : [], "total" : 0 , "enabled_count" : 0 , "disabled_count" : 0 }},
6981 print_table = None ,
7082 ) as mocks :
71- plugins_list ( search = "pii" , mode = "enforce" , hook = "tool_pre_invoke" , tag = "security" , json_output = False )
83+ invoke_typer_command ( plugins_list , search = "pii" , mode = PluginMode . ENFORCE , hook = "tool_pre_invoke" , tag = "security" )
7284
7385 call_args = mocks .make_authenticated_request .call_args
7486 assert call_args [0 ][0 ] == "GET"
@@ -79,7 +91,7 @@ def test_plugins_list_error(self, mock_console) -> None:
7991 """Test plugins list error handling."""
8092 with patch_functions ("cforge.commands.resources.plugins" , get_console = mock_console , make_authenticated_request = {"side_effect" : Exception ("API error" )}):
8193 with pytest .raises (typer .Exit ):
82- plugins_list ( json_output = False )
94+ invoke_typer_command ( plugins_list )
8395
8496 def test_plugins_get_success (self , mock_console ) -> None :
8597 """Test plugins get command."""
@@ -90,14 +102,14 @@ def test_plugins_get_success(self, mock_console) -> None:
90102 make_authenticated_request = {"return_value" : mock_plugin },
91103 print_json = None ,
92104 ) as mocks :
93- plugins_get ( name = "pii_filter" )
105+ invoke_typer_command ( plugins_get , name = "pii_filter" )
94106 mocks .print_json .assert_called_once ()
95107
96108 def test_plugins_get_error (self , mock_console ) -> None :
97109 """Test plugins get error handling."""
98110 with patch_functions ("cforge.commands.resources.plugins" , get_console = mock_console , make_authenticated_request = {"side_effect" : Exception ("API error" )}):
99111 with pytest .raises (typer .Exit ):
100- plugins_get ( name = "pii_filter" )
112+ invoke_typer_command ( plugins_get , name = "pii_filter" )
101113
102114 def test_plugins_stats_success (self , mock_console ) -> None :
103115 """Test plugins stats command."""
@@ -108,14 +120,14 @@ def test_plugins_stats_success(self, mock_console) -> None:
108120 make_authenticated_request = {"return_value" : mock_stats },
109121 print_json = None ,
110122 ) as mocks :
111- plugins_stats ( )
123+ invoke_typer_command ( plugins_stats )
112124 mocks .print_json .assert_called_once ()
113125
114126 def test_plugins_stats_error (self , mock_console ) -> None :
115127 """Test plugins stats error handling."""
116128 with patch_functions ("cforge.commands.resources.plugins" , get_console = mock_console , make_authenticated_request = {"side_effect" : Exception ("API error" )}):
117129 with pytest .raises (typer .Exit ):
118- plugins_stats ( )
130+ invoke_typer_command ( plugins_stats )
119131
120132 def test_plugins_list_forbidden_shows_permission_hint (self , mock_console ) -> None :
121133 """Test plugins list shows a targeted hint on forbidden/admin failures."""
@@ -125,7 +137,7 @@ def test_plugins_list_forbidden_shows_permission_hint(self, mock_console) -> Non
125137 make_authenticated_request = {"side_effect" : AuthenticationError ("Authentication required but not configured" )},
126138 ):
127139 with pytest .raises (typer .Exit ):
128- plugins_list ( json_output = False )
140+ invoke_typer_command ( plugins_list )
129141
130142 assert any ("Requires admin.plugins permission" in str (call ) for call in mock_console .print .call_args_list )
131143
@@ -137,6 +149,6 @@ def test_plugins_list_not_found_shows_admin_api_hint(self, mock_console) -> None
137149 make_authenticated_request = {"side_effect" : CLIError ("API request failed (404): Not Found" )},
138150 ):
139151 with pytest .raises (typer .Exit ):
140- plugins_list ( json_output = False )
152+ invoke_typer_command ( plugins_list )
141153
142154 assert any ("Admin plugin API unavailable" in str (call ) for call in mock_console .print .call_args_list )
0 commit comments