Search in sources :

Example 6 with StudentParticipation

use of de.tum.in.www1.artemis.domain.participation.StudentParticipation in project Artemis by ls1intum.

the class ProgrammingSubmissionIntegrationTest method triggerFailedBuildEmptyLatestPendingSubmission.

@Test
@WithMockUser(username = "student1", roles = "USER")
void triggerFailedBuildEmptyLatestPendingSubmission() throws Exception {
    bambooRequestMockProvider.enableMockingOfRequests();
    doReturn(COMMIT_HASH_OBJECT_ID).when(gitService).getLastCommitHash(any());
    String login = "student1";
    StudentParticipation participation = database.addStudentParticipationForProgrammingExercise(exercise, login);
    bambooRequestMockProvider.mockTriggerBuild((ProgrammingExerciseParticipation) participation);
    doReturn(Optional.empty()).when(programmingSubmissionService).getLatestPendingSubmission(anyLong(), anyBoolean());
    String url = "/api/programming-submissions/" + participation.getId() + "/trigger-failed-build";
    request.postWithoutLocation(url, null, HttpStatus.NOT_FOUND, new HttpHeaders());
}
Also used : HttpHeaders(org.springframework.http.HttpHeaders) ProgrammingExerciseStudentParticipation(de.tum.in.www1.artemis.domain.participation.ProgrammingExerciseStudentParticipation) StudentParticipation(de.tum.in.www1.artemis.domain.participation.StudentParticipation) WithMockUser(org.springframework.security.test.context.support.WithMockUser) AbstractSpringIntegrationBambooBitbucketJiraTest(de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest) Test(org.junit.jupiter.api.Test) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest)

Example 7 with StudentParticipation

use of de.tum.in.www1.artemis.domain.participation.StudentParticipation in project Artemis by ls1intum.

the class ProgrammingSubmissionIntegrationTest method triggerBuildInstructorTutorForbidden.

@Test
@WithMockUser(username = "tutor1", roles = "TA")
void triggerBuildInstructorTutorForbidden() throws Exception {
    String login = "student1";
    StudentParticipation participation = database.addStudentParticipationForProgrammingExercise(exercise, login);
    String url = "/api/programming-submissions/" + participation.getId() + "/trigger-build?submissionType=INSTRUCTOR";
    request.postWithoutLocation(url, null, HttpStatus.FORBIDDEN, new HttpHeaders());
}
Also used : HttpHeaders(org.springframework.http.HttpHeaders) ProgrammingExerciseStudentParticipation(de.tum.in.www1.artemis.domain.participation.ProgrammingExerciseStudentParticipation) StudentParticipation(de.tum.in.www1.artemis.domain.participation.StudentParticipation) WithMockUser(org.springframework.security.test.context.support.WithMockUser) AbstractSpringIntegrationBambooBitbucketJiraTest(de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest) Test(org.junit.jupiter.api.Test) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest)

Example 8 with StudentParticipation

use of de.tum.in.www1.artemis.domain.participation.StudentParticipation in project Artemis by ls1intum.

the class AssessmentService method cancelAssessmentOfSubmission.

/**
 * Cancel an assessment of a given submission for the current user, i.e. delete the corresponding result / release the lock. Then the submission is available for assessment
 * again.
 *
 * @param submission the submission for which the current assessment should be canceled
 */
// NOTE: As we use delete methods with underscores, we need a transactional context here!
@Transactional
public void cancelAssessmentOfSubmission(Submission submission) {
    StudentParticipation participation = studentParticipationRepository.findWithEagerResultsById(submission.getParticipation().getId()).orElseThrow(() -> new BadRequestAlertException("Participation could not be found", "participation", "notfound"));
    // cancel is only possible for the latest result.
    Result result = submission.getLatestResult();
    // We only want to be able to cancel a result if it is not of the AUTOMATIC AssessmentType
    if (result != null && result.getAssessmentType() != null && result.getAssessmentType() != AssessmentType.AUTOMATIC) {
        participation.removeResult(result);
        feedbackRepository.deleteByResult_Id(result.getId());
        resultRepository.deleteById(result.getId());
    }
}
Also used : BadRequestAlertException(de.tum.in.www1.artemis.web.rest.errors.BadRequestAlertException) StudentParticipation(de.tum.in.www1.artemis.domain.participation.StudentParticipation) Transactional(org.springframework.transaction.annotation.Transactional)

Example 9 with StudentParticipation

use of de.tum.in.www1.artemis.domain.participation.StudentParticipation in project Artemis by ls1intum.

the class ExerciseDeletionService method cleanup.

