Compare commits
No commits in common. "29a73c3c477b5207fd838252e7f8a3c6b360cc23" and "cda4523b666c2649dbd880b6024d4b927a31378b" have entirely different histories.
29a73c3c47
...
cda4523b66
|
@ -1,62 +0,0 @@
|
||||||
"""
|
|
||||||
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
|
|
|
@ -4,7 +4,6 @@ pytest test fixtures
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from amanuensis.db import DbContext
|
from amanuensis.db import DbContext
|
||||||
import amanuensis.backend.character as charq
|
|
||||||
import amanuensis.backend.lexicon as lexiq
|
import amanuensis.backend.lexicon as lexiq
|
||||||
import amanuensis.backend.membership as memq
|
import amanuensis.backend.membership as memq
|
||||||
import amanuensis.backend.user as userq
|
import amanuensis.backend.user as userq
|
||||||
|
@ -63,52 +62,12 @@ def make_membership(db: DbContext):
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def make_character(db: DbContext):
|
def lexicon_with_editor(make_user, make_lexicon, make_membership):
|
||||||
"""Provides a factory function for creating characters, with valid default values."""
|
|
||||||
def character_factory(state={'nonce': 1}, **kwargs):
|
|
||||||
default_kwargs = {
|
|
||||||
'name': f'Character {state["nonce"]}',
|
|
||||||
'signature': None,
|
|
||||||
}
|
|
||||||
state['nonce'] += 1
|
|
||||||
updated_kwargs = {**default_kwargs, **kwargs}
|
|
||||||
return charq.create(db, **updated_kwargs)
|
|
||||||
return character_factory
|
|
||||||
|
|
||||||
|
|
||||||
class TestFactory:
|
|
||||||
def __init__(self, db, **factories):
|
|
||||||
self.db = db
|
|
||||||
self.factories = factories
|
|
||||||
|
|
||||||
def __getattr__(self, name):
|
|
||||||
return self.factories[name]
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
|
||||||
def make(
|
|
||||||
db: DbContext,
|
|
||||||
make_user,
|
|
||||||
make_lexicon,
|
|
||||||
make_membership,
|
|
||||||
make_character) -> TestFactory:
|
|
||||||
"""Fixture that groups all factory fixtures together."""
|
|
||||||
return TestFactory(
|
|
||||||
db,
|
|
||||||
user=make_user,
|
|
||||||
lexicon=make_lexicon,
|
|
||||||
membership=make_membership,
|
|
||||||
character=make_character,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
|
||||||
def lexicon_with_editor(make):
|
|
||||||
"""Shortcut setup for a lexicon game with an editor."""
|
"""Shortcut setup for a lexicon game with an editor."""
|
||||||
editor = make.user()
|
editor = make_user()
|
||||||
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)
|
||||||
|
|
|
@ -1,53 +0,0 @@
|
||||||
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)
|
|
|
@ -5,7 +5,7 @@ import amanuensis.backend.character as charq
|
||||||
from amanuensis.errors import ArgumentError
|
from amanuensis.errors import ArgumentError
|
||||||
|
|
||||||
|
|
||||||
def test_create_character(db: DbContext, lexicon_with_editor, make):
|
def test_create_character(db: DbContext, lexicon_with_editor, make_user):
|
||||||
"""Test creating a character."""
|
"""Test creating a character."""
|
||||||
lexicon, user = lexicon_with_editor
|
lexicon, user = lexicon_with_editor
|
||||||
kwargs = {
|
kwargs = {
|
||||||
|
@ -33,7 +33,7 @@ def test_create_character(db: DbContext, lexicon_with_editor, make):
|
||||||
assert char.signature is not None
|
assert char.signature is not None
|
||||||
|
|
||||||
# User must be in lexicon
|
# User must be in lexicon
|
||||||
new_user = make.user()
|
new_user = make_user()
|
||||||
with pytest.raises(ArgumentError):
|
with pytest.raises(ArgumentError):
|
||||||
charq.create(**{**kwargs, 'user_id': new_user.id})
|
charq.create(**{**kwargs, 'user_id': new_user.id})
|
||||||
|
|
||||||
|
|
|
@ -7,12 +7,12 @@ from amanuensis.errors import ArgumentError
|
||||||
import amanuensis.backend.membership as memq
|
import amanuensis.backend.membership as memq
|
||||||
|
|
||||||
|
|
||||||
def test_create_membership(db: DbContext, make):
|
def test_create_membership(db: DbContext, make_user, make_lexicon):
|
||||||
"""Test joining a game."""
|
"""Test joining a game."""
|
||||||
# Set up a user and a lexicon
|
# Set up a user and a lexicon
|
||||||
new_user = make.user()
|
new_user = make_user()
|
||||||
assert new_user.id, 'Failed to create user'
|
assert new_user.id, 'Failed to create user'
|
||||||
new_lexicon = make.lexicon()
|
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
|
# Add the user to the lexicon as an editor
|
||||||
|
|
Loading…
Reference in New Issue