Add create_lexicon method

This commit is contained in:
Tim Van Baak 2021-05-27 18:23:48 -07:00
parent 63f17cfc7a
commit fc58a91490
2 changed files with 90 additions and 0 deletions

View File

@ -0,0 +1,51 @@
"""
Lexicon query interface
"""
import re
from sqlalchemy import select, func
from amanuensis.db import DbContext, Lexicon
from amanuensis.errors import ArgumentError
RE_ALPHANUM_DASH_UNDER = re.compile(r'^[A-Za-z0-9-_]*$')
def create_lexicon(
db: DbContext,
name: str,
title: str,
prompt: str) -> Lexicon:
"""
Create a new lexicon.
"""
# Verify name
if not isinstance(name, str):
raise ArgumentError('Lexicon name must be a string')
if not name.strip():
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')
# Verify title
if title is not None and not isinstance(name, str):
raise ArgumentError('Lexicon name must be a string')
# Verify prompt
if not isinstance(prompt, str):
raise ArgumentError('Lexicon prompt must be a string')
# Query the db to make sure the lexicon name isn't taken
if db.session.query(func.count(Lexicon.id)).filter(Lexicon.name == name).scalar() > 0:
raise ArgumentError('Lexicon name is already taken')
new_lexicon = Lexicon(
name=name,
title=title,
prompt=prompt,
)
db.session.add(new_lexicon)
db.session.commit()
return new_lexicon

View File

@ -1,7 +1,10 @@
import datetime
import pytest import pytest
from sqlalchemy import func from sqlalchemy import func
from amanuensis.db import * from amanuensis.db import *
import amanuensis.backend.lexicon as lexiq
import amanuensis.backend.user as userq import amanuensis.backend.user as userq
from amanuensis.errors import ArgumentError from amanuensis.errors import ArgumentError
@ -62,3 +65,39 @@ def test_create_user(db):
user2_kw = {**kwargs, 'username': 'user2', 'display_name': None} user2_kw = {**kwargs, 'username': 'user2', 'display_name': None}
user2 = userq.create_user(db, **user2_kw) user2 = userq.create_user(db, **user2_kw)
assert user2.display_name is not None assert user2.display_name is not None
def test_create_lexicon(db):
"""Test new game creation."""
kwargs = {
'name': 'Test',
'title': None,
'prompt': 'A test Lexicon game'
}
# Test name constraints
with pytest.raises(ArgumentError):
lexiq.create_lexicon(db, **{**kwargs, 'name': None})
with pytest.raises(ArgumentError):
lexiq.create_lexicon(db, **{**kwargs, 'name': ''})
with pytest.raises(ArgumentError):
lexiq.create_lexicon(db, **{**kwargs, 'name': ' '})
with pytest.raises(ArgumentError):
lexiq.create_lexicon(db, **{**kwargs, 'name': '..'})
with pytest.raises(ArgumentError):
lexiq.create_lexicon(db, **{**kwargs, 'name': '\x00'})
with pytest.raises(ArgumentError):
lexiq.create_lexicon(db, **{**kwargs, 'name': 'space in name'})
# Validate that creation populates fields, including timestamps
before = datetime.datetime.utcnow() - datetime.timedelta(seconds=1)
new_lexicon = lexiq.create_lexicon(db, **kwargs)
after = datetime.datetime.utcnow() + datetime.timedelta(seconds=1)
assert new_lexicon
assert new_lexicon.id is not None
assert new_lexicon.created is not None
assert before < new_lexicon.created
assert new_lexicon.created < after
# No duplicate lexicon names
with pytest.raises(ArgumentError):
duplicate = lexiq.create_lexicon(db, **kwargs)