Package org.projectforge.task

Source Code of org.projectforge.task.TaskTest

/////////////////////////////////////////////////////////////////////////////
//
// Project ProjectForge Community Edition
//         www.projectforge.org
//
// Copyright (C) 2001-2014 Kai Reinhard (k.reinhard@micromata.de)
//
// ProjectForge is dual-licensed.
//
// This community edition is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as published
// by the Free Software Foundation; version 3 of the License.
//
// This community edition is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
// Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, see http://www.gnu.org/licenses/.
//
/////////////////////////////////////////////////////////////////////////////

package org.projectforge.task;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.io.Serializable;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import org.junit.Test;
import org.projectforge.access.AccessException;
import org.projectforge.access.AccessType;
import org.projectforge.access.OperationType;
import org.projectforge.common.DateHolder;
import org.projectforge.core.UserException;
import org.projectforge.fibu.ProjektDO;
import org.projectforge.fibu.ProjektDao;
import org.projectforge.fibu.kost.Kost2ArtDO;
import org.projectforge.fibu.kost.Kost2ArtDao;
import org.projectforge.fibu.kost.Kost2DO;
import org.projectforge.fibu.kost.Kost2Dao;
import org.projectforge.test.TestBase;
import org.projectforge.timesheet.TimesheetDO;
import org.projectforge.timesheet.TimesheetDao;
import org.projectforge.user.GroupDO;

public class TaskTest extends TestBase
{
  // private static final Logger log = Logger.getLogger(TaskTest.class);

  private TaskDao taskDao;

  private ProjektDao projektDao;

  private Kost2Dao kost2Dao;

  private Kost2ArtDao kost2ArtDao;

  private TaskTree taskTree;

  private TimesheetDao timesheetDao;

  public void setTaskDao(final TaskDao taskDao)
  {
    this.taskDao = taskDao;
  }

  public void setProjektDao(final ProjektDao projektDao)
  {
    this.projektDao = projektDao;
  }

  public void setKost2Dao(final Kost2Dao kost2Dao)
  {
    this.kost2Dao = kost2Dao;
  }

  public void setKost2ArtDao(final Kost2ArtDao kost2ArtDao)
  {
    this.kost2ArtDao = kost2ArtDao;
  }

  public void setTaskTree(final TaskTree taskTree)
  {
    this.taskTree = taskTree;
  }

  public void setTimesheetDao(final TimesheetDao timesheetDao)
  {
    this.timesheetDao = timesheetDao;
  }

  @Test
  public void testTaskDO()
  {
    final List<TaskDO> list = taskDao.internalLoadAll();
    for (final TaskDO task : list) {
      if ("root".equals(task.getTitle()) == true) {
        assertNull("Only root node has no parent task.", task.getParentTaskId());
      } else {
        assertNotNull("Only root node has no parent task.", task.getParentTaskId());
      }
    }
    final TaskDO task = super.getTask("1.1");
    logon(ADMIN);
    final TaskDO dbTask = taskDao.getById(task.getId());
    assertEquals(task.getId(), dbTask.getId());
    assertEquals(task.getTitle(), dbTask.getTitle());
  }

  @Test
  public void testTaskTree()
  {
    final TaskTree taskTree = taskDao.getTaskTree();
    final TaskNode root = taskTree.getRootTaskNode();
    assertNull(root.getParent());
    assertEquals("root", root.getTask().getTitle());
    assertNotNull("root node must have childs", root.getChilds());
    assertTrue("root node must have childs", root.getChilds().size() > 0);

    final TaskNode node1_1 = taskTree.getTaskNodeById(getTask("1.1").getId());
    assertEquals(getTask("1.1").getTitle(), node1_1.getTask().getTitle());
    assertEquals(getTask("1.1").getParentTaskId(), node1_1.getParent().getId());
    final TaskNode node1 = taskTree.getTaskNodeById(getTask("1").getId());
    final List<TaskNode> list = node1.getChilds();
    assertEquals("Childs of 1 are 1.1 and 1.2", 2, list.size());
    final TaskNode task1_1_1 = taskTree.getTaskNodeById(getTask("1.1.1").getId());
    final List<TaskNode> path = task1_1_1.getPathToRoot();
    assertEquals("Node has 2 ancestors plus itself.", 3, path.size());
    assertEquals("Top task in path should be '1'", getTask("1").getId(), path.get(0).getId());
    assertEquals("Second task in path sould be '1.1'", getTask("1.1").getId(), path.get(1).getId());
    assertEquals("Third task in path is the node itself: '1.1'", getTask("1.1.1").getId(), path.get(2).getId());
  }

