1+ """Tests for turnserver functionality, particularly metadata integration."""
2+
3+ import socket
4+ import tempfile
5+ import threading
6+ from pathlib import Path
7+
8+ from chatmaild .config import read_config , write_initial_config
9+ from chatmaild .metadata import MetadataDictProxy , Metadata
10+ from chatmaild .notifier import Notifier
11+ from chatmaild .turnserver import turn_credentials
12+
13+
14+ def test_turn_credentials_function_with_custom_socket ():
15+ """Test that turn_credentials function works with a custom socket path from config."""
16+ # Create a temporary directory and socket file
17+ temp_dir = Path (tempfile .mkdtemp ())
18+ temp_socket_path = temp_dir / "test_turn.socket"
19+
20+ # Create a mock TURN credentials server
21+ def mock_server ():
22+ server_sock = socket .socket (socket .AF_UNIX , socket .SOCK_STREAM )
23+ server_sock .bind (str (temp_socket_path ))
24+ server_sock .listen (1 )
25+
26+ # Accept connection and send mock credentials
27+ conn , addr = server_sock .accept ()
28+ with conn :
29+ conn .send (b"mock_turn_credentials_abc123\n " )
30+ server_sock .close ()
31+
32+ # Start server in a background thread
33+ server_thread = threading .Thread (target = mock_server , daemon = True )
34+ server_thread .start ()
35+
36+ # Create a config with custom socket path
37+ config_path = temp_dir / "chatmail.ini"
38+ write_initial_config (config_path , "test.example.org" , {
39+ "turn_socket_path" : str (temp_socket_path )
40+ })
41+ config = read_config (config_path )
42+
43+ # Allow time for server to start
44+ import time
45+ time .sleep (0.01 )
46+
47+ # Test that turn_credentials can connect using the config
48+ credentials = turn_credentials (config )
49+ assert credentials == "mock_turn_credentials_abc123"
50+
51+ server_thread .join (timeout = 1 ) # Clean up thread
52+
53+
54+ def test_metadata_turn_lookup_integration (tmp_path ):
55+ """Test that metadata service properly handles TURN metadata lookups."""
56+ # Create mock config with custom turn socket path
57+ config_path = tmp_path / "chatmail.ini"
58+ socket_path = tmp_path / "test_turn.socket"
59+ write_initial_config (config_path , "example.org" , {
60+ "turn_socket_path" : str (socket_path )
61+ })
62+ config = read_config (config_path )
63+
64+ # Create mock TURN server to return credentials
65+ def mock_turn_server ():
66+ import os
67+ os .makedirs (socket_path .parent , exist_ok = True ) # Ensure parent directory exists
68+
69+ server_sock = socket .socket (socket .AF_UNIX , socket .SOCK_STREAM )
70+ server_sock .bind (str (socket_path ))
71+ server_sock .listen (1 )
72+
73+ # Accept connection and send mock credentials
74+ conn , addr = server_sock .accept ()
75+ with conn :
76+ conn .send (b"test_creds_12345\n " )
77+ server_sock .close ()
78+
79+ server_thread = threading .Thread (target = mock_turn_server , daemon = True )
80+ server_thread .start ()
81+
82+ import time
83+ time .sleep (0.01 ) # Allow server to start
84+
85+ # Create a MetadataDictProxy with config
86+ queue_dir = tmp_path / "queue"
87+ queue_dir .mkdir ()
88+ notifier = Notifier (queue_dir )
89+ metadata = Metadata (tmp_path / "vmail" )
90+
91+ dict_proxy = MetadataDictProxy (
92+ notifier = notifier ,
93+ metadata = metadata ,
94+ iroh_relay = "https://example.org" ,
95+ turn_hostname = "example.org" ,
96+ config = config
97+ )
98+
99+ # Simulate a lookup for TURN credentials using the correct format
100+ # Input: "shared/0123/vendor/vendor.dovecot/pvt/server/vendor/deltachat/turn"
101+ # After parts[0].split("/", 2):
102+ # - keyparts[0] = "shared"
103+ # - keyparts[1] = "0123"
104+ # - keyparts[2] = "vendor/vendor.dovecot/pvt/server/vendor/deltachat/turn"
105+ # So keyname = keyparts[2] should match "vendor/vendor.dovecot/pvt/server/vendor/deltachat/turn"
106+ parts = [
107+ "shared/0123/vendor/vendor.dovecot/pvt/server/vendor/deltachat/turn" ,
108+ "dummy@user.org"
109+ ]
110+
111+ # Call handle_lookup directly
112+ result = dict_proxy .handle_lookup (parts )
113+
114+ # Verify the response format is correct for TURN credentials
115+ assert result .startswith ("O" ) # Output response starts with 'O'
116+ assert ":3478:" in result # Contains port 3478
117+ assert "test_creds_12345" in result # Contains credentials returned by mock server
118+ assert "example.org:3478:test_creds_12345" in result
119+
120+ server_thread .join (timeout = 1 ) # Clean up thread
0 commit comments