server/tests: use real database
I'm experimenting with snapshots and found following limitation of SQLite: https://www.sqlite.org/isolation.html
This commit is contained in:
parent
0320a0b55b
commit
87b1ee4564
6 changed files with 117 additions and 78 deletions
|
@ -25,6 +25,15 @@ database:
|
|||
pass: # example: dog
|
||||
name: # example: szuru
|
||||
|
||||
# required for runing the test suite
|
||||
test_database:
|
||||
schema: postgres
|
||||
host: # example: localhost
|
||||
port: # example: 5432
|
||||
user: # example: szuru
|
||||
pass: # example: dog
|
||||
name: # example: szuru_test
|
||||
|
||||
# used to send password reminders
|
||||
smtp:
|
||||
host: # example: localhost
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
# pylint: disable=redefined-outer-name
|
||||
import contextlib
|
||||
import os
|
||||
import datetime
|
||||
import uuid
|
||||
import random
|
||||
import string
|
||||
from datetime import datetime
|
||||
import pytest
|
||||
import freezegun
|
||||
import sqlalchemy
|
||||
|
@ -30,8 +31,19 @@ class QueryCounter(object):
|
|||
return self._statements
|
||||
|
||||
|
||||
if not config.config['test_database']['host']:
|
||||
raise RuntimeError('Test database not configured.')
|
||||
|
||||
_query_counter = QueryCounter()
|
||||
_engine = sqlalchemy.create_engine('sqlite:///:memory:')
|
||||
_engine = sqlalchemy.create_engine(
|
||||
'{schema}://{user}:{password}@{host}:{port}/{name}'.format(
|
||||
schema=config.config['test_database']['schema'],
|
||||
user=config.config['test_database']['user'],
|
||||
password=config.config['test_database']['pass'],
|
||||
host=config.config['test_database']['host'],
|
||||
port=config.config['test_database']['port'],
|
||||
name=config.config['test_database']['name']))
|
||||
db.Base.metadata.drop_all(bind=_engine)
|
||||
db.Base.metadata.create_all(bind=_engine)
|
||||
sqlalchemy.event.listen(
|
||||
_engine,
|
||||
|
@ -40,7 +52,8 @@ sqlalchemy.event.listen(
|
|||
|
||||
|
||||
def get_unique_name():
|
||||
return str(uuid.uuid4())
|
||||
alphabet = string.ascii_letters + string.digits
|
||||
return ''.join(random.choice(alphabet) for _ in range(8))
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
|
@ -72,16 +85,15 @@ def query_logger():
|
|||
|
||||
@pytest.yield_fixture(scope='function', autouse=True)
|
||||
def session(query_logger): # pylint: disable=unused-argument
|
||||
session_maker = sqlalchemy.orm.sessionmaker(bind=_engine)
|
||||
session = sqlalchemy.orm.scoped_session(session_maker)
|
||||
db.session = session
|
||||
db.sessionmaker = sqlalchemy.orm.sessionmaker(bind=_engine)
|
||||
db.session = sqlalchemy.orm.scoped_session(db.sessionmaker)
|
||||
try:
|
||||
yield session
|
||||
yield db.session
|
||||
finally:
|
||||
session.remove()
|
||||
db.session.remove()
|
||||
for table in reversed(db.Base.metadata.sorted_tables):
|
||||
session.execute(table.delete())
|
||||
session.commit()
|
||||
db.session.execute(table.delete())
|
||||
db.session.commit()
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
|
@ -115,7 +127,7 @@ def user_factory():
|
|||
user.password_hash = 'dummy'
|
||||
user.email = email
|
||||
user.rank = rank
|
||||
user.creation_time = datetime.datetime(1997, 1, 1)
|
||||
user.creation_time = datetime(1997, 1, 1)
|
||||
user.avatar_style = db.User.AVATAR_GRAVATAR
|
||||
return user
|
||||
return factory
|
||||
|
@ -142,7 +154,7 @@ def tag_factory():
|
|||
tag.names = [
|
||||
db.TagName(name) for name in names or [get_unique_name()]]
|
||||
tag.category = category
|
||||
tag.creation_time = datetime.datetime(1996, 1, 1)
|
||||
tag.creation_time = datetime(1996, 1, 1)
|
||||
return tag
|
||||
return factory
|
||||
|
||||
|
@ -162,14 +174,14 @@ def post_factory():
|
|||
post.checksum = checksum
|
||||
post.flags = []
|
||||
post.mime_type = 'application/octet-stream'
|
||||
post.creation_time = datetime.datetime(1996, 1, 1)
|
||||
post.creation_time = datetime(1996, 1, 1)
|
||||
return post
|
||||
return factory
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def comment_factory(user_factory, post_factory):
|
||||
def factory(user=None, post=None, text='dummy'):
|
||||
def factory(user=None, post=None, text='dummy', time=None):
|
||||
if not user:
|
||||
user = user_factory()
|
||||
db.session.add(user)
|
||||
|
@ -180,7 +192,7 @@ def comment_factory(user_factory, post_factory):
|
|||
comment.user = user
|
||||
comment.post = post
|
||||
comment.text = text
|
||||
comment.creation_time = datetime.datetime(1996, 1, 1)
|
||||
comment.creation_time = time or datetime(1996, 1, 1)
|
||||
return comment
|
||||
return factory
|
||||
|
||||
|
|
|
@ -145,12 +145,12 @@ def test_cascade_deletions(post_factory, user_factory, comment_factory):
|
|||
snapshot.user = user
|
||||
snapshot.creation_time = datetime(1997, 1, 1)
|
||||
snapshot.resource_type = '-'
|
||||
snapshot.resource_id = '-'
|
||||
snapshot.resource_id = 1
|
||||
snapshot.resource_repr = '-'
|
||||
snapshot.operation = '-'
|
||||
|
||||
db.session.add_all([user, post, comment, snapshot])
|
||||
db.session.flush()
|
||||
db.session.commit()
|
||||
|
||||
assert not db.session.dirty
|
||||
assert post.user is not None and post.user.user_id is not None
|
||||
|
|
|
@ -35,8 +35,9 @@ def test_serialize_user(user_factory, comment_factory):
|
|||
def test_try_get_comment(comment_factory):
|
||||
comment = comment_factory()
|
||||
db.session.add(comment)
|
||||
assert comments.try_get_comment_by_id(999) is None
|
||||
assert comments.try_get_comment_by_id(1) is comment
|
||||
db.session.flush()
|
||||
assert comments.try_get_comment_by_id(comment.comment_id + 1) is None
|
||||
assert comments.try_get_comment_by_id(comment.comment_id) is comment
|
||||
with pytest.raises(comments.InvalidCommentIdError):
|
||||
comments.try_get_comment_by_id('-')
|
||||
|
||||
|
@ -44,9 +45,10 @@ def test_try_get_comment(comment_factory):
|
|||
def test_get_comment(comment_factory):
|
||||
comment = comment_factory()
|
||||
db.session.add(comment)
|
||||
db.session.flush()
|
||||
with pytest.raises(comments.CommentNotFoundError):
|
||||
comments.get_comment_by_id(999)
|
||||
assert comments.get_comment_by_id(1) is comment
|
||||
comments.get_comment_by_id(comment.comment_id + 1)
|
||||
assert comments.get_comment_by_id(comment.comment_id) is comment
|
||||
with pytest.raises(comments.InvalidCommentIdError):
|
||||
comments.get_comment_by_id('-')
|
||||
|
||||
|
|
|
@ -110,8 +110,14 @@ def test_serialize_post(
|
|||
|
||||
db.session.flush()
|
||||
db.session.add_all([
|
||||
comment_factory(user=user_factory(name='commenter1'), post=post),
|
||||
comment_factory(user=user_factory(name='commenter2'), post=post),
|
||||
comment_factory(
|
||||
user=user_factory(name='commenter1'),
|
||||
post=post,
|
||||
time=datetime(1999, 1, 1)),
|
||||
comment_factory(
|
||||
user=user_factory(name='commenter2'),
|
||||
post=post,
|
||||
time=datetime(1999, 1, 2)),
|
||||
db.PostFavorite(
|
||||
post=post,
|
||||
user=user_factory(name='fav1'),
|
||||
|
@ -458,8 +464,8 @@ def test_update_post_relations(post_factory):
|
|||
post = post_factory()
|
||||
posts.update_post_relations(post, [relation1.post_id, relation2.post_id])
|
||||
assert len(post.relations) == 2
|
||||
assert post.relations[0].post_id == relation1.post_id
|
||||
assert post.relations[1].post_id == relation2.post_id
|
||||
assert sorted(r.post_id for r in post.relations) == [
|
||||
relation1.post_id, relation2.post_id]
|
||||
|
||||
|
||||
def test_update_post_relations_bidirectionality(post_factory):
|
||||
|
|
|
@ -110,7 +110,12 @@ def test_export_to_json(
|
|||
export_path = os.path.join(str(tmpdir), 'tags.json')
|
||||
assert os.path.exists(export_path)
|
||||
with open(export_path, 'r') as handle:
|
||||
assert json.loads(handle.read()) == {
|
||||
actual_json = json.loads(handle.read())
|
||||
assert actual_json['tags']
|
||||
assert actual_json['categories']
|
||||
actual_json['tags'].sort(key=lambda tag: tag['names'][0])
|
||||
actual_json['categories'].sort(key=lambda category: category['name'])
|
||||
assert actual_json == {
|
||||
'tags': [
|
||||
{
|
||||
'names': ['alias1', 'alias2'],
|
||||
|
@ -119,14 +124,14 @@ def test_export_to_json(
|
|||
'suggestions': ['sug1', 'sug2'],
|
||||
'implications': ['imp1', 'imp2'],
|
||||
},
|
||||
{'names': ['sug1'], 'usages': 0, 'category': 'cat1'},
|
||||
{'names': ['sug2'], 'usages': 0, 'category': 'cat1'},
|
||||
{'names': ['imp1'], 'usages': 0, 'category': 'cat1'},
|
||||
{'names': ['imp2'], 'usages': 0, 'category': 'cat1'},
|
||||
{'names': ['sug1'], 'usages': 0, 'category': 'cat1'},
|
||||
{'names': ['sug2'], 'usages': 0, 'category': 'cat1'},
|
||||
],
|
||||
'categories': [
|
||||
{'name': 'cat2', 'color': 'white'},
|
||||
{'name': 'cat1', 'color': 'black'},
|
||||
{'name': 'cat2', 'color': 'white'},
|
||||
]
|
||||
}
|
||||
|
||||
|
@ -164,76 +169,81 @@ def test_get_tag_by_name(name_to_search, expected_to_find, tag_factory):
|
|||
tags.get_tag_by_name(name_to_search)
|
||||
|
||||
|
||||
@pytest.mark.parametrize('names,expected_ids', [
|
||||
@pytest.mark.parametrize('names,expected_indexes', [
|
||||
([], []),
|
||||
(['name1'], [1]),
|
||||
(['NAME1'], [1]),
|
||||
(['alias1'], [1]),
|
||||
(['ALIAS1'], [1]),
|
||||
(['name2'], [2]),
|
||||
(['name1', 'name1'], [1]),
|
||||
(['name1', 'NAME1'], [1]),
|
||||
(['name1', 'alias1'], [1]),
|
||||
(['name1', 'alias2'], [1, 2]),
|
||||
(['NAME1', 'alias2'], [1, 2]),
|
||||
(['name1', 'ALIAS2'], [1, 2]),
|
||||
(['name2', 'alias1'], [1, 2]),
|
||||
(['name1'], [0]),
|
||||
(['NAME1'], [0]),
|
||||
(['alias1'], [0]),
|
||||
(['ALIAS1'], [0]),
|
||||
(['name2'], [1]),
|
||||
(['name1', 'name1'], [0]),
|
||||
(['name1', 'NAME1'], [0]),
|
||||
(['name1', 'alias1'], [0]),
|
||||
(['name1', 'alias2'], [0, 1]),
|
||||
(['NAME1', 'alias2'], [0, 1]),
|
||||
(['name1', 'ALIAS2'], [0, 1]),
|
||||
(['name2', 'alias1'], [0, 1]),
|
||||
])
|
||||
def test_get_tag_by_names(names, expected_ids, tag_factory):
|
||||
tag1 = tag_factory(names=['name1', 'ALIAS1'])
|
||||
tag2 = tag_factory(names=['name2', 'ALIAS2'])
|
||||
tag1.tag_id = 1
|
||||
tag2.tag_id = 2
|
||||
db.session.add_all([tag1, tag2])
|
||||
def test_get_tag_by_names(names, expected_indexes, tag_factory):
|
||||
input_tags = [
|
||||
tag_factory(names=['name1', 'ALIAS1']),
|
||||
tag_factory(names=['name2', 'ALIAS2']),
|
||||
]
|
||||
db.session.add_all(input_tags)
|
||||
db.session.flush()
|
||||
expected_ids = [input_tags[i].tag_id for i in expected_indexes]
|
||||
actual_ids = [tag.tag_id for tag in tags.get_tags_by_names(names)]
|
||||
assert actual_ids == expected_ids
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
'names,expected_ids,expected_created_names', [
|
||||
'names,expected_indexes,expected_created_names', [
|
||||
([], [], []),
|
||||
(['name1'], [1], []),
|
||||
(['NAME1'], [1], []),
|
||||
(['alias1'], [1], []),
|
||||
(['ALIAS1'], [1], []),
|
||||
(['name2'], [2], []),
|
||||
(['name1', 'name1'], [1], []),
|
||||
(['name1', 'NAME1'], [1], []),
|
||||
(['name1', 'alias1'], [1], []),
|
||||
(['name1', 'alias2'], [1, 2], []),
|
||||
(['NAME1', 'alias2'], [1, 2], []),
|
||||
(['name1', 'ALIAS2'], [1, 2], []),
|
||||
(['name2', 'alias1'], [1, 2], []),
|
||||
(['name1'], [0], []),
|
||||
(['NAME1'], [0], []),
|
||||
(['alias1'], [0], []),
|
||||
(['ALIAS1'], [0], []),
|
||||
(['name2'], [1], []),
|
||||
(['name1', 'name1'], [0], []),
|
||||
(['name1', 'NAME1'], [0], []),
|
||||
(['name1', 'alias1'], [0], []),
|
||||
(['name1', 'alias2'], [0, 1], []),
|
||||
(['NAME1', 'alias2'], [0, 1], []),
|
||||
(['name1', 'ALIAS2'], [0, 1], []),
|
||||
(['name2', 'alias1'], [0, 1], []),
|
||||
(['new'], [], ['new']),
|
||||
(['new', 'name1'], [1], ['new']),
|
||||
(['new', 'NAME1'], [1], ['new']),
|
||||
(['new', 'alias1'], [1], ['new']),
|
||||
(['new', 'ALIAS1'], [1], ['new']),
|
||||
(['new', 'name2'], [2], ['new']),
|
||||
(['new', 'name1', 'name1'], [1], ['new']),
|
||||
(['new', 'name1', 'NAME1'], [1], ['new']),
|
||||
(['new', 'name1', 'alias1'], [1], ['new']),
|
||||
(['new', 'name1', 'alias2'], [1, 2], ['new']),
|
||||
(['new', 'NAME1', 'alias2'], [1, 2], ['new']),
|
||||
(['new', 'name1', 'ALIAS2'], [1, 2], ['new']),
|
||||
(['new', 'name2', 'alias1'], [1, 2], ['new']),
|
||||
(['new', 'name1'], [0], ['new']),
|
||||
(['new', 'NAME1'], [0], ['new']),
|
||||
(['new', 'alias1'], [0], ['new']),
|
||||
(['new', 'ALIAS1'], [0], ['new']),
|
||||
(['new', 'name2'], [1], ['new']),
|
||||
(['new', 'name1', 'name1'], [0], ['new']),
|
||||
(['new', 'name1', 'NAME1'], [0], ['new']),
|
||||
(['new', 'name1', 'alias1'], [0], ['new']),
|
||||
(['new', 'name1', 'alias2'], [0, 1], ['new']),
|
||||
(['new', 'NAME1', 'alias2'], [0, 1], ['new']),
|
||||
(['new', 'name1', 'ALIAS2'], [0, 1], ['new']),
|
||||
(['new', 'name2', 'alias1'], [0, 1], ['new']),
|
||||
(['new', 'new'], [], ['new']),
|
||||
(['new', 'NEW'], [], ['new']),
|
||||
(['new', 'new2'], [], ['new', 'new2']),
|
||||
])
|
||||
def test_get_or_create_tags_by_names(
|
||||
names,
|
||||
expected_ids,
|
||||
expected_indexes,
|
||||
expected_created_names,
|
||||
tag_factory,
|
||||
tag_category_factory,
|
||||
config_injector):
|
||||
config_injector({'tag_name_regex': '.*'})
|
||||
category = tag_category_factory()
|
||||
tag1 = tag_factory(names=['name1', 'ALIAS1'], category=category)
|
||||
tag2 = tag_factory(names=['name2', 'ALIAS2'], category=category)
|
||||
db.session.add_all([tag1, tag2])
|
||||
input_tags = [
|
||||
tag_factory(names=['name1', 'ALIAS1'], category=category),
|
||||
tag_factory(names=['name2', 'ALIAS2'], category=category),
|
||||
]
|
||||
db.session.add_all(input_tags)
|
||||
result = tags.get_or_create_tags_by_names(names)
|
||||
expected_ids = [input_tags[i].tag_id for i in expected_indexes]
|
||||
actual_ids = [tag.tag_id for tag in result[0]]
|
||||
actual_created_names = [tag.names[0].name for tag in result[1]]
|
||||
assert actual_ids == expected_ids
|
||||
|
|
Loading…
Reference in a new issue