private void testActionSuccessTypical(AccountAttributes student) {
    gaeSimulation.loginAsStudent(student.googleId);
    ______TS("Typical case");
    String[] submissionParams = new String[] {};
    StudentProfilePageAction action = getAction(submissionParams);
    ShowPageResult result = (ShowPageResult) action.executeAndPostProcess();

    AssertHelper.assertContains(
        "/jsp/studentProfilePage.jsp?error=false&user="******"", result.getStatusMessage());

    verifyAccountsAreSame(student, result);
    verifyLogMessage(student, action, false);
  }
  private void testActionInMasquerade(AccountAttributes student) {
    gaeSimulation.loginAsAdmin("admin.user");
    ______TS("Typical case: masquerade mode");
    String[] submissionParams =
        new String[] {
          Const.ParamsNames.STUDENT_PROFILE_PHOTOEDIT,
          "false",
          Const.ParamsNames.USER_ID,
          student.googleId
        };

    StudentProfilePageAction action =
        getAction(addUserIdToParams(student.googleId, submissionParams));
    ShowPageResult result = (ShowPageResult) action.executeAndPostProcess();

    AssertHelper.assertContains(
        Const.ViewURIs.STUDENT_PROFILE_PAGE + "?error=false&user="******"", result.getStatusMessage());

    verifyAccountsAreSame(student, result);
    verifyLogMessage(student, action, true);
  }
  @Test
  public void testExecute() throws Exception {
    InstructorAttributes instructor1OfCourse1 = dataBundle.instructors.get("instructor1OfCourse1");
    String instructorId = instructor1OfCourse1.googleId;

    String adminUserId = "admin.user";

    gaeSimulation.loginAsInstructor(instructorId);

    ______TS("Not enough parameters");
    verifyAssumptionFailure();
    verifyAssumptionFailure(Const.ParamsNames.COURSE_NAME, "ticac tac name");

    ______TS("Error: Invalid parameter for Course ID");

    Action addAction =
        getAction(
            Const.ParamsNames.COURSE_ID, "ticac,tpa1,id",
            Const.ParamsNames.COURSE_NAME, "ticac tpa1 name");
    ShowPageResult pageResult = (ShowPageResult) addAction.executeAndPostProcess();

    assertEquals(
        Const.ViewURIs.INSTRUCTOR_COURSES + "?error=true&user=idOfInstructor1OfCourse1",
        pageResult.getDestinationWithParams());
    assertEquals(true, pageResult.isError);
    assertEquals(Const.StatusMessages.COURSE_INVALID_ID, pageResult.getStatusMessage());

    InstructorCoursesPageData pageData = (InstructorCoursesPageData) pageResult.data;
    assertEquals(1, pageData.allCourses.size());

    String expectedLogMessage =
        "TEAMMATESLOG|||instructorCourseAdd|||instructorCourseAdd"
            + "|||true|||Instructor|||Instructor 1 of Course 1|||idOfInstructor1OfCourse1|||[email protected]"
            + "|||Please use only alphabets, numbers, dots, hyphens, underscores and dollar signs in course ID."
            + "|||/page/instructorCourseAdd";
    assertEquals(expectedLogMessage, addAction.getLogMessage());

    ______TS("Typical case, 1 existing course");

    addAction =
        getAction(
            Const.ParamsNames.COURSE_ID, "ticac.tpa1.id",
            Const.ParamsNames.COURSE_NAME, "ticac tpa1 name");
    pageResult = (ShowPageResult) addAction.executeAndPostProcess();

    pageData = (InstructorCoursesPageData) pageResult.data;
    assertEquals(2, pageData.allCourses.size());

    expectedLogMessage =
        "TEAMMATESLOG|||instructorCourseAdd"
            + "|||instructorCourseAdd|||true|||Instructor|||Instructor 1 of Course 1"
            + "|||idOfInstructor1OfCourse1|||[email protected]"
            + "|||Course added : ticac.tpa1.id<br>Total courses: 2|||/page/instructorCourseAdd";
    assertEquals(expectedLogMessage, addAction.getLogMessage());

    String expected =
        Const.StatusMessages.COURSE_ADDED
            .replace(
                "${courseEnrollLink}",
                "/page/instructorCourseEnrollPage?courseid=ticac.tpa1.id&user=idOfInstructor1OfCourse1")
            .replace(
                "${courseEditLink}",
                "/page/instructorCourseEditPage?courseid=ticac.tpa1.id&user=idOfInstructor1OfCourse1");
    assertEquals(expected, pageResult.getStatusMessage());

    ______TS("Error: Try to add the same course again");

    addAction =
        getAction(
            Const.ParamsNames.COURSE_ID, "ticac.tpa1.id",
            Const.ParamsNames.COURSE_NAME, "ticac tpa1 name");
    pageResult = (ShowPageResult) addAction.executeAndPostProcess();

    assertEquals(
        Const.ViewURIs.INSTRUCTOR_COURSES + "?error=true&user=idOfInstructor1OfCourse1",
        pageResult.getDestinationWithParams());
    assertEquals(true, pageResult.isError);
    assertEquals(Const.StatusMessages.COURSE_EXISTS, pageResult.getStatusMessage());

    pageData = (InstructorCoursesPageData) pageResult.data;
    assertEquals(2, pageData.allCourses.size());

    expectedLogMessage =
        "TEAMMATESLOG|||instructorCourseAdd|||instructorCourseAdd"
            + "|||true|||Instructor|||Instructor 1 of Course 1|||idOfInstructor1OfCourse1"
            + "|||[email protected]|||A course by the same ID already exists in the system, possibly created by another user. Please choose a different course ID"
            + "|||/page/instructorCourseAdd";
    assertEquals(expectedLogMessage, addAction.getLogMessage());

    ______TS("Masquerade mode, 0 courses");

    CoursesLogic.inst().deleteCourseCascade(instructor1OfCourse1.courseId);
    CoursesLogic.inst().deleteCourseCascade("ticac.tpa1.id");
    gaeSimulation.loginAsAdmin(adminUserId);
    addAction =
        getAction(
            Const.ParamsNames.USER_ID, instructorId,
            Const.ParamsNames.COURSE_ID, "ticac.tpa2.id",
            Const.ParamsNames.COURSE_NAME, "ticac tpa2 name");
    pageResult = (ShowPageResult) addAction.executeAndPostProcess();

    String expectedDestination =
        Const.ViewURIs.INSTRUCTOR_COURSES + "?error=false&user=idOfInstructor1OfCourse1";
    assertEquals(expectedDestination, pageResult.getDestinationWithParams());
    assertEquals(false, pageResult.isError);
    String expectedStatus =
        "The course has been added.. Click <a href=\"/page/instructorCourseEnrollPage?courseid=ticac.tpa2.id&user=idOfInstructor1OfCourse1\">here</a> to add students to the course or "
            + "click <a href=\"/page/instructorCourseEditPage?courseid=ticac.tpa2.id&user=idOfInstructor1OfCourse1\">here</a> to add other instructors.<br>If you don't see the course in the list below, please refresh the page after a few moments.";
    assertEquals(expectedStatus, pageResult.getStatusMessage());

    pageData = (InstructorCoursesPageData) pageResult.data;
    assertEquals(1, pageData.allCourses.size());

    expectedLogMessage =
        "TEAMMATESLOG|||instructorCourseAdd|||instructorCourseAdd"
            + "|||true|||Instructor(M)|||Instructor 1 of Course 1"
            + "|||idOfInstructor1OfCourse1|||[email protected]|||Course added : ticac.tpa2.id<br>Total courses: 1"
            + "|||/page/instructorCourseAdd";
    assertEquals(expectedLogMessage, addAction.getLogMessage());

    // delete the new course
    CoursesLogic.inst().deleteCourseCascade("ticac.tpa2.id");
  }
  @Test
  public void testExecuteAndPostProcess() throws Exception {
    InstructorAttributes instructor = dataBundle.instructors.get("instructor3OfCourse1");
    StudentAttributes student = dataBundle.students.get("student2InCourse1");
    String instructorId = instructor.googleId;

    gaeSimulation.loginAsInstructor(instructorId);

    ______TS("Invalid parameters");

    // no params
    verifyAssumptionFailure();

    // null courseId
    String[] invalidParams = new String[] {Const.ParamsNames.STUDENT_EMAIL, student.email};

    verifyAssumptionFailure(invalidParams);

    // null student email
    invalidParams = new String[] {Const.ParamsNames.COURSE_ID, instructor.courseId};

    verifyAssumptionFailure(invalidParams);

    // student not in course
    String studentEmailOfStudent1InCourse2 = dataBundle.students.get("student1InCourse2").email;
    invalidParams =
        new String[] {
          Const.ParamsNames.COURSE_ID,
          instructor.courseId,
          Const.ParamsNames.STUDENT_EMAIL,
          studentEmailOfStudent1InCourse2
        };

    RedirectResult redirect = getRedirectResult(getAction(invalidParams));

    AssertHelper.assertContains(
        Const.ActionURIs.INSTRUCTOR_HOME_PAGE, redirect.getDestinationWithParams());
    AssertHelper.assertContains(
        Const.StatusMessages.STUDENT_NOT_FOUND_FOR_RECORDS, redirect.getStatusMessage());

    ______TS("Typical case: student has some records and has profile");

    String[] submissionParams =
        new String[] {
          Const.ParamsNames.COURSE_ID, instructor.courseId,
          Const.ParamsNames.STUDENT_EMAIL, student.email
        };

    InstructorStudentRecordsPageAction a = getAction(submissionParams);
    ShowPageResult r = getShowPageResult(a);

    assertEquals(
        Const.ViewURIs.INSTRUCTOR_STUDENT_RECORDS + "?error=false&user=idOfInstructor3",
        r.getDestinationWithParams());
    assertFalse(r.isError);
    assertEquals("", r.getStatusMessage());

    InstructorStudentRecordsPageData actualData = (InstructorStudentRecordsPageData) r.data;
    StudentProfileAttributes expectedProfile = new StudentProfileAttributes();
    expectedProfile.googleId = student.googleId;
    expectedProfile.modifiedDate = actualData.spa.modifiedDate;
    expectedProfile.pictureKey = actualData.spa.pictureKey;

    assertEquals(instructorId, actualData.account.googleId);
    assertEquals(instructor.courseId, actualData.getCourseId());
    assertEquals(1, actualData.getCommentsForStudentTable().get(0).getRows().size());
    assertEquals(6, actualData.getSessionNames().size());
    assertEquals(student.googleId, actualData.spa.googleId);

    String expectedLogMessage =
        "TEAMMATESLOG|||instructorStudentRecordsPage|||instructorStudentRecordsPage"
            + "|||true|||Instructor|||Instructor 3 of Course 1 and 2|||idOfInstructor3"
            + "|||[email protected]|||instructorStudentRecords Page Load<br>"
            + "Viewing <span class=\"bold\">"
            + student.email
            + "'s</span> records "
            + "for Course <span class=\"bold\">["
            + instructor.courseId
            + "]</span><br>"
            + "Number of sessions: 6<br>"
            + "Student Profile: "
            + expectedProfile.toString()
            + "|||/page/instructorStudentRecordsPage";
    AssertHelper.assertLogMessageEquals(expectedLogMessage, a.getLogMessage());

    ______TS("Typical case: instructor cannot view sections");

    instructor = dataBundle.instructors.get("helperOfCourse1");
    gaeSimulation.loginAsInstructor(instructor.googleId);

    submissionParams =
        new String[] {
          Const.ParamsNames.COURSE_ID, instructor.courseId,
          Const.ParamsNames.STUDENT_EMAIL, student.email
        };

    a = getAction(submissionParams);
    r = getShowPageResult(a);

    assertEquals(
        Const.ViewURIs.INSTRUCTOR_STUDENT_RECORDS + "?error=false&user=idOfHelperOfCourse1",
        r.getDestinationWithParams());
    assertFalse(r.isError);
    assertEquals(
        "Normally, we would show the student’s profile here. "
            + "However, you do not have access to view this student's profile<br>"
            + "No records were found for this student",
        r.getStatusMessage());

    ______TS("Typical case: student has no records, no profiles");

    String instructor4Id = dataBundle.instructors.get("instructor4").googleId;
    // re-login as another instructor for new test
    gaeSimulation.loginAsInstructor(instructor4Id);
    String courseIdWithNoSession = "idOfCourseNoEvals";

    StudentAttributes testStudent = createStudentInTypicalDataBundleForCourseWithNoSession();

    String[] submissionParamsWithNoSession =
        new String[] {
          Const.ParamsNames.COURSE_ID,
          courseIdWithNoSession,
          Const.ParamsNames.STUDENT_EMAIL,
          "*****@*****.**"
        };

    InstructorStudentRecordsPageAction aWithNoSession = getAction(submissionParamsWithNoSession);
    ShowPageResult rWithNoSession = getShowPageResult(aWithNoSession);
    List<String> expectedMessages = new ArrayList<String>();
    expectedMessages.add("No records were found for this student");
    expectedMessages.add(Const.StatusMessages.STUDENT_NOT_JOINED_YET_FOR_RECORDS);
    AssertHelper.assertContains(expectedMessages, rWithNoSession.getStatusMessage());

    ______TS("Typical case: student has profile but no records");

    testStudent.googleId = "valid.no.sessions";
    StudentsLogic.inst().updateStudentCascadeWithoutDocument(testStudent.email, testStudent);
    logic.createAccount(
        testStudent.googleId, testStudent.name, false, testStudent.email, "valid institute");

    a = getAction(submissionParamsWithNoSession);
    r = getShowPageResult(a);

    AssertHelper.assertContains("No records were found for this student", r.getStatusMessage());
  }