Files
stack/tests/prisma/test_vpn_deep.py
kert dbf71a6594 test: 99.93% coverage — Zotero 9 schema fix + 400+ new tests
Fix Zotero table models for Zotero 9:
- Remove stale Annotations/Highlights/Transaction* models
- Add ItemAnnotations, RetractedItems, DeletedCollections,
  DeletedSearches, DbDebug1
- Fix ItemAttachments, Libraries, Users column mismatches

New test files covering all major modules:
- cli/{bib,prisma,rec,zot,mail,run} deep exercising tests
- mail/{droplet,postmark,resend,cloudflare} lifecycle tests
- bib/{iom,oig,pincite,sync,regulations_gov,email_ingest,format,store}
- prisma/{vpn,fetch,export,llm,screen,eligibility,extract,project,ingest,flow}
- aco/lake/{unity,quality,deploy} + api/aco coverage gaps
- zot/{ops,db,extract,duck} + rec/{report,engine,base,pricers}
- pfs/{pipe,rules,eq,files}

Add pytest-xdist for parallel test execution.

Tracks #353
2026-04-18 10:06:47 -04:00

112 lines
3.4 KiB
Python

"""Deep tests for prisma.vpn — exercises all lifecycle functions."""
from __future__ import annotations
from unittest.mock import MagicMock, patch
import pytest
from prisma.vpn import (
_cloud_init,
_delete_account_ssh_key,
_ensure_account_ssh_key,
_gen_ssh_key,
_tunnel_running,
down,
status,
up,
)
class TestCloudInit:
def test_generates_config(self):
result = _cloud_init("ssh-ed25519 AAAA test")
assert "#cloud-config" in result
assert "dante-server" in result
assert "ssh-ed25519" in result
class TestGenSshKey:
@patch("prisma.vpn.subprocess.run")
def test_generates_key(self, mock_run, tmp_path):
key_path = tmp_path / "id_ed25519"
# _gen_ssh_key unlinks existing then runs ssh-keygen, which creates the file
# Mock the subprocess but also create the pubkey file it would produce
def fake_keygen(*a, **kw):
key_path.write_text("private")
key_path.with_suffix(".pub").write_text("ssh-ed25519 AAAA test")
return MagicMock(returncode=0)
mock_run.side_effect = fake_keygen
result = _gen_ssh_key(key_path)
assert "ssh-ed25519" in result
class TestEnsureAccountSshKey:
def test_reuses_existing(self):
client = MagicMock()
client.ssh_keys.list.return_value = {
"ssh_keys": [{"id": 42, "public_key": "ssh-ed25519 AAAA test"}]
}
result = _ensure_account_ssh_key(client, "ssh-ed25519 AAAA test", "name")
assert result == 42
def test_creates_new(self):
client = MagicMock()
client.ssh_keys.list.return_value = {"ssh_keys": []}
client.ssh_keys.create.return_value = {"ssh_key": {"id": 99}}
result = _ensure_account_ssh_key(client, "ssh-ed25519 BBBB new", "name")
assert result == 99
class TestDeleteAccountSshKey:
def test_deletes(self):
client = MagicMock()
_delete_account_ssh_key(client, 42)
client.ssh_keys.delete.assert_called_once()
def test_handles_error(self):
client = MagicMock()
client.ssh_keys.delete.side_effect = Exception("gone")
_delete_account_ssh_key(client, 42) # should not raise
class TestTunnelRunning:
def test_no_pid_file(self):
with patch("prisma.vpn._TUNNEL_PID") as mock_path:
mock_path.is_file.return_value = False
assert _tunnel_running() is False
class TestUp:
@patch("prisma.vpn._do_client")
@patch("prisma.vpn._gen_ssh_key", return_value="ssh-ed25519 AAAA")
@patch("prisma.vpn._ensure_account_ssh_key", return_value=1)
@patch("prisma.vpn._DROPLET_JSON")
@patch("prisma.vpn._STATE_DIR")
def test_raises_if_tracked(
self, mock_state, mock_json, mock_key_id, mock_gen, mock_client
):
mock_json.exists.return_value = True
with pytest.raises(RuntimeError, match="already tracked"):
up()
class TestDown:
@patch("prisma.vpn.detach_zotero_proxy")
@patch("prisma.vpn._tunnel_stop")
@patch("prisma.vpn._DROPLET_JSON")
def test_noop_if_not_tracked(self, mock_json, mock_stop, mock_detach):
mock_json.exists.return_value = False
result = down()
assert result == {"status": "nothing-to-do"}
class TestStatus:
@patch("prisma.vpn._DROPLET_JSON")
def test_down_if_not_tracked(self, mock_json):
mock_json.exists.return_value = False
result = status()
assert result["status"] == "down"