def test_clean_stale_images(self, original_names, keep_previous): """ Ensure that previously-stored image files are cleaned up according to our custom logic. """ listdir_results = [] expected_deleted_names = [] historical_ctimes = {} fake_ctime = 1458446945 # populate a mock directory (listdir_results) with names of originals and copies # and assign incrementing ctimes to the originals for i, original_name in enumerate(original_names): resized_names = [ '{}__{}x{}.jpg'.format(original_name, *size) for size in TEST_SIZES ] listdir_results += [original_name] + resized_names original_path = '{}/{}'.format(self.field.path_template, original_name) historical_ctimes[original_path] = fake_ctime fake_ctime += 1 # keep track of the file names we expect to be deleted by this logic if i < len(original_names) - (2 if keep_previous else 1): expected_deleted_names += [original_name] + resized_names random.shuffle( listdir_results ) # ensure names / ctimes are encountered in a random order current_name = original_names[-1] if original_names else None field_value = ResizingImageFieldFile(self.model_instance, self.field, current_name) with mock.patch.object(field_value, 'storage') as mock_storage: mock_storage.listdir = mock.Mock(return_value=([], listdir_results)) mock_storage.delete = mock.Mock(return_value=None) mock_storage.modified_time = mock.Mock( side_effect=lambda n: historical_ctimes[n]) field_value.clean_stale_images(keep_previous=keep_previous) expected_deleted_paths = [ '{}/{}'.format(self.field.path_template, name) for name in expected_deleted_names ] actual_deleted_paths = [ args[0][0] for args in mock_storage.delete.call_args_list ] self.assertEqual(sorted(expected_deleted_paths), sorted(actual_deleted_paths))
def test_clean_stale_images(self, original_names, keep_previous): """ Ensure that previously-stored image files are cleaned up according to our custom logic. """ listdir_results = [] expected_deleted_names = [] historical_ctimes = {} fake_ctime = 1458446945 # populate a mock directory (listdir_results) with names of originals and copies # and assign incrementing ctimes to the originals for i, original_name in enumerate(original_names): resized_names = ['{}__{}x{}.jpg'.format(original_name, *size) for size in TEST_SIZES] listdir_results += [original_name] + resized_names original_path = '{}/{}'.format(self.field.path_template, original_name) historical_ctimes[original_path] = fake_ctime fake_ctime += 1 # keep track of the file names we expect to be deleted by this logic if i < len(original_names) - (2 if keep_previous else 1): expected_deleted_names += [original_name] + resized_names random.shuffle(listdir_results) # ensure names / ctimes are encountered in a random order current_name = original_names[-1] if original_names else None field_value = ResizingImageFieldFile(self.model_instance, self.field, current_name) with mock.patch.object(field_value, 'storage') as mock_storage: mock_storage.listdir = mock.Mock(return_value=([], listdir_results)) mock_storage.delete = mock.Mock(return_value=None) mock_storage.modified_time = mock.Mock(side_effect=lambda n: historical_ctimes[n]) field_value.clean_stale_images(keep_previous=keep_previous) expected_deleted_paths = ['{}/{}'.format(self.field.path_template, name) for name in expected_deleted_names] actual_deleted_paths = [args[0][0] for args in mock_storage.delete.call_args_list] self.assertEqual(sorted(expected_deleted_paths), sorted(actual_deleted_paths))