Adopt black as a code formatter #6
|
@ -8,11 +8,7 @@ from amanuensis.db import *
|
||||||
from amanuensis.errors import ArgumentError
|
from amanuensis.errors import ArgumentError
|
||||||
|
|
||||||
|
|
||||||
def create(
|
def create(db: DbContext, lexicon_id: int, user_id: int, character_id: int) -> Article:
|
||||||
db: DbContext,
|
|
||||||
lexicon_id: int,
|
|
||||||
user_id: int,
|
|
||||||
character_id: int) -> Article:
|
|
||||||
"""
|
"""
|
||||||
Create a new article in a lexicon.
|
Create a new article in a lexicon.
|
||||||
"""
|
"""
|
||||||
|
@ -37,8 +33,7 @@ def create(
|
||||||
# and the character belongs to the lexicon
|
# and the character belongs to the lexicon
|
||||||
if character_id is not None:
|
if character_id is not None:
|
||||||
character: Character = db(
|
character: Character = db(
|
||||||
select(Character)
|
select(Character).where(Character.id == character_id)
|
||||||
.where(Character.id == character_id)
|
|
||||||
).scalar_one_or_none()
|
).scalar_one_or_none()
|
||||||
if not character:
|
if not character:
|
||||||
raise ArgumentError('Character does not exist')
|
raise ArgumentError('Character does not exist')
|
||||||
|
|
|
@ -9,11 +9,8 @@ from amanuensis.errors import ArgumentError
|
||||||
|
|
||||||
|
|
||||||
def create(
|
def create(
|
||||||
db: DbContext,
|
db: DbContext, lexicon_id: int, user_id: int, name: str, signature: str
|
||||||
lexicon_id: int,
|
) -> Character:
|
||||||
user_id: int,
|
|
||||||
name: str,
|
|
||||||
signature: str) -> Character:
|
|
||||||
"""
|
"""
|
||||||
Create a new character for a user.
|
Create a new character for a user.
|
||||||
"""
|
"""
|
||||||
|
@ -50,7 +47,10 @@ def create(
|
||||||
.where(Character.lexicon_id == lexicon_id)
|
.where(Character.lexicon_id == lexicon_id)
|
||||||
.where(Character.user_id == user_id)
|
.where(Character.user_id == user_id)
|
||||||
).scalar()
|
).scalar()
|
||||||
if mem.lexicon.character_limit is not None and num_user_chars >= mem.lexicon.character_limit:
|
if (
|
||||||
|
mem.lexicon.character_limit is not None
|
||||||
|
and num_user_chars >= mem.lexicon.character_limit
|
||||||
|
):
|
||||||
raise ArgumentError('User is at character limit')
|
raise ArgumentError('User is at character limit')
|
||||||
|
|
||||||
new_character = Character(
|
new_character = Character(
|
||||||
|
|
|
@ -13,11 +13,7 @@ from amanuensis.errors import ArgumentError
|
||||||
RE_ALPHANUM_DASH_UNDER = re.compile(r'^[A-Za-z0-9-_]*$')
|
RE_ALPHANUM_DASH_UNDER = re.compile(r'^[A-Za-z0-9-_]*$')
|
||||||
|
|
||||||
|
|
||||||
def create(
|
def create(db: DbContext, name: str, title: str, prompt: str) -> Lexicon:
|
||||||
db: DbContext,
|
|
||||||
name: str,
|
|
||||||
title: str,
|
|
||||||
prompt: str) -> Lexicon:
|
|
||||||
"""
|
"""
|
||||||
Create a new lexicon.
|
Create a new lexicon.
|
||||||
"""
|
"""
|
||||||
|
@ -27,7 +23,9 @@ def create(
|
||||||
if not name.strip():
|
if not name.strip():
|
||||||
raise ArgumentError('Lexicon name must not be blank')
|
raise ArgumentError('Lexicon name must not be blank')
|
||||||
if not RE_ALPHANUM_DASH_UNDER.match(name):
|
if not RE_ALPHANUM_DASH_UNDER.match(name):
|
||||||
raise ArgumentError('Lexicon name may only contain alphanumerics, dash, and underscore')
|
raise ArgumentError(
|
||||||
|
'Lexicon name may only contain alphanumerics, dash, and underscore'
|
||||||
|
)
|
||||||
|
|
||||||
# Verify title
|
# Verify title
|
||||||
if title is not None and not isinstance(name, str):
|
if title is not None and not isinstance(name, str):
|
||||||
|
@ -38,10 +36,7 @@ def create(
|
||||||
raise ArgumentError('Lexicon prompt must be a string')
|
raise ArgumentError('Lexicon prompt must be a string')
|
||||||
|
|
||||||
# Query the db to make sure the lexicon name isn't taken
|
# Query the db to make sure the lexicon name isn't taken
|
||||||
if db(
|
if db(select(func.count(Lexicon.id)).where(Lexicon.name == name)).scalar() > 0:
|
||||||
select(func.count(Lexicon.id))
|
|
||||||
.where(Lexicon.name == name)
|
|
||||||
).scalar() > 0:
|
|
||||||
raise ArgumentError('Lexicon name is already taken')
|
raise ArgumentError('Lexicon name is already taken')
|
||||||
|
|
||||||
new_lexicon = Lexicon(
|
new_lexicon = Lexicon(
|
||||||
|
|
|
@ -8,11 +8,7 @@ from amanuensis.db import DbContext, Membership
|
||||||
from amanuensis.errors import ArgumentError
|
from amanuensis.errors import ArgumentError
|
||||||
|
|
||||||
|
|
||||||
def create(
|
def create(db: DbContext, user_id: int, lexicon_id: int, is_editor: bool) -> Membership:
|
||||||
db: DbContext,
|
|
||||||
user_id: int,
|
|
||||||
lexicon_id: int,
|
|
||||||
is_editor: bool) -> Membership:
|
|
||||||
"""
|
"""
|
||||||
Create a new user membership in a lexicon.
|
Create a new user membership in a lexicon.
|
||||||
"""
|
"""
|
||||||
|
@ -25,11 +21,14 @@ def create(
|
||||||
raise ArgumentError('is_editor')
|
raise ArgumentError('is_editor')
|
||||||
|
|
||||||
# Verify user has not already joined lexicon
|
# Verify user has not already joined lexicon
|
||||||
if db(
|
if (
|
||||||
select(func.count(Membership.id))
|
db(
|
||||||
.where(Membership.user_id == user_id)
|
select(func.count(Membership.id))
|
||||||
.where(Membership.lexicon_id == lexicon_id)
|
.where(Membership.user_id == user_id)
|
||||||
).scalar() > 0:
|
.where(Membership.lexicon_id == lexicon_id)
|
||||||
|
).scalar()
|
||||||
|
> 0
|
||||||
|
):
|
||||||
raise ArgumentError('User is already a member of lexicon')
|
raise ArgumentError('User is already a member of lexicon')
|
||||||
|
|
||||||
new_membership = Membership(
|
new_membership = Membership(
|
||||||
|
|
|
@ -9,11 +9,8 @@ from sqlalchemy import select, func
|
||||||
from amanuensis.db import DbContext, Post
|
from amanuensis.db import DbContext, Post
|
||||||
from amanuensis.errors import ArgumentError
|
from amanuensis.errors import ArgumentError
|
||||||
|
|
||||||
def create(
|
|
||||||
db: DbContext,
|
def create(db: DbContext, lexicon_id: int, user_id: int, body: str) -> Post:
|
||||||
lexicon_id: int,
|
|
||||||
user_id: int,
|
|
||||||
body: str) -> Post:
|
|
||||||
"""
|
"""
|
||||||
Create a new post
|
Create a new post
|
||||||
"""
|
"""
|
||||||
|
@ -32,11 +29,7 @@ def create(
|
||||||
if not body.strip():
|
if not body.strip():
|
||||||
raise ArgumentError('Post body cannot be empty.')
|
raise ArgumentError('Post body cannot be empty.')
|
||||||
|
|
||||||
new_post = Post(
|
new_post = Post(lexicon_id=lexicon_id, user_id=user_id, body=body)
|
||||||
lexicon_id=lexicon_id,
|
|
||||||
user_id=user_id,
|
|
||||||
body=body
|
|
||||||
)
|
|
||||||
db.session.add(new_post)
|
db.session.add(new_post)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
return new_post
|
return new_post
|
||||||
|
|
|
@ -11,7 +11,7 @@ from amanuensis.db import DbContext, User
|
||||||
from amanuensis.errors import ArgumentError
|
from amanuensis.errors import ArgumentError
|
||||||
|
|
||||||
|
|
||||||
RE_NO_LETTERS = re.compile(r'^[0-9-_]*$')
|
RE_NO_LETTERS = re.compile(r'^[0-9-_]*$')
|
||||||
RE_ALPHANUM_DASH_UNDER = re.compile(r'^[A-Za-z0-9-_]*$')
|
RE_ALPHANUM_DASH_UNDER = re.compile(r'^[A-Za-z0-9-_]*$')
|
||||||
|
|
||||||
|
|
||||||
|
@ -21,7 +21,8 @@ def create(
|
||||||
password: str,
|
password: str,
|
||||||
display_name: str,
|
display_name: str,
|
||||||
email: str,
|
email: str,
|
||||||
is_site_admin: bool) -> User:
|
is_site_admin: bool,
|
||||||
|
) -> User:
|
||||||
"""
|
"""
|
||||||
Create a new user.
|
Create a new user.
|
||||||
"""
|
"""
|
||||||
|
@ -33,7 +34,9 @@ def create(
|
||||||
if RE_NO_LETTERS.match(username):
|
if RE_NO_LETTERS.match(username):
|
||||||
raise ArgumentError('Username must contain a letter')
|
raise ArgumentError('Username must contain a letter')
|
||||||
if not RE_ALPHANUM_DASH_UNDER.match(username):
|
if not RE_ALPHANUM_DASH_UNDER.match(username):
|
||||||
raise ArgumentError('Username may only contain alphanumerics, dash, and underscore')
|
raise ArgumentError(
|
||||||
|
'Username may only contain alphanumerics, dash, and underscore'
|
||||||
|
)
|
||||||
|
|
||||||
# Verify password
|
# Verify password
|
||||||
if not isinstance(password, str):
|
if not isinstance(password, str):
|
||||||
|
@ -51,10 +54,7 @@ def create(
|
||||||
raise ArgumentError('Email must be a string')
|
raise ArgumentError('Email must be a string')
|
||||||
|
|
||||||
# Query the db to make sure the username isn't taken
|
# Query the db to make sure the username isn't taken
|
||||||
if db(
|
if db(select(func.count(User.id)).where(User.username == username)).scalar() > 0:
|
||||||
select(func.count(User.id))
|
|
||||||
.where(User.username == username)
|
|
||||||
).scalar() > 0:
|
|
||||||
raise ArgumentError('Username is already taken')
|
raise ArgumentError('Username is already taken')
|
||||||
|
|
||||||
new_user = User(
|
new_user = User(
|
||||||
|
|
|
@ -28,4 +28,4 @@ __all__ = [
|
||||||
'ArticleContentRuleType',
|
'ArticleContentRuleType',
|
||||||
'ArticleContentRule',
|
'ArticleContentRule',
|
||||||
'Post',
|
'Post',
|
||||||
]
|
]
|
||||||
|
|
|
@ -8,22 +8,25 @@ from sqlalchemy.orm import sessionmaker
|
||||||
|
|
||||||
|
|
||||||
# Define naming conventions for generated constraints
|
# Define naming conventions for generated constraints
|
||||||
metadata = MetaData(naming_convention={
|
metadata = MetaData(
|
||||||
"ix": "ix_%(column_0_label)s",
|
naming_convention={
|
||||||
"uq": "uq_%(table_name)s_%(column_0_name)s",
|
"ix": "ix_%(column_0_label)s",
|
||||||
"ck": "ck_%(table_name)s_%(constraint_name)s",
|
"uq": "uq_%(table_name)s_%(column_0_name)s",
|
||||||
"fk": "fk_%(table_name)s_%(column_0_name)s_%(referred_table_name)s",
|
"ck": "ck_%(table_name)s_%(constraint_name)s",
|
||||||
"pk": "pk_%(table_name)s"
|
"fk": "fk_%(table_name)s_%(column_0_name)s_%(referred_table_name)s",
|
||||||
})
|
"pk": "pk_%(table_name)s",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
# Base class for ORM models
|
# Base class for ORM models
|
||||||
ModelBase = declarative_base(metadata=metadata)
|
ModelBase = declarative_base(metadata=metadata)
|
||||||
|
|
||||||
|
|
||||||
class DbContext():
|
class DbContext:
|
||||||
def __init__(self, db_uri, debug=False):
|
def __init__(self, db_uri, debug=False):
|
||||||
# Create an engine and enable foreign key constraints in sqlite
|
# Create an engine and enable foreign key constraints in sqlite
|
||||||
self.engine = create_engine(db_uri, echo=debug)
|
self.engine = create_engine(db_uri, echo=debug)
|
||||||
|
|
||||||
@event.listens_for(self.engine, "connect")
|
@event.listens_for(self.engine, "connect")
|
||||||
def set_sqlite_pragma(dbapi_connection, connection_record):
|
def set_sqlite_pragma(dbapi_connection, connection_record):
|
||||||
cursor = dbapi_connection.cursor()
|
cursor = dbapi_connection.cursor()
|
||||||
|
|
|
@ -28,6 +28,7 @@ class Uuid(TypeDecorator):
|
||||||
"""
|
"""
|
||||||
A uuid backed by a char(32) field in sqlite.
|
A uuid backed by a char(32) field in sqlite.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
impl = CHAR(32)
|
impl = CHAR(32)
|
||||||
|
|
||||||
def process_bind_param(self, value, dialect):
|
def process_bind_param(self, value, dialect):
|
||||||
|
@ -51,6 +52,7 @@ class User(ModelBase):
|
||||||
"""
|
"""
|
||||||
Represents a single user of Amanuensis.
|
Represents a single user of Amanuensis.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__tablename__ = 'user'
|
__tablename__ = 'user'
|
||||||
|
|
||||||
#############
|
#############
|
||||||
|
@ -104,6 +106,7 @@ class Lexicon(ModelBase):
|
||||||
"""
|
"""
|
||||||
Represents a single game of Lexicon.
|
Represents a single game of Lexicon.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__tablename__ = 'lexicon'
|
__tablename__ = 'lexicon'
|
||||||
|
|
||||||
#############
|
#############
|
||||||
|
@ -131,7 +134,9 @@ class Lexicon(ModelBase):
|
||||||
created = Column(DateTime, nullable=False, server_default=text('CURRENT_TIMESTAMP'))
|
created = Column(DateTime, nullable=False, server_default=text('CURRENT_TIMESTAMP'))
|
||||||
|
|
||||||
# The timestamp of the last change in game state
|
# The timestamp of the last change in game state
|
||||||
last_updated = Column(DateTime, nullable=False, server_default=text('CURRENT_TIMESTAMP'))
|
last_updated = Column(
|
||||||
|
DateTime, nullable=False, server_default=text('CURRENT_TIMESTAMP')
|
||||||
|
)
|
||||||
|
|
||||||
# The timestamp the first turn was started
|
# The timestamp the first turn was started
|
||||||
# This is NULL until the game starts
|
# This is NULL until the game starts
|
||||||
|
@ -234,10 +239,9 @@ class Membership(ModelBase):
|
||||||
"""
|
"""
|
||||||
Represents a user's participation in a Lexicon game.
|
Represents a user's participation in a Lexicon game.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__tablename__ = 'membership'
|
__tablename__ = 'membership'
|
||||||
__table_args__ = (
|
__table_args__ = (UniqueConstraint('user_id', 'lexicon_id'),)
|
||||||
UniqueConstraint('user_id', 'lexicon_id'),
|
|
||||||
)
|
|
||||||
|
|
||||||
###################
|
###################
|
||||||
# Membership keys #
|
# Membership keys #
|
||||||
|
@ -295,6 +299,7 @@ class Character(ModelBase):
|
||||||
"""
|
"""
|
||||||
Represents a character played by a uaser in a Lexicon game.
|
Represents a character played by a uaser in a Lexicon game.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__tablename__ = 'character'
|
__tablename__ = 'character'
|
||||||
|
|
||||||
##################
|
##################
|
||||||
|
@ -333,6 +338,7 @@ class ArticleState(enum.Enum):
|
||||||
"""
|
"""
|
||||||
The step of the editorial process an article is in.
|
The step of the editorial process an article is in.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
DRAFT = 0
|
DRAFT = 0
|
||||||
SUBMITTED = 1
|
SUBMITTED = 1
|
||||||
APPROVED = 2
|
APPROVED = 2
|
||||||
|
@ -342,6 +348,7 @@ class Article(ModelBase):
|
||||||
"""
|
"""
|
||||||
Represents a single article in a lexicon.
|
Represents a single article in a lexicon.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__tablename__ = 'article'
|
__tablename__ = 'article'
|
||||||
|
|
||||||
################
|
################
|
||||||
|
@ -386,7 +393,9 @@ class Article(ModelBase):
|
||||||
####################
|
####################
|
||||||
|
|
||||||
# Timestamp the content of the article was last updated
|
# Timestamp the content of the article was last updated
|
||||||
last_updated = Column(DateTime, nullable=False, server_default=text('CURRENT_TIMESTAMP'))
|
last_updated = Column(
|
||||||
|
DateTime, nullable=False, server_default=text('CURRENT_TIMESTAMP')
|
||||||
|
)
|
||||||
|
|
||||||
# Timestamp the article was last submitted
|
# Timestamp the article was last submitted
|
||||||
# This is NULL until the article is submitted
|
# This is NULL until the article is submitted
|
||||||
|
@ -420,6 +429,7 @@ class IndexType(enum.Enum):
|
||||||
"""
|
"""
|
||||||
The title-matching behavior of an article index.
|
The title-matching behavior of an article index.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
CHAR = 0
|
CHAR = 0
|
||||||
RANGE = 1
|
RANGE = 1
|
||||||
PREFIX = 2
|
PREFIX = 2
|
||||||
|
@ -430,6 +440,7 @@ class ArticleIndex(ModelBase):
|
||||||
"""
|
"""
|
||||||
Represents an index definition.
|
Represents an index definition.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__tablename__ = 'article_index'
|
__tablename__ = 'article_index'
|
||||||
|
|
||||||
##############
|
##############
|
||||||
|
@ -472,6 +483,7 @@ class ArticleIndexRule(ModelBase):
|
||||||
A character with multiple index rules may write in any index that satisfies
|
A character with multiple index rules may write in any index that satisfies
|
||||||
a rule. A character with no index rules may write in any index.
|
a rule. A character with no index rules may write in any index.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__tablename__ = 'article_index_rule'
|
__tablename__ = 'article_index_rule'
|
||||||
|
|
||||||
###################
|
###################
|
||||||
|
@ -510,6 +522,7 @@ class ArticleContentRuleType(enum.Enum):
|
||||||
"""
|
"""
|
||||||
The possible article content rules.
|
The possible article content rules.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Whether characters can cite themselves
|
# Whether characters can cite themselves
|
||||||
ALLOW_SELF_CITE = 0
|
ALLOW_SELF_CITE = 0
|
||||||
# Whether characters can write new articles instead of phantoms
|
# Whether characters can write new articles instead of phantoms
|
||||||
|
@ -543,6 +556,7 @@ class ArticleContentRule(ModelBase):
|
||||||
"""
|
"""
|
||||||
Represents a restriction on the content of an article for a turn.
|
Represents a restriction on the content of an article for a turn.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__tablename__ = 'article_content_rule'
|
__tablename__ = 'article_content_rule'
|
||||||
|
|
||||||
#####################
|
#####################
|
||||||
|
@ -584,6 +598,7 @@ class Post(ModelBase):
|
||||||
"""
|
"""
|
||||||
Represents a post in the game feed.
|
Represents a post in the game feed.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__tablename__ = 'post'
|
__tablename__ = 'post'
|
||||||
|
|
||||||
#############
|
#############
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
Submodule of custom exception types
|
Submodule of custom exception types
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class AmanuensisError(Exception):
|
class AmanuensisError(Exception):
|
||||||
"""Base class for exceptions in amanuensis"""
|
"""Base class for exceptions in amanuensis"""
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@ def db():
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def make_user(db: DbContext):
|
def make_user(db: DbContext):
|
||||||
"""Provides a factory function for creating users, with valid default values."""
|
"""Provides a factory function for creating users, with valid default values."""
|
||||||
|
|
||||||
def user_factory(state={'nonce': 1}, **kwargs):
|
def user_factory(state={'nonce': 1}, **kwargs):
|
||||||
default_kwargs = {
|
default_kwargs = {
|
||||||
'username': f'test_user_{state["nonce"]}',
|
'username': f'test_user_{state["nonce"]}',
|
||||||
|
@ -32,39 +33,45 @@ def make_user(db: DbContext):
|
||||||
state['nonce'] += 1
|
state['nonce'] += 1
|
||||||
updated_kwargs = {**default_kwargs, **kwargs}
|
updated_kwargs = {**default_kwargs, **kwargs}
|
||||||
return userq.create(db, **updated_kwargs)
|
return userq.create(db, **updated_kwargs)
|
||||||
|
|
||||||
return user_factory
|
return user_factory
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def make_lexicon(db: DbContext):
|
def make_lexicon(db: DbContext):
|
||||||
"""Provides a factory function for creating lexicons, with valid default values."""
|
"""Provides a factory function for creating lexicons, with valid default values."""
|
||||||
|
|
||||||
def lexicon_factory(state={'nonce': 1}, **kwargs):
|
def lexicon_factory(state={'nonce': 1}, **kwargs):
|
||||||
default_kwargs = {
|
default_kwargs = {
|
||||||
'name': f'Test_{state["nonce"]}',
|
'name': f'Test_{state["nonce"]}',
|
||||||
'title': None,
|
'title': None,
|
||||||
'prompt': f'Test Lexicon game {state["nonce"]}'
|
'prompt': f'Test Lexicon game {state["nonce"]}',
|
||||||
}
|
}
|
||||||
state['nonce'] += 1
|
state['nonce'] += 1
|
||||||
updated_kwargs = {**default_kwargs, **kwargs}
|
updated_kwargs = {**default_kwargs, **kwargs}
|
||||||
return lexiq.create(db, **updated_kwargs)
|
return lexiq.create(db, **updated_kwargs)
|
||||||
|
|
||||||
return lexicon_factory
|
return lexicon_factory
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def make_membership(db: DbContext):
|
def make_membership(db: DbContext):
|
||||||
"""Provides a factory function for creating memberships, with valid default values."""
|
"""Provides a factory function for creating memberships, with valid default values."""
|
||||||
|
|
||||||
def membership_factory(**kwargs):
|
def membership_factory(**kwargs):
|
||||||
default_kwargs = {
|
default_kwargs = {
|
||||||
'is_editor': False,
|
'is_editor': False,
|
||||||
}
|
}
|
||||||
updated_kwargs = {**default_kwargs, **kwargs}
|
updated_kwargs = {**default_kwargs, **kwargs}
|
||||||
return memq.create(db, **updated_kwargs)
|
return memq.create(db, **updated_kwargs)
|
||||||
|
|
||||||
return membership_factory
|
return membership_factory
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def make_character(db: DbContext):
|
def make_character(db: DbContext):
|
||||||
"""Provides a factory function for creating characters, with valid default values."""
|
"""Provides a factory function for creating characters, with valid default values."""
|
||||||
|
|
||||||
def character_factory(state={'nonce': 1}, **kwargs):
|
def character_factory(state={'nonce': 1}, **kwargs):
|
||||||
default_kwargs = {
|
default_kwargs = {
|
||||||
'name': f'Character {state["nonce"]}',
|
'name': f'Character {state["nonce"]}',
|
||||||
|
@ -73,6 +80,7 @@ def make_character(db: DbContext):
|
||||||
state['nonce'] += 1
|
state['nonce'] += 1
|
||||||
updated_kwargs = {**default_kwargs, **kwargs}
|
updated_kwargs = {**default_kwargs, **kwargs}
|
||||||
return charq.create(db, **updated_kwargs)
|
return charq.create(db, **updated_kwargs)
|
||||||
|
|
||||||
return character_factory
|
return character_factory
|
||||||
|
|
||||||
|
|
||||||
|
@ -87,11 +95,8 @@ class TestFactory:
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def make(
|
def make(
|
||||||
db: DbContext,
|
db: DbContext, make_user, make_lexicon, make_membership, make_character
|
||||||
make_user,
|
) -> TestFactory:
|
||||||
make_lexicon,
|
|
||||||
make_membership,
|
|
||||||
make_character) -> TestFactory:
|
|
||||||
"""Fixture that groups all factory fixtures together."""
|
"""Fixture that groups all factory fixtures together."""
|
||||||
return TestFactory(
|
return TestFactory(
|
||||||
db,
|
db,
|
||||||
|
@ -109,6 +114,8 @@ def lexicon_with_editor(make):
|
||||||
assert editor
|
assert editor
|
||||||
lexicon = make.lexicon()
|
lexicon = make.lexicon()
|
||||||
assert lexicon
|
assert lexicon
|
||||||
membership = make.membership(user_id=editor.id, lexicon_id=lexicon.id, is_editor=True)
|
membership = make.membership(
|
||||||
|
user_id=editor.id, lexicon_id=lexicon.id, is_editor=True
|
||||||
|
)
|
||||||
assert membership
|
assert membership
|
||||||
return (lexicon, editor)
|
return (lexicon, editor)
|
||||||
|
|
|
@ -52,7 +52,9 @@ def test_character_limits(db: DbContext, lexicon_with_editor):
|
||||||
|
|
||||||
# Creating a second character should fail
|
# Creating a second character should fail
|
||||||
with pytest.raises(ArgumentError):
|
with pytest.raises(ArgumentError):
|
||||||
char2 = charq.create(db, lexicon.id, user.id, 'Test Character 2', signature=None)
|
char2 = charq.create(
|
||||||
|
db, lexicon.id, user.id, 'Test Character 2', signature=None
|
||||||
|
)
|
||||||
assert char2
|
assert char2
|
||||||
|
|
||||||
# Raising the limit to 2 should allow a second character
|
# Raising the limit to 2 should allow a second character
|
||||||
|
@ -63,7 +65,9 @@ def test_character_limits(db: DbContext, lexicon_with_editor):
|
||||||
|
|
||||||
# Creating a third character should fail
|
# Creating a third character should fail
|
||||||
with pytest.raises(ArgumentError):
|
with pytest.raises(ArgumentError):
|
||||||
char3 = charq.create(db, lexicon.id, user.id, 'Test Character 3', signature=None)
|
char3 = charq.create(
|
||||||
|
db, lexicon.id, user.id, 'Test Character 3', signature=None
|
||||||
|
)
|
||||||
assert char3
|
assert char3
|
||||||
|
|
||||||
# Setting the limit to null should allow a third character
|
# Setting the limit to null should allow a third character
|
||||||
|
|
|
@ -9,11 +9,7 @@ from amanuensis.errors import ArgumentError
|
||||||
|
|
||||||
def test_create_lexicon(db: DbContext):
|
def test_create_lexicon(db: DbContext):
|
||||||
"""Test new game creation."""
|
"""Test new game creation."""
|
||||||
kwargs = {
|
kwargs = {'name': 'Test', 'title': None, 'prompt': 'A test Lexicon game'}
|
||||||
'name': 'Test',
|
|
||||||
'title': None,
|
|
||||||
'prompt': 'A test Lexicon game'
|
|
||||||
}
|
|
||||||
# Test name constraints
|
# Test name constraints
|
||||||
with pytest.raises(ArgumentError):
|
with pytest.raises(ArgumentError):
|
||||||
lexiq.create(db, **{**kwargs, 'name': None})
|
lexiq.create(db, **{**kwargs, 'name': None})
|
||||||
|
|
|
@ -11,11 +11,7 @@ def test_create_post(db: DbContext, lexicon_with_editor):
|
||||||
lexicon, editor = lexicon_with_editor
|
lexicon, editor = lexicon_with_editor
|
||||||
|
|
||||||
# argument dictionary for post object
|
# argument dictionary for post object
|
||||||
kwargs = {
|
kwargs = {'lexicon_id': lexicon.id, 'user_id': editor.id, 'body': 'body'}
|
||||||
'lexicon_id': lexicon.id,
|
|
||||||
'user_id': editor.id,
|
|
||||||
'body': 'body'
|
|
||||||
}
|
|
||||||
|
|
||||||
# ids are integers
|
# ids are integers
|
||||||
with pytest.raises(ArgumentError):
|
with pytest.raises(ArgumentError):
|
||||||
|
|
|
@ -12,14 +12,16 @@ def test_create_user(db: DbContext):
|
||||||
'password': 'password',
|
'password': 'password',
|
||||||
'display_name': 'User Name',
|
'display_name': 'User Name',
|
||||||
'email': 'user@example.com',
|
'email': 'user@example.com',
|
||||||
'is_site_admin': False
|
'is_site_admin': False,
|
||||||
}
|
}
|
||||||
|
|
||||||
# Test length constraints
|
# Test length constraints
|
||||||
with pytest.raises(ArgumentError):
|
with pytest.raises(ArgumentError):
|
||||||
userq.create(db, **{**kwargs, 'username': 'me'})
|
userq.create(db, **{**kwargs, 'username': 'me'})
|
||||||
with pytest.raises(ArgumentError):
|
with pytest.raises(ArgumentError):
|
||||||
userq.create(db, **{**kwargs, 'username': 'the right honorable user-name, esquire'})
|
userq.create(
|
||||||
|
db, **{**kwargs, 'username': 'the right honorable user-name, esquire'}
|
||||||
|
)
|
||||||
# Test allowed characters
|
# Test allowed characters
|
||||||
with pytest.raises(ArgumentError):
|
with pytest.raises(ArgumentError):
|
||||||
userq.create(db, **{**kwargs, 'username': 'user name'})
|
userq.create(db, **{**kwargs, 'username': 'user name'})
|
||||||
|
|
Loading…
Reference in New Issue