Skip to content

Commit a745481

Browse files
authored
OP#10323: Never refuse a save because of where the file lies
The destination guard added alongside the s3 upload refused saving an otconfig outside user_source/<prefix>/. Saving should always succeed locally regardless of destination; only whether it also uploads to s3 depends on the project naming a key prefix. Drops GuardSaveDestination and its s3 implementation.
1 parent d93d904 commit a745481

9 files changed

Lines changed: 0 additions & 265 deletions

File tree

‎OTAnalytics/application/save_destination.py‎

Lines changed: 0 additions & 33 deletions
This file was deleted.

‎OTAnalytics/application/use_cases/config.py‎

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
from OTAnalytics.application.datastore import Datastore
44
from OTAnalytics.application.parser.config_parser import ConfigParser
5-
from OTAnalytics.application.save_destination import GuardSaveDestination
65
from OTAnalytics.application.state import ConfigurationFile, CurrentKeyPrefix, FileState
76
from OTAnalytics.application.upload_otconfig import UploadOtconfig
87
from OTAnalytics.application.use_cases.get_current_remark import GetCurrentRemark
@@ -25,15 +24,13 @@ def __init__(
2524
get_current_remark: GetCurrentRemark,
2625
current_key_prefix: CurrentKeyPrefix,
2726
otconfig_upload: UploadOtconfig,
28-
guard_save_destination: GuardSaveDestination,
2927
) -> None:
3028
self._datastore = datastore
3129
self._config_parser = config_parser
3230
self._state = state
3331
self._get_current_remark = get_current_remark
3432
self._current_key_prefix = current_key_prefix
3533
self._otconfig_upload = otconfig_upload
36-
self._guard_save_destination = guard_save_destination
3734

3835
async def __call__(self, file: Path) -> None:
3936
project = self._datastore.project
@@ -56,8 +53,6 @@ async def __call__(self, file: Path) -> None:
5653
# The same value reaches `convert` below. Passing it to only one of the
5754
# two would make every project report itself as permanently unsaved.
5855
s3_key_prefix = self._current_key_prefix.get()
59-
if s3_key_prefix is not None:
60-
self._guard_save_destination(file, s3_key_prefix)
6156
self._config_parser.serialize(
6257
project=project,
6358
video_files=video_files,

‎OTAnalytics/plugin_s3/save_destination.py‎

Lines changed: 0 additions & 27 deletions
This file was deleted.

‎OTAnalytics/plugin_ui/base_application.py‎

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,6 @@
3838
RunConfiguration,
3939
RunConfigurationError,
4040
)
41-
from OTAnalytics.application.save_destination import (
42-
GuardSaveDestination,
43-
NoDestinationGuard,
44-
)
4541
from OTAnalytics.application.state import (
4642
ActionState,
4743
CurrentKeyPrefix,
@@ -442,7 +438,6 @@ def save_otconfig(self) -> SaveOtconfig:
442438
self.get_current_remark,
443439
self.current_key_prefix,
444440
self.otconfig_upload,
445-
self.guard_save_destination,
446441
)
447442

448443
@cached_property
@@ -454,15 +449,6 @@ def otconfig_upload(self) -> UploadOtconfig:
454449
"""
455450
return NoOtconfigUpload()
456451

457-
@cached_property
458-
def guard_save_destination(self) -> GuardSaveDestination:
459-
"""Refuses a save a later s3-mode load could not find again.
460-
461-
Overridden where s3 can be configured. This starter never sees a
462-
project naming a location, so no destination needs guarding.
463-
"""
464-
return NoDestinationGuard()
465-
466452
@cached_property
467453
def current_key_prefix(self) -> CurrentKeyPrefix:
468454
"""One holder for the whole application.

‎OTAnalytics/plugin_ui/nicegui_application.py‎

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,6 @@
1313
RefuseAnyProjectLocation,
1414
ValidateProjectLocation,
1515
)
16-
from OTAnalytics.application.save_destination import (
17-
GuardSaveDestination,
18-
NoDestinationGuard,
19-
)
2016
from OTAnalytics.application.upload_otconfig import NoOtconfigUpload, UploadOtconfig
2117
from OTAnalytics.application.use_cases.ask_for_load_window import AskForLoadWindow
2218
from OTAnalytics.application.use_cases.provide_input_files import (
@@ -43,7 +39,6 @@
4339
S3TrackFileProvider,
4440
S3VideoFileProvider,
4541
)
46-
from OTAnalytics.plugin_s3.save_destination import RequireDestinationUnderUserSource
4742
from OTAnalytics.plugin_s3.store import S3Store
4843
from OTAnalytics.plugin_s3.upload import S3Upload
4944
from OTAnalytics.plugin_ui.gui_application import OtAnalyticsGuiApplicationStarter
@@ -342,12 +337,6 @@ def otconfig_upload(self) -> UploadOtconfig:
342337
return S3OtconfigUpload(S3Upload(self.s3_store))
343338
return NoOtconfigUpload()
344339

