from __future__ import annotations from textwrap import dedent import pytest @pytest.fixture def storage(tmpdir, runner): runner.write_with_general( dedent( """ [storage foo] type = "filesystem" path = "{base}/foo/" fileext = ".txt" """ ).format(base=str(tmpdir)) ) return tmpdir.mkdir("foo") @pytest.mark.parametrize("collection", [None, "foocoll"]) def test_basic(storage, runner, collection): if collection is not None: storage = storage.mkdir(collection) collection_arg = f"foo/{collection}" else: collection_arg = "foo" argv = ["repair", collection_arg] result = runner.invoke(argv, input="y") assert not result.exception storage.join("item.txt").write("BEGIN:VCARD\nEND:VCARD") storage.join("toobroken.txt").write("") result = runner.invoke(argv, input="y") assert not result.exception assert "No UID" in result.output assert "'toobroken.txt' is malformed beyond repair" in result.output (new_fname,) = (x for x in storage.listdir() if "toobroken" not in str(x)) assert "UID:" in new_fname.read() @pytest.mark.parametrize("repair_uids", [None, True, False]) def test_repair_uids(storage, runner, repair_uids): f = storage.join("baduid.txt") orig_f = "BEGIN:VCARD\nUID:!!!!!\nEND:VCARD" f.write(orig_f) if repair_uids is None: opt = [] elif repair_uids: opt = ["--repair-unsafe-uid"] else: opt = ["--no-repair-unsafe-uid"] result = runner.invoke(["repair", *opt, "foo"], input="y") assert not result.exception if repair_uids: assert "UID or href is unsafe, assigning random UID" in result.output assert not f.exists() (new_f,) = storage.listdir() s = new_f.read() assert s.startswith("BEGIN:VCARD") assert s.endswith("END:VCARD") assert s != orig_f else: assert ( "UID may cause problems, add --repair-unsafe-uid to repair." in result.output ) assert f.read() == orig_f