diff --git a/src/e2e/java/teammates/e2e/cases/sql/FeedbackMcqQuestionE2ETest.java b/src/e2e/java/teammates/e2e/cases/sql/FeedbackMcqQuestionE2ETest.java new file mode 100644 index 00000000000..2ac889f826a --- /dev/null +++ b/src/e2e/java/teammates/e2e/cases/sql/FeedbackMcqQuestionE2ETest.java @@ -0,0 +1,140 @@ +package teammates.e2e.cases.sql; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +import org.testng.annotations.Test; + +import teammates.common.datatransfer.questions.FeedbackMcqQuestionDetails; +import teammates.common.datatransfer.questions.FeedbackMcqResponseDetails; +import teammates.e2e.pageobjects.FeedbackSubmitPage; +import teammates.e2e.pageobjects.InstructorFeedbackEditPage; +import teammates.storage.sqlentity.FeedbackQuestion; +import teammates.storage.sqlentity.FeedbackResponse; + +/** + * SUT: {@link Const.WebPageURIs#INSTRUCTOR_SESSION_EDIT_PAGE}, + * {@link Const.WebPageURIs#SESSION_SUBMISSION_PAGE} + * specifically for MCQ questions. + */ +public class FeedbackMcqQuestionE2ETest extends BaseFeedbackQuestionE2ETest { + + @Override + protected void prepareTestData() { + testData = removeAndRestoreDataBundle(loadSqlDataBundle("/FeedbackMcqQuestionE2ESqlTest.json")); + + instructor = testData.instructors.get("instructor"); + course = testData.courses.get("course"); + feedbackSession = testData.feedbackSessions.get("openSession"); + student = testData.students.get("alice.tmms@FMcqQn.CS2104"); + } + + @Test + @Override + public void testAll() { + testEditPage(); + logout(); + testSubmitPage(); + } + + @Override + protected void testEditPage() { + InstructorFeedbackEditPage feedbackEditPage = loginToFeedbackEditPage(); + + ______TS("verify loaded question"); + FeedbackQuestion loadedQuestion = testData.feedbackQuestions.get("qn1ForFirstSession"); + FeedbackMcqQuestionDetails questionDetails = (FeedbackMcqQuestionDetails) loadedQuestion + .getQuestionDetailsCopy(); + feedbackEditPage.verifyMcqQuestionDetails(1, questionDetails); + + ______TS("add new question"); + // add new question exactly like loaded question + loadedQuestion.setQuestionNumber(2); + feedbackEditPage.addMcqQuestion(loadedQuestion); + + feedbackEditPage.verifyMcqQuestionDetails(2, questionDetails); + verifyPresentInDatabase(loadedQuestion); + + ______TS("copy question"); + FeedbackQuestion copiedQuestion = testData.feedbackQuestions.get("qn1ForSecondSession"); + questionDetails = (FeedbackMcqQuestionDetails) copiedQuestion.getQuestionDetailsCopy(); + feedbackEditPage.copyQuestion(copiedQuestion.getCourseId(), + copiedQuestion.getQuestionDetailsCopy().getQuestionText()); + copiedQuestion.setFeedbackSession(feedbackSession); + copiedQuestion.setQuestionNumber(3); + + feedbackEditPage.verifyMcqQuestionDetails(3, questionDetails); + verifyPresentInDatabase(copiedQuestion); + + ______TS("edit question"); + questionDetails = (FeedbackMcqQuestionDetails) loadedQuestion.getQuestionDetailsCopy(); + questionDetails.setHasAssignedWeights(false); + questionDetails.setMcqWeights(new ArrayList<>()); + questionDetails.setOtherEnabled(false); + questionDetails.setQuestionDropdownEnabled(false); + questionDetails.setMcqOtherWeight(0); + List choices = questionDetails.getMcqChoices(); + choices.add("Edited choice"); + questionDetails.setMcqChoices(choices); + loadedQuestion = testData.feedbackQuestions.get("qn1ForFirstSession").makeDeepCopy(feedbackSession); + loadedQuestion.setQuestionDetails(questionDetails); + feedbackEditPage.editMcqQuestion(2, questionDetails); + feedbackEditPage.waitForPageToLoad(); + + feedbackEditPage.verifyMcqQuestionDetails(2, questionDetails); + verifyPresentInDatabase(loadedQuestion); + } + + @Override + protected void testSubmitPage() { + FeedbackSubmitPage feedbackSubmitPage = loginToFeedbackSubmitPage(); + + ______TS("verify loaded question"); + FeedbackQuestion question = testData.feedbackQuestions.get("qn1ForFirstSession"); + feedbackSubmitPage.verifyMcqQuestion(1, "", + (FeedbackMcqQuestionDetails) question.getQuestionDetailsCopy()); + + ______TS("verify question with generated options"); + feedbackSubmitPage.verifyGeneratedMcqQuestion(3, "", getGeneratedStudentOptions()); + + ______TS("submit response"); + FeedbackResponse response = getResponse(question, false, "UI"); + feedbackSubmitPage.fillMcqResponse(1, "", response); + feedbackSubmitPage.clickSubmitQuestionButton(1); + + // verifyPresentInDatabase(response); + + // ______TS("check previous response"); + // feedbackSubmitPage = getFeedbackSubmitPage(); + // feedbackSubmitPage.verifyMcqResponse(1, "", response); + + // ______TS("edit response"); + // response = getResponse(questionId, true, "This is the edited response."); + // feedbackSubmitPage.fillMcqResponse(1, "", response); + // feedbackSubmitPage.clickSubmitQuestionButton(1); + + // feedbackSubmitPage = getFeedbackSubmitPage(); + // feedbackSubmitPage.verifyMcqResponse(1, "", response); + // verifyPresentInDatabase(response); + } + + private List getGeneratedStudentOptions() { + return testData.students.values().stream() + .filter(s -> s.getCourse().equals(student.getCourse())) + .map(s -> s.getName() + " (" + s.getTeam().getName() + ")") + .collect(Collectors.toList()); + } + + private FeedbackResponse getResponse(FeedbackQuestion feedbackQuestion, boolean isOther, String answer) { + FeedbackMcqResponseDetails details = new FeedbackMcqResponseDetails(); + if (isOther) { + details.setOther(true); + details.setOtherFieldContent(answer); + } else { + details.setAnswer(answer); + } + return FeedbackResponse.makeResponse(feedbackQuestion, student.getEmail(), null, instructor.getEmail(), null, + details); + } +} diff --git a/src/e2e/java/teammates/e2e/pageobjects/FeedbackSubmitPage.java b/src/e2e/java/teammates/e2e/pageobjects/FeedbackSubmitPage.java index 2690df6e866..e32bbcaaa96 100644 --- a/src/e2e/java/teammates/e2e/pageobjects/FeedbackSubmitPage.java +++ b/src/e2e/java/teammates/e2e/pageobjects/FeedbackSubmitPage.java @@ -215,6 +215,22 @@ public void fillMcqResponse(int qnNumber, String recipient, FeedbackResponseAttr } } + public void fillMcqResponse(int qnNumber, String recipient, FeedbackResponse response) { + FeedbackMcqResponseDetails responseDetails = (FeedbackMcqResponseDetails) response.getFeedbackResponseDetailsCopy(); + if (responseDetails.isOther()) { + markOptionAsSelected(getMcqOtherOptionRadioBtn(qnNumber, recipient)); + fillTextBox(getMcqOtherOptionTextbox(qnNumber, recipient), responseDetails.getOtherFieldContent()); + } else { + List optionTexts = getMcqOptions(qnNumber, recipient); + for (int i = 0; i < optionTexts.size(); i++) { + if (optionTexts.get(i).getText().equals(responseDetails.getAnswer())) { + markOptionAsSelected(getMcqRadioBtns(qnNumber, recipient).get(i)); + break; + } + } + } + } + public void verifyMcqResponse(int qnNumber, String recipient, FeedbackResponseAttributes response) { FeedbackMcqResponseDetails responseDetails = (FeedbackMcqResponseDetails) response.getResponseDetailsCopy(); if (responseDetails.isOther()) { diff --git a/src/e2e/java/teammates/e2e/pageobjects/InstructorFeedbackEditPage.java b/src/e2e/java/teammates/e2e/pageobjects/InstructorFeedbackEditPage.java index 4eeebab77b9..f104afcc7ba 100644 --- a/src/e2e/java/teammates/e2e/pageobjects/InstructorFeedbackEditPage.java +++ b/src/e2e/java/teammates/e2e/pageobjects/InstructorFeedbackEditPage.java @@ -605,6 +605,15 @@ public void addMcqQuestion(FeedbackQuestionAttributes feedbackQuestion) { clickSaveNewQuestionButton(); } + public void addMcqQuestion(FeedbackQuestion feedbackQuestion) { + addNewQuestion(3); + int questionNum = getNumQuestions(); + inputQuestionDetails(questionNum, feedbackQuestion); + FeedbackMcqQuestionDetails questionDetails = (FeedbackMcqQuestionDetails) feedbackQuestion.getQuestionDetailsCopy(); + inputMcqDetails(questionNum, questionDetails); + clickSaveNewQuestionButton(); + } + public void editMcqQuestion(int questionNum, FeedbackMcqQuestionDetails questionDetails) { clickEditQuestionButton(questionNum); inputMcqDetails(questionNum, questionDetails); diff --git a/src/e2e/resources/data/FeedbackMcqQuestionE2ESqlTest.json b/src/e2e/resources/data/FeedbackMcqQuestionE2ESqlTest.json new file mode 100644 index 00000000000..1745f1115c3 --- /dev/null +++ b/src/e2e/resources/data/FeedbackMcqQuestionE2ESqlTest.json @@ -0,0 +1,268 @@ +{ + "accounts": { + "instructorWithSessions": { + "id": "00000000-0000-4000-8000-000000000001", + "googleId": "tm.e2e.FMcqQn.instructor", + "name": "Teammates Test", + "email": "tmms.test@gmail.tmt" + }, + "tm.e2e.FMcqQn.alice.tmms": { + "id": "00000000-0000-4000-8000-000000000002", + "googleId": "tm.e2e.FMcqQn.alice.tmms", + "name": "Alice Betsy", + "email": "alice.b.tmms@gmail.tmt" + }, + "tm.e2e.FMcqQn.benny.tmms": { + "id": "00000000-0000-4000-8000-000000000003", + "googleId": "tm.e2e.FMcqQn.benny.tmms", + "name": "Benny Charles", + "email": "benny.c.tmms@gmail.tmt" + } + }, + "accountRequests": {}, + "courses": { + "course": { + "id": "tm.e2e.FMcqQn.CS2104", + "name": "Programming Language Concepts", + "institute": "TEAMMATES Test Institute 1", + "timeZone": "Africa/Johannesburg" + }, + "course2": { + "id": "tm.e2e.FMcqQn.CS1101", + "name": "Programming Methodology", + "institute": "TEAMMATES Test Institute 1", + "timeZone": "Africa/Johannesburg" + } + }, + "instructors": { + "instructor": { + "id": "00000000-0000-4000-8000-000000000501", + "account": { + "id": "00000000-0000-4000-8000-000000000001" + }, + "name": "Teammates Test", + "email": "tmms.test@gmail.tmt", + "role": "INSTRUCTOR_PERMISSION_ROLE_COOWNER", + "isDisplayedToStudents": true, + "displayName": "Co-owner", + "privileges": { + "courseLevel": { + "canViewStudentInSections": true, + "canSubmitSessionInSections": true, + "canModifySessionCommentsInSections": true, + "canModifyCourse": true, + "canViewSessionInSections": true, + "canModifySession": true, + "canModifyStudent": true, + "canModifyInstructor": true + }, + "sectionLevel": {}, + "sessionLevel": {} + }, + "course": { + "id": "tm.e2e.FMcqQn.CS2104" + } + }, + "instructor2": { + "id": "00000000-0000-4000-8000-000000000502", + "account": { + "id": "00000000-0000-4000-8000-000000000001" + }, + "course": { + "id": "tm.e2e.FMcqQn.CS1101" + }, + "displayName": "Co-owner", + "email": "tmms.test@gmail.tmt", + "isDisplayedToStudents": true, + "name": "Teammates Test", + "privileges": { + "courseLevel": { + "canModifyCourse": true, + "canModifyInstructor": true, + "canModifySession": true, + "canModifySessionCommentsInSections": true, + "canModifyStudent": true, + "canSubmitSessionInSections": true, + "canViewSessionInSections": true, + "canViewStudentInSections": true + }, + "sectionLevel": { + }, + "sessionLevel": { + } + }, + "role": "INSTRUCTOR_PERMISSION_ROLE_COOWNER" + } + }, + "sections": { + "ProgrammingLanguageConceptsSection1": { + "id": "00000000-0000-4000-8000-000000000101", + "course": { + "id": "tm.e2e.FMcqQn.CS2104" + }, + "name": "Section 1" + } + }, + "teams": { + "ProgrammingLanguageConceptsTeam1": { + "id": "00000000-0000-4000-8000-000000000201", + "section": { + "id": "00000000-0000-4000-8000-000000000101" + }, + "name": "Team 1" + } + }, + "students": { + "alice.tmms@FMcqQn.CS2104": { + "id": "00000000-0000-4000-8000-000000000601", + "account": { + "id": "00000000-0000-4000-8000-000000000002" + }, + "course": { + "id": "tm.e2e.FMcqQn.CS2104" + }, + "team": { + "id": "00000000-0000-4000-8000-000000000201" + }, + "email": "alice.b.tmms@gmail.tmt", + "name": "Alice Betsy", + "comments": "This student's name is Alice Betsy" + }, + "benny.tmms@FMcqQn.CS2104": { + "id": "00000000-0000-4000-8000-000000000602", + "account": { + "id": "00000000-0000-4000-8000-000000000003" + }, + "course": { + "id": "tm.e2e.FMcqQn.CS2104" + }, + "team": { + "id": "00000000-0000-4000-8000-000000000201" + }, + "email": "benny.c.tmms@gmail.tmt", + "name": "Benny Charles", + "comments": "This student's name is Benny Charles" + } + }, + "feedbackSessions": { + "openSession": { + "id": "00000000-0000-4000-8000-000000000701", + "name": "First Session", + "creatorEmail": "tmms.test@gmail.tmt", + "instructions": "

Instructions for first session

", + "createdTime": "2012-04-01T23:59:00Z", + "startTime": "2012-04-01T22:00:00Z", + "endTime": "2026-04-30T22:00:00Z", + "sessionVisibleFromTime": "2012-04-01T22:00:00Z", + "resultsVisibleFromTime": "2026-05-01T22:00:00Z", + "timeZone": "Africa/Johannesburg", + "gracePeriod": 10, + "sentOpenEmail": false, + "sentClosingEmail": false, + "sentClosedEmail": false, + "sentPublishedEmail": false, + "isOpeningEmailEnabled": true, + "isClosingEmailEnabled": true, + "isPublishedEmailEnabled": true, + "studentDeadlines": {}, + "instructorDeadlines": {}, + "course": { + "id": "tm.e2e.FMcqQn.CS2104" + } + }, + "openSession2": { + "id": "00000000-0000-4000-8000-000000000702", + "name": "Second Session", + "creatorEmail": "tmms.test@gmail.tmt", + "instructions": "

Instructions for Second session

", + "createdTime": "2012-04-01T23:59:00Z", + "startTime": "2012-04-01T22:00:00Z", + "endTime": "2026-04-30T22:00:00Z", + "sessionVisibleFromTime": "2012-04-01T22:00:00Z", + "resultsVisibleFromTime": "2026-05-01T22:00:00Z", + "timeZone": "Africa/Johannesburg", + "gracePeriod": 10, + "sentOpenEmail": false, + "sentClosingEmail": false, + "sentClosedEmail": false, + "sentPublishedEmail": false, + "isOpeningEmailEnabled": true, + "isClosingEmailEnabled": true, + "isPublishedEmailEnabled": true, + "studentDeadlines": {}, + "instructorDeadlines": {}, + "course": { + "id": "tm.e2e.FMcqQn.CS1101" + } + } + }, + "feedbackQuestions": { + "qn1ForFirstSession": { + "id": "00000000-0000-4000-8000-000000000801", + "feedbackSession": { + "id": "00000000-0000-4000-8000-000000000701" + }, + "questionDetails": { + "questionType": "MCQ", + "questionText": "Which area did you work on the most?", + "mcqChoices": [ + "UI", + "Algo", + "Testing" + ], + "otherEnabled": true, + "hasAssignedWeights": true, + "mcqWeights": [ + 30.61, + 29.4, + 20 + ], + "mcqOtherWeight": 60 + }, + "description": "

Testing description for first session

", + "questionNumber": 1, + "giverType": "STUDENTS", + "recipientType": "NONE", + "numOfEntitiesToGiveFeedbackTo": 1, + "showResponsesTo": [ + "INSTRUCTORS" + ], + "showGiverNameTo": [ + "INSTRUCTORS" + ], + "showRecipientNameTo": [ + "INSTRUCTORS" + ] + }, + "qn1ForSecondSession": { + "id": "00000000-0000-4000-8000-000000000802", + "feedbackSession": { + "id": "00000000-0000-4000-8000-000000000702" + }, + "questionDetails": { + "mcqChoices": [], + "questionText": "Who is the best student?", + "questionType": "MCQ", + "generateOptionsFor": "STUDENTS", + "otherEnabled": false + }, + "description": "

Testing description for second session

", + "questionNumber": 1, + "giverType": "STUDENTS", + "recipientType": "NONE", + "numOfEntitiesToGiveFeedbackTo": 1, + "showResponsesTo": [ + "INSTRUCTORS" + ], + "showGiverNameTo": [ + "INSTRUCTORS" + ], + "showRecipientNameTo": [ + "INSTRUCTORS" + ] + } + }, + "feedbackResponseComments": {}, + "notifications": {}, + "readNotifications": {} +} diff --git a/src/e2e/resources/testng-e2e-sql.xml b/src/e2e/resources/testng-e2e-sql.xml index 533f8e5343f..bfb28c3b2c0 100644 --- a/src/e2e/resources/testng-e2e-sql.xml +++ b/src/e2e/resources/testng-e2e-sql.xml @@ -6,6 +6,7 @@ + diff --git a/src/main/java/teammates/sqllogic/core/FeedbackQuestionsLogic.java b/src/main/java/teammates/sqllogic/core/FeedbackQuestionsLogic.java index e502e2d2189..02dd878541c 100644 --- a/src/main/java/teammates/sqllogic/core/FeedbackQuestionsLogic.java +++ b/src/main/java/teammates/sqllogic/core/FeedbackQuestionsLogic.java @@ -340,7 +340,7 @@ public void populateFieldsToGenerateInQuestion(FeedbackQuestion feedbackQuestion } for (Student student : studentList) { - optionList.add(student.getName() + " (" + student.getTeam() + ")"); + optionList.add(student.getName() + " (" + student.getTeam().getName() + ")"); } optionList.sort(null);