|
12 | 12 | TrackParser, |
13 | 13 | TracksParseResult, |
14 | 14 | ) |
15 | | -from OTAnalytics.application.use_cases.load_track_files import LoadTrackFiles |
| 15 | +from OTAnalytics.application.use_cases.load_track_files import ( |
| 16 | + PARSING_DESCRIPTION, |
| 17 | + PARSING_UNIT, |
| 18 | + LoadTrackFiles, |
| 19 | +) |
16 | 20 | from OTAnalytics.domain.georeference import GeoreferenceMetadata |
17 | 21 | from OTAnalytics.domain.track import TrackId |
18 | 22 | from OTAnalytics.domain.track_dataset.track_dataset import ( |
@@ -416,6 +420,119 @@ def record_publishes_so_far(files: list[Path]) -> Any: |
416 | 420 | given.track_repository.add_all.assert_called_once() |
417 | 421 |
|
418 | 422 |
|
| 423 | +class TestLoadTrackFilesShowsProgress: |
| 424 | + """#Requirement https://openproject.platomo.de/wp/10282""" |
| 425 | + |
| 426 | + def test_blocking_call_shows_a_progressbar_until_the_files_are_loaded( |
| 427 | + self, |
| 428 | + ) -> None: |
| 429 | + given = setup( |
| 430 | + track_ids=[TrackId("1"), TrackId("2")], |
| 431 | + video_files=[Path("video1.mp4"), Path("video2.mp4")], |
| 432 | + track_files=[some_file, other_file], |
| 433 | + existing_track_files=[], |
| 434 | + classes={"class1"}, |
| 435 | + ) |
| 436 | + target = create_target(given) |
| 437 | + |
| 438 | + target([some_file, other_file]) |
| 439 | + |
| 440 | + given.progressbar.start.assert_called_once_with( |
| 441 | + PARSING_DESCRIPTION, PARSING_UNIT, 2 |
| 442 | + ) |
| 443 | + given.progressbar.start.return_value.close.assert_called_once_with() |
| 444 | + |
| 445 | + async def test_shows_a_progressbar_until_the_files_are_loaded(self) -> None: |
| 446 | + """Parsing off the event loop leaves the ui free to show what it is doing.""" |
| 447 | + given = setup( |
| 448 | + track_ids=[TrackId("1")], |
| 449 | + video_files=[Path("video1.mp4")], |
| 450 | + track_files=[some_file], |
| 451 | + existing_track_files=[], |
| 452 | + classes={"class1"}, |
| 453 | + ) |
| 454 | + target = create_target(given) |
| 455 | + |
| 456 | + await target.load([some_file]) |
| 457 | + |
| 458 | + given.progressbar.start.assert_called_once_with( |
| 459 | + PARSING_DESCRIPTION, PARSING_UNIT, 1 |
| 460 | + ) |
| 461 | + given.progressbar.start.return_value.close.assert_called_once_with() |
| 462 | + |
| 463 | + async def test_counts_only_the_files_it_is_going_to_parse(self) -> None: |
| 464 | + given = setup( |
| 465 | + track_ids=[TrackId("1")], |
| 466 | + video_files=[Path("video1.mp4")], |
| 467 | + track_files=[other_file], |
| 468 | + existing_track_files=[some_file], |
| 469 | + classes={"class1"}, |
| 470 | + ) |
| 471 | + target = create_target(given) |
| 472 | + |
| 473 | + await target.load([some_file, other_file]) |
| 474 | + |
| 475 | + given.progressbar.start.assert_called_once_with( |
| 476 | + PARSING_DESCRIPTION, PARSING_UNIT, 1 |
| 477 | + ) |
| 478 | + |
| 479 | + async def test_opens_the_progressbar_before_parsing_and_closes_it_after( |
| 480 | + self, |
| 481 | + ) -> None: |
| 482 | + given = setup( |
| 483 | + track_ids=[TrackId("1")], |
| 484 | + video_files=[Path("video1.mp4")], |
| 485 | + track_files=[some_file], |
| 486 | + existing_track_files=[], |
| 487 | + classes={"class1"}, |
| 488 | + ) |
| 489 | + target = create_target(given) |
| 490 | + |
| 491 | + await target.load([some_file]) |
| 492 | + |
| 493 | + assert call_names(given) == [ |
| 494 | + "progressbar.start", |
| 495 | + "track_parser.parse_files", |
| 496 | + "videos_metadata.update", |
| 497 | + "video_parser.parse", |
| 498 | + "video_repository.add_all", |
| 499 | + "track_repository.add_all", |
| 500 | + "tracks_metadata.update_detection_classes", |
| 501 | + "progressbar.start().close", |
| 502 | + ] |
| 503 | + |
| 504 | + async def test_closes_the_progressbar_when_parsing_fails(self) -> None: |
| 505 | + """A progressbar left open would hide the ui behind it for good.""" |
| 506 | + given = setup( |
| 507 | + track_ids=[TrackId("1")], |
| 508 | + video_files=[Path("video1.mp4")], |
| 509 | + track_files=[some_file], |
| 510 | + existing_track_files=[], |
| 511 | + classes={"class1"}, |
| 512 | + ) |
| 513 | + given.track_parser.parse_files.side_effect = ValueError("broken track file") |
| 514 | + target = create_target(given) |
| 515 | + |
| 516 | + with pytest.raises(ValueError): |
| 517 | + await target.load([some_file]) |
| 518 | + |
| 519 | + given.progressbar.start.return_value.close.assert_called_once_with() |
| 520 | + |
| 521 | + async def test_shows_nothing_when_every_file_is_loaded_already(self) -> None: |
| 522 | + given = setup( |
| 523 | + track_ids=[], |
| 524 | + video_files=[], |
| 525 | + track_files=[], |
| 526 | + existing_track_files=[some_file], |
| 527 | + classes=set(), |
| 528 | + ) |
| 529 | + target = create_target(given) |
| 530 | + |
| 531 | + await target.load([some_file]) |
| 532 | + |
| 533 | + given.progressbar.start.assert_not_called() |
| 534 | + |
| 535 | + |
419 | 536 | def call_names(given: "Given") -> list[str]: |
420 | 537 | """The collaborator methods called, in call order.""" |
421 | 538 | return [name for name, _, _ in given.order.mock_calls] |
@@ -451,6 +568,7 @@ def __post_init__(self) -> None: |
451 | 568 | self.order.track_repository = self.track_repository |
452 | 569 | self.order.video_parser = self.video_parser |
453 | 570 | self.order.tracks_metadata = self.tracks_metadata |
| 571 | + self.order.progressbar = self.progressbar |
454 | 572 |
|
455 | 573 |
|
456 | 574 | def setup( |
|
0 commit comments