Esempio n. 1
0
    def test_view_all_submissions_does_not_show_code_for_submissions(self):
        second_submission = Submission(language=self.python_language, challenge=self.challenge, author=self.auth_user, code="time")
        second_submission.save()
        response = self.client.get(path='/challenges/{}/submissions/all'.format(self.challenge.id), HTTP_AUTHORIZATION=self.auth_token)

        self.assertEqual(response.status_code, 200)
        for submission in response.data:
            self.assertNotIn('code', submission.keys())
Esempio n. 2
0
    def test_view_all_submissions(self):
        second_submission = Submission(language=self.python_language, challenge=self.challenge, author=self.auth_user, code="")
        second_submission.save()
        response = self.client.get(path='/challenges/{}/submissions/all'.format(self.challenge.id), HTTP_AUTHORIZATION=self.auth_token)

        self.assertEqual(response.status_code, 200)
        # Should order them by creation date descending
        self.assertEqual(LimitedSubmissionSerializer([second_submission, self.submission], many=True).data, response.data)
Esempio n. 3
0
    def test_can_save_duplicate_submission(self):
        s = Submission(language=self.python_language, challenge=self.challenge, author=self.auth_user, code="")
        s.save()
        s = Submission(language=self.python_language, challenge=self.challenge, author=self.auth_user, code="")
        s.save()

        self.assertEqual(Submission.objects.count(), 2)
Esempio n. 4
0
    def create_challenge_completion_post(self, submission: Submission):
        """
        Creates a NewsfeedItem of type ChallengeCompletion
            ex: Stanislav has completed challenge Firefox with 100/100 score after 30 attempts
        """
        challenge = submission.challenge
        author: User = submission.author
        if not submission.has_solved_challenge():
            raise Exception(f'Submission has not solved the challenge!')

        return self.create(
            author_id=author.id,
            type=NW_ITEM_CHALLENGE_COMPLETION_POST,
            content={
                'challenge_id':
                challenge.id,
                'challenge_name':
                challenge.name,
                'submission_id':
                submission.id,
                'challenge_score':
                challenge.score,
                'attempts_count':
                author.fetch_unsuccessful_challenge_attempts_count(challenge)
            })
Esempio n. 5
0
    def to_representation(self, instance: Submission):
        """
        Modification to add four variables to the serialized data
            - user_has_voted - Boolean indicating if the user has voted at all for this
            - user_has_upvoted - Boolean indicating if the user has upvoted the submission (user_has_voted must be true)
            - upvote_count - int showing the amount of upvotes this submission has
            - downvote_count - int showing the amount of downvotes this submission has
        """
        from accounts.models import User
        result = super().to_representation(instance)
        user: User = getattr(self.context.get('request', None), 'user', None)
        # TODO: Move to helper
        # TODO: Make user be passed in __init__
        if user is None:
            result['user_has_voted'] = False
            result['user_has_upvoted'] = False
        else:
            user_vote = user.get_vote_for_submission(submission_id=instance.id)
            if user_vote is None:
                result['user_has_voted'] = False
                result['user_has_upvoted'] = False
            else:
                result['user_has_voted'] = True
                result['user_has_upvoted'] = user_vote.is_upvote

        upvote_count, downvote_count = instance.get_votes_count()
        result['upvote_count'] = upvote_count
        result['downvote_count'] = downvote_count

        return result
Esempio n. 6
0
    def test_fetch_top_submission_for_challenge_and_user_ignores_pending_submissions(self):
        SubmissionFactory(author=self.auth_user, challenge=self.challenge, result_score=50, pending=True)
        SubmissionFactory(author=self.auth_user, challenge=self.challenge, result_score=66, pending=True)

        received_submission = Submission.fetch_top_submission_for_challenge_and_user(self.challenge.id,
                                                                                     self.auth_user.id)
        # should return None as there is no top submission
        self.assertIsNone(received_submission)
Esempio n. 7
0
    def fetch_max_score_for_challenge(self, challenge_id):
        """
        Fetches the maximum score this user has scored for the given challenge
        """
        from challenges.models import Submission

        top_submission = Submission.fetch_top_submission_for_challenge_and_user(
            challenge_id, self.id)
        max_score = top_submission.maxscore if top_submission else 0
        return max_score
