Feature add sync command 887 (#921)
* Starting work on sync command, #887 * Added parsing for --set, --merge * Added query options * Added --incloud, --not-incloud, --not-missing, --cloudasset, --not-cloudasset to query options, #800 (#902) * Got basic import logic working * Got basic set/merge logic working * add to album now working * Resolve paths for --import * Refactored report writer to reuse code from export report * Removed report_writer_sync.py * add oPromessa as a contributor for code (#914) * update README.md [skip ci] * update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> * Added --profile, --watch, --breakpoint, --debug as global options (#917) * Removed unnecessary import * Release 0.56.0 (#918) * Release 0 56 0 (#919) * Release 0.56.0 * Release 0.56.0 * Updated CHANGELOG.md [skip ci] * Got CSV reporting, summary results done * Added json report for sync results * Added sqlite report for sync * Basic set/merge working for sync * sync mvp working * Added help text for sync * Added test for sync * Updated tests for sync Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com>
This commit is contained in:
@@ -15,9 +15,12 @@ from .test_catalina_10_15_7 import UUID_DICT_LOCAL
|
||||
# run timewarp tests (configured with --timewarp)
|
||||
TEST_TIMEWARP = False
|
||||
|
||||
# run import tests (configured with --import)
|
||||
# run import tests (configured with --test-import)
|
||||
TEST_IMPORT = False
|
||||
|
||||
# run sync tests (configured with --test-sync)
|
||||
TEST_SYNC = False
|
||||
|
||||
# don't clean up crash logs (configured with --no-cleanup)
|
||||
NO_CLEANUP = False
|
||||
|
||||
@@ -46,10 +49,12 @@ OS_VER = get_os_version()[1]
|
||||
if OS_VER == "15":
|
||||
TEST_LIBRARY = "tests/Test-10.15.7.photoslibrary"
|
||||
TEST_LIBRARY_IMPORT = TEST_LIBRARY
|
||||
TEST_LIBRARY_SYNC = TEST_LIBRARY
|
||||
from tests.config_timewarp_catalina import TEST_LIBRARY_TIMEWARP
|
||||
else:
|
||||
TEST_LIBRARY = None
|
||||
TEST_LIBRARY_TIMEWARP = None
|
||||
TEST_LIBRARY_SYNC = None
|
||||
# pytest.exit("This test suite currently only runs on MacOS Catalina ")
|
||||
|
||||
|
||||
@@ -67,6 +72,13 @@ def setup_photos_import():
|
||||
copy_photos_library(TEST_LIBRARY_IMPORT, delay=10)
|
||||
|
||||
|
||||
@pytest.fixture(scope="session", autouse=True)
|
||||
def setup_photos_sync():
|
||||
if not TEST_SYNC:
|
||||
return
|
||||
copy_photos_library(TEST_LIBRARY_SYNC, delay=10)
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def reset_singletons():
|
||||
"""Need to clean up any ExifTool singletons between tests"""
|
||||
@@ -89,6 +101,12 @@ def pytest_addoption(parser):
|
||||
default=False,
|
||||
help="run `osxphotos import` tests",
|
||||
)
|
||||
parser.addoption(
|
||||
"--test-sync",
|
||||
action="store_true",
|
||||
default=False,
|
||||
help="run `osxphotos sync` tests",
|
||||
)
|
||||
parser.addoption(
|
||||
"--no-cleanup",
|
||||
action="store_true",
|
||||
@@ -105,11 +123,14 @@ def pytest_configure(config):
|
||||
config.getoption("--addalbum"),
|
||||
config.getoption("--timewarp"),
|
||||
config.getoption("--test-import"),
|
||||
config.getoption("--test-sync"),
|
||||
]
|
||||
)
|
||||
> 1
|
||||
):
|
||||
pytest.exit("--addalbum, --timewarp, --test-import are mutually exclusive")
|
||||
pytest.exit(
|
||||
"--addalbum, --timewarp, --test-import, --test-sync are mutually exclusive"
|
||||
)
|
||||
|
||||
config.addinivalue_line(
|
||||
"markers", "addalbum: mark test as requiring --addalbum to run"
|
||||
@@ -120,6 +141,9 @@ def pytest_configure(config):
|
||||
config.addinivalue_line(
|
||||
"markers", "test_import: mark test as requiring --test-import to run"
|
||||
)
|
||||
config.addinivalue_line(
|
||||
"markers", "test_sync: mark test as requiring --test-sync to run"
|
||||
)
|
||||
|
||||
# this is hacky but I can't figure out how to check config options in other fixtures
|
||||
if config.getoption("--timewarp"):
|
||||
@@ -130,6 +154,10 @@ def pytest_configure(config):
|
||||
global TEST_IMPORT
|
||||
TEST_IMPORT = True
|
||||
|
||||
if config.getoption("--test-sync"):
|
||||
global TEST_SYNC
|
||||
TEST_SYNC = True
|
||||
|
||||
if config.getoption("--no-cleanup"):
|
||||
global NO_CLEANUP
|
||||
NO_CLEANUP = True
|
||||
@@ -160,6 +188,14 @@ def pytest_collection_modifyitems(config, items):
|
||||
if "test_import" in item.keywords:
|
||||
item.add_marker(skip_test_import)
|
||||
|
||||
if not (config.getoption("--test-sync") and TEST_LIBRARY_SYNC is not None):
|
||||
skip_test_sync = pytest.mark.skip(
|
||||
reason="need --test-sync option and MacOS Catalina to run"
|
||||
)
|
||||
for item in items:
|
||||
if "test_sync" in item.keywords:
|
||||
item.add_marker(skip_test_sync)
|
||||
|
||||
|
||||
def copy_photos_library(photos_library, delay=0):
|
||||
"""copy the test library and open Photos, returns path to copied library"""
|
||||
|
||||
108
tests/test_cli_sync.py
Normal file
108
tests/test_cli_sync.py
Normal file
@@ -0,0 +1,108 @@
|
||||
"""Test osxphotos sync command"""
|
||||
|
||||
import os
|
||||
import json
|
||||
import photoscript
|
||||
import pytest
|
||||
from click.testing import CliRunner
|
||||
|
||||
from osxphotos.cli.sync import sync
|
||||
|
||||
UUID_TEST_PHOTO_1 = "D79B8D77-BFFC-460B-9312-034F2877D35B" # Pumkins2.jpg
|
||||
UUID_TEST_PHOTO_2 = "E9BC5C36-7CD1-40A1-A72B-8B8FAC227D51" # wedding.jpg
|
||||
|
||||
TEST_ALBUM_NAME = "SyncTestAlbum"
|
||||
|
||||
|
||||
@pytest.mark.test_sync
|
||||
def test_sync_export():
|
||||
"""Test --export"""
|
||||
with CliRunner().isolated_filesystem():
|
||||
result = CliRunner().invoke(
|
||||
sync,
|
||||
[
|
||||
"--export",
|
||||
"test.db",
|
||||
],
|
||||
)
|
||||
assert result.exit_code == 0
|
||||
assert os.path.exists("test.db")
|
||||
|
||||
|
||||
@pytest.mark.test_sync
|
||||
def test_sync_export_import():
|
||||
"""Test --export and --import"""
|
||||
|
||||
photoslib = photoscript.PhotosLibrary()
|
||||
|
||||
# create a new album and initialize metadata
|
||||
test_album = photoslib.create_album(TEST_ALBUM_NAME)
|
||||
for uuid in [UUID_TEST_PHOTO_1, UUID_TEST_PHOTO_2]:
|
||||
photo = photoscript.Photo(uuid)
|
||||
photo.favorite = True
|
||||
test_album.add([photo])
|
||||
|
||||
# export data
|
||||
with CliRunner().isolated_filesystem():
|
||||
result = CliRunner().invoke(
|
||||
sync,
|
||||
[
|
||||
"--export",
|
||||
"test.db",
|
||||
],
|
||||
)
|
||||
assert result.exit_code == 0
|
||||
|
||||
# preserve metadata for comparison and clear metadata
|
||||
metadata_before = {}
|
||||
for uuid in [UUID_TEST_PHOTO_1, UUID_TEST_PHOTO_2]:
|
||||
photo = photoscript.Photo(uuid)
|
||||
metadata_before[uuid] = {
|
||||
"title": photo.title,
|
||||
"description": photo.description,
|
||||
"keywords": photo.keywords,
|
||||
"favorites": photo.favorite,
|
||||
}
|
||||
photo.title = ""
|
||||
photo.description = ""
|
||||
photo.keywords = ["NewKeyword"]
|
||||
photo.favorite = False
|
||||
|
||||
# delete the test album
|
||||
photoslib.delete_album(test_album)
|
||||
|
||||
# import metadata
|
||||
result = CliRunner().invoke(
|
||||
sync,
|
||||
[
|
||||
"--import",
|
||||
"test.db",
|
||||
"--set",
|
||||
"title,description,favorite,albums",
|
||||
"--merge",
|
||||
"keywords",
|
||||
"--report",
|
||||
"test_report.json",
|
||||
],
|
||||
)
|
||||
assert result.exit_code == 0
|
||||
assert os.path.exists("test_report.json")
|
||||
|
||||
# check metadata
|
||||
for uuid in [UUID_TEST_PHOTO_1, UUID_TEST_PHOTO_2]:
|
||||
photo = photoscript.Photo(uuid)
|
||||
assert photo.title == metadata_before[uuid]["title"]
|
||||
assert photo.description == metadata_before[uuid]["description"]
|
||||
assert sorted(photo.keywords) == sorted(
|
||||
["NewKeyword", *metadata_before[uuid]["keywords"]]
|
||||
)
|
||||
assert photo.favorite == metadata_before[uuid]["favorites"]
|
||||
assert TEST_ALBUM_NAME in [album.title for album in photo.albums]
|
||||
|
||||
# check report
|
||||
with open("test_report.json", "r") as f:
|
||||
report = json.load(f)
|
||||
report_data = {record["uuid"]: record for record in report}
|
||||
for uuid in [UUID_TEST_PHOTO_1, UUID_TEST_PHOTO_2]:
|
||||
assert report_data[uuid]["updated"]
|
||||
assert report_data[uuid]["albums"]["updated"]
|
||||
Reference in New Issue
Block a user