errands
small jobs the runtime does for the studio.
git clone https://owenrusk.dev/errands.git
errands / tests/test_vault.py -rw-r--r-- · 3082 bytes
1 import json
2 import subprocess
3 import tempfile
4 import unittest
5 from pathlib import Path
6
7 from errands import settings, vault
8
9 ITEMS = [
10 {"name": "stillwater api", "login": {"username": "papermoth", "password": "not-a-real-token"}, "notes": None},
11 {"name": "wifi", "login": None, "notes": "office network: see the sticker on the router"},
12 {"name": "stillwater api (old)", "login": {"username": "papermoth", "password": "older"}, "notes": None},
13 ]
14
15
16 class FakeBw:
17 def __init__(self):
18 self.calls = []
19 self.stale = set()
20
21 def __call__(self, args, **kwargs):
22 self.calls.append(args[1:])
23 session = (kwargs.get("env") or {}).get("BW_SESSION")
24 if session in self.stale:
25 raise subprocess.CalledProcessError(1, args, "", "Vault is locked.")
26 if args[1] == "unlock":
27 out = "session-key"
28 elif args[1:3] == ["list", "items"]:
29 out = json.dumps(ITEMS)
30 else:
31 raise AssertionError(args)
32 return subprocess.CompletedProcess(args, 0, stdout=out + "\n", stderr="")
33
34
35 class VaultTest(unittest.TestCase):
36 def setUp(self):
37 self.dir = tempfile.TemporaryDirectory()
38 self.state = settings.STATE
39 settings.STATE = Path(self.dir.name)
40 self.bw = FakeBw()
41 self.vault = vault.Vault(self.bw)
42
43 def tearDown(self):
44 settings.STATE = self.state
45 self.dir.cleanup()
46
47 def test_exact_name_only(self):
48 self.assertEqual(self.vault.password("stillwater api"), "not-a-real-token")
49 self.assertEqual(self.vault.username("stillwater api"), "papermoth")
50
51 def test_unlocks_once(self):
52 self.vault.password("stillwater api")
53 self.vault.password("stillwater api")
54 self.assertEqual(sum(1 for call in self.bw.calls if call[0] == "unlock"), 1)
55
56 def test_session_outlives_the_process(self):
57 self.vault.password("stillwater api")
58 again = vault.Vault(self.bw)
59 again.password("stillwater api")
60 self.assertEqual(sum(1 for call in self.bw.calls if call[0] == "unlock"), 1)
61 self.assertEqual((settings.STATE / "bw-session").stat().st_mode & 0o777, 0o600)
62
63 def test_looks_in_every_folder(self):
64 self.vault.password("stillwater api")
65 self.assertIn(["list", "items", "--search", "stillwater api"], self.bw.calls)
66
67 def test_note(self):
68 self.assertEqual(self.vault.note("wifi"), "office network: see the sticker on the router")
69 self.assertEqual(self.vault.note("stillwater api"), "")
70
71 def test_stale_session(self):
72 self.vault.password("stillwater api")
73 self.bw.stale.add("session-key")
74 with self.assertRaises(subprocess.CalledProcessError):
75 # the fake hands out the same key, so the second try fails too and gives up.
76 self.vault.password("stillwater api")
77 self.assertEqual(sum(1 for call in self.bw.calls if call[0] == "unlock"), 2)
78
79 def test_missing(self):
80 with self.assertRaises(LookupError):
81 self.vault.password("nothing like it")