Search in sources :

Example 6 with ExerciseHint

use of de.tum.in.www1.artemis.domain.hestia.ExerciseHint 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 7 with ExerciseHint

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

the class ExerciseHintIntegrationTest method getHintForAnExerciseAsTutorForbidden.

@Test
@WithMockUser(username = "tutor1", roles = "TA")
public void getHintForAnExerciseAsTutorForbidden() throws Exception {
    ExerciseHint exerciseHint = exerciseHintRepository.findAll().get(0);
    request.get("/api/exercises/" + exerciseHint.getExercise().getId() + "/exercise-hints/" + exerciseHint.getId(), HttpStatus.FORBIDDEN, ExerciseHint.class);
}
Also used : ExerciseHint(de.tum.in.www1.artemis.domain.hestia.ExerciseHint) WithMockUser(org.springframework.security.test.context.support.WithMockUser) Test(org.junit.jupiter.api.Test) AbstractSpringIntegrationBambooBitbucketJiraTest(de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest)

Example 8 with ExerciseHint

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

the class DatabaseUtilService method addHintsToExercise.

public void addHintsToExercise(Exercise exercise) {
    ExerciseHint exerciseHint1 = new ExerciseHint().content("content 1").exercise(exercise).title("title 1");
    ExerciseHint exerciseHint2 = new ExerciseHint().content("content 2").exercise(exercise).title("title 2");
    ExerciseHint exerciseHint3 = new ExerciseHint().content("content 3").exercise(exercise).title("title 3");
    Set<ExerciseHint> hints = new HashSet<>();
    hints.add(exerciseHint1);
    hints.add(exerciseHint2);
    hints.add(exerciseHint3);
    exercise.setExerciseHints(hints);
    exerciseHintRepository.saveAll(hints);
}
Also used : ExerciseHint(de.tum.in.www1.artemis.domain.hestia.ExerciseHint)

Example 9 with ExerciseHint

use of de.tum.in.www1.artemis.domain.hestia.ExerciseHint 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)

Example 10 with ExerciseHint

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

the class ExerciseHintService method getAvailableExerciseHints.

/**
 * Returns all exercise hints that the user can currently activate for a given programming exercise.
 * Exercise hints will be shown for the first task that meets the following conditions:
 * (1) the subsequent number of the latest submissions the previous task is successful is greater or equal to the hint's threshold
 * (2) the subsequent number of the latest submissions the current task is unsuccessful is greater or equal to the hint's threshold
 * If no task matches these conditions, no exercise hints will be returned
 * Note: A task is successful, if the feedback within the submission is positive for all associated test cases within this task
 *
 * @param exercise The programming exercise
 * @param user     The user
 * @return All available exercise hints
 */
