diff --git a/pgcommitfest/commitfest/ajax.py b/pgcommitfest/commitfest/ajax.py index 8137dfdf..1592e800 100644 --- a/pgcommitfest/commitfest/ajax.py +++ b/pgcommitfest/commitfest/ajax.py @@ -87,13 +87,19 @@ def getThreads(request): else: attachonly = 0 - # Make a JSON api call to the archives server + # Make a JSON api call to the archives server for each list. A message + # that was sent to more than one list is only returned once. params = {"n": 100, "a": attachonly} if search: params["s"] = search - r = _archivesAPI("/list/pgsql-hackers/latest.json", params) - return sorted(r, key=lambda x: x["date"], reverse=True) + messages = {} + for listname in ("pgsql-hackers", "pgsql-bugs"): + for m in _archivesAPI("/list/%s/latest.json" % listname, params): + messages.setdefault(m["msgid"], m) + + r = sorted(messages.values(), key=lambda x: x["date"], reverse=True) + return r[: params["n"]] def getMessages(request): diff --git a/pgcommitfest/commitfest/tests/test_get_threads.py b/pgcommitfest/commitfest/tests/test_get_threads.py new file mode 100644 index 00000000..6ca209d6 --- /dev/null +++ b/pgcommitfest/commitfest/tests/test_get_threads.py @@ -0,0 +1,38 @@ +from django.test import RequestFactory + +from unittest.mock import patch + +from pgcommitfest.commitfest.ajax import getThreads + + +def _msg(msgid, date): + return {"msgid": msgid, "date": date, "from": "a@example.com", "subj": msgid} + + +def test_get_threads_searches_hackers_and_bugs(): + hackers = [ + _msg("h%d" % i, "2026-01-01T%02d:%02d:00" % (i // 60, i % 60)) + for i in range(100) + ] + # b1 is newer than everything on hackers, h99 was sent to both lists + bugs = [_msg("b1", "2026-01-02T00:00:00"), hackers[99]] + + def fake(suburl, params=None): + return { + "/list/pgsql-hackers/latest.json": hackers, + "/list/pgsql-bugs/latest.json": bugs, + }[suburl] + + request = RequestFactory().get("/ajax/getThreads/", {"s": "x", "a": "1"}) + with patch("pgcommitfest.commitfest.ajax._archivesAPI", side_effect=fake) as api: + result = getThreads(request) + + assert [c.args for c in api.call_args_list] == [ + ("/list/pgsql-hackers/latest.json", {"n": 100, "a": 1, "s": "x"}), + ("/list/pgsql-bugs/latest.json", {"n": 100, "a": 1, "s": "x"}), + ] + # Merged newest first, h99 deduplicated, and capped at 100 so the oldest + # message (h0) is dropped. + assert [m["msgid"] for m in result] == ["b1"] + [ + "h%d" % i for i in range(99, 0, -1) + ]