  @Test
  public void testTraversingTaskTree()
  {
    final TaskTree taskTree = taskDao.getTaskTree();
    final TaskNode root = taskTree.getRootTaskNode();
    logStart("Traversing TaskTree");
    traverseTaskTree(root);
    logEnd();
  }

  @Test
  public void testCyclicTasks()
  {
    final TaskTree tree = taskDao.getTaskTree();
    initTestDB.addTask("cyclictest", "root");
    initTestDB.addTask("c", "cyclictest");
    initTestDB.addTask("c.1", "c");
    initTestDB.addTask("c.1.1", "c.1");
    final TaskNode c = tree.getTaskNodeById(getTask("c").getId());
    final TaskNode c_1_1 = tree.getTaskNodeById(getTask("c.1.1").getId());
    try {
      c.setParent(c_1_1);
      fail("Cyclic reference not detected.");
    } catch (final UserException ex) {
      assertEquals(TaskDao.I18N_KEY_ERROR_CYCLIC_REFERENCE, ex.getI18nKey());
    }
    try {
      c.setParent(c);
      fail("Cyclic reference not detected.");
    } catch (final UserException ex) {
      assertEquals(TaskDao.I18N_KEY_ERROR_CYCLIC_REFERENCE, ex.getI18nKey());
    }
  }

  @Test
  public void testTaskDescendants()
  {
    final TaskTree tree = taskDao.getTaskTree();
    initTestDB.addTask("descendanttest", "root");
    initTestDB.addTask("d", "descendanttest");
    initTestDB.addTask("d.1", "d");
    initTestDB.addTask("d.1.1", "d.1");
    initTestDB.addTask("d.1.2", "d.1");
    initTestDB.addTask("d.1.2.1", "d.1.2");
    initTestDB.addTask("d.2", "d");
    final TaskNode d = tree.getTaskNodeById(getTask("d").getId());
    final List<Integer> ids = d.getDescendantIds();
    assertEquals(5, ids.size());
    assertTrue(ids.contains(getTask("d.1").getId()));
    assertTrue(ids.contains(getTask("d.1.1").getId()));
    assertTrue(ids.contains(getTask("d.1.2").getId()));
    assertTrue(ids.contains(getTask("d.1.2.1").getId()));
    assertTrue(ids.contains(getTask("d.2").getId()));
    assertFalse(ids.contains(getTask("d").getId()));
  }

  @Test
  public void testTaskTreeUpdate()
  {
    final TaskTree tree = taskDao.getTaskTree();
    initTestDB.addTask("taskTreeUpdateTest", "root");
    initTestDB.addTask("u", "taskTreeUpdateTest");
    final TaskNode u = tree.getTaskNodeById(getTask("u").getId());
    final TaskNode parent = tree.getTaskNodeById(getTask("taskTreeUpdateTest").getId());
    assertEquals("Should have no childs", false, u.hasChilds());
    assertEquals(u.getParent().getId(), parent.getId());
    initTestDB.addTask("u.1", "u");
    assertEquals("Should have childs", true, u.hasChilds());
    assertEquals("Should have exact 1 child", 1, u.getChilds().size());
    initTestDB.addTask("u.2", "u");
    assertEquals("Should have exact 2 childs", 2, u.getChilds().size());
    initTestDB.addTask("u.2.1", "u.2");
    initTestDB.addTask("u.2.2", "u.2");
    initTestDB.addTask("u.2.3", "u.2");
    final TaskNode u1 = tree.getTaskNodeById(getTask("u.1").getId());
    final TaskNode u2 = tree.getTaskNodeById(getTask("u.2").getId());
    assertEquals("Should have exact 3 childs", 3, u2.getChilds().size());
    // Now we move u.2.3 to u.1.1:
    final TaskDO tu_2_3 = taskDao.internalGetById(getTask("u.2.3").getId());
    tu_2_3.setTitle("u.1.1");
    taskDao.setParentTask(tu_2_3, getTask("u.1").getId());
    taskDao.internalUpdate(tu_2_3);
    assertEquals("Should have exact 2 childs", 2, u2.getChilds().size());
    assertEquals("Should have exact 1 child", 1, u1.getChilds().size());
    final TaskDO tu_1_1 = taskDao.internalGetById(getTask("u.2.3").getId());
    assertEquals("u.1.1", tu_1_1.getTitle());
    assertEquals(getTask("u.1").getId(), tu_1_1.getParentTaskId());
    final TaskNode u_1_1 = tree.getTaskNodeById(tu_1_1.getId());
    assertEquals("u.1.1", u_1_1.getTask().getTitle());
    assertEquals(getTask("u.1").getId(), u_1_1.getParent().getId());
  }

