Fix tests

This commit is contained in:
Andreas Zweili 2023-12-29 20:52:40 +01:00
parent 663f88d1b4
commit 5b6723c394
3 changed files with 129 additions and 147 deletions

9
conftest.py Normal file
View File

@ -0,0 +1,9 @@
import pytest
import src.main as snapbin
@pytest.fixture()
def app():
snapbin.app.config["TESTING"] = True
return snapbin.app.test_client()

View File

@ -11,7 +11,6 @@ from .utils import strtobool
NO_SSL = bool(strtobool(os.environ.get("NO_SSL", "False"))) NO_SSL = bool(strtobool(os.environ.get("NO_SSL", "False")))
URL_PREFIX = os.environ.get("URL_PREFIX", None)
HOST_OVERRIDE = os.environ.get("HOST_OVERRIDE", None) HOST_OVERRIDE = os.environ.get("HOST_OVERRIDE", None)
TOKEN_SEPARATOR = "~" TOKEN_SEPARATOR = "~"

266
tests.py
View File

@ -1,163 +1,137 @@
import re import re
import time import time
import unittest
import uuid import uuid
from unittest import TestCase
from unittest import mock import pytest
from urllib.parse import unquote
from cryptography.fernet import Fernet from cryptography.fernet import Fernet
from freezegun import freeze_time from freezegun import freeze_time
from werkzeug.exceptions import BadRequest from werkzeug.exceptions import BadRequest
from fakeredis import FakeStrictRedis
# noinspection PyPep8Naming # noinspection PyPep8Naming
import src.main as snapbin import src.main as snapbin
__author__ = 'davedash'
def test_get_password():
password = "melatonin overdose 1337!$"
key = snapbin.set_password(password, 30)
assert password == snapbin.get_password(key)
# Assert that we can't look this up a second time.
assert snapbin.get_password(key) == None
class SnapPassTestCase(TestCase): def test_password_is_not_stored_in_plaintext():
password = "trustno1"
@mock.patch('redis.client.StrictRedis', FakeStrictRedis) token = snapbin.set_password(password, 30)
def test_get_password(self): redis_key = token.split(snapbin.TOKEN_SEPARATOR)[0]
password = "melatonin overdose 1337!$" stored_password_text = snapbin.redis_client.get(redis_key).decode("utf-8")
key = snapbin.set_password(password, 30) assert stored_password_text not in password
self.assertEqual(password, snapbin.get_password(key))
# Assert that we can't look this up a second time.
self.assertIsNone(snapbin.get_password(key))
def test_password_is_not_stored_in_plaintext(self):
password = "trustno1"
token = snapbin.set_password(password, 30)
redis_key = token.split(snapbin.TOKEN_SEPARATOR)[0]
stored_password_text = snapbin.redis_client.get(redis_key).decode('utf-8')
self.assertNotIn(password, stored_password_text)
def test_returned_token_format(self):
password = "trustsome1"
token = snapbin.set_password(password, 30)
token_fragments = token.split(snapbin.TOKEN_SEPARATOR)
self.assertEqual(2, len(token_fragments))
redis_key, encryption_key = token_fragments
self.assertEqual(32 + len(snapbin.REDIS_PREFIX), len(redis_key))
try:
Fernet(encryption_key.encode('utf-8'))
except ValueError:
self.fail('the encryption key is not valid')
def test_encryption_key_is_returned(self):
password = "trustany1"
token = snapbin.set_password(password, 30)
token_fragments = token.split(snapbin.TOKEN_SEPARATOR)
redis_key, encryption_key = token_fragments
stored_password = snapbin.redis_client.get(redis_key)
fernet = Fernet(encryption_key.encode('utf-8'))
decrypted_password = fernet.decrypt(stored_password).decode('utf-8')
self.assertEqual(password, decrypted_password)
def test_unencrypted_passwords_still_work(self):
unencrypted_password = "trustevery1"
storage_key = uuid.uuid4().hex
snapbin.redis_client.setex(storage_key, 30, unencrypted_password)
retrieved_password = snapbin.get_password(storage_key)
self.assertEqual(unencrypted_password, retrieved_password)
def test_password_is_decoded(self):
password = "correct horse battery staple"
key = snapbin.set_password(password, 30)
self.assertFalse(isinstance(snapbin.get_password(key), bytes))
def test_clean_input(self):
# Test Bad Data
with snapbin.app.test_request_context(
"/", data={'password': 'foo', 'ttl': 'bar'}, method='POST'):
self.assertRaises(BadRequest, snapbin.clean_input)
# No Password
with snapbin.app.test_request_context(
"/", method='POST'):
self.assertRaises(BadRequest, snapbin.clean_input)
# No TTL
with snapbin.app.test_request_context(
"/", data={'password': 'foo'}, method='POST'):
self.assertRaises(BadRequest, snapbin.clean_input)
with snapbin.app.test_request_context(
"/", data={'password': 'foo', 'ttl': 'hour'}, method='POST'):
self.assertEqual((3600, 'foo'), snapbin.clean_input())
def test_password_before_expiration(self):
password = 'fidelio'
key = snapbin.set_password(password, 1)
self.assertEqual(password, snapbin.get_password(key))
def test_password_after_expiration(self):
password = 'open sesame'
key = snapbin.set_password(password, 1)
time.sleep(1.5)
self.assertIsNone(snapbin.get_password(key))
class SnapPassRoutesTestCase(TestCase): def test_returned_token_format():
# noinspection PyPep8Naming password = "trustsome1"
def setUp(self): token = snapbin.set_password(password, 30)
snapbin.app.config['TESTING'] = True token_fragments = token.split(snapbin.TOKEN_SEPARATOR)
self.app = snapbin.app.test_client() assert 2 == len(token_fragments)
redis_key, encryption_key = token_fragments
def test_preview_password(self): assert (32 + len(snapbin.REDIS_PREFIX)) == len(redis_key)
password = "I like novelty kitten statues!" try:
key = snapbin.set_password(password, 30) Fernet(encryption_key.encode("utf-8"))
rv = self.app.get('/{0}'.format(key)) except ValueError:
self.assertNotIn(password, rv.get_data(as_text=True)) assert False, "the encryption key is not valid"
def test_show_password(self):
password = "I like novelty kitten statues!"
key = snapbin.set_password(password, 30)
rv = self.app.post('/{0}'.format(key))
self.assertIn(password, rv.get_data(as_text=True))
def test_url_prefix(self):
password = "I like novelty kitten statues!"
snapbin.URL_PREFIX = "/test/prefix"
rv = self.app.post('/', data={'password': password, 'ttl': 'hour'})
self.assertIn("localhost/test/prefix/", rv.get_data(as_text=True))
def test_set_password(self):
with freeze_time("2020-05-08 12:00:00") as frozen_time:
password = 'my name is my passport. verify me.'
rv = self.app.post('/', data={'password': password, 'ttl': 'three days'})
html_content = rv.data.decode("ascii")
key = re.search(r'id="password-link" value="http://localhost/([^"]+)', html_content).group(1)
key = unquote(key)
frozen_time.move_to("2020-05-22 11:59:59")
self.assertEqual(snapbin.get_password(key), password)
frozen_time.move_to("2020-05-22 12:00:00")
self.assertIsNone(snapbin.get_password(key))
def test_set_password_json(self):
with freeze_time("2020-05-08 12:00:00") as frozen_time:
password = 'my name is my passport. verify me.'
rv = self.app.post(
'/',
headers={'Accept': 'application/json'},
data={'password': password, 'ttl': 'three days'},
)
json_content = rv.get_json()
key = re.search(r'http://localhost/([^"]+)', json_content['link']).group(1)
key = unquote(key)
frozen_time.move_to("2020-05-22 11:59:59")
self.assertEqual(snapbin.get_password(key), password)
frozen_time.move_to("2020-05-22 12:00:00")
self.assertIsNone(snapbin.get_password(key))
if __name__ == '__main__': def test_encryption_key_is_returned():
unittest.main() password = "trustany1"
token = snapbin.set_password(password, 30)
token_fragments = token.split(snapbin.TOKEN_SEPARATOR)
redis_key, encryption_key = token_fragments
stored_password = snapbin.redis_client.get(redis_key)
fernet = Fernet(encryption_key.encode("utf-8"))
decrypted_password = fernet.decrypt(stored_password).decode("utf-8")
assert password == decrypted_password
def test_unencrypted_passwords_still_work():
unencrypted_password = "trustevery1"
storage_key = uuid.uuid4().hex
snapbin.redis_client.setex(storage_key, 30, unencrypted_password)
retrieved_password = snapbin.get_password(storage_key)
assert unencrypted_password == retrieved_password
def test_password_is_decoded():
password = "correct horse battery staple"
key = snapbin.set_password(password, 30)
assert not isinstance(snapbin.get_password(key), bytes)
def test_clean_input():
# Test Bad Data
with snapbin.app.test_request_context(
"/", data={"password": "foo", "ttl": "bar"}, method="POST"
):
with pytest.raises(BadRequest):
snapbin.clean_input()
# No Password
with snapbin.app.test_request_context("/", method="POST"):
with pytest.raises(BadRequest):
snapbin.clean_input()
# No TTL
with snapbin.app.test_request_context(
"/", data={"password": "foo", "ttl": ""}, method="POST"
):
assert (604800, "foo") == snapbin.clean_input()
with snapbin.app.test_request_context(
"/", data={"password": "foo", "ttl": 3600}, method="POST"
):
assert (3600, "foo") == snapbin.clean_input()
def test_password_before_expiration():
password = "fidelio"
key = snapbin.set_password(password, 1)
assert password == snapbin.get_password(key)
def test_password_after_expiration():
password = "open sesame"
key = snapbin.set_password(password, 1)
time.sleep(1.5)
assert snapbin.get_password(key) == None
def test_preview_password(app):
password = "I like novelty kitten statues!"
key = snapbin.set_password(password, 30)
rv = app.get("/{0}".format(key))
assert password not in rv.get_data(as_text=True)
def test_show_password(app):
password = "I like novelty kitten statues!"
key = snapbin.set_password(password, 30)
rv = app.post("/get-secret", data={"key": key})
assert password in rv.get_data(as_text=True)
def test_set_password_json(app):
with freeze_time("2020-05-08 12:00:00") as frozen_time:
password = "my name is my passport. verify me."
rv = app.post(
"/",
headers={"Accept": "application/json"},
data={"password": password, "ttl": 3000},
)
json_content = rv.get_json()
key = json_content["key"]
frozen_time.move_to("2020-05-22 11:59:59")
assert snapbin.get_password(key) == password
frozen_time.move_to("2020-05-22 12:00:00")
assert snapbin.get_password(key) == None