Coverage for intelligence_toolkit/tests/unit/anonymize_case_data/test_visuals.py: 100%

171 statements  

« prev     ^ index     » next       coverage.py v7.10.7, created at 2025-10-16 13:41 -0300

1# Copyright (c) 2024 Microsoft Corporation. All rights reserved. 

2# Licensed under the MIT license. See LICENSE file in the project. 

3 

4import pytest 

5import pandas as pd 

6import plotly.graph_objs as go 

7from intelligence_toolkit.anonymize_case_data.visuals import ( 

8 hsl_to_hex, 

9 hex_to_rgb, 

10 color_to_hsl, 

11 get_bar_chart, 

12 get_line_chart, 

13 get_flow_chart, 

14 print_selections, 

15 color_schemes, 

16) 

17 

18 

19def test_hsl_to_hex_red(): 

20 # Pure red: H=0, S=100, L=50 

21 hex_color = hsl_to_hex(0, 100, 50) 

22 assert hex_color == "#ff0000" 

23 

24 

25def test_hsl_to_hex_blue(): 

26 # Pure blue: H=240, S=100, L=50 

27 hex_color = hsl_to_hex(240, 100, 50) 

28 assert hex_color == "#0000ff" 

29 

30 

31def test_hsl_to_hex_green(): 

32 # Pure green: H=120, S=100, L=50 

33 hex_color = hsl_to_hex(120, 100, 50) 

34 assert hex_color == "#00ff00" 

35 

36 

37def test_hsl_to_hex_gray(): 

38 # Gray: S=0, any H, L=50 

39 hex_color = hsl_to_hex(0, 0, 50) 

40 assert hex_color.startswith("#") 

41 assert len(hex_color) == 7 

42 

43 

44def test_hex_to_rgb_red(): 

45 rgb = hex_to_rgb("#ff0000") 

46 assert rgb == (255, 0, 0) 

47 

48 

49def test_hex_to_rgb_blue(): 

50 rgb = hex_to_rgb("#0000ff") 

51 assert rgb == (0, 0, 255) 

52 

53 

54def test_hex_to_rgb_without_hash(): 

55 rgb = hex_to_rgb("00ff00") 

56 assert rgb == (0, 255, 0) 

57 

58 

59def test_hex_to_rgb_mixed(): 

60 rgb = hex_to_rgb("#a1b2c3") 

61 assert rgb == (161, 178, 195) 

62 

63 

64def test_color_to_hsl_from_hex(): 

65 hsl = color_to_hsl("#ff0000") 

66 assert hsl[0] == 0 # Hue for red 

67 assert hsl[1] == 100 # Saturation 

68 assert hsl[2] == 50 # Lightness 

69 

70 

71def test_color_to_hsl_from_rgb(): 

72 hsl = color_to_hsl("rgb(255,0,0)") 

73 assert hsl[0] == 0 # Hue for red 

74 assert hsl[1] == 100 # Saturation 

75 assert hsl[2] == 50 # Lightness 

76 

77 

78def test_color_to_hsl_blue(): 

79 hsl = color_to_hsl("#0000ff") 

80 assert hsl[0] == 240 # Hue for blue 

81 

82 

83def test_get_bar_chart_basic(): 

84 chart_df = pd.DataFrame( 

85 { 

86 "Attribute": ["Color", "Color", "Size"], 

87 "Attribute Value": ["Red", "Blue", "Large"], 

88 "Count": [10, 5, 8], 

89 } 

90 ) 

91 selection = [] 

92 show_attributes = ["Color"] 

93 unit = "record" 

94 width = 800 

95 height = 600 

96 scheme = color_schemes["Plotly"] 

97 

98 fig = get_bar_chart(selection, show_attributes, unit, chart_df, width, height, scheme) 

99 

100 assert isinstance(fig, go.Figure) 

101 assert fig.layout.width == width 

102 assert fig.layout.height == height 