Esempio n. 8
0
    def test_fetch_top_submission_for_challenge_and_user_returns_bigger_score(self):
        SubmissionFactory(author=self.auth_user, challenge=self.challenge, result_score=50, pending=False)
        SubmissionFactory(author=self.auth_user, challenge=self.challenge, result_score=66, pending=False)
        # IS PENDING!
        SubmissionFactory(author=self.auth_user, challenge=self.challenge, result_score=1000, pending=True)
        SubmissionFactory(author=self.auth_user, challenge=self.challenge, result_score=100, pending=False)

        received_submission = Submission.fetch_top_submission_for_challenge_and_user(self.challenge.id,
                                                                                     self.auth_user.id)
        self.assertIsNotNone(received_submission)
        self.assertEqual(received_submission.maxscore, 100)
Esempio n. 9
0
    def list(self, request, *args, **kwargs):
        latest_submissions = Submission.fetch_last_10_submissions_for_unique_challenges_by_user(
            user_id=request.user.id)

        latest_challenges = [
            submission.challenge for submission in latest_submissions
        ]

        return Response(data=LimitedChallengeSerializer(
            latest_challenges, many=True, context={
                'request': request
            }).data)
Esempio n. 10
0
def archive_submission(submission, form, link_form, phase):
    """Archive the old ``Submisssion`` and create a new entry for the currrent
    ``Phase`` ``PhaseRound`` combination"""
    previous_submission = submission
    new_submission = Submission(created_by=previous_submission.created_by,
                                category=previous_submission.category,
                                phase=phase)
    # ``Submission`` enters to tne open ``PhaseRound``
    if phase.current_round:
        new_submission.phase_round = phase.current_round
    # Reuse the existing image if one hasn't been provided
    if not form.cleaned_data.get('sketh_note'):
        new_submission.sketh_note = submission.sketh_note
    # Create a new instance of the ``ModelForm`` since we want to duplicate
    # and call whatever mechanisms might be triggered through the form
    new_form = form.__class__(form.data, form.files, instance=new_submission)
    new_submission = new_form.save()
    submission.parent.update_version(new_submission)
    # Duplicate the links sent for this ``Submission``
    create_link = lambda link: ExternalLink.objects.create(
        url=link['url'], name=link['name'], submission=new_submission)
    link_form = [create_link(link) for link in link_form.cleaned_data if link]
    return new_submission
Esempio n. 11
0
    def list(self, request, *args, **kwargs):
        challenge_pk = kwargs.get('challenge_pk', '')
        try:
            Challenge.objects.get(pk=challenge_pk)
        except Challenge.DoesNotExist:
            return Response(
                data={'error': f'Invalid challenge id {challenge_pk}!'},
                status=400)

        top_submissions = Submission.fetch_top_submissions_for_challenge(
            challenge_id=challenge_pk)

        return Response(
            data=LimitedSubmissionSerializer(top_submissions, many=True).data)
Esempio n. 12
0
def archive_submission(submission, form, link_form, phase):
    """Archive the old ``Submisssion`` and create a new entry for the currrent
    ``Phase`` ``PhaseRound`` combination"""
    previous_submission = submission
    new_submission = Submission(created_by=previous_submission.created_by,
                                category=previous_submission.category,
                                phase=phase)
    # ``Submission`` enters to tne open ``PhaseRound``
    if phase.current_round:
        new_submission.phase_round = phase.current_round
    # Reuse the existing image if one hasn't been provided
    if not form.cleaned_data.get('sketh_note'):
        new_submission.sketh_note = submission.sketh_note
    # Create a new instance of the ``ModelForm`` since we want to duplicate
    # and call whatever mechanisms might be triggered through the form
    new_form = form.__class__(form.data, form.files, instance=new_submission)
    new_submission = new_form.save()
    submission.parent.update_version(new_submission)
    # Duplicate the links sent for this ``Submission``
    create_link = lambda link: ExternalLink.objects.create(
        url=link['url'], name=link['name'], submission=new_submission)
    link_form = [create_link(link) for link in link_form.cleaned_data if link]
    return new_submission
Esempio n. 13
0
    def retrieve(self, request, *args, **kwargs):
        challenge_pk = kwargs.get('challenge_pk', '')
        try:
            Challenge.objects.get(pk=challenge_pk)
        except Challenge.DoesNotExist:
            return Response(
                data={'error': f'Invalid challenge id {challenge_pk}!'},
                status=400)

        top_submission = Submission.fetch_top_submission_for_challenge_and_user(
            challenge_id=challenge_pk, user_id=request.user.id)

        if top_submission is None:
            return Response(status=404)  # doesnt exist

        return Response(data=LimitedSubmissionSerializer(top_submission).data)
