diff --git a/osf/metrics/reporters/institution_summary_monthly.py b/osf/metrics/reporters/institution_summary_monthly.py index 61a86faf9d8..953b1639aa2 100644 --- a/osf/metrics/reporters/institution_summary_monthly.py +++ b/osf/metrics/reporters/institution_summary_monthly.py @@ -88,6 +88,7 @@ def get_monthly_logged_in_user_count(self, institution, yearmonth): def get_monthly_active_user_count(self, institution, yearmonth): return institution.get_institution_users().filter( date_disabled__isnull=True, - date_last_login__gte=yearmonth.target_month(), - date_last_login__lt=yearmonth.next_month() + logs__created__gte=yearmonth.target_month(), + logs__created__lt=yearmonth.next_month(), + ).count() diff --git a/osf_tests/metrics/reporters/test_institutional_summary_reporter.py b/osf_tests/metrics/reporters/test_institutional_summary_reporter.py index 957523b6276..8527c6c89a7 100644 --- a/osf_tests/metrics/reporters/test_institutional_summary_reporter.py +++ b/osf_tests/metrics/reporters/test_institutional_summary_reporter.py @@ -15,46 +15,62 @@ class TestInstiSummaryMonthlyReporter(TestCase): @classmethod def setUpTestData(cls): - cls._yearmonth = YearMonth(2018, 2) + cls._yearmonth = YearMonth(2018, 2) # February 2018 cls._institution = InstitutionFactory() cls._now = datetime.datetime(2018, 2, 4, tzinfo=datetime.UTC) - cls._public_project = cls._create_affiliated_project(is_public=True) - cls._private_project = cls._create_affiliated_project(is_public=False) - cls._public_registration = cls._create_affiliated_registration(is_public=True) - cls._embargoed_registration = cls._create_affiliated_registration(is_public=False) + # Existing data for the primary institution + cls._public_project = cls._create_affiliated_project(cls._institution, is_public=True, created=cls._now) + cls._private_project = cls._create_affiliated_project(cls._institution, is_public=False, created=cls._now) + cls._public_registration = cls._create_affiliated_registration(cls._institution, is_public=True, created=cls._now) + cls._embargoed_registration = cls._create_affiliated_registration(cls._institution, is_public=False, created=cls._now) - cls._published_preprint = PreprintFactory(is_public=True) - cls._published_preprint.affiliated_institutions.add(cls._institution) + cls._published_preprint = cls._create_affiliated_preprint(cls._institution, is_public=True, created=cls._now) - cls._logged_in_user = cls._create_logged_in_user() - cls._active_user = cls._create_active_user() + cls._logged_in_user = cls._create_logged_in_user(cls._institution, date_last_login=cls._now) + cls._active_user = cls._create_active_user(cls._institution, date_confirmed=cls._now - datetime.timedelta(days=1)) @classmethod - def _create_affiliated_project(cls, is_public): + def _create_affiliated_preprint(cls, institution, is_public, created): + published_preprint = PreprintFactory(is_public=is_public) + published_preprint.affiliated_institutions.add(institution) + published_preprint.created = created + published_preprint.save() + return published_preprint + + @classmethod + def _create_affiliated_project(cls, institution, is_public, created): project = ProjectFactory(is_public=is_public) - project.affiliated_institutions.add(cls._institution) + project.affiliated_institutions.add(institution) + project.created = created + project.save() return project @classmethod - def _create_affiliated_registration(cls, is_public): + def _create_affiliated_registration(cls, institution, is_public, created): registration = RegistrationFactory(is_public=is_public) - registration.affiliated_institutions.add(cls._institution) + registration.affiliated_institutions.add(institution) + registration.created = created + registration.save() return registration @classmethod - def _create_logged_in_user(cls): + def _create_logged_in_user(cls, institution, date_last_login): user = AuthUserFactory() - user.add_or_update_affiliated_institution(cls._institution) - user.date_last_login = cls._now + user.add_or_update_affiliated_institution(institution) + user.date_last_login = date_last_login user.save() return user @classmethod - def _create_active_user(cls): + def _create_active_user(cls, institution, date_confirmed): user = AuthUserFactory() - user.add_or_update_affiliated_institution(cls._institution) - user.date_confirmed = cls._now - datetime.timedelta(days=1) + user.add_or_update_affiliated_institution(institution) + user.date_confirmed = date_confirmed + ProjectFactory(creator=user) # adds log to make active + log = user.logs.get() + log.created = date_confirmed + log.save() user.save() return user @@ -75,3 +91,45 @@ def test_report_generation(self): self.assertEqual(report.public_file_count, 1) self.assertEqual(report.monthly_logged_in_user_count, 1) self.assertEqual(report.monthly_active_user_count, 1) + + def test_report_generation_multiple_institutions(self): + institution2 = InstitutionFactory() + institution3 = InstitutionFactory() + + # Set up dates for different months + now = datetime.datetime(2018, 2, 4, tzinfo=datetime.UTC) + last_month = datetime.datetime(2018, 1, 15, tzinfo=datetime.UTC) + next_month = datetime.datetime(2018, 3, 10, tzinfo=datetime.UTC) + + self._create_affiliated_project(institution2, is_public=True, created=now) + self._create_affiliated_project(institution3, is_public=True, created=last_month) + + # Create future projects for self._institution (should not be counted) + self._create_affiliated_project(self._institution, is_public=True, created=next_month) + + # Create users affiliated with different institutions + self._create_active_user(institution2, date_confirmed=now) + self._create_active_user(institution3, date_confirmed=last_month) + + # Run the reporter for the current month (February 2018) + reporter = InstitutionalSummaryMonthlyReporter() + reports = list(reporter.report(self._yearmonth)) + self.assertEqual(len(reports), 3) # Reports for self._institution, institution2, institution3 + + # Extract reports by institution + report_institution = next(r for r in reports if r.institution_id == self._institution._id) + report_institution2 = next(r for r in reports if r.institution_id == institution2._id) + + # Validate report for self._institution + self.assertEqual(report_institution.public_project_count, 1) + self.assertEqual(report_institution.private_project_count, 1) + self.assertEqual(report_institution.user_count, 2) + self.assertEqual(report_institution.monthly_active_user_count, 1) + self.assertEqual(report_institution.monthly_logged_in_user_count, 1) + + # Validate report for institution2 + self.assertEqual(report_institution2.public_project_count, 1) + self.assertEqual(report_institution2.private_project_count, 0) + self.assertEqual(report_institution2.user_count, 1) + self.assertEqual(report_institution2.monthly_active_user_count, 1) + self.assertEqual(report_institution2.monthly_logged_in_user_count, 0) # No logged-in users