Add article backend
This commit is contained in:
parent
dc23f6343a
commit
29a73c3c47
|
@ -0,0 +1,62 @@
|
||||||
|
"""
|
||||||
|
Article query interface
|
||||||
|
"""
|
||||||
|
|
||||||
|
from sqlalchemy import select
|
||||||
|
|
||||||
|
from amanuensis.db import *
|
||||||
|
from amanuensis.errors import ArgumentError
|
||||||
|
|
||||||
|
|
||||||
|
def create(
|
||||||
|
db: DbContext,
|
||||||
|
lexicon_id: int,
|
||||||
|
user_id: int,
|
||||||
|
character_id: int) -> Article:
|
||||||
|
"""
|
||||||
|
Create a new article in a lexicon.
|
||||||
|
"""
|
||||||
|
# Verify argument types are correct
|
||||||
|
if not isinstance(lexicon_id, int):
|
||||||
|
raise ArgumentError('lexicon_id')
|
||||||
|
if not isinstance(user_id, int):
|
||||||
|
raise ArgumentError('user_id')
|
||||||
|
if character_id is not None and not isinstance(character_id, int):
|
||||||
|
raise ArgumentError('character_id')
|
||||||
|
|
||||||
|
# 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')
|
||||||
|
|
||||||
|
# If the character id is provided, check that the user owns the character
|
||||||
|
# and the character belongs to the lexicon
|
||||||
|
if character_id is not None:
|
||||||
|
character: Character = db(
|
||||||
|
select(Character)
|
||||||
|
.where(Character.id == character_id)
|
||||||
|
).scalar_one_or_none()
|
||||||
|
if not character:
|
||||||
|
raise ArgumentError('Character does not exist')
|
||||||
|
if character.user.id != user_id:
|
||||||
|
raise ArgumentError('Character is owned by the wrong player')
|
||||||
|
if character.lexicon.id != lexicon_id:
|
||||||
|
raise ArgumentError('Character belongs to the wrong lexicon')
|
||||||
|
signature = character.signature
|
||||||
|
else:
|
||||||
|
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}',
|
||||||
|
)
|
||||||
|
db.session.add(new_article)
|
||||||
|
db.session.commit()
|
||||||
|
return new_article
|
|
@ -0,0 +1,53 @@
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
from amanuensis.db import DbContext
|
||||||
|
import amanuensis.backend.article as artiq
|
||||||
|
|
||||||
|
from amanuensis.errors import ArgumentError
|
||||||
|
|
||||||
|
|
||||||
|
def test_create_article(db: DbContext, make):
|
||||||
|
"""Test new article creation"""
|
||||||
|
# Create two users in a shared lexicon
|
||||||
|
user1 = make.user()
|
||||||
|
user2 = make.user()
|
||||||
|
lexicon1 = make.lexicon()
|
||||||
|
make.membership(user_id=user1.id, lexicon_id=lexicon1.id)
|
||||||
|
make.membership(user_id=user2.id, lexicon_id=lexicon1.id)
|
||||||
|
char1_1 = make.character(lexicon_id=lexicon1.id, user_id=user1.id)
|
||||||
|
char1_2 = make.character(lexicon_id=lexicon1.id, user_id=user2.id)
|
||||||
|
|
||||||
|
# Create a lexicon that only one user is in
|
||||||
|
lexicon2 = make.lexicon()
|
||||||
|
make.membership(user_id=user2.id, lexicon_id=lexicon2.id)
|
||||||
|
char2_2 = make.character(lexicon_id=lexicon2.id, user_id=user2.id)
|
||||||
|
|
||||||
|
# User cannot create article for another user's character
|
||||||
|
with pytest.raises(ArgumentError):
|
||||||
|
artiq.create(db, lexicon1.id, user1.id, char1_2.id)
|
||||||
|
with pytest.raises(ArgumentError):
|
||||||
|
artiq.create(db, lexicon1.id, user2.id, char1_1.id)
|
||||||
|
|
||||||
|
# User cannot create article for their character in the wrong lexicon
|
||||||
|
with pytest.raises(ArgumentError):
|
||||||
|
artiq.create(db, lexicon1.id, user2.id, char2_2.id)
|
||||||
|
with pytest.raises(ArgumentError):
|
||||||
|
artiq.create(db, lexicon2.id, user2.id, char1_2.id)
|
||||||
|
|
||||||
|
# User cannot create article in a lexicon they aren't in
|
||||||
|
with pytest.raises(ArgumentError):
|
||||||
|
artiq.create(db, lexicon2.id, user1.id, char1_1.id)
|
||||||
|
|
||||||
|
# User cannot create anonymous articles in a lexicon they aren't in
|
||||||
|
with pytest.raises(ArgumentError):
|
||||||
|
artiq.create(db, lexicon2.id, user1.id, character_id=None)
|
||||||
|
|
||||||
|
# Users can create character-owned articles
|
||||||
|
assert artiq.create(db, lexicon1.id, user1.id, char1_1.id)
|
||||||
|
assert artiq.create(db, lexicon1.id, user2.id, char1_2.id)
|
||||||
|
assert artiq.create(db, lexicon2.id, user2.id, char2_2.id)
|
||||||
|
|
||||||
|
# Users can create anonymous articles
|
||||||
|
assert artiq.create(db, lexicon1.id, user1.id, character_id=None)
|
||||||
|
assert artiq.create(db, lexicon1.id, user2.id, character_id=None)
|
||||||
|
assert artiq.create(db, lexicon2.id, user2.id, character_id=None)
|
Loading…
Reference in New Issue