Coverage for tests / unit / utils / output / test_file_writer_html.py: 100%

33 statements  

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

1"""Unit tests for write_output_file function - HTML format. 

2 

3Tests verify HTML output structure with proper elements and XSS prevention. 

4""" 

5 

6from __future__ import annotations 

7 

8from pathlib import Path 

9from typing import TYPE_CHECKING 

10 

11from assertpy import assert_that 

12 

13from lintro.enums.action import Action 

14from lintro.enums.output_format import OutputFormat 

15from lintro.utils.output.file_writer import write_output_file 

16 

17if TYPE_CHECKING: 

18 from collections.abc import Callable 

19 

20 from .conftest import MockIssue, MockToolResult 

21 

22 

23def test_write_html_file_creates_valid_structure( 

24 tmp_path: Path, 

25 sample_results_empty: list[MockToolResult], 

26) -> None: 

27 """Verify HTML file contains proper document structure with headers and tables. 

28 

29 Args: 

30 tmp_path: Temporary directory path for test output. 

31 sample_results_empty: Mock tool results with no issues. 

32 """ 

33 output_path = tmp_path / "report.html" 

34 

35 write_output_file( 

36 output_path=str(output_path), 

37 output_format=OutputFormat.HTML, 

38 all_results=sample_results_empty, # type: ignore[arg-type] 

39 action=Action.CHECK, 

40 total_issues=0, 

41 total_fixed=0, 

42 ) 

43 

44 assert_that(output_path.exists()).is_true() 

45 content = output_path.read_text() 

46 

47 assert_that(content).contains("<html>") 

48 assert_that(content).contains("</html>") 

49 assert_that(content).contains("<h1>Lintro Report</h1>") 

50 assert_that(content).contains("<h2>Summary</h2>") 

51 assert_that(content).contains("<table") 

52 

53 

54def test_write_html_file_includes_issue_table( 

55 tmp_path: Path, 

56 sample_results_with_issues: list[MockToolResult], 

57) -> None: 

58 """Verify HTML output includes issues in table cells with proper structure. 

59 

60 Args: 

61 tmp_path: Temporary directory path for test output. 

62 sample_results_with_issues: Mock tool results containing issues. 

63 """ 

64 output_path = tmp_path / "report.html" 

65 

66 write_output_file( 

67 output_path=str(output_path), 

68 output_format=OutputFormat.HTML, 

69 all_results=sample_results_with_issues, # type: ignore[arg-type] 

70 action=Action.CHECK, 

71 total_issues=1, 

72 total_fixed=0, 

73 ) 

74 

75 content = output_path.read_text() 

76 

77 assert_that(content).contains("<td>src/main.py</td>") 

78 assert_that(content).contains("<td>10</td>") 

79 assert_that(content).contains("<td>E001</td>") 

80 assert_that(content).contains("<td>Test error</td>") 

81 

82 

83def test_write_html_file_escapes_xss_characters( 

84 tmp_path: Path, 

85 mock_tool_result_factory: Callable[..., MockToolResult], 

86 mock_issue_factory: Callable[..., MockIssue], 

87) -> None: 

88 """Verify HTML special characters are escaped to prevent XSS vulnerabilities. 

89 

90 Args: 

91 tmp_path: Temporary directory path for test output. 

92 mock_tool_result_factory: Factory for creating mock tool results. 

93 mock_issue_factory: Factory for creating mock issues. 

94 """ 

95 output_path = tmp_path / "report.html" 

96 results = [ 

97 mock_tool_result_factory( 

98 name="<script>alert('xss')</script>", 

99 issues_count=1, 

100 issues=[mock_issue_factory(message="<b>test</b>")], 

101 ), 

102 ] 

103 

104 write_output_file( 

105 output_path=str(output_path), 

106 output_format=OutputFormat.HTML, 

107 all_results=results, # type: ignore[arg-type] 

108 action=Action.CHECK, 

109 total_issues=1, 

110 total_fixed=0, 

111 ) 

112 

113 content = output_path.read_text() 

114 

115 # Script tags should be escaped, not rendered 

116 assert_that(content).does_not_contain("<script>") 

117 assert_that(content).contains("&lt;script&gt;") 

118 assert_that(content).contains("&lt;b&gt;test&lt;/b&gt;")