diff --git a/src/octoprint/filemanager/__init__.py b/src/octoprint/filemanager/__init__.py index b9b5030e..284864fb 100644 --- a/src/octoprint/filemanager/__init__.py +++ b/src/octoprint/filemanager/__init__.py @@ -12,7 +12,6 @@ import octoprint.plugin import octoprint.util from octoprint.events import eventManager, Events -from octoprint.settings import settings from .destinations import FileDestinations from .analysis import QueueEntry, AnalysisQueue @@ -176,7 +175,8 @@ class FileManager(object): self._progress_plugins = [] self._preprocessor_hooks = dict() - self._recovery_file = os.path.join(settings().getBaseFolder("data"), "print_recovery_data.yaml") + import octoprint.settings + self._recovery_file = os.path.join(octoprint.settings.settings().getBaseFolder("data"), "print_recovery_data.yaml") def initialize(self): self.reload_plugins() diff --git a/tests/filemanager/test_filemanager.py b/tests/filemanager/test_filemanager.py index 68d49ecd..e7e3cc21 100644 --- a/tests/filemanager/test_filemanager.py +++ b/tests/filemanager/test_filemanager.py @@ -13,6 +13,8 @@ import mock import octoprint.filemanager import octoprint.filemanager.util +import octoprint.settings + class FilemanagerMethodTest(unittest.TestCase): def setUp(self): @@ -124,6 +126,15 @@ class FileManagerTest(unittest.TestCase): self.plugin_manager_patcher = mock.patch("octoprint.plugin.plugin_manager") self.plugin_manager = self.plugin_manager_patcher.start() + # mock settings + self.settings_patcher = mock.patch("octoprint.settings.settings") + self.settings_getter = self.settings_patcher.start() + + self.settings = mock.create_autospec(octoprint.settings.Settings) + self.settings.getBaseFolder.return_value = "/path/to/a/base_folder" + + self.settings_getter.return_value = self.settings + self.analysis_queue = mock.MagicMock(spec=octoprint.filemanager.AnalysisQueue) self.slicing_manager = mock.MagicMock(spec=octoprint.slicing.SlicingManager) @@ -141,6 +152,7 @@ class FileManagerTest(unittest.TestCase): def cleanUp(self): self.event_manager_patcher.stop() self.plugin_manager_patcher.stop() + self.settings_patcher.stop() def test_add_file(self): wrapper = object() @@ -192,6 +204,129 @@ class FileManagerTest(unittest.TestCase): self.file_manager.remove_folder(octoprint.filemanager.FileDestinations.LOCAL, "test_folder", recursive=False) self.local_storage.remove_folder.assert_called_once_with("test_folder", recursive=False) + @mock.patch("octoprint.util.atomic_write", create=True) + @mock.patch("yaml.safe_dump", create=True) + @mock.patch("time.time") + def test_save_recovery_data(self, mock_time, mock_yaml_safe_dump, mock_atomic_write): + import os + + now = 123456789 + path = "some_file.gco" + pos = 1234 + recovery_file = os.path.join("/path/to/a/base_folder", "print_recovery_data.yaml") + + mock_atomic_write.return_value = mock.MagicMock(spec=file) + mock_atomic_write_handle = mock_atomic_write.return_value.__enter__.return_value + mock_time.return_value = now + self.local_storage.path_in_storage.return_value = path + + self.file_manager.save_recovery_data(octoprint.filemanager.FileDestinations.LOCAL, path, pos) + + expected = dict(origin=octoprint.filemanager.FileDestinations.LOCAL, + path=path, + pos=pos, + date=now) + + + mock_atomic_write.assert_called_with(recovery_file) + mock_yaml_safe_dump.assert_called_with(expected, stream=mock_atomic_write_handle, default_flow_style=False, indent=" ", allow_unicode=True) + + @mock.patch("octoprint.util.atomic_write", create=True) + @mock.patch("yaml.safe_dump", create=True) + @mock.patch("time.time") + def test_save_recovery_data(self, mock_time, mock_yaml_safe_dump, mock_atomic_write): + import os + + now = 123456789 + path = "some_file.gco" + pos = 1234 + recovery_file = os.path.join("/path/to/a/base_folder", "print_recovery_data.yaml") + + mock_atomic_write.return_value = mock.MagicMock(spec=file) + mock_atomic_write_handle = mock_atomic_write.return_value.__enter__.return_value + mock_time.return_value = now + self.local_storage.path_in_storage.return_value = path + + mock_yaml_safe_dump.side_effect = RuntimeError + + self.file_manager.save_recovery_data(octoprint.filemanager.FileDestinations.LOCAL, path, pos) + + @mock.patch("os.path.isfile") + @mock.patch("os.remove") + def test_delete_recovery_data(self, mock_remove, mock_isfile): + import os + recovery_file = os.path.join("/path/to/a/base_folder", "print_recovery_data.yaml") + + mock_isfile.return_value = True + + self.file_manager.delete_recovery_data() + + mock_remove.assert_called_with(recovery_file) + + @mock.patch("os.path.isfile") + @mock.patch("os.remove") + def test_delete_recovery_data_no_file(self, mock_remove, mock_isfile): + mock_isfile.return_value = False + + self.file_manager.delete_recovery_data() + + self.assertFalse(mock_remove.called) + + @mock.patch("os.path.isfile") + @mock.patch("os.remove") + def test_delete_recovery_data_error(self, mock_remove, mock_isfile): + mock_isfile.return_value = True + mock_remove.side_effect = RuntimeError + + self.file_manager.delete_recovery_data() + + @mock.patch("os.path.isfile") + @mock.patch("yaml.safe_load") + def test_get_recovery_data(self, mock_yaml_safe_load, mock_isfile): + import os + recovery_file = os.path.join("/path/to/a/base_folder", "print_recovery_data.yaml") + + mock_isfile.return_value = True + + data = dict(path="some_path.gco", + origin="local", + pos=1234, + date=123456789) + mock_yaml_safe_load.return_value = data + + with mock.patch("__builtin__.open", mock.mock_open(read_data=data), create=True) as m: + result = self.file_manager.get_recovery_data() + + self.assertDictEqual(data, result) + + m.assert_called_with(recovery_file) + + mock_handle = m() + mock_yaml_safe_load.assert_called_with(mock_handle) + + @mock.patch("os.path.isfile") + def test_get_recovery_data_no_file(self, mock_isfile): + mock_isfile.return_value = False + + result = self.file_manager.get_recovery_data() + + self.assertIsNone(result) + + @mock.patch("os.path.isfile") + @mock.patch("yaml.safe_load") + @mock.patch("os.remove") + def test_get_recovery_data_broken_file(self, mock_remove, mock_yaml_safe_load, mock_isfile): + import os + recovery_file = os.path.join("/path/to/a/base_folder", "print_recovery_data.yaml") + + mock_isfile.return_value = True + mock_yaml_safe_load.side_effect = RuntimeError + + result = self.file_manager.get_recovery_data() + + self.assertIsNone(result) + mock_remove.assert_called_with(recovery_file) + def test_get_metadata(self): expected = dict(key="value") self.local_storage.get_metadata.return_value = expected