/// <summary>
        /// Add question to existing which is not assigned to test.
        /// </summary>
        /// <param name="testId"></param>
        /// <param name="question"></param>
        /// <returns>Returns id of new question</returns>
        public async Task <int> AddQuestionAsync(int testId, QuestionDto question)
        {
            Test test = await context.Tests.FindAsync(testId);

            test.ThrowIfNull(new InvalidOperationException($"Test with id {testId} does not exists"));
            question.ThrowIfNull(new ArgumentNullException(nameof(question)));
            await ThrowIfTestAssignedToUserAsync(test);

            Question newQuestion = new Question();

            question.UpdateEntity(newQuestion);

            if (question.QuestionTypeId == QuestionTypeEnum.Closed)
            {
                List <QuestionAnswerOption> options = new List <QuestionAnswerOption>(question.Options.Count);
                foreach (QuestionAnswerOptionDto answerOption in question.Options)
                {
                    QuestionAnswerOption option = new QuestionAnswerOption();
                    answerOption.UpdateEntity(option);
                    options.Add(option);
                }

                newQuestion.QuestionAnswerOptions = options;
            }

            test.Questions.Add(newQuestion);
            await context.SaveChangesAsync();

            return(newQuestion.Id);
        }
        /// <summary>
        /// Add new answer
        /// </summary>
        /// <param name="answer"></param>
        /// <returns>Returns id of answer</returns>
        public async Task <int> AddAnswerAsync(AnswerDto answer)
        {
            /**
             * Internally answer exists but with are not accepted
             * It's made to manage which questions have UserTest object
             *
             */
            Answer existingAnswer = await context.Answers
                                    .Include(a => a.UserTest)
                                    .Include(a => a.Question.QuestionAnswerOptions)
                                    .Where(a => a.UserTestId == answer.UserTestId)
                                    .Where(a => a.QuestionId == answer.QuestionId)
                                    .FirstOrDefaultAsync();

            existingAnswer.ThrowIfNull(new InvalidOperationException(
                                           $"Answer with {nameof(answer.UserTestId)} {answer.UserTestId} and {nameof(answer.QuestionId)} {answer.QuestionId} does not exists")
                                       );

            ThrowIfTestAlreadyEnded(existingAnswer.UserTest);

            // only Closed questions can have more than one right answer
            if (existingAnswer.Question.RightAnswers != 1 &&
                existingAnswer.Question.QuestionTypeId == QuestionTypeEnum.Closed)
            {
                QuestionAnswerOption option = existingAnswer.Question
                                              .QuestionAnswerOptions
                                              .Where(q => q.Content == answer.Content) // it's closed question. content should be the same
                                              .FirstOrDefault();

                if (existingAnswer.IsAccepted) // add new
                {
                    Answer newAnswer = new Answer()
                    {
                        IsAccepted = true,
                        IsCorrect  = option == null ? false : true,
                        QuestionId = answer.QuestionId,
                        UserTestId = answer.UserTestId,
                        Content    = answer.Content
                    };

                    context.Answers.Add(newAnswer);
                }
                else
                {
                    existingAnswer.IsAccepted = true;
                }
            }
            else // is open question
            {
                existingAnswer.IsCorrect  = null;
                existingAnswer.IsAccepted = true;
            }

            await context.SaveChangesAsync();

            return(existingAnswer.Id);
        }
        /// <summary>
        /// Creates new test
        /// </summary>
        /// <param name="test"></param>
        /// <returns>Returns TestId of supplied test</returns>
        public async Task <int> CreateTestAsync(TestDto test)
        {
            ThrowIfTestIsInvalid(test);

            Test newTest = new Test();

            test.UpdateEntity(newTest);

            List <Question> testQuestions = new List <Question>(test.Questions.Count);

            foreach (QuestionDto questionDto in test.Questions)
            {
                ThrowIfQuestionIsInvalid(questionDto);

                // if questions for passing is zero, than it is like quiz. Whatewer you will pass is.
                // if questons count is zero,  than current test should contains them all

                // questions count in test.
                if (test.QuestionsCount == 0)
                {
                    newTest.QuestionsCount++;
                }

                Question question = new Question();
                questionDto.UpdateEntity(question);
                if (questionDto.QuestionTypeId == QuestionTypeEnum.Closed)
                {
                    List <QuestionAnswerOption> options = new List <QuestionAnswerOption>(questionDto.Options.Count);
                    foreach (QuestionAnswerOptionDto answerOption in questionDto.Options)
                    {
                        QuestionAnswerOption option = new QuestionAnswerOption();
                        answerOption.UpdateEntity(option);
                        options.Add(option);
                    }

                    question.QuestionAnswerOptions = options;
                }

                testQuestions.Add(question);
            }

            testQuestions.ForEach(q => newTest.Questions.Add(q));

            context.Tests.Add(newTest);
            await context.SaveChangesAsync();

            return(newTest.Id);
        }
Beispiel #4
0
 internal void CopyEntityData(QuestionAnswerOption entity)
 {
     this.Id        = entity.Id;
     this.Content   = entity.Content;
     this.IsCorrect = entity.IsCorrect;
 }
Beispiel #5
0
 internal void UpdateEntity(QuestionAnswerOption entity)
 {
     entity.Id        = this.Id;
     entity.Content   = this.Content;
     entity.IsCorrect = this.IsCorrect;
 }
Beispiel #6
0
 internal QuestionAnswerOptionDto(QuestionAnswerOption entity)
 {
     CopyEntityData(entity);
 }