Skip to content
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

Adding Tests #9

Merged
merged 10 commits into from
Apr 11, 2022
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions pytest.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[pytest]
asyncio_mode=strict
2 changes: 2 additions & 0 deletions requirements.test.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pytest-asyncio-0.18.3
pytest==7.1.1
12 changes: 6 additions & 6 deletions sharkiq/ayla_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ def __init__(
self._app_secret = app_secret
self.websession = websession

def ensure_session(self) -> aiohttp.ClientSession:
async def ensure_session(self) -> aiohttp.ClientSession:
JeffResc marked this conversation as resolved.
Show resolved Hide resolved
"""Ensure that we have an aiohttp ClientSession"""
if self.websession is None:
self.websession = aiohttp.ClientSession()
Expand All @@ -75,7 +75,7 @@ def _set_credentials(self, status_code: int, login_result: Dict):
self._access_token = login_result["access_token"]
self._refresh_token = login_result["refresh_token"]
self._auth_expiration = datetime.now() + timedelta(seconds=login_result["expires_in"])
self._is_authed = True
self._is_authed = True # TODO: Any non 200 status code should cause this to be false
JeffResc marked this conversation as resolved.
Show resolved Hide resolved

def sign_in(self):
"""Authenticate to Ayla API synchronously."""
Expand All @@ -91,14 +91,14 @@ def refresh_auth(self):

async def async_sign_in(self):
"""Authenticate to Ayla API synchronously."""
session = self.ensure_session()
session = await self.ensure_session()
login_data = self._login_data
async with session.post(f"{LOGIN_URL:s}/users/sign_in.json", json=login_data) as resp:
self._set_credentials(resp.status, await resp.json())

async def async_refresh_auth(self):
"""Refresh the authentication synchronously."""
session = self.ensure_session()
session = await self.ensure_session()
refresh_data = {"user": {"refresh_token": self._refresh_token}}
async with session.post(f"{LOGIN_URL:s}/users/refresh_token.json", json=refresh_data) as resp:
self._set_credentials(resp.status, await resp.json())
Expand All @@ -122,7 +122,7 @@ def sign_out(self):

async def async_sign_out(self):
"""Sign out and invalidate the access token"""
session = self.ensure_session()
session = await self.ensure_session()
async with session.post(f"{LOGIN_URL:s}/users/sign_out.json", json=self.sign_out_data) as _:
pass
self._clear_auth()
Expand Down Expand Up @@ -183,7 +183,7 @@ def request(self, method: str, url: str, **kwargs) -> requests.Response:
return requests.request(method, url, headers=headers, **kwargs)

async def async_request(self, http_method: str, url: str, **kwargs):
session = self.ensure_session()
session = await self.ensure_session()
headers = self._get_headers(kwargs)
return session.request(http_method, url, headers=headers, **kwargs)

Expand Down
28 changes: 28 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import pytest
import os
from sharkiq.ayla_api import get_ayla_api


@pytest.fixture
def dummy_api():
username = "[email protected]"
password = "mypassword"

return get_ayla_api(username=username, password=password)


@pytest.fixture
def sample_api():
username = os.getenv("SHARKIQ_USERNAME")
password = os.getenv("SHARKIQ_PASSWORD")

assert username is not None, "SHARKIQ_USERNAME environment variable unset"
assert password is not None, "SHARKIQ_PASSWORD environment variable unset"

return get_ayla_api(username=username, password=password)


@pytest.fixture
def sample_api_logged_in(sample_api):
sample_api.sign_in()
return sample_api
Empty file added tests/test_ayla_api.py
Empty file.
119 changes: 119 additions & 0 deletions tests/test_sharkiq.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import aiohttp
import pytest
from sharkiq.ayla_api import get_ayla_api, AylaApi
from sharkiq.const import SHARK_APP_ID, SHARK_APP_SECRET
from sharkiq.exc import SharkIqAuthError
from datetime import datetime, timedelta


def test_get_ayla_api():
api = get_ayla_api("[email protected]", "mypassword")

assert api._email == "[email protected]"
assert api._password == "mypassword"
assert api._access_token is None
assert api._refresh_token is None
assert api._auth_expiration is None
assert api._is_authed == False
assert api._app_id == SHARK_APP_ID
assert api._app_secret == SHARK_APP_SECRET
assert api.websession is None


class TestAylaApi:
def test_init__required_vals(self):
api = AylaApi(
"[email protected]", "mypassword", "app_id_123", "appsecret_123"
)

assert api._email == "[email protected]"
assert api._password == "mypassword"
assert api._access_token is None
assert api._refresh_token is None
assert api._auth_expiration is None
assert api._is_authed == False
assert api._app_id == "app_id_123"
assert api._app_secret == "appsecret_123"
assert api.websession is None

@pytest.mark.asyncio
async def test_ensure_session(self, dummy_api):
# Initially created with no websession
assert dummy_api.websession is None

session = await dummy_api.ensure_session()

# Check that session was created and returned
assert isinstance(session, aiohttp.ClientSession)
assert dummy_api.websession is session

def test_property__login_data(self, dummy_api):
assert dummy_api._login_data == {
"user": {
"email": "[email protected]",
"password": "mypassword",
"application": {
"app_id": SHARK_APP_ID,
"app_secret": SHARK_APP_SECRET,
},
}
}

def test_set_credentials__404_response(self, dummy_api):
with pytest.raises(SharkIqAuthError) as e:
dummy_api._set_credentials(404, {"error": {"message": "Not found"}})
assert (
e.value.args[0] == "Not found (Confirm app_id and app_secret are correct)"
)

def test_set_credentials__401_response(self, dummy_api):
with pytest.raises(SharkIqAuthError) as e:
dummy_api._set_credentials(401, {"error": {"message": "Unauthorized"}})
assert e.value.args[0] == "Unauthorized"

def test_set_credentials__valid_response(self, dummy_api):
assert dummy_api._access_token is None
assert dummy_api._refresh_token is None
assert dummy_api._auth_expiration is None
assert dummy_api._is_authed == False

t1 = datetime.now() + timedelta(seconds=3600)
dummy_api._set_credentials(
200,
{
"access_token": "token123",
"refresh_token": "token321",
"expires_in": 3600,
},
)

assert dummy_api._access_token == "token123"
assert dummy_api._refresh_token == "token321"
assert dummy_api._auth_expiration.timestamp() == pytest.approx(t1.timestamp())
assert dummy_api._is_authed == True

def test_property__sign_out_data(self, dummy_api):
assert dummy_api.sign_out_data == {
"user": {"access_token": dummy_api._access_token}
}

def test_clear_auth(self, dummy_api):
# populate auth values
assert dummy_api._is_authed == False
dummy_api._set_credentials(
200,
{
"access_token": "token123",
"refresh_token": "token321",
"expires_in": 3600,
},
)

assert dummy_api._is_authed == True

dummy_api._clear_auth()

assert dummy_api._access_token is None
assert dummy_api._refresh_token is None
assert dummy_api._auth_expiration is None
assert dummy_api._is_authed == False