Skip to content

Commit 85f2397

Browse files
committed
Made several changes to testing to increase code coverage
- Added a ton of tests to cover areas that weren't covered before - Added a pep8 tox env to run pep8 tests as part of the build - Moved keys into tests/keys - Added test_algorithms.py for algorithms module tests - Changed setup.py to run all tests in tests/
1 parent eb4bb53 commit 85f2397

File tree

14 files changed

+355
-51
lines changed

14 files changed

+355
-51
lines changed

.travis.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ env:
66
- TOXENV=py32
77
- TOXENV=py33
88
- TOXENV=py34
9+
- TOXENV=pep8
910
install:
1011
- pip install tox coveralls
1112
script:

jwt/api.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@
44
from collections import Mapping
55
from datetime import datetime, timedelta
66

7-
from .utils import base64url_decode, base64url_encode
87
from .compat import json, string_types, text_type, timedelta_total_seconds
98
from .exceptions import (
109
DecodeError, ExpiredSignatureError,
1110
InvalidAudienceError, InvalidIssuerError
1211
)
12+
from .utils import base64url_decode, base64url_encode
1313

1414

1515
_algorithms = {}

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,5 +46,5 @@
4646
'Programming Language :: Python :: 3.4',
4747
'Topic :: Utilities',
4848
],
49-
test_suite='tests.test_jwt'
49+
test_suite='tests'
5050
)

tests/compat.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# flake8: noqa
2+
3+
import sys
4+
5+
if sys.version_info >= (2, 7):
6+
import unittest
7+
else:
8+
import unittest2 as unittest
9+
10+
PY3 = sys.version_info[0] == 3
11+
12+
if PY3:
13+
string_types = str,
14+
text_type = str
15+
else:
16+
string_types = basestring,
17+
text_type = unicode

tests/keys/testkey2_rsa.pub.pem

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
-----BEGIN PUBLIC KEY-----
2+
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1tUH3/0v8fvLensHO1g2
3+
6+U4r7jBg43DVOgqmXAWQa8ArAb4NfTrsYX8YkVhZZYwuLmKczRj0GhXUVY9iDbT
4+
sIGmgG+ySj6eiREz5VLqofFkAvRZ6y7yNv8PIGgXEhQTiDDNIkHGaFNMvn/eZ54H
5+
is70pdTjR5Ko+/y/wg71df1nb/5KwttSvy0YsTu/XpkduonPruYfAVRG3HK+3GZd
6+
xTygLcdamwe9jj+kjxtXRlrXVMQiXGFSU8U6bjafWnQiQ9XzjxvygBt0ZD0kRorr
7+
p74XGyQY5ThkN8DlpJbTTFsxOnBUAQz4zhohjobIGBRimi5yVlyLOwTlpaKGFC7O
8+
7wIDAQAB
9+
-----END PUBLIC KEY-----
File renamed without changes.

