public class RemoveSubinvestigatorActionTest extends AbstractWebTest {

  @Rule public ExpectedException thrown = ExpectedException.none();
  @Inject private PersonAssociationService mockPersonAssociationService;
  @Inject private InvestigatorProfileService mockProfileService;
  @Inject private ProtocolRegistrationService mockRegistrationService;
  @Inject private RemoveSubinvestigatorAction action;
  private InvestigatorProfile profile = InvestigatorProfileFactory.getInstance().create();
  private InvestigatorProfile subInvestigatorProfile =
      InvestigatorProfileFactory.getInstance().create();
  private Person person = subInvestigatorProfile.getPerson();
  private SubInvestigator subInvestigator;

  @Before
  @Override
  public void setUp() throws Exception {
    super.setUp();
    action.setServletRequest(getMockRequest());
    subInvestigator = profile.addSubInvestigator(person);
    subInvestigator.setId(ValueGenerator.getUniqueLong());
    action.setProfile(profile);
    action.setPersonAssociationId(subInvestigator.getId());
    action.setPersonAssociation(subInvestigator);
    when(mockPersonAssociationService.getSubInvestigatorById(subInvestigator.getId()))
        .thenReturn(subInvestigator);
  }

  @Test
  public void testPrepare() {
    action.setPersonAssociation(null);
    action.prepare();
    assertSame(subInvestigator, action.getPersonAssociation());
  }

  @Test
  public void testEnter_SubInvestigator() {
    assertEquals(ActionSupport.SUCCESS, action.enter());
  }

  @Test
  public void testEnter_NoProfile() {
    action.setProfile(null);
    thrown.expect(NullPointerException.class);
    thrown.expectMessage(
        "User Profile does not exist! You must create a user profile before editing an person.");
    action.enter();
  }

  @Test
  public void testEnter_NoSubinvestigatorId() {
    action.setPersonAssociation(null);
    thrown.expect(NullPointerException.class);
    thrown.expectMessage("No Person Association selected for removal.");
    action.enter();
  }

  @Test
  public void testRemovePersonAssociation() {
    assertEquals(FirebirdUIConstants.RETURN_CLOSE_DIALOG, action.removePersonAssociation());
    verify(mockProfileService).deleteAssociatedSubInvestigator(profile, subInvestigator);
  }

  @Test
  public void testGetSubinvestigatorRegistrationsJson() throws JSONException {
    SubInvestigatorRegistration inProgressReg =
        createSubInvestigatorRegistration(RegistrationStatus.IN_PROGRESS);
    SubInvestigatorRegistration returnedReg =
        createSubInvestigatorRegistration(RegistrationStatus.RETURNED);
    SubInvestigatorRegistration submittedReg =
        createSubInvestigatorRegistration(RegistrationStatus.SUBMITTED);
    when(mockRegistrationService.getSubinvestigatorRegistrations(profile, person))
        .thenReturn(Lists.newArrayList(inProgressReg, returnedReg, submittedReg));
    String json = action.getSubinvestigatorRegistrationsJson();
    checkRegistrationInJson(inProgressReg, json);
    checkRegistrationInJson(returnedReg, json);
    checkRegistrationInJson(submittedReg, json);
  }

  private SubInvestigatorRegistration createSubInvestigatorRegistration(RegistrationStatus status) {
    InvestigatorRegistration investigatorRegistration =
        RegistrationFactory.getInstanceWithId().createInvestigatorRegistration(profile);
    SubInvestigatorRegistration registration =
        RegistrationFactory.getInstanceWithId()
            .createSubinvestigatorRegistration(investigatorRegistration, subInvestigatorProfile);
    investigatorRegistration.setStatus(status);
    return registration;
  }

  private void checkRegistrationInJson(SubInvestigatorRegistration registration, String json) {
    assertTrue(json.contains(registration.getId().toString()));
    assertTrue(json.contains(registration.getProtocol().getProtocolTitle()));
    InvestigatorRegistration primaryRegistration = registration.getPrimaryRegistration();
    assertTrue(json.contains(primaryRegistration.getStatus().getDisplay()));
    if (primaryRegistration.isLockedForInvestigator()
        || primaryRegistration.getStatus() == RegistrationStatus.RETURNED) {
      assertTrue(json.contains(action.getText("label.no")));
    } else {
      assertTrue(json.contains(action.getText("label.yes")));
    }
  }
}
public class ManageCertificationCredentialsActionTest extends AbstractWebTest {

  @Inject private InvestigatorProfileService mockProfileService;
  @Inject private GenericDataRetrievalService mockDataService;
  @Inject private ManageCertificationCredentialsAction action;
  private InvestigatorProfile profile = InvestigatorProfileFactory.getInstance().create();
  private Certification certification = CredentialFactory.getInstance().createCertification();

  @Before
  public void setUp() throws Exception {
    super.setUp();
    action.setProfile(profile);
    action.setServletRequest(getMockRequest());
    action.setPage(CERTIFICATION.name());
  }

  @Test
  public void testManageCredentialsAjaxEnter() {
    action.setPage(null);
    assertEquals(FirebirdUIConstants.RETURN_FIELDS_PAGE, action.manageCredentialsAjaxEnter());
    action.setPage("CLOSE");
    assertEquals("CLOSE", action.manageCredentialsAjaxEnter());
  }

