Skip to content
Snippets Groups Projects
Commit efb7d92b authored by jan.bednarik's avatar jan.bednarik
Browse files

Exclude superseded reports from results and agregates

parent 4c34d202
Branches
No related tags found
No related merge requests found
...@@ -36,9 +36,7 @@ class SearchReportsConnection(relay.Connection): ...@@ -36,9 +36,7 @@ class SearchReportsConnection(relay.Connection):
def _get_authors_cache(ids): def _get_authors_cache(ids):
authors = User.objects.filter(id__in=ids).annotate( authors = User.objects.with_total_reports().filter(id__in=ids)
total_reports=Count("report", filter=Q(report__is_draft=False))
)
return {a.id: types.Author.from_db(a) for a in authors} return {a.id: types.Author.from_db(a) for a in authors}
......
...@@ -154,9 +154,7 @@ class Author(graphene.ObjectType): ...@@ -154,9 +154,7 @@ class Author(graphene.ObjectType):
@classmethod @classmethod
def get_node(cls, info, id): def get_node(cls, info, id):
try: try:
author = models.User.objects.annotate( author = models.User.objects.with_total_reports().get(id=id, is_author=True)
total_reports=Count("report", filter=Q(report__is_draft=False))
).get(id=id, is_author=True)
return cls.from_db(author) return cls.from_db(author)
except models.User.DoesNotExist: except models.User.DoesNotExist:
return None return None
...@@ -176,7 +174,9 @@ class Author(graphene.ObjectType): ...@@ -176,7 +174,9 @@ class Author(graphene.ObjectType):
return ReportConnection(page_info=page_info, edges=edges, total_count=total) return ReportConnection(page_info=page_info, edges=edges, total_count=total)
def resolve_total_reports(self, info, **kwargs): def resolve_total_reports(self, info, **kwargs):
return models.Report.objects.filter(author_id=self.id, is_draft=False).count() return models.Report.objects.filter(
author_id=self.id, is_draft=False, superseded_by=None
).count()
class LoginShortcut(graphene.ObjectType): class LoginShortcut(graphene.ObjectType):
......
...@@ -19,7 +19,7 @@ class ReportDoc(DocType): ...@@ -19,7 +19,7 @@ class ReportDoc(DocType):
other_participants = fields.TextField(analyzer=settings.ES_TEXT_ANALYZER) other_participants = fields.TextField(analyzer=settings.ES_TEXT_ANALYZER)
# there is no support for JSONField now, so we serialize it to keyword # there is no support for JSONField now, so we serialize it to keyword
extra_serialized = fields.KeywordField() extra_serialized = fields.KeywordField()
superseded_by = fields.IntegerField() superseded_by_id = fields.IntegerField()
def prepare_extra_serialized(self, instance): def prepare_extra_serialized(self, instance):
return json.dumps(instance.extra) return json.dumps(instance.extra)
......
...@@ -10,6 +10,14 @@ from django.utils import timezone ...@@ -10,6 +10,14 @@ from django.utils import timezone
class CustomUserManager(UserManager): class CustomUserManager(UserManager):
def with_total_reports(self):
return self.get_queryset().annotate(
total_reports=Count(
"report",
filter=Q(report__is_draft=False) & Q(report__superseded_by=None),
)
)
def sorted(self, **kwargs): def sorted(self, **kwargs):
# inline import intentionally # inline import intentionally
from openlobby.core.api.schema import ( from openlobby.core.api.schema import (
...@@ -17,9 +25,7 @@ class CustomUserManager(UserManager): ...@@ -17,9 +25,7 @@ class CustomUserManager(UserManager):
AUTHOR_SORT_TOTAL_REPORTS_ID, AUTHOR_SORT_TOTAL_REPORTS_ID,
) )
qs = self.get_queryset().annotate( qs = self.with_total_reports()
total_reports=Count("report", filter=Q(report__is_draft=False))
)
sort_field = kwargs.get("sort", AUTHOR_SORT_LAST_NAME_ID) sort_field = kwargs.get("sort", AUTHOR_SORT_LAST_NAME_ID)
if sort_field == AUTHOR_SORT_LAST_NAME_ID: if sort_field == AUTHOR_SORT_LAST_NAME_ID:
......
...@@ -19,6 +19,7 @@ def query_reports(query, paginator, *, highlight=False): ...@@ -19,6 +19,7 @@ def query_reports(query, paginator, *, highlight=False):
] ]
s = ReportDoc.search() s = ReportDoc.search()
s = s.exclude("term", is_draft=True) s = s.exclude("term", is_draft=True)
s = s.exclude("exists", field="superseded_by_id")
if query != "": if query != "":
s = s.query("multi_match", query=query, fields=fields) s = s.query("multi_match", query=query, fields=fields)
if highlight: if highlight:
...@@ -31,6 +32,7 @@ def query_reports(query, paginator, *, highlight=False): ...@@ -31,6 +32,7 @@ def query_reports(query, paginator, *, highlight=False):
def reports_by_author(author_id, paginator): def reports_by_author(author_id, paginator):
s = ReportDoc.search() s = ReportDoc.search()
s = s.exclude("term", is_draft=True) s = s.exclude("term", is_draft=True)
s = s.exclude("exists", field="superseded_by_id")
s = s.filter("term", author_id=author_id) s = s.filter("term", author_id=author_id)
s = s.sort("-date") s = s.sort("-date")
s = s[paginator.slice_from : paginator.slice_to] s = s[paginator.slice_from : paginator.slice_to]
......
...@@ -14,16 +14,16 @@ authors = [ ...@@ -14,16 +14,16 @@ authors = [
}, },
{ {
"id": 2, "id": 2,
"username": "sponge", "username": "shaun",
"first_name": "Spongebob", "first_name": "Shaun",
"last_name": "Squarepants", "last_name": "Sheep",
"is_author": True, "is_author": True,
}, },
{ {
"id": 3, "id": 3,
"username": "shaun", "username": "sponge",
"first_name": "Shaun", "first_name": "Spongebob",
"last_name": "Sheep", "last_name": "Squarepants",
"is_author": True, "is_author": True,
}, },
] ]
...@@ -92,6 +92,47 @@ reports = [ ...@@ -92,6 +92,47 @@ reports = [
"other_participants": "", "other_participants": "",
"is_draft": True, "is_draft": True,
}, },
{
"id": 6,
"superseded_by_id": 2,
"date": arrow.get(2018, 1, 3).datetime,
"published": arrow.get(2018, 1, 4).datetime,
"edited": arrow.get(2018, 2, 1).datetime,
"title": "The Two Towers",
"body": "Another long story in progress.",
"received_benefit": "Mithrill Jacket",
"provided_benefit": "The Ring",
"our_participants": "Frodo, Gimli, Legolas",
"other_participants": "Saruman, Sauron",
"extra": {"rings": 2},
},
{
"id": 7,
"superseded_by_id": 2,
"date": arrow.get(2018, 1, 3).datetime,
"published": arrow.get(2018, 1, 4).datetime,
"edited": arrow.get(2018, 2, 5).datetime,
"title": "The Towels",
"body": "What am I doing?",
"received_benefit": "Jacket",
"provided_benefit": "The Ringo",
"our_participants": "Ringo Starr",
"other_participants": "",
"extra": {"rings": 1},
},
{
"id": 8,
"superseded_by_id": 1,
"date": arrow.get(2018, 1, 1).datetime,
"published": arrow.get(2018, 1, 2).datetime,
"edited": arrow.get(2018, 1, 3).datetime,
"title": "The Fellowship of the Ringing Bell",
"body": "The bell is ringing!",
"received_benefit": "bell",
"provided_benefit": "noise",
"our_participants": "",
"other_participants": "",
},
] ]
...@@ -104,6 +145,9 @@ def prepare_reports(): ...@@ -104,6 +145,9 @@ def prepare_reports():
Report.objects.create(author=author1, **reports[2]) Report.objects.create(author=author1, **reports[2])
Report.objects.create(author=author1, **reports[3]) Report.objects.create(author=author1, **reports[3])
Report.objects.create(author=author3, **reports[4]) Report.objects.create(author=author3, **reports[4])
Report.objects.create(author=author2, **reports[5])
Report.objects.create(author=author2, **reports[6])
Report.objects.create(author=author1, **reports[7])
def prepare_author(): def prepare_author():
......
...@@ -17,9 +17,9 @@ snapshots["test_all 1"] = { ...@@ -17,9 +17,9 @@ snapshots["test_all 1"] = {
"extra": None, "extra": None,
"firstName": "Shaun", "firstName": "Shaun",
"hasCollidingName": False, "hasCollidingName": False,
"id": "QXV0aG9yOjM=", "id": "QXV0aG9yOjI=",
"lastName": "Sheep", "lastName": "Sheep",
"totalReports": 0, "totalReports": 1,
}, },
}, },
{ {
...@@ -28,9 +28,9 @@ snapshots["test_all 1"] = { ...@@ -28,9 +28,9 @@ snapshots["test_all 1"] = {
"extra": None, "extra": None,
"firstName": "Spongebob", "firstName": "Spongebob",
"hasCollidingName": False, "hasCollidingName": False,
"id": "QXV0aG9yOjI=", "id": "QXV0aG9yOjM=",
"lastName": "Squarepants", "lastName": "Squarepants",
"totalReports": 1, "totalReports": 0,
}, },
}, },
{ {
...@@ -66,9 +66,9 @@ snapshots["test_first 1"] = { ...@@ -66,9 +66,9 @@ snapshots["test_first 1"] = {
"extra": None, "extra": None,
"firstName": "Shaun", "firstName": "Shaun",
"hasCollidingName": False, "hasCollidingName": False,
"id": "QXV0aG9yOjM=", "id": "QXV0aG9yOjI=",
"lastName": "Sheep", "lastName": "Sheep",
"totalReports": 0, "totalReports": 1,
}, },
}, },
{ {
...@@ -77,9 +77,9 @@ snapshots["test_first 1"] = { ...@@ -77,9 +77,9 @@ snapshots["test_first 1"] = {
"extra": None, "extra": None,
"firstName": "Spongebob", "firstName": "Spongebob",
"hasCollidingName": False, "hasCollidingName": False,
"id": "QXV0aG9yOjI=", "id": "QXV0aG9yOjM=",
"lastName": "Squarepants", "lastName": "Squarepants",
"totalReports": 1, "totalReports": 0,
}, },
}, },
], ],
...@@ -104,9 +104,9 @@ snapshots["test_first_after 1"] = { ...@@ -104,9 +104,9 @@ snapshots["test_first_after 1"] = {
"extra": None, "extra": None,
"firstName": "Spongebob", "firstName": "Spongebob",
"hasCollidingName": False, "hasCollidingName": False,
"id": "QXV0aG9yOjI=", "id": "QXV0aG9yOjM=",
"lastName": "Squarepants", "lastName": "Squarepants",
"totalReports": 1, "totalReports": 0,
}, },
} }
], ],
...@@ -142,9 +142,9 @@ snapshots["test_last_before 1"] = { ...@@ -142,9 +142,9 @@ snapshots["test_last_before 1"] = {
"extra": None, "extra": None,
"firstName": "Spongebob", "firstName": "Spongebob",
"hasCollidingName": False, "hasCollidingName": False,
"id": "QXV0aG9yOjI=", "id": "QXV0aG9yOjM=",
"lastName": "Squarepants", "lastName": "Squarepants",
"totalReports": 1, "totalReports": 0,
}, },
} }
], ],
...@@ -168,19 +168,8 @@ snapshots["test_with_reports 1"] = { ...@@ -168,19 +168,8 @@ snapshots["test_with_reports 1"] = {
"extra": None, "extra": None,
"firstName": "Shaun", "firstName": "Shaun",
"hasCollidingName": False, "hasCollidingName": False,
"id": "QXV0aG9yOjM=",
"lastName": "Sheep",
"reports": {"edges": [], "totalCount": 0},
"totalReports": 0,
}
},
{
"node": {
"extra": None,
"firstName": "Spongebob",
"hasCollidingName": False,
"id": "QXV0aG9yOjI=", "id": "QXV0aG9yOjI=",
"lastName": "Squarepants", "lastName": "Sheep",
"reports": { "reports": {
"edges": [ "edges": [
{ {
...@@ -206,6 +195,17 @@ snapshots["test_with_reports 1"] = { ...@@ -206,6 +195,17 @@ snapshots["test_with_reports 1"] = {
"totalReports": 1, "totalReports": 1,
} }
}, },
{
"node": {
"extra": None,
"firstName": "Spongebob",
"hasCollidingName": False,
"id": "QXV0aG9yOjM=",
"lastName": "Squarepants",
"reports": {"edges": [], "totalCount": 0},
"totalReports": 0,
}
},
{ {
"node": { "node": {
"extra": '{"movies": 1}', "extra": '{"movies": 1}',
...@@ -270,9 +270,9 @@ snapshots["test_sort_by_last_name 1"] = { ...@@ -270,9 +270,9 @@ snapshots["test_sort_by_last_name 1"] = {
"extra": None, "extra": None,
"firstName": "Shaun", "firstName": "Shaun",
"hasCollidingName": False, "hasCollidingName": False,
"id": "QXV0aG9yOjM=", "id": "QXV0aG9yOjI=",
"lastName": "Sheep", "lastName": "Sheep",
"totalReports": 0, "totalReports": 1,
}, },
}, },
{ {
...@@ -281,9 +281,9 @@ snapshots["test_sort_by_last_name 1"] = { ...@@ -281,9 +281,9 @@ snapshots["test_sort_by_last_name 1"] = {
"extra": None, "extra": None,
"firstName": "Spongebob", "firstName": "Spongebob",
"hasCollidingName": False, "hasCollidingName": False,
"id": "QXV0aG9yOjI=", "id": "QXV0aG9yOjM=",
"lastName": "Squarepants", "lastName": "Squarepants",
"totalReports": 1, "totalReports": 0,
}, },
}, },
{ {
...@@ -330,9 +330,9 @@ snapshots["test_sort_by_last_name_reversed 1"] = { ...@@ -330,9 +330,9 @@ snapshots["test_sort_by_last_name_reversed 1"] = {
"extra": None, "extra": None,
"firstName": "Spongebob", "firstName": "Spongebob",
"hasCollidingName": False, "hasCollidingName": False,
"id": "QXV0aG9yOjI=", "id": "QXV0aG9yOjM=",
"lastName": "Squarepants", "lastName": "Squarepants",
"totalReports": 1, "totalReports": 0,
}, },
}, },
{ {
...@@ -341,9 +341,9 @@ snapshots["test_sort_by_last_name_reversed 1"] = { ...@@ -341,9 +341,9 @@ snapshots["test_sort_by_last_name_reversed 1"] = {
"extra": None, "extra": None,
"firstName": "Shaun", "firstName": "Shaun",
"hasCollidingName": False, "hasCollidingName": False,
"id": "QXV0aG9yOjM=", "id": "QXV0aG9yOjI=",
"lastName": "Sheep", "lastName": "Sheep",
"totalReports": 0, "totalReports": 1,
}, },
}, },
], ],
...@@ -377,10 +377,10 @@ snapshots["test_sort_by_total_reports 1"] = { ...@@ -377,10 +377,10 @@ snapshots["test_sort_by_total_reports 1"] = {
"cursor": "Mg==", "cursor": "Mg==",
"node": { "node": {
"extra": None, "extra": None,
"firstName": "Spongebob", "firstName": "Shaun",
"hasCollidingName": False, "hasCollidingName": False,
"id": "QXV0aG9yOjI=", "id": "QXV0aG9yOjI=",
"lastName": "Squarepants", "lastName": "Sheep",
"totalReports": 1, "totalReports": 1,
}, },
}, },
...@@ -388,10 +388,10 @@ snapshots["test_sort_by_total_reports 1"] = { ...@@ -388,10 +388,10 @@ snapshots["test_sort_by_total_reports 1"] = {
"cursor": "Mw==", "cursor": "Mw==",
"node": { "node": {
"extra": None, "extra": None,
"firstName": "Shaun", "firstName": "Spongebob",
"hasCollidingName": False, "hasCollidingName": False,
"id": "QXV0aG9yOjM=", "id": "QXV0aG9yOjM=",
"lastName": "Sheep", "lastName": "Squarepants",
"totalReports": 0, "totalReports": 0,
}, },
}, },
...@@ -415,10 +415,10 @@ snapshots["test_sort_by_total_reports_reversed 1"] = { ...@@ -415,10 +415,10 @@ snapshots["test_sort_by_total_reports_reversed 1"] = {
"cursor": "MQ==", "cursor": "MQ==",
"node": { "node": {
"extra": None, "extra": None,
"firstName": "Shaun", "firstName": "Spongebob",
"hasCollidingName": False, "hasCollidingName": False,
"id": "QXV0aG9yOjM=", "id": "QXV0aG9yOjM=",
"lastName": "Sheep", "lastName": "Squarepants",
"totalReports": 0, "totalReports": 0,
}, },
}, },
...@@ -426,10 +426,10 @@ snapshots["test_sort_by_total_reports_reversed 1"] = { ...@@ -426,10 +426,10 @@ snapshots["test_sort_by_total_reports_reversed 1"] = {
"cursor": "Mg==", "cursor": "Mg==",
"node": { "node": {
"extra": None, "extra": None,
"firstName": "Spongebob", "firstName": "Shaun",
"hasCollidingName": False, "hasCollidingName": False,
"id": "QXV0aG9yOjI=", "id": "QXV0aG9yOjI=",
"lastName": "Squarepants", "lastName": "Sheep",
"totalReports": 1, "totalReports": 1,
}, },
}, },
...@@ -477,9 +477,9 @@ snapshots["test_sort_by_default_reversed 1"] = { ...@@ -477,9 +477,9 @@ snapshots["test_sort_by_default_reversed 1"] = {
"extra": None, "extra": None,
"firstName": "Spongebob", "firstName": "Spongebob",
"hasCollidingName": False, "hasCollidingName": False,
"id": "QXV0aG9yOjI=", "id": "QXV0aG9yOjM=",
"lastName": "Squarepants", "lastName": "Squarepants",
"totalReports": 1, "totalReports": 0,
}, },
}, },
{ {
...@@ -488,9 +488,9 @@ snapshots["test_sort_by_default_reversed 1"] = { ...@@ -488,9 +488,9 @@ snapshots["test_sort_by_default_reversed 1"] = {
"extra": None, "extra": None,
"firstName": "Shaun", "firstName": "Shaun",
"hasCollidingName": False, "hasCollidingName": False,
"id": "QXV0aG9yOjM=", "id": "QXV0aG9yOjI=",
"lastName": "Sheep", "lastName": "Sheep",
"totalReports": 0, "totalReports": 1,
}, },
}, },
], ],
......
...@@ -41,10 +41,10 @@ snapshots["test_all 1"] = { ...@@ -41,10 +41,10 @@ snapshots["test_all 1"] = {
"node": { "node": {
"author": { "author": {
"extra": None, "extra": None,
"firstName": "Spongebob", "firstName": "Shaun",
"hasCollidingName": False, "hasCollidingName": False,
"id": "QXV0aG9yOjI=", "id": "QXV0aG9yOjI=",
"lastName": "Squarepants", "lastName": "Sheep",
"totalReports": 1, "totalReports": 1,
}, },
"body": "Another long story.", "body": "Another long story.",
...@@ -107,10 +107,10 @@ snapshots["test_query 1"] = { ...@@ -107,10 +107,10 @@ snapshots["test_query 1"] = {
"node": { "node": {
"author": { "author": {
"extra": None, "extra": None,
"firstName": "Spongebob", "firstName": "Shaun",
"hasCollidingName": False, "hasCollidingName": False,
"id": "QXV0aG9yOjI=", "id": "QXV0aG9yOjI=",
"lastName": "Squarepants", "lastName": "Sheep",
"totalReports": 1, "totalReports": 1,
}, },
"body": "Another long story.", "body": "Another long story.",
......
...@@ -10,6 +10,8 @@ from openlobby.core.api.schema import ( ...@@ -10,6 +10,8 @@ from openlobby.core.api.schema import (
from openlobby.core.documents import ReportDoc from openlobby.core.documents import ReportDoc
from openlobby.core.models import Report, User, OpenIdClient, LoginAttempt from openlobby.core.models import Report, User, OpenIdClient, LoginAttempt
from .dummy import prepare_reports
pytestmark = [pytest.mark.django_db, pytest.mark.usefixtures("django_es")] pytestmark = [pytest.mark.django_db, pytest.mark.usefixtures("django_es")]
...@@ -34,6 +36,7 @@ def test_report__is_saved_in_elasticsearch(): ...@@ -34,6 +36,7 @@ def test_report__is_saved_in_elasticsearch():
date = arrow.get(2018, 1, 1).datetime date = arrow.get(2018, 1, 1).datetime
published = arrow.get(2018, 1, 2).datetime published = arrow.get(2018, 1, 2).datetime
edited = arrow.get(2018, 1, 3).datetime edited = arrow.get(2018, 1, 3).datetime
replacement = Report.objects.create(id=4, author=author, date=date, body="IDDQD")
Report.objects.create( Report.objects.create(
id=3, id=3,
author=author, author=author,
...@@ -48,12 +51,14 @@ def test_report__is_saved_in_elasticsearch(): ...@@ -48,12 +51,14 @@ def test_report__is_saved_in_elasticsearch():
other_participants="them", other_participants="them",
extra={"a": 3}, extra={"a": 3},
is_draft=False, is_draft=False,
superseded_by=replacement,
) )
docs = list(ReportDoc.search()) docs = list(ReportDoc.search())
assert len(docs) == 1 assert len(docs) == 2
doc = docs[0] doc = docs[1]
assert doc.meta.id == "3" assert doc.meta.id == "3"
assert doc.author_id == 6 assert doc.author_id == 6
assert doc.superseded_by_id == 4
assert doc.date == date assert doc.date == date
assert doc.published == published assert doc.published == published
assert doc.edited == edited assert doc.edited == edited
...@@ -141,74 +146,39 @@ def test_user__name_collision_excludes_self_on_update(): ...@@ -141,74 +146,39 @@ def test_user__name_collision_excludes_self_on_update():
assert User.objects.get(username="a").has_colliding_name is False assert User.objects.get(username="a").has_colliding_name is False
def test_user__sorted_default(): @pytest.mark.parametrize(
User.objects.create( "params, expected",
username="a", is_author=False, first_name="Ryan", last_name="AGosling" [
) ({}, ["Sheep", "Squarepants", "Wolfe"]),
User.objects.create( ({"reversed": False}, ["Sheep", "Squarepants", "Wolfe"]),
username="b", is_author=True, first_name="Ryan", last_name="BGosling" ({"reversed": True}, ["Wolfe", "Squarepants", "Sheep"]),
) ({"sort": AUTHOR_SORT_LAST_NAME_ID}, ["Sheep", "Squarepants", "Wolfe"]),
User.objects.create( (
username="c", is_author=False, first_name="Ryan", last_name="CGosling" {"sort": AUTHOR_SORT_LAST_NAME_ID, "reversed": False},
) ["Sheep", "Squarepants", "Wolfe"],
assert User.objects.sorted()[0].username == "a" ),
(
{"sort": AUTHOR_SORT_LAST_NAME_ID, "reversed": True},
def test_user__sorted_default_reversed(): ["Wolfe", "Squarepants", "Sheep"],
User.objects.create( ),
username="a", is_author=False, first_name="Ryan", last_name="AGosling" ({"sort": AUTHOR_SORT_TOTAL_REPORTS_ID}, ["Wolfe", "Sheep", "Squarepants"]),
) (
User.objects.create( {"sort": AUTHOR_SORT_TOTAL_REPORTS_ID, "reversed": False},
username="b", is_author=True, first_name="Ryan", last_name="BGosling" ["Wolfe", "Sheep", "Squarepants"],
) ),
User.objects.create( (
username="c", is_author=False, first_name="Ryan", last_name="CGosling" {"sort": AUTHOR_SORT_TOTAL_REPORTS_ID, "reversed": True},
) ["Squarepants", "Sheep", "Wolfe"],
assert User.objects.sorted(reversed=True)[0].username == "c" ),
],
)
def test_user__sorted_last_name(): def test_user__sorted(params, expected):
User.objects.create( prepare_reports()
username="a", is_author=False, first_name="Ryan", last_name="AGosling" last_names = User.objects.sorted(**params).values_list("last_name", flat=True)
) assert list(last_names) == expected
User.objects.create(
username="b", is_author=True, first_name="Ryan", last_name="BGosling"
)
User.objects.create(
username="c", is_author=False, first_name="Ryan", last_name="CGosling"
)
assert User.objects.sorted(sort=AUTHOR_SORT_LAST_NAME_ID)[0].username == "a"
assert (
User.objects.sorted(sort=AUTHOR_SORT_LAST_NAME_ID, reversed=False)[0].username
== "a"
)
assert (
User.objects.sorted(sort=AUTHOR_SORT_LAST_NAME_ID, reversed=True)[0].username
== "c"
)
def test_user__sorted_total_reports(): def test_user__with_total_reports():
author = User.objects.create( prepare_reports()
username="a", is_author=True, first_name="Ryan", last_name="AGosling" users = User.objects.with_total_reports().values_list("last_name", "total_reports")
) assert set(users) == {("Wolfe", 2), ("Sheep", 1), ("Squarepants", 0)}
User.objects.create(
username="b", is_author=True, first_name="Ryan", last_name="BGosling"
)
date = arrow.get(2018, 1, 1).datetime
Report.objects.create(
id=7, author=author, date=date, published=date, body="Lorem ipsum."
)
assert User.objects.sorted(sort=AUTHOR_SORT_TOTAL_REPORTS_ID)[0].username == "a"
assert (
User.objects.sorted(sort=AUTHOR_SORT_TOTAL_REPORTS_ID, reversed=False)[
0
].username
== "a"
)
assert (
User.objects.sorted(sort=AUTHOR_SORT_TOTAL_REPORTS_ID, reversed=True)[
0
].username
== "b"
)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment