From aca9e6c67a28664e6a3dcbe4eb92d58d61f6ea3b Mon Sep 17 00:00:00 2001 From: Julien WITTOUCK Date: Thu, 16 Nov 2023 15:11:36 +0100 Subject: [PATCH 1/2] =?UTF-8?q?=E2=9C=A8=20:=20classrooms=20can=20have=20m?= =?UTF-8?q?ultiple=20teachers?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../classrooms/classrooms/Classroom.java | 16 ++++++---- .../classrooms/ClassroomServiceImpl.java | 2 +- .../gitlab/classrooms/gitlab/GitlabImpl.java | 11 +++++-- .../AssignmentServiceImplTest.java | 4 +-- .../classrooms/ClassroomServiceImplTest.java | 4 ++- .../classrooms/gitlab/GitlabImplTest.java | 32 ++++++++++++++++--- 6 files changed, 52 insertions(+), 17 deletions(-) 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 index 749be99..121bd7f 100644 --- 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 @@ public class Classroom { 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 class Classroom { this.gitlabUrl = gitlabUrl; } - public ClassroomUser getTeacher() { - return teacher; + public Set getTeachers() { + return teachers; + } + + public void setTeachers(Set teachers) { + this.teachers = teachers; } - public void setTeacher(ClassroomUser teacher) { - this.teacher = teacher; + 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 index 84df05b..6d47a50 100644 --- 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 @@ class ClassroomServiceImpl implements ClassroomService { 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 index fb5dca3..ec74f68 100644 --- 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 @@ class GitlabImpl implements Gitlab { @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/test/java/fr/univ_lille/gitlab/classrooms/assignments/AssignmentServiceImplTest.java b/src/test/java/fr/univ_lille/gitlab/classrooms/assignments/AssignmentServiceImplTest.java index ee0f1cc..11cd009 100644 --- 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 @@ class AssignmentServiceImplTest { 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 @@ class AssignmentServiceImplTest { 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 index fd6b945..9f80333 100644 --- 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 @@ class ClassroomServiceImplTest { 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 index a9ffa61..531b5e3 100644 --- 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 @@ class GitlabImplTest { 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); @@ -159,6 +159,30 @@ class GitlabImplTest { 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)); @@ -175,7 +199,7 @@ class GitlabImplTest { 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 @@ class GitlabImplTest { 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 @@ class GitlabImplTest { 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); -- 2.51.2 From 3b51e655e48a29a08d3237aeb59b2201a4af1e0f Mon Sep 17 00:00:00 2001 From: Julien WITTOUCK Date: Thu, 16 Nov 2023 15:37:00 +0100 Subject: [PATCH 2/2] =?UTF-8?q?=F0=9F=97=83=EF=B8=8F=20:=20add=20classroom?= =?UTF-8?q?=5Fteachers=20table?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../db/migration/V20__CLASSROOM_TEACHERS.sql | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 src/main/resources/db/migration/V20__CLASSROOM_TEACHERS.sql 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 index 0000000..72ca838 --- /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; -- 2.51.2