use of de.tum.in.www1.artemis.domain.Team in project ArTEMiS by ls1intum.
the class TeamIntegrationTest method getCourseWithExercisesAndParticipationsForTeam_AsTutor.
@Test
@WithMockUser(username = "tutor1", roles = "TA")
public void getCourseWithExercisesAndParticipationsForTeam_AsTutor() throws Exception {
List<Course> courses = database.createCoursesWithExercisesAndLectures(false);
Course course = courses.get(0);
ProgrammingExercise programmingExercise = (ProgrammingExercise) course.getExercises().stream().filter(exercise -> exercise instanceof ProgrammingExercise).findAny().orElseThrow();
TextExercise textExercise = (TextExercise) course.getExercises().stream().filter(exercise -> exercise instanceof TextExercise).findAny().orElseThrow();
ModelingExercise modelingExercise = (ModelingExercise) course.getExercises().stream().filter(exercise -> exercise instanceof ModelingExercise).findAny().orElseThrow();
// make exercises team-based
Stream.of(programmingExercise, textExercise, modelingExercise).forEach(exercise -> {
exercise.setMode(ExerciseMode.TEAM);
exerciseRepo.save(exercise);
});
String shortNamePrefix1 = "team";
String shortNamePrefix2 = "otherTeam";
Team team1a = database.addTeamsForExercise(programmingExercise, shortNamePrefix1, "team1astudent", 1, tutor).get(0);
Team team1b = database.addTeamsForExercise(textExercise, shortNamePrefix1, "team1bstudent", 1, tutor).get(0);
Team team1c = database.addTeamsForExercise(modelingExercise, shortNamePrefix1, "team1cstudent", 1, tutor).get(0);
Team team2a = database.addTeamsForExercise(programmingExercise, shortNamePrefix2, "team2astudent", 1, null).get(0);
Team team2b = database.addTeamsForExercise(textExercise, shortNamePrefix2, "team2bstudent", 1, null).get(0);
assertThat(Stream.of(team1a, team1b, team1c).map(Team::getShortName).distinct()).as("Teams 1 need the same short name for this test").hasSize(1);
assertThat(Stream.of(team2a, team2b).map(Team::getShortName).distinct()).as("Teams 2 need the same short name for this test").hasSize(1);
assertThat(Stream.of(team1a, team1b, team1c, team2a, team2b).map(Team::getShortName).distinct()).as("Teams 1 and Teams 2 need different short names").hasSize(2);
database.addTeamParticipationForExercise(programmingExercise, team1a.getId());
database.addTeamParticipationForExercise(textExercise, team1b.getId());
database.addTeamParticipationForExercise(programmingExercise, team2a.getId());
database.addTeamParticipationForExercise(textExercise, team2b.getId());
Course course1 = request.get(resourceUrlCourseWithExercisesAndParticipationsForTeam(course, team1a), HttpStatus.OK, Course.class);
assertThat(course1.getExercises()).as("All exercises of team 1 in course were returned").hasSize(3);
assertThat(course1.getExercises().stream().map(Exercise::getTeams).collect(Collectors.toSet())).as("All team instances of team 1 in course were returned").hasSize(3);
assertThat(course1.getExercises().stream().flatMap(exercise -> exercise.getStudentParticipations().stream()).collect(Collectors.toSet())).as("All participations of team 1 in course were returned").hasSize(2);
Course course2 = request.get(resourceUrlCourseWithExercisesAndParticipationsForTeam(course, team2a), HttpStatus.OK, Course.class);
assertThat(course2.getExercises()).as("All exercises of team 2 in course were returned").hasSize(2);
StudentParticipation studentParticipation = course2.getExercises().iterator().next().getStudentParticipations().iterator().next();
assertThat(studentParticipation.getSubmissionCount()).as("Participation includes submission count").isNotNull();
// Submission and Result should be present for Team of which the user is the Team Owner
final String submissionText = "Hello World";
TextSubmission submission = ModelFactory.generateTextSubmission(submissionText, Language.ENGLISH, true);
database.saveTextSubmissionWithResultAndAssessor(textExercise, submission, team1b.getId(), tutor.getLogin());
Course course3 = request.get(resourceUrlCourseWithExercisesAndParticipationsForTeam(course, team1a), HttpStatus.OK, Course.class);
StudentParticipation participation = course3.getExercises().stream().filter(exercise -> exercise.equals(textExercise)).findAny().orElseThrow().getStudentParticipations().iterator().next();
assertThat(participation.getSubmissions()).as("Latest submission is present").hasSize(1);
assertThat(((TextSubmission) participation.getSubmissions().iterator().next()).getText()).as("Latest submission is present").isEqualTo(submissionText);
assertThat(participation.getResults()).as("Latest result is present").hasSize(1);
// Submission and Result should not be present for a Team of which the user is not (!) the Team Owner
submission = ModelFactory.generateTextSubmission(submissionText, Language.ENGLISH, true);
database.saveTextSubmissionWithResultAndAssessor(textExercise, submission, team2b.getId(), "tutor2");
Course course4 = request.get(resourceUrlCourseWithExercisesAndParticipationsForTeam(course, team2a), HttpStatus.OK, Course.class);
participation = course4.getExercises().stream().filter(exercise -> exercise.equals(textExercise)).findAny().orElseThrow().getStudentParticipations().iterator().next();
assertThat(participation.getSubmissions()).as("Latest submission is not present").isEmpty();
assertThat(participation.getResults()).as("Latest result is not present").isEmpty();
}
use of de.tum.in.www1.artemis.domain.Team in project ArTEMiS by ls1intum.
the class TeamWebsocketServiceTest method testSendTeamAssignmentUpdateOnTeamCreate.
@Test
@WithMockUser(username = "tutor1", roles = "TA")
void testSendTeamAssignmentUpdateOnTeamCreate() throws Exception {
Team team = new Team().name("Team").shortName("team").exercise(modelingExercise).students(students);
team = request.postWithResponseBody(teamResourceUrl(), team, Team.class, HttpStatus.CREATED);
TeamAssignmentPayload expectedPayload = new TeamAssignmentPayload(modelingExercise, team);
team.getStudents().forEach(user -> verify(messagingTemplate).convertAndSendToUser(user.getLogin(), assignmentTopic, expectedPayload));
}
use of de.tum.in.www1.artemis.domain.Team in project Artemis by ls1intum.
the class ParticipantScoreService method calculateScores.
private List<ScoreDTO> calculateScores(Set<Exercise> exercises, Set<User> users, Double scoreCalculationDenominator) {
// 0.0 means we can not reasonably calculate the achieved points / scores
if (scoreCalculationDenominator.equals(0.0)) {
return List.of();
}
Set<Exercise> individualExercises = exercises.stream().filter(exercise -> !exercise.isTeamMode()).collect(Collectors.toSet());
Set<Exercise> teamExercises = exercises.stream().filter(Exercise::isTeamMode).collect(Collectors.toSet());
Course course = exercises.stream().findAny().get().getCourseViaExerciseGroupOrCourseMember();
// For every student we want to calculate the score
Map<Long, ScoreDTO> userIdToScores = users.stream().collect(Collectors.toMap(User::getId, ScoreDTO::new));
// individual exercises
// [0] -> User
// [1] -> sum of achieved points in exercises
List<Object[]> studentAndAchievedPoints = studentScoreRepository.getAchievedPointsOfStudents(individualExercises);
for (Object[] rawData : studentAndAchievedPoints) {
User user = (User) rawData[0];
double achievedPoints = rawData[1] != null ? ((Number) rawData[1]).doubleValue() : 0.0;
if (userIdToScores.containsKey(user.getId())) {
userIdToScores.get(user.getId()).pointsAchieved += achievedPoints;
}
}
// team exercises
// [0] -> Team
// [1] -> sum of achieved points in exercises
List<Object[]> teamAndAchievedPoints = teamScoreRepository.getAchievedPointsOfTeams(teamExercises);
for (Object[] rawData : teamAndAchievedPoints) {
Team team = (Team) rawData[0];
double achievedPoints = rawData[1] != null ? ((Number) rawData[1]).doubleValue() : 0.0;
for (User student : team.getStudents()) {
if (userIdToScores.containsKey(student.getId())) {
userIdToScores.get(student.getId()).pointsAchieved += achievedPoints;
}
}
}
// calculating achieved score
for (ScoreDTO scoreDTO : userIdToScores.values()) {
scoreDTO.scoreAchieved = roundScoreSpecifiedByCourseSettings((scoreDTO.pointsAchieved / scoreCalculationDenominator) * 100.0, course);
// sending this for debugging purposes to find out why the scores' calculation could be wrong
scoreDTO.regularPointsAchievable = scoreCalculationDenominator;
}
return new ArrayList<>(userIdToScores.values());
}
use of de.tum.in.www1.artemis.domain.Team in project Artemis by ls1intum.
the class ScoreService method getExistingParticipationScore.
/**
* Gets the existing participation score for an exercise and a participant or null if none can be found
*
* @param studentParticipation participation containing the information about the participant
* @param exercise exercise for which to find the participation score of the participant
* @return existing participation score or null if none can be found
*/
private ParticipantScore getExistingParticipationScore(StudentParticipation studentParticipation, Exercise exercise) {
ParticipantScore existingParticipationScoreForExerciseAndParticipant = null;
if (exercise.isTeamMode()) {
Team team = studentParticipation.getTeam().get();
Optional<TeamScore> teamScoreOptional = teamScoreRepository.findTeamScoreByExerciseAndTeam(exercise, team);
if (teamScoreOptional.isPresent()) {
existingParticipationScoreForExerciseAndParticipant = teamScoreOptional.get();
}
} else {
User user = studentParticipation.getStudent().get();
Optional<StudentScore> studentScoreOptional = studentScoreRepository.findStudentScoreByExerciseAndUser(exercise, user);
if (studentScoreOptional.isPresent()) {
existingParticipationScoreForExerciseAndParticipant = studentScoreOptional.get();
}
}
return existingParticipationScoreForExerciseAndParticipant;
}
use of de.tum.in.www1.artemis.domain.Team in project Artemis by ls1intum.
the class ParticipationTeamWebsocketService method updateSubmission.
/**
* Updates a modeling or text submission
*
* @param participationId id of participation
* @param submission updated modeling text submission
* @param principal principal of user who wants to update the submission
* @param topicPath path of websocket destination topic where to send the new submission
*/
private void updateSubmission(@DestinationVariable Long participationId, @Payload Submission submission, Principal principal, String topicPath) {
// Without this, custom jpa repository methods don't work in websocket channel.
SecurityUtils.setAuthorizationObject();
final StudentParticipation participation = studentParticipationRepository.findByIdElseThrow(participationId);
// user must belong to the team who owns the participation in order to update a submission
if (!participation.isOwnedBy(principal.getName())) {
return;
}
final User user = userRepository.getUserWithGroupsAndAuthorities(principal.getName());
final Exercise exercise = exerciseRepository.findByIdElseThrow(participation.getExercise().getId());
if (submission instanceof ModelingSubmission && exercise instanceof ModelingExercise) {
submission = modelingSubmissionService.save((ModelingSubmission) submission, (ModelingExercise) exercise, principal.getName());
modelingSubmissionService.hideDetails(submission, user);
} else if (submission instanceof TextSubmission && exercise instanceof TextExercise) {
submission = textSubmissionService.handleTextSubmission((TextSubmission) submission, (TextExercise) exercise, principal);
textSubmissionService.hideDetails(submission, user);
} else {
throw new IllegalArgumentException("Submission type '" + submission.getType() + "' not allowed.");
}
// update the last action date for the user and send out list of team members
updateValue(lastActionTracker, participationId, principal.getName());
sendOnlineTeamStudents(participationId);
SubmissionSyncPayload payload = new SubmissionSyncPayload(submission, user);
messagingTemplate.convertAndSend(getDestination(participationId, topicPath), payload);
}
Aggregations