  /**
   * Checks task movements: Does the user has access to delete the task in the old hierarchy and the access to insert the task in the new
   * hierarchy?
   */
  @Test
  public void checkTaskAccess()
  {
    initTestDB.addTask("accesstest", "root");
    initTestDB.addTask("a", "accesstest");
    initTestDB.addTask("a.1", "a");
    initTestDB.addTask("a.1.1", "a.1");
    initTestDB.addTask("a.1.2", "a.1");
    initTestDB.addTask("a.2", "a");
    initTestDB.addTask("a.2.1", "a.2");
    initTestDB.addTask("a.2.2", "a.2");
    initTestDB.addUser("taskTest1");
    logon("taskTest1");
    try {
      taskDao.getById(getTask("a.1").getId());
      fail("User has no access to select task a.1");
    } catch (final AccessException ex) {
      assertAccessException(ex, getTask("a.1").getId(), AccessType.TASKS, OperationType.SELECT);
    }
    initTestDB.addGroup("taskTest1", new String[] { "taskTest1"});
    initTestDB.createGroupTaskAccess(getGroup("taskTest1"), getTask("a.1"), AccessType.TASKS, true, true, true, true);
    TaskDO task = taskDao.getById(getTask("a.1").getId());
    assertEquals("Now readable.", "a.1", task.getTitle());
    task = taskDao.getById(getTask("a.1.1").getId());
    assertEquals("Also child tasks are now readable.", "a.1.1", task.getTitle());
    taskDao.setParentTask(task, getTask("a.2").getId());
    try {
      taskDao.update(task);
      fail("User has no access to insert task as child of a.2");
    } catch (final AccessException ex) {
      assertAccessException(ex, getTask("a.2").getId(), AccessType.TASKS, OperationType.INSERT);
    }
    initTestDB.createGroupTaskAccess(getGroup("taskTest1"), getTask("a.2"), AccessType.TASKS, true, false, false, false);
    task = taskDao.getById(getTask("a.2.1").getId());
    task.setTitle("a.2.1test");
    try {
      taskDao.update(task);
      fail("User has no access to update child task of a.2");
    } catch (final AccessException ex) {
      assertAccessException(ex, getTask("a.2.1").getId(), AccessType.TASKS, OperationType.UPDATE);
    }

    initTestDB.addUser("taskTest2");
    logon("taskTest2");
    initTestDB.addGroup("taskTest2", new String[] { "taskTest2"});
    initTestDB.createGroupTaskAccess(getGroup("taskTest2"), getTask("a.1"), AccessType.TASKS, true, true, true, true);
    initTestDB.createGroupTaskAccess(getGroup("taskTest2"), getTask("a.2"), AccessType.TASKS, true, true, true, false);
    task = taskDao.getById(getTask("a.2.1").getId());
    taskDao.setParentTask(task, getTask("a.1").getId());
    try {
      taskDao.update(task);
      fail("User has no access to delete child task from a.2");
    } catch (final AccessException ex) {
      assertAccessException(ex, getTask("a.2").getId(), AccessType.TASKS, OperationType.DELETE);
    }
  }

