diff --git a/VERSION.txt b/VERSION.txt index 7ab4deefee9b6ebd6f301d19340d542413892b8c..7013f798c13edaa645c943547cd9d191ae1dd64b 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1,3 +1,4 @@ +2.2.7 Add more descriptive message when training phase contains no tasks. Add answer required field to Adaptive Question. 2.2.6 Implement the ANSWER tag replacing in task solution. 2.2.5 Fix ATD update not setting createdAt. 2.2.4 Fix ATD simulator not accepting passkey content field. diff --git a/src/main/java/cz/muni/ics/kypo/training/adaptive/facade/TrainingRunFacade.java b/src/main/java/cz/muni/ics/kypo/training/adaptive/facade/TrainingRunFacade.java index 3d37d580fcc5898c25262dba9d6408039493deb4..ebbfd1d0a1ee951dfe1f22e6f386aca04ee2990d 100644 --- a/src/main/java/cz/muni/ics/kypo/training/adaptive/facade/TrainingRunFacade.java +++ b/src/main/java/cz/muni/ics/kypo/training/adaptive/facade/TrainingRunFacade.java @@ -340,11 +340,7 @@ public class TrainingRunFacade { "or @securityService.isTraineeOfGivenTrainingRun(#trainingRunId)") @TransactionalWO public String getSolution(Long trainingRunId) { - String solution = trainingRunService.getSolution(trainingRunId); - if (solution.contains("${ANSWER}")) { - solution = solution.replaceAll("\\$\\{ANSWER\\}", solution); - } - return solution; + return trainingRunService.getSolution(trainingRunId); } /** diff --git a/src/main/java/cz/muni/ics/kypo/training/adaptive/service/training/TrainingRunService.java b/src/main/java/cz/muni/ics/kypo/training/adaptive/service/training/TrainingRunService.java index c47ae1efe42567f29e77d7bdc793db67a00bef6b..797c046334b271d10b7c643386ff4d048fd1a067 100644 --- a/src/main/java/cz/muni/ics/kypo/training/adaptive/service/training/TrainingRunService.java +++ b/src/main/java/cz/muni/ics/kypo/training/adaptive/service/training/TrainingRunService.java @@ -547,6 +547,13 @@ public class TrainingRunService { throw new EntityConflictException(new EntityErrorDetail(TrainingInstance.class, "id", trainingInstance.getId().getClass(), trainingInstance.getId(), "At first organizer must allocate sandboxes for training instance.")); } + List<AbstractPhase> phases = abstractPhaseRepository.findAllByTrainingDefinitionIdOrderByOrder(trainingInstance.getTrainingDefinition().getId()); + for (var phase: phases) { + if (phase instanceof TrainingPhase && ((TrainingPhase) phase).getTasks().isEmpty()) { + throw new EntityConflictException(new EntityErrorDetail(TrainingInstance.class, "id", trainingInstance.getId().getClass(), trainingInstance.getId(), + "Training phase " + phase.getOrder() + " contains no tasks.")); + } + } return trainingInstance; } @@ -745,7 +752,11 @@ public class TrainingRunService { trainingRunRepository.save(trainingRun); auditEventsService.auditSolutionDisplayedAction(trainingRun); } - return trainingRun.getCurrentTask().getSolution(); + String solution = trainingRun.getCurrentTask().getSolution(); + if (solution.contains("${ANSWER}")) { + solution = solution.replaceAll("\\$\\{ANSWER\\}", trainingRun.getCurrentTask().getAnswer()); + } + return solution; } else { throw new BadRequestException("Current phase is not training phase and does not have solution."); }