@Test
  public void testUpdateRetry() {
    TenantContext.setTenantId("SLIUnitTest");
    repository.deleteAll("student", null);

    DBObject indexKeys = new BasicDBObject("body.cityOfBirth", 1);
    mongoTemplate.getCollection("student").ensureIndex(indexKeys);

    repository.create("student", buildTestStudentEntity());

    Entity entity = repository.findOne("student", new NeutralQuery());
    Map<String, Object> studentBody = entity.getBody();
    studentBody.put("cityOfBirth", "ABC");

    Entity studentEntity =
        new MongoEntity("student", entity.getEntityId(), studentBody, entity.getMetaData());
    repository.updateWithRetries("student", studentEntity, 5);

    NeutralQuery neutralQuery = new NeutralQuery();
    neutralQuery.addCriteria(new NeutralCriteria("cityOfBirth=ABC"));
    assertEquals(1, repository.count("student", neutralQuery));

    repository.deleteAll("student", null);
    mongoTemplate.getCollection("student").dropIndex(indexKeys);
  }
  @Test
  public void findOneMultipleMatches() {
    repository.deleteAll("student", null);
    DBObject indexKeys = new BasicDBObject("body.firstName", 1);
    mongoTemplate.getCollection("student").ensureIndex(indexKeys);

    Map<String, Object> student = buildTestStudentEntity();
    student.put("firstName", "Jadwiga");
    this.repository.create("student", student);

    student = buildTestStudentEntity();
    student.put("firstName", "Jadwiga");
    this.repository.create("student", student);

    student = buildTestStudentEntity();
    student.put("firstName", "Jadwiga");
    this.repository.create("student", student);

    NeutralQuery neutralQuery = new NeutralQuery();
    neutralQuery.addCriteria(new NeutralCriteria("firstName=Jadwiga"));
    assertNotNull(this.repository.findOne("student", neutralQuery));

    repository.deleteAll("student", null);
    mongoTemplate.getCollection("student").dropIndex(indexKeys);
  }
 private void clearSafeDeleteGradingPeriodData() {
   repository.deleteAll("gradingPeriod", null);
   repository.deleteAll("session", null);
   repository.deleteAll(MongoRepository.CUSTOM_ENTITY_COLLECTION, null);
   repository.deleteAll("yearlyTranscript", null); // actual mongo
   // collection for grade
   // and reportCard
 }
  @Test
  public void testCRUDEntityRepository() {

    // clean up the existing student data
    repository.deleteAll("student", null);

    // create new student entity
    Map<String, Object> student = buildTestStudentEntity();

    // test save
    Entity saved = repository.create("student", student);
    String id = saved.getEntityId();
    assertTrue(!id.equals(""));

    // test findAll
    NeutralQuery neutralQuery = new NeutralQuery();
    neutralQuery.setOffset(0);
    neutralQuery.setLimit(20);
    Iterable<Entity> entities = repository.findAll("student", neutralQuery);
    assertNotNull(entities);
    Entity found = entities.iterator().next();
    assertEquals(found.getBody().get("birthDate"), student.get("birthDate"));
    assertEquals((found.getBody()).get("firstName"), "Jane");
    assertEquals((found.getBody()).get("lastName"), "Doe");

    // test find by id
    Entity foundOne = repository.findById("student", saved.getEntityId());
    assertNotNull(foundOne);
    assertEquals(foundOne.getBody().get("birthDate"), student.get("birthDate"));
    assertEquals((found.getBody()).get("firstName"), "Jane");

    // test update
    found.getBody().put("firstName", "Mandy");
    assertTrue(repository.update("student", found, false));
    entities = repository.findAll("student", neutralQuery);
    assertNotNull(entities);
    Entity updated = entities.iterator().next();
    assertEquals(updated.getBody().get("firstName"), "Mandy");

    // test delete by id
    Map<String, Object> student2Body = buildTestStudentEntity();
    Entity student2 = repository.create("student", student2Body);
    entities = repository.findAll("student", neutralQuery);
    assertNotNull(entities.iterator().next());
    repository.delete("student", student2.getEntityId());
    Entity zombieStudent = repository.findById("student", student2.getEntityId());
    assertNull(zombieStudent);

    assertFalse(repository.delete("student", student2.getEntityId()));

    // test deleteAll by entity type
    repository.deleteAll("student", null);
    entities = repository.findAll("student", neutralQuery);
    assertFalse(entities.iterator().hasNext());
  }
  @Test
  public void findOneTestNegative() {
    repository.deleteAll("student", null);
    DBObject indexKeys = new BasicDBObject("body.firstName", 1);
    mongoTemplate.getCollection("student").ensureIndex(indexKeys);

    NeutralQuery neutralQuery = new NeutralQuery();
    neutralQuery.addCriteria(new NeutralCriteria("firstName=Jadwiga"));

    assertNull(this.repository.findOne("student", neutralQuery));

    repository.deleteAll("student", null);
    mongoTemplate.getCollection("student").dropIndex(indexKeys);
  }
  @Test
  public void testTimestamps() throws Exception {

    // clean up the existing student data
    repository.deleteAll("student", null);

    // create new student entity
    Map<String, Object> student = buildTestStudentEntity();

    // test save
    Entity saved = repository.create("student", student);

    DateTime created = new DateTime(saved.getMetaData().get(EntityMetadataKey.CREATED.getKey()));
    DateTime updated = new DateTime(saved.getMetaData().get(EntityMetadataKey.UPDATED.getKey()));

    assertEquals(created, updated);

    saved.getBody().put("cityOfBirth", "Evanston");

    // Needs to be here to prevent cases where code execution is so fast,
    // there
    // is no difference between create/update times
    Thread.sleep(2);

    repository.update("student", saved, false);

    updated = new DateTime(saved.getMetaData().get(EntityMetadataKey.UPDATED.getKey()));

    assertTrue(updated.isAfter(created));
  }
 @Test
 public void testCreateWithMetadata() {
   repository.deleteAll("student", null);
   Map<String, Object> studentBody = buildTestStudentEntity();
   Map<String, Object> studentMetaData = new HashMap<String, Object>();
   repository.create("student", studentBody, studentMetaData, "student");
   assertEquals(1, repository.count("student", new NeutralQuery()));
 }
  @Test
  public void testCount() {
    repository.deleteAll("student", null);

    DBObject indexKeys = new BasicDBObject("body.cityOfBirth", 1);
    mongoTemplate.getCollection("student").ensureIndex(indexKeys);

    repository.create("student", buildTestStudentEntity());
    repository.create("student", buildTestStudentEntity());
    repository.create("student", buildTestStudentEntity());
    repository.create("student", buildTestStudentEntity());
    Map<String, Object> oddStudent = buildTestStudentEntity();
    oddStudent.put("cityOfBirth", "Nantucket");
    repository.create("student", oddStudent);
    assertEquals(5, repository.count("student", new NeutralQuery()));
    NeutralQuery neutralQuery = new NeutralQuery();
    neutralQuery.addCriteria(new NeutralCriteria("cityOfBirth=Nantucket"));
    assertEquals(1, repository.count("student", neutralQuery));

    repository.deleteAll("student", null);
    mongoTemplate.getCollection("student").dropIndex(indexKeys);
  }
  @Test
  public void testDeleteAll() {
    repository.deleteAll("student", null);

    DBObject indexKeys = new BasicDBObject("body.firstName", 1);
    mongoTemplate.getCollection("student").ensureIndex(indexKeys);

    Map<String, Object> studentMap = buildTestStudentEntity();
    studentMap.put("firstName", "John");
    repository.create("student", buildTestStudentEntity());
    repository.create("student", buildTestStudentEntity());
    repository.create("student", buildTestStudentEntity());
    repository.create("student", buildTestStudentEntity());
    repository.create("student", studentMap);
    assertEquals(5, repository.count("student", new NeutralQuery()));
    NeutralQuery neutralQuery = new NeutralQuery();
    neutralQuery.addCriteria(new NeutralCriteria("firstName=John"));
    repository.deleteAll("student", neutralQuery);
    assertEquals(4, repository.count("student", new NeutralQuery()));

    repository.deleteAll("student", null);
    mongoTemplate.getCollection("student").dropIndex(indexKeys);
  }
  private String insertAttendanceEventData(boolean skipFirst) {
    // Clear attendance collection.
    repository.deleteAll("attendance", null);

    // Populate the attendance record to be deleted, and add it to the db.
    Map<String, Object> attendanceMap = new HashMap<String, Object>();
    List<Map<String, String>> attendanceEvents = getAttendanceEvents(skipFirst);
    attendanceMap.put("attendanceEvent", attendanceEvents);
    attendanceMap.put("schoolId", "schoolId1");
    attendanceMap.put("schoolYear", "2011-2012");
    attendanceMap.put("studentId", "studentId1");
    repository.create("attendance", attendanceMap);

    // Get the db id of the attendance record; there is only one.
    NeutralQuery neutralQuery = new NeutralQuery();
    Entity attendance = repository.findOne("attendance", neutralQuery);
    return attendance.getEntityId();
  }
  @Test
  public void testFindIdsByQuery() {
    repository.deleteAll("student", null);
    repository.create("student", buildTestStudentEntity());
    repository.create("student", buildTestStudentEntity());
    repository.create("student", buildTestStudentEntity());
    repository.create("student", buildTestStudentEntity());
    repository.create("student", buildTestStudentEntity());
    NeutralQuery neutralQuery = new NeutralQuery();
    neutralQuery.setOffset(0);
    neutralQuery.setLimit(100);

    Iterable<String> ids = repository.findAllIds("student", neutralQuery);
    List<String> idList = new ArrayList<String>();
    for (String id : ids) {
      idList.add(id);
    }

    assertEquals(5, idList.size());
  }
  @SuppressWarnings("unchecked")
  @Test
  public void testSort() {

    // clean up the existing student data
    repository.deleteAll("student", null);

    // create new student entity
    Map<String, Object> body1 = buildTestStudentEntity();
    Map<String, Object> body2 = buildTestStudentEntity();
    Map<String, Object> body3 = buildTestStudentEntity();
    Map<String, Object> body4 = buildTestStudentEntity();

    body1.put("firstName", "Austin");
    body2.put("firstName", "Jane");
    body3.put("firstName", "Mary");
    body4.put("firstName", "Suzy");

    body1.put("performanceLevels", new String[] {"1"});
    body2.put("performanceLevels", new String[] {"2"});
    body3.put("performanceLevels", new String[] {"3"});
    body4.put("performanceLevels", new String[] {"4"});

    // save entities
    repository.create("student", body1);
    repository.create("student", body2);
    repository.create("student", body3);
    repository.create("student", body4);

    // sort entities by firstName with ascending order
    NeutralQuery sortQuery1 = new NeutralQuery();
    sortQuery1.setSortBy("firstName");
    sortQuery1.setSortOrder(NeutralQuery.SortOrder.ascending);
    sortQuery1.setOffset(0);
    sortQuery1.setLimit(100);

    Iterable<Entity> entities = repository.findAll("student", sortQuery1);
    assertNotNull(entities);
    Iterator<Entity> it = entities.iterator();
    assertEquals("Austin", it.next().getBody().get("firstName"));
    assertEquals("Jane", it.next().getBody().get("firstName"));
    assertEquals("Mary", it.next().getBody().get("firstName"));
    assertEquals("Suzy", it.next().getBody().get("firstName"));

    // sort entities by firstName with descending order
    NeutralQuery sortQuery2 = new NeutralQuery();
    sortQuery2.setSortBy("firstName");
    sortQuery2.setSortOrder(NeutralQuery.SortOrder.descending);
    sortQuery2.setOffset(0);
    sortQuery2.setLimit(100);
    entities = repository.findAll("student", sortQuery2);
    assertNotNull(entities);
    it = entities.iterator();
    assertEquals("Suzy", it.next().getBody().get("firstName"));
    assertEquals("Mary", it.next().getBody().get("firstName"));
    assertEquals("Jane", it.next().getBody().get("firstName"));
    assertEquals("Austin", it.next().getBody().get("firstName"));

    // sort entities by performanceLevels which is an array with ascending
    // order
    NeutralQuery sortQuery3 = new NeutralQuery();
    sortQuery3.setSortBy("performanceLevels");
    sortQuery3.setSortOrder(NeutralQuery.SortOrder.ascending);
    sortQuery3.setOffset(0);
    sortQuery3.setLimit(100);
    entities = repository.findAll("student", sortQuery3);
    assertNotNull(entities);
    it = entities.iterator();
    assertEquals("1", ((List<String>) (it.next().getBody().get("performanceLevels"))).get(0));
    assertEquals("2", ((List<String>) (it.next().getBody().get("performanceLevels"))).get(0));
    assertEquals("3", ((List<String>) (it.next().getBody().get("performanceLevels"))).get(0));
    assertEquals("4", ((List<String>) (it.next().getBody().get("performanceLevels"))).get(0));

    // sort entities by performanceLevels which is an array with descending
    // order
    NeutralQuery sortQuery4 = new NeutralQuery();
    sortQuery4.setSortBy("performanceLevels");
    sortQuery4.setSortOrder(NeutralQuery.SortOrder.descending);
    sortQuery4.setOffset(0);
    sortQuery4.setLimit(100);
    entities = repository.findAll("student", sortQuery4);
    assertNotNull(entities);
    it = entities.iterator();
    assertEquals("4", ((List<String>) (it.next().getBody().get("performanceLevels"))).get(0));
    assertEquals("3", ((List<String>) (it.next().getBody().get("performanceLevels"))).get(0));
    assertEquals("2", ((List<String>) (it.next().getBody().get("performanceLevels"))).get(0));
    assertEquals("1", ((List<String>) (it.next().getBody().get("performanceLevels"))).get(0));
  }
  @Test
  public void testSchoolLineage() {
    NeutralQuery query = null;

    repository.deleteAll(EntityNames.EDUCATION_ORGANIZATION, null);

    DBObject indexKeys = new BasicDBObject("body." + ParameterConstants.STATE_ORGANIZATION_ID, 1);
    mongoTemplate.getCollection(EntityNames.EDUCATION_ORGANIZATION).ensureIndex(indexKeys);
    mongoTemplate
        .getCollection(EntityNames.EDUCATION_ORGANIZATION)
        .ensureIndex(new BasicDBObject("metaData.edOrgs", 1), new BasicDBObject("sparse", true));

    // Add a school
    Entity school = createEducationOrganizationEntity("school1", "school", "School", null);
    Set<String> expectedEdOrgs = new HashSet();
    expectedEdOrgs.add(school.getEntityId());
    assertTrue(
        "School not found in lineage.", schoolLineageIs(school.getEntityId(), expectedEdOrgs));

    // Add an SEA
    Entity sea =
        createEducationOrganizationEntity(
            "sea1", "stateEducationAgency", "State Education Agency", null);
    assertTrue(
        "After adding SEA expected edOrgs not found in lineage.",
        schoolLineageIs(school.getEntityId(), expectedEdOrgs));

    // Add an LEA
    List<String> parentRefs = new ArrayList<String>(Arrays.asList(sea.getEntityId()));
    Entity lea =
        createEducationOrganizationEntity(
            "lea1", "localEducationAgency", "Local Education Agency", parentRefs);
    assertTrue(
        "After adding LEA expected edOrgs not found in lineage.",
        schoolLineageIs(school.getEntityId(), expectedEdOrgs));

    // doUpdate School parent ref to LEA
    List<String> parentRefsUpdate = new ArrayList<String>(Arrays.asList(lea.getEntityId()));
    query =
        new NeutralQuery(
            new NeutralCriteria("_id", NeutralCriteria.OPERATOR_EQUAL, school.getEntityId()));
    Update update =
        new Update()
            .set("body." + ParameterConstants.PARENT_EDUCATION_AGENCY_REFERENCE, parentRefsUpdate);
    repository.doUpdate(EntityNames.EDUCATION_ORGANIZATION, query, update);
    expectedEdOrgs.add(lea.getEntityId());
    expectedEdOrgs.add(sea.getEntityId());
    assertTrue(
        "After updating school parent ref expected edOrgs not found in lineage.",
        schoolLineageIs(school.getEntityId(), expectedEdOrgs));

    // Patch LEA parent ref to an undefined id
    List<String> parentRefsPatch = new ArrayList<String>(Arrays.asList("undefinedId"));
    Map<String, Object> newValues = new HashMap<String, Object>();
    newValues.put(ParameterConstants.PARENT_EDUCATION_AGENCY_REFERENCE, parentRefsPatch);
    repository.patch(
        "localEducationEntity", EntityNames.EDUCATION_ORGANIZATION, lea.getEntityId(), newValues);
    expectedEdOrgs.remove(sea.getEntityId());
    assertTrue(
        "After updating school parent ref expected edOrgs not found in lineage.",
        schoolLineageIs(school.getEntityId(), expectedEdOrgs));

    // Update LEA to set parent ref back to SEA
    repository.update(EntityNames.EDUCATION_ORGANIZATION, lea, false);
    expectedEdOrgs.add(sea.getEntityId());
    assertTrue(
        "After updating school parent ref expected edOrgs not found in lineage.",
        schoolLineageIs(school.getEntityId(), expectedEdOrgs));

    // Delete LEA - lineage should be recalculated
    repository.delete(EntityNames.EDUCATION_ORGANIZATION, lea.getEntityId());
    expectedEdOrgs.remove(lea.getEntityId());
    expectedEdOrgs.remove(sea.getEntityId());
    assertTrue(
        "After deleting lea expected edOrgs not found in lineage.",
        schoolLineageIs(school.getEntityId(), expectedEdOrgs));

    // Insert LEA with no parent ref to SEA
    lea.getBody().remove(ParameterConstants.PARENT_EDUCATION_AGENCY_REFERENCE);
    Entity insertedLea =
        ((MongoEntityRepository) repository).insert(lea, EntityNames.EDUCATION_ORGANIZATION);
    expectedEdOrgs.add(lea.getEntityId());
    assertTrue(
        "After re-adding LEA with no parent ref expected edOrgs not found in lineage.",
        schoolLineageIs(school.getEntityId(), expectedEdOrgs));

    // findAndUpdate School parent ref to SEA
    List<String> parentRefsSEA = new ArrayList<String>(Arrays.asList(sea.getEntityId()));
    query =
        new NeutralQuery(
            new NeutralCriteria("_id", NeutralCriteria.OPERATOR_EQUAL, school.getEntityId()));
    update =
        new Update()
            .set("body." + ParameterConstants.PARENT_EDUCATION_AGENCY_REFERENCE, parentRefsSEA);
    repository.findAndUpdate(EntityNames.EDUCATION_ORGANIZATION, query, update);
    expectedEdOrgs.remove(lea.getEntityId());
    expectedEdOrgs.add(sea.getEntityId());
    assertTrue(
        "After updating school parent ref to SEA, expected edOrgs not found in lineage.",
        schoolLineageIs(school.getEntityId(), expectedEdOrgs));

    // Clear lineage for negative tests
    clearSchoolLineage(school);

    // Create an unrelated entity type and make sure school lineage isn't recalculated
    repository.create("student", buildTestStudentEntity());
    assertTrue(
        "After adding a student lineage school lineage should not change.",
        schoolLineageIs(school.getEntityId(), new HashSet<String>()));

    // Patch an edOrg non-parent-ref and make sure school lineage isn't recalculated
    newValues = new HashMap<String, Object>();
    newValues.put("body.nameOfInstitution", "updatedName");
    repository.patch("school", EntityNames.EDUCATION_ORGANIZATION, school.getEntityId(), newValues);
    assertTrue(
        "Updating a school non-parent ref should not change school lineage.",
        schoolLineageIs(school.getEntityId(), new HashSet<String>()));

    mongoTemplate.getCollection(EntityNames.EDUCATION_ORGANIZATION).drop();
  }