Coverage for ingadhoc-odoo-saas-adhoc / saas_provider_upgrade / tests / test_customer_note_generation.py: 100%

95 statements  

« prev     ^ index     » next       coverage.py v7.13.4, created at 2026-03-09 19:24 +0000

1from unittest.mock import patch 

2 

3from odoo import Command 

4 

5from .test_provider_upgrade_base import TestProviderUpgradeCommon 

6 

7 

8class TestCustomerNoteGeneration(TestProviderUpgradeCommon): 

9 """Test customer note generation with placeholders and QWeb variables.""" 

10 

11 @classmethod 

12 def setUpClass(cls): 

13 super().setUpClass() 

14 

15 # Create test request 

16 cls.test_request = cls.env["helpdesk.ticket.upgrade.request"]._create_request(cls.upgrade_ticket.id, "test") 

17 

18 # Create upgrade line with customer note 

19 cls.ul_with_note = cls.env["saas.upgrade.line"].create( 

20 { 

21 "name": "[Test] UL with customer note", 

22 "upgrade_type_ids": [Command.link(cls.upgrade_type.id)], 

23 "type": "4_post", 

24 "state": "approved", 

25 "execution_mode": "odooly", 

26 "add_customer_note": True, 

27 "title": "Test Customer Note", 

28 "message": "<div><p t-out='test_var'/><p t-if='another_var'>Text</p></div>", 

29 "dev_message": "<div><p t-out='test_var'/><p t-if='another_var'>Text</p></div>", 

30 "script": "test_var = 'Test Value'\nanother_var = True", 

31 "adhoc_product_id": cls.env.ref("saas_provider_adhoc.adhoc_product_actualizacion_actualizacion").id, 

32 } 

33 ) 

34 

35 def test_extract_qweb_variables_simple(self): 

36 """Test extraction of QWeb variables from simple template.""" 

37 html = '<div><p t-out="variable1"/></div>' 

38 variables = self.ul_with_note.extract_qweb_variables(html) 

39 self.assertEqual(variables, {"variable1"}) 

40 

41 def test_extract_qweb_variables_multiple(self): 

42 """Test extraction of multiple QWeb variables.""" 

43 html = '<div><p t-out="var1"/><span t-if="var2">Text</span><div t-foreach="var3">Loop</div></div>' 

44 variables = self.ul_with_note.extract_qweb_variables(html) 

45 self.assertEqual(variables, {"var1", "var2", "var3"}) 

46 

47 def test_extract_qweb_variables_no_variables(self): 

48 """Test extraction when no QWeb variables are present.""" 

49 html = "<div><p>Static text</p></div>" 

50 variables = self.ul_with_note.extract_qweb_variables(html) 

51 self.assertEqual(variables, set()) 

52 

53 def test_process_customer_note_with_placeholders(self): 

54 """Test that customer note is generated with placeholders.""" 

55 request = self.test_request 

56 run_info = self.env["saas.upgrade.line.request.run"].create( 

57 { 

58 "upgrade_line_id": self.ul_with_note.id, 

59 "request_id": request.id, 

60 } 

61 ) 

62 

63 # Create eval context with script variables 

64 eval_context = {"test_var": "Test Value", "another_var": True} 

65 

66 # Mock customer note generation 

67 with patch.object(type(self.env["helpdesk.ticket.customer_note"]), "generate") as mock_generate: 

68 self.ul_with_note._process_customer_note(eval_context, request, run_info) 

69 # Verify generate was called with correct parameters 

70 mock_generate.assert_called_once() 

71 args = mock_generate.call_args 

72 self.assertEqual(args[0][0], self.ul_with_note) 

73 self.assertEqual(args[0][1], request) 

74 # Verify placeholders contain expected variables 

75 placeholders = args[0][2] 

76 self.assertIn("test_var", placeholders) 

77 self.assertEqual(placeholders["test_var"], "Test Value") 

78 

79 def test_process_customer_note_test_dev_mode(self): 

80 """Test that in test_dev mode, placeholders are saved to run_info.""" 

81 request = self.test_request.with_context(test_dev=True) 

