diff --git a/src/main/resources/templates/error/5xx.html b/src/main/resources/templates/error/5xx.html
new file mode 100644
index 0000000..77563b2
--- /dev/null
+++ b/src/main/resources/templates/error/5xx.html
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+
Error code
+
+ Error message
+
+
+
+
+
+
+
--
2.51.2
From d726d1b2f0e1f5286485bbca8071595a6707ba78 Mon Sep 17 00:00:00 2001
From: Julien WITTOUCK
Date: Mon, 4 Sep 2023 15:27:01 +0200
Subject: [PATCH 2/6] =?UTF-8?q?=E2=9C=A8=20:=20add=20custom=20exception=20?=
=?UTF-8?q?class?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../gitlab/classrooms/gitlab/GitLabException.java | 9 +++++++++
1 file changed, 9 insertions(+)
create mode 100644 src/main/java/fr/univ_lille/gitlab/classrooms/gitlab/GitLabException.java
diff --git a/src/main/java/fr/univ_lille/gitlab/classrooms/gitlab/GitLabException.java b/src/main/java/fr/univ_lille/gitlab/classrooms/gitlab/GitLabException.java
new file mode 100644
index 0000000..b1c50a8
--- /dev/null
+++ b/src/main/java/fr/univ_lille/gitlab/classrooms/gitlab/GitLabException.java
@@ -0,0 +1,9 @@
+package fr.univ_lille.gitlab.classrooms.gitlab;
+
+import org.gitlab4j.api.GitLabApiException;
+
+public class GitLabException extends Exception {
+ public GitLabException(String message, GitLabApiException cause) {
+ super(message, cause);
+ }
+}
--
2.51.2
From 14619d5585916bd29cec1caf24bfbfdde1d0aa28 Mon Sep 17 00:00:00 2001
From: Julien WITTOUCK
Date: Mon, 4 Sep 2023 15:28:35 +0200
Subject: [PATCH 3/6] =?UTF-8?q?=E2=9C=A8=20:=20do=20not=20create=20projet?=
=?UTF-8?q?=20if=20it=20already=20exists?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
when accepting assignment twice
---
.../assignments/AssignmentController.java | 3 +-
.../assignments/AssignmentService.java | 3 +-
.../assignments/AssignmentServiceImpl.java | 3 +-
.../gitlab/classrooms/gitlab/Gitlab.java | 2 +-
.../gitlab/classrooms/gitlab/GitlabImpl.java | 43 ++++++--
.../AssignmentServiceImplTest.java | 5 +-
.../classrooms/gitlab/GitlabImplTest.java | 103 ++++++++++++++++--
7 files changed, 140 insertions(+), 22 deletions(-)
diff --git a/src/main/java/fr/univ_lille/gitlab/classrooms/assignments/AssignmentController.java b/src/main/java/fr/univ_lille/gitlab/classrooms/assignments/AssignmentController.java
index 0be35ce..ad9285f 100644
--- a/src/main/java/fr/univ_lille/gitlab/classrooms/assignments/AssignmentController.java
+++ b/src/main/java/fr/univ_lille/gitlab/classrooms/assignments/AssignmentController.java
@@ -1,6 +1,7 @@
package fr.univ_lille.gitlab.classrooms.assignments;
import fr.univ_lille.gitlab.classrooms.classrooms.ClassroomService;
+import fr.univ_lille.gitlab.classrooms.gitlab.GitLabException;
import fr.univ_lille.gitlab.classrooms.gitlab.Gitlab;
import fr.univ_lille.gitlab.classrooms.quiz.QuizService;
import fr.univ_lille.gitlab.classrooms.users.ClassroomUser;
@@ -85,7 +86,7 @@ class AssignmentController {
try {
this.assignmentService.acceptAssigment(assignment, student);
}
- catch (GitLabApiException e){
+ catch (GitLabApiException | GitLabException e){
LOGGER.log(System.Logger.Level.ERROR, "Could not accept assignment");
throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, "Could not accept assignment", e);
}
diff --git a/src/main/java/fr/univ_lille/gitlab/classrooms/assignments/AssignmentService.java b/src/main/java/fr/univ_lille/gitlab/classrooms/assignments/AssignmentService.java
index ff3f1f1..60c8455 100644
--- a/src/main/java/fr/univ_lille/gitlab/classrooms/assignments/AssignmentService.java
+++ b/src/main/java/fr/univ_lille/gitlab/classrooms/assignments/AssignmentService.java
@@ -1,6 +1,7 @@
package fr.univ_lille.gitlab.classrooms.assignments;
import fr.univ_lille.gitlab.classrooms.classrooms.Classroom;
+import fr.univ_lille.gitlab.classrooms.gitlab.GitLabException;
import fr.univ_lille.gitlab.classrooms.users.ClassroomUser;
import jakarta.transaction.Transactional;
import org.gitlab4j.api.GitLabApiException;
@@ -13,7 +14,7 @@ public interface AssignmentService {
Optional getAssignment(UUID id);
@Transactional
- void acceptAssigment(Assignment assignment, ClassroomUser student) throws GitLabApiException;
+ void acceptAssigment(Assignment assignment, ClassroomUser student) throws GitLabApiException, GitLabException;
List getAssignmentResults(Assignment assignment);
diff --git a/src/main/java/fr/univ_lille/gitlab/classrooms/assignments/AssignmentServiceImpl.java b/src/main/java/fr/univ_lille/gitlab/classrooms/assignments/AssignmentServiceImpl.java
index cdfe497..66840f8 100644
--- a/src/main/java/fr/univ_lille/gitlab/classrooms/assignments/AssignmentServiceImpl.java
+++ b/src/main/java/fr/univ_lille/gitlab/classrooms/assignments/AssignmentServiceImpl.java
@@ -2,6 +2,7 @@ package fr.univ_lille.gitlab.classrooms.assignments;
import fr.univ_lille.gitlab.classrooms.classrooms.Classroom;
import fr.univ_lille.gitlab.classrooms.classrooms.ClassroomService;
+import fr.univ_lille.gitlab.classrooms.gitlab.GitLabException;
import fr.univ_lille.gitlab.classrooms.gitlab.Gitlab;
import fr.univ_lille.gitlab.classrooms.quiz.QuizService;
import fr.univ_lille.gitlab.classrooms.users.ClassroomUser;
@@ -43,7 +44,7 @@ class AssignmentServiceImpl implements AssignmentService {
@Override
@Transactional
- public void acceptAssigment(Assignment assignment, ClassroomUser student) throws GitLabApiException {
+ public void acceptAssigment(Assignment assignment, ClassroomUser student) throws GitLabApiException, GitLabException {
assignment.accept(student);
this.assignmentRepository.save(assignment);
diff --git a/src/main/java/fr/univ_lille/gitlab/classrooms/gitlab/Gitlab.java b/src/main/java/fr/univ_lille/gitlab/classrooms/gitlab/Gitlab.java
index 62d4467..dc71230 100644
--- a/src/main/java/fr/univ_lille/gitlab/classrooms/gitlab/Gitlab.java
+++ b/src/main/java/fr/univ_lille/gitlab/classrooms/gitlab/Gitlab.java
@@ -44,5 +44,5 @@ public interface Gitlab {
* @param student the student who accepted the assignment
* @return the Gitlab Project
*/
- Project createProject(ExerciseAssignment exerciseAssignment, ClassroomUser student) throws GitLabApiException;
+ Project createProject(ExerciseAssignment exerciseAssignment, ClassroomUser student) throws GitLabApiException, GitLabException;
}
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 4bfa963..8f2683c 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
@@ -86,20 +86,26 @@ class GitlabImpl implements Gitlab {
}
@Override
- public Project createProject(ExerciseAssignment exerciseAssignment, ClassroomUser student) throws GitLabApiException {
+ public Project createProject(ExerciseAssignment exerciseAssignment, ClassroomUser student) throws GitLabApiException, 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);
- Project project;
+ Project project = null;
+ // get gitlab group info
+ var group = teacherGitlabApi.getGroupApi().getGroup(exerciseAssignment.getGitlabGroupId());
var projectName = exerciseAssignment.getName() + "-" + student.getName();
- if (exerciseAssignment.getGitlabRepositoryTemplateId() != null && !exerciseAssignment.getGitlabRepositoryTemplateId().isBlank()) {
- // get gitlab group info
- var group = teacherGitlabApi.getGroupApi().getGroup(exerciseAssignment.getGitlabGroupId());
+ try {
+ project = teacherGitlabApi.getProjectApi().getProject(group.getFullPath(), projectName);
+ }
+ catch (GitLabApiException ignore){
+ // ignoring the 404 exception, meaning that the project doesn't exists yet
+ }
+ if (project == null && (exerciseAssignment.getGitlabRepositoryTemplateId() != null && !exerciseAssignment.getGitlabRepositoryTemplateId().isBlank())) {
var path = slugify(projectName);
// fork the template project
project = teacherGitlabApi.getProjectApi().forkProject(
@@ -109,16 +115,37 @@ class GitlabImpl implements Gitlab {
projectName);
// remove the fork link
teacherGitlabApi.getProjectApi().deleteForkedFromRelationship(project.getId());
- } else {
+ } else if (project == null) {
// create a blank project
var projectParams = new Project()
.withName(projectName)
- .withNamespaceId(exerciseAssignment.getGitlabGroupId());
+ .withNamespaceId(group.getId());
project = teacherGitlabApi.getProjectApi().createProject(projectParams);
}
+
// grant the student access to its project
- teacherGitlabApi.getProjectApi().addMember(project.getId(), student.getGitlabUserId(), AccessLevel.MAINTAINER);
+ this.ensureStudentCanAccessItsProject(teacherGitlabApi, project, student);
return project;
}
+
+ private void ensureStudentCanAccessItsProject(GitLabApi gitlabApi, Project project, ClassroomUser student) throws GitLabException {
+ try {
+ var member = gitlabApi.getProjectApi().getMember(project.getId(), student.getGitlabUserId(), true);
+ if(member != null){
+ // found, student has access
+ return;
+ }
+ } catch (GitLabApiException ignore) {
+ // ignoring the 404 exception, meaning that the student doesn't have access to its repository
+ }
+ // grant the student access to its project
+ try {
+ gitlabApi.getProjectApi().addMember(project.getId(), student.getGitlabUserId(), AccessLevel.MAINTAINER);
+ } catch (GitLabApiException e) {
+ var message = String.format("Unable to give student %s access to its GitLab project %s", student.getGitlabUserId(), project.getId());
+ throw new GitLabException(message, e);
+ }
+
+ }
}
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 fa30c31..f2f5d06 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
@@ -2,6 +2,7 @@ package fr.univ_lille.gitlab.classrooms.assignments;
import fr.univ_lille.gitlab.classrooms.classrooms.Classroom;
import fr.univ_lille.gitlab.classrooms.classrooms.ClassroomService;
+import fr.univ_lille.gitlab.classrooms.gitlab.GitLabException;
import fr.univ_lille.gitlab.classrooms.gitlab.Gitlab;
import fr.univ_lille.gitlab.classrooms.quiz.QuizEntity;
import fr.univ_lille.gitlab.classrooms.quiz.QuizService;
@@ -50,7 +51,7 @@ class AssignmentServiceImplTest {
}
@Test
- void acceptAssignment_shouldAssociateTheStudentWithTheAssignment_andSave() throws GitLabApiException {
+ void acceptAssignment_shouldAssociateTheStudentWithTheAssignment_andSave() throws GitLabApiException, GitLabException {
var assignment = new QuizAssignment();
var student = new ClassroomUser();
@@ -63,7 +64,7 @@ class AssignmentServiceImplTest {
}
@Test
- void acceptExerciceAssignment_shouldCreateAGitlabProject() throws GitLabApiException {
+ void acceptExerciceAssignment_shouldCreateAGitlabProject() throws GitLabApiException, GitLabException {
var teacher = new ClassroomUser();
var classroom = new Classroom();
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 3d4452b..f71888b 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
@@ -6,10 +6,7 @@ import fr.univ_lille.gitlab.classrooms.users.ClassroomRole;
import fr.univ_lille.gitlab.classrooms.users.ClassroomUser;
import org.gitlab4j.api.GitLabApi;
import org.gitlab4j.api.GitLabApiException;
-import org.gitlab4j.api.models.AccessLevel;
-import org.gitlab4j.api.models.Group;
-import org.gitlab4j.api.models.GroupParams;
-import org.gitlab4j.api.models.Project;
+import org.gitlab4j.api.models.*;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Answers;
@@ -117,7 +114,7 @@ class GitlabImplTest {
}
@Test
- void createProject_shouldCreateAProject_andGiveAccessToTheStudent() throws GitLabApiException {
+ void createProject_shouldCreateAProject_andGiveAccessToTheStudent() throws GitLabApiException, GitLabException {
var student = new ClassroomUser("luke.skywalker", List.of(ClassroomRole.STUDENT));
student.setGitlabUserId(8L);
var teacher = new ClassroomUser("obiwan.kenobi", List.of(ClassroomRole.TEACHER));
@@ -126,6 +123,11 @@ class GitlabImplTest {
assignment.setName("Exercice 1");
assignment.setGitlabGroupId(72L);
+ var group = new Group();
+ group.setId(72L);
+ group.setFullPath("my-group/path");
+ when(gitLabApi.getGroupApi().getGroup(72L)).thenReturn(group);
+
var classroom = new Classroom();
classroom.setTeacher(teacher);
classroom.addAssignment(assignment);
@@ -134,8 +136,13 @@ class GitlabImplTest {
var projectMock = new Project();
projectMock.setId(125L);
+ // project non existing
+ when(gitLabApi.getProjectApi().getProject("my-group/path", "Exercice 1-luke.skywalker")).thenThrow(new GitLabApiException("Not Member"));
when(gitLabApi.getProjectApi().createProject(any(Project.class))).thenReturn(projectMock);
+ // no rights on project yet
+ when(gitLabApi.getProjectApi().getMember(125L, 8L, true)).thenThrow(new GitLabApiException("Not Member"));
+
gitlab.createProject(assignment, student);
var projectCaptor = ArgumentCaptor.forClass(Project.class);
@@ -152,7 +159,77 @@ class GitlabImplTest {
}
@Test
- void createProject_withTemplate_shouldForkAProject_andGiveAccessToTheStudent() throws GitLabApiException {
+ void createProject_shouldNotCreateAProject_ifProjectAlreadyExists() throws GitLabApiException, GitLabException {
+ var student = new ClassroomUser("luke.skywalker", List.of(ClassroomRole.STUDENT));
+ student.setGitlabUserId(8L);
+ var teacher = new ClassroomUser("obiwan.kenobi", List.of(ClassroomRole.TEACHER));
+
+ 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().getGroup(72L)).thenReturn(group);
+
+ var classroom = new Classroom();
+ classroom.setTeacher(teacher);
+ classroom.addAssignment(assignment);
+
+ when(gitlabApiFactory.userGitlabApi(teacher)).thenReturn(gitLabApi);
+
+ // project already exists
+ var projectMock = new Project();
+ projectMock.setId(125L);
+ when(gitLabApi.getProjectApi().getProject("my-group/path", "Exercice 1-luke.skywalker")).thenReturn(projectMock);
+
+ // no rights on project
+ when(gitLabApi.getProjectApi().getMember(125L, 8L, true)).thenThrow(new GitLabApiException("Not Member"));
+
+ gitlab.createProject(assignment, student);
+
+ verify(gitLabApi.getProjectApi()).addMember(125L, 8L, AccessLevel.MAINTAINER);
+
+ verifyNoMoreInteractions(gitLabApi.getProjectApi());
+ }
+
+ @Test
+ void createProject_shouldNotCreateAProject_ifProjectAlreadyExistsAndStudentAlreadyHasRights() throws GitLabApiException, GitLabException {
+ var student = new ClassroomUser("luke.skywalker", List.of(ClassroomRole.STUDENT));
+ student.setGitlabUserId(8L);
+ var teacher = new ClassroomUser("obiwan.kenobi", List.of(ClassroomRole.TEACHER));
+
+ 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().getGroup(72L)).thenReturn(group);
+
+ var classroom = new Classroom();
+ classroom.setTeacher(teacher);
+ classroom.addAssignment(assignment);
+
+ when(gitlabApiFactory.userGitlabApi(teacher)).thenReturn(gitLabApi);
+
+ // project already exists
+ var projectMock = new Project();
+ projectMock.setId(125L);
+ when(gitLabApi.getProjectApi().getProject("my-group/path", "Exercice 1-luke.skywalker")).thenReturn(projectMock);
+
+ // rights on project
+ when(gitLabApi.getProjectApi().getMember(125L, 8L, true)).thenReturn(new Member());
+
+ gitlab.createProject(assignment, student);
+
+ verifyNoMoreInteractions(gitLabApi.getProjectApi());
+ }
+
+ @Test
+ void createProject_withTemplate_shouldForkAProject_andGiveAccessToTheStudent() throws GitLabApiException, GitLabException {
var student = new ClassroomUser("luke.skywalker", List.of(ClassroomRole.STUDENT));
student.setGitlabUserId(8L);
var teacher = new ClassroomUser("obiwan.kenobi", List.of(ClassroomRole.TEACHER));
@@ -162,6 +239,11 @@ class GitlabImplTest {
assignment.setGitlabGroupId(72L);
assignment.setGitlabRepositoryTemplateId("12");
+ var group = new Group();
+ group.setId(72L);
+ group.setFullPath("my-group/path");
+ when(gitLabApi.getGroupApi().getGroup(72L)).thenReturn(group);
+
var classroom = new Classroom();
classroom.setTeacher(teacher);
classroom.addAssignment(assignment);
@@ -170,11 +252,16 @@ class GitlabImplTest {
var projectMock = new Project();
projectMock.setId(125L);
- when(gitLabApi.getProjectApi().forkProject("12", null, "Exercice_2_-_Template-luke.skywalker", "Exercice 2 - Template-luke.skywalker")).thenReturn(projectMock);
+ // project non existing
+ when(gitLabApi.getProjectApi().getProject("my-group/path", "Exercice 2 - Template-luke.skywalker")).thenThrow(new GitLabApiException("Not Member"));
+ when(gitLabApi.getProjectApi().forkProject("12", "my-group/path", "Exercice_2_-_Template-luke.skywalker", "Exercice 2 - Template-luke.skywalker")).thenReturn(projectMock);
+
+ // no rights on project
+ when(gitLabApi.getProjectApi().getMember(125L, 8L, true)).thenThrow(new GitLabApiException("Not Member"));
gitlab.createProject(assignment, student);
- verify(gitLabApi.getProjectApi()).forkProject("12", null, "Exercice_2_-_Template-luke.skywalker", "Exercice 2 - Template-luke.skywalker");
+ verify(gitLabApi.getProjectApi()).forkProject("12", "my-group/path", "Exercice_2_-_Template-luke.skywalker", "Exercice 2 - Template-luke.skywalker");
verify(gitLabApi.getProjectApi()).deleteForkedFromRelationship(125L);
verify(gitLabApi.getProjectApi()).addMember(125L, 8L, AccessLevel.MAINTAINER);
--
2.51.2
From 76eb04ad9f2bb43966eaf3db9c0377f2399590e2 Mon Sep 17 00:00:00 2001
From: Julien WITTOUCK
Date: Mon, 4 Sep 2023 15:43:03 +0200
Subject: [PATCH 4/6] =?UTF-8?q?=F0=9F=90=9B=20:=20do=20not=20create=20Stud?=
=?UTF-8?q?entExerciseAssignment=20if=20already=20existing?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../assignments/AssignmentServiceImpl.java | 10 ++++--
.../StudentAssignmentRepository.java | 2 ++
.../AssignmentServiceImplTest.java | 35 +++++++++++++++++++
3 files changed, 44 insertions(+), 3 deletions(-)
diff --git a/src/main/java/fr/univ_lille/gitlab/classrooms/assignments/AssignmentServiceImpl.java b/src/main/java/fr/univ_lille/gitlab/classrooms/assignments/AssignmentServiceImpl.java
index 66840f8..2b7302d 100644
--- a/src/main/java/fr/univ_lille/gitlab/classrooms/assignments/AssignmentServiceImpl.java
+++ b/src/main/java/fr/univ_lille/gitlab/classrooms/assignments/AssignmentServiceImpl.java
@@ -51,7 +51,9 @@ class AssignmentServiceImpl implements AssignmentService {
if (assignment instanceof ExerciseAssignment exerciseAssignment) {
// create the project in gitlab
var project = gitlab.createProject(exerciseAssignment, student);
-
+ if (this.studentAssignmentRepository.existsByAssignmentAndStudent(exerciseAssignment, student)) {
+ return;
+ }
// create the student exercise assignment
var studentExercise = new StudentExerciseAssignment();
studentExercise.setAssignment(exerciseAssignment);
@@ -59,8 +61,10 @@ class AssignmentServiceImpl implements AssignmentService {
studentExercise.setGitlabProjectId(project.getId());
studentExercise.setGitlabProjectUrl(project.getWebUrl());
this.studentAssignmentRepository.save(studentExercise);
- }
- else if (assignment instanceof QuizAssignment quizAssignment) {
+ } else if (assignment instanceof QuizAssignment quizAssignment) {
+ if (this.studentAssignmentRepository.existsByAssignmentAndStudent(quizAssignment, student)) {
+ return;
+ }
// create the student quiz assignment
var studentExercise = new StudentQuizAssignment();
studentExercise.setAssignment(quizAssignment);
diff --git a/src/main/java/fr/univ_lille/gitlab/classrooms/assignments/StudentAssignmentRepository.java b/src/main/java/fr/univ_lille/gitlab/classrooms/assignments/StudentAssignmentRepository.java
index 5e50f88..638b4a2 100644
--- a/src/main/java/fr/univ_lille/gitlab/classrooms/assignments/StudentAssignmentRepository.java
+++ b/src/main/java/fr/univ_lille/gitlab/classrooms/assignments/StudentAssignmentRepository.java
@@ -10,6 +10,8 @@ import java.util.UUID;
interface StudentAssignmentRepository extends JpaRepository {
List findAllByAssignment(Assignment assignment);
+ boolean existsByAssignmentAndStudent(Assignment assignment, ClassroomUser student);
+
StudentAssignment findByAssignmentAndStudent(Assignment assignment, ClassroomUser student);
List findByAssignmentClassroomAndStudent(Classroom classroom, ClassroomUser 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 f2f5d06..1a9813f 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
@@ -63,6 +63,19 @@ class AssignmentServiceImplTest {
verify(assignmentRepository).save(assignment);
}
+ @Test
+ void acceptAssignment_shouldDoNothing_ifQuizAssignmentIsAlreadyAccepted() throws GitLabApiException, GitLabException {
+ var assignment = new QuizAssignment();
+
+ var student = new ClassroomUser();
+
+ when(studentAssignmentRepository.existsByAssignmentAndStudent(assignment, student)).thenReturn(true);
+
+ this.assignmentService.acceptAssigment(assignment, student);
+
+ verifyNoMoreInteractions(studentAssignmentRepository);
+ }
+
@Test
void acceptExerciceAssignment_shouldCreateAGitlabProject() throws GitLabApiException, GitLabException {
var teacher = new ClassroomUser();
@@ -98,6 +111,28 @@ class AssignmentServiceImplTest {
assertThat(studentExercise.getGitlabProjectUrl()).isEqualTo("https://gitlab.univ-lille.fr/gitlab-classroom");
}
+ @Test
+ void acceptAssignment_shouldDoNothing_ifExerciseAssignmentIsAlreadyAccepted() throws GitLabApiException, GitLabException {
+ var teacher = new ClassroomUser();
+
+ var classroom = new Classroom();
+ classroom.setTeacher(teacher);
+
+ var assignment = new ExerciseAssignment();
+ assignment.setName("Exercice 1");
+ assignment.setGitlabGroupId(12L);
+ classroom.addAssignment(assignment);
+
+ var student = new ClassroomUser();
+ student.setName("luke.skywalker");
+
+ when(studentAssignmentRepository.existsByAssignmentAndStudent(assignment, student)).thenReturn(true);
+
+ this.assignmentService.acceptAssigment(assignment, student);
+
+ verifyNoMoreInteractions(studentAssignmentRepository);
+ }
+
@Test
void createQuizAssignment_shouldAssociateTheAssignmentWithTheQuiz_andSaveTheClassroom(){
var quiz = new QuizEntity();
--
2.51.2
From 95b43f2224a2dd16e684dccfa8668dfea1bada30 Mon Sep 17 00:00:00 2001
From: Julien WITTOUCK
Date: Mon, 4 Sep 2023 15:55:18 +0200
Subject: [PATCH 5/6] =?UTF-8?q?=E2=9C=85=20:=20show=20error=20when=20accep?=
=?UTF-8?q?ting=20assignment?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../assignments/AssignmentControllerMVCTest.java | 16 ++++++++++++++--
1 file changed, 14 insertions(+), 2 deletions(-)
diff --git a/src/test/java/fr/univ_lille/gitlab/classrooms/assignments/AssignmentControllerMVCTest.java b/src/test/java/fr/univ_lille/gitlab/classrooms/assignments/AssignmentControllerMVCTest.java
index b72cf95..fabff56 100644
--- a/src/test/java/fr/univ_lille/gitlab/classrooms/assignments/AssignmentControllerMVCTest.java
+++ b/src/test/java/fr/univ_lille/gitlab/classrooms/assignments/AssignmentControllerMVCTest.java
@@ -2,11 +2,13 @@ package fr.univ_lille.gitlab.classrooms.assignments;
import fr.univ_lille.gitlab.classrooms.classrooms.Classroom;
import fr.univ_lille.gitlab.classrooms.classrooms.ClassroomService;
+import fr.univ_lille.gitlab.classrooms.gitlab.GitLabException;
import fr.univ_lille.gitlab.classrooms.gitlab.Gitlab;
import fr.univ_lille.gitlab.classrooms.quiz.*;
import fr.univ_lille.gitlab.classrooms.users.ClassroomUserService;
import fr.univ_lille.gitlab.classrooms.users.WithMockStudent;
import fr.univ_lille.gitlab.classrooms.users.WithMockTeacher;
+import org.gitlab4j.api.GitLabApiException;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
@@ -22,8 +24,7 @@ import java.util.UUID;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.*;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
@@ -132,6 +133,17 @@ class AssignmentControllerMVCTest {
verify(assignmentService).acceptAssigment(any(), any());
}
+ @Test
+ @WithMockStudent
+ void acceptAssignment_shouldShowAnError_whenGitLabException() throws Exception {
+ doThrow(new GitLabException("Could not create project", new GitLabApiException("500"))).when(this.assignmentService).acceptAssigment(any(), any());
+
+ mockMvc.perform(post("/assignments/"+ exerciseAssignmentId +"/accept").with(csrf()))
+ .andExpect(status().is5xxServerError());
+
+ verify(assignmentService).acceptAssigment(any(), any());
+ }
+
@Test
@WithMockTeacher
void viewQuizAssignment_shouldShowTheAssignmentResults() throws Exception {
--
2.51.2
From a3d8574651cf0aa118d9157490f45ee3eebbefc5 Mon Sep 17 00:00:00 2001
From: Julien WITTOUCK
Date: Mon, 4 Sep 2023 17:31:57 +0200
Subject: [PATCH 6/6] =?UTF-8?q?=F0=9F=94=96=20:=20version=200.0.7?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
CHANGELOG.md | 20 ++++++++++++++++++++
pom.xml | 2 +-
2 files changed, 21 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3d5ebbb..4d92f9f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,25 @@
# Changelog
+
+## 0.0.7 (2023-09-04)
+
+### Added
+
+- ✅ : show error when accepting assignment [95b43f2]
+- ✨ : do not create projet if it already exists [14619d5]
+- ✨ : add custom exception class [d726d1b]
+- ✨ : add error page for 5XX errors [8224af9]
+
+### Fixed
+
+- 🐛 : do not create StudentExerciseAssignment if already existing [76eb04a]
+
+### Miscellaneous
+
+- 🔀 : merge branch 'bugfix/existing-projects' into develop [8dfa3a8]
+- 🔀 : merge tag '0.0.6' into develop [b210b03]
+
+
## 0.0.6 (2023-09-01)
diff --git a/pom.xml b/pom.xml
index 696a0ae..dc64fe7 100644
--- a/pom.xml
+++ b/pom.xml
@@ -12,7 +12,7 @@
fr.univ-lille
gitlab-classrooms
- 0.0.6
+ 0.0.7
gitlab-classrooms
GitLab Classroom is a modest clone of GitHub Classroom, aimed at GitLab.