Skip to content

Commit

Permalink
Add initial tests for better exception handling
Browse files Browse the repository at this point in the history
  • Loading branch information
iMicknl committed Jun 4, 2023
1 parent 2ac68d0 commit bbac6b0
Show file tree
Hide file tree
Showing 16 changed files with 156 additions and 4 deletions.
8 changes: 7 additions & 1 deletion pyoverkiz/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
NoRegisteredEventListenerException,
NotAuthenticatedException,
NotSuchTokenException,
ServiceUnavailableException,
SessionAndBearerInSameRequestException,
SomfyBadCredentialsException,
SomfyServiceException,
Expand Down Expand Up @@ -802,8 +803,13 @@ async def check_response(response: ClientResponse) -> None:
result = await response.json(content_type=None)
except JSONDecodeError as error:
result = await response.text()
if "Server is down for maintenance" in result:

if "is down for maintenance" in result:
raise MaintenanceException("Server is down for maintenance") from error

if response.status == 503:
raise ServiceUnavailableException(result) from error

raise Exception(
f"Unknown error while requesting {response.url}. {response.status} - {result}"
) from error
Expand Down
6 changes: 5 additions & 1 deletion pyoverkiz/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,11 @@ class TooManyConcurrentRequestsException(BaseOverkizException):
pass


class MaintenanceException(BaseOverkizException):
class ServiceUnavailableException(BaseOverkizException):
pass


class MaintenanceException(ServiceUnavailableException):
pass


Expand Down
Empty file.
64 changes: 64 additions & 0 deletions tests/fixtures/exceptions/cloud/503-maintenance.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<html>

<head>
<style>
body {
font-family: Circular, "Helvetica Neue", Helvetica, Arial, sans-serif;
color: rgb(72, 72, 72);
}
</style>
</head>

<body style="margin:0;padding:0">
<div style="padding: 20px 25px 20px 20px"> <svg version="1.1" x="0px" y="0px" viewBox="0 0 150 150"
xml:space="preserve" width="150" height="150" xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg" xmlns:i="&amp;ns_ai;">
<style type="text/css" id="style18">
.st0 {
fill: none;
}

.st1 {
fill: #3D423D;
}

.st2 {
fill: #8C918C;
}

.st3 {
fill: #C8D419;
}

.st4 {
fill: #F39200;
}
</style>
<switch id="switch40">
<foreignObject requiredExtensions="http://ns.adobe.com/AdobeIllustrator/10.0/" x="0" y="0" width="1"
height="1"></foreignObject>
<g i:extraneous="self" id="g38">
<rect class="st0" width="965.29999" height="265.29999" id="rect20" x="0" y="0" />
<g id="g36" style="display:inline">
<g id="g34" transform="translate(-68.977383,-46.879183)">
<g id="g32">
<polygon class="st3" points="87.2,88.9 203.6,88.9 145.4,59.3 " id="polygon26" />
<polygon class="st4" points="203.6,160.8 203.6,88.9 149.8,182.7 " id="polygon28" />
<polygon class="st3" points="87.2,160.9 87.2,88.9 145.4,160.9 " id="polygon30" />
</g>
</g>
</g>
<polygon class="st2" points="87.2,160.9 145.4,59.3 87.2,88.9 " id="polygon24"
style="fill:#8c918c;fill-opacity:0.847297" transform="translate(-68.977383,-46.879183)" />
</g>
</switch>
</svg> </div>
<div
style="padding: 100px;text-align: center;font-size: 40px;background-color: #eeeeee;border-bottom: 2px solid #dddddd;border-top: 2px solid #dddddd">
<span style="font-64px: size;font-weight: bold">Oops !</span><br />
Our service is down for maintenance.<br />Please try again later.<br /> <br /> <span
style="font-64px: size;font-weight: bold;color: #bbbbbb">503</span>
</div>
</body>

</html>
4 changes: 4 additions & 0 deletions tests/fixtures/exceptions/cloud/access-denied-to-gateway.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"errorCode": "RESOURCE_ACCESS_DENIED",
"error": "Access denied to gateway #1234-5678-1234 for action ADD_TOKEN"
}
4 changes: 4 additions & 0 deletions tests/fixtures/exceptions/cloud/bad-credentials.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"errorCode": "AUTHENTICATION_ERROR",
"error": "Bad credentials"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"error": "Missing authorization token.",
"errorCode": "RESOURCE_ACCESS_DENIED"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"error": "\"No registered event listener.\"",
"errorCode": "UNSPECIFIED_ERROR"
}
4 changes: 4 additions & 0 deletions tests/fixtures/exceptions/cloud/not-authenticated.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"errorCode": "RESOURCE_ACCESS_DENIED",
"error": "Not authenticated"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"errorCode": "RESOURCE_ACCESS_DENIED",
"error": "too many concurrent requests"
}
3 changes: 3 additions & 0 deletions tests/fixtures/exceptions/cloud/too-many-executions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"error": "Server busy, please try again later. (Too many executions)"
}
4 changes: 4 additions & 0 deletions tests/fixtures/exceptions/cloud/too-many-requests.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"errorCode": "AUTHENTICATION_ERROR",
"error": "Too many requests, try again later : login with xxx@xxx.tld"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"errorCode": "UNSPECIFIED_ERROR",
"error": "No registered event listener"
}
4 changes: 4 additions & 0 deletions tests/fixtures/exceptions/local/not-authenticated.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"error": "Not authenticated.",
"errorCode": "RESOURCE_ACCESS_DENIED"
}
4 changes: 4 additions & 0 deletions tests/fixtures/exceptions/local/unknown-object.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"error": "Unknown object.",
"errorCode": "UNSPECIFIED_ERROR"
}
39 changes: 37 additions & 2 deletions tests/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import pytest
from pytest import fixture

from pyoverkiz import exceptions
from pyoverkiz.client import OverkizClient
from pyoverkiz.const import SUPPORTED_SERVERS
from pyoverkiz.enums import DataType
Expand Down Expand Up @@ -193,16 +194,50 @@ async def test_get_diagnostic_data(self, client: OverkizClient, fixture_name: st
diagnostics = await client.get_diagnostic_data()
assert diagnostics

@pytest.mark.parametrize(
"fixture_name, status_code, exception",
[
("cloud/503-empty.html", 503, exceptions.ServiceUnavailableException),
("cloud/503-maintenance.html", 503, exceptions.MaintenanceException),
(
"cloud/access-denied-to-gateway.json",
400,
exceptions.AccessDeniedToGatewayException,
),
],
)
@pytest.mark.asyncio
async def test_check_response_exception_handling(
self,
client: OverkizClient,
fixture_name: str,
status_code: int,
exception: Exception,
):
with pytest.raises(exception):
if fixture_name:
with open(
os.path.join(CURRENT_DIR, "fixtures/exceptions/" + fixture_name),
encoding="utf-8",
) as raw_events:
resp = MockResponse(raw_events.read(), status_code)
else:
resp = MockResponse(None, status_code)

await client.check_response(resp)


class MockResponse:
def __init__(self, text, status=200):
def __init__(self, text, status=200, url=""):
self._text = text
self.status = status
self.url = url

async def text(self):
return self._text

async def json(self):
# pylint: disable=unused-argument
async def json(self, content_type=None):
return json.loads(self._text)

async def __aexit__(self, exc_type, exc, tb):
Expand Down

0 comments on commit bbac6b0

Please sign in to comment.