@Test
  public void shouldThrowExceptionIfCaseIdIsEmpty() {
    String instanceId = "myInstanceId";

    expectedException.expect(RuntimeException.class);
    expectedException.expectMessage(String.format("Empty case id found in form(%s)", instanceId));

    FormValueElement childCaseElement =
        new FormValueElementBuilder()
            .addAttribute("case_id", "")
            .addAttribute("date_modified", "2012-07-21T12:02:59.923+05:30")
            .build();

    FormValueElement childInfoElement = getFVE("case", childCaseElement);

    CommcareForm commcareForm =
        new CommcareFormBuilder().addSubElement("child_info", childInfoElement).build();
    commcareForm.setId(instanceId);

    when(infoParser.getCaseElement(childInfoElement)).thenReturn(childCaseElement);

    childInfoParser.parse(commcareForm);
    verify(infoParser, never()).parse(childCaseElement, true);
    verify(infoParser, never()).parse(childInfoElement, true);
  }
  @Test
  public void shouldPopulateCaseInformation() throws Exception {

    String caseId1 = "3e8998ce-b19f-4fa7-b1a1-721b6951e3cf";
    String caseId2 = "3e8998ce-b19f-4fa7-b1a1-721b6951e3cc";

    String dateModified1 = "2012-07-21T12:02:59.923+05:30";
    String dateModified2 = null;
    String receivedOn = DateTime.now().toString();

    FormValueElement childCaseElement1 =
        new FormValueElementBuilder()
            .addAttribute("case_id", caseId1)
            .addAttribute("date_modified", dateModified1)
            .build();

    FormValueElement childCaseElement2 =
        new FormValueElementBuilder()
            .addAttribute("case_id", caseId2)
            .addAttribute("date_modified", dateModified2)
            .build();

    FormValueElement childInfoElement1 = getFVE("case", childCaseElement1);
    FormValueElement childInfoElement2 = getFVE("case", childCaseElement2);

    CommcareForm commcareForm =
        new CommcareFormBuilder()
            .addSubElement("child_info", childInfoElement1)
            .addSubElement("child_info", childInfoElement2)
            .withReceivedOn(receivedOn)
            .build();

    when(infoParser.getCaseElement(childInfoElement1)).thenReturn(childCaseElement1);
    when(infoParser.getCaseElement(childInfoElement2)).thenReturn(childCaseElement2);

    List<Map<String, String>> childrenMapList = childInfoParser.parse(commcareForm);

    assertEquals(2, childrenMapList.size());

    verify(infoParser).parse(childInfoElement1, true);
    verify(infoParser).parse(childInfoElement1, true);
    verify(infoParser).parse(childCaseElement2, true);
    verify(infoParser).parse(childInfoElement2, true);

    Collections.sort(
        childrenMapList,
        new Comparator<Map<String, String>>() {
          @Override
          public int compare(Map<String, String> o1, Map<String, String> o2) {
            return new CompareToBuilder().append(o1.get("caseId"), o2.get("caseId")).toComparison();
          }
        });

    ReflectionAssert.assertReflectionEquals(
        getExpectedChild(caseId1, dateModified1, receivedOn), childrenMapList.get(1));
    ReflectionAssert.assertReflectionEquals(
        getExpectedChild(caseId2, dateModified2, receivedOn), childrenMapList.get(0));
  }
  @Test
  public void shouldChildFormInfoOverwriteChildCaseInfo() {
    final String receivedOn = DateTime.now().toString();
    final String dateModified = "2012-07-21T12:02:59.923+05:30";
    FormValueElement childCaseElement =
        new FormValueElementBuilder()
            .addAttribute("case_id", "3e8998ce-b19f-4fa7-b1a1-721b6951e3cf")
            .addAttribute("date_modified", dateModified)
            .build();

    FormValueElement childInfoElement = getFVE("case", childCaseElement);

    CommcareForm commcareForm =
        new CommcareFormBuilder()
            .addSubElement("child_info", childInfoElement)
            .withReceivedOn(receivedOn)
            .build();

    final HashMap<String, String> expected =
        new HashMap<String, String>() {
          {
            put("caseId", "3e8998ce-b19f-4fa7-b1a1-721b6951e3cf");
            put("dateModified", dateModified);
            put("serverDateModified", receivedOn);
            put("age", "22");
          }
        };

    when(infoParser.parse(childCaseElement, true))
        .thenReturn(
            new HashMap<String, String>() {
              {
                put("age", "21");
              }
            });

    when(infoParser.parse(childInfoElement, true))
        .thenReturn(
            new HashMap<String, String>() {
              {
                put("age", "22");
              }
            });
    when(infoParser.getCaseElement(childInfoElement)).thenReturn(childCaseElement);

    List<Map<String, String>> childrenList = childInfoParser.parse(commcareForm);

    assertEquals(1, childrenList.size());

    verify(infoParser).parse(childInfoElement, true);
    verify(infoParser).parse(childCaseElement, true);

    ReflectionAssert.assertReflectionEquals(expected, childrenList.get(0));
  }
  @Test
  public void
      shouldIgnoreChildrenIfCaseElementNotFoundWhilePopulatingCaseInformationAndNotLogError()
          throws Exception {
    TestAppender.clear();
    String instanceId = "myInstanceId";
    String caseId1 = "3e8998ce-b19f-4fa7-b1a1-721b6951e3cf";
    String caseId2 = "3e8998ce-b19f-4fa7-b1a1-721b6951e3cc";

    String dateModified1 = "2012-07-21T12:02:59.923+05:30";
    String dateModified2 = null;
    String receivedOn = DateTime.now().toString();

    FormValueElement childCaseElement1 =
        new FormValueElementBuilder()
            .addAttribute("case_id", caseId1)
            .addAttribute("date_modified", dateModified1)
            .build();

    FormValueElement childCaseElement2 =
        new FormValueElementBuilder()
            .addAttribute("case_id", caseId2)
            .addAttribute("date_modified", dateModified2)
            .build();

    FormValueElement childInfoElement1 = getFVE("case", childCaseElement1);
    FormValueElement childInfoElement2 = getFVE("case", childCaseElement2);

    CommcareForm commcareForm =
        new CommcareFormBuilder()
            .addSubElement("child_info", childInfoElement1)
            .addSubElement("child_info", childInfoElement2)
            .withReceivedOn(receivedOn)
            .build();

    commcareForm.setId(instanceId);

    when(infoParser.getCaseElement(childInfoElement2)).thenReturn(childCaseElement2);
    when(infoParser.shouldReportMissingCaseElement()).thenReturn(false);

    List<Map<String, String>> childrenMapList = childInfoParser.parse(commcareForm);

    assertEquals(1, childrenMapList.size());

    verify(infoParser, never()).parse(childInfoElement1, true);
    verify(infoParser, never()).parse(childInfoElement1, true);
    verify(infoParser).parse(childCaseElement2, true);
    verify(infoParser).parse(childInfoElement2, true);

    Collections.sort(
        childrenMapList,
        new Comparator<Map<String, String>>() {
          @Override
          public int compare(Map<String, String> o1, Map<String, String> o2) {
            return new CompareToBuilder().append(o1.get("caseId"), o2.get("caseId")).toComparison();
          }
        });

    ReflectionAssert.assertReflectionEquals(
        getExpectedChild(caseId2, dateModified2, receivedOn), childrenMapList.get(0));

    assertNull(TestAppender.findMatching(new IsEqual(Level.ERROR), new IsAnything<String>()));
  }