use of de.tum.in.www1.artemis.domain.exam.ExerciseGroup in project ArTEMiS by ls1intum.
the class ProgrammingExerciseTestService method setup.
public void setup(MockDelegate mockDelegate, VersionControlService versionControlService, ContinuousIntegrationService continuousIntegrationService) throws Exception {
exerciseRepo = new LocalRepository(defaultBranch);
testRepo = new LocalRepository(defaultBranch);
solutionRepo = new LocalRepository(defaultBranch);
auxRepo = new LocalRepository(defaultBranch);
sourceExerciseRepo = new LocalRepository(defaultBranch);
sourceTestRepo = new LocalRepository(defaultBranch);
sourceSolutionRepo = new LocalRepository(defaultBranch);
sourceAuxRepo = new LocalRepository(defaultBranch);
studentRepo = new LocalRepository(defaultBranch);
studentTeamRepo = new LocalRepository(defaultBranch);
this.mockDelegate = mockDelegate;
this.versionControlService = versionControlService;
course = database.addEmptyCourse();
ExerciseGroup exerciseGroup = database.addExerciseGroupWithExamAndCourse(true);
examExercise = ModelFactory.generateProgrammingExerciseForExam(exerciseGroup);
exercise = ModelFactory.generateProgrammingExercise(ZonedDateTime.now().minusDays(1), ZonedDateTime.now().plusDays(7), course);
exerciseRepo.configureRepos("exerciseLocalRepo", "exerciseOriginRepo");
testRepo.configureRepos("testLocalRepo", "testOriginRepo");
solutionRepo.configureRepos("solutionLocalRepo", "solutionOriginRepo");
auxRepo.configureRepos("auxLocalRepo", "auxOriginRepo");
sourceExerciseRepo.configureRepos("sourceExerciseLocalRepo", "sourceExerciseOriginRepo");
sourceTestRepo.configureRepos("sourceTestLocalRepo", "sourceTestOriginRepo");
sourceSolutionRepo.configureRepos("sourceSolutionLocalRepo", "sourceSolutionOriginRepo");
sourceAuxRepo.configureRepos("sourceAuxLocalRepo", "sourceAuxOriginRepo");
studentRepo.configureRepos("studentRepo", "studentOriginRepo");
studentTeamRepo.configureRepos("studentTeamRepo", "studentTeamOriginRepo");
setupRepositoryMocks(exercise, exerciseRepo, solutionRepo, testRepo, auxRepo);
setupRepositoryMocksParticipant(exercise, studentLogin, studentRepo);
setupRepositoryMocksParticipant(exercise, teamShortName, studentTeamRepo);
}
use of de.tum.in.www1.artemis.domain.exam.ExerciseGroup in project ArTEMiS by ls1intum.
the class ExamIntegrationTest method unlockAllRepositories.
@Test
@WithMockUser(username = "instructor1", roles = "INSTRUCTOR")
public void unlockAllRepositories() throws Exception {
bitbucketRequestMockProvider.enableMockingOfRequests(true);
assertThat(studentExamRepository.findStudentExam(new ProgrammingExercise(), null)).isEmpty();
ExerciseGroup exerciseGroup1 = new ExerciseGroup();
Exam exam = database.addExam(course1);
exam.addExerciseGroup(exerciseGroup1);
exam = examRepository.save(exam);
exam = examRepository.findWithExerciseGroupsAndExercisesById(exam.getId()).get();
exerciseGroup1 = exam.getExerciseGroups().get(0);
ProgrammingExercise programmingExercise = ModelFactory.generateProgrammingExerciseForExam(exerciseGroup1);
programmingExercise = programmingExerciseRepository.save(programmingExercise);
exerciseGroup1.addExercise(programmingExercise);
ProgrammingExercise programmingExercise2 = ModelFactory.generateProgrammingExerciseForExam(exerciseGroup1);
programmingExercise2 = programmingExerciseRepository.save(programmingExercise2);
exerciseGroup1.addExercise(programmingExercise2);
exerciseGroupRepository.save(exerciseGroup1);
User student1 = database.getUserByLogin("student1");
User student2 = database.getUserByLogin("student2");
var studentExam1 = database.addStudentExamWithUser(exam, student1, 10);
studentExam1.setExercises(List.of(programmingExercise, programmingExercise2));
var studentExam2 = database.addStudentExamWithUser(exam, student2, 0);
studentExam2.setExercises(List.of(programmingExercise, programmingExercise2));
studentExamRepository.saveAll(Set.of(studentExam1, studentExam2));
var participationExSt1 = database.addStudentParticipationForProgrammingExercise(programmingExercise, "student1");
var participationExSt2 = database.addStudentParticipationForProgrammingExercise(programmingExercise, "student2");
var participationEx2St1 = database.addStudentParticipationForProgrammingExercise(programmingExercise2, "student1");
var participationEx2St2 = database.addStudentParticipationForProgrammingExercise(programmingExercise2, "student2");
assertThat(studentExamRepository.findStudentExam(programmingExercise, participationExSt1)).contains(studentExam1);
assertThat(studentExamRepository.findStudentExam(programmingExercise, participationExSt2)).contains(studentExam2);
assertThat(studentExamRepository.findStudentExam(programmingExercise2, participationEx2St1)).contains(studentExam1);
assertThat(studentExamRepository.findStudentExam(programmingExercise2, participationEx2St2)).contains(studentExam2);
mockConfigureRepository(programmingExercise, "student1", Set.of(student1), true);
mockConfigureRepository(programmingExercise, "student2", Set.of(student2), true);
mockConfigureRepository(programmingExercise2, "student1", Set.of(student1), true);
mockConfigureRepository(programmingExercise2, "student2", Set.of(student2), true);
Integer numOfUnlockedExercises = request.postWithResponseBody("/api/courses/" + course1.getId() + "/exams/" + exam.getId() + "/student-exams/unlock-all-repositories", Optional.empty(), Integer.class, HttpStatus.OK);
assertThat(numOfUnlockedExercises).isEqualTo(2);
verify(programmingExerciseScheduleService, times(1)).unlockAllStudentRepositories(programmingExercise);
verify(programmingExerciseScheduleService, times(1)).unlockAllStudentRepositories(programmingExercise2);
}
use of de.tum.in.www1.artemis.domain.exam.ExerciseGroup in project ArTEMiS by ls1intum.
the class ExamIntegrationTest method lockAllRepositories_noInstructor.
@Test
@WithMockUser(username = "student1", roles = "USER")
public void lockAllRepositories_noInstructor() throws Exception {
ExerciseGroup exerciseGroup1 = new ExerciseGroup();
Exam exam = database.addExam(course1);
exam.addExerciseGroup(exerciseGroup1);
exam = examRepository.save(exam);
request.postWithResponseBody("/api/courses/" + course1.getId() + "/exams/" + exam.getId() + "/student-exams/lock-all-repositories", Optional.empty(), Integer.class, HttpStatus.FORBIDDEN);
}
use of de.tum.in.www1.artemis.domain.exam.ExerciseGroup in project ArTEMiS by ls1intum.
the class ExamIntegrationTest method testGetExamScore.
@Test
@WithMockUser(username = "instructor1", roles = "INSTRUCTOR")
public void testGetExamScore() throws Exception {
// TODO avoid duplicated code with StudentExamIntegrationTest
var examVisibleDate = ZonedDateTime.now().minusMinutes(5);
var examStartDate = ZonedDateTime.now().plusMinutes(5);
var examEndDate = ZonedDateTime.now().plusMinutes(20);
Course course = database.addEmptyCourse();
Exam exam = database.addExam(course, examVisibleDate, examStartDate, examEndDate);
// TODO: it would be nice if we can support programming exercises here as well
exam = database.addExerciseGroupsAndExercisesToExam(exam, false);
// register users. Instructors are ignored from scores as they are exclusive for test run exercises
Set<User> registeredStudents = users.stream().filter(user -> !user.getLogin().contains("instructor") && !user.getLogin().contains("admin")).collect(Collectors.toSet());
exam.setRegisteredUsers(registeredStudents);
exam.setNumberOfExercisesInExam(exam.getExerciseGroups().size());
exam.setRandomizeExerciseOrder(false);
exam = examRepository.save(exam);
exam = examRepository.findWithRegisteredUsersAndExerciseGroupsAndExercisesById(exam.getId()).get();
// generate individual student exams
List<StudentExam> studentExams = request.postListWithResponseBody("/api/courses/" + course.getId() + "/exams/" + exam.getId() + "/generate-student-exams", Optional.empty(), StudentExam.class, HttpStatus.OK);
assertThat(studentExams).hasSize(exam.getRegisteredUsers().size());
assertThat(studentExamRepository.findAll()).hasSize(registeredStudents.size());
// start exercises
Integer noGeneratedParticipations = request.postWithResponseBody("/api/courses/" + course.getId() + "/exams/" + exam.getId() + "/student-exams/start-exercises", Optional.empty(), Integer.class, HttpStatus.OK);
assertThat(noGeneratedParticipations).isEqualTo(registeredStudents.size() * exam.getExerciseGroups().size());
// explicitly set the user again to prevent issues in the following server call due to the use of SecurityUtils.setAuthorizationObject();
database.changeUser("instructor1");
// instructor exam checklist checks
ExamChecklistDTO examChecklistDTO = examService.getStatsForChecklist(exam, true);
assertThat(examChecklistDTO).isNotNull();
assertThat(examChecklistDTO.getNumberOfGeneratedStudentExams()).isEqualTo(15L);
assertThat(examChecklistDTO.getAllExamExercisesAllStudentsPrepared()).isTrue();
assertThat(examChecklistDTO.getNumberOfTotalParticipationsForAssessment()).isZero();
// check that an adapted version is computed for tutors
database.changeUser("tutor1");
examChecklistDTO = examService.getStatsForChecklist(exam, false);
assertThat(examChecklistDTO).isNotNull();
assertThat(examChecklistDTO.getNumberOfGeneratedStudentExams()).isNull();
assertThat(examChecklistDTO.getAllExamExercisesAllStudentsPrepared()).isFalse();
assertThat(examChecklistDTO.getNumberOfTotalParticipationsForAssessment()).isZero();
database.changeUser("instructor1");
// set start and submitted date as results are created below
studentExams.forEach(studentExam -> {
studentExam.setStarted(true);
studentExam.setStartedDate(ZonedDateTime.now().minusMinutes(2));
studentExam.setSubmitted(true);
studentExam.setSubmissionDate(ZonedDateTime.now().minusMinutes(1));
});
studentExamRepository.saveAll(studentExams);
// Fetch the created participations and assign them to the exercises
int participationCounter = 0;
List<Exercise> exercisesInExam = exam.getExerciseGroups().stream().map(ExerciseGroup::getExercises).flatMap(Collection::stream).toList();
for (var exercise : exercisesInExam) {
List<StudentParticipation> participations = studentParticipationRepository.findByExerciseIdWithEagerLegalSubmissionsResult(exercise.getId());
exercise.setStudentParticipations(new HashSet<>(participations));
participationCounter += exercise.getStudentParticipations().size();
}
assertEquals(participationCounter, noGeneratedParticipations);
// Score used for all exercise results
Double resultScore = 75D;
// Assign results to participations and submissions
for (var exercise : exercisesInExam) {
for (var participation : exercise.getStudentParticipations()) {
Submission submission;
// Programming exercises don't have a submission yet
if (exercise instanceof ProgrammingExercise) {
assertThat(participation.getSubmissions()).isEmpty();
submission = new ProgrammingSubmission();
submission.setParticipation(participation);
submission = submissionRepository.save(submission);
} else {
// There should only be one submission for text, quiz, modeling and file upload
assertThat(participation.getSubmissions()).hasSize(1);
submission = participation.getSubmissions().iterator().next();
}
// Create results
var result = new Result().score(resultScore).rated(true).resultString("Good").completionDate(ZonedDateTime.now().minusMinutes(5));
result.setParticipation(participation);
result.setAssessor(instructor);
result = resultRepository.save(result);
result.setSubmission(submission);
submission.addResult(result);
submission.submitted(true);
submission.setSubmissionDate(ZonedDateTime.now().minusMinutes(6));
submissionRepository.save(submission);
}
}
// explicitly set the user again to prevent issues in the following server call due to the use of SecurityUtils.setAuthorizationObject();
database.changeUser("instructor1");
final var exerciseWithNoUsers = ModelFactory.generateTextExerciseForExam(exam.getExerciseGroups().get(0));
exerciseWithNoUsers.setKnowledge(textAssessmentKnowledgeService.createNewKnowledge());
exerciseRepo.save(exerciseWithNoUsers);
GradingScale gradingScale = new GradingScale();
gradingScale.setExam(exam);
gradingScale.setGradeType(GradeType.GRADE);
gradingScale.setGradeSteps(database.generateGradeStepSet(gradingScale, true));
gradingScaleRepository.save(gradingScale);
var response = request.get("/api/courses/" + course.getId() + "/exams/" + exam.getId() + "/scores", HttpStatus.OK, ExamScoresDTO.class);
// Compare generated results to data in ExamScoresDTO
// Compare top-level DTO properties
assertThat(response.maxPoints).isEqualTo(exam.getMaxPoints());
// For calculation assume that all exercises within an exerciseGroups have the same max points
double calculatedAverageScore = 0.0;
for (var exerciseGroup : exam.getExerciseGroups()) {
var exercise = exerciseGroup.getExercises().stream().findAny().get();
if (exercise.getIncludedInOverallScore().equals(IncludedInOverallScore.NOT_INCLUDED)) {
continue;
}
calculatedAverageScore += Math.round(exercise.getMaxPoints() * resultScore / 100.00 * 10) / 10.0;
}
assertThat(response.averagePointsAchieved).isEqualTo(calculatedAverageScore);
assertThat(response.title).isEqualTo(exam.getTitle());
assertThat(response.examId).isEqualTo(exam.getId());
// Ensure that all exerciseGroups of the exam are present in the DTO
List<Long> exerciseGroupIdsInDTO = response.exerciseGroups.stream().map(exerciseGroup -> exerciseGroup.id).collect(Collectors.toList());
List<Long> exerciseGroupIdsInExam = exam.getExerciseGroups().stream().map(ExerciseGroup::getId).collect(Collectors.toList());
assertThat(exerciseGroupIdsInExam).containsExactlyInAnyOrderElementsOf(exerciseGroupIdsInDTO);
// Compare exerciseGroups in DTO to exam exerciseGroups
// Tolerated absolute difference for floating-point number comparisons
double EPSILON = 0000.1;
for (var exerciseGroupDTO : response.exerciseGroups) {
// Find the original exerciseGroup of the exam using the id in ExerciseGroupId
ExerciseGroup originalExerciseGroup = exam.getExerciseGroups().stream().filter(exerciseGroup -> exerciseGroup.getId().equals(exerciseGroupDTO.id)).findFirst().get();
// Assume that all exercises in a group have the same max score
Double groupMaxScoreFromExam = originalExerciseGroup.getExercises().stream().findAny().get().getMaxPoints();
assertThat(exerciseGroupDTO.maxPoints).isEqualTo(originalExerciseGroup.getExercises().stream().findAny().get().getMaxPoints());
assertEquals(exerciseGroupDTO.maxPoints, groupMaxScoreFromExam, EPSILON);
// Compare exercise information
long noOfExerciseGroupParticipations = 0;
for (var originalExercise : originalExerciseGroup.getExercises()) {
// Find the corresponding ExerciseInfo object
var exerciseDTO = exerciseGroupDTO.containedExercises.stream().filter(exerciseInfo -> exerciseInfo.exerciseId.equals(originalExercise.getId())).findFirst().get();
// Check the exercise title
assertThat(originalExercise.getTitle()).isEqualTo(exerciseDTO.title);
// Check the max points of the exercise
assertThat(originalExercise.getMaxPoints()).isEqualTo(exerciseDTO.maxPoints);
// Check the number of exercise participants and update the group participant counter
var noOfExerciseParticipations = originalExercise.getStudentParticipations().size();
noOfExerciseGroupParticipations += noOfExerciseParticipations;
assertThat(Long.valueOf(originalExercise.getStudentParticipations().size())).isEqualTo(exerciseDTO.numberOfParticipants);
}
assertThat(noOfExerciseGroupParticipations).isEqualTo(exerciseGroupDTO.numberOfParticipants);
}
// Ensure that all registered students have a StudentResult
List<Long> studentIdsWithStudentResults = response.studentResults.stream().map(studentResult -> studentResult.userId).collect(Collectors.toList());
List<Long> registeredUsersIds = exam.getRegisteredUsers().stream().map(DomainObject::getId).collect(Collectors.toList());
assertThat(studentIdsWithStudentResults).containsExactlyInAnyOrderElementsOf(registeredUsersIds);
// Compare StudentResult with the generated results
for (var studentResult : response.studentResults) {
// Find the original user using the id in StudentResult
User originalUser = exam.getRegisteredUsers().stream().filter(users -> users.getId().equals(studentResult.userId)).findFirst().get();
StudentExam studentExamOfUser = studentExams.stream().filter(studentExam -> studentExam.getUser().equals(originalUser)).findFirst().get();
assertThat(studentResult.name).isEqualTo(originalUser.getName());
assertThat(studentResult.eMail).isEqualTo(originalUser.getEmail());
assertThat(studentResult.login).isEqualTo(originalUser.getLogin());
assertThat(studentResult.registrationNumber).isEqualTo(originalUser.getRegistrationNumber());
// Calculate overall points achieved
var calculatedOverallPoints = studentExamOfUser.getExercises().stream().filter(exercise -> !exercise.getIncludedInOverallScore().equals(IncludedInOverallScore.NOT_INCLUDED)).map(Exercise::getMaxPoints).reduce(0.0, (total, maxScore) -> (Math.round((total + maxScore * resultScore / 100) * 10) / 10.0));
assertEquals(studentResult.overallPointsAchieved, calculatedOverallPoints, EPSILON);
// Calculate overall score achieved
var calculatedOverallScore = calculatedOverallPoints / response.maxPoints * 100;
assertEquals(studentResult.overallScoreAchieved, calculatedOverallScore, EPSILON);
assertThat(studentResult.overallGrade).isNotNull();
assertThat(studentResult.hasPassed).isNotNull();
// Ensure that the exercise ids of the student exam are the same as the exercise ids in the students exercise results
List<Long> exerciseIdsOfStudentResult = studentResult.exerciseGroupIdToExerciseResult.values().stream().map(exerciseResult -> exerciseResult.exerciseId).collect(Collectors.toList());
List<Long> exerciseIdsInStudentExam = studentExamOfUser.getExercises().stream().map(DomainObject::getId).collect(Collectors.toList());
assertThat(exerciseIdsOfStudentResult).containsExactlyInAnyOrderElementsOf(exerciseIdsInStudentExam);
for (Map.Entry<Long, ExamScoresDTO.ExerciseResult> entry : studentResult.exerciseGroupIdToExerciseResult.entrySet()) {
var exerciseResult = entry.getValue();
// Find the original exercise using the id in ExerciseResult
Exercise originalExercise = studentExamOfUser.getExercises().stream().filter(exercise -> exercise.getId().equals(exerciseResult.exerciseId)).findFirst().get();
// Check that the key is associated with the exerciseGroup which actually contains the exercise in the exerciseResult
assertThat(originalExercise.getExerciseGroup().getId()).isEqualTo(entry.getKey());
assertThat(exerciseResult.title).isEqualTo(originalExercise.getTitle());
assertThat(exerciseResult.maxScore).isEqualTo(originalExercise.getMaxPoints());
assertThat(exerciseResult.achievedScore).isEqualTo(resultScore);
assertEquals(exerciseResult.achievedPoints, originalExercise.getMaxPoints() * resultScore / 100, EPSILON);
}
}
// change back to instructor user
database.changeUser("instructor1");
// check if stats are set correctly for the instructor
examChecklistDTO = examService.getStatsForChecklist(exam, true);
assertThat(examChecklistDTO).isNotNull();
assertThat(examChecklistDTO.getNumberOfGeneratedStudentExams()).isEqualTo(15);
assertThat(examChecklistDTO.getNumberOfExamsSubmitted()).isEqualTo(15);
assertThat(examChecklistDTO.getNumberOfExamsStarted()).isEqualTo(15);
assertThat(examChecklistDTO.getAllExamExercisesAllStudentsPrepared()).isTrue();
assertThat(examChecklistDTO.getNumberOfTotalParticipationsForAssessment()).isEqualTo(75);
assertThat(examChecklistDTO.getNumberOfTestRuns()).isZero();
assertThat(examChecklistDTO.getNumberOfTotalExamAssessmentsFinishedByCorrectionRound()).hasSize(1).containsAll((Collections.singletonList(90L)));
// change to a tutor
database.changeUser("tutor1");
// check that a modified version is returned
// check if stats are set correctly for the instructor
examChecklistDTO = examService.getStatsForChecklist(exam, false);
assertThat(examChecklistDTO).isNotNull();
assertThat(examChecklistDTO.getNumberOfGeneratedStudentExams()).isNull();
assertThat(examChecklistDTO.getNumberOfExamsSubmitted()).isNull();
assertThat(examChecklistDTO.getNumberOfExamsStarted()).isNull();
assertThat(examChecklistDTO.getAllExamExercisesAllStudentsPrepared()).isFalse();
assertThat(examChecklistDTO.getNumberOfTotalParticipationsForAssessment()).isEqualTo(75);
assertThat(examChecklistDTO.getNumberOfTestRuns()).isNull();
assertThat(examChecklistDTO.getNumberOfTotalExamAssessmentsFinishedByCorrectionRound()).hasSize(1).containsExactly(90L);
// change back to instructor user
database.changeUser("instructor1");
// Make sure delete also works if so many objects have been created before
request.delete("/api/courses/" + course.getId() + "/exams/" + exam.getId(), HttpStatus.OK);
}
use of de.tum.in.www1.artemis.domain.exam.ExerciseGroup in project ArTEMiS by ls1intum.
the class ExamIntegrationTest method unlockAllRepositories_preAuthNoInstructor.
@Test
@WithMockUser(username = "student1", roles = "USER")
public void unlockAllRepositories_preAuthNoInstructor() throws Exception {
ExerciseGroup exerciseGroup1 = new ExerciseGroup();
Exam exam = database.addExam(course1);
exam.addExerciseGroup(exerciseGroup1);
exam = examRepository.save(exam);
request.postWithResponseBody("/api/courses/" + course1.getId() + "/exams/" + exam.getId() + "/student-exams/unlock-all-repositories", Optional.empty(), Integer.class, HttpStatus.FORBIDDEN);
}
Aggregations