Skip to content

Commit

Permalink
improve test coverage
Browse files Browse the repository at this point in the history
  • Loading branch information
SimonEntholzer committed Oct 18, 2024
1 parent ecd4138 commit f3aa1b8
Show file tree
Hide file tree
Showing 3 changed files with 197 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.argThat;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.reset;
Expand All @@ -21,6 +22,8 @@
import org.apache.commons.io.FileUtils;
import org.eclipse.jgit.api.ListBranchCommand;
import org.eclipse.jgit.api.MergeResult;
import org.eclipse.jgit.api.errors.TransportException;
import org.eclipse.jgit.api.errors.WrongRepositoryStateException;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.merge.MergeStrategy;
import org.junit.jupiter.api.AfterEach;
Expand Down Expand Up @@ -76,6 +79,8 @@ class AuxiliaryRepositoryResourceIntegrationTest extends AbstractSpringIntegrati

private final LocalRepository localAuxiliaryRepo = new LocalRepository(defaultBranch);

private GitUtilService.MockFileRepositoryUri auxRepoUri;

@BeforeEach
void setup() throws Exception {
userUtilService.addUsers(TEST_PREFIX, 1, 1, 0, 1);
Expand All @@ -98,7 +103,7 @@ void setup() throws Exception {

// add the auxiliary repository
auxiliaryRepositoryRepository.deleteAll();
var auxRepoUri = new GitUtilService.MockFileRepositoryUri(localAuxiliaryRepo.localRepoFile);
auxRepoUri = new GitUtilService.MockFileRepositoryUri(localAuxiliaryRepo.localRepoFile);
programmingExercise.setTestRepositoryUri(auxRepoUri.toString());
var newAuxiliaryRepo = new AuxiliaryRepository();
newAuxiliaryRepo.setName("AuxiliaryRepo");
Expand Down Expand Up @@ -147,6 +152,15 @@ void testGetFilesAsStudent_accessForbidden() throws Exception {
request.getMap(testRepoBaseUrl + auxiliaryRepository.getId() + "/files", HttpStatus.FORBIDDEN, String.class, FileType.class);
}

@Test
@WithMockUser(username = TEST_PREFIX + "instructor1", roles = "INSTRUCTOR")
void testGetFilesAsInstructor_checkoutConflict() throws Exception {
programmingExerciseRepository.save(programmingExercise);
doThrow(new WrongRepositoryStateException("conflict")).when(gitService).getOrCheckoutRepository(auxRepoUri, true);

request.getMap(testRepoBaseUrl + auxiliaryRepository.getId() + "/files", HttpStatus.CONFLICT, String.class, FileType.class);
}

@Test
@WithMockUser(username = TEST_PREFIX + "instructor1", roles = "INSTRUCTOR")
void testGetFile() throws Exception {
Expand Down Expand Up @@ -395,6 +409,24 @@ void testSaveFiles_accessForbidden() throws Exception {
request.put(testRepoBaseUrl + auxiliaryRepository.getId() + "/files?commit=true", List.of(), HttpStatus.FORBIDDEN);
}

@Test
@WithMockUser(username = TEST_PREFIX + "instructor1", roles = "INSTRUCTOR")
void testSaveFiles_conflict() throws Exception {
programmingExerciseRepository.save(programmingExercise);
doThrow(new WrongRepositoryStateException("conflict")).when(gitService).getOrCheckoutRepository(auxRepoUri, true);

request.put(testRepoBaseUrl + auxiliaryRepository.getId() + "/files?commit=true", List.of(), HttpStatus.CONFLICT);
}

@Test
@WithMockUser(username = TEST_PREFIX + "instructor1", roles = "INSTRUCTOR")
void testSaveFiles_serviceUnavailable() throws Exception {
programmingExerciseRepository.save(programmingExercise);
doThrow(new TransportException("unavailable")).when(gitService).getOrCheckoutRepository(auxRepoUri, true);

request.put(testRepoBaseUrl + auxiliaryRepository.getId() + "/files?commit=true", List.of(), HttpStatus.SERVICE_UNAVAILABLE);
}

@Test
@WithMockUser(username = TEST_PREFIX + "instructor1", roles = "INSTRUCTOR")
void testPullChanges() throws Exception {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2188,6 +2188,14 @@ private AuxiliaryRepository addAuxiliaryRepositoryToExercise() {
return repository;
}

public void addAuxiliaryRepositoryToExercise(ProgrammingExercise exercise) {
AuxiliaryRepository repository = AuxiliaryRepositoryBuilder.defaults().get();
auxiliaryRepositoryRepository.save(repository);
exercise.setAuxiliaryRepositories(new ArrayList<>());
exercise.addAuxiliaryRepository(repository);
programmingExerciseRepository.save(exercise);
}

private String defaultAuxiliaryRepositoryEndpoint() {
return "/api/programming-exercises/setup";
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,24 @@
package de.tum.cit.aet.artemis.programming;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.doThrow;

import java.io.IOException;
import java.net.URISyntaxException;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Stream;

import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.api.errors.NoHeadException;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
Expand All @@ -35,11 +41,15 @@
import de.tum.cit.aet.artemis.exercise.test_repository.ParticipationTestRepository;
import de.tum.cit.aet.artemis.exercise.test_repository.StudentParticipationTestRepository;
import de.tum.cit.aet.artemis.programming.domain.ProgrammingExercise;
import de.tum.cit.aet.artemis.programming.domain.ProgrammingExerciseParticipation;
import de.tum.cit.aet.artemis.programming.domain.ProgrammingExerciseStudentParticipation;
import de.tum.cit.aet.artemis.programming.domain.ProgrammingSubmission;
import de.tum.cit.aet.artemis.programming.domain.Repository;
import de.tum.cit.aet.artemis.programming.domain.SolutionProgrammingExerciseParticipation;
import de.tum.cit.aet.artemis.programming.domain.TemplateProgrammingExerciseParticipation;
import de.tum.cit.aet.artemis.programming.domain.VcsRepositoryUri;
import de.tum.cit.aet.artemis.programming.dto.CommitInfoDTO;
import de.tum.cit.aet.artemis.programming.repository.AuxiliaryRepositoryRepository;
import de.tum.cit.aet.artemis.programming.test_repository.ProgrammingExerciseStudentParticipationTestRepository;
import de.tum.cit.aet.artemis.programming.test_repository.ProgrammingExerciseTestRepository;
import de.tum.cit.aet.artemis.programming.util.ProgrammingExerciseUtilService;
Expand Down Expand Up @@ -71,6 +81,13 @@ class ProgrammingExerciseParticipationIntegrationTest extends AbstractSpringInte
@Autowired
private ParticipationUtilService participationUtilService;

@Autowired
private AuxiliaryRepositoryRepository auxiliaryRepositoryRepository;

// TODO remove again after refactoring and cleanup
@Autowired
private ProgrammingExerciseIntegrationTestService programmingExerciseIntegrationTestService;

private ProgrammingExercise programmingExercise;

private Participation programmingExerciseParticipation;
Expand All @@ -81,6 +98,7 @@ void initTestCase() {
var course = programmingExerciseUtilService.addCourseWithOneProgrammingExerciseAndTestCases();
programmingExercise = exerciseUtilService.getFirstExerciseWithType(course, ProgrammingExercise.class);
programmingExercise = programmingExerciseRepository.findWithEagerStudentParticipationsById(programmingExercise.getId()).orElseThrow();
programmingExerciseIntegrationTestService.addAuxiliaryRepositoryToExercise(programmingExercise);
}

private static Stream<Arguments> argumentsForGetParticipationResults() {
Expand Down Expand Up @@ -704,6 +722,144 @@ void checkResetRepository_exam_badRequest() throws Exception {
request.put("/api/programming-exercise-participations/" + programmingExerciseParticipation.getId() + "/reset-repository", null, HttpStatus.BAD_REQUEST);
}

/**
* TODO move the following test into a different test file, as they do not use the programming-exercise-participations/.. endpoint, but programming-exercise/..
* move the endpoint itself too
* <p>
* Test for GET - programming-exercise/{exerciseID}/commit-history/{repositoryType}
*/
@Nested
class GetCommitHistoryForTemplateSolutionTestOrAuxRepo {

String PATH_PREFIX;

ProgrammingExercise programmingExerciseWithAuxRepo;

@BeforeEach
void setup() throws GitAPIException {
userUtilService.addUsers(TEST_PREFIX, 4, 2, 0, 2);
var course = programmingExerciseUtilService.addCourseWithOneProgrammingExerciseAndTestCases();
programmingExerciseWithAuxRepo = exerciseUtilService.getFirstExerciseWithType(course, ProgrammingExercise.class);
programmingExerciseWithAuxRepo = programmingExerciseRepository.findWithEagerStudentParticipationsById(programmingExerciseWithAuxRepo.getId()).orElseThrow();
programmingExerciseIntegrationTestService.addAuxiliaryRepositoryToExercise(programmingExerciseWithAuxRepo);

doThrow(new NoHeadException("error")).when(gitService).getCommitInfos(any());
PATH_PREFIX = "/api/programming-exercise/" + programmingExerciseWithAuxRepo.getId() + "/commit-history/";
}

@Test
@WithMockUser(username = TEST_PREFIX + "instructor1", roles = "INSTRUCTOR")
void shouldReturnBadRequestForInvalidRepositoryType() throws Exception {
request.getList(PATH_PREFIX + "INVALIDTYPE", HttpStatus.BAD_REQUEST, CommitInfoDTO.class);
}

@Test
@WithMockUser(username = TEST_PREFIX + "instructor1", roles = "INSTRUCTOR")
void shouldGetListForTemplateRepository() throws Exception {
assertThat(request.getList(PATH_PREFIX + "TEMPLATE", HttpStatus.OK, CommitInfoDTO.class)).isEmpty();
}

@Test
@WithMockUser(username = TEST_PREFIX + "instructor1", roles = "INSTRUCTOR")
void shouldGetListForSolutionRepository() throws Exception {
assertThat(request.getList(PATH_PREFIX + "SOLUTION", HttpStatus.OK, CommitInfoDTO.class)).isEmpty();
}

@Test
@WithMockUser(username = TEST_PREFIX + "instructor1", roles = "INSTRUCTOR")
void shouldGetListForTestsRepository() throws Exception {
assertThat(request.getList(PATH_PREFIX + "TESTS", HttpStatus.OK, CommitInfoDTO.class)).isEmpty();
}

@Test
@WithMockUser(username = TEST_PREFIX + "instructor1", roles = "INSTRUCTOR")
void shouldGetListForAuxiliaryRepository() throws Exception {
assertThat(request.getList(PATH_PREFIX + "AUXILIARY?repositoryId=" + programmingExerciseWithAuxRepo.getAuxiliaryRepositories().getFirst().getId(), HttpStatus.OK,
CommitInfoDTO.class)).isEmpty();
}

@Test
@WithMockUser(username = TEST_PREFIX + "instructor1", roles = "INSTRUCTOR")
void shouldThrowWithInvalidAuxiliaryRepositoryId() throws Exception {
request.getList(PATH_PREFIX + "AUXILIARY?repositoryId=" + 128, HttpStatus.NOT_FOUND, CommitInfoDTO.class);
}
}

/**
* Tests for programming-exercise-participations/{participationId}/files-content/{commitId}
*/
@Test
@WithMockUser(username = TEST_PREFIX + "instructor1", roles = "INSTRUCTOR")
void getParticipationRepositoryFilesInstructorSuccess() throws Exception {
var commitHash = "commitHash";
var participation = participationUtilService.addStudentParticipationForProgrammingExercise(programmingExercise, TEST_PREFIX + "student1");
var commitInfo = new CommitInfoDTO("hash", "msg1", ZonedDateTime.of(2020, 1, 1, 0, 0, 0, 0, ZoneId.of("UTC")), "author", "authorEmail");
var commitInfo2 = new CommitInfoDTO("hash2", "msg2", ZonedDateTime.of(2020, 1, 2, 0, 0, 0, 0, ZoneId.of("UTC")), "author2", "authorEmail2");
doReturn(List.of(commitInfo, commitInfo2)).when(gitService).getCommitInfos(participation.getVcsRepositoryUri());
doReturn(new Repository("ab", new VcsRepositoryUri("uri"))).when(gitService).checkoutRepositoryAtCommit(participation.getVcsRepositoryUri(), commitHash, true);
doReturn(Map.of()).when(gitService).listFilesAndFolders(any());
doNothing().when(gitService).switchBackToDefaultBranchHead(any());

request.getMap("/api/programming-exercise-participations/" + participation.getId() + "/files-content/" + commitHash, HttpStatus.OK, String.class, String.class);
}

/**
* TODO refactor endpoint to contain participation -> programming-exercise-participations
* tests GET - programming-exercise/{exerciseId}/files-content-commit-details/{commitId}
*/
@Nested
class GetParticipationRepositoryFilesForCommitsDetailsView {

String PATH_PREFIX;

String COMMIT_HASH;

ProgrammingExerciseParticipation participation;

@BeforeEach
void setup() throws GitAPIException, URISyntaxException, IOException {
userUtilService.addUsers(TEST_PREFIX, 4, 2, 0, 2);
participation = participationUtilService.addStudentParticipationForProgrammingExercise(programmingExercise, TEST_PREFIX + "student1");
var course = programmingExerciseUtilService.addCourseWithOneProgrammingExerciseAndTestCases();
programmingExercise = exerciseUtilService.getFirstExerciseWithType(course, ProgrammingExercise.class);
programmingExercise = programmingExerciseRepository.findWithEagerStudentParticipationsById(programmingExercise.getId()).orElseThrow();
programmingExerciseIntegrationTestService.addAuxiliaryRepositoryToExercise(programmingExercise);
COMMIT_HASH = "commitHash";

doReturn(Map.of()).when(gitService).listFilesAndFolders(any());
doNothing().when(gitService).switchBackToDefaultBranchHead(any());
doReturn(new Repository("ab", new VcsRepositoryUri("uri"))).when(gitService).checkoutRepositoryAtCommit(any(VcsRepositoryUri.class), any(String.class),
any(Boolean.class));
doThrow(new NoHeadException("error")).when(gitService).getCommitInfos(any());
PATH_PREFIX = "/api/programming-exercise/" + participation.getProgrammingExercise().getId() + "/files-content-commit-details/" + COMMIT_HASH;
}

@Test
@WithMockUser(username = TEST_PREFIX + "instructor1", roles = "INSTRUCTOR")
void shouldReturnBadRequestWithoutAnyProvidedParameters() throws Exception {
request.getMap(PATH_PREFIX, HttpStatus.BAD_REQUEST, String.class, String.class);
}

@Test
@WithMockUser(username = TEST_PREFIX + "instructor1", roles = "INSTRUCTOR")
void shouldReturnForParticipation() throws Exception {
assertThat(request.getMap(PATH_PREFIX + "?participationId=" + participation.getId(), HttpStatus.OK, String.class, String.class)).isEmpty();
}

@Test
@WithMockUser(username = TEST_PREFIX + "instructor1", roles = "INSTRUCTOR")
void shouldReturnFilesForTemplateRepository() throws Exception {
assertThat(request.getMap(PATH_PREFIX + "?repositoryType=TEMPLATE", HttpStatus.OK, String.class, String.class)).isEmpty();
}

@Test
@WithMockUser(username = TEST_PREFIX + "instructor1", roles = "INSTRUCTOR")
void shouldReturnFilesForSolutionRepository() throws Exception {
assertThat(request.getMap(PATH_PREFIX + "?repositoryType=SOLUTION", HttpStatus.OK, String.class, String.class)).isEmpty();
}

}

@Test
@WithMockUser(username = TEST_PREFIX + "instructor1", roles = "INSTRUCTOR")
void retrieveCommitInfoInstructorSuccess() throws Exception {
Expand Down

0 comments on commit f3aa1b8

Please sign in to comment.