Commit 38dc2bb9 authored by Kevin Morris's avatar Kevin Morris
Browse files

Sanitize and modernize pytests



Some of these tests were written before some of our convenient
tooling existed. Additionally, some of the tests were not
cooperating with PEP-8 guidelines or isorted.

This commit does the following:
    - Replaces all calls to make_(user|session) with
      aurweb.db.create(Model, ...).
    - Replace calls to session.add(...) + session.commit() with
      aurweb.db.create.
    - Removes the majority of calls to (session|aurweb.db).delete(...).
    - Replaces session.query calls with aurweb.db.query.
    - Initializes all mutable globals in pytest fixture setup().
    - Makes mutable global declarations more concise:
      `var1, var2 = None, None` -> `var1 = var2 = None`
    - Defines a warning exclusion for test/test_ssh_pub_key.py.
    - Removes the aurweb.testing.models module.
    - Removes some useless pytest.fixture yielding.

As of this commit, developers should use the following guidelines
when writing tests:
    - Always use aurweb.db.(create|delete|query) for database
      operations, where possible.
    - Always define mutable globals in the style: `var1 = var2 = None`.
    - `yield` the most dependent model in pytest setup fixture **iff**
      you must delete records after test runs to maintain database
      integrity. Example: test/test_account_type.py.

