Skip to content

Commit

Permalink
Merge pull request #42 from Lightmatter/feature/test-coverage
Browse files Browse the repository at this point in the history
Feature/test coverage
  • Loading branch information
samamorgan authored Oct 3, 2022
2 parents 34dd435 + 2708384 commit a666fa9
Show file tree
Hide file tree
Showing 5 changed files with 247 additions and 16 deletions.
58 changes: 58 additions & 0 deletions test/cassettes/test_exception.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
interactions:
- request:
body: null
headers:
Accept:
- '*/*'
Accept-Encoding:
- gzip, deflate
Authorization:
- API_TOKEN_752685dc-679c-4ac5-b117-063ede39f931
Connection:
- keep-alive
User-Agent:
- python-welkin/0.0.5
method: GET
uri: https://api.live.welkincloud.io/tenant_REDACTED/admin/users/me
response:
body:
string: '[{"errorCode": "USER_NOT_FOUND", "componentType": "USER", "message":
"User doesn''t exist", "details": {}, "date": "2022-09-16T22:22:39.437Z"}]'
headers:
Access-Control-Allow-Headers:
- authorization, content-type, xsrf-token, security-role
Access-Control-Allow-Methods:
- GET, POST, PUT, DELETE, PATCH, OPTIONS
Access-Control-Allow-Origin:
- '*'
Access-Control-Expose-Headers:
- xsrf-token
Access-Control-Max-Age:
- '3600'
Cache-Control:
- no-cache, no-store, max-age=0, must-revalidate
Connection:
- keep-alive
Content-Type:
- application/json
Date:
- Fri, 16 Sep 2022 22:22:39 GMT
Expires:
- '0'
Pragma:
- no-cache
Set-Cookie:
- AWSALB=+x9R4DkRsJT6cNBrIWMs7Ynnq98L8ABw9esO072EZs21NsAgweoL3da/PnnsSwn3E2fE34ahU5ymyTXkfDxZvQrscrascof+yAbdrXRsjV9jW1HpSmyvVsvoDRvR;
Expires=Fri, 23 Sep 2022 22:22:39 GMT; Path=/
- AWSALBCORS=+x9R4DkRsJT6cNBrIWMs7Ynnq98L8ABw9esO072EZs21NsAgweoL3da/PnnsSwn3E2fE34ahU5ymyTXkfDxZvQrscrascof+yAbdrXRsjV9jW1HpSmyvVsvoDRvR;
Expires=Fri, 23 Sep 2022 22:22:39 GMT; Path=/; SameSite=None; Secure
Transfer-Encoding:
- chunked
X-Content-Type-Options:
- nosniff
X-XSS-Protection:
- 1; mode=block
status:
code: 404
message: ''
version: 1
38 changes: 38 additions & 0 deletions test/cassettes/test_exception_no_json.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
interactions:
- request:
body: null
headers:
Accept:
- '*/*'
Accept-Encoding:
- gzip, deflate
Authorization:
- API_TOKEN_f700bac7-69db-4c84-a1e4-1d02faea8337
Connection:
- keep-alive
User-Agent:
- python-welkin/0.0.5
method: GET
uri: https://httpbin.org/status/400
response:
body:
string: ''
headers:
Access-Control-Allow-Credentials:
- 'true'
Access-Control-Allow-Origin:
- '*'
Connection:
- keep-alive
Content-Length:
- '0'
Content-Type:
- text/html; charset=utf-8
Date:
- Fri, 16 Sep 2022 22:22:32 GMT
Server:
- gunicorn/19.9.0
status:
code: 400
message: BAD REQUEST
version: 1
25 changes: 25 additions & 0 deletions test/test_exception.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import json

import pytest

from welkin.exceptions import WelkinHTTPError


@pytest.mark.vcr()
def test_exception(client):
url = "admin/users/me"
with pytest.raises(WelkinHTTPError) as exc_info:
client.get(url)

exc = exc_info.value
assert str(exc).endswith(json.dumps(exc.response.json(), indent=2))


@pytest.mark.vcr()
def test_exception_no_json(client):
url = "https://httpbin.org/status/400"
with pytest.raises(WelkinHTTPError) as exc_info:
client.get(url)

exc = exc_info.value
assert str(exc) == f"400 Client Error: BAD REQUEST for url: {url}"
101 changes: 101 additions & 0 deletions test/test_util.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import sys
from datetime import date, datetime, timedelta, timezone

from welkin.util import (
clean_date,
clean_datetime,
clean_json_list,
clean_request_params,
clean_request_payload,
)

UTC = timezone.utc
PST = timezone(timedelta(hours=-8))
EST = timezone(timedelta(hours=-5))


