Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Backend test upgrades #259

Merged
merged 44 commits into from
May 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
d9149d0
updated ClusterControllerTests
Aqua-sc Apr 28, 2024
14bcc40
use interceptor in tests,start upgrade coursetests
Aqua-sc Apr 28, 2024
ded5f6b
courseUpdate tests upgraded
Aqua-sc Apr 28, 2024
3f62f4f
courseControllerTest almost finished
Aqua-sc Apr 29, 2024
5563a5a
cleanup courseController test
Aqua-sc Apr 30, 2024
4fee23e
clustercontroller test cleanup
Aqua-sc Apr 30, 2024
3ee0fe2
update groupcontroller tests
Aqua-sc Apr 30, 2024
fe86dca
start groupfeedbackcontroller tests
Aqua-sc Apr 30, 2024
f475446
GroupFeedbackController tests upgrades
Aqua-sc May 5, 2024
d51ce6e
Update GroupMembersControllerTest.java
Aqua-sc May 5, 2024
0354cd4
Start projectcontroller test upgrades
Aqua-sc May 5, 2024
7bae207
projectcontrollertest upgrade finished
Aqua-sc May 5, 2024
8830fd3
UserControllertests
Aqua-sc May 5, 2024
0c38c98
Added a transactional to file submission
Aqua-sc May 5, 2024
d0b38a3
ClusterUtilTests
Aqua-sc May 5, 2024
1088603
courseUtil tests
Aqua-sc May 5, 2024
0260207
Update CourseUtilTest.java
Aqua-sc May 6, 2024
3c01ef5
groupfeedbackutil tests
Aqua-sc May 6, 2024
b9fbba6
GroupUtil tests
Aqua-sc May 6, 2024
02d31dd
ProjectUtilTests
Aqua-sc May 6, 2024
e08bdbd
StringMatcher tests
Aqua-sc May 6, 2024
ab1fb51
Update UserUtilTest.java
Aqua-sc May 7, 2024
63eeee6
start globalerrorhandler test
Aqua-sc May 7, 2024
9b58a01
GlobalErroHandlerTest
Aqua-sc May 8, 2024
77923bb
RolesInterceptorTest
Aqua-sc May 8, 2024
d739e05
Merge branch 'development' into backendtestadditions
Aqua-sc May 10, 2024
ebcd892
small fixes to test and controller
Aqua-sc May 10, 2024
0e2bee5
test getSubmission(s)
Aqua-sc May 10, 2024
732901b
submitfile fully tested
Aqua-sc May 10, 2024
548b3b1
SubmissionController fully tested
Aqua-sc May 10, 2024
cf4d2b7
Update altertest to make it easier to test
Aqua-sc May 10, 2024
ec27a13
AlterTest through PUT/PATCH/POST tested
Aqua-sc May 10, 2024
ef31dfe
TestController fully tested
Aqua-sc May 10, 2024
c49f868
Commondatabaseactions tests
Aqua-sc May 10, 2024
c09f9af
Merge branch 'development' into backendtestadditions
Aqua-sc May 11, 2024
c3c80f5
EntityToJsonConverter test
Aqua-sc May 11, 2024
bb0cc3d
Fileutil + submissionUtil tests
Aqua-sc May 11, 2024
078deb6
Filehandler tests
Aqua-sc May 11, 2024
1cbbe1a
TestUtiltests
Aqua-sc May 11, 2024
c21384e
TestRunnerTest
Aqua-sc May 11, 2024
50566b3
Merge branch 'development' into backendtestadditions
Aqua-sc May 11, 2024
5be50ce
update testControllerTests
Aqua-sc May 11, 2024
7ce666b
Merge branch 'development' into backendtestadditions
Aqua-sc May 12, 2024
a2b3de1
updated test for clusterfillroute
Aqua-sc May 12, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file added backend/app/artifactPath
Empty file.
18 changes: 16 additions & 2 deletions backend/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
runtimeOnly 'org.postgresql:postgresql'
implementation 'org.springframework.boot:spring-boot-starter-oauth2-client'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.security:spring-security-config'
implementation 'org.springframework.boot:spring-boot-starter-oauth2-resource-server'
Expand All @@ -44,6 +43,9 @@ dependencies {
implementation "org.springframework.boot:spring-boot-devtools"
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.springframework.security:spring-security-test'
testImplementation 'org.mockito:mockito-junit-jupiter:4.0.0'
implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310'
testImplementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310'
}

