"""Structure tools (search, info, market, container logs), auth & ESI mocked.""" import asyncio import pytest from conftest import route from familiar import auth, structures from familiar.server import mcp CHARS = [ {"character_id": 99, "character_name": "Alpha", "scopes": []}, {"character_id": 100, "character_name": "Beta", "scopes": []}, ] @pytest.fixture def fake_auth(monkeypatch): monkeypatch.setattr(auth, "list_characters", lambda: list(CHARS)) async def get_auth(cid, **kw): return f"token-{cid}", cid monkeypatch.setattr(auth, "get_auth", get_auth) def resolve(identifier): for c in CHARS: if ( str(c["character_id"]) == str(identifier) or (c["character_name"] or "").lower() == str(identifier).lower() ): return c["character_id"] raise auth.NotAuthenticated("no such character") monkeypatch.setattr(auth, "resolve_character", resolve) return CHARS def test_search_structures_per_character(mock_esi, fake_auth): mock_esi(lambda r: route(r, {"/search/": {"structure": [1001, 1002]}})) res = asyncio.run(structures.search_structures("Sotiyo")) assert len(res["characters"]) == 2 assert res["characters"][0]["matches"] == [1001, 1002] def test_get_structure_uses_one_token(mock_esi, fake_auth): body = {"name": "Jita Trade Hub Citadel", "solar_system_id": 30000142, "type_id": 35834} mock_esi(lambda r: route(r, {"/universe/structures/": body})) res = asyncio.run(structures.get_structure(1001)) assert res["structure_id"] == 1001 assert res["solar_system_id"] == 30000142 def test_get_structure_market(mock_esi, fake_auth): orders = [{"order_id": 1, "price": 5.0}, {"order_id": 2, "price": 6.0}] mock_esi(lambda r: route(r, {"/markets/structures/": orders})) res = asyncio.run(structures.get_structure_market(1001, character="Alpha")) assert res["count"] == 2 def test_container_logs_resolves_corp(mock_esi, fake_auth): fixtures = { "/containers/logs/": [{"action": "add"}], "/characters/": {"corporation_id": 2000}, } mock_esi(lambda r: route(r, fixtures)) res = asyncio.run(structures.get_container_logs(character=99)) assert res["characters"][0]["corporation_id"] == 2000 assert res["characters"][0]["count"] == 1 def test_structure_tools_registered(): tools = {t.name for t in asyncio.run(mcp.list_tools())} assert { "search_structures", "get_structure", "get_structure_market", "get_container_logs", } <= tools