103 

104 

105def test_get_bar_chart_with_selection(): 

106 chart_df = pd.DataFrame( 

107 { 

108 "Attribute": ["Color"], 

109 "Attribute Value": ["Red"], 

110 "Count": [10], 

111 } 

112 ) 

113 selection = [{"attribute": "Size", "value": "Large"}] 

114 show_attributes = [] 

115 unit = "item" 

116 width = 600 

117 height = 400 

118 scheme = color_schemes["D3"] 

119 

120 fig = get_bar_chart(selection, show_attributes, unit, chart_df, width, height, scheme) 

121 

122 assert isinstance(fig, go.Figure) 

123 assert "matching" in fig.layout.title.text.lower() 

124 

125 

126def test_get_bar_chart_empty_unit(): 

127 chart_df = pd.DataFrame( 

128 { 

129 "Attribute": ["Color"], 

130 "Attribute Value": ["Red"], 

131 "Count": [10], 

132 } 

133 ) 

134 selection = [] 

135 show_attributes = [] 

136 unit = "" 

137 width = 800 

138 height = 600 

139 scheme = color_schemes["Plotly"] 

140 

141 fig = get_bar_chart(selection, show_attributes, unit, chart_df, width, height, scheme) 

142 

143 assert isinstance(fig, go.Figure) 

144 

145 

146def test_get_line_chart_basic(): 

147 chart_df = pd.DataFrame( 

148 { 

149 "Year": ["2020", "2020", "2021"], 

150 "Attribute Value": ["Red", "Blue", "Red"], 

151 "Count": [10, 5, 12], 

152 } 

153 ) 

154 selection = [] 

155 series_attributes = ["Color"] 

156 unit = "record" 

157 time_attribute = "Year" 

158 width = 800 

159 height = 600 

160 scheme = color_schemes["Plotly"] 

161 

162 fig = get_line_chart( 

163 selection, series_attributes, unit, chart_df, time_attribute, width, height, scheme 

164 ) 

165 

166 assert isinstance(fig, go.Figure) 

167 assert fig.layout.width == width 

168 assert fig.layout.height == height 

169 

170 

171def test_get_line_chart_with_selection(): 

172 chart_df = pd.DataFrame( 

173 { 

174 "Year": ["2020"], 

175 "Attribute Value": ["Red"], 

176 "Count": [10], 

177 } 

178 ) 

179 selection = [{"attribute": "Size", "value": "Large"}] 

180 series_attributes = ["Color"] 

181 unit = "case" 

182 time_attribute = "Year" 

183 width = 600 

184 height = 400 

185 scheme = color_schemes["Set1"] 

186 

187 fig = get_line_chart( 

188 selection, series_attributes, unit, chart_df, time_attribute, width, height, scheme 

189 ) 

190 

191 assert isinstance(fig, go.Figure) 

192 assert "matching" in fig.layout.title.text.lower() 

193 

194 

195def test_get_flow_chart_basic(): 

196 links_df = pd.DataFrame( 

197 { 

198 "Source": ["A", "B"], 

199 "Target": ["X", "Y"], 

200 "Count": [10, 5], 

201 "Highlight": [2, 1], 

202 "Proportion": [0.2, 0.2], 

203 } 

204 ) 

205 selection = [] 

206 source_attribute = "From" 

207 target_attribute = "To" 

208 highlight_attribute = "" 

209 width = 800 

210 height = 600 

211 unit = "record" 

212 scheme = color_schemes["Plotly"] 

213 

214 fig = get_flow_chart( 

215 links_df, 

216 selection, 

217 source_attribute, 

218 target_attribute, 

219 highlight_attribute, 

220 width, 

221 height, 

222 unit, 

223 scheme, 

224 ) 

225 

226 assert isinstance(fig, go.Figure) 

227 assert fig.layout.width == width 

228 assert fig.layout.height == height 

229 

230 