345-
@cached_property
346-
def guard_save_destination(self) -> GuardSaveDestination:
347-
if config := self.s3_config:
348-
return RequireDestinationUnderUserSource(Path(config.user_source))
349-
return NoDestinationGuard()
350-
351340
@cached_property
352341
def reset_application(self) -> ResetApplication:
353342
"""Resetting a project also frees the staged downloads it used.

‎tests/unit/OTAnalytics/application/test_save_destination.py‎

Lines changed: 0 additions & 27 deletions
This file was deleted.

‎tests/unit/OTAnalytics/application/use_cases/test_config.py‎

Lines changed: 0 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
from OTAnalytics.application.key_prefix import S3KeyPrefix
99
from OTAnalytics.application.parser.config_parser import ConfigParser
1010
from OTAnalytics.application.project import Project
11-
from OTAnalytics.application.save_destination import UnsupportedSaveDestination
1211
from OTAnalytics.application.state import ConfigurationFile
1312
from OTAnalytics.application.use_cases.config import ConfigValidationError, SaveOtconfig
1413
from OTAnalytics.domain.track_repository import TrackFileRepository
@@ -31,15 +30,13 @@ async def test_correct_date(self, test_data_tmp_dir: Path) -> None:
3130
current_key_prefix = Mock()
3231
current_key_prefix.get.return_value = A_PREFIX
3332
otconfig_upload = AsyncMock()
34-
guard_save_destination = Mock()
3533
use_case = SaveOtconfig(
3634
datastore,
3735
config_parser,
3836
file_state,
3937
get_current_remark,
4038
current_key_prefix,
4139
otconfig_upload,
42-
guard_save_destination,
4340
)
4441

4542
await use_case(output)
@@ -75,7 +72,6 @@ async def test_writes_the_same_location_it_records_as_saved(
7572
Mock(),
7673
current_key_prefix,
7774
AsyncMock(),
78-
Mock(),
7975
)
8076

8177
await use_case(test_data_tmp_dir / "test.otconfig")
@@ -103,7 +99,6 @@ async def test_uploads_when_project_names_a_key_prefix(
10399
Mock(),
104100
current_key_prefix,
105101
otconfig_upload,
106-
Mock(),
107102
)
108103

109104
await use_case(output)
@@ -128,90 +123,12 @@ async def test_does_not_upload_when_project_names_no_key_prefix(
128123
Mock(),
129124
current_key_prefix,
130125
otconfig_upload,
131-
Mock(),
132126
)
133127

134128
await use_case(test_data_tmp_dir / "test.otconfig")
135129

136130
otconfig_upload.upload.assert_not_awaited()
137131

138-
async def test_guards_the_destination_when_project_names_a_key_prefix(
139-
self, test_data_tmp_dir: Path
140-
) -> None:
141-
track_file_repository = Mock(spec=TrackFileRepository)
142-
datastore = Mock(spec=Datastore)
143-
datastore._track_file_repository = track_file_repository
144-
datastore.project = Project("name", start_date=datetime(2023, 1, 1))
145-
config_parser = Mock(spec=ConfigParser)
146-
current_key_prefix = Mock()
147-
current_key_prefix.get.return_value = A_PREFIX
148-
guard_save_destination = Mock()
149-
output = test_data_tmp_dir / "test.otconfig"
150-
use_case = SaveOtconfig(
151-
datastore,
152-
config_parser,
153-
Mock(),
154-
Mock(),
155-
current_key_prefix,
156-
AsyncMock(),
157-
guard_save_destination,
158-
)
159-
160-
await use_case(output)
161-
162-
guard_save_destination.assert_called_once_with(output, A_PREFIX)
163-
164-
async def test_does_not_guard_when_project_names_no_key_prefix(
165-
self, test_data_tmp_dir: Path
166-
) -> None:
167-
track_file_repository = Mock(spec=TrackFileRepository)
168-
datastore = Mock(spec=Datastore)
169-
datastore._track_file_repository = track_file_repository
170-
datastore.project = Project("name", start_date=datetime(2023, 1, 1))
171-
config_parser = Mock(spec=ConfigParser)
172-
current_key_prefix = Mock()
173-
current_key_prefix.get.return_value = None
174-
guard_save_destination = Mock()
175-
use_case = SaveOtconfig(
176-
datastore,
177-
config_parser,
178-
Mock(),
179-
Mock(),
180-
current_key_prefix,
181-
AsyncMock(),
182-
guard_save_destination,
183-
)
184-
185-
await use_case(test_data_tmp_dir / "test.otconfig")
186-
187-
guard_save_destination.assert_not_called()
188-
189-
async def test_refused_destination_is_not_serialized(
190-
self, test_data_tmp_dir: Path
191-
) -> None:
192-
track_file_repository = Mock(spec=TrackFileRepository)
193-
datastore = Mock(spec=Datastore)
194-
datastore._track_file_repository = track_file_repository
195-
datastore.project = Project("name", start_date=datetime(2023, 1, 1))
196-
config_parser = Mock(spec=ConfigParser)
197-
current_key_prefix = Mock()
198-
current_key_prefix.get.return_value = A_PREFIX
199-
guard_save_destination = Mock(side_effect=UnsupportedSaveDestination())
200-
use_case = SaveOtconfig(
201-
datastore,
202-
config_parser,
203-
Mock(),
204-
Mock(),
205-
current_key_prefix,
206-
AsyncMock(),
207-
guard_save_destination,
208-
)
209-
210-
with pytest.raises(UnsupportedSaveDestination):
211-
await use_case(test_data_tmp_dir / "test.otconfig")
212-
213-
config_parser.serialize.assert_not_called()
214-
215132
async def test_missing_date(self, test_data_tmp_dir: Path) -> None:
216133
datastore = Mock(spec=Datastore)
217134
datastore.project = Project("name", start_date=None)
@@ -226,7 +143,6 @@ async def test_missing_date(self, test_data_tmp_dir: Path) -> None:
226143
get_current_remark,
227144
Mock(),
228145
AsyncMock(),
229-
Mock(),
230146
)
231147

232148
with pytest.raises(ConfigValidationError) as exc_info:

‎tests/unit/OTAnalytics/plugin_s3/test_save_destination.py‎

Lines changed: 0 additions & 50 deletions
This file was deleted.

0 commit comments

Comments
 (0)