public void SubmitActionWhenParticipantSendsAnotherSubmissionBeforeLimitHasPassedShouldThrowException()
        {
            var contest = this.CreateAndSaveContest("test contest", this.ActiveContestNoPasswordOptions, this.ActiveContestNoPasswordOptions);
            contest.LimitBetweenSubmissions = 100;

            var problem = new Problem
            {
                Name = "test problem"
            };

            var submissionType = new SubmissionType
            {
                Name = "test submission type"
            };

            contest.Problems.Add(problem);
            contest.SubmissionTypes.Add(submissionType);
            contest.Participants.Add(new Participant(contest.Id, this.FakeUserProfile.Id, this.IsCompete));
            this.EmptyOjsData.SaveChanges();

            var submission = new SubmissionModel
            {
                Content = "test content",
                ProblemId = problem.Id,
                SubmissionTypeId = submissionType.Id
            };

            var result = this.CompeteController.Submit(submission, this.IsCompete) as JsonResult;
            var receivedContestId = (int)result.Data;
            Assert.AreEqual(receivedContestId, contest.Id);

            try
            {
                var secondSubmissionResult = this.CompeteController.Submit(submission, this.IsCompete);
                Assert.Fail("Expected an exception when a participant sends too many submissions");
            }
            catch (HttpException ex)
            {
                Assert.AreEqual((int)HttpStatusCode.ServiceUnavailable, ex.GetHttpCode());
            }
        }
        public void SubmitActionWhenParticipantSendsAnotherSubmissionAndThereIsNoLimitShouldReturnJson()
        {
            var contest = this.CreateAndSaveContest("test contest", this.ActiveContestNoPasswordOptions, this.ActiveContestNoPasswordOptions);

            // no limit between submissions
            contest.LimitBetweenSubmissions = 0;

            var problem = new Problem
            {
                Name = "test problem"
            };

            var submissionType = new SubmissionType
            {
                Name = "test submission type"
            };

            contest.Problems.Add(problem);
            contest.SubmissionTypes.Add(submissionType);
            contest.Participants.Add(new Participant(contest.Id, this.FakeUserProfile.Id, this.IsCompete));
            this.EmptyOjsData.SaveChanges();

            var submission = new SubmissionModel
            {
                Content = "test content",
                ProblemId = problem.Id,
                SubmissionTypeId = submissionType.Id
            };

            var result = this.CompeteController.Submit(submission, this.IsCompete) as JsonResult;
            var receivedContestId = (int)result.Data;
            Assert.AreEqual(receivedContestId, contest.Id);

            var secondSubmissionResult = this.CompeteController.Submit(submission, this.IsCompete) as JsonResult;
            var secondSubmissionResultContestId = (int)secondSubmissionResult.Data;

            Assert.AreEqual(receivedContestId, secondSubmissionResultContestId);
        }
        public ActionResult Submit(SubmissionModel participantSubmission, int id, bool official)
        {
            var participant = this.Data.Participants.GetWithContest(id, this.UserProfile.Id, official);
            var problem = this.Data.Problems.All().FirstOrDefault(x => x.Id == participantSubmission.ProblemId);

            if (participant == null)
            {
                throw new HttpException((int)HttpStatusCode.Unauthorized, Resource.ContestsGeneral.User_is_not_registered_for_exam);
            }

            ValidateContest(participant.Contest, official);

            if (participant.Submissions.Any())
            {
                // check if the submission was sent after the submission time limit has passed
                var latestSubmissionTime = participant.Submissions.Max(x => x.CreatedOn);
                TimeSpan differenceBetweenSubmissions = DateTime.Now - latestSubmissionTime;
                int limitBetweenSubmissions = participant.Contest.LimitBetweenSubmissions;

                if (differenceBetweenSubmissions.TotalSeconds < limitBetweenSubmissions)
                {
                    throw new HttpException((int)HttpStatusCode.ServiceUnavailable, Resource.ContestsGeneral.Submission_was_sent_too_soon);
                }
            }

            if (problem.SourceCodeSizeLimit < participantSubmission.Content.Length)
            {
                throw new HttpException((int)HttpStatusCode.BadRequest, Resource.ContestsGeneral.Submission_too_long);
            }

            if (!ModelState.IsValid)
            {
                throw new HttpException((int)HttpStatusCode.BadRequest, Resource.ContestsGeneral.Invalid_request);
            }

            this.Data.Submissions.Add(new Submission
            {
                ContentAsString = participantSubmission.Content,
                ProblemId = participantSubmission.ProblemId,
                SubmissionTypeId = participantSubmission.SubmissionTypeId,
                ParticipantId = participant.Id
            });

            this.Data.SaveChanges();

            return this.Json(participantSubmission.ProblemId);
        }
        public ActionResult Submit(SubmissionModel participantSubmission, bool official)
        {
            var problem = this.Data.Problems.All().FirstOrDefault(x => x.Id == participantSubmission.ProblemId);
            if (problem == null)
            {
                throw new HttpException((int)HttpStatusCode.Unauthorized, Resource.ContestsGeneral.Problem_not_found);
            }

            var participant = this.Data.Participants.GetWithContest(problem.ContestId, this.UserProfile.Id, official);
            if (participant == null)
            {
                throw new HttpException((int)HttpStatusCode.Unauthorized, Resource.ContestsGeneral.User_is_not_registered_for_exam);
            }

            ValidateContest(participant.Contest, official);
            ValidateSubmissionType(participantSubmission.SubmissionTypeId, participant.Contest);

            if (this.Data.Submissions.HasSubmissionTimeLimitPassedForParticipant(participant.Id, participant.Contest.LimitBetweenSubmissions))
            {
                throw new HttpException((int)HttpStatusCode.ServiceUnavailable, Resource.ContestsGeneral.Submission_was_sent_too_soon);
            }

            if (problem.SourceCodeSizeLimit < participantSubmission.Content.Length)
            {
                throw new HttpException((int)HttpStatusCode.BadRequest, Resource.ContestsGeneral.Submission_too_long);
            }

            if (!this.ModelState.IsValid)
            {
                throw new HttpException((int)HttpStatusCode.BadRequest, Resource.ContestsGeneral.Invalid_request);
            }

            this.Data.Submissions.Add(new Submission
            {
                ContentAsString = participantSubmission.Content,
                ProblemId = participantSubmission.ProblemId,
                SubmissionTypeId = participantSubmission.SubmissionTypeId,
                ParticipantId = participant.Id,
                IpAddress = this.Request.UserHostAddress,
            });

            this.Data.SaveChanges();

            return this.Json(participantSubmission.ProblemId);
        }
        public void SubmitActionWhenUserIsNotRegisteredToParticipateShouldThrowException()
        {
            var contest = this.CreateAndSaveContest("someContest", this.ActiveContestNoPasswordOptions, this.ActiveContestNoPasswordOptions);
            var problem = new Problem
            {
                Name = "test problem"
            };

            var submissionType = new SubmissionType
            {
                Name = "test submission type"
            };

            contest.Problems.Add(problem);
            contest.SubmissionTypes.Add(submissionType);
            this.EmptyOjsData.SaveChanges();

            var submission = new SubmissionModel
            {
                Content = "test submission",
                ProblemId = problem.Id,
                SubmissionTypeId = submissionType.Id
            };

            try
            {
                var result = this.CompeteController.Submit(submission, this.IsCompete);
                Assert.Fail("An exception was expected when a user is trying to submit for a contest that he isn't registered for.");
            }
            catch (HttpException ex)
            {
                Assert.AreEqual((int)HttpStatusCode.Unauthorized, ex.GetHttpCode());
            }
        }
        public void SubmitActionWhenParticipantSendsEmptySubmissionContestShouldThrowException()
        {
            var contest = this.CreateAndSaveContest("test contest", this.ActiveContestNoPasswordOptions, this.ActiveContestNoPasswordOptions);

            // no limit between submissions
            contest.LimitBetweenSubmissions = 0;

            var problem = new Problem
            {
                Name = "test problem"
            };

            var submissionType = new SubmissionType
            {
                Name = "test submission type"
            };

            contest.Problems.Add(problem);
            contest.SubmissionTypes.Add(submissionType);
            contest.Participants.Add(new Participant(contest.Id, this.FakeUserProfile.Id, this.IsCompete));
            this.EmptyOjsData.SaveChanges();

            var submission = new SubmissionModel
            {
                Content = string.Empty,
                ProblemId = problem.Id,
                SubmissionTypeId = submissionType.Id
            };

            this.TryValidateModel(submission, this.CompeteController);

            try
            {
                var result = this.CompeteController.Submit(submission, this.IsCompete);
                Assert.Fail("Expected an exception when sending a submission with no content");
            }
            catch (HttpException ex)
            {
                Assert.AreEqual((int)HttpStatusCode.BadRequest, ex.GetHttpCode());
            }
        }