231def test_get_flow_chart_with_highlight(): 

232 links_df = pd.DataFrame( 

233 { 

234 "Source": ["A"], 

235 "Target": ["X"], 

236 "Count": [10], 

237 "Highlight": [3], 

238 "Proportion": [0.3], 

239 } 

240 ) 

241 selection = [] 

242 source_attribute = "From" 

243 target_attribute = "To" 

244 highlight_attribute = "Status:Active" 

245 width = 1000 

246 height = 700 

247 unit = "case" 

248 scheme = color_schemes["D3"] 

249 

250 fig = get_flow_chart( 

251 links_df, 

252 selection, 

253 source_attribute, 

254 target_attribute, 

255 highlight_attribute, 

256 width, 

257 height, 

258 unit, 

259 scheme, 

260 ) 

261 

262 assert isinstance(fig, go.Figure) 

263 assert "colored by proportion" in fig.layout.title.text.lower() 

264 

265 

266def test_get_flow_chart_with_selection(): 

267 links_df = pd.DataFrame( 

268 { 

269 "Source": ["A"], 

270 "Target": ["X"], 

271 "Count": [10], 

272 "Highlight": [0], 

273 "Proportion": [0.0], 

274 } 

275 ) 

276 selection = [{"attribute": "Color", "value": "Red"}] 

277 source_attribute = "From" 

278 target_attribute = "To" 

279 highlight_attribute = "" 

280 width = 800 

281 height = 600 

282 unit = "" 

283 scheme = color_schemes["Plotly"] 

284 

285 fig = get_flow_chart( 

286 links_df, 

287 selection, 

288 source_attribute, 

289 target_attribute, 

290 highlight_attribute, 

291 width, 

292 height, 

293 unit, 

294 scheme, 

295 ) 

296 

297 assert isinstance(fig, go.Figure) 

298 assert "matching" in fig.layout.title.text.lower() 

299 

300 

301def test_print_selections_single_attribute(): 

302 selection = [ 

303 {"attribute": "Color", "value": "Red"}, 

304 {"attribute": "Color", "value": "Blue"}, 

305 ] 

306 

307 result = print_selections(selection, multiline=False) 

308 

309 assert "Color:" in result 

310 assert "Red" in result 

311 assert "Blue" in result 

312 

313 

314def test_print_selections_multiple_attributes(): 

315 selection = [ 

316 {"attribute": "Color", "value": "Red"}, 

317 {"attribute": "Size", "value": "Large"}, 

318 ] 

319 

320 result = print_selections(selection, multiline=False) 

321 

322 assert "Color:" in result 

323 assert "Size:" in result 

324 assert "Red" in result 

325 assert "Large" in result 

326 

327 

328def test_print_selections_multiline(): 

329 selection = [ 

330 {"attribute": "Color", "value": "Red"}, 

331 {"attribute": "Size", "value": "Large"}, 

332 ] 

333 

334 result = print_selections(selection, multiline=True) 

335 

336 assert "- " in result 

337 assert "\n" in result 

338 

339 

340def test_print_selections_sorted(): 

341 selection = [ 

342 {"attribute": "Color", "value": "Red"}, 

343 {"attribute": "Color", "value": "Blue"}, 

344 ] 

345 

346 result = print_selections(selection, multiline=False) 

347 

348 # Values within same attribute should be sorted 

349 assert "Blue|Red" in result or "Color:Blue|Red" in result 

350 

351 

352def test_color_schemes_available(): 

353 # Test that color schemes are defined 

354 assert "Plotly" in color_schemes 

355 assert "D3" in color_schemes 

356 assert "Set1" in color_schemes 

357 assert len(color_schemes) > 0 

358 

359 

360def test_color_schemes_contain_colors(): 

361 # Test that schemes contain actual color values 

362 for scheme_name, colors in color_schemes.items(): 

363 assert len(colors) > 0 

364 assert isinstance(colors, list)