Skip to content

add a test suite #7

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

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all 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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
*.pyc
.tox
.coverage
withings.conf
withings.egg-info
10 changes: 10 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
language: python
python: 3.3
env:
- TOX_ENV=pypy
- TOX_ENV=py27
- TOX_ENV=py26
install:
- pip install coveralls tox
script: tox -e $TOX_ENV
after_success: coveralls
1 change: 1 addition & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
include LICENSE README.md requirements/*
File renamed without changes.
5 changes: 5 additions & 0 deletions requirements/test.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
-r base.txt

coverage==3.7.1
mock==1.0.1
tox==1.7.2
5 changes: 4 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#!/usr/bin/env python
from setuptools import setup

required = [line for line in open('requirements/base.txt').read().split("\n")]

setup(
name='withings',
version='0.3',
Expand All @@ -10,7 +12,8 @@
url="https://github.com/maximebf/python-withings",
license = "MIT License",
packages = ['withings'],
install_requires = ['requests', 'requests-oauth'],
install_requires = required,
test_suite='tests.all_tests',
scripts=['bin/withings'],
keywords="withings",
zip_safe = True
Expand Down
17 changes: 17 additions & 0 deletions tests/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import unittest

from .test_withings_credentials import TestWithingsCredentials
from .test_withings_auth import TestWithingsAuth
from .test_withings_api import TestWithingsApi
from .test_withings_measures import TestWithingsMeasures
from .test_withings_measure_group import TestWithingsMeasureGroup


def all_tests():
suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(TestWithingsCredentials))
suite.addTest(unittest.makeSuite(TestWithingsAuth))
suite.addTest(unittest.makeSuite(TestWithingsApi))
suite.addTest(unittest.makeSuite(TestWithingsMeasures))
suite.addTest(unittest.makeSuite(TestWithingsMeasureGroup))
return suite
232 changes: 232 additions & 0 deletions tests/test_withings_api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,232 @@
import json
import time
import unittest

from datetime import datetime
from requests import Session
from withings import (
WithingsApi,
WithingsCredentials,
WithingsMeasureGroup,
WithingsMeasures
)

try:
import configparser
except ImportError: # Python 2.x fallback
import ConfigParser as configparser

try:
from unittest.mock import MagicMock
except ImportError: # Python 2.x fallback
from mock import MagicMock


class TestWithingsApi(unittest.TestCase):
def setUp(self):
self.mock_api = True
if self.mock_api:
self.creds = WithingsCredentials()
else:
config = ConfigParser.ConfigParser()
config.read('withings.conf')
self.creds = WithingsCredentials(
consumer_key=config.get('withings', 'consumer_key'),
consumer_secret=config.get('withings', 'consumer_secret'),
access_token=config.get('withings', 'access_token'),
access_token_secret=config.get('withings',
'access_token_secret'),
user_id=config.get('withings', 'user_id'))
self.api = WithingsApi(self.creds)

def test_attributes(self):
""" Make sure the WithingsApi objects have the right attributes """
assert hasattr(WithingsApi, 'URL')
creds = WithingsCredentials(user_id='FAKEID')
api = WithingsApi(creds)
assert hasattr(api, 'credentials')
assert hasattr(api, 'oauth')
assert hasattr(api, 'client')

def test_attribute_defaults(self):
"""
Make sure WithingsApi object attributes have the correct defaults
"""
self.assertEqual(WithingsApi.URL, 'http://wbsapi.withings.net')
creds = WithingsCredentials(user_id='FAKEID')
api = WithingsApi(creds)
self.assertEqual(api.credentials, creds)
self.assertEqual(api.client.auth, api.oauth)
self.assertEqual(api.client.params, {'userid': creds.user_id})

def test_request(self):
"""
Make sure the request method builds the proper URI and returns the
request body as a python dict.
"""
self.mock_request({})
resp = self.api.request('fake_service', 'fake_action')
Session.request.assert_called_once_with(
'GET', 'http://wbsapi.withings.net/fake_service',
params={'action': 'fake_action'})
self.assertEqual(resp, {})

def test_request_params(self):
"""
Check that the request method passes along extra params and works
with different HTTP methods
"""
self.mock_request({})
resp = self.api.request('user', 'getbyuserid', params={'p2': 'p2'},
method='POST')
Session.request.assert_called_once_with(
'POST', 'http://wbsapi.withings.net/user',
params={'p2': 'p2', 'action': 'getbyuserid'})
self.assertEqual(resp, {})

def test_request_error(self):
""" Check that requests raises an exception when there is an error """
self.mock_request('', status=1)
self.assertRaises(Exception, self.api.request, ('user', 'getbyuserid'))

def test_get_user(self):
""" Check that the get_user method fetches the right URL """
self.mock_request({
'users': [
{'id': 1111111, 'birthdate': 364305600, 'lastname': 'Baggins',
'ispublic': 255, 'firstname': 'Frodo', 'fatmethod': 131,
'gender': 0, 'shortname': 'FRO'}
]
})
resp = self.api.get_user()
Session.request.assert_called_once_with(
'GET', 'http://wbsapi.withings.net/user',
params={'action': 'getbyuserid'})
self.assertEqual(type(resp), dict)
assert 'users' in resp
self.assertEqual(type(resp['users']), list)
self.assertEqual(len(resp['users']), 1)
self.assertEqual(resp['users'][0]['firstname'], 'Frodo')
self.assertEqual(resp['users'][0]['lastname'], 'Baggins')

def test_get_measures(self):
"""
Check that get_measures fetches the appriate URL, the response looks
correct, and the return value is a WithingsMeasures object
"""
body = {
'updatetime': 1409596058,
'measuregrps': [
{'attrib': 2, 'measures': [
{'unit': -1, 'type': 1, 'value': 860}
], 'date': 1409361740, 'category': 1, 'grpid': 111111111},
{'attrib': 2, 'measures': [
{'unit': -2, 'type': 4, 'value': 185}
], 'date': 1409361740, 'category': 1, 'grpid': 111111112}
]
}
self.mock_request(body)
resp = self.api.get_measures()
Session.request.assert_called_once_with(
'GET', 'http://wbsapi.withings.net/measure',
params={'action': 'getmeas'})
self.assertEqual(type(resp), WithingsMeasures)
self.assertEqual(len(resp), 2)
self.assertEqual(type(resp[0]), WithingsMeasureGroup)
self.assertEqual(resp[0].weight, 86.0)
self.assertEqual(resp[1].height, 1.85)

# Test limit=1
body['measuregrps'].pop()
self.mock_request(body)
resp = self.api.get_measures(limit=1)
Session.request.assert_called_once_with(
'GET', 'http://wbsapi.withings.net/measure',
params={'action': 'getmeas', 'limit': 1})
self.assertEqual(len(resp), 1)
self.assertEqual(resp[0].weight, 86.0)

def test_subscribe(self):
"""
Check that subscribe fetches the right URL and returns the expected
results
"""
self.mock_request(None)
resp = self.api.subscribe('http://www.example.com/', 'fake_comment')
Session.request.assert_called_once_with(
'GET', 'http://wbsapi.withings.net/notify',
params={'action': 'subscribe', 'appli': 1,
'comment': 'fake_comment',
'callbackurl': 'http://www.example.com/'})
self.assertEqual(resp, None)

def test_unsubscribe(self):
"""
Check that unsubscribe fetches the right URL and returns the expected
results
"""
self.mock_request(None)
resp = self.api.unsubscribe('http://www.example.com/')
Session.request.assert_called_once_with(
'GET', 'http://wbsapi.withings.net/notify',
params={'action': 'revoke', 'appli': 1,
'callbackurl': 'http://www.example.com/'})
self.assertEqual(resp, None)


def test_is_subscribed(self):
"""
Check that is_subscribed fetches the right URL and returns the
expected results
"""
url = 'http://wbsapi.withings.net/notify'
params = {
'callbackurl': 'http://www.example.com/',
'action': 'get',
'appli': 1
}
self.mock_request({'expires': 2147483647, 'comment': 'fake_comment'})
resp = self.api.is_subscribed('http://www.example.com/')
Session.request.assert_called_once_with('GET', url, params=params)
self.assertEquals(resp, True)

# Not subscribed
self.mock_request(None, status=343)
resp = self.api.is_subscribed('http://www.example.com/')
Session.request.assert_called_once_with('GET', url, params=params)
self.assertEquals(resp, False)

def test_list_subscriptions(self):
"""
Check that list_subscriptions fetches the right URL and returns the
expected results
"""
self.mock_request({'profiles': [
{'comment': 'fake_comment', 'expires': 2147483647}
]})
resp = self.api.list_subscriptions()
Session.request.assert_called_once_with(
'GET', 'http://wbsapi.withings.net/notify',
params={'action': 'list', 'appli': 1})
self.assertEqual(type(resp), list)
self.assertEqual(len(resp), 1)
self.assertEqual(resp[0]['comment'], 'fake_comment')
self.assertEqual(resp[0]['expires'], 2147483647)

# No subscriptions
self.mock_request({'profiles': []})
resp = self.api.list_subscriptions()
Session.request.assert_called_once_with(
'GET', 'http://wbsapi.withings.net/notify',
params={'action': 'list', 'appli': 1})
self.assertEqual(type(resp), list)
self.assertEqual(len(resp), 0)

def mock_request(self, body, status=0):
if self.mock_api:
json_content = {'status': status}
if body != None:
json_content['body'] = body
response = MagicMock()
response.content = json.dumps(json_content).encode('utf8')
Session.request = MagicMock(return_value=response)
67 changes: 67 additions & 0 deletions tests/test_withings_auth.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import unittest

from withings import WithingsAuth, WithingsCredentials
from requests_oauthlib import OAuth1Session

try:
from unittest.mock import MagicMock
except ImportError:
from mock import MagicMock


class TestWithingsAuth(unittest.TestCase):
def setUp(self):
self.consumer_key = 'fake_consumer_key'
self.consumer_secret = 'fake_consumer_secret'
self.request_token = {
'oauth_token': 'fake_oauth_token',
'oauth_token_secret': 'fake_oauth_token_secret'
}
self.access_token = self.request_token
self.access_token.update({'userid': 'FAKEID'})
OAuth1Session.fetch_request_token = MagicMock(
return_value=self.request_token)
OAuth1Session.authorization_url = MagicMock(return_value='URL')
OAuth1Session.fetch_access_token = MagicMock(
return_value=self.access_token)

def test_attributes(self):
""" Make sure the WithingsAuth objects have the right attributes """
assert hasattr(WithingsAuth, 'URL')
auth = WithingsAuth(self.consumer_key, self.consumer_secret)
assert hasattr(auth, 'consumer_key')
self.assertEqual(auth.consumer_key, self.consumer_key)
assert hasattr(auth, 'consumer_secret')
self.assertEqual(auth.consumer_secret, self.consumer_secret)

def test_attribute_defaults(self):
""" Make sure WithingsAuth attributes have the proper defaults """
self.assertEqual(WithingsAuth.URL,
'https://oauth.withings.com/account')
auth = WithingsAuth(self.consumer_key, self.consumer_secret)
self.assertEqual(auth.oauth_token, None)
self.assertEqual(auth.oauth_secret, None)

def test_get_authorize_url(self):
""" Make sure the get_authorize_url function works as expected """
auth = WithingsAuth(self.consumer_key, self.consumer_secret)
# Returns the OAuth1Session.authorization_url results
self.assertEqual(auth.get_authorize_url(), 'URL')
# oauth_token and oauth_secret have now been set to the values
# returned by OAuth1Session.fetch_request_token
self.assertEqual(auth.oauth_token, 'fake_oauth_token')
self.assertEqual(auth.oauth_secret, 'fake_oauth_token_secret')

def test_get_credentials(self):
""" Make sure the get_credentials function works as expected """
auth = WithingsAuth(self.consumer_key, self.consumer_secret)
# Returns an authorized WithingsCredentials object
creds = auth.get_credentials('FAKE_OAUTH_VERIFIER')
assert isinstance(creds, WithingsCredentials)
# Check that the attributes of the WithingsCredentials object are
# correct.
self.assertEqual(creds.access_token, 'fake_oauth_token')
self.assertEqual(creds.access_token_secret, 'fake_oauth_token_secret')
self.assertEqual(creds.consumer_key, self.consumer_key)
self.assertEqual(creds.consumer_secret, self.consumer_secret)
self.assertEqual(creds.user_id, 'FAKEID')
35 changes: 35 additions & 0 deletions tests/test_withings_credentials.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import unittest

from withings import WithingsAuth, WithingsCredentials


class TestWithingsCredentials(unittest.TestCase):

def test_attributes(self):
"""
Make sure the WithingsCredentials objects have the right attributes
"""
creds = WithingsCredentials(access_token=1, access_token_secret=1,
consumer_key=1, consumer_secret=1,
user_id=1)
assert hasattr(creds, 'access_token')
self.assertEqual(creds.access_token, 1)
assert hasattr(creds, 'access_token_secret')
self.assertEqual(creds.access_token_secret, 1)
assert hasattr(creds, 'consumer_key')
self.assertEqual(creds.consumer_key, 1)
assert hasattr(creds, 'consumer_secret')
self.assertEqual(creds.consumer_secret, 1)
assert hasattr(creds, 'user_id')
self.assertEqual(creds.user_id, 1)

def test_attribute_defaults(self):
"""
Make sure WithingsCredentials attributes have the proper defaults
"""
creds = WithingsCredentials()
self.assertEqual(creds.access_token, None)
self.assertEqual(creds.access_token_secret, None)
self.assertEqual(creds.consumer_key, None)
self.assertEqual(creds.consumer_secret, None)
self.assertEqual(creds.user_id, None)
Loading