public Set<ExerciseHint> getAvailableExerciseHints(ProgrammingExercise exercise, User user) {
    var submissions = getSubmissionsForStudent(exercise, user);
    if (submissions.isEmpty()) {
        return new HashSet<>();
    }
    var latestResult = submissions.get(0).getLatestResult();
    // latest submissions has no result or latest result has no feedback (most commonly due to a build error)
    if (latestResult == null || latestResult.getFeedbacks().isEmpty()) {
        return new HashSet<>();
    }
    var exerciseHints = exerciseHintRepository.findByExerciseId(exercise.getId());
    var tasks = programmingExerciseTaskService.getSortedTasks(exercise);
    var subsequentNumberOfUnsuccessfulSubmissionsByTask = tasks.stream().collect(Collectors.toMap(task -> task, task -> subsequentNumberOfSubmissionsForTaskWithStatus(submissions, task, false)));
    var subsequentNumberOfSuccessfulSubmissionsByTask = tasks.stream().collect(Collectors.toMap(task -> task, task -> subsequentNumberOfSubmissionsForTaskWithStatus(submissions, task, true)));
    for (int i = 0; i < tasks.size(); i++) {
        var task = tasks.get(i);
        int subsequentNumberOfUnsuccessfulSubmissionsForCurrentTask = subsequentNumberOfUnsuccessfulSubmissionsByTask.get(task);
        // current task is successful
        if (subsequentNumberOfUnsuccessfulSubmissionsForCurrentTask == 0) {
            continue;
        }
        var hintsInTask = exerciseHints.stream().filter(hint -> Objects.nonNull(hint.getProgrammingExerciseTask()) && Objects.equals(hint.getProgrammingExerciseTask().getId(), task.getId())).collect(Collectors.toSet());
        // no hints exist for the current task
        if (hintsInTask.isEmpty()) {
            continue;
        }
        Optional<Integer> subsequentNumberSuccessfulSubmissionsForPreviousTask;
        if (i == 0) {
            subsequentNumberSuccessfulSubmissionsForPreviousTask = Optional.empty();
        } else {
            subsequentNumberSuccessfulSubmissionsForPreviousTask = Optional.of(subsequentNumberOfSuccessfulSubmissionsByTask.get(tasks.get(i - 1)));
        }
        // skip current task if the previous task was not successful
        if (0 == subsequentNumberSuccessfulSubmissionsForPreviousTask.orElse(-1)) {
            continue;
        }
        // add the available hints for the current task
        var availableHintsForCurrentTask = getAvailableExerciseHintsForTask(subsequentNumberSuccessfulSubmissionsForPreviousTask, subsequentNumberOfUnsuccessfulSubmissionsForCurrentTask, hintsInTask);
        if (!availableHintsForCurrentTask.isEmpty()) {
            return availableHintsForCurrentTask;
        }
    }
    return new HashSet<>();
}
Also used : java.util(java.util) Feedback(de.tum.in.www1.artemis.domain.Feedback) StudentParticipationRepository(de.tum.in.www1.artemis.repository.StudentParticipationRepository) ProgrammingExercise(de.tum.in.www1.artemis.domain.ProgrammingExercise) BadRequestAlertException(de.tum.in.www1.artemis.web.rest.errors.BadRequestAlertException) ZonedDateTime(java.time.ZonedDateTime) ExerciseHintRepository(de.tum.in.www1.artemis.repository.hestia.ExerciseHintRepository) Submission(de.tum.in.www1.artemis.domain.Submission) Role(de.tum.in.www1.artemis.security.Role) Collectors(java.util.stream.Collectors) User(de.tum.in.www1.artemis.domain.User) ExerciseHint(de.tum.in.www1.artemis.domain.hestia.ExerciseHint) Service(org.springframework.stereotype.Service) ExerciseHintActivationRepository(de.tum.in.www1.artemis.repository.hestia.ExerciseHintActivationRepository) AuthorizationCheckService(de.tum.in.www1.artemis.service.AuthorizationCheckService) ExerciseHintActivation(de.tum.in.www1.artemis.domain.hestia.ExerciseHintActivation) ProgrammingExerciseTask(de.tum.in.www1.artemis.domain.hestia.ProgrammingExerciseTask) ExerciseHint(de.tum.in.www1.artemis.domain.hestia.ExerciseHint)

Aggregations

ExerciseHint (de.tum.in.www1.artemis.domain.hestia.ExerciseHint)52 AbstractSpringIntegrationBambooBitbucketJiraTest (de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest)38 Test (org.junit.jupiter.api.Test)38 WithMockUser (org.springframework.security.test.context.support.WithMockUser)38 ProgrammingExercise (de.tum.in.www1.artemis.domain.ProgrammingExercise)14 PreAuthorize (org.springframework.security.access.prepost.PreAuthorize)12 CodeHint (de.tum.in.www1.artemis.domain.hestia.CodeHint)10 BadRequestAlertException (de.tum.in.www1.artemis.web.rest.errors.BadRequestAlertException)8 ConflictException (de.tum.in.www1.artemis.web.rest.errors.ConflictException)8 AccessForbiddenException (de.tum.in.www1.artemis.web.rest.errors.AccessForbiddenException)6 Exercise (de.tum.in.www1.artemis.domain.Exercise)4 Feedback (de.tum.in.www1.artemis.domain.Feedback)2 Submission (de.tum.in.www1.artemis.domain.Submission)2 User (de.tum.in.www1.artemis.domain.User)2 ExerciseHintActivation (de.tum.in.www1.artemis.domain.hestia.ExerciseHintActivation)2 ProgrammingExerciseTask (de.tum.in.www1.artemis.domain.hestia.ProgrammingExerciseTask)2 StudentParticipationRepository (de.tum.in.www1.artemis.repository.StudentParticipationRepository)2 ExerciseHintActivationRepository (de.tum.in.www1.artemis.repository.hestia.ExerciseHintActivationRepository)2 ExerciseHintRepository (de.tum.in.www1.artemis.repository.hestia.ExerciseHintRepository)2 Role (de.tum.in.www1.artemis.security.Role)2