diff options
Diffstat (limited to 'packages/meshbay-hub/tests/test_photo_sync.py')
| -rw-r--r-- | packages/meshbay-hub/tests/test_photo_sync.py | 50 |
1 files changed, 33 insertions, 17 deletions
diff --git a/packages/meshbay-hub/tests/test_photo_sync.py b/packages/meshbay-hub/tests/test_photo_sync.py index cbc5f5d..98f49ba 100644 --- a/packages/meshbay-hub/tests/test_photo_sync.py +++ b/packages/meshbay-hub/tests/test_photo_sync.py @@ -43,7 +43,14 @@ export class ConnectionPool { PRELUDE = r""" const fake = globalThis.fake = { log: [], pools: [], refuseConnect: null, uploadError: null, - afterUpload: null }; + afterUpload: null, adminId: 'u-bob', membersError: null, + members: [{ user_id: 'u-bob', username: 'bob' }], invited: [] }; +// The hub's member list, asked before every run reads anything. +const hubFetch = async (path) => { + fake.log.push(['hub', path]); + if (fake.membersError) throw new Error(fake.membersError); + return { admin_id: fake.adminId, members: fake.members, invited: fake.invited }; +}; const win = new EventTarget(); const doc = new EventTarget(); doc.visibilityState = 'visible'; @@ -58,8 +65,9 @@ globalThis.fetch = async (url) => { const NOW = Date.now(); fake.status = { permission: 'granted', unmetered: true, sent: 0, now: NOW, - config: { account: 'bob', groupId: 'g1', groupName: 'Family', owner: 'alice', - folder: 'Media/Photos/Bob', albums: ['cam'], includeExisting: true, since: 0 }, + config: { albums: ['cam'], includeExisting: true, since: 0 }, + destination: { account: 'bob', groupId: 'g1', groupName: 'Mine', folder: 'Media/Photos/Bob' }, + dir: 'Media/Photos/Bob/bob-photos', lastCompleted: null, failure: null, failureAt: null, }; fake.items = [ @@ -116,7 +124,7 @@ def _run(body, tmp_path): script.write_text( PRELUDE + f"const m = await import('{(root / 'photo-sync.js').as_uri()}');\n" - + "const ctx = { hub: 'https://hub.invalid', getUser: () => ({ username: 'bob', " + + "const ctx = { hub: 'https://hub.invalid', hubFetch, getUser: () => ({ username: 'bob', " "userId: 'u-bob', token: 'tok' }), getBundleKey: async () => 'bk' };\n" + body # The next run's timer would keep Node alive for a day. @@ -274,23 +282,31 @@ def test_a_folder_no_longer_writable_is_found_before_sending(tmp_path): def test_another_account_on_the_phone_sends_nothing(tmp_path): - log = _run(_start("fake.status.config.account = 'carol';"), tmp_path) + log = _run(_start("fake.status.destination.account = 'carol';"), tmp_path) assert ["plan"] not in log -# ── choosing a folder ─────────────────────────────────────────────────────── +# ── the account's own group, at every run ─────────────────────────────────── -def test_only_writable_folders_the_photos_tab_shows_are_offered(tmp_path): - log = _run(""" -fake.log.push(['folders', m.backupFolders( - { photo_directories: ['Media/Photos', 'Archive/Pictures'] }, - { roots: [{ name: 'Media', writable: true, available: true }, - { name: 'Archive', writable: false, available: true }, - { name: 'Ejected', writable: true, available: false }], - dirs: ['Media/Films', 'Media/Photos', 'Media/Photos/Bob', 'Archive/Pictures', - 'Ejected/Photos'] })]); -""", tmp_path) - assert _of(log, "folders") == [[["Media/Photos", "Media/Photos/Bob"]]] +@pytest.mark.parametrize("setup", [ + "fake.members.push({ user_id: 'u-carol', username: 'carol' });", + "fake.invited = [{ user_id: 'u-carol', username: 'carol' }];", + "fake.adminId = 'u-carol';", +]) +def test_a_group_not_ones_own_alone_stops_it_before_anything_is_read(tmp_path, setup): + log = _run(_start(setup), tmp_path) + assert _of(log, "failed") == [["not_private"]] + assert ["plan"] not in log and _of(log, "upload") == [] + + +def test_the_group_is_asked_about_before_the_photos_are_listed(tmp_path): + log = _run(_start(), tmp_path) + assert log.index(["hub", "/v1/groups/g1/members"]) < log.index(["plan"]) + + +def test_an_unreachable_hub_is_not_a_lasting_refusal(tmp_path): + log = _run(_start("fake.membersError = 'Failed to fetch';"), tmp_path) + assert _of(log, "failed") == [] and ["plan"] not in log # ── nothing is ever removed ───────────────────────────────────────────────── |