black string quote normalization
This commit is contained in:
parent
de09030b1c
commit
2982f6ea0f
@ -14,11 +14,11 @@ def create(db: DbContext, lexicon_id: int, user_id: int, character_id: int) -> A
|
||||
"""
|
||||
# Verify argument types are correct
|
||||
if not isinstance(lexicon_id, int):
|
||||
raise ArgumentError('lexicon_id')
|
||||
raise ArgumentError("lexicon_id")
|
||||
if not isinstance(user_id, int):
|
||||
raise ArgumentError('user_id')
|
||||
raise ArgumentError("user_id")
|
||||
if character_id is not None and not isinstance(character_id, int):
|
||||
raise ArgumentError('character_id')
|
||||
raise ArgumentError("character_id")
|
||||
|
||||
# Check that the user is a member of this lexicon
|
||||
mem: Membership = db(
|
||||
@ -27,7 +27,7 @@ def create(db: DbContext, lexicon_id: int, user_id: int, character_id: int) -> A
|
||||
.where(Membership.lexicon_id == lexicon_id)
|
||||
).scalar_one_or_none()
|
||||
if not mem:
|
||||
raise ArgumentError('User is not a member of lexicon')
|
||||
raise ArgumentError("User is not a member of lexicon")
|
||||
|
||||
# If the character id is provided, check that the user owns the character
|
||||
# and the character belongs to the lexicon
|
||||
@ -36,21 +36,21 @@ def create(db: DbContext, lexicon_id: int, user_id: int, character_id: int) -> A
|
||||
select(Character).where(Character.id == character_id)
|
||||
).scalar_one_or_none()
|
||||
if not character:
|
||||
raise ArgumentError('Character does not exist')
|
||||
raise ArgumentError("Character does not exist")
|
||||
if character.user.id != user_id:
|
||||
raise ArgumentError('Character is owned by the wrong player')
|
||||
raise ArgumentError("Character is owned by the wrong player")
|
||||
if character.lexicon.id != lexicon_id:
|
||||
raise ArgumentError('Character belongs to the wrong lexicon')
|
||||
raise ArgumentError("Character belongs to the wrong lexicon")
|
||||
signature = character.signature
|
||||
else:
|
||||
signature = '~Ersatz Scrivener'
|
||||
signature = "~Ersatz Scrivener"
|
||||
|
||||
new_article = Article(
|
||||
lexicon_id=lexicon_id,
|
||||
user_id=user_id,
|
||||
character_id=character_id,
|
||||
title='Article title',
|
||||
body=f'\n\n{signature}',
|
||||
title="Article title",
|
||||
body=f"\n\n{signature}",
|
||||
)
|
||||
db.session.add(new_article)
|
||||
db.session.commit()
|
||||
|
@ -16,21 +16,21 @@ def create(
|
||||
"""
|
||||
# Verify argument types are correct
|
||||
if not isinstance(lexicon_id, int):
|
||||
raise ArgumentError('lexicon_id')
|
||||
raise ArgumentError("lexicon_id")
|
||||
if not isinstance(user_id, int):
|
||||
raise ArgumentError('user_id')
|
||||
raise ArgumentError("user_id")
|
||||
if not isinstance(name, str):
|
||||
raise ArgumentError('name')
|
||||
raise ArgumentError("name")
|
||||
if signature is not None and not isinstance(signature, str):
|
||||
raise ArgumentError('signature')
|
||||
raise ArgumentError("signature")
|
||||
|
||||
# Verify character name is valid
|
||||
if not name.strip():
|
||||
raise ArgumentError('Character name cannot be blank')
|
||||
raise ArgumentError("Character name cannot be blank")
|
||||
|
||||
# If no signature is provided, use a default signature
|
||||
if not signature or not signature.strip():
|
||||
signature = f'~{name}'
|
||||
signature = f"~{name}"
|
||||
|
||||
# Check that the user is a member of this lexicon
|
||||
mem: Membership = db(
|
||||
@ -39,7 +39,7 @@ def create(
|
||||
.where(Membership.lexicon_id == lexicon_id)
|
||||
).scalar_one_or_none()
|
||||
if not mem:
|
||||
raise ArgumentError('User is not a member of lexicon')
|
||||
raise ArgumentError("User is not a member of lexicon")
|
||||
|
||||
# Check that this user is below the limit for creating characters
|
||||
num_user_chars = db(
|
||||
@ -51,7 +51,7 @@ def create(
|
||||
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(
|
||||
lexicon_id=lexicon_id,
|
||||
|
@ -10,7 +10,7 @@ from amanuensis.db import DbContext, Lexicon
|
||||
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(db: DbContext, name: str, title: str, prompt: str) -> Lexicon:
|
||||
@ -19,25 +19,25 @@ def create(db: DbContext, name: str, title: str, prompt: str) -> Lexicon:
|
||||
"""
|
||||
# Verify name
|
||||
if not isinstance(name, str):
|
||||
raise ArgumentError('Lexicon name must be a string')
|
||||
raise ArgumentError("Lexicon name must be a string")
|
||||
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):
|
||||
raise ArgumentError(
|
||||
'Lexicon name may only contain alphanumerics, dash, and underscore'
|
||||
"Lexicon name may only contain alphanumerics, dash, and underscore"
|
||||
)
|
||||
|
||||
# Verify title
|
||||
if title is not None and not isinstance(name, str):
|
||||
raise ArgumentError('Lexicon name must be a string')
|
||||
raise ArgumentError("Lexicon name must be a string")
|
||||
|
||||
# Verify prompt
|
||||
if not isinstance(prompt, str):
|
||||
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
|
||||
if db(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(
|
||||
name=name,
|
||||
|
@ -14,11 +14,11 @@ def create(db: DbContext, user_id: int, lexicon_id: int, is_editor: bool) -> Mem
|
||||
"""
|
||||
# Verify argument types are correct
|
||||
if not isinstance(user_id, int):
|
||||
raise ArgumentError('user_id')
|
||||
raise ArgumentError("user_id")
|
||||
if not isinstance(lexicon_id, int):
|
||||
raise ArgumentError('lexicon_id')
|
||||
raise ArgumentError("lexicon_id")
|
||||
if not isinstance(is_editor, bool):
|
||||
raise ArgumentError('is_editor')
|
||||
raise ArgumentError("is_editor")
|
||||
|
||||
# Verify user has not already joined lexicon
|
||||
if (
|
||||
@ -29,7 +29,7 @@ def create(db: DbContext, user_id: int, lexicon_id: int, is_editor: bool) -> Mem
|
||||
).scalar()
|
||||
> 0
|
||||
):
|
||||
raise ArgumentError('User is already a member of lexicon')
|
||||
raise ArgumentError("User is already a member of lexicon")
|
||||
|
||||
new_membership = Membership(
|
||||
user_id=user_id,
|
||||
|
@ -17,17 +17,17 @@ def create(db: DbContext, lexicon_id: int, user_id: int, body: str) -> Post:
|
||||
|
||||
# Verify lexicon id
|
||||
if not isinstance(lexicon_id, int):
|
||||
raise ArgumentError('Lexicon id must be an integer.')
|
||||
raise ArgumentError("Lexicon id must be an integer.")
|
||||
|
||||
# Verify user_id
|
||||
if not (isinstance(user_id, int) or user_id is None):
|
||||
raise ArgumentError('User id must be an integer.')
|
||||
raise ArgumentError("User id must be an integer.")
|
||||
|
||||
# Verify body
|
||||
if not isinstance(body, str):
|
||||
raise ArgumentError('Post body must be a string.')
|
||||
raise ArgumentError("Post body must be a string.")
|
||||
if not body.strip():
|
||||
raise ArgumentError('Post body cannot be empty.')
|
||||
raise ArgumentError("Post body cannot be empty.")
|
||||
|
||||
new_post = Post(lexicon_id=lexicon_id, user_id=user_id, body=body)
|
||||
db.session.add(new_post)
|
||||
|
@ -11,8 +11,8 @@ from amanuensis.db import DbContext, User
|
||||
from amanuensis.errors import ArgumentError
|
||||
|
||||
|
||||
RE_NO_LETTERS = re.compile(r'^[0-9-_]*$')
|
||||
RE_ALPHANUM_DASH_UNDER = re.compile(r'^[A-Za-z0-9-_]*$')
|
||||
RE_NO_LETTERS = re.compile(r"^[0-9-_]*$")
|
||||
RE_ALPHANUM_DASH_UNDER = re.compile(r"^[A-Za-z0-9-_]*$")
|
||||
|
||||
|
||||
def create(
|
||||
@ -28,34 +28,34 @@ def create(
|
||||
"""
|
||||
# Verify username
|
||||
if not isinstance(username, str):
|
||||
raise ArgumentError('Username must be a string')
|
||||
raise ArgumentError("Username must be a string")
|
||||
if len(username) < 3 or len(username) > 32:
|
||||
raise ArgumentError('Username must be between 3 and 32 characters')
|
||||
raise ArgumentError("Username must be between 3 and 32 characters")
|
||||
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):
|
||||
raise ArgumentError(
|
||||
'Username may only contain alphanumerics, dash, and underscore'
|
||||
"Username may only contain alphanumerics, dash, and underscore"
|
||||
)
|
||||
|
||||
# Verify password
|
||||
if not isinstance(password, str):
|
||||
raise ArgumentError('Password must be a string')
|
||||
raise ArgumentError("Password must be a string")
|
||||
|
||||
# Verify display name
|
||||
if display_name is not None and not isinstance(display_name, str):
|
||||
raise ArgumentError('Display name must be a string')
|
||||
raise ArgumentError("Display name must be a string")
|
||||
# If display name is not provided, use the username
|
||||
if not display_name or not display_name.strip():
|
||||
display_name = username
|
||||
|
||||
# Verify email
|
||||
if not isinstance(email, str):
|
||||
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
|
||||
if db(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(
|
||||
username=username,
|
||||
|
@ -15,17 +15,17 @@ from .models import (
|
||||
)
|
||||
|
||||
__all__ = [
|
||||
'DbContext',
|
||||
'User',
|
||||
'Lexicon',
|
||||
'Membership',
|
||||
'Character',
|
||||
'ArticleState',
|
||||
'Article',
|
||||
'IndexType',
|
||||
'ArticleIndex',
|
||||
'ArticleIndexRule',
|
||||
'ArticleContentRuleType',
|
||||
'ArticleContentRule',
|
||||
'Post',
|
||||
"DbContext",
|
||||
"User",
|
||||
"Lexicon",
|
||||
"Membership",
|
||||
"Character",
|
||||
"ArticleState",
|
||||
"Article",
|
||||
"IndexType",
|
||||
"ArticleIndex",
|
||||
"ArticleIndexRule",
|
||||
"ArticleContentRuleType",
|
||||
"ArticleContentRule",
|
||||
"Post",
|
||||
]
|
||||
|
@ -35,9 +35,9 @@ class Uuid(TypeDecorator):
|
||||
if value is None:
|
||||
return value
|
||||
elif not isinstance(value, uuid.UUID):
|
||||
return f'{uuid.UUID(value).int:32x}'
|
||||
return f"{uuid.UUID(value).int:32x}"
|
||||
else:
|
||||
return f'{value.int:32x}'
|
||||
return f"{value.int:32x}"
|
||||
|
||||
def process_result_value(self, value, dialect):
|
||||
if value is None:
|
||||
@ -53,7 +53,7 @@ class User(ModelBase):
|
||||
Represents a single user of Amanuensis.
|
||||
"""
|
||||
|
||||
__tablename__ = 'user'
|
||||
__tablename__ = "user"
|
||||
|
||||
#############
|
||||
# User info #
|
||||
@ -75,14 +75,14 @@ class User(ModelBase):
|
||||
email = Column(String, nullable=False)
|
||||
|
||||
# Whether the user can access site admin functions
|
||||
is_site_admin = Column(Boolean, nullable=False, server_default=text('FALSE'))
|
||||
is_site_admin = Column(Boolean, nullable=False, server_default=text("FALSE"))
|
||||
|
||||
####################
|
||||
# History tracking #
|
||||
####################
|
||||
|
||||
# The timestamp the user was created
|
||||
created = Column(DateTime, nullable=False, server_default=text('CURRENT_TIMESTAMP'))
|
||||
created = Column(DateTime, nullable=False, server_default=text("CURRENT_TIMESTAMP"))
|
||||
|
||||
# The timestamp the user last logged in
|
||||
# This is NULL if the user has never logged in
|
||||
@ -96,10 +96,10 @@ class User(ModelBase):
|
||||
# Foreign key relationships #
|
||||
#############################
|
||||
|
||||
memberships = relationship('Membership', back_populates='user')
|
||||
characters = relationship('Character', back_populates='user')
|
||||
articles = relationship('Article', back_populates='user')
|
||||
posts = relationship('Post', back_populates='user')
|
||||
memberships = relationship("Membership", back_populates="user")
|
||||
characters = relationship("Character", back_populates="user")
|
||||
articles = relationship("Article", back_populates="user")
|
||||
posts = relationship("Post", back_populates="user")
|
||||
|
||||
|
||||
class Lexicon(ModelBase):
|
||||
@ -107,7 +107,7 @@ class Lexicon(ModelBase):
|
||||
Represents a single game of Lexicon.
|
||||
"""
|
||||
|
||||
__tablename__ = 'lexicon'
|
||||
__tablename__ = "lexicon"
|
||||
|
||||
#############
|
||||
# Game info #
|
||||
@ -131,11 +131,11 @@ class Lexicon(ModelBase):
|
||||
####################
|
||||
|
||||
# The timestamp the lexicon was created
|
||||
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
|
||||
last_updated = Column(
|
||||
DateTime, nullable=False, server_default=text('CURRENT_TIMESTAMP')
|
||||
DateTime, nullable=False, server_default=text("CURRENT_TIMESTAMP")
|
||||
)
|
||||
|
||||
# The timestamp the first turn was started
|
||||
@ -226,13 +226,13 @@ class Lexicon(ModelBase):
|
||||
# Foreign key relationships #
|
||||
#############################
|
||||
|
||||
memberships = relationship('Membership', back_populates='lexicon')
|
||||
characters = relationship('Character', back_populates='lexicon')
|
||||
articles = relationship('Article', back_populates='lexicon')
|
||||
indexes = relationship('ArticleIndex', back_populates='lexicon')
|
||||
index_rules = relationship('ArticleIndexRule', back_populates='lexicon')
|
||||
content_rules = relationship('ArticleContentRule', back_populates='lexicon')
|
||||
posts = relationship('Post', back_populates='lexicon')
|
||||
memberships = relationship("Membership", back_populates="lexicon")
|
||||
characters = relationship("Character", back_populates="lexicon")
|
||||
articles = relationship("Article", back_populates="lexicon")
|
||||
indexes = relationship("ArticleIndex", back_populates="lexicon")
|
||||
index_rules = relationship("ArticleIndexRule", back_populates="lexicon")
|
||||
content_rules = relationship("ArticleContentRule", back_populates="lexicon")
|
||||
posts = relationship("Post", back_populates="lexicon")
|
||||
|
||||
|
||||
class Membership(ModelBase):
|
||||
@ -240,8 +240,8 @@ class Membership(ModelBase):
|
||||
Represents a user's participation in a Lexicon game.
|
||||
"""
|
||||
|
||||
__tablename__ = 'membership'
|
||||
__table_args__ = (UniqueConstraint('user_id', 'lexicon_id'),)
|
||||
__tablename__ = "membership"
|
||||
__table_args__ = (UniqueConstraint("user_id", "lexicon_id"),)
|
||||
|
||||
###################
|
||||
# Membership keys #
|
||||
@ -251,17 +251,17 @@ class Membership(ModelBase):
|
||||
id = Column(Integer, primary_key=True)
|
||||
|
||||
# The user who is a member of a lexicon
|
||||
user_id = Column(Integer, ForeignKey('user.id'), nullable=False)
|
||||
user_id = Column(Integer, ForeignKey("user.id"), nullable=False)
|
||||
|
||||
# The lexicon of which the user is a member
|
||||
lexicon_id = Column(Integer, ForeignKey('lexicon.id'), nullable=False)
|
||||
lexicon_id = Column(Integer, ForeignKey("lexicon.id"), nullable=False)
|
||||
|
||||
####################
|
||||
# History tracking #
|
||||
####################
|
||||
|
||||
# Timestamp the user joined the game
|
||||
joined = Column(DateTime, nullable=False, server_default=text('CURRENT_TIMESTAMP'))
|
||||
joined = Column(DateTime, nullable=False, server_default=text("CURRENT_TIMESTAMP"))
|
||||
|
||||
# Timestamp of the last time the user viewed the post feed
|
||||
# This is NULL if the player has never viewed posts
|
||||
@ -272,7 +272,7 @@ class Membership(ModelBase):
|
||||
###################
|
||||
|
||||
# Whether the user can access editor functions
|
||||
is_editor = Column(Boolean, nullable=False, server_default=text('FALSE'))
|
||||
is_editor = Column(Boolean, nullable=False, server_default=text("FALSE"))
|
||||
|
||||
#########################
|
||||
# Notification settings #
|
||||
@ -291,8 +291,8 @@ class Membership(ModelBase):
|
||||
# Foreign key relationships #
|
||||
#############################
|
||||
|
||||
user = relationship('User', back_populates='memberships')
|
||||
lexicon = relationship('Lexicon', back_populates='memberships')
|
||||
user = relationship("User", back_populates="memberships")
|
||||
lexicon = relationship("Lexicon", back_populates="memberships")
|
||||
|
||||
|
||||
class Character(ModelBase):
|
||||
@ -300,7 +300,7 @@ class Character(ModelBase):
|
||||
Represents a character played by a uaser in a Lexicon game.
|
||||
"""
|
||||
|
||||
__tablename__ = 'character'
|
||||
__tablename__ = "character"
|
||||
|
||||
##################
|
||||
# Character info #
|
||||
@ -313,10 +313,10 @@ class Character(ModelBase):
|
||||
public_id = Column(Uuid, nullable=False, unique=True, default=uuid.uuid4)
|
||||
|
||||
# The lexicon to which this character belongs
|
||||
lexicon_id = Column(Integer, ForeignKey('lexicon.id'), nullable=False)
|
||||
lexicon_id = Column(Integer, ForeignKey("lexicon.id"), nullable=False)
|
||||
|
||||
# The user to whom this character belongs
|
||||
user_id = Column(Integer, ForeignKey('user.id'), nullable=False)
|
||||
user_id = Column(Integer, ForeignKey("user.id"), nullable=False)
|
||||
|
||||
# The character's name
|
||||
name = Column(String, nullable=False)
|
||||
@ -328,10 +328,10 @@ class Character(ModelBase):
|
||||
# Foreign key relationships #
|
||||
#############################
|
||||
|
||||
user = relationship('User', back_populates='characters')
|
||||
lexicon = relationship('Lexicon', back_populates='characters')
|
||||
articles = relationship('Article', back_populates='character')
|
||||
index_rules = relationship('ArticleIndexRule', back_populates='character')
|
||||
user = relationship("User", back_populates="characters")
|
||||
lexicon = relationship("Lexicon", back_populates="characters")
|
||||
articles = relationship("Article", back_populates="character")
|
||||
index_rules = relationship("ArticleIndexRule", back_populates="character")
|
||||
|
||||
|
||||
class ArticleState(enum.Enum):
|
||||
@ -349,7 +349,7 @@ class Article(ModelBase):
|
||||
Represents a single article in a lexicon.
|
||||
"""
|
||||
|
||||
__tablename__ = 'article'
|
||||
__tablename__ = "article"
|
||||
|
||||
################
|
||||
# Article info #
|
||||
@ -362,17 +362,17 @@ class Article(ModelBase):
|
||||
public_id = Column(Uuid, nullable=False, unique=True, default=uuid.uuid4)
|
||||
|
||||
# The lexicon to which this article belongs
|
||||
lexicon_id = Column(Integer, ForeignKey('lexicon.id'), nullable=False)
|
||||
lexicon_id = Column(Integer, ForeignKey("lexicon.id"), nullable=False)
|
||||
|
||||
# The character who is the author of this article
|
||||
# If this is NULL, the article is written by Ersatz Scrivener
|
||||
character_id = Column(Integer, ForeignKey('character.id'), nullable=True)
|
||||
character_id = Column(Integer, ForeignKey("character.id"), nullable=True)
|
||||
|
||||
# The user who owns this article
|
||||
user_id = Column(Integer, ForeignKey('user.id'), nullable=False)
|
||||
user_id = Column(Integer, ForeignKey("user.id"), nullable=False)
|
||||
|
||||
# The article to which this is an addendum
|
||||
addendum_to = Column(Integer, ForeignKey('article.id'), nullable=True)
|
||||
addendum_to = Column(Integer, ForeignKey("article.id"), nullable=True)
|
||||
|
||||
#################
|
||||
# Article state #
|
||||
@ -394,7 +394,7 @@ class Article(ModelBase):
|
||||
|
||||
# Timestamp the content of the article was last updated
|
||||
last_updated = Column(
|
||||
DateTime, nullable=False, server_default=text('CURRENT_TIMESTAMP')
|
||||
DateTime, nullable=False, server_default=text("CURRENT_TIMESTAMP")
|
||||
)
|
||||
|
||||
# Timestamp the article was last submitted
|
||||
@ -419,10 +419,10 @@ class Article(ModelBase):
|
||||
# Foreign key relationships #
|
||||
#############################
|
||||
|
||||
lexicon = relationship('Lexicon', back_populates='articles')
|
||||
character = relationship('Character', back_populates='articles')
|
||||
user = relationship('User', back_populates='articles')
|
||||
addenda = relationship('Article', backref=backref('parent', remote_side=[id]))
|
||||
lexicon = relationship("Lexicon", back_populates="articles")
|
||||
character = relationship("Character", back_populates="articles")
|
||||
user = relationship("User", back_populates="articles")
|
||||
addenda = relationship("Article", backref=backref("parent", remote_side=[id]))
|
||||
|
||||
|
||||
class IndexType(enum.Enum):
|
||||
@ -441,7 +441,7 @@ class ArticleIndex(ModelBase):
|
||||
Represents an index definition.
|
||||
"""
|
||||
|
||||
__tablename__ = 'article_index'
|
||||
__tablename__ = "article_index"
|
||||
|
||||
##############
|
||||
# Index info #
|
||||
@ -451,7 +451,7 @@ class ArticleIndex(ModelBase):
|
||||
id = Column(Integer, primary_key=True)
|
||||
|
||||
# The lexicon this index is in
|
||||
lexicon_id = Column(Integer, ForeignKey('lexicon.id'), nullable=False)
|
||||
lexicon_id = Column(Integer, ForeignKey("lexicon.id"), nullable=False)
|
||||
|
||||
# The index type
|
||||
index_type = Column(Enum(IndexType), nullable=False)
|
||||
@ -473,8 +473,8 @@ class ArticleIndex(ModelBase):
|
||||
# Foreign key relationships #
|
||||
#############################
|
||||
|
||||
lexicon = relationship('Lexicon', back_populates='indexes')
|
||||
index_rules = relationship('ArticleIndexRule', back_populates='index')
|
||||
lexicon = relationship("Lexicon", back_populates="indexes")
|
||||
index_rules = relationship("ArticleIndexRule", back_populates="index")
|
||||
|
||||
|
||||
class ArticleIndexRule(ModelBase):
|
||||
@ -484,7 +484,7 @@ class ArticleIndexRule(ModelBase):
|
||||
a rule. A character with no index rules may write in any index.
|
||||
"""
|
||||
|
||||
__tablename__ = 'article_index_rule'
|
||||
__tablename__ = "article_index_rule"
|
||||
|
||||
###################
|
||||
# Index rule info #
|
||||
@ -494,17 +494,17 @@ class ArticleIndexRule(ModelBase):
|
||||
id = Column(Integer, primary_key=True)
|
||||
|
||||
# The lexicon of this index rule
|
||||
lexicon_id = Column(Integer, ForeignKey('lexicon.id'), nullable=False)
|
||||
lexicon_id = Column(Integer, ForeignKey("lexicon.id"), nullable=False)
|
||||
|
||||
####################
|
||||
# Index rule scope #
|
||||
####################
|
||||
|
||||
# The character to whom this rule applies
|
||||
character_id = Column(Integer, ForeignKey('character.id'), nullable=False)
|
||||
character_id = Column(Integer, ForeignKey("character.id"), nullable=False)
|
||||
|
||||
# The index to which the character is restricted
|
||||
index_id = Column(Integer, ForeignKey('article_index.id'), nullable=False)
|
||||
index_id = Column(Integer, ForeignKey("article_index.id"), nullable=False)
|
||||
|
||||
# The turn in which this rule applies
|
||||
turn = Column(Integer, nullable=False)
|
||||
@ -513,9 +513,9 @@ class ArticleIndexRule(ModelBase):
|
||||
# Foreign key relationships #
|
||||
#############################
|
||||
|
||||
lexicon = relationship('Lexicon', back_populates='index_rules')
|
||||
index = relationship('ArticleIndex', back_populates='index_rules')
|
||||
character = relationship('Character', back_populates='index_rules')
|
||||
lexicon = relationship("Lexicon", back_populates="index_rules")
|
||||
index = relationship("ArticleIndex", back_populates="index_rules")
|
||||
character = relationship("Character", back_populates="index_rules")
|
||||
|
||||
|
||||
class ArticleContentRuleType(enum.Enum):
|
||||
@ -557,7 +557,7 @@ class ArticleContentRule(ModelBase):
|
||||
Represents a restriction on the content of an article for a turn.
|
||||
"""
|
||||
|
||||
__tablename__ = 'article_content_rule'
|
||||
__tablename__ = "article_content_rule"
|
||||
|
||||
#####################
|
||||
# Content rule info #
|
||||
@ -567,7 +567,7 @@ class ArticleContentRule(ModelBase):
|
||||
id = Column(Integer, primary_key=True)
|
||||
|
||||
# The lexicon of this content rule
|
||||
lexicon_id = Column(Integer, ForeignKey('lexicon.id'), nullable=False)
|
||||
lexicon_id = Column(Integer, ForeignKey("lexicon.id"), nullable=False)
|
||||
|
||||
######################
|
||||
# Content rule scope #
|
||||
@ -591,7 +591,7 @@ class ArticleContentRule(ModelBase):
|
||||
# Foreign key relationships #
|
||||
#############################
|
||||
|
||||
lexicon = relationship('Lexicon', back_populates='content_rules')
|
||||
lexicon = relationship("Lexicon", back_populates="content_rules")
|
||||
|
||||
|
||||
class Post(ModelBase):
|
||||
@ -599,7 +599,7 @@ class Post(ModelBase):
|
||||
Represents a post in the game feed.
|
||||
"""
|
||||
|
||||
__tablename__ = 'post'
|
||||
__tablename__ = "post"
|
||||
|
||||
#############
|
||||
# Post info #
|
||||
@ -609,18 +609,18 @@ class Post(ModelBase):
|
||||
id = Column(Integer, primary_key=True)
|
||||
|
||||
# The lexicon in which the post was made
|
||||
lexicon_id = Column(Integer, ForeignKey('lexicon.id'), nullable=False)
|
||||
lexicon_id = Column(Integer, ForeignKey("lexicon.id"), nullable=False)
|
||||
|
||||
# The user who made the post
|
||||
# This may be NULL if the post was made by Amanuensis
|
||||
user_id = Column(Integer, ForeignKey('user.id'), nullable=True)
|
||||
user_id = Column(Integer, ForeignKey("user.id"), nullable=True)
|
||||
|
||||
################
|
||||
# Post content #
|
||||
################
|
||||
|
||||
# The timestamp the post was created
|
||||
created = Column(DateTime, nullable=False, server_default=text('CURRENT_TIMESTAMP'))
|
||||
created = Column(DateTime, nullable=False, server_default=text("CURRENT_TIMESTAMP"))
|
||||
|
||||
# The body of the post
|
||||
body = Column(Text, nullable=False)
|
||||
@ -629,5 +629,5 @@ class Post(ModelBase):
|
||||
# Foreign key relationships #
|
||||
#############################
|
||||
|
||||
user = relationship('User', back_populates='posts')
|
||||
lexicon = relationship('Lexicon', back_populates='posts')
|
||||
user = relationship("User", back_populates="posts")
|
||||
lexicon = relationship("Lexicon", back_populates="posts")
|
||||
|
@ -16,7 +16,6 @@ pytest = "^5.2"
|
||||
black = "^21.5b2"
|
||||
|
||||
[tool.black]
|
||||
skip-string-normalization = true
|
||||
extend-exclude = '''
|
||||
^/amanuensis/cli/.*|
|
||||
^/amanuensis/config/.*|
|
||||
|
@ -13,7 +13,7 @@ import amanuensis.backend.user as userq
|
||||
@pytest.fixture
|
||||
def db():
|
||||
"""Provides an initialized database in memory."""
|
||||
db = DbContext('sqlite:///:memory:', debug=False)
|
||||
db = DbContext("sqlite:///:memory:", debug=False)
|
||||
db.create_all()
|
||||
return db
|
||||
|
||||
@ -22,15 +22,15 @@ def db():
|
||||
def make_user(db: DbContext):
|
||||
"""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 = {
|
||||
'username': f'test_user_{state["nonce"]}',
|
||||
'password': 'password',
|
||||
'display_name': None,
|
||||
'email': 'user@example.com',
|
||||
'is_site_admin': False,
|
||||
"username": f'test_user_{state["nonce"]}',
|
||||
"password": "password",
|
||||
"display_name": None,
|
||||
"email": "user@example.com",
|
||||
"is_site_admin": False,
|
||||
}
|
||||
state['nonce'] += 1
|
||||
state["nonce"] += 1
|
||||
updated_kwargs = {**default_kwargs, **kwargs}
|
||||
return userq.create(db, **updated_kwargs)
|
||||
|
||||
@ -41,13 +41,13 @@ def make_user(db: DbContext):
|
||||
def make_lexicon(db: DbContext):
|
||||
"""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 = {
|
||||
'name': f'Test_{state["nonce"]}',
|
||||
'title': None,
|
||||
'prompt': f'Test Lexicon game {state["nonce"]}',
|
||||
"name": f'Test_{state["nonce"]}',
|
||||
"title": None,
|
||||
"prompt": f'Test Lexicon game {state["nonce"]}',
|
||||
}
|
||||
state['nonce'] += 1
|
||||
state["nonce"] += 1
|
||||
updated_kwargs = {**default_kwargs, **kwargs}
|
||||
return lexiq.create(db, **updated_kwargs)
|
||||
|
||||
@ -60,7 +60,7 @@ def make_membership(db: DbContext):
|
||||
|
||||
def membership_factory(**kwargs):
|
||||
default_kwargs = {
|
||||
'is_editor': False,
|
||||
"is_editor": False,
|
||||
}
|
||||
updated_kwargs = {**default_kwargs, **kwargs}
|
||||
return memq.create(db, **updated_kwargs)
|
||||
@ -72,12 +72,12 @@ def make_membership(db: DbContext):
|
||||
def make_character(db: DbContext):
|
||||
"""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 = {
|
||||
'name': f'Character {state["nonce"]}',
|
||||
'signature': None,
|
||||
"name": f'Character {state["nonce"]}',
|
||||
"signature": None,
|
||||
}
|
||||
state['nonce'] += 1
|
||||
state["nonce"] += 1
|
||||
updated_kwargs = {**default_kwargs, **kwargs}
|
||||
return charq.create(db, **updated_kwargs)
|
||||
|
||||
|
@ -9,33 +9,33 @@ def test_create_character(db: DbContext, lexicon_with_editor, make):
|
||||
"""Test creating a character."""
|
||||
lexicon, user = lexicon_with_editor
|
||||
kwargs = {
|
||||
'db': db,
|
||||
'user_id': user.id,
|
||||
'lexicon_id': lexicon.id,
|
||||
'name': 'Character Name',
|
||||
'signature': 'Signature',
|
||||
"db": db,
|
||||
"user_id": user.id,
|
||||
"lexicon_id": lexicon.id,
|
||||
"name": "Character Name",
|
||||
"signature": "Signature",
|
||||
}
|
||||
|
||||
# Bad argument types
|
||||
with pytest.raises(ArgumentError):
|
||||
charq.create(**{**kwargs, 'name': b'bytestring'})
|
||||
charq.create(**{**kwargs, "name": b"bytestring"})
|
||||
with pytest.raises(ArgumentError):
|
||||
charq.create(**{**kwargs, 'name': None})
|
||||
charq.create(**{**kwargs, "name": None})
|
||||
with pytest.raises(ArgumentError):
|
||||
charq.create(**{**kwargs, 'signature': b'bytestring'})
|
||||
charq.create(**{**kwargs, "signature": b"bytestring"})
|
||||
|
||||
# Bad character name
|
||||
with pytest.raises(ArgumentError):
|
||||
charq.create(**{**kwargs, 'name': ' '})
|
||||
charq.create(**{**kwargs, "name": " "})
|
||||
|
||||
# Signature is auto-populated
|
||||
char = charq.create(**{**kwargs, 'signature': None})
|
||||
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})
|
||||
charq.create(**{**kwargs, "user_id": new_user.id})
|
||||
|
||||
|
||||
def test_character_limits(db: DbContext, lexicon_with_editor):
|
||||
@ -47,31 +47,31 @@ def test_character_limits(db: DbContext, 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'
|
||||
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
|
||||
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'
|
||||
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
|
||||
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()
|
||||
char3 = charq.create(db, lexicon.id, user.id, 'Test Character 3', signature=None)
|
||||
assert char3.id, 'Failed to create character 3'
|
||||
char3 = charq.create(db, lexicon.id, user.id, "Test Character 3", signature=None)
|
||||
assert char3.id, "Failed to create character 3"
|
||||
|
@ -9,20 +9,20 @@ from amanuensis.errors import ArgumentError
|
||||
|
||||
def test_create_lexicon(db: DbContext):
|
||||
"""Test new game creation."""
|
||||
kwargs = {'name': 'Test', 'title': None, 'prompt': 'A test Lexicon game'}
|
||||
kwargs = {"name": "Test", "title": None, "prompt": "A test Lexicon game"}
|
||||
# Test name constraints
|
||||
with pytest.raises(ArgumentError):
|
||||
lexiq.create(db, **{**kwargs, 'name': None})
|
||||
lexiq.create(db, **{**kwargs, "name": None})
|
||||
with pytest.raises(ArgumentError):
|
||||
lexiq.create(db, **{**kwargs, 'name': ''})
|
||||
lexiq.create(db, **{**kwargs, "name": ""})
|
||||
with pytest.raises(ArgumentError):
|
||||
lexiq.create(db, **{**kwargs, 'name': ' '})
|
||||
lexiq.create(db, **{**kwargs, "name": " "})
|
||||
with pytest.raises(ArgumentError):
|
||||
lexiq.create(db, **{**kwargs, 'name': '..'})
|
||||
lexiq.create(db, **{**kwargs, "name": ".."})
|
||||
with pytest.raises(ArgumentError):
|
||||
lexiq.create(db, **{**kwargs, 'name': '\x00'})
|
||||
lexiq.create(db, **{**kwargs, "name": "\x00"})
|
||||
with pytest.raises(ArgumentError):
|
||||
lexiq.create(db, **{**kwargs, 'name': 'space in name'})
|
||||
lexiq.create(db, **{**kwargs, "name": "space in name"})
|
||||
|
||||
# Validate that creation populates fields, including timestamps
|
||||
before = datetime.datetime.utcnow() - datetime.timedelta(seconds=1)
|
||||
|
@ -11,13 +11,13 @@ def test_create_membership(db: DbContext, make):
|
||||
"""Test joining a game."""
|
||||
# Set up a user and a lexicon
|
||||
new_user = make.user()
|
||||
assert new_user.id, 'Failed to create user'
|
||||
assert new_user.id, "Failed to create user"
|
||||
new_lexicon = make.lexicon()
|
||||
assert new_lexicon.id, 'Failed to create lexicon'
|
||||
assert new_lexicon.id, "Failed to create lexicon"
|
||||
|
||||
# Add the user to the lexicon as an editor
|
||||
mem = memq.create(db, new_user.id, new_lexicon.id, True)
|
||||
assert mem, 'Failed to create membership'
|
||||
assert mem, "Failed to create membership"
|
||||
|
||||
# Check that the user and lexicon are mutually visible in the ORM relationships
|
||||
assert any(map(lambda mem: mem.lexicon == new_lexicon, new_user.memberships))
|
||||
|
@ -11,25 +11,25 @@ def test_create_post(db: DbContext, lexicon_with_editor):
|
||||
lexicon, editor = lexicon_with_editor
|
||||
|
||||
# argument dictionary for post object
|
||||
kwargs = {'lexicon_id': lexicon.id, 'user_id': editor.id, 'body': 'body'}
|
||||
kwargs = {"lexicon_id": lexicon.id, "user_id": editor.id, "body": "body"}
|
||||
|
||||
# ids are integers
|
||||
with pytest.raises(ArgumentError):
|
||||
postq.create(db, **{**kwargs, 'user_id': 'zero'})
|
||||
postq.create(db, **{**kwargs, "user_id": "zero"})
|
||||
with pytest.raises(ArgumentError):
|
||||
postq.create(db, **{**kwargs, 'lexicon_id': 'zero'})
|
||||
postq.create(db, **{**kwargs, "lexicon_id": "zero"})
|
||||
|
||||
# empty arguments don't work
|
||||
with pytest.raises(ArgumentError):
|
||||
postq.create(db, **{**kwargs, 'lexicon_id': ''})
|
||||
postq.create(db, **{**kwargs, "lexicon_id": ""})
|
||||
with pytest.raises(ArgumentError):
|
||||
postq.create(db, **{**kwargs, 'user_id': ''})
|
||||
postq.create(db, **{**kwargs, "user_id": ""})
|
||||
with pytest.raises(ArgumentError):
|
||||
postq.create(db, **{**kwargs, 'body': ''})
|
||||
postq.create(db, **{**kwargs, "body": ""})
|
||||
|
||||
# post with only whitespace doesn't work
|
||||
with pytest.raises(ArgumentError):
|
||||
postq.create(db, **{**kwargs, 'body': ' '})
|
||||
postq.create(db, **{**kwargs, "body": " "})
|
||||
|
||||
# post creation works and populates fields
|
||||
new_post = postq.create(db, **kwargs)
|
||||
@ -39,6 +39,6 @@ def test_create_post(db: DbContext, lexicon_with_editor):
|
||||
assert new_post.body is not None
|
||||
|
||||
# post creation works when user is None
|
||||
new_post = postq.create(db, **{**kwargs, 'user_id': None})
|
||||
new_post = postq.create(db, **{**kwargs, "user_id": None})
|
||||
assert new_post
|
||||
assert new_post.user_id is None
|
||||
|
@ -8,26 +8,26 @@ from amanuensis.errors import ArgumentError
|
||||
def test_create_user(db: DbContext):
|
||||
"""Test new user creation."""
|
||||
kwargs = {
|
||||
'username': 'username',
|
||||
'password': 'password',
|
||||
'display_name': 'User Name',
|
||||
'email': 'user@example.com',
|
||||
'is_site_admin': False,
|
||||
"username": "username",
|
||||
"password": "password",
|
||||
"display_name": "User Name",
|
||||
"email": "user@example.com",
|
||||
"is_site_admin": False,
|
||||
}
|
||||
|
||||
# Test length constraints
|
||||
with pytest.raises(ArgumentError):
|
||||
userq.create(db, **{**kwargs, 'username': 'me'})
|
||||
userq.create(db, **{**kwargs, "username": "me"})
|
||||
with pytest.raises(ArgumentError):
|
||||
userq.create(
|
||||
db, **{**kwargs, 'username': 'the right honorable user-name, esquire'}
|
||||
db, **{**kwargs, "username": "the right honorable user-name, esquire"}
|
||||
)
|
||||
# Test allowed characters
|
||||
with pytest.raises(ArgumentError):
|
||||
userq.create(db, **{**kwargs, 'username': 'user name'})
|
||||
userq.create(db, **{**kwargs, "username": "user name"})
|
||||
# No password
|
||||
with pytest.raises(ArgumentError):
|
||||
userq.create(db, **{**kwargs, 'password': None})
|
||||
userq.create(db, **{**kwargs, "password": None})
|
||||
|
||||
# Valid creation works and populates fields
|
||||
new_user = userq.create(db, **kwargs)
|
||||
@ -40,6 +40,6 @@ def test_create_user(db: DbContext):
|
||||
duplicate = userq.create(db, **kwargs)
|
||||
|
||||
# Missing display name populates with username
|
||||
user2_kw = {**kwargs, 'username': 'user2', 'display_name': None}
|
||||
user2_kw = {**kwargs, "username": "user2", "display_name": None}
|
||||
user2 = userq.create(db, **user2_kw)
|
||||
assert user2.display_name is not None
|
||||
|
Loading…
Reference in New Issue
Block a user