Search in sources :

Example 41 with StudentExam

use of de.tum.in.www1.artemis.domain.exam.StudentExam in project Artemis by ls1intum.

the class StudentExamAccessServiceTest method testExamIsLive.

@Test
@WithMockUser(username = "student1", roles = "USER")
public void testExamIsLive() {
    // Exam is not visible.
    Exam examNotStarted = database.addExam(course1, users.get(0), ZonedDateTime.now().plusHours(1), ZonedDateTime.now().plusHours(2), ZonedDateTime.now().plusHours(3));
    assertThrows(AccessForbiddenException.class, () -> studentExamAccessService.checkCourseAndExamAccessElseThrow(course1.getId(), examNotStarted.getId(), users.get(0), false));
    assertThrows(AccessForbiddenException.class, () -> studentExamAccessService.checkStudentExamAccessElseThrow(course1.getId(), examNotStarted.getId(), studentExam1.getId(), false));
    assertThrows(AccessForbiddenException.class, () -> studentExamAccessService.checkStudentExamAccessElseThrow(course1.getId(), examNotStarted.getId(), studentExam1.getId(), users.get(0), false));
    // Exam has ended. After exam has ended, it should still be retrievable by the students to see their participation
    Exam examEnded = database.addExam(course1, users.get(0), ZonedDateTime.now().minusHours(4), ZonedDateTime.now().minusHours(3), ZonedDateTime.now().minusHours(1));
    StudentExam studentExamEnded = database.addStudentExam(examEnded);
    studentExamEnded.setUser(users.get(0));
    studentExamRepository.save(studentExamEnded);
    // does not throw
    studentExamAccessService.checkCourseAndExamAccessElseThrow(course1.getId(), examEnded.getId(), users.get(0), false);
    // does not throw
    studentExamAccessService.checkStudentExamAccessElseThrow(course1.getId(), examEnded.getId(), studentExamEnded.getId(), false);
    // does not throw
    studentExamAccessService.checkStudentExamAccessElseThrow(course1.getId(), examEnded.getId(), studentExamEnded.getId(), users.get(0), false);
}
Also used : StudentExam(de.tum.in.www1.artemis.domain.exam.StudentExam) StudentExam(de.tum.in.www1.artemis.domain.exam.StudentExam) Exam(de.tum.in.www1.artemis.domain.exam.Exam) WithMockUser(org.springframework.security.test.context.support.WithMockUser) Test(org.junit.jupiter.api.Test) AbstractSpringIntegrationBambooBitbucketJiraTest(de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest)

Example 42 with StudentExam

use of de.tum.in.www1.artemis.domain.exam.StudentExam in project ArTEMiS by ls1intum.

the class ExamResource method generateStudentExams.

/**
 * POST /courses/:courseId/exams/:examId/generate-student-exams : Generates the student exams randomly based on the exam configuration and the exercise groups
 *
 * @param courseId the id of the course
 * @param examId   the id of the exam
 * @return the list of student exams with their corresponding users
 */
@PostMapping(value = "/courses/{courseId}/exams/{examId}/generate-student-exams")
@PreAuthorize("hasRole('INSTRUCTOR')")
public ResponseEntity<List<StudentExam>> generateStudentExams(@PathVariable Long courseId, @PathVariable Long examId) {
    long start = System.nanoTime();
    log.info("REST request to generate student exams for exam {}", examId);
    final Exam exam = examRepository.findByIdWithRegisteredUsersExerciseGroupsAndExercisesElseThrow(examId);
    examAccessService.checkCourseAndExamAccessForInstructorElseThrow(courseId, exam);
    // Validate settings of the exam
    examService.validateForStudentExamGeneration(exam);
    examService.combineTemplateCommitsOfAllProgrammingExercisesInExam(exam);
    List<StudentExam> studentExams = studentExamRepository.generateStudentExams(exam);
    // we need to break a cycle for the serialization
    for (StudentExam studentExam : studentExams) {
        studentExam.getExam().setRegisteredUsers(null);
        studentExam.getExam().setExerciseGroups(null);
        studentExam.getExam().setStudentExams(null);
    }
    log.info("Generated {} student exams in {} for exam {}", studentExams.size(), formatDurationFrom(start), examId);
    return ResponseEntity.ok().body(studentExams);
}
Also used : StudentExam(de.tum.in.www1.artemis.domain.exam.StudentExam) StudentExam(de.tum.in.www1.artemis.domain.exam.StudentExam) Exam(de.tum.in.www1.artemis.domain.exam.Exam) PreAuthorize(org.springframework.security.access.prepost.PreAuthorize)

