@@ -637,6 +637,32 @@ def test_user_must_confirm_before_saving_component_data(self, editor_for_save_te
637637 validation_mock .assert_called_once ()
638638 mock_save .assert_called_once ()
639639
640+ def test_user_stays_in_component_editor_when_save_fails (self , editor_for_save_tests : ComponentEditorWindowBase ) -> None :
641+ """
642+ The editor window remains open when the save operation fails.
643+
644+ GIVEN: A user attempts to save component configuration
645+ WHEN: The save operation fails due to invalid JSON or filesystem error
646+ THEN: The component editor window should stay open
647+ """
648+ # Arrange: Simulate failed save operation
649+ editor_for_save_tests .validate_data_and_highlight_errors_in_red = MagicMock (return_value = "" )
650+ with (
651+ patch (
652+ "ardupilot_methodic_configurator.frontend_tkinter_component_editor_base."
653+ "ConfirmationPopupWindow.should_display" ,
654+ return_value = False ,
655+ ),
656+ patch .object (editor_for_save_tests , "save_component_json" , return_value = True ) as mock_save ,
657+ patch .object (editor_for_save_tests .root , "destroy" ),
658+ ):
659+ # Act: Trigger on-save handler
660+ editor_for_save_tests .on_save_pressed ()
661+
662+ # Assert: Failed save does not close the window
663+ mock_save .assert_called_once ()
664+ editor_for_save_tests .root .destroy .assert_not_called ()
665+
640666
641667class TestWindowClosingWorkflows :
642668 """Test user workflows for closing the editor window."""
@@ -672,6 +698,34 @@ def test_user_can_save_before_closing_when_prompted(self, editor_for_closing_tes
672698 editor_for_closing_tests .save_component_json .assert_called_once ()
673699 mock_exit .assert_called_once_with (0 )
674700
701+ def test_user_stays_in_component_editor_when_closing_save_fails (
702+ self ,
703+ editor_for_closing_tests : ComponentEditorWindowBase ,
704+ ) -> None :
705+ """
706+ The editor window remains open when closing fails due to a save error.
707+
708+ GIVEN: A user attempts to close the component editor and chooses to save
709+ WHEN: The save operation fails
710+ THEN: The component editor window should remain open and no exit should occur
711+ """
712+ editor_for_closing_tests .save_component_json = MagicMock (return_value = True )
713+ with (
714+ patch (
715+ "ardupilot_methodic_configurator.frontend_tkinter_component_editor_base.messagebox.askyesnocancel" ,
716+ return_value = True ,
717+ ),
718+ patch .object (editor_for_closing_tests .root , "destroy" ),
719+ patch ("ardupilot_methodic_configurator.frontend_tkinter_component_editor_base.sys_exit" ) as mock_exit ,
720+ ):
721+ # Act: Trigger window closing
722+ editor_for_closing_tests .on_closing ()
723+
724+ # Assert: Failed save does not close or exit the application
725+ editor_for_closing_tests .save_component_json .assert_called_once ()
726+ editor_for_closing_tests .root .destroy .assert_not_called ()
727+ mock_exit .assert_not_called ()
728+
675729 def test_user_can_close_without_saving_when_prompted (self , editor_for_closing_tests : ComponentEditorWindowBase ) -> None :
676730 """
677731 User can choose to close without saving when prompted.
@@ -1505,7 +1559,7 @@ def test_user_must_confirm_component_properties_before_save(
15051559 WHEN: The confirmation popup is enabled
15061560 THEN: They should be asked to confirm all properties are correct before saving
15071561 """
1508- editor_for_validation_tests .save_component_json = MagicMock ()
1562+ editor_for_validation_tests .save_component_json = MagicMock (return_value = False )
15091563
15101564 with (
15111565 patch .object (editor_for_validation_tests .root , "destroy" ) as mock_destroy ,
@@ -1530,7 +1584,7 @@ def test_user_can_save_without_confirmation_when_popup_disabled(
15301584 self , editor_for_validation_tests : ComponentEditorWindowBase
15311585 ) -> None :
15321586 """If the confirmation popup is disabled, saving should proceed immediately."""
1533- editor_for_validation_tests .save_component_json = MagicMock ()
1587+ editor_for_validation_tests .save_component_json = MagicMock (return_value = False )
15341588
15351589 with (
15361590 patch .object (editor_for_validation_tests .root , "destroy" ) as mock_destroy ,
0 commit comments