tests/test_algorithms.py

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
import base64
2+
import hashlib
3+
4+
from jwt.algorithms import Algorithm, HMACAlgorithm
5+
6+
from .compat import unittest
7+
from .utils import ensure_bytes, ensure_unicode
8+
9+
try:
10+
from cryptography.hazmat.primitives import hashes
11+
from jwt.algorithms import RSAAlgorithm, ECAlgorithm
12+
13+
has_crypto = True
14+
except ImportError:
15+
has_crypto = False
16+
17+
18+
class TestJWT(unittest.TestCase):
19+
def setUp(self): # noqa
20+
pass
21+
22+
def test_algorithm_should_throw_exception_if_prepare_key_not_impl(self):
23+
algo = Algorithm()
24+
25+
with self.assertRaises(NotImplementedError):
26+
algo.prepare_key('test')
27+
28+
def test_algorithm_should_throw_exception_if_sign_not_impl(self):
29+
algo = Algorithm()
30+
31+
with self.assertRaises(NotImplementedError):
32+
algo.sign('message', 'key')
33+
34+
def test_algorithm_should_throw_exception_if_verify_not_impl(self):
35+
algo = Algorithm()
36+
37+
with self.assertRaises(NotImplementedError):
38+
algo.verify('message', 'key', 'signature')
39+
40+
def test_hmac_should_reject_nonstring_key(self):
41+
algo = HMACAlgorithm(hashlib.sha256())
42+
43+
with self.assertRaises(TypeError) as context:
44+
algo.prepare_key(object())
45+
46+
exception = context.exception
47+
self.assertEqual(str(exception), 'Expecting a string- or bytes-formatted key.')
48+
49+
def test_hmac_should_accept_unicode_key(self):
50+
algo = HMACAlgorithm(hashlib.sha256())
51+
52+
algo.prepare_key(ensure_unicode('awesome'))
53+
54+
@unittest.skipIf(not has_crypto, 'Not supported without cryptography library')
55+
def test_rsa_should_parse_pem_public_key(self):
56+
algo = RSAAlgorithm(hashes.SHA256())
57+
58+
with open('tests/keys/testkey2_rsa.pub.pem', 'r') as pem_key:
59+
algo.prepare_key(pem_key.read())
60+
61+
@unittest.skipIf(not has_crypto, 'Not supported without cryptography library')
62+
def test_rsa_should_accept_unicode_key(self):
63+
algo = RSAAlgorithm(hashes.SHA256())
64+
65+
with open('tests/keys/testkey_rsa', 'r') as rsa_key:
66+
algo.prepare_key(ensure_unicode(rsa_key.read()))
67+
68+
@unittest.skipIf(not has_crypto, 'Not supported without cryptography library')
69+
def test_rsa_should_reject_non_string_key(self):
70+
algo = RSAAlgorithm(hashes.SHA256())
71+
72+
with self.assertRaises(TypeError):
73+
algo.prepare_key(None)
74+
75+
@unittest.skipIf(not has_crypto, 'Not supported without cryptography library')
76+
def test_rsa_verify_should_return_false_if_signature_invalid(self):
77+
algo = RSAAlgorithm(hashes.SHA256())
78+
79+
jwt_message = ensure_bytes('Hello World!')
80+
81+
jwt_sig = base64.b64decode(ensure_bytes(
82+
'yS6zk9DBkuGTtcBzLUzSpo9gGJxJFOGvUqN01iLhWHrzBQ9ZEz3+Ae38AXp'
83+
'10RWwscp42ySC85Z6zoN67yGkLNWnfmCZSEv+xqELGEvBJvciOKsrhiObUl'
84+
'2mveSc1oeO/2ujkGDkkkJ2epn0YliacVjZF5+/uDmImUfAAj8lzjnHlzYix'
85+
'sn5jGz1H07jYYbi9diixN8IUhXeTafwFg02IcONhum29V40Wu6O5tAKWlJX'
86+
'fHJnNUzAEUOXS0WahHVb57D30pcgIji9z923q90p5c7E2cU8V+E1qe8NdCA'
87+
'APCDzZZ9zQ/dgcMVaBrGrgimrcLbPjueOKFgSO+SSjIElKA=='))
88+
89+
jwt_sig = jwt_sig + ensure_bytes('123') # Signature is now invalid
90+
91+
with open('tests/keys/testkey_rsa.pub', 'r') as keyfile:
92+
jwt_pub_key = algo.prepare_key(keyfile.read())
93+
94+
result = algo.verify(jwt_message, jwt_pub_key, jwt_sig)
95+
self.assertFalse(result)
96+
97+
@unittest.skipIf(not has_crypto, 'Not supported without cryptography library')
98+
def test_rsa_verify_should_return_true_if_signature_valid(self):
99+
algo = RSAAlgorithm(hashes.SHA256())
100+
101+
jwt_message = ensure_bytes('Hello World!')
102+
103+
jwt_sig = base64.b64decode(ensure_bytes(
104+
'yS6zk9DBkuGTtcBzLUzSpo9gGJxJFOGvUqN01iLhWHrzBQ9ZEz3+Ae38AXp'
105+
'10RWwscp42ySC85Z6zoN67yGkLNWnfmCZSEv+xqELGEvBJvciOKsrhiObUl'
106+
'2mveSc1oeO/2ujkGDkkkJ2epn0YliacVjZF5+/uDmImUfAAj8lzjnHlzYix'
107+
'sn5jGz1H07jYYbi9diixN8IUhXeTafwFg02IcONhum29V40Wu6O5tAKWlJX'
108+
'fHJnNUzAEUOXS0WahHVb57D30pcgIji9z923q90p5c7E2cU8V+E1qe8NdCA'
109+
'APCDzZZ9zQ/dgcMVaBrGrgimrcLbPjueOKFgSO+SSjIElKA=='))
110+
111+
with open('tests/keys/testkey_rsa.pub', 'r') as keyfile:
112+
jwt_pub_key = algo.prepare_key(keyfile.read())
113+
114+
result = algo.verify(jwt_message, jwt_pub_key, jwt_sig)
115+
self.assertTrue(result)
116+
117+
@unittest.skipIf(not has_crypto, 'Not supported without cryptography library')
118+
def test_ec_should_reject_non_string_key(self):
119+
algo = ECAlgorithm(hashes.SHA256())
120+
121+
with self.assertRaises(TypeError):
122+
algo.prepare_key(None)
123+
124+
@unittest.skipIf(not has_crypto, 'Not supported without cryptography library')
125+
def test_ec_verify_should_return_false_if_signature_invalid(self):
126+
algo = ECAlgorithm(hashes.SHA256())
127+
128+
jwt_message = ensure_bytes('Hello World!')
129+
130+
jwt_sig = base64.b64decode(ensure_bytes(
131+
'MIGIAkIB9vYz+inBL8aOTA4auYz/zVuig7TT1bQgKROIQX9YpViHkFa4DT5'
132+
'5FuFKn9XzVlk90p6ldEj42DC9YecXHbC2t+cCQgCicY+8f3f/KCNtWK7cif'
133+
'6vdsVwm6Lrjs0Ag6ZqCf+olN11hVt1qKBC4lXppqB1gNWEmNQaiz1z2QRyc'
134+
'zJ8hSJmbw=='))
135+
136+
jwt_sig = ensure_bytes('123') # Signature is now invalid
137+
138+
with open('tests/keys/testkey_ec.pub', 'r') as keyfile:
139+
jwt_pub_key = algo.prepare_key(keyfile.read())
140+
141+
result = algo.verify(jwt_message, jwt_pub_key, jwt_sig)
142+
self.assertFalse(result)
143+
144+
@unittest.skipIf(not has_crypto, 'Not supported without cryptography library')
145+
def test_ec_verify_should_return_true_if_signature_valid(self):
146+
algo = ECAlgorithm(hashes.SHA256())
147+
148+
jwt_message = ensure_bytes('Hello World!')
149+
150+
jwt_sig = base64.b64decode(ensure_bytes(
151+
'MIGIAkIB9vYz+inBL8aOTA4auYz/zVuig7TT1bQgKROIQX9YpViHkFa4DT5'
152+
'5FuFKn9XzVlk90p6ldEj42DC9YecXHbC2t+cCQgCicY+8f3f/KCNtWK7cif'
153+
'6vdsVwm6Lrjs0Ag6ZqCf+olN11hVt1qKBC4lXppqB1gNWEmNQaiz1z2QRyc'
154+
'zJ8hSJmbw=='))
155+
156+
with open('tests/keys/testkey_ec.pub', 'r') as keyfile:
157+
jwt_pub_key = algo.prepare_key(keyfile.read())
158+
159+
result = algo.verify(jwt_message, jwt_pub_key, jwt_sig)
160+
self.assertTrue(result)

0 commit comments

Comments
 (0)