From d6c25d383f96c70b68c79dd1092d70ed11a7211e Mon Sep 17 00:00:00 2001 From: Luke Payyapilli Date: Tue, 27 Jan 2026 10:01:03 -0500 Subject: [PATCH] feat: display view tracking start date on metrics page --- .../project/published_project_metrics.html | 2 +- physionet-django/project/test_views.py | 25 +++++++++++++++++++ physionet-django/project/views.py | 5 +++- 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/physionet-django/project/templates/project/published_project_metrics.html b/physionet-django/project/templates/project/published_project_metrics.html index 4610398bd..7bd4544d0 100644 --- a/physionet-django/project/templates/project/published_project_metrics.html +++ b/physionet-django/project/templates/project/published_project_metrics.html @@ -27,7 +27,7 @@

{{ all_versions_views_count }}

All Versions - Total number of unique registered users who have viewed this project + Total number of unique registered users who have viewed this project.{% if tracking_start_date %} Views tracked since {{ tracking_start_date|date:"F Y" }}.{% endif %} diff --git a/physionet-django/project/test_views.py b/physionet-django/project/test_views.py index 478fdec9e..b8bb50812 100644 --- a/physionet-django/project/test_views.py +++ b/physionet-django/project/test_views.py @@ -1847,6 +1847,7 @@ def test_metrics_detail_page_context(self): self.assertIn('project_views_count', response.context) self.assertIn('views_over_time', response.context) self.assertIn('views_by_version', response.context) + self.assertIn('tracking_start_date', response.context) def test_metrics_link_on_project_page(self): """Project page includes link to metrics detail page.""" @@ -1882,6 +1883,30 @@ def test_metrics_detail_with_access_data(self): self.assertEqual(len(response.context['views_by_version']), 1) self.assertEqual(response.context['views_by_version'][0]['count'], 2) + def test_tracking_start_date_with_views(self): + """Tracking start date is set when views exist.""" + project = PublishedProject.objects.get(title='Demo ECG Signal Toolbox') + user = User.objects.get(email='rgmark@mit.edu') + content_type = ContentType.objects.get_for_model(project) + + AccessLog.objects.create( + user=user, + object_id=project.id, + content_type=content_type, + data='' + ) + + response = self.client.get(reverse('published_project_metrics', + args=(project.slug, project.version))) + self.assertIsNotNone(response.context['tracking_start_date']) + + def test_tracking_start_date_without_views(self): + """Tracking start date is None when no views exist.""" + project = PublishedProject.objects.get(title='Demo ECG Signal Toolbox') + response = self.client.get(reverse('published_project_metrics', + args=(project.slug, project.version))) + self.assertIsNone(response.context['tracking_start_date']) + def test_unique_viewers_count(self): """AccessLog.unique_viewers_count() returns correct count.""" project = PublishedProject.objects.get(title='Demo ECG Signal Toolbox') diff --git a/physionet-django/project/views.py b/physionet-django/project/views.py index 56a4710ef..3833d475f 100644 --- a/physionet-django/project/views.py +++ b/physionet-django/project/views.py @@ -2104,13 +2104,16 @@ def published_project_metrics(request, project_slug, version): Public metrics page for a published project. """ project = get_object_or_404(PublishedProject, slug=project_slug, version=version) + views_over_time = project.views_over_time() + tracking_start_date = views_over_time[0]['month'] if views_over_time else None return render(request, 'project/published_project_metrics.html', { 'project': project, 'project_views_count': project.view_count(), 'all_versions_views_count': project.view_count(all_versions=True), - 'views_over_time': project.views_over_time(), + 'views_over_time': views_over_time, 'views_by_version': project.views_by_version(), + 'tracking_start_date': tracking_start_date, })