/**
   * @see Encounter#setProvider(EncounterRole,Provider)
   * @verifies set provider for new role
   */
  @Test
  public void setProvider_shouldSetProviderForNewRole() throws Exception {
    // given
    Encounter encounter = new Encounter();
    EncounterRole role = new EncounterRole();
    Provider provider = new Provider();

    // when
    encounter.setProvider(role, provider);

    // then
    Assert.assertEquals(1, encounter.getProvidersByRole(role).size());
    Assert.assertTrue(encounter.getProvidersByRole(role).contains(provider));
  }
  /**
   * @see Encounter#addProvider(EncounterRole,Provider)
   * @verifies add provider for new role
   */
  @Test
  public void addProvider_shouldAddProviderForNewRole() throws Exception {
    // given
    Encounter encounter = new Encounter();
    EncounterRole encounterRole = new EncounterRole();
    Provider provider = new Provider();

    // when
    encounter.addProvider(encounterRole, provider);

    // then
    Assert.assertTrue(encounter.getProvidersByRole(encounterRole).contains(provider));
  }
  /**
   * @see Encounter#removeProvider(EncounterRole,Provider)
   * @verifies void existing EncounterProvider
   */
  @Test
  public void removeProvider_shouldVoidExistingEncounterProvider() throws Exception {
    Encounter encounter = new Encounter();
    EncounterRole role = new EncounterRole();
    Provider provider = new Provider();

    encounter.addProvider(role, provider);

    Assert.assertEquals(1, encounter.getProvidersByRole(role).size());
    Assert.assertTrue(encounter.getProvidersByRole(role).contains(provider));

    encounter.removeProvider(role, provider);

    // the size should be 0 for non voided providers
    Assert.assertEquals(0, encounter.getProvidersByRole(role).size());

    // the size should be 1 if we include voided providers
    Assert.assertEquals(1, encounter.getProvidersByRole(role, true).size());

    // should contain the voided provider
    Assert.assertTrue(encounter.getProvidersByRole(role, true).contains(provider));
  }
  /**
   * @see Encounter#setProvider(EncounterRole,Provider)
   * @verifies void existing EncounterProvider
   */
  @Test
  public void setProvider_shouldVoidExistingEncounterProvider() throws Exception {
    Encounter encounter = new Encounter();
    EncounterRole role = new EncounterRole();
    Provider provider1 = new Provider();
    Provider provider2 = new Provider();

    encounter.setProvider(role, provider1);
    encounter.setProvider(role, provider2);

    // the size should be 1 for non voided providers
    Assert.assertEquals(1, encounter.getProvidersByRole(role, false).size());

    // should contain the second provider since the first was voided.
    Assert.assertTrue(encounter.getProvidersByRole(role, false).contains(provider2));

    // the size should be 2 if we include voided providers
    Assert.assertEquals(2, encounter.getProvidersByRole(role, true).size());

    // should contain both the first (voided) and second (non voided) providers
    Assert.assertTrue(
        encounter.getProvidersByRole(role, true).containsAll(Arrays.asList(provider1, provider2)));
  }
  /**
   * @see Encounter#getProvidersByRole(EncounterRole)
   * @verifies return empty set for null role
   */
  @Test
  public void getProvidersByRole_shouldReturnEmptySetForNullRole() throws Exception {
    // given
    Encounter encounter = new Encounter();
    EncounterRole role = new EncounterRole();
    Provider provider = new Provider();
    encounter.addProvider(role, provider);

    // when
    Set<Provider> providers = encounter.getProvidersByRole(null);

    // then
    Assert.assertEquals(0, providers.size());
  }
  /**
   * @see Encounter#setProvider(Person)
   * @verifies set existing provider for unknown role
   */
  @Test
  public void setProvider_shouldSetExistingProviderForUnknownRole() throws Exception {
    // given
    Encounter encounter = new Encounter();
    EncounterRole unknownRole = new EncounterRole();
    Person person = new Person();
    Provider provider = new Provider();
    provider.setPerson(person);
    List<Provider> providers = new ArrayList<Provider>();
    providers.add(provider);

    when(encounterService.getEncounterRoleByUuid(EncounterRole.UNKNOWN_ENCOUNTER_ROLE_UUID))
        .thenReturn(unknownRole);

    when(providerService.getProvidersByPerson(person)).thenReturn(providers);

    // when
    encounter.setProvider(person);

    // then
    assertEquals(1, encounter.getProvidersByRoles().size());
    assertEquals(1, encounter.getProvidersByRole(unknownRole).size());
    assertEquals(provider, encounter.getProvidersByRole(unknownRole).iterator().next());
  }
  /**
   * @see Encounter#addProvider(EncounterRole,Provider)
   * @verifies add second provider for role
   */
  @Test
  public void addProvider_shouldAddSecondProviderForRole() throws Exception {
    // given
    Encounter encounter = new Encounter();
    EncounterRole role = new EncounterRole();
    Provider provider1 = new Provider();
    Provider provider2 = new Provider();

    // when
    encounter.addProvider(role, provider1);
    encounter.addProvider(role, provider2);

    // then
    List<Provider> providers = Arrays.asList(provider1, provider2);
    Assert.assertTrue(encounter.getProvidersByRole(role).containsAll(providers));
  }
  /**
   * @see Encounter#addProvider(EncounterRole,Provider)
   * @verifies not add same provider twice for role
   */
  @Test
  public void addProvider_shouldNotAddSameProviderTwiceForRole() throws Exception {
    // given
    Encounter encounter = new Encounter();
    EncounterRole role = new EncounterRole();
    Provider provider1 = new Provider();

    // when
    encounter.addProvider(role, provider1);
    encounter.addProvider(role, provider1);

    // then
    // we need to cheat and use reflection to look at the private encounterProviders property; we
    // don't want the getProvidersByRole method hiding duplicates from us
    Collection<EncounterProvider> providers =
        (Collection<EncounterProvider>) FieldUtils.readField(encounter, "encounterProviders", true);
    Assert.assertEquals(1, providers.size());
    Assert.assertTrue(encounter.getProvidersByRole(role).contains(provider1));
  }
  /**
   * @see Encounter#getProvidersByRole(EncounterRole)
   * @verifies return providers for role
   */
  @Test
  public void getProvidersByRole_shouldReturnProvidersForRole() throws Exception {
    // given
    Encounter encounter = new Encounter();
    EncounterRole role = new EncounterRole();

    Provider provider = new Provider();
    encounter.addProvider(role, provider);

    Provider provider2 = new Provider();
    encounter.addProvider(role, provider2);

    EncounterRole role2 = new EncounterRole();
    Provider provider3 = new Provider();
    encounter.addProvider(role2, provider3);

    // when
    Set<Provider> providers = encounter.getProvidersByRole(role);

    // then
    Assert.assertEquals(2, providers.size());
    Assert.assertTrue(providers.containsAll(Arrays.asList(provider, provider2)));
  }
  /** @see Encounter#copyAndAssignToAnotherPatient(org.openmrs.Patient) */
  @Test
  @Verifies(
      value =
          "should copy all Encounter data except visit and assign copied Encounter to given Patient",
      method = "copy()")
  public void copy_shouldCopyAllEncounterDataExceptVisitAndAssignCopiedEncounterToGivenPatient()
      throws Exception {
    Encounter encounter = new Encounter();

    encounter.setCreator(new User());
    encounter.setDateCreated(new Date());
    encounter.setChangedBy(new User());
    encounter.setDateChanged(new Date());
    encounter.setVoidReason("void");
    encounter.setDateVoided(new Date());

    encounter.setEncounterDatetime(new Date());
    encounter.setEncounterType(new EncounterType());
    encounter.setForm(new Form());
    encounter.setLocation(new Location());
    encounter.setPatient(new Patient());

    encounter.addObs(new Obs());
    encounter.addOrder(new Order());

    EncounterRole encounterRole = new EncounterRole();
    encounter.addProvider(encounterRole, new Provider());

    encounter.setVisit(new Visit());

    Patient patient = new Patient(1234);

    Encounter encounterCopy = encounter.copyAndAssignToAnotherPatient(patient);

    Assert.assertNotEquals(encounter, encounterCopy);

    Assert.assertEquals(encounter.getCreator(), encounterCopy.getCreator());
    Assert.assertEquals(encounter.getDateCreated(), encounterCopy.getDateCreated());
    Assert.assertEquals(encounter.getChangedBy(), encounterCopy.getChangedBy());
    Assert.assertEquals(encounter.getDateChanged(), encounterCopy.getDateChanged());
    Assert.assertEquals(encounter.getVoided(), encounterCopy.getVoided());
    Assert.assertEquals(encounter.getVoidReason(), encounterCopy.getVoidReason());
    Assert.assertEquals(encounter.getDateVoided(), encounterCopy.getDateVoided());

    Assert.assertEquals(encounter.getEncounterDatetime(), encounterCopy.getEncounterDatetime());
    Assert.assertEquals(encounter.getEncounterType(), encounterCopy.getEncounterType());
    Assert.assertEquals(encounter.getForm(), encounterCopy.getForm());
    Assert.assertEquals(encounter.getLocation(), encounterCopy.getLocation());

    Assert.assertEquals(1, encounter.getObs().size());
    Assert.assertEquals(1, encounterCopy.getObs().size());
    Assert.assertEquals(1, encounter.getOrders().size());
    Assert.assertEquals(1, encounterCopy.getOrders().size());

    Assert.assertEquals(1, encounter.getProvidersByRole(encounterRole).size());
    Assert.assertEquals(1, encounterCopy.getProvidersByRole(encounterRole).size());
    Assert.assertEquals(
        true,
        encounter
            .getProvidersByRole(encounterRole)
            .containsAll(encounterCopy.getProvidersByRole(encounterRole)));

    Assert.assertNotNull(encounter.getVisit());
    Assert.assertNull(encounterCopy.getVisit());

    Assert.assertEquals(patient, encounterCopy.getPatient());
  }