Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 20 additions & 1 deletion api/institutions/serializers.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
from django.db.models import Count, F

from rest_framework import serializers as ser
from rest_framework import exceptions

from osf.models import Node, Registration
from framework import sentry
from osf.models import Node, Registration, OSFUser
from osf.utils import permissions as osf_permissions

from api.base.serializers import (
Expand Down Expand Up @@ -355,12 +358,28 @@ class Meta:
related_view='institutions:institution-detail',
related_view_kwargs={'institution_id': '<institution_id>'},
)
contacts = ser.SerializerMethodField()

links = LinksField({})

def get_absolute_url(self):
return None # there is no detail view for institution-users

def get_contacts(self, obj):
user = OSFUser.load(obj._d_['user_id'])
if not user:
sentry.log_message(f'Institutional report with id {obj.meta['id']} has missing user')
return []

results = user.received_user_messages.annotate(
sender_name=F('sender__fullname'),
).values(
'sender_name',
).annotate(
count=Count('sender_name'),
).order_by('sender_name')
return list(results)


class NewInstitutionSummaryMetricsSerializer(JSONAPISerializer):
'''serializer for institution-summary metrics
Expand Down
93 changes: 93 additions & 0 deletions api_tests/institutions/views/test_institution_user_metric_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@

from osf.metrics import UserInstitutionProjectCounts
from osf.metrics.reports import InstitutionalUserReport
from osf.models import UserMessage


@pytest.mark.es_metrics
@pytest.mark.django_db
Expand Down Expand Up @@ -350,6 +352,10 @@ def test_get_reports(self, app, url, institutional_admin, institution, reports,
_expected_user_ids = {_report.user_id for _report in reports}
assert set(_user_ids(_resp)) == _expected_user_ids

# # users haven't any received messages from institutional admins
for response_object in _resp.json['data']:
assert len(response_object['attributes']['contacts']) == 0

def test_filter_reports(self, app, url, institutional_admin, institution, reports, unshown_reports):
for _query, _expected_user_ids in (
({'filter[department]': 'nunavum'}, set()),
Expand Down Expand Up @@ -447,6 +453,7 @@ def test_get_report_formats_csv_tsv(self, app, url, institutional_admin, institu
[
'report_yearmonth',
'account_creation_date',
'contacts',
'department',
'embargoed_registration_count',
'month_last_active',
Expand All @@ -463,6 +470,7 @@ def test_get_report_formats_csv_tsv(self, app, url, institutional_admin, institu
[
'2024-08',
'2018-02',
'[]',
'Center, \t Greatest Ever',
'1',
'2018-02',
Expand Down Expand Up @@ -516,6 +524,7 @@ def test_csv_tsv_ignores_pagination(self, app, url, institutional_admin, institu
expected_data.append([
'2024-08',
'2018-02',
'[]',
'QBatman',
'1',
'2018-02',
Expand Down Expand Up @@ -557,6 +566,7 @@ def test_csv_tsv_ignores_pagination(self, app, url, institutional_admin, institu
expected_header = [
'report_yearmonth',
'account_creation_date',
'contacts',
'department',
'embargoed_registration_count',
'month_last_active',
Expand Down Expand Up @@ -612,6 +622,7 @@ def test_get_report_format_table_json(self, app, url, institutional_admin, insti
{
'report_yearmonth': '2024-08',
'account_creation_date': '2018-02',
'contacts': [],
'department': 'Safety "The Wolverine" Weapon X',
'embargoed_registration_count': 1,
'month_last_active': '2018-02',
Expand All @@ -628,6 +639,88 @@ def test_get_report_format_table_json(self, app, url, institutional_admin, insti
]
assert response_data == expected_data

def test_correct_number_of_contact_messages(self, app, url, institutional_admin, institution):
user1 = AuthUserFactory()
user2 = AuthUserFactory()
user3 = AuthUserFactory()
user4 = AuthUserFactory()
_report_factory(
'2024-08', institution,
user_id=user1._id,
storage_byte_count=53,
),
_report_factory(
'2024-08', institution,
user_id=user2._id,
orcid_id='5555-4444-3333-2222',
storage_byte_count=8277,
),
_report_factory(
'2024-08', institution,
user_id=user3._id,
department_name='blargl',
storage_byte_count=34834834,
),
_report_factory(
'2024-08', institution,
user_id=user4._id,
orcid_id='4444-3333-2222-1111',
department_name='a department, or so, that happens, incidentally, to have commas',
storage_byte_count=736662999298,
)

receiver = user1
UserMessage.objects.create(
sender=institutional_admin,
recipient=receiver,
message_text='message1',
message_type='institutional_request',
institution=institution
)
UserMessage.objects.create(
sender=institutional_admin,
recipient=receiver,
message_text='message2',
message_type='institutional_request',
institution=institution
)
UserMessage.objects.create(
sender=institutional_admin,
recipient=receiver,
message_text='message3',
message_type='institutional_request',
institution=institution
)

new_admin = AuthUserFactory()
institution.get_group('institutional_admins').user_set.add(new_admin)

# messages from another admin
UserMessage.objects.create(
sender=new_admin,
recipient=receiver,
message_text='message4',
message_type='institutional_request',
institution=institution
)
UserMessage.objects.create(
sender=new_admin,
recipient=receiver,
message_text='message5',
message_type='institutional_request',
institution=institution
)

res = app.get(f'/{API_BASE}institutions/{institution._id}/metrics/users/', auth=institutional_admin.auth)
contact_object = list(filter(lambda contact: receiver._id in contact['relationships']['user']['links']['related']['href'], res.json['data']))[0]
contacts = contact_object['attributes']['contacts']

first_admin_contact = list(filter(lambda x: x['sender_name'] == institutional_admin.fullname, contacts))[0]
assert first_admin_contact['count'] == 3

another_admin_contact = list(filter(lambda x: x['sender_name'] == new_admin.fullname, contacts))[0]
assert another_admin_contact['count'] == 2


def _user_ids(api_response):
for _datum in api_response.json['data']:
Expand Down
Loading