Skip to content

Commit c2d0a5a

Browse files
authored
Allow ordering messages by received date ascending (#1017)
1 parent 857ba29 commit c2d0a5a

File tree

3 files changed

+46
-16
lines changed

3 files changed

+46
-16
lines changed

inbox/api/filtering.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,7 @@ def messages_or_drafts( # type: ignore[no-untyped-def] # noqa: ANN201
237237
in_,
238238
unread,
239239
starred,
240+
order_by,
240241
limit,
241242
offset,
242243
view,
@@ -476,7 +477,15 @@ def messages_or_drafts( # type: ignore[no-untyped-def] # noqa: ANN201
476477
res = query.params(**param_dict).one()[0]
477478
return {"count": res}
478479

479-
query = query.order_by(desc(Message.received_date))
480+
if not order_by:
481+
query = query.order_by(desc(Message.received_date))
482+
elif order_by == "received_date":
483+
query = query.order_by(asc(Message.received_date))
484+
elif order_by == "-received_date":
485+
query = query.order_by(desc(Message.received_date))
486+
else:
487+
raise ValueError(f"Unknown 'order_by' value: '{order_by}'")
488+
480489
query = query.limit(bindparam("limit"))
481490
if offset:
482491
query = query.offset(bindparam("offset"))

inbox/api/ns_api.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -554,6 +554,7 @@ def message_query_api(): # type: ignore[no-untyped-def] # noqa: ANN201
554554
g.parser.add_argument("thread_id", type=valid_public_id, location="args")
555555
g.parser.add_argument("unread", type=strict_bool, location="args")
556556
g.parser.add_argument("starred", type=strict_bool, location="args")
557+
g.parser.add_argument("order_by", type=bounded_str, location="args")
557558
g.parser.add_argument("view", type=view, location="args")
558559

559560
args = strict_parse_args(g.parser, request.args)
@@ -578,6 +579,7 @@ def message_query_api(): # type: ignore[no-untyped-def] # noqa: ANN201
578579
in_=args["in"],
579580
unread=args["unread"],
580581
starred=args["starred"],
582+
order_by=args["order_by"],
581583
limit=args["limit"],
582584
offset=args["offset"],
583585
view=args["view"],
@@ -1739,6 +1741,7 @@ def draft_query_api(): # type: ignore[no-untyped-def] # noqa: ANN201
17391741
g.parser.add_argument("thread_id", type=valid_public_id, location="args")
17401742
g.parser.add_argument("unread", type=strict_bool, location="args")
17411743
g.parser.add_argument("starred", type=strict_bool, location="args")
1744+
g.parser.add_argument("order_by", type=bounded_str, location="args")
17421745
g.parser.add_argument("view", type=view, location="args")
17431746

17441747
args = strict_parse_args(g.parser, request.args)
@@ -1763,6 +1766,7 @@ def draft_query_api(): # type: ignore[no-untyped-def] # noqa: ANN201
17631766
in_=args["in"],
17641767
unread=args["unread"],
17651768
starred=args["starred"],
1769+
order_by=args["order_by"],
17661770
limit=args["limit"],
17671771
offset=args["offset"],
17681772
view=args["view"],

tests/api/test_filtering.py

Lines changed: 32 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,7 @@
22
import datetime
33
import json
44

5-
from sqlalchemy import desc
6-
7-
from inbox.models import Block, Category, Message, Namespace, Thread
5+
from inbox.models import Block, Category, Namespace, Thread
86
from inbox.util.misc import dt_to_timestamp
97
from tests.util.base import add_fake_message, add_fake_thread, test_client
108

@@ -256,27 +254,46 @@ def test_query_target(db, api_client, thread, default_namespace):
256254

257255

258256
def test_ordering(api_client, db, default_namespace):
257+
thr = add_fake_thread(db.session, default_namespace.id)
258+
messages = []
259259
for i in range(3):
260-
thr = add_fake_thread(db.session, default_namespace.id)
261260
received_date = datetime.datetime.utcnow() + datetime.timedelta(
262261
seconds=22 * (i + 1)
263262
)
264-
add_fake_message(
265-
db.session, default_namespace.id, thr, received_date=received_date
263+
messages.append(
264+
add_fake_message(
265+
db.session,
266+
default_namespace.id,
267+
thr,
268+
received_date=received_date,
269+
)
266270
)
271+
267272
ordered_results = api_client.get_data("/messages")
273+
ordered_ids = [result["id"] for result in ordered_results]
268274
ordered_dates = [result["date"] for result in ordered_results]
275+
assert ordered_ids == list(reversed([m.public_id for m in messages]))
269276
assert ordered_dates == sorted(ordered_dates, reverse=True)
270277

271-
ordered_results = api_client.get_data("/messages?limit=3")
272-
expected_public_ids = [
273-
public_id
274-
for public_id, in db.session.query(Message.public_id)
275-
.filter(Message.namespace_id == default_namespace.id)
276-
.order_by(desc(Message.received_date))
277-
.limit(3)
278-
]
279-
assert expected_public_ids == [r["id"] for r in ordered_results]
278+
ordered_results = api_client.get_data("/messages?order_by=received_date")
279+
ordered_ids = [result["id"] for result in ordered_results]
280+
ordered_dates = [result["date"] for result in ordered_results]
281+
assert ordered_ids == [m.public_id for m in messages]
282+
assert ordered_dates == sorted(ordered_dates)
283+
284+
ordered_results = api_client.get_data("/messages?order_by=-received_date")
285+
ordered_ids = [result["id"] for result in ordered_results]
286+
ordered_dates = [result["date"] for result in ordered_results]
287+
assert ordered_ids == list(reversed([m.public_id for m in messages]))
288+
assert ordered_dates == sorted(ordered_dates, reverse=True)
289+
290+
response = api_client.get_data("/messages?order_by=nonsense")
291+
assert response == {
292+
"message": (
293+
"An internal error occured. If this issue persists, please contact"
294+
" [email protected] and include this request_uid: None"
295+
)
296+
}
280297

281298

282299
def test_strict_argument_parsing(api_client):

0 commit comments

Comments
 (0)