- 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)
96 lines
3.5 KiB
Python
96 lines
3.5 KiB
Python
# 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"
|