async def test_enabled(aresponses): """Test request of current AdGuard Home safe search enforcing status.""" aresponses.add( "example.com:3000", "/control/safesearch/status", "GET", aresponses.Response( status=200, headers={"Content-Type": "application/json"}, text='{"enabled": true}', ), ) aresponses.add( "example.com:3000", "/control/safesearch/status", "GET", aresponses.Response( status=200, headers={"Content-Type": "application/json"}, text='{"enabled": false}', ), ) async with aiohttp.ClientSession() as session: adguard = AdGuardHome("example.com", session=session) enabled = await adguard.safesearch.enabled() assert enabled enabled = await adguard.safesearch.enabled() assert not enabled
async def test_enabled(event_loop, aresponses): """Test request of current AdGuard Home filter status.""" aresponses.add( "example.com:3000", "/control/filtering/status", "GET", aresponses.Response( status=200, headers={"Content-Type": "application/json"}, text='{"enabled": true}', ), ) aresponses.add( "example.com:3000", "/control/filtering/status", "GET", aresponses.Response( status=200, headers={"Content-Type": "application/json"}, text='{"enabled": false}', ), ) async with aiohttp.ClientSession(loop=event_loop) as session: adguard = AdGuardHome("example.com", session=session, loop=event_loop) enabled = await adguard.filtering.enabled() assert enabled enabled = await adguard.filtering.enabled() assert not enabled
async def test_enabled(aresponses): """Test request of current AdGuard Home query log status.""" aresponses.add( "example.com:3000", "/control/querylog_info", "GET", aresponses.Response( status=200, headers={"Content-Type": "application/json"}, text='{"enabled": true,"interval": 1}', ), ) aresponses.add( "example.com:3000", "/control/querylog_info", "GET", aresponses.Response( status=200, headers={"Content-Type": "application/json"}, text='{"enabled": false,"interval": 1}', ), ) async with aiohttp.ClientSession() as session: adguard = AdGuardHome("example.com", session=session) enabled = await adguard.querylog.enabled() enabled = await adguard.querylog.enabled() assert not enabled
async def test_refresh(event_loop, aresponses): """Test enabling filter subscription in AdGuard Home filtering.""" aresponses.add( "example.com:3000", "/control/filtering/refresh?force=false", "POST", aresponses.Response(status=200, text="OK"), match_querystring=True, ) aresponses.add( "example.com:3000", "/control/filtering/refresh?force=true", "POST", aresponses.Response(status=200, text="OK"), match_querystring=True, ) aresponses.add( "example.com:3000", "/control/filtering/refresh?force=false", "POST", aresponses.Response(status=200, text="Not OK"), match_querystring=True, ) async with aiohttp.ClientSession(loop=event_loop) as session: adguard = AdGuardHome("example.com", session=session, loop=event_loop) result = await adguard.filtering.refresh(False) assert result result = await adguard.filtering.refresh(True) assert result with pytest.raises(AdGuardHomeError): await adguard.filtering.refresh(False)
async def test_rules_count(event_loop, aresponses): """Test getting rules count of the AdGuard Home filtering.""" aresponses.add( "example.com:3000", "/control/filtering/status", "GET", aresponses.Response( status=200, headers={"Content-Type": "application/json"}, text='{"filters": [{"rulesCount": 99}, {"rulesCount": 1}]}', ), ) aresponses.add( "example.com:3000", "/control/filtering/status", "GET", aresponses.Response( status=200, headers={"Content-Type": "application/json"}, text='{"filters": []}', ), ) async with aiohttp.ClientSession(loop=event_loop) as session: adguard = AdGuardHome("example.com", session=session, loop=event_loop) result = await adguard.filtering.rules_count() assert result == 100 result = await adguard.filtering.rules_count() assert result == 0
async def test_add_url(event_loop, aresponses): """Test add new filter subscription to AdGuard Home filtering.""" # Handle to run asserts on request in async def response_handler(request): data = await request.json() assert data == {"name": "Example", "url": "https://example.com/1.txt"} return aresponses.Response(status=200, text="OK 12345 filters added") aresponses.add("example.com:3000", "/control/filtering/add_url", "POST", response_handler) aresponses.add( "example.com:3000", "/control/filtering/add_url", "POST", aresponses.Response(status=200, text="Invalid URL"), ) async with aiohttp.ClientSession(loop=event_loop) as session: adguard = AdGuardHome("example.com", session=session, loop=event_loop) result = await adguard.filtering.add_url("Example", "https://example.com/1.txt") assert result with pytest.raises(AdGuardHomeError): await adguard.filtering.add_url("Example", "https://example.com/1.txt")
async def test_disable_url(event_loop, aresponses): """Test enabling filter subscription in AdGuard Home filtering.""" # Handle to run asserts on request in async def response_handler(request): data = await request.text() assert data == "url=https://example.com/1.txt" return aresponses.Response(status=200, text="OK") aresponses.add("example.com:3000", "/control/filtering/disable_url", "POST", response_handler) aresponses.add( "example.com:3000", "/control/filtering/disable_url", "POST", aresponses.Response(status=200, text="Invalid URL"), ) async with aiohttp.ClientSession(loop=event_loop) as session: adguard = AdGuardHome("example.com", session=session, loop=event_loop) result = await adguard.filtering.disable_url( "https://example.com/1.txt") assert result with pytest.raises(AdGuardHomeError): await adguard.filtering.disable_url("https://example.com/1.txt")
async def test_remove_url(aresponses): """Test remove filter subscription from AdGuard Home filtering.""" # Handle to run asserts on request in async def response_handler(request): """Response handler for this test.""" data = await request.json() assert data == {"url": "https://example.com/1.txt", "whitelist": False} return aresponses.Response(status=200, text="OK") aresponses.add("example.com:3000", "/control/filtering/remove_url", "POST", response_handler) aresponses.add( "example.com:3000", "/control/filtering/remove_url", "POST", aresponses.Response(status=400, text="Invalid URL"), ) async with aiohttp.ClientSession() as session: adguard = AdGuardHome("example.com", session=session) await adguard.filtering.remove_url(allowlist=False, url="https://example.com/1.txt") with pytest.raises(AdGuardHomeError): await adguard.filtering.remove_url(allowlist=False, url="https://example.com/1.txt")
async def async_step_hassio_confirm(self, user_input=None): """Confirm Hass.io discovery.""" if user_input is None: return await self._show_hassio_form() errors = {} session = async_get_clientsession(self.hass, False) adguard = AdGuardHome( self._hassio_discovery[CONF_HOST], port=self._hassio_discovery[CONF_PORT], tls=False, session=session, ) try: await adguard.version() except AdGuardHomeConnectionError: errors["base"] = "cannot_connect" return await self._show_hassio_form(errors) return self.async_create_entry( title=self._hassio_discovery["addon"], data={ CONF_HOST: self._hassio_discovery[CONF_HOST], CONF_PORT: self._hassio_discovery[CONF_PORT], CONF_PASSWORD: None, CONF_SSL: False, CONF_USERNAME: None, CONF_VERIFY_SSL: True, }, )
async def main(): """Show example how to get status of your AdGuard Home instance.""" async with AdGuardHome("192.168.1.2") as adguard: version = await adguard.version() print("AdGuard version:", version) active = await adguard.protection_enabled() active = "Yes" if active else "No" print("Protection enabled?", active) active = await adguard.filtering.enabled() active = "Yes" if active else "No" print("Filtering enabled?", active) active = await adguard.parental.enabled() active = "Yes" if active else "No" print("Parental control enabled?", active) active = await adguard.safebrowsing.enabled() active = "Yes" if active else "No" print("Safe browsing enabled?", active) active = await adguard.safesearch.enabled() active = "Yes" if active else "No" print("Enforce safe search enabled?", active)
async def main(): """Show example on stats from your AdGuard Home instance.""" async with AdGuardHome("192.168.1.2") as adguard: version = await adguard.version() print("AdGuard version:", version) period = await adguard.stats.period() print("Stats period:", period) result = await adguard.stats.avg_processing_time() print("Avarage processing time per query in ms:", result) result = await adguard.stats.dns_queries() print("DNS queries:", result) result = await adguard.stats.blocked_filtering() print("Blocked DNS queries:", result) result = await adguard.stats.blocked_percentage() print("Blocked DNS queries ratio:", result) result = await adguard.stats.replaced_safebrowsing() print("Pages blocked by safe browsing:", result) result = await adguard.stats.replaced_parental() print("Pages blocked by parental control:", result) result = await adguard.stats.replaced_safesearch() print("Number of enforced safe searches:", result) result = await adguard.filtering.rules_count() print("Total number of active rules:", result)
async def test_post_request(aresponses): """Test POST requests are handled correctly.""" aresponses.add("example.com:3000", "/", "POST", aresponses.Response(status=200, text="OK")) async with aiohttp.ClientSession() as session: adguard = AdGuardHome("example.com", session=session) response = await adguard.request("/", method="POST") assert response == {"message": "OK"}
async def test_text_request(event_loop, aresponses): """Test non JSON response is handled correctly.""" aresponses.add("example.com:3000", "/", "GET", aresponses.Response(status=200, text="OK")) async with aiohttp.ClientSession(loop=event_loop) as session: adguard = AdGuardHome("example.com", session=session, loop=event_loop) response = await adguard._request("/") assert response == "OK"
async def test_client_error(): """Test request client error from AdGuard Home.""" # Faking a timeout by sleeping async with aiohttp.ClientSession() as session: adguard = AdGuardHome("example.com", session=session) with patch.object(session, "request", side_effect=aiohttp.ClientError), pytest.raises( AdGuardHomeConnectionError): assert await adguard.request("/")
async def test_disable_url(aresponses): """Test enabling filter subscription in AdGuard Home filtering.""" # Handle to run asserts on request in async def response_handler(request): """Response handler for this test.""" data = await request.json() assert data == { "url": "https://example.com/1.txt", "whitelist": False, "data": { "enabled": False, "name": "test", "url": "https://example.com/1.txt", }, } return aresponses.Response(status=200) aresponses.add( "example.com:3000", "/control/filtering/status", "GET", aresponses.Response( status=200, headers={"Content-Type": "application/json"}, text= '{"filters": [{"url": "https://EXAMPLE.com/1.txt", "name": "test"}]}', ), ) aresponses.add("example.com:3000", "/control/filtering/set_url", "POST", response_handler) aresponses.add( "example.com:3000", "/control/filtering/status", "GET", aresponses.Response( status=200, headers={"Content-Type": "application/json"}, text= '{"filters": [{"url": "https://example.com/1.txt", "name": "test"}]}', ), ) aresponses.add( "example.com:3000", "/control/filtering/set_url", "POST", aresponses.Response(status=400), ) async with aiohttp.ClientSession() as session: adguard = AdGuardHome("example.com", session=session) await adguard.filtering.disable_url(allowlist=False, url="https://example.com/1.txt") with pytest.raises(AdGuardHomeError): await adguard.filtering.disable_url( allowlist=False, url="https://example.com/1.txt")
async def test_interval(aresponses): """Test interval settings of the AdGuard Home filtering.""" async def response_handler(request): data = await request.json() assert data == {"enabled": True, "interval": 1} return aresponses.Response(status=200) aresponses.add( "example.com:3000", "/control/filtering/status", "GET", aresponses.Response( status=200, headers={"Content-Type": "application/json"}, text='{"interval": 7}', ), ) aresponses.add( "example.com:3000", "/control/filtering/status", "GET", aresponses.Response( status=200, headers={"Content-Type": "application/json"}, text='{"enabled": true}', ), ) aresponses.add( "example.com:3000", "/control/filtering/config", "POST", response_handler ) aresponses.add( "example.com:3000", "/control/filtering/status", "GET", aresponses.Response( status=200, headers={"Content-Type": "application/json"}, text='{"enabled": true}', ), ) aresponses.add( "example.com:3000", "/control/filtering/config", "POST", aresponses.Response(status=400), ) async with aiohttp.ClientSession() as session: adguard = AdGuardHome("example.com", session=session) interval = await adguard.filtering.interval() assert interval == 7 interval = await adguard.filtering.interval(interval=1) assert interval == 1 with pytest.raises(AdGuardHomeError): await adguard.filtering.interval(interval=1)
async def test_rules_count(aresponses): """Test getting rules count of the AdGuard Home filtering.""" aresponses.add( "example.com:3000", "/control/filtering/status", "GET", aresponses.Response( status=200, headers={"Content-Type": "application/json"}, text='{"filters": [{"rules_count": 99}, {"rules_count": 1}]}', ), ) aresponses.add( "example.com:3000", "/control/filtering/status", "GET", aresponses.Response( status=200, headers={"Content-Type": "application/json"}, text='{"filters": []}', ), ) aresponses.add( "example.com:3000", "/control/filtering/status", "GET", aresponses.Response( status=200, headers={"Content-Type": "application/json"}, text= '{"whitelist_filters": [{"rules_count": 98}, {"rules_count": 1}]}', ), ) aresponses.add( "example.com:3000", "/control/filtering/status", "GET", aresponses.Response( status=200, headers={"Content-Type": "application/json"}, text='{"whitelist_filters": null}', ), ) async with aiohttp.ClientSession() as session: adguard = AdGuardHome("example.com", session=session) result = await adguard.filtering.rules_count(allowlist=False) assert result == 100 result = await adguard.filtering.rules_count(allowlist=False) assert result == 0 result = await adguard.filtering.rules_count(allowlist=True) assert result == 99 result = await adguard.filtering.rules_count(allowlist=True) assert result == 0
async def test_request_port(aresponses): """Test AdGuard Home running on non-standard port.""" aresponses.add( "example.com:3333", "/", "GET", aresponses.Response(text="OMG PUPPIES!", status=200), ) async with aiohttp.ClientSession() as session: adguard = AdGuardHome("example.com", port=3333, session=session) response = await adguard.request("/") assert response == {"message": "OMG PUPPIES!"}
async def test_http_error400(event_loop, aresponses): """Test HTTP 404 response handling.""" aresponses.add( "example.com:3000", "/", "GET", aresponses.Response(text="OMG PUPPIES!", status=404), ) async with aiohttp.ClientSession(loop=event_loop) as session: adguard = AdGuardHome("example.com", session=session, loop=event_loop) with pytest.raises(AdGuardHomeError): assert await adguard._request("/")
async def test_refresh(aresponses): """Test enabling filter subscription in AdGuard Home filtering.""" async def response_handler_whitelist(request): """Response handler for this test.""" data = await request.json() assert data == {"whitelist": True} return aresponses.Response(status=200) async def response_handler_blocklist(request): """Response handler for this test.""" data = await request.json() assert data == {"whitelist": False} return aresponses.Response(status=200) aresponses.add( "example.com:3000", "/control/filtering/refresh?force=false", "POST", response_handler_blocklist, match_querystring=True, ) aresponses.add( "example.com:3000", "/control/filtering/refresh?force=false", "POST", response_handler_whitelist, match_querystring=True, ) aresponses.add( "example.com:3000", "/control/filtering/refresh?force=true", "POST", aresponses.Response(status=200, text="OK"), match_querystring=True, ) aresponses.add( "example.com:3000", "/control/filtering/refresh?force=false", "POST", aresponses.Response(status=400, text="Not OK"), match_querystring=True, ) async with aiohttp.ClientSession() as session: adguard = AdGuardHome("example.com", session=session) await adguard.filtering.refresh(allowlist=False, force=False) await adguard.filtering.refresh(allowlist=True, force=False) await adguard.filtering.refresh(allowlist=False, force=True) with pytest.raises(AdGuardHomeError): await adguard.filtering.refresh(allowlist=False, force=False)
async def async_step_user(self, user_input=None): """Handle a flow initiated by the user.""" if self._async_current_entries(): return self.async_abort(reason="single_instance_allowed") if user_input is None: return await self._show_setup_form(user_input) errors = {} session = async_get_clientsession(self.hass, user_input[CONF_VERIFY_SSL]) adguard = AdGuardHome( user_input[CONF_HOST], port=user_input[CONF_PORT], username=user_input.get(CONF_USERNAME), password=user_input.get(CONF_PASSWORD), tls=user_input[CONF_SSL], verify_ssl=user_input[CONF_VERIFY_SSL], session=session, ) try: version = await adguard.version() except AdGuardHomeConnectionError: errors["base"] = "connection_error" return await self._show_setup_form(errors) if version and LooseVersion(MIN_ADGUARD_HOME_VERSION) > LooseVersion( version): return self.async_abort( reason="adguard_home_outdated", description_placeholders={ "current_version": version, "minimal_version": MIN_ADGUARD_HOME_VERSION, }, ) return self.async_create_entry( title=user_input[CONF_HOST], data={ CONF_HOST: user_input[CONF_HOST], CONF_PASSWORD: user_input.get(CONF_PASSWORD), CONF_PORT: user_input[CONF_PORT], CONF_SSL: user_input[CONF_SSL], CONF_USERNAME: user_input.get(CONF_USERNAME), CONF_VERIFY_SSL: user_input[CONF_VERIFY_SSL], }, )
async def test_request_user_agent(aresponses): """Test AdGuard Home client sending correct user agent headers.""" # Handle to run asserts on request in async def response_handler(request): """Response handler for this test.""" assert request.headers["User-Agent"] == "PythonAdGuardHome/0.0.0" return aresponses.Response(text="TEDDYBEAR", status=200) aresponses.add("example.com:3000", "/", "GET", response_handler) async with aiohttp.ClientSession() as session: adguard = AdGuardHome("example.com", base_path="/", session=session) await adguard.request("/")
async def test_internal_eventloop(aresponses): """Test JSON response is handled correctly.""" aresponses.add( "example.com:3000", "/", "GET", aresponses.Response( status=200, headers={"Content-Type": "application/json"}, text='{"status": "ok"}', ), ) async with AdGuardHome("example.com") as adguard: response = await adguard._request("/") assert response["status"] == "ok"
async def test_request_base_path(aresponses): """Test AdGuard Home running on different base path.""" aresponses.add( "example.com:3000", "/admin/status", "GET", aresponses.Response(text="OMG PUPPIES!", status=200), ) async with aiohttp.ClientSession() as session: adguard = AdGuardHome("example.com", base_path="/admin", session=session) response = await adguard.request("status") assert response == {"message": "OMG PUPPIES!"}
async def test_replaced_parental(event_loop, aresponses): """Test requesting AdGuard Home parental control stats.""" aresponses.add( "example.com:3000", "/control/stats", "GET", aresponses.Response( status=200, headers={"Content-Type": "application/json"}, text='{"replaced_parental": 13}', ), ) async with aiohttp.ClientSession(loop=event_loop) as session: adguard = AdGuardHome("example.com", session=session, loop=event_loop) result = await adguard.stats.replaced_parental() assert result == 13
async def test_verion(event_loop, aresponses): """Test requesting AdGuard Home instance version.""" aresponses.add( "example.com:3000", "/control/status", "GET", aresponses.Response( status=200, headers={"Content-Type": "application/json"}, text='{"version": "1.1"}', ), ) async with aiohttp.ClientSession(loop=event_loop) as session: adguard = AdGuardHome("example.com", session=session, loop=event_loop) version = await adguard.version() assert version == "1.1"
async def test_blocked_percentage(event_loop, aresponses): """Test requesting AdGuard Home filtering stats.""" aresponses.add( "example.com:3000", "/control/stats", "GET", aresponses.Response( status=200, headers={"Content-Type": "application/json"}, text='{"dns_queries": 100, "blocked_filtering": 25}', ), ) async with aiohttp.ClientSession(loop=event_loop) as session: adguard = AdGuardHome("example.com", session=session, loop=event_loop) result = await adguard.stats.blocked_percentage() assert result == 25.0
async def test_avg_processing_time(aresponses): """Test requesting AdGuard Home DNS average processing time stats.""" aresponses.add( "example.com:3000", "/control/stats", "GET", aresponses.Response( status=200, headers={"Content-Type": "application/json"}, text='{"avg_processing_time": 0.03141}', ), ) async with aiohttp.ClientSession() as session: adguard = AdGuardHome("example.com", session=session) result = await adguard.stats.avg_processing_time() assert result == 31.41
async def test_dns_queries(aresponses): """Test requesting AdGuard Home number of DNS query stats.""" aresponses.add( "example.com:3000", "/control/stats", "GET", aresponses.Response( status=200, headers={"Content-Type": "application/json"}, text='{"num_dns_queries": 666}', ), ) async with aiohttp.ClientSession() as session: adguard = AdGuardHome("example.com", session=session) result = await adguard.stats.dns_queries() assert result == 666
async def test_replaced_safebrowsing(aresponses): """Test requesting AdGuard Home safebrowsing stats.""" aresponses.add( "example.com:3000", "/control/stats", "GET", aresponses.Response( status=200, headers={"Content-Type": "application/json"}, text='{"num_replaced_safebrowsing": 42}', ), ) async with aiohttp.ClientSession() as session: adguard = AdGuardHome("example.com", session=session) result = await adguard.stats.replaced_safebrowsing() assert result == 42