Coverage for tests / unit / utils / test_enrich_doc_urls.py: 100%

66 statements  

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

1"""Tests for _enrich_issues_with_doc_urls orchestration function. 

2 

3Verifies that doc_url enrichment works correctly for all edge cases: 

4tools with/without doc_url support, issues with/without existing URLs, 

5and issues with empty codes. 

6""" 

7 

8from __future__ import annotations 

9 

10from unittest.mock import MagicMock 

11 

12from assertpy import assert_that 

13 

14from lintro.models.core.tool_result import ToolResult 

15from lintro.parsers.base_issue import BaseIssue 

16from lintro.utils.tool_executor import _enrich_issues_with_doc_urls 

17 

18 

19def _make_issue(*, code: str = "", doc_url: str = "") -> BaseIssue: 

20 """Create a BaseIssue with the given code and doc_url. 

21 

22 Args: 

23 code: Rule code for the issue. 

24 doc_url: Pre-existing doc_url value. 

25 

26 Returns: 

27 A BaseIssue instance. 

28 """ 

29 issue = BaseIssue(file="test.py", line=1, message="test") 

30 issue.code = code # type: ignore[attr-defined] 

31 issue.doc_url = doc_url 

32 return issue 

33 

34 

35def test_tool_without_doc_url_method_is_noop() -> None: 

36 """Tools without a doc_url method should not modify issues.""" 

37 tool = MagicMock(spec=[]) # no doc_url attribute 

38 issue = _make_issue(code="E501") 

39 result = ToolResult(name="test", success=False, output="", issues=[issue]) 

40 

41 _enrich_issues_with_doc_urls(tool, result) 

42 

43 assert_that(issue.doc_url).is_empty() 

44 

45 

46def test_result_with_no_issues_is_noop() -> None: 

47 """Results with no issues should not call doc_url.""" 

48 tool = MagicMock() 

49 tool.doc_url.return_value = "https://example.com" 

50 result = ToolResult(name="test", success=True, output="", issues=[]) 

51 

52 _enrich_issues_with_doc_urls(tool, result) 

53 

54 tool.doc_url.assert_not_called() 

55 

56 

57def test_issue_with_existing_doc_url_not_overwritten() -> None: 

58 """Issues that already have a doc_url should be skipped.""" 

59 tool = MagicMock() 

60 tool.doc_url.return_value = "https://new.com" 

61 issue = _make_issue(code="E501", doc_url="https://existing.com") 

62 result = ToolResult(name="test", success=False, output="", issues=[issue]) 

63 

64 _enrich_issues_with_doc_urls(tool, result) 

65 

66 assert_that(issue.doc_url).is_equal_to("https://existing.com") 

67 tool.doc_url.assert_not_called() 

68 

69 

70def test_issue_with_empty_code_skipped() -> None: 

71 """Issues with empty code should not trigger doc_url lookup.""" 

72 tool = MagicMock() 

73 tool.doc_url.return_value = "https://example.com" 

74 issue = _make_issue(code="") 

75 result = ToolResult(name="test", success=False, output="", issues=[issue]) 

76 

77 _enrich_issues_with_doc_urls(tool, result) 

78 

79 assert_that(issue.doc_url).is_empty() 

80 tool.doc_url.assert_not_called() 

81 

82 

83def test_happy_path_doc_url_populated() -> None: 

84 """Issues with a code get their doc_url populated from the tool.""" 

85 tool = MagicMock() 

86 tool.doc_url.return_value = "https://example.com/E501" 

87 issue = _make_issue(code="E501") 

88 result = ToolResult(name="test", success=False, output="", issues=[issue]) 

89 

90 _enrich_issues_with_doc_urls(tool, result) 

91 

92 assert_that(issue.doc_url).is_equal_to("https://example.com/E501") 

93 tool.doc_url.assert_called_once_with("E501") 

94 

95 

96def test_tool_returns_none_leaves_doc_url_empty() -> None: 

97 """When tool.doc_url returns None, issue.doc_url stays empty.""" 

98 tool = MagicMock() 

99 tool.doc_url.return_value = None 

100 issue = _make_issue(code="UNKNOWN") 

101 result = ToolResult(name="test", success=False, output="", issues=[issue]) 

102 

103 _enrich_issues_with_doc_urls(tool, result) 

104 

105 assert_that(issue.doc_url).is_empty() 

106 

107 

108def test_multiple_mixed_issues() -> None: 

109 """Only eligible issues get enriched; others are left unchanged.""" 

110 tool = MagicMock() 

111 tool.doc_url.side_effect = lambda code: f"https://example.com/{code}" 

112 

113 issue_with_url = _make_issue(code="E501", doc_url="https://existing.com") 

114 issue_empty_code = _make_issue(code="") 

115 issue_eligible = _make_issue(code="F401") 

116 

117 result = ToolResult( 

118 name="test", 

119 success=False, 

120 output="", 

121 issues=[issue_with_url, issue_empty_code, issue_eligible], 

122 ) 

123 

124 _enrich_issues_with_doc_urls(tool, result) 

125 

126 assert_that(issue_with_url.doc_url).is_equal_to("https://existing.com") 

127 assert_that(issue_empty_code.doc_url).is_empty() 

128 assert_that(issue_eligible.doc_url).is_equal_to("https://example.com/F401") 

129 tool.doc_url.assert_called_once_with("F401")