  @Test
  public void checkAccess()
  {
    logon(TEST_ADMIN_USER);
    final TaskDO task = initTestDB.addTask("checkAccessTestTask", "root");
    initTestDB.addGroup("checkAccessTestGroup", new String[] { TEST_USER});
    initTestDB.createGroupTaskAccess(getGroup("checkAccessTestGroup"), getTask("checkAccessTestTask"), AccessType.TASKS, true, true, true,
        true);
    logon(TEST_FINANCE_USER);
    final Kost2ArtDO kost2Art = new Kost2ArtDO();
    kost2Art.setId(42);
    kost2Art.setName("Test");
    kost2ArtDao.save(kost2Art);
    final Kost2DO kost2 = new Kost2DO();
    kost2.setNummernkreis(3);
    kost2.setBereich(0);
    kost2.setTeilbereich(42);
    kost2.setKost2Art(kost2Art);
    kost2Dao.save(kost2);
    final ProjektDO projekt = new ProjektDO();
    projekt.setInternKost2_4(123);
    projekt.setName("Testprojekt");
    projektDao.save(projekt);
    checkAccess(TEST_ADMIN_USER, task.getId(), projekt, kost2);
    checkAccess(TEST_USER, task.getId(), projekt, kost2);
  }

  @Test
  public void checkKost2AndTimesheetBookingStatusAccess()
  {
    logon(TEST_FINANCE_USER);
    final TaskDO task = initTestDB.addTask("checkKost2AndTimesheetStatusAccessTask", "root");
    final String groupName = "checkKost2AndTimesheetBookingStatusAccessGroup";
    // Please note: TEST_USER is no project manager or assistant!
    final GroupDO projectManagers = initTestDB.addGroup(groupName, new String[] { TEST_PROJECT_MANAGER_USER, TEST_PROJECT_ASSISTANT_USER,
        TEST_USER});
    initTestDB.createGroupTaskAccess(projectManagers, task, AccessType.TASKS, true, true, true, true); // All rights.
    final ProjektDO projekt = new ProjektDO().setName("checkKost2AndTimesheetBookingStatusAccess").setInternKost2_4(764).setNummer(1)
        .setProjektManagerGroup(projectManagers).setTask(task);
    projektDao.save(projekt);
    logon(TEST_USER);
    TaskDO task1 = new TaskDO().setParentTask(task).setTitle("Task 1").setKost2BlackWhiteList("Hurzel");
    try {
      taskDao.save(task1);
      fail("AccessException expected.");
    } catch (final AccessException ex) {
      assertEquals("task.error.kost2Readonly", ex.getI18nKey()); // OK
    }
    try {
      task1.setKost2BlackWhiteList(null);
      task1.setKost2IsBlackList(true);
      taskDao.save(task1);
      fail("AccessException expected.");
    } catch (final AccessException ex) {
      assertEquals("task.error.kost2Readonly", ex.getI18nKey()); // OK
    }
    try {
      task1.setKost2IsBlackList(false);
      task1.setTimesheetBookingStatus(TimesheetBookingStatus.ONLY_LEAFS);
      taskDao.save(task1);
      fail("AccessException expected.");
    } catch (final AccessException ex) {
      assertEquals("task.error.timesheetBookingStatus2Readonly", ex.getI18nKey()); // OK
    }
    logon(TEST_PROJECT_MANAGER_USER);
    task1.setKost2IsBlackList(true);
    task1.setTimesheetBookingStatus(TimesheetBookingStatus.ONLY_LEAFS);
    task1 = taskDao.getById(taskDao.save(task1));
    logon(TEST_USER);
    task1.setKost2BlackWhiteList("123456");
    try {
      taskDao.update(task1);
      fail("AccessException expected.");
    } catch (final AccessException ex) {
      assertEquals("task.error.kost2Readonly", ex.getI18nKey()); // OK
    }
    try {
      task1.setKost2BlackWhiteList(null);
      task1.setKost2IsBlackList(false);
      taskDao.update(task1);
      fail("AccessException expected.");
    } catch (final AccessException ex) {
      assertEquals("task.error.kost2Readonly", ex.getI18nKey()); // OK
    }
    try {
      task1.setKost2IsBlackList(true);
      task1.setTimesheetBookingStatus(TimesheetBookingStatus.INHERIT);
      taskDao.update(task1);
      fail("AccessException expected.");
    } catch (final AccessException ex) {
      assertEquals("task.error.timesheetBookingStatus2Readonly", ex.getI18nKey()); // OK
    }
    logon(TEST_PROJECT_MANAGER_USER);
    task1.setKost2BlackWhiteList("123456");
    task1.setKost2IsBlackList(false);
    task1.setTimesheetBookingStatus(TimesheetBookingStatus.INHERIT);
    taskDao.update(task1);
  }