Example 43 with StudentExam

use of de.tum.in.www1.artemis.domain.exam.StudentExam in project ArTEMiS by ls1intum.

the class ExerciseDeletionService method delete.

/**
 * Delete the exercise by id and all its participations.
 *
 * @param exerciseId                   the exercise to be deleted
 * @param deleteStudentReposBuildPlans whether the student repos and build plans should be deleted (can be true for programming exercises and should be false for all other exercise types)
 * @param deleteBaseReposBuildPlans    whether the template and solution repos and build plans should be deleted (can be true for programming exercises and should be false for all other exercise types)
 */
// ok
@Transactional
public void delete(long exerciseId, boolean deleteStudentReposBuildPlans, boolean deleteBaseReposBuildPlans) {
    // Delete has a transactional mechanism. Therefore, all lazy objects that are deleted below, should be fetched when needed.
    final var exercise = exerciseRepository.findByIdElseThrow(exerciseId);
    log.info("Checking if exercise {} is modeling exercise", exercise.getId());
    if (exercise instanceof ModelingExercise) {
        log.info("Deleting clusters, elements and cancel scheduled operations of exercise {}", exercise.getId());
        modelingExerciseService.deleteClustersAndElements((ModelingExercise) exercise);
        modelingExerciseService.cancelScheduledOperations(exerciseId);
    }
    participantScoreRepository.deleteAllByExerciseIdTransactional(exerciseId);
    // delete all exercise units linking to the exercise
    List<ExerciseUnit> exerciseUnits = this.exerciseUnitRepository.findByIdWithLearningGoalsBidirectional(exerciseId);
    for (ExerciseUnit exerciseUnit : exerciseUnits) {
        this.lectureUnitService.removeLectureUnit(exerciseUnit);
    }
    // delete all plagiarism results belonging to this exercise
    plagiarismResultRepository.deletePlagiarismResultsByExerciseId(exerciseId);
    // delete all participations belonging to this exercise, this will also delete submissions, results, feedback, complaints, etc.
    participationService.deleteAllByExerciseId(exercise.getId(), deleteStudentReposBuildPlans, deleteStudentReposBuildPlans);
    // clean up the many-to-many relationship to avoid problems when deleting the entities but not the relationship table
    // to avoid a ConcurrentModificationException, we need to use a copy of the set
    var exampleSubmissions = new HashSet<>(exercise.getExampleSubmissions());
    for (ExampleSubmission exampleSubmission : exampleSubmissions) {
        exampleSubmissionService.deleteById(exampleSubmission.getId());
    }
    // make sure tutor participations are deleted before the exercise is deleted
    tutorParticipationRepository.deleteAllByAssessedExerciseId(exercise.getId());
    if (exercise.isExamExercise()) {
        Exam exam = examRepository.findOneWithEagerExercisesGroupsAndStudentExams(exercise.getExerciseGroup().getExam().getId());
        for (StudentExam studentExam : exam.getStudentExams()) {
            if (studentExam.getExercises().contains(exercise)) {
                // remove exercise reference from student exam
                List<Exercise> exerciseList = studentExam.getExercises();
                exerciseList.remove(exercise);
                studentExam.setExercises(exerciseList);
                studentExamRepository.save(studentExam);
            }
        }
    }
    // Programming exercises have some special stuff that needs to be cleaned up (solution/template participation, build plans, etc.).
    if (exercise instanceof ProgrammingExercise) {
        // TODO: delete all schedules related to this programming exercise
        programmingExerciseService.delete(exercise.getId(), deleteBaseReposBuildPlans);
    } else {
        // delete text assessment knowledge if exercise is of type TextExercise and if no other exercise uses same knowledge
        if (exercise instanceof TextExercise) {
            // explicitly load the text exercise as such so that the knowledge is eagerly loaded as well
            TextExercise textExercise = textExerciseRepository.findByIdElseThrow(exercise.getId());
            if (textExercise.getKnowledge() != null) {
                textAssessmentKnowledgeService.deleteKnowledge(textExercise.getKnowledge().getId(), textExercise.getId());
            }
        } else // delete model assessment knowledge if exercise is of type ModelExercise and if no other exercise uses same knowledge
        if (exercise instanceof ModelingExercise) {
            // explicitly load the modeling exercise as such so that the knowledge is eagerly loaded as well
            ModelingExercise modelingExercise = modelingExerciseRepository.findByIdElseThrow(exercise.getId());
            if (modelingExercise.getKnowledge() != null) {
                modelAssessmentKnowledgeService.deleteKnowledge(modelingExercise.getKnowledge().getId(), modelingExercise.getId());
            }
        }
        exerciseRepository.delete(exercise);
    }
}
Also used : ExerciseUnit(de.tum.in.www1.artemis.domain.lecture.ExerciseUnit) QuizExercise(de.tum.in.www1.artemis.domain.quiz.QuizExercise) ProgrammingExercise(de.tum.in.www1.artemis.domain.ProgrammingExercise) TextExercise(de.tum.in.www1.artemis.domain.TextExercise) Exercise(de.tum.in.www1.artemis.domain.Exercise) ModelingExercise(de.tum.in.www1.artemis.domain.modeling.ModelingExercise) ExampleSubmission(de.tum.in.www1.artemis.domain.ExampleSubmission) ModelingExercise(de.tum.in.www1.artemis.domain.modeling.ModelingExercise) ProgrammingExercise(de.tum.in.www1.artemis.domain.ProgrammingExercise) TextExercise(de.tum.in.www1.artemis.domain.TextExercise) StudentExam(de.tum.in.www1.artemis.domain.exam.StudentExam) StudentExam(de.tum.in.www1.artemis.domain.exam.StudentExam) Exam(de.tum.in.www1.artemis.domain.exam.Exam) HashSet(java.util.HashSet) Transactional(org.springframework.transaction.annotation.Transactional)