Esempio n. 14
0
    def test_fetch_last_10_submissions_for_unique_challenges_by_author(self):
        """ The method should return the last 10 submissions for unique challenges by the author """
        for _ in range(20):
            # Create 20 submissions
            SubmissionFactory(author=self.auth_user)
        for _ in range(10):
            # Create last 10 submissions for one challenge
            SubmissionFactory(author=self.auth_user, challenge=self.challenge)

        latest_unique_submissions = Submission.fetch_last_10_submissions_for_unique_challenges_by_user(user_id=self.auth_user.id)

        # the first one should be for self.challenge, since we made it last
        self.assertEqual(latest_unique_submissions[0].challenge, self.challenge)

        # they should all be for unique challenges
        unique_challenge_ids = set([s.challenge.id for s in latest_unique_submissions])
        self.assertEqual(10, len(unique_challenge_ids))
Esempio n. 15
0
    def test_fetch_top_submissions(self):
        """
        The method should return the top submissions for a given challenge,
            selecting the top submission for each user
        """
        """ Arrange """
        f_submission = SubmissionFactory(author=self.auth_user, challenge=self.challenge, result_score=50)
        # Second user with submissions
        s_user = UserFactory()
        SubmissionFactory(author=s_user, challenge=self.challenge)  # should get ignored
        top_submission = SubmissionFactory(author=s_user, challenge=self.challenge, result_score=51)
        # Third user with equal to first submission
        t_user = UserFactory()
        tr_sub = SubmissionFactory(challenge=self.challenge, author=t_user, result_score=50)

        expected_submissions = [top_submission, f_submission, tr_sub]  # ordered by score, then by date (oldest first)

        received_submissions = list(Submission.fetch_top_submissions_for_challenge(self.challenge.id))
        self.assertEqual(expected_submissions, received_submissions)
Esempio n. 16
0
    def create(self, request, *args, **kwargs):
        challenge_pk = kwargs.get('challenge_pk')
        code_given = request.data.get('code')
        language_given = request.data.get('language')

        challenge, language, is_valid, response = self.validate_data(
            challenge_pk, code_given, language_given, request.user)
        if not is_valid:
            return response  # invalid data

        submission = Submission(code=code_given,
                                author=request.user,
                                challenge=challenge,
                                task_id=1,
                                language=language)
        submission.save()
        celery_task = run_grader_task.delay(
            test_case_count=challenge.test_case_count,
            test_folder_name=challenge.test_file_name,
            code=code_given,
            lang=language.name,
            submission_id=submission.id)

        request.user.last_submit_at = timezone.now()
        request.user.save()

        submission.task_id = celery_task
        submission.save()

        # Create the test cases
        TestCase.objects.bulk_create([
            TestCase(submission=submission)
            for _ in range(challenge.test_case_count)
        ])

        return Response(data=SubmissionSerializer(submission).data, status=201)
Esempio n. 17
0
def grade_result(submission: Submission, timed_out_percentage: int,
                 elapsed_seconds: float):
    """
    Given a tested submission and the percentage of test cases that have timed out,
        update its score in accordance to the number of test cases passed
        and if more than 40% of the test cases have timed out, set the Submission's timed_out field as true
    """
    challenge: Challenge = submission.challenge

    num_successful_tests = len([
        True for ts_cs in submission.testcase_set.all()
        if not ts_cs.pending and ts_cs.success
    ])
    result_per_test = challenge.score / challenge.test_case_count

    submission.result_score = num_successful_tests * result_per_test
    submission.pending = False
    submission.elapsed_seconds = elapsed_seconds
    if timed_out_percentage >= SUBMISSION_MINIMUM_TIMED_OUT_PERCENTAGE:
        submission.timed_out = True
    submission.save()
Esempio n. 18
0
 def test_fetch_top_submission_for_challenge_and_user_no_submissions_should_be_empty(self):
     received_submission = Submission.fetch_top_submission_for_challenge_and_user(self.challenge.id, self.auth_user.id)
     self.assertIsNone(received_submission)
Esempio n. 19
0
 def test_fetch_top_submissions_no_submissions_should_be_empty(self):
     received_submissions = list(Submission.fetch_top_submissions_for_challenge(self.challenge.id))
     self.assertEqual([], received_submissions)
Esempio n. 20
0
 def test_cannot_save_blank_submission(self):
     s = Submission(language=self.python_language, challenge=self.challenge, author=self.auth_user, code='')
     with self.assertRaises(Exception):
         s.full_clean()
Esempio n. 21
0
    def test_absolute_url(self):
        s = Submission(language=self.python_language, challenge=self.challenge, author=self.auth_user, code="")
        s.save()

        self.assertEqual(s.get_absolute_url(), '/challenges/{}/submissions/{}'.format(s.challenge_id, s.id))