def test_clean_request_payload():
payload = {
"datetime": datetime(2022, 9, 15, 23, 0, 0, 0, PST),
"date": date(2022, 9, 15),
"dict": {"foo": "bar", "nested": {"date": date(2022, 9, 15)}},
"list": [datetime(2022, 9, 15, 23, 0, 0, 0, UTC)],
"str": "Don't clean me please.",
"int": [-sys.maxsize, 0, sys.maxsize],
"float": [sys.float_info.min, 1, sys.float_info.max],
"bool": [True, False],
"none": None,
}
payload_copy = dict(payload)

cleaned = clean_request_payload(payload)
assert payload == payload_copy, "Payload was modified"

assert cleaned["datetime"] == "2022-09-16T07:00:00.000Z"
assert cleaned["date"] == "2022-09-15T00:00:00.000Z"
assert cleaned["dict"]["nested"]["date"] == "2022-09-15T00:00:00.000Z"
assert cleaned["list"][0] == "2022-09-15T23:00:00.000Z"


def test_clean_json_list():
json_list = [
datetime(2022, 9, 15, 23, 0, 0, 0, UTC),
date(2022, 9, 15),
[
{
"foo": [datetime(2022, 9, 15, 23, 0, 0, 0, PST)],
},
],
"Strings don't get cleaned",
]
json_list_copy = list(json_list)

cleaned = clean_json_list(json_list)
assert json_list == json_list_copy, "JSON list was modified"

assert cleaned[0] == "2022-09-15T23:00:00.000Z"
assert cleaned[1] == "2022-09-15T00:00:00.000Z"
assert cleaned[2][0]["foo"][0] == "2022-09-16T07:00:00.000Z"


def test_clean_request_params():
params = {
"datetime": datetime(2022, 9, 15, 23, 0, 0, 0, PST),
"date": date(2022, 9, 15),
"list": ["foo", "bar", "baz"],
}
params_copy = dict(params)
cleaned = clean_request_params(params)

assert params == params_copy, "Parameter dict was modified"

assert cleaned["datetime"] == "2022-09-16T07:00:00.000Z"
assert cleaned["date"] == "2022-09-15T00:00:00.000Z"
assert cleaned["list"] == "foo,bar,baz"


def test_clean_date():
cleaned = clean_date(date(2022, 9, 15))

assert cleaned == "2022-09-15T00:00:00.000Z"


def test_clean_datetime():
datetime_tests = {
"utc": {
"dt": datetime(2022, 9, 15, 23, 0, 0, 0, UTC),
"expected": "2022-09-15T23:00:00.000Z",
},
"pst": {
"dt": datetime(2022, 9, 15, 23, 0, 0, 0, PST),
"expected": "2022-09-16T07:00:00.000Z",
},
"est": {
"dt": datetime(2022, 9, 15, 23, 0, 0, 0, EST),
"expected": "2022-09-16T04:00:00.000Z",
},
}
timedelta()
for name, data in datetime_tests.items():
cleaned = clean_datetime(data["dt"])
assert cleaned == data["expected"], f"Unexpected result for '{name}'"
41 changes: 25 additions & 16 deletions welkin/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,47 +6,56 @@


def clean_request_payload(payload: dict) -> dict:
result = {}
for k, v in payload.items():
if isinstance(v, datetime):
payload[k] = clean_datetime(v)
result[k] = clean_datetime(v)
elif isinstance(v, date):
payload[k] = clean_date(v)
result[k] = clean_date(v)
elif isinstance(v, dict):
payload[k] = clean_request_payload(v)
result[k] = clean_request_payload(v)
elif isinstance(v, list):
payload[k] = clean_json_list(v)
result[k] = clean_json_list(v)
else:
result[k] = v

return payload
return result


def clean_json_list(data: list) -> list:
for ind, item in enumerate(data):
result = []
for item in data:
if isinstance(item, datetime):
data[ind] = clean_datetime(item)
result.append(clean_datetime(item))
elif isinstance(item, date):
data[ind] = clean_date(item)
result.append(clean_date(item))
elif isinstance(item, dict):
data[ind] = clean_request_payload(item)
result.append(clean_request_payload(item))
elif isinstance(item, list):
data[ind] = clean_json_list(item)
result.append(clean_json_list(item))
else:
result.append(item)

return data
return result


def clean_request_params(params: dict) -> dict:
result = {}
for k, v in params.items():
if isinstance(v, datetime):
params[k] = clean_datetime(v)
result[k] = clean_datetime(v)
elif isinstance(v, date):
params[k] = clean_date(v)
result[k] = clean_date(v)
elif isinstance(v, list):
params[k] = ",".join(v)
result[k] = ",".join(v)
else:
result[k] = v

return params
return result


def clean_date(date: date) -> str:
dt = datetime(date.year, date.month, date.day, 0, 0, 0)
dt = datetime(date.year, date.month, date.day, 0, 0, 0, tzinfo=timezone.utc)

return clean_datetime(dt)

Expand Down

0 comments on commit a666fa9

Please sign in to comment.