Compare commits

..

3 Commits

Author SHA1 Message Date
Tim Van Baak 243df40ac7 Add stopgap pytest.ini 2021-05-31 15:12:43 -07:00
Tim Van Baak 1df96107a1 Reduce test output 2021-05-31 15:12:33 -07:00
Tim Van Baak 1268b53d2a Add character backend 2021-05-31 15:09:26 -07:00
5 changed files with 109 additions and 23 deletions

View File

@ -1,8 +1,10 @@
""" """
Membership query interface Character query interface
""" """
from amanuensis.db import DbContext, Character from sqlalchemy import select, func
from amanuensis.db import *
from amanuensis.errors import ArgumentError from amanuensis.errors import ArgumentError
@ -15,19 +17,41 @@ def create(
""" """
Create a new character for a user. Create a new character for a user.
""" """
# Quick argument verification # Verify argument types are correct
if not isinstance(lexicon_id, int): if not isinstance(lexicon_id, int):
raise ArgumentError('lexicon_id') raise ArgumentError('lexicon_id')
if not isinstance(user_id, int): if not isinstance(user_id, int):
raise ArgumentError('user_id') raise ArgumentError('user_id')
# Verify character information
if not isinstance(name, str): if not isinstance(name, str):
raise ArgumentError('Character name must be a string') raise ArgumentError('name')
if signature is not None and not isinstance(signature, str):
raise ArgumentError('signature')
# Verify character name is valid
if not name.strip(): if not name.strip():
raise ArgumentError('Character name cannot be blank') raise ArgumentError('Character name cannot be blank')
if signature is not None and not isinstance(signature, str):
raise ArgumentError('Signature must be a string') # If no signature is provided, use a default signature
if not signature or not signature.strip():
signature = f'~{name}'
# Check that the user is a member of this lexicon
mem: Membership = db(
select(Membership)
.where(Membership.user_id == user_id)
.where(Membership.lexicon_id == lexicon_id)
).scalar_one_or_none()
if not mem:
raise ArgumentError('User is not a member of lexicon')
# Check that this user is below the limit for creating characters
num_user_chars = db(
select(func.count(Character.id))
.where(Character.lexicon_id == lexicon_id)
.where(Character.user_id == user_id)
).scalar()
if mem.lexicon.character_limit is not None and num_user_chars >= mem.lexicon.character_limit:
raise ArgumentError('User is at character limit')
new_character = Character( new_character = Character(
lexicon_id=lexicon_id, lexicon_id=lexicon_id,

View File

@ -14,6 +14,9 @@ SQLAlchemy = "^1.4.12"
[tool.poetry.dev-dependencies] [tool.poetry.dev-dependencies]
pytest = "^5.2" pytest = "^5.2"
[tool.pytest.ini_options]
addopts = "--show-capture=log"
[build-system] [build-system]
requires = ["poetry-core>=1.0.0"] requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api" build-backend = "poetry.core.masonry.api"

5
pytest.ini Normal file
View File

@ -0,0 +1,5 @@
[pytest]
addopts = --show-capture=log
; pytest should be able to read the pyproject.toml file, but for some reason it
; doesn't seem to be working here. This file is a temporary fix until that gets
; resolved.

View File

@ -12,7 +12,7 @@ import amanuensis.backend.user as userq
@pytest.fixture @pytest.fixture
def db(): def db():
"""Provides an initialized database in memory.""" """Provides an initialized database in memory."""
db = DbContext('sqlite:///:memory:', debug=True) db = DbContext('sqlite:///:memory:', debug=False)
db.create_all() db.create_all()
return db return db

View File

@ -1,19 +1,73 @@
import pytest
from amanuensis.db import * from amanuensis.db import *
import amanuensis.backend.lexicon as lexiq import amanuensis.backend.character as charq
import amanuensis.backend.membership as memq from amanuensis.errors import ArgumentError
import amanuensis.backend.user as userq
from .test_db import db
def test_create_character(db: DbContext): def test_create_character(db: DbContext, lexicon_with_editor, make_user):
"""Test creating a character.""" """Test creating a character."""
# Set up a user and lexicon lexicon, user = lexicon_with_editor
new_user = userq.create(db, 'username', 'password', 'user', 'a@b.c', False) kwargs = {
assert new_user.id, 'Failed to create user' 'db': db,
new_lexicon = lexiq.create(db, 'Test', None, 'prompt') 'user_id': user.id,
assert new_lexicon.id, 'Failed to create lexicon' 'lexicon_id': lexicon.id,
mem = memq.create(db, new_user.id, new_lexicon.id, True) 'name': 'Character Name',
assert mem, 'Failed to create membership' 'signature': 'Signature',
}
# # Bad argument types
with pytest.raises(ArgumentError):
charq.create(**{**kwargs, 'name': b'bytestring'})
with pytest.raises(ArgumentError):
charq.create(**{**kwargs, 'name': None})
with pytest.raises(ArgumentError):
charq.create(**{**kwargs, 'signature': b'bytestring'})
# Bad character name
with pytest.raises(ArgumentError):
charq.create(**{**kwargs, 'name': ' '})
# Signature is auto-populated
char = charq.create(**{**kwargs, 'signature': None})
assert char.signature is not None
# User must be in lexicon
new_user = make_user()
with pytest.raises(ArgumentError):
charq.create(**{**kwargs, 'user_id': new_user.id})
def test_character_limits(db: DbContext, lexicon_with_editor):
"""Test lexicon settings limiting character creation."""
lexicon: Lexicon
user: User
lexicon, user = lexicon_with_editor
# Set character limit to one and create a character
lexicon.character_limit = 1
db.session.commit()
char1 = charq.create(db, lexicon.id, user.id, 'Test Character 1', signature=None)
assert char1.id, 'Failed to create character 1'
# Creating a second character should fail
with pytest.raises(ArgumentError):
char2 = charq.create(db, lexicon.id, user.id, 'Test Character 2', signature=None)
assert char2
# Raising the limit to 2 should allow a second character
lexicon.character_limit = 2
db.session.commit()
char2 = charq.create(db, lexicon.id, user.id, 'Test Character 2', signature=None)
assert char2.id, 'Failed to create character 2'
# Creating a third character should fail
with pytest.raises(ArgumentError):
char3 = charq.create(db, lexicon.id, user.id, 'Test Character 3', signature=None)
assert char3
# Setting the limit to null should allow a third character
lexicon.character_limit = None
db.session.commit()
char2 = charq.create(db, lexicon.id, user.id, 'Test Character 3', signature=None)
assert char2.id, 'Failed to create character 3'