@Test
  public void testDelete_deleteChoices_withChildren_deleteChildren() {
    Story child = new Story();
    child.setBacklog(storyInIteration.getBacklog());
    child.setIteration(iteration);
    child.setId(2333);
    child.setParent(storyInIteration);
    storyInIteration.getChildren().add(child);
    storyInIteration.setIteration(null);

    blheBusiness.updateHistory(child.getBacklog().getId());
    iheBusiness.updateIterationHistory(iteration.getId());

    hourEntryBusiness.deleteAll(child.getHourEntries());
    hourEntryBusiness.deleteAll(storyInIteration.getHourEntries());

    //        storyRankBusiness.removeStoryRanks(child);
    //        storyRankBusiness.removeStoryRanks(storyInIteration);

    //        expect(storyDAO.get(2333)).andReturn(child);

    storyDAO.remove(child.getId());
    storyDAO.remove(storyInIteration);

    replayAll();
    storyBusiness.delete(
        storyInIteration,
        TaskHandlingChoice.DELETE,
        HourEntryHandlingChoice.DELETE,
        HourEntryHandlingChoice.DELETE,
        ChildHandlingChoice.DELETE);
    //        assertNull(child.getParent());
    assertTrue(storyInIteration.getChildren().isEmpty());
    verifyAll();
  }
  @Test
  public void testStore_updateBacklogAndClearResponsibles() {
    this.store_createMockStoryBusiness();
    Backlog newBacklog = new Project();
    newBacklog.setId(123);
    Set<User> users = new HashSet<User>(Arrays.asList(new User(), new User()));
    storyInIteration.setResponsibles(users);

    expect(storyDAO.get(storyInIteration.getId())).andReturn(storyInIteration);
    expect(backlogBusiness.retrieve(newBacklog.getId())).andReturn(newBacklog);

    storyDAO.store(EasyMock.isA(Story.class));

    blheBusiness.updateHistory(storyInIteration.getBacklog().getId());

    replayAll();
    Story actual =
        storyBusiness.store(
            storyInIteration.getId(),
            new Story(),
            newBacklog.getId(),
            new HashSet<Integer>(),
            false);
    verifyAll();

    assertEquals(0, actual.getResponsibles().size());

    assertTrue(storyBacklogUpdated);
  }
  @Test
  @DirtiesContext
  public void moveSingleFromProjectToProjectNoViolation() {
    Story parent = new Story();
    Story child = new Story();
    story.setBacklog(secondProject);
    story.setParent(parent);
    story.getChildren().add(child);
    child.setParent(story);

    expect(backlogBusiness.getParentProduct(secondProject)).andReturn(firstProduct).anyTimes();
    expect(backlogBusiness.getParentProduct(firstProject)).andReturn(firstProduct).anyTimes();

    storyDAO.store(child);
    storyDAO.store(story);
    expect(storyTreeIntegrityBusiness.hasParentStoryConflict(story, firstProject)).andReturn(false);
    storyHierarchyBusiness.updateChildrenTreeRanks(parent);
    backlogHistoryEntryBusiness.updateHistory(secondProject.getId());
    backlogHistoryEntryBusiness.updateHistory(firstProject.getId());

    storyRankBusiness.removeRank(story, secondProject);
    storyRankBusiness.rankToBottom(story, firstProject);
    replayAll();

    storyBusiness.moveSingleStoryToBacklog(story, firstProject);
    verifyAll();
    assertEquals(firstProject, story.getBacklog());
    assertEquals(parent, story.getParent());
    assertEquals(parent, child.getParent());
  }
  @Test
  @DirtiesContext
  public void moveFromIterationToIteration_inProject() {
    firstIteration.setParent(firstProject);
    secondIteration.setParent(firstProject);
    story.setBacklog(firstIteration);

    expect(storyTreeIntegrityBusiness.canStoryBeMovedToBacklog(story, secondIteration))
        .andReturn(true);
    storyDAO.store(story);
    storyRankBusiness.removeRank(story, firstIteration);
    storyRankBusiness.rankToBottom(story, secondIteration);

    backlogHistoryEntryBusiness.updateHistory(firstIteration.getId());
    backlogHistoryEntryBusiness.updateHistory(secondIteration.getId());

    iterationHistoryBusiness.updateIterationHistory(firstIteration.getId());
    iterationHistoryBusiness.updateIterationHistory(secondIteration.getId());

    replayAll();

    storyBusiness.moveStoryToBacklog(story, secondIteration);
    verifyAll();
    assertEquals(secondIteration, story.getBacklog());
  }
  @Test
  public void testStore_updateResponsibles() {
    this.store_createMockStoryBusiness();

    Backlog backlog = storyInIteration.getBacklog();
    User user1 = new User();
    User user2 = new User();
    Set<User> users = new HashSet<User>(Arrays.asList(user1, user2));

    expect(storyDAO.get(storyInIteration.getId())).andReturn(storyInIteration);
    expect(userDAO.get(123)).andReturn(user1);
    expect(userDAO.get(222)).andReturn(user2);
    storyDAO.store(EasyMock.isA(Story.class));

    Story dataItem = new Story();
    dataItem.setName("Foo item");
    dataItem.setDescription("Fubar");
    dataItem.setStoryPoints(333);
    dataItem.setState(StoryState.PENDING);

    blheBusiness.updateHistory(storyInIteration.getBacklog().getId());

    replayAll();
    Story actual =
        storyBusiness.store(
            storyInIteration.getId(),
            dataItem,
            null,
            new HashSet<Integer>(Arrays.asList(123, 222)),
            false);
    verifyAll();

    assertSame("The backlogs don't match", backlog, actual.getBacklog());
    assertEquals("The responsibles don't match", users, actual.getResponsibles());

    assertEquals(dataItem.getName(), actual.getName());
    assertEquals(dataItem.getDescription(), actual.getDescription());
    assertEquals(dataItem.getStoryPoints(), actual.getStoryPoints());
    assertEquals(dataItem.getState(), actual.getState());

    assertFalse(storyBacklogUpdated);
  }
 @Test
 public void testDelete_hourEntryChoice_move() {
   storyInIteration.getHourEntries().add(new StoryHourEntry());
   hourEntryBusiness.moveToBacklog(
       storyInIteration.getHourEntries(), storyInIteration.getBacklog());
   //        storyRankBusiness.removeStoryRanks(storyInIteration);
   storyDAO.remove(storyInIteration);
   replayAll();
   storyBusiness.delete(storyInIteration, null, HourEntryHandlingChoice.MOVE, null, null);
   verifyAll();
   assertTrue(storyInIteration.getHourEntries().isEmpty());
 }
 @Test
 public void testDelete_taskChoice_move() {
   Task task = new Task();
   storyInIteration.getTasks().add(task);
   expect(taskBusiness.move(task, storyInIteration.getBacklog().getId(), null)).andReturn(task);
   //        storyRankBusiness.removeStoryRanks(storyInIteration);
   storyDAO.remove(storyInIteration);
   replayAll();
   storyBusiness.delete(storyInIteration, TaskHandlingChoice.MOVE, null, null, null);
   verifyAll();
   assertTrue(storyInIteration.getTasks().isEmpty());
 }
  @Test
  public void testDeleteAndUpdateHistory() {
    expect(storyDAO.get(storyInIteration.getId())).andReturn(storyInIteration);
    //        storyRankBusiness.removeStoryRanks(storyInIteration);
    storyDAO.remove(storyInIteration);
    blheBusiness.updateHistory(storyInIteration.getBacklog().getId());
    iheBusiness.updateIterationHistory(storyInIteration.getIteration().getId());
    replayAll();

    storyBusiness.deleteAndUpdateHistory(storyInIteration.getId(), null, null, null, null);
    verifyAll();
  }
 @Test
 public void testDelete_taskChoice_delete() {
   Task task = new Task();
   storyInIteration.getTasks().add(task);
   hourEntryBusiness.moveToBacklog(task.getHourEntries(), storyInIteration.getBacklog());
   taskBusiness.delete(task.getId(), HourEntryHandlingChoice.MOVE);
   //        storyRankBusiness.removeStoryRanks(storyInIteration);
   storyDAO.remove(storyInIteration);
   replayAll();
   storyBusiness.delete(
       storyInIteration, TaskHandlingChoice.DELETE, null, HourEntryHandlingChoice.MOVE, null);
   verifyAll();
   assertNull(task.getStory());
   assertTrue(storyInIteration.getTasks().isEmpty());
 }
 @Test
 @DirtiesContext
 public void moveFromProductToProduct() {
   Product prod = new Product();
   prod.setId(313);
   story.setBacklog(firstProduct);
   expect(storyTreeIntegrityBusiness.canStoryBeMovedToBacklog(story, prod)).andReturn(true);
   storyDAO.store(story);
   backlogHistoryEntryBusiness.updateHistory(prod.getId());
   backlogHistoryEntryBusiness.updateHistory(firstProduct.getId());
   replayAll();
   storyBusiness.moveStoryToBacklog(story, prod);
   assertEquals(prod, story.getBacklog());
   verifyAll();
 }
  @Test
  @DirtiesContext
  public void moveFromProductToProject() {
    story.setBacklog(firstProduct);

    expect(storyTreeIntegrityBusiness.canStoryBeMovedToBacklog(story, firstProject))
        .andReturn(true);
    storyDAO.store(story);
    storyRankBusiness.rankToBottom(story, firstProject);

    backlogHistoryEntryBusiness.updateHistory(firstProduct.getId());
    backlogHistoryEntryBusiness.updateHistory(firstProject.getId());

    replayAll();
    storyBusiness.moveStoryToBacklog(story, firstProject);
    verifyAll();
    assertEquals(firstProject, story.getBacklog());
  }
  @Test
  @DirtiesContext
  public void moveFromProjectToProject_hasChildren() {
    story.setBacklog(secondProject);
    Story child = new Story();
    story.getChildren().add(child);

    expect(backlogBusiness.getParentProduct(secondProject)).andReturn(firstProduct);
    expect(backlogBusiness.getParentProduct(firstProject)).andReturn(firstProduct);

    expect(storyTreeIntegrityBusiness.canStoryBeMovedToBacklog(story, firstProject))
        .andReturn(true);
    storyDAO.store(story);
    backlogHistoryEntryBusiness.updateHistory(secondProject.getId());
    backlogHistoryEntryBusiness.updateHistory(firstProject.getId());
    replayAll();

    storyBusiness.moveStoryToBacklog(story, firstProject);
    verifyAll();
    assertEquals(firstProject, story.getBacklog());
  }
  @Override
  public String intercept(ActionInvocation invocation) throws Exception {
    // System.out.println("URL: " + ServletActionContext.getRequest().getRequestURL().toString());
    HttpServletRequest req = ServletActionContext.getRequest();
    String actionName = ServletActionContext.getActionMapping().getName();

    User loggedUser =
        SecurityUtil
            .getLoggedUser(); // SecurityUtil.getLoggedUser() can't get all needed information of
                              // user -> should retrieve by making new user.
    User user = userBusiness.retrieve(loggedUser.getId());

    boolean admin = user.isAdmin();
    boolean readOnly = user.getName().equals("readonly");
    boolean access = false;

    if (admin) {
      // if admin, everything is fine
      access = true;
    } else if (readOnly) {
      // check read only operations
      if (actionName.equals("ROIterationHistoryByToken")
          || actionName.equals("ROIterationMetricsByToken")
          || actionName.equals(("ROIterationData"))) {
        access = true;
      }
    } else {
      if (actionName.equals("createTeam")
          || actionName.equals("deleteTeam")
          || actionName.equals("deleteTeamForm")
          || actionName.equals("storeTeam")
          || actionName.equals("storeNewTeam")) {

        // these are admin-only operations
        access = false;

      } else if (actionName.equals("storeUserAndRedirect")) {
        Map params = req.getParameterMap();
        boolean attemptAdmin = params.containsKey("user.admin");
        int id = Integer.parseInt(((String[]) params.get("userId"))[0]);
        if (id == user.getId() && !attemptAdmin) {
          access = true;
        }
      } else if (actionName.equals("storeUser")) {

        // check if ID is of current user, and what is being stored
        // can't set user.admin or team
        Map params = req.getParameterMap();
        boolean attemptAdmin = params.containsKey("user.admin");
        boolean attemptTeam = params.containsKey("teamsChanged") || params.containsKey("teamIds");
        int id = Integer.parseInt(((String[]) params.get("userId"))[0]);

        if (id == user.getId() && !attemptAdmin && !attemptTeam) {
          // check not setting user.admin
          access = true;
        }
      } else if (actionName.equals("storeNewUser")) {
        Map params = req.getParameterMap();
        boolean attemptToCreateNonAdmin =
            params.containsKey("user.admin")
                && ((String[]) params.get("user.admin"))[0].equals("false");
        // Non admins can create only other non admin users
        if (attemptToCreateNonAdmin) {
          // Non admins can only add new users to their teams
          if (params.containsKey("teamIds")) {
            Set<String> myTeamIds = new HashSet<String>();
            for (Team team : user.getTeams()) {
              myTeamIds.add("" + team.getId());
            }
            String[] teamIds = (String[]) params.get("teamIds");
            Set<String> newUserTeamIds = new HashSet<String>();
            for (String teamId : teamIds) {
              newUserTeamIds.add(teamId);
            }
            if (myTeamIds.containsAll(newUserTeamIds)) {
              access = true;
            }
          } else {
            access = true;
          }
        }
      } else if (actionName.equals("retrieveAllProducts")
          || actionName.equals("retrieveAllSAIterations")) {
        // access matrix operations
        access = false;
      } else if (actionName.equals("storeNewIteration") || actionName.equals("storeNewProduct")) {
        // these are operations available to everyone
        access = true;
      } else if ((actionName.equals("retrieveBranchMetrics")
              || actionName.equals("getStoryHierarchy"))
          && req.getParameterMap().containsKey("storyId")) {
        Map params = req.getParameterMap();
        int storyId = Integer.parseInt(((String[]) params.get("storyId"))[0]);
        Story story = storyBusiness.retrieve(storyId);
        if (story.getIteration() != null) {
          access =
              this.authorizationBusiness.isBacklogAccessible(story.getIteration().getId(), user);
        }
        if (!access && story.getBacklog() != null) {
          access = this.authorizationBusiness.isBacklogAccessible(story.getBacklog().getId(), user);
        }
      } else {
        // Default case: Try to find a backlog id of some kind to check.

        Map params = req.getParameterMap();
        int id = -1;
        if (params.containsKey("iterationId"))
          id = Integer.parseInt(((String[]) params.get("iterationId"))[0]);
        else if (params.containsKey("backlogId"))
          id = Integer.parseInt(((String[]) params.get("backlogId"))[0]);
        else if (params.containsKey("productId"))
          id = Integer.parseInt(((String[]) params.get("productId"))[0]);
        else if (params.containsKey("projectId"))
          id = Integer.parseInt(((String[]) params.get("projectId"))[0]);
        else if (params.containsKey("taskId")) {
          int taskId = Integer.parseInt(((String[]) params.get("taskId"))[0]);
          Task task = taskBusiness.retrieve(taskId);
          if (task.getIteration() != null) id = task.getIteration().getId();
          else if (task.getStory().getIteration() != null)
            id = task.getStory().getIteration().getId();
          else id = task.getStory().getBacklog().getId(); // story in project/product w/a iteration
        } else if (params.containsKey("storyId")) {
          int storyId = Integer.parseInt(((String[]) params.get("storyId"))[0]);
          Story story = storyBusiness.retrieve(storyId);
          if (story.getIteration() != null) {
            id = story.getIteration().getId();
          } else {
            id = story.getBacklog().getId();
          }
        }

        boolean attemptTeam = params.containsKey("teamsChanged");
        if (!attemptTeam) {
          if (id != -1
              && !(id == 0 && actionName.equals("retrieveSubBacklogs") && params.size() == 1))
            access = this.authorizationBusiness.isBacklogAccessible(id, user);
          else
            // Operations without ids must be allowed
            access = true;
        }
      }
    }

    if (access) return invocation.invoke();
    else return "noauth";
  }