/**
   * Tests <code>{@link CopilotProjectDAOImpl#getCopilotProjects(long)}</code> method.
   *
   * @throws CopilotDAOException if any error occurs
   */
  @Test
  public void testGetCopilotProjects1() throws CopilotDAOException {

    CopilotProfile copilotProfile1 = TestHelper.createCopilotProfile();
    CopilotProject copilotProject1 = TestHelper.createCopilotProject();

    TestHelper.persistCopilotProjectDependencies(
        hibernateTemplate, copilotProfile1, copilotProject1);
    hibernateTemplate.save(copilotProject1);

    CopilotProfile copilotProfile2 = TestHelper.createCopilotProfile();
    CopilotProject copilotProject2 = TestHelper.createCopilotProject();

    TestHelper.persistCopilotProjectDependencies(
        hibernateTemplate, copilotProfile2, copilotProject2);
    hibernateTemplate.save(copilotProject2);

    List<CopilotProject> result =
        instance.getCopilotProjects(copilotProject1.getCopilotProfileId());

    Assert.assertEquals("Only one result was expected.", 1, result.size());
    assertCopilotProject(copilotProject1, result.get(0));

    result = instance.getCopilotProjects(copilotProject2.getCopilotProfileId());

    Assert.assertEquals("Only one result was expected.", 1, result.size());
    assertCopilotProject(copilotProject2, result.get(0));
  }
  /**
   * Tests <code>{@link CopilotProjectDAOImpl#delete(long)}</code> method.
   *
   * @throws CopilotDAOException if any error occurs
   */
  @Test
  @SuppressWarnings("unchecked")
  public void testDelete2() throws CopilotDAOException {

    CopilotProfile copilotProfile = TestHelper.createCopilotProfile();
    CopilotProject copilotProject = TestHelper.createCopilotProject();

    TestHelper.persistCopilotProjectDependencies(hibernateTemplate, copilotProfile, copilotProject);

    CopilotProjectInfoType copilotProjectInfoType = TestHelper.createCopilotProjectInfoType();
    hibernateTemplate.save(copilotProjectInfoType);

    CopilotProjectInfo copilotProjectInfo = TestHelper.createCopilotProjectInfo();
    copilotProjectInfo.setCopilotProjectId(copilotProject.getId());
    copilotProjectInfo.setInfoType(copilotProjectInfoType);
    copilotProject.getProjectInfos().add(copilotProjectInfo);
    hibernateTemplate.save(copilotProject);

    instance.delete(copilotProject.getId());

    Assert.assertEquals(
        "None entity in database should exist.",
        0,
        hibernateTemplate.find("from CopilotProject").size());
    Assert.assertEquals(
        "None entity in database should exist.",
        0,
        hibernateTemplate.find("from CopilotProjectInfo").size());
  }
  /**
   * Tests <code>{@link CopilotProjectDAOImpl#retrieve(long)}</code> method.
   *
   * @throws CopilotDAOException if any error occurs
   */
  @Test
  public void testRetrieve1() throws CopilotDAOException {

    CopilotProfile copilotProfile1 = TestHelper.createCopilotProfile();
    CopilotProject copilotProject1 = TestHelper.createCopilotProject();

    TestHelper.persistCopilotProjectDependencies(
        hibernateTemplate, copilotProfile1, copilotProject1);
    hibernateTemplate.save(copilotProject1);

    CopilotProfile copilotProfile2 = TestHelper.createCopilotProfile();
    CopilotProject copilotProject2 = TestHelper.createCopilotProject();

    TestHelper.persistCopilotProjectDependencies(
        hibernateTemplate, copilotProfile2, copilotProject2);
    hibernateTemplate.save(copilotProject2);

    CopilotProject result = instance.retrieve(copilotProject1.getId());

    assertCopilotProject(copilotProject1, result);

    result = instance.retrieve(copilotProject2.getId());

    assertCopilotProject(copilotProject2, result);
  }
  /**
   * Tests <code>{@link
   * CopilotProjectDAOImpl#create(com.topcoder.direct.services.copilot.model.IdentifiableEntity)}
   * </code> method.
   *
   * <p>{@link CopilotDAOException} is expected.
   *
   * @throws CopilotDAOException if any error occurs
   */
  @Test(expected = CopilotDAOException.class)
  public void testCreateFailure1() throws CopilotDAOException {

    CopilotProject copilotProject = TestHelper.createCopilotProject();
    copilotProject.setId(1);
    hibernateTemplate.save(copilotProject.getStatus());

    instance.create(copilotProject);
  }
  /**
   * Tests <code>{@link CopilotProjectDAOImpl#getCopilotProjects(long)}</code> method.
   *
   * @throws CopilotDAOException if any error occurs
   */
  @Test
  public void testGetCopilotProjects2() throws CopilotDAOException {

    CopilotProfile copilotProfile = TestHelper.createCopilotProfile();
    CopilotProject copilotProject1 = TestHelper.createCopilotProject();
    CopilotProject copilotProject2 = TestHelper.createCopilotProject();

    hibernateTemplate.save(copilotProfile.getStatus());
    hibernateTemplate.save(copilotProfile);

    copilotProject1.setCopilotProfileId(copilotProfile.getId());
    hibernateTemplate.save(copilotProject1.getStatus());
    hibernateTemplate.save(copilotProject1.getCopilotType());
    hibernateTemplate.save(copilotProject1);

    copilotProject2.setCopilotProfileId(copilotProfile.getId());
    hibernateTemplate.save(copilotProject2.getStatus());
    hibernateTemplate.save(copilotProject2.getCopilotType());
    hibernateTemplate.save(copilotProject2);

    List<CopilotProject> result =
        instance.getCopilotProjects(copilotProject1.getCopilotProfileId());

    Assert.assertEquals("Two results were expected.", 2, result.size());
    assertCopilotProject(copilotProject1, result.get(0));
    assertCopilotProject(copilotProject2, result.get(1));
  }
  /**
   * Tests <code>{@link
   * CopilotProjectDAOImpl#update(com.topcoder.direct.services.copilot.model.IdentifiableEntity)}
   * </code> method.
   *
   * <p>{@link CopilotDAOException} is expected.
   *
   * @throws CopilotDAOException if any error occurs
   */
  @Test(expected = CopilotDAOException.class)
  public void testUpdateFailure1() throws CopilotDAOException {

    CopilotProject copilotProject = TestHelper.createCopilotProject();

    Session session = instance.getSession();
    session.save(copilotProject.getStatus());
    session.save(copilotProject);
    session.delete(copilotProject);

    instance.update(copilotProject);
  }
  /**
   * Tests <code>{@link
   * CopilotProjectDAOImpl#update(com.topcoder.direct.services.copilot.model.IdentifiableEntity)}
   * </code> method.
   *
   * <p>{@link CopilotDAOException} is expected.
   *
   * @throws CopilotDAOException if any error occurs
   */
  @Test(expected = CopilotDAOException.class)
  public void testUpdateFailure2() throws CopilotDAOException {

    CopilotProject copilotProject = TestHelper.createCopilotProject();
    copilotProject.setId(1L);

    ApplicationContext applicationContext =
        new ClassPathXmlApplicationContext("invalidApplicationContext.xml");
    CopilotProjectDAOImpl copilotProjectDAO = new CopilotProjectDAOImpl();
    copilotProjectDAO.setSessionFactory(
        (SessionFactory) applicationContext.getBean("sessionFactory"));

    copilotProjectDAO.update(copilotProject);
  }
  /**
   * Tests <code>{@link
   * CopilotProjectDAOImpl#update(com.topcoder.direct.services.copilot.model.IdentifiableEntity)}
   * </code> method.
   *
   * @throws CopilotDAOException if any error occurs
   */
  @Test
  @SuppressWarnings("unchecked")
  public void testUpdate() throws CopilotDAOException {

    CopilotProfile copilotProfile = TestHelper.createCopilotProfile();
    CopilotProject copilotProject = TestHelper.createCopilotProject();

    TestHelper.persistCopilotProjectDependencies(hibernateTemplate, copilotProfile, copilotProject);
    hibernateTemplate.save(copilotProject);

    copilotProject.setCompletionDate(new Date());
    copilotProject.setCustomerFeedback("test customer feedback");
    copilotProject.setCustomerRating(0.9F);
    copilotProject.setPmFeedback("test pm feedback");
    copilotProject.setPmRating(0.9F);

    CopilotProjectInfoType copilotProjectInfoType = TestHelper.createCopilotProjectInfoType();
    hibernateTemplate.save(copilotProjectInfoType);

    CopilotProjectInfo copilotProjectInfo = TestHelper.createCopilotProjectInfo();
    copilotProjectInfo.setInfoType(copilotProjectInfoType);
    copilotProject.getProjectInfos().add(copilotProjectInfo);

    instance.update(copilotProject);

    List<CopilotProject> result =
        (List<CopilotProject>)
            hibernateTemplate.find("from CopilotProject where id = ?", copilotProject.getId());

    assertCopilotProject(copilotProject, result.get(0));
  }
  /**
   * Tests <code>{@link
   * CopilotProjectDAOImpl#updateAuditTimestamp(com.topcoder.direct.services.copilot.model.IdentifiableEntity
   * , boolean)}</code> method.
   *
   * @throws Exception if any error occurs
   */
  @Test
  public void testUpdateAuditTimestamp2() throws Exception {

    CopilotProject copilotProject = TestHelper.createCopilotProject();

    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
    Date date = simpleDateFormat.parse("2010-01-30");
    copilotProject.setCreateDate(date);
    copilotProject.setModifyDate(date);

    instance.updateAuditTimestamp(copilotProject, false);

    Assert.assertEquals("Create date should be not changed", date, copilotProject.getCreateDate());
    Assert.assertFalse(
        "Modification date was not changed", copilotProject.getModifyDate().equals(date));
  }
  /**
   * Tests <code>{@link
   * CopilotProjectDAOImpl#create(com.topcoder.direct.services.copilot.model.IdentifiableEntity)}
   * </code> method.
   *
   * @throws com.topcoder.direct.services.copilot.dao.CopilotDAOException if any error occurs
   */
  @Test
  @SuppressWarnings("unchecked")
  public void testCreate1() throws CopilotDAOException {

    CopilotProfile copilotProfile = TestHelper.createCopilotProfile();
    CopilotProject copilotProject = TestHelper.createCopilotProject();

    TestHelper.persistCopilotProjectDependencies(hibernateTemplate, copilotProfile, copilotProject);

    instance.create(copilotProject);

    List<CopilotProject> result =
        (List<CopilotProject>)
            hibernateTemplate.find("from CopilotProject where id = ?", copilotProject.getId());

    assertCopilotProject(copilotProject, result.get(0));
  }
  /**
   * Tests <code>{@link CopilotProjectDAOImpl#delete(long)}</code> method.
   *
   * @throws CopilotDAOException if any error occurs
   */
  @Test
  @SuppressWarnings("unchecked")
  public void testDelete1() throws CopilotDAOException {

    CopilotProfile copilotProfile1 = TestHelper.createCopilotProfile();
    CopilotProject copilotProject1 = TestHelper.createCopilotProject();

    TestHelper.persistCopilotProjectDependencies(
        hibernateTemplate, copilotProfile1, copilotProject1);
    hibernateTemplate.save(copilotProject1);

    CopilotProfile copilotProfile2 = TestHelper.createCopilotProfile();
    CopilotProject copilotProject2 = TestHelper.createCopilotProject();

    TestHelper.persistCopilotProjectDependencies(
        hibernateTemplate, copilotProfile2, copilotProject2);
    hibernateTemplate.save(copilotProject2);

    instance.delete(copilotProject1.getId());

    List<CopilotProject> result =
        hibernateTemplate.find("from CopilotProject where id = ?", copilotProject1.getId());

    Assert.assertEquals(
        "One entity in database should still exist.",
        1,
        hibernateTemplate.find("from CopilotProject").size());
    Assert.assertEquals("Entity was not deleted.", 0, result.size());

    instance.delete(copilotProject2.getId());

    result = hibernateTemplate.find("from CopilotProject where id = ?", copilotProject2.getId());

    Assert.assertEquals(
        "None entity in database should exist.",
        0,
        hibernateTemplate.find("from CopilotProject").size());
    Assert.assertEquals("Entity was not deleted.", 0, result.size());
  }
  /**
   * The main logic to create the new project and assign permissions to the new project.
   *
   * @throws Exception if there is any error.
   */
  @Override
  protected void executeAction() throws Exception {
    TCSubject currentUser = DirectStrutsActionsHelper.getTCSubjectFromSession();

    Map<String, String> result = new HashMap<String, String>();

    // create new project first
    ProjectServiceFacade projectServiceFacade = getProjectServiceFacade();

    if (null == projectServiceFacade) {
      throw new IllegalStateException("The project service facade is not initialized");
    }

    // create the project data with the input parameters.
    ProjectData projectData = new ProjectData();
    projectData.setName(getProjectName());
    projectData.setDescription(getProjectDescription());
    // prepare the project answer.
    for (ProjectAnswer answer : getProjectData().getProjectAnswers()) {
      if (answer.getOptionAnswers() != null) {
        for (ProjectAnswerOption answerOption : answer.getOptionAnswers()) {
          answerOption.setProjectAnswer(answer);
        }
      }
      // replace XWorkList by ArrayList.
      if (answer.getMultipleAnswers() != null) {
        List<String> s = new ArrayList<String>();
        for (String mAnswer : answer.getMultipleAnswers()) {
          s.add(mAnswer);
        }
        answer.setMultipleAnswers(s);
      }
    }
    projectData.setProjectAnswers(getProjectData().getProjectAnswers());

    // set project billing account id if exists
    if (getProjectData().getProjectBillingAccountId() > 0) {

      // check if user has access to the billing account
      if (!canAccessBillingAccount(getProjectData().getProjectBillingAccountId())) {
        throw new IllegalArgumentException(
            "You don't have permission to access the billing account you set");
      }
      projectData.setProjectBillingAccountId(getProjectData().getProjectBillingAccountId());
    }

    if (forums != null) {
      Map<String, String> forumsMap = new HashMap<String, String>();
      for (ProjectForumTemplateDTO forum : forums) {
        forumsMap.put(forum.getForumName(), forum.getForumDescription());
      }
      // delegate to ProjectServiceFacade to create the project.
      projectData =
          projectServiceFacade.createTCDirectProject(
              currentUser, projectData, getPermissions(), forumsMap);
    } else {
      // delegate to ProjectServiceFacade to create the project.
      projectData =
          projectServiceFacade.createTCDirectProject(currentUser, projectData, getPermissions());
    }

    if (getProjectData().getProjectBillingAccountId() > 0) {
      DirectUtils.updateDirectProjectBugContestFee(
          DirectUtils.getTCSubjectFromSession(),
          projectData.getProjectId(),
          getProjectServiceFacade(),
          getProjectContestFeeService(),
          getProjectContestFeePercentageService());
    }

    // put data into result
    result.put("projectName", projectData.getName());
    result.put("projectId", String.valueOf(projectData.getProjectId()));

    if (!isCreateCopilotPosting()) {
      // check whether has copilots to add
      if (getCopilotIds() != null && getCopilotIds().length > 0) {
        // add the copilot into the new project
        List<CopilotProject> copilotProjects = new ArrayList<CopilotProject>();
        List<Boolean> removeFlags = new ArrayList<Boolean>();

        for (long id : getCopilotIds()) {
          removeFlags.add(false);

          CopilotProject copilotProject = new CopilotProject();
          copilotProject.setTcDirectProjectId(projectData.getProjectId());
          copilotProject.setCopilotProfileId(id);
          copilotProject.setId(0);
          copilotProjects.add(copilotProject);
        }

        // update copilots projects
        getContestServiceFacade().updateCopilotProjects(currentUser, copilotProjects, removeFlags);
      }

      if (presentationProject) {
        // create the draft copilot contest
        createPPTCopilotDraftPosting(projectData);
        // create JIRA issue
        Map<String, Object> conetstResult = (Map<String, Object>) getResult();
        String description =
            "Copilot Opportunities: " + copilotURLPrefix + conetstResult.get("projectId");
        JiraRpcServiceWrapper.createIssue(
            pptJIRAProject, pptJIRAIssueTypeId, projectName, description, pptJIRAIssueReporter);
      }
    } else {
      createCopilotDraftPosting(projectData);
    }

    setResult(result);
  }
 /**
  * Tests <code>{@link
  * CopilotProjectDAOImpl#update(com.topcoder.direct.services.copilot.model.IdentifiableEntity)}
  * </code> method when entity has negative id.
  *
  * <p>{@link IllegalArgumentException} is expected.
  *
  * @throws CopilotDAOException if any error occurs
  */
 @Test(expected = IllegalArgumentException.class)
 public void testUpdateNegative() throws CopilotDAOException {
   CopilotProject copilotProject = new CopilotProject();
   copilotProject.setId(-1);
   instance.update(copilotProject);
 }
  /**
   * Asserts that the passed {@link CopilotProject} instances are exactly the same.
   *
   * @param copilotProject project to compare
   * @param result project to compare
   */
  private void assertCopilotProject(CopilotProject copilotProject, CopilotProject result) {
    Assert.assertEquals("Invalid CopilotProject id", copilotProject.getId(), result.getId());
    Assert.assertEquals(
        "Invalid CopilotProject status", copilotProject.getStatus(), result.getStatus());

    Assert.assertEquals("Invalid CopilotProject name", copilotProject.getName(), result.getName());
    Assert.assertEquals(
        "Invalid CopilotProject completion date",
        copilotProject.getCompletionDate(),
        result.getCompletionDate());
    Assert.assertEquals(
        "Invalid CopilotProject copilot type",
        copilotProject.getCopilotType(),
        result.getCopilotType());
    Assert.assertEquals(
        "Invalid CopilotProject customer feedback",
        copilotProject.getCustomerFeedback(),
        result.getCustomerFeedback());
    Assert.assertEquals(
        "Invalid CopilotProject customer rating",
        copilotProject.getCustomerRating(),
        result.getCustomerRating());
    Assert.assertEquals(
        "Invalid CopilotProject pm feedback",
        copilotProject.getPmFeedback(),
        result.getPmFeedback());
    Assert.assertEquals(
        "Invalid CopilotProject pm rating", copilotProject.getPmRating(), result.getPmRating());
    Assert.assertEquals(
        "Invalid CopilotProject tcDirectProjectId",
        copilotProject.getTcDirectProjectId(),
        result.getTcDirectProjectId());

    Assert.assertEquals(
        "Invalid CopilotProject create user",
        copilotProject.getCreateUser(),
        result.getCreateUser());
    Assert.assertEquals(
        "Invalid CopilotProject modify user",
        copilotProject.getModifyUser(),
        result.getModifyUser());
  }