use of de.tum.in.www1.artemis.domain.exam.Exam in project ArTEMiS by ls1intum.
the class ExamIntegrationTest method testRemovingAllStudentsAndParticipations.
@Test
@WithMockUser(username = "admin", roles = "ADMIN")
public void testRemovingAllStudentsAndParticipations() throws Exception {
Exam exam = database.setupExamWithExerciseGroupsExercisesRegisteredStudents(course1);
// Generate student exams
List<StudentExam> studentExams = request.postListWithResponseBody("/api/courses/" + course1.getId() + "/exams/" + exam.getId() + "/generate-student-exams", Optional.empty(), StudentExam.class, HttpStatus.OK);
assertThat(studentExams).hasSize(4);
assertThat(exam.getRegisteredUsers()).hasSize(4);
// /courses/{courseId}/exams/{examId}/student-exams/start-exercises
Integer numberOfGeneratedParticipations = request.postWithResponseBody("/api/courses/" + course1.getId() + "/exams/" + exam.getId() + "/student-exams/start-exercises", Optional.empty(), Integer.class, HttpStatus.OK);
assertThat(numberOfGeneratedParticipations).isEqualTo(16);
// Fetch student exams
List<StudentExam> studentExamsDB = request.getList("/api/courses/" + course1.getId() + "/exams/" + exam.getId() + "/student-exams", HttpStatus.OK, StudentExam.class);
assertThat(studentExamsDB).hasSize(4);
List<StudentParticipation> participationList = new ArrayList<>();
Exercise[] exercises = examRepository.findAllExercisesByExamId(exam.getId()).toArray(new Exercise[0]);
for (Exercise value : exercises) {
participationList.addAll(studentParticipationRepository.findByExerciseId(value.getId()));
}
assertThat(participationList).hasSize(16);
// TODO there should be some participation but no submissions unfortunately
// remove all students
var paramsParticipations = new LinkedMultiValueMap<String, String>();
paramsParticipations.add("withParticipationsAndSubmission", "true");
request.delete("/api/courses/" + course1.getId() + "/exams/" + exam.getId() + "/students", HttpStatus.OK, paramsParticipations);
// Get the exam with all registered users
var params = new LinkedMultiValueMap<String, String>();
params.add("withStudents", "true");
Exam storedExam = request.get("/api/courses/" + course1.getId() + "/exams/" + exam.getId(), HttpStatus.OK, Exam.class, params);
assertThat(storedExam.getRegisteredUsers()).isEmpty();
// Fetch student exams
studentExamsDB = request.getList("/api/courses/" + course1.getId() + "/exams/" + exam.getId() + "/student-exams", HttpStatus.OK, StudentExam.class);
assertThat(studentExamsDB).isEmpty();
// Fetch participations
exercises = examRepository.findAllExercisesByExamId(exam.getId()).toArray(new Exercise[0]);
participationList = new ArrayList<>();
for (Exercise exercise : exercises) {
participationList.addAll(studentParticipationRepository.findByExerciseId(exercise.getId()));
}
assertThat(participationList).isEmpty();
}
use of de.tum.in.www1.artemis.domain.exam.Exam in project ArTEMiS by ls1intum.
the class ExamIntegrationTest method testCreateExam_checkCourseAccess_InstructorNotInCourse_forbidden.
@Test
@WithMockUser(username = "instructor6", roles = "INSTRUCTOR")
public void testCreateExam_checkCourseAccess_InstructorNotInCourse_forbidden() throws Exception {
Exam exam = ModelFactory.generateExam(course1);
request.post("/api/courses/" + course1.getId() + "/exams", exam, HttpStatus.FORBIDDEN);
}
use of de.tum.in.www1.artemis.domain.exam.Exam in project ArTEMiS by ls1intum.
the class ExamIntegrationTest method testStartExercisesWithModelingExercise.
@Test
@WithMockUser(username = "instructor1", roles = "INSTRUCTOR")
public void testStartExercisesWithModelingExercise() throws Exception {
// TODO IMPORTANT test more complex exam configurations (mixed exercise type, more variants and more registered students)
// registering users
var student1 = database.getUserByLogin("student1");
var student2 = database.getUserByLogin("student2");
var registeredUsers = Set.of(student1, student2);
exam2.setRegisteredUsers(registeredUsers);
// setting dates
exam2.setStartDate(now().plusHours(2));
exam2.setEndDate(now().plusHours(3));
exam2.setVisibleDate(now().plusHours(1));
// creating exercise
ModelingExercise modelingExercise = ModelFactory.generateModelingExerciseForExam(DiagramType.ClassDiagram, exam2.getExerciseGroups().get(0));
exam2.getExerciseGroups().get(0).addExercise(modelingExercise);
exerciseGroupRepository.save(exam2.getExerciseGroups().get(0));
modelingExercise = exerciseRepo.save(modelingExercise);
List<StudentExam> createdStudentExams = new ArrayList<>();
// creating student exams
for (User user : registeredUsers) {
StudentExam studentExam = new StudentExam();
studentExam.addExercise(modelingExercise);
studentExam.setUser(user);
exam2.addStudentExam(studentExam);
createdStudentExams.add(studentExamRepository.save(studentExam));
}
exam2 = examRepository.save(exam2);
// invoke start exercises
Integer noGeneratedParticipations = request.postWithResponseBody("/api/courses/" + course1.getId() + "/exams/" + exam2.getId() + "/student-exams/start-exercises", Optional.empty(), Integer.class, HttpStatus.OK);
assertThat(noGeneratedParticipations).isEqualTo(exam2.getStudentExams().size());
List<Participation> studentParticipations = participationTestRepository.findAllWithSubmissions();
for (Participation participation : studentParticipations) {
assertThat(participation.getExercise()).isEqualTo(modelingExercise);
assertThat(participation.getExercise().getCourseViaExerciseGroupOrCourseMember()).isNotNull();
assertThat(participation.getExercise().getExerciseGroup()).isEqualTo(exam2.getExerciseGroups().get(0));
assertThat(participation.getSubmissions()).hasSize(1);
var textSubmission = (ModelingSubmission) participation.getSubmissions().iterator().next();
assertThat(textSubmission.getModel()).isNull();
assertThat(textSubmission.getExplanationText()).isNull();
}
// Cleanup of Bidirectional Relationships
for (StudentExam studentExam : createdStudentExams) {
exam2.removeStudentExam(studentExam);
}
examRepository.save(exam2);
}
use of de.tum.in.www1.artemis.domain.exam.Exam in project ArTEMiS by ls1intum.
the class ExamSessionIntegrationTest method initTestCase.
@BeforeEach
public void initTestCase() {
List<User> users = database.addUsers(1, 1, 0, 1);
Course course1 = database.addEmptyCourse();
Exam exam1 = database.addActiveExamWithRegisteredUser(course1, users.get(0));
studentExam1 = database.addStudentExam(exam1);
studentExam1.setUser(users.get(0));
studentExamRepository.save(studentExam1);
}
use of de.tum.in.www1.artemis.domain.exam.Exam in project ArTEMiS by ls1intum.
the class FileUploadAssessmentIntegrationTest method multipleCorrectionRoundsForExam.
@Test
@WithMockUser(username = "tutor1", roles = "TA")
public void multipleCorrectionRoundsForExam() throws Exception {
// Setup exam with 2 correction rounds and a programming exercise
ExerciseGroup exerciseGroup1 = new ExerciseGroup();
Exam exam = database.addExam(course);
exam.setNumberOfCorrectionRoundsInExam(2);
exam.addExerciseGroup(exerciseGroup1);
exam.setVisibleDate(ZonedDateTime.now().minusHours(3));
exam.setStartDate(ZonedDateTime.now().minusHours(2));
exam.setEndDate(ZonedDateTime.now().minusHours(1));
exam = examRepository.save(exam);
Exam examWithExerciseGroups = examRepository.findWithExerciseGroupsAndExercisesById(exam.getId()).get();
exerciseGroup1 = examWithExerciseGroups.getExerciseGroups().get(0);
FileUploadExercise exercise = ModelFactory.generateFileUploadExerciseForExam("test.pdf", exerciseGroup1);
exercise = fileUploadExerciseRepository.save(exercise);
exerciseGroup1.addExercise(exercise);
// add student submission
var submission = ModelFactory.generateFileUploadSubmission(true);
submission = database.addFileUploadSubmission(exercise, submission, "student1");
// verify setup
assertThat(exam.getNumberOfCorrectionRoundsInExam()).isEqualTo(2);
assertThat(exam.getEndDate()).isBefore(ZonedDateTime.now());
var optionalFetchedExercise = exerciseRepository.findWithEagerStudentParticipationsStudentAndSubmissionsById(exercise.getId());
assertThat(optionalFetchedExercise).isPresent();
final var exerciseWithParticipation = optionalFetchedExercise.get();
final var studentParticipation = exerciseWithParticipation.getStudentParticipations().stream().iterator().next();
// request to manually assess latest submission (correction round: 0)
LinkedMultiValueMap<String, String> params = new LinkedMultiValueMap<>();
params.add("lock", "true");
params.add("correction-round", "0");
FileUploadSubmission submissionWithoutFirstAssessment = request.get("/api/exercises/" + exerciseWithParticipation.getId() + "/file-upload-submission-without-assessment", HttpStatus.OK, FileUploadSubmission.class, params);
// verify that no new submission was created
assertThat(submissionWithoutFirstAssessment).isEqualTo(submission);
// verify that the lock has been set
assertThat(submissionWithoutFirstAssessment.getLatestResult()).isNotNull();
assertThat(submissionWithoutFirstAssessment.getLatestResult().getAssessor().getLogin()).isEqualTo("tutor1");
assertThat(submissionWithoutFirstAssessment.getLatestResult().getAssessmentType()).isEqualTo(AssessmentType.MANUAL);
// make sure that new result correctly appears inside the continue box
LinkedMultiValueMap<String, String> paramsGetAssessedCR1Tutor1 = new LinkedMultiValueMap<>();
paramsGetAssessedCR1Tutor1.add("assessedByTutor", "true");
paramsGetAssessedCR1Tutor1.add("correction-round", "0");
var assessedSubmissionList = request.getList("/api/exercises/" + exerciseWithParticipation.getId() + "/file-upload-submissions", HttpStatus.OK, FileUploadSubmission.class, paramsGetAssessedCR1Tutor1);
assertThat(assessedSubmissionList).hasSize(1);
assertThat(assessedSubmissionList.get(0).getId()).isEqualTo(submissionWithoutFirstAssessment.getId());
assertThat(assessedSubmissionList.get(0).getResultForCorrectionRound(0)).isEqualTo(submissionWithoutFirstAssessment.getLatestResult());
// assess submission and submit
List<Feedback> feedbacks = ModelFactory.generateFeedback().stream().peek(feedback -> feedback.setDetailText("Good work here")).collect(Collectors.toList());
params = new LinkedMultiValueMap<>();
params.add("submit", "true");
final Result firstSubmittedManualResult = request.putWithResponseBodyAndParams(API_FILE_UPLOAD_SUBMISSIONS + submissionWithoutFirstAssessment.getId() + "/feedback", feedbacks, Result.class, HttpStatus.OK, params);
// make sure that new result correctly appears after the assessment for first correction round
assessedSubmissionList = request.getList("/api/exercises/" + exerciseWithParticipation.getId() + "/file-upload-submissions", HttpStatus.OK, FileUploadSubmission.class, paramsGetAssessedCR1Tutor1);
assertThat(assessedSubmissionList).hasSize(1);
assertThat(assessedSubmissionList.get(0).getId()).isEqualTo(submissionWithoutFirstAssessment.getId());
assertThat(assessedSubmissionList.get(0).getResultForCorrectionRound(0)).isNotNull();
assertThat(firstSubmittedManualResult.getAssessor().getLogin()).isEqualTo("tutor1");
// verify that the result contains the relationship
assertThat(firstSubmittedManualResult).isNotNull();
assertThat(firstSubmittedManualResult.getParticipation()).isEqualTo(studentParticipation);
// verify that the relationship between student participation,
var databaseRelationshipStateOfResultsOverParticipation = studentParticipationRepository.findWithEagerLegalSubmissionsAndResultsAssessorsById(studentParticipation.getId());
assertThat(databaseRelationshipStateOfResultsOverParticipation).isPresent();
var fetchedParticipation = databaseRelationshipStateOfResultsOverParticipation.get();
assertThat(fetchedParticipation.getSubmissions()).hasSize(1);
assertThat(fetchedParticipation.findLatestSubmission()).contains(submissionWithoutFirstAssessment);
assertThat(fetchedParticipation.findLatestLegalResult()).isEqualTo(firstSubmittedManualResult);
var databaseRelationshipStateOfResultsOverSubmission = studentParticipationRepository.findAllWithEagerSubmissionsAndEagerResultsAndEagerAssessorByExerciseId(exercise.getId());
assertThat(databaseRelationshipStateOfResultsOverSubmission).hasSize(1);
fetchedParticipation = databaseRelationshipStateOfResultsOverSubmission.get(0);
assertThat(fetchedParticipation.getSubmissions()).hasSize(1);
assertThat(fetchedParticipation.findLatestSubmission()).isPresent();
// it should contain the lock for the manual result
assertThat(fetchedParticipation.findLatestSubmission().get().getResults()).hasSize(1);
assertThat(fetchedParticipation.findLatestSubmission().get().getLatestResult()).isEqualTo(firstSubmittedManualResult);
// SECOND ROUND OF CORRECTION
database.changeUser("tutor2");
LinkedMultiValueMap<String, String> paramsSecondCorrection = new LinkedMultiValueMap<>();
paramsSecondCorrection.add("lock", "true");
paramsSecondCorrection.add("correction-round", "1");
final var submissionWithoutSecondAssessment = request.get("/api/exercises/" + exerciseWithParticipation.getId() + "/file-upload-submission-without-assessment", HttpStatus.OK, FileUploadSubmission.class, paramsSecondCorrection);
// verify that the submission is not new
assertThat(submissionWithoutSecondAssessment).isEqualTo(submission);
// verify that the lock has been set
assertThat(submissionWithoutSecondAssessment.getLatestResult()).isNotNull();
assertThat(submissionWithoutSecondAssessment.getLatestResult().getAssessor().getLogin()).isEqualTo("tutor2");
assertThat(submissionWithoutSecondAssessment.getLatestResult().getAssessmentType()).isEqualTo(AssessmentType.MANUAL);
// verify that the relationship between student participation,
databaseRelationshipStateOfResultsOverParticipation = studentParticipationRepository.findWithEagerLegalSubmissionsAndResultsAssessorsById(studentParticipation.getId());
assertThat(databaseRelationshipStateOfResultsOverParticipation).isPresent();
fetchedParticipation = databaseRelationshipStateOfResultsOverParticipation.get();
assertThat(fetchedParticipation.getSubmissions()).hasSize(1);
assertThat(fetchedParticipation.findLatestSubmission()).contains(submissionWithoutSecondAssessment);
assertThat(fetchedParticipation.getResults().stream().filter(x -> x.getCompletionDate() == null).findFirst()).contains(submissionWithoutSecondAssessment.getLatestResult());
databaseRelationshipStateOfResultsOverSubmission = studentParticipationRepository.findAllWithEagerSubmissionsAndEagerResultsAndEagerAssessorByExerciseId(exercise.getId());
assertThat(databaseRelationshipStateOfResultsOverSubmission).hasSize(1);
fetchedParticipation = databaseRelationshipStateOfResultsOverSubmission.get(0);
assertThat(fetchedParticipation.getSubmissions()).hasSize(1);
assertThat(fetchedParticipation.findLatestSubmission()).isPresent();
assertThat(fetchedParticipation.findLatestSubmission().get().getResults()).hasSize(2);
assertThat(fetchedParticipation.findLatestSubmission().get().getLatestResult()).isEqualTo(submissionWithoutSecondAssessment.getLatestResult());
// assess submission and submit
feedbacks = ModelFactory.generateFeedback().stream().peek(feedback -> feedback.setDetailText("Good work here")).collect(Collectors.toList());
params = new LinkedMultiValueMap<>();
params.add("submit", "true");
final var secondSubmittedManualResult = request.putWithResponseBodyAndParams(API_FILE_UPLOAD_SUBMISSIONS + submissionWithoutFirstAssessment.getId() + "/feedback", feedbacks, Result.class, HttpStatus.OK, params);
assertThat(secondSubmittedManualResult).isNotNull();
// make sure that new result correctly appears after the assessment for second correction round
LinkedMultiValueMap<String, String> paramsGetAssessedCR2 = new LinkedMultiValueMap<>();
paramsGetAssessedCR2.add("assessedByTutor", "true");
paramsGetAssessedCR2.add("correction-round", "1");
assessedSubmissionList = request.getList("/api/exercises/" + exerciseWithParticipation.getId() + "/file-upload-submissions", HttpStatus.OK, FileUploadSubmission.class, paramsGetAssessedCR2);
assertThat(assessedSubmissionList).hasSize(1);
assertThat(assessedSubmissionList.get(0).getId()).isEqualTo(submissionWithoutSecondAssessment.getId());
assertThat(assessedSubmissionList.get(0).getResultForCorrectionRound(1)).isEqualTo(secondSubmittedManualResult);
// make sure that they do not appear for the first correction round as the tutor only assessed the second correction round
LinkedMultiValueMap<String, String> paramsGetAssessedCR1 = new LinkedMultiValueMap<>();
paramsGetAssessedCR1.add("assessedByTutor", "true");
paramsGetAssessedCR1.add("correction-round", "0");
assessedSubmissionList = request.getList("/api/exercises/" + exerciseWithParticipation.getId() + "/file-upload-submissions", HttpStatus.OK, FileUploadSubmission.class, paramsGetAssessedCR1);
assertThat(assessedSubmissionList).isEmpty();
// Student should not have received a result over WebSocket as manual correction is ongoing
verify(messagingTemplate, never()).convertAndSendToUser(notNull(), eq(Constants.NEW_RESULT_TOPIC), isA(Result.class));
}
Aggregations