"""Unit tests for terminal container-user resolution.""" from unittest.mock import AsyncMock, MagicMock import pytest from src.api.system.terminal import _resolve_container_user @pytest.mark.unit async def test_resolve_container_user_legacy_tool_type(): """Legacy tools have no manifest user.""" tool_type = MagicMock() tool_type.definition_type = "legacy" tool_type.manifest_id = None instance = MagicMock() instance.tool_type_id = "tool-type-uuid" session = AsyncMock() session.get = AsyncMock(return_value=tool_type) result = await _resolve_container_user(session, instance) assert result is None session.get.assert_awaited_once() @pytest.mark.unit async def test_resolve_container_user_manifest_no_manifest_id(): """Manifest-based tools without a manifest_id return None.""" tool_type = MagicMock() tool_type.definition_type = "manifest" tool_type.manifest_id = None instance = MagicMock() instance.tool_type_id = "tool-type-uuid" session = AsyncMock() session.get = AsyncMock(return_value=tool_type) result = await _resolve_container_user(session, instance) assert result is None @pytest.mark.unit async def test_resolve_container_user_manifest_with_user(): """Manifest-based tools resolve the declared container user.""" manifest_id = "manifest-uuid" tool_type = MagicMock() tool_type.definition_type = "manifest" tool_type.manifest_id = manifest_id manifest_def = MagicMock() manifest_def.manifest = {"user": {"name": "dev", "uid": 1000, "gid": 1000}} manifest_def.base_definition_id = None instance = MagicMock() instance.tool_type_id = "tool-type-uuid" session = AsyncMock() async def session_get(model, obj_id): if obj_id == "tool-type-uuid": return tool_type if obj_id == manifest_id: return manifest_def return None session.get.side_effect = session_get result = await _resolve_container_user(session, instance) assert result == "dev" @pytest.mark.unit async def test_resolve_container_user_manifest_with_base_definition(): """Base-definition users are inherited and overridden by tool manifests.""" base_id = "base-uuid" manifest_id = "manifest-uuid" tool_type = MagicMock() tool_type.definition_type = "manifest" tool_type.manifest_id = manifest_id manifest_def = MagicMock() manifest_def.manifest = {"user": {"name": "override", "uid": 1001, "gid": 1001}} manifest_def.base_definition_id = base_id base_def = MagicMock() base_def.manifest = { "base_image": "ubuntu:24.04", "user": {"name": "base", "uid": 1000, "gid": 1000}, } instance = MagicMock() instance.tool_type_id = "tool-type-uuid" session = AsyncMock() async def session_get(model, obj_id): if obj_id == "tool-type-uuid": return tool_type if obj_id == manifest_id: return manifest_def if obj_id == base_id: return base_def return None session.get.side_effect = session_get result = await _resolve_container_user(session, instance) assert result == "override" @pytest.mark.unit async def test_resolve_container_user_missing_manifest_definition(): """A manifest_id pointing to a missing definition returns None.""" manifest_id = "manifest-uuid" tool_type = MagicMock() tool_type.definition_type = "manifest" tool_type.manifest_id = manifest_id instance = MagicMock() instance.tool_type_id = "tool-type-uuid" session = AsyncMock() async def session_get(model, obj_id): if obj_id == "tool-type-uuid": return tool_type return None session.get.side_effect = session_get result = await _resolve_container_user(session, instance) assert result is None