private List<StudentAttributes> createStudentList(String... studentData) {
   List<StudentAttributes> students = new ArrayList<StudentAttributes>();
   for (int i = 0; i < studentData.length; i = i + 2) {
     StudentAttributes student = new StudentAttributes();
     student.team = studentData[i];
     student.email = studentData[i + 1];
     students.add(student);
   }
   return students;
 }
 public StudentListTeamData(TeamDetailsBundle team, Map<String, String> emailPhotoUrlMapping, String googleId) {
     this.teamName = team.name;
     List<StudentListStudentData> studentsDetails =
                                     new ArrayList<StudentListStudentData>();
     for (StudentAttributes student: team.students) {
         studentsDetails.add(new StudentListStudentData(googleId, student.name, student.email, student.course,
                                                        student.getStudentStatus(),
                                                        emailPhotoUrlMapping.get(student.email)));
     }
     this.students = studentsDetails;
 }
  @Test
  public void testDeleteStudent() throws InvalidParametersException, EntityDoesNotExistException {
    StudentAttributes s = createNewStudent();
    s.googleId = "validGoogleId";
    studentsDb.updateStudent(s.course, s.email, s.name, s.team, s.email, s.googleId, s.comments);
    // Delete
    studentsDb.deleteStudent(s.course, s.email);

    StudentAttributes deleted = studentsDb.getStudentForEmail(s.course, s.email);

    assertNull(deleted);
    studentsDb.deleteStudentsForGoogleId(s.googleId);
    assertEquals(null, studentsDb.getStudentForGoogleId(s.course, s.googleId));
    int currentStudentNum = studentsDb.getAllStudents().size();
    s = createNewStudent();
    createNewStudent("*****@*****.**");
    assertEquals(2 + currentStudentNum, studentsDb.getAllStudents().size());
    studentsDb.deleteStudentsForCourse(s.course);
    assertEquals(currentStudentNum, studentsDb.getAllStudents().size());
    // delete again - should fail silently
    studentsDb.deleteStudent(s.course, s.email);

    // Null params check:
    try {
      studentsDb.deleteStudent(null, s.email);
      Assert.fail();
    } catch (AssertionError a) {
      assertEquals(Const.StatusCodes.DBLEVEL_NULL_INPUT, a.getMessage());
    }

    try {
      studentsDb.deleteStudent(s.course, null);
      Assert.fail();
    } catch (AssertionError a) {
      assertEquals(Const.StatusCodes.DBLEVEL_NULL_INPUT, a.getMessage());
    }
  }
  @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());
    }
  }
  private StudentAttributes createNewStudent(String email) throws InvalidParametersException {
    StudentAttributes s = new StudentAttributes();
    s.name = "valid student 2";
    s.course = "valid-course";
    s.email = email;
    s.team = "valid team name";
    s.comments = "";
    s.googleId = "";
    try {
      studentsDb.createEntity(s);
    } catch (EntityAlreadyExistsException e) {
      // Okay if it's already inside
    }

    return s;
  }
  @Test
  public void testCreateStudent() throws EntityAlreadyExistsException, InvalidParametersException {

    StudentAttributes s = new StudentAttributes();
    s.name = "valid student";
    s.email = "*****@*****.**";
    s.team = "validTeamName";
    s.comments = "";
    s.googleId = "validGoogleId";

    ______TS("fail : invalid params");
    s.course = "invalid id space";
    try {
      studentsDb.createEntity(s);
      Assert.fail();
    } catch (InvalidParametersException e) {
      AssertHelper.assertContains(
          String.format(COURSE_ID_ERROR_MESSAGE, s.course, REASON_INCORRECT_FORMAT),
          e.getMessage());
    }
    LogicTest.verifyAbsentInDatastore(s);

    ______TS("success : valid params");
    s.course = "valid-course";
    studentsDb.createEntity(s);
    LogicTest.verifyPresentInDatastore(s);
    StudentAttributes retrievedStudent = studentsDb.getStudentForGoogleId(s.course, s.googleId);
    assertEquals(true, retrievedStudent.isEnrollInfoSameAs(s));
    assertEquals(null, studentsDb.getStudentForGoogleId(s.course + "not existing", s.googleId));
    assertEquals(null, studentsDb.getStudentForGoogleId(s.course, s.googleId + "not existing"));
    assertEquals(
        null,
        studentsDb.getStudentForGoogleId(s.course + "not existing", s.googleId + "not existing"));

    ______TS("fail : duplicate");
    try {
      studentsDb.createEntity(s);
      Assert.fail();
    } catch (EntityAlreadyExistsException e) {
      AssertHelper.assertContains(
          String.format(StudentsDb.ERROR_CREATE_ENTITY_ALREADY_EXISTS, s.getEntityTypeAsString())
              + s.getIdentificationString(),
          e.getMessage());
    }

    ______TS("null params check");
    try {
      studentsDb.createEntity(null);
      Assert.fail();
    } catch (AssertionError a) {
      assertEquals(Const.StatusCodes.DBLEVEL_NULL_INPUT, a.getMessage());
    }
  }
  @Test
  public void testUpdateStudent() throws InvalidParametersException, EntityDoesNotExistException {

    // Create a new student with valid attributes
    StudentAttributes s = createNewStudent();
    studentsDb.updateStudent(
        s.course,
        s.email,
        "new-name",
        "new-team",
        "*****@*****.**",
        "new.google.id",
        "lorem ipsum dolor si amet");

    ______TS("non-existent case");
    try {
      studentsDb.updateStudent(
          "non-existent-course",
          "*****@*****.**",
          "no-name",
          "non-existent-team",
          "non.existent.ID",
          "blah",
          "blah");
      signalFailureToDetectException();
    } catch (EntityDoesNotExistException e) {
      assertEquals(
          StudentsDb.ERROR_UPDATE_NON_EXISTENT_STUDENT + "non-existent-course/[email protected]",
          e.getMessage());
    }

    // Only check first 2 params (course & email) which are used to identify the student entry. The
    // rest are actually allowed to be null.
    ______TS("null course case");
    try {
      studentsDb.updateStudent(
          null,
          s.email,
          "new-name",
          "new-team",
          "*****@*****.**",
          "new.google.id",
          "lorem ipsum dolor si amet");
      signalFailureToDetectException();
    } catch (AssertionError a) {
      assertEquals(Const.StatusCodes.DBLEVEL_NULL_INPUT, a.getMessage());
    }

    ______TS("null email case");
    try {
      studentsDb.updateStudent(
          s.course,
          null,
          "new-name",
          "new-team",
          "*****@*****.**",
          "new.google.id",
          "lorem ipsum dolor si amet");
      signalFailureToDetectException();
    } catch (AssertionError a) {
      assertEquals(Const.StatusCodes.DBLEVEL_NULL_INPUT, a.getMessage());
    }

    ______TS("duplicate email case");
    s = createNewStudent();
    // Create a second student with different email address
    StudentAttributes s2 = createNewStudent("*****@*****.**");
    try {
      studentsDb.updateStudent(
          s.course,
          s.email,
          "new-name",
          "new-team",
          s2.email,
          "new.google.id",
          "lorem ipsum dolor si amet");
      signalFailureToDetectException();
    } catch (InvalidParametersException e) {
      assertEquals(
          StudentsDb.ERROR_UPDATE_EMAIL_ALREADY_USED + s2.name + "/" + s2.email, e.getMessage());
    }

    ______TS("typical success case");
    String originalEmail = s.email;
    s.name = "new-name-2";
    s.team = "new-team-2";
    s.email = "new-email-2";
    s.googleId = "new-id-2";
    s.comments = "this are new comments";
    studentsDb.updateStudent(
        s.course, originalEmail, s.name, s.team, s.email, s.googleId, s.comments);

    StudentAttributes updatedStudent = studentsDb.getStudentForEmail(s.course, s.email);
    assertTrue(updatedStudent.isEnrollInfoSameAs(s));
  }
  @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());
  }