/**
 * Delete student build plans (except BASE/SOLUTION) and optionally git repositories of all exercise student participations.
 *
 * @param exerciseId         programming exercise for which build plans in respective student participations are deleted
 * @param deleteRepositories if true, the repositories gets deleted
 */
public void cleanup(Long exerciseId, boolean deleteRepositories) {
    Exercise exercise = exerciseRepository.findByIdWithStudentParticipationsElseThrow(exerciseId);
    log.info("Request to cleanup all participations for Exercise : {}", exercise.getTitle());
    if (exercise instanceof ProgrammingExercise) {
        for (StudentParticipation participation : exercise.getStudentParticipations()) {
            participationService.cleanupBuildPlan((ProgrammingExerciseStudentParticipation) participation);
        }
        if (!deleteRepositories) {
            // in this case, we are done
            return;
        }
        for (StudentParticipation participation : exercise.getStudentParticipations()) {
            participationService.cleanupRepository((ProgrammingExerciseStudentParticipation) participation);
        }
    } else {
        log.warn("Exercise with exerciseId {} is not an instance of ProgrammingExercise. Ignoring the request to cleanup repositories and build plan", exerciseId);
    }
}
Also used : QuizExercise(de.tum.in.www1.artemis.domain.quiz.QuizExercise) ProgrammingExercise(de.tum.in.www1.artemis.domain.ProgrammingExercise) TextExercise(de.tum.in.www1.artemis.domain.TextExercise) Exercise(de.tum.in.www1.artemis.domain.Exercise) ModelingExercise(de.tum.in.www1.artemis.domain.modeling.ModelingExercise) ProgrammingExercise(de.tum.in.www1.artemis.domain.ProgrammingExercise) ProgrammingExerciseStudentParticipation(de.tum.in.www1.artemis.domain.participation.ProgrammingExerciseStudentParticipation) StudentParticipation(de.tum.in.www1.artemis.domain.participation.StudentParticipation)

Example 10 with StudentParticipation

use of de.tum.in.www1.artemis.domain.participation.StudentParticipation in project Artemis by ls1intum.

the class ProgrammingExerciseExportService method exportProgrammingExerciseRepositories.

/**
 * Export instructor repositories and optionally students' repositories in a zip file.
 *
 * The outputDir is used to store the zip file and temporary files used for zipping so make
 * sure to delete it if it's no longer used.
 *
 * @param exercise              the programming exercise
 * @param includingStudentRepos flag for including the students repos as well
 * @param outputDir             the path to a directory that will be used to store the zipped programming exercise.
 * @param exportErrors          List of failures that occurred during the export
 * @param reportData            List of all exercises and their statistics
 * @return the path to the zip file
 */
public Path exportProgrammingExerciseRepositories(ProgrammingExercise exercise, Boolean includingStudentRepos, Path outputDir, List<String> exportErrors, List<ArchivalReportEntry> reportData) {
    log.info("Exporting programming exercise {} with title {}", exercise.getId(), exercise.getTitle());
    // List to add paths of files that should be contained in the zip folder of exported programming exercise repositories:
    // i.e., student repositories (if `includingStudentRepos` is true), instructor repositories template, solution and tests
    var pathsToBeZipped = new ArrayList<Path>();
    if (includingStudentRepos) {
        // Lazy load student participation, sort by id, and set the export options
        var studentParticipations = studentParticipationRepository.findByExerciseId(exercise.getId()).stream().map(studentParticipation -> (ProgrammingExerciseStudentParticipation) studentParticipation).sorted(Comparator.comparing(DomainObject::getId)).collect(Collectors.toList());
        var exportOptions = new RepositoryExportOptionsDTO();
        exportOptions.setHideStudentNameInZippedFolder(false);
        // Export student repositories and add them to list
        var exportedStudentRepositoryFiles = exportStudentRepositories(exercise, studentParticipations, exportOptions, outputDir, exportErrors).stream().filter(Objects::nonNull).toList();
        pathsToBeZipped.addAll(exportedStudentRepositoryFiles);
    }
    // Export the template, solution, and tests repositories and add them to list
    pathsToBeZipped.add(exportInstructorRepositoryForExercise(exercise.getId(), RepositoryType.TEMPLATE, outputDir, exportErrors).map(File::toPath).orElse(null));
    pathsToBeZipped.add(exportInstructorRepositoryForExercise(exercise.getId(), RepositoryType.SOLUTION, outputDir, exportErrors).map(File::toPath).orElse(null));
    pathsToBeZipped.add(exportInstructorRepositoryForExercise(exercise.getId(), RepositoryType.TESTS, outputDir, exportErrors).map(File::toPath).orElse(null));
    List<AuxiliaryRepository> auxiliaryRepositories = auxiliaryRepositoryRepository.findByExerciseId(exercise.getId());
    // Export the auxiliary repositories and add them to list
    auxiliaryRepositories.forEach(auxiliaryRepository -> {
        pathsToBeZipped.add(exportInstructorAuxiliaryRepositoryForExercise(exercise.getId(), auxiliaryRepository, outputDir, exportErrors).map(File::toPath).orElse(null));
    });
    // Setup path to store the zip file for the exported repositories
    var timestamp = ZonedDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd-Hmss"));
    String filename = exercise.getCourseViaExerciseGroupOrCourseMember().getShortName() + "-" + exercise.getTitle() + "-" + exercise.getId() + "-" + timestamp + ".zip";
    String cleanFilename = fileService.removeIllegalCharacters(filename);
    Path pathToZippedExercise = Path.of(outputDir.toString(), cleanFilename);
    // Remove null elements and get the file path of each file to be included, i.e. each entry in the pathsToBeZipped list
    List<Path> includedFilePathsNotNull = pathsToBeZipped.stream().filter(Objects::nonNull).collect(Collectors.toList());
    String cleanProjectName = fileService.removeIllegalCharacters(exercise.getProjectName());
    // Add report entry, programming repositories cannot be skipped
    reportData.add(new ArchivalReportEntry(exercise, cleanProjectName, pathsToBeZipped.size(), includedFilePathsNotNull.size(), 0));
    try {
        // Only create zip file if there's files to zip
        if (includedFilePathsNotNull.isEmpty()) {
            String info = "Will not export programming exercise " + exercise.getId() + " with title " + exercise.getTitle() + " because it's empty";
            log.info(info);
            exportErrors.add(info);
            return null;
        }
        // Create the zip folder of the exported programming exercise and return the path to the created folder
        zipFileService.createZipFile(pathToZippedExercise, includedFilePathsNotNull, false);
        return pathToZippedExercise;
    } catch (Exception e) {
        var error = "Failed to export programming exercise because the zip file " + pathToZippedExercise + " could not be created: " + e.getMessage();
        log.info(error);
        exportErrors.add(error);
        return null;
    }
}
Also used : Path(java.nio.file.Path) XPath(javax.xml.xpath.XPath) RepositoryExportOptionsDTO(de.tum.in.www1.artemis.web.rest.dto.RepositoryExportOptionsDTO) ArchivalReportEntry(de.tum.in.www1.artemis.service.archival.ArchivalReportEntry) File(java.io.File) GitException(de.tum.in.www1.artemis.exception.GitException) GitAPIException(org.eclipse.jgit.api.errors.GitAPIException) UncheckedIOException(java.io.UncheckedIOException) SAXException(org.xml.sax.SAXException) TransformerException(javax.xml.transform.TransformerException) XPathException(javax.xml.xpath.XPathException) IOException(java.io.IOException) ParserConfigurationException(javax.xml.parsers.ParserConfigurationException)

Aggregations

StudentParticipation (de.tum.in.www1.artemis.domain.participation.StudentParticipation)217 Test (org.junit.jupiter.api.Test)118 WithMockUser (org.springframework.security.test.context.support.WithMockUser)112 ModelingSubmission (de.tum.in.www1.artemis.domain.modeling.ModelingSubmission)60 ModelingExercise (de.tum.in.www1.artemis.domain.modeling.ModelingExercise)50 ProgrammingExerciseStudentParticipation (de.tum.in.www1.artemis.domain.participation.ProgrammingExerciseStudentParticipation)48 ZonedDateTime (java.time.ZonedDateTime)43 QuizExercise (de.tum.in.www1.artemis.domain.quiz.QuizExercise)40 EntityNotFoundException (de.tum.in.www1.artemis.web.rest.errors.EntityNotFoundException)40 AbstractSpringIntegrationBambooBitbucketJiraTest (de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest)36 ParameterizedTest (org.junit.jupiter.params.ParameterizedTest)36 Exam (de.tum.in.www1.artemis.domain.exam.Exam)30 PreAuthorize (org.springframework.security.access.prepost.PreAuthorize)30 TextPlagiarismResult (de.tum.in.www1.artemis.domain.plagiarism.text.TextPlagiarismResult)28 de.tum.in.www1.artemis.repository (de.tum.in.www1.artemis.repository)27 ModelingPlagiarismResult (de.tum.in.www1.artemis.domain.plagiarism.modeling.ModelingPlagiarismResult)26 de.tum.in.www1.artemis.domain (de.tum.in.www1.artemis.domain)24 StudentExam (de.tum.in.www1.artemis.domain.exam.StudentExam)24 Participation (de.tum.in.www1.artemis.domain.participation.Participation)24 LinkedMultiValueMap (org.springframework.util.LinkedMultiValueMap)24