Example 44 with StudentExam

use of de.tum.in.www1.artemis.domain.exam.StudentExam in project ArTEMiS by ls1intum.

the class ExamQuizServiceTest method evaluateQuiz.

@Test
@WithMockUser(username = "instructor1", roles = "INSTRUCTOR")
public void evaluateQuiz() throws Exception {
    for (int i = 0; i < numberOfParticipants; i++) {
        exam.addRegisteredUser(users.get(i));
    }
    exam = examRepository.save(exam);
    exerciseGroup.setExam(exam);
    exerciseGroup = exerciseGroupRepository.save(exerciseGroup);
    exam.setExerciseGroups(List.of(exerciseGroup));
    quizExercise.setExerciseGroup(exerciseGroup);
    quizExercise = quizExerciseService.save(quizExercise);
    exerciseGroup.setExercises(Set.of(quizExercise));
    assertThat(studentExamRepository.generateStudentExams(exam)).hasSize(numberOfParticipants);
    assertThat(studentExamRepository.findByExamId(exam.getId())).hasSize(numberOfParticipants);
    assertThat(studentExamService.startExercises(exam.getId())).isEqualTo(numberOfParticipants);
    for (int i = 0; i < numberOfParticipants; i++) {
        database.changeUser("student" + (i + 1));
        QuizSubmission quizSubmission = database.generateSubmissionForThreeQuestions(quizExercise, i + 1, true, ZonedDateTime.now());
        request.put("/api/exercises/" + quizExercise.getId() + "/submissions/exam", quizSubmission, HttpStatus.OK);
    }
    database.changeUser("instructor1");
    // All exams should be over before evaluation
    for (StudentExam studentExam : studentExamRepository.findByExamId(exam.getId())) {
        studentExam.setWorkingTime(0);
        studentExamRepository.save(studentExam);
    }
    Integer numberOfEvaluatedExercises = request.postWithResponseBody("/api/courses/" + course.getId() + "/exams/" + exam.getId() + "/student-exams/evaluate-quiz-exercises", Optional.empty(), Integer.class, HttpStatus.OK);
    assertThat(numberOfEvaluatedExercises).isEqualTo(1);
    checkStatistics(quizExercise);
    studentExamRepository.deleteAll();
    // Make sure delete also works if so many objects have been created before
    request.delete("/api/courses/" + course.getId() + "/exams/" + exam.getId(), HttpStatus.OK);
    userRepository.deleteAll();
}
Also used : StudentExam(de.tum.in.www1.artemis.domain.exam.StudentExam) WithMockUser(org.springframework.security.test.context.support.WithMockUser) Test(org.junit.jupiter.api.Test) AbstractSpringIntegrationBambooBitbucketJiraTest(de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest)

Example 45 with StudentExam

use of de.tum.in.www1.artemis.domain.exam.StudentExam in project ArTEMiS by ls1intum.

the class ExamQuizServiceTest method evaluateQuiz_twice.

