diff --git a/apps/challenges/admin.py b/apps/challenges/admin.py index a765f8f338..d03a3a27a1 100644 --- a/apps/challenges/admin.py +++ b/apps/challenges/admin.py @@ -40,6 +40,7 @@ class ChallengeAdmin(ImportExportTimeStampedAdmin): "end_date", "creator", "published", + "is_profile_required", "is_registration_open", "enable_forum", "anonymous_leaderboard", diff --git a/apps/challenges/migrations/0058_add_is_profile_required_field_in_challenge_model.py b/apps/challenges/migrations/0058_add_is_profile_required_field_in_challenge_model.py new file mode 100644 index 0000000000..3d01b4d727 --- /dev/null +++ b/apps/challenges/migrations/0058_add_is_profile_required_field_in_challenge_model.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-07-30 19:18 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('challenges', '0057_add_task_def_arn_and_workers_field_to_challenge_model'), + ] + + operations = [ + migrations.AddField( + model_name='challenge', + name='is_profile_required', + field=models.BooleanField(default=False), + ), + ] diff --git a/apps/challenges/models.py b/apps/challenges/models.py index 62729cc0ea..3b4b7400bb 100644 --- a/apps/challenges/models.py +++ b/apps/challenges/models.py @@ -58,6 +58,7 @@ def __init__(self, *args, **kwargs): published = models.BooleanField( default=False, verbose_name="Publicly Available", db_index=True ) + is_profile_required = models.BooleanField(default=False) is_registration_open = models.BooleanField(default=True) enable_forum = models.BooleanField(default=True) forum_url = models.URLField(max_length=100, blank=True, null=True) diff --git a/apps/challenges/serializers.py b/apps/challenges/serializers.py index a7ec47e50b..70fabd0ca8 100644 --- a/apps/challenges/serializers.py +++ b/apps/challenges/serializers.py @@ -43,6 +43,7 @@ class Meta: "end_date", "creator", "published", + "is_profile_required", "is_registration_open", "enable_forum", "anonymous_leaderboard", @@ -180,6 +181,7 @@ class Meta: "creator", "evaluation_details", "published", + "is_profile_required", "is_registration_open", "enable_forum", "anonymous_leaderboard", diff --git a/apps/challenges/views.py b/apps/challenges/views.py index a824612cf6..1da304ff1a 100644 --- a/apps/challenges/views.py +++ b/apps/challenges/views.py @@ -329,9 +329,25 @@ def add_participant_team_to_challenge( "participant_team_id": int(participant_team_pk), } return Response(response_data, status=status.HTTP_200_OK) - else: - challenge.participant_teams.add(participant_team) - return Response(status=status.HTTP_201_CREATED) + + if challenge.is_profile_required: + participants = Participant.objects.filter(team=participant_team) + for participant in participants: + if ( + participant.user.first_name == "" or participant.user.last_name == "" + or participant.user.profile.affiliation == "" + or participant.user.profile.google_scholar_url == "" + ): + response_data = { + "error": "Each participant of a team must complete their profile" + " in order to participate in this challenge.", + "is_profile_complete": False + } + return Response( + response_data, status=status.HTTP_406_NOT_ACCEPTABLE + ) + challenge.participant_teams.add(participant_team) + return Response(status=status.HTTP_201_CREATED) @api_view(["POST"]) diff --git a/docs/source/configuration.md b/docs/source/configuration.md index 606e89fc18..379bb7f5df 100644 --- a/docs/source/configuration.md +++ b/docs/source/configuration.md @@ -14,6 +14,8 @@ Following fields are required (and can be customized) in the [`challenge_config. - **image**: Logo of the challenge (use a relative path for the logo in the zip configuration, e.g. `images/logo/challenge_logo.jpg`). **Note**: The image must be in jpg, jpeg or png format. +- **is_profile_required**: True/False (boolean field that require participants to complete their profile before participating in challenge) + - **submission_guidelines**: Submission guidelines of the challenge (use a relative path for the HTML file, e.g. `challenge_details/submission_guidelines.html`) - **evaluation_script**: Python script which will decide how to evaluate submissions in different phases (path of the evaluation script file or folder relative to this YAML file. For e.g. `evaluation_script/`) diff --git a/tests/unit/challenges/test_views.py b/tests/unit/challenges/test_views.py index e6231f4a5c..ed1179cc1d 100644 --- a/tests/unit/challenges/test_views.py +++ b/tests/unit/challenges/test_views.py @@ -74,6 +74,7 @@ def setUp(self): submission_guidelines="Submission guidelines for test challenge", creator=self.challenge_host_team, published=False, + is_profile_required=False, is_registration_open=True, enable_forum=True, anonymous_leaderboard=False, @@ -153,6 +154,7 @@ def test_get_challenge(self): "team_url": self.challenge.creator.team_url, }, "published": self.challenge.published, + "is_profile_required": self.challenge.is_profile_required, "is_registration_open": self.challenge.is_registration_open, "enable_forum": self.challenge.enable_forum, "leaderboard_description": self.challenge.leaderboard_description, @@ -262,6 +264,7 @@ def test_get_particular_challenge(self): "team_url": self.challenge.creator.team_url, }, "published": self.challenge.published, + "is_profile_required": self.challenge.is_profile_required, "is_registration_open": self.challenge.is_registration_open, "enable_forum": self.challenge.enable_forum, "leaderboard_description": self.challenge.leaderboard_description, @@ -332,6 +335,7 @@ def test_update_challenge_when_user_is_its_creator(self): "team_url": self.challenge.creator.team_url, }, "published": self.challenge.published, + "is_profile_required": self.challenge.is_profile_required, "is_registration_open": self.challenge.is_registration_open, "enable_forum": self.challenge.enable_forum, "leaderboard_description": self.challenge.leaderboard_description, @@ -423,6 +427,7 @@ def test_particular_challenge_partial_update(self): "team_url": self.challenge.creator.team_url, }, "published": self.challenge.published, + "is_profile_required": self.challenge.is_profile_required, "is_registration_open": self.challenge.is_registration_open, "enable_forum": self.challenge.enable_forum, "leaderboard_description": self.challenge.leaderboard_description, @@ -470,6 +475,7 @@ def test_particular_challenge_update(self): "team_url": self.challenge.creator.team_url, }, "published": self.challenge.published, + "is_profile_required": self.challenge.is_profile_required, "is_registration_open": self.challenge.is_registration_open, "enable_forum": self.challenge.enable_forum, "leaderboard_description": self.challenge.leaderboard_description, @@ -894,6 +900,7 @@ def setUp(self): submission_guidelines="Submission guidelines for test challenge 2", creator=self.challenge_host_team, published=True, + is_profile_required=False, is_registration_open=True, enable_forum=True, approved_by_admin=True, @@ -911,6 +918,7 @@ def setUp(self): submission_guidelines="Submission guidelines for test challenge 3", creator=self.challenge_host_team, published=True, + is_profile_required=False, is_registration_open=True, enable_forum=True, approved_by_admin=True, @@ -929,6 +937,7 @@ def setUp(self): submission_guidelines="Submission guidelines for test challenge 4", creator=self.challenge_host_team, published=True, + is_profile_required=False, is_registration_open=True, enable_forum=True, approved_by_admin=True, @@ -980,6 +989,7 @@ def test_get_past_challenges(self): "team_url": self.challenge3.creator.team_url, }, "published": self.challenge3.published, + "is_profile_required": self.challenge3.is_profile_required, "is_registration_open": self.challenge3.is_registration_open, "enable_forum": self.challenge3.enable_forum, "leaderboard_description": self.challenge3.leaderboard_description, @@ -1029,6 +1039,7 @@ def test_get_present_challenges(self): "team_url": self.challenge2.creator.team_url, }, "published": self.challenge2.published, + "is_profile_required": self.challenge2.is_profile_required, "is_registration_open": self.challenge2.is_registration_open, "enable_forum": self.challenge2.enable_forum, "leaderboard_description": self.challenge2.leaderboard_description, @@ -1078,6 +1089,7 @@ def test_get_future_challenges(self): "team_url": self.challenge4.creator.team_url, }, "published": self.challenge4.published, + "is_profile_required": self.challenge4.is_profile_required, "is_registration_open": self.challenge4.is_registration_open, "enable_forum": self.challenge4.enable_forum, "leaderboard_description": self.challenge4.leaderboard_description, @@ -1126,6 +1138,7 @@ def test_get_all_challenges(self): "team_url": self.challenge4.creator.team_url, }, "published": self.challenge4.published, + "is_profile_required": self.challenge4.is_profile_required, "is_registration_open": self.challenge4.is_registration_open, "enable_forum": self.challenge4.enable_forum, "leaderboard_description": self.challenge4.leaderboard_description, @@ -1163,6 +1176,7 @@ def test_get_all_challenges(self): "team_url": self.challenge3.creator.team_url, }, "published": self.challenge3.published, + "is_profile_required": self.challenge3.is_profile_required, "is_registration_open": self.challenge3.is_registration_open, "enable_forum": self.challenge3.enable_forum, "leaderboard_description": self.challenge3.leaderboard_description, @@ -1200,6 +1214,7 @@ def test_get_all_challenges(self): "team_url": self.challenge2.creator.team_url, }, "published": self.challenge2.published, + "is_profile_required": self.challenge2.is_profile_required, "is_registration_open": self.challenge2.is_registration_open, "enable_forum": self.challenge2.enable_forum, "leaderboard_description": self.challenge2.leaderboard_description, @@ -1264,6 +1279,7 @@ def setUp(self): submission_guidelines="Submission guidelines for test challenge 3", creator=self.challenge_host_team, published=True, + is_profile_required=False, is_registration_open=True, enable_forum=True, approved_by_admin=True, @@ -1298,6 +1314,7 @@ def test_get_featured_challenges(self): "team_url": self.challenge3.creator.team_url, }, "published": self.challenge3.published, + "is_profile_required": self.challenge3.is_profile_required, "is_registration_open": self.challenge3.is_registration_open, "enable_forum": self.challenge3.enable_forum, "leaderboard_description": self.challenge3.leaderboard_description, @@ -1344,6 +1361,7 @@ def setUp(self): submission_guidelines="Submission guidelines for test challenge 3", creator=self.challenge_host_team, published=False, + is_profile_required=False, is_registration_open=True, enable_forum=True, anonymous_leaderboard=False, @@ -1360,6 +1378,7 @@ def setUp(self): submission_guidelines="Submission guidelines for test challenge 4", creator=self.challenge_host_team, published=True, + is_profile_required=False, is_registration_open=True, enable_forum=True, leaderboard_description="Curabitur nec placerat libero.", @@ -1423,6 +1442,7 @@ def test_get_challenge_by_pk_when_user_is_challenge_host(self): "team_url": self.challenge3.creator.team_url, }, "published": self.challenge3.published, + "is_profile_required": self.challenge3.is_profile_required, "is_registration_open": self.challenge3.is_registration_open, "enable_forum": self.challenge3.enable_forum, "leaderboard_description": self.challenge3.leaderboard_description, @@ -1484,6 +1504,7 @@ def test_get_challenge_by_pk_when_user_is_participant(self): "team_url": self.challenge4.creator.team_url, }, "published": self.challenge4.published, + "is_profile_required": self.challenge4.is_profile_required, "is_registration_open": self.challenge4.is_registration_open, "enable_forum": self.challenge4.enable_forum, "leaderboard_description": self.challenge4.leaderboard_description, @@ -1538,6 +1559,7 @@ def setUp(self): submission_guidelines="Submission guidelines for test challenge", creator=self.challenge_host_team, published=True, + is_profile_required=False, is_registration_open=True, enable_forum=True, leaderboard_description=None, @@ -1555,6 +1577,7 @@ def setUp(self): submission_guidelines="Submission guidelines for some test challenge", creator=self.challenge_host_team2, published=True, + is_profile_required=False, is_registration_open=True, enable_forum=True, anonymous_leaderboard=False, @@ -1601,6 +1624,7 @@ def test_get_challenge_when_host_team_is_given(self): "team_url": self.challenge2.creator.team_url, }, "published": self.challenge2.published, + "is_profile_required": self.challenge2.is_profile_required, "is_registration_open": self.challenge2.is_registration_open, "enable_forum": self.challenge2.enable_forum, "leaderboard_description": self.challenge2.leaderboard_description, @@ -1650,6 +1674,7 @@ def test_get_challenge_when_participant_team_is_given(self): "team_url": self.challenge2.creator.team_url, }, "published": self.challenge2.published, + "is_profile_required": self.challenge2.is_profile_required, "is_registration_open": self.challenge2.is_registration_open, "enable_forum": self.challenge2.enable_forum, "leaderboard_description": self.challenge2.leaderboard_description, @@ -1699,6 +1724,7 @@ def test_get_challenge_when_mode_is_participant(self): "team_url": self.challenge2.creator.team_url, }, "published": self.challenge2.published, + "is_profile_required": self.challenge2.is_profile_required, "is_registration_open": self.challenge2.is_registration_open, "enable_forum": self.challenge2.enable_forum, "leaderboard_description": self.challenge2.leaderboard_description, @@ -1746,6 +1772,7 @@ def test_get_challenge_when_mode_is_host(self): "team_url": self.challenge.creator.team_url, }, "published": self.challenge.published, + "is_profile_required": self.challenge.is_profile_required, "is_registration_open": self.challenge.is_registration_open, "enable_forum": self.challenge.enable_forum, "leaderboard_description": self.challenge.leaderboard_description, @@ -1783,6 +1810,7 @@ def test_get_challenge_when_mode_is_host(self): "team_url": self.challenge2.creator.team_url, }, "published": self.challenge2.published, + "is_profile_required": self.challenge2.is_profile_required, "is_registration_open": self.challenge2.is_registration_open, "enable_forum": self.challenge2.enable_forum, "leaderboard_description": self.challenge2.leaderboard_description, diff --git a/tests/unit/participants/test_views.py b/tests/unit/participants/test_views.py index f7028f58d5..13ab885a63 100644 --- a/tests/unit/participants/test_views.py +++ b/tests/unit/participants/test_views.py @@ -576,6 +576,7 @@ def setUp(self): submission_guidelines="Submission guidelines for test challenge 1", creator=self.challenge_host_team, published=False, + is_profile_required=False, is_registration_open=True, enable_forum=True, leaderboard_description="Lorem ipsum dolor sit amet, consectetur adipiscing elit", @@ -640,6 +641,7 @@ def test_get_teams_and_corresponding_challenges_for_a_participant(self): "team_url": self.challenge_host_team.team_url, }, "published": self.challenge1.published, + "is_profile_required": self.challenge1.is_profile_required, "is_registration_open": self.challenge1.is_registration_open, "enable_forum": self.challenge1.enable_forum, "leaderboard_description": self.challenge1.leaderboard_description, @@ -704,6 +706,7 @@ def test_get_participant_team_challenge_list(self): "team_url": self.challenge_host_team.team_url, }, "published": self.challenge1.published, + "is_profile_required": self.challenge1.is_profile_required, "is_registration_open": self.challenge1.is_registration_open, "enable_forum": self.challenge1.enable_forum, "leaderboard_description": self.challenge1.leaderboard_description,