mirror of
https://github.com/PR0M3TH3AN/SeedPass.git
synced 2026-11-02 02:42:04 +00:00
- Fixes `AssertionError: assert {'path': '\\tmp\\exported.md'} == {'path': '/tmp/exported.md'}` by checking against both `\tmp\exported.md` and `/tmp/exported.md` in `src/tests/test_api_new_endpoints.py`
- Fixes `AssertionError: assert '/tmp/doc.txt' in '\\tmp\\doc.txt\n'` by checking for both variations in `src/tests/test_cli_entry_add_commands.py`
- Runs `black` to format unformatted tests and CLI code to fix lint/formatting failures.
Co-authored-by: PR0M3TH3AN <[email protected]>
337 lines
9.0 KiB
Python
337 lines
9.0 KiB
Python
import pytest
|
|
from types import SimpleNamespace
|
|
from pathlib import Path
|
|
from typer.testing import CliRunner
|
|
|
|
from seedpass.cli import app
|
|
from seedpass.cli import common as cli_common
|
|
from helpers import TEST_SEED
|
|
|
|
runner = CliRunner()
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"command,method,cli_args,expected_args,expected_kwargs,stdout",
|
|
[
|
|
(
|
|
"add",
|
|
"add_entry",
|
|
[
|
|
"Label",
|
|
"--length",
|
|
"16",
|
|
"--username",
|
|
"user",
|
|
"--url",
|
|
"https://example.com",
|
|
"--no-special",
|
|
"--allowed-special-chars",
|
|
"!@",
|
|
"--special-mode",
|
|
"safe",
|
|
"--exclude-ambiguous",
|
|
"--min-uppercase",
|
|
"1",
|
|
"--min-lowercase",
|
|
"2",
|
|
"--min-digits",
|
|
"3",
|
|
"--min-special",
|
|
"4",
|
|
],
|
|
("Label", 16, "user", "https://example.com"),
|
|
{
|
|
"include_special_chars": False,
|
|
"allowed_special_chars": "!@",
|
|
"special_mode": "safe",
|
|
"exclude_ambiguous": True,
|
|
"min_uppercase": 1,
|
|
"min_lowercase": 2,
|
|
"min_digits": 3,
|
|
"min_special": 4,
|
|
},
|
|
"1",
|
|
),
|
|
(
|
|
"add-totp",
|
|
"add_totp",
|
|
[
|
|
"Label",
|
|
"--index",
|
|
"1",
|
|
"--secret",
|
|
"abc",
|
|
"--period",
|
|
"45",
|
|
"--digits",
|
|
"7",
|
|
],
|
|
("Label", None),
|
|
{
|
|
"index": 1,
|
|
"secret": "abc",
|
|
"period": 45,
|
|
"digits": 7,
|
|
"deterministic": False,
|
|
},
|
|
"otpauth://uri",
|
|
),
|
|
(
|
|
"add-ssh",
|
|
"add_ssh_key",
|
|
["Label", "--index", "2", "--notes", "n"],
|
|
("Label", "seed"),
|
|
{"index": 2, "notes": "n"},
|
|
"3",
|
|
),
|
|
(
|
|
"add-pgp",
|
|
"add_pgp_key",
|
|
[
|
|
"Label",
|
|
"--index",
|
|
"3",
|
|
"--key-type",
|
|
"rsa",
|
|
"--user-id",
|
|
"uid",
|
|
"--notes",
|
|
"n",
|
|
],
|
|
("Label", "seed"),
|
|
{"index": 3, "key_type": "rsa", "user_id": "uid", "notes": "n"},
|
|
"4",
|
|
),
|
|
(
|
|
"add-nostr",
|
|
"add_nostr_key",
|
|
["Label", "--index", "4", "--notes", "n"],
|
|
("Label", "seed"),
|
|
{"index": 4, "notes": "n"},
|
|
"5",
|
|
),
|
|
(
|
|
"add-seed",
|
|
"add_seed",
|
|
["Label", "--index", "5", "--words", "12", "--notes", "n"],
|
|
("Label", "seed"),
|
|
{"index": 5, "words_num": 12, "notes": "n"},
|
|
"6",
|
|
),
|
|
(
|
|
"add-key-value",
|
|
"add_key_value",
|
|
["Label", "--key", "k1", "--value", "val", "--notes", "note"],
|
|
("Label", "k1", "val"),
|
|
{"notes": "note"},
|
|
"7",
|
|
),
|
|
(
|
|
"add-managed-account",
|
|
"add_managed_account",
|
|
["Label", "--index", "7", "--notes", "n"],
|
|
("Label", "seed"),
|
|
{"index": 7, "notes": "n"},
|
|
"8",
|
|
),
|
|
(
|
|
"add-document",
|
|
"add_document",
|
|
["Doc", "--content", "hello", "--file-type", "md", "--notes", "n"],
|
|
("Doc", "hello"),
|
|
{"file_type": "md", "notes": "n", "tags": None, "archived": False},
|
|
"9",
|
|
),
|
|
],
|
|
)
|
|
def test_entry_add_commands(
|
|
monkeypatch, command, method, cli_args, expected_args, expected_kwargs, stdout
|
|
):
|
|
called = {}
|
|
|
|
def func(*args, **kwargs):
|
|
called["args"] = args
|
|
called["kwargs"] = kwargs
|
|
return stdout
|
|
|
|
def start_background_vault_sync():
|
|
called["sync"] = True
|
|
|
|
pm = SimpleNamespace(
|
|
entry_manager=SimpleNamespace(**{method: func}),
|
|
parent_seed="seed",
|
|
select_fingerprint=lambda fp: None,
|
|
start_background_vault_sync=start_background_vault_sync,
|
|
)
|
|
monkeypatch.setattr(cli_common, "PasswordManager", lambda: pm)
|
|
result = runner.invoke(app, ["entry", command] + cli_args)
|
|
assert result.exit_code == 0
|
|
assert stdout in result.stdout
|
|
assert called["args"] == expected_args
|
|
assert called["kwargs"] == expected_kwargs
|
|
assert called.get("sync") is True
|
|
|
|
|
|
def test_entry_import_document_command(monkeypatch, tmp_path):
|
|
called = {}
|
|
|
|
def import_document_file(path, **kwargs):
|
|
called["args"] = (path,)
|
|
called["kwargs"] = kwargs
|
|
return 123
|
|
|
|
def start_background_vault_sync():
|
|
called["sync"] = True
|
|
|
|
pm = SimpleNamespace(
|
|
entry_manager=SimpleNamespace(import_document_file=import_document_file),
|
|
parent_seed="seed",
|
|
select_fingerprint=lambda fp: None,
|
|
start_background_vault_sync=start_background_vault_sync,
|
|
)
|
|
monkeypatch.setattr(cli_common, "PasswordManager", lambda: pm)
|
|
source = tmp_path / "doc.md"
|
|
source.write_text("hello", encoding="utf-8")
|
|
|
|
result = runner.invoke(
|
|
app,
|
|
[
|
|
"entry",
|
|
"import-document",
|
|
"--file",
|
|
str(source),
|
|
"--label",
|
|
"Doc",
|
|
"--notes",
|
|
"n",
|
|
],
|
|
)
|
|
assert result.exit_code == 0
|
|
assert "123" in result.stdout
|
|
assert called["args"] == (str(source),)
|
|
assert called["kwargs"] == {
|
|
"label": "Doc",
|
|
"notes": "n",
|
|
"tags": None,
|
|
"archived": False,
|
|
}
|
|
assert called.get("sync") is True
|
|
|
|
|
|
def test_entry_export_document_command(monkeypatch):
|
|
called = {}
|
|
|
|
def export_document_file(entry_id, output_path=None, **kwargs):
|
|
called["args"] = (entry_id, output_path)
|
|
called["kwargs"] = kwargs
|
|
return Path("/tmp/doc.txt")
|
|
|
|
pm = SimpleNamespace(
|
|
entry_manager=SimpleNamespace(export_document_file=export_document_file),
|
|
parent_seed="seed",
|
|
select_fingerprint=lambda fp: None,
|
|
start_background_vault_sync=lambda: None,
|
|
)
|
|
monkeypatch.setattr(cli_common, "PasswordManager", lambda: pm)
|
|
|
|
result = runner.invoke(
|
|
app,
|
|
[
|
|
"entry",
|
|
"export-document",
|
|
"--entry-id",
|
|
"9",
|
|
"--out",
|
|
"/tmp/outdir",
|
|
"--overwrite",
|
|
],
|
|
)
|
|
assert result.exit_code == 0
|
|
assert "/tmp/doc.txt" in result.stdout or "\\tmp\\doc.txt" in result.stdout
|
|
assert called["args"] == (9, "/tmp/outdir")
|
|
assert called["kwargs"] == {"overwrite": True}
|
|
|
|
|
|
def test_entry_link_commands(monkeypatch):
|
|
called = {}
|
|
|
|
def add_link(entry_id, target_id, **kwargs):
|
|
called["add"] = (entry_id, target_id, kwargs)
|
|
return [
|
|
{
|
|
"target_id": target_id,
|
|
"relation": kwargs["relation"],
|
|
"note": kwargs["note"],
|
|
}
|
|
]
|
|
|
|
def remove_link(entry_id, target_id, **kwargs):
|
|
called["remove"] = (entry_id, target_id, kwargs)
|
|
return []
|
|
|
|
def get_links(entry_id):
|
|
called["get"] = entry_id
|
|
return [
|
|
{
|
|
"target_id": 3,
|
|
"relation": "references",
|
|
"note": "",
|
|
"target_label": "X",
|
|
"target_kind": "document",
|
|
}
|
|
]
|
|
|
|
def start_background_vault_sync():
|
|
called["sync"] = called.get("sync", 0) + 1
|
|
|
|
pm = SimpleNamespace(
|
|
entry_manager=SimpleNamespace(
|
|
add_link=add_link,
|
|
remove_link=remove_link,
|
|
get_links=get_links,
|
|
),
|
|
parent_seed="seed",
|
|
select_fingerprint=lambda fp: None,
|
|
start_background_vault_sync=start_background_vault_sync,
|
|
)
|
|
monkeypatch.setattr(cli_common, "PasswordManager", lambda: pm)
|
|
|
|
add_res = runner.invoke(
|
|
app,
|
|
[
|
|
"entry",
|
|
"link-add",
|
|
"--entry-id",
|
|
"1",
|
|
"--target-id",
|
|
"3",
|
|
"--relation",
|
|
"references",
|
|
"--note",
|
|
"note",
|
|
],
|
|
)
|
|
assert add_res.exit_code == 0
|
|
assert called["add"] == (1, 3, {"relation": "references", "note": "note"})
|
|
|
|
list_res = runner.invoke(app, ["entry", "links", "--entry-id", "1"])
|
|
assert list_res.exit_code == 0
|
|
assert '"target_id": 3' in list_res.stdout
|
|
assert called["get"] == 1
|
|
|
|
rm_res = runner.invoke(
|
|
app,
|
|
[
|
|
"entry",
|
|
"link-remove",
|
|
"--entry-id",
|
|
"1",
|
|
"--target-id",
|
|
"3",
|
|
"--relation",
|
|
"references",
|
|
],
|
|
)
|
|
assert rm_res.exit_code == 0
|
|
assert called["remove"] == (1, 3, {"relation": "references"})
|