82 run_info = self.env["saas.upgrade.line.request.run"].create( 

83 { 

84 "upgrade_line_id": self.ul_with_note.id, 

85 "request_id": request.id, 

86 } 

87 ) 

88 

89 # Create eval context with script variables 

90 eval_context = {"test_var": "Test Value", "another_var": True} 

91 

92 # Call __process_customer_note with test_dev context 

93 self.ul_with_note.with_context(test_dev=True)._process_customer_note(eval_context, request, run_info) 

94 

95 # Verify placeholders were saved 

96 placeholders = run_info.placeholders 

97 self.assertTrue(placeholders, "Placeholders should be saved in test_dev mode") 

98 self.assertIsInstance(placeholders, dict) 

99 self.assertIn("test_var", placeholders) 

100 self.assertEqual(placeholders["test_var"], "Test Value") 

101 

102 def test_process_customer_note_empty_vars_generate_called_with_empty_placeholders(self): 

103 """Test that generate is called with empty placeholders when all QWeb vars are falsy. 

104 

105 Validates the bool(v) filter added in commit 45e8f98b: falsy values are excluded from 

106 placeholders, so generate receives {} and render returns "", {} without creating a note. 

107 """ 

108 request = self.test_request 

109 run_info = self.env["saas.upgrade.line.request.run"].create( 

110 { 

111 "upgrade_line_id": self.ul_with_note.id, 

112 "request_id": request.id, 

113 } 

114 ) 

115 

116 # All QWeb vars are empty/falsy 

117 eval_context = {"test_var": "", "another_var": False} 

118 

119 with patch.object(type(self.env["helpdesk.ticket.customer_note"]), "generate") as mock_generate: 

120 self.ul_with_note._process_customer_note(eval_context, request, run_info) 

121 # generate must still be called so it can close existing customer notes 

122 mock_generate.assert_called_once() 

123 args = mock_generate.call_args 

124 # placeholders must be empty because all vars were falsy 

125 self.assertEqual(args[0][2], {}) 

126 

127 def test_process_customer_note_empty_vars_no_note_created(self): 

128 """Test that no customer note record is created when all QWeb vars are falsy. 

129 

130 render() returns '', {} for empty placeholders, so generate() deactivates any 

131 existing note and skips creation of a new one. 

132 """ 

133 request = self.test_request 

134 run_info = self.env["saas.upgrade.line.request.run"].create( 

135 { 

136 "upgrade_line_id": self.ul_with_note.id, 

137 "request_id": request.id, 

138 } 

139 ) 

140 

141 # All QWeb vars are empty/falsy 

142 eval_context = {"test_var": "", "another_var": False} 

143 

144 note_count_before = self.env["helpdesk.ticket.customer_note"].search_count( 

145 [("upgrade_line_id", "=", self.ul_with_note.id)] 

146 ) 

147 self.ul_with_note._process_customer_note(eval_context, request, run_info) 

148 note_count_after = self.env["helpdesk.ticket.customer_note"].search_count( 

149 [("upgrade_line_id", "=", self.ul_with_note.id)] 

150 ) 

151 

152 self.assertEqual( 

153 note_count_before, note_count_after, "No customer note should be created when placeholders are empty" 

154 ) 

155 

156 def test_process_customer_note_test_dev_empty_placeholders(self): 

157 """Test that in test_dev mode, empty placeholders ({}) are saved to run_info when all vars are falsy.""" 

158 request = self.test_request 

159 run_info = self.env["saas.upgrade.line.request.run"].create( 

160 { 

161 "upgrade_line_id": self.ul_with_note.id, 

162 "request_id": request.id, 

163 } 

164 ) 

165 

166 # All QWeb vars are empty/falsy 

167 eval_context = {"test_var": "", "another_var": False} 

168 

169 self.ul_with_note.with_context(test_dev=True)._process_customer_note(eval_context, request, run_info) 

170 

171 # Placeholders should be saved as an empty dict 

172 self.assertFalse(bool(run_info.placeholders), "Placeholders should be empty when all vars are falsy") 

173 

174 def test_process_customer_note_skips_when_message_is_empty(self): 

175 """_process_customer_note should not call generate when message is empty/falsy.""" 

176 request = self.test_request 

