@Override public String getAnswerHtml(FeedbackQuestionDetails questionDetails) { FeedbackRubricQuestionDetails fqd = (FeedbackRubricQuestionDetails) questionDetails; StringBuilder html = new StringBuilder(100); for (int i = 0; i < answer.size(); i++) { int chosenIndex = answer.get(i); String chosenChoice = ""; if (chosenIndex == -1) { chosenChoice = "<span class=\"color_neutral\"><i>" + Const.INSTRUCTOR_FEEDBACK_RESULTS_MISSING_RESPONSE + "</i></span>"; html.append( StringHelper.integerToLowerCaseAlphabeticalIndex(i + 1) + ") " + chosenChoice + "<br>"); } else { chosenChoice = Sanitizer.sanitizeForHtml(fqd.getRubricChoices().get(answer.get(i))); html.append( StringHelper.integerToLowerCaseAlphabeticalIndex(i + 1) + ") " + chosenChoice + " <span class=\"color_neutral\"><i>(Choice " + (chosenIndex + 1) + ")</i></span><br>"); } } return html.toString(); }
/** * This method should be used by admin only since the previous searching does not restrict the * visibility according to the logged-in user's google ID. Therefore,This fromResults method does * not require a googleID as a parameter. Returned results bundle will contain information related * to matched instructors only. * * @param results * @return studentResultBundle containing information related to matched students only. */ public InstructorSearchResultBundle getInstructorsfromResults(Results<ScoredDocument> results) { if (results == null) { return this; } cursor = results.getCursor(); for (ScoredDocument doc : results) { InstructorAttributes instructor = JsonUtils.fromJson( doc.getOnlyField(Const.SearchDocumentField.INSTRUCTOR_ATTRIBUTE).getText(), InstructorAttributes.class); if (instructorsLogic.getInstructorForRegistrationKey(StringHelper.encrypt(instructor.key)) == null) { instructorsLogic.deleteDocument(instructor); continue; } instructorList.add(instructor); numberOfResults++; } sortInstructorResultList(); return this; }
/** * This recovers a set of html-sanitized string to original encoding for appropriate display in * files such as csv file <br> * It restores encoding for < > \ / ' & <br> * * @param sanitized string set * @return recovered string set */ public static Set<String> recoverFromSanitizedText(Set<String> textSet) { Set<String> textSetTemp = new HashSet<String>(); for (String text : textSet) { textSetTemp.add(StringHelper.recoverFromSanitizedText(text)); } return textSetTemp; }
public String getRegistrationUrl() { return new Url(Config.APP_URL + Const.ActionURIs.STUDENT_COURSE_JOIN_NEW) .withRegistrationKey(StringHelper.encrypt(key)) .withStudentEmail(email) .withCourseId(course) .toString(); }
public String toString(int indent) { String indentString = StringHelper.getIndent(indent); StringBuilder sb = new StringBuilder(); sb.append(indentString + "Student:" + name + "[" + email + "]" + EOL); return sb.toString(); }
@Test public void testGetStudent() throws InvalidParametersException, EntityDoesNotExistException { int currentNumberOfStudent = studentsDb.getAllStudents().size(); StudentAttributes s = createNewStudent(); s.googleId = "validGoogleId"; s.googleId = "validTeam"; studentsDb.updateStudent(s.course, s.email, s.name, s.team, s.email, s.googleId, s.comments); ______TS("typical success case: existent"); StudentAttributes retrieved = studentsDb.getStudentForEmail(s.course, s.email); assertNotNull(retrieved); assertNotNull(studentsDb.getStudentForRegistrationKey(retrieved.key)); assertNotNull(studentsDb.getStudentForRegistrationKey(StringHelper.encrypt(retrieved.key))); assertNull(studentsDb.getStudentForRegistrationKey("notExistingKey")); ______TS("non existant student case"); retrieved = studentsDb.getStudentForEmail("any-course-id", "*****@*****.**"); assertNull(retrieved); StudentAttributes s2 = createNewStudent("*****@*****.**"); s2.googleId = "validGoogleId2"; studentsDb.updateStudent( s2.course, s2.email, s2.name, s2.team, s2.email, s2.googleId, s2.comments); studentsDb.deleteStudentsForGoogleId(s2.googleId); assertNull(studentsDb.getStudentForGoogleId(s2.course, s2.googleId)); s2 = createNewStudent("*****@*****.**"); assertEquals( true, studentsDb.getUnregisteredStudentsForCourse(s2.course).get(0).isEnrollInfoSameAs(s2)); s2.googleId = null; studentsDb.updateStudent( s2.course, s2.email, s2.name, s2.team, s2.email, s2.googleId, s2.comments); assertEquals( true, studentsDb.getUnregisteredStudentsForCourse(s2.course).get(0).isEnrollInfoSameAs(s2)); assertTrue(s.isEnrollInfoSameAs(studentsDb.getStudentsForGoogleId(s.googleId).get(0))); assertEquals(true, studentsDb.getStudentsForCourse(s.course).get(0).isEnrollInfoSameAs(s)); assertEquals( true, studentsDb.getStudentsForTeam(s.team, s.course).get(0).isEnrollInfoSameAs(s)); assertEquals(2 + currentNumberOfStudent, studentsDb.getAllStudents().size()); ______TS("null params case"); try { studentsDb.getStudentForEmail(null, "*****@*****.**"); Assert.fail(); } catch (AssertionError a) { assertEquals(Const.StatusCodes.DBLEVEL_NULL_INPUT, a.getMessage()); } try { studentsDb.getStudentForEmail("any-course-id", null); Assert.fail(); } catch (AssertionError a) { assertEquals(Const.StatusCodes.DBLEVEL_NULL_INPUT, a.getMessage()); } }
public StudentAttributes( String section, String team, String name, String email, String comment, String courseId) { this(); this.section = Sanitizer.sanitizeTitle(section); this.team = Sanitizer.sanitizeTitle(team); this.lastName = Sanitizer.sanitizeName(StringHelper.splitName(name)[1]); this.name = Sanitizer.sanitizeName(name); this.email = Sanitizer.sanitizeEmail(email); this.comments = Sanitizer.sanitizeTextField(comment); this.course = Sanitizer.sanitizeTitle(courseId); }
private void testInputValidation() { ______TS("Checking max-length enforcement by the text boxes"); String maxLengthInstructorName = StringHelper.generateStringOfLength(FieldValidator.PERSON_NAME_MAX_LENGTH); String longInstructorName = StringHelper.generateStringOfLength(FieldValidator.PERSON_NAME_MAX_LENGTH + 1); courseEditPage.clickEditInstructorLink(1); courseEditPage.clickShowNewInstructorFormButton(); // Add instructor assertEquals( maxLengthInstructorName, courseEditPage.fillNewInstructorName(maxLengthInstructorName)); assertEquals( longInstructorName.substring(0, FieldValidator.PERSON_NAME_MAX_LENGTH), courseEditPage.fillNewInstructorName(longInstructorName)); // Edit instructor assertEquals( maxLengthInstructorName, courseEditPage.editInstructorName(1, maxLengthInstructorName)); assertEquals( longInstructorName.substring(0, FieldValidator.PERSON_NAME_MAX_LENGTH), courseEditPage.editInstructorName(1, longInstructorName)); String maxLengthEmail = StringHelper.generateStringOfLength(FieldValidator.EMAIL_MAX_LENGTH); String longEmail = StringHelper.generateStringOfLength(FieldValidator.EMAIL_MAX_LENGTH + 1); // Add instructor assertEquals(maxLengthEmail, courseEditPage.fillNewInstructorEmail(maxLengthEmail)); assertEquals( longEmail.substring(0, FieldValidator.EMAIL_MAX_LENGTH), courseEditPage.fillNewInstructorEmail(longEmail)); // Edit instructor assertEquals(maxLengthEmail, courseEditPage.editInstructorEmail(1, maxLengthEmail)); assertEquals( longEmail.substring(0, FieldValidator.EMAIL_MAX_LENGTH), courseEditPage.editInstructorEmail(1, longEmail)); }
@Test public void testExecuteAndPostProcess() throws Exception { InstructorsDb instrDb = new InstructorsDb(); InstructorAttributes instructor = dataBundle.instructors.get("instructor1OfCourse1"); instructor = instrDb.getInstructorForEmail(instructor.courseId, instructor.email); gaeSimulation.loginAsInstructor(instructor.googleId); ______TS("not enough parameters"); verifyAssumptionFailure(); ______TS("invalid key"); String[] submissionParams = new String[] {Const.ParamsNames.REGKEY, "invalidKey"}; InstructorCourseJoinAuthenticatedAction a = getAction(submissionParams); RedirectResult r = (RedirectResult) a.executeAndPostProcess(); assertEquals( Const.ActionURIs.INSTRUCTOR_HOME_PAGE + "?message=You+have+used+an+invalid+join+link" + "%3A+%2Fpage%2FinstructorCourseJoin%3Fregkey%3DinvalidKey" + "&error=true&user="******"instructor already registered"); submissionParams = new String[] {Const.ParamsNames.REGKEY, StringHelper.encrypt(instructor.key)}; a = getAction(submissionParams); r = (RedirectResult) a.executeAndPostProcess(); assertEquals( Const.ActionURIs.INSTRUCTOR_HOME_PAGE + "?message=idOfInstructor1OfCourse1+has+already+joined+this+course" + "&persistencecourse=" + instructor.courseId + "&error=true&user="******"instructor object belongs to another account"); InstructorAttributes instructor2 = dataBundle.instructors.get("instructor2OfCourse1"); instructor2 = instrDb.getInstructorForGoogleId(instructor2.courseId, instructor2.googleId); submissionParams = new String[] {Const.ParamsNames.REGKEY, StringHelper.encrypt(instructor2.key)}; a = getAction(submissionParams); r = (RedirectResult) a.executeAndPostProcess(); assertEquals( Const.ActionURIs.INSTRUCTOR_HOME_PAGE + "?message=The+join+link+used+belongs+to+a+different+user" + "+whose+Google+ID+is+idOfInst..fCourse1" + "+%28only+part+of+the+Google+ID+is+shown+to+protect+privacy%29." + "+If+that+Google+ID+is+owned+by+you%2C+please+logout+and" + "+re-login+using+that+Google+account.+If+it+doesn%E2%80%99t" + "+belong+to+you%2C+please+%3Ca+href%3D%22mailto" + "%3Ateammates%40comp.nus.edu.sg%3Fbody%3D" + "Your+name%3A%250AYour+course%3A%250AYour+university%3A%22%3E" + "contact+us%3C%2Fa%3E+so+that+we+can+investigate." + "&persistencecourse=" + instructor2.courseId + "&error=true&user="******"typical case"); instructor = new InstructorAttributes( "ICJAAT.instr", instructor.courseId, "New Instructor", "*****@*****.**"); InstructorsLogic.inst().addInstructor(instructor.courseId, instructor.name, instructor.email); AccountAttributes newInstructorAccount = new AccountAttributes(instructor.googleId, instructor.name, false, instructor.email, "NUS"); AccountsLogic.inst().createAccount(newInstructorAccount); InstructorAttributes newInstructor = instrDb.getInstructorForEmail(instructor.courseId, instructor.email); gaeSimulation.loginUser(instructor.googleId); submissionParams = new String[] {Const.ParamsNames.REGKEY, StringHelper.encrypt(newInstructor.key)}; a = getAction(submissionParams); r = (RedirectResult) a.executeAndPostProcess(); assertEquals( Const.ActionURIs.INSTRUCTOR_HOME_PAGE + "?persistencecourse=idOfTypicalCourse1" + "&error=false&user=ICJAAT.instr", r.getDestinationWithParams()); assertFalse(r.isError); InstructorAttributes retrievedInstructor = instrDb.getInstructorForEmail(instructor.courseId, instructor.email); assertEquals(instructor.googleId, retrievedInstructor.googleId); }
@Override public ActionResult execute() throws EntityDoesNotExistException { String newCourseId = getRequestParamValue(Const.ParamsNames.COURSE_ID); Assumption.assertNotNull(newCourseId); String newCourseName = getRequestParamValue(Const.ParamsNames.COURSE_NAME); Assumption.assertNotNull(newCourseName); /* Check if user has the right to execute the action */ new GateKeeper().verifyInstructorPrivileges(account); /* Create a new course in the database */ data = new InstructorCoursesPageData(account); CourseAttributes newCourse = new CourseAttributes(newCourseId, newCourseName); createCourse(newCourse); /* Prepare data for the refreshed page after executing the adding action */ List<CourseDetailsBundle> allCourses = new ArrayList<CourseDetailsBundle>( logic.getCourseSummariesForInstructor(data.account.googleId).values()); CourseDetailsBundle.sortDetailedCoursesByCourseId(allCourses); List<CourseDetailsBundle> activeCourses = logic.extractActiveCourses(allCourses, data.account.googleId); List<CourseDetailsBundle> archivedCourses = logic.extractArchivedCourses(allCourses, data.account.googleId); String CourseIdToShowParam = ""; String CourseNameToShowParam = ""; if (isError) { // there is error in adding the course CourseIdToShowParam = Sanitizer.sanitizeForHtml(newCourse.id); CourseNameToShowParam = Sanitizer.sanitizeForHtml(newCourse.name); List<String> statusMessageTexts = new ArrayList<String>(); for (StatusMessage msg : statusToUser) { statusMessageTexts.add(msg.getText()); } statusToAdmin = StringHelper.toString(statusMessageTexts, "<br>"); } else { statusToAdmin = "Course added : " + newCourse.id; statusToAdmin += "<br>Total courses: " + allCourses.size(); } List<CourseAttributes> courseList = logic.getCoursesForInstructor(data.account.googleId); Map<String, InstructorAttributes> instructorsForCourses = new HashMap<String, InstructorAttributes>(); for (CourseAttributes course : courseList) { instructorsForCourses.put( course.id, logic.getInstructorForGoogleId(course.id, data.account.googleId)); } data.init( activeCourses, archivedCourses, instructorsForCourses, CourseIdToShowParam, CourseNameToShowParam); return createShowPageResult(Const.ViewURIs.INSTRUCTOR_COURSES, data); }
@Override protected ActionResult execute() throws EntityDoesNotExistException { courseId = getRequestParamValue(Const.ParamsNames.COURSE_ID); feedbackSessionName = getRequestParamValue(Const.ParamsNames.FEEDBACK_SESSION_NAME); Assumption.assertPostParamNotNull(Const.ParamsNames.COURSE_ID, courseId); Assumption.assertPostParamNotNull(Const.ParamsNames.FEEDBACK_SESSION_NAME, feedbackSessionName); setAdditionalParameters(); verifyAccesibleForSpecificUser(); String userEmailForCourse = getUserEmailForCourse(); String userTeamForCourse = getUserTeamForCourse(); String userSectionForCourse = getUserSectionForCourse(); data = new FeedbackSubmissionEditPageData(account, student); data.bundle = getDataBundle(userEmailForCourse); Assumption.assertNotNull( "Feedback session " + feedbackSessionName + " does not exist in " + courseId + ".", data.bundle); checkAdditionalConstraints(); setStatusToAdmin(); if (!isSessionOpenForSpecificUser(data.bundle.feedbackSession)) { isError = true; statusToUser.add( new StatusMessage( Const.StatusMessages.FEEDBACK_SUBMISSIONS_NOT_OPEN, StatusMessageColor.WARNING)); return createSpecificRedirectResult(); } int numOfQuestionsToGet = data.bundle.questionResponseBundle.size(); for (int questionIndx = 1; questionIndx <= numOfQuestionsToGet; questionIndx++) { String totalResponsesForQuestion = getRequestParamValue( Const.ParamsNames.FEEDBACK_QUESTION_RESPONSETOTAL + "-" + questionIndx); if (totalResponsesForQuestion == null) { continue; // question has been skipped (not displayed). } List<FeedbackResponseAttributes> responsesForQuestion = new ArrayList<FeedbackResponseAttributes>(); String questionId = HttpRequestHelper.getValueFromParamMap( requestParameters, Const.ParamsNames.FEEDBACK_QUESTION_ID + "-" + questionIndx); FeedbackQuestionAttributes questionAttributes = data.bundle.getQuestionAttributes(questionId); if (questionAttributes == null) { statusToUser.add( new StatusMessage( "The feedback session or questions may have changed while you were submitting. " + "Please check your responses to make sure they are saved correctly.", StatusMessageColor.WARNING)); isError = true; log.warning( "Question not found. (deleted or invalid id passed?) id: " + questionId + " index: " + questionIndx); continue; } FeedbackQuestionDetails questionDetails = questionAttributes.getQuestionDetails(); int numOfResponsesToGet = Integer.parseInt(totalResponsesForQuestion); String qnId = ""; Set<String> emailSet = data.bundle.getRecipientEmails(questionAttributes.getId()); emailSet.add(""); emailSet = StringHelper.recoverFromSanitizedText(emailSet); ArrayList<String> responsesRecipients = new ArrayList<String>(); List<String> errors = new ArrayList<String>(); for (int responseIndx = 0; responseIndx < numOfResponsesToGet; responseIndx++) { FeedbackResponseAttributes response = extractFeedbackResponseData( requestParameters, questionIndx, responseIndx, questionAttributes); if (response.feedbackQuestionType != questionAttributes.questionType) { errors.add( String.format( Const.StatusMessages.FEEDBACK_RESPONSES_WRONG_QUESTION_TYPE, questionIndx)); } qnId = response.feedbackQuestionId; boolean isExistingResponse = response.getId() != null; // test that if editing an existing response, that the edited response's id // came from the original set of existing responses loaded on the submission page if (isExistingResponse && !isExistingResponseValid(response)) { errors.add( String.format(Const.StatusMessages.FEEDBACK_RESPONSES_INVALID_ID, questionIndx)); continue; } responsesRecipients.add(response.recipientEmail); // if the answer is not empty but the recipient is empty if (response.recipientEmail.isEmpty() && !response.responseMetaData.getValue().isEmpty()) { errors.add( String.format( Const.StatusMessages.FEEDBACK_RESPONSES_MISSING_RECIPIENT, questionIndx)); } if (response.responseMetaData.getValue().isEmpty()) { // deletes the response since answer is empty saveResponse(response); } else { response.giverEmail = questionAttributes.giverType.isTeam() ? userTeamForCourse : userEmailForCourse; response.giverSection = userSectionForCourse; responsesForQuestion.add(response); } } List<String> questionSpecificErrors = questionDetails.validateResponseAttributes( responsesForQuestion, data.bundle.recipientList.get(qnId).size()); errors.addAll(questionSpecificErrors); if (!emailSet.containsAll(responsesRecipients)) { errors.add( String.format(Const.StatusMessages.FEEDBACK_RESPONSE_INVALID_RECIPIENT, questionIndx)); } if (errors.isEmpty()) { for (FeedbackResponseAttributes response : responsesForQuestion) { saveResponse(response); } } else { List<StatusMessage> errorMessages = new ArrayList<StatusMessage>(); for (String error : errors) { errorMessages.add(new StatusMessage(error, StatusMessageColor.DANGER)); } statusToUser.addAll(errorMessages); isError = true; } } if (!isError) { statusToUser.add( new StatusMessage( Const.StatusMessages.FEEDBACK_RESPONSES_SAVED, StatusMessageColor.SUCCESS)); } if (isUserRespondentOfSession()) { appendRespondant(); } else { removeRespondant(); } return createSpecificRedirectResult(); }
private boolean isMultipleFieldsEmpty() { int numEmptyFields = StringHelper.countEmptyStrings(shortName, email, nationality, moreInfo, pictureKey); return numEmptyFields > 1; }
@Test public void testValidate() { EvaluationAttributes e = new EvaluationAttributes(); e.courseId = ""; e.name = ""; e.instructions = new Text("Instruction to students."); e.startTime = TimeHelper.getDateOffsetToCurrentTime(1); e.endTime = TimeHelper.getDateOffsetToCurrentTime(2); e.activated = false; e.published = false; e.timeZone = 0.0; e.gracePeriod = 5; e.p2pEnabled = true; assertEquals("invalid values", false, e.isValid()); String errorMessage = String.format(COURSE_ID_ERROR_MESSAGE, e.courseId, REASON_EMPTY) + EOL + String.format(EVALUATION_NAME_ERROR_MESSAGE, e.name, REASON_EMPTY); assertEquals("valid values", errorMessage, StringHelper.toString(e.getInvalidityInfo())); e.courseId = "valid-course"; e.name = "valid name"; e.instructions = new Text("valid instructions"); assertTrue("valid, minimal properties", e.isValid()); assertEquals("valid values", true, e.isValid()); e.startTime = null; try { e.getInvalidityInfo(); signalFailureToDetectException("null start time not detected"); } catch (AssertionError e1) { ignoreExpectedException(); } e.startTime = TimeHelper.getDateOffsetToCurrentTime(1); e.endTime = null; try { e.getInvalidityInfo(); signalFailureToDetectException("null end time not detected"); } catch (AssertionError e1) { ignoreExpectedException(); } // SUCCESS : end == start e.endTime = TimeHelper.getDateOffsetToCurrentTime(1); e.startTime = e.endTime; assertTrue(e.isValid()); // FAIL : end before start e.endTime = TimeHelper.getDateOffsetToCurrentTime(1); e.startTime = TimeHelper.getDateOffsetToCurrentTime(2); assertFalse(e.isValid()); errorMessage = String.format( TIME_FRAME_ERROR_MESSAGE, END_TIME_FIELD_NAME, EVALUATION_NAME, START_TIME_FIELD_NAME); assertEquals(errorMessage, StringHelper.toString(e.getInvalidityInfo())); // FAIL : published before endtime: invalid e.published = true; e.startTime = TimeHelper.getDateOffsetToCurrentTime(0); e.endTime = TimeHelper.getMsOffsetToCurrentTime(5); assertFalse(e.isValid()); assertEquals( FieldValidator.EVALUATION_END_TIME_ERROR_MESSAGE, StringHelper.toString(e.getInvalidityInfo())); // SUCCESS : just after endtime and published: valid e.startTime = TimeHelper.getDateOffsetToCurrentTime(-1); e.endTime = TimeHelper.getMsOffsetToCurrentTime(-5); e.published = true; assertTrue(e.isValid()); // FAIL : activated before start time: invalid e.startTime = TimeHelper.getDateOffsetToCurrentTime(1); e.endTime = TimeHelper.getDateOffsetToCurrentTime(2); e.published = false; e.activated = true; assertFalse(e.isValid()); assertEquals( FieldValidator.EVALUATION_START_TIME_ERROR_MESSAGE, StringHelper.toString(e.getInvalidityInfo())); }
public String getPublicProfilePictureUrl() { return new Url(Const.ActionURIs.STUDENT_PROFILE_PICTURE) .withStudentEmail(StringHelper.encrypt(email)) .withCourseId(StringHelper.encrypt(course)) .toString(); }
public class InstructorCourseJoinConfirmationPageUiTest extends BaseUiTestCase { private static Browser browser; private static DataBundle testData; private static InstructorCourseJoinConfirmationPage confirmationPage; String invalidEncryptedKey = StringHelper.encrypt("invalidKey"); @BeforeClass public void classSetup() { printTestClassHeader(); testData = loadDataBundle("/InstructorCourseJoinConfirmationPageUiTest.json"); // use the instructor account injected for this test testData.instructors.get("ICJConfirmationUiT.instr.CS2104").googleId = TestProperties.TEST_INSTRUCTOR_ACCOUNT; testData.instructors.get("ICJConfirmationUiT.instr.CS2104").email = TestProperties.TEST_INSTRUCTOR_ACCOUNT + "@gmail.com"; testData.instructors.get("ICJConfirmationUiT.instr.CS1101").email = TestProperties.TEST_INSTRUCTOR_ACCOUNT + "@gmail.com"; removeAndRestoreDataBundle(testData); browser = BrowserPool.getBrowser(true); browser.driver.manage().deleteAllCookies(); } @Test public void testAll() throws Exception { testContent(); testJoinConfirmation(); } private void testContent() { /*covered in testJoinConfirmation() *case: Click join link then confirm: success: valid key */ } private void testJoinConfirmation() throws Exception { ______TS("Click join link then cancel"); String joinLink = createUrl(Const.ActionURIs.INSTRUCTOR_COURSE_JOIN) .withRegistrationKey(invalidEncryptedKey) .toAbsoluteString(); logout(browser); browser.driver.get(joinLink); confirmationPage = AppPage.createCorrectLoginPageType(browser) .loginAsJoiningInstructor( TestProperties.TEST_INSTRUCTOR_ACCOUNT, TestProperties.TEST_INSTRUCTOR_PASSWORD); confirmationPage.clickCancelButton(); ______TS("Click join link then confirm: fail: invalid key"); browser.driver.get(joinLink); confirmationPage = AppPage.createCorrectLoginPageType(browser) .loginAsJoiningInstructor( TestProperties.TEST_INSTRUCTOR_ACCOUNT, TestProperties.TEST_INSTRUCTOR_PASSWORD); InstructorHomePage instructorHome = confirmationPage.clickConfirmButton(); instructorHome.verifyContains( "You have used an invalid join link: /page/instructorCourseJoin?key=" + invalidEncryptedKey); ______TS("Click join link then confirm: success: valid key"); String courseId = testData.courses.get("ICJConfirmationUiT.CS1101").getId(); String instructorEmail = testData.instructors.get("ICJConfirmationUiT.instr.CS1101").email; String regkey = BackDoor.getEncryptedKeyForInstructor(courseId, instructorEmail); joinLink = createUrl(Const.ActionURIs.INSTRUCTOR_COURSE_JOIN) .withRegistrationKey(regkey) .toAbsoluteString(); browser.driver.get(joinLink); confirmationPage = AppPage.getNewPageInstance(browser, InstructorCourseJoinConfirmationPage.class); // test content here to make test finish faster ______TS("test instructor confirmation page content"); // this test uses accounts from test.properties // This is the full HTML verification for Instructor Course Join Confirmation Page, // the rest can all be verifyMainHtml confirmationPage.verifyHtml("/instructorCourseJoinConfirmationHTML.html"); instructorHome = confirmationPage.clickConfirmButton(); ______TS("Already joined, no confirmation page"); browser.driver.get(joinLink); instructorHome = AppPage.getNewPageInstance(browser, InstructorHomePage.class); instructorHome.verifyStatus( TestProperties.TEST_INSTRUCTOR_ACCOUNT + " has already joined this course"); } @AfterClass public static void classTearDown() { BrowserPool.release(browser); } }
@SuppressWarnings("deprecation") private void testCreateInstructorAction() throws Exception { InstructorAttributes instructor = new InstructorAttributes(); String shortName = "Instrúctör"; instructor.name = "AHPUiT Instrúctör"; instructor.email = "*****@*****.**"; String institute = "TEAMMATES Test Institute 1"; String demoCourseId = "AHPUiT.instr1.gma-demo"; ______TS( "action success : create instructor account and the account is created successfully after user's verification"); BackDoor.deleteAccount(TestProperties.inst().TEST_INSTRUCTOR_ACCOUNT); BackDoor.deleteCourse(demoCourseId); BackDoor.deleteInstructor(demoCourseId, instructor.email); homePage.createInstructor(shortName, instructor, institute); String expectedjoinUrl = Config.APP_URL + Const.ActionURIs.INSTRUCTOR_COURSE_JOIN; expectedjoinUrl = Url.addParamToUrl( expectedjoinUrl, Const.ParamsNames.REGKEY, StringHelper.encrypt(BackDoor.getKeyForInstructor(demoCourseId, instructor.email))); expectedjoinUrl = Url.addParamToUrl(expectedjoinUrl, Const.ParamsNames.INSTRUCTOR_INSTITUTION, institute); homePage .getStatus() .contains( "Instructor AHPUiT Instrúctör has been successfully created with join link:\n" + expectedjoinUrl); homePage.logout(); // verify the instructor and the demo course have been created assertNotNull(BackDoor.getCourse(demoCourseId)); assertNotNull(BackDoor.getInstructorByEmail(instructor.email, demoCourseId)); // get the joinURL which sent to the requester's email String joinActionUrl = TestProperties.inst().TEAMMATES_URL + Const.ActionURIs.INSTRUCTOR_COURSE_JOIN; String joinLink = Url.addParamToUrl( joinActionUrl, Const.ParamsNames.REGKEY, StringHelper.encrypt(BackDoor.getKeyForInstructor(demoCourseId, instructor.email))); joinLink = Url.addParamToUrl(joinLink, Const.ParamsNames.INSTRUCTOR_INSTITUTION, institute); // simulate the user's verification here because it is added by admin browser.driver.get(joinLink); confirmationPage = createCorrectLoginPageType(browser.driver.getPageSource()) .loginAsJoiningInstructor( TestProperties.inst().TEST_INSTRUCTOR_ACCOUNT, TestProperties.inst().TEST_INSTRUCTOR_PASSWORD); confirmationPage.clickCancelButton(); browser.driver.get(joinLink); confirmationPage = createCorrectLoginPageType(browser.driver.getPageSource()) .loginAsJoiningInstructor( TestProperties.inst().TEST_INSTRUCTOR_ACCOUNT, TestProperties.inst().TEST_INSTRUCTOR_PASSWORD); confirmationPage.clickConfirmButton(); // check a account has been created for the requester successfully assertNotNull(BackDoor.getAccount(TestProperties.inst().TEST_INSTRUCTOR_ACCOUNT)); // verify sample course is accessible for newly joined instructor as an instructor ______TS("new instructor can see sample course in homepage"); InstructorHomePage instructorHomePage = AppPage.getNewPageInstance(browser, InstructorHomePage.class); instructorHomePage.verifyHtmlMainContent("/newlyJoinedInstructorHomePage.html"); ______TS("new instructor can access sample coure enroll page"); InstructorCourseEnrollPage enrollPage = instructorHomePage.clickCourseErollLink(demoCourseId); enrollPage.verifyHtmlMainContent("/newlyJoinedInstructorCourseEnrollPage.html"); ______TS("new instructor can access sample coure details page"); instructorHomePage = enrollPage.goToPreviousPage(InstructorHomePage.class); InstructorCourseDetailsPage detailsPage = instructorHomePage.clickCourseViewLink(demoCourseId); detailsPage.verifyHtmlMainContent("/newlyJoinedInstructorCourseDetailsPage.html"); ______TS("new instructor can access sample coure edit page"); instructorHomePage = detailsPage.goToPreviousPage(InstructorHomePage.class); InstructorCourseEditPage editPage = instructorHomePage.clickCourseEditLink(demoCourseId); editPage.verifyHtmlMainContent("/newlyJoinedInstructorCourseEditPage.html"); ______TS("new instructor can access sample coure feedback session adding page"); instructorHomePage = editPage.goToPreviousPage(InstructorHomePage.class); InstructorFeedbacksPage feedbacksPage = instructorHomePage.clickCourseAddEvaluationLink(demoCourseId); feedbacksPage.verifyHtmlMainContent("/newlyJoinedInstructorFeedbacksPage.html"); ______TS("new instructor can archive sample course"); instructorHomePage = feedbacksPage.goToPreviousPage(InstructorHomePage.class); instructorHomePage.clickArchiveCourseLinkAndConfirm(demoCourseId); instructorHomePage.verifyHtmlMainContent( "/newlyJoinedInstructorHomePageSampleCourseArchived.html"); ______TS("new instructor can unarchive sample course"); String url = Url.addParamToUrl( TestProperties.inst().TEAMMATES_URL + Const.ActionURIs.INSTRUCTOR_COURSES_PAGE, Const.ParamsNames.USER_ID, TestProperties.inst().TEST_INSTRUCTOR_ACCOUNT); browser.driver.get(url); InstructorCoursesPage coursesPage = AppPage.getNewPageInstance(browser, InstructorCoursesPage.class); coursesPage.unarchiveCourse(demoCourseId); coursesPage.verifyHtmlMainContent( "/newlyJoinedInstructorCoursesPageSampleCourseUnarhived.html"); ______TS("new instructor can access sample course students page"); coursesPage .loadStudentsTab() .verifyHtmlMainContent("/newlyJoinedInstructorStudentListPage.html"); ______TS("new instructor can access sample course comments page"); coursesPage .loadInstructorCommentsTab() .verifyHtmlMainContent("/newlyJoinedInstructorCommentsPage.html"); ______TS("new instructor can view feedbackSession result of sample course"); coursesPage.loadInstructorHomeTab(); instructorHomePage = AppPage.getNewPageInstance(browser, InstructorHomePage.class); instructorHomePage .clickFeedbackSessionViewResultsLink( "AHPUiT.instr1.gma-demo", "Second team feedback session") .verifyHtmlMainContent("/newlyJoinedInstructorFeedbackResultsPage.html"); ______TS("new instructor can edit feedbackSession of sample course"); instructorHomePage.loadInstructorHomeTab(); InstructorFeedbackEditPage feedbackEditPage = instructorHomePage.clickFeedbackSessionEditLink( "AHPUiT.instr1.gma-demo", "Second team feedback session"); feedbackEditPage.clickEditSessionButton(); FeedbackSessionAttributes feedbackSession = BackDoor.getFeedbackSession("AHPUiT.instr1.gma-demo", "Second team feedback session"); feedbackEditPage.editFeedbackSession( feedbackSession.startTime, feedbackSession.endTime, new Text("updated instructions"), feedbackSession.gracePeriod); instructorHomePage.verifyHtmlMainContent( "/newlyJoinedInstructorFeedbackSessionSuccessEdited.html"); ______TS("new instructor can click submit button of sample feedbackSession"); instructorHomePage.loadInstructorHomeTab(); FeedbackSubmitPage fbsp = instructorHomePage.clickFeedbackSessionSubmitLink( "AHPUiT.instr1.gma-demo", "Second team feedback session"); fbsp.verifyHtmlMainContent("/newlyJoinedInstructorFeedbackSubmissionEditPage.html"); ______TS("new instructor can send reminder of sample course"); instructorHomePage.loadInstructorHomeTab(); feedbacksPage = instructorHomePage.clickFeedbackSessionRemindLink( "AHPUiT.instr1.gma-demo", "Second team feedback session"); feedbacksPage.verifyHtmlMainContent("/newlyJoinedInstructorFeedbackSessionRemind.html"); ______TS("new instructor can unpublish feedbackSession of sample course"); instructorHomePage.loadInstructorHomeTab(); feedbacksPage = instructorHomePage.clickFeedbackSessionUnpublishLink( "AHPUiT.instr1.gma-demo", "Second team feedback session"); feedbacksPage.verifyHtmlMainContent("/newlyJoinedInstructorFeedbackSessionUnpublished.html"); ______TS("new instructor can publish feedbackSession of sample course"); instructorHomePage.loadInstructorHomeTab(); feedbacksPage = instructorHomePage.clickFeedbackSessionPublishLink( "AHPUiT.instr1.gma-demo", "Second team feedback session"); feedbacksPage.verifyHtmlMainContent("/newlyJoinedInstructorFeedbackSessionPublished.html"); feedbacksPage.logout(); ______TS("action failure : invalid parameter"); Url homeUrl = createUrl(Const.ActionURIs.ADMIN_HOME_PAGE); homePage = loginAdminToPage(browser, homeUrl, AdminHomePage.class); instructor.email = "AHPUiT.email.tmt"; homePage .createInstructor(shortName, instructor, institute) .verifyStatus( String.format( FieldValidator.EMAIL_ERROR_MESSAGE, instructor.email, FieldValidator.REASON_INCORRECT_FORMAT)); ______TS("action success: course is accessible for newly joined instructor as student"); // in staging server, the student account uses the hardcoded email above, so this can only be // test on dev server if (!TestProperties.inst().TEAMMATES_URL.contains("local")) { BackDoor.deleteCourse(demoCourseId); BackDoor.deleteAccount(TestProperties.inst().TEST_INSTRUCTOR_ACCOUNT); BackDoor.deleteInstructor(demoCourseId, instructor.email); return; } // verify sample course is accessible for newly joined instructor as an student StudentHomePage studentHomePage = HomePage.getNewInstance(browser) .clickStudentLogin() .loginAsStudent( TestProperties.inst().TEST_INSTRUCTOR_ACCOUNT, TestProperties.inst().TEST_INSTRUCTOR_PASSWORD); studentHomePage.verifyContains(demoCourseId); studentHomePage.clickViewTeam(); StudentCourseDetailsPage courseDetailsPage = AppPage.getNewPageInstance(browser, StudentCourseDetailsPage.class); courseDetailsPage.verifyHtmlMainContent("/newlyJoinedInstructorStudentCourseDetailsPage.html"); studentHomePage = courseDetailsPage.goToPreviousPage(StudentHomePage.class); studentHomePage.getViewFeedbackButton("First team feedback session").click(); StudentFeedbackResultsPage sfrp = AppPage.getNewPageInstance(browser, StudentFeedbackResultsPage.class); sfrp.verifyHtmlMainContent("/newlyJoinedInstructorStudentFeedbackResultsPage.html"); studentHomePage = sfrp.goToPreviousPage(StudentHomePage.class); studentHomePage.getEditFeedbackButton("First team feedback session").click(); FeedbackSubmitPage fsp = AppPage.getNewPageInstance(browser, FeedbackSubmitPage.class); fsp.verifyHtmlMainContent("/newlyJoinedInstructorStudentFeedbackSubmissionEdit.html"); studentHomePage = fsp.loadStudentHomeTab(); StudentCommentsPage scp = studentHomePage.loadStudentCommentsTab(); scp.verifyHtmlMainContent("/newlyJoinedInstructorStudentCommentsPage.html"); studentHomePage = scp.loadStudentHomeTab(); StudentProfilePage spp = studentHomePage.loadProfileTab(); spp.verifyContains("Student Profile"); spp.verifyContains("AHPUiT Instrúctör"); studentHomePage.logout(); // login in as instructor again to test sample course deletion instructorHomePage = HomePage.getNewInstance(browser) .clickInstructorLogin() .loginAsInstructor( TestProperties.inst().TEST_INSTRUCTOR_ACCOUNT, TestProperties.inst().TEST_INSTRUCTOR_PASSWORD); instructorHomePage.clickAndConfirm(instructorHomePage.getDeleteCourseLink(demoCourseId)); assertTrue( instructorHomePage .getStatus() .contains("The course " + demoCourseId + " has been deleted.")); instructorHomePage.logout(); BackDoor.deleteAccount(TestProperties.inst().TEST_INSTRUCTOR_ACCOUNT); BackDoor.deleteCourse(demoCourseId); BackDoor.deleteInstructor(demoCourseId, instructor.email); }
@Test public void testExecuteAndPostProcess() throws Exception { StudentsDb studentsDb = new StudentsDb(); AccountsDb accountsDb = new AccountsDb(); StudentAttributes student1InCourse1 = dataBundle.students.get("student1InCourse1"); student1InCourse1 = studentsDb.getStudentForGoogleId(student1InCourse1.course, student1InCourse1.googleId); gaeSimulation.loginAsStudent(student1InCourse1.googleId); ______TS("not enough parameters"); verifyAssumptionFailure(); ______TS("invalid key"); String invalidKey = StringHelper.encrypt("invalid key"); String[] submissionParams = new String[] { Const.ParamsNames.REGKEY, invalidKey, Const.ParamsNames.NEXT_URL, Const.ActionURIs.STUDENT_HOME_PAGE }; try { StudentCourseJoinAuthenticatedAction authenticatedAction = getAction(submissionParams); getRedirectResult(authenticatedAction); } catch (UnauthorizedAccessException uae) { assertEquals("No student with given registration key:" + invalidKey, uae.getMessage()); } ______TS("already registered student"); submissionParams = new String[] { Const.ParamsNames.REGKEY, StringHelper.encrypt(student1InCourse1.key), Const.ParamsNames.NEXT_URL, Const.ActionURIs.STUDENT_PROFILE_PAGE }; StudentCourseJoinAuthenticatedAction authenticatedAction = getAction(submissionParams); RedirectResult redirectResult = getRedirectResult(authenticatedAction); assertEquals( Const.ActionURIs.STUDENT_HOME_PAGE + "?error=true&user="******"You (student1InCourse1) have already joined this course", redirectResult.getStatusMessage()); /*______TS("student object belongs to another account"); StudentAttributes student2InCourse1 = dataBundle.students .get("student2InCourse1"); student2InCourse1 = studentsDb.getStudentForGoogleId( student2InCourse1.course, student2InCourse1.googleId); submissionParams = new String[] { Const.ParamsNames.REGKEY, StringHelper.encrypt(student2InCourse1.key), Const.ParamsNames.NEXT_URL, Const.ActionURIs.STUDENT_HOME_PAGE }; authenticatedAction = getAction(submissionParams); redirectResult = getRedirectResult(authenticatedAction); assertEquals( Const.ActionURIs.STUDENT_HOME_PAGE + "?persistencecourse=" + student1InCourse1.course + "&error=true&user="******"The join link used belongs to a different user" + " whose Google ID is stude..ourse1 " + "(only part of the Google ID is shown to protect privacy)." + " If that Google ID is owned by you, " + "please logout and re-login using that Google account." + " If it doesn’t belong to you, please " + "<a href=\"mailto:" + Config.SUPPORT_EMAIL + "?body=Your name:%0AYour course:%0AYour university:\">" + "contact us</a> so that we can investigate.", redirectResult.getStatusMessage()); */ ______TS("join course with no feedback sessions, profile is empty"); AccountAttributes studentWithEmptyProfile = dataBundle.accounts.get("noFSStudent"); studentWithEmptyProfile = accountsDb.getAccount(studentWithEmptyProfile.googleId, true); assertNotNull(studentWithEmptyProfile.studentProfile); assertEquals("", studentWithEmptyProfile.studentProfile.pictureKey); assertEquals("", studentWithEmptyProfile.studentProfile.shortName); assertEquals("", studentWithEmptyProfile.studentProfile.nationality); assertEquals("", studentWithEmptyProfile.studentProfile.moreInfo); assertEquals("", studentWithEmptyProfile.studentProfile.email); StudentAttributes studentWithEmptyProfileAttributes = dataBundle.students.get("noFSStudentWithNoProfile"); studentWithEmptyProfileAttributes = studentsDb.getStudentForEmail( studentWithEmptyProfileAttributes.course, studentWithEmptyProfileAttributes.email); gaeSimulation.loginUser("idOfNoFSStudent"); submissionParams = new String[] { Const.ParamsNames.REGKEY, StringHelper.encrypt(studentWithEmptyProfileAttributes.key), Const.ParamsNames.NEXT_URL, Const.ActionURIs.STUDENT_HOME_PAGE }; authenticatedAction = getAction(submissionParams); redirectResult = getRedirectResult(authenticatedAction); assertEquals( Const.ActionURIs.STUDENT_HOME_PAGE + "?persistencecourse=idOfCourseNoEvals" + "&error=false&user=idOfNoFSStudent", redirectResult.getDestinationWithParams()); assertFalse(redirectResult.isError); assertEquals( String.format( Const.StatusMessages.STUDENT_COURSE_JOIN_SUCCESSFUL, "[idOfCourseNoEvals] Typical Course 3 with 0 Evals") + "<br>" + String.format( Const.StatusMessages.HINT_FOR_NO_SESSIONS_STUDENT, "[idOfCourseNoEvals] Typical Course 3 with 0 Evals") + "<br>" + Const.StatusMessages.STUDENT_UPDATE_PROFILE, redirectResult.getStatusMessage()); ______TS("join course with no feedback sessions, profile has only one missing field"); AccountAttributes studentWithoutProfilePicture = dataBundle.accounts.get("noFSStudent2"); studentWithoutProfilePicture = accountsDb.getAccount(studentWithoutProfilePicture.googleId, true); assertNotNull(studentWithoutProfilePicture.studentProfile); assertEquals("", studentWithoutProfilePicture.studentProfile.pictureKey); assertFalse(studentWithoutProfilePicture.studentProfile.nationality.isEmpty()); assertFalse(studentWithoutProfilePicture.studentProfile.shortName.isEmpty()); assertFalse(studentWithoutProfilePicture.studentProfile.moreInfo.isEmpty()); assertFalse(studentWithoutProfilePicture.studentProfile.email.isEmpty()); StudentAttributes studentWithoutProfilePictureAttributes = dataBundle.students.get("noFSStudentWithPartialProfile"); studentWithoutProfilePictureAttributes = studentsDb.getStudentForEmail( studentWithoutProfilePictureAttributes.course, studentWithoutProfilePictureAttributes.email); gaeSimulation.loginUser("idOfNoFSStudent2"); submissionParams = new String[] { Const.ParamsNames.REGKEY, StringHelper.encrypt(studentWithoutProfilePictureAttributes.key), Const.ParamsNames.NEXT_URL, Const.ActionURIs.STUDENT_HOME_PAGE }; authenticatedAction = getAction(submissionParams); redirectResult = getRedirectResult(authenticatedAction); assertEquals( Const.ActionURIs.STUDENT_HOME_PAGE + "?persistencecourse=idOfCourseNoEvals" + "&error=false&user=idOfNoFSStudent2", redirectResult.getDestinationWithParams()); assertFalse(redirectResult.isError); assertEquals( String.format( Const.StatusMessages.STUDENT_COURSE_JOIN_SUCCESSFUL, "[idOfCourseNoEvals] Typical Course 3 with 0 Evals") + "<br>" + String.format( Const.StatusMessages.HINT_FOR_NO_SESSIONS_STUDENT, "[idOfCourseNoEvals] Typical Course 3 with 0 Evals") + "<br>" + Const.StatusMessages.STUDENT_UPDATE_PROFILE_PICTURE, redirectResult.getStatusMessage()); ______TS("join course with no feedback sessions, profile has no missing field"); AccountAttributes studentWithFullProfile = dataBundle.accounts.get("noFSStudent3"); studentWithFullProfile = accountsDb.getAccount(studentWithFullProfile.googleId, true); assertNotNull(studentWithFullProfile.studentProfile); assertFalse(studentWithFullProfile.studentProfile.pictureKey.isEmpty()); assertFalse(studentWithoutProfilePicture.studentProfile.nationality.isEmpty()); assertFalse(studentWithoutProfilePicture.studentProfile.shortName.isEmpty()); assertFalse(studentWithoutProfilePicture.studentProfile.moreInfo.isEmpty()); assertFalse(studentWithoutProfilePicture.studentProfile.email.isEmpty()); StudentAttributes studentWithFullProfileAttributes = dataBundle.students.get("noFSStudentWithFullProfile"); studentWithFullProfileAttributes = studentsDb.getStudentForEmail( studentWithFullProfileAttributes.course, studentWithFullProfileAttributes.email); gaeSimulation.loginUser("idOfNoFSStudent3"); submissionParams = new String[] { Const.ParamsNames.REGKEY, StringHelper.encrypt(studentWithFullProfileAttributes.key), Const.ParamsNames.NEXT_URL, Const.ActionURIs.STUDENT_HOME_PAGE }; authenticatedAction = getAction(submissionParams); redirectResult = getRedirectResult(authenticatedAction); assertEquals( Const.ActionURIs.STUDENT_HOME_PAGE + "?persistencecourse=idOfCourseNoEvals" + "&error=false&user=idOfNoFSStudent3", redirectResult.getDestinationWithParams()); assertFalse(redirectResult.isError); assertEquals( String.format( Const.StatusMessages.STUDENT_COURSE_JOIN_SUCCESSFUL, "[idOfCourseNoEvals] Typical Course 3 with 0 Evals") + "<br>" + String.format( Const.StatusMessages.HINT_FOR_NO_SESSIONS_STUDENT, "[idOfCourseNoEvals] Typical Course 3 with 0 Evals"), redirectResult.getStatusMessage()); ______TS("typical case"); AccountAttributes newStudentAccount = new AccountAttributes( "idOfNewStudent", "nameOfNewStudent", false, "*****@*****.**", "TEAMMATES Test Institute 5"); accountsDb.createAccount(newStudentAccount); StudentAttributes newStudentAttributes = new StudentAttributes( student1InCourse1.section, student1InCourse1.team, "nameOfNewStudent", "*****@*****.**", "This is a new student", student1InCourse1.course); studentsDb.createEntity(newStudentAttributes); newStudentAttributes = studentsDb.getStudentForEmail(newStudentAttributes.course, newStudentAttributes.email); gaeSimulation.loginUser("idOfNewStudent"); submissionParams = new String[] { Const.ParamsNames.REGKEY, StringHelper.encrypt(newStudentAttributes.key), Const.ParamsNames.NEXT_URL, Const.ActionURIs.STUDENT_PROFILE_PAGE }; authenticatedAction = getAction(submissionParams); redirectResult = getRedirectResult(authenticatedAction); assertEquals( Const.ActionURIs.STUDENT_PROFILE_PAGE + "?persistencecourse=idOfTypicalCourse1" + "&error=false&user=idOfNewStudent", redirectResult.getDestinationWithParams()); assertFalse(redirectResult.isError); assertEquals( String.format( Const.StatusMessages.STUDENT_COURSE_JOIN_SUCCESSFUL, "[idOfTypicalCourse1] Typical Course 1 with 2 Evals"), redirectResult.getStatusMessage()); }
public static String generateStringOfLength(int length) { return StringHelper.generateStringOfLength(length, 'a'); }