  private void checkAccess(final String user, final Serializable id, final ProjektDO projekt, final Kost2DO kost2)
  {
    logon(user);
    TaskDO task = taskDao.getById(id);
    task.setProtectTimesheetsUntil(new Date());
    try {
      taskDao.update(task);
      fail("AccessException expected.");
    } catch (final AccessException ex) {
      // OK
      assertEquals("task.error.protectTimesheetsUntilReadonly", ex.getI18nKey());
    }
    task.setProtectTimesheetsUntil(null);
    task.setProtectionOfPrivacy(true);
    try {
      taskDao.update(task);
      fail("AccessException expected.");
    } catch (final AccessException ex) {
      // OK
      assertEquals("task.error.protectionOfPrivacyReadonly", ex.getI18nKey());
    }
    task = taskDao.getById(id);
    task = new TaskDO();
    task.setParentTask(getTask("checkAccessTestTask"));
    task.setProtectTimesheetsUntil(new Date());
    try {
      taskDao.save(task);
      fail("AccessException expected.");
    } catch (final AccessException ex) {
      // OK
      assertEquals("task.error.protectTimesheetsUntilReadonly", ex.getI18nKey());
    }
    task.setProtectTimesheetsUntil(null);
    task.setProtectionOfPrivacy(true);
    try {
      taskDao.save(task);
      fail("AccessException expected.");
    } catch (final AccessException ex) {
      // OK
      assertEquals("task.error.protectionOfPrivacyReadonly", ex.getI18nKey());
    }
    task = taskDao.getById(id);
  }

  /**
   * Sister tasks should have different names.
   */
  @Test
  public void testDuplicateTaskNames()
  {
    initTestDB.addTask("duplicateTaskNamesTest", "root");
    initTestDB.addTask("dT.1", "duplicateTaskNamesTest");
    initTestDB.addTask("dT.2", "duplicateTaskNamesTest");
    initTestDB.addTask("dT.1.1", "dT.1");
    try {
      // Try to insert sister task with same name:
      initTestDB.addTask("dT.1.1", "dT.1");
      fail("Duplicate task was not detected.");
    } catch (final UserException ex) {
      assertEquals(TaskDao.I18N_KEY_ERROR_DUPLICATE_CHILD_TASKS, ex.getI18nKey());
    }
    TaskDO task = initTestDB.addTask("dT.1.2", "dT.1");
    task.setTitle("dT.1.1");
    try {
      // Try to rename task to same name as a sister task:
      taskDao.internalUpdate(task);
      fail("Duplicate task was not detected.");
    } catch (final UserException ex) {
      assertEquals(TaskDao.I18N_KEY_ERROR_DUPLICATE_CHILD_TASKS, ex.getI18nKey());
    }
    task = initTestDB.addTask("dT.1.1", "dT.2");
    task.setParentTask(initTestDB.getTask("dT.1"));
    try {
      // Try to move task from dT.1.2 to dT.1.1 where already a task with the same name exists.
      taskDao.internalUpdate(task);
      fail("Duplicate task was not detected.");
    } catch (final UserException ex) {
      assertEquals(TaskDao.I18N_KEY_ERROR_DUPLICATE_CHILD_TASKS, ex.getI18nKey());
    }
    task.setParentTask(initTestDB.getTask("dT.2"));
    taskDao.internalUpdate(task);
  }

