{{ title }} wirklich dauerhaft gelöscht werden? Alle zugehörigen Elemente werden gelöscht, inklusive der Klausuren der Studierenden. Diese Aktion kann NICHT rückgängig gemacht werden!",
"typeNameToConfirm": "Bitte gib den Namen der Klausur zur Bestätigung ein."
diff --git a/src/main/webapp/i18n/de/quizPool.json b/src/main/webapp/i18n/de/quizPool.json
new file mode 100644
index 000000000000..9e70f7aed8fe
--- /dev/null
+++ b/src/main/webapp/i18n/de/quizPool.json
@@ -0,0 +1,23 @@
+{
+ "artemisApp": {
+ "quizPool": {
+ "editTitle": "Quiz-Pool bearbeiten",
+ "group": "Gruppe",
+ "groupName": "Gruppenname",
+ "addGroup": "Gruppe hinzufügen",
+ "delete": {
+ "question": "Möchten Sie die Quizgruppe {{ title }} wirklich löschen? Alle zugewiesenen Fragen werden nicht zugeordnet."
+ },
+ "dragExplanation": "Ziehen Sie die Frage unten, um sie einer Gruppe zuzuordnen.",
+ "groupExplanation": "Fragen in der gleichen Gruppe werden für jeden Schüler nach dem Zufallsprinzip ausgewählt. Fragen, die nicht in einer Gruppe sind, werden allen Schülern zugewiesen.",
+ "updated": "Quiz Pool aktualisiert mit ID {{ param }}",
+ "invalidReasons": {
+ "groupNameEmpty": "Der Gruppenname kann nicht leer sein.",
+ "groupNameLength": "Der Gruppenname kann nicht länger als 100 Zeichen sein.",
+ "groupSameName": "Der Gruppenname muss einmalig sein.",
+ "groupNoQuestion": "Gruppe {{name}}: Die Gruppe hat keine Fragen.",
+ "groupHasDifferentQuestionPoints": "Gruppe {{name}}: Gruppe hat Fragen mit unterschiedlichen Schwerpunkten."
+ }
+ }
+ }
+}
diff --git a/src/main/webapp/i18n/en/exam.json b/src/main/webapp/i18n/en/exam.json
index 0d0ad9daac6d..c42fb45f9d59 100644
--- a/src/main/webapp/i18n/en/exam.json
+++ b/src/main/webapp/i18n/en/exam.json
@@ -563,6 +563,7 @@
},
"importSuccessful": "Exercise Groups successfully imported!"
},
+ "quizPool": "Quiz Pool",
"delete": {
"question": "Are you sure you want to permanently delete the Exam {{ title }}? All associated elements will be deleted including the Student Exams. This action can NOT be undone!",
"typeNameToConfirm": "Please type in the name of the exam to confirm."
diff --git a/src/main/webapp/i18n/en/quizPool.json b/src/main/webapp/i18n/en/quizPool.json
new file mode 100644
index 000000000000..1104b0f0e19d
--- /dev/null
+++ b/src/main/webapp/i18n/en/quizPool.json
@@ -0,0 +1,23 @@
+{
+ "artemisApp": {
+ "quizPool": {
+ "editTitle": "Edit Quiz Pool",
+ "group": "Group",
+ "groupName": "Group Name",
+ "addGroup": "Add Group",
+ "delete": {
+ "question": "Are you sure you want to delete Quiz Group {{ title }}? All assigned Questions will be unmapped."
+ },
+ "dragExplanation": "Drag the question below to assign it to a group.",
+ "groupExplanation": "Questions in the same group will be randomly chosen for each student. Questions that are not in a group will be assigned to all students.",
+ "updated": "Updated Quiz Pool with identifier {{ param }}",
+ "invalidReasons": {
+ "groupNameEmpty": "Group name cannot be empty.",
+ "groupNameLength": "Group name cannot be longer than 100 characters.",
+ "groupSameName": "Group name must be unique.",
+ "groupNoQuestion": "Group {{name}}: Group does not have any question.",
+ "groupHasDifferentQuestionPoints": "Group {{name}}: Group has questions with different points."
+ }
+ }
+ }
+}
diff --git a/src/test/java/de/tum/in/www1/artemis/exam/QuizPoolIntegrationTest.java b/src/test/java/de/tum/in/www1/artemis/exam/QuizPoolIntegrationTest.java
new file mode 100644
index 000000000000..9616695f0892
--- /dev/null
+++ b/src/test/java/de/tum/in/www1/artemis/exam/QuizPoolIntegrationTest.java
@@ -0,0 +1,206 @@
+package de.tum.in.www1.artemis.exam;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.groups.Tuple.tuple;
+
+import java.util.List;
+import java.util.Set;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.security.test.context.support.WithMockUser;
+
+import de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest;
+import de.tum.in.www1.artemis.course.CourseUtilService;
+import de.tum.in.www1.artemis.domain.Course;
+import de.tum.in.www1.artemis.domain.User;
+import de.tum.in.www1.artemis.domain.exam.Exam;
+import de.tum.in.www1.artemis.domain.quiz.DragAndDropQuestion;
+import de.tum.in.www1.artemis.domain.quiz.MultipleChoiceQuestion;
+import de.tum.in.www1.artemis.domain.quiz.QuizGroup;
+import de.tum.in.www1.artemis.domain.quiz.QuizPool;
+import de.tum.in.www1.artemis.domain.quiz.QuizQuestion;
+import de.tum.in.www1.artemis.domain.quiz.ShortAnswerQuestion;
+import de.tum.in.www1.artemis.exercise.quizexercise.QuizExerciseFactory;
+import de.tum.in.www1.artemis.exercise.quizexercise.QuizExerciseUtilService;
+import de.tum.in.www1.artemis.service.QuizPoolService;
+import de.tum.in.www1.artemis.user.UserUtilService;
+import de.tum.in.www1.artemis.util.RequestUtilService;
+
+class QuizPoolIntegrationTest extends AbstractSpringIntegrationBambooBitbucketJiraTest {
+
+ private static final String TEST_PREFIX = "quizpoolintegration";
+
+ @Autowired
+ private QuizPoolService quizPoolService;
+
+ @Autowired
+ private CourseUtilService courseUtilService;
+
+ @Autowired
+ private ExamUtilService examUtilService;
+
+ @Autowired
+ private QuizExerciseUtilService quizExerciseUtilService;
+
+ @Autowired
+ private UserUtilService userUtilService;
+
+ @Autowired
+ private RequestUtilService request;
+
+ private Course course;
+
+ private Exam exam;
+
+ private QuizPool quizPool;
+
+ private QuizGroup quizGroup0;
+
+ private QuizGroup quizGroup1;
+
+ private QuizGroup quizGroup2;
+
+ @BeforeEach
+ void initTestCase() {
+ userUtilService.addUsers(TEST_PREFIX, 0, 0, 0, 1);
+ course = courseUtilService.addEmptyCourse();
+ User instructor = userUtilService.getUserByLogin(TEST_PREFIX + "instructor1");
+ instructor.setGroups(Set.of(course.getInstructorGroupName()));
+ exam = examUtilService.addExam(course);
+ quizPool = quizPoolService.update(exam.getId(), new QuizPool());
+ }
+
+ @Test
+ @WithMockUser(username = TEST_PREFIX + "instructor1", roles = "INSTRUCTOR")
+ void testCreateQuizPoolSuccessful() throws Exception {
+ QuizPool responseQuizPool = createQuizPool();
+ assertThat(responseQuizPool.getExam().getId()).isEqualTo(exam.getId());
+ assertThat(responseQuizPool.getQuizGroups()).hasSize(quizPool.getQuizGroups().size()).extracting("name").containsExactly(quizPool.getQuizGroups().get(0).getName(),
+ quizPool.getQuizGroups().get(1).getName(), quizPool.getQuizGroups().get(2).getName());
+ assertThat(responseQuizPool.getQuizQuestions()).hasSize(quizPool.getQuizQuestions().size()).extracting("title", "quizGroup.name").containsExactly(
+ tuple(quizPool.getQuizQuestions().get(0).getTitle(), quizGroup0.getName()), tuple(quizPool.getQuizQuestions().get(1).getTitle(), quizGroup0.getName()),
+ tuple(quizPool.getQuizQuestions().get(2).getTitle(), quizGroup1.getName()), tuple(quizPool.getQuizQuestions().get(3).getTitle(), quizGroup2.getName()),
+ tuple(quizPool.getQuizQuestions().get(4).getTitle(), null));
+ }
+
+ @Test
+ @WithMockUser(username = TEST_PREFIX + "instructor1", roles = "INSTRUCTOR")
+ void testUpdateQuizPoolSuccessful() throws Exception {
+ QuizPool quizPool = createQuizPool();
+
+ QuizGroup quizGroup3 = quizExerciseUtilService.createQuizGroup("Exception Handling");
+ QuizQuestion saQuizQuestion1 = quizExerciseUtilService.createShortAnswerQuestionWithTitleAndGroup("SA 1", quizGroup2);
+ QuizQuestion saQuizQuestion2 = quizExerciseUtilService.createShortAnswerQuestionWithTitleAndGroup("SA 2", quizGroup3);
+ QuizQuestion saQuizQuestion3 = quizExerciseUtilService.createShortAnswerQuestionWithTitleAndGroup("SA 3", null);
+ quizPool.setQuizGroups(List.of(quizPool.getQuizGroups().get(0), quizPool.getQuizGroups().get(2), quizGroup3));
+ quizPool.setQuizQuestions(List.of(quizPool.getQuizQuestions().get(0), quizPool.getQuizQuestions().get(1), quizPool.getQuizQuestions().get(2), saQuizQuestion1,
+ saQuizQuestion2, saQuizQuestion3));
+ quizPool.getQuizQuestions().get(2).setQuizGroup(quizGroup3);
+
+ QuizPool responseQuizPool = request.putWithResponseBody("/api/courses/" + course.getId() + "/exams/" + exam.getId() + "/quiz-pools", quizPool, QuizPool.class,
+ HttpStatus.OK, null);
+
+ assertThat(responseQuizPool.getExam().getId()).isEqualTo(exam.getId());
+ assertThat(responseQuizPool.getQuizGroups()).hasSize(quizPool.getQuizGroups().size()).extracting("name").containsExactly(quizPool.getQuizGroups().get(0).getName(),
+ quizPool.getQuizGroups().get(1).getName(), quizPool.getQuizGroups().get(2).getName());
+ assertThat(responseQuizPool.getQuizQuestions()).hasSize(quizPool.getQuizQuestions().size()).extracting("title", "quizGroup.name").containsExactly(
+ tuple(quizPool.getQuizQuestions().get(0).getTitle(), quizGroup0.getName()), tuple(quizPool.getQuizQuestions().get(1).getTitle(), quizGroup0.getName()),
+ tuple(quizPool.getQuizQuestions().get(2).getTitle(), quizGroup3.getName()), tuple(quizPool.getQuizQuestions().get(3).getTitle(), quizGroup2.getName()),
+ tuple(quizPool.getQuizQuestions().get(4).getTitle(), quizGroup3.getName()), tuple(quizPool.getQuizQuestions().get(5).getTitle(), null));
+ }
+
+ @Test
+ @WithMockUser(username = TEST_PREFIX + "instructor1", roles = "INSTRUCTOR")
+ void testUpdateQuizPoolBadRequestInvalidMCQuestion() throws Exception {
+ MultipleChoiceQuestion quizQuestion = QuizExerciseFactory.createMultipleChoiceQuestion();
+ quizQuestion.setTitle(null);
+ quizPool.setQuizQuestions(List.of(quizQuestion));
+
+ request.putWithResponseBody("/api/courses/" + course.getId() + "/exams/" + exam.getId() + "/quiz-pools", quizPool, QuizPool.class, HttpStatus.BAD_REQUEST, null);
+ }
+
+ @Test
+ @WithMockUser(username = TEST_PREFIX + "instructor1", roles = "INSTRUCTOR")
+ void testUpdateQuizPoolBadRequestInvalidDnDQuestion() throws Exception {
+ DragAndDropQuestion quizQuestion = QuizExerciseFactory.createDragAndDropQuestion();
+ quizQuestion.setCorrectMappings(null);
+ quizPool.setQuizQuestions(List.of(quizQuestion));
+
+ request.putWithResponseBody("/api/courses/" + course.getId() + "/exams/" + exam.getId() + "/quiz-pools", quizPool, QuizPool.class, HttpStatus.BAD_REQUEST, null);
+ }
+
+ @Test
+ @WithMockUser(username = TEST_PREFIX + "instructor1", roles = "INSTRUCTOR")
+ void testUpdateQuizPoolBadRequestInvalidSAQuestion() throws Exception {
+ ShortAnswerQuestion quizQuestion = QuizExerciseFactory.createShortAnswerQuestion();
+ quizQuestion.setCorrectMappings(null);
+ quizPool.setQuizQuestions(List.of(quizQuestion));
+
+ request.putWithResponseBody("/api/courses/" + course.getId() + "/exams/" + exam.getId() + "/quiz-pools", quizPool, QuizPool.class, HttpStatus.BAD_REQUEST, null);
+ }
+
+ @Test
+ @WithMockUser(username = TEST_PREFIX + "instructor1", roles = "INSTRUCTOR")
+ void testUpdateQuizPoolNotFoundCourse() throws Exception {
+ QuizQuestion quizQuestion = QuizExerciseFactory.createMultipleChoiceQuestion();
+ quizPool.setQuizQuestions(List.of(quizQuestion));
+
+ int notFoundCourseId = 0;
+ request.putWithResponseBody("/api/courses/" + notFoundCourseId + "/exams/" + exam.getId() + "/quiz-pools", quizPool, QuizPool.class, HttpStatus.NOT_FOUND, null);
+ }
+
+ @Test
+ @WithMockUser(username = TEST_PREFIX + "instructor1", roles = "INSTRUCTOR")
+ void testUpdateQuizPoolNotFoundExam() throws Exception {
+ QuizQuestion quizQuestion = QuizExerciseFactory.createMultipleChoiceQuestion();
+ quizPool.setQuizQuestions(List.of(quizQuestion));
+
+ int notFoundExamId = 0;
+ request.putWithResponseBody("/api/courses/" + course.getId() + "/exams/" + notFoundExamId + "/quiz-pools", quizPool, QuizPool.class, HttpStatus.NOT_FOUND, null);
+ }
+
+ @Test
+ @WithMockUser(username = TEST_PREFIX + "instructor1", roles = "INSTRUCTOR")
+ void testGetQuizPoolSuccessful() throws Exception {
+ QuizGroup quizGroup0 = quizExerciseUtilService.createQuizGroup("Encapsulation");
+ QuizGroup quizGroup1 = quizExerciseUtilService.createQuizGroup("Inheritance");
+ QuizQuestion mcQuizQuestion = quizExerciseUtilService.createMultipleChoiceQuestionWithTitleAndGroup("MC", quizGroup0);
+ QuizQuestion dndQuizQuestion = quizExerciseUtilService.createDragAndDropQuestionWithTitleAndGroup("DND", quizGroup1);
+ QuizQuestion saQuizQuestion = quizExerciseUtilService.createShortAnswerQuestionWithTitleAndGroup("SA", null);
+ quizPool.setQuizGroups(List.of(quizGroup0, quizGroup1));
+ quizPool.setQuizQuestions(List.of(mcQuizQuestion, dndQuizQuestion, saQuizQuestion));
+ QuizPool savedQuizPool = quizPoolService.update(exam.getId(), quizPool);
+
+ QuizPool responseQuizPool = request.get("/api/courses/" + course.getId() + "/exams/" + exam.getId() + "/quiz-pools", HttpStatus.OK, QuizPool.class);
+ assertThat(responseQuizPool.getExam().getId()).isEqualTo(exam.getId());
+ assertThat(responseQuizPool.getQuizGroups()).hasSize(savedQuizPool.getQuizGroups().size()).containsExactly(savedQuizPool.getQuizGroups().get(0),
+ savedQuizPool.getQuizGroups().get(1));
+ assertThat(responseQuizPool.getQuizQuestions()).hasSize(savedQuizPool.getQuizQuestions().size()).containsExactly(savedQuizPool.getQuizQuestions().get(0),
+ savedQuizPool.getQuizQuestions().get(1), savedQuizPool.getQuizQuestions().get(2));
+ }
+
+ @Test
+ @WithMockUser(username = TEST_PREFIX + "instructor1", roles = "INSTRUCTOR")
+ void testGetQuizPoolNotFoundExam() throws Exception {
+ int notFoundExamId = 0;
+ request.get("/api/courses/" + course.getId() + "/exams/" + notFoundExamId + "/quiz-pools", HttpStatus.NOT_FOUND, QuizPool.class);
+ }
+
+ private QuizPool createQuizPool() throws Exception {
+ quizGroup0 = quizExerciseUtilService.createQuizGroup("Encapsulation");
+ quizGroup1 = quizExerciseUtilService.createQuizGroup("Inheritance");
+ quizGroup2 = quizExerciseUtilService.createQuizGroup("Polymorphism");
+ QuizQuestion mcQuizQuestion0 = quizExerciseUtilService.createMultipleChoiceQuestionWithTitleAndGroup("MC 0", quizGroup0);
+ QuizQuestion mcQuizQuestion1 = quizExerciseUtilService.createMultipleChoiceQuestionWithTitleAndGroup("MC 1", quizGroup0);
+ QuizQuestion dndQuizQuestion0 = quizExerciseUtilService.createDragAndDropQuestionWithTitleAndGroup("DND 0", quizGroup1);
+ QuizQuestion dndQuizQuestion1 = quizExerciseUtilService.createDragAndDropQuestionWithTitleAndGroup("DND 1", quizGroup2);
+ QuizQuestion saQuizQuestion0 = quizExerciseUtilService.createShortAnswerQuestionWithTitleAndGroup("SA 0", null);
+ quizPool.setQuizGroups(List.of(quizGroup0, quizGroup1, quizGroup2));
+ quizPool.setQuizQuestions(List.of(mcQuizQuestion0, mcQuizQuestion1, dndQuizQuestion0, dndQuizQuestion1, saQuizQuestion0));
+
+ return request.putWithResponseBody("/api/courses/" + course.getId() + "/exams/" + exam.getId() + "/quiz-pools", quizPool, QuizPool.class, HttpStatus.OK, null);
+ }
+}
diff --git a/src/test/java/de/tum/in/www1/artemis/exercise/quizexercise/QuizExerciseUtilService.java b/src/test/java/de/tum/in/www1/artemis/exercise/quizexercise/QuizExerciseUtilService.java
index 909215386516..27594619aae1 100644
--- a/src/test/java/de/tum/in/www1/artemis/exercise/quizexercise/QuizExerciseUtilService.java
+++ b/src/test/java/de/tum/in/www1/artemis/exercise/quizexercise/QuizExerciseUtilService.java
@@ -362,4 +362,37 @@ public void joinQuizBatch(QuizExercise quizExercise, QuizBatch batch, String use
user.setLogin(username);
quizScheduleService.joinQuizBatch(quizExercise, batch, user);
}
+
+ @NotNull
+ public QuizGroup createQuizGroup(String name) {
+ QuizGroup quizGroup = new QuizGroup();
+ quizGroup.setName(name);
+ return quizGroup;
+ }
+
+ @NotNull
+ public MultipleChoiceQuestion createMultipleChoiceQuestionWithTitleAndGroup(String title, QuizGroup quizGroup) {
+ MultipleChoiceQuestion quizQuestion = QuizExerciseFactory.createMultipleChoiceQuestion();
+ setQuizQuestionsTitleAndGroup(quizQuestion, title, quizGroup);
+ return quizQuestion;
+ }
+
+ @NotNull
+ public DragAndDropQuestion createDragAndDropQuestionWithTitleAndGroup(String title, QuizGroup quizGroup) {
+ DragAndDropQuestion quizQuestion = QuizExerciseFactory.createDragAndDropQuestion();
+ setQuizQuestionsTitleAndGroup(quizQuestion, title, quizGroup);
+ return quizQuestion;
+ }
+
+ @NotNull
+ public ShortAnswerQuestion createShortAnswerQuestionWithTitleAndGroup(String title, QuizGroup quizGroup) {
+ ShortAnswerQuestion quizQuestion = QuizExerciseFactory.createShortAnswerQuestion();
+ setQuizQuestionsTitleAndGroup(quizQuestion, title, quizGroup);
+ return quizQuestion;
+ }
+
+ private void setQuizQuestionsTitleAndGroup(Q quizQuestion, String title, QuizGroup quizGroup) {
+ quizQuestion.setTitle(title);
+ quizQuestion.setQuizGroup(quizGroup);
+ }
}
diff --git a/src/test/javascript/spec/component/documentation-button/documentation-button.component.spec.ts b/src/test/javascript/spec/component/documentation-button/documentation-button.component.spec.ts
index d66e439351c2..bb218b917349 100644
--- a/src/test/javascript/spec/component/documentation-button/documentation-button.component.spec.ts
+++ b/src/test/javascript/spec/component/documentation-button/documentation-button.component.spec.ts
@@ -46,7 +46,7 @@ describe('DocumentationButtonComponent', () => {
window.open = mockedOpen;
comp.openDocumentation();
- expect(mockedOpen).toHaveBeenCalledWith('https://ls1intum.github.io/Artemis/user/courses/customizable/', expect.anything());
+ expect(mockedOpen).toHaveBeenCalledWith('https://docs.artemis.cit.tum.de/user/courses/customizable/', expect.anything());
window.open = originalOpen;
});
diff --git a/src/test/javascript/spec/component/exam/manage/exams/exam-detail.component.spec.ts b/src/test/javascript/spec/component/exam/manage/exams/exam-detail.component.spec.ts
index b3645afd842f..5116fe8891f9 100644
--- a/src/test/javascript/spec/component/exam/manage/exams/exam-detail.component.spec.ts
+++ b/src/test/javascript/spec/component/exam/manage/exams/exam-detail.component.spec.ts
@@ -33,6 +33,8 @@ import { JhiWebsocketService } from 'app/core/websocket/websocket.service';
import { MockWebsocketService } from '../../../../helpers/mocks/service/mock-websocket.service';
import { ExamEditWorkingTimeComponent } from 'app/exam/manage/exams/exam-checklist-component/exam-edit-workingtime-dialog/exam-edit-working-time.component';
import { ExamLiveAnnouncementCreateButtonComponent } from 'app/exam/manage/exams/exam-checklist-component/exam-announcement-dialog/exam-live-announcement-create-button.component';
+import { QuizPoolService } from 'app/exercises/quiz/manage/quiz-pool.service';
+import { QuizPool } from 'app/entities/quiz/quiz-pool.model';
@Component({
template: '',
@@ -43,6 +45,7 @@ describe('ExamDetailComponent', () => {
let examDetailComponentFixture: ComponentFixture;
let examDetailComponent: ExamDetailComponent;
let service: ExamManagementService;
+ let quizPoolService: QuizPoolService;
let router: Router;
const exampleHTML = 'Sample Markdown
';
@@ -112,6 +115,7 @@ describe('ExamDetailComponent', () => {
examDetailComponentFixture = TestBed.createComponent(ExamDetailComponent);
examDetailComponent = examDetailComponentFixture.componentInstance;
service = TestBed.inject(ExamManagementService);
+ quizPoolService = TestBed.inject(QuizPoolService);
});
router = TestBed.inject(Router);
@@ -129,6 +133,7 @@ describe('ExamDetailComponent', () => {
exam.examMaxPoints = 100;
exam.exerciseGroups = [];
examDetailComponent.exam = exam;
+ jest.spyOn(quizPoolService, 'find').mockReturnValue(of(new HttpResponse({ body: new QuizPool() })));
});
afterEach(() => {
diff --git a/src/test/javascript/spec/component/exercises/quiz/manage/quiz-pool-mapping-question-list.component.spec.ts b/src/test/javascript/spec/component/exercises/quiz/manage/quiz-pool-mapping-question-list.component.spec.ts
new file mode 100644
index 000000000000..c5828a1ec76a
--- /dev/null
+++ b/src/test/javascript/spec/component/exercises/quiz/manage/quiz-pool-mapping-question-list.component.spec.ts
@@ -0,0 +1,65 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { ArtemisDatePipe } from 'app/shared/pipes/artemis-date.pipe';
+import { ArtemisTranslatePipe } from 'app/shared/pipes/artemis-translate.pipe';
+import { MockDirective, MockPipe } from 'ng-mocks';
+import { ArtemisTestModule } from '../../../../test.module';
+import { TranslateDirective } from 'app/shared/language/translate.directive';
+import { QuizPoolMappingQuestionListComponent } from 'app/exercises/quiz/manage/quiz-pool-mapping-question-list.component';
+import * as DragDrop from '@angular/cdk/drag-drop';
+import { QuizQuestion } from 'app/entities/quiz/quiz-question.model';
+
+describe('QuizPoolMappingQuestionListComponent', () => {
+ let fixture: ComponentFixture;
+ let component: QuizPoolMappingQuestionListComponent;
+
+ beforeEach(() => {
+ TestBed.configureTestingModule({
+ imports: [ArtemisTestModule, DragDrop.DragDropModule, HttpClientTestingModule],
+ declarations: [QuizPoolMappingQuestionListComponent, MockPipe(ArtemisTranslatePipe), MockPipe(ArtemisDatePipe), MockDirective(TranslateDirective)],
+ providers: [],
+ })
+ .compileComponents()
+ .then(() => {
+ fixture = TestBed.createComponent(QuizPoolMappingQuestionListComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+ });
+ it('should move question in the same group', () => {
+ const container = {
+ data: {},
+ };
+ const event = {
+ previousContainer: container,
+ container: container,
+ previousIndex: 0,
+ currentIndex: 1,
+ } as DragDrop.CdkDragDrop;
+ const moveItemInArray = jest.spyOn(DragDrop, 'moveItemInArray').mockImplementation(() => {});
+
+ component.handleOnDropQuestion(event);
+
+ expect(moveItemInArray).toHaveBeenCalledOnce();
+ });
+
+ it('should move question within different groups', () => {
+ const container0 = {
+ data: {},
+ };
+ const container1 = {
+ data: {},
+ };
+ const event = {
+ previousContainer: container0,
+ container: container1,
+ previousIndex: 0,
+ currentIndex: 0,
+ } as DragDrop.CdkDragDrop;
+ const transferArrayItem = jest.spyOn(DragDrop, 'transferArrayItem').mockImplementation(() => {});
+
+ component.handleOnDropQuestion(event);
+
+ expect(transferArrayItem).toHaveBeenCalledOnce();
+ });
+});
diff --git a/src/test/javascript/spec/component/exercises/quiz/manage/quiz-pool-mapping.component.spec.ts b/src/test/javascript/spec/component/exercises/quiz/manage/quiz-pool-mapping.component.spec.ts
new file mode 100644
index 000000000000..595a8cb073a1
--- /dev/null
+++ b/src/test/javascript/spec/component/exercises/quiz/manage/quiz-pool-mapping.component.spec.ts
@@ -0,0 +1,225 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { ButtonComponent } from 'app/shared/components/button.component';
+import { ArtemisDatePipe } from 'app/shared/pipes/artemis-date.pipe';
+import { ArtemisTranslatePipe } from 'app/shared/pipes/artemis-translate.pipe';
+import { MockComponent, MockDirective, MockPipe } from 'ng-mocks';
+import { ArtemisTestModule } from '../../../../test.module';
+import { TranslateDirective } from 'app/shared/language/translate.directive';
+import { NgbTooltip } from '@ng-bootstrap/ng-bootstrap';
+import { NgModel } from '@angular/forms';
+import { QuizPoolMappingQuestionListComponent } from 'app/exercises/quiz/manage/quiz-pool-mapping-question-list.component';
+import { QuizPoolMappingComponent } from 'app/exercises/quiz/manage/quiz-pool-mapping.component';
+import { QuizGroup } from 'app/entities/quiz/quiz-group.model';
+import { MultipleChoiceQuestion } from 'app/entities/quiz/multiple-choice-question.model';
+import { DeleteButtonDirective } from 'app/shared/delete-dialog/delete-button.directive';
+
+describe('QuizPoolMappingComponent', () => {
+ let fixture: ComponentFixture;
+ let component: QuizPoolMappingComponent;
+
+ beforeEach(() => {
+ TestBed.configureTestingModule({
+ imports: [ArtemisTestModule, HttpClientTestingModule, MockDirective(NgbTooltip)],
+ declarations: [
+ QuizPoolMappingComponent,
+ ButtonComponent,
+ MockPipe(ArtemisTranslatePipe),
+ MockPipe(ArtemisDatePipe),
+ MockDirective(TranslateDirective),
+ MockComponent(QuizPoolMappingQuestionListComponent),
+ MockDirective(NgModel),
+ MockDirective(DeleteButtonDirective),
+ ],
+ providers: [],
+ })
+ .compileComponents()
+ .then(() => {
+ fixture = TestBed.createComponent(QuizPoolMappingComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+ });
+
+ it('should add group', () => {
+ expect(component.quizGroups).toBeArrayOfSize(0);
+
+ component.addGroup('Test Group');
+
+ expect(component.quizGroups).toBeArrayOfSize(1);
+ });
+
+ it('should not add group with empty name', () => {
+ expect(component.quizGroups).toBeArrayOfSize(0);
+
+ component.addGroup('');
+
+ expect(component.quizGroups).toBeArrayOfSize(0);
+ });
+
+ it('should not add group with name consisting of more than 100 characters', () => {
+ expect(component.quizGroups).toBeArrayOfSize(0);
+
+ component.addGroup('Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean ma');
+
+ expect(component.quizGroups).toBeArrayOfSize(0);
+ });
+
+ it('should not add group with the same name', () => {
+ expect(component.quizGroups).toBeArrayOfSize(0);
+
+ component.addGroup('Test Group');
+ component.addGroup('Test Group');
+
+ expect(component.quizGroups).toBeArrayOfSize(1);
+ });
+
+ it('should delete group', () => {
+ const quizGroup = new QuizGroup();
+ quizGroup.name = 'Group 1';
+ const question = new MultipleChoiceQuestion();
+ question.quizGroup = quizGroup;
+ component.quizGroups = [quizGroup];
+ component.quizQuestions = [question];
+ const addQuestion = jest.spyOn(component, 'addQuestion').mockImplementation();
+
+ component.handleUpdate();
+ component.deleteGroup(0);
+
+ expect(component.quizGroups).toBeArrayOfSize(0);
+ expect(addQuestion).toHaveBeenCalledOnce();
+ expect(addQuestion).toHaveBeenCalledWith(question);
+ });
+
+ it('should add question', () => {
+ const question = new MultipleChoiceQuestion();
+ component.addQuestion(question);
+ expect(component.unmappedQuizQuestions).toBeArrayOfSize(1);
+ expect(component.unmappedQuizQuestions[0]).toEqual(question);
+ });
+
+ it('should delete unmapped question', () => {
+ const question = new MultipleChoiceQuestion();
+ component.deleteQuestion(question);
+ expect(component.unmappedQuizQuestions).toBeEmpty();
+ });
+
+ it('should delete mapped question', () => {
+ const quizGroup = new QuizGroup();
+ quizGroup.name = 'Test Group';
+ const question = new MultipleChoiceQuestion();
+ question.quizGroup = quizGroup;
+ component.quizGroups = [quizGroup];
+ component.handleUpdate();
+
+ component.deleteQuestion(question);
+
+ const questions = component.quizGroupNameQuestionsMap.get(quizGroup.name);
+ expect(questions).toBeEmpty();
+ });
+
+ it('should return group names that do not have questions', () => {
+ component.quizGroupNameQuestionsMap.set('Group 1', []);
+ component.quizGroupNameQuestionsMap.set('Group 2', [new MultipleChoiceQuestion()]);
+ const groupNamesWithNoQuestion = component.getGroupNamesWithNoQuestion();
+ expect(groupNamesWithNoQuestion).toBeArrayOfSize(1);
+ expect(groupNamesWithNoQuestion[0]).toBe('Group 1');
+ });
+
+ it('should return true if some groups with no questions', () => {
+ component.quizGroupNameQuestionsMap.set('Group 1', []);
+ component.quizGroupNameQuestionsMap.set('Group 2', [new MultipleChoiceQuestion()]);
+ expect(component.hasGroupsWithNoQuestion()).toBeTrue();
+ });
+
+ it('should return false if all groups have at least 1 question', () => {
+ component.quizGroupNameQuestionsMap.set('Group 1', [new MultipleChoiceQuestion()]);
+ component.quizGroupNameQuestionsMap.set('Group 2', [new MultipleChoiceQuestion()]);
+ expect(component.hasGroupsWithNoQuestion()).toBeFalse();
+ });
+
+ it('should return group names that have questions with different points', () => {
+ const question0 = new MultipleChoiceQuestion();
+ question0.points = 1;
+ const question1 = new MultipleChoiceQuestion();
+ question1.points = 1;
+ const question2 = new MultipleChoiceQuestion();
+ question2.points = 1;
+ const question3 = new MultipleChoiceQuestion();
+ question3.points = 2;
+ component.quizGroupNameQuestionsMap.set('Group 1', [question0, question1]);
+ component.quizGroupNameQuestionsMap.set('Group 2', [question2, question3]);
+ const groupNamesWithNoQuestion = component.getGroupNamesWithDifferentQuestionPoints();
+ expect(groupNamesWithNoQuestion).toBeArrayOfSize(1);
+ expect(groupNamesWithNoQuestion[0]).toBe('Group 2');
+ });
+
+ it('should return true if some groups have questions with different points', () => {
+ const question0 = new MultipleChoiceQuestion();
+ question0.points = 1;
+ const question1 = new MultipleChoiceQuestion();
+ question1.points = 1;
+ const question2 = new MultipleChoiceQuestion();
+ question2.points = 1;
+ const question3 = new MultipleChoiceQuestion();
+ question3.points = 2;
+ component.quizGroupNameQuestionsMap.set('Group 1', [question0, question1]);
+ component.quizGroupNameQuestionsMap.set('Group 2', [question2, question3]);
+ expect(component.hasGroupsWithDifferentQuestionPoints()).toBeTrue();
+ });
+
+ it('should return false if some groups have questions with different points', () => {
+ const question0 = new MultipleChoiceQuestion();
+ question0.points = 1;
+ const question1 = new MultipleChoiceQuestion();
+ question1.points = 1;
+ const question2 = new MultipleChoiceQuestion();
+ question2.points = 1;
+ const question3 = new MultipleChoiceQuestion();
+ question3.points = 1;
+ component.quizGroupNameQuestionsMap.set('Group 1', [question0, question1]);
+ component.quizGroupNameQuestionsMap.set('Group 2', [question2, question3]);
+ expect(component.hasGroupsWithDifferentQuestionPoints()).toBeFalse();
+ });
+
+ it('should set unmappedQuizQuestions and quizGroupNameQuestionsMap when inputs are changed', () => {
+ const quizGroup = new QuizGroup();
+ quizGroup.name = 'Test Group';
+ const question0 = new MultipleChoiceQuestion();
+ const question1 = new MultipleChoiceQuestion();
+ question0.quizGroup = quizGroup;
+ component.quizGroups = [quizGroup];
+ component.quizQuestions = [question0, question1];
+ component.ngOnChanges();
+ expect(component.unmappedQuizQuestions).toBeArrayOfSize(1);
+ expect(component.unmappedQuizQuestions[0]).toEqual(question1);
+ expect(component.quizGroupNameQuestionsMap.size).toBe(1);
+ const questions = component.quizGroupNameQuestionsMap.get('Test Group');
+ expect(questions).toBeArrayOfSize(1);
+ expect(questions![0]).toEqual(question0);
+ });
+
+ it('should set quiz group to quiz question when question is dropped to the group', () => {
+ const quizGroup = new QuizGroup();
+ quizGroup.name = 'Test Group';
+ const question = new MultipleChoiceQuestion();
+ component.handleOnQuizQuestionDropped(question, quizGroup);
+ expect(question.quizGroup).toEqual(quizGroup);
+ });
+
+ it('should return max points', () => {
+ const question0 = new MultipleChoiceQuestion();
+ question0.points = 1;
+ const question1 = new MultipleChoiceQuestion();
+ question1.points = undefined;
+ const question2 = new MultipleChoiceQuestion();
+ question2.points = 1;
+ const question3 = new MultipleChoiceQuestion();
+ question3.points = undefined;
+ component.quizGroupNameQuestionsMap = new Map();
+ component.quizGroupNameQuestionsMap.set('Group 1', [question0, question1]);
+ component.quizGroupNameQuestionsMap.set('Group 2', []);
+ component.unmappedQuizQuestions = [question2, question3];
+ expect(component.getMaxPoints()).toBe(2);
+ });
+});
diff --git a/src/test/javascript/spec/component/exercises/quiz/manage/quiz-pool.component.spec.ts b/src/test/javascript/spec/component/exercises/quiz/manage/quiz-pool.component.spec.ts
new file mode 100644
index 000000000000..8cb46261cc4e
--- /dev/null
+++ b/src/test/javascript/spec/component/exercises/quiz/manage/quiz-pool.component.spec.ts
@@ -0,0 +1,212 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { ArtemisDatePipe } from 'app/shared/pipes/artemis-date.pipe';
+import { ArtemisTranslatePipe } from 'app/shared/pipes/artemis-translate.pipe';
+import { MockComponent, MockDirective, MockPipe, MockProvider } from 'ng-mocks';
+import { ArtemisTestModule } from '../../../../test.module';
+import { TranslateDirective } from 'app/shared/language/translate.directive';
+import { QuizPoolComponent } from 'app/exercises/quiz/manage/quiz-pool.component';
+import { ActivatedRoute, convertToParamMap } from '@angular/router';
+import { QuizPoolService } from 'app/exercises/quiz/manage/quiz-pool.service';
+import { of, throwError } from 'rxjs';
+import { HttpResponse } from '@angular/common/http';
+import { QuizPool } from 'app/entities/quiz/quiz-pool.model';
+import { MultipleChoiceQuestion } from 'app/entities/quiz/multiple-choice-question.model';
+import { QuizGroup } from 'app/entities/quiz/quiz-group.model';
+import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
+import { ExamManagementService } from 'app/exam/manage/exam-management.service';
+import { Exam } from 'app/entities/exam.model';
+import dayjs from 'dayjs/esm';
+import { QuizPoolMappingComponent } from 'app/exercises/quiz/manage/quiz-pool-mapping.component';
+import { QuizQuestionListEditComponent } from 'app/exercises/quiz/manage/quiz-question-list-edit.component';
+import { AnswerOption } from 'app/entities/quiz/answer-option.model';
+import { ChangeDetectorRef } from '@angular/core';
+import { FormsModule } from '@angular/forms';
+import { AlertService } from 'app/core/util/alert.service';
+
+describe('QuizPoolComponent', () => {
+ let fixture: ComponentFixture;
+ let component: QuizPoolComponent;
+ let quizPoolService: QuizPoolService;
+ let examService: ExamManagementService;
+ let alertService: AlertService;
+ let changeDetectorRef: ChangeDetectorRef;
+
+ const courseId = 1;
+ const examId = 2;
+ const route = { snapshot: { paramMap: convertToParamMap({ courseId, examId }) }, queryParams: of({}) } as any as ActivatedRoute;
+
+ beforeEach(() => {
+ TestBed.configureTestingModule({
+ imports: [ArtemisTestModule, HttpClientTestingModule, NgbModule, FormsModule],
+ declarations: [
+ QuizPoolComponent,
+ MockComponent(QuizPoolMappingComponent),
+ MockComponent(QuizQuestionListEditComponent),
+ MockPipe(ArtemisTranslatePipe),
+ MockPipe(ArtemisDatePipe),
+ MockDirective(TranslateDirective),
+ ],
+ providers: [{ provide: ActivatedRoute, useValue: route }, MockProvider(ChangeDetectorRef), MockProvider(AlertService)],
+ })
+ .compileComponents()
+ .then(() => {
+ fixture = TestBed.createComponent(QuizPoolComponent);
+ component = fixture.componentInstance;
+ quizPoolService = fixture.debugElement.injector.get(QuizPoolService);
+ examService = fixture.debugElement.injector.get(ExamManagementService);
+ alertService = fixture.debugElement.injector.get(AlertService);
+ changeDetectorRef = fixture.debugElement.injector.get(ChangeDetectorRef);
+ fixture.detectChanges();
+ });
+ });
+
+ it('should initialize quiz pool', () => {
+ const quizPool = new QuizPool();
+ const quizGroup = new QuizGroup();
+ quizGroup.name = 'Test Group';
+ const quizQuestion = new MultipleChoiceQuestion();
+ quizQuestion.quizGroup = quizGroup;
+ quizPool.id = 1;
+ quizPool.quizQuestions = [quizQuestion];
+ quizPool.quizGroups = [quizGroup];
+ jest.spyOn(quizPoolService, 'find').mockReturnValue(of(new HttpResponse({ body: quizPool })));
+ component.ngOnInit();
+ expect(component.quizPool).toEqual(quizPool);
+ });
+
+ it('should initialize quiz pool with new object if existing quiz pool is not found', () => {
+ jest.spyOn(quizPoolService, 'find').mockReturnValue(throwError(() => ({ status: 404 })));
+ component.ngOnInit();
+ expect(component.quizPool.quizGroups).toBeArrayOfSize(0);
+ expect(component.quizPool.quizQuestions).toBeArrayOfSize(0);
+ });
+
+ it('should set isExamStarted to true', () => {
+ const exam = new Exam();
+ exam.startDate = dayjs().subtract(1, 'hour');
+ jest.spyOn(examService, 'find').mockReturnValue(of(new HttpResponse({ body: exam })));
+ component.ngOnInit();
+ expect(component.isExamStarted).toBeTrue();
+ });
+
+ it('should set isExamStarted to false', () => {
+ const exam = new Exam();
+ exam.startDate = dayjs().add(1, 'hour');
+ jest.spyOn(examService, 'find').mockReturnValue(of(new HttpResponse({ body: exam })));
+ component.ngOnInit();
+ expect(component.isExamStarted).toBeFalse();
+ });
+
+ it('should call QuizGroupQuestionMappingComponent.addQuestion when there is a new question', () => {
+ component.quizPool = new QuizPool();
+ component.quizPoolMappingComponent = new QuizPoolMappingComponent(alertService);
+ const addQuestionSpy = jest.spyOn(component.quizPoolMappingComponent, 'addQuestion');
+ const quizQuestion = new MultipleChoiceQuestion();
+ component.handleQuestionAdded(quizQuestion);
+ expect(addQuestionSpy).toHaveBeenCalledOnce();
+ expect(addQuestionSpy).toHaveBeenCalledWith(quizQuestion);
+ });
+
+ it('should call QuizGroupQuestionMappingComponent.deleteQuestion when a question is deleted', () => {
+ component.quizPool = new QuizPool();
+ component.quizPoolMappingComponent = new QuizPoolMappingComponent(alertService);
+ const deleteQuestionSpy = jest.spyOn(component.quizPoolMappingComponent, 'deleteQuestion');
+ const quizQuestion = new MultipleChoiceQuestion();
+ component.handleQuestionDeleted(quizQuestion);
+ expect(deleteQuestionSpy).toHaveBeenCalledOnce();
+ expect(deleteQuestionSpy).toHaveBeenCalledWith(quizQuestion);
+ });
+
+ it('should call QuizPoolService.update when saving', () => {
+ const quizPool = new QuizPool();
+ component.courseId = courseId;
+ component.examId = examId;
+ component.quizPool = quizPool;
+ component.hasPendingChanges = true;
+ component.isValid = true;
+ component.quizQuestionsEditComponent = new QuizQuestionListEditComponent();
+ component.quizPoolMappingComponent = new QuizPoolMappingComponent(alertService);
+ const parseAllQuestionsSpy = jest.spyOn(component.quizQuestionsEditComponent, 'parseAllQuestions').mockImplementation();
+ const getMaxPointsSpy = jest.spyOn(component.quizPoolMappingComponent, 'getMaxPoints').mockImplementation();
+ const updateQuizPoolSpy = jest.spyOn(quizPoolService, 'update').mockReturnValue(of(new HttpResponse({ body: quizPool })));
+ component.save();
+ expect(parseAllQuestionsSpy).toHaveBeenCalledOnce();
+ expect(getMaxPointsSpy).toHaveBeenCalledOnce();
+ expect(updateQuizPoolSpy).toHaveBeenCalledOnce();
+ });
+
+ it('should not call QuizPoolService.update if there is no pending changes or is not valid', () => {
+ const quizPool = new QuizPool();
+ component.courseId = courseId;
+ component.examId = examId;
+ component.quizPool = quizPool;
+ component.hasPendingChanges = false;
+ component.isValid = false;
+ const updateQuizPoolSpy = jest.spyOn(quizPoolService, 'update').mockImplementation();
+ component.save();
+ expect(updateQuizPoolSpy).toHaveBeenCalledTimes(0);
+ });
+
+ it('should set isValid to true if all questions and groups are valid', () => {
+ const answerOption0 = new AnswerOption();
+ answerOption0.isCorrect = true;
+ const answerOption1 = new AnswerOption();
+ answerOption1.isCorrect = false;
+ const question = new MultipleChoiceQuestion();
+ question.points = 1;
+ question.answerOptions = [answerOption0, answerOption1];
+ component.quizPool = new QuizPool();
+ component.quizPool.quizQuestions = [question];
+ component.quizPoolMappingComponent = new QuizPoolMappingComponent(alertService);
+ component.isValid = false;
+ component.handleUpdate();
+ component.isValid = true;
+ });
+
+ it('should set isValid to false if at least 1 question is invalid', () => {
+ const question = new MultipleChoiceQuestion();
+ question.points = -1;
+ question.answerOptions = [];
+ component.quizPool = new QuizPool();
+ component.quizPool.quizQuestions = [question];
+ component.quizPoolMappingComponent = new QuizPoolMappingComponent(alertService);
+ component.isValid = true;
+ component.handleUpdate();
+ component.isValid = false;
+ });
+
+ it('should set invalid reasons when there is a group that does not have any question', () => {
+ component.quizPool = new QuizPool();
+ component.quizPoolMappingComponent = new QuizPoolMappingComponent(alertService);
+ jest.spyOn(changeDetectorRef.constructor.prototype, 'detectChanges').mockImplementation();
+ jest.spyOn(component.quizPoolMappingComponent, 'hasGroupsWithNoQuestion').mockReturnValue(true);
+ jest.spyOn(component.quizPoolMappingComponent, 'getGroupNamesWithNoQuestion').mockReturnValue(['Test Group']);
+ jest.spyOn(component.quizPoolMappingComponent, 'hasGroupsWithDifferentQuestionPoints').mockReturnValue(false);
+ component.handleUpdate();
+ expect(component.invalidReasons).toBeArrayOfSize(1);
+ expect(component.invalidReasons[0]).toEqual({
+ translateKey: 'artemisApp.quizPool.invalidReasons.groupNoQuestion',
+ translateValues: {
+ name: 'Test Group',
+ },
+ });
+ });
+
+ it('should set invalid reasons when there is a group whose questions do not have the same points', () => {
+ component.quizPool = new QuizPool();
+ component.quizPoolMappingComponent = new QuizPoolMappingComponent(alertService);
+ jest.spyOn(changeDetectorRef.constructor.prototype, 'detectChanges').mockImplementation();
+ jest.spyOn(component.quizPoolMappingComponent, 'hasGroupsWithNoQuestion').mockReturnValue(false);
+ jest.spyOn(component.quizPoolMappingComponent, 'hasGroupsWithDifferentQuestionPoints').mockReturnValue(true);
+ jest.spyOn(component.quizPoolMappingComponent, 'getGroupNamesWithDifferentQuestionPoints').mockReturnValue(['Test Group']);
+ component.handleUpdate();
+ expect(component.invalidReasons).toBeArrayOfSize(1);
+ expect(component.invalidReasons[0]).toEqual({
+ translateKey: 'artemisApp.quizPool.invalidReasons.groupHasDifferentQuestionPoints',
+ translateValues: {
+ name: 'Test Group',
+ },
+ });
+ });
+});
diff --git a/src/test/javascript/spec/service/quiz-pool.service.spec.ts b/src/test/javascript/spec/service/quiz-pool.service.spec.ts
new file mode 100644
index 000000000000..049a8be08df1
--- /dev/null
+++ b/src/test/javascript/spec/service/quiz-pool.service.spec.ts
@@ -0,0 +1,49 @@
+import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
+import { TestBed } from '@angular/core/testing';
+import { QuizPoolService } from 'app/exercises/quiz/manage/quiz-pool.service';
+import { ArtemisTestModule } from '../test.module';
+import { QuizPool } from 'app/entities/quiz/quiz-pool.model';
+import { firstValueFrom } from 'rxjs';
+
+describe('QuizPoolService', () => {
+ let quizPoolService: QuizPoolService;
+ let httpMock: HttpTestingController;
+
+ beforeEach(() => {
+ TestBed.configureTestingModule({
+ imports: [ArtemisTestModule, HttpClientTestingModule],
+ providers: [QuizPoolService],
+ });
+ quizPoolService = TestBed.inject(QuizPoolService);
+ httpMock = TestBed.inject(HttpTestingController);
+ });
+
+ it('should return updated quiz pool', async () => {
+ const updatedQuizPool = new QuizPool();
+ updatedQuizPool.id = 1;
+ const courseId = 2;
+ const examId = 3;
+ const quizPool = new QuizPool();
+ const response = firstValueFrom(quizPoolService.update(courseId, examId, quizPool));
+ const req = httpMock.expectOne({
+ method: 'PUT',
+ url: `api/courses/${courseId}/exams/${examId}/quiz-pools`,
+ });
+ req.flush(updatedQuizPool);
+ expect((await response)?.body).toEqual(updatedQuizPool);
+ });
+
+ it('should return quiz pool', async () => {
+ const quizPool = new QuizPool();
+ quizPool.id = 1;
+ const courseId = 2;
+ const examId = 3;
+ const response = firstValueFrom(quizPoolService.find(courseId, examId));
+ const req = httpMock.expectOne({
+ method: 'GET',
+ url: `api/courses/${courseId}/exams/${examId}/quiz-pools`,
+ });
+ req.flush(quizPool);
+ expect((await response)?.body).toEqual(quizPool);
+ });
+});