ForcePilot/backend/test/unit/channels/test_nostr_nip05.py

122 lines
4.4 KiB
Python
Raw Normal View History

from __future__ import annotations
from unittest.mock import AsyncMock, MagicMock, patch
import pytest
from yuxi.channels.adapters.nostr.nip05 import verify_nip05
class AsyncContextManagerMock:
def __init__(self, return_value=None):
self.return_value = return_value
async def __aenter__(self):
return self.return_value
async def __aexit__(self, *args, **kwargs):
pass
class TestNip05:
@pytest.fixture
def mock_session_factory(self):
pubkey_hex = "79c2cae114ea28a981e7559b4fe7854a473521a8d22a66bbab9fa248eb820ff6"
async def json_response():
return {"names": {"alice": pubkey_hex, "eve": pubkey_hex}}
mock_resp = MagicMock()
mock_resp.status = 200
mock_resp.json = json_response
mock_get_cm = AsyncContextManagerMock(return_value=mock_resp)
mock_session = AsyncContextManagerMock()
mock_session.return_value = mock_session
mock_session.get = MagicMock(return_value=mock_get_cm)
return mock_session
@pytest.mark.asyncio
async def test_verify_valid(self, mock_session_factory):
pubkey_hex = "79c2cae114ea28a981e7559b4fe7854a473521a8d22a66bbab9fa248eb820ff6"
with patch("aiohttp.ClientSession", return_value=mock_session_factory):
result = await verify_nip05("alice@example.com", pubkey_hex)
assert result is True
@pytest.mark.asyncio
async def test_verify_no_at_sign(self):
result = await verify_nip05("invalid_name", "some_pubkey_hex")
assert result is False
@pytest.mark.asyncio
async def test_verify_http_error(self):
pubkey_hex = "79c2cae114ea28a981e7559b4fe7854a473521a8d22a66bbab9fa248eb820ff6"
mock_resp = MagicMock()
mock_resp.status = 404
mock_get_cm = AsyncContextManagerMock(return_value=mock_resp)
mock_session = AsyncContextManagerMock()
mock_session.return_value = mock_session
mock_session.get = MagicMock(return_value=mock_get_cm)
with patch("aiohttp.ClientSession", return_value=mock_session):
result = await verify_nip05("alice@example.com", pubkey_hex)
assert result is False
@pytest.mark.asyncio
async def test_verify_network_error(self):
pubkey_hex = "79c2cae114ea28a981e7559b4fe7854a473521a8d22a66bbab9fa248eb820ff6"
mock_session = AsyncContextManagerMock()
mock_session.return_value = mock_session
mock_session.get = MagicMock(side_effect=Exception("Network error"))
with patch("aiohttp.ClientSession", return_value=mock_session):
result = await verify_nip05("bob@example.com", pubkey_hex)
assert result is False
@pytest.mark.asyncio
async def test_verify_name_not_found(self):
pubkey_hex = "79c2cae114ea28a981e7559b4fe7854a473521a8d22a66bbab9fa248eb820ff6"
async def json_empty():
return {"names": {}}
mock_resp = MagicMock()
mock_resp.status = 200
mock_resp.json = json_empty
mock_get_cm = AsyncContextManagerMock(return_value=mock_resp)
mock_session = AsyncContextManagerMock()
mock_session.return_value = mock_session
mock_session.get = MagicMock(return_value=mock_get_cm)
with patch("aiohttp.ClientSession", return_value=mock_session):
result = await verify_nip05("charlie@example.com", pubkey_hex)
assert result is False
@pytest.mark.asyncio
async def test_verify_pubkey_mismatch(self):
async def json_mismatch():
return {"names": {"dave": "different_pubkey_hex"}}
mock_resp = MagicMock()
mock_resp.status = 200
mock_resp.json = json_mismatch
mock_get_cm = AsyncContextManagerMock(return_value=mock_resp)
mock_session = AsyncContextManagerMock()
mock_session.return_value = mock_session
mock_session.get = MagicMock(return_value=mock_get_cm)
with patch("aiohttp.ClientSession", return_value=mock_session):
result = await verify_nip05("dave@example.com", "expected_pubkey")
assert result is False
@pytest.mark.asyncio
async def test_verify_case_insensitive_pubkey_match(self, mock_session_factory):
pubkey_hex = "79c2cae114ea28a981e7559b4fe7854a473521a8d22a66bbab9fa248eb820ff6"
with patch("aiohttp.ClientSession", return_value=mock_session_factory):
result = await verify_nip05("eve@example.com", pubkey_hex)
assert result is True