  @Test
  public void testSaveCertification() throws Exception {
    when(mockDataService.getPersistentObject(eq(CertificationType.class), anyLong()))
        .thenReturn(CredentialFactory.getInstance().createCertification().getCertificationType());
    action.setCertification(certification);
    action.setEffectiveDate("11/2010");
    action.setExpirationDate("12/2010");
    action.setCertificationTypeId(1234L);
    assertEquals(FirebirdUIConstants.RETURN_CLOSE_DIALOG, action.saveCertification());
    verify(mockProfileService).saveCredential(profile, certification, FormTypeEnum.CV);
  }

  @Test
  public void testSaveCertification_SaveError() throws Exception {
    when(mockDataService.getPersistentObject(eq(CertificationType.class), anyLong()))
        .thenReturn(CredentialFactory.getInstance().createCertification().getCertificationType());
    doThrow(new CredentialAlreadyExistsException())
        .when(mockProfileService)
        .saveCredential(profile, certification, FormTypeEnum.CV);
    action.setCertification(certification);
    action.setEffectiveDate("12/2010");
    action.setCertificationTypeId(1234L);
    assertEquals(ActionSupport.INPUT, action.saveCertification());
  }

  @Test
  public void testSaveCertification_ValidationError() throws Exception {
    when(mockDataService.getPersistentObject(eq(CertificationType.class), anyLong()))
        .thenReturn(CredentialFactory.getInstance().createCertification().getCertificationType());
    doThrow(ValidationExceptionFactory.getInstance().create())
        .when(mockProfileService)
        .saveCredential(profile, certification, FormTypeEnum.CV);
    action.setCertification(certification);
    action.setEffectiveDate("12/2010");
    action.setCertificationTypeId(1234L);
    assertEquals(ActionSupport.INPUT, action.saveCertification());
  }

  @Test
  public void testSaveCertification_InvalidDates() throws Exception {
    action.setCertification(certification);
    action.setEffectiveDate("12/2010");
    action.setExpirationDate("11/2010");
    assertEquals(ActionSupport.INPUT, action.saveCertification());
    verifyZeroInteractions(mockProfileService);
    assertEquals(
        action.getText("error.expiration.date.before.effective"),
        action.getFieldErrors().get("expirationDate").get(0));
  }

  @Test
  public void testDeleteCertification() throws CredentialAlreadyExistsException {
    profile.addCredential(certification);
    action.setProfile(profile);
    action.setCertification(certification);
    assertEquals(1, profile.getCredentials().size());

    action.deleteCertification();
    assertEquals(0, profile.getCredentials().size());
    verify(mockProfileService).save(profile, FormTypeEnum.CV);
  }

  @Test
  public void testGetRankedCertifications() {
    List<CertificationType> certifications = new ArrayList<CertificationType>();
    Certification cert1 = CredentialFactory.getInstance().createCertification();
    Certification cert2 = CredentialFactory.getInstance().createCertification();
    Certification cert3 = CredentialFactory.getInstance().createCertification();
    certifications.add(cert1.getCertificationType());
    certifications.add(cert2.getCertificationType());
    certifications.add(cert3.getCertificationType());
    when(mockDataService.getAllRanked(CertificationType.class)).thenReturn(certifications);
    List<CertificationType> rankedCertifications = action.getRankedCertifications();
    assertNotNull(rankedCertifications);
    assertEquals(3, rankedCertifications.size());
    assertTrue(rankedCertifications.contains(cert1.getCertificationType()));
    assertTrue(rankedCertifications.contains(cert2.getCertificationType()));
    assertTrue(rankedCertifications.contains(cert3.getCertificationType()));
  }

  @Test
  public void testGetCertificationsWithRankedOnTop() {
    List<CertificationType> certifications = Lists.newArrayList();
    Certification cert = CredentialFactory.getInstance().createCertification();
    Certification rankedCert = CredentialFactory.getInstance().createCertification();
    certifications.add(cert.getCertificationType());
    certifications.add(rankedCert.getCertificationType());
    List<CertificationType> rankedCertifications = Lists.newArrayList();
    rankedCertifications.add(rankedCert.getCertificationType());

    when(mockDataService.getAllSorted(CertificationType.class)).thenReturn(certifications);
    when(mockDataService.getAllRanked(CertificationType.class)).thenReturn(rankedCertifications);

    List<CertificationType> expectedCertifications = Lists.newArrayList(rankedCertifications);
    expectedCertifications.addAll(certifications);
    assertEquals(expectedCertifications, action.getCertificationsWithRankedOnTop());
  }

  @Test
  public void testCertificationGetters() {
    Certification credential = CredentialFactory.getInstance().createCertification();
    credential.getCertificationType().setId(1L);

    action.setCredential(new Degree());
    assertNull(action.getCertification());

    action.setCertification(new Certification());

    when(mockDataService.getPersistentObject(CertificationType.class, null)).thenReturn(null);
    when(mockDataService.getPersistentObject(CertificationType.class, 1L))
        .thenReturn(credential.getCertificationType());

    action.setCertificationTypeId(null);
    assertNull(action.getCertificationTypeId());
    action.setCertificationTypeId(1L);
    assertEquals(Long.valueOf(1L), action.getCertificationTypeId());
  }
}