from __future__ import annotations import json import time from unittest.mock import AsyncMock, MagicMock import pytest from yuxi.channels.adapters.nostr.config import NostrConfig from yuxi.channels.adapters.nostr.guard import GuardPolicy from yuxi.channels.models import ( ChannelIdentity, ChannelResponse, ChannelType, ) @pytest.fixture def sample_config() -> NostrConfig: return NostrConfig( relays=["wss://test.relay"], dm_policy="open", streaming_mode="block", ) @pytest.fixture def mock_crypto(): crypto = MagicMock() crypto.npub = "npub1test0000000000000000000000000000000000000000000000000000" crypto.pubkey_hex.return_value = "a" * 64 crypto.verify_event.return_value = True crypto.build_and_sign_event.return_value = { "id": "e" * 64, "pubkey": "a" * 64, "kind": 1, "content": "test_content", "tags": [], "created_at": int(time.time()), "sig": "s" * 128, } crypto.decrypt_nip04.return_value = "decrypted nip04" crypto.decrypt_nip17 = AsyncMock(return_value="decrypted nip17") crypto.encrypt_nip04.return_value = "encrypted_nip04_content" crypto.encrypt_nip17 = AsyncMock(return_value=json.dumps({ "id": "g" * 64, "kind": 1059, "content": "encrypted_nip17_content", "tags": [["p", "r" * 64]], })) return crypto @pytest.fixture def mock_relay_manager(): manager = MagicMock() manager.broadcast = AsyncMock(return_value=2) manager.connect_all = AsyncMock() manager.disconnect_all = AsyncMock() manager.active_count = MagicMock(return_value=(1, 2)) manager.query = AsyncMock(return_value=[]) manager.send_auth = AsyncMock(return_value={}) manager.on_connect = MagicMock() manager.on_disconnect = MagicMock() return manager @pytest.fixture def sample_guard_policy() -> GuardPolicy: return GuardPolicy( allowed_kinds={1, 4, 5, 7, 1059}, dm_policy="open", ) @pytest.fixture def sample_kind1_event() -> dict: return { "id": "a" * 64, "pubkey": "b" * 64, "kind": 1, "content": "hello world", "tags": [], "created_at": 1715000000, "sig": "c" * 128, } @pytest.fixture def sample_kind4_event() -> dict: return { "id": "d" * 64, "pubkey": "e" * 64, "kind": 4, "content": "encrypted_content_here", "tags": [["p", "f" * 64]], "created_at": 1715000000, "sig": "g" * 128, } @pytest.fixture def sample_kind5_dm_event() -> dict: return { "id": "h" * 64, "pubkey": "i" * 64, "kind": 5, "content": "deleted", "tags": [["e", "j" * 64], ["p", "k" * 64]], "created_at": 1715000000, "sig": "l" * 128, } @pytest.fixture def sample_kind5_group_event() -> dict: return { "id": "m" * 64, "pubkey": "n" * 64, "kind": 5, "content": "deleted", "tags": [["e", "o" * 64]], "created_at": 1715000000, "sig": "p" * 128, } @pytest.fixture def sample_kind7_reaction_event() -> dict: return { "id": "q" * 64, "pubkey": "r" * 64, "kind": 7, "content": "+", "tags": [["e", "s" * 64], ["p", "t" * 64]], "created_at": 1715000000, "sig": "u" * 128, } @pytest.fixture def sample_kind1059_event() -> dict: return { "id": "v" * 64, "pubkey": "w" * 64, "kind": 1059, "content": json.dumps({"kind": 9, "content": "nip17 encrypted"}), "tags": [["p", "x" * 64]], "created_at": 1715000000, "sig": "y" * 128, } @pytest.fixture def sample_response() -> ChannelResponse: return ChannelResponse( identity=ChannelIdentity( channel_id="nostr", channel_type=ChannelType.NOSTR, channel_user_id="sender_hex", channel_chat_id="dm:receiver_hex", ), content="hello nostr", )