This all makes the test code look and behave much cleaner.
Previously, aurweb.testing.setup_test_db was buggy and leaving
objects around in SQLAlchemy's IdentityMap.
Signed-off-by: Kevin Morris's avatarKevin Morris <kevr@0cost.org>
parent f2121fb8
import warnings
from sqlalchemy import exc
import aurweb.db
def make_user(**kwargs):
with warnings.catch_warnings():
warnings.simplefilter("ignore", exc.SAWarning)
from aurweb.models.user import User
user = User(**kwargs)
aurweb.db.session.add(user)
aurweb.db.session.commit()
return user
def make_session(**kwargs):
with warnings.catch_warnings():
warnings.simplefilter("ignore", exc.SAWarning)
from aurweb.models.session import Session
session = Session(**kwargs)
aurweb.db.session.add(session)
aurweb.db.session.commit()
return session
......@@ -2,18 +2,26 @@
max-line-length = 127
max-complexity = 10
# Ignore some unavoidable flake8 warnings; we know this is against
# pycodestyle, but some of the existing codebase uses `I` variables,
# so specifically silence warnings about it in pre-defined files.
# In E741, the 'I', 'O', 'l' are ambiguous variable names.
# Our current implementation uses these variables through HTTP
# and the FastAPI form specification wants them named as such.
# In C901's case, our process_account_form function is way too
# complex for PEP (too many if statements). However, we need to
# process these anyways, and making it any more complex would
# just add confusion to the implementation.
# aurweb/routers/accounts.py
# Ignore some unavoidable flake8 warnings; we know this is against
# pycodestyle, but some of the existing codebase uses `I` variables,
# so specifically silence warnings about it in pre-defined files.
# In E741, the 'I', 'O', 'l' are ambiguous variable names.
# Our current implementation uses these variables through HTTP
# and the FastAPI form specification wants them named as such.
# In C901's case, our process_account_form function is way too
# complex for PEP (too many if statements). However, we need to
# process these anyways, and making it any more complex would
# just add confusion to the implementation.
#
# test/test_ssh_pub_key.py
# E501 is detected due to our >127 width test constant. Ignore it.
# Due to this, line width should _always_ be looked at in code reviews.
# Anything like this should be questioned.
#
per-file-ignores =
aurweb/routers/accounts.py:E741,C901
test/test_ssh_pub_key.py:E501
[isort]
line_length = 127
......
......@@ -2,14 +2,14 @@ import pytest
from sqlalchemy.exc import IntegrityError
from aurweb.db import create, delete, query
from aurweb.db import create, query
from aurweb.models.accepted_term import AcceptedTerm
from aurweb.models.account_type import AccountType
from aurweb.models.term import Term
from aurweb.models.user import User
from aurweb.testing import setup_test_db
user, term, accepted_term = None, None, None
user = term = accepted_term = None
@pytest.fixture(autouse=True)
......@@ -26,11 +26,6 @@ def setup():
term = create(Term, Description="Test term", URL="https://test.term")
yield term
delete(Term, Term.ID == term.ID)
delete(User, User.ID == user.ID)
def test_accepted_term():
accepted_term = create(AcceptedTerm, User=user, Term=term)
......@@ -40,8 +35,6 @@ def test_accepted_term():
assert accepted_term in user.accepted_terms
assert accepted_term in term.accepted
delete(AcceptedTerm, AcceptedTerm.User == user, AcceptedTerm.Term == term)
def test_accepted_term_null_user_raises_exception():
from aurweb.db import session
......
import pytest
from aurweb.db import create, delete, query
from aurweb.models.account_type import AccountType
from aurweb.models.user import User
from aurweb.testing import setup_test_db
from aurweb.testing.models import make_user
account_type = None
......@@ -12,24 +12,17 @@ account_type = None
def setup():
setup_test_db("Users")
from aurweb.db import session
global account_type
account_type = AccountType(AccountType="TestUser")
session.add(account_type)
session.commit()
account_type = create(AccountType, AccountType="TestUser")
yield account_type
session.delete(account_type)
session.commit()
delete(AccountType, AccountType.ID == account_type.ID)
def test_account_type():
""" Test creating an AccountType, and reading its columns. """
from aurweb.db import session
# Make sure it got created and was given an ID.
assert bool(account_type.ID)
......@@ -39,20 +32,17 @@ def test_account_type():
"<AccountType(ID='%s', AccountType='TestUser')>" % (
account_type.ID)
record = session.query(AccountType).filter(
AccountType.AccountType == "TestUser").first()
record = query(AccountType,
AccountType.AccountType == "TestUser").first()
assert account_type == record
def test_user_account_type_relationship():
from aurweb.db import session
user = make_user(Username="test", Email="test@example.org",
RealName="Test User", Passwd="testPassword",
AccountType=account_type)
user = create(User, Username="test", Email="test@example.org",
RealName="Test User", Passwd="testPassword",
AccountType=account_type)
assert user.AccountType == account_type
assert account_type.users.filter(User.ID == user.ID).first()
session.delete(user)
session.commit()
delete(User, User.ID == user.ID)
......@@ -12,14 +12,13 @@ from fastapi.testclient import TestClient
from aurweb import captcha
from aurweb.asgi import app
from aurweb.db import create, delete, query
from aurweb.db import create, query
from aurweb.models.account_type import AccountType
from aurweb.models.ban import Ban
from aurweb.models.session import Session
from aurweb.models.ssh_pub_key import SSHPubKey, get_fingerprint
from aurweb.models.user import User
from aurweb.testing import setup_test_db
from aurweb.testing.models import make_user
from aurweb.testing.requests import Request
# Some test global constants.
......@@ -39,9 +38,9 @@ def setup():
account_type = query(AccountType,
AccountType.AccountType == "User").first()
user = make_user(Username=TEST_USERNAME, Email=TEST_EMAIL,
RealName="Test User", Passwd="testPassword",
AccountType=account_type)
user = create(User, Username=TEST_USERNAME, Email=TEST_EMAIL,
RealName="Test User", Passwd="testPassword",
AccountType=account_type)
def test_get_passreset_authed_redirects():
......@@ -751,8 +750,8 @@ def test_post_account_edit_error_unauthorized():
request = Request()
sid = user.login(request, "testPassword")
test2 = create(User, Username="test2", Email="test2@example.org",
Passwd="testPassword")
create(User, Username="test2",
Email="test2@example.org", Passwd="testPassword")
post_data = {
"U": "test",
......
......@@ -5,16 +5,14 @@ import pytest
from starlette.authentication import AuthenticationError
from aurweb.auth import BasicAuthBackend, has_credential
from aurweb.db import query
from aurweb.db import create, query
from aurweb.models.account_type import AccountType
from aurweb.models.session import Session
from aurweb.models.user import User
from aurweb.testing import setup_test_db
from aurweb.testing.models import make_session, make_user
from aurweb.testing.requests import Request
# Persistent user object, initialized in our setup fixture.
user = None
backend = None
request = None
user = backend = request = None
@pytest.fixture(autouse=True)
......@@ -23,16 +21,11 @@ def setup():
setup_test_db("Users", "Sessions")
from aurweb.db import session
account_type = query(AccountType,
AccountType.AccountType == "User").first()
user = make_user(Username="test", Email="test@example.com",
RealName="Test User", Passwd="testPassword",
AccountType=account_type)
session.add(user)
session.commit()
user = create(User, Username="test", Email="test@example.com",
RealName="Test User", Passwd="testPassword",
AccountType=account_type)
backend = BasicAuthBackend()
request = Request()
......@@ -60,8 +53,8 @@ async def test_auth_backend_invalid_sid():
async def test_auth_backend_invalid_user_id():
# Create a new session with a fake user id.
now_ts = datetime.utcnow().timestamp()
make_session(UsersID=666, SessionID="realSession",
LastUpdateTS=now_ts + 5)
create(Session, UsersID=666, SessionID="realSession",
LastUpdateTS=now_ts + 5)
# Here, we specify a real SID; but it's user is not there.
request.cookies["AURSID"] = "realSession"
......@@ -74,8 +67,8 @@ async def test_basic_auth_backend():
# This time, everything matches up. We expect the user to
# equal the real_user.
now_ts = datetime.utcnow().timestamp()
make_session(UsersID=user.ID, SessionID="realSession",
LastUpdateTS=now_ts + 5)
create(Session, UsersID=user.ID, SessionID="realSession",
LastUpdateTS=now_ts + 5)
_, result = await backend.authenticate(request)
assert result == user
......
......@@ -8,33 +8,34 @@ from fastapi.testclient import TestClient
import aurweb.config
from aurweb.asgi import app
from aurweb.db import query
from aurweb.db import create, query
from aurweb.models.account_type import AccountType
from aurweb.models.session import Session
from aurweb.models.user import User
from aurweb.testing import setup_test_db
from aurweb.testing.models import make_user
# Some test global constants.
TEST_USERNAME = "test"
TEST_EMAIL = "test@example.org"
# Global mutables.
client = TestClient(app)
user = None
user = client = None
@pytest.fixture(autouse=True)
def setup():
global user
global user, client
setup_test_db("Users", "Sessions", "Bans")
account_type = query(AccountType,
AccountType.AccountType == "User").first()
user = make_user(Username=TEST_USERNAME, Email=TEST_EMAIL,
RealName="Test User", Passwd="testPassword",
AccountType=account_type)
user = create(User, Username=TEST_USERNAME, Email=TEST_EMAIL,
RealName="Test User", Passwd="testPassword",
AccountType=account_type)
client = TestClient(app)
def test_login_logout():
......
......@@ -6,27 +6,23 @@ import pytest
from sqlalchemy import exc as sa_exc
from aurweb.db import create
from aurweb.models.ban import Ban, is_banned
from aurweb.testing import setup_test_db
from aurweb.testing.requests import Request
ban = None
request = Request()
ban = request = None
@pytest.fixture(autouse=True)
def setup():
from aurweb.db import session
global ban
global ban, request
setup_test_db("Bans")
ban = Ban(IPAddress="127.0.0.1",
BanTS=datetime.utcnow() + timedelta(seconds=30))
session.add(ban)
session.commit()
ts = datetime.utcnow() + timedelta(seconds=30)
ban = create(Ban, IPAddress="127.0.0.1", BanTS=ts)
request = Request()
def test_ban():
......
from aurweb.exceptions import (AlreadyVotedException, AurwebException, BannedException, BrokenUpdateHookException,
InvalidArgumentsException, InvalidCommentException, InvalidPackageBaseException,
InvalidReasonException, InvalidRepositoryNameException, InvalidUserException,
MaintenanceException, NotVotedException, PackageBaseExistsException, PermissionDeniedException)
from aurweb import exceptions
def test_aurweb_exception():
try:
raise AurwebException("test")
except AurwebException as exc:
raise exceptions.AurwebException("test")
except exceptions.AurwebException as exc:
assert str(exc) == "test"
def test_maintenance_exception():
try:
raise MaintenanceException("test")
except MaintenanceException as exc:
raise exceptions.MaintenanceException("test")
except exceptions.MaintenanceException as exc:
assert str(exc) == "test"
def test_banned_exception():
try:
raise BannedException("test")
except BannedException as exc:
raise exceptions.BannedException("test")
except exceptions.BannedException as exc:
assert str(exc) == "test"
def test_already_voted_exception():
try:
raise AlreadyVotedException("test")
except AlreadyVotedException as exc:
raise exceptions.AlreadyVotedException("test")
except exceptions.AlreadyVotedException as exc:
assert str(exc) == "already voted for package base: test"
def test_broken_update_hook_exception():
try:
raise BrokenUpdateHookException("test")
except BrokenUpdateHookException as exc:
raise exceptions.BrokenUpdateHookException("test")
except exceptions.BrokenUpdateHookException as exc:
assert str(exc) == "broken update hook: test"
def test_invalid_arguments_exception():
try:
raise InvalidArgumentsException("test")
except InvalidArgumentsException as exc:
raise exceptions.InvalidArgumentsException("test")
except exceptions.InvalidArgumentsException as exc:
assert str(exc) == "test"
def test_invalid_packagebase_exception():
try:
raise InvalidPackageBaseException("test")
except InvalidPackageBaseException as exc:
raise exceptions.InvalidPackageBaseException("test")
except exceptions.InvalidPackageBaseException as exc:
assert str(exc) == "package base not found: test"
def test_invalid_comment_exception():
try:
raise InvalidCommentException("test")
except InvalidCommentException as exc:
raise exceptions.InvalidCommentException("test")
except exceptions.InvalidCommentException as exc:
assert str(exc) == "comment is too short: test"
def test_invalid_reason_exception():
try:
raise InvalidReasonException("test")
except InvalidReasonException as exc:
raise exceptions.InvalidReasonException("test")
except exceptions.InvalidReasonException as exc:
assert str(exc) == "invalid reason: test"
def test_invalid_user_exception():
try:
raise InvalidUserException("test")
except InvalidUserException as exc:
raise exceptions.InvalidUserException("test")
except exceptions.InvalidUserException as exc:
assert str(exc) == "unknown user: test"
def test_not_voted_exception():
try:
raise NotVotedException("test")
except NotVotedException as exc:
raise exceptions.NotVotedException("test")
except exceptions.NotVotedException as exc:
assert str(exc) == "missing vote for package base: test"
def test_packagebase_exists_exception():
try:
raise PackageBaseExistsException("test")
except PackageBaseExistsException as exc:
raise exceptions.PackageBaseExistsException("test")
except exceptions.PackageBaseExistsException as exc:
assert str(exc) == "package base already exists: test"
def test_permission_denied_exception():
try:
raise PermissionDeniedException("test")
except PermissionDeniedException as exc:
raise exceptions.PermissionDeniedException("test")
except exceptions.PermissionDeniedException as exc:
assert str(exc) == "permission denied: test"
def test_repository_name_exception():
try:
raise InvalidRepositoryNameException("test")
except InvalidRepositoryNameException as exc:
raise exceptions.InvalidRepositoryNameException("test")
except exceptions.InvalidRepositoryNameException as exc:
assert str(exc) == "invalid repository name: test"
......@@ -2,16 +2,20 @@ import pytest
from sqlalchemy.exc import IntegrityError
from aurweb.db import create, delete, get_engine
from aurweb.db import create
from aurweb.models.group import Group
from aurweb.testing import setup_test_db
@pytest.fixture(autouse=True)
def setup():
setup_test_db("Groups")
def test_group_creation():
get_engine()
group = create(Group, Name="Test Group")
assert bool(group.ID)
assert group.Name == "Test Group"
delete(Group, Group.ID == group.ID)
def test_group_null_name_raises_exception():
......
......@@ -23,5 +23,6 @@ def test_run():
use_alembic = True
verbose = False
aurweb.initdb.run(Args())
assert aurweb.db.session.query(AccountType).filter(
AccountType.AccountType == "User").first() is not None
record = aurweb.db.query(AccountType,
AccountType.AccountType == "User").first()
assert record is not None
......@@ -34,8 +34,6 @@ def setup():
Description="Test description.",
URL="https://test.package")
yield package
def test_package():
from aurweb.db import session
......
......@@ -5,8 +5,8 @@ from sqlalchemy.exc import IntegrityError
from aurweb.db import create, query
from aurweb.models.account_type import AccountType
from aurweb.models.package_base import PackageBase
from aurweb.models.user import User
from aurweb.testing import setup_test_db
from aurweb.testing.models import make_user
user = None
......@@ -19,10 +19,9 @@ def setup():
account_type = query(AccountType,
AccountType.AccountType == "User").first()
user = make_user(Username="test", Email="test@example.org",
RealName="Test User", Passwd="testPassword",
AccountType=account_type)
yield user
user = create(User, Username="test", Email="test@example.org",
RealName="Test User", Passwd="testPassword",
AccountType=account_type)
def test_package_base():
......
......@@ -6,10 +6,10 @@ from aurweb.db import create, query
from aurweb.models.account_type import AccountType
from aurweb.models.package_base import PackageBase
from aurweb.models.package_keyword import PackageKeyword
from aurweb.models.user import User
from aurweb.testing import setup_test_db
from aurweb.testing.models import make_user
user, pkgbase = None, None
user = pkgbase = None
@pytest.fixture(autouse=True)
......@@ -20,15 +20,13 @@ def setup():
account_type = query(AccountType,
AccountType.AccountType == "User").first()
user = make_user(Username="test", Email="test@example.org",
RealName="Test User", Passwd="testPassword",
AccountType=account_type)
user = create(User, Username="test", Email="test@example.org",
RealName="Test User", Passwd="testPassword",
AccountType=account_type)
pkgbase = create(PackageBase,
Name="beautiful-package",
Maintainer=user)
yield pkgbase
def test_package_keyword():
pkg_keyword = create(PackageKeyword,
......
......@@ -7,27 +7,28 @@ import pytest
from fastapi.testclient import TestClient
from aurweb.asgi import app
from aurweb.db import query
from aurweb.db import create, query
from aurweb.models.account_type import AccountType
from aurweb.models.user import User
from aurweb.testing import setup_test_db
from aurweb.testing.models import make_user
from aurweb.testing.requests import Request
client = TestClient(app)
user = None
user = client = None
@pytest.fixture(autouse=True)
def setup():
global user
global user, client
setup_test_db("Users", "Sessions")
account_type = query(AccountType,
AccountType.AccountType == "User").first()
user = make_user(Username="test", Email="test@example.org",
RealName="Test User", Passwd="testPassword",
AccountType=account_type)
user = create(User, Username="test", Email="test@example.org",
RealName="Test User", Passwd="testPassword",
AccountType=account_type)
client = TestClient(app)
def test_index():
......