async def test_connection_msg_for_handler_raising(mock_client, mock_handle_message, cloud_mock_iot): """Test we sent error when handler raises exception.""" conn = iot.CloudIoT(cloud_mock_iot) mock_client.receive.return_value = mock_coro( MagicMock( type=WSMsgType.text, json=MagicMock( return_value={ "msgid": "test-msg-id", "handler": "test-handler", "payload": "test-payload", }), )) mock_handle_message.side_effect = Exception("Broken") mock_client.send_json.return_value = mock_coro(None) await conn.connect() # Check that we sent the correct error assert len(mock_client.send_json.mock_calls) == 1 assert mock_client.send_json.mock_calls[0][1][0] == { "msgid": "test-msg-id", "error": "exception", }
async def test_connection_msg_for_handler_raising(mock_iot_client, cloud_mock_iot): """Test we sent error when handler raises exception.""" conn = iot.CloudIoT(cloud_mock_iot) mock_iot_client.receive = AsyncMock( return_value=MagicMock( type=WSMsgType.text, json=MagicMock( return_value={ "msgid": "test-msg-id", "handler": "test-handler", "payload": "test-payload", } ), ) ) mock_iot_client.send_json = AsyncMock() with patch.dict( iot.HANDLERS, {"test-handler": Mock(side_effect=Exception("Broken"))} ): await conn.connect() await asyncio.sleep(0) # Check that we sent the correct error assert len(mock_iot_client.send_json.mock_calls) == 1 assert mock_iot_client.send_json.mock_calls[0][1][0] == { "msgid": "test-msg-id", "error": "exception", }
async def test_connection_msg_for_unknown_handler(mock_iot_client, cloud_mock_iot): """Test a msg for an unknown handler.""" conn = iot.CloudIoT(cloud_mock_iot) mock_iot_client.receive.return_value = mock_coro( MagicMock( type=WSMsgType.text, json=MagicMock( return_value={ "msgid": "test-msg-id", "handler": "non-existing-handler", "payload": "test-payload", }), )) mock_iot_client.send_json.return_value = mock_coro(None) await conn.connect() await asyncio.sleep(0) # Check that we sent the correct error assert len(mock_iot_client.send_json.mock_calls) == 1 assert mock_iot_client.send_json.mock_calls[0][1][0] == { "msgid": "test-msg-id", "error": "unknown-handler", }
async def test_cloud_calling_handler(mock_iot_client, cloud_mock_iot): """Test we call handle message with correct info.""" conn = iot.CloudIoT(cloud_mock_iot) mock_iot_client.receive.return_value = mock_coro( MagicMock( type=WSMsgType.text, json=MagicMock( return_value={ "msgid": "test-msg-id", "handler": "test-handler", "payload": "test-payload", }), )) mock_handler = Mock(return_value=mock_coro("response")) mock_iot_client.send_json.return_value = mock_coro(None) with patch.dict(iot.HANDLERS, {"test-handler": mock_handler}, clear=True): await conn.connect() await asyncio.sleep(0) # Check that we sent message to handler correctly assert len(mock_handler.mock_calls) == 1 cloud, payload = mock_handler.mock_calls[0][1] assert cloud is cloud_mock_iot assert payload == "test-payload" # Check that we forwarded response from handler to cloud assert len(mock_iot_client.send_json.mock_calls) == 1 assert mock_iot_client.send_json.mock_calls[0][1][0] == { "msgid": "test-msg-id", "payload": "response", }
async def test_cloud_calling_handler(mock_client, mock_handle_message, cloud_mock_iot): """Test we call handle message with correct info.""" conn = iot.CloudIoT(cloud_mock_iot) mock_client.receive.return_value = mock_coro( MagicMock( type=WSMsgType.text, json=MagicMock( return_value={ "msgid": "test-msg-id", "handler": "test-handler", "payload": "test-payload", }), )) mock_handle_message.return_value = mock_coro("response") mock_client.send_json.return_value = mock_coro(None) await conn.connect() # Check that we sent message to handler correctly assert len(mock_handle_message.mock_calls) == 1 cloud, handler_name, payload = mock_handle_message.mock_calls[0][1] assert cloud is cloud_mock_iot assert handler_name == "test-handler" assert payload == "test-payload" # Check that we forwarded response from handler to cloud assert len(mock_client.send_json.mock_calls) == 1 assert mock_client.send_json.mock_calls[0][1][0] == { "msgid": "test-msg-id", "payload": "response", }
async def test_cloud_random_exception(mock_client, caplog, cloud_mock_iot): """Test random exception.""" conn = iot.CloudIoT(cloud_mock_iot) mock_client.receive.side_effect = Exception await conn.connect() assert "Unexpected error" in caplog.text
async def test_cloud_unable_to_connect(mock_client, caplog, cloud_mock_iot): """Test unable to connect error.""" conn = iot.CloudIoT(cloud_mock_iot) mock_client.receive.side_effect = client_exceptions.ClientError(None, None) await conn.connect() assert "Unable to connect:" in caplog.text
async def test_cloud_connect_invalid_auth(mock_client, caplog, cloud_mock_iot): """Test invalid auth detected by server.""" conn = iot.CloudIoT(cloud_mock_iot) mock_client.receive.side_effect = client_exceptions.WSServerHandshakeError( None, None, status=401) await conn.connect() assert "Connection closed: Invalid auth." in caplog.text
async def test_cloud_sending_invalid_json(mock_client, caplog, cloud_mock_iot): """Test cloud sending invalid JSON.""" conn = iot.CloudIoT(cloud_mock_iot) mock_client.receive.return_value = mock_coro( MagicMock(type=WSMsgType.TEXT, json=MagicMock(side_effect=ValueError))) await conn.connect() assert "Connection closed: Received invalid JSON." in caplog.text
async def test_cloud_receiving_bytes(mock_client, caplog, cloud_mock_iot): """Test server disconnecting instance.""" conn = iot.CloudIoT(cloud_mock_iot) mock_client.receive.return_value = mock_coro( MagicMock(type=WSMsgType.BINARY)) await conn.connect() assert "Connection closed: Received non-Text message" in caplog.text
async def test_cloud_check_token_raising(mock_client, caplog, cloud_mock_iot): """Test cloud unable to check token.""" conn = iot.CloudIoT(cloud_mock_iot) cloud_mock_iot.run_executor = mock_coro_func( exception=auth_api.CloudError("BLA")) await conn.connect() assert "Unable to refresh token: BLA" in caplog.text
async def test_refresh_token_expired(cloud_mock): """Test handling Unauthenticated error raised if refresh token expired.""" cloud_mock.subscription_expired = True conn = iot.CloudIoT(cloud_mock) await conn.connect() assert len(cloud_mock.auth.check_token.mock_calls) == 1 assert len(cloud_mock.client.mock_user) == 1
async def test_refresh_token_before_expiration_fails(cloud_mock): """Test that we don't connect if token is expired.""" cloud_mock.subscription_expired = True conn = iot.CloudIoT(cloud_mock) await conn.connect() assert len(cloud_mock.auth.check_token.mock_calls) == 1 assert len(cloud_mock.client.mock_user) == 1
async def test_send_message_no_answer(cloud_mock_iot): """Test sending a message that expects no answer.""" cloud_iot = iot.CloudIoT(cloud_mock_iot) cloud_iot.state = iot_base.STATE_CONNECTED cloud_iot.client = MagicMock(send_json=AsyncMock()) await cloud_iot.async_send_message("webhook", {"msg": "yo"}, expect_answer=False) assert not cloud_iot._response_handler assert len(cloud_iot.client.send_json.mock_calls) == 1 msg = cloud_iot.client.send_json.mock_calls[0][1][0] assert msg["handler"] == "webhook" assert msg["payload"] == {"msg": "yo"}
async def test_cloud_getting_disconnected_by_server(mock_client, caplog, cloud_mock_iot): """Test server disconnecting instance.""" conn = iot.CloudIoT(cloud_mock_iot) mock_client.receive.return_value = mock_coro( MagicMock(type=WSMsgType.CLOSING)) with patch("asyncio.sleep", side_effect=[mock_coro(), asyncio.CancelledError]): await conn.connect() assert "Connection closed" in caplog.text
async def test_send_message_answer(loop, cloud_mock_iot): """Test sending a message that expects no answer.""" cloud_iot = iot.CloudIoT(cloud_mock_iot) cloud_iot.state = iot.STATE_CONNECTED cloud_iot.client = MagicMock(send_json=MagicMock(return_value=mock_coro())) uuid = 5 with patch("hass_nabucasa.iot.uuid.uuid4", return_value=MagicMock(hex=uuid)): send_task = loop.create_task( cloud_iot.async_send_message("webhook", {"msg": "yo"})) await asyncio.sleep(0) assert len(cloud_iot.client.send_json.mock_calls) == 1 assert len(cloud_iot._response_handler) == 1 msg = cloud_iot.client.send_json.mock_calls[0][1][0] assert msg["handler"] == "webhook" assert msg["payload"] == {"msg": "yo"} cloud_iot._response_handler[uuid].set_result({"response": True}) response = await send_task assert response == {"response": True}
async def test_send_message_not_connected(cloud_mock_iot): """Test sending a message that expects no answer.""" cloud_iot = iot.CloudIoT(cloud_mock_iot) with pytest.raises(iot.NotConnected): await cloud_iot.async_send_message("webhook", {"msg": "yo"})