Coverage for tests / unit / tools / gitleaks / test_execution.py: 94%

36 statements  

« prev     ^ index     » next       coverage.py v7.13.0, created at 2026-04-03 18:53 +0000

1"""Unit tests for gitleaks plugin check method execution.""" 

2 

3from __future__ import annotations 

4 

5from pathlib import Path 

6from typing import Any 

7from unittest.mock import patch 

8 

9from assertpy import assert_that 

10 

11from lintro.tools.definitions.gitleaks import GitleaksPlugin 

12 

13 

14def _get_report_path(cmd: list[str]) -> str | None: 

15 """Extract the report path from a gitleaks command. 

16 

17 Args: 

18 cmd: The command list. 

19 

20 Returns: 

21 The report path if found, None otherwise. 

22 """ 

23 try: 

24 idx = cmd.index("--report-path") 

25 return cmd[idx + 1] 

26 except (ValueError, IndexError): 

27 return None 

28 

29 

30def _mock_subprocess_factory(output: str) -> Any: 

31 """Create a mock subprocess function that writes output to the report file. 

32 

33 Args: 

34 output: The JSON output to write to the report file. 

35 

36 Returns: 

37 A callable that can be used as a side_effect for _run_subprocess. 

38 """ 

39 

40 def mock_run(cmd: list[str], **kwargs: Any) -> tuple[bool, str]: 

41 report_path = _get_report_path(cmd) 

42 if report_path: 

43 Path(report_path).write_text(output) 

44 return (True, "") 

45 

46 return mock_run 

47 

48 

49def test_check_with_mocked_subprocess_success( 

50 gitleaks_plugin: GitleaksPlugin, 

51 tmp_path: Path, 

52) -> None: 

53 """Check returns success when no secrets found. 

54 

55 Args: 

56 gitleaks_plugin: The GitleaksPlugin instance to test. 

57 tmp_path: Temporary directory path for test files. 

58 """ 

59 test_file = tmp_path / "test_module.py" 

60 test_file.write_text('"""Test module with no secrets."""\n') 

61 

62 with patch.object( 

63 gitleaks_plugin, 

64 "_run_subprocess", 

65 side_effect=_mock_subprocess_factory("[]"), 

66 ): 

67 result = gitleaks_plugin.check([str(test_file)], {}) 

68 

69 assert_that(result.success).is_true() 

70 assert_that(result.issues_count).is_equal_to(0) 

71 

72 

73def test_check_with_mocked_subprocess_secrets_found( 

74 gitleaks_plugin: GitleaksPlugin, 

75 tmp_path: Path, 

76) -> None: 

77 """Check returns issues when gitleaks finds secrets. 

78 

79 Args: 

80 gitleaks_plugin: The GitleaksPlugin instance to test. 

81 tmp_path: Temporary directory path for test files. 

82 """ 

83 test_file = tmp_path / "test_module.py" 

84 test_file.write_text('API_KEY = "AKIAIOSFODNN7EXAMPLE"\n') 

85 

86 gitleaks_output = """[ 

87 { 

88 "File": "test_module.py", 

89 "StartLine": 1, 

90 "StartColumn": 11, 

91 "EndLine": 1, 

92 "EndColumn": 34, 

93 "RuleID": "aws-access-key-id", 

94 "Description": "AWS Access Key ID", 

95 "Secret": "REDACTED", 

96 "Match": "AKIAIOSFODNN7EXAMPLE", 

97 "Fingerprint": "test_module.py:aws-access-key-id:1", 

98 "Entropy": 3.5 

99 } 

100 ]""" 

101 

102 with patch.object( 

103 gitleaks_plugin, 

104 "_run_subprocess", 

105 side_effect=_mock_subprocess_factory(gitleaks_output), 

106 ): 

107 result = gitleaks_plugin.check([str(test_file)], {}) 

108 

109 assert_that(result.success).is_true() 

110 assert_that(result.issues_count).is_equal_to(1) 

111 assert_that(result.issues).is_not_none() 

112 assert_that(result.issues).is_length(1)