// tasks.named('test',Test) {
Expand All @@ -52,14 +54,14 @@ dependencies {

// testLogging {
// events "passed"

// }
// }

task unitTests (type: Test){

exclude '**/docker'


useJUnitPlatform()
maxHeapSize = '1G'

Expand All @@ -69,3 +71,15 @@ task unitTests (type: Test){

}

task allTest (type: Test) {

include '**'
useJUnitPlatform()
maxHeapSize = '1G'


testLogging {
events "passed"
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ private void logError(Exception ex) {
logger.log(Level.SEVERE, ex.getMessage(), ex);
}

/* Gets thrown when a invalid json is sent */
@ExceptionHandler(HttpMessageNotReadableException.class)
public ResponseEntity<ApiErrorReponse> handleHttpMessageNotReadableException(HttpServletRequest request, Exception ex) {
logError(ex);
Expand All @@ -40,15 +41,17 @@ public ResponseEntity<ApiErrorReponse> handleHttpMessageNotReadableException(Htt
"Unable to process the request due to invalid or missing data. Please ensure the request body is properly formatted and all required fields are provided.", path));
}

@ExceptionHandler(NoResourceFoundException.class)
public ResponseEntity<ApiErrorReponse> handleHttpMessageNotFoundException(HttpServletRequest request, Exception ex) {
/* Gets thrown when endpoint doesn't exist */
@ExceptionHandler(NoHandlerFoundException.class)
public ResponseEntity<ApiErrorReponse> handleNoHandlerFoundException(HttpServletRequest request, Exception ex) {
logError(ex);
String path = request.getRequestURI();
HttpStatus status = HttpStatus.NOT_FOUND;
return ResponseEntity.status(status).body(new ApiErrorReponse(OffsetDateTime.now(), status.value(), status.getReasonPhrase(),
"Endpoint doesn't exist", path));
"Resource/endpoint doesn't exist", path));
}

/* Gets thrown when the method is not allowed */
@ExceptionHandler(HttpRequestMethodNotSupportedException.class)
public ResponseEntity<ApiErrorReponse> handleMethodNotSupportedException(HttpServletRequest request, Exception ex) {
logError(ex);
Expand All @@ -58,6 +61,7 @@ public ResponseEntity<ApiErrorReponse> handleMethodNotSupportedException(HttpSer
"Method not supported", path));
}

/* Gets thrown when u path variable is of the wrong type */
@ExceptionHandler(MethodArgumentTypeMismatchException.class)
public ResponseEntity<ApiErrorReponse> handleMethodArgumentTypeMismatchException(HttpServletRequest request, Exception ex) {
logError(ex);
Expand All @@ -67,6 +71,7 @@ public ResponseEntity<ApiErrorReponse> handleMethodArgumentTypeMismatchException
"Invalid url argument type", path));
}

