@@ -225,9 +225,108 @@ def test_wizard_onchange_clears_mismatched_registrant(self):
225225 self .assertFalse (wizard .registrant_id )
226226
227227
228+ @tagged ("post_install" , "-at_install" , "cr_ux" )
229+ class TestBatchApprovalWizardBase (TestChangeRequestBase ):
230+ """Tests for batch approval wizard that don't require pending CRs."""
231+
232+ def _create_wizard (self , cr_ids , action_type = "approve" , ** kwargs ):
233+ """Helper to create a batch wizard via create_from_selection."""
234+ result = (
235+ self .env ["spp.cr.batch.approval.wizard" ].with_context (active_ids = cr_ids ).create_from_selection (action_type )
236+ )
237+ wizard = self .env ["spp.cr.batch.approval.wizard" ].browse (result ["res_id" ])
238+ if kwargs :
239+ wizard .write (kwargs )
240+ return wizard
241+
242+ def test_create_from_selection_no_active_ids (self ):
243+ """Test create_from_selection raises error with no active_ids."""
244+ with self .assertRaises (UserError ):
245+ self .env ["spp.cr.batch.approval.wizard" ].create_from_selection ("approve" )
246+
247+ def test_create_from_selection_returns_action (self ):
248+ """Test create_from_selection returns a valid window action."""
249+ cr_type = self .env ["spp.change.request.type" ].search ([], limit = 1 )
250+ if not cr_type :
251+ self .skipTest ("No CR type available" )
252+ draft_cr = self .env ["spp.change.request" ].create (
253+ {"request_type_id" : cr_type .id , "registrant_id" : self .group .id }
254+ )
255+ result = (
256+ self .env ["spp.cr.batch.approval.wizard" ]
257+ .with_context (active_ids = [draft_cr .id ])
258+ .create_from_selection ("approve" )
259+ )
260+ self .assertEqual (result ["type" ], "ir.actions.act_window" )
261+ self .assertEqual (result ["res_model" ], "spp.cr.batch.approval.wizard" )
262+ self .assertEqual (result ["target" ], "new" )
263+ self .assertTrue (result ["res_id" ])
264+
265+ def test_create_from_selection_action_types (self ):
266+ """Test create_from_selection sets action_type correctly."""
267+ cr_type = self .env ["spp.change.request.type" ].search ([], limit = 1 )
268+ if not cr_type :
269+ self .skipTest ("No CR type available" )
270+ draft_cr = self .env ["spp.change.request" ].create (
271+ {"request_type_id" : cr_type .id , "registrant_id" : self .group .id }
272+ )
273+ for action_type in ("approve" , "reject" , "revision" ):
274+ result = (
275+ self .env ["spp.cr.batch.approval.wizard" ]
276+ .with_context (active_ids = [draft_cr .id ])
277+ .create_from_selection (action_type )
278+ )
279+ wizard = self .env ["spp.cr.batch.approval.wizard" ].browse (result ["res_id" ])
280+ self .assertEqual (wizard .action_type , action_type )
281+
282+ def test_error_message_not_pending (self ):
283+ """Test error message for CR not in pending state."""
284+ cr_type = self .env ["spp.change.request.type" ].search ([], limit = 1 )
285+ if not cr_type :
286+ self .skipTest ("No CR type available" )
287+ draft_cr = self .env ["spp.change.request" ].create (
288+ {"request_type_id" : cr_type .id , "registrant_id" : self .group .id }
289+ )
290+ wizard = self ._create_wizard ([draft_cr .id ])
291+ line = wizard .line_ids [0 ]
292+ self .assertFalse (line .can_process )
293+ self .assertIn ("Not pending approval" , line .error_message )
294+
295+ def test_batch_approve_requires_valid_crs (self ):
296+ """Test batch approve fails if no valid CRs."""
297+ cr_type = self .env ["spp.change.request.type" ].search ([], limit = 1 )
298+ if not cr_type :
299+ self .skipTest ("No CR type available" )
300+ draft_cr = self .env ["spp.change.request" ].create (
301+ {"request_type_id" : cr_type .id , "registrant_id" : self .group .id }
302+ )
303+ wizard = self ._create_wizard ([draft_cr .id ])
304+ self .assertEqual (wizard .valid_count , 0 )
305+ with self .assertRaises (UserError ):
306+ wizard .action_confirm ()
307+
308+ def test_batch_wizard_line_removal (self ):
309+ """Test that lines can be removed from a saved wizard."""
310+ cr_type = self .env ["spp.change.request.type" ].search ([], limit = 1 )
311+ if not cr_type :
312+ self .skipTest ("No CR type available" )
313+ crs = self .env ["spp.change.request" ]
314+ for _i in range (3 ):
315+ crs |= self .env ["spp.change.request" ].create (
316+ {"request_type_id" : cr_type .id , "registrant_id" : self .group .id }
317+ )
318+ wizard = self ._create_wizard (crs .ids )
319+ self .assertEqual (len (wizard .line_ids ), 3 )
320+
321+ # Remove one line
322+ wizard .line_ids [0 ].unlink ()
323+ wizard .invalidate_recordset ()
324+ self .assertEqual (len (wizard .line_ids ), 2 )
325+
326+
228327@tagged ("post_install" , "-at_install" , "cr_ux" )
229328class TestBatchApprovalWizard (TestChangeRequestBase ):
230- """Tests for the batch approval wizard."""
329+ """Tests for batch approval wizard that require pending CRs ."""
231330
232331 @classmethod
233332 def setUpClass (cls ):
@@ -237,7 +336,6 @@ def setUpClass(cls):
237336
238337 def setUp (self ):
239338 super ().setUp ()
240- # Create multiple pending CRs for batch testing
241339 cr_type = self .env ["spp.change.request.type" ].search ([("approval_definition_id" , "!=" , False )], limit = 1 )
242340
243341 if not cr_type :
@@ -278,25 +376,6 @@ def test_batch_wizard_counts(self):
278376 # All should be valid if user can approve
279377 self .assertEqual (wizard .total_count , wizard .valid_count + wizard .invalid_count )
280378
281- def test_batch_approve_requires_valid_crs (self ):
282- """Test batch approve fails if no valid CRs."""
283- # Create wizard with draft CR (cannot be approved)
284- cr_type = self .env ["spp.change.request.type" ].search ([], limit = 1 )
285- draft_cr = self .env ["spp.change.request" ].create (
286- {
287- "request_type_id" : cr_type .id ,
288- "registrant_id" : self .group .id ,
289- }
290- )
291-
292- wizard = self ._create_wizard ([draft_cr .id ])
293-
294- # Should have 0 valid CRs
295- self .assertEqual (wizard .valid_count , 0 )
296-
297- with self .assertRaises (UserError ):
298- wizard .action_confirm ()
299-
300379 def test_batch_reject_requires_comment (self ):
301380 """Test batch reject requires a reason."""
302381 wizard = self ._create_wizard (self .pending_crs .ids , action_type = "reject" , comment = "" )
@@ -305,86 +384,25 @@ def test_batch_reject_requires_comment(self):
305384 with self .assertRaises (UserError ):
306385 wizard .action_confirm ()
307386
308- def test_create_from_selection_no_active_ids (self ):
309- """Test create_from_selection raises error with no active_ids."""
310- with self .assertRaises (UserError ):
311- self .env ["spp.cr.batch.approval.wizard" ].create_from_selection ("approve" )
312-
313- def test_create_from_selection_returns_action (self ):
314- """Test create_from_selection returns a valid window action."""
315- result = (
316- self .env ["spp.cr.batch.approval.wizard" ]
317- .with_context (active_ids = self .pending_crs .ids )
318- .create_from_selection ("approve" )
319- )
320- self .assertEqual (result ["type" ], "ir.actions.act_window" )
321- self .assertEqual (result ["res_model" ], "spp.cr.batch.approval.wizard" )
322- self .assertEqual (result ["target" ], "new" )
323- self .assertTrue (result ["res_id" ])
324-
325- def test_create_from_selection_action_types (self ):
326- """Test create_from_selection sets action_type correctly."""
327- for action_type in ("approve" , "reject" , "revision" ):
328- result = (
329- self .env ["spp.cr.batch.approval.wizard" ]
330- .with_context (active_ids = self .pending_crs .ids )
331- .create_from_selection (action_type )
332- )
333- wizard = self .env ["spp.cr.batch.approval.wizard" ].browse (result ["res_id" ])
334- self .assertEqual (wizard .action_type , action_type )
387+ def test_batch_revision_requires_comment (self ):
388+ """Test batch revision requires notes."""
389+ wizard = self ._create_wizard (self .pending_crs .ids , action_type = "revision" , comment = "" )
335390
336- def test_error_message_not_pending (self ):
337- """Test error message for CR not in pending state."""
338- cr_type = self .env ["spp.change.request.type" ].search ([], limit = 1 )
339- draft_cr = self .env ["spp.change.request" ].create (
340- {
341- "request_type_id" : cr_type .id ,
342- "registrant_id" : self .group .id ,
343- }
344- )
345- wizard = self ._create_wizard ([draft_cr .id ])
346- line = wizard .line_ids [0 ]
347- self .assertFalse (line .can_process )
348- self .assertIn ("Not pending approval" , line .error_message )
391+ with self .assertRaises (UserError ):
392+ wizard .action_confirm ()
349393
350- def test_error_message_not_authorized (self ):
351- """Test error message for CR user cannot approve."""
352- # Mix pending + draft CRs to test both error paths
394+ def test_error_message_mixed_crs (self ):
395+ """Test error messages with mix of pending and draft CRs."""
353396 cr_type = self .env ["spp.change.request.type" ].search ([], limit = 1 )
354397 draft_cr = self .env ["spp.change.request" ].create (
355- {
356- "request_type_id" : cr_type .id ,
357- "registrant_id" : self .group .id ,
358- }
398+ {"request_type_id" : cr_type .id , "registrant_id" : self .group .id }
359399 )
360400 wizard = self ._create_wizard (self .pending_crs .ids + [draft_cr .id ])
361- # Should have both valid and invalid lines
362401 self .assertTrue (wizard .total_count > 0 )
363402 invalid_lines = wizard .line_ids .filtered (lambda ln : not ln .can_process )
364403 for line in invalid_lines :
365404 self .assertTrue (line .error_message )
366405
367- def test_batch_revision_requires_comment (self ):
368- """Test batch revision requires notes."""
369- wizard = self ._create_wizard (self .pending_crs .ids , action_type = "revision" , comment = "" )
370-
371- with self .assertRaises (UserError ):
372- wizard .action_confirm ()
373-
374- def test_batch_wizard_line_removal (self ):
375- """Test that lines can be removed from a saved wizard."""
376- wizard = self ._create_wizard (self .pending_crs .ids )
377- initial_count = wizard .total_count
378- self .assertEqual (initial_count , 3 )
379-
380- # Remove one line
381- line_to_remove = wizard .line_ids [0 ]
382- line_to_remove .unlink ()
383-
384- # Count should update
385- wizard .invalidate_recordset ()
386- self .assertEqual (len (wizard .line_ids ), 2 )
387-
388406
389407@tagged ("post_install" , "-at_install" , "cr_ux" )
390408class TestConflictComparisonWizard (TestChangeRequestBase ):
0 commit comments