prole/tests/installer/test_onepassword.py

169 lines
5.8 KiB
Python

"""Unit tests for knoe.core.onepassword — mocks the op CLI subprocess calls."""
from __future__ import annotations
import json
from unittest.mock import MagicMock, patch
import pytest
from knoe.core.onepassword import (
op_available,
ensure_op_signed_in,
ensure_knoey_vault,
get_secret,
set_secret,
get_administrator_password,
ensure_administrator_secret,
)
def _make_result(returncode: int = 0, stdout: str = "", stderr: str = "") -> MagicMock:
m = MagicMock()
m.returncode = returncode
m.stdout = stdout
m.stderr = stderr
return m
class TestOpAvailable:
def test_found(self):
with patch("knoe.core.onepassword.shutil.which", return_value="/usr/bin/op"):
assert op_available() is True
def test_not_found(self):
with patch("knoe.core.onepassword.shutil.which", return_value=None):
assert op_available() is False
class TestEnsureOpSignedIn:
def test_already_signed_in(self):
with patch("knoe.core.onepassword.shutil.which", return_value="/usr/bin/op"), \
patch("knoe.core.onepassword.subprocess.run", return_value=_make_result(0)):
ensure_op_signed_in()
def test_not_signed_in_triggers_signin(self):
calls = []
def fake_run(cmd, **_):
calls.append(cmd)
if "whoami" in cmd:
return _make_result(1)
return _make_result(0)
with patch("knoe.core.onepassword.shutil.which", return_value="/usr/bin/op"), \
patch("knoe.core.onepassword.subprocess.run", side_effect=fake_run):
ensure_op_signed_in()
assert any("signin" in c for c in calls)
def test_raises_when_op_missing(self):
with patch("knoe.core.onepassword.shutil.which", return_value=None):
with pytest.raises(RuntimeError, match="1Password CLI"):
ensure_op_signed_in()
class TestEnsureKnoeyVault:
def test_vault_already_exists(self):
vaults = json.dumps([{"name": "knoey"}, {"name": "Personal"}])
with patch("knoe.core.onepassword.shutil.which", return_value="/usr/bin/op"), \
patch("knoe.core.onepassword.subprocess.run",
return_value=_make_result(0, vaults)):
ensure_knoey_vault()
def test_vault_created_when_absent(self):
vaults = json.dumps([{"name": "Personal"}])
calls = []
def fake_run(cmd, **_):
calls.append(list(cmd))
return _make_result(0, vaults if "list" in cmd else "")
with patch("knoe.core.onepassword.shutil.which", return_value="/usr/bin/op"), \
patch("knoe.core.onepassword.subprocess.run", side_effect=fake_run):
ensure_knoey_vault()
assert any("create" in c and "knoey" in c for c in calls)
class TestGetSecret:
def test_returns_value(self):
with patch("knoe.core.onepassword.shutil.which", return_value="/usr/bin/op"), \
patch("knoe.core.onepassword.subprocess.run",
return_value=_make_result(0, "mysecret")):
result = get_secret("administrator")
assert result == "mysecret"
def test_returns_empty_on_failure(self):
with patch("knoe.core.onepassword.shutil.which", return_value="/usr/bin/op"), \
patch("knoe.core.onepassword.subprocess.run",
return_value=_make_result(1, "")):
result = get_secret("administrator")
assert result == ""
class TestSetSecret:
def test_edits_existing_item(self):
calls = []
def fake_run(cmd, **_):
calls.append(list(cmd))
return _make_result(0)
with patch("knoe.core.onepassword.shutil.which", return_value="/usr/bin/op"), \
patch("knoe.core.onepassword.subprocess.run", side_effect=fake_run):
set_secret("administrator", "password", "newpassword")
assert any("edit" in c for c in calls)
def test_creates_new_item(self):
calls = []
def fake_run(cmd, **_):
calls.append(list(cmd))
if "get" in cmd:
return _make_result(1)
return _make_result(0)
with patch("knoe.core.onepassword.shutil.which", return_value="/usr/bin/op"), \
patch("knoe.core.onepassword.subprocess.run", side_effect=fake_run):
set_secret("administrator", "password", "newpassword")
assert any("create" in c for c in calls)
class TestGetAdministratorPassword:
def test_delegates_to_get_secret(self):
with patch("knoe.core.onepassword.shutil.which", return_value="/usr/bin/op"), \
patch("knoe.core.onepassword.subprocess.run",
return_value=_make_result(0, "adminpass")):
result = get_administrator_password()
assert result == "adminpass"
class TestEnsureAdministratorSecret:
def test_returns_existing(self):
with patch("knoe.core.onepassword.shutil.which", return_value="/usr/bin/op"), \
patch("knoe.core.onepassword.subprocess.run",
return_value=_make_result(0, "existingpass")):
result = ensure_administrator_secret()
assert result == "existingpass"
def test_creates_when_missing(self):
calls = []
def fake_run(cmd, **_):
calls.append(list(cmd))
if "get" in cmd and "--fields" in cmd:
return _make_result(0, "")
if "get" in cmd:
return _make_result(1)
return _make_result(0)
with patch("knoe.core.onepassword.shutil.which", return_value="/usr/bin/op"), \
patch("knoe.core.onepassword.subprocess.run", side_effect=fake_run):
result = ensure_administrator_secret()
assert isinstance(result, str) and len(result) == 32
assert any("create" in c for c in calls)