async def test_update(event_loop, aresponses): """Test request for updating data from Twente Milieu.""" aresponses.add( API_HOST, "{}FetchAdress".format(API_BASE_URI), "POST", aresponses.Response( status=200, headers={"Content-Type": "application/json"}, text='{"dataList": [{"UniqueId": "12345"}]}', ), ) aresponses.add( API_HOST, "{}GetCalendar".format(API_BASE_URI), "POST", aresponses.Response( status=200, headers={"Content-Type": "application/json"}, text=json.dumps({ "dataList": [ { "pickupDates": [ "2019-07-19T00:00:00", "2019-07-20T00:00:00", ], "_pickupTypeText": "GREEN", }, { "pickupDates": ["2019-07-21T00:00:00"], "_pickupTypeText": "GREY", }, { "pickupDates": ["2019-07-22T00:00:00"], "_pickupTypeText": "PAPER", }, { "pickupDates": [], "_pickupTypeText": "PACKAGES" }, ] }), ), ) async with aiohttp.ClientSession(loop=event_loop) as session: tw = TwenteMilieu(post_code="1234AB", house_number=1, session=session, loop=event_loop) await tw.update() pickup = await tw.next_pickup(WASTE_TYPE_NON_RECYCLABLE) assert pickup == datetime(2019, 7, 21, 0, 0) pickup = await tw.next_pickup(WASTE_TYPE_ORGANIC) assert pickup == datetime(2019, 7, 19, 0, 0) pickup = await tw.next_pickup(WASTE_TYPE_PAPER) assert pickup == datetime(2019, 7, 22, 0, 0) pickup = await tw.next_pickup(WASTE_TYPE_PLASTIC) assert pickup is None
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Set up Twente Milieu from a config entry.""" session = async_get_clientsession(hass) twentemilieu = TwenteMilieu( post_code=entry.data[CONF_POST_CODE], house_number=entry.data[CONF_HOUSE_NUMBER], house_letter=entry.data[CONF_HOUSE_LETTER], session=session, ) coordinator: DataUpdateCoordinator[ dict[WasteType, date | None] ] = DataUpdateCoordinator( hass, LOGGER, name=DOMAIN, update_interval=SCAN_INTERVAL, update_method=twentemilieu.update, ) await coordinator.async_config_entry_first_refresh() # For backwards compat, set unique ID if entry.unique_id is None: hass.config_entries.async_update_entry( entry, unique_id=str(entry.data[CONF_ID]) ) hass.data.setdefault(DOMAIN, {})[entry.data[CONF_ID]] = coordinator hass.config_entries.async_setup_platforms(entry, PLATFORMS) return True
async def test_text_request(event_loop, aresponses): """Test non JSON response is handled correctly.""" aresponses.add(API_HOST, API_BASE_URI, "POST", aresponses.Response(status=200, text="OK")) async with aiohttp.ClientSession(loop=event_loop) as session: tw = TwenteMilieu(post_code="1234AB", house_number=1, session=session, loop=event_loop) response = await tw._request("") assert response == "OK"
async def test_internal_eventloop(aresponses): """Test JSON response is handled correctly.""" aresponses.add( API_HOST, API_BASE_URI, "POST", aresponses.Response( status=200, headers={"Content-Type": "application/json"}, text='{"status": "ok"}', ), ) async with TwenteMilieu(post_code="1234AB", house_number=1) as tw: response = await tw._request("") assert response["status"] == "ok"
async def main(loop): """Show example on stats from Twente Milieu.""" async with TwenteMilieu(post_code="7545KR", house_number=175, loop=loop) as tw: print(tw) unique_id = await tw.unique_id() print("Unique Address ID:", unique_id) await tw.update() pickup = await tw.next_pickup(WASTE_TYPE_ORGANIC) print("Next pickup for Organic:", pickup) pickup = await tw.next_pickup(WASTE_TYPE_PLASTIC) print("Next pickup for Plastic:", pickup) pickup = await tw.next_pickup(WASTE_TYPE_PAPER) print("Next pickup for Paper:", pickup) pickup = await tw.next_pickup(WASTE_TYPE_NON_RECYCLABLE) print("Next pickup for Non-recyclable:", pickup)
async def test_http_error400(event_loop, aresponses): """Test HTTP 404 response handling.""" aresponses.add( API_HOST, API_BASE_URI, "POST", aresponses.Response(text="OMG PUPPIES!", status=404), ) async with aiohttp.ClientSession(loop=event_loop) as session: tw = TwenteMilieu(post_code="1234AB", house_number=1, session=session, loop=event_loop) with pytest.raises(TwenteMilieuError): assert await tw._request("")
async def test_request_user_agent(event_loop, aresponses): """Test if client is sending correct user agent headers.""" # Handle to run asserts on request in async def response_handler(request): assert request.headers["User-Agent"] == "PythonTwenteMilieu/{}".format( __version__) return aresponses.Response(text="TEDDYBEAR", status=200) aresponses.add(API_HOST, API_BASE_URI, "POST", response_handler) async with aiohttp.ClientSession(loop=event_loop) as session: tw = TwenteMilieu(post_code="1234AB", house_number=1, session=session, loop=event_loop) await tw._request("")
async def test_json_request(event_loop, aresponses): """Test JSON response is handled correctly.""" aresponses.add( API_HOST, API_BASE_URI, "POST", aresponses.Response( status=200, headers={"Content-Type": "application/json"}, text='{"status": "ok"}', ), ) async with aiohttp.ClientSession(loop=event_loop) as session: tw = TwenteMilieu(post_code="1234AB", house_number=1, session=session, loop=event_loop) response = await tw._request("") assert response["status"] == "ok"
async def test_invalid_address(event_loop, aresponses): """Test request of invalid address information.""" aresponses.add( API_HOST, "{}FetchAdress".format(API_BASE_URI), "POST", aresponses.Response( status=200, headers={"Content-Type": "application/json"}, text='{"dataList": []}', ), ) async with aiohttp.ClientSession(loop=event_loop) as session: tw = TwenteMilieu(post_code="1234AB", house_number=1, session=session, loop=event_loop) with pytest.raises(TwenteMilieuAddressError): assert await tw.unique_id()
async def test_unique_id(event_loop, aresponses): """Test request of a unique address identifier.""" aresponses.add( API_HOST, "{}FetchAdress".format(API_BASE_URI), "POST", aresponses.Response( status=200, headers={"Content-Type": "application/json"}, text='{"dataList": [{"UniqueId": "12345"}]}', ), ) async with aiohttp.ClientSession(loop=event_loop) as session: tw = TwenteMilieu(post_code="1234AB", house_number=1, session=session, loop=event_loop) unique_id = await tw.unique_id() assert unique_id == "12345"
async def test_http_error500(event_loop, aresponses): """Test HTTP 500 response handling.""" aresponses.add( API_HOST, API_BASE_URI, "POST", aresponses.Response( body=b'{"status":"nok"}', status=500, headers={"Content-Type": "application/json"}, ), ) async with aiohttp.ClientSession(loop=event_loop) as session: tw = TwenteMilieu(post_code="1234AB", house_number=1, session=session, loop=event_loop) with pytest.raises(TwenteMilieuError): assert await tw._request("")
async def test_timeout(event_loop, aresponses): """Test request timeout from Twente Milieu.""" # Faking a timeout by sleeping async def response_handler(_): await asyncio.sleep(2) return aresponses.Response(body="Goodmorning!") aresponses.add(API_HOST, API_BASE_URI, "POST", response_handler) async with aiohttp.ClientSession(loop=event_loop) as session: tw = TwenteMilieu( post_code="1234AB", house_number=1, session=session, loop=event_loop, request_timeout=1, ) with pytest.raises(TwenteMilieuConnectionError): assert await tw._request("")
async def async_step_user( self, user_input: dict[str, Any] | None = None ) -> dict[str, Any]: """Handle a flow initiated by the user.""" if user_input is None: return await self._show_setup_form(user_input) errors = {} session = async_get_clientsession(self.hass) twentemilieu = TwenteMilieu( post_code=user_input[CONF_POST_CODE], house_number=user_input[CONF_HOUSE_NUMBER], house_letter=user_input.get(CONF_HOUSE_LETTER), session=session, ) try: unique_id = await twentemilieu.unique_id() except TwenteMilieuConnectionError: errors["base"] = "cannot_connect" return await self._show_setup_form(errors) except TwenteMilieuAddressError: errors["base"] = "invalid_address" return await self._show_setup_form(errors) entries = self._async_current_entries() for entry in entries: if entry.data[CONF_ID] == unique_id: return self.async_abort(reason="already_configured") return self.async_create_entry( title=str(unique_id), data={ CONF_ID: unique_id, CONF_POST_CODE: user_input[CONF_POST_CODE], CONF_HOUSE_NUMBER: user_input[CONF_HOUSE_NUMBER], CONF_HOUSE_LETTER: user_input.get(CONF_HOUSE_LETTER), }, )
async def async_setup_entry(opp: OpenPeerPower, entry: ConfigEntry) -> bool: """Set up Twente Milieu from a config entry.""" session = async_get_clientsession(opp) twentemilieu = TwenteMilieu( post_code=entry.data[CONF_POST_CODE], house_number=entry.data[CONF_HOUSE_NUMBER], house_letter=entry.data[CONF_HOUSE_LETTER], session=session, ) unique_id = entry.data[CONF_ID] opp.data.setdefault(DOMAIN, {})[unique_id] = twentemilieu opp.config_entries.async_setup_platforms(entry, PLATFORMS) async def _interval_update(now=None) -> None: """Update Twente Milieu data.""" await _update_twentemilieu(opp, unique_id) async_track_time_interval(opp, _interval_update, SCAN_INTERVAL) return True
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Set up Twente Milieu from a config entry.""" session = async_get_clientsession(hass) twentemilieu = TwenteMilieu( post_code=entry.data[CONF_POST_CODE], house_number=entry.data[CONF_HOUSE_NUMBER], house_letter=entry.data[CONF_HOUSE_LETTER], session=session, ) unique_id = entry.data[CONF_ID] hass.data.setdefault(DOMAIN, {})[unique_id] = twentemilieu hass.async_create_task( hass.config_entries.async_forward_entry_setup(entry, "sensor") ) async def _interval_update(now=None) -> None: """Update Twente Milieu data.""" await _update_twentemilieu(hass, unique_id) async_track_time_interval(hass, _interval_update, SCAN_INTERVAL) return True