@Test
@WithMockUser(username = "instructor1", roles = "INSTRUCTOR")
public void evaluateQuiz_twice() throws Exception {
    for (int i = 0; i < numberOfParticipants; i++) {
        exam.addRegisteredUser(users.get(i));
    }
    exam = examRepository.save(exam);
    exerciseGroup.setExam(exam);
    exerciseGroup = exerciseGroupRepository.save(exerciseGroup);
    exam.setExerciseGroups(List.of(exerciseGroup));
    quizExercise.setExerciseGroup(exerciseGroup);
    quizExercise = quizExerciseService.save(quizExercise);
    exerciseGroup.setExercises(Set.of(quizExercise));
    assertThat(studentExamRepository.generateStudentExams(exam)).hasSize(numberOfParticipants);
    assertThat(studentExamRepository.findByExamId(exam.getId())).hasSize(numberOfParticipants);
    assertThat(studentExamService.startExercises(exam.getId())).isEqualTo(numberOfParticipants);
    for (int i = 0; i < numberOfParticipants; i++) {
        database.changeUser("student" + (i + 1));
        QuizSubmission quizSubmission = database.generateSubmissionForThreeQuestions(quizExercise, i + 1, true, ZonedDateTime.now());
        request.put("/api/exercises/" + quizExercise.getId() + "/submissions/exam", quizSubmission, HttpStatus.OK);
    }
    database.changeUser("instructor1");
    // All exams should be over before evaluation
    for (StudentExam studentExam : studentExamRepository.findByExamId(exam.getId())) {
        studentExam.setWorkingTime(0);
        studentExamRepository.save(studentExam);
    }
    Integer numberOfEvaluatedExercises = request.postWithResponseBody("/api/courses/" + course.getId() + "/exams/" + exam.getId() + "/student-exams/evaluate-quiz-exercises", Optional.empty(), Integer.class, HttpStatus.OK);
    assertThat(numberOfEvaluatedExercises).isEqualTo(1);
    // Evaluate quiz twice
    numberOfEvaluatedExercises = request.postWithResponseBody("/api/courses/" + course.getId() + "/exams/" + exam.getId() + "/student-exams/evaluate-quiz-exercises", Optional.empty(), Integer.class, HttpStatus.OK);
    assertThat(numberOfEvaluatedExercises).isEqualTo(1);
    checkStatistics(quizExercise);
    studentExamRepository.deleteAll();
    // Make sure delete also works if so many objects have been created before
    request.delete("/api/courses/" + course.getId() + "/exams/" + exam.getId(), HttpStatus.OK);
    userRepository.deleteAll();
}
Also used : StudentExam(de.tum.in.www1.artemis.domain.exam.StudentExam) WithMockUser(org.springframework.security.test.context.support.WithMockUser) Test(org.junit.jupiter.api.Test) AbstractSpringIntegrationBambooBitbucketJiraTest(de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest)

Aggregations

StudentExam (de.tum.in.www1.artemis.domain.exam.StudentExam)69 WithMockUser (org.springframework.security.test.context.support.WithMockUser)44 Test (org.junit.jupiter.api.Test)42 Exam (de.tum.in.www1.artemis.domain.exam.Exam)37 StudentParticipation (de.tum.in.www1.artemis.domain.participation.StudentParticipation)22 ModelingExercise (de.tum.in.www1.artemis.domain.modeling.ModelingExercise)20 QuizExercise (de.tum.in.www1.artemis.domain.quiz.QuizExercise)18 EntityNotFoundException (de.tum.in.www1.artemis.web.rest.errors.EntityNotFoundException)18 AbstractSpringIntegrationBambooBitbucketJiraTest (de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest)16 ModelingSubmission (de.tum.in.www1.artemis.domain.modeling.ModelingSubmission)14 ZonedDateTime (java.time.ZonedDateTime)14 ExerciseGroup (de.tum.in.www1.artemis.domain.exam.ExerciseGroup)12 Participation (de.tum.in.www1.artemis.domain.participation.Participation)12 de.tum.in.www1.artemis.repository (de.tum.in.www1.artemis.repository)12 java.util (java.util)12 Collectors (java.util.stream.Collectors)12 LinkedMultiValueMap (org.springframework.util.LinkedMultiValueMap)12 de.tum.in.www1.artemis.domain (de.tum.in.www1.artemis.domain)10 AssessmentType (de.tum.in.www1.artemis.domain.enumeration.AssessmentType)10 de.tum.in.www1.artemis.web.rest.dto (de.tum.in.www1.artemis.web.rest.dto)10