import asyncio from unittest import mock from testfixtures import LogCapture import bumper def return_send_data(data): return data def mock_transport_extra_info(): return ("127.0.0.1", 5223) async def test_xmpp_server(): xmpp_address = ("127.0.0.1", 5223) xmpp_server = bumper.XMPPServer(xmpp_address) await xmpp_server.start_async_server() with LogCapture("xmppserver") as l: reader, writer = await asyncio.open_connection("127.0.0.1", 5223) writer.write(b"") # Start stream await writer.drain() await asyncio.sleep(0.1) assert len(xmpp_server.clients) == 1 # Client count increased assert ( xmpp_server.clients[0].address[1] == writer.transport.get_extra_info("sockname")[1] ) writer.close() # Close connection await writer.wait_closed() await asyncio.sleep(0.1) assert len(xmpp_server.clients) == 0 # Client count decreased reader, writer = await asyncio.open_connection("127.0.0.1", 5223) writer.write(b"") # Start stream await writer.drain() await asyncio.sleep(0.1) xmpp_server.disconnect() async def test_client_connect_no_starttls(): test_transport = mock.Mock() test_transport.get_extra_info = mock.Mock(return_value=mock_transport_extra_info()) test_transport.write = mock.Mock(return_value=return_send_data) xmppclient = bumper.xmppserver.XMPPAsyncClient(test_transport) xmppclient.state = xmppclient.CONNECT # Set client state to CONNECT mock_send = xmppclient.send = mock.Mock(side_effect=return_send_data) # Send connect stream from "client" test_data = b"" xmppclient._parse_data(test_data) # Expect 2 calls to send assert mock_send.call_count == 2 # Server opens stream assert ( mock_send.mock_calls[0][1][0] == '' ) # Server tells client available features assert ( mock_send.mock_calls[1][1][0] == 'PLAIN' ) # Reset mock calls mock_send.reset_mock() # Client sendss auth - Ignoring the starttls, we don't force this with bumper test_data = b'AGZ1aWRfdG1wdXNlcgAwL0lPU0Y1M0QwN0JBL3VzXzg5ODgwMmZkYmM0NDQxYjBiYzgxNWIxZDFjNjgzMDJl' xmppclient._parse_data(test_data) assert ( mock_send.mock_calls[0][1][0] == '' ) # Client successfully authenticated assert xmppclient.state == xmppclient.INIT # Client moved to INIT state async def test_client_end_stream(): test_transport = mock.Mock() test_transport.get_extra_info = mock.Mock(return_value=mock_transport_extra_info()) test_transport.write = mock.Mock(return_value=return_send_data) xmppclient = bumper.xmppserver.XMPPAsyncClient(test_transport) xmppclient.state = xmppclient.CONNECT # Set client state to CONNECT mock_send = xmppclient.send = mock.Mock(side_effect=return_send_data) # Send end stream from "client" test_data = b"" xmppclient._parse_data(test_data) # Expect 2 calls to send assert mock_send.call_count == 1 # Server opens stream assert mock_send.mock_calls[0][1][0] == "" # Reset mock calls mock_send.reset_mock() # Send abnormal stream from "client" test_data = b"" xmppclient._parse_data(test_data) # Reset mock calls mock_send.reset_mock() # Send blank from "client" test_data = b"" xmppclient._parse_data(test_data) async def test_client_connect_starttls_called(): test_transport = mock.Mock() test_transport.get_extra_info = mock.Mock(return_value=mock_transport_extra_info()) test_transport.write = mock.Mock(return_value=return_send_data) xmppclient = bumper.xmppserver.XMPPAsyncClient(test_transport) xmppclient.state = xmppclient.CONNECT # Set client state to CONNECT mock_send = xmppclient.send = mock.Mock(side_effect=return_send_data) # Send connect stream from "client" test_data = b"" xmppclient._parse_data(test_data) # Expect 2 calls to send assert mock_send.call_count == 2 # Server opens stream assert ( mock_send.mock_calls[0][1][0] == '' ) # Server tells client available features assert ( mock_send.mock_calls[1][1][0] == 'PLAIN' ) # Reset mock calls mock_send.reset_mock() mock_tls = xmppclient._handle_starttls = mock.Mock() # Send start tls from "client" test_data = b"" xmppclient._parse_data(test_data) # After upgrading connection, server tells client to proceed with auth again assert mock_tls.called xmppclient.TLSUpgraded = True # After TLS is upgraded, Client establishes session again and will auth this time # Send connect stream from "client" test_data = b"" xmppclient._parse_data(test_data) # Expect 2 calls to send assert mock_send.call_count == 2 # Server opens stream assert ( mock_send.mock_calls[0][1][0] == '' ) # Server tells client available features (without STARTTLS) assert ( mock_send.mock_calls[1][1][0] == 'PLAIN' ) # Reset mock calls mock_send.reset_mock() # Client sends auth test_data = b'AGZ1aWRfdG1wdXNlcgAwL0lPU0Y1M0QwN0JBL3VzXzg5ODgwMmZkYmM0NDQxYjBiYzgxNWIxZDFjNjgzMDJl' xmppclient._parse_data(test_data) assert ( mock_send.mock_calls[0][1][0] == '' ) # Client successfully authenticated assert xmppclient.state == xmppclient.INIT # Client moved to INIT state async def test_client_init(): test_transport = mock.Mock() test_transport.get_extra_info = mock.Mock(return_value=mock_transport_extra_info()) test_transport.write = mock.Mock(return_value=return_send_data) xmppclient = bumper.xmppserver.XMPPAsyncClient(test_transport) xmppclient.state = xmppclient.INIT # Set client state to INIT xmppclient.uid = "fuid_tmpuser" xmppclient.resource = "IOSF53D07BA" xmppclient.bumper_jid = "fuid_tmpuser@ecouser.net/IOSF53D07BA" xmppclient.type = xmppclient.CONTROLLER mock_send = xmppclient.send = mock.Mock(side_effect=return_send_data) # Send connect stream from "client" test_data = b"" xmppclient._parse_data(test_data) # Expect 2 calls to send assert mock_send.call_count == 2 # Server opens stream assert ( mock_send.mock_calls[0][1][0] == '' ) # Server tells client binds assert ( mock_send.mock_calls[1][1][0] == '' ) # Reset mock calls mock_send.reset_mock() # Send bind from "client" test_data = b'IOSF53D07BA' xmppclient._parse_data(test_data) assert ( mock_send.mock_calls[0][1][0] == 'fuid_tmpuser@ecouser.net/IOSF53D07BA' ) # client successfully binded assert xmppclient.state == xmppclient.BIND # client moved to BIND state # Reset mock calls mock_send.reset_mock() # Send set session from client test_data = b'' xmppclient._parse_data(test_data) assert xmppclient.state == xmppclient.READY # client moved to READY state assert ( mock_send.mock_calls[0][1][0] == '' ) # client ready # Reset mock calls mock_send.reset_mock() # Send presence from client test_data = b'' xmppclient._parse_data(test_data) assert ( mock_send.mock_calls[0][1][0] == ' dummy ' ) # client presence - dummy response async def test_bot_connect(): test_transport = mock.Mock() test_transport.get_extra_info = mock.Mock(return_value=mock_transport_extra_info()) test_transport.write = mock.Mock(return_value=return_send_data) xmppclient = bumper.xmppserver.XMPPAsyncClient(test_transport) xmppclient.state = xmppclient.CONNECT # Set client state to CONNECT mock_send = xmppclient.send = mock.Mock(side_effect=return_send_data) # Send connect stream from "bot" test_data = b"" xmppclient._parse_data(test_data) # Expect 2 calls to send assert mock_send.call_count == 2 # Server opens stream assert ( mock_send.mock_calls[0][1][0] == '' ) # Server tells client available features assert ( mock_send.mock_calls[1][1][0] == 'PLAIN' ) # Reset mock calls mock_send.reset_mock() # Send auth from "bot" test_data = b"AEUwMDAwMDAwMDAwMDAwMDAxMjM0AGVuY3J5cHRlZF9wYXNz" xmppclient._parse_data(test_data) assert ( mock_send.mock_calls[0][1][0] == '' ) # Bot successfully authenticated assert xmppclient.state == xmppclient.INIT # Bot moved to INIT state assert xmppclient.type == xmppclient.BOT # Client type is now bot async def test_bot_init(): test_transport = mock.Mock() test_transport.get_extra_info = mock.Mock(return_value=mock_transport_extra_info()) test_transport.write = mock.Mock(return_value=return_send_data) xmppclient = bumper.xmppserver.XMPPAsyncClient(test_transport) xmppclient.state = xmppclient.INIT # Set client state to INIT xmppclient.uid = "E0000000000000001234" xmppclient.devclass = "159" xmppclient.type = xmppclient.BOT mock_send = xmppclient.send = mock.Mock(side_effect=return_send_data) # Send connect stream from "bot" test_data = b"" xmppclient._parse_data(test_data) # Expect 2 calls to send assert mock_send.call_count == 2 # Server opens stream assert ( mock_send.mock_calls[0][1][0] == '' ) # Server tells client binds assert ( mock_send.mock_calls[1][1][0] == '' ) # Reset mock calls mock_send.reset_mock() # Send bind from "bot" test_data = b"atom" xmppclient._parse_data(test_data) assert ( mock_send.mock_calls[0][1][0] == 'E0000000000000001234@159.ecorobot.net/atom' ) # Bot successfully binded assert xmppclient.state == xmppclient.BIND # Bot moved to BIND state # Reset mock calls mock_send.reset_mock() # Send set session from bot test_data = b"" xmppclient._parse_data(test_data) assert xmppclient.state == xmppclient.READY # Bot moved to READY state assert ( mock_send.mock_calls[0][1][0] == '' ) # Bot ready # Reset mock calls mock_send.reset_mock() # Send presence from bot test_data = b"hello world" xmppclient._parse_data(test_data) assert ( mock_send.mock_calls[0][1][0] == ' dummy ' ) # bot presence - dummy response async def test_ping_server(): test_transport = mock.Mock() test_transport.get_extra_info = mock.Mock(return_value=mock_transport_extra_info()) test_transport.write = mock.Mock(return_value=return_send_data) xmppclient = bumper.xmppserver.XMPPAsyncClient(test_transport) xmppclient.state = xmppclient.READY # Set client state to READY xmppclient.uid = "E0000000000000001234" xmppclient.devclass = "159" mock_send = xmppclient.send = mock.Mock(side_effect=return_send_data) # Ping from bot test_data = b'' xmppclient._parse_data(test_data) assert ( mock_send.mock_calls[0][1][0] == '' ) # ping response async def test_ping_client_to_client(): test_transport = mock.Mock() test_transport.get_extra_info = mock.Mock(return_value=mock_transport_extra_info()) test_transport.write = mock.Mock(return_value=return_send_data) xmppclient = bumper.xmppserver.XMPPAsyncClient(test_transport) xmppclient.state = xmppclient.READY # Set client state to READY xmppclient.uid = "E0000000000000001234" xmppclient.devclass = "159" xmppclient.bumper_jid = "E0000000000000001234@159.ecorobot.net/atom" mock_send = xmppclient.send = mock.Mock(side_effect=return_send_data) xmppclient2 = bumper.xmppserver.XMPPAsyncClient(test_transport) xmppclient2.state = xmppclient.READY # Set client state to READY xmppclient2.uid = "fuid_tmpuser" xmppclient2.resource = "IOSF53D07BA" xmppclient2.bumper_jid = "fuid_tmpuser@ecouser.net/IOSF53D07BA" mock_send2 = xmppclient2.send = mock.Mock(side_effect=return_send_data) bumper.xmppserver.XMPPServer.clients.append(xmppclient) bumper.xmppserver.XMPPServer.clients.append(xmppclient2) # Ping from user to bot test_data = b'' xmppclient._parse_data(test_data) assert ( mock_send2.mock_calls[0][1][0] == '' ) # ping response # Ping response from bot to user test_data = b"" xmppclient2._parse_data(test_data) assert ( mock_send.mock_calls[0][1][0] == '' ) # ping response async def test_client_send_iq(): test_transport = mock.Mock() test_transport.get_extra_info = mock.Mock(return_value=mock_transport_extra_info()) test_transport.write = mock.Mock(return_value=return_send_data) xmppclient = bumper.xmppserver.XMPPAsyncClient(test_transport) xmppclient.state = xmppclient.READY # Set client state to READY xmppclient.uid = "fuid_tmpuser" xmppclient.resource = "IOSF53D07BA" xmppclient.bumper_jid = "fuid_tmpuser@ecouser.net/IOSF53D07BA" xmppclient.type - xmppclient.CONTROLLER mock_send = xmppclient.send = mock.Mock(side_effect=return_send_data) bumper.xmppserver.XMPPServer.clients.append(xmppclient) xmppclient2 = bumper.xmppserver.XMPPAsyncClient(test_transport) xmppclient2.state = xmppclient.READY # Set client state to READY xmppclient2.uid = "E0000000000000001234" xmppclient2.devclass = "159" xmppclient2.bumper_jid = "E0000000000000001234@159.ecorobot.net/atom" xmppclient2.type = xmppclient2.BOT mock_send2 = xmppclient2.send = mock.Mock(side_effect=return_send_data) bumper.xmppserver.XMPPServer.clients.append(xmppclient2) # Roster IQ - Only seen from Android app so far test_data = ( b'' ) xmppclient._parse_data(test_data) assert ( mock_send.mock_calls[0][1][0] == '' ) # feature not implemented response # Reset mock calls mock_send.reset_mock() # Bot Command test_data = b'' xmppclient._parse_data(test_data) assert ( mock_send2.mock_calls[0][1][0] == '' ) # command was sent to bot # Reset mock calls mock_send.reset_mock() # Bot response to query test_data = b'' xmppclient2._parse_data(test_data) assert ( mock_send.mock_calls[0][1][0] == '' ) # result sent to client # Reset mock calls mock_send.reset_mock() # Bot result test_data = b"" xmppclient2._parse_data(test_data) assert ( mock_send.mock_calls[0][1][0] == '' ) # result sent to ecouser.net # Reset mock calls mock_send.reset_mock() # Bot iq set test_data = b"" xmppclient2._parse_data(test_data) assert ( mock_send.mock_calls[0][1][0] == '' ) # result sent to ecouser.net # Reset mock calls mock_send.reset_mock() # Bot error report test_data = b"" xmppclient2._parse_data(test_data) assert ( mock_send.mock_calls[0][1][0] == '' ) # result sent to ecouser.net # Reset mock calls mock_send.reset_mock() # Bot "DorpError" to all test_data = b"" xmppclient2._parse_data(test_data) assert mock_send.mock_calls[0][1][0] == ( '' ) # result sent to ecouser.net # Reset mock calls mock_send.reset_mock()