diff --git a/app/models/book.py b/app/models/book.py index 35a28d5..6928b3b 100644 --- a/app/models/book.py +++ b/app/models/book.py @@ -1,4 +1,5 @@ from flask_login import current_user +from sqlalchemy import and_, or_ from app import db, models as m from app.models.utils import BaseModel @@ -17,7 +18,7 @@ class Book(BaseModel): owner = db.relationship("User", viewonly=True) stars = db.relationship("User", secondary="books_stars", back_populates="stars") contributors = db.relationship("BookContributor") - versions = db.relationship("BookVersion") + versions = db.relationship("BookVersion", order_by="asc(BookVersion.id)") def __repr__(self): return f"<{self.id}: {self.label}>" @@ -34,3 +35,55 @@ class Book(BaseModel): ).first() if book_star: return True + + @property + def approved_comments(self): + comments = ( + db.session.query( + m.Comment, + ) + .filter( + and_( + m.BookVersion.id == self.last_version.id, + m.Section.version_id == m.BookVersion.id, + m.Collection.id == m.Section.collection_id, + m.Interpretation.section_id == m.Section.id, + m.Comment.interpretation_id == m.Interpretation.id, + m.Comment.approved.is_(True), + m.Comment.is_deleted.is_(False), + m.BookVersion.is_deleted.is_(False), + m.Interpretation.is_deleted.is_(False), + m.Section.is_deleted.is_(False), + m.Collection.is_deleted.is_(False), + ), + ) + .order_by(m.Comment.created_at.desc()) + .all() + ) + + return comments + + @property + def approved_interpretations(self): + interpretations = ( + db.session.query( + m.Interpretation, + ) + .filter( + and_( + m.BookVersion.id == self.last_version.id, + m.Section.version_id == m.BookVersion.id, + m.Collection.id == m.Section.collection_id, + m.Interpretation.section_id == m.Section.id, + m.Interpretation.approved.is_(True), + m.BookVersion.is_deleted.is_(False), + m.Interpretation.is_deleted.is_(False), + m.Section.is_deleted.is_(False), + m.Collection.is_deleted.is_(False), + ), + ) + .order_by(m.Interpretation.created_at.desc()) + .all() + ) + + return interpretations diff --git a/tests/test_book_stats_properties.py b/tests/test_book_stats_properties.py new file mode 100644 index 0000000..d53a458 --- /dev/null +++ b/tests/test_book_stats_properties.py @@ -0,0 +1,114 @@ +from flask.testing import FlaskClient + +from app import models as m +from tests.utils import login, create_test_book + + +def test_approved_interpretations(client: FlaskClient): + _, user = login(client) + create_test_book(user.id) + + dummy_user = m.User(username="Bob").save() + create_test_book(dummy_user.id) + + book: m.Book = m.Book.query.first() + + assert len(book.approved_interpretations) == 0 + + for interpretation in m.Interpretation.query.all(): + interpretation.approved = True + interpretation.save() + + assert len(book.approved_interpretations) == 1 + + section: m.Section = m.Section.query.first() + assert section + interpretation: m.Interpretation = m.Interpretation( + section_id=section.id, label="231", text="123", approved=True + ).save() + + assert len(book.approved_interpretations) == 2 + + interpretation.is_deleted = True + interpretation.save() + + assert len(book.approved_interpretations) == 1 + + collection: m.Collection = m.Collection.query.first() + sub_collection: m.Collection = m.Collection( + parent_id=collection.id, + label="123", + ).save() + section: m.Section = m.Section( + label="123", collection_id=sub_collection.id, version_id=book.last_version.id + ).save() + interpretation: m.Interpretation = m.Interpretation( + section_id=section.id, label="231", text="123", approved=True + ).save() + + assert len(book.approved_interpretations) == 2 + + sub_collection.is_deleted = True + sub_collection.save() + assert len(book.approved_interpretations) == 1 + + sub_collection.is_deleted = False + sub_collection.save() + assert len(book.approved_interpretations) == 2 + + # collection.is_deleted = True + # collection.save() + # assert len(book.approved_interpretations) == 0 + + +def test_approved_comments(client: FlaskClient): + _, user = login(client) + create_test_book(user.id) + + dummy_user = m.User(username="Bob").save() + create_test_book(dummy_user.id) + + book: m.Book = m.Book.query.first() + + assert len(book.approved_comments) == 0 + + for comment in m.Comment.query.all(): + comment.approved = True + comment.save() + + assert len(book.approved_comments) == 1 + + interpretation: m.Interpretation = m.Interpretation.query.first() + assert interpretation + comment: m.Comment = m.Comment( + text="231", approved=True, interpretation_id=interpretation.id + ).save() + + assert len(book.approved_comments) == 2 + + comment.is_deleted = True + comment.save() + + assert len(book.approved_comments) == 1 + + comment: m.Comment = m.Comment( + text="456", approved=True, interpretation_id=interpretation.id + ).save() + + assert len(book.approved_comments) == 2 + + interpretation.is_deleted = True + interpretation.save() + assert len(book.approved_comments) == 0 + + interpretation.is_deleted = False + interpretation.save() + assert len(book.approved_comments) == 2 + + collection: m.Collection = m.Collection.query.first() + collection.is_deleted = True + collection.save() + + interpretation.is_deleted = False + interpretation.save() + assert len(book.approved_comments) == 0