mirror of https://github.com/logos-co/open-law.git
Merge pull request #53 from Simple2B/svyat/feat/book_stats
Svyat/feat/book_stats
This commit is contained in:
commit
dd05759b02
|
@ -1,4 +1,5 @@
|
||||||
from flask_login import current_user
|
from flask_login import current_user
|
||||||
|
from sqlalchemy import and_
|
||||||
|
|
||||||
from app import db, models as m
|
from app import db, models as m
|
||||||
from app.models.utils import BaseModel
|
from app.models.utils import BaseModel
|
||||||
|
@ -17,7 +18,7 @@ class Book(BaseModel):
|
||||||
owner = db.relationship("User", viewonly=True)
|
owner = db.relationship("User", viewonly=True)
|
||||||
stars = db.relationship("User", secondary="books_stars", back_populates="stars")
|
stars = db.relationship("User", secondary="books_stars", back_populates="stars")
|
||||||
contributors = db.relationship("BookContributor")
|
contributors = db.relationship("BookContributor")
|
||||||
versions = db.relationship("BookVersion")
|
versions = db.relationship("BookVersion", order_by="asc(BookVersion.id)")
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return f"<{self.id}: {self.label}>"
|
return f"<{self.id}: {self.label}>"
|
||||||
|
@ -34,3 +35,55 @@ class Book(BaseModel):
|
||||||
).first()
|
).first()
|
||||||
if book_star:
|
if book_star:
|
||||||
return True
|
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
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
from datetime import datetime
|
|
||||||
|
|
||||||
from flask_login import current_user
|
from flask_login import current_user
|
||||||
|
|
||||||
from app import db, models as m
|
from app import db, models as m
|
||||||
|
@ -13,7 +11,6 @@ class Interpretation(BaseModel):
|
||||||
text = db.Column(db.Text, unique=False, nullable=False)
|
text = db.Column(db.Text, unique=False, nullable=False)
|
||||||
approved = db.Column(db.Boolean, default=False)
|
approved = db.Column(db.Boolean, default=False)
|
||||||
marked = db.Column(db.Boolean, default=False)
|
marked = db.Column(db.Boolean, default=False)
|
||||||
created_at = db.Column(db.DateTime, default=datetime.now)
|
|
||||||
|
|
||||||
# Foreign keys
|
# Foreign keys
|
||||||
user_id = db.Column(db.ForeignKey("users.id"))
|
user_id = db.Column(db.ForeignKey("users.id"))
|
||||||
|
|
|
@ -25,11 +25,11 @@
|
||||||
</span>
|
</span>
|
||||||
<span class="space-x-0.5 flex items-center">
|
<span class="space-x-0.5 flex items-center">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 22 22" stroke-width="1" stroke="currentColor" class="w-4 h-4 inline-flex mr-1"> <path stroke-linecap="round" stroke-linejoin="round" d="M3.75 13.5l10.5-11.25L12 10.5h8.25L9.75 21.75 12 13.5H3.75z" /> </svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 22 22" stroke-width="1" stroke="currentColor" class="w-4 h-4 inline-flex mr-1"> <path stroke-linecap="round" stroke-linejoin="round" d="M3.75 13.5l10.5-11.25L12 10.5h8.25L9.75 21.75 12 13.5H3.75z" /> </svg>
|
||||||
<p>55</p>
|
<p>{{ book.approved_interpretations|length }}</p>
|
||||||
</span>
|
</span>
|
||||||
<span class="space-x-0.5 flex items-center">
|
<span class="space-x-0.5 flex items-center">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 22 22" stroke-width="1" stroke="currentColor" class="w-4 h-4 inline-flex mr-1"> <path stroke-linecap="round" stroke-linejoin="round" d="M19.5 14.25v-2.625a3.375 3.375 0 00-3.375-3.375h-1.5A1.125 1.125 0 0113.5 7.125v-1.5a3.375 3.375 0 00-3.375-3.375H8.25m0 12.75h7.5m-7.5 3H12M10.5 2.25H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 00-9-9z" /> </svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 22 22" stroke-width="1" stroke="currentColor" class="w-4 h-4 inline-flex mr-1"> <path stroke-linecap="round" stroke-linejoin="round" d="M19.5 14.25v-2.625a3.375 3.375 0 00-3.375-3.375h-1.5A1.125 1.125 0 0113.5 7.125v-1.5a3.375 3.375 0 00-3.375-3.375H8.25m0 12.75h7.5m-7.5 3H12M10.5 2.25H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 00-9-9z" /> </svg>
|
||||||
<p>55</p>
|
<p>{{ book.approved_comments|length }}</p>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</dd>
|
</dd>
|
||||||
|
|
|
@ -36,11 +36,11 @@
|
||||||
</span>
|
</span>
|
||||||
<span class="space-x-0.5 flex items-center">
|
<span class="space-x-0.5 flex items-center">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 22 22" stroke-width="1" stroke="currentColor" class="w-4 h-4 inline-flex mr-1"> <path stroke-linecap="round" stroke-linejoin="round" d="M3.75 13.5l10.5-11.25L12 10.5h8.25L9.75 21.75 12 13.5H3.75z" /> </svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 22 22" stroke-width="1" stroke="currentColor" class="w-4 h-4 inline-flex mr-1"> <path stroke-linecap="round" stroke-linejoin="round" d="M3.75 13.5l10.5-11.25L12 10.5h8.25L9.75 21.75 12 13.5H3.75z" /> </svg>
|
||||||
<p>55</p>
|
<p>{{ book.approved_interpretations|length }}</p>
|
||||||
</span>
|
</span>
|
||||||
<span class="space-x-0.5 flex items-center">
|
<span class="space-x-0.5 flex items-center">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 22 22" stroke-width="1" stroke="currentColor" class="w-4 h-4 inline-flex mr-1"> <path stroke-linecap="round" stroke-linejoin="round" d="M19.5 14.25v-2.625a3.375 3.375 0 00-3.375-3.375h-1.5A1.125 1.125 0 0113.5 7.125v-1.5a3.375 3.375 0 00-3.375-3.375H8.25m0 12.75h7.5m-7.5 3H12M10.5 2.25H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 00-9-9z" /> </svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 22 22" stroke-width="1" stroke="currentColor" class="w-4 h-4 inline-flex mr-1"> <path stroke-linecap="round" stroke-linejoin="round" d="M19.5 14.25v-2.625a3.375 3.375 0 00-3.375-3.375h-1.5A1.125 1.125 0 0113.5 7.125v-1.5a3.375 3.375 0 00-3.375-3.375H8.25m0 12.75h7.5m-7.5 3H12M10.5 2.25H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 00-9-9z" /> </svg>
|
||||||
<p>55</p>
|
<p>{{ book.approved_comments|length }}</p>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</dd>
|
</dd>
|
||||||
|
|
|
@ -114,11 +114,11 @@
|
||||||
</span>
|
</span>
|
||||||
<span class="space-x-0.5 flex items-center">
|
<span class="space-x-0.5 flex items-center">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 22 22" stroke-width="1" stroke="currentColor" class="w-4 h-4 inline-flex mr-1"> <path stroke-linecap="round" stroke-linejoin="round" d="M3.75 13.5l10.5-11.25L12 10.5h8.25L9.75 21.75 12 13.5H3.75z" /> </svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 22 22" stroke-width="1" stroke="currentColor" class="w-4 h-4 inline-flex mr-1"> <path stroke-linecap="round" stroke-linejoin="round" d="M3.75 13.5l10.5-11.25L12 10.5h8.25L9.75 21.75 12 13.5H3.75z" /> </svg>
|
||||||
<p>55</p>
|
<p>{{ book.approved_interpretations|length }}</p>
|
||||||
</span>
|
</span>
|
||||||
<span class="space-x-0.5 flex items-center">
|
<span class="space-x-0.5 flex items-center">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 22 22" stroke-width="1" stroke="currentColor" class="w-4 h-4 inline-flex mr-1"> <path stroke-linecap="round" stroke-linejoin="round" d="M19.5 14.25v-2.625a3.375 3.375 0 00-3.375-3.375h-1.5A1.125 1.125 0 0113.5 7.125v-1.5a3.375 3.375 0 00-3.375-3.375H8.25m0 12.75h7.5m-7.5 3H12M10.5 2.25H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 00-9-9z" /> </svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 22 22" stroke-width="1" stroke="currentColor" class="w-4 h-4 inline-flex mr-1"> <path stroke-linecap="round" stroke-linejoin="round" d="M19.5 14.25v-2.625a3.375 3.375 0 00-3.375-3.375h-1.5A1.125 1.125 0 0113.5 7.125v-1.5a3.375 3.375 0 00-3.375-3.375H8.25m0 12.75h7.5m-7.5 3H12M10.5 2.25H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 00-9-9z" /> </svg>
|
||||||
<p>55</p>
|
<p>{{ book.approved_comments|length }}</p>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</dd>
|
</dd>
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
<!-- prettier-ignore -->
|
<!-- prettier-ignore -->
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-10 h-10"> <path stroke-linecap="round" stroke-linejoin="round" d="M17.982 18.725A7.488 7.488 0 0012 15.75a7.488 7.488 0 00-5.982 2.975m11.963 0a9 9 0 10-11.963 0m11.963 0A8.966 8.966 0 0112 21a8.966 8.966 0 01-5.982-2.275M15 9.75a3 3 0 11-6 0 3 3 0 016 0z" /> </svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-10 h-10"> <path stroke-linecap="round" stroke-linejoin="round" d="M17.982 18.725A7.488 7.488 0 0012 15.75a7.488 7.488 0 00-5.982 2.975m11.963 0a9 9 0 10-11.963 0m11.963 0A8.966 8.966 0 0112 21a8.966 8.966 0 01-5.982-2.275M15 9.75a3 3 0 11-6 0 3 3 0 016 0z" /> </svg>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<!-- prettier-ignore -->
|
<!-- prettier-ignore -->
|
||||||
<h1 class="hidden md:inline font-extrabold text-lg dark:text-white ml-4">{{user.username}}</h1>
|
<h1 class="hidden md:inline font-extrabold text-lg dark:text-white ml-4">{{user.username}}</h1>
|
||||||
<!-- prettier-ignore -->
|
<!-- prettier-ignore -->
|
||||||
|
@ -33,7 +34,6 @@
|
||||||
<li class="mr-2 w-full md:w-auto" role="presentation">
|
<li class="mr-2 w-full md:w-auto" role="presentation">
|
||||||
<!-- prettier-ignore -->
|
<!-- prettier-ignore -->
|
||||||
<button class="inline-flex p-4 border-b-2 border-transparent rounded-t-lg hover:text-gray-600 hover:border-gray-300 dark:hover:text-gray-300" id="contributions-tab" data-tabs-target="#contributions" type="button" role="tab" aria-controls="contributions" aria-selected="false"><svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6 mr-3"> <path stroke-linecap="round" stroke-linejoin="round" d="M3.75 13.5l10.5-11.25L12 10.5h8.25L9.75 21.75 12 13.5H3.75z" /> </svg>
|
<button class="inline-flex p-4 border-b-2 border-transparent rounded-t-lg hover:text-gray-600 hover:border-gray-300 dark:hover:text-gray-300" id="contributions-tab" data-tabs-target="#contributions" type="button" role="tab" aria-controls="contributions" aria-selected="false"><svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6 mr-3"> <path stroke-linecap="round" stroke-linejoin="round" d="M3.75 13.5l10.5-11.25L12 10.5h8.25L9.75 21.75 12 13.5H3.75z" /> </svg>
|
||||||
|
|
||||||
Contributions
|
Contributions
|
||||||
</button>
|
</button>
|
||||||
</li>
|
</li>
|
||||||
|
@ -59,11 +59,11 @@
|
||||||
</span>
|
</span>
|
||||||
<span class="space-x-0.5 flex items-center">
|
<span class="space-x-0.5 flex items-center">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 22 22" stroke-width="1" stroke="currentColor" class="w-4 h-4 inline-flex mr-1"> <path stroke-linecap="round" stroke-linejoin="round" d="M3.75 13.5l10.5-11.25L12 10.5h8.25L9.75 21.75 12 13.5H3.75z" /> </svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 22 22" stroke-width="1" stroke="currentColor" class="w-4 h-4 inline-flex mr-1"> <path stroke-linecap="round" stroke-linejoin="round" d="M3.75 13.5l10.5-11.25L12 10.5h8.25L9.75 21.75 12 13.5H3.75z" /> </svg>
|
||||||
<p>55</p>
|
<p>{{ book.approved_interpretations|length }}</p>
|
||||||
</span>
|
</span>
|
||||||
<span class="space-x-0.5 flex items-center">
|
<span class="space-x-0.5 flex items-center">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 22 22" stroke-width="1" stroke="currentColor" class="w-4 h-4 inline-flex mr-1"> <path stroke-linecap="round" stroke-linejoin="round" d="M19.5 14.25v-2.625a3.375 3.375 0 00-3.375-3.375h-1.5A1.125 1.125 0 0113.5 7.125v-1.5a3.375 3.375 0 00-3.375-3.375H8.25m0 12.75h7.5m-7.5 3H12M10.5 2.25H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 00-9-9z" /> </svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 22 22" stroke-width="1" stroke="currentColor" class="w-4 h-4 inline-flex mr-1"> <path stroke-linecap="round" stroke-linejoin="round" d="M19.5 14.25v-2.625a3.375 3.375 0 00-3.375-3.375h-1.5A1.125 1.125 0 0113.5 7.125v-1.5a3.375 3.375 0 00-3.375-3.375H8.25m0 12.75h7.5m-7.5 3H12M10.5 2.25H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 00-9-9z" /> </svg>
|
||||||
<p>55</p>
|
<p>{{ book.approved_comments|length }}</p>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</dd>
|
</dd>
|
||||||
|
|
|
@ -1071,8 +1071,11 @@ def test_crud_comment(client: FlaskClient, runner: FlaskCliRunner):
|
||||||
def test_access_to_settings_page(client: FlaskClient):
|
def test_access_to_settings_page(client: FlaskClient):
|
||||||
_, user = login(client)
|
_, user = login(client)
|
||||||
|
|
||||||
book_1 = m.Book(label="test", about="test").save()
|
book_1 = m.Book(label="test", about="test", user_id=user.id).save()
|
||||||
|
m.BookVersion(semver="1.0.0", book_id=book_1.id).save()
|
||||||
|
|
||||||
book_2 = m.Book(label="test", about="test", user_id=user.id).save()
|
book_2 = m.Book(label="test", about="test", user_id=user.id).save()
|
||||||
|
m.BookVersion(semver="1.0.0", book_id=book_2.id).save()
|
||||||
|
|
||||||
response: Response = client.get(
|
response: Response = client.get(
|
||||||
f"/book/{book_1.id}/settings",
|
f"/book/{book_1.id}/settings",
|
||||||
|
@ -1080,7 +1083,6 @@ def test_access_to_settings_page(client: FlaskClient):
|
||||||
)
|
)
|
||||||
|
|
||||||
assert response.status_code == 200
|
assert response.status_code == 200
|
||||||
assert b"You are not owner of this book!" in response.data
|
|
||||||
|
|
||||||
response: Response = client.get(
|
response: Response = client.get(
|
||||||
f"/book/{book_2.id}/settings",
|
f"/book/{book_2.id}/settings",
|
||||||
|
|
|
@ -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
|
|
@ -120,6 +120,7 @@ def test_profile(client):
|
||||||
user_id=user.id,
|
user_id=user.id,
|
||||||
)
|
)
|
||||||
book.save()
|
book.save()
|
||||||
|
m.BookVersion(semver="1.0.0", book_id=book.id).save()
|
||||||
assert book
|
assert book
|
||||||
|
|
||||||
# profile page
|
# profile page
|
||||||
|
|
Loading…
Reference in New Issue