/* Gets thrown when an unexpected error occurs */
@ExceptionHandler(Exception.class)
public ResponseEntity<ApiErrorReponse> handleException(HttpServletRequest request, Exception ex) {
logError(ex);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public boolean preHandle(HttpServletRequest request, HttpServletResponse respons
userEntity = new UserEntity(auth.getUser().firstName,auth.getUser().lastName, auth.getEmail(), UserRole.student, auth.getOid());
OffsetDateTime now = OffsetDateTime.now();
userEntity.setCreatedAt(now);
userRepository.save(userEntity);
userEntity = userRepository.save(userEntity);
System.out.println("User created with id: " + userEntity.getId());

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
public final class ApiRoutes {
public static final String USERS_BASE_PATH = "/api/users";
public static final String COURSE_BASE_PATH = "/api/courses";
public static final String DEADLINE_BASE_PATH = "/api/deadlines";
public static final String PROJECT_BASE_PATH = "/api/projects";

public static final String LOGGEDIN_USER_PATH = "/api/user";
Expand All @@ -14,10 +13,4 @@ public final class ApiRoutes {
public static final String GROUP_MEMBER_BASE_PATH = GROUP_BASE_PATH + "/{groupid}/members";
public static final String GROUP_FEEDBACK_PATH = PROJECT_BASE_PATH + "/{projectid}/groups/{groupid}/score";
public static final String CLUSTER_BASE_PATH = "/api/clusters";

public static final String USER_AUTH_PATH = "/api/auth";

public static final String GROUP_SCORE_PATH = GROUP_BASE_PATH + "/{groupid}/score";


}
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ public ResponseEntity<?> doGroupClusterUpdate(GroupClusterEntity clusterEntity,
}
clusterEntity.setMaxSize(clusterJson.getCapacity());
clusterEntity.setName(clusterJson.getName());
groupClusterRepository.save(clusterEntity);
clusterEntity = groupClusterRepository.save(clusterEntity);
return ResponseEntity.ok(entityToJsonConverter.clusterEntityToClusterJson(clusterEntity));
}

Expand All @@ -183,7 +183,7 @@ public ResponseEntity<?> doGroupClusterUpdate(GroupClusterEntity clusterEntity,
*
* @param clusterid identifier of a cluster
* @param auth authentication object of the requesting user
* @param clusterFillJson ClusterFillJson object containing a map of all groups and their
* @param clusterFillMap Map object containing a map of all groups and their
* members of that cluster
* @return ResponseEntity<?>
* @HttpMethod PUT
Expand Down Expand Up @@ -226,7 +226,7 @@ public ResponseEntity<?> fillCluster(@PathVariable("clusterid") Long clusterid,

groupCluster.setGroupAmount(clusterFillJson.getClusterGroupMembers().size());
groupClusterRepository.save(groupCluster);
return ResponseEntity.status(HttpStatus.OK).body("Filled group cluster successfully");
return ResponseEntity.status(HttpStatus.OK).body(entityToJsonConverter.clusterEntityToClusterJson(groupCluster));
} catch (Exception e) {
Logger.getGlobal().severe(e.getMessage());
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Something went wrong");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import com.ugent.pidgeon.postgre.models.types.UserRole;
import com.ugent.pidgeon.postgre.repository.*;
import com.ugent.pidgeon.util.*;
import jakarta.validation.constraints.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
Expand Down Expand Up @@ -59,14 +60,14 @@ public class CourseController {
public ResponseEntity<?> getUserCourses(Auth auth, @RequestParam(value = "archived", required = false) Boolean archived) {
long userID = auth.getUserEntity().getId();
try {
Logger.getGlobal().info("Archived: " + archived);
List<UserRepository.CourseIdWithRelation> userCourses = new ArrayList<>();
if (archived == null || !archived) {
userCourses.addAll(userRepository.findCourseIdsByUserId(userID));
}
if (archived == null || archived) {
userCourses.addAll(userRepository.findArchivedCoursesByUserId(userID));
}

// Retrieve course entities based on user courses
List<CourseWithRelationJson> courseJSONObjects = userCourses.stream()
.map(courseWithRelation -> {
Expand All @@ -79,7 +80,10 @@ public ResponseEntity<?> getUserCourses(Auth auth, @RequestParam(value = "archiv
)
.filter(Objects::nonNull)
.toList();
for (CourseWithRelationJson courseJson: courseJSONObjects) {
Logger.getGlobal().info("UserCourses: " + courseJson);

}
// Return the JSON string in ResponseEntity
return ResponseEntity.ok(courseJSONObjects);
} catch (Exception e) {
Expand Down Expand Up @@ -117,7 +121,7 @@ public ResponseEntity<?> createCourse(@RequestBody CourseJson courseJson, Auth a
courseEntity.setCreatedAt(currentTimestamp);
courseEntity.setJoinKey(UUID.randomUUID().toString());
// Save course
courseRepository.save(courseEntity);
courseEntity = courseRepository.save(courseEntity);

// Add user as course creator
CourseUserEntity courseUserEntity = new CourseUserEntity(courseEntity.getId(), userId, CourseRelation.creator);
Expand Down Expand Up @@ -147,7 +151,7 @@ private ResponseEntity<?> doCourseUpdate(CourseEntity courseEntity, CourseJson c
if (courseJson.getArchived() != null) {
courseEntity.setArchivedAt(courseJson.getArchived() ? OffsetDateTime.now() : null);
}
courseRepository.save(courseEntity);
courseEntity = courseRepository.save(courseEntity);
return ResponseEntity.ok(entityToJsonConverter.courseEntityToCourseWithInfo(courseEntity, courseUtil.getJoinLink(courseEntity.getJoinKey(), "" + courseEntity.getId()), false));
}

Expand Down Expand Up @@ -192,10 +196,6 @@ public ResponseEntity<?> patchCourse(@RequestBody CourseJson courseJson, @PathVa
return ResponseEntity.status(checkResult.getStatus()).body(checkResult.getMessage());
}

if (courseJson.getName() == null && courseJson.getDescription() == null && courseJson.getYear() == null) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Name, description or year is required");
}

CourseEntity courseEntity = checkResult.getData();
if (courseJson.getName() == null) {
courseJson.setName(courseEntity.getName());
Expand Down Expand Up @@ -281,9 +281,9 @@ public ResponseEntity<?> deleteCourse(@PathVariable long courseId, Auth auth) {
}
}


Iterable<CourseUserEntity> courseUsers = courseUserRepository.findAllUsersByCourseId(courseId);
// Delete all courseusers linked to the course
courseUserRepository.deleteAll(courseUserRepository.findAllUsersByCourseId(courseId));
courseUserRepository.deleteAll(courseUsers);

// Delete the course
courseRepository.deleteById(courseId);
Expand Down Expand Up @@ -390,7 +390,7 @@ public ResponseEntity<?> joinCourse(Auth auth, @PathVariable Long courseId, @Pat
*/
@GetMapping(ApiRoutes.COURSE_BASE_PATH + "/{courseId}/join/{courseKey}")
@Roles({UserRole.student, UserRole.teacher})
public ResponseEntity<?> getCourseJoinKey(Auth auth, @PathVariable Long courseId, @PathVariable String courseKey) {
public ResponseEntity<?> getCourseJoinInformation(Auth auth, @PathVariable Long courseId, @PathVariable String courseKey) {
return getJoinLinkGetResponseEntity(courseId, courseKey, auth.getUserEntity());
}

Expand Down Expand Up @@ -424,7 +424,7 @@ public ResponseEntity<?> joinCourse(Auth auth, @PathVariable Long courseId) {
*/
@GetMapping(ApiRoutes.COURSE_BASE_PATH + "/{courseId}/join")
@Roles({UserRole.student, UserRole.teacher})
public ResponseEntity<?> getCourseJoinKey(Auth auth, @PathVariable Long courseId) {
public ResponseEntity<?> getCourseJoinInformation(Auth auth, @PathVariable Long courseId) {
return getJoinLinkGetResponseEntity(courseId, null, auth.getUserEntity());
}

Expand All @@ -445,20 +445,7 @@ public ResponseEntity<?> leaveCourse(@PathVariable long courseId, Auth auth) {
try {
long userId = auth.getUserEntity().getId();
CheckResult<CourseRelation> checkResult = courseUtil.canLeaveCourse(courseId, auth.getUserEntity());
if (!checkResult.getStatus().equals(HttpStatus.OK)) {
return ResponseEntity.status(checkResult.getStatus()).body(checkResult.getMessage());
}
CourseRelation userRelation = checkResult.getData();

// Delete the user from the course
courseUserRepository.deleteById(new CourseUserId(courseId, userId));
if (userRelation.equals(CourseRelation.enrolled)) {
if (!commonDatabaseActions.removeIndividualClusterGroup(courseId, userId)) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Failed to remove user from individual group, contact admin.");
}
}

return ResponseEntity.ok().build();
return doRemoveFromCourse(courseId, userId, checkResult);
} catch (Exception e) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
}
Expand All @@ -480,6 +467,14 @@ public ResponseEntity<?> leaveCourse(@PathVariable long courseId, Auth auth) {
@Roles({UserRole.teacher, UserRole.admin, UserRole.student})
public ResponseEntity<?> removeCourseMember(Auth auth, @PathVariable Long courseId, @PathVariable Long userId) {
CheckResult<CourseRelation> checkResult = courseUtil.canDeleteUser(courseId, userId, auth.getUserEntity());
return doRemoveFromCourse(courseId, userId, checkResult);
}

@NotNull
private ResponseEntity<?> doRemoveFromCourse(
Long courseId,
Long userId,
CheckResult<CourseRelation> checkResult) {
if (!checkResult.getStatus().equals(HttpStatus.OK)) {
return ResponseEntity.status(checkResult.getStatus()).body(checkResult.getMessage());
}
Expand Down Expand Up @@ -562,7 +557,9 @@ public ResponseEntity<?> updateCourseMember(Auth auth, @PathVariable Long course
if (user == null) {
return ResponseEntity.status(HttpStatus.NOT_FOUND).body("User not found");
}
commonDatabaseActions.createNewIndividualClusterGroup(courseId, user);
if (!commonDatabaseActions.createNewIndividualClusterGroup(courseId, user)) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Failed to add user to individual group, contact admin.");
}
} else if (courseUserEntity.getRelation().equals(CourseRelation.enrolled)){
if (!commonDatabaseActions.removeIndividualClusterGroup(courseId, requestwithid.getUserId())) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Failed to remove user from individual group, contact admin.");
Expand Down Expand Up @@ -697,9 +694,12 @@ public ResponseEntity<?> copyCourse(@PathVariable long courseId, Auth auth) {
CourseEntity course = checkResult.getData().getFirst();

CheckResult<CourseEntity> copyCheckRes = commonDatabaseActions.copyCourse(course, auth.getUserEntity().getId());
if (copyCheckRes.getStatus() != HttpStatus.OK) {
return ResponseEntity.status(copyCheckRes.getStatus()).body(copyCheckRes.getMessage());
}
CourseEntity newCourse = copyCheckRes.getData();

return ResponseEntity.ok(entityToJsonConverter.courseEntityToCourseWithInfo(newCourse, courseUtil.getJoinLink(newCourse.getJoinKey(), "" + newCourse.getId()), false));
return ResponseEntity.status(HttpStatus.CREATED).body(entityToJsonConverter.courseEntityToCourseWithInfo(newCourse, courseUtil.getJoinLink(newCourse.getJoinKey(), "" + newCourse.getId()), false));
} catch (Exception e) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,9 @@ public ResponseEntity<?> deleteGroup(@PathVariable("groupid") Long groupid, Auth
return ResponseEntity.status(checkResult.getStatus()).body(checkResult.getMessage());
}

commonDatabaseActions.removeGroup(groupid);
if (!commonDatabaseActions.removeGroup(groupid)) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Error deleting group");
}
// Return 204
return ResponseEntity.status(HttpStatus.NO_CONTENT).body("Group deleted");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,12 @@ public class GroupFeedbackController {
private GroupUtil groupUtil;
@Autowired
private EntityToJsonConverter entityToJsonConverter;
@Autowired
private ProjectRepository projectRepository;
@Autowired
private GroupRepository groupRepository;
@Autowired
private CourseUtil courseUtil;
@Autowired
private ProjectRepository projectRepository;
@Autowired
private GroupRepository groupRepository;
@Autowired
private CourseUtil courseUtil;

/**
* Function to update the score of a group
Expand Down Expand Up @@ -222,19 +222,19 @@ public ResponseEntity<?> getCourseGrades(@PathVariable("courseId") long courseId

List<GroupFeedbackJsonWithProject> grades = new ArrayList<>();
for (ProjectEntity project : projects) {
Long GroupId = groupRepository.groupIdByProjectAndUser(project.getId(), user.getId());
if (GroupId == null) { // Student not yet in a group for this project
Long groupId = groupRepository.groupIdByProjectAndUser(project.getId(), user.getId());
if (groupId == null) { // Student not yet in a group for this project
grades.add(entityToJsonConverter.groupFeedbackEntityToJsonWithProject(null, project));
}
CheckResult<GroupFeedbackEntity> checkResult = groupFeedbackUtil.getGroupFeedbackIfExists(GroupId, project.getId());
if (checkResult.getStatus() != HttpStatus.OK) {
grades.add(entityToJsonConverter.groupFeedbackEntityToJsonWithProject(null, project));
} else {
CheckResult<GroupFeedbackEntity> checkResult = groupFeedbackUtil.getGroupFeedbackIfExists(groupId, project.getId());
if (checkResult.getStatus() != HttpStatus.OK) {
grades.add(entityToJsonConverter.groupFeedbackEntityToJsonWithProject(null, project));
} else {
GroupFeedbackEntity groupFeedbackEntity = checkResult.getData();
grades.add(entityToJsonConverter.groupFeedbackEntityToJsonWithProject(groupFeedbackEntity, project));
}
}
}

return ResponseEntity.ok(grades);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ public ResponseEntity<?> getProjects(Auth auth) {
}
}

return ResponseEntity.ok().body(new userProjectsJson(enrolledProjects, adminProjects));
return ResponseEntity.ok().body(new UserProjectsJson(enrolledProjects, adminProjects));
}


Expand Down
Loading
Loading