From 590fde867ba3d9cec22bc2e1b0c84b3c5a3ec204 Mon Sep 17 00:00:00 2001 From: Shaz Zahra Zaidi Date: Mon, 29 Dec 2025 01:31:04 +0530 Subject: [PATCH 01/11] Add weekly team stats aggregation service --- website/services/team_weekly_stats.py | 48 +++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 website/services/team_weekly_stats.py diff --git a/website/services/team_weekly_stats.py b/website/services/team_weekly_stats.py new file mode 100644 index 0000000000..d01f4b43eb --- /dev/null +++ b/website/services/team_weekly_stats.py @@ -0,0 +1,48 @@ +from django.db.models import Sum +from website.models import Organization, ContributorStats + + +def get_weekly_team_stats(start_date, end_date): + """ + Aggregate weekly stats for teams (Organization type = TEAM). + + Returns an empty list if no TEAM organizations or contributor stats + exist in the given date range. + """ + team_stats = [] + + teams = Organization.objects.filter(type="team") + + for team in teams: + # Get all repos owned by this team + repos = team.repos.all() + + # Aggregate contributor stats for these repos in the given week + stats = ContributorStats.objects.filter( + repo__in=repos, + granularity="day", + date__gte=start_date, + date__lte=end_date, + ).aggregate( + commits=Sum("commits"), + issues_opened=Sum("issues_opened"), + issues_closed=Sum("issues_closed"), + pull_requests=Sum("pull_requests"), + comments=Sum("comments"), + ) + + team_stats.append({ + "team_id": team.id, + "team_name": team.name, + "start_date": start_date, + "end_date": end_date, + "stats": { + "commits": stats["commits"] or 0, + "issues_opened": stats["issues_opened"] or 0, + "issues_closed": stats["issues_closed"] or 0, + "pull_requests": stats["pull_requests"] or 0, + "comments": stats["comments"] or 0, + }, + }) + + return team_stats From 13b4ea1525bc6b6e6ca06ced33bb5ed4c2c39c56 Mon Sep 17 00:00:00 2001 From: Shaz Zahra Zaidi Date: Mon, 29 Dec 2025 01:54:27 +0530 Subject: [PATCH 02/11] Pre-commit fixes --- website/services/team_weekly_stats.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/website/services/team_weekly_stats.py b/website/services/team_weekly_stats.py index d01f4b43eb..af676ad3de 100644 --- a/website/services/team_weekly_stats.py +++ b/website/services/team_weekly_stats.py @@ -1,5 +1,6 @@ from django.db.models import Sum -from website.models import Organization, ContributorStats + +from website.models import ContributorStats, Organization def get_weekly_team_stats(start_date, end_date): From 009f2ac054992e280de3ac857803309a08ad901c Mon Sep 17 00:00:00 2001 From: Shaz Zahra Zaidi Date: Mon, 29 Dec 2025 02:15:33 +0530 Subject: [PATCH 03/11] fixes pre-commit issues and N+1 query --- website/services/team_weekly_stats.py | 54 ++++++++++++++++----------- 1 file changed, 33 insertions(+), 21 deletions(-) diff --git a/website/services/team_weekly_stats.py b/website/services/team_weekly_stats.py index af676ad3de..8c5ceb52ab 100644 --- a/website/services/team_weekly_stats.py +++ b/website/services/team_weekly_stats.py @@ -10,40 +10,52 @@ def get_weekly_team_stats(start_date, end_date): Returns an empty list if no TEAM organizations or contributor stats exist in the given date range. """ - team_stats = [] + # Step 1: Get all teams teams = Organization.objects.filter(type="team") - for team in teams: - # Get all repos owned by this team - repos = team.repos.all() + if not teams.exists(): + return [] - # Aggregate contributor stats for these repos in the given week - stats = ContributorStats.objects.filter( - repo__in=repos, + # Step 2: Aggregate stats for all repos of all teams at once + stats_queryset = ( + ContributorStats.objects.filter( + repo__organization__in=teams, granularity="day", date__gte=start_date, date__lte=end_date, - ).aggregate( + ) + .values("repo__organization_id") # Group by team + .annotate( commits=Sum("commits"), issues_opened=Sum("issues_opened"), issues_closed=Sum("issues_closed"), pull_requests=Sum("pull_requests"), comments=Sum("comments"), ) + ) + + # Step 3: Map stats by team ID + stats_map = {s["repo__organization_id"]: s for s in stats_queryset} - team_stats.append({ - "team_id": team.id, - "team_name": team.name, - "start_date": start_date, - "end_date": end_date, - "stats": { - "commits": stats["commits"] or 0, - "issues_opened": stats["issues_opened"] or 0, - "issues_closed": stats["issues_closed"] or 0, - "pull_requests": stats["pull_requests"] or 0, - "comments": stats["comments"] or 0, - }, - }) + # Step 4: Build final list + team_stats = [] + for team in teams: + s = stats_map.get(team.id, {}) + team_stats.append( + { + "team_id": team.id, + "team_name": team.name, + "start_date": start_date, + "end_date": end_date, + "stats": { + "commits": s.get("commits", 0), + "issues_opened": s.get("issues_opened", 0), + "issues_closed": s.get("issues_closed", 0), + "pull_requests": s.get("pull_requests", 0), + "comments": s.get("comments", 0), + }, + } + ) return team_stats From 6f877011272aae5f229317810a42ed5ea342f181 Mon Sep 17 00:00:00 2001 From: Shaz Zahra Zaidi Date: Tue, 30 Dec 2025 20:25:54 +0530 Subject: [PATCH 04/11] fixed enum, null-safe aggregation, logging --- website/services/team_weekly_stats.py | 40 ++++++++++++++++----------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/website/services/team_weekly_stats.py b/website/services/team_weekly_stats.py index 8c5ceb52ab..10db2bfca0 100644 --- a/website/services/team_weekly_stats.py +++ b/website/services/team_weekly_stats.py @@ -1,44 +1,52 @@ +import logging +from datetime import date +from typing import Any, Dict, List + from django.db.models import Sum +from django.db.models.functions import Coalesce + +from website.models import ContributorStats, OrganisationType, Organization -from website.models import ContributorStats, Organization +logger = logging.getLogger(__name__) -def get_weekly_team_stats(start_date, end_date): +def get_weekly_team_stats(start_date: date, end_date: date) -> List[Dict[str, Any]]: """ - Aggregate weekly stats for teams (Organization type = TEAM). + Aggregate weekly stats for TEAM organizations. Returns an empty list if no TEAM organizations or contributor stats exist in the given date range. """ - # Step 1: Get all teams - teams = Organization.objects.filter(type="team") + logger.info("Aggregating weekly team stats from %s to %s", start_date, end_date) + + teams = Organization.objects.filter(type=OrganisationType.TEAM.value).only("id", "name") if not teams.exists(): + logger.debug("No TEAM organizations found") return [] - # Step 2: Aggregate stats for all repos of all teams at once + # ContributorStats are stored at daily granularity. + # Weekly stats are computed by aggregating daily records + # over the given date range. stats_queryset = ( ContributorStats.objects.filter( repo__organization__in=teams, granularity="day", - date__gte=start_date, - date__lte=end_date, + date__range=(start_date, end_date), ) - .values("repo__organization_id") # Group by team + .values("repo__organization_id") .annotate( - commits=Sum("commits"), - issues_opened=Sum("issues_opened"), - issues_closed=Sum("issues_closed"), - pull_requests=Sum("pull_requests"), - comments=Sum("comments"), + commits=Coalesce(Sum("commits"), 0), + issues_opened=Coalesce(Sum("issues_opened"), 0), + issues_closed=Coalesce(Sum("issues_closed"), 0), + pull_requests=Coalesce(Sum("pull_requests"), 0), + comments=Coalesce(Sum("comments"), 0), ) ) - # Step 3: Map stats by team ID stats_map = {s["repo__organization_id"]: s for s in stats_queryset} - # Step 4: Build final list team_stats = [] for team in teams: s = stats_map.get(team.id, {}) From 23abb8b6658d1d9df161669b8ed143cf2f7d867e Mon Sep 17 00:00:00 2001 From: Shaz Zahra Zaidi Date: Wed, 31 Dec 2025 11:39:07 +0530 Subject: [PATCH 05/11] Unit tests added for get_weekly_test_stats function --- website/tests/test_team_weekly_stats.py | 81 +++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 website/tests/test_team_weekly_stats.py diff --git a/website/tests/test_team_weekly_stats.py b/website/tests/test_team_weekly_stats.py new file mode 100644 index 0000000000..07351e2eda --- /dev/null +++ b/website/tests/test_team_weekly_stats.py @@ -0,0 +1,81 @@ +from datetime import date + +import pytest + +from website.models import Contributor, ContributorStats, OrganisationType, Organization +from website.services.team_weekly_stats import get_weekly_team_stats + + +@pytest.mark.django_db +def test_no_teams_returns_empty_list(): + result = get_weekly_team_stats( + start_date=date(2025, 1, 1), + end_date=date(2025, 1, 7), + ) + assert result == [] + + +@pytest.mark.django_db +def test_team_with_no_stats_returns_zeros(): + team = Organization.objects.create( + name="Test Team", + type=OrganisationType.TEAM.value, + ) + + result = get_weekly_team_stats( + start_date=date(2025, 1, 1), + end_date=date(2025, 1, 7), + ) + + assert result[0]["stats"]["commits"] == 0 + assert result[0]["stats"]["issues_opened"] == 0 + + +@pytest.mark.django_db +def test_single_team_with_stats(): + # Create a TEAM + team = Organization.objects.create( + name="Team A", + type=OrganisationType.TEAM.value, + ) + + # Create a repo under the team + from website.models import Repo # import here to avoid unused import warnings + + repo = Repo.objects.create( + name="test-repo", + organization=team, + ) + contributor = Contributor.objects.create( + name="Test User", + github_id=12345, # optional if nullable + github_url="https://github.com/test-user", + contributor_type="INDIVIDUAL", # or whatever valid type + contributions=0, # can default to 0 + ) + + # Add contributor stats for that repo + ContributorStats.objects.create( + repo=repo, + contributor=contributor, + granularity="day", + date=date(2025, 1, 3), + commits=5, + issues_opened=2, + issues_closed=1, + pull_requests=1, + comments=3, + ) + + # Call the service + result = get_weekly_team_stats( + start_date=date(2025, 1, 1), + end_date=date(2025, 1, 7), + ) + + # Assert stats are correctly aggregated + assert result[0]["stats"]["commits"] == 5 + assert result[0]["stats"]["issues_opened"] == 2 + assert result[0]["stats"]["issues_closed"] == 1 + assert result[0]["stats"]["pull_requests"] == 1 + assert result[0]["stats"]["comments"] == 3 From be5ae64b9ee04a5975cbae4b943b4d3005b5b500 Mon Sep 17 00:00:00 2001 From: Shaz Zahra Zaidi Date: Wed, 31 Dec 2025 12:10:36 +0530 Subject: [PATCH 06/11] Fixed CI failures in team_weekly_stats tests --- website/tests/test_team_weekly_stats.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/website/tests/test_team_weekly_stats.py b/website/tests/test_team_weekly_stats.py index 07351e2eda..59166e82b2 100644 --- a/website/tests/test_team_weekly_stats.py +++ b/website/tests/test_team_weekly_stats.py @@ -20,6 +20,7 @@ def test_team_with_no_stats_returns_zeros(): team = Organization.objects.create( name="Test Team", type=OrganisationType.TEAM.value, + url="https://example.com/test-team", ) result = get_weekly_team_stats( @@ -37,21 +38,24 @@ def test_single_team_with_stats(): team = Organization.objects.create( name="Team A", type=OrganisationType.TEAM.value, + url="https://example.com/test-team", ) # Create a repo under the team - from website.models import Repo # import here to avoid unused import warnings + from website.models import Repo repo = Repo.objects.create( name="test-repo", organization=team, + repo_url="https://github.com/example/test-repo", ) contributor = Contributor.objects.create( name="Test User", - github_id=12345, # optional if nullable + github_id=12345, github_url="https://github.com/test-user", - contributor_type="INDIVIDUAL", # or whatever valid type - contributions=0, # can default to 0 + avatar_url="https://avatars.githubusercontent.com/u/12345", + contributor_type="INDIVIDUAL", + contributions=0, # default to 0 ) # Add contributor stats for that repo From 32f1c745d82fcf84e552f2a6ede81137aadd93b2 Mon Sep 17 00:00:00 2001 From: Shaz Zahra Zaidi Date: Wed, 31 Dec 2025 13:15:09 +0530 Subject: [PATCH 07/11] resolved minor length check issues --- website/tests/test_team_weekly_stats.py | 33 +++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/website/tests/test_team_weekly_stats.py b/website/tests/test_team_weekly_stats.py index 59166e82b2..c4c908c3e2 100644 --- a/website/tests/test_team_weekly_stats.py +++ b/website/tests/test_team_weekly_stats.py @@ -28,8 +28,21 @@ def test_team_with_no_stats_returns_zeros(): end_date=date(2025, 1, 7), ) - assert result[0]["stats"]["commits"] == 0 - assert result[0]["stats"]["issues_opened"] == 0 + assert len(result) == 1 + team_result = result[0] + + assert team_result["team_id"] == team.id + assert team_result["team_name"] == "Test Team" + assert team_result["start_date"] == date(2025, 1, 1) + assert team_result["end_date"] == date(2025, 1, 7) + + assert team_result["stats"] == { + "commits": 0, + "issues_opened": 0, + "issues_closed": 0, + "pull_requests": 0, + "comments": 0, + } @pytest.mark.django_db @@ -76,6 +89,22 @@ def test_single_team_with_stats(): start_date=date(2025, 1, 1), end_date=date(2025, 1, 7), ) + assert len(result) == 1 + + team_result = result[0] + + assert team_result["team_id"] == team.id + assert team_result["team_name"] == "Team A" + assert team_result["start_date"] == date(2025, 1, 1) + assert team_result["end_date"] == date(2025, 1, 7) + + assert team_result["stats"] == { + "commits": 5, + "issues_opened": 2, + "issues_closed": 1, + "pull_requests": 1, + "comments": 3, + } # Assert stats are correctly aggregated assert result[0]["stats"]["commits"] == 5 From fbc4f91a66043b5e2371b2d94f03c83765c836f9 Mon Sep 17 00:00:00 2001 From: Shaz Zahra Zaidi Date: Wed, 31 Dec 2025 15:11:13 +0530 Subject: [PATCH 08/11] fixed team queryset --- website/services/team_weekly_stats.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/website/services/team_weekly_stats.py b/website/services/team_weekly_stats.py index 10db2bfca0..51757943aa 100644 --- a/website/services/team_weekly_stats.py +++ b/website/services/team_weekly_stats.py @@ -20,18 +20,19 @@ def get_weekly_team_stats(start_date: date, end_date: date) -> List[Dict[str, An logger.info("Aggregating weekly team stats from %s to %s", start_date, end_date) - teams = Organization.objects.filter(type=OrganisationType.TEAM.value).only("id", "name") + teams = list(Organization.objects.filter(type=OrganisationType.TEAM.value).only("id", "name")) - if not teams.exists(): + if not teams: logger.debug("No TEAM organizations found") return [] # ContributorStats are stored at daily granularity. # Weekly stats are computed by aggregating daily records # over the given date range. + team_ids = [t.id for t in teams] stats_queryset = ( ContributorStats.objects.filter( - repo__organization__in=teams, + repo__organization_id__in=team_ids, granularity="day", date__range=(start_date, end_date), ) From c00cdffb90620e289c2d5a9373ba4794d57d3975 Mon Sep 17 00:00:00 2001 From: Shaz Zahra Zaidi Date: Wed, 31 Dec 2025 15:44:48 +0530 Subject: [PATCH 09/11] added team stats aggregation with date validation and tests --- website/services/team_weekly_stats.py | 4 +++- website/tests/test_team_weekly_stats.py | 10 ++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/website/services/team_weekly_stats.py b/website/services/team_weekly_stats.py index 51757943aa..1b196cfe09 100644 --- a/website/services/team_weekly_stats.py +++ b/website/services/team_weekly_stats.py @@ -2,6 +2,7 @@ from datetime import date from typing import Any, Dict, List +from django.core.exceptions import ValidationError from django.db.models import Sum from django.db.models.functions import Coalesce @@ -13,10 +14,11 @@ def get_weekly_team_stats(start_date: date, end_date: date) -> List[Dict[str, Any]]: """ Aggregate weekly stats for TEAM organizations. - Returns an empty list if no TEAM organizations or contributor stats exist in the given date range. """ + if start_date > end_date: + raise ValidationError("start_date must be before or equal to end_date") logger.info("Aggregating weekly team stats from %s to %s", start_date, end_date) diff --git a/website/tests/test_team_weekly_stats.py b/website/tests/test_team_weekly_stats.py index c4c908c3e2..9558ddd16e 100644 --- a/website/tests/test_team_weekly_stats.py +++ b/website/tests/test_team_weekly_stats.py @@ -1,11 +1,21 @@ from datetime import date import pytest +from django.core.exceptions import ValidationError from website.models import Contributor, ContributorStats, OrganisationType, Organization from website.services.team_weekly_stats import get_weekly_team_stats +@pytest.mark.django_db +def test_get_weekly_team_stats_invalid_date_range(): + with pytest.raises(ValidationError): + get_weekly_team_stats( + start_date=date(2024, 5, 10), + end_date=date(2024, 5, 1), + ) + + @pytest.mark.django_db def test_no_teams_returns_empty_list(): result = get_weekly_team_stats( From ddd40101fffe70d72558eac81aa29c9514ee281d Mon Sep 17 00:00:00 2001 From: Shaz Zahra Zaidi Date: Wed, 31 Dec 2025 15:58:47 +0530 Subject: [PATCH 10/11] Convert weekly team stats tests to Django TestCase for CI compatibility --- website/tests/test_team_weekly_stats.py | 191 +++++++++++------------- 1 file changed, 84 insertions(+), 107 deletions(-) diff --git a/website/tests/test_team_weekly_stats.py b/website/tests/test_team_weekly_stats.py index 9558ddd16e..c666fd9631 100644 --- a/website/tests/test_team_weekly_stats.py +++ b/website/tests/test_team_weekly_stats.py @@ -1,124 +1,101 @@ from datetime import date -import pytest from django.core.exceptions import ValidationError +from django.test import TestCase -from website.models import Contributor, ContributorStats, OrganisationType, Organization +from website.models import Contributor, ContributorStats, OrganisationType, Organization, Repo from website.services.team_weekly_stats import get_weekly_team_stats -@pytest.mark.django_db -def test_get_weekly_team_stats_invalid_date_range(): - with pytest.raises(ValidationError): - get_weekly_team_stats( - start_date=date(2024, 5, 10), - end_date=date(2024, 5, 1), - ) - - -@pytest.mark.django_db -def test_no_teams_returns_empty_list(): - result = get_weekly_team_stats( - start_date=date(2025, 1, 1), - end_date=date(2025, 1, 7), - ) - assert result == [] - - -@pytest.mark.django_db -def test_team_with_no_stats_returns_zeros(): - team = Organization.objects.create( - name="Test Team", - type=OrganisationType.TEAM.value, - url="https://example.com/test-team", - ) - - result = get_weekly_team_stats( - start_date=date(2025, 1, 1), - end_date=date(2025, 1, 7), - ) - - assert len(result) == 1 - team_result = result[0] - - assert team_result["team_id"] == team.id - assert team_result["team_name"] == "Test Team" - assert team_result["start_date"] == date(2025, 1, 1) - assert team_result["end_date"] == date(2025, 1, 7) - - assert team_result["stats"] == { - "commits": 0, - "issues_opened": 0, - "issues_closed": 0, - "pull_requests": 0, - "comments": 0, - } +class TestWeeklyTeamStats(TestCase): + def test_invalid_date_range_raises_error(self): + with self.assertRaises(ValidationError): + get_weekly_team_stats( + start_date=date(2024, 5, 10), + end_date=date(2024, 5, 1), + ) + def test_no_teams_returns_empty_list(self): + result = get_weekly_team_stats( + start_date=date(2025, 1, 1), + end_date=date(2025, 1, 7), + ) + self.assertEqual(result, []) -@pytest.mark.django_db -def test_single_team_with_stats(): - # Create a TEAM - team = Organization.objects.create( - name="Team A", - type=OrganisationType.TEAM.value, - url="https://example.com/test-team", - ) + def test_team_with_no_stats_returns_zeros(self): + team = Organization.objects.create( + name="Test Team", + type=OrganisationType.TEAM.value, + url="https://example.com/test-team", + ) - # Create a repo under the team - from website.models import Repo + result = get_weekly_team_stats( + start_date=date(2025, 1, 1), + end_date=date(2025, 1, 7), + ) - repo = Repo.objects.create( - name="test-repo", - organization=team, - repo_url="https://github.com/example/test-repo", - ) - contributor = Contributor.objects.create( - name="Test User", - github_id=12345, - github_url="https://github.com/test-user", - avatar_url="https://avatars.githubusercontent.com/u/12345", - contributor_type="INDIVIDUAL", - contributions=0, # default to 0 - ) + self.assertEqual(len(result), 1) + team_result = result[0] + + self.assertEqual(team_result["team_id"], team.id) + self.assertEqual(team_result["team_name"], "Test Team") + self.assertEqual( + team_result["stats"], + { + "commits": 0, + "issues_opened": 0, + "issues_closed": 0, + "pull_requests": 0, + "comments": 0, + }, + ) - # Add contributor stats for that repo - ContributorStats.objects.create( - repo=repo, - contributor=contributor, - granularity="day", - date=date(2025, 1, 3), - commits=5, - issues_opened=2, - issues_closed=1, - pull_requests=1, - comments=3, - ) + def test_single_team_with_stats(self): + team = Organization.objects.create( + name="Team A", + type=OrganisationType.TEAM.value, + url="https://example.com/test-team", + ) - # Call the service - result = get_weekly_team_stats( - start_date=date(2025, 1, 1), - end_date=date(2025, 1, 7), - ) - assert len(result) == 1 + repo = Repo.objects.create( + name="test-repo", + organization=team, + repo_url="https://github.com/example/test-repo", + ) - team_result = result[0] + contributor = Contributor.objects.create( + name="Test User", + github_id=12345, + github_url="https://github.com/test-user", + avatar_url="https://avatars.githubusercontent.com/u/12345", + contributor_type="INDIVIDUAL", + contributions=0, + ) - assert team_result["team_id"] == team.id - assert team_result["team_name"] == "Team A" - assert team_result["start_date"] == date(2025, 1, 1) - assert team_result["end_date"] == date(2025, 1, 7) + ContributorStats.objects.create( + repo=repo, + contributor=contributor, + granularity="day", + date=date(2025, 1, 3), + commits=5, + issues_opened=2, + issues_closed=1, + pull_requests=1, + comments=3, + ) - assert team_result["stats"] == { - "commits": 5, - "issues_opened": 2, - "issues_closed": 1, - "pull_requests": 1, - "comments": 3, - } + result = get_weekly_team_stats( + start_date=date(2025, 1, 1), + end_date=date(2025, 1, 7), + ) - # Assert stats are correctly aggregated - assert result[0]["stats"]["commits"] == 5 - assert result[0]["stats"]["issues_opened"] == 2 - assert result[0]["stats"]["issues_closed"] == 1 - assert result[0]["stats"]["pull_requests"] == 1 - assert result[0]["stats"]["comments"] == 3 + self.assertEqual( + result[0]["stats"], + { + "commits": 5, + "issues_opened": 2, + "issues_closed": 1, + "pull_requests": 1, + "comments": 3, + }, + ) From ae9bce12993adb1ae8f685178cf4f88b1a67ed0a Mon Sep 17 00:00:00 2001 From: Shaz Zahra Zaidi Date: Wed, 31 Dec 2025 16:13:00 +0530 Subject: [PATCH 11/11] length check added, returned fields verified --- website/tests/test_team_weekly_stats.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/website/tests/test_team_weekly_stats.py b/website/tests/test_team_weekly_stats.py index c666fd9631..5062e60be4 100644 --- a/website/tests/test_team_weekly_stats.py +++ b/website/tests/test_team_weekly_stats.py @@ -83,14 +83,22 @@ def test_single_team_with_stats(self): pull_requests=1, comments=3, ) - result = get_weekly_team_stats( start_date=date(2025, 1, 1), end_date=date(2025, 1, 7), ) + self.assertEqual(len(result), 1) + + team_result = result[0] + + self.assertEqual(team_result["team_id"], team.id) + self.assertEqual(team_result["team_name"], "Team A") + self.assertEqual(team_result["start_date"], date(2025, 1, 1)) + self.assertEqual(team_result["end_date"], date(2025, 1, 7)) + self.assertEqual( - result[0]["stats"], + team_result["stats"], { "commits": 5, "issues_opened": 2,