Skip to content

Commit

Permalink
Merge pull request #603 from ucb-rit/issue_571
Browse files Browse the repository at this point in the history
Adding unit testing for export_data renewal_survey_answers command
  • Loading branch information
matthew-li authored May 21, 2024
2 parents fa672e5 + e28dc91 commit c6eaa85
Showing 1 changed file with 198 additions and 1 deletion.
199 changes: 198 additions & 1 deletion coldfront/core/utils/tests/test_export_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,15 @@

from django.contrib.auth.models import User
from django.core.management import call_command, CommandError
from django.urls import reverse
from django import forms
from http import HTTPStatus

from coldfront.api.statistics.utils import get_accounting_allocation_objects, \
create_project_allocation, create_user_project_allocation
from coldfront.core.allocation.models import AllocationAttributeType, \
AllocationUserAttribute
AllocationUserAttribute, AllocationRenewalRequest, AllocationPeriod, \
AllocationRenewalRequestStatusChoice
from coldfront.core.statistics.models import Job
from coldfront.core.user.models import UserProfile
from coldfront.core.utils.common import display_time_zone_date_to_utc_datetime
Expand All @@ -23,6 +27,8 @@
ProjectUser, ProjectUserStatusChoice, ProjectUserRoleChoice, \
ProjectAllocationRequestStatusChoice, SavioProjectAllocationRequest, \
VectorProjectAllocationRequest
from coldfront.core.project.forms_.renewal_forms.request_forms import ProjectRenewalSurveyForm
from coldfront.core.project.utils_.renewal_utils import get_current_allowance_year_period
from coldfront.core.resource.models import Resource
from coldfront.core.resource.utils_.allowance_utils.constants import BRCAllowances
from coldfront.core.resource.utils_.allowance_utils.interface import ComputingAllowanceInterface
Expand Down Expand Up @@ -999,3 +1005,194 @@ def test_get_new_project_survey_responses_allowance_type(self):

err.seek(0)
self.assertEqual(err.read(), '')

class TestRenewalSurveyResponses(TestBase):
""" Test class to test export data subcommand renewal_survey_responses
runs correctly """

@enable_deployment('BRC')
def setUp(self):
super().setUp()

fixtures = []
filtered_fixtures = []

allocation_period = AllocationPeriod.objects.get(
name__exact='Allowance Year 2024 - 2025')

for index in range(5):

renewal_survey = {
'brc_feedback': 'N/A',
'mybrc_comments': '',
'do_you_use_mybrc': 'no',
'classes_being_taught': f'sample answer {index}',
'colleague_suggestions': 'N/A',
'grants_supported_by_brc': 'Grant #1 etc. etc.\r\nGrant #2 etc. etc.',
'which_brc_services_used': ['savio_hpc', 'srdc'],
'indicate_topic_interests': ['have_visited_rdmp_website',
'have_had_rdmp_event_or_consultation',
'want_to_learn_security_and_have_rdm_consult'],
'brc_recommendation_rating': '6',
'publications_supported_by_brc': 'N/A',
'which_open_ondemand_apps_used': ['desktop', 'matlab',
'jupyter_notebook', 'vscode_server'],
'recruitment_or_retention_cases': 'N/A',
'brc_recommendation_rating_reason': 'Easy to use',
'how_important_to_research_is_brc': '5',
'training_session_other_topics_of_interest': 'None',
'how_brc_helped_bootstrap_computational_methods': 'N/A',
'training_session_usefulness_of_basic_savio_cluster': '4',
'training_session_usefulness_of_singularity_on_savio': '4',
'training_session_usefulness_of_advanced_savio_cluster': '2',
'training_session_usefulness_of_analytic_envs_on_demand': '5',
'training_session_usefulness_of_computational_platforms_training': '3'}

active_project_status = ProjectStatusChoice.objects.get(name='Active')

project_prefix = 'fc_' if index % 2 else 'pc_'
project = Project.objects.create(
name=f'{project_prefix}test_project{index}',
status=active_project_status)

requester = User.objects.create(
email=f'requester{index}@email.com',
first_name='Requester',
last_name=f'User {index}',
username=f'requester{index}')
pi = User.objects.create(
email=f'pi{index}@email.com',
first_name='PI',
last_name=f'User {index}',
username=f'pi{index}')
allocation_period_start_utc = display_time_zone_date_to_utc_datetime(
allocation_period.start_date)
fixture = AllocationRenewalRequest.objects.create(
requester=requester,
pi=pi,
computing_allowance=Resource.objects.get(
name=BRCAllowances.FCA),
allocation_period=allocation_period,
status=AllocationRenewalRequestStatusChoice.objects.get(
name='Under Review'),
renewal_survey_answers = renewal_survey,
pre_project=project,
post_project=project,
request_time=allocation_period_start_utc - datetime.timedelta(days=1))

