diff --git a/socketio/asgi.py b/socketio/asgi.py index 2339462..bb77d88 100644 --- a/socketio/asgi.py +++ b/socketio/asgi.py @@ -1,7 +1,7 @@ import engineio -class ASGIApp(engineio.ASGIApp): +class ASGIApp(engineio.ASGIApp): # pragma: no cover """ASGI application middleware for Socket.IO. This middleware dispatches traffic to an Socket.IO application. It can diff --git a/socketio/asyncio_namespace.py b/socketio/asyncio_namespace.py index 2ec24b9..07a0e54 100644 --- a/socketio/asyncio_namespace.py +++ b/socketio/asyncio_namespace.py @@ -120,7 +120,7 @@ class AsyncClientNamespace(namespace.ClientNamespace): Note: this method is a coroutine. """ - return await self.server.emit(event, data=data, + return await self.client.emit(event, data=data, namespace=namespace or self.namespace, callback=callback) @@ -133,7 +133,7 @@ class AsyncClientNamespace(namespace.ClientNamespace): Note: this method is a coroutine. """ - return await self.server.send(data, + return await self.client.send(data, namespace=namespace or self.namespace, callback=callback) @@ -146,5 +146,5 @@ class AsyncClientNamespace(namespace.ClientNamespace): Note: this method is a coroutine. """ - return await self.server.disconnect( + return await self.client.disconnect( namespace=namespace or self.namespace) diff --git a/socketio/namespace.py b/socketio/namespace.py index 029779f..158657f 100644 --- a/socketio/namespace.py +++ b/socketio/namespace.py @@ -149,7 +149,7 @@ class ClientNamespace(BaseNamespace): that when the ``namespace`` argument is not given the namespace associated with the class is used. """ - return self.server.send(data, namespace=namespace or self.namespace, + return self.client.send(data, namespace=namespace or self.namespace, callback=callback) def disconnect(self, namespace=None): @@ -159,4 +159,4 @@ class ClientNamespace(BaseNamespace): is that when the ``namespace`` argument is not given the namespace associated with the class is used. """ - return self.server.disconnect(namespace=namespace or self.namespace) + return self.client.disconnect(namespace=namespace or self.namespace) diff --git a/socketio/tornado.py b/socketio/tornado.py index 10a4d4d..adfa6a4 100644 --- a/socketio/tornado.py +++ b/socketio/tornado.py @@ -3,10 +3,10 @@ if sys.version_info >= (3, 5): try: from engineio.async_drivers.tornado import get_tornado_handler as \ get_engineio_handler - except ImportError: + except ImportError: # pragma: no cover from engineio.async_tornado import get_tornado_handler as \ get_engineio_handler -def get_tornado_handler(socketio_server): +def get_tornado_handler(socketio_server): # pragma: no cover return get_engineio_handler(socketio_server.eio) diff --git a/tests/test_asyncio_namespace.py b/tests/test_asyncio_namespace.py index abb7c10..d56b292 100644 --- a/tests/test_asyncio_namespace.py +++ b/tests/test_asyncio_namespace.py @@ -179,3 +179,37 @@ class TestAsyncNamespace(unittest.TestCase): ns.server.disconnect.mock.assert_called_with('sid', namespace='/foo') _run(ns.disconnect('sid', namespace='/bar')) ns.server.disconnect.mock.assert_called_with('sid', namespace='/bar') + + def test_emit_client(self): + ns = asyncio_namespace.AsyncClientNamespace('/foo') + mock_client = mock.MagicMock() + mock_client.emit = AsyncMock() + ns._set_client(mock_client) + _run(ns.emit('ev', data='data', callback='cb')) + ns.client.emit.mock.assert_called_with( + 'ev', data='data', namespace='/foo', callback='cb') + _run(ns.emit('ev', data='data', namespace='/bar', callback='cb')) + ns.client.emit.mock.assert_called_with( + 'ev', data='data', namespace='/bar', callback='cb') + + def test_send_client(self): + ns = asyncio_namespace.AsyncClientNamespace('/foo') + mock_client = mock.MagicMock() + mock_client.send = AsyncMock() + ns._set_client(mock_client) + _run(ns.send(data='data', callback='cb')) + ns.client.send.mock.assert_called_with( + 'data', namespace='/foo', callback='cb') + _run(ns.send(data='data', namespace='/bar', callback='cb')) + ns.client.send.mock.assert_called_with( + 'data', namespace='/bar', callback='cb') + + def test_disconnect_client(self): + ns = asyncio_namespace.AsyncClientNamespace('/foo') + mock_client = mock.MagicMock() + mock_client.disconnect = AsyncMock() + ns._set_client(mock_client) + _run(ns.disconnect()) + ns.client.disconnect.mock.assert_called_with(namespace='/foo') + _run(ns.disconnect(namespace='/bar')) + ns.client.disconnect.mock.assert_called_with(namespace='/bar') diff --git a/tests/test_client.py b/tests/test_client.py index a096a00..b43510f 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -74,6 +74,11 @@ class TesClient(unittest.TestCase): c = client.Client(logger=my_logger) self.assertEqual(c.logger, my_logger) + @mock.patch('socketio.client.Client._engineio_client_class') + def test_engineio_logger(self, engineio_client_class): + client.Client(engineio_logger='foo') + engineio_client_class().assert_called_once_with(logger='foo') + def test_on_event(self): c = client.Client() @@ -629,3 +634,76 @@ class TesClient(unittest.TestCase): mock.call(1.5) ]) self.assertEqual(c._reconnect_task, 'foo') + + def test_handle_eio_message(self): + c = client.Client() + c._handle_connect = mock.MagicMock() + c._handle_disconnect = mock.MagicMock() + c._handle_event = mock.MagicMock() + c._handle_ack = mock.MagicMock() + c._handle_error = mock.MagicMock() + + c._handle_eio_message('0') + c._handle_connect.assert_called_with(None) + c._handle_eio_message('0/foo') + c._handle_connect.assert_called_with('/foo') + c._handle_eio_message('1') + c._handle_disconnect.assert_called_with(None) + c._handle_eio_message('1/foo') + c._handle_disconnect.assert_called_with('/foo') + c._handle_eio_message('2["foo"]') + c._handle_event.assert_called_with(None, None, ['foo']) + c._handle_eio_message('3/foo,["bar"]') + c._handle_ack.assert_called_with('/foo', None, ['bar']) + c._handle_eio_message('4') + c._handle_error.assert_called_with(None) + c._handle_eio_message('4/foo') + c._handle_error.assert_called_with('/foo') + c._handle_eio_message('51-{"_placeholder":true,"num":0}') + self.assertEqual(c._binary_packet.packet_type, packet.BINARY_EVENT) + c._handle_eio_message(b'foo') + c._handle_event.assert_called_with(None, None, b'foo') + c._handle_eio_message('62-/foo,{"1":{"_placeholder":true,"num":1},' + '"2":{"_placeholder":true,"num":0}}') + self.assertEqual(c._binary_packet.packet_type, packet.BINARY_ACK) + c._handle_eio_message(b'bar') + c._handle_eio_message(b'foo') + c._handle_ack.assert_called_with('/foo', None, {'1': b'foo', + '2': b'bar'}) + self.assertRaises(ValueError, c._handle_eio_message, '9') + + def test_eio_disconnect(self): + c = client.Client() + c._trigger_event = mock.MagicMock() + c._handle_eio_disconnect() + c._trigger_event.assert_called_once_with('disconnect', namespace='/') + + def test_eio_disconnect_namespaces(self): + c = client.Client() + c.namespaces = ['/foo', '/bar'] + c._trigger_event = mock.MagicMock() + c._handle_eio_disconnect() + c._trigger_event.assert_any_call('disconnect', namespace='/foo') + c._trigger_event.assert_any_call('disconnect', namespace='/bar') + c._trigger_event.assert_any_call('disconnect', namespace='/') + + def test_eio_disconnect_reconnect(self): + c = client.Client(reconnection=True) + c.start_background_task = mock.MagicMock() + c.eio.state = 'connected' + c._handle_eio_disconnect() + c.start_background_task.assert_called_once_with(c._handle_reconnect) + + def test_eio_disconnect_self_disconnect(self): + c = client.Client(reconnection=True) + c.start_background_task = mock.MagicMock() + c.eio.state = 'disconnected' + c._handle_eio_disconnect() + c.start_background_task.assert_not_called() + + def test_eio_disconnect_no_reconnect(self): + c = client.Client(reconnection=False) + c.start_background_task = mock.MagicMock() + c.eio.state = 'connected' + c._handle_eio_disconnect() + c.start_background_task.assert_not_called() diff --git a/tests/test_namespace.py b/tests/test_namespace.py index 514fe9b..8eaec96 100644 --- a/tests/test_namespace.py +++ b/tests/test_namespace.py @@ -127,3 +127,31 @@ class TestNamespace(unittest.TestCase): ns.server.disconnect.assert_called_with('sid', namespace='/foo') ns.disconnect('sid', namespace='/bar') ns.server.disconnect.assert_called_with('sid', namespace='/bar') + + def test_emit_client(self): + ns = namespace.ClientNamespace('/foo') + ns._set_client(mock.MagicMock()) + ns.emit('ev', data='data', callback='cb') + ns.client.emit.assert_called_with( + 'ev', data='data', namespace='/foo', callback='cb') + ns.emit('ev', data='data', namespace='/bar', callback='cb') + ns.client.emit.assert_called_with( + 'ev', data='data', namespace='/bar', callback='cb') + + def test_send_client(self): + ns = namespace.ClientNamespace('/foo') + ns._set_client(mock.MagicMock()) + ns.send(data='data', callback='cb') + ns.client.send.assert_called_with( + 'data', namespace='/foo', callback='cb') + ns.send(data='data', namespace='/bar', callback='cb') + ns.client.send.assert_called_with( + 'data', namespace='/bar', callback='cb') + + def test_disconnect_client(self): + ns = namespace.ClientNamespace('/foo') + ns._set_client(mock.MagicMock()) + ns.disconnect() + ns.client.disconnect.assert_called_with(namespace='/foo') + ns.disconnect(namespace='/bar') + ns.client.disconnect.assert_called_with(namespace='/bar')