from unittest import TestCase from unittest.mock import patch, Mock, PropertyMock from parameterized import parameterized from samcli.commands.docs.command_context import ( DocsCommandContext, ERROR_MESSAGE, SUCCESS_MESSAGE, CommandImplementation, ) from samcli.commands.docs.exceptions import InvalidDocsCommandException from samcli.lib.docs.browser_configuration import BrowserConfigurationError SUPPORTED_COMMANDS = [ "config", "build", "local", "local invoke", "local start-api", "local start-lambda", "list", "list stack-outputs", "list endpoints", "list resources", "deploy", "remote invoke", "package", "delete", "sync", "publish", "validate", "init", "logs", "traces", ] class TestDocsCommandContext(TestCase): @patch("samcli.commands.docs.command_context.sys.argv", ["sam", "docs", "local", "invoke"]) def test_properties(self) -> None: docs_command_context = DocsCommandContext() self.assertEqual(docs_command_context.base_command, "sam docs") self.assertEqual(docs_command_context.sub_commands, ["local", "invoke"]) self.assertEqual(docs_command_context.sub_command_string, "local invoke") self.assertEqual(docs_command_context.all_commands, SUPPORTED_COMMANDS) def test_get_complete_command_paths(self): docs_command_context = DocsCommandContext() with patch( "samcli.commands.docs.command_context.DocsCommandContext.all_commands", new_callable=PropertyMock ) as mock_all_commands: mock_all_commands.return_value = ["config", "build", "local invoke"] command_paths = docs_command_context.get_complete_command_paths() self.assertEqual(command_paths, ["sam docs config", "sam docs build", "sam docs local invoke"]) @parameterized.expand( [ (["local", "invoke", "--help"], ["local", "invoke"]), (["local", "invoke", "-h"], ["local", "invoke"]), (["build", "--random-args"], ["build"]), ] ) def test_filter_arguments(self, commands, expected): output = DocsCommandContext._filter_arguments(commands) self.assertEqual(output, expected) class TestCommandImplementation(TestCase): @patch("samcli.commands.docs.command_context.echo") @patch("samcli.commands.docs.command_context.Documentation.open_docs") def test_run_command(self, mock_open_docs, mock_echo): command_implementation = CommandImplementation(command="build") command_implementation.run_command() mock_open_docs.assert_called_once() mock_echo.assert_called_once_with(SUCCESS_MESSAGE) @patch("samcli.commands.docs.command_context.echo") @patch("samcli.commands.docs.command_context.Documentation.open_docs") def test_run_command_invalid_command(self, mock_open_docs, mock_echo): with patch( "samcli.commands.docs.command_context.DocsCommandContext.sub_commands", new_callable=PropertyMock ) as mock_sub_commands: with self.assertRaises(InvalidDocsCommandException): mock_sub_commands.return_value = True command_implementation = CommandImplementation(command="not-a-command") command_implementation.run_command() mock_open_docs.assert_not_called() mock_echo.assert_not_called() @patch("samcli.commands.docs.command_context.echo") @patch("samcli.commands.docs.command_context.Documentation") @patch("samcli.commands.docs.command_context.BrowserConfiguration") def test_run_command_no_browser(self, mock_browser_config, mock_documentation, mock_echo): mock_browser = Mock() mock_documentation_object = Mock() mock_documentation_object.open_docs.side_effect = BrowserConfigurationError mock_documentation_object.url = "some-url" mock_documentation_object.sub_commands = [] mock_browser_config.return_value = mock_browser mock_documentation.return_value = mock_documentation_object command_implementation = CommandImplementation(command="build") command_implementation.docs_command = Mock() command_implementation.docs_command.sub_commands = [] command_implementation.run_command() mock_echo.assert_called_once_with(ERROR_MESSAGE.format(URL="some-url"), err=True)