2023-06-01 14:01:45 +00:00
|
|
|
from random import randint
|
2023-06-01 15:00:42 +00:00
|
|
|
from uuid import uuid4
|
2023-06-01 14:01:45 +00:00
|
|
|
|
|
|
|
from flask import current_app as Response
|
|
|
|
|
2023-05-11 15:02:14 +00:00
|
|
|
from app import models as m
|
2023-05-25 07:10:22 +00:00
|
|
|
from app.controllers.create_access_groups import (
|
|
|
|
create_editor_group,
|
|
|
|
create_moderator_group,
|
|
|
|
)
|
2023-05-11 15:02:14 +00:00
|
|
|
|
2023-04-20 13:10:16 +00:00
|
|
|
TEST_ADMIN_NAME = "bob"
|
|
|
|
TEST_ADMIN_EMAIL = "bob@test.com"
|
|
|
|
TEST_ADMIN_PASSWORD = "password"
|
|
|
|
|
|
|
|
|
2023-04-20 14:37:38 +00:00
|
|
|
def create(username=TEST_ADMIN_NAME, password=TEST_ADMIN_PASSWORD):
|
2023-05-11 15:02:14 +00:00
|
|
|
user = m.User(username=username)
|
2023-04-20 13:10:16 +00:00
|
|
|
user.password = password
|
|
|
|
user.save()
|
2023-06-12 12:18:21 +00:00
|
|
|
return user
|
2023-04-20 13:10:16 +00:00
|
|
|
|
|
|
|
|
2023-06-12 12:19:16 +00:00
|
|
|
def login(
|
|
|
|
client,
|
|
|
|
username=TEST_ADMIN_NAME,
|
|
|
|
password=TEST_ADMIN_PASSWORD,
|
|
|
|
create_user_if_not_exists=True,
|
|
|
|
):
|
2023-05-11 15:02:14 +00:00
|
|
|
user = m.User.query.filter_by(username=username).first()
|
2023-06-12 12:19:16 +00:00
|
|
|
if create_user_if_not_exists and not user:
|
2023-06-12 12:18:21 +00:00
|
|
|
user = create(username, password)
|
|
|
|
|
2023-04-24 08:29:05 +00:00
|
|
|
response = client.post(
|
2023-04-20 13:10:16 +00:00
|
|
|
"/login", data=dict(user_id=username, password=password), follow_redirects=True
|
|
|
|
)
|
2023-04-24 08:29:05 +00:00
|
|
|
return response, user
|
2023-04-20 13:10:16 +00:00
|
|
|
|
|
|
|
|
|
|
|
def logout(client):
|
|
|
|
return client.get("/logout", follow_redirects=True)
|
2023-05-11 15:02:14 +00:00
|
|
|
|
|
|
|
|
2023-05-29 13:14:00 +00:00
|
|
|
def create_test_book(owner_id: int, entity_id: int = 0):
|
|
|
|
if not entity_id:
|
2023-06-01 04:57:31 +00:00
|
|
|
entity_id = randint(1, 500)
|
2023-05-11 15:02:14 +00:00
|
|
|
book: m.Book = m.Book(
|
|
|
|
label=f"Book {entity_id}", about=f"About {entity_id}", user_id=owner_id
|
|
|
|
).save()
|
|
|
|
|
|
|
|
version: m.BookVersion = m.BookVersion(semver="1.0.0", book_id=book.id).save()
|
|
|
|
|
2023-05-25 07:10:22 +00:00
|
|
|
root_collection: m.Collection = m.Collection(
|
|
|
|
label="Root", version_id=version.id, is_root=True
|
|
|
|
).save()
|
|
|
|
|
2023-05-11 15:02:14 +00:00
|
|
|
collection: m.Collection = m.Collection(
|
2023-05-25 07:10:22 +00:00
|
|
|
label=f"Collection {entity_id}",
|
|
|
|
version_id=version.id,
|
2023-05-25 09:37:58 +00:00
|
|
|
is_leaf=True,
|
2023-05-25 07:10:22 +00:00
|
|
|
parent_id=root_collection.id,
|
2023-05-11 15:02:14 +00:00
|
|
|
).save()
|
|
|
|
|
|
|
|
section: m.Section = m.Section(
|
|
|
|
label=f"Section {entity_id}",
|
|
|
|
user_id=owner_id,
|
|
|
|
collection_id=collection.id,
|
|
|
|
version_id=version.id,
|
|
|
|
).save()
|
|
|
|
|
|
|
|
interpretation: m.Interpretation = m.Interpretation(
|
|
|
|
section_id=section.id,
|
|
|
|
text=f"Interpretation Text {entity_id}",
|
|
|
|
user_id=owner_id,
|
|
|
|
).save()
|
|
|
|
|
|
|
|
m.Comment(
|
|
|
|
text=f"Comment {entity_id}",
|
|
|
|
user_id=owner_id,
|
|
|
|
interpretation_id=interpretation.id,
|
|
|
|
).save()
|
2023-05-25 09:37:58 +00:00
|
|
|
|
|
|
|
# subcollection
|
|
|
|
collection_2: m.Collection = m.Collection(
|
|
|
|
label=f"Collection {entity_id}",
|
|
|
|
version_id=version.id,
|
|
|
|
parent_id=root_collection.id,
|
|
|
|
).save()
|
|
|
|
|
|
|
|
subcollection: m.Collection = m.Collection(
|
|
|
|
label=f"subCollection {entity_id}",
|
|
|
|
version_id=version.id,
|
|
|
|
parent_id=collection_2.id,
|
|
|
|
is_leaf=True,
|
|
|
|
).save()
|
|
|
|
|
2023-05-25 09:38:08 +00:00
|
|
|
section_in_subcollection: m.Section = m.Section(
|
|
|
|
label=f"Section in sub {entity_id}",
|
|
|
|
user_id=owner_id,
|
|
|
|
collection_id=subcollection.id,
|
|
|
|
version_id=version.id,
|
|
|
|
).save()
|
|
|
|
|
2023-05-25 09:37:58 +00:00
|
|
|
# access groups
|
|
|
|
editor_access_group = create_editor_group(book_id=book.id)
|
|
|
|
moderator_access_group = create_moderator_group(book_id=book.id)
|
|
|
|
access_groups = [editor_access_group, moderator_access_group]
|
|
|
|
|
|
|
|
for access_group in access_groups:
|
|
|
|
m.BookAccessGroups(book_id=book.id, access_group_id=access_group.id).save()
|
|
|
|
# root
|
|
|
|
m.CollectionAccessGroups(
|
|
|
|
collection_id=root_collection.id, access_group_id=access_group.id
|
|
|
|
).save()
|
|
|
|
# leaf
|
|
|
|
m.CollectionAccessGroups(
|
|
|
|
collection_id=collection.id, access_group_id=access_group.id
|
|
|
|
).save()
|
|
|
|
|
|
|
|
m.CollectionAccessGroups(
|
|
|
|
collection_id=collection_2.id, access_group_id=access_group.id
|
|
|
|
).save()
|
|
|
|
# subcollection
|
|
|
|
m.CollectionAccessGroups(
|
|
|
|
collection_id=subcollection.id, access_group_id=access_group.id
|
|
|
|
).save()
|
|
|
|
|
2023-05-25 09:38:08 +00:00
|
|
|
m.SectionAccessGroups(
|
|
|
|
section_id=section.id, access_group_id=access_group.id
|
|
|
|
).save()
|
|
|
|
m.SectionAccessGroups(
|
|
|
|
section_id=section_in_subcollection.id, access_group_id=access_group.id
|
|
|
|
).save()
|
|
|
|
m.InterpretationAccessGroups(
|
|
|
|
interpretation_id=section.id, access_group_id=access_group.id
|
|
|
|
).save()
|
|
|
|
|
2023-05-29 13:14:00 +00:00
|
|
|
# Contributors
|
|
|
|
u = m.User(username=f"Bob {entity_id}").save()
|
|
|
|
m.BookContributor(book_id=book.id, user_id=u.id).save()
|
2023-05-25 09:37:58 +00:00
|
|
|
|
2023-05-25 07:10:22 +00:00
|
|
|
return book
|
2023-05-15 14:55:36 +00:00
|
|
|
|
|
|
|
|
2023-05-15 15:09:03 +00:00
|
|
|
def check_if_nested_book_entities_is_deleted(book: m.Book, is_deleted: bool = True):
|
|
|
|
for version in book.versions:
|
|
|
|
version: m.BookVersion
|
|
|
|
assert version.is_deleted == is_deleted
|
|
|
|
|
|
|
|
check_if_nested_version_entities_is_deleted(version)
|
|
|
|
|
|
|
|
|
|
|
|
def check_if_nested_version_entities_is_deleted(
|
|
|
|
book_version: m.BookVersion, is_deleted: bool = True
|
|
|
|
):
|
|
|
|
root_collection: m.Collection = book_version.root_collection
|
|
|
|
assert root_collection.is_deleted == is_deleted
|
|
|
|
for collection in root_collection.children:
|
|
|
|
collection: m.Collection
|
|
|
|
assert collection.is_deleted == is_deleted
|
|
|
|
|
|
|
|
check_if_nested_collection_entities_is_deleted(collection)
|
|
|
|
|
|
|
|
|
2023-05-15 14:55:36 +00:00
|
|
|
def check_if_nested_collection_entities_is_deleted(
|
|
|
|
collection: m.Collection, is_deleted: bool = True
|
|
|
|
):
|
|
|
|
for section in collection.sections:
|
|
|
|
section: m.Section
|
|
|
|
assert section.is_deleted == is_deleted
|
|
|
|
check_if_nested_section_entities_is_deleted(section, is_deleted)
|
|
|
|
|
|
|
|
|
|
|
|
def check_if_nested_section_entities_is_deleted(
|
|
|
|
section: m.Section, is_deleted: bool = True
|
|
|
|
):
|
|
|
|
for interpretation in section.interpretations:
|
|
|
|
interpretation: m.Interpretation
|
|
|
|
assert interpretation.is_deleted == is_deleted
|
|
|
|
|
|
|
|
check_if_nested_interpretation_entities_is_deleted(interpretation, is_deleted)
|
|
|
|
|
|
|
|
|
|
|
|
def check_if_nested_interpretation_entities_is_deleted(
|
|
|
|
interpretation: m.Interpretation, is_deleted: bool = True
|
|
|
|
):
|
|
|
|
for comment in interpretation.comments:
|
|
|
|
comment: m.Comment
|
|
|
|
assert comment.is_deleted == is_deleted
|
|
|
|
|
|
|
|
|
|
|
|
def check_if_nested_comment_entities_is_deleted(
|
|
|
|
comment: m.Comment, is_deleted: bool = True
|
|
|
|
):
|
|
|
|
for child in comment.children:
|
|
|
|
child: m.Comment
|
|
|
|
assert child.is_deleted == is_deleted
|
2023-06-01 14:01:45 +00:00
|
|
|
|
|
|
|
|
|
|
|
# book entities:
|
|
|
|
|
|
|
|
|
|
|
|
def create_book(client):
|
2023-06-01 15:00:42 +00:00
|
|
|
random_id = str(uuid4())
|
2023-06-01 14:01:45 +00:00
|
|
|
BOOK_NAME = f"TBook {random_id}"
|
|
|
|
response: Response = client.post(
|
|
|
|
"/book/create",
|
|
|
|
data=dict(label=BOOK_NAME),
|
|
|
|
follow_redirects=True,
|
|
|
|
)
|
|
|
|
|
|
|
|
assert response.status_code == 200
|
|
|
|
assert b"Book added!" in response.data
|
|
|
|
|
|
|
|
book: m.Book = m.Book.query.filter_by(label=BOOK_NAME).first()
|
|
|
|
|
|
|
|
assert book
|
|
|
|
assert book.versions
|
|
|
|
assert len(book.versions) == 1
|
|
|
|
assert book.access_groups
|
|
|
|
assert len(book.access_groups) == 2
|
|
|
|
|
2023-06-12 12:18:21 +00:00
|
|
|
root_collection: m.Collection = book.active_version.collections[0]
|
2023-06-01 14:01:45 +00:00
|
|
|
assert root_collection
|
|
|
|
assert root_collection.access_groups
|
|
|
|
assert len(root_collection.access_groups) == 2
|
|
|
|
|
|
|
|
return book
|
|
|
|
|
|
|
|
|
|
|
|
def create_collection(client, book_id):
|
2023-06-01 15:00:42 +00:00
|
|
|
random_id = str(uuid4())
|
2023-06-01 14:01:45 +00:00
|
|
|
LABEL = f"TCollection {random_id}"
|
|
|
|
response: Response = client.post(
|
|
|
|
f"/book/{book_id}/create_collection",
|
|
|
|
data=dict(label=LABEL),
|
|
|
|
follow_redirects=True,
|
|
|
|
)
|
|
|
|
|
|
|
|
assert response.status_code == 200
|
|
|
|
collection: m.Collection = m.Collection.query.filter_by(label=LABEL).first()
|
|
|
|
|
|
|
|
return collection, response
|
|
|
|
|
|
|
|
|
2023-06-01 15:00:42 +00:00
|
|
|
def create_sub_collection(client, book_id, collection_id):
|
|
|
|
random_id = str(uuid4())
|
|
|
|
LABEL = f"TCollection {random_id}"
|
|
|
|
response: Response = client.post(
|
|
|
|
f"/book/{book_id}/{collection_id}/create_sub_collection",
|
|
|
|
data=dict(label=LABEL),
|
|
|
|
follow_redirects=True,
|
|
|
|
)
|
|
|
|
|
|
|
|
assert response.status_code == 200
|
|
|
|
collection: m.Collection = m.Collection.query.filter_by(label=LABEL).first()
|
|
|
|
|
|
|
|
return collection, response
|
|
|
|
|
|
|
|
|
2023-06-01 14:01:45 +00:00
|
|
|
def create_section(client, book_id, collection_id):
|
2023-06-01 15:00:42 +00:00
|
|
|
random_id = str(uuid4())
|
2023-06-01 14:01:45 +00:00
|
|
|
LABEL = f"TSection {random_id}"
|
|
|
|
response: Response = client.post(
|
|
|
|
f"/book/{book_id}/{collection_id}/create_section",
|
|
|
|
data=dict(collection_id=collection_id, label=LABEL),
|
|
|
|
follow_redirects=True,
|
|
|
|
)
|
|
|
|
|
|
|
|
section: m.Section = m.Section.query.filter_by(
|
|
|
|
label=LABEL, collection_id=collection_id
|
|
|
|
).first()
|
|
|
|
return section, response
|
|
|
|
|
|
|
|
|
|
|
|
def create_interpretation(client, book_id, section_id):
|
2023-06-01 15:00:42 +00:00
|
|
|
random_id = str(uuid4())
|
2023-06-01 14:01:45 +00:00
|
|
|
LABEL = f"TInterpretation {random_id}"
|
|
|
|
response: Response = client.post(
|
|
|
|
f"/book/{book_id}/{section_id}/create_interpretation",
|
|
|
|
data=dict(section_id=section_id, text=LABEL),
|
|
|
|
follow_redirects=True,
|
|
|
|
)
|
|
|
|
interpretation: m.Interpretation = m.Interpretation.query.filter_by(
|
|
|
|
section_id=section_id, text=LABEL
|
|
|
|
).first()
|
|
|
|
return interpretation, response
|
|
|
|
|
|
|
|
|
|
|
|
def create_comment(client, book_id, interpretation_id):
|
2023-06-01 15:00:42 +00:00
|
|
|
random_id = str(uuid4())
|
2023-06-01 14:01:45 +00:00
|
|
|
TEXT = f"TComment {random_id}"
|
|
|
|
response: Response = client.post(
|
|
|
|
f"/book/{book_id}/{interpretation_id}/create_comment",
|
|
|
|
data=dict(
|
|
|
|
text=TEXT,
|
|
|
|
interpretation_id=interpretation_id,
|
|
|
|
),
|
|
|
|
follow_redirects=True,
|
|
|
|
)
|
|
|
|
comment: m.Comment = m.Comment.query.filter_by(text=TEXT).first()
|
|
|
|
return comment, response
|