Files
net-kingdom/local-identity/tests/test_user.py
tegwick 4491beaffe feat(local-identity): implement Stage 1 — core file store (NK-WP-0002-T01)
Deliverables:
- src/local_identity/gecos.py: /etc/passwd GECOS parsing, current_username()
- src/local_identity/user.py: UserRecord dataclass, ProductionIdentity, make_test_user()
  - Pure test-user derivation: <user>N / +testN email alias / source_user tracking
- src/local_identity/store.py: file store CRUD backed by LOCAL_IDENTITY_HOME
  - ~/.local-identity/ mode 700, user files mode 600
  - All path lookups dynamic (env-var override enables clean test isolation)
- src/local_identity/cli.py: init/list/show commands; email from flag > config > prompt
- pyproject.toml + uv.lock: pyyaml dep, local-identity script entry point

Tests (41 passing):
- test_gecos.py: 9 tests — simple/comma/empty/non-ASCII/whitespace GECOS, fallback
- test_user.py: 14 tests — test-user derivation, YAML roundtrip, non-ASCII, idempotency
- test_store.py: 18 tests — dir creation, permissions (700/600), CRUD, list, config,
  idempotency (reinit with --force produces identical users)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-02 00:01:54 +01:00

92 lines
3.2 KiB
Python

"""Tests for UserRecord and make_test_user."""
import pytest
from local_identity.user import UserRecord, ProductionIdentity, make_test_user
PRIMARY = UserRecord(
username="tegwick",
fullname="Bernd Worsch",
email="bernd.worsch@gmail.com",
)
class TestMakeTestUser:
def test_username_suffix(self):
assert make_test_user(PRIMARY, 1).username == "tegwick1"
assert make_test_user(PRIMARY, 2).username == "tegwick2"
def test_fullname_suffix(self):
assert make_test_user(PRIMARY, 1).fullname == "Bernd Worsch+test1"
assert make_test_user(PRIMARY, 2).fullname == "Bernd Worsch+test2"
def test_email_plus_alias(self):
assert make_test_user(PRIMARY, 1).email == "bernd.worsch+test1@gmail.com"
assert make_test_user(PRIMARY, 2).email == "bernd.worsch+test2@gmail.com"
def test_generated_flag(self):
assert make_test_user(PRIMARY, 1).generated is True
def test_source_user(self):
assert make_test_user(PRIMARY, 1).source_user == "tegwick"
def test_environment_is_local(self):
assert make_test_user(PRIMARY, 1).environment == "local"
def test_email_without_at(self):
p = UserRecord(username="foo", fullname="Foo Bar", email="noemail")
assert make_test_user(p, 1).email == "noemail+test1"
def test_invalid_n_raises(self):
with pytest.raises(ValueError):
make_test_user(PRIMARY, 0)
def test_deterministic(self):
a = make_test_user(PRIMARY, 1)
b = make_test_user(PRIMARY, 1)
assert a.to_dict() == b.to_dict()
class TestUserRecordYamlRoundtrip:
def test_basic_roundtrip(self):
text = PRIMARY.to_yaml()
loaded = UserRecord.from_yaml(text)
assert loaded.username == PRIMARY.username
assert loaded.fullname == PRIMARY.fullname
assert loaded.email == PRIMARY.email
assert loaded.environment == PRIMARY.environment
assert loaded.generated == PRIMARY.generated
assert loaded.source_user is None
assert loaded.production_identity is None
def test_roundtrip_with_production_identity(self):
u = UserRecord(
username="tegwick",
fullname="Bernd Worsch",
email="bernd.worsch@gmail.com",
production_identity=ProductionIdentity(
username="tegwick", realm="net-kingdom"
),
)
loaded = UserRecord.from_yaml(u.to_yaml())
assert loaded.production_identity is not None
assert loaded.production_identity.username == "tegwick"
assert loaded.production_identity.realm == "net-kingdom"
def test_roundtrip_test_user(self):
t = make_test_user(PRIMARY, 1)
loaded = UserRecord.from_yaml(t.to_yaml())
assert loaded.generated is True
assert loaded.source_user == "tegwick"
def test_yaml_contains_expected_fields(self):
text = PRIMARY.to_yaml()
assert "username: tegwick" in text
assert "environment: local" in text
assert "generated: false" in text
def test_non_ascii_roundtrip(self):
u = UserRecord(username="amueller", fullname="Ärger Müller", email="a@b.de")
loaded = UserRecord.from_yaml(u.to_yaml())
assert loaded.fullname == "Ärger Müller"