def test_create_session_from_password(client): """Test opening a session from the users password.""" resp = AsyncMock() resp.status = 200 resp.json.return_value = { "access_token": "mock_access", "expires_in": 123456, "scope": ("scope:location scope:vehicle:profile " "scope:user:profile scope:trip"), "refresh_token": "mock_refresh", "token_type": "Bearer", } client._client_session.request.return_value = resp client.loop.run_until_complete( client.create_session_from_password(['location', 'trip'], "mock_user", "mock_pass")) assert client._client_session.request.called assert len(client._client_session.request.mock_calls) == 2 assert client._client_session.request.mock_calls[0][1][0] == "POST" assert client._client_session.request.mock_calls[0][1][1] == \ "https://accounts.automatic.com/oauth/access_token" assert client._client_session.request.mock_calls[0][2]['data'] == { "client_id": client.client_id, "client_secret": client.client_secret, "grant_type": "password", "username": "******", "password": "******", "scope": ("scope:location scope:trip"), }
def test_api_post(aiohttp_session): """Test the post api object method.""" mock_kwargs = { "timeout": 10, } obj = base.BaseApiObject(None, request_kwargs=mock_kwargs, client_session=aiohttp_session) resp = AsyncMock() resp.status = 200 mock_json = { "mock_attr", "mock_val", } resp.json.return_value = mock_json aiohttp_session.request.return_value = resp mock_request = { "request_attr": "request_data", } result = aiohttp_session.loop.run_until_complete( obj._post("mock_url", mock_request)) assert result == mock_json assert aiohttp_session.request.called assert len(aiohttp_session.request.mock_calls) == 2 assert aiohttp_session.request.mock_calls[0][1][0] == "POST" assert aiohttp_session.request.mock_calls[0][1][1] == "mock_url" assert aiohttp_session.request.mock_calls[0][2]["data"] == mock_request assert aiohttp_session.request.mock_calls[0][2]["timeout"] == 10
def test_create_session_from_oauth_code(client): """Test opening a session from an oauth code.""" resp = AsyncMock() resp.status = 200 resp.json.return_value = { "access_token": "mock_access", "expires_in": 123456, "scope": ("scope:location scope:vehicle:profile " "scope:user:profile scope:trip"), "refresh_token": "mock_refresh", "token_type": "bearer", } client._client_session.request.return_value = resp client.state = "mock_state" session = client.loop.run_until_complete( client.create_session_from_oauth_code("mock_code", "mock_state")) assert client._client_session.request.called assert len(client._client_session.request.mock_calls) == 2 assert client._client_session.request.mock_calls[0][1][0] == "POST" assert client._client_session.request.mock_calls[0][1][1] == \ "https://accounts.automatic.com/oauth/access_token" assert client._client_session.request.mock_calls[0][2]['data'] == { "client_id": client.client_id, "client_secret": client.client_secret, "grant_type": "authorization_code", "code": "mock_code", } assert session.refresh_token == "mock_refresh"
def test_get_devices(session): """Test getting device list.""" resp = AsyncMock() resp.status = 200 resp.json.return_value = { "_metadata": { "count": 1, "next": None, "previous": None, }, "results": [{ "url": "mock_url", "id": "mock_id", "version": 2, }], } session._client_session.request.return_value = resp device = session.loop.run_until_complete(session.get_devices())[0] assert session._client_session.request.called assert len(session._client_session.request.mock_calls) == 2 assert session._client_session.request.mock_calls[0][1][0] == "GET" assert session._client_session.request.mock_calls[0][1][1] == \ "https://api.automatic.com/device?" assert device.url == "mock_url" assert device.id == "mock_id" assert device.version == 2
def test_get_ws_connection_upgrade_error(client): """Test error opening a websocket connection with an engineIO session.""" mock_ws = AsyncMock() receive_queue = asyncio.Queue(loop=client.loop) mock_ws.receive_str = receive_queue.get @asyncio.coroutine def mock_send_str(data): if data == "2probe": yield from receive_queue.put("3probe") return if data == "5": yield from receive_queue.put('44"socketIO Mock Error"') mock_ws.send_str = mock_send_str client._client_session.ws_connect.return_value = mock_ws session_data = { "sid": "mock_session_id", "pingTimeout": 12.345, "pingInterval": 23.456, } with pytest.raises(exceptions.SocketIOError) as exc: client.loop.run_until_complete(client._get_ws_connection(session_data)) assert str(exc.value) == "socketIO Mock Error"
async def test_chunks_from_path(): test = AsyncMock(spec=mock.Mock) with mock.patch("trio.open_file", AsyncMock(spec=mock.Mock, side_effect=[test])) as mo: test.read = AsyncMock(spec=mock.Mock, side_effect="chunk") res = await rsync._chunks_from_path("src_file", 1) mo.assert_called_once_with("src_file", "rb") test.read.assert_has_calls([ mock.call(1), mock.call(1), mock.call(1), mock.call(1), mock.call(1), mock.call(1) ]) assert res == ["c", "h", "u", "n", "k"] test.reset_mock() with mock.patch("trio.open_file", AsyncMock(spec=mock.Mock, side_effect=[test])) as mo: test.read = AsyncMock(spec=mock.Mock, side_effect=["ch", "un", "k"]) res = await rsync._chunks_from_path("src_file", 2) mo.assert_called_once_with("src_file", "rb") test.read.assert_has_calls( [mock.call(2), mock.call(2), mock.call(2), mock.call(2)]) assert res == ["ch", "un", "k"]
def test_ws_loop_messages(client): """Test websocket loop messages received.""" mock_ws = AsyncMock() receive_queue = asyncio.Queue(loop=client.loop) mock_ws.receive = receive_queue.get client._ws_connection = mock_ws client.ws_close = AsyncMock() client._handle_packet = MagicMock() msg = MagicMock() msg.type = aiohttp.WSMsgType.TEXT msg.data = 'mock message 1' client.loop.run_until_complete(receive_queue.put(msg)) msg = MagicMock() msg.type = aiohttp.WSMsgType.TEXT msg.data = 'mock message 2' client.loop.run_until_complete(receive_queue.put(msg)) msg = MagicMock() msg.type = aiohttp.WSMsgType.BINARY msg.data = b'binary message to be ignored' client.loop.run_until_complete(receive_queue.put(msg)) msg = MagicMock() msg.type = aiohttp.WSMsgType.CLOSED client.loop.run_until_complete(receive_queue.put(msg)) client.loop.run_until_complete(client._ws_loop()) assert client._handle_packet.called assert len(client._handle_packet.mock_calls) == 2 assert client._handle_packet.mock_calls[0][1][0] == 'mock message 1' assert client._handle_packet.mock_calls[1][1][0] == 'mock message 2'
def test_request_status_error(aiohttp_session): """Test the api request client error.""" obj = base.BaseApiObject(None, client_session=aiohttp_session) resp = AsyncMock() resp.status = 500 resp.json.return_value = {"error": "mock_error"} aiohttp_session.request.return_value = resp with pytest.raises(exceptions.InternalError): aiohttp_session.loop.run_until_complete(obj._request("GET", "url", {}))
def test_scope_forbidden(client): """Test opening a session from an invalid token.""" resp = AsyncMock() resp.status = 403 resp.json.return_value = { "error": "access_denied", } client._client_session.request.return_value = resp with pytest.raises(exceptions.ForbiddenError): client.loop.run_until_complete( client.create_session_from_refresh_token("bad_token"))
def test_scope_forbidden(client): """Test opening a session from the users password.""" resp = AsyncMock() resp.status = 403 resp.json.return_value = { "error": "access_denied", } client._client_session.request.return_value = resp with pytest.raises(exceptions.ForbiddenError): client.loop.run_until_complete( client.create_session_from_password(['location', 'trip'], "mock_user", "mock_pass"))
def test_request_status_bad_json(aiohttp_session): """Test the api request client error.""" obj = base.BaseApiObject(None, client_session=aiohttp_session) resp = AsyncMock() resp.status = 200 def side_effect(*args, **kwargs): raise ValueError() resp.json.side_effect = side_effect aiohttp_session.request.return_value = resp with pytest.raises(exceptions.InvalidResponseError): aiohttp_session.loop.run_until_complete(obj._request("GET", "url", {}))
def test_get_engineio_session_empty_packet(mock_time, client): """Test error requesting an engineIO session from Automatic.""" resp = AsyncMock() resp.status = 200 # Simulate an empty packet return resp.read.return_value = b'' client._client_session.request.return_value = resp with pytest.raises(exceptions.TransportError) as exc: client.loop.run_until_complete(client._get_engineio_session()) assert str(exc.value) == \ "engineIO session packet not received"
def test_ws_handle_next_ping(client): """Test websocket ping.""" old_handle = MagicMock() client._ping = AsyncMock() client.loop.call_later = MagicMock() client._ws_session_data = { "sid": "mock_session_id", "pingTimeout": 12.345, "pingInterval": 23.456, "pingIntervalHandle": old_handle, } client._handle_packet('3') assert old_handle.cancel.called assert len(old_handle.cancel.mock_calls) == 1 assert client.loop.call_later.called assert len(client.loop.call_later.mock_calls) == 1 assert client.loop.call_later.mock_calls[0][1][0] == 23.456 interval = client.loop.call_later.mock_calls[0][1][1] assert not client._ping.called future = interval() client.loop.run_until_complete(future) assert client._ping.called assert len(client._ping.mock_calls) == 1
async def test_unload_entry(hass, mock_smile_adam): """Test being able to unload an entry.""" entry = await async_init_integration(hass, mock_smile_adam) mock_smile_adam.async_reset = AsyncMock(return_value=True) assert await async_unload_entry(hass, entry) assert not hass.data[DOMAIN]
def test_realtime_get_user(client): """Test getting user information.""" event = data.BaseRealtimeEvent(client, { 'id': 'mock_id', 'user': { 'id': 'mock_user_id', 'url': 'mock_user_url', }, 'type': 'location:updated', 'vehicle': { 'id': 'mock_vehicle_id', 'url': 'mock_vehicle_url', }, 'device': { 'id': 'mock_device_id', }, }) event._get = AsyncMock() resp = { 'id': 'mock_user_id', 'url': 'mock_user_url', 'username': '******', } event._get.return_value = resp user = client.loop.run_until_complete(event.get_user()) assert event._get.called assert len(event._get.mock_calls) == 1 assert event._get.mock_calls[0][1][0] == \ 'https://api.automatic.com/user/mock_user_id' assert user.id == 'mock_user_id' assert user.url == 'mock_user_url' assert user.username == 'mock_username'
def test_share_workspace(tmp_path, monkeypatch, alice, bob, cli_workspace_role): config_dir = tmp_path / "config" # Mocking factory_mock = AsyncMock() workspace_role, expected_workspace_role = cli_workspace_role @asynccontextmanager async def logged_core_factory(*args, **kwargs): yield factory_mock(*args, **kwargs) password = "******" save_device_with_password_in_config(config_dir, bob, password) alice_info = [ UserInfo( user_id=alice.user_id, human_handle=alice.human_handle, profile=alice.profile, created_on=alice.timestamp(), revoked_on=None, ) ] def _run_cli_share_workspace_test(args, expected_error_code, use_recipiant): factory_mock.reset_mock() factory_mock.return_value.user_fs.workspace_share.is_async = True factory_mock.return_value.find_humans.is_async = True factory_mock.return_value.find_humans.return_value = (alice_info, 1) factory_mock.return_value.find_workspace_from_name.return_value.id = "ws1_id" monkeypatch.setattr( "parsec.core.cli.share_workspace.logged_core_factory", logged_core_factory) runner = CliRunner() result = runner.invoke(cli, args) assert result.exit_code == expected_error_code factory_mock.assert_called_once_with(ANY, bob) factory_mock.return_value.user_fs.workspace_share.assert_called_once_with( "ws1_id", alice.user_id, expected_workspace_role) if use_recipiant: factory_mock.return_value.find_humans.assert_called_once() else: factory_mock.return_value.find_humans.assert_not_called() default_args = ( f"core share_workspace --password {password} " f"--device={bob.slughash} --config-dir={config_dir.as_posix()} " f"--role={workspace_role} " f"--workspace-name=ws1 ") # Test with user-id args = default_args + f"--user-id={alice.user_id}" _run_cli_share_workspace_test(args, 0, False) # Test with recipiant args = default_args + f"[email protected]" _run_cli_share_workspace_test(args, 0, True)
def test_get_engineio_session_error(mock_time, client): """Test error requesting an engineIO session from Automatic.""" resp = AsyncMock() resp.status = 200 data = 'Error Requesting Session'.encode('utf-8') length_str = str(len(data)).encode('utf-8') # Build engineIO session create packet resp.read.return_value = \ b'\x01\x00' + length_str + b'\xFF\xFF4' + data client._client_session.request.return_value = resp with pytest.raises(exceptions.TransportError) as exc: client.loop.run_until_complete(client._get_engineio_session()) assert str(exc.value) == \ "engineIO packet is not open type: Error Requesting Session"
def session(aiohttp_session): """Create a test aioautomatic session.""" client = AsyncMock() client.client_session = aiohttp_session client.request_kwargs = {} data = { "access_token": "123", "refresh_token": "ABCD", "expires_in": 12345, "scope": ("scope:location scope:vehicle:profile " "scope:user:profile scope:trip"), } session = Session(client, **data) yield session
def test_get_vehicles(session): """Test getting vehicle list.""" resp = AsyncMock() resp.status = 200 resp.json.return_value = { "_metadata": { "count": 1, "next": None, "previous": None, }, "results": [{ "url": "mock_url", "id": "mock_id", "make": "mock_make", "model": "mock_model", "submodel": None, "created_at": "2015-03-20T01:43:36.738000Z", "fuel_level_percent": 73.9, }], } session._client_session.request.return_value = resp dt = datetime(2017, 1, 28) vehicle = session.loop.run_until_complete( session.get_vehicles(vin="VINVIN", created_at__gte=dt))[0] assert session._client_session.request.called assert len(session._client_session.request.mock_calls) == 2 assert session._client_session.request.mock_calls[0][1][0] == "GET" assert session._client_session.request.mock_calls[0][1][1][:34] == \ "https://api.automatic.com/vehicle?" assert vehicle.url == "mock_url" assert vehicle.id == "mock_id" assert vehicle.make == "mock_make" assert vehicle.model == "mock_model" assert vehicle.vin is None assert vehicle.submodel is None assert vehicle.created_at == datetime(2015, 3, 20, 1, 43, 36, 738000, tzinfo=timezone.utc) assert vehicle.fuel_level_percent == 73.9
async def test_unload_entry(opp, mock_smile_adam): """Test being able to unload an entry.""" entry = await async_init_integration(opp, mock_smile_adam) mock_smile_adam.async_reset = AsyncMock(return_value=True) await opp.config_entries.async_unload(entry.entry_id) await opp.async_block_till_done() assert entry.state is ConfigEntryState.NOT_LOADED assert not opp.data[DOMAIN]
async def test_unload_entry(hass, mock_smile_adam): """Test being able to unload an entry.""" entry = await async_init_integration(hass, mock_smile_adam) mock_smile_adam.async_reset = AsyncMock(return_value=True) await hass.config_entries.async_unload(entry.entry_id) await hass.async_block_till_done() assert entry.state == ENTRY_STATE_NOT_LOADED assert not hass.data[DOMAIN]
async def test_import_file(alice_workspace): with mock.patch( "parsec.core.cli.rsync._chunks_from_path", AsyncMock(spec=mock.Mock, side_effect=[[b"random", b"chunks"]]), ): f = await alice_workspace.open_file("/foo/bar", "wb+") assert await f.read() == b"" await rsync._import_file(alice_workspace, "/src_file", "/foo/bar") rsync._chunks_from_path.assert_called_once_with("/src_file") assert await f.read() == b"randomchunks" await f.close()
def test_ws_ping(client): """Test websocket ping.""" mock_ws = AsyncMock() send_queue = queue.Queue() receive_queue = asyncio.Queue(loop=client.loop) mock_ws.receive = receive_queue.get @asyncio.coroutine def mock_send_str(data): send_queue.put(data) mock_ws.send_str = mock_send_str old_handle = MagicMock() client.ws_close = AsyncMock() client.loop.call_later = MagicMock() client._ws_connection = mock_ws client._ws_session_data = { "sid": "mock_session_id", "pingTimeout": 12.345, "pingInterval": 23.456, "pingTimeoutHandle": old_handle, } client.loop.run_until_complete(client._ping()) packet = send_queue.get(False) assert send_queue.empty() assert packet == "2" assert old_handle.cancel.called assert len(old_handle.cancel.mock_calls) == 1 assert client.loop.call_later.called assert len(client.loop.call_later.mock_calls) == 1 assert client.loop.call_later.mock_calls[0][1][0] == 12.345 timeout = client.loop.call_later.mock_calls[0][1][1] assert not client.ws_close.called future = timeout() client.loop.run_until_complete(future) assert client.ws_close.called assert len(client.ws_close.mock_calls) == 1
def test_result_previous_list(session): """Test the result object get previous list.""" obj = base.ResultList(parent=session, item_class=MockDataObject, resp={ "_metadata": { "count": 0, "next": None, "previous": "previous_url", }, "results": [], }) resp = AsyncMock() resp.status = 200 mock_json = { "_metadata": { "count": 2, "next": None, "previous": None, }, "results": [{ "attr1": "value1", "attr2": "value2", }, { "attr1": "value3" }], } resp.json.return_value = mock_json session._client_session.request.return_value = resp next_list = session.loop.run_until_complete(obj.get_next()) previous_list = session.loop.run_until_complete(obj.get_previous()) assert obj.next is None assert next_list is None assert len(obj) == 0 assert obj.previous is "previous_url" assert len(obj) == 0 assert len(previous_list) == 2 assert sorted([item.attr1 for item in previous_list]) == \ sorted(["value1", "value3"])
def test_get_engineio_session(mock_time, client): """Test requesting an engineIO session from Automatic.""" resp = AsyncMock() resp.status = 200 data = json.dumps({ "sid": "mock_session_id", "pingTimeout": 12345, "pingInterval": 23456, }).encode('utf-8') length_str = str(len(data)).encode('utf-8') # Build engineIO session create packet resp.read.return_value = \ b'\x01\x00' + length_str + b'\xFF\xFF0' + data client._client_session.request.return_value = resp session_data = client.loop.run_until_complete( client._get_engineio_session()) assert client._client_session.request.called assert len(client._client_session.request.mock_calls) == 2 assert client._client_session.request.mock_calls[0][1][0] == "GET" assert client._client_session.request.mock_calls[0][1][1][:40] == \ "https://stream.automatic.com/socket.io/?" query = client._client_session.request.mock_calls[0][1][1][40:].split('&') params = {} for item in query: k, v = item.split('=') params[k] = v assert params == { "EIO": "3", "token": "mock_id:mock_secret", "transport": "polling", "t": "1493426946.123-0", } assert session_data == { "sid": "mock_session_id", "pingTimeout": 12.345, "pingInterval": 23.456, }
def test_get_ws_connection(client): """Test opening a websocket connection with an engineIO session.""" mock_ws = AsyncMock() receive_queue = asyncio.Queue(loop=client.loop) mock_ws.receive_str = receive_queue.get @asyncio.coroutine def mock_send_str(data): if data == "2probe": yield from receive_queue.put("3probe") return if data == "5": yield from receive_queue.put("40") mock_ws.send_str = mock_send_str client._client_session.ws_connect.return_value = mock_ws session_data = { "sid": "mock_session_id", "pingTimeout": 12.345, "pingInterval": 23.456, } client.loop.run_until_complete(client._get_ws_connection(session_data)) assert client._client_session.ws_connect.called assert len(client._client_session.ws_connect.mock_calls) == 1 assert client._client_session.ws_connect.mock_calls[0][1][0][:38] == \ "wss://stream.automatic.com/socket.io/?" query = \ client._client_session.ws_connect.mock_calls[0][1][0][38:].split('&') params = {} for item in query: k, v = item.split('=') params[k] = v assert params == { "EIO": "3", "token": "mock_id:mock_secret", "transport": "websocket", "sid": "mock_session_id", }
def test_ws_loop_exception(client): """Test websocket loop exception.""" @asyncio.coroutine def side_effect(*args, **kwargs): raise aiohttp.ClientError("Mock Exception") mock_ws = AsyncMock() mock_ws.receive.side_effect = side_effect client._ws_connection = mock_ws client.ws_close = AsyncMock() client._handle_event = MagicMock() with pytest.raises(exceptions.TransportError): client.loop.run_until_complete(client._ws_loop()) assert client.ws_close.called assert len(client.ws_close.mock_calls) == 1 assert client._handle_event.called assert len(client._handle_event.mock_calls) == 1 assert client._handle_event.mock_calls[0][1][0] == 'closed' assert client._handle_event.mock_calls[0][1][1] is None
def test_ws_loop_error(client): """Test websocket loop error message.""" mock_ws = AsyncMock() receive_queue = asyncio.Queue(loop=client.loop) mock_ws.receive = receive_queue.get client._ws_connection = mock_ws client.ws_close = AsyncMock() client._handle_event = MagicMock() msg = MagicMock() msg.type = aiohttp.WSMsgType.ERROR client.loop.run_until_complete(receive_queue.put(msg)) with pytest.raises(exceptions.TransportError) as exc: client.loop.run_until_complete(client._ws_loop()) assert client.ws_close.called assert len(client.ws_close.mock_calls) == 1 assert client._handle_event.called assert len(client._handle_event.mock_calls) == 1 assert client._handle_event.mock_calls[0][1][0] == 'closed' assert client._handle_event.mock_calls[0][1][1] is None assert str(exc.value) == "Websocket error detected. Connection closed."
def test_session_refresh(session): """Test refreshing a session with the refresh token.""" resp = AsyncMock() resp.status = 200 resp.json.return_value = { "access_token": "mock_access", "expires_in": 123456, "scope": ("scope:location scope:vehicle:profile " "scope:user:profile scope:trip"), "refresh_token": "mock_refresh", "token_type": "Bearer", } session._client_session.request.return_value = resp refresh_token = session._refresh_token renew_handle = MagicMock() session._renew_handle = renew_handle session._client.client_id = "123" session._client.client_secret = "456" session.loop.run_until_complete(session.refresh()) assert session._client_session.request.called assert len(session._client_session.request.mock_calls) == 2 assert session._client_session.request.mock_calls[0][1][0] == "POST" assert session._client_session.request.mock_calls[0][1][1] == \ "https://accounts.automatic.com/oauth/access_token" assert session._client_session.request.mock_calls[0][2]['data'] == { "client_id": "123", "client_secret": "456", "grant_type": "refresh_token", "refresh_token": refresh_token, } assert renew_handle.cancel.called
async def test_no_still_image_url(hass, hass_client, mock_av_open): """Test that the component can grab images from stream with no still_image_url.""" with mock_av_open: assert await async_setup_component( hass, "camera", { "camera": { "name": "config_test", "platform": "generic", "stream_source": "rtsp://example.com:554/rtsp/", }, }, ) await hass.async_block_till_done() client = await hass_client() with patch( "homeassistant.components.generic.camera.GenericCamera.stream_source", return_value=None, ) as mock_stream_source: # First test when there is no stream_source should fail resp = await client.get("/api/camera_proxy/camera.config_test") await hass.async_block_till_done() mock_stream_source.assert_called_once() assert resp.status == HTTPStatus.INTERNAL_SERVER_ERROR with patch("homeassistant.components.camera.create_stream" ) as mock_create_stream: # Now test when creating the stream succeeds mock_stream = Mock() mock_stream.async_get_image = AsyncMock() mock_stream.async_get_image.return_value = b"stream_keyframe_image" mock_create_stream.return_value = mock_stream # should start the stream and get the image resp = await client.get("/api/camera_proxy/camera.config_test") await hass.async_block_till_done() mock_create_stream.assert_called_once() mock_stream.async_get_image.assert_called_once() assert resp.status == HTTPStatus.OK assert await resp.read() == b"stream_keyframe_image"