Coverage for tests / unit / parsers / gitleaks_parser / test_plugin_parsing.py: 97%

68 statements  

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

1"""Unit tests for GitleaksPlugin parsing integration.""" 

2 

3from __future__ import annotations 

4 

5import json 

6from pathlib import Path 

7from types import SimpleNamespace 

8from typing import Any 

9 

10import pytest 

11from assertpy import assert_that 

12 

13from lintro.models.core.tool_result import ToolResult 

14from lintro.plugins import ToolRegistry 

15 

16 

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

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

19 

20 Args: 

21 cmd: The command list. 

22 

23 Returns: 

24 The report path if found, None otherwise. 

25 """ 

26 try: 

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

28 return cmd[idx + 1] 

29 except (ValueError, IndexError): 

30 return None 

31 

32 

33def test_gitleaks_check_parses_output( 

34 monkeypatch: pytest.MonkeyPatch, 

35 tmp_path: Path, 

36) -> None: 

37 """GitleaksPlugin.check should parse JSON output correctly. 

38 

39 Args: 

40 monkeypatch: Pytest monkeypatch fixture. 

41 tmp_path: Temporary directory path fixture. 

42 """ 

43 p = tmp_path / "secret.py" 

44 p.write_text("API_KEY = 'sk_test_example'\n") 

45 

46 sample = [ 

47 { 

48 "Description": "Generic API Key", 

49 "StartLine": 1, 

50 "EndLine": 1, 

51 "StartColumn": 11, 

52 "EndColumn": 27, 

53 "File": str(p), 

54 "RuleID": "generic-api-key", 

55 "Fingerprint": f"{p}:generic-api-key:1", 

56 }, 

57 ] 

58 

59 def fake_run( 

60 cmd: list[str], 

61 capture_output: bool, 

62 text: bool, 

63 timeout: int, 

64 **kwargs: Any, 

65 ) -> SimpleNamespace: 

66 # Handle version check calls (check for --version flag) 

67 if "--version" in cmd or "version" in cmd: 

68 return SimpleNamespace(stdout="8.30.0", stderr="", returncode=0) 

69 # Handle actual check calls - write JSON to the report file 

70 report_path = _get_report_path(cmd) 

71 if report_path: 

72 Path(report_path).write_text(json.dumps(sample)) 

73 return SimpleNamespace( 

74 stdout="", 

75 stderr="", 

76 returncode=0, 

77 ) 

78 

79 monkeypatch.setattr("subprocess.run", fake_run) 

80 tool = ToolRegistry.get("gitleaks") 

81 assert_that(tool).is_not_none() 

82 

83 result: ToolResult = tool.check([str(tmp_path)], {}) 

84 

85 assert_that(result).is_instance_of(ToolResult) 

86 assert_that(result.name).is_equal_to("gitleaks") 

87 assert_that(result.success).is_true() # success=True means tool ran, not no issues 

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

89 

90 

91def test_gitleaks_check_handles_no_secrets( 

92 monkeypatch: pytest.MonkeyPatch, 

93 tmp_path: Path, 

94) -> None: 

95 """GitleaksPlugin.check should handle clean output. 

96 

97 Args: 

98 monkeypatch: Pytest monkeypatch fixture. 

99 tmp_path: Temporary directory path fixture. 

100 """ 

101 p = tmp_path / "clean.py" 

102 p.write_text("x = 1\n") 

103 

104 def fake_run( 

105 cmd: list[str], 

106 capture_output: bool, 

107 text: bool, 

108 timeout: int, 

109 **kwargs: Any, 

110 ) -> SimpleNamespace: 

111 # Handle version check calls (check for --version flag) 

112 if "--version" in cmd or "version" in cmd: 

113 return SimpleNamespace(stdout="8.30.0", stderr="", returncode=0) 

114 # Handle actual check calls - write empty array to report file 

115 report_path = _get_report_path(cmd) 

116 if report_path: 

117 Path(report_path).write_text("[]") 

118 return SimpleNamespace(stdout="", stderr="", returncode=0) 

119 

120 monkeypatch.setattr("subprocess.run", fake_run) 

121 tool = ToolRegistry.get("gitleaks") 

122 assert_that(tool).is_not_none() 

123 

124 result: ToolResult = tool.check([str(tmp_path)], {}) 

125 

126 assert_that(result.success).is_true() 

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

128 

129 

130def test_gitleaks_check_handles_unparseable_output( 

131 monkeypatch: pytest.MonkeyPatch, 

132 tmp_path: Path, 

133) -> None: 

134 """On unparseable output, GitleaksPlugin.check should fail gracefully. 

135 

136 Args: 

137 monkeypatch: Pytest monkeypatch fixture. 

138 tmp_path: Temporary directory path fixture. 

139 """ 

140 p = tmp_path / "test.py" 

141 p.write_text("x = 1\n") 

142 

143 def fake_run( 

144 cmd: list[str], 

145 capture_output: bool, 

146 text: bool, 

147 timeout: int, 

148 **kwargs: Any, 

149 ) -> SimpleNamespace: 

150 # Handle version check calls (check for --version flag) 

151 if "--version" in cmd or "version" in cmd: 

152 return SimpleNamespace(stdout="8.30.0", stderr="", returncode=0) 

153 # Handle actual check calls - write invalid JSON to report file 

154 report_path = _get_report_path(cmd) 

155 if report_path: 

156 Path(report_path).write_text("not json") 

157 return SimpleNamespace(stdout="", stderr="error", returncode=1) 

158 

159 monkeypatch.setattr("subprocess.run", fake_run) 

160 tool = ToolRegistry.get("gitleaks") 

161 assert_that(tool).is_not_none() 

162 

163 result: ToolResult = tool.check([str(tmp_path)], {}) 

164 

165 assert_that(result).is_instance_of(ToolResult) 

166 assert_that(result.name).is_equal_to("gitleaks") 

167 # Parser raises ValueError for invalid JSON, which is caught and reported as failure 

168 assert_that(result.success).is_false() 

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