async def test_literal(aresponses): """Test literal is handled correctly.""" aresponses.add( MATCH_HOST, "/keypress/Lit_t", "POST", aresponses.Response(status=200), ) aresponses.add( MATCH_HOST, "/keypress/Lit_h", "POST", aresponses.Response(status=200), ) aresponses.add( MATCH_HOST, "/keypress/Lit_e", "POST", aresponses.Response(status=200), ) async with ClientSession() as session: roku = Roku(HOST, session=session) await roku.literal("the")
async def test_client_error() -> None: """Test HTTP client error.""" async with ClientSession() as session: session.request = AsyncMock(side_effect=ClientError) client = Roku(HOST, session=session) with pytest.raises(RokuConnectionError): assert await client._request("client/error", method="ABC")
async def test_text_request(aresponses): """Test non XML response is handled correctly.""" aresponses.add( MATCH_HOST, "/response/text", "GET", aresponses.Response(status=200, text="OK"), ) async with ClientSession() as session: client = Roku(HOST, session=session) response = await client._request("response/text") assert response == "OK"
async def test_resolve_hostname_error(resolver: AsyncMock) -> None: """Test that hostname resolution errors are handled.""" resolver.side_effect = SocketGIAError async with ClientSession() as session: client = Roku(HOSTNAME, session=session) with pytest.raises(RokuConnectionError): await client._request("support/hostname-error")
async def test_get_dns_state( aresponses: ResponsesMockServer, resolver: AsyncMock, freezer, ) -> None: """Test get_dns_state is handled correctly.""" aresponses.add( f"192.168.1.99:{PORT}", "/support/hostname", "GET", aresponses.Response(status=200, text="OK"), ) aresponses.add( f"192.168.1.89:{PORT}", "/support/hostname", "GET", aresponses.Response(status=200, text="OK"), ) async with ClientSession() as session: roku = Roku(HOST, session=session) assert roku.get_dns_state() == { "enabled": False, "hostname": None, "ip_address": None, "resolved_at": None, } roku2 = Roku("roku.dev", session=session) assert roku2.get_dns_state() == { "enabled": True, "hostname": "roku.dev", "ip_address": None, "resolved_at": None, } resolver.return_value = fake_addrinfo_results(["192.168.1.99"]) assert await roku2._request("support/hostname") dns = roku2.get_dns_state() assert dns["enabled"] assert dns["hostname"] == "roku.dev" assert dns["ip_address"] == "192.168.1.99" assert dns["resolved_at"] == datetime(2022, 3, 27, 0, 0) resolver.return_value = fake_addrinfo_results(["192.168.1.89"]) freezer.tick(delta=timedelta(hours=3)) assert await roku2._request("support/hostname") dns = roku2.get_dns_state() assert dns["enabled"] assert dns["hostname"] == "roku.dev" assert dns["ip_address"] == "192.168.1.89" assert dns["resolved_at"] == datetime(2022, 3, 27, 3, 0)
async def test_post_request(aresponses): """Test POST requests are handled correctly.""" aresponses.add( MATCH_HOST, "/method/post", "POST", aresponses.Response(status=200, text="OK") ) async with ClientSession() as session: client = Roku(HOST, session=session) response = await client._request("method/post", method="POST") assert response == "OK"
async def test_resolve_hostname( aresponses: ResponsesMockServer, resolver: AsyncMock, freezer, ) -> None: """Test that hostnames are resolved before request.""" resolver.return_value = fake_addrinfo_results([HOST]) aresponses.add( MATCH_HOST, "/support/hostname", "GET", aresponses.Response(status=200, text="OK"), ) aresponses.add( f"192.168.1.68:{PORT}", "/support/hostname", "GET", aresponses.Response(status=200, text="OK"), ) async with ClientSession() as session: client = Roku(HOSTNAME, session=session) assert await client._request("support/hostname") dns = client.get_dns_state() assert dns["enabled"] assert dns["hostname"] == HOSTNAME assert dns["ip_address"] == HOST assert dns["resolved_at"] == datetime(2022, 3, 27, 0, 0) freezer.tick(delta=timedelta(hours=3)) resolver.return_value = fake_addrinfo_results(["192.168.1.68"]) assert await client._request("support/hostname") dns = client.get_dns_state() assert dns["enabled"] assert dns["hostname"] == HOSTNAME assert dns["ip_address"] == "192.168.1.68" assert dns["resolved_at"] == datetime(2022, 3, 27, 3, 0)
async def test_remote_search(aresponses): """Test remote search keypress is handled correctly.""" aresponses.add( MATCH_HOST, "/search/browse", "POST", aresponses.Response(status=200), ) async with ClientSession() as session: roku = Roku(HOST, session=session) await roku.remote("search")
async def test_remote(aresponses): """Test remote is handled correctly.""" aresponses.add( MATCH_HOST, "/keypress/Home", "POST", aresponses.Response(status=200), ) async with ClientSession() as session: roku = Roku(HOST, session=session) await roku.remote("home")
async def test_search(aresponses: ResponsesMockServer) -> None: """Test search is handled correctly.""" aresponses.add( MATCH_HOST, "/search/browse?keyword=test", "POST", aresponses.Response(status=200, text="OK"), match_querystring=True, ) async with ClientSession() as session: roku = Roku(HOST, session=session) await roku.search("test")
async def validate_input(hass: HomeAssistantType, data: Dict) -> Dict: """Validate the user input allows us to connect. Data has the keys from DATA_SCHEMA with values provided by the user. """ session = async_get_clientsession(hass) roku = Roku(data[CONF_HOST], session=session) device = await roku.update() return { "title": device.info.name, "serial_number": device.info.serial_number, }
async def test_launch(aresponses): """Test launch is handled correctly.""" aresponses.add( MATCH_HOST, "/launch/101?contentID=101", "POST", aresponses.Response(status=200), match_querystring=True, ) async with ClientSession() as session: roku = Roku(HOST, session=session) await roku.launch("101")
async def test_request_port(aresponses: ResponsesMockServer) -> None: """Test the handling of non-standard API port.""" aresponses.add( f"{HOST}:{NON_STANDARD_PORT}", "/support/port", "GET", aresponses.Response(status=200, text="OK"), ) async with ClientSession() as session: client = Roku(host=HOST, port=NON_STANDARD_PORT, session=session) response = await client._request("support/port") assert response == "OK"
async def test_http_error500(aresponses: ResponsesMockServer) -> None: """Test HTTP 500 response handling.""" aresponses.add( MATCH_HOST, "/http/500", "GET", aresponses.Response(text="Internal Server Error", status=500), ) async with ClientSession() as session: client = Roku(HOST, session=session) with pytest.raises(RokuError): assert await client._request("http/500")
async def test_http_error404(aresponses: ResponsesMockServer) -> None: """Test HTTP 404 response handling.""" aresponses.add( MATCH_HOST, "/http/404", "GET", aresponses.Response(text="Not Found!", status=404), ) async with ClientSession() as session: client = Roku(HOST, session=session) with pytest.raises(RokuError): assert await client._request("http/404")
async def test_timeout(aresponses): """Test request timeout from the API.""" # Faking a timeout by sleeping async def response_handler(_): await asyncio.sleep(2) return aresponses.Response(body="Timeout!") aresponses.add(MATCH_HOST, "/timeout", "GET", response_handler) async with ClientSession() as session: client = Roku(HOST, session=session, request_timeout=1) with pytest.raises(RokuConnectionError): assert await client._request("timeout")
async def test_tune(aresponses): """Test tune is handled correctly.""" aresponses.add( MATCH_HOST, "/launch/tvinput.dtv?contentID=tvinput.dtv&ch=13.4", "POST", aresponses.Response(status=200, text="OK"), match_querystring=True, ) async with ClientSession() as session: roku = Roku(HOST, session=session) await roku.tune("13.4")
async def main(): """Show example of connecting to your Roku.""" async with Roku("192.168.1.61") as roku: # Get Roku Device Info device = await roku.update() print(device.info) await roku.remote("poweron") await asyncio.sleep(2) await roku.remote("home") # Open Netflix await asyncio.sleep(2) await roku.launch("12")
async def test_xml_request_parse_error(aresponses): """Test invalid XML response is handled correctly.""" aresponses.add( MATCH_HOST, "/response/xml-parse-error", "GET", aresponses.Response( status=200, headers={"Content-Type": "application/xml"}, text="<!status>>", ), ) async with ClientSession() as session: client = Roku(HOST, session=session) with pytest.raises(RokuError): assert await client._request("response/xml-parse-error")
async def test_get_active_app(aresponses): """Test _get_active_app method is handled correctly.""" aresponses.add( MATCH_HOST, "/query/active-app", "GET", aresponses.Response( status=200, headers={"Content-Type": "application/xml"}, text=load_fixture("active-app-amazon.xml"), ), ) async with ClientSession() as session: client = Roku(HOST, session=session) assert await client._get_active_app()
async def test_get_media_state_play(aresponses): """Test _get_media_state method is handled correctly with playing media.""" aresponses.add( MATCH_HOST, "/query/media-player", "GET", aresponses.Response( status=200, headers={"Content-Type": "application/xml"}, text=load_fixture("media-player-pluto-play.xml"), ), ) async with ClientSession() as session: client = Roku(HOST, session=session) assert await client._get_media_state()
async def test_play_on_roku(aresponses: ResponsesMockServer) -> None: """Test play_on_roku is handled correctly.""" video_url = "http://example.com/video file÷awe.mp4?v=2" encoded = "http%3A%2F%2Fexample.com%2Fvideo+file%C3%B7awe.mp4%3Fv%3D2" aresponses.add( MATCH_HOST, f"/input/15985?t=v&u={encoded}", "POST", aresponses.Response(status=200), match_querystring=True, ) async with ClientSession() as session: roku = Roku(HOST, session=session) await roku.play_on_roku(video_url)
async def test_get_device_info(aresponses: ResponsesMockServer) -> None: """Test _get_device_info method is handled correctly.""" aresponses.add( MATCH_HOST, "/query/device-info", "GET", aresponses.Response( status=200, headers={"Content-Type": "application/xml"}, text="<other>value</other>", ), ) async with ClientSession() as session: client = Roku(HOST, session=session) with pytest.raises(RokuError): assert await client._get_device_info()
async def test_get_media_state_invalid(aresponses): """Test _get_media_state method is handled correctly with invalid data.""" aresponses.add( MATCH_HOST, "/query/media-player", "GET", aresponses.Response( status=200, headers={"Content-Type": "application/xml"}, text="<other>value</other>", ), ) async with ClientSession() as session: client = Roku(HOST, session=session) with pytest.raises(RokuError): assert await client._get_media_state()
async def test_get_tv_channels(aresponses): """Test _get_tv_channels method is handled correctly.""" aresponses.add( MATCH_HOST, "/query/tv-channels", "GET", aresponses.Response( status=200, headers={"Content-Type": "application/xml"}, text="<other>value</other>", ), ) async with ClientSession() as session: client = Roku(HOST, session=session) with pytest.raises(RokuError): assert await client._get_tv_channels()
async def test_get_tv_channels_single_channel(aresponses): """Test _get_tv_channels method is handled correctly with single channel.""" aresponses.add( MATCH_HOST, "/query/tv-channels", "GET", aresponses.Response( status=200, headers={"Content-Type": "application/xml"}, text=load_fixture("tv-channels-single.xml"), ), ) async with ClientSession() as session: client = Roku(HOST, session=session) res = await client._get_tv_channels() assert isinstance(res, List) assert len(res) == 1
async def test_get_apps_single_app(aresponses: ResponsesMockServer) -> None: """Test _get_apps method is handled correctly with single app.""" aresponses.add( MATCH_HOST, "/query/apps", "GET", aresponses.Response( status=200, headers={"Content-Type": "application/xml"}, text=load_fixture("apps-single.xml"), ), ) async with ClientSession() as session: client = Roku(HOST, session=session) res = await client._get_apps() assert isinstance(res, list) assert len(res) == 1
def __init__( self, hass: HomeAssistantType, *, host: str, ): """Initialize global Roku data updater.""" self.roku = Roku(host=host, session=async_get_clientsession(hass)) self.full_update_interval = timedelta(minutes=15) self.last_full_update = None super().__init__( hass, _LOGGER, name=DOMAIN, update_interval=SCAN_INTERVAL, )
async def test_internal_session(aresponses: ResponsesMockServer) -> None: """Test JSON response is handled correctly with internal session.""" aresponses.add( MATCH_HOST, "/response/xml", "GET", aresponses.Response( status=200, headers={"Content-Type": "application/xml"}, text="<status>OK</status>", ), ) async with Roku(HOST) as client: response = await client._request("response/xml") assert isinstance(response, dict) assert response["status"] == "OK"
def __init__( self, opp: OpenPeerPower, *, host: str, ) -> None: """Initialize global Roku data updater.""" self.roku = Roku(host=host, session=async_get_clientsession(opp)) self.full_update_interval = timedelta(minutes=15) self.last_full_update = None super().__init__( opp, _LOGGER, name=DOMAIN, update_interval=SCAN_INTERVAL, )