diff --git a/src/main/java/de/tum/cit/aet/artemis/assessment/service/ResultService.java b/src/main/java/de/tum/cit/aet/artemis/assessment/service/ResultService.java index 80d564e4695a..92b1f6e19030 100644 --- a/src/main/java/de/tum/cit/aet/artemis/assessment/service/ResultService.java +++ b/src/main/java/de/tum/cit/aet/artemis/assessment/service/ResultService.java @@ -198,8 +198,8 @@ public Result createNewManualResult(Result result, boolean ratedResult) { return savedResult; } - public Result createNewRatedManualResult(Result result) { - return createNewManualResult(result, true); + public void createNewRatedManualResult(Result result) { + createNewManualResult(result, true); } /** diff --git a/src/main/java/de/tum/cit/aet/artemis/assessment/web/ResultWebsocketService.java b/src/main/java/de/tum/cit/aet/artemis/assessment/web/ResultWebsocketService.java index 927cf64f7999..99089f035083 100644 --- a/src/main/java/de/tum/cit/aet/artemis/assessment/web/ResultWebsocketService.java +++ b/src/main/java/de/tum/cit/aet/artemis/assessment/web/ResultWebsocketService.java @@ -18,7 +18,6 @@ import de.tum.cit.aet.artemis.communication.service.WebsocketMessagingService; import de.tum.cit.aet.artemis.core.service.AuthorizationCheckService; import de.tum.cit.aet.artemis.exam.service.ExamDateService; -import de.tum.cit.aet.artemis.exercise.domain.Exercise; import de.tum.cit.aet.artemis.exercise.domain.Team; import de.tum.cit.aet.artemis.exercise.domain.participation.Participation; import de.tum.cit.aet.artemis.exercise.domain.participation.StudentParticipation; @@ -73,7 +72,7 @@ public void broadcastNewResult(Participation participation, Result result) { } private void broadcastNewResultToParticipants(StudentParticipation studentParticipation, Result result) { - final Exercise exercise = studentParticipation.getExercise(); + final var exercise = studentParticipation.getExercise(); boolean isWorkingPeriodOver; if (exercise.isExamExercise()) { isWorkingPeriodOver = examDateService.isIndividualExerciseWorkingPeriodOver(exercise.getExam(), studentParticipation); diff --git a/src/main/java/de/tum/cit/aet/artemis/core/domain/User.java b/src/main/java/de/tum/cit/aet/artemis/core/domain/User.java index c435194cdf40..cebc42aafde9 100644 --- a/src/main/java/de/tum/cit/aet/artemis/core/domain/User.java +++ b/src/main/java/de/tum/cit/aet/artemis/core/domain/User.java @@ -534,6 +534,10 @@ public void setIrisAcceptedTimestamp(@Nullable ZonedDateTime irisAccepted) { this.irisAccepted = irisAccepted; } + public boolean hasAcceptedIris() { + return irisAccepted != null; + } + /** * Checks if the user has accepted the Iris privacy policy. * If not, an {@link AccessForbiddenException} is thrown. diff --git a/src/main/java/de/tum/cit/aet/artemis/iris/repository/IrisExerciseChatSessionRepository.java b/src/main/java/de/tum/cit/aet/artemis/iris/repository/IrisExerciseChatSessionRepository.java index 514be1f1d575..c6da437ac731 100644 --- a/src/main/java/de/tum/cit/aet/artemis/iris/repository/IrisExerciseChatSessionRepository.java +++ b/src/main/java/de/tum/cit/aet/artemis/iris/repository/IrisExerciseChatSessionRepository.java @@ -36,7 +36,6 @@ public interface IrisExerciseChatSessionRepository extends ArtemisJpaRepository< * @return A list of chat sessions sorted by creation date in descending order. */ @Query(""" - SELECT s FROM IrisExerciseChatSession s WHERE s.exercise.id = :exerciseId @@ -68,11 +67,9 @@ public interface IrisExerciseChatSessionRepository extends ArtemisJpaRepository< */ default List findLatestByExerciseIdAndUserIdWithMessages(Long exerciseId, Long userId, Pageable pageable) { List ids = findSessionsByExerciseIdAndUserId(exerciseId, userId, pageable).stream().map(DomainObject::getId).toList(); - if (ids.isEmpty()) { return Collections.emptyList(); } - return findSessionsWithMessagesByIdIn(ids); } diff --git a/src/main/java/de/tum/cit/aet/artemis/iris/repository/IrisExerciseSettingsRepository.java b/src/main/java/de/tum/cit/aet/artemis/iris/repository/IrisExerciseSettingsRepository.java new file mode 100644 index 000000000000..8035ec965a2b --- /dev/null +++ b/src/main/java/de/tum/cit/aet/artemis/iris/repository/IrisExerciseSettingsRepository.java @@ -0,0 +1,24 @@ +package de.tum.cit.aet.artemis.iris.repository; + +import static de.tum.cit.aet.artemis.core.config.Constants.PROFILE_IRIS; + +import org.springframework.context.annotation.Profile; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; +import org.springframework.stereotype.Repository; + +import de.tum.cit.aet.artemis.core.repository.base.ArtemisJpaRepository; +import de.tum.cit.aet.artemis.iris.domain.settings.IrisExerciseSettings; + +@Repository +@Profile(PROFILE_IRIS) +public interface IrisExerciseSettingsRepository extends ArtemisJpaRepository { + + @Query(""" + SELECT EXISTS(s) + FROM IrisExerciseSettings s + WHERE s.exercise.id = :exerciseId + AND s.irisTextExerciseChatSettings.enabled = TRUE + """) + boolean isExerciseChatEnabled(@Param("exerciseId") long exerciseId); +} diff --git a/src/main/java/de/tum/cit/aet/artemis/iris/service/pyris/PyrisEventService.java b/src/main/java/de/tum/cit/aet/artemis/iris/service/pyris/PyrisEventService.java index 58f0b8a069b8..e2a8a785fc77 100644 --- a/src/main/java/de/tum/cit/aet/artemis/iris/service/pyris/PyrisEventService.java +++ b/src/main/java/de/tum/cit/aet/artemis/iris/service/pyris/PyrisEventService.java @@ -5,6 +5,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.annotation.Profile; +import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import de.tum.cit.aet.artemis.iris.domain.session.IrisChatSession; @@ -41,17 +42,18 @@ public PyrisEventService(IrisCourseChatSessionService irisCourseChatSessionServi * * @see PyrisEvent */ + @Async public void trigger(PyrisEvent, ?> event) { log.debug("Starting to process event of type: {}", event.getClass().getSimpleName()); try { switch (event) { case CompetencyJolSetEvent competencyJolSetEvent -> { - log.info("Processing CompetencyJolSetEvent: {}", competencyJolSetEvent); + log.debug("Processing CompetencyJolSetEvent: {}", competencyJolSetEvent); competencyJolSetEvent.handleEvent(irisCourseChatSessionService); log.debug("Successfully processed CompetencyJolSetEvent"); } case NewResultEvent newResultEvent -> { - log.info("Processing NewResultEvent: {}", newResultEvent); + log.debug("Processing NewResultEvent: {}", newResultEvent); newResultEvent.handleEvent(irisExerciseChatSessionService); log.debug("Successfully processed NewResultEvent"); } diff --git a/src/main/java/de/tum/cit/aet/artemis/lti/service/LtiNewResultService.java b/src/main/java/de/tum/cit/aet/artemis/lti/service/LtiNewResultService.java index 7a64018a6969..a1dc241afa40 100644 --- a/src/main/java/de/tum/cit/aet/artemis/lti/service/LtiNewResultService.java +++ b/src/main/java/de/tum/cit/aet/artemis/lti/service/LtiNewResultService.java @@ -3,6 +3,7 @@ import static de.tum.cit.aet.artemis.core.config.Constants.PROFILE_LTI; import org.springframework.context.annotation.Profile; +import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import de.tum.cit.aet.artemis.exercise.domain.participation.StudentParticipation; @@ -22,6 +23,7 @@ public LtiNewResultService(Lti13Service lti13Service) { * * @param participation The exercise participation for which a new build result is available */ + @Async public void onNewResult(StudentParticipation participation) { if (!participation.getExercise().getCourseViaExerciseGroupOrCourseMember().isOnlineCourse()) { return; diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/service/ProgrammingMessagingService.java b/src/main/java/de/tum/cit/aet/artemis/programming/service/ProgrammingMessagingService.java index 349aa53bc89e..7a7861cbcbcc 100644 --- a/src/main/java/de/tum/cit/aet/artemis/programming/service/ProgrammingMessagingService.java +++ b/src/main/java/de/tum/cit/aet/artemis/programming/service/ProgrammingMessagingService.java @@ -28,6 +28,7 @@ import de.tum.cit.aet.artemis.exercise.dto.SubmissionDTO; import de.tum.cit.aet.artemis.exercise.repository.ParticipationRepository; import de.tum.cit.aet.artemis.exercise.repository.TeamRepository; +import de.tum.cit.aet.artemis.iris.repository.IrisExerciseSettingsRepository; import de.tum.cit.aet.artemis.iris.service.pyris.PyrisEventService; import de.tum.cit.aet.artemis.iris.service.pyris.event.NewResultEvent; import de.tum.cit.aet.artemis.lti.service.LtiNewResultService; @@ -57,16 +58,20 @@ public class ProgrammingMessagingService { private final Optional pyrisEventService; + private final Optional irisExerciseSettingsRepository; + private final ParticipationRepository participationRepository; public ProgrammingMessagingService(GroupNotificationService groupNotificationService, WebsocketMessagingService websocketMessagingService, ResultWebsocketService resultWebsocketService, Optional ltiNewResultService, TeamRepository teamRepository, - Optional pyrisEventService, ParticipationRepository participationRepository) { + Optional pyrisEventService, Optional irisExerciseSettingsRepository, + ParticipationRepository participationRepository) { this.groupNotificationService = groupNotificationService; this.websocketMessagingService = websocketMessagingService; this.resultWebsocketService = resultWebsocketService; this.ltiNewResultService = ltiNewResultService; this.teamRepository = teamRepository; + this.irisExerciseSettingsRepository = irisExerciseSettingsRepository; this.participationRepository = participationRepository; this.pyrisEventService = pyrisEventService; } @@ -188,13 +193,16 @@ public void notifyUserAboutNewResult(Result result, ProgrammingExerciseParticipa if (participation instanceof ProgrammingExerciseStudentParticipation studentParticipation) { // do not try to report results for template or solution participations ltiNewResultService.ifPresent(newResultService -> newResultService.onNewResult(studentParticipation)); - // Inform Iris about the submission status + // Inform Iris about the submission status (when certain conditions are met) notifyIrisAboutSubmissionStatus(result, studentParticipation); } } /** * Notify Iris about the submission status for the given result and student participation. + * Only notifies if the user has accepted Iris, the exercise is not an exam exercise, and the exercise chat is enabled in the exercise settings + * NOTE: we check those settings early to prevent unnecessary database queries and exceptions later on in most cases. More sophisticated checks are done in the Iris service. + *

* If the submission was successful, Iris will be informed about the successful submission. * If the submission failed, Iris will be informed about the submission failure. * Iris will only be informed about the submission status if the participant is a user. @@ -203,14 +211,18 @@ public void notifyUserAboutNewResult(Result result, ProgrammingExerciseParticipa * @param studentParticipation the student participation for which Iris should be informed about the submission status */ private void notifyIrisAboutSubmissionStatus(Result result, ProgrammingExerciseStudentParticipation studentParticipation) { - if (studentParticipation.getParticipant() instanceof User) { + if (studentParticipation.getParticipant() instanceof User user) { pyrisEventService.ifPresent(eventService -> { - // Inform event service about the new result - try { - eventService.trigger(new NewResultEvent(result)); - } - catch (Exception e) { - log.error("Could not trigger service for result {}", result.getId(), e); + final var exercise = studentParticipation.getExercise(); + if (user.hasAcceptedIris() && !exercise.isExamExercise() && irisExerciseSettingsRepository.get().isExerciseChatEnabled(exercise.getId())) { + // Inform event service about the new result + try { + // This is done asynchronously to prevent blocking the current thread + eventService.trigger(new NewResultEvent(result)); + } + catch (Exception e) { + log.error("Could not trigger service for result {}", result.getId(), e); + } } }); } diff --git a/src/test/java/de/tum/cit/aet/artemis/buildagent/service/BuildAgentDockerServiceTest.java b/src/test/java/de/tum/cit/aet/artemis/buildagent/service/BuildAgentDockerServiceTest.java index cdc2af3ec1b1..6b13982262f5 100644 --- a/src/test/java/de/tum/cit/aet/artemis/buildagent/service/BuildAgentDockerServiceTest.java +++ b/src/test/java/de/tum/cit/aet/artemis/buildagent/service/BuildAgentDockerServiceTest.java @@ -4,6 +4,7 @@ import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -83,7 +84,7 @@ void testDeleteOldDockerImages_NoOutdatedImages() { buildAgentDockerService.deleteOldDockerImages(); // Verify that removeImageCmd() was not called. - verify(dockerClient, times(0)).removeImageCmd(anyString()); + verify(dockerClient, never()).removeImageCmd(anyString()); } @Test diff --git a/src/test/java/de/tum/cit/aet/artemis/exercise/service/ParticipationTeamWebsocketServiceTest.java b/src/test/java/de/tum/cit/aet/artemis/exercise/service/ParticipationTeamWebsocketServiceTest.java index 37bf559d6b73..8c74aff1d9ff 100644 --- a/src/test/java/de/tum/cit/aet/artemis/exercise/service/ParticipationTeamWebsocketServiceTest.java +++ b/src/test/java/de/tum/cit/aet/artemis/exercise/service/ParticipationTeamWebsocketServiceTest.java @@ -2,6 +2,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.RETURNS_MOCKS; +import static org.mockito.Mockito.after; import static org.mockito.Mockito.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.timeout; @@ -139,7 +140,7 @@ void testPatchModelingSubmissionWithWrongPrincipal() { // when we submit a patch, but with the wrong user ... participationTeamWebsocketService.patchModelingSubmission(participation.getId(), patch, getPrincipalMock("student2")); // the patch should not be broadcast. - verify(websocketMessagingService, timeout(2000).times(0)).sendMessage(websocketTopic(participation), List.of()); + verify(websocketMessagingService, after(1000).never()).sendMessage(websocketTopic(participation), List.of()); } @Test @@ -152,7 +153,7 @@ void testUpdateModelingSubmission() { // the submission should be handled by the service (i.e. saved), ... verify(modelingSubmissionService, timeout(2000).times(1)).handleModelingSubmission(any(), any(), any()); // but it should NOT be broadcast (sync is handled with patches only). - verify(websocketMessagingService, timeout(2000).times(0)).sendMessage(websocketTopic(participation), List.of()); + verify(websocketMessagingService, after(1000).never()).sendMessage(websocketTopic(participation), List.of()); } @Test @@ -163,9 +164,9 @@ void testUpdateModelingSubmissionWithWrongPrincipal() { // when we submit a new modeling submission with the wrong user ... participationTeamWebsocketService.updateModelingSubmission(participation.getId(), submission, getPrincipalMock("student2")); // the submission is NOT saved ... - verify(modelingSubmissionService, timeout(2000).times(0)).handleModelingSubmission(any(), any(), any()); + verify(modelingSubmissionService, after(1000).never()).handleModelingSubmission(any(), any(), any()); // it is also not broadcast. - verify(websocketMessagingService, timeout(2000).times(0)).sendMessage(websocketTopic(participation), List.of()); + verify(websocketMessagingService, after(1000).never()).sendMessage(websocketTopic(participation), List.of()); } @Test diff --git a/src/test/java/de/tum/cit/aet/artemis/iris/PyrisEventSystemIntegrationTest.java b/src/test/java/de/tum/cit/aet/artemis/iris/PyrisEventSystemIntegrationTest.java index 95b620850ddd..44aa312cc340 100644 --- a/src/test/java/de/tum/cit/aet/artemis/iris/PyrisEventSystemIntegrationTest.java +++ b/src/test/java/de/tum/cit/aet/artemis/iris/PyrisEventSystemIntegrationTest.java @@ -5,6 +5,7 @@ import static org.awaitility.Awaitility.await; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -30,7 +31,6 @@ import de.tum.cit.aet.artemis.atlas.domain.competency.CompetencyJol; import de.tum.cit.aet.artemis.core.domain.Course; import de.tum.cit.aet.artemis.core.domain.User; -import de.tum.cit.aet.artemis.core.exception.AccessForbiddenAlertException; import de.tum.cit.aet.artemis.core.user.util.UserUtilService; import de.tum.cit.aet.artemis.exercise.domain.SubmissionType; import de.tum.cit.aet.artemis.exercise.participation.util.ParticipationFactory; @@ -40,13 +40,7 @@ import de.tum.cit.aet.artemis.iris.domain.settings.event.IrisEventType; import de.tum.cit.aet.artemis.iris.repository.IrisSettingsRepository; import de.tum.cit.aet.artemis.iris.service.pyris.PyrisEventProcessingException; -import de.tum.cit.aet.artemis.iris.service.pyris.PyrisEventService; -import de.tum.cit.aet.artemis.iris.service.pyris.PyrisJobService; -import de.tum.cit.aet.artemis.iris.service.pyris.PyrisStatusUpdateService; -import de.tum.cit.aet.artemis.iris.service.pyris.UnsupportedPyrisEventException; import de.tum.cit.aet.artemis.iris.service.pyris.event.NewResultEvent; -import de.tum.cit.aet.artemis.iris.service.pyris.event.PyrisEvent; -import de.tum.cit.aet.artemis.iris.service.session.IrisExerciseChatSessionService; import de.tum.cit.aet.artemis.programming.domain.ProgrammingExercise; import de.tum.cit.aet.artemis.programming.domain.ProgrammingExerciseStudentParticipation; import de.tum.cit.aet.artemis.programming.domain.ProgrammingSubmission; @@ -59,12 +53,6 @@ class PyrisEventSystemIntegrationTest extends AbstractIrisIntegrationTest { private static final String TEST_PREFIX = "pyriseventsystemintegration"; - @Autowired - protected PyrisStatusUpdateService pyrisStatusUpdateService; - - @Autowired - protected PyrisJobService pyrisJobService; - @Autowired protected IrisSettingsRepository irisSettingsRepository; @@ -74,9 +62,6 @@ class PyrisEventSystemIntegrationTest extends AbstractIrisIntegrationTest { @Autowired private SubmissionTestRepository submissionRepository; - @Autowired - private PyrisEventService pyrisEventService; - @Autowired private ParticipationUtilService participationUtilService; @@ -103,6 +88,13 @@ class PyrisEventSystemIntegrationTest extends AbstractIrisIntegrationTest { void initTestCase() throws GitAPIException, IOException, URISyntaxException { userUtilService.addUsers(TEST_PREFIX, 2, 0, 0, 1); + var student1 = userUtilService.getUserByLogin(TEST_PREFIX + "student1"); + student1.setIrisAcceptedTimestamp(ZonedDateTime.now().minusDays(1)); + userTestRepository.save(student1); + var student2 = userUtilService.getUserByLogin(TEST_PREFIX + "student2"); + student2.setIrisAcceptedTimestamp(ZonedDateTime.now().minusDays(1)); + userTestRepository.save(student2); + course = programmingExerciseUtilService.addCourseWithOneProgrammingExercise(); competency = competencyUtilService.createCompetency(course); exercise = exerciseUtilService.getFirstExerciseWithType(course, ProgrammingExercise.class); @@ -194,7 +186,9 @@ void testShouldFireProgressStalledEvent() { }); pyrisEventService.trigger(new NewResultEvent(result)); - verify(irisExerciseChatSessionService, times(1)).onNewResult(eq(result)); + // Wrap the following code into await() to ensure that the pipeline is executed before the test finishes. + + await().atMost(2, TimeUnit.SECONDS).untilAsserted(() -> verify(irisExerciseChatSessionService, times(1)).onNewResult(eq(result))); await().atMost(2, TimeUnit.SECONDS).until(() -> pipelineDone.get()); @@ -214,12 +208,13 @@ void testShouldFireBuildFailedEvent() { }); pyrisEventService.trigger(new NewResultEvent(result)); - verify(irisExerciseChatSessionService, times(1)).onBuildFailure(eq(result)); + + await().atMost(2, TimeUnit.SECONDS).untilAsserted(() -> verify(irisExerciseChatSessionService, times(1)).onBuildFailure(eq(result))); await().atMost(2, TimeUnit.SECONDS).until(() -> pipelineDone.get()); - verify(pyrisPipelineService, times(1)).executeExerciseChatPipeline(eq("default"), eq(Optional.ofNullable((ProgrammingSubmission) result.getSubmission())), eq(exercise), - eq(irisSession), eq(Optional.of("build_failed"))); + await().atMost(2, TimeUnit.SECONDS).untilAsserted(() -> verify(pyrisPipelineService, times(1)).executeExerciseChatPipeline(eq("default"), + eq(Optional.ofNullable((ProgrammingSubmission) result.getSubmission())), eq(exercise), eq(irisSession), eq(Optional.of("build_failed")))); } @Test @@ -237,20 +232,6 @@ void testShouldFireJolEvent() { verify(irisCourseChatSessionService, times(1)).onJudgementOfLearningSet(any(CompetencyJol.class)); verify(pyrisPipelineService, times(1)).executeCourseChatPipeline(eq("default"), eq(irisSession), any(CompetencyJol.class)); - - } - - @Test - @WithMockUser(username = TEST_PREFIX + "student1", roles = "USER") - void testShouldThrowUnsupportedEventException() { - assertThatExceptionOfType(UnsupportedPyrisEventException.class).isThrownBy(() -> pyrisEventService.trigger(new PyrisEvent() { - - @Override - public void handleEvent(IrisExerciseChatSessionService service) { - // Do nothing - } - })).withMessageStartingWith("Unsupported event"); - } @Test @@ -264,7 +245,7 @@ void testShouldNotFireProgressStalledEventWithEventDisabled() { createSubmissionWithScore(studentParticipation, 40); createSubmissionWithScore(studentParticipation, 40); var result = createSubmissionWithScore(studentParticipation, 40); - assertThatExceptionOfType(AccessForbiddenAlertException.class).isThrownBy(() -> pyrisEventService.trigger(new NewResultEvent(result))); + verify(pyrisEventService, never()).trigger(new NewResultEvent(result)); } @Test @@ -278,7 +259,8 @@ void testShouldNotFireBuildFailedEventWhenEventSettingDisabled() { irisExerciseChatSessionService.createChatSessionForProgrammingExercise(exercise, userUtilService.getUserByLogin(TEST_PREFIX + "student1")); // Create a failing submission for the student. var result = createFailingSubmission(studentParticipation); - assertThatExceptionOfType(AccessForbiddenAlertException.class).isThrownBy(() -> pyrisEventService.trigger(new NewResultEvent(result))); + // very that the event is not fired + verify(pyrisEventService, never()).trigger(new NewResultEvent(result)); } @Test @@ -301,8 +283,10 @@ void testShouldShouldNotFireProgressStalledEventWithExistingSuccessfulSubmission pyrisEventService.trigger(new NewResultEvent(result)); await().atMost(2, TimeUnit.SECONDS); - verify(irisExerciseChatSessionService, times(2)).onNewResult(any(Result.class)); - verify(pyrisPipelineService, times(0)).executeExerciseChatPipeline(any(), any(), any(), any(), any()); + await().atMost(2, TimeUnit.SECONDS).untilAsserted(() -> { + verify(irisExerciseChatSessionService, times(2)).onNewResult(any(Result.class)); + verify(pyrisPipelineService, never()).executeExerciseChatPipeline(any(), any(), any(), any(), any()); + }); } @Test @@ -315,8 +299,8 @@ void testShouldNotFireProgressStalledEventWithLessThanThreeSubmissions() { pyrisEventService.trigger(new NewResultEvent(result)); - verify(irisExerciseChatSessionService, times(1)).onNewResult(any(Result.class)); - verify(pyrisPipelineService, times(0)).executeExerciseChatPipeline(any(), any(), any(), any(), any()); + verify(irisExerciseChatSessionService, never()).onNewResult(any(Result.class)); + verify(pyrisPipelineService, never()).executeExerciseChatPipeline(any(), any(), any(), any(), any()); } @Test @@ -330,8 +314,8 @@ void testShouldNotFireProgressStalledEventWithIncreasingScores() { pyrisEventService.trigger(new NewResultEvent(result)); - verify(irisExerciseChatSessionService, times(1)).onNewResult(any(Result.class)); - verify(pyrisPipelineService, times(0)).executeExerciseChatPipeline(any(), any(), any(), any(), any()); + verify(irisExerciseChatSessionService, never()).onNewResult(any(Result.class)); + verify(pyrisPipelineService, never()).executeExerciseChatPipeline(any(), any(), any(), any(), any()); } @Test diff --git a/src/test/java/de/tum/cit/aet/artemis/shared/base/AbstractSpringIntegrationLocalCILocalVCTest.java b/src/test/java/de/tum/cit/aet/artemis/shared/base/AbstractSpringIntegrationLocalCILocalVCTest.java index e05cf257fbf7..90e651dfbac8 100644 --- a/src/test/java/de/tum/cit/aet/artemis/shared/base/AbstractSpringIntegrationLocalCILocalVCTest.java +++ b/src/test/java/de/tum/cit/aet/artemis/shared/base/AbstractSpringIntegrationLocalCILocalVCTest.java @@ -66,7 +66,6 @@ import de.tum.cit.aet.artemis.atlas.service.competency.CompetencyJolService; import de.tum.cit.aet.artemis.buildagent.BuildAgentConfiguration; import de.tum.cit.aet.artemis.buildagent.service.BuildAgentDockerService; -import de.tum.cit.aet.artemis.communication.service.notifications.GroupNotificationScheduleService; import de.tum.cit.aet.artemis.core.domain.Course; import de.tum.cit.aet.artemis.core.domain.User; import de.tum.cit.aet.artemis.core.service.ResourceLoaderService; @@ -74,6 +73,7 @@ import de.tum.cit.aet.artemis.core.user.util.UserUtilService; import de.tum.cit.aet.artemis.exam.service.ExamLiveEventsService; import de.tum.cit.aet.artemis.exercise.domain.Team; +import de.tum.cit.aet.artemis.iris.service.pyris.PyrisEventService; import de.tum.cit.aet.artemis.iris.service.pyris.PyrisPipelineService; import de.tum.cit.aet.artemis.iris.service.session.IrisCourseChatSessionService; import de.tum.cit.aet.artemis.iris.service.session.IrisExerciseChatSessionService; @@ -120,21 +120,6 @@ public abstract class AbstractSpringIntegrationLocalCILocalVCTest extends Abstra @Autowired protected LocalVCLocalCITestService localVCLocalCITestService; - @MockitoSpyBean - protected LdapUserService ldapUserService; - - @MockitoSpyBean - protected SpringSecurityLdapTemplate ldapTemplate; - - @MockitoSpyBean - protected LocalVCService versionControlService; - - @MockitoSpyBean - protected LocalCIService continuousIntegrationService; - - @MockitoSpyBean - protected BuildAgentConfiguration buildAgentConfiguration; - @Autowired protected ProgrammingExerciseTestRepository programmingExerciseRepository; @@ -159,6 +144,21 @@ public abstract class AbstractSpringIntegrationLocalCILocalVCTest extends Abstra @Autowired protected BuildJobTestRepository buildJobRepository; + @MockitoSpyBean + protected LdapUserService ldapUserService; + + @MockitoSpyBean + protected SpringSecurityLdapTemplate ldapTemplate; + + @MockitoSpyBean + protected LocalVCService versionControlService; + + @MockitoSpyBean + protected LocalCIService continuousIntegrationService; + + @MockitoSpyBean + protected BuildAgentConfiguration buildAgentConfiguration; + /** * This is the mock(DockerClient.class). * Subclasses can use this to dynamically mock methods of the DockerClient. @@ -174,9 +174,6 @@ public abstract class AbstractSpringIntegrationLocalCILocalVCTest extends Abstra @MockitoSpyBean protected ExamLiveEventsService examLiveEventsService; - @MockitoSpyBean - protected GroupNotificationScheduleService groupNotificationScheduleService; - @MockitoSpyBean protected IrisCourseChatSessionService irisCourseChatSessionService; @@ -189,6 +186,9 @@ public abstract class AbstractSpringIntegrationLocalCILocalVCTest extends Abstra @MockitoSpyBean protected IrisExerciseChatSessionService irisExerciseChatSessionService; + @MockitoSpyBean + protected PyrisEventService pyrisEventService; + @Value("${artemis.version-control.url}") protected URL localVCBaseUrl;