fixtures.append(fixture)
if index % 2:
filtered_fixtures.append(fixture)

fixtures = list(sorted(
fixtures, key=lambda x: x.pre_project.name, reverse=True))
filtered_fixtures = list(sorted(
filtered_fixtures, key=lambda x: x.pre_project.name, reverse=True))
self.fixtures = fixtures
self.filtered_fixtures = filtered_fixtures

@enable_deployment('BRC')
def test_get_renewal_survey_responses_json(self):
out, err = StringIO(''), StringIO('')
call_command('export_data', 'renewal_survey_responses',
'--format=json',
'--allocation_period=Allowance Year 2024 - 2025',
stdout=out, stderr=err)
sys.stdout = sys.__stdout__

out.seek(0)
output = json.loads(''.join(out.readlines()))
for index, item in enumerate(output):
project_name = item.pop('project_name')
fixture = self.fixtures[index]
self.assertEqual(project_name, fixture.pre_project.name)
self.assertEqual(item['renewal_survey_responses'],
self.swap_form_answer_id_for_text(
fixture.renewal_survey_answers))
err.seek(0)
self.assertEqual(err.read(), '')

@enable_deployment('BRC')
def test_get_renewal_survey_responses_csv(self):
out, err = StringIO(''), StringIO('')
call_command('export_data', 'renewal_survey_responses',
'--format=csv',
'--allocation_period=Allowance Year 2024 - 2025',
stdout=out, stderr=err)
sys.stdout = sys.__stdout__

out.seek(0)
reader = DictReader(out.readlines())
for index, item in enumerate(reader):
project_name = item.pop('project_name')
project_title = item.pop('project_title')
project_pi = item.pop('project_pi')
fixture = self.fixtures[index]
self.assertEqual(project_title, fixture.pre_project.title)
self.assertEqual(project_pi, fixture.pi.username)
self.assertEqual(project_name, fixture.pre_project.name)
self.assertEqual(len(item), len(fixture.renewal_survey_answers))
sample = ('6. Based upon your overall experience using BRC '
'services, how likely are you to recommend Berkeley '
'Research Computing to others?')
sample_answer = '6'
self.assertEqual(item[sample], sample_answer)

err.seek(0)
self.assertEqual(err.read(), '')

@enable_deployment('BRC')
def test_get_renewal_survey_responses_allowance_type(self):
out, err = StringIO(''), StringIO('')
call_command('export_data', 'renewal_survey_responses',
'--format=json',
'--allocation_period=Allowance Year 2024 - 2025',
'--allowance_type=fc_', stdout=out, stderr=err)
sys.stdout = sys.__stdout__

out.seek(0)
output = json.loads(''.join(out.readlines()))
for index, item in enumerate(output):
project_name = item.pop('project_name')
fixture = self.filtered_fixtures[index]
self.assertEqual(project_name, fixture.pre_project.name)
self.assertEqual(item['renewal_survey_responses'],
self.swap_form_answer_id_for_text(
fixture.renewal_survey_answers))

err.seek(0)
self.assertEqual(err.read(), '')

@staticmethod
def swap_form_answer_id_for_text(survey):
'''
Takes a survey, a dict mapping survey question IDs to answer IDs.
Uses ProjectRenewalSurveyForm.
Swaps answer IDs for answer text, then question IDs for question text.
Returns the modified survey.
Parameter
----------
survey : survey to modify
'''
multiple_choice_fields = {}
form = ProjectRenewalSurveyForm()
for k, v in form.fields.items():
# Only ChoiceField or MultipleChoiceField
# (in this specific survey form) have choices
if (isinstance(v, (forms.MultipleChoiceField, forms.ChoiceField))):
multiple_choice_fields[k] = {
_k: _v for _k, _v in form.fields[k].choices}
for question, answer in survey.items():
if question in multiple_choice_fields.keys():
sub_map = multiple_choice_fields[question]
if (isinstance(answer, list)):
# Multiple choice, array
survey[question] = [sub_map.get(i,i) for i in answer]
elif answer != '':
# Single choice replacement
survey[question] = sub_map[answer]
# Change keys of survey (question IDs) to be the human-readable text
for id, text in form.fields.items():
survey[text.label] = survey.pop(id)
return survey

0 comments on commit c6eaa85

Please sign in to comment.