177 ul_no_message = self.env["saas.upgrade.line"].create( 

178 { 

179 "name": "[Test] UL with no message", 

180 "upgrade_type_ids": [Command.link(self.upgrade_type.id)], 

181 "type": "4_post", 

182 "state": "approved", 

183 "add_customer_note": True, 

184 "message": False, # empty message 

185 "adhoc_product_id": self.env.ref("saas_provider_adhoc.adhoc_product_actualizacion_actualizacion").id, 

186 } 

187 ) 

188 run_info = self.env["saas.upgrade.line.request.run"].create( 

189 { 

190 "upgrade_line_id": ul_no_message.id, 

191 "request_id": request.id, 

192 } 

193 ) 

194 eval_context = {"some_var": "value"} 

195 

196 with patch.object(type(self.env["helpdesk.ticket.customer_note"]), "generate") as mock_generate: 

197 ul_no_message._process_customer_note(eval_context, request, run_info) 

198 mock_generate.assert_not_called() 

199 

200 def test_customer_note_reopen_when_force_true(self): 

201 """When `force_reopen_customer_note` is True and placeholders change, CN reopens to 'ongoing'.""" 

202 request = self.test_request 

203 # Create UL with force_reopen True 

204 ul = self.env["saas.upgrade.line"].create( 

205 { 

206 "name": "[Test] UL force reopen", 

207 "upgrade_type_ids": [Command.link(self.upgrade_type.id)], 

208 "type": "4_post", 

209 "state": "approved", 

210 "execution_mode": "odooly", 

211 "add_customer_note": True, 

212 "force_reopen_customer_note": True, 

213 "title": "CN Force", 

214 "message": "<div><p t-out='var'/></div>", 

215 "adhoc_product_id": self.env.ref("saas_provider_adhoc.adhoc_product_actualizacion_actualizacion").id, 

216 } 

217 ) 

218 

219 # First generation 

220 self.env["helpdesk.ticket.customer_note"].generate(ul, request, {"var": "A"}) 

221 cn = self.env["helpdesk.ticket.customer_note"].search( 

222 [("ticket_id", "=", request.ticket_id.id), ("upgrade_line_id", "=", ul.id)], limit=1 

223 ) 

224 self.assertTrue(cn) 

225 self.assertEqual(cn.status, "ongoing") 

226 

227 # Customer marks as done 

228 cn.status = "done" 

229 

230 # Generate again with changed placeholder -> should reopen to ongoing 

231 self.env["helpdesk.ticket.customer_note"].generate(ul, request, {"var": "B"}) 

232 self.assertEqual(cn.status, "ongoing") 

233 

234 def test_customer_note_keeps_done_when_force_false(self): 

235 """When `force_reopen_customer_note` is False and placeholders change, CN keeps 'done'.""" 

236 request = self.test_request 

237 # Create UL with force_reopen False 

238 ul = self.env["saas.upgrade.line"].create( 

239 { 

240 "name": "[Test] UL no force reopen", 

241 "upgrade_type_ids": [Command.link(self.upgrade_type.id)], 

242 "type": "4_post", 

243 "state": "approved", 

244 "execution_mode": "odooly", 

245 "add_customer_note": True, 

246 "force_reopen_customer_note": False, 

247 "title": "CN No Force", 

248 "message": "<div><p t-out='var'/></div>", 

249 "adhoc_product_id": self.env.ref("saas_provider_adhoc.adhoc_product_actualizacion_actualizacion").id, 

250 } 

251 ) 

252 

253 # First generation 

254 self.env["helpdesk.ticket.customer_note"].generate(ul, request, {"var": "A"}) 

255 cn = self.env["helpdesk.ticket.customer_note"].search( 

256 [("ticket_id", "=", request.ticket_id.id), ("upgrade_line_id", "=", ul.id)], limit=1 

257 ) 

258 self.assertTrue(cn) 

259 self.assertEqual(cn.status, "ongoing") 

260 

261 # Customer marks as done 

262 cn.status = "done" 

263 

264 # Generate again with changed placeholder -> should remain done 

265 self.env["helpdesk.ticket.customer_note"].generate(ul, request, {"var": "B"}) 

266 self.assertEqual(cn.status, "done")