From 51a0a516c48d93b0cb0c1677f9cb6440edaae70c Mon Sep 17 00:00:00 2001 From: Sarah Boyce <42296566+sarahboyce@users.noreply.github.com> Date: Tue, 26 Nov 2024 15:36:08 +0100 Subject: [PATCH] Fixed "Commiter" stat Revision query git commit author format. --- accounts/tests.py | 47 ++++++++++++++++++++++++++++++++++++++--------- accounts/views.py | 2 +- tracdb/stats.py | 29 ++++++++++++++++------------- 3 files changed, 55 insertions(+), 23 deletions(-) diff --git a/accounts/tests.py b/accounts/tests.py index bc6c48e50..93fa97128 100644 --- a/accounts/tests.py +++ b/accounts/tests.py @@ -21,32 +21,61 @@ def test_username_is_page_title(self): response = self.client.get(self.user1_url) self.assertContains(response, "

user1

", html=True) - def test_stat_commits(self): + def test_stat_commits_no_commits(self): + user1_response = self.client.get(self.user1_url) + self.assertNotContains(user1_response, "Commits") + + def test_stat_commits_commiter_full_name(self): + User.objects.create_user( + first_name="James", + last_name="Bond", + username="007", + email="007@mi5.co.uk", + password="*****************", + ) Revision.objects.create( - author="user1", + author="James Bond <007@mi5.co.uk>", rev="91c879eda595c12477bbfa6f51115e88b75ddf88", _time=1731669560, ) Revision.objects.create( - author="user1", + author="James Bonderson ", rev="da2432cccae841f0d7629f17a5d79ec47ed7b7cb", _time=1731669560, ) + user1_response = self.client.get(reverse("user_profile", args=["007"])) + self.assertContains( + user1_response, + 'Commits: 1.', + html=True, + ) + + def test_stat_commits_commiter_username(self): + User.objects.create_user( + first_name="James", + last_name="Bond", + username="007", + email="007@mi5.co.uk", + password="*****************", + ) Revision.objects.create( - author="user3", + author="007 <007@mi5.co.uk>", + rev="91c879eda595c12477bbfa6f51115e88b75ddf88", + _time=1731669560, + ) + Revision.objects.create( + author="Elizabeth Bennet <300792567+pnp@users.noreply.github.com>", rev="63dbe30d3363715deaf280214d75b03f6d65a571", _time=1731669560, ) - - user1_response = self.client.get(self.user1_url) - user2_response = self.client.get(self.user2_url) + user1_response = self.client.get(reverse("user_profile", args=["007"])) self.assertContains( user1_response, 'Commits: 2.', + '?author=007">Commits: 1.', html=True, ) - self.assertNotContains(user2_response, "Commits") def test_stat_tickets(self): Ticket.objects.create(status="new", reporter="user1") diff --git a/accounts/views.py b/accounts/views.py index bbdf888db..81b1303b4 100644 --- a/accounts/views.py +++ b/accounts/views.py @@ -40,7 +40,7 @@ def get_user_stats(user): key = "user_vital_status:%s" % hashlib.md5(username).hexdigest() info = c.get(key) if info is None: - info = trac_stats.get_user_stats(user.username) + info = trac_stats.get_user_stats(user) # Hide any stat with a value = 0 so that we don't accidentally insult # non-contributors. for k, v in list(info.items()): diff --git a/tracdb/stats.py b/tracdb/stats.py index 2cfa6c1b2..853c17933 100644 --- a/tracdb/stats.py +++ b/tracdb/stats.py @@ -6,6 +6,7 @@ from collections import OrderedDict, namedtuple from django.conf import settings +from django.db.models import Q from .models import Revision, Ticket, TicketChange @@ -34,44 +35,46 @@ def _inner(f): return _inner -def get_user_stats(username): +def get_user_stats(user): stats = OrderedDict() for func in sorted(_statfuncs, key=operator.attrgetter("title")): - stats[func.title] = func(username) + stats[func.title] = func(user) return stats @stat("Commits") -def commit_count(username): - count = Revision.objects.filter(author=username).count() - # This assumes that the username is their GitHub username, this is very - # often the case. If this is incorrect, the GitHub will show no commits. - link = f"https://github.com/django/django/commits/main/?author={username}" +def commit_count(user): + count = Revision.objects.filter( + Q(author__istartswith=f"{user.username} <") + | Q(author__istartswith=f"{user.get_full_name()} <") + ).count() + # This assumes that the username is their GitHub username. + link = f"https://github.com/django/django/commits/main/?author={user.username}" return StatData(count=count, link=link) @stat("Tickets fixed") -def tickets_fixed(username): - query = f"owner={username}&resolution=fixed" +def tickets_fixed(user): + query = f"owner={user.username}&resolution=fixed" count = Ticket.objects.from_querystring(query).count() link = get_trac_link(query) return StatData(count=count, link=link) @stat("Tickets opened") -def tickets_opened(username): - query = f"reporter={username}" +def tickets_opened(user): + query = f"reporter={user.username}" count = Ticket.objects.from_querystring(query).count() link = get_trac_link(query) return StatData(count=count, link=link) @stat("New tickets triaged") -def new_tickets_reviewed(username): +def new_tickets_reviewed(user): # We don't want to de-dup as for tickets_closed: multiple reviews of the # same ticket should "count" as a review. qs = TicketChange.objects.filter( - author=username, field="stage", oldvalue="Unreviewed" + author=user.username, field="stage", oldvalue="Unreviewed" ) qs = qs.exclude(newvalue="Unreviewed") return StatData(count=qs.count(), link=None)