diff options
Diffstat (limited to 'gitlint-core/gitlint/tests/test_hooks.py')
-rw-r--r-- | gitlint-core/gitlint/tests/test_hooks.py | 139 |
1 files changed, 139 insertions, 0 deletions
diff --git a/gitlint-core/gitlint/tests/test_hooks.py b/gitlint-core/gitlint/tests/test_hooks.py new file mode 100644 index 0000000..7390f14 --- /dev/null +++ b/gitlint-core/gitlint/tests/test_hooks.py @@ -0,0 +1,139 @@ +import os +from unittest.mock import ANY, mock_open, patch + +from gitlint.config import LintConfig +from gitlint.hooks import ( + COMMIT_MSG_HOOK_DST_PATH, + COMMIT_MSG_HOOK_SRC_PATH, + GITLINT_HOOK_IDENTIFIER, + GitHookInstaller, + GitHookInstallerError, +) +from gitlint.tests.base import BaseTestCase + + +class HookTests(BaseTestCase): + @patch("gitlint.hooks.git_hooks_dir") + def test_commit_msg_hook_path(self, git_hooks_dir): + git_hooks_dir.return_value = os.path.join("/föo", "bar") + lint_config = LintConfig() + lint_config.target = self.SAMPLES_DIR + expected_path = os.path.join(git_hooks_dir.return_value, COMMIT_MSG_HOOK_DST_PATH) + path = GitHookInstaller.commit_msg_hook_path(lint_config) + + git_hooks_dir.assert_called_once_with(self.SAMPLES_DIR) + self.assertEqual(path, expected_path) + + @staticmethod + @patch("os.chmod") + @patch("os.stat") + @patch("gitlint.hooks.shutil.copy") + @patch("os.path.exists", return_value=False) + @patch("os.path.isdir", return_value=True) + @patch("gitlint.hooks.git_hooks_dir") + def test_install_commit_msg_hook(git_hooks_dir, isdir, path_exists, copy, stat, chmod): + lint_config = LintConfig() + lint_config.target = os.path.join("/hür", "dur") + git_hooks_dir.return_value = os.path.join("/föo", "bar", ".git", "hooks") + expected_dst = os.path.join(git_hooks_dir.return_value, COMMIT_MSG_HOOK_DST_PATH) + GitHookInstaller.install_commit_msg_hook(lint_config) + isdir.assert_called_with(git_hooks_dir.return_value) + path_exists.assert_called_once_with(expected_dst) + copy.assert_called_once_with(COMMIT_MSG_HOOK_SRC_PATH, expected_dst) + stat.assert_called_once_with(expected_dst) + chmod.assert_called_once_with(expected_dst, ANY) + git_hooks_dir.assert_called_with(lint_config.target) + + @patch("gitlint.hooks.shutil.copy") + @patch("os.path.exists", return_value=False) + @patch("os.path.isdir", return_value=True) + @patch("gitlint.hooks.git_hooks_dir") + def test_install_commit_msg_hook_negative(self, git_hooks_dir, isdir, path_exists, copy): + lint_config = LintConfig() + lint_config.target = os.path.join("/hür", "dur") + git_hooks_dir.return_value = os.path.join("/föo", "bar", ".git", "hooks") + # mock that current dir is not a git repo + isdir.return_value = False + expected_msg = f"{lint_config.target} is not a git repository." + with self.assertRaisesMessage(GitHookInstallerError, expected_msg): + GitHookInstaller.install_commit_msg_hook(lint_config) + + isdir.assert_called_with(git_hooks_dir.return_value) + path_exists.assert_not_called() + copy.assert_not_called() + + # mock that there is already a commit hook present + isdir.return_value = True + path_exists.return_value = True + expected_dst = os.path.join(git_hooks_dir.return_value, COMMIT_MSG_HOOK_DST_PATH) + expected_msg = ( + f"There is already a commit-msg hook file present in {expected_dst}.\n" + "gitlint currently does not support appending to an existing commit-msg file." + ) + with self.assertRaisesMessage(GitHookInstallerError, expected_msg): + GitHookInstaller.install_commit_msg_hook(lint_config) + + @staticmethod + @patch("os.remove") + @patch("os.path.exists", return_value=True) + @patch("os.path.isdir", return_value=True) + @patch("gitlint.hooks.git_hooks_dir") + def test_uninstall_commit_msg_hook(git_hooks_dir, isdir, path_exists, remove): + lint_config = LintConfig() + git_hooks_dir.return_value = os.path.join("/föo", "bar", ".git", "hooks") + lint_config.target = os.path.join("/hür", "dur") + read_data = "#!/bin/sh\n" + GITLINT_HOOK_IDENTIFIER + with patch("builtins.open", mock_open(read_data=read_data), create=True): + GitHookInstaller.uninstall_commit_msg_hook(lint_config) + + expected_dst = os.path.join(git_hooks_dir.return_value, COMMIT_MSG_HOOK_DST_PATH) + isdir.assert_called_with(git_hooks_dir.return_value) + path_exists.assert_called_once_with(expected_dst) + remove.assert_called_with(expected_dst) + git_hooks_dir.assert_called_with(lint_config.target) + + @patch("os.remove") + @patch("os.path.exists", return_value=True) + @patch("os.path.isdir", return_value=True) + @patch("gitlint.hooks.git_hooks_dir") + def test_uninstall_commit_msg_hook_negative(self, git_hooks_dir, isdir, path_exists, remove): + lint_config = LintConfig() + lint_config.target = os.path.join("/hür", "dur") + git_hooks_dir.return_value = os.path.join("/föo", "bar", ".git", "hooks") + + # mock that the current directory is not a git repo + isdir.return_value = False + expected_msg = f"{lint_config.target} is not a git repository." + with self.assertRaisesMessage(GitHookInstallerError, expected_msg): + GitHookInstaller.uninstall_commit_msg_hook(lint_config) + + isdir.assert_called_with(git_hooks_dir.return_value) + path_exists.assert_not_called() + remove.assert_not_called() + + # mock that there is no commit hook present + isdir.return_value = True + path_exists.return_value = False + expected_dst = os.path.join(git_hooks_dir.return_value, COMMIT_MSG_HOOK_DST_PATH) + expected_msg = f"There is no commit-msg hook present in {expected_dst}." + with self.assertRaisesMessage(GitHookInstallerError, expected_msg): + GitHookInstaller.uninstall_commit_msg_hook(lint_config) + + isdir.assert_called_with(git_hooks_dir.return_value) + path_exists.assert_called_once_with(expected_dst) + remove.assert_not_called() + + # mock that there is a different (=not gitlint) commit hook + isdir.return_value = True + path_exists.return_value = True + read_data = "#!/bin/sh\nfoo" + expected_dst = os.path.join(git_hooks_dir.return_value, COMMIT_MSG_HOOK_DST_PATH) + expected_msg = ( + f"The commit-msg hook in {expected_dst} was not installed by gitlint " + "(or it was modified).\nUninstallation of 3th party or modified gitlint hooks " + "is not supported." + ) + with patch("builtins.open", mock_open(read_data=read_data), create=True): + with self.assertRaisesMessage(GitHookInstallerError, expected_msg): + GitHookInstaller.uninstall_commit_msg_hook(lint_config) + remove.assert_not_called() |