feat: add user avatar and username, match moonlock icon style
- Add users.py with avatar detection (pwd, AccountsService, ~/.face) - Display avatar + username above action buttons - Look up 22px icon variant (same as moonlock) and render at 64px - Round action buttons (border-radius 50%) - 9 new tests for user/avatar detection (63 total)
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
# ABOUTME: Tests for current user detection and avatar loading.
|
||||
# ABOUTME: Verifies user info retrieval from the system.
|
||||
|
||||
from pathlib import Path
|
||||
from unittest.mock import patch
|
||||
|
||||
from moonset.users import get_current_user, get_avatar_path, get_default_avatar_path, User
|
||||
|
||||
|
||||
class TestGetCurrentUser:
|
||||
"""Tests for current user detection."""
|
||||
|
||||
@patch("moonset.users.os.getuid", return_value=1000)
|
||||
@patch("moonset.users.pwd.getpwuid")
|
||||
def test_returns_user_with_correct_username(self, mock_pwd, mock_uid):
|
||||
mock_pwd.return_value.pw_name = "testuser"
|
||||
mock_pwd.return_value.pw_gecos = "Test User"
|
||||
mock_pwd.return_value.pw_dir = "/home/testuser"
|
||||
mock_pwd.return_value.pw_uid = 1000
|
||||
user = get_current_user()
|
||||
assert user.username == "testuser"
|
||||
assert user.display_name == "Test User"
|
||||
assert user.home == Path("/home/testuser")
|
||||
mock_pwd.assert_called_once_with(1000)
|
||||
|
||||
@patch("moonset.users.os.getuid", return_value=1000)
|
||||
@patch("moonset.users.pwd.getpwuid")
|
||||
def test_empty_gecos_falls_back_to_username(self, mock_pwd, mock_uid):
|
||||
mock_pwd.return_value.pw_name = "testuser"
|
||||
mock_pwd.return_value.pw_gecos = ""
|
||||
mock_pwd.return_value.pw_dir = "/home/testuser"
|
||||
mock_pwd.return_value.pw_uid = 1000
|
||||
user = get_current_user()
|
||||
assert user.display_name == "testuser"
|
||||
|
||||
@patch("moonset.users.os.getuid", return_value=1000)
|
||||
@patch("moonset.users.pwd.getpwuid")
|
||||
def test_gecos_with_commas_uses_first_field(self, mock_pwd, mock_uid):
|
||||
mock_pwd.return_value.pw_name = "testuser"
|
||||
mock_pwd.return_value.pw_gecos = "Test User,,,Room 42"
|
||||
mock_pwd.return_value.pw_dir = "/home/testuser"
|
||||
mock_pwd.return_value.pw_uid = 1000
|
||||
user = get_current_user()
|
||||
assert user.display_name == "Test User"
|
||||
|
||||
|
||||
class TestGetAvatarPath:
|
||||
"""Tests for avatar path resolution."""
|
||||
|
||||
def test_returns_face_file_if_exists(self, tmp_path: Path):
|
||||
face = tmp_path / ".face"
|
||||
face.write_text("fake image")
|
||||
path = get_avatar_path(tmp_path)
|
||||
assert path == face
|
||||
|
||||
def test_returns_accountsservice_icon_if_exists(self, tmp_path: Path):
|
||||
username = "testuser"
|
||||
icons_dir = tmp_path / "icons"
|
||||
icons_dir.mkdir()
|
||||
icon = icons_dir / username
|
||||
icon.write_text("fake image")
|
||||
path = get_avatar_path(
|
||||
tmp_path, username=username, accountsservice_dir=icons_dir
|
||||
)
|
||||
assert path == icon
|
||||
|
||||
def test_face_file_takes_priority_over_accountsservice(self, tmp_path: Path):
|
||||
face = tmp_path / ".face"
|
||||
face.write_text("fake image")
|
||||
icons_dir = tmp_path / "icons"
|
||||
icons_dir.mkdir()
|
||||
icon = icons_dir / "testuser"
|
||||
icon.write_text("fake image")
|
||||
path = get_avatar_path(
|
||||
tmp_path, username="testuser", accountsservice_dir=icons_dir
|
||||
)
|
||||
assert path == face
|
||||
|
||||
def test_returns_none_when_no_avatar(self, tmp_path: Path):
|
||||
path = get_avatar_path(tmp_path)
|
||||
assert path is None
|
||||
|
||||
|
||||
class TestGetDefaultAvatarPath:
|
||||
"""Tests for default avatar fallback."""
|
||||
|
||||
def test_default_avatar_exists(self):
|
||||
"""The package default avatar must always be present."""
|
||||
path = get_default_avatar_path()
|
||||
assert path.is_file()
|
||||
|
||||
def test_default_avatar_is_svg(self):
|
||||
"""The default avatar should be an SVG file."""
|
||||
path = get_default_avatar_path()
|
||||
assert path.suffix == ".svg"
|
||||
Reference in New Issue
Block a user