  @Test
  public void readTotalDuration()
  {
    logon(getUser(TEST_ADMIN_USER));
    final TaskDO task = initTestDB.addTask("totalDurationTask", "root");
    final TaskDO subTask1 = initTestDB.addTask("totalDurationTask.subtask1", "totalDurationTask");
    final TaskDO subTask2 = initTestDB.addTask("totalDurationTask.subtask2", "totalDurationTask");
    assertEquals(0, taskDao.readTotalDuration(task.getId()));
    final DateHolder dh = new DateHolder();
    dh.setDate(2010, Calendar.APRIL, 20, 8, 0);
    TimesheetDO ts = new TimesheetDO().setUser(getUser(TEST_USER)).setStartDate(dh.getDate()).setStopTime(
        dh.add(Calendar.HOUR_OF_DAY, 4).getTimestamp()).setTask(task);
    timesheetDao.save(ts);
    assertEquals(4 * 3600, taskDao.readTotalDuration(task.getId()));
    assertEquals(4 * 3600, getTotalDuration(task.getId()));
    ts = new TimesheetDO().setUser(getUser(TEST_USER)).setStartDate(dh.add(Calendar.HOUR_OF_DAY, 1).getDate()).setStopTime(
        dh.add(Calendar.HOUR_OF_DAY, 4).getTimestamp()).setTask(task);
    timesheetDao.save(ts);
    assertEquals(8 * 3600, taskDao.readTotalDuration(task.getId()));
    assertEquals(8 * 3600, getTotalDuration(task.getId()));
    ts = new TimesheetDO().setUser(getUser(TEST_USER)).setStartDate(dh.add(Calendar.HOUR_OF_DAY, 1).getDate()).setStopTime(
        dh.add(Calendar.HOUR_OF_DAY, 4).getTimestamp()).setTask(subTask1);
    timesheetDao.save(ts);
    final List<Object[]> list = taskDao.readTotalDurations();
    boolean taskFound = false;
    boolean subtask1Found = false;
    for (final Object[] oa : list) {
      final Integer taskId = (Integer) oa[1];
      if (taskId == task.getId()) {
        assertFalse("Entry should only exist once.", taskFound);
        assertFalse("Entry not first.", subtask1Found);
        taskFound = true;
        assertEquals(new Long(8 * 3600), oa[0]);
      } else if (taskId == subTask1.getId()) {
        assertFalse("Entry should only exist once.", subtask1Found);
        assertTrue("Entry not second.", taskFound);
        subtask1Found = true;
        assertEquals(new Long(4 * 3600), oa[0]);
      } else if (taskId == subTask2.getId()) {
        fail("Entry not not expected.");
      }
    }
    assertEquals(12 * 3600, getTotalDuration(task.getId()));
    assertEquals(8 * 3600, getDuration(task.getId()));
    assertEquals(4 * 3600, getTotalDuration(subTask1.getId()));
    assertEquals(4 * 3600, getDuration(subTask1.getId()));
    assertEquals(0, getTotalDuration(subTask2.getId()));
    assertEquals(0, getDuration(subTask2.getId()));
    taskTree.refresh(); // Should be same after refresh (there was an error).
    assertEquals(12 * 3600, getTotalDuration(task.getId()));
    assertEquals(8 * 3600, getDuration(task.getId()));
    assertEquals(4 * 3600, getTotalDuration(subTask1.getId()));
    assertEquals(4 * 3600, getDuration(subTask1.getId()));
    assertEquals(0, getTotalDuration(subTask2.getId()));
    assertEquals(0, getDuration(subTask2.getId()));
  }

  private long getTotalDuration(final Integer taskId)
  {
    return taskTree.getTaskNodeById(taskId).getDuration(taskTree, true);
  }

  private long getDuration(final Integer taskId)
  {
    return taskTree.getTaskNodeById(taskId).getDuration(taskTree, false);
  }

  private void traverseTaskTree(final TaskNode node)
  {
    logDot();
    final List<TaskNode> childs = node.getChilds();
    if (childs != null) {
      for (final TaskNode child : childs) {
        assertEquals("Child should have parent id of current node.", node.getId(), child.getParentId());
        traverseTaskTree(child);
      }
    }
  }
}
TOP

Related Classes of org.projectforge.task.TaskTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.