diff --git a/src/main/java/fr/univ_lille/gitlab/classrooms/classrooms/Classroom.java b/src/main/java/fr/univ_lille/gitlab/classrooms/classrooms/Classroom.java --- a/src/main/java/fr/univ_lille/gitlab/classrooms/classrooms/Classroom.java +++ b/src/main/java/fr/univ_lille/gitlab/classrooms/classrooms/Classroom.java @@ -19,8 +19,8 @@ private URL gitlabUrl; private Long gitlabGroupId; - @ManyToOne - private ClassroomUser teacher; + @ManyToMany(fetch = FetchType.EAGER) + private Set teachers = new HashSet<>(); @ManyToMany(fetch = FetchType.EAGER) private Set students = new HashSet<>(); @@ -52,12 +52,16 @@ public void setGitlabUrl(URL gitlabUrl) { this.gitlabUrl = gitlabUrl; } - public ClassroomUser getTeacher() { - return teacher; + public Set getTeachers() { + return teachers; } - public void setTeacher(ClassroomUser teacher) { - this.teacher = teacher; + public void setTeachers(Set teachers) { + this.teachers = teachers; + } + + public void addTeacher(ClassroomUser teacher) { + this.teachers.add(teacher); } public Set getStudents() { diff --git a/src/main/java/fr/univ_lille/gitlab/classrooms/classrooms/ClassroomServiceImpl.java b/src/main/java/fr/univ_lille/gitlab/classrooms/classrooms/ClassroomServiceImpl.java --- a/src/main/java/fr/univ_lille/gitlab/classrooms/classrooms/ClassroomServiceImpl.java +++ b/src/main/java/fr/univ_lille/gitlab/classrooms/classrooms/ClassroomServiceImpl.java @@ -50,7 +50,7 @@ @Override public void createClassroom(String classroomName, Long parentGitlabGroupId, ClassroomUser teacher) throws GitLabApiException { var classroom = new Classroom(); classroom.setName(classroomName); - classroom.setTeacher(teacher); + classroom.addTeacher(teacher); this.gitlab.createGroup(classroom, Optional.ofNullable(parentGitlabGroupId)); diff --git a/src/main/java/fr/univ_lille/gitlab/classrooms/gitlab/GitlabImpl.java b/src/main/java/fr/univ_lille/gitlab/classrooms/gitlab/GitlabImpl.java --- a/src/main/java/fr/univ_lille/gitlab/classrooms/gitlab/GitlabImpl.java +++ b/src/main/java/fr/univ_lille/gitlab/classrooms/gitlab/GitlabImpl.java @@ -88,9 +88,14 @@ @Override public Project createStudentProject(ExerciseAssignment exerciseAssignment, ClassroomUser student) throws GitLabException { var classroom = exerciseAssignment.getClassroom(); - var teacher = classroom.getTeacher(); - // get a gitlab api client ith the teacher's rights - var teacherGitlabApi = this.gitlabApiFactory.userGitlabApi(teacher); + + var teacher = classroom.getTeachers().stream().findFirst(); + + if(teacher.isEmpty()){ + throw new GitLabException("Could not create student %s project for assignment %s. Classroom has no teacher.".formatted(student.getName(), exerciseAssignment.getName())); + } + // get a gitlab api client with the teacher's rights + var teacherGitlabApi = this.gitlabApiFactory.userGitlabApi(teacher.get()); // create the project if needed var project = this.ensureStudentProjectExists(teacherGitlabApi, exerciseAssignment, student); diff --git a/src/main/resources/db/migration/V20__CLASSROOM_TEACHERS.sql b/src/main/resources/db/migration/V20__CLASSROOM_TEACHERS.sql new file mode 100644 --- /dev/null +++ b/src/main/resources/db/migration/V20__CLASSROOM_TEACHERS.sql @@ -0,0 +1,22 @@ +CREATE TABLE classroom_teachers +( + classroom_id UUID NOT NULL, + teachers_name VARCHAR(255) NOT NULL, + CONSTRAINT pk_classroom_teachers PRIMARY KEY (classroom_id, teachers_name) +); + +ALTER TABLE classroom_teachers + ADD CONSTRAINT fk_classroom FOREIGN KEY (classroom_id) REFERENCES classroom (id); + +ALTER TABLE classroom_teachers + ADD CONSTRAINT fk_classroom_user FOREIGN KEY (teachers_name) REFERENCES classroom_user (name); + +-- migrate data to new table +INSERT INTO classroom_teachers (classroom_id, teachers_name) + SELECT id, teacher_name FROM classroom; + +ALTER TABLE classroom + DROP CONSTRAINT fk_classroom_user; + +ALTER TABLE classroom + DROP COLUMN teacher_name; diff --git a/src/test/java/fr/univ_lille/gitlab/classrooms/assignments/AssignmentServiceImplTest.java b/src/test/java/fr/univ_lille/gitlab/classrooms/assignments/AssignmentServiceImplTest.java --- a/src/test/java/fr/univ_lille/gitlab/classrooms/assignments/AssignmentServiceImplTest.java +++ b/src/test/java/fr/univ_lille/gitlab/classrooms/assignments/AssignmentServiceImplTest.java @@ -81,7 +81,7 @@ void acceptExerciceAssignment_shouldCreateAGitlabProject() throws GitLabApiException, GitLabException { var teacher = new ClassroomUser(); var classroom = new Classroom(); - classroom.setTeacher(teacher); + classroom.addTeacher(teacher); var assignment = new ExerciseAssignment(); assignment.setName("Exercice 1"); @@ -116,7 +116,7 @@ void acceptAssignment_shouldUpdateGitlabInfo_ifExerciseAssignmentIsAlreadyAccepted() throws GitLabApiException, GitLabException { var teacher = new ClassroomUser(); var classroom = new Classroom(); - classroom.setTeacher(teacher); + classroom.addTeacher(teacher); var assignment = new ExerciseAssignment(); assignment.setName("Exercice 1"); diff --git a/src/test/java/fr/univ_lille/gitlab/classrooms/classrooms/ClassroomServiceImplTest.java b/src/test/java/fr/univ_lille/gitlab/classrooms/classrooms/ClassroomServiceImplTest.java --- a/src/test/java/fr/univ_lille/gitlab/classrooms/classrooms/ClassroomServiceImplTest.java +++ b/src/test/java/fr/univ_lille/gitlab/classrooms/classrooms/ClassroomServiceImplTest.java @@ -76,6 +76,8 @@ verify(classroomRepository).save(classroomCaptor.capture()); assertThat(classroomCaptor.getValue()) .isNotNull() - .hasFieldOrPropertyWithValue("teacher.name", "obiwan.kenobi"); + .satisfies(it -> { + assertThat(it.getTeachers()).contains(teacher); + }); } } diff --git a/src/test/java/fr/univ_lille/gitlab/classrooms/gitlab/GitlabImplTest.java b/src/test/java/fr/univ_lille/gitlab/classrooms/gitlab/GitlabImplTest.java --- a/src/test/java/fr/univ_lille/gitlab/classrooms/gitlab/GitlabImplTest.java +++ b/src/test/java/fr/univ_lille/gitlab/classrooms/gitlab/GitlabImplTest.java @@ -129,7 +129,7 @@ group.setFullPath("my-group/path"); when(gitLabApi.getGroupApi().getOptionalGroup(72L)).thenReturn(Optional.of(group)); var classroom = new Classroom(); - classroom.setTeacher(teacher); + classroom.addTeacher(teacher); classroom.addAssignment(assignment); when(gitlabApiFactory.userGitlabApi(teacher)).thenReturn(gitLabApi); @@ -160,6 +160,30 @@ verifyNoMoreInteractions(gitLabApi.getProjectApi()); } @Test + void createProject_shouldNotCreateAProject_ifClassroomHasNoTeacher() throws GitLabApiException, GitLabException { + var student = new ClassroomUser("luke.skywalker", List.of(ClassroomRole.STUDENT)); + student.setGitlabUserId(8L); + + var assignment = new ExerciseAssignment(); + assignment.setName("Exercice 1"); + assignment.setGitlabGroupId(72L); + + var group = new Group(); + group.setId(72L); + group.setFullPath("my-group/path"); + when(gitLabApi.getGroupApi().getOptionalGroup(72L)).thenReturn(Optional.of(group)); + + var classroom = new Classroom(); + classroom.addAssignment(assignment); + + assertThatThrownBy(() -> gitlab.createStudentProject(assignment, student)) + .isInstanceOf(GitLabException.class) + .hasMessage("Could not create student luke.skywalker project for assignment Exercice 1. Classroom has no teacher."); + + verifyNoMoreInteractions(gitLabApi.getProjectApi()); + } + + @Test void createProject_shouldNotCreateAProject_ifProjectAlreadyExists() throws GitLabApiException, GitLabException { var student = new ClassroomUser("luke.skywalker", List.of(ClassroomRole.STUDENT)); student.setGitlabUserId(8L); @@ -175,7 +199,7 @@ group.setFullPath("my-group/path"); when(gitLabApi.getGroupApi().getOptionalGroup(72L)).thenReturn(Optional.of(group)); var classroom = new Classroom(); - classroom.setTeacher(teacher); + classroom.addTeacher(teacher); classroom.addAssignment(assignment); when(gitlabApiFactory.userGitlabApi(teacher)).thenReturn(gitLabApi); @@ -211,7 +235,7 @@ group.setFullPath("my-group/path"); when(gitLabApi.getGroupApi().getOptionalGroup(72L)).thenReturn(Optional.of(group)); var classroom = new Classroom(); - classroom.setTeacher(teacher); + classroom.addTeacher(teacher); classroom.addAssignment(assignment); when(gitlabApiFactory.userGitlabApi(teacher)).thenReturn(gitLabApi); @@ -246,7 +270,7 @@ group.setFullPath("my-group/path"); when(gitLabApi.getGroupApi().getOptionalGroup(72L)).thenReturn(Optional.of(group)); var classroom = new Classroom(); - classroom.setTeacher(teacher); + classroom.addTeacher(teacher); classroom.addAssignment(assignment); when(gitlabApiFactory.userGitlabApi(teacher)).thenReturn(gitLabApi);