diff --git a/apps/challenges/models.py b/apps/challenges/models.py index 1b0cb0656a..b7b6228cf9 100644 --- a/apps/challenges/models.py +++ b/apps/challenges/models.py @@ -5,6 +5,7 @@ from django.contrib.auth.models import User from django.contrib.postgres.fields import ArrayField, JSONField from django.core import serializers +from django.core.exceptions import ValidationError from django.db import models from django.db.models import signals from django.db.models.signals import pre_save @@ -354,10 +355,26 @@ def get_end_date(self): @property def is_active(self): """Returns if the challenge is active or not""" - if self.start_date < timezone.now() and self.end_date > timezone.now(): + if ( + self.start_date + and self.end_date + and self.start_date < timezone.now() + and self.end_date > timezone.now() + ): return True return False + def save(self, *args, **kwargs): + if ( + self.start_date + and self.end_date + and self.start_date >= self.end_date + ): + raise ValidationError( + "Challenge start date must be before end date." + ) + super(Challenge, self).save(*args, **kwargs) + @receiver(signals.post_save, sender="challenges.Challenge") def create_eks_cluster_or_ec2_for_challenge( @@ -586,11 +603,58 @@ def get_end_date(self): @property def is_active(self): """Returns if the challenge is active or not""" - if self.start_date < timezone.now() and self.end_date > timezone.now(): + if ( + self.start_date + and self.end_date + and self.start_date < timezone.now() + and self.end_date > timezone.now() + ): return True return False def save(self, *args, **kwargs): + challenge = self.challenge + if challenge: + if ( + self.start_date + and challenge.start_date + and self.start_date < challenge.start_date + ): + raise ValidationError( + "Phase start date must be on or after challenge start date." + ) + if ( + self.start_date + and challenge.end_date + and self.start_date >= challenge.end_date + ): + raise ValidationError( + "Phase start date must be before challenge end date." + ) + if ( + self.end_date + and challenge.start_date + and self.end_date <= challenge.start_date + ): + raise ValidationError( + "Phase end date must be after challenge start date." + ) + if ( + self.end_date + and challenge.end_date + and self.end_date > challenge.end_date + ): + raise ValidationError( + "Phase end date must be on or before challenge end date." + ) + if ( + self.start_date + and self.end_date + and self.start_date >= self.end_date + ): + raise ValidationError( + "Phase start date must be before end date." + ) # If the max_submissions_per_day is less than the # max_concurrent_submissions_allowed. diff --git a/apps/challenges/serializers.py b/apps/challenges/serializers.py index 90fbf3bcba..63f4aa1030 100644 --- a/apps/challenges/serializers.py +++ b/apps/challenges/serializers.py @@ -36,6 +36,19 @@ class ChallengeSerializer(serializers.ModelSerializer): def get_domain_name(self, obj): return obj.get_domain_display() + def validate(self, attrs): + start_date = attrs.get( + "start_date", getattr(self.instance, "start_date", None) + ) + end_date = attrs.get( + "end_date", getattr(self.instance, "end_date", None) + ) + if start_date and end_date and start_date >= end_date: + raise serializers.ValidationError( + "Challenge start date must be before end date." + ) + return attrs + def validate_worker_python_version(self, value): if value in (None, ""): return DEFAULT_WORKER_PYTHON_VERSION @@ -147,6 +160,45 @@ class ChallengePhaseSerializer(serializers.ModelSerializer): is_active = serializers.ReadOnlyField() + def validate(self, attrs): + start_date = attrs.get( + "start_date", getattr(self.instance, "start_date", None) + ) + end_date = attrs.get( + "end_date", getattr(self.instance, "end_date", None) + ) + challenge = attrs.get( + "challenge", getattr(self.instance, "challenge", None) + ) + if challenge: + csd = challenge.start_date + ced = challenge.end_date + if start_date and csd and start_date < csd: + raise serializers.ValidationError( + "Phase start date must be on or after " + "challenge start date." + ) + if start_date and ced and start_date >= ced: + raise serializers.ValidationError( + "Phase start date must be before " + "challenge end date." + ) + if end_date and csd and end_date <= csd: + raise serializers.ValidationError( + "Phase end date must be after " + "challenge start date." + ) + if end_date and ced and end_date > ced: + raise serializers.ValidationError( + "Phase end date must be on or before " + "challenge end date." + ) + if start_date and end_date and start_date >= end_date: + raise serializers.ValidationError( + "Phase start date must be before end date." + ) + return attrs + def __init__(self, *args, **kwargs): super(ChallengePhaseSerializer, self).__init__(*args, **kwargs) context = kwargs.get("context") @@ -441,6 +493,45 @@ class ChallengePhaseCreateSerializer(serializers.ModelSerializer): is_active = serializers.ReadOnlyField() + def validate(self, attrs): + start_date = attrs.get( + "start_date", getattr(self.instance, "start_date", None) + ) + end_date = attrs.get( + "end_date", getattr(self.instance, "end_date", None) + ) + challenge = attrs.get( + "challenge", getattr(self.instance, "challenge", None) + ) + if challenge: + csd = challenge.start_date + ced = challenge.end_date + if start_date and csd and start_date < csd: + raise serializers.ValidationError( + "Phase start date must be on or after " + "challenge start date." + ) + if start_date and ced and start_date >= ced: + raise serializers.ValidationError( + "Phase start date must be before " + "challenge end date." + ) + if end_date and csd and end_date <= csd: + raise serializers.ValidationError( + "Phase end date must be after " + "challenge start date." + ) + if end_date and ced and end_date > ced: + raise serializers.ValidationError( + "Phase end date must be on or before " + "challenge end date." + ) + if start_date and end_date and start_date >= end_date: + raise serializers.ValidationError( + "Phase start date must be before end date." + ) + return attrs + def __init__(self, *args, **kwargs): super(ChallengePhaseCreateSerializer, self).__init__(*args, **kwargs) context = kwargs.get("context") diff --git a/frontend/src/js/controllers/challengeCtrl.js b/frontend/src/js/controllers/challengeCtrl.js index b485cec378..5858221f02 100644 --- a/frontend/src/js/controllers/challengeCtrl.js +++ b/frontend/src/js/controllers/challengeCtrl.js @@ -71,6 +71,7 @@ vm.isSubmissionUsingUrl = null; vm.isSubmissionUsingCli = null; vm.isSubmissionUsingFile = null; + vm.submissionType = null; vm.isRemoteChallenge = false; vm.allowResumingSubmisisons = false; vm.allowCancelRunningSubmissions = false; @@ -738,6 +739,10 @@ vm.projectUrl = ""; vm.publicationUrl = ""; vm.isPublicSubmission = null; + vm.isSubmissionUsingCli = null; + vm.isSubmissionUsingFile = null; + vm.isSubmissionUsingUrl = null; + vm.submissionType = null; $rootScope.notify("success", "Your submission has been recorded succesfully!"); vm.disableSubmit = true; vm.showSubmissionNumbers = false; @@ -755,6 +760,10 @@ vm.projectUrl = null; vm.publicationUrl = null; vm.isPublicSubmission = null; + vm.isSubmissionUsingCli = null; + vm.isSubmissionUsingFile = null; + vm.isSubmissionUsingUrl = null; + vm.submissionType = null; if (status == 404) { vm.subErrors.msg = "Please select phase!"; } else { diff --git a/frontend/src/views/web/challenge/submission.html b/frontend/src/views/web/challenge/submission.html index 860c402169..ebe0763564 100644 --- a/frontend/src/views/web/challenge/submission.html +++ b/frontend/src/views/web/challenge/submission.html @@ -224,14 +224,14 @@
Select submission type: