Search in sources :

Example 1 with CodeHint

use of de.tum.in.www1.artemis.domain.hestia.CodeHint in project Artemis by ls1intum.

the class ExerciseHintResource method deleteExerciseHint.

/**
 * {@code DELETE  exercises/:exerciseId/exercise-hints/:exerciseHintId} : delete the exerciseHint with given id.
 *
 * @param exerciseHintId the id of the exerciseHint to delete
 * @param exerciseId the exercise id of which to delete the exercise hint
 * @return the {@link ResponseEntity} with status {@code 204 (NO_CONTENT)},
 * or with status {@code 400 (Bad Request)} if the exerciseHint is a codeHint,
 * or with status {@code 409 (Conflict)} if the exerciseId is not valid.
 */
@DeleteMapping("exercises/{exerciseId}/exercise-hints/{exerciseHintId}")
@PreAuthorize("hasRole('EDITOR')")
public ResponseEntity<Void> deleteExerciseHint(@PathVariable Long exerciseId, @PathVariable Long exerciseHintId) {
    log.debug("REST request to delete ExerciseHint : {}", exerciseHintId);
    ProgrammingExercise exercise = programmingExerciseRepository.findByIdElseThrow(exerciseId);
    authCheckService.checkHasAtLeastRoleForExerciseElseThrow(Role.EDITOR, exercise, null);
    var exerciseHint = exerciseHintRepository.findByIdElseThrow(exerciseHintId);
    if (exerciseHint instanceof CodeHint) {
        throw new BadRequestAlertException("A code hint cannot be deleted manually.", CODE_HINT_ENTITY_NAME, "manualCodeHintOperation");
    }
    if (!exerciseHint.getExercise().getId().equals(exerciseId)) {
        throw new ConflictException("An exercise hint can only be deleted if the exerciseIds match.", EXERCISE_HINT_ENTITY_NAME, "exerciseIdsMismatch");
    }
    exerciseHintRepository.deleteById(exerciseHintId);
    return ResponseEntity.noContent().headers(HeaderUtil.createEntityDeletionAlert(applicationName, true, EXERCISE_HINT_ENTITY_NAME, exerciseHintId.toString())).build();
}
Also used : BadRequestAlertException(de.tum.in.www1.artemis.web.rest.errors.BadRequestAlertException) ConflictException(de.tum.in.www1.artemis.web.rest.errors.ConflictException) ProgrammingExercise(de.tum.in.www1.artemis.domain.ProgrammingExercise) CodeHint(de.tum.in.www1.artemis.domain.hestia.CodeHint) PreAuthorize(org.springframework.security.access.prepost.PreAuthorize)

Example 2 with CodeHint

use of de.tum.in.www1.artemis.domain.hestia.CodeHint in project Artemis by ls1intum.

the class ExerciseHintIntegrationTest method updateCodeHintShouldFail.

@Test
@WithMockUser(username = "instructor1", roles = "INSTRUCTOR")
public void updateCodeHintShouldFail() throws Exception {
    CodeHint codeHint = new CodeHint();
    codeHint.setTitle("Hint 1");
    codeHint.setExercise(exercise);
    exerciseHintRepository.save(codeHint);
    codeHint.setTitle("New Title");
    request.put("/api/exercises/" + codeHint.getExercise().getId() + "/exercise-hints/" + codeHint.getId(), codeHint, HttpStatus.BAD_REQUEST);
    Optional<ExerciseHint> hintAfterSave = exerciseHintRepository.findById(codeHint.getId());
    assertThat(hintAfterSave).isPresent();
    assertThat(hintAfterSave.get()).isInstanceOf(CodeHint.class);
    assertThat((hintAfterSave.get()).getTitle()).isEqualTo("Hint 1");
}
Also used : ExerciseHint(de.tum.in.www1.artemis.domain.hestia.ExerciseHint) CodeHint(de.tum.in.www1.artemis.domain.hestia.CodeHint) WithMockUser(org.springframework.security.test.context.support.WithMockUser) Test(org.junit.jupiter.api.Test) AbstractSpringIntegrationBambooBitbucketJiraTest(de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest)

Example 3 with CodeHint

use of de.tum.in.www1.artemis.domain.hestia.CodeHint in project ArTEMiS by ls1intum.

the class ExerciseHintResource method deleteExerciseHint.

/**
 * {@code DELETE  exercises/:exerciseId/exercise-hints/:exerciseHintId} : delete the exerciseHint with given id.
 *
 * @param exerciseHintId the id of the exerciseHint to delete
 * @param exerciseId the exercise id of which to delete the exercise hint
 * @return the {@link ResponseEntity} with status {@code 204 (NO_CONTENT)},
 * or with status {@code 400 (Bad Request)} if the exerciseHint is a codeHint,
 * or with status {@code 409 (Conflict)} if the exerciseId is not valid.
 */
@DeleteMapping("exercises/{exerciseId}/exercise-hints/{exerciseHintId}")
@PreAuthorize("hasRole('EDITOR')")
public ResponseEntity<Void> deleteExerciseHint(@PathVariable Long exerciseId, @PathVariable Long exerciseHintId) {
    log.debug("REST request to delete ExerciseHint : {}", exerciseHintId);
    ProgrammingExercise exercise = programmingExerciseRepository.findByIdElseThrow(exerciseId);
    authCheckService.checkHasAtLeastRoleForExerciseElseThrow(Role.EDITOR, exercise, null);
    var exerciseHint = exerciseHintRepository.findByIdElseThrow(exerciseHintId);
    if (exerciseHint instanceof CodeHint) {
        throw new BadRequestAlertException("A code hint cannot be deleted manually.", CODE_HINT_ENTITY_NAME, "manualCodeHintOperation");
    }
    if (!exerciseHint.getExercise().getId().equals(exerciseId)) {
        throw new ConflictException("An exercise hint can only be deleted if the exerciseIds match.", EXERCISE_HINT_ENTITY_NAME, "exerciseIdsMismatch");
    }
    exerciseHintRepository.deleteById(exerciseHintId);
    return ResponseEntity.noContent().headers(HeaderUtil.createEntityDeletionAlert(applicationName, true, EXERCISE_HINT_ENTITY_NAME, exerciseHintId.toString())).build();
}
Also used : BadRequestAlertException(de.tum.in.www1.artemis.web.rest.errors.BadRequestAlertException) ConflictException(de.tum.in.www1.artemis.web.rest.errors.ConflictException) ProgrammingExercise(de.tum.in.www1.artemis.domain.ProgrammingExercise) CodeHint(de.tum.in.www1.artemis.domain.hestia.CodeHint) PreAuthorize(org.springframework.security.access.prepost.PreAuthorize)

Example 4 with CodeHint

use of de.tum.in.www1.artemis.domain.hestia.CodeHint in project ArTEMiS by ls1intum.

the class ProgrammingExerciseImportService method importSolutionEntries.

/**
 * Copies solution entries from one exercise to another. Because the solution entries from the template exercise
 * references its test cases and code hint, the references between them also need to be changed.
 *
 * @param templateExercise     The template exercise which tasks should be copied
 * @param targetExercise       The new exercise to which all tasks should get copied to
 * @param newTestCaseIdByOldId A map with the old test case id as a key and the new test case id as a value
 * @param newHintIdByOldId     A map with the old hint id as a key and the new hint id as a value
 */
private void importSolutionEntries(final ProgrammingExercise templateExercise, final ProgrammingExercise targetExercise, Map<Long, Long> newTestCaseIdByOldId, Map<Long, Long> newHintIdByOldId) {
    templateExercise.getTestCases().forEach(testCase -> {
        var newSolutionEntries = solutionEntryRepository.findByTestCaseIdWithCodeHint(testCase.getId()).stream().map(solutionEntry -> {
            Long newTestCaseId = newTestCaseIdByOldId.get(testCase.getId());
            var targetTestCase = targetExercise.getTestCases().stream().filter(newTestCase -> Objects.equals(newTestCaseId, newTestCase.getId())).findFirst().orElseThrow();
            CodeHint codeHint = null;
            if (solutionEntry.getCodeHint() != null) {
                Long newHintId = newHintIdByOldId.get(solutionEntry.getCodeHint().getId());
                codeHint = (CodeHint) targetExercise.getExerciseHints().stream().filter(newHint -> Objects.equals(newHintId, newHint.getId())).findFirst().orElseThrow();
            }
            var copy = new ProgrammingExerciseSolutionEntry();
            copy.setCode(solutionEntry.getCode());
            copy.setPreviousCode(solutionEntry.getPreviousCode());
            copy.setLine(solutionEntry.getLine());
            copy.setPreviousLine(solutionEntry.getPreviousLine());
            copy.setTestCase(targetTestCase);
            targetTestCase.getSolutionEntries().add(copy);
            copy.setCodeHint(codeHint);
            if (codeHint != null) {
                codeHint.getSolutionEntries().add(copy);
            }
            return copy;
        }).collect(Collectors.toSet());
        solutionEntryRepository.saveAll(newSolutionEntries);
    });
}
Also used : ContinuousIntegrationException(de.tum.in.www1.artemis.exception.ContinuousIntegrationException) java.util(java.util) de.tum.in.www1.artemis.repository(de.tum.in.www1.artemis.repository) LoggerFactory(org.slf4j.LoggerFactory) ExerciseHintRepository(de.tum.in.www1.artemis.repository.hestia.ExerciseHintRepository) FileService(de.tum.in.www1.artemis.service.FileService) GitService(de.tum.in.www1.artemis.service.connectors.GitService) ContinuousIntegrationService(de.tum.in.www1.artemis.service.connectors.ContinuousIntegrationService) ProgrammingExerciseSolutionEntryRepository(de.tum.in.www1.artemis.repository.hestia.ProgrammingExerciseSolutionEntryRepository) AbstractBaseProgrammingExerciseParticipation(de.tum.in.www1.artemis.domain.participation.AbstractBaseProgrammingExerciseParticipation) ProgrammingExerciseTaskRepository(de.tum.in.www1.artemis.repository.hestia.ProgrammingExerciseTaskRepository) Service(org.springframework.stereotype.Service) RepositoryType(de.tum.in.www1.artemis.domain.enumeration.RepositoryType) TEST_REPO_NAME(de.tum.in.www1.artemis.config.Constants.TEST_REPO_NAME) ProgrammingExerciseSolutionEntry(de.tum.in.www1.artemis.domain.hestia.ProgrammingExerciseSolutionEntry) SolutionProgrammingExerciseParticipation(de.tum.in.www1.artemis.domain.participation.SolutionProgrammingExerciseParticipation) SubmissionPolicy(de.tum.in.www1.artemis.domain.submissionpolicy.SubmissionPolicy) Logger(org.slf4j.Logger) BuildPlanType(de.tum.in.www1.artemis.domain.enumeration.BuildPlanType) GitAPIException(org.eclipse.jgit.api.errors.GitAPIException) ExerciseMode(de.tum.in.www1.artemis.domain.enumeration.ExerciseMode) IOException(java.io.IOException) Collectors(java.util.stream.Collectors) CodeHint(de.tum.in.www1.artemis.domain.hestia.CodeHint) TemplateProgrammingExerciseParticipation(de.tum.in.www1.artemis.domain.participation.TemplateProgrammingExerciseParticipation) ExerciseHintService(de.tum.in.www1.artemis.service.hestia.ExerciseHintService) de.tum.in.www1.artemis.domain(de.tum.in.www1.artemis.domain) ASSIGNMENT_REPO_NAME(de.tum.in.www1.artemis.config.Constants.ASSIGNMENT_REPO_NAME) VersionControlService(de.tum.in.www1.artemis.service.connectors.VersionControlService) UrlService(de.tum.in.www1.artemis.service.UrlService) ProgrammingExerciseTask(de.tum.in.www1.artemis.domain.hestia.ProgrammingExerciseTask) StaticCodeAnalysisService(de.tum.in.www1.artemis.service.StaticCodeAnalysisService) Transactional(org.springframework.transaction.annotation.Transactional) ProgrammingExerciseSolutionEntry(de.tum.in.www1.artemis.domain.hestia.ProgrammingExerciseSolutionEntry) CodeHint(de.tum.in.www1.artemis.domain.hestia.CodeHint)

Example 5 with CodeHint

use of de.tum.in.www1.artemis.domain.hestia.CodeHint in project ArTEMiS by ls1intum.

the class CodeHintResource method generateCodeHintsForExercise.

/**
 * {@code POST programming-exercises/:exerciseId/code-hints} : Create a new exerciseHint for an exercise.
 *
 * @param exerciseId the exerciseId of the exercise of which to create the exerciseHint
 * @param deleteOldCodeHints Whether old code hints should be deleted
 * @return the {@link ResponseEntity} with status {@code 200 (Ok)} and with body the new code hints,
 */
@PostMapping("programming-exercises/{exerciseId}/code-hints")
@PreAuthorize("hasRole('EDITOR')")
public ResponseEntity<List<CodeHint>> generateCodeHintsForExercise(@PathVariable Long exerciseId, @RequestParam(value = "deleteOldCodeHints", defaultValue = "true") boolean deleteOldCodeHints) {
    log.debug("REST request to generate CodeHints for ProgrammingExercise: {}", exerciseId);
    ProgrammingExercise exercise = programmingExerciseRepository.findByIdElseThrow(exerciseId);
    authCheckService.checkHasAtLeastRoleForExerciseElseThrow(Role.EDITOR, exercise, null);
    // Hints for exam exercises are not supported at the moment
    if (exercise.isExamExercise()) {
        throw new AccessForbiddenException("Code hints for exams are currently not supported");
    }
    var codeHints = codeHintService.generateCodeHintsForExercise(exercise, deleteOldCodeHints);
    return ResponseEntity.ok(codeHints);
}
Also used : ProgrammingExercise(de.tum.in.www1.artemis.domain.ProgrammingExercise) AccessForbiddenException(de.tum.in.www1.artemis.web.rest.errors.AccessForbiddenException) PreAuthorize(org.springframework.security.access.prepost.PreAuthorize)

Aggregations

CodeHint (de.tum.in.www1.artemis.domain.hestia.CodeHint)24 AbstractSpringIntegrationBambooBitbucketJiraTest (de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest)12 ProgrammingExercise (de.tum.in.www1.artemis.domain.ProgrammingExercise)12 ExerciseHint (de.tum.in.www1.artemis.domain.hestia.ExerciseHint)12 Test (org.junit.jupiter.api.Test)12 PreAuthorize (org.springframework.security.access.prepost.PreAuthorize)12 ProgrammingExerciseSolutionEntry (de.tum.in.www1.artemis.domain.hestia.ProgrammingExerciseSolutionEntry)10 ConflictException (de.tum.in.www1.artemis.web.rest.errors.ConflictException)10 WithMockUser (org.springframework.security.test.context.support.WithMockUser)10 BadRequestAlertException (de.tum.in.www1.artemis.web.rest.errors.BadRequestAlertException)6 AccessForbiddenException (de.tum.in.www1.artemis.web.rest.errors.AccessForbiddenException)5 Exercise (de.tum.in.www1.artemis.domain.Exercise)4 ProgrammingExerciseTestCase (de.tum.in.www1.artemis.domain.ProgrammingExerciseTestCase)4 ProgrammingExerciseTask (de.tum.in.www1.artemis.domain.hestia.ProgrammingExerciseTask)4 ASSIGNMENT_REPO_NAME (de.tum.in.www1.artemis.config.Constants.ASSIGNMENT_REPO_NAME)2 TEST_REPO_NAME (de.tum.in.www1.artemis.config.Constants.TEST_REPO_NAME)2 de.tum.in.www1.artemis.domain (de.tum.in.www1.artemis.domain)2 BuildPlanType (de.tum.in.www1.artemis.domain.enumeration.BuildPlanType)2 ExerciseMode (de.tum.in.www1.artemis.domain.enumeration.ExerciseMode)2 RepositoryType (de.tum.in.www1.artemis.domain.enumeration.RepositoryType)2