-
Notifications
You must be signed in to change notification settings - Fork 7
#13 Refactor usage of roles to add support for delegated devices #14
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6,6 +6,7 @@ | |
| DEVICE_TYPE_UNKNOWN = "unknown" | ||
|
|
||
| ACCESS_LEVEL = { | ||
| "USER": 2, | ||
| "GUEST": 3, | ||
| "OWNER": 4, | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -24,10 +24,10 @@ class Device(ABC): | |
| """MELCloud base device representation.""" | ||
|
|
||
| def __init__( | ||
| self, | ||
| device_conf: Dict[str, Any], | ||
| client: Client, | ||
| set_debounce=timedelta(seconds=1), | ||
| self, | ||
| device_conf: Dict[str, Any], | ||
| client: Client, | ||
| set_debounce=timedelta(seconds=1), | ||
| ): | ||
| """Initialize a device.""" | ||
| self.device_id = device_conf.get("DeviceID") | ||
|
|
@@ -96,9 +96,7 @@ async def update(self): | |
| self._state = await self._client.fetch_device_state(self) | ||
| self._energy_report = await self._client.fetch_energy_report(self) | ||
|
|
||
| if self._device_units is None and self.access_level != ACCESS_LEVEL.get( | ||
| "GUEST" | ||
| ): | ||
| if self._device_units is None: | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If I understand this correctly, removing the check if the access level is not guest, will allow the usage for delegated devices?
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I removed it because a try-catch block covers this case |
||
| self._device_units = await self._client.fetch_device_units(self) | ||
|
|
||
| async def set(self, properties: Dict[str, Any]): | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,63 @@ | ||
| """Client tests.""" | ||
| import pytest | ||
| from unittest.mock import AsyncMock, Mock, patch | ||
| from aiohttp import ClientResponseError, ClientSession | ||
| from pymelcloud.client import Client | ||
|
|
||
|
|
||
| @pytest.mark.asyncio | ||
| async def test_fetch_energy_report_ignores_403(): | ||
| session = Mock(spec=ClientSession) | ||
| cm = AsyncMock() | ||
| session.post.return_value = cm | ||
|
|
||
| resp = Mock() | ||
| cm.__aenter__.return_value = resp | ||
|
|
||
| request_info = Mock() | ||
| request_info.real_url = "https://example.test/EnergyCost/Report" | ||
|
|
||
| resp.raise_for_status.side_effect = ClientResponseError( | ||
| request_info=request_info, | ||
| history=(), | ||
| status=403, | ||
| message="Forbidden", | ||
| ) | ||
|
|
||
| client = Client(token="dummy", session=session) | ||
|
|
||
| class DummyDevice: | ||
| device_id = 123 | ||
|
|
||
| device = DummyDevice() | ||
| result = await client.fetch_energy_report(device) | ||
| assert result is None | ||
|
|
||
|
|
||
| @pytest.mark.asyncio | ||
| async def test_fetch_device_units_ignores_403(): | ||
| session = Mock(spec=ClientSession) | ||
| cm = AsyncMock() | ||
| session.post.return_value = cm | ||
|
|
||
| resp = Mock() | ||
| cm.__aenter__.return_value = resp | ||
|
|
||
| request_info = Mock() | ||
| request_info.real_url = "https://example.test/Device/ListDeviceUnits" | ||
|
|
||
| resp.raise_for_status.side_effect = ClientResponseError( | ||
| request_info=request_info, | ||
| history=(), | ||
| status=403, | ||
| message="Forbidden", | ||
| ) | ||
|
|
||
| client = Client(token="dummy", session=session) | ||
|
|
||
| class DummyDevice: | ||
| device_id = 123 | ||
|
|
||
| device = DummyDevice() | ||
| result = await client.fetch_device_units(device) | ||
| assert result is None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there also a more thorough way to determine the a successful call of this type? HTTP statuscode or content-type returned?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Status code is checked by raise_for_status. I will add an additional check for content-type. Thank you for the idea