Java tutorial
/******************************************************************************* * Copyright (c) 2010, 2012 Tasktop Technologies * Copyright (c) 2010, 2011 SpringSource, a division of VMware * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Tasktop Technologies - initial API and implementation ******************************************************************************/ package com.tasktop.c2c.server.tasks.tests.service; 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.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.math.BigDecimal; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.UUID; import javax.persistence.EntityManager; import javax.persistence.NoResultException; import javax.persistence.PersistenceContext; import javax.persistence.Query; import javax.persistence.TypedQuery; import org.apache.commons.lang.RandomStringUtils; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.transaction.annotation.Transactional; import com.tasktop.c2c.server.auth.service.AuthenticationServiceUser; import com.tasktop.c2c.server.auth.service.AuthenticationToken; import com.tasktop.c2c.server.common.service.ConcurrentUpdateException; import com.tasktop.c2c.server.common.service.EntityNotFoundException; import com.tasktop.c2c.server.common.service.InsufficientPermissionsException; import com.tasktop.c2c.server.common.service.JacksonJsonObjectMapper; import com.tasktop.c2c.server.common.service.ReplicationScope; import com.tasktop.c2c.server.common.service.ValidationException; import com.tasktop.c2c.server.common.service.WrappedCheckedException; import com.tasktop.c2c.server.common.service.domain.QueryResult; import com.tasktop.c2c.server.common.service.domain.Region; import com.tasktop.c2c.server.common.service.domain.Role; import com.tasktop.c2c.server.common.service.domain.SortInfo; import com.tasktop.c2c.server.common.service.domain.SortInfo.Order; import com.tasktop.c2c.server.common.service.domain.criteria.ColumnCriteria; import com.tasktop.c2c.server.common.service.domain.criteria.Criteria; import com.tasktop.c2c.server.common.service.domain.criteria.Criteria.Operator; import com.tasktop.c2c.server.common.service.domain.criteria.NaryCriteria; import com.tasktop.c2c.server.common.service.domain.criteria.RelativeDate; import com.tasktop.c2c.server.common.service.domain.criteria.TimeUnit; import com.tasktop.c2c.server.common.tests.util.ValidationAssert; import com.tasktop.c2c.server.event.domain.Event; import com.tasktop.c2c.server.event.domain.TaskActivityEvent; import com.tasktop.c2c.server.event.service.EventService; import com.tasktop.c2c.server.internal.tasks.domain.Component; import com.tasktop.c2c.server.internal.tasks.domain.ConfigurationProperty; import com.tasktop.c2c.server.internal.tasks.domain.Milestone; import com.tasktop.c2c.server.internal.tasks.domain.Priority; import com.tasktop.c2c.server.internal.tasks.domain.Product; import com.tasktop.c2c.server.internal.tasks.domain.Profile; import com.tasktop.c2c.server.internal.tasks.domain.Resolution; import com.tasktop.c2c.server.internal.tasks.domain.StatusWorkflow; import com.tasktop.c2c.server.internal.tasks.domain.Task; import com.tasktop.c2c.server.internal.tasks.domain.TaskSeverity; import com.tasktop.c2c.server.internal.tasks.domain.TaskStatus; import com.tasktop.c2c.server.internal.tasks.domain.conversion.DomainConversionContext; import com.tasktop.c2c.server.internal.tasks.domain.conversion.DomainConverter; import com.tasktop.c2c.server.internal.tasks.domain.conversion.ProductConverter; import com.tasktop.c2c.server.internal.tasks.domain.conversion.ProfileConverter; import com.tasktop.c2c.server.internal.tasks.domain.conversion.TaskDomain; import com.tasktop.c2c.server.internal.tasks.service.TaskCustomFieldService; import com.tasktop.c2c.server.internal.tasks.service.TaskServiceDependencies; import com.tasktop.c2c.server.internal.tasks.service.sql.SqlDialect; import com.tasktop.c2c.server.tasks.domain.AbstractReferenceValue; import com.tasktop.c2c.server.tasks.domain.AttachmentHandle; import com.tasktop.c2c.server.tasks.domain.Comment; import com.tasktop.c2c.server.tasks.domain.ExternalTaskRelation; import com.tasktop.c2c.server.tasks.domain.FieldDescriptor; import com.tasktop.c2c.server.tasks.domain.FieldType; import com.tasktop.c2c.server.tasks.domain.Iteration; import com.tasktop.c2c.server.tasks.domain.Keyword; import com.tasktop.c2c.server.tasks.domain.PredefinedTaskQuery; import com.tasktop.c2c.server.tasks.domain.QuerySpec; import com.tasktop.c2c.server.tasks.domain.RepositoryConfiguration; import com.tasktop.c2c.server.tasks.domain.SavedTaskQuery; import com.tasktop.c2c.server.tasks.domain.TaskActivity; import com.tasktop.c2c.server.tasks.domain.TaskActivity.FieldUpdate; import com.tasktop.c2c.server.tasks.domain.TaskActivity.Type; import com.tasktop.c2c.server.tasks.domain.TaskFieldConstants; import com.tasktop.c2c.server.tasks.domain.TaskHandle; import com.tasktop.c2c.server.tasks.domain.TaskResolution; import com.tasktop.c2c.server.tasks.domain.TaskSummary; import com.tasktop.c2c.server.tasks.domain.TaskSummaryItem; import com.tasktop.c2c.server.tasks.domain.TaskUserProfile; import com.tasktop.c2c.server.tasks.domain.WorkLog; import com.tasktop.c2c.server.tasks.service.TaskService; import com.tasktop.c2c.server.tasks.tests.domain.mock.MockComponentFactory; import com.tasktop.c2c.server.tasks.tests.domain.mock.MockKeyworddefFactory; import com.tasktop.c2c.server.tasks.tests.domain.mock.MockMilestoneFactory; import com.tasktop.c2c.server.tasks.tests.domain.mock.MockPriorityFactory; import com.tasktop.c2c.server.tasks.tests.domain.mock.MockProductFactory; import com.tasktop.c2c.server.tasks.tests.domain.mock.MockProfileFactory; import com.tasktop.c2c.server.tasks.tests.domain.mock.MockTaskFactory; import com.tasktop.c2c.server.tasks.tests.util.TestSecurity; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration({ "/applicationContext-test.xml" }) @Transactional public class TaskServiceTest { private static final int NUM_TASKS_TO_CREATE = TaskService.DEFAULT_PAGE_INFO.getSize() + 2; @Qualifier("main") @Autowired protected TaskService taskService; @PersistenceContext(unitName = "tasksDomain") protected EntityManager entityManager; protected Profile currentUser = null; @Autowired private DomainConverter domainConverter; @Autowired private ProductConverter productConverter; @Autowired protected TaskCustomFieldService customFieldService; @Autowired protected TaskDomain taskDomain; @Autowired SqlDialect sqlDialect; private Set<FieldDescriptor> createdFields = new HashSet<FieldDescriptor>(); private String[] taskTypeValues; private String[] iterationValues; private Event lastEvent = null; protected void setupAuthContext() { if (currentUser == null) { currentUser = MockProfileFactory.create(entityManager); String username = "testuser" + System.currentTimeMillis(); currentUser.setLoginName(username); entityManager.flush(); TestSecurity.login(currentUser); } } @Before public void before() throws Exception { // for subclass to override setupAuthContext(); taskTypeValues = computeCustomFieldValues("cf_tasktype"); iterationValues = computeCustomFieldValues("cf_iteration"); lastEvent = null; } @Before public void injectMockServices() { ((TaskServiceDependencies) taskService).setEventService(new EventService() { @Override public void publishEvent(Event event) { lastEvent = event; } }); } // TODO - only call this where needed protected String[] computeCustomFieldValues(String tableName) { @SuppressWarnings("unchecked") List<String> results = entityManager .createNativeQuery( String.format("select %s from %s order by %s", sqlDialect.quoteIdentifier("value"), sqlDialect.quoteIdentifier(tableName), sqlDialect.quoteIdentifier("sortkey"))) .getResultList(); return results.toArray(new String[results.size()]); } @After public void after() { if (!createdFields.isEmpty()) { // Special transaction handling is necessary here due to how MySQL handles alter table statements. // See http://ebergen.net/wordpress/2007/05/07/how-alter-table-locks-tables-and-handles-transactions entityManager.clear(); entityManager.createNativeQuery("rollback").executeUpdate(); for (FieldDescriptor descriptor : createdFields) { try { customFieldService.removeCustomField(descriptor); } catch (Throwable t) { // ignore t.printStackTrace(); } } } } private List<TaskSeverity> severities; private TaskStatus openStatus = null; private TaskStatus closedStatus = null; private List<Task> tasks; private static final int MINIMUM_DATE_RESOLUTION = 1000; protected int count(Class<?> objToCount) { Query countQ = entityManager .createQuery(String.format("SELECT count(o) FROM %s o", objToCount.getSimpleName())); return ((Number) countQ.getSingleResult()).intValue(); } private void setupTestData() { setupTestData(NUM_TASKS_TO_CREATE); } @SuppressWarnings("unchecked") protected List<TaskStatus> getStatuses() { List<TaskStatus> statuses = entityManager .createQuery("select e from " + TaskStatus.class.getSimpleName() + " e").getResultList(); return statuses; } @SuppressWarnings("unchecked") private void setupTestData(int numberOfTasksToCreate) { assertTrue(numberOfTasksToCreate > 0); computeSeverities(); assertTrue(severities.size() > 3); List<TaskStatus> statuses = getStatuses(); for (TaskStatus status : statuses) { if (status.getIsOpen()) { openStatus = status; } else { closedStatus = status; } } assertNotNull(openStatus); assertNotNull(closedStatus); Product product = MockProductFactory.create(entityManager); Profile profile = MockProfileFactory.create(entityManager); com.tasktop.c2c.server.internal.tasks.domain.Priority priority = MockPriorityFactory.create(entityManager); tasks = MockTaskFactory.create(entityManager, product, profile, numberOfTasksToCreate); long initalTime = System.currentTimeMillis() - (MINIMUM_DATE_RESOLUTION * tasks.size()); for (int x = 0; x < tasks.size(); ++x) { Task task = tasks.get(x); task.setSeverity(severities.get(x % severities.size()).getValue()); task.setStatus(x % 3 == 0 ? closedStatus.getValue() : openStatus.getValue()); task.setPriority(priority.getValue()); task.setCreationTs(new Date(initalTime + (x * MINIMUM_DATE_RESOLUTION))); task.setDeltaTs(new Date(task.getCreationTs().getTime() + 100000)); } entityManager.flush(); tasks.clear(); List<Object> results = entityManager .createQuery("select task from " + com.tasktop.c2c.server.internal.tasks.domain.Task.class.getSimpleName() + " task ") .getResultList(); for (Object result : results) { tasks.add((Task) result); } } @SuppressWarnings("unchecked") private void computeSeverities() { severities = entityManager .createQuery("select e from " + TaskSeverity.class.getSimpleName() + " e order by e.sortkey asc") .getResultList(); } @Test public void testFindTasksWithCriteria_CustomFields() throws ValidationException, EntityNotFoundException, ConcurrentUpdateException { FieldDescriptor descriptor = new FieldDescriptor(); descriptor.setAvailableForNewTasks(true); descriptor.setDescription("TestA"); descriptor.setFieldType(FieldType.SINGLE_SELECT); descriptor.setName("testA" + System.currentTimeMillis()); descriptor.setValueStrings(Arrays.asList("one", "two")); createdFields.add(descriptor); customFieldService.createCustomField(descriptor); setupTestData(); // sanity assertTrue(tasks.size() > 20); Set<Integer> expectedTasks = new HashSet<Integer>(); for (int x = 0; x < 3; ++x) { Task task = tasks.get(x); com.tasktop.c2c.server.tasks.domain.Task stask = taskService.retrieveTask(task.getId()); stask.getCustomFields().put(descriptor.getName(), "two"); stask = taskService.updateTask(stask); assertEquals("two", stask.getCustomFields().get(descriptor.getName())); expectedTasks.add(stask.getId()); } Criteria criteria = new ColumnCriteria(descriptor.getName(), Operator.EQUALS, "two"); QuerySpec querySpec = new QuerySpec(new Region(0, tasks.size() * 2), new SortInfo(descriptor.getName(), Order.ASCENDING)); QueryResult<com.tasktop.c2c.server.tasks.domain.Task> result = taskService.findTasksWithCriteria(criteria, querySpec); assertEquals(expectedTasks.size(), result.getTotalResultSize().intValue()); assertEquals(expectedTasks.size(), result.getResultPage().size()); for (com.tasktop.c2c.server.tasks.domain.Task task : result.getResultPage()) { assertTrue(expectedTasks.contains(task.getId())); } criteria = new ColumnCriteria(descriptor.getName(), Operator.NOT_EQUALS, "two"); querySpec = new QuerySpec(new Region(0, tasks.size() * 2), new SortInfo(descriptor.getName(), Order.DESCENDING)); result = taskService.findTasksWithCriteria(criteria, querySpec); assertEquals(tasks.size() - expectedTasks.size(), result.getTotalResultSize().intValue()); for (com.tasktop.c2c.server.tasks.domain.Task task : result.getResultPage()) { assertFalse(expectedTasks.contains(task.getId())); } } @Test public void testFindTasksWithCriteria_Keywords() throws ValidationException, EntityNotFoundException, ConcurrentUpdateException { setupTestData(); // sanity assertTrue(tasks.size() > 20); Keyword keyword1 = new Keyword(); keyword1.setName("keywordX"); Keyword keyword2 = new Keyword(); keyword2.setName("keywordY"); List<Keyword> keywords = new ArrayList<Keyword>(); keywords.add(keyword1); keywords.add(keyword2); Set<Integer> expectedTasks = new HashSet<Integer>(); for (int x = 0; x < 3; ++x) { Task task = tasks.get(x); com.tasktop.c2c.server.tasks.domain.Task serviceTask = taskService.retrieveTask(task.getId()); serviceTask.setKeywords(keywords); serviceTask = taskService.updateTask(serviceTask); assertEquals(2, serviceTask.getKeywords().size()); assertTrue(keyword1.getName().equals(serviceTask.getKeywords().get(0).getName()) || keyword1.getName().equals(serviceTask.getKeywords().get(1).getName())); expectedTasks.add(serviceTask.getId()); } Criteria criteria = new ColumnCriteria(TaskFieldConstants.KEYWORDS_FIELD, Operator.EQUALS, keyword1.getName()); QuerySpec querySpec = new QuerySpec(new Region(0, tasks.size() * 2), null); QueryResult<com.tasktop.c2c.server.tasks.domain.Task> result = taskService.findTasksWithCriteria(criteria, querySpec); assertEquals(expectedTasks.size(), result.getTotalResultSize().intValue()); assertEquals(expectedTasks.size(), result.getResultPage().size()); for (com.tasktop.c2c.server.tasks.domain.Task task : result.getResultPage()) { assertTrue(expectedTasks.contains(task.getId())); } } @Test public void testFindTasksWithCriteria_CreationDateRange() throws ValidationException, EntityNotFoundException, ConcurrentUpdateException { setupTestData(); // sanity assertTrue(tasks.size() > 20); Date createdStart = new Date(System.currentTimeMillis() - 1000 * 60 * 60 * 48); Date createdEnd = new Date(System.currentTimeMillis() - 1000 * 60 * 60 * 24); int numExpectedTasks = 10; Set<Integer> expectedTasks = new HashSet<Integer>(); for (Task task : tasks) { if (expectedTasks.size() >= numExpectedTasks) { task.setCreationTs(new Date(createdEnd.getTime() + 4000)); break; } task.setCreationTs(new Date(createdStart.getTime() + 1000 + expectedTasks.size() * 1000)); expectedTasks.add(task.getId()); } Criteria criteria = new NaryCriteria(Operator.AND, new ColumnCriteria(TaskFieldConstants.CREATION_TIME_FIELD, Operator.GREATER_THAN, createdStart), new ColumnCriteria(TaskFieldConstants.CREATION_TIME_FIELD, Operator.LESS_THAN, createdEnd)); QuerySpec querySpec = new QuerySpec(new Region(0, tasks.size() * 2), null); QueryResult<com.tasktop.c2c.server.tasks.domain.Task> result = taskService.findTasksWithCriteria(criteria, querySpec); assertEquals(expectedTasks.size(), result.getTotalResultSize().intValue()); assertEquals(expectedTasks.size(), result.getResultPage().size()); for (com.tasktop.c2c.server.tasks.domain.Task task : result.getResultPage()) { assertTrue(expectedTasks.contains(task.getId())); } // do the inverse criteria = new NaryCriteria(Operator.OR, new ColumnCriteria(TaskFieldConstants.CREATION_TIME_FIELD, Operator.LESS_THAN, createdStart), new ColumnCriteria(TaskFieldConstants.CREATION_TIME_FIELD, Operator.GREATER_THAN, createdEnd)); querySpec = new QuerySpec(new Region(0, tasks.size() * 2), null); result = taskService.findTasksWithCriteria(criteria, querySpec); assertEquals(tasks.size() - expectedTasks.size(), result.getTotalResultSize().intValue()); assertEquals(tasks.size() - expectedTasks.size(), result.getResultPage().size()); for (com.tasktop.c2c.server.tasks.domain.Task task : result.getResultPage()) { assertFalse(expectedTasks.contains(task.getId())); } // And one that should not match any criteria = new NaryCriteria(Operator.AND, new ColumnCriteria(TaskFieldConstants.CREATION_TIME_FIELD, Operator.LESS_THAN, createdStart), new ColumnCriteria(TaskFieldConstants.CREATION_TIME_FIELD, Operator.GREATER_THAN, createdEnd)); querySpec = new QuerySpec(new Region(0, tasks.size() * 2), null); result = taskService.findTasksWithCriteria(criteria, querySpec); assertEquals(0, result.getTotalResultSize().intValue()); assertEquals(0, result.getResultPage().size()); } @Test public void testFindTasksWithCriteria_RelativeDate() throws Exception { setupTestData(); // sanity assertTrue(tasks.size() > 20); Date oneDayAgo = new Date(System.currentTimeMillis() - (1000 * 60 * 60 * 24 * 1)); Date threeDaysAgo = new Date(System.currentTimeMillis() - (1000 * 60 * 60 * 24 * 3)); int numExpectedTasks = 1; Set<Integer> expectedTasks = new HashSet<Integer>(); for (Task task : tasks) { if (expectedTasks.size() >= numExpectedTasks) { task.setDeltaTs(threeDaysAgo); } else { task.setDeltaTs(oneDayAgo); } entityManager.persist(task); expectedTasks.add(task.getId()); } RelativeDate relativeDate = new RelativeDate(-2, TimeUnit.DAYS); // convert it to JSON and back, to replicate what happens in a REST call JacksonJsonObjectMapper jsonMapper = new JacksonJsonObjectMapper(); String relativeDateJson = jsonMapper.writeValueAsString(relativeDate); Object relativeDateFromJson = jsonMapper.readValue(relativeDateJson, Object.class); Criteria criteria = new ColumnCriteria(TaskFieldConstants.LAST_UPDATE_FIELD, Operator.GREATER_THAN, relativeDateFromJson); QuerySpec querySpec = new QuerySpec(new Region(0, tasks.size() * 2), null); QueryResult<com.tasktop.c2c.server.tasks.domain.Task> result = taskService.findTasksWithCriteria(criteria, querySpec); assertEquals(numExpectedTasks, result.getTotalResultSize().intValue()); assertEquals(numExpectedTasks, result.getResultPage().size()); } @Test public void testFindTasksWithCriteria_UpdatedDateRange() throws ValidationException, EntityNotFoundException, ConcurrentUpdateException { setupTestData(); // sanity assertTrue(tasks.size() > 20); Date updatedStart = new Date(System.currentTimeMillis() - 1000 * 60 * 60 * 48); Date updatedEnd = new Date(System.currentTimeMillis() - 1000 * 60 * 60 * 24); int numExpectedTasks = 10; Set<Integer> expectedTasks = new HashSet<Integer>(); for (Task task : tasks) { if (expectedTasks.size() >= numExpectedTasks) { task.setDeltaTs(new Date(updatedEnd.getTime() + 4000)); break; } task.setDeltaTs(new Date(updatedStart.getTime() + 1000 + expectedTasks.size() * 1000)); expectedTasks.add(task.getId()); } Criteria criteria = new NaryCriteria(Operator.AND, new ColumnCriteria(TaskFieldConstants.LAST_UPDATE_FIELD, Operator.GREATER_THAN, updatedStart), new ColumnCriteria(TaskFieldConstants.LAST_UPDATE_FIELD, Operator.LESS_THAN, updatedEnd)); QuerySpec querySpec = new QuerySpec(new Region(0, tasks.size() * 2), null); QueryResult<com.tasktop.c2c.server.tasks.domain.Task> result = taskService.findTasksWithCriteria(criteria, querySpec); assertEquals(expectedTasks.size(), result.getTotalResultSize().intValue()); assertEquals(expectedTasks.size(), result.getResultPage().size()); for (com.tasktop.c2c.server.tasks.domain.Task task : result.getResultPage()) { assertTrue(expectedTasks.contains(task.getId())); } // do the inverse criteria = new NaryCriteria(Operator.OR, new ColumnCriteria(TaskFieldConstants.LAST_UPDATE_FIELD, Operator.LESS_THAN, updatedStart), new ColumnCriteria(TaskFieldConstants.LAST_UPDATE_FIELD, Operator.GREATER_THAN, updatedEnd)); querySpec = new QuerySpec(new Region(0, tasks.size() * 2), null); result = taskService.findTasksWithCriteria(criteria, querySpec); assertEquals(tasks.size() - expectedTasks.size(), result.getTotalResultSize().intValue()); assertEquals(tasks.size() - expectedTasks.size(), result.getResultPage().size()); for (com.tasktop.c2c.server.tasks.domain.Task task : result.getResultPage()) { assertFalse(expectedTasks.contains(task.getId())); } // And one that should not match any criteria = new NaryCriteria(Operator.AND, new ColumnCriteria(TaskFieldConstants.LAST_UPDATE_FIELD, Operator.LESS_THAN, updatedStart), new ColumnCriteria(TaskFieldConstants.LAST_UPDATE_FIELD, Operator.GREATER_THAN, updatedEnd)); querySpec = new QuerySpec(new Region(0, tasks.size() * 2), null); result = taskService.findTasksWithCriteria(criteria, querySpec); assertEquals(0, result.getTotalResultSize().intValue()); assertEquals(0, result.getResultPage().size()); } @Test public void findAllTasksForProductName() throws Exception { setupTestData(); // Get the generated name of our product String productName = tasks.get(0).getProduct().getName(); Criteria criteria = new ColumnCriteria(TaskFieldConstants.PRODUCT_NAME_FIELD, Operator.EQUALS, productName); QuerySpec querySpec = new QuerySpec(new Region(0, 10000), new SortInfo(TaskFieldConstants.TASK_ID_FIELD, Order.ASCENDING)); QueryResult<com.tasktop.c2c.server.tasks.domain.Task> result = taskService.findTasksWithCriteria(criteria, querySpec); Set<Integer> resultIds = new HashSet<Integer>(); for (com.tasktop.c2c.server.tasks.domain.Task task : result.getResultPage()) { resultIds.add(task.getId()); } // Make sure we got back all of our items, and that the query was accurate. for (Task task : tasks) { // We want to confirm that, if the name was present, then it was in the returned set - as a result, // we don't use the short-circuit &&, but rather the always-evaluated & assertEquals(task.getProduct().getName().equals(productName), resultIds.contains(task.getId())); } } @Test public void findTasksForReporter_bug1649() throws Exception { // see related bug 1649 setupTestData(1); // Get the first task Task firstTask = tasks.get(0); Profile reporter = firstTask.getReporter(); final int reporterBugs = ((Long) entityManager .createQuery( "select count(t) from " + Task.class.getSimpleName() + " t where t.reporter = :reporter") .setParameter("reporter", reporter).getSingleResult()).intValue(); assertTrue(reporterBugs > 0); Criteria criteria = new ColumnCriteria(TaskFieldConstants.REPORTER_FIELD, Operator.EQUALS, reporter.getLoginName()); QuerySpec querySpec = new QuerySpec(new Region(0, 10000), new SortInfo(TaskFieldConstants.TASK_ID_FIELD, Order.ASCENDING)); QueryResult<com.tasktop.c2c.server.tasks.domain.Task> result = taskService.findTasksWithCriteria(criteria, querySpec); assertEquals(reporterBugs, result.getResultPage().size()); assertEquals(firstTask.getId(), result.getResultPage().get(0).getId()); setupTestData(2); criteria = new ColumnCriteria(TaskFieldConstants.REPORTER_FIELD, Operator.NOT_EQUALS, reporter.getLoginName()); result = taskService.findTasksWithCriteria(criteria, querySpec); int expectedSize = taskService.findTasksWithQuery(PredefinedTaskQuery.ALL, null).getTotalResultSize() - reporterBugs; assertTrue(expectedSize > 0); assertEquals(expectedSize, result.getResultPage().size()); for (com.tasktop.c2c.server.tasks.domain.Task task : result.getResultPage()) { assertFalse(firstTask.getId().equals(task.getId())); } } @Test public void findAllTasksForProductNameAndComponentName() throws Exception { setupTestData(); // Get the generated name of our product String productName = tasks.get(0).getProduct().getName(); Criteria productCriteria = new ColumnCriteria(TaskFieldConstants.PRODUCT_NAME_FIELD, Operator.EQUALS, productName); // Get the generated name of our component String componentName = tasks.get(0).getComponent().getName(); Criteria componentCriteria = new ColumnCriteria(TaskFieldConstants.COMPONENT_NAME_FIELD, Operator.EQUALS, componentName); QuerySpec querySpec = new QuerySpec(new Region(0, 10000), new SortInfo(TaskFieldConstants.TASK_ID_FIELD, Order.ASCENDING)); QueryResult<com.tasktop.c2c.server.tasks.domain.Task> result = taskService.findTasksWithCriteria( new NaryCriteria(Operator.AND, productCriteria, componentCriteria), querySpec); Set<Integer> resultIds = new HashSet<Integer>(); for (com.tasktop.c2c.server.tasks.domain.Task task : result.getResultPage()) { resultIds.add(task.getId()); } // Make sure we got back all of our items, and that the query was accurate. for (Task task : tasks) { // We want to confirm that, if the name was present, then it was in the returned set. assertEquals( task.getProduct().getName().equals(productName) && task.getComponent().getName().equals(componentName), resultIds.contains(task.getId())); } } @Test public void findAllTasksForProductIdComponentIdAndMilestone() throws Exception { setupTestData(); // Get the generated name of our product String productName = tasks.get(0).getProduct().getName(); Criteria productCriteria = new ColumnCriteria(TaskFieldConstants.PRODUCT_NAME_FIELD, Operator.EQUALS, productName); // Get the generated name of our component Short componentId = tasks.get(0).getComponent().getId(); Criteria componentCriteria = new ColumnCriteria(TaskFieldConstants.COMPONENT_FIELD, Operator.EQUALS, componentId); // Get the generated milestone String milestone = tasks.get(0).getTargetMilestone(); Criteria milestoneCriteria = new ColumnCriteria(TaskFieldConstants.MILESTONE_FIELD, Operator.EQUALS, milestone); QuerySpec querySpec = new QuerySpec(new Region(0, 10000), new SortInfo(TaskFieldConstants.TASK_ID_FIELD, Order.ASCENDING)); QueryResult<com.tasktop.c2c.server.tasks.domain.Task> result = taskService.findTasksWithCriteria( new NaryCriteria(Operator.AND, productCriteria, componentCriteria, milestoneCriteria), querySpec); Set<Integer> resultIds = new HashSet<Integer>(); for (com.tasktop.c2c.server.tasks.domain.Task task : result.getResultPage()) { resultIds.add(task.getId()); } // Make sure we got back all of our items, and that the query was accurate. for (Task task : tasks) { // We want to confirm that, if the name was present, then it was in the returned set. assertEquals(task.getProduct().getName().equals(productName) && task.getComponent().getId().equals(componentId) && task.getTargetMilestone().equals(milestone), resultIds.contains(task.getId())); } } @Test public void findAllTasksForProductIdAndMilestone() throws Exception { setupTestData(); // Get the generated name of our product Short productId = tasks.get(0).getProduct().getId(); Criteria productCriteria = new ColumnCriteria(TaskFieldConstants.PRODUCT_FIELD, Operator.EQUALS, productId); // Get the generated milestone String milestone = tasks.get(0).getTargetMilestone(); Criteria milestoneCriteria = new ColumnCriteria(TaskFieldConstants.MILESTONE_FIELD, Operator.EQUALS, milestone); QuerySpec querySpec = new QuerySpec(new Region(0, 10000), new SortInfo(TaskFieldConstants.TASK_ID_FIELD, Order.ASCENDING)); QueryResult<com.tasktop.c2c.server.tasks.domain.Task> result = taskService.findTasksWithCriteria( new NaryCriteria(Operator.AND, productCriteria, milestoneCriteria), querySpec); Set<Integer> resultIds = new HashSet<Integer>(); for (com.tasktop.c2c.server.tasks.domain.Task task : result.getResultPage()) { resultIds.add(task.getId()); } // Make sure we got back all of our items, and that the query was accurate. for (Task task : tasks) { // We want to confirm that, if the name was present, then it was in the returned set. assertEquals(task.getProduct().getId().equals(productId) && task.getTargetMilestone().equals(milestone), resultIds.contains(task.getId())); } } @Test public void testTaskSummary() { setupTestData(1000); TaskSummary taskSummary = taskService.getTaskSummary(); assertNotNull(taskSummary); assertEquals(severities.size(), taskSummary.getItems().size()); // it all has to add up. long sum = 0; short previousSortKey = Short.MIN_VALUE; for (TaskSummaryItem item : taskSummary.getItems()) { System.out.println(String.format("%s open=%s closed=%s", item.getSeverity().getValue(), item.getOpenCount(), item.getClosedCount())); assertNotNull(item.getSeverity()); assertNotNull(item.getSeverity().getValue()); assertTrue(item.getSeverity().getSortkey() > previousSortKey); previousSortKey = item.getSeverity().getSortkey(); assertTrue(item.getOpenCount() > 40); assertTrue(item.getClosedCount() > 40); sum += item.getOpenCount(); sum += item.getClosedCount(); } assertEquals(sum, tasks.size()); } @Test public void testTaskSummaryHasAllSeverities() { computeSeverities(); assertTrue(severities.size() > 3); TaskSummary taskSummary = taskService.getTaskSummary(); assertNotNull(taskSummary); assertEquals(severities.size(), taskSummary.getItems().size()); } @Test public void testFindAllTasks() { setupTestData(); QueryResult<com.tasktop.c2c.server.tasks.domain.Task> queryResult = taskService .findTasksWithQuery(PredefinedTaskQuery.ALL, null); assertNotNull(queryResult); assertEquals(tasks.size(), (int) queryResult.getTotalResultSize()); assertEquals(TaskService.DEFAULT_PAGE_INFO.getOffset(), queryResult.getOffset()); assertEquals(TaskService.DEFAULT_PAGE_INFO.getSize(), queryResult.getPageSize()); assertEquals(TaskService.DEFAULT_PAGE_INFO.getSize(), (Integer) queryResult.getResultPage().size()); } @Test public void testFindAllTasksSortedByTaskIdPagingThroughResults() { setupTestData(50); int pageSize = TaskService.DEFAULT_PAGE_INFO.getSize() + 3; // intentionally // not the // default int numPages = (int) Math.ceil((double) tasks.size() / (double) pageSize); Region pageInfo = new Region(); pageInfo.setSize(pageSize); assertTrue(numPages > 0); SortInfo sortInfo = new SortInfo(TaskFieldConstants.TASK_ID_FIELD, Order.ASCENDING); com.tasktop.c2c.server.tasks.domain.Task lastResult = null; for (int pageNum = 0; pageNum < numPages; pageNum++) { pageInfo.setOffset(pageNum * pageSize); QueryResult<com.tasktop.c2c.server.tasks.domain.Task> queryResult = taskService .findTasksWithQuery(PredefinedTaskQuery.ALL, new QuerySpec(pageInfo, sortInfo)); assertNotNull(queryResult); assertEquals(tasks.size(), (int) queryResult.getTotalResultSize()); assertEquals(pageInfo.getOffset(), queryResult.getOffset()); assertEquals(pageInfo.getSize(), queryResult.getPageSize()); if (pageNum != numPages - 1) { assertEquals(Integer.valueOf(pageSize), (Integer) queryResult.getResultPage().size()); } for (com.tasktop.c2c.server.tasks.domain.Task result : queryResult.getResultPage()) { if (lastResult != null) { assertTrue("bad sort", lastResult.getId().compareTo(result.getId()) <= 0); } lastResult = result; } } } @Test public void testFindAllTasksSortedByCreation() { setupTestData(); QueryResult<com.tasktop.c2c.server.tasks.domain.Task> queryResult = taskService.findTasksWithQuery( PredefinedTaskQuery.ALL, new QuerySpec(null, new SortInfo(TaskFieldConstants.CREATION_TIME_FIELD, Order.ASCENDING))); assertNotNull(queryResult); assertEquals(tasks.size(), (int) queryResult.getTotalResultSize()); assertEquals(TaskService.DEFAULT_PAGE_INFO.getOffset(), queryResult.getOffset()); assertEquals(TaskService.DEFAULT_PAGE_INFO.getSize(), queryResult.getPageSize()); assertEquals(TaskService.DEFAULT_PAGE_INFO.getSize(), (Integer) queryResult.getResultPage().size()); com.tasktop.c2c.server.tasks.domain.Task lastResult = null; for (com.tasktop.c2c.server.tasks.domain.Task result : queryResult.getResultPage()) { if (lastResult != null) { assertTrue( "bad sort: " + lastResult.getCreationDate().getTime() + " " + result.getCreationDate().getTime(), lastResult.getCreationDate().compareTo(result.getCreationDate()) <= 0); } lastResult = result; } } @Test public void testFindAllTasksSortedBySeverity() { setupTestData(); QueryResult<com.tasktop.c2c.server.tasks.domain.Task> queryResult = taskService.findTasksWithQuery( PredefinedTaskQuery.ALL, new QuerySpec(null, new SortInfo(TaskFieldConstants.SEVERITY_FIELD, Order.ASCENDING))); assertNotNull(queryResult); assertEquals(tasks.size(), (int) queryResult.getTotalResultSize()); assertEquals(TaskService.DEFAULT_PAGE_INFO.getOffset(), queryResult.getOffset()); assertEquals(TaskService.DEFAULT_PAGE_INFO.getSize(), queryResult.getPageSize()); assertEquals(TaskService.DEFAULT_PAGE_INFO.getSize(), (Integer) queryResult.getResultPage().size()); com.tasktop.c2c.server.tasks.domain.Task lastResult = null; for (com.tasktop.c2c.server.tasks.domain.Task result : queryResult.getResultPage()) { if (lastResult != null) { assertTrue("bad sort", lastResult.getSeverity().getSortkey().compareTo(result.getSeverity().getSortkey()) <= 0); } lastResult = result; } } @Test public void testFindAllTasksSortedByStatus() { setupTestData(); QueryResult<com.tasktop.c2c.server.tasks.domain.Task> queryResult = taskService.findTasksWithQuery( PredefinedTaskQuery.ALL, new QuerySpec(null, new SortInfo(TaskFieldConstants.STATUS_FIELD, Order.ASCENDING))); assertNotNull(queryResult); assertEquals(tasks.size(), (int) queryResult.getTotalResultSize()); assertEquals(TaskService.DEFAULT_PAGE_INFO.getOffset(), queryResult.getOffset()); assertEquals(TaskService.DEFAULT_PAGE_INFO.getSize(), queryResult.getPageSize()); assertEquals(TaskService.DEFAULT_PAGE_INFO.getSize(), (Integer) queryResult.getResultPage().size()); com.tasktop.c2c.server.tasks.domain.Task lastResult = null; for (com.tasktop.c2c.server.tasks.domain.Task result : queryResult.getResultPage()) { if (lastResult != null) { assertTrue("bad sort", ((Short) lastResult.getStatus().getSortkey()) .compareTo(result.getStatus().getSortkey()) <= 0); } lastResult = result; } } @Test public void testFindAllTasksSortedByPriority() { setupTestData(); QueryResult<com.tasktop.c2c.server.tasks.domain.Task> queryResult = taskService.findTasksWithQuery( PredefinedTaskQuery.ALL, new QuerySpec(null, new SortInfo(TaskFieldConstants.PRIORITY_FIELD, Order.ASCENDING))); assertNotNull(queryResult); assertEquals(tasks.size(), (int) queryResult.getTotalResultSize()); assertEquals(TaskService.DEFAULT_PAGE_INFO.getOffset(), queryResult.getOffset()); assertEquals(TaskService.DEFAULT_PAGE_INFO.getSize(), queryResult.getPageSize()); assertEquals(TaskService.DEFAULT_PAGE_INFO.getSize(), (Integer) queryResult.getResultPage().size()); com.tasktop.c2c.server.tasks.domain.Task lastResult = null; for (com.tasktop.c2c.server.tasks.domain.Task result : queryResult.getResultPage()) { if (lastResult != null) { assertTrue("bad sort", ((Short) lastResult.getPriority().getSortkey()) .compareTo(result.getPriority().getSortkey()) <= 0); } lastResult = result; } } @Test public void testFindResultsAreThin() { setupTestData(); QueryResult<com.tasktop.c2c.server.tasks.domain.Task> queryResult = taskService.findTasksWithQuery( PredefinedTaskQuery.ALL, new QuerySpec(null, new SortInfo(TaskFieldConstants.CREATION_TIME_FIELD, Order.DESCENDING))); assertFalse(queryResult.getResultPage().isEmpty()); for (com.tasktop.c2c.server.tasks.domain.Task result : queryResult.getResultPage()) { assertNotNull(result.getShortDescription()); assertNotNull(result.getDescription()); assertNotNull(result.getComments()); assertNull(result.getBlocksTasks()); assertNull(result.getAttachments()); assertNull(result.getSubTasks()); } } @Test public void testFindResultsExposesParent() { setupTestData(2); Task task1 = tasks.get(0); Task task2 = tasks.get(1); entityManager.persist(task1.addBlocked(task2)); entityManager.flush(); entityManager.clear(); Criteria criteria = new ColumnCriteria(TaskFieldConstants.TASK_ID_FIELD, task1.getId()); QueryResult<com.tasktop.c2c.server.tasks.domain.Task> result = taskService.findTasksWithCriteria(criteria, null); assertEquals(Integer.valueOf(1), result.getTotalResultSize()); com.tasktop.c2c.server.tasks.domain.Task task = result.getResultPage().get(0); assertEquals(task1.getId(), task.getId()); assertNotNull(task.getParentTask()); assertEquals(task2.getId(), task.getParentTask().getId()); } @Test public void testFindAllTasksSortedByUpdate() { setupTestData(); QueryResult<com.tasktop.c2c.server.tasks.domain.Task> queryResult = taskService .findTasksWithQuery(PredefinedTaskQuery.RECENT, null); assertNotNull(queryResult); assertEquals(tasks.size(), (int) queryResult.getTotalResultSize()); assertEquals(TaskService.DEFAULT_PAGE_INFO.getOffset(), queryResult.getOffset()); assertEquals(TaskService.DEFAULT_PAGE_INFO.getSize(), queryResult.getPageSize()); assertEquals(TaskService.DEFAULT_PAGE_INFO.getSize(), (Integer) queryResult.getResultPage().size()); com.tasktop.c2c.server.tasks.domain.Task lastResult = null; for (com.tasktop.c2c.server.tasks.domain.Task result : queryResult.getResultPage()) { if (lastResult != null) { assertTrue( "bad sort: " + lastResult.getModificationDate().getTime() + " " + result.getModificationDate().getTime(), lastResult.getModificationDate().compareTo(result.getModificationDate()) >= 0); } lastResult = result; } } @Test public void testFindAllTasksSortedByTaskId() { setupTestData(); QueryResult<com.tasktop.c2c.server.tasks.domain.Task> queryResult = taskService.findTasksWithQuery( PredefinedTaskQuery.ALL, new QuerySpec(null, new SortInfo(TaskFieldConstants.TASK_ID_FIELD, Order.ASCENDING))); assertNotNull(queryResult); assertEquals(tasks.size(), (int) queryResult.getTotalResultSize()); assertEquals(TaskService.DEFAULT_PAGE_INFO.getOffset(), queryResult.getOffset()); assertEquals(TaskService.DEFAULT_PAGE_INFO.getSize(), queryResult.getPageSize()); assertEquals(TaskService.DEFAULT_PAGE_INFO.getSize(), (Integer) queryResult.getResultPage().size()); com.tasktop.c2c.server.tasks.domain.Task lastResult = null; for (com.tasktop.c2c.server.tasks.domain.Task result : queryResult.getResultPage()) { if (lastResult != null) { assertTrue("bad sort", lastResult.getId().compareTo(result.getId()) <= 0); } lastResult = result; } } @Test public void testFindAllOpenTasks() { setupTestData(); QueryResult<com.tasktop.c2c.server.tasks.domain.Task> queryResult = taskService.findTasksWithQuery( PredefinedTaskQuery.OPEN, new QuerySpec(null, new SortInfo(TaskFieldConstants.STATUS_FIELD, SortInfo.Order.ASCENDING))); assertNotNull(queryResult); for (com.tasktop.c2c.server.tasks.domain.Task t : queryResult.getResultPage()) { Assert.assertTrue(t.getStatus().isOpen()); } int numOpenTasks = sumOpenTasks(); assertEquals(numOpenTasks, (int) queryResult.getTotalResultSize()); assertEquals(TaskService.DEFAULT_PAGE_INFO.getOffset(), queryResult.getOffset()); assertEquals(TaskService.DEFAULT_PAGE_INFO.getSize(), queryResult.getPageSize()); assertEquals(Math.min(numOpenTasks, TaskService.DEFAULT_PAGE_INFO.getSize()), queryResult.getResultPage().size()); } private int sumOpenTasks() { Number openTasks = (Number) entityManager.createQuery( "select count(task) from " + com.tasktop.c2c.server.internal.tasks.domain.Task.class.getSimpleName() + " task, " + com.tasktop.c2c.server.internal.tasks.domain.TaskStatus.class.getSimpleName() + " stat " + " where stat.value = task.status and stat.isOpen = true") .getSingleResult(); return openTasks.intValue(); } @Test public void testFindMyTasks() throws ValidationException { int numNewTasks = 5; Product product = MockProductFactory.create(entityManager); ProfileConverter.copy(currentUser); entityManager.flush(); for (int i = 0; i < numNewTasks; i++) { Task t = MockTaskFactory.create(entityManager, product, currentUser); t.setAssignee(currentUser); } entityManager.flush(); QueryResult<com.tasktop.c2c.server.tasks.domain.Task> queryResult = taskService .findTasksWithQuery(PredefinedTaskQuery.MINE, null); assertNotNull(queryResult); assertEquals((Integer) numNewTasks, queryResult.getTotalResultSize()); assertEquals(numNewTasks, queryResult.getResultPage().size()); for (com.tasktop.c2c.server.tasks.domain.Task task : queryResult.getResultPage()) { assertEquals(currentUser.getLoginName(), task.getReporter().getLoginName()); } } @Test public void testFindMyRelatedTasks() throws ValidationException, EntityNotFoundException, ConcurrentUpdateException { Product product = MockProductFactory.create(entityManager); Profile otherCreatorUser = getCreatedMockProfile(); Profile assigneeUser = getCreatedMockProfile(); entityManager.flush(); // 3 cases - assignee, commentor, cc int numNewTasks = 3; // create task with creator of currentUser Task task1 = MockTaskFactory.create(entityManager, product, currentUser); task1.setAssignee(assigneeUser); entityManager.flush(); // create task with cc of currentUser Task task2 = MockTaskFactory.create(entityManager, product, otherCreatorUser); task2.setAssignee(assigneeUser); entityManager.flush(); com.tasktop.c2c.server.tasks.domain.Task serviceTask2 = taskService.retrieveTask(task2.getId()); serviceTask2.getWatchers().add(ProfileConverter.copy(currentUser)); taskService.updateTask(serviceTask2); // create task with comment authored by currentUser Task task3 = MockTaskFactory.create(entityManager, product, otherCreatorUser); task3.setAssignee(otherCreatorUser); entityManager.flush(); com.tasktop.c2c.server.tasks.domain.Task serviceTask3 = taskService.retrieveTask(task3.getId()); serviceTask3.addComment("new comment"); taskService.updateTask(serviceTask3); QueryResult<com.tasktop.c2c.server.tasks.domain.Task> queryResult = taskService .findTasksWithQuery(PredefinedTaskQuery.RELATED, null); assertNotNull(queryResult); assertEquals((Integer) numNewTasks, queryResult.getTotalResultSize()); assertEquals(numNewTasks, queryResult.getResultPage().size()); } @Test public void testInvalidCreates() throws Exception { com.tasktop.c2c.server.tasks.domain.Task toCreate = getMockTask(); toCreate.setShortDescription(null); // Required try { taskService.createTask(toCreate); Assert.fail("Expect validation exception"); } catch (ValidationException ex) { // Expected assertEquals("A summary is required.", ex.getMessage()); } toCreate = getMockTask(); toCreate.setComponent(null); // Required try { taskService.createTask(toCreate); Assert.fail("Expect validation exception"); } catch (ValidationException ex) { // Expected assertEquals("A component is required.", ex.getMessage()); } toCreate = getMockTask(); toCreate.setProduct(null); // Required try { taskService.createTask(toCreate); Assert.fail("Expect validation exception"); } catch (ValidationException ex) { // Expected assertEquals("A product is required.", ex.getMessage()); } toCreate = getMockTask(); toCreate.setAssignee(new TaskUserProfile()); toCreate.getAssignee().setLoginName("foo"); try { taskService.createTask(toCreate); Assert.fail("Expect entity not found exception"); } catch (EntityNotFoundException ex) { // Expected } toCreate = getMockTask(); toCreate.setAssignee(new TaskUserProfile()); try { taskService.createTask(toCreate); Assert.fail("Expect validation exception"); } catch (ValidationException ex) { assertEquals("An owner is required.", ex.getMessage()); // Expected } toCreate = getMockTask(); toCreate.setWatchers(Arrays.asList(new TaskUserProfile())); try { taskService.createTask(toCreate); Assert.fail("Expect validation exception"); } catch (ValidationException ex) { assertEquals("The watcher's login name or id should be set.", ex.getMessage()); // Expected } toCreate = getMockTask(); toCreate.setProduct(new com.tasktop.c2c.server.tasks.domain.Product()); toCreate.getProduct().setId(999999999); try { taskService.createTask(toCreate); Assert.fail("Expect entity not found exception"); } catch (EntityNotFoundException ex) { // Expected } } @Test public void testLineDelimitersConsistent() throws Exception { final String textWithVaryingLineDelimiters = "line1\r\nline2\rline3\nline4"; final String expectedTextConversion = "line1\nline2\nline3\nline4"; com.tasktop.c2c.server.tasks.domain.Task toCreate = getMockTask(); toCreate.setDescription(textWithVaryingLineDelimiters); com.tasktop.c2c.server.tasks.domain.Task created = taskService.createTask(toCreate); Assert.assertEquals(expectedTextConversion, created.getDescription()); Comment comment = new Comment(); comment.setAuthor(created.getReporter()); comment.setCommentText(textWithVaryingLineDelimiters); created.getComments().add(comment); com.tasktop.c2c.server.tasks.domain.Task updated = taskService.updateTask(created); Assert.assertEquals(expectedTextConversion, updated.getComments().get(0).getCommentText()); } @Test public void testTrailingWhitespaceNotLost() throws Exception { final String textWithVaryingLineDelimiters = "line1 \r\nline2"; final String expectedTextConversion = "line1 \nline2"; com.tasktop.c2c.server.tasks.domain.Task toCreate = getMockTask(); toCreate.setDescription(textWithVaryingLineDelimiters); com.tasktop.c2c.server.tasks.domain.Task created = taskService.createTask(toCreate); Assert.assertEquals(expectedTextConversion, created.getDescription()); Comment comment = new Comment(); comment.setAuthor(created.getReporter()); comment.setCommentText(textWithVaryingLineDelimiters); created.getComments().add(comment); com.tasktop.c2c.server.tasks.domain.Task updated = taskService.updateTask(created); Assert.assertEquals(expectedTextConversion, updated.getComments().get(0).getCommentText()); } @Test public void testUpdateExceptions() throws Exception { com.tasktop.c2c.server.tasks.domain.Task toCreate = getMockTask(); com.tasktop.c2c.server.tasks.domain.Task created = taskService.createTask(toCreate); created.setShortDescription(null); // required try { taskService.updateTask(created); Assert.fail("Expect validation exception"); } catch (ValidationException ex) { // Expected assertEquals("A summary is required.", ex.getMessage()); } created.setShortDescription("sd"); created.setId(100); try { taskService.updateTask(created); Assert.fail("Expect ENF exception"); } catch (EntityNotFoundException ex) { // Expected // TODO, verify message } } @Test public void testUpdateSendsCorrectActivityEvent() throws Exception { com.tasktop.c2c.server.tasks.domain.Task toCreate = getMockTask(); com.tasktop.c2c.server.tasks.domain.Task created = taskService.createTask(toCreate); // So that we do not merge with the create activity Thread.sleep(1000L); String newDesc = "My new desc"; created.setDescription(newDesc); com.tasktop.c2c.server.tasks.domain.Task updated = taskService.updateTask(created); Assert.assertEquals(newDesc, updated.getDescription()); Assert.assertNotNull(lastEvent); TaskActivityEvent activityEvent = (TaskActivityEvent) lastEvent; Assert.assertEquals(1, activityEvent.getTaskActivities().size()); TaskActivity activity = activityEvent.getTaskActivities().get(0); Assert.assertEquals(TaskActivity.Type.UPDATED, activity.getActivityType()); Assert.assertEquals(1, activity.getFieldUpdates().size()); Assert.assertEquals(newDesc, activity.getFieldUpdates().get(0).getNewValue()); Assert.assertEquals(newDesc, activity.getTask().getDescription()); } @Test public void testUpdateTaskModifiesTaskVersion() throws Exception { com.tasktop.c2c.server.tasks.domain.Task toCreate = getMockTask(); com.tasktop.c2c.server.tasks.domain.Task created = taskService.createTask(toCreate); Assert.assertNotNull(created.getVersion()); created.setShortDescription(created.getShortDescription() + " changed"); // required // resolution of version is timestamp-based... so we have to wait here. Thread.sleep(1000L); com.tasktop.c2c.server.tasks.domain.Task updatedTask = taskService.updateTask(created); Assert.assertNotNull(updatedTask.getVersion()); Assert.assertFalse(updatedTask.getVersion() + " = " + created.getVersion(), updatedTask.getVersion().equals(created.getVersion())); } @Test public void testUpdateAssociations() throws Exception { // bug 810: submitting a task can overwrite the parent association com.tasktop.c2c.server.tasks.domain.Task parent = getMockTask(); com.tasktop.c2c.server.tasks.domain.Task child1 = getMockTask(); com.tasktop.c2c.server.tasks.domain.Task child2 = getMockTask(); parent = taskService.createTask(parent); child1 = taskService.createTask(child1); child2 = taskService.createTask(child2); // adding child to subtasks causes parent/child parent.getSubTasks().add(child1); parent = taskService.updateTask(parent); child1 = taskService.retrieveTask(child1.getId()); assertParentChild(parent, child1); parent = taskService.retrieveTask(parent.getId()); assertParentChild(parent, child1); // setting parent on child causes parent/child child2.setParentTask(parent); child2 = taskService.updateTask(child2); parent = taskService.retrieveTask(parent.getId()); assertParentChild(parent, child2); // verify adding a child to parent doesn't remove existing children assertParentChild(parent, child1); // removing a child from a parent disassociates child parent.getSubTasks().remove(child1); parent = taskService.updateTask(parent); child1 = taskService.retrieveTask(child1.getId()); assertParentChild(parent, child2); assertNotParentChild(parent, child1); // setting parent to null disassociates child child2.setParentTask(null); child2 = taskService.updateTask(child2); parent = taskService.retrieveTask(parent.getId()); assertNotParentChild(parent, child1); assertNotParentChild(parent, child2); Thread.sleep(500L); } @Test public void testUpdateAssociationsDeltaTimestamp() throws Exception { com.tasktop.c2c.server.tasks.domain.Task parent = getMockTask(); com.tasktop.c2c.server.tasks.domain.Task child1 = getMockTask(); com.tasktop.c2c.server.tasks.domain.Task child2 = getMockTask(); parent = taskService.createTask(parent); child1 = taskService.createTask(child1); child2 = taskService.createTask(child2); entityManager.flush(); Date parentDeltaTimestamp = parent.getModificationDate(); Date child1DeltaTimestamp = child1.getModificationDate(); Date child2DeltaTimestamp = child2.getModificationDate(); Thread.sleep(1000L); // adding child to subtasks causes parent/child parent.getSubTasks().add(child1); parent = taskService.updateTask(parent); child1 = taskService.retrieveTask(child1.getId()); assertParentChild(parent, child1); assertAfter(child1DeltaTimestamp, child1.getModificationDate()); assertAfter(parentDeltaTimestamp, parent.getModificationDate()); Thread.sleep(1000L); parentDeltaTimestamp = parent.getModificationDate(); child1DeltaTimestamp = child1.getModificationDate(); child2DeltaTimestamp = child2.getModificationDate(); // setting parent on child causes parent/child child2.setParentTask(parent); child2 = taskService.updateTask(child2); child1 = taskService.retrieveTask(child1.getId()); parent = taskService.retrieveTask(parent.getId()); assertParentChild(parent, child1); assertParentChild(parent, child2); assertAfter(child2DeltaTimestamp, child2.getModificationDate()); assertAfter(parentDeltaTimestamp, parent.getModificationDate()); assertEquals(child1DeltaTimestamp, child1.getModificationDate()); Thread.sleep(1000L); parentDeltaTimestamp = parent.getModificationDate(); child1DeltaTimestamp = child1.getModificationDate(); child2DeltaTimestamp = child2.getModificationDate(); // removing a child by setting parent task to null child2.setParentTask(null); child2 = taskService.updateTask(child2); child1 = taskService.retrieveTask(child1.getId()); parent = taskService.retrieveTask(parent.getId()); assertNotParentChild(parent, child2); assertParentChild(parent, child1); assertAfter(child2DeltaTimestamp, child2.getModificationDate()); assertAfter(parentDeltaTimestamp, parent.getModificationDate()); assertEquals(child1DeltaTimestamp, child1.getModificationDate()); Thread.sleep(1000L); parentDeltaTimestamp = parent.getModificationDate(); child1DeltaTimestamp = child1.getModificationDate(); child2DeltaTimestamp = child2.getModificationDate(); // removing a child by removing from parent collection parent.getSubTasks().clear(); parent = taskService.updateTask(parent); child1 = taskService.retrieveTask(child1.getId()); child2 = taskService.retrieveTask(child2.getId()); assertNotParentChild(parent, child2); assertNotParentChild(parent, child1); assertAfter(child1DeltaTimestamp, child1.getModificationDate()); assertAfter(parentDeltaTimestamp, parent.getModificationDate()); assertEquals(child2DeltaTimestamp, child2.getModificationDate()); } private void assertAfter(Date referenceTimestamp, Date timestamp) { DateFormat format = new SimpleDateFormat("yyyyMMdd-HH:mm:ss.SSS"); assertTrue(String.format("Expected timestamp to be after %s but was %s", format.format(referenceTimestamp), format.format(timestamp)), timestamp.after(referenceTimestamp)); } private void assertNotParentChild(com.tasktop.c2c.server.tasks.domain.Task parent, com.tasktop.c2c.server.tasks.domain.Task child) { assertFalse(parent.getSubTasks().contains(child)); assertNull(child.getParentTask()); } private void assertParentChild(com.tasktop.c2c.server.tasks.domain.Task parent, com.tasktop.c2c.server.tasks.domain.Task child) { assertTrue(parent.getSubTasks().contains(child)); assertEquals(child.getParentTask(), parent); } @Test public void testUpdateWithNoOwner() throws Exception { // bug 276: saving a new task with no owner causes a validation error com.tasktop.c2c.server.tasks.domain.Task toCreate = getMockTask(); com.tasktop.c2c.server.tasks.domain.Task created = taskService.createTask(toCreate); created.setAssignee(null); com.tasktop.c2c.server.tasks.domain.Task updated = taskService.updateTask(created); assertNotNull(updated.getAssignee()); } @Test public void testUpdateWithCustomFields() throws ValidationException, EntityNotFoundException, ConcurrentUpdateException { FieldDescriptor descriptor = new FieldDescriptor(); descriptor.setAvailableForNewTasks(true); descriptor.setDescription("TestA"); descriptor.setFieldType(FieldType.SINGLE_SELECT); descriptor.setName("testA" + System.currentTimeMillis()); descriptor.setValueStrings(Arrays.asList("one", "two", "three")); createdFields.add(descriptor); customFieldService.createCustomField(descriptor); com.tasktop.c2c.server.tasks.domain.Task toCreate = getMockTask(); com.tasktop.c2c.server.tasks.domain.Task created = taskService.createTask(toCreate); assertNotNull(created.getCustomFields()); assertTrue(!created.getCustomFields().isEmpty()); assertEquals("---", created.getCustomFields().get(descriptor.getName())); Map<String, String> customFields = new HashMap<String, String>(); customFields.put(descriptor.getName(), "abc123 4"); created.setCustomFields(customFields); try { taskService.updateTask(created); fail("expected validation exception"); } catch (ValidationException e) { // expected } created = taskService.retrieveTask(created.getId()); created.getCustomFields().put(descriptor.getName(), "one"); com.tasktop.c2c.server.tasks.domain.Task updated = taskService.updateTask(created); assertNotNull(updated.getCustomFields()); assertEquals("one", updated.getCustomFields().get(descriptor.getName())); } @Test public void testUpdateWithCustomFields_MultiSelect() throws ValidationException, EntityNotFoundException, ConcurrentUpdateException { FieldDescriptor descriptor = new FieldDescriptor(); descriptor.setAvailableForNewTasks(true); descriptor.setDescription("TestA"); descriptor.setFieldType(FieldType.MULTI_SELECT); descriptor.setName("testA" + System.currentTimeMillis()); descriptor.setValueStrings(Arrays.asList("one", "two", "three")); createdFields.add(descriptor); customFieldService.createCustomField(descriptor); com.tasktop.c2c.server.tasks.domain.Task toCreate = getMockTask(); com.tasktop.c2c.server.tasks.domain.Task created = taskService.createTask(toCreate); assertNotNull(created.getCustomFields()); assertTrue(!created.getCustomFields().isEmpty()); assertEquals("", created.getCustomFields().get(descriptor.getName())); Map<String, String> customFields = new HashMap<String, String>(); customFields.put(descriptor.getName(), "abc123 4"); created.setCustomFields(customFields); try { taskService.updateTask(created); fail("expected validation exception"); } catch (ValidationException e) { // expected } created = taskService.retrieveTask(created.getId()); // two values created.getCustomFields().put(descriptor.getName(), "one,two"); com.tasktop.c2c.server.tasks.domain.Task updated = taskService.updateTask(created); assertNotNull(updated.getCustomFields()); assertEquals("one,two", updated.getCustomFields().get(descriptor.getName())); // one value updated.getCustomFields().put(descriptor.getName(), "one"); updated = taskService.updateTask(updated); assertNotNull(updated.getCustomFields()); assertEquals("one", updated.getCustomFields().get(descriptor.getName())); // null value updated.getCustomFields().put(descriptor.getName(), null); updated = taskService.updateTask(updated); assertNotNull(updated.getCustomFields()); assertEquals("", updated.getCustomFields().get(descriptor.getName())); // empty value updated.getCustomFields().put(descriptor.getName(), ""); updated = taskService.updateTask(updated); assertNotNull(updated.getCustomFields()); assertEquals("", updated.getCustomFields().get(descriptor.getName())); } @Test public void testUpdateWithTaskTypeCustomField() throws Exception { String taskType = taskTypeValues[0]; com.tasktop.c2c.server.tasks.domain.Task toCreate = getMockTask(); toCreate.setTaskType(taskType); com.tasktop.c2c.server.tasks.domain.Task created = taskService.createTask(toCreate); int numCustomFields = created.getCustomFields().size(); assertEquals(taskType, created.getTaskType()); // Modify and re-save taskType = taskTypeValues[1]; created.setTaskType(taskType); com.tasktop.c2c.server.tasks.domain.Task updated = taskService.updateTask(created); assertEquals(numCustomFields, updated.getCustomFields().size()); assertEquals(taskType, updated.getTaskType()); } @Test(expected = ValidationException.class) public void testUpdateWithInvalidTaskTypeCustomField() throws Exception { String taskType = taskTypeValues[0]; com.tasktop.c2c.server.tasks.domain.Task toCreate = getMockTask(); toCreate.setTaskType(taskType); com.tasktop.c2c.server.tasks.domain.Task created = taskService.createTask(toCreate); assertEquals(taskType, created.getTaskType()); // Modify and re-save taskType = taskTypeValues[1] + "crazystuff"; created.setTaskType(taskType); // This should blow up. taskService.updateTask(created); } @Test public void testUpdateWithIterationCustomField() throws Exception { Iteration iteration = new Iteration(iterationValues[0]); com.tasktop.c2c.server.tasks.domain.Task toCreate = getMockTask(); toCreate.setIteration(iteration); com.tasktop.c2c.server.tasks.domain.Task created = taskService.createTask(toCreate); int numCustomFields = created.getCustomFields().size(); assertEquals(iteration.getValue(), created.getIteration().getValue()); // Modify and re-save iteration = new Iteration(iterationValues[1]); created.setIteration(iteration); com.tasktop.c2c.server.tasks.domain.Task updated = taskService.updateTask(created); assertEquals(numCustomFields, updated.getCustomFields().size()); assertEquals(iteration.getValue(), updated.getIteration().getValue()); } @Test public void testUpdateWithInvalidIterationCustomField() throws Exception { Iteration iteration = new Iteration(iterationValues[0]); com.tasktop.c2c.server.tasks.domain.Task toCreate = getMockTask(); toCreate.setIteration(iteration); com.tasktop.c2c.server.tasks.domain.Task created = taskService.createTask(toCreate); assertEquals(iteration.getValue(), created.getIteration().getValue()); // Modify and re-save iteration = new Iteration("wackystuff"); created.setIteration(iteration); // This should blow up. try { taskService.updateTask(created); Assert.fail(); } catch (ValidationException e) { // expected } } @Test(expected = EntityNotFoundException.class) public void testInvalidRetrieve() throws ValidationException, EntityNotFoundException { taskService.retrieveTask(1223523); } protected com.tasktop.c2c.server.tasks.domain.Task getMockTask() throws ValidationException { return getMockTask("some description"); } private RepositoryConfiguration repositoryConfiguration = null; private RepositoryConfiguration getRepositoryConfiguration() { if (repositoryConfiguration == null) { repositoryConfiguration = taskService.getRepositoryContext(); } return repositoryConfiguration; } private com.tasktop.c2c.server.tasks.domain.Task getMockTask(String desc) throws ValidationException { RepositoryConfiguration repositoryConfiguration = getRepositoryConfiguration(); com.tasktop.c2c.server.tasks.domain.Task toCreate = MockTaskFactory.createDO(); toCreate.setId(null); toCreate.setDescription(desc); toCreate.setProduct(repositoryConfiguration.getProducts().get(0)); toCreate.setComponent(getMockComponent()); toCreate.setAssignee(ProfileConverter.copy(currentUser)); toCreate.setSeverity(repositoryConfiguration.getSeverities().get(0)); for (com.tasktop.c2c.server.tasks.domain.Milestone milestone : repositoryConfiguration.getMilestones()) { if (milestone.getProduct().equals(toCreate.getProduct())) { toCreate.setMilestone(milestone); break; } } toCreate.setStatus(repositoryConfiguration.getStatuses().get(0)); toCreate.setPriority(repositoryConfiguration.getPriorities().get(0)); toCreate.setResolution(repositoryConfiguration.getResolutions().get(0)); return toCreate; } private com.tasktop.c2c.server.tasks.domain.Component getMockComponent() throws ValidationException { com.tasktop.c2c.server.tasks.domain.Component testComponent = new com.tasktop.c2c.server.tasks.domain.Component(); testComponent.setName(RandomStringUtils.randomAlphanumeric(24)); testComponent.setDescription(RandomStringUtils.randomAlphanumeric(1024)); testComponent.setInitialOwner(getCreatedMockTaskUserProfile()); testComponent.setProduct(getCreatedMockDomainProduct()); com.tasktop.c2c.server.tasks.domain.Component createdComponent = taskService.createComponent(testComponent); return createdComponent; } @Test public void testWorkflowTaskCreation() throws ValidationException { int creationStatusCount = 0; int creationTestCount = 0; for (com.tasktop.c2c.server.tasks.domain.TaskStatus status : getRepositoryConfiguration().getStatuses()) { ++creationTestCount; Boolean requireComment = false; Boolean canCreate = false; try { requireComment = (Boolean) entityManager.createQuery("select sw.id.requireComment from " + StatusWorkflow.class.getSimpleName() + " sw where sw.oldStatus is null and sw.newStatus.value = '" + status.getValue() + "'") .getSingleResult(); canCreate = true; } catch (NoResultException e) { // expected } if (canCreate) { ++creationStatusCount; } com.tasktop.c2c.server.tasks.domain.Task task = getMockTask("test " + status.getValue()); task.setId(null); task.setStatus(status); if (requireComment) { Comment comment = new Comment(); comment.setAuthor(task.getReporter()); comment.setCommentText("a comment"); task.getComments().add(comment); } ensureValidResolutionForStatus(task); try { taskService.createTask(task); if (canCreate) { // expected } else { fail("Should not be able to create a task with status " + status); } } catch (ValidationException e) { if (canCreate) { fail("Should be able to create a task with status " + status); } } catch (EntityNotFoundException e) { throw new IllegalStateException(e); } } // sanity assertTrue(creationStatusCount > 0); assertTrue(creationTestCount > creationStatusCount); } @Test public void testWorkflowTaskUpdate() throws EntityNotFoundException, ConcurrentUpdateException, ValidationException { int updateTestCount = 0; for (com.tasktop.c2c.server.tasks.domain.TaskStatus status : getRepositoryConfiguration().getStatuses()) { for (com.tasktop.c2c.server.tasks.domain.TaskStatus status2 : getRepositoryConfiguration() .getStatuses()) { System.out.println("Test " + status + " -> " + status2); ++updateTestCount; boolean transitionAllowed = false; boolean commentRequired = false; if (status.equals(status2)) { transitionAllowed = true; } else { try { commentRequired = (Boolean) entityManager .createQuery( "select sw.id.requireComment from " + StatusWorkflow.class.getSimpleName() + " sw where sw.oldStatus.value = '" + status.getValue() + "' and sw.newStatus.value = '" + status2.getValue() + "'") .getSingleResult(); transitionAllowed = true; } catch (NoResultException e) { // expected } } com.tasktop.c2c.server.tasks.domain.Task toCreate = getMockTask("test " + status.getValue()); com.tasktop.c2c.server.tasks.domain.Task task = taskService.createTask(toCreate); // create the initial state, bypassing workflow Task itask = entityManager.find(Task.class, task.getId()); itask.setStatus(status.getValue()); task.setStatus(status2); if (commentRequired) { Comment comment = new Comment(); comment.setAuthor(task.getReporter()); comment.setCommentText("a comment"); task.getComments().add(comment); } ensureValidResolutionForStatus(task); try { taskService.updateTask(task); if (transitionAllowed) { // expected } else { fail("Should not be able to transition a task with status from " + status + " to " + status2); } } catch (ValidationException e) { if (transitionAllowed) { fail("Should be able to transition a task with status from " + status + " to " + status2 + ": " + e.getMessage()); } } } } // sanity assertTrue(updateTestCount > 0); } @Test public void testAdminCanBypassStatusWorkflow() throws Exception { // log in again, with the Admin role TestSecurity.login(currentUser, Role.Admin); // create a Task com.tasktop.c2c.server.tasks.domain.Task mock = getMockTask(); com.tasktop.c2c.server.tasks.domain.Task task = taskService.createTask(mock); assertEquals("UNCONFIRMED", task.getStatus().getValue()); List<com.tasktop.c2c.server.tasks.domain.TaskStatus> taskStatuses = taskService.getRepositoryContext() .getStatuses(); for (com.tasktop.c2c.server.tasks.domain.TaskStatus ts : taskStatuses) { // invalid statuses from unconfirmed: reopened, verified, closed if ("REOPENED".equals(ts.getValue())) { task.setStatus(ts); task = taskService.updateTask(task); assertEquals("REOPENED", task.getStatus().getValue()); } } } private void ensureValidResolutionForStatus(com.tasktop.c2c.server.tasks.domain.Task task) { if (task.getStatus().getValue().equals("RESOLVED")) { task.setResolution(new TaskResolution()); task.getResolution().setValue("FIXED"); } else { task.setResolution(null); } } @Test public void testTaskCreateRetrieveUpdateRetrieve() throws Exception { com.tasktop.c2c.server.tasks.domain.Task toCreate = getMockTask(); toCreate.setReporter(null); toCreate.setWatchers(null); toCreate.setCreationDate(null); toCreate.setModificationDate(null); toCreate.setVersion(null); toCreate.setDescription(null); toCreate.setAssignee(null); toCreate.setDeadline(null); com.tasktop.c2c.server.tasks.domain.Task created = taskService.createTask(toCreate); assertNotNull(created); assertNotNull(created.getShortDescription()); assertNotNull(created.getDescription()); assertNotNull(created.getId()); assertNotNull(created.getCreationDate()); assertNotNull(created.getModificationDate()); assertNotNull(created.getProduct()); assertNotNull(created.getComponent()); assertNotNull(created.getStatus()); assertNotNull(created.getPriority()); assertNotNull(created.getMilestone()); assertNotNull(created.getReporter()); assertNotNull(created.getReporter().getLoginName()); assertNotNull(created.getWatchers()); assertNotNull(created.getSubTasks()); assertNotNull(created.getBlocksTasks()); assertNotNull(created.getAttachments()); assertNotNull(created.getComments()); assertNotNull(created.getAssignee()); assertNotNull(created.getAssignee().getLoginName()); assertNull(created.getDeadline()); com.tasktop.c2c.server.tasks.domain.Task fromService = taskService.retrieveTask(created.getId()); assertNotNull(fromService); assertNotNull(fromService.getCreationDate()); assertNotNull(fromService.getModificationDate()); assertEquals(created.getId(), fromService.getId()); assertEquals(toCreate.getShortDescription(), fromService.getShortDescription()); assertEquals("", fromService.getDescription()); assertEquals(toCreate.getSeverity().getValue(), fromService.getSeverity().getValue()); assertEquals(toCreate.getMilestone().getId(), fromService.getMilestone().getId()); assertEquals(toCreate.getStatus().getId(), fromService.getStatus().getId()); assertEquals(toCreate.getPriority().getId(), fromService.getPriority().getId()); // Try create again try { taskService.createTask(created); Assert.fail("created existing task"); } catch (Exception e) { // expecte } // Update com.tasktop.c2c.server.tasks.domain.Task toUpdate = fromService; toUpdate.setShortDescription("New short description"); toUpdate.setDeadline(new Date(System.currentTimeMillis() + 100000)); // FIXME toUpdate.setKeywords("NEW KEYWORD"); toUpdate.setCreationDate(null); com.tasktop.c2c.server.tasks.domain.Task updated = taskService.updateTask(toUpdate); fromService = taskService.retrieveTask(toUpdate.getId()); assertEquals(toUpdate.getId(), fromService.getId()); assertNotNull(fromService); assertNotNull(fromService.getReporter()); assertNotNull(fromService.getReporter().getLoginName()); assertNotNull(fromService.getCreationDate()); assertEquals(updated.getId(), fromService.getId()); assertEquals(toUpdate.getShortDescription(), fromService.getShortDescription()); assertEquals(toUpdate.getDescription(), fromService.getDescription()); assertEquals(toUpdate.getSeverity().getValue(), fromService.getSeverity().getValue()); assertEquals(toUpdate.getMilestone().getId(), fromService.getMilestone().getId()); assertEquals(toUpdate.getStatus().getId(), fromService.getStatus().getId()); assertEquals(toUpdate.getPriority().getId(), fromService.getPriority().getId()); assertEquals(toUpdate.getKeywords(), fromService.getKeywords()); assertNotNull(fromService.getDeadline()); } @Test public void testUpdateRetrieveProductComponentAsigneeAndDelta() throws Exception { RepositoryConfiguration repo = taskService.getRepositoryContext(); com.tasktop.c2c.server.tasks.domain.Task toCreate = getMockTask(); toCreate.setProduct(repo.getProducts().get(0)); toCreate.setComponent(repo.getComponents() .get(repo.getComponents().indexOf(toCreate.getProduct().getDefaultComponent()))); com.tasktop.c2c.server.tasks.domain.Task created = taskService.createTask(toCreate); assertEquals(repo.getProducts().get(0), created.getProduct()); assertEquals(repo.getProducts().get(0).getDefaultComponent(), created.getComponent()); Date createdDiff = created.getModificationDate(); com.tasktop.c2c.server.tasks.domain.Component testComponent = new com.tasktop.c2c.server.tasks.domain.Component(); testComponent.setName(RandomStringUtils.randomAlphanumeric(24)); testComponent.setDescription(RandomStringUtils.randomAlphanumeric(1024)); testComponent.setProduct(getCreatedMockDomainProduct()); com.tasktop.c2c.server.tasks.domain.Component createComponent = taskService.createComponent(testComponent); created.setProduct(testComponent.getProduct()); created.setComponent(createComponent); created.setAssignee(repo.getUsers().get(0)); Assert.assertNotSame(toCreate.getAssignee(), created.getAssignee()); Thread.sleep(1000);// To get a later delta com.tasktop.c2c.server.tasks.domain.Task updated = taskService.updateTask(created); assertEquals(createComponent.getProduct(), updated.getProduct()); assertEquals(createComponent, updated.getComponent()); assertEquals(repo.getUsers().get(0), updated.getAssignee()); assertTrue(createdDiff.before(updated.getModificationDate())); } @Test public void testFindTasksWithNumbericSearchTerm() { setupTestData(); Integer id = tasks.get(0).getId(); QueryResult<com.tasktop.c2c.server.tasks.domain.Task> queryResult = taskService.findTasks(id.toString(), null); assertNotNull(queryResult); assertEquals((Integer) 1, queryResult.getTotalResultSize()); assertEquals(1, queryResult.getResultPage().size()); assertEquals(id, queryResult.getResultPage().get(0).getId()); // Test no results queryResult = taskService.findTasks("1234567", null); assertNotNull(queryResult); assertEquals(0, queryResult.getResultPage().size()); assertEquals((Integer) 0, queryResult.getTotalResultSize()); } @Test public void testFindTasksWithMatchingCommentText() { setupTestData(); final String word = UUID.randomUUID().toString(); String text = "leading text " + word + " trailing text"; Task task = tasks.get(0); com.tasktop.c2c.server.internal.tasks.domain.Comment comment = new com.tasktop.c2c.server.internal.tasks.domain.Comment(); comment.setProfile(currentUser); comment.setThetext(text); comment.setTask(task); task.getComments().add(comment); entityManager.persist(comment); QueryResult<com.tasktop.c2c.server.tasks.domain.Task> result = taskService.findTasks(word, null); assertNotNull(result); assertEquals(Integer.valueOf(1), result.getTotalResultSize()); assertEquals(task.getId(), result.getResultPage().get(0).getId()); } @Test public void testFindTasksWithMatchingTwoCommentText() { setupTestData(); String word1 = UUID.randomUUID().toString(); String text1 = "leading text " + word1 + " trailing text"; String word2 = UUID.randomUUID().toString(); String text2 = "leading text " + word2 + " trailing text"; Task task = tasks.get(0); com.tasktop.c2c.server.internal.tasks.domain.Comment comment1 = new com.tasktop.c2c.server.internal.tasks.domain.Comment(); comment1.setProfile(currentUser); comment1.setThetext(text1); comment1.setTask(task); com.tasktop.c2c.server.internal.tasks.domain.Comment comment2 = new com.tasktop.c2c.server.internal.tasks.domain.Comment(); comment2.setProfile(currentUser); comment2.setThetext(text2); comment2.setTask(task); task.getComments().add(comment1); task.getComments().add(comment2); entityManager.persist(comment1); entityManager.persist(comment2); QueryResult<com.tasktop.c2c.server.tasks.domain.Task> result = taskService .findTasks(word1 + " " + word2, null); assertNotNull(result); assertEquals(Integer.valueOf(1), result.getTotalResultSize()); assertEquals(task.getId(), result.getResultPage().get(0).getId()); // Verify not found w/extra term. result = taskService.findTasks(word1 + " " + word2 + " " + UUID.randomUUID().toString(), null); assertNotNull(result); assertEquals(Integer.valueOf(0), result.getTotalResultSize()); assertEquals(0, result.getResultPage().size()); } @Test public void testFindTasksWithMatchingCommentAndSummaryText() { setupTestData(); String word1 = UUID.randomUUID().toString(); String text1 = "leading text " + word1 + " trailing text"; String word2 = UUID.randomUUID().toString(); String text2 = "leading text " + word2 + " trailing text"; Task task = tasks.get(0); com.tasktop.c2c.server.internal.tasks.domain.Comment comment1 = new com.tasktop.c2c.server.internal.tasks.domain.Comment(); comment1.setProfile(currentUser); comment1.setThetext(text1); comment1.setTask(task); task.setShortDesc(text2); task.getComments().add(comment1); entityManager.persist(comment1); QueryResult<com.tasktop.c2c.server.tasks.domain.Task> result = taskService .findTasks(word1 + " " + word2, null); assertNotNull(result); assertEquals(Integer.valueOf(1), result.getTotalResultSize()); assertEquals(task.getId(), result.getResultPage().get(0).getId()); // Verify not found w/extra term. result = taskService.findTasks(word1 + " " + word2 + " " + UUID.randomUUID().toString(), null); assertNotNull(result); assertEquals(Integer.valueOf(0), result.getTotalResultSize()); assertEquals(0, result.getResultPage().size()); } @Test public void testCreateRetrieveUpdateComments() throws Exception { com.tasktop.c2c.server.tasks.domain.Task toCreate = getMockTask(); String c1Text = "c1Text"; String c2Text = "c2Text"; int numInitalComments = getNumCommentsInDB(); com.tasktop.c2c.server.tasks.domain.Task created = taskService.createTask(toCreate); Comment myComment = new Comment(); myComment.setCommentText(c1Text); created.setComments(Arrays.asList(myComment)); com.tasktop.c2c.server.tasks.domain.Task updated = taskService.updateTask(created); assertNotNull(updated); assertNotNull(updated.getComments()); assertEquals(1, updated.getComments().size()); assertEquals(toCreate.getDescription(), updated.getDescription()); assertEquals(c1Text, updated.getComments().get(0).getCommentText()); assertNotNull(updated.getComments().get(0).getAuthor()); assertNotNull(updated.getComments().get(0).getCreationDate()); assertEquals(numInitalComments + 2, getNumCommentsInDB()); // One is // description Comment anotherComment = new Comment(); anotherComment.setCommentText(c2Text); updated.getComments().add(anotherComment); Thread.sleep(MINIMUM_DATE_RESOLUTION); updated = taskService.updateTask(updated); assertNotNull(updated); assertNotNull(updated.getComments()); assertEquals(2, updated.getComments().size()); assertEquals(c2Text, updated.getComments().get(1).getCommentText()); assertNotNull(updated.getComments().get(0).getAuthor()); assertNotNull(updated.getComments().get(0).getCreationDate()); assertEquals(numInitalComments + 3, getNumCommentsInDB()); com.tasktop.c2c.server.tasks.domain.Task retrieved = taskService.retrieveTask(updated.getId()); assertNotNull(retrieved); assertNotNull(retrieved.getComments()); assertEquals(2, retrieved.getComments().size()); assertEquals(c2Text, retrieved.getComments().get(1).getCommentText()); } @Test public void testCreateWithInitialComment() throws ValidationException, EntityNotFoundException { com.tasktop.c2c.server.tasks.domain.Task toCreate = getMockTask(); String c1Text = "c1Text"; Comment myComment = new Comment(); myComment.setCommentText(c1Text); myComment.setAuthor(toCreate.getReporter()); myComment.setCreationDate(new Date()); toCreate.setComments(Arrays.asList(myComment)); com.tasktop.c2c.server.tasks.domain.Task created = taskService.createTask(toCreate); assertEquals(1, created.getComments().size()); assertEquals(c1Text, created.getComments().get(0).getCommentText()); } @Test public void testCreateWithInitialComments() throws ValidationException, EntityNotFoundException { com.tasktop.c2c.server.tasks.domain.Task toCreate = getMockTask(); String c1Text = "c1Text"; String c2Text = "c2Text"; String c3Text = "c3Text"; Comment c1 = new Comment(); c1.setCommentText(c1Text); Comment c2 = new Comment(); c2.setCommentText(c2Text); Comment c3 = new Comment(); c3.setCommentText(c3Text); toCreate.setComments(Arrays.asList(c1, c2, c3)); com.tasktop.c2c.server.tasks.domain.Task created = taskService.createTask(toCreate); assertEquals(3, created.getComments().size()); Assert.assertEquals(c1Text, created.getComments().get(0).getCommentText()); Assert.assertEquals(c2Text, created.getComments().get(1).getCommentText()); Assert.assertEquals(c3Text, created.getComments().get(2).getCommentText()); } private int getNumCommentsInDB() { Number comments = (Number) entityManager .createQuery("select count(c) from " + com.tasktop.c2c.server.internal.tasks.domain.Comment.class.getSimpleName() + " c") .getSingleResult(); return comments.intValue(); } @Test public void testCreateRetrieveUpdateParentAndBlocks() throws Exception { com.tasktop.c2c.server.tasks.domain.Task parentTask = taskService.createTask(getMockTask("parent")); com.tasktop.c2c.server.tasks.domain.Task blockedTask1 = taskService.createTask(getMockTask("blocked1")); com.tasktop.c2c.server.tasks.domain.Task blockedTask2 = taskService.createTask(getMockTask("blocked2")); // FIXME ?? It is this ordering that defines which is the parent assertTrue(parentTask.getId() < blockedTask1.getId()); assertTrue(parentTask.getId() < blockedTask2.getId()); assertTrue(blockedTask1.getId() < blockedTask2.getId()); com.tasktop.c2c.server.tasks.domain.Task toCreate = getMockTask("task with parents and blocks"); toCreate.setBlocksTasks(Arrays.asList(parentTask, blockedTask1, blockedTask2)); com.tasktop.c2c.server.tasks.domain.Task created = taskService.createTask(toCreate); assertNotNull(created.getParentTask()); assertEquals(parentTask.getId(), created.getParentTask().getId()); assertEquals(3, created.getBlocksTasks().size()); // task 331 updateTask deletes tasks com.tasktop.c2c.server.tasks.domain.Task updated = taskService.updateTask(created); assertEquals(3, updated.getBlocksTasks().size()); try { com.tasktop.c2c.server.tasks.domain.Task self = new com.tasktop.c2c.server.tasks.domain.Task(); self.setId(updated.getId()); updated.setBlocksTasks(Arrays.asList(blockedTask1, blockedTask2, self)); taskService.updateTask(updated); Assert.fail("expceted validation exception"); } catch (ValidationException ex) { // Expected } try { updated.setBlocksTasks(Arrays.asList(blockedTask1)); updated.setSubTasks(Arrays.asList(blockedTask1)); taskService.updateTask(updated); Assert.fail("expceted validation exception"); } catch (ValidationException ex) { // Expected } // Check the dep is represented in parent parentTask = taskService.retrieveTask(parentTask.getId()); assertNotNull(parentTask.getSubTasks()); assertEquals(1, parentTask.getSubTasks().size()); assertEquals(created.getId(), parentTask.getSubTasks().get(0).getId()); assertNotNull(parentTask.getSubTasks().get(0).getShortDescription()); assertNotNull(parentTask.getSubTasks().get(0).getPriority()); assertNotNull(parentTask.getSubTasks().get(0).getStatus()); assertNotNull(parentTask.getSubTasks().get(0).getSeverity()); // Check the dep is represented in the other blocked blockedTask1 = taskService.retrieveTask(blockedTask1.getId()); assertNotNull(blockedTask1.getSubTasks()); assertEquals(1, blockedTask1.getSubTasks().size()); assertEquals(created.getId(), blockedTask1.getSubTasks().get(0).getId()); blockedTask2 = taskService.retrieveTask(blockedTask2.getId()); assertNotNull(blockedTask2.getSubTasks()); assertEquals(1, blockedTask2.getSubTasks().size()); assertEquals(created.getId(), blockedTask2.getSubTasks().get(0).getId()); // Now remove the assosication updated.setParentTask(null); updated.setBlocksTasks(null); updated.setSubTasks(null); taskService.updateTask(updated); updated = taskService.retrieveTask(created.getId()); assertNull(updated.getParentTask()); assertTrue(updated.getBlocksTasks().isEmpty()); blockedTask1 = taskService.retrieveTask(blockedTask1.getId()); assertTrue(blockedTask1.getSubTasks().isEmpty()); blockedTask2 = taskService.retrieveTask(blockedTask2.getId()); assertTrue(blockedTask2.getSubTasks().isEmpty()); // Now add it back updated.setBlocksTasks(Arrays.asList(parentTask, blockedTask1, blockedTask2)); updated = taskService.updateTask(updated); assertNotNull(updated.getParentTask()); assertEquals(parentTask.getId(), updated.getParentTask().getId()); assertEquals(3, updated.getBlocksTasks().size()); } @Test public void testCreateUpdateWithSubtaskCycle() throws Exception { // Create a -> b -> c com.tasktop.c2c.server.tasks.domain.Task a = taskService.createTask(getMockTask("a")); com.tasktop.c2c.server.tasks.domain.Task b = getMockTask("b"); b.setParentTask(a); b = taskService.createTask(b); com.tasktop.c2c.server.tasks.domain.Task c = getMockTask("c"); c.setParentTask(b); c = taskService.createTask(c); com.tasktop.c2c.server.tasks.domain.Task createsCycle = getMockTask("cycle"); createsCycle.setParentTask(c); createsCycle.setSubTasks(Arrays.asList(a)); try { taskService.createTask(createsCycle); Assert.fail("Expect validation exception"); } catch (ValidationException e) { // expected } createsCycle.setParentTask(null); createsCycle.setSubTasks(null); createsCycle = taskService.createTask(createsCycle); createsCycle.setParentTask(a); createsCycle.setSubTasks(Arrays.asList(c)); try { taskService.updateTask(createsCycle); Assert.fail("Expect validation exception"); } catch (ValidationException e) { // expected } } @Test public void testCreateUpdateWithSelfParent() throws Exception { // Create a -> a com.tasktop.c2c.server.tasks.domain.Task a = getMockTask("a"); a.setParentTask(new com.tasktop.c2c.server.tasks.domain.Task()); try { taskService.createTask(a); Assert.fail("Expect validation exception"); } catch (ValidationException e) { // expected } a.setParentTask(null); a = taskService.createTask(a); a.setParentTask(taskService.retrieveTask(a.getId())); try { taskService.updateTask(a); Assert.fail("Expect validation exception"); } catch (ValidationException e) { // expected } } @SuppressWarnings("unchecked") @Test public void testCreateRetrieveUpdateSubtasks() throws Exception { // Now try creating the relationship through the subTask association. com.tasktop.c2c.server.tasks.domain.Task subTask1 = taskService.createTask(getMockTask("subTask1")); com.tasktop.c2c.server.tasks.domain.Task subTask2 = taskService.createTask(getMockTask("subTask2")); com.tasktop.c2c.server.tasks.domain.Task subTask3 = taskService.createTask(getMockTask("subTask3")); com.tasktop.c2c.server.tasks.domain.Task toCreate = getMockTask("task with subTasks"); toCreate.setSubTasks(Arrays.asList(subTask1, subTask2)); com.tasktop.c2c.server.tasks.domain.Task created = taskService.createTask(toCreate); assertNotNull(created.getSubTasks()); assertEquals(2, created.getSubTasks().size()); // Check the dep is represented in the subtasks subTask1 = taskService.retrieveTask(subTask1.getId()); assertNotNull(subTask1.getParentTask()); assertEquals(created.getId(), subTask1.getParentTask().getId()); subTask2 = taskService.retrieveTask(subTask2.getId()); assertNotNull(subTask2.getParentTask()); assertEquals(created.getId(), subTask2.getParentTask().getId()); // Now remove that association created.setSubTasks(Collections.EMPTY_LIST); taskService.updateTask(created); created = taskService.retrieveTask(created.getId()); assertTrue(created.getSubTasks() == null || created.getSubTasks().isEmpty()); subTask1 = taskService.retrieveTask(subTask1.getId()); assertNull(subTask1.getParentTask()); subTask2 = taskService.retrieveTask(subTask2.getId()); assertNull(subTask2.getParentTask()); created.setSubTasks(Arrays.asList(subTask2)); created = taskService.updateTask(created); assertEquals(1, created.getSubTasks().size()); created.setSubTasks(Arrays.asList(subTask1, subTask2, subTask3)); created = taskService.updateTask(created); assertEquals(3, created.getSubTasks().size()); } @Test public void testCreateUpdateWatchers() throws Exception { TaskUserProfile watcher1 = getCreatedMockTaskUserProfile(); TaskUserProfile watcher2 = getCreatedMockTaskUserProfile(); TaskUserProfile watcher3 = getCreatedMockTaskUserProfile(); com.tasktop.c2c.server.tasks.domain.Task toCreate = getMockTask(); toCreate.setWatchers(Arrays.asList(watcher1)); com.tasktop.c2c.server.tasks.domain.Task created = taskService.createTask(toCreate); assertNotNull(created.getWatchers()); assertEquals(1, created.getWatchers().size()); assertEquals(watcher1.getId(), created.getWatchers().get(0).getId()); // Remove wather1 created.setWatchers(null); com.tasktop.c2c.server.tasks.domain.Task updated = taskService.updateTask(created); assertTrue(updated.getWatchers().isEmpty()); // Add wather2 updated.setWatchers(Arrays.asList(watcher2)); updated = taskService.updateTask(updated); assertNotNull(updated.getWatchers()); assertEquals(1, updated.getWatchers().size()); assertEquals(watcher2.getId(), updated.getWatchers().get(0).getId()); // Add all watchers updated.setWatchers(Arrays.asList(watcher1, watcher2, watcher3)); updated = taskService.updateTask(updated); assertEquals(3, updated.getWatchers().size()); } @Test public void testCreateUpdateDuplicates() throws Exception { com.tasktop.c2c.server.tasks.domain.Task dupOf1 = taskService.createTask(getMockTask()); com.tasktop.c2c.server.tasks.domain.Task dupOf2 = taskService.createTask(getMockTask()); com.tasktop.c2c.server.tasks.domain.Task toCreate = getMockTask(); toCreate.setDuplicateOf(dupOf1); com.tasktop.c2c.server.tasks.domain.Task created = taskService.createTask(toCreate); assertNotNull(created.getDuplicateOf()); assertEquals(dupOf1.getId(), created.getDuplicateOf().getId()); dupOf1 = taskService.retrieveTask(dupOf1.getId()); assertEquals(1, dupOf1.getDuplicates().size()); assertEquals(created.getId(), dupOf1.getDuplicates().get(0).getId()); // Do a regular update (no changes) com.tasktop.c2c.server.tasks.domain.Task updated = taskService.updateTask(created); // Try without an id. updated.setDuplicateOf(new com.tasktop.c2c.server.tasks.domain.Task()); try { taskService.updateTask(updated); Assert.fail("expected exception"); } catch (ValidationException e) { // Expected } // Try with self updated.setDuplicateOf(new com.tasktop.c2c.server.tasks.domain.Task()); updated.getDuplicateOf().setId(updated.getId()); try { taskService.updateTask(updated); Assert.fail("expected exception"); } catch (ValidationException e) { // Expected } // Really change the duplicate updated.setDuplicateOf(new com.tasktop.c2c.server.tasks.domain.Task()); updated.getDuplicateOf().setId(dupOf2.getId()); updated = taskService.updateTask(updated); assertEquals(dupOf2.getId(), updated.getDuplicateOf().getId()); // Remove the duplicate updated.setDuplicateOf(null); updated = taskService.updateTask(updated); assertTrue(updated.getDuplicateOf() == null); dupOf1 = taskService.retrieveTask(dupOf1.getId()); assertEquals(0, dupOf1.getDuplicates().size()); dupOf2 = taskService.retrieveTask(dupOf2.getId()); assertEquals(0, dupOf2.getDuplicates().size()); // Add it back updated.setDuplicateOf(dupOf1); updated = taskService.updateTask(updated); assertNotNull(updated.getDuplicateOf()); assertEquals(dupOf1.getId(), updated.getDuplicateOf().getId()); dupOf1 = taskService.retrieveTask(dupOf1.getId()); assertEquals(1, dupOf1.getDuplicates().size()); assertEquals(created.getId(), dupOf1.getDuplicates().get(0).getId()); } /** * If the owner is null and the component has a default, then set assignee. */ @Test public void testCreateWithNoOwner_ComponentWithDefaultOwner() throws ValidationException, EntityNotFoundException { com.tasktop.c2c.server.tasks.domain.Task toCreate = getMockTask(); toCreate.setAssignee(null); com.tasktop.c2c.server.tasks.domain.Task created = taskService.createTask(toCreate); assertNotNull(created.getAssignee()); } /** * Explicitly allow null owner. If the owner is null and the component has a default, then set assignee. */ @Test public void testCreateWithNoOwner_ComponentWithNoDefaultOwner() throws ValidationException, EntityNotFoundException { com.tasktop.c2c.server.tasks.domain.Task toCreate = getMockTask(); toCreate.setAssignee(null); Component component = MockComponentFactory.create(entityManager); component.setInitialOwner(null); entityManager.flush(); entityManager.refresh(component); com.tasktop.c2c.server.tasks.domain.Component dComponent = new com.tasktop.c2c.server.tasks.domain.Component(); dComponent.setId(component.getId().intValue()); toCreate.setComponent(dComponent); com.tasktop.c2c.server.tasks.domain.Task created = taskService.createTask(toCreate); assertNull(created.getAssignee()); } /** * An owner with a null id or name should be handled gracefully as if it were a null object. */ @Test public void testCreateWithInvalidOwner() throws ValidationException, EntityNotFoundException { com.tasktop.c2c.server.tasks.domain.Task toCreate = getMockTask(); TaskUserProfile owner = new TaskUserProfile(); owner.setId(null); owner.setLoginName(""); owner.setRealname("Some Guy"); toCreate.setAssignee(owner); com.tasktop.c2c.server.tasks.domain.Task created = taskService.createTask(toCreate); // FIXME: this depends on prelaoded fixture data. // confirm the Name is not the fake one we set. (It's really from fixture data.) assertFalse(owner.getRealname().equals(created.getAssignee())); } @Test public void testCreateDoesntUpdateComponent() throws ValidationException, EntityNotFoundException { com.tasktop.c2c.server.tasks.domain.Task toCreate = getMockTask(); com.tasktop.c2c.server.tasks.domain.Component component = toCreate.getComponent(); String originalName = component.getName(); component.setName(originalName + "_changed"); com.tasktop.c2c.server.tasks.domain.Task created = taskService.createTask(toCreate); Component component2 = entityManager.find(Component.class, component.getId().shortValue()); assertEquals(originalName, component2.getName()); assertEquals(originalName, created.getComponent().getName()); } @Test public void testCreateWithCustomFields() throws ValidationException, EntityNotFoundException { FieldDescriptor descriptor = new FieldDescriptor(); descriptor.setAvailableForNewTasks(true); descriptor.setDescription("TestA"); descriptor.setFieldType(FieldType.TEXT); descriptor.setName("testA" + System.currentTimeMillis()); createdFields.add(descriptor); customFieldService.createCustomField(descriptor); com.tasktop.c2c.server.tasks.domain.Task toCreate = getMockTask(); Map<String, String> customFields = new HashMap<String, String>(); customFields.put(descriptor.getName(), "abc123 4"); toCreate.setCustomFields(customFields); com.tasktop.c2c.server.tasks.domain.Task created = taskService.createTask(toCreate); assertNotNull(created.getCustomFields()); assertEquals("abc123 4", created.getCustomFields().get(descriptor.getName())); } @Test public void testCreateWithCustomFieldsValidationFails() throws ValidationException, EntityNotFoundException { // test for task 512: task is created even when a custom field // validation fails FieldDescriptor descriptor = new FieldDescriptor(); descriptor.setAvailableForNewTasks(true); descriptor.setDescription("TestA"); descriptor.setFieldType(FieldType.SINGLE_SELECT); descriptor.setName("testA" + System.currentTimeMillis()); descriptor.setValueStrings(Arrays.asList("one", "two")); createdFields.add(descriptor); customFieldService.createCustomField(descriptor); com.tasktop.c2c.server.tasks.domain.Task toCreate = getMockTask(); // something distinctive that will make it easy to find toCreate.setShortDescription(UUID.randomUUID().toString()); Map<String, String> customFields = new HashMap<String, String>(); customFields.put(descriptor.getName(), "three"); // intentionally // provide an // invalid value assertFalse(descriptor.getValues().contains(customFields.get(descriptor.getName()))); toCreate.setCustomFields(customFields); try { taskService.createTask(toCreate); fail("Expected validation error"); } catch (ValidationException e) { // expected } // verify that when the transaction is rolled back, the row does not // exist entityManager.flush(); entityManager.clear(); entityManager.createNativeQuery("rollback").executeUpdate(); List<?> tasks = entityManager .createQuery("select e from " + Task.class.getSimpleName() + " e where e.shortDesc = :s") .setParameter("s", toCreate.getShortDescription()).getResultList(); assertTrue(tasks.isEmpty()); } @Test public void testCreateWithTaskTypeCustomField() throws ValidationException, EntityNotFoundException { String taskType = taskTypeValues[0]; com.tasktop.c2c.server.tasks.domain.Task toCreate = getMockTask(); toCreate.setTaskType(taskType); com.tasktop.c2c.server.tasks.domain.Task created = taskService.createTask(toCreate); assertEquals(taskType, created.getTaskType()); } @Test(expected = ValidationException.class) public void testCreateWithInvalidTaskTypeCustomField() throws ValidationException, EntityNotFoundException { String taskType = taskTypeValues[0] + "invalidStuff"; com.tasktop.c2c.server.tasks.domain.Task toCreate = getMockTask(); toCreate.setTaskType(taskType); // This should blow up. taskService.createTask(toCreate); } @Test public void testCreateWithIterationCustomField() throws ValidationException, EntityNotFoundException { Iteration iteration = new Iteration(iterationValues[0]); com.tasktop.c2c.server.tasks.domain.Task toCreate = getMockTask(); toCreate.setIteration(iteration); com.tasktop.c2c.server.tasks.domain.Task created = taskService.createTask(toCreate); assertEquals(iteration.getValue(), created.getIteration().getValue()); } @Test(expected = ValidationException.class) public void testCreateWithInvalidIterationCustomField() throws ValidationException, EntityNotFoundException { Iteration iteration = new Iteration("invalidStuff"); com.tasktop.c2c.server.tasks.domain.Task toCreate = getMockTask(); toCreate.setIteration(iteration); // This should blow up. taskService.createTask(toCreate); } private Profile getCreatedMockProfile() { Profile p = MockProfileFactory.create(entityManager); entityManager.flush(); assertNotNull(p.getId()); return p; } private TaskUserProfile getCreatedMockTaskUserProfile() { return ProfileConverter.copy(getCreatedMockProfile()); } @Test public void testGetRepositoryContext() { MockKeyworddefFactory.create(entityManager, 5); RepositoryConfiguration ctx = taskService.getRepositoryContext(); assertNotNull(ctx); assertEquals(2, ctx.getMilestones().size()); assertEquals(count(Priority.class), ctx.getPriorities().size()); assertEquals(count(TaskSeverity.class), ctx.getSeverities().size()); assertEquals(count(TaskStatus.class), ctx.getStatuses().size()); assertEquals(count(Resolution.class), ctx.getResolutions().size()); assertTrue(ctx.getUsers().size() >= 2); assertEquals(1, ctx.getProducts().size()); assertEquals(1, ctx.getComponents().size()); assertNotNull(ctx.getComponents().get(0).getProduct()); assertNotNull(ctx.getDefaultPriority()); assertEquals("Normal", ctx.getDefaultPriority().getValue()); assertNotNull(ctx.getDefaultProduct()); assertNotNull(ctx.getDefaultProduct().getDefaultComponent()); assertNotNull(ctx.getDefaultProduct().getDefaultMilestone()); assertNotNull(ctx.getDefaultSeverity()); assertEquals("normal", ctx.getDefaultSeverity().getValue()); assertNotNull(ctx.getDefaultStatus()); assertNotNull(ctx.getDefaultResolution()); assertNotNull(ctx.getKeywords()); assertFalse(ctx.getKeywords().isEmpty()); for (Keyword keyword : ctx.getKeywords()) { assertNotNull(keyword.getName()); assertNotNull(keyword.getDescription()); } assertNotNull(ctx.getMarkupLanguage()); int numComponentsFound = 0; for (com.tasktop.c2c.server.tasks.domain.Product product : ctx.getProducts()) { List<com.tasktop.c2c.server.tasks.domain.Component> componentsForProduct = ctx.getComponents(product); numComponentsFound += componentsForProduct.size(); } assertEquals(ctx.getComponents().size(), numComponentsFound); // Make sure our special fields aren't in the custom field list. for (FieldDescriptor desc : ctx.getCustomFields()) { assertFalse(Task.CUSTOM_TYPE_FIELD_NAME.equals(desc.getName())); assertFalse(Task.CUSTOM_ITERATION_FIELD_NAME.equals(desc.getName())); } for (String curTaskType : taskTypeValues) { assertTrue(ctx.getTaskTypes().contains(curTaskType)); } Set<String> itValues = new HashSet<String>(); for (Iteration it : ctx.getIterations()) { itValues.add(it.getValue()); } for (String curIteration : iterationValues) { assertTrue(itValues.contains(curIteration)); } assertSerializable(ctx); } @Test public void testGetRepositoryContextStateTransitions() { RepositoryConfiguration ctx = taskService.getRepositoryContext(); assertNotNull(ctx); assertNotNull(ctx.getStateTransitions()); assertFalse(ctx.getStateTransitions().isEmpty()); List<com.tasktop.c2c.server.tasks.domain.TaskStatus> initialStatuses = ctx.computeValidStatuses(null); assertNotNull(initialStatuses); assertFalse(initialStatuses.isEmpty()); for (com.tasktop.c2c.server.tasks.domain.TaskStatus status : initialStatuses) { List<com.tasktop.c2c.server.tasks.domain.TaskStatus> states = ctx.computeValidStatuses(status); assertNotNull(states); assertFalse(states.isEmpty()); assertTrue(states.contains(status)); } } private void assertSerializable(Object object) { assertNotNull(object); try { ByteArrayOutputStream out = new ByteArrayOutputStream(); ObjectOutputStream objectOut = new ObjectOutputStream(out); objectOut.writeObject(object); objectOut.close(); ObjectInputStream objectIn = new ObjectInputStream(new ByteArrayInputStream(out.toByteArray())); Object deserializedObject = objectIn.readObject(); assertNotNull(deserializedObject); } catch (Throwable t) { Assert.fail("Object is not serializable: " + object); } } @Test public void testGetRepositoryContextWithCustomField() throws Exception { FieldDescriptor descriptor = new FieldDescriptor(); descriptor.setAvailableForNewTasks(true); descriptor.setDescription("Test1"); descriptor.setFieldType(FieldType.TEXT); descriptor.setName("test" + System.currentTimeMillis()); createdFields.add(descriptor); customFieldService.createCustomField(descriptor); FieldDescriptor descriptor2 = new FieldDescriptor(); descriptor2.setAvailableForNewTasks(true); descriptor2.setDescription("Test2"); descriptor2.setFieldType(FieldType.SINGLE_SELECT); descriptor2.setName("test2" + System.currentTimeMillis()); descriptor2.setValueStrings(Arrays.asList("one", "two")); createdFields.add(descriptor2); customFieldService.createCustomField(descriptor2); RepositoryConfiguration ctx = taskService.getRepositoryContext(); assertNotNull(ctx); assertNotNull(ctx.getCustomFields()); FieldDescriptor[] originalDescriptors = new FieldDescriptor[] { descriptor, descriptor2 }; int foundCount = 0; for (FieldDescriptor fd : ctx.getCustomFields()) { for (FieldDescriptor original : originalDescriptors) { if (original.equals(fd)) { ++foundCount; assertEquals(original.getName(), fd.getName()); assertEquals(original.getDescription(), fd.getDescription()); assertEquals(original.getFieldType(), fd.getFieldType()); if (fd.getValues() != null) { assertNotNull(original.getValues()); assertTrue(fd.getValueStrings().containsAll(original.getValueStrings())); } else { assertNull(original.getValues()); } break; } } } assertEquals(originalDescriptors.length, foundCount); } private void assertByteArrayEquals(byte[] expected, byte[] actual) { assertEquals(expected.length, actual.length); for (int i = 0; i < expected.length; i++) { assertEquals(expected[i], actual[i]); } } @Test public void testSaveAndRetrieveAttachment() throws Exception { com.tasktop.c2c.server.tasks.domain.Task task = taskService.createTask(getMockTask()); com.tasktop.c2c.server.tasks.domain.Attachment attachment1 = new com.tasktop.c2c.server.tasks.domain.Attachment(); attachment1.setDescription("desc"); attachment1.setFilename("filename"); attachment1.setMimeType("mimetype"); Thread.sleep(MINIMUM_DATE_RESOLUTION); try { taskService.saveAttachment(task.getTaskHandle(), attachment1); Assert.fail("expect validation exception"); } catch (ValidationException e) { // expected } attachment1.setAttachmentData("DATA".getBytes()); AttachmentHandle attachmentHandle = taskService.saveAttachment(task.getTaskHandle(), attachment1); int attachId = attachmentHandle.getId(); com.tasktop.c2c.server.tasks.domain.Task retrieved = taskService.retrieveTask(task.getId()); assertNotNull(retrieved.getAttachments()); assertEquals(1, retrieved.getAttachments().size()); assertEquals((Integer) attachId, retrieved.getAttachments().get(0).getId()); assertEquals(attachment1.getMimeType(), retrieved.getAttachments().get(0).getMimeType()); assertNotNull(retrieved.getAttachments().get(0).getCreationDate()); assertNull(retrieved.getAttachments().get(0).getAttachmentData()); assertEquals((Integer) attachment1.getAttachmentData().length, retrieved.getAttachments().get(0).getByteSize()); // Make sure updating attachments updates the timestamp. assertTrue(task.getModificationDate().before(retrieved.getModificationDate())); com.tasktop.c2c.server.tasks.domain.Attachment fatAttachment = taskService.retrieveAttachment(attachId); assertNotNull(fatAttachment); assertNotNull(fatAttachment.getAttachmentData()); assertByteArrayEquals(attachment1.getAttachmentData(), fatAttachment.getAttachmentData()); com.tasktop.c2c.server.tasks.domain.Attachment attachment2 = new com.tasktop.c2c.server.tasks.domain.Attachment(); attachment2.setDescription("desc2"); attachment2.setFilename("filename2"); attachment2.setMimeType("mimetype2"); attachment2.setAttachmentData("DATA2ABCD".getBytes()); try { taskService.saveAttachment(task.getTaskHandle(), attachment2); Assert.fail("Using old task handle should fail to update"); } catch (ConcurrentUpdateException ex) { // Expected } task.setTaskHandle(attachmentHandle.getTaskHandle()); attachmentHandle = taskService.saveAttachment(task.getTaskHandle(), attachment2); attachId = attachmentHandle.getId(); task = taskService.retrieveTask(task.getId()); assertEquals(2, task.getAttachments().size()); assertEquals((Integer) attachId, task.getAttachments().get(1).getId()); assertEquals(attachment2.getMimeType(), task.getAttachments().get(1).getMimeType()); assertNotNull(task.getAttachments().get(1).getCreationDate()); assertNull(task.getAttachments().get(1).getAttachmentData()); assertEquals((Integer) attachment2.getAttachmentData().length, task.getAttachments().get(1).getByteSize()); } @Test public void testSaveAndRetrieveAttachmentViaUpdate() throws Exception { com.tasktop.c2c.server.tasks.domain.Task task = taskService.createTask(getMockTask()); com.tasktop.c2c.server.tasks.domain.Attachment attachment1 = new com.tasktop.c2c.server.tasks.domain.Attachment(); attachment1.setDescription("desc"); attachment1.setFilename("filename"); attachment1.setMimeType("mimetype"); attachment1.setAttachmentData("DATA".getBytes()); task.getAttachments().add(attachment1); com.tasktop.c2c.server.tasks.domain.Task retrieved = taskService.updateTask(task); assertNotNull(retrieved.getAttachments()); assertEquals(1, retrieved.getAttachments().size()); assertEquals(attachment1.getMimeType(), retrieved.getAttachments().get(0).getMimeType()); assertNotNull(retrieved.getAttachments().get(0).getCreationDate()); assertNull(retrieved.getAttachments().get(0).getAttachmentData()); assertEquals((Integer) attachment1.getAttachmentData().length, retrieved.getAttachments().get(0).getByteSize()); com.tasktop.c2c.server.tasks.domain.Attachment fatAttachment = taskService .retrieveAttachment(retrieved.getAttachments().get(0).getId()); assertNotNull(fatAttachment); assertNotNull(fatAttachment.getAttachmentData()); assertByteArrayEquals(attachment1.getAttachmentData(), fatAttachment.getAttachmentData()); com.tasktop.c2c.server.tasks.domain.Attachment attachment2 = new com.tasktop.c2c.server.tasks.domain.Attachment(); attachment2.setDescription("desc2"); attachment2.setFilename("filename2"); attachment2.setMimeType("mimetype2"); attachment2.setAttachmentData("DATA2ABCD".getBytes()); retrieved.getAttachments().clear(); retrieved.getAttachments().add(attachment2); task = taskService.updateTask(retrieved); assertEquals(2, task.getAttachments().size()); assertEquals(attachment2.getMimeType(), task.getAttachments().get(1).getMimeType()); assertNotNull(task.getAttachments().get(1).getCreationDate()); assertNull(task.getAttachments().get(1).getAttachmentData()); assertEquals((Integer) attachment2.getAttachmentData().length, task.getAttachments().get(1).getByteSize()); } @Test public void testSaveAndRetrieveAttachmentAndComment() throws Exception { com.tasktop.c2c.server.tasks.domain.Task task = taskService.createTask(getMockTask()); com.tasktop.c2c.server.tasks.domain.Attachment attachment1 = new com.tasktop.c2c.server.tasks.domain.Attachment(); attachment1.setDescription("desc"); attachment1.setFilename("filename"); attachment1.setMimeType("mimetype"); attachment1.setAttachmentData("DATA".getBytes()); Comment comment = new Comment(); comment.setCommentText("Attaching: " + attachment1.getFilename()); AttachmentHandle attachmentHandle = taskService.saveAttachment(task.getTaskHandle(), attachment1, comment); task = taskService.retrieveTask(task.getId()); assertNotNull(task.getAttachments()); assertEquals(1, task.getAttachments().size()); assertEquals((Integer) attachmentHandle.getId(), task.getAttachments().get(0).getId()); assertEquals(attachment1.getMimeType(), task.getAttachments().get(0).getMimeType()); assertNotNull(task.getAttachments().get(0).getCreationDate()); assertNull(task.getAttachments().get(0).getAttachmentData()); assertEquals((Integer) attachment1.getAttachmentData().length, task.getAttachments().get(0).getByteSize()); assertEquals(1, task.getComments().size()); assertEquals(comment.getCommentText(), task.getComments().get(0).getCommentText()); com.tasktop.c2c.server.tasks.domain.Attachment fatAttachment = taskService .retrieveAttachment(attachmentHandle.getId()); assertNotNull(fatAttachment); assertNotNull(fatAttachment.getAttachmentData()); assertByteArrayEquals(attachment1.getAttachmentData(), fatAttachment.getAttachmentData()); } // TASK 162 @Test public void testQueryWithInvalidTasks() { QueryResult<com.tasktop.c2c.server.tasks.domain.Task> queryResult = taskService .findTasksWithQuery(PredefinedTaskQuery.ALL, null); int initialPageSize = queryResult.getResultPage().size(); int initialTotalSize = queryResult.getTotalResultSize(); Milestone stone = entityManager.find(Milestone.class, 1); stone.setValue("---X"); entityManager.flush(); queryResult = taskService.findTasksWithQuery(PredefinedTaskQuery.ALL, null); int finalPageSize = queryResult.getResultPage().size(); int finalTotalSize = queryResult.getTotalResultSize(); assertEquals(initialTotalSize, finalTotalSize); assertEquals(initialPageSize, finalPageSize); } @Test public void testProvisionCurrentUser() throws ValidationException, EntityNotFoundException { entityManager.remove(currentUser); entityManager.flush(); AuthenticationToken token = new AuthenticationToken(); token.setFirstName("first"); token.setLastName("Las"); token.setUsername("username"); token.setLanguage("en"); token.setKey("foobar"); SecurityContextHolder.getContext().setAuthentication(new PreAuthenticatedAuthenticationToken( AuthenticationServiceUser.fromAuthenticationToken(token), "ROLES")); com.tasktop.c2c.server.tasks.domain.Task toCreate = getMockTask(); toCreate.setAssignee(null); com.tasktop.c2c.server.tasks.domain.Task created = taskService.createTask(toCreate); Assert.assertEquals(token.getUsername(), created.getReporter().getLoginName()); } @Test public void testDeltaTimestampMaintainance() throws Exception { com.tasktop.c2c.server.tasks.domain.Task created = taskService.createTask(getMockTask()); created.setDescription("description"); Thread.sleep(MINIMUM_DATE_RESOLUTION); com.tasktop.c2c.server.tasks.domain.Task updated = taskService.updateTask(created); Assert.assertFalse(created.getModificationDate().equals(updated.getModificationDate())); } @Test public void testOptimisticLocking() throws Exception { com.tasktop.c2c.server.tasks.domain.Task created = taskService.createTask(getMockTask()); com.tasktop.c2c.server.tasks.domain.Task created2 = taskService.retrieveTask(created.getId()); Thread.sleep(MINIMUM_DATE_RESOLUTION); created.setDescription("New description"); taskService.updateTask(created); created2.setDescription("Another new description"); try { taskService.updateTask(created2); Assert.fail("mid-air collision was not detected"); } catch (ConcurrentUpdateException e) { // expected } } @SuppressWarnings("unchecked") private void removeTasks() { for (Task task : (List<Task>) entityManager.createQuery("SELECT task FROM Task task").getResultList()) { entityManager.remove(task); } } @Test public void testCriteriaQueryWithSimpleFieldsPlusAndOr() throws Exception { removeTasks(); com.tasktop.c2c.server.tasks.domain.Task expectedResult = getMockTask(); Criteria summaryCrit = new ColumnCriteria(TaskFieldConstants.SUMMARY_FIELD, expectedResult.getShortDescription()); Criteria descriptionCrit = new ColumnCriteria(TaskFieldConstants.DESCRIPTION_FIELD, expectedResult.getDescription()); Criteria priorityCrit = new ColumnCriteria(TaskFieldConstants.PRIORITY_FIELD, expectedResult.getPriority().getValue()); Criteria statusCrit = new ColumnCriteria(TaskFieldConstants.STATUS_FIELD, expectedResult.getStatus().getValue()); Criteria severityCrit = new ColumnCriteria(TaskFieldConstants.SEVERITY_FIELD, expectedResult.getSeverity().getValue()); Criteria resolutionCrit = new ColumnCriteria(TaskFieldConstants.RESOLUTION_FIELD, expectedResult.getResolution().getValue()); Criteria milestoneCrit = new ColumnCriteria(TaskFieldConstants.MILESTONE_FIELD, expectedResult.getMilestone().getValue()); Criteria productCrit = new ColumnCriteria(TaskFieldConstants.PRODUCT_FIELD, expectedResult.getProduct().getId()); Criteria componentCrit = new ColumnCriteria(TaskFieldConstants.COMPONENT_FIELD, expectedResult.getComponent().getId()); NaryCriteria andCrit = new NaryCriteria(Operator.AND, summaryCrit, priorityCrit, statusCrit, severityCrit, resolutionCrit, milestoneCrit, productCrit, componentCrit, descriptionCrit); NaryCriteria orCrit = new NaryCriteria(Operator.OR, summaryCrit, priorityCrit, statusCrit, severityCrit, resolutionCrit, milestoneCrit, productCrit, componentCrit, descriptionCrit); assertNoResults(summaryCrit); assertNoResults(descriptionCrit); assertNoResults(statusCrit); assertNoResults(priorityCrit); assertNoResults(severityCrit); assertNoResults(resolutionCrit); assertNoResults(milestoneCrit); assertNoResults(productCrit); assertNoResults(componentCrit); assertNoResults(andCrit); assertNoResults(orCrit); // Now create the result expectedResult = taskService.createTask(expectedResult); assertSingleResult(expectedResult, summaryCrit); assertSingleResult(expectedResult, descriptionCrit); assertSingleResult(expectedResult, statusCrit); assertSingleResult(expectedResult, priorityCrit); assertSingleResult(expectedResult, severityCrit); assertSingleResult(expectedResult, resolutionCrit); assertSingleResult(expectedResult, milestoneCrit); assertSingleResult(expectedResult, productCrit); assertSingleResult(expectedResult, componentCrit); assertSingleResult(expectedResult, andCrit); assertSingleResult(expectedResult, orCrit); Criteria neverMatchCrit = new ColumnCriteria(TaskFieldConstants.PRIORITY_FIELD, "NOSUCHPRIOIRITY"); NaryCriteria neverMatchAnd = new NaryCriteria(Operator.AND, priorityCrit, statusCrit, severityCrit, resolutionCrit, milestoneCrit, productCrit, componentCrit, neverMatchCrit); assertNoResults(neverMatchAnd); NaryCriteria stillMatchOr = new NaryCriteria(Operator.OR, priorityCrit, statusCrit, severityCrit, resolutionCrit, milestoneCrit, productCrit, componentCrit, neverMatchCrit); assertSingleResult(expectedResult, stillMatchOr); } private void assertSingleResult(com.tasktop.c2c.server.tasks.domain.Task expectedResult, Criteria crit) { QueryResult<com.tasktop.c2c.server.tasks.domain.Task> queryResult = taskService.findTasksWithCriteria(crit, null); assertNotNull(queryResult); assertEquals((Integer) 1, queryResult.getTotalResultSize()); assertEquals(1, queryResult.getResultPage().size()); assertEquals(expectedResult, queryResult.getResultPage().get(0)); } private void assertNoResults(Criteria crit) { assertResultCount(crit, 0); } private void assertResultCount(Criteria crit, int count) { QueryResult<com.tasktop.c2c.server.tasks.domain.Task> queryResult; queryResult = taskService.findTasksWithCriteria(crit, null); assertNotNull(queryResult); assertEquals("Expected exactly " + count + " results", (Integer) count, queryResult.getTotalResultSize()); assertEquals("Expected exactly " + count + " results", count, queryResult.getResultPage().size()); } @Test public void testFindTasksByWatcherMultiple() throws Exception { // 709: can't search for multiple people at once // search with two watchers removeTasks(); Product product = MockProductFactory.create(entityManager); Profile profile = MockProfileFactory.create(entityManager); Profile profile1 = MockProfileFactory.create(entityManager); Profile profile2 = MockProfileFactory.create(entityManager); Task internalTask = MockTaskFactory.create(entityManager, product, profile); entityManager.flush(); entityManager.persist(internalTask.addCc(profile1)); entityManager.persist(internalTask.addCc(profile2)); entityManager.flush(); ColumnCriteria criteria1 = new ColumnCriteria(TaskFieldConstants.WATCHER_FIELD, Criteria.Operator.STRING_CONTAINS, profile1.getLoginName()); ColumnCriteria criteria2 = new ColumnCriteria(TaskFieldConstants.WATCHER_FIELD, Criteria.Operator.STRING_CONTAINS, profile2.getLoginName()); Criteria criteria = new NaryCriteria(Operator.OR, criteria1, criteria2); assertResultCount(criteria, 1); assertNoResults(new NaryCriteria(Operator.NOT, criteria)); } @Test public void testCriteriaQueryWithAssigneeReporterAndWatcher() throws Exception { removeTasks(); com.tasktop.c2c.server.tasks.domain.Task expectedResult = getMockTask(); ColumnCriteria exactAssigneeCrit = new ColumnCriteria(TaskFieldConstants.ASSIGNEE_FIELD, getMockTask().getAssignee().getLoginName()); ColumnCriteria approxAssigneeCrit = new ColumnCriteria(TaskFieldConstants.ASSIGNEE_FIELD, Criteria.Operator.STRING_CONTAINS, getMockTask().getAssignee().getLoginName().substring(2, 5)); ColumnCriteria exactReporterCrit = new ColumnCriteria(TaskFieldConstants.REPORTER_FIELD, currentUser.getLoginName()); ColumnCriteria approxReporterCrit = new ColumnCriteria(TaskFieldConstants.REPORTER_FIELD, Criteria.Operator.STRING_CONTAINS, currentUser.getLoginName().substring(2, 5)); ColumnCriteria exactWatcherCrit = new ColumnCriteria(TaskFieldConstants.WATCHER_FIELD, getMockTask().getAssignee().getLoginName()); ColumnCriteria approxWatcherCrit = new ColumnCriteria(TaskFieldConstants.WATCHER_FIELD, Criteria.Operator.STRING_CONTAINS, getMockTask().getAssignee().getLoginName().substring(2, 5)); assertNoResults(exactAssigneeCrit); assertNoResults(approxAssigneeCrit); assertNoResults(exactReporterCrit); assertNoResults(approxReporterCrit); assertNoResults(exactWatcherCrit); assertNoResults(approxWatcherCrit); expectedResult.setWatchers(Arrays.asList(expectedResult.getAssignee())); expectedResult = taskService.createTask(expectedResult); assertSingleResult(expectedResult, exactAssigneeCrit); assertSingleResult(expectedResult, approxAssigneeCrit); assertSingleResult(expectedResult, exactReporterCrit); assertSingleResult(expectedResult, approxReporterCrit); assertSingleResult(expectedResult, exactWatcherCrit); assertSingleResult(expectedResult, approxWatcherCrit); } // Think this is the shape the connector will generate. @Test public void testOrOfAndCriteria() throws Exception { RepositoryConfiguration repo = getRepositoryConfiguration(); Criteria statusCriteria = new NaryCriteria(Operator.OR, new ColumnCriteria(TaskFieldConstants.STATUS_FIELD, repo.getStatuses().get(0).getValue()), new ColumnCriteria(TaskFieldConstants.STATUS_FIELD, repo.getStatuses().get(0).getValue())); Criteria severityCriteria = new NaryCriteria(Operator.OR, new ColumnCriteria(TaskFieldConstants.SEVERITY_FIELD, repo.getSeverities().get(0).getValue()), new ColumnCriteria(TaskFieldConstants.SEVERITY_FIELD, repo.getSeverities().get(0).getValue())); Criteria bigAnd = new NaryCriteria(Operator.AND, statusCriteria, severityCriteria); assertNoResults(bigAnd); } @Test public void testGetRecentActivity() throws Exception { com.tasktop.c2c.server.tasks.domain.Task toCreate = getMockTask(); com.tasktop.c2c.server.tasks.domain.Task created = taskService.createTask(toCreate); List<TaskActivity> activity = taskService.getRecentActivity(new Region(0, 10)); int activityCount = 1; assertActivityForTask(activity, created, activityCount); // Update com.tasktop.c2c.server.tasks.domain.Task toUpdate = created; toUpdate.setShortDescription("New short description"); taskService.updateTask(toUpdate); activity = taskService.getRecentActivity(new Region(0, 10)); activityCount += 1; assertActivityForTask(activity, created, 2); } private void assertActivityForTask(List<TaskActivity> activity, com.tasktop.c2c.server.tasks.domain.Task task, int count) { int actual = 0; for (TaskActivity a : activity) { if (a.getTask().equals(task)) { ++actual; } } assertEquals(count, actual); } @Test public void testGetActivitySinceDate() throws Exception { List<TaskActivity> activity = taskService.getRecentActivity(null); // Constructing this value is very complex, so to start with we just let the service method do it since it would // be a series of complicated EntityManager queries to get the right number. Thread.sleep(1200L); final Date referenceDate = new Date(); Thread.sleep(1200L); com.tasktop.c2c.server.tasks.domain.Task toCreate = getMockTask(); com.tasktop.c2c.server.tasks.domain.Task created = taskService.createTask(toCreate); int newActivityCount = 1; // Update com.tasktop.c2c.server.tasks.domain.Task toUpdate = created; toUpdate.setShortDescription("New short description"); taskService.updateTask(toUpdate); newActivityCount += 1; List<TaskActivity> activitySinceDate = taskService.listActivity(referenceDate); assertEquals(newActivityCount, activitySinceDate.size()); for (TaskActivity a : activitySinceDate) { assertTrue(a.getActivityDate().compareTo(referenceDate) >= 0); } activity = taskService.getRecentActivity(null); assertActivityForTask(activity, created, newActivityCount); } @Test public void testGetTaskActivity() throws Exception { com.tasktop.c2c.server.tasks.domain.Task toCreate = getMockTask(); com.tasktop.c2c.server.tasks.domain.Task created = taskService.createTask(toCreate); com.tasktop.c2c.server.tasks.domain.Task toUpdate = created; toUpdate.setShortDescription("New short description"); toUpdate.setDeadline(new Date(System.currentTimeMillis() + (1000L * 60L * 60L * 24L * 10L))); taskService.updateTask(toUpdate); List<TaskActivity> taskActivity = taskService.listTaskActivity(created.getId()); assertEquals(2, taskActivity.size()); TaskActivity createdActivity = taskActivity.get(1); assertEquals(TaskActivity.Type.CREATED, createdActivity.getActivityType()); assertNotNull(createdActivity.getAuthor()); assertNotNull(createdActivity.getTask()); assertEquals(created.getId(), createdActivity.getTask().getId()); assertEquals(toUpdate.getShortDescription(), createdActivity.getTask().getShortDescription()); TaskActivity updatedActivity = taskActivity.get(0); assertEquals(TaskActivity.Type.UPDATED, updatedActivity.getActivityType()); assertNotNull(createdActivity.getAuthor()); assertEquals(2, updatedActivity.getFieldUpdates().size()); Map<String, FieldUpdate> updateByFieldName = new HashMap<String, TaskActivity.FieldUpdate>(); for (FieldUpdate fieldUpdate : updatedActivity.getFieldUpdates()) { updateByFieldName.put(fieldUpdate.getFieldName(), fieldUpdate); } assertContainsKey(updateByFieldName, "deadline"); assertContainsKey(updateByFieldName, "short_desc"); } private void assertContainsKey(Map<?, ?> map, Object key) { if (!map.containsKey(key)) { fail("Expected to find key " + key + " in map keys " + map.keySet()); } } @Test public void testGetTaskActivity_CustomFields() throws ValidationException, EntityNotFoundException, ConcurrentUpdateException { FieldDescriptor descriptor = new FieldDescriptor(); descriptor.setAvailableForNewTasks(true); descriptor.setDescription("TestA"); descriptor.setFieldType(FieldType.SINGLE_SELECT); descriptor.setName("testA" + System.currentTimeMillis()); descriptor.setValueStrings(Arrays.asList("one", "two", "three")); createdFields.add(descriptor); customFieldService.createCustomField(descriptor); com.tasktop.c2c.server.tasks.domain.Task toCreate = getMockTask(); com.tasktop.c2c.server.tasks.domain.Task created = taskService.createTask(toCreate); assertNotNull(created.getCustomFields()); assertTrue(!created.getCustomFields().isEmpty()); assertEquals("---", created.getCustomFields().get(descriptor.getName())); created.getCustomFields().put(descriptor.getName(), "one"); com.tasktop.c2c.server.tasks.domain.Task updated = taskService.updateTask(created); assertNotNull(updated.getCustomFields()); assertEquals("one", updated.getCustomFields().get(descriptor.getName())); List<TaskActivity> taskActivity = taskService.listTaskActivity(created.getId()); assertEquals(2, taskActivity.size()); TaskActivity createdActivity = taskActivity.get(1); assertEquals(TaskActivity.Type.CREATED, createdActivity.getActivityType()); assertNotNull(createdActivity.getAuthor()); TaskActivity updatedActivity = taskActivity.get(0); assertEquals(TaskActivity.Type.UPDATED, updatedActivity.getActivityType()); assertEquals(1, updatedActivity.getFieldUpdates().size()); FieldUpdate fieldUpdate = updatedActivity.getFieldUpdates().get(0); assertEquals(descriptor.getName(), fieldUpdate.getFieldName()); assertEquals("one", fieldUpdate.getNewValue()); assertEquals("---", fieldUpdate.getOldValue()); } @Test public void testGetProductActivity() throws Exception { com.tasktop.c2c.server.tasks.domain.Task task = taskService.createTask(getMockTask()); // Update task.setProduct(getCreatedMockDomainProduct()); task.setComponent(getMockComponent()); task = taskService.updateTask(task); List<TaskActivity> updates = getUpdates(taskService.getRecentActivity(null)); assertEquals(1, updates.size()); assertEquals(2, updates.get(0).getFieldUpdates().size()); } @Test public void testGetDepActivity() throws Exception { com.tasktop.c2c.server.tasks.domain.Task task = taskService.createTask(getMockTask()); com.tasktop.c2c.server.tasks.domain.Task parent = taskService.createTask(getMockTask()); // Update task.setParentTask(parent); task = taskService.updateTask(task); List<TaskActivity> updates = getUpdates(taskService.getRecentActivity(null)); assertEquals(1, updates.size()); assertEquals(1, updates.get(0).getFieldUpdates().size()); assertEquals("dependson", updates.get(0).getFieldUpdates().get(0).getFieldName()); assertEquals("" + parent.getId(), updates.get(0).getFieldUpdates().get(0).getNewValue()); assertEquals("", updates.get(0).getFieldUpdates().get(0).getOldValue()); Thread.sleep(MINIMUM_DATE_RESOLUTION); task.setParentTask(null); task = taskService.updateTask(task); updates = getUpdates(taskService.getRecentActivity(null)); assertEquals(2, updates.size()); assertEquals(1, updates.get(1).getFieldUpdates().size()); assertEquals("dependson", updates.get(1).getFieldUpdates().get(0).getFieldName()); assertEquals("" + parent.getId(), updates.get(0).getFieldUpdates().get(0).getOldValue()); assertEquals("", updates.get(0).getFieldUpdates().get(0).getNewValue()); } @Test public void testGetBlocksActivity() throws Exception { com.tasktop.c2c.server.tasks.domain.Task task = taskService.createTask(getMockTask()); com.tasktop.c2c.server.tasks.domain.Task subTask = taskService.createTask(getMockTask()); // Update task.setSubTasks(Arrays.asList(subTask)); task = taskService.updateTask(task); List<TaskActivity> updates = getUpdates(taskService.getRecentActivity(null)); assertEquals(1, updates.size()); assertEquals(1, updates.get(0).getFieldUpdates().size()); assertEquals("blocked", updates.get(0).getFieldUpdates().get(0).getFieldName()); assertEquals("" + subTask.getId(), updates.get(0).getFieldUpdates().get(0).getNewValue()); assertEquals("", updates.get(0).getFieldUpdates().get(0).getOldValue()); Thread.sleep(MINIMUM_DATE_RESOLUTION); task.setSubTasks(null); task = taskService.updateTask(task); updates = getUpdates(taskService.getRecentActivity(null)); assertEquals(2, updates.size()); assertEquals(1, updates.get(1).getFieldUpdates().size()); assertEquals("blocked", updates.get(1).getFieldUpdates().get(0).getFieldName()); assertEquals("" + subTask.getId(), updates.get(0).getFieldUpdates().get(0).getOldValue()); assertEquals("", updates.get(0).getFieldUpdates().get(0).getNewValue()); } private List<TaskActivity> getUpdates(List<TaskActivity> activity) { List<TaskActivity> result = new ArrayList<TaskActivity>(); for (TaskActivity a : activity) { if (a.getActivityType().equals(Type.UPDATED)) { result.add(a); } } return result; } // Task-897 @Test public void testUpdateWithCommentDateSet() throws ValidationException, EntityNotFoundException, ConcurrentUpdateException { com.tasktop.c2c.server.tasks.domain.Task task = getMockTask(); task.setDescription("Desc"); task = taskService.createTask(task); entityManager.flush(); Comment c = new Comment(); c.setCommentText("Comment"); c.setCreationDate(new Date(task.getCreationDate().getTime() - 20000l)); task.setComments(Arrays.asList(c)); task = taskService.updateTask(task); Assert.assertEquals("Desc", task.getDescription()); Assert.assertEquals("Comment", task.getComments().get(0).getCommentText()); Assert.assertFalse(task.getCreationDate().after(task.getComments().get(0).getCreationDate())); } @Test public void testCreateProduct() throws Exception { com.tasktop.c2c.server.tasks.domain.Product p = new com.tasktop.c2c.server.tasks.domain.Product(); p.setName("Product"); p.setDescription("Description"); com.tasktop.c2c.server.tasks.domain.Product createdProduct = taskService.createProduct(p); assertNotNull(createdProduct.getId()); assertEquals(p.getName(), createdProduct.getName()); assertEquals(p.getDescription(), createdProduct.getDescription()); assertEquals(true, createdProduct.getIsActive()); assertEquals(Collections.EMPTY_LIST, createdProduct.getComponents()); assertNotNull(createdProduct.getMilestones()); assertEquals(1, createdProduct.getMilestones().size()); assertEquals("---", createdProduct.getDefaultMilestone().getValue()); } @Test public void testRetrieveProduct() throws Exception { Product mockProduct = MockProductFactory.create(entityManager); entityManager.flush(); entityManager.refresh(mockProduct); com.tasktop.c2c.server.tasks.domain.Product product = taskService .retrieveProduct(mockProduct.getId().intValue()); assertEquals(mockProduct.getId().intValue(), product.getId().intValue()); assertEquals(mockProduct.getName(), product.getName()); } @Test public void testRetrieveAllProducts() { int initialNumProducts = count(Product.class); int numProducts = 5; MockProductFactory.create(entityManager, numProducts); entityManager.flush(); List<com.tasktop.c2c.server.tasks.domain.Product> productsAfter = taskService.listAllProducts(); assertEquals(initialNumProducts + numProducts, productsAfter.size()); } @Test public void testUpdateProduct() throws Exception { Product mockProduct = MockProductFactory.create(entityManager); entityManager.flush(); entityManager.refresh(mockProduct); com.tasktop.c2c.server.tasks.domain.Product product = taskService .retrieveProduct(mockProduct.getId().intValue()); product.setName(RandomStringUtils.randomAlphanumeric(24)); product.setDescription(RandomStringUtils.randomAlphanumeric(1024)); product.setIsActive(false); com.tasktop.c2c.server.tasks.domain.Product updatedProduct = taskService.updateProduct(product); assertEquals(product.getName(), updatedProduct.getName()); assertEquals(updatedProduct.getDescription(), product.getDescription()); assertEquals(updatedProduct.getIsActive(), product.getIsActive()); assertEquals(updatedProduct.getDefaultMilestone(), product.getDefaultMilestone()); } // Test case for task 976 @Test(expected = ConcurrentUpdateException.class) public void testDependencyUpdateConflict() throws Exception { com.tasktop.c2c.server.tasks.domain.Task parent = taskService.createTask(getMockTask("parent")); com.tasktop.c2c.server.tasks.domain.Task child = taskService.createTask(getMockTask("child")); // We have a forced granularity of 1 second on our timestamp optimistic locking, due to existing schema // limitations - as a result, we need to inject a delay slightly greater than 1s to ensure that our update is // correctly detected. Thread.sleep(1001); parent.setSubTasks(Arrays.asList(child)); taskService.updateTask(parent); child.setDescription("All I changed is description"); child = taskService.updateTask(child); Assert.assertTrue("Mid-air collision resulted in overwriting of data.", child.getParentTask() != null); } // Test case for task 976 @Test(expected = ConcurrentUpdateException.class) public void testWithDependencyUpdateConflictFromCreate() throws Exception { com.tasktop.c2c.server.tasks.domain.Task child = taskService.createTask(getMockTask("child")); com.tasktop.c2c.server.tasks.domain.Task parent = getMockTask("parent"); parent.setSubTasks(Arrays.asList(child)); // We have a forced granularity of 1 second on our timestamp optimistic locking, due to existing schema // limitations - as a result, we need to inject a delay slightly greater than 1s to ensure that our update is // correctly detected. Thread.sleep(1001); taskService.createTask(parent); child.setDescription("All I changed is description"); child = taskService.updateTask(child); Assert.assertTrue("Mid-air collision resulted in overwriting of data.", child.getParentTask() != null); } @Test public void testCreateComponentWithInitialOwner() throws Exception { com.tasktop.c2c.server.tasks.domain.Component testComponent = new com.tasktop.c2c.server.tasks.domain.Component(); testComponent.setName(RandomStringUtils.randomAlphanumeric(24)); testComponent.setDescription(RandomStringUtils.randomAlphanumeric(1024)); testComponent.setInitialOwner(getCreatedMockTaskUserProfile()); testComponent.setProduct(getCreatedMockDomainProduct()); com.tasktop.c2c.server.tasks.domain.Component createdComponent = taskService.createComponent(testComponent); assertNotNull(createdComponent.getId()); assertEquals(testComponent.getName(), createdComponent.getName()); assertEquals(testComponent.getDescription(), createdComponent.getDescription()); assertEquals(testComponent.getInitialOwner().getId(), createdComponent.getInitialOwner().getId()); assertEquals(testComponent.getProduct().getId(), createdComponent.getProduct().getId()); } /** * Should successfully create a component with no intitial owner (task 1727) */ @Test public void testCreateComponentNoInitialOwner() throws Throwable { com.tasktop.c2c.server.tasks.domain.Component testComponent = new com.tasktop.c2c.server.tasks.domain.Component(); testComponent.setName(RandomStringUtils.randomAlphanumeric(24)); testComponent.setDescription(RandomStringUtils.randomAlphanumeric(1024)); testComponent.setProduct(getCreatedMockDomainProduct()); com.tasktop.c2c.server.tasks.domain.Component createComponent = taskService.createComponent(testComponent); assertNull(createComponent.getInitialOwner()); } private Product getCreatedMockProduct() { Product p = MockProductFactory.create(entityManager); entityManager.flush(); assertNotNull(p.getId()); return p; } private com.tasktop.c2c.server.tasks.domain.Product getCreatedMockDomainProduct() { com.tasktop.c2c.server.tasks.domain.Product retProd = new com.tasktop.c2c.server.tasks.domain.Product(); // Perform our conversion now. productConverter.copy(retProd, getCreatedMockProduct(), domainConverter, new DomainConversionContext(entityManager, taskDomain)); return retProd; } @Test public void testRetrieveComponent() throws Exception { Component mockComponent = MockComponentFactory.create(entityManager); entityManager.flush(); entityManager.refresh(mockComponent); com.tasktop.c2c.server.tasks.domain.Component domainComponent = taskService .retrieveComponent(Integer.valueOf(mockComponent.getId())); assertEquals(mockComponent.getId().intValue(), domainComponent.getId().intValue()); assertEquals(mockComponent.getName(), domainComponent.getName()); } @Test(expected = EntityNotFoundException.class) public void testRetrieveComponentForBadID() throws Throwable { try { // This should blow up, since the ID of a Component is a short - an // ID // of Integer.MAX_VALUE will be impossible in the database. assertNotNull(taskService.retrieveComponent(new Integer(Integer.MAX_VALUE))); } catch (WrappedCheckedException wce) { // If this was wrapped due to the REST interface, throw the original // exception throw wce.getCause(); } } @Test(expected = IllegalArgumentException.class) public void testRetrieveComponentForNullID() throws Exception { // This should blow up assertNotNull(taskService.retrieveComponent(null)); } @Test public void testRetrieveAllComponents() { // First, figure out our initial number of components before this test. int origNumComponents = count(Component.class); int numComponentsToCreate = 5; MockComponentFactory.create(entityManager, numComponentsToCreate); entityManager.flush(); List<com.tasktop.c2c.server.tasks.domain.Component> componentsAfter = taskService.listAllComponents(); assertEquals(origNumComponents + numComponentsToCreate, componentsAfter.size()); } @Test public void testUpdateComponent() throws Exception { // Save a random component before we start our test. Component mockComponent = MockComponentFactory.create(entityManager); entityManager.flush(); // Grab our domain object through the task service. com.tasktop.c2c.server.tasks.domain.Component origComponent = taskService .retrieveComponent(Integer.valueOf(mockComponent.getId())); // Sanity check, to make sure we had a component to start with. assertNotNull(origComponent); // Perform a couple of updates, and push them to the Task Service origComponent.setName(RandomStringUtils.randomAlphanumeric(24)); origComponent.setDescription(RandomStringUtils.randomAlphanumeric(1024)); com.tasktop.c2c.server.tasks.domain.Component updatedComponent = taskService.updateComponent(origComponent); assertEquals(origComponent.getName(), updatedComponent.getName()); assertEquals(updatedComponent.getDescription(), origComponent.getDescription()); } @Test(expected = ValidationException.class) public void testUpdateComponentNoName() throws Throwable { // Save a random component before we start our test. Component mockComponent = MockComponentFactory.create(entityManager); entityManager.flush(); // Grab our domain object through the task service. com.tasktop.c2c.server.tasks.domain.Component origComponent = taskService .retrieveComponent(Integer.valueOf(mockComponent.getId())); // Sanity check, to make sure we had a component to start with. assertNotNull(origComponent); // Perform a couple of updates, and push them to the Task Service origComponent.setName(null); origComponent.setDescription(RandomStringUtils.randomAlphanumeric(1024)); // This should blow up. taskService.updateComponent(origComponent); } @Test public void testUpdateProductTree_ValidationErrors() throws Exception { Product mockProduct = MockProductFactory.create(entityManager); entityManager.flush(); entityManager.refresh(mockProduct); com.tasktop.c2c.server.tasks.domain.Product product = taskService .retrieveProduct(mockProduct.getId().intValue()); product.setName(RandomStringUtils.randomAlphanumeric(24)); product.setDescription(RandomStringUtils.randomAlphanumeric(1024)); product.setIsActive(false); // Now, make some invalid data. product.setName(null); for (com.tasktop.c2c.server.tasks.domain.Component curComponent : product.getComponents()) { curComponent.setName(null); } try { // This should blow up with an exception. taskService.updateProductTree(product); } catch (ValidationException ve) { // We should have an error for every product, and 2 for every component assertEquals(1 + product.getComponents().size(), ve.getMessages().size()); } } @Test public void testUpdateProductTree() throws Exception { Product mockProduct = MockProductFactory.create(entityManager); entityManager.flush(); entityManager.refresh(mockProduct); com.tasktop.c2c.server.tasks.domain.Product product = taskService .retrieveProduct(mockProduct.getId().intValue()); String appender = RandomStringUtils.randomAlphanumeric(12); product.setName(RandomStringUtils.randomAlphanumeric(24)); product.setDescription(RandomStringUtils.randomAlphanumeric(1024)); product.setIsActive(false); for (com.tasktop.c2c.server.tasks.domain.Component curComponent : product.getComponents()) { curComponent.setName(curComponent.getName() + appender); } com.tasktop.c2c.server.tasks.domain.Product updatedProduct = taskService.updateProductTree(product); assertEquals(product.getName(), updatedProduct.getName()); assertEquals(updatedProduct.getDescription(), product.getDescription()); assertEquals(updatedProduct.getIsActive(), product.getIsActive()); assertEquals(updatedProduct.getDefaultMilestone(), product.getDefaultMilestone()); for (com.tasktop.c2c.server.tasks.domain.Component curComponent : product.getComponents()) { assertTrue(curComponent.getName().endsWith(appender)); } } @Ignore @Test public void testUpdateProductTree_task2891() throws Exception { Product mockProduct = MockProductFactory.create(entityManager); entityManager.flush(); entityManager.refresh(mockProduct); com.tasktop.c2c.server.tasks.domain.Product product = taskService .retrieveProduct(mockProduct.getId().intValue()); product.setName(RandomStringUtils.randomAlphanumeric(24)); product.setDescription(RandomStringUtils.randomAlphanumeric(1024)); product.setIsActive(false); String lastComponentName = null; for (com.tasktop.c2c.server.tasks.domain.Component curComponent : product.getComponents()) { String thisName = curComponent.getName(); if (lastComponentName != null) { curComponent.setName(lastComponentName); } lastComponentName = thisName; } product.getComponents().get(0).setName(lastComponentName); com.tasktop.c2c.server.tasks.domain.Product updatedProduct = taskService.updateProductTree(product); Assert.assertEquals(lastComponentName, updatedProduct.getComponents().get(0).getName()); } @Test public void testUpdateMilestoneNameUpdatesAssosiatedTasks_task2434() throws Exception { Product mockProduct = MockProductFactory.create(entityManager); entityManager.flush(); entityManager.refresh(mockProduct); com.tasktop.c2c.server.tasks.domain.Product product = taskService .retrieveProduct(mockProduct.getId().intValue()); com.tasktop.c2c.server.tasks.domain.Milestone newMileStone = new com.tasktop.c2c.server.tasks.domain.Milestone(); String origMilestoneName = "origMilestone"; newMileStone.setValue(origMilestoneName); newMileStone.setSortkey((short) 2); product.getMilestones().add(newMileStone); product = taskService.updateProductTree(product); assertEquals(2, product.getMilestones().size()); assertEquals(origMilestoneName, product.getMilestones().get(1).getValue()); com.tasktop.c2c.server.tasks.domain.Task newTask = getMockTask(); newTask.setProduct(product); newTask.setComponent(product.getComponents().get(0)); newTask.setMilestone(product.getMilestones().get(1)); newTask = taskService.createTask(newTask); assertNotNull(newTask.getMilestone()); assertEquals(origMilestoneName, newTask.getMilestone().getValue()); String newMilestoneName = "newMilestone"; product.getMilestones().get(1).setValue(newMilestoneName); product = taskService.updateProductTree(product); assertEquals(2, product.getMilestones().size()); assertEquals(newMilestoneName, product.getMilestones().get(1).getValue()); newTask = taskService.retrieveTask(newTask.getId()); assertNotNull(newTask.getMilestone()); assertEquals(newMilestoneName, newTask.getMilestone().getValue()); } @Test public void testDeleteMilestone() throws Exception { // First, create a product tree and a few milestones. int numMilestones = 10; Product mockProduct = MockProductFactory.create(entityManager); MockMilestoneFactory.createWithProduct(entityManager, numMilestones, mockProduct); entityManager.flush(); entityManager.refresh(mockProduct); // Confirm that we have the number of milestones that we expect, to start from a known point. assertEquals(numMilestones + 1, mockProduct.getMilestones().size()); // Now, iterate through each of the non-default ones and delete them - these should all succeed. for (Milestone curMilestone : mockProduct.getMilestones()) { if (mockProduct.getDefaultmilestone().equals(curMilestone.getValue())) { // If this is our default milestone, skip it. continue; } taskService.deleteMilestone(curMilestone.getId()); } // Refresh our product now. entityManager.refresh(mockProduct); // Now, make sure that we only have 1 milestone left, and that it's our default. assertEquals(1, mockProduct.getMilestones().size()); assertEquals(mockProduct.getDefaultmilestone(), mockProduct.getMilestones().get(0).getValue()); } @Test(expected = ValidationException.class) public void testDeleteDefaultMilestone() throws Exception { // First, create a product tree - this will also create a default milestone. Product mockProduct = MockProductFactory.create(entityManager); entityManager.flush(); entityManager.refresh(mockProduct); // Confirm that we have the number of milestones that we expect, to start from a known point - also make sure // that our one milestone is our default. assertEquals(1, mockProduct.getMilestones().size()); assertEquals(mockProduct.getDefaultmilestone(), mockProduct.getMilestones().get(0).getValue()); // Now, try to delete that milestone - this should blow up. taskService.deleteMilestone(mockProduct.getMilestones().get(0).getId()); } @Test(expected = ValidationException.class) public void testDeleteMilestoneWithTask() throws Exception { // First, create a product tree and a non-default milestone. Product mockProduct = MockProductFactory.create(entityManager); MockMilestoneFactory.createWithProduct(entityManager, 1, mockProduct); entityManager.flush(); entityManager.refresh(mockProduct); // Confirm that we have the number of milestones that we expect, to start from a known point - also make sure // that our one milestone is our default. assertEquals(2, mockProduct.getMilestones().size()); Milestone targetMilestone = null; for (Milestone curMilestone : mockProduct.getMilestones()) { if (!mockProduct.getDefaultmilestone().equals(curMilestone.getValue())) { // If this is our default milestone, skip it. targetMilestone = curMilestone; } } assertNotNull(targetMilestone); assertFalse(targetMilestone.getValue().equals(mockProduct.getDefaultmilestone())); // Create a new task, and make sure it's got that milestone. Profile newUser = MockProfileFactory.create(entityManager); Task curTask = MockTaskFactory.create(entityManager, mockProduct, newUser); curTask.setTargetMilestone(targetMilestone.getValue()); entityManager.flush(); // Now, try to delete that milestone - this should blow up. taskService.deleteMilestone(targetMilestone.getId()); } @Test public void testDeleteComponent() throws Exception { // First, create a product tree Product mockProduct = MockProductFactory.create(entityManager); entityManager.flush(); entityManager.refresh(mockProduct); // Confirm that we have at least one component, so we're starting from a known good point. assertTrue(mockProduct.getComponents().size() > 0); // Now, iterate through each of the components and delete them - these should all succeed. for (Component curMilestone : mockProduct.getComponents()) { taskService.deleteComponent(curMilestone.getId().intValue()); } // Refresh our product now. entityManager.refresh(mockProduct); // Now, make sure that we have no components left. assertEquals(0, mockProduct.getComponents().size()); } @Test(expected = ValidationException.class) public void testDeleteComponentWithTask() throws Exception { // First, create a product tree Product mockProduct = MockProductFactory.create(entityManager); entityManager.flush(); entityManager.refresh(mockProduct); // Confirm that we have at least one component, so we're starting from a known good point. assertTrue(mockProduct.getComponents().size() > 0); // Grab one of our components - any one will do. Component targetComponent = mockProduct.getComponents().iterator().next(); assertNotNull(targetComponent); // Create a new task, and make sure it's got that milestone. Profile newUser = MockProfileFactory.create(entityManager); Task curTask = MockTaskFactory.create(entityManager, mockProduct, newUser); curTask.setComponent(targetComponent); entityManager.flush(); // Now, try to delete that milestone - this should blow up. taskService.deleteComponent(targetComponent.getId().intValue()); } @Test(expected = EntityNotFoundException.class) public void testDeleteProduct() throws Exception { // First, create a product tree Product mockProduct = MockProductFactory.create(entityManager); entityManager.flush(); entityManager.refresh(mockProduct); // Now, delete it. taskService.deleteProduct(mockProduct.getId().intValue()); // Confirm that it's gone - this will blow up. taskService.retrieveProduct(mockProduct.getId().intValue()); } @Test(expected = ValidationException.class) public void testDeleteProductWithTask() throws Exception { // First, create a product tree Product mockProduct = MockProductFactory.create(entityManager); entityManager.flush(); entityManager.refresh(mockProduct); // Create a new task, and make sure it's got that milestone. Profile newUser = MockProfileFactory.create(entityManager); Task curTask = MockTaskFactory.create(entityManager, mockProduct, newUser); curTask.setProduct(mockProduct); entityManager.flush(); // Now, try to delete that milestone - this should blow up. taskService.deleteProduct(mockProduct.getId().intValue()); } @Test public void testHistoricalSummary() { removeTasks(); int numDays = 5; int tasksPerDay = 2; int daysOpen = 10; long millisPerDay = 1000 * 60 * 60 * 24; long now = System.currentTimeMillis(); long startDay = now - (millisPerDay * (numDays - 1)); for (int day = 0; day < numDays; day++) { for (int task = 0; task < tasksPerDay; task++) { Task t = MockTaskFactory.create(null, getCreatedMockProduct(), getCreatedMockProfile()); long openTime = startDay + day * millisPerDay; t.setCreationTs(new Date(openTime)); long closeTime = openTime + daysOpen * millisPerDay; if (closeTime < now) { t.setDeltaTs(new Date(closeTime)); t.setStatus("RESOLVED"); } entityManager.persist(t); } } entityManager.flush(); List<TaskSummary> summaries = taskService.getHistoricalSummary(numDays); Assert.assertEquals(numDays, summaries.size()); Integer lastClosed = null; for (int i = 0; i < summaries.size(); i++) { TaskSummary summary = summaries.get(i); int open = 0; int closed = 0; for (TaskSummaryItem tsi : summary.getItems()) { open += tsi.getOpenCount(); closed += tsi.getClosedCount(); } if (i == 0) { Assert.assertEquals(0, closed); Assert.assertEquals(tasksPerDay, open); } else if (i == numDays - 1) { Assert.assertEquals(numDays * tasksPerDay, closed + open); } if (lastClosed != null) { Assert.assertTrue("closed should only grow", closed >= lastClosed); } lastClosed = closed; } } @Test public void replicateProfile() { Profile profile = MockProfileFactory.create(entityManager); TaskUserProfile user1 = new TaskUserProfile(); user1.setLoginName(profile.getLoginName()); user1.setRealname(profile.getRealname() + "changed"); taskService.replicateProfile(user1, ReplicationScope.CREATE_OR_UPDATE); assertUserExistsWithCurrentValues(user1); } @Test public void gravatarHash() throws EntityNotFoundException { Profile profile = MockProfileFactory.create(entityManager); String gravatarHash = UUID.randomUUID().toString().replace("-", ""); TaskUserProfile user1 = new TaskUserProfile(); user1.setLoginName(profile.getLoginName()); user1.setRealname(profile.getRealname() + "changed"); user1.setGravatarHash(gravatarHash); taskService.replicateProfile(user1, ReplicationScope.CREATE_OR_UPDATE); entityManager.flush(); Product product = MockProductFactory.create(entityManager); Task task = MockTaskFactory.create(entityManager, product, profile); entityManager.flush(); com.tasktop.c2c.server.tasks.domain.Task serviceTask = taskService.retrieveTask(task.getId()); assertEquals(gravatarHash, serviceTask.getReporter().getGravatarHash()); Criteria criteria = new ColumnCriteria(TaskFieldConstants.TASK_ID_FIELD, Operator.EQUALS, serviceTask.getId()); QueryResult<com.tasktop.c2c.server.tasks.domain.Task> results = taskService.findTasksWithCriteria(criteria, null); assertEquals(1, results.getResultPage().size()); assertEquals(gravatarHash, results.getResultPage().get(0).getReporter().getGravatarHash()); } protected void assertUserExistsWithCurrentValues(TaskUserProfile user1) { TypedQuery<Profile> query = entityManager .createQuery("select u from " + Profile.class.getSimpleName() + " u where u.loginName = :name", Profile.class) .setParameter("name", user1.getLoginName()); Profile result = query.getSingleResult(); assertEquals(user1.getLoginName(), result.getLoginName()); assertEquals(user1.getRealname(), result.getRealname()); } @Test public void createTask_NewKeyword() throws ValidationException, EntityNotFoundException { com.tasktop.c2c.server.tasks.domain.Task mockTask = getMockTask("description"); Keyword keyword = new Keyword("tag1", "desc1"); List<Keyword> keys = new ArrayList<Keyword>(); keys.add(keyword); mockTask.setKeywords(keys); com.tasktop.c2c.server.tasks.domain.Task createdTask = taskService.createTask(mockTask); assertEquals(mockTask.getKeywords().size(), createdTask.getKeywords().size()); } @Test public void updateTask_NewKeyword() throws ValidationException, EntityNotFoundException, ConcurrentUpdateException { com.tasktop.c2c.server.tasks.domain.Task mockTask = getMockTask("description"); Keyword keyword = new Keyword("tag1", "desc1"); List<Keyword> keys = new ArrayList<Keyword>(); keys.add(keyword); mockTask.setKeywords(keys); com.tasktop.c2c.server.tasks.domain.Task createdTask = taskService.createTask(mockTask); assertEquals(mockTask.getKeywords().size(), createdTask.getKeywords().size()); // add a second keyword and update Keyword keyword2 = new Keyword("tag2", "desc2"); createdTask.getKeywords().add(keyword2); com.tasktop.c2c.server.tasks.domain.Task updatedTask = taskService.updateTask(createdTask); assertEquals(createdTask.getKeywords().size(), updatedTask.getKeywords().size()); } @Test public void updateTask_RemoveKeyword() throws ValidationException, EntityNotFoundException, ConcurrentUpdateException { com.tasktop.c2c.server.tasks.domain.Task mockTask = getMockTask("description"); List<Keyword> keys = new ArrayList<Keyword>(); keys.add(new Keyword("tag1", "desc1")); Keyword keyword2 = new Keyword("tag2", "desc2"); keys.add(keyword2); mockTask.setKeywords(keys); com.tasktop.c2c.server.tasks.domain.Task createdTask = taskService.createTask(mockTask); assertEquals(createdTask.getKeywords().size(), createdTask.getKeywords().size()); for (Keyword kw : createdTask.getKeywords()) { assertTrue(createdTask.getKeywords().contains(kw)); } // add a second keyword and update createdTask.getKeywords().remove(keyword2); com.tasktop.c2c.server.tasks.domain.Task updatedTask = taskService.updateTask(createdTask); // order is unimportant assertEquals(createdTask.getKeywords().size(), updatedTask.getKeywords().size()); for (Keyword kw : createdTask.getKeywords()) { assertTrue(updatedTask.getKeywords().contains(kw)); } } private <T extends AbstractReferenceValue> T findByName(String name, Collection<T> values) { for (T val : values) { if (val.getValue().equals(name)) { return val; } } return null; } // Task 1975 @Test public void testResolveDuplicateAddsToCCOfDuplicatedTask() throws Exception { com.tasktop.c2c.server.tasks.domain.Task duplicate = taskService.createTask(getMockTask()); com.tasktop.c2c.server.tasks.domain.Task duplicateed = taskService.createTask(getMockTask()); Profile duplicatedOwner = getCreatedMockProfile(); duplicatedOwner.setLoginName("duplicatedOwner"); duplicate.setAssignee(ProfileConverter.copy(duplicatedOwner)); duplicate = taskService.updateTask(duplicate); duplicate.setStatus(findByName("RESOLVED", getRepositoryConfiguration().getStatuses())); duplicate.setResolution(findByName("DUPLICATE", getRepositoryConfiguration().getResolutions())); duplicate.setDuplicateOf(duplicateed); duplicate = taskService.updateTask(duplicate); duplicateed = taskService.retrieveTask(duplicateed.getId()); Assert.assertTrue("Duplicate assignee missing from watchers of duplicated", duplicateed.getWatchers().contains(duplicate.getAssignee())); } @Test public void createKeyword() throws ValidationException { Keyword newKeyword = new Keyword("name", "description"); Keyword createdKeyword = taskService.createKeyword(newKeyword); assertEquals(newKeyword.getName(), createdKeyword.getName()); assertEquals(newKeyword.getDescription(), createdKeyword.getDescription()); } @Test public void updateKeyword() throws ValidationException, EntityNotFoundException { Keyword newKeyword = new Keyword("name", "description"); Keyword createdKeyword = taskService.createKeyword(newKeyword); List<Keyword> allKeywords = taskService.getRepositoryContext().getKeywords(); boolean foundKeywordInRepository = false; for (Keyword keyword : allKeywords) { if (keyword.equals(createdKeyword)) foundKeywordInRepository = true; } assertTrue(foundKeywordInRepository); createdKeyword.setName("name2"); Keyword updateKeyword = taskService.updateKeyword(createdKeyword); assertTrue(updateKeyword.equals(createdKeyword)); } @Test public void deleteKeyword() throws ValidationException, EntityNotFoundException { Keyword newKeyword = new Keyword("name", "description"); Keyword createdKeyword = taskService.createKeyword(newKeyword); List<Keyword> allKeywords = taskService.getRepositoryContext().getKeywords(); int numKeywords = allKeywords.size(); taskService.deleteKeyword(createdKeyword.getId()); List<Keyword> afterKeywords = taskService.getRepositoryContext().getKeywords(); assertEquals(numKeywords - 1, afterKeywords.size()); } @Test public void testFoundInRelease() throws ValidationException, EntityNotFoundException, ConcurrentUpdateException { com.tasktop.c2c.server.tasks.domain.Task task = getMockTask(); String foundInRelease = "1.0.0#29"; task.setFoundInRelease(foundInRelease); task = taskService.createTask(task); RepositoryConfiguration repoCtx = taskService.getRepositoryContext(); com.tasktop.c2c.server.tasks.domain.Product updatedProduct = null; for (com.tasktop.c2c.server.tasks.domain.Product p : repoCtx.getProducts()) { if (p.equals(task.getProduct())) { updatedProduct = p; break; } } Assert.assertEquals(1, updatedProduct.getReleaseTags().size()); Assert.assertEquals(foundInRelease, updatedProduct.getReleaseTags().get(0)); task.setFoundInRelease(null); task = taskService.updateTask(task); repoCtx = taskService.getRepositoryContext(); updatedProduct = null; for (com.tasktop.c2c.server.tasks.domain.Product p : repoCtx.getProducts()) { if (p.equals(task.getProduct())) { updatedProduct = p; break; } } Assert.assertEquals(1, updatedProduct.getReleaseTags().size()); Assert.assertEquals(foundInRelease, updatedProduct.getReleaseTags().get(0)); String foundInRelease2 = "1.0.0#30"; task.setFoundInRelease(foundInRelease2); task = taskService.updateTask(task); repoCtx = taskService.getRepositoryContext(); updatedProduct = null; for (com.tasktop.c2c.server.tasks.domain.Product p : repoCtx.getProducts()) { if (p.equals(task.getProduct())) { updatedProduct = p; break; } } Assert.assertEquals(2, updatedProduct.getReleaseTags().size()); Assert.assertEquals(foundInRelease2, updatedProduct.getReleaseTags().get(1)); task.setFoundInRelease(foundInRelease2); task = taskService.updateTask(task); repoCtx = taskService.getRepositoryContext(); updatedProduct = null; for (com.tasktop.c2c.server.tasks.domain.Product p : repoCtx.getProducts()) { if (p.equals(task.getProduct())) { updatedProduct = p; break; } } Assert.assertEquals(2, updatedProduct.getReleaseTags().size()); Assert.assertEquals(foundInRelease2, updatedProduct.getReleaseTags().get(1)); } @Test public void saveQueryListCreateUpdate() throws ValidationException, EntityNotFoundException { Assert.assertEquals(0, taskService.getRepositoryContext().getSavedTaskQueries().size()); SavedTaskQuery query = new SavedTaskQuery(); query.setName("My New Query"); try { taskService.createQuery(query); Assert.fail("Expect validation exception"); } catch (ValidationException e) { ValidationAssert.assertHaveValidationError(e, "A query is required."); } query.setQueryString("DOES NOT PARSE"); try { taskService.createQuery(query); Assert.fail("Expect validation exception"); } catch (ValidationException e) { ValidationAssert.assertHaveValidationError(e, "Invalid query."); } query.setQueryString("status = 'NEW'"); query = taskService.createQuery(query); Assert.assertNotNull(query.getId()); Assert.assertEquals(1, taskService.getRepositoryContext().getSavedTaskQueries().size()); String newName = "NEWNAME"; query.setName(newName); query = taskService.updateQuery(query); Assert.assertEquals(newName, query.getName()); query.setName("Invalid@Name"); try { taskService.updateQuery(query); Assert.fail("Expect validation exception"); } catch (ValidationException e) { ValidationAssert.assertHaveValidationError(e, "Query name must not contain special characters."); } query = new SavedTaskQuery(); query.setName(newName); query.setQueryString("status = 'NEW'"); try { taskService.createQuery(query); Assert.fail("Expect validation exception"); } catch (ValidationException e) { ValidationAssert.assertHaveValidationError(e, "Name is in use, choose another name."); } } // task 2728 @Test public void testUpdateProductComponentActivity() throws Exception { com.tasktop.c2c.server.tasks.domain.Product p = new com.tasktop.c2c.server.tasks.domain.Product(); String newProductName = "newProduct"; p.setName(newProductName); p.setDescription("Description"); taskService.createProduct(p); com.tasktop.c2c.server.tasks.domain.Task toCreate = getMockTask(); com.tasktop.c2c.server.tasks.domain.Task created = taskService.createTask(toCreate); com.tasktop.c2c.server.tasks.domain.Product newProduct = getRepositoryConfiguration().getProducts().get(1); newProduct.setName(null); // This is how the web ui sends it. Fair enough... Assert.assertFalse(newProduct.equals(created.getProduct())); created.setProduct(newProduct); taskService.updateTask(created); List<TaskActivity> activity = taskService.listTaskActivity(created.getId()); Assert.assertEquals(2, activity.size()); Assert.assertEquals(TaskActivity.Type.CREATED, activity.get(1).getActivityType()); Assert.assertEquals(TaskActivity.Type.UPDATED, activity.get(0).getActivityType()); Assert.assertEquals(1, activity.get(0).getFieldUpdates().size()); Assert.assertEquals(newProductName, activity.get(0).getFieldUpdates().get(0).getNewValue()); } @Test public void createTask_taskRelation() throws Exception { com.tasktop.c2c.server.tasks.domain.Task mockTask = getMockTask(); ExternalTaskRelation relation = new ExternalTaskRelation("type", "kind", "http://example.com"); List<ExternalTaskRelation> relations = new ArrayList<ExternalTaskRelation>(); relations.add(relation); mockTask.setExternalTaskRelations(relations); com.tasktop.c2c.server.tasks.domain.Task createdTask = taskService.createTask(mockTask); assertEquals(mockTask.getExternalTaskRelations().size(), createdTask.getExternalTaskRelations().size()); assertEquals(mockTask.getExternalTaskRelations().get(0), createdTask.getExternalTaskRelations().get(0)); Integer taskId = createdTask.getId(); com.tasktop.c2c.server.tasks.domain.Task retrievedTask = taskService.retrieveTask(taskId); assertEquals(1, retrievedTask.getExternalTaskRelations().size()); } @Test public void updateTask_taskRelations() throws Exception { com.tasktop.c2c.server.tasks.domain.Task mockTask = getMockTask(); ExternalTaskRelation relation = new ExternalTaskRelation("type", "kind", "http://abc123.com/adfasdf#1231231"); List<ExternalTaskRelation> relations = new ArrayList<ExternalTaskRelation>(); relations.add(relation); mockTask.setExternalTaskRelations(relations); com.tasktop.c2c.server.tasks.domain.Task createdTask = taskService.createTask(mockTask); createdTask.getExternalTaskRelations() .add(new ExternalTaskRelation("type", "kind2", "http://example.com/otherURI")); com.tasktop.c2c.server.tasks.domain.Task updatedTask = taskService.updateTask(createdTask); assertEquals(2, updatedTask.getExternalTaskRelations().size()); updatedTask.setExternalTaskRelations(null); com.tasktop.c2c.server.tasks.domain.Task updatedTask2 = taskService.updateTask(updatedTask); assertEquals(0, updatedTask2.getExternalTaskRelations().size()); } @Test public void createTask_withWorkLog() throws Exception { com.tasktop.c2c.server.tasks.domain.Task mockTask = getMockTask(); WorkLog worklog = new WorkLog(); worklog.setProfile(ProfileConverter.copy(currentUser)); Date now = new Date(); worklog.setDateWorked(now); worklog.setHoursWorked(new BigDecimal(1.0)); mockTask.getWorkLogs().add(worklog); com.tasktop.c2c.server.tasks.domain.Task createdTask = taskService.createTask(mockTask); assertEquals(1, createdTask.getWorkLogs().size()); assertEquals(BigDecimal.ONE, createdTask.getWorkLogs().get(0).getHoursWorked()); // the date that is stored is set by the client, not the server assertEquals(0, now.compareTo(createdTask.getWorkLogs().get(0).getDateWorked())); } @Test public void updateTask_withWorkLog() throws Exception { com.tasktop.c2c.server.tasks.domain.Task mockTask = getMockTask(); WorkLog worklog = new WorkLog(); worklog.setProfile(ProfileConverter.copy(currentUser)); worklog.setDateWorked(new Date()); worklog.setHoursWorked(new BigDecimal(1.0)); mockTask.getWorkLogs().add(worklog); com.tasktop.c2c.server.tasks.domain.Task createdTask = taskService.createTask(mockTask); BigDecimal time = BigDecimal.valueOf(3.3); WorkLog w2 = new WorkLog(); w2.setDateWorked(new Date()); w2.setHoursWorked(time); w2.setProfile(ProfileConverter.copy(currentUser)); createdTask.getWorkLogs().add(w2); com.tasktop.c2c.server.tasks.domain.Task updatedTask = taskService.updateTask(createdTask); assertEquals(2, updatedTask.getWorkLogs().size()); assertEquals(time, updatedTask.getWorkLogs().get(1).getHoursWorked()); } @Test public void updateTask_withOnlyNewWorkLog() throws Exception { com.tasktop.c2c.server.tasks.domain.Task mockTask = getMockTask(); WorkLog worklog = new WorkLog(); worklog.setProfile(ProfileConverter.copy(currentUser)); worklog.setDateWorked(new Date()); worklog.setHoursWorked(new BigDecimal(1.0)); mockTask.getWorkLogs().add(worklog); com.tasktop.c2c.server.tasks.domain.Task createdTask = taskService.createTask(mockTask); BigDecimal time = BigDecimal.valueOf(4.44); WorkLog w2 = new WorkLog(); w2.setDateWorked(new Date()); w2.setHoursWorked(time); w2.setProfile(ProfileConverter.copy(currentUser)); // remove all work logs, only submit the new one createdTask.getWorkLogs().clear(); createdTask.getWorkLogs().add(w2); assertEquals(1, createdTask.getWorkLogs().size()); Thread.sleep(1000L); com.tasktop.c2c.server.tasks.domain.Task updatedTask = taskService.updateTask(createdTask); // should still return two worklogs assertEquals(2, updatedTask.getWorkLogs().size()); assertEquals(time, updatedTask.getWorkLogs().get(1).getHoursWorked()); } @Test public void updateTask_workLogsShouldBeImmutable() throws Exception { BigDecimal originalHoursWorked = new BigDecimal(1.0); BigDecimal changedHoursWorked = new BigDecimal(2.0); com.tasktop.c2c.server.tasks.domain.Task mockTask = getMockTask(); WorkLog worklog = new WorkLog(); worklog.setProfile(ProfileConverter.copy(currentUser)); worklog.setDateWorked(new Date()); worklog.setHoursWorked(originalHoursWorked); mockTask.getWorkLogs().add(worklog); com.tasktop.c2c.server.tasks.domain.Task createdTask = taskService.createTask(mockTask); assertEquals(originalHoursWorked, createdTask.getWorkLogs().get(0).getHoursWorked()); createdTask.getWorkLogs().get(0).setHoursWorked(changedHoursWorked); com.tasktop.c2c.server.tasks.domain.Task updatedTask = taskService.updateTask(createdTask); assertEquals(originalHoursWorked, updatedTask.getWorkLogs().get(0).getHoursWorked()); } @Test public void createUpdateIteration() throws ValidationException, EntityNotFoundException { RepositoryConfiguration originalConfig = taskService.getRepositoryContext(); Iteration newIteration = new Iteration("32-nextSprint"); newIteration = taskService.createIteration(newIteration); Assert.assertNotNull(newIteration); Assert.assertNotNull(newIteration.getId()); RepositoryConfiguration newConfig = taskService.getRepositoryContext(); Assert.assertEquals(originalConfig.getIterations().size() + 1, newConfig.getIterations().size()); newIteration.setIsActive(false); newIteration = taskService.updateIteration(newIteration); newConfig = taskService.getRepositoryContext(); Assert.assertEquals(newConfig.getIterations().size() - 1, newConfig.getActiveIterations().size()); } @Test public void testWorkLogBeforeTaskCreationOnUpdate_task2812() throws ValidationException, EntityNotFoundException, ConcurrentUpdateException { com.tasktop.c2c.server.tasks.domain.Task mockTask = getMockTask(); String desc = "Description"; mockTask.setDescription(desc); com.tasktop.c2c.server.tasks.domain.Task createdTask = taskService.createTask(mockTask); WorkLog worklog = new WorkLog(); worklog.setDateWorked(new Date(createdTask.getCreationDate().getTime() - 20000l)); worklog.setHoursWorked(BigDecimal.valueOf(3.4)); worklog.setComment("worklog"); createdTask.getWorkLogs().add(worklog); com.tasktop.c2c.server.tasks.domain.Task updatedTask = taskService.updateTask(createdTask); Assert.assertEquals(desc, updatedTask.getDescription()); } @Test public void testWorkLogBeforeTaskCreationOnCreate_task2812() throws ValidationException, EntityNotFoundException, ConcurrentUpdateException { com.tasktop.c2c.server.tasks.domain.Task mockTask = getMockTask(); String desc = "Description"; mockTask.setDescription(desc); WorkLog worklog = new WorkLog(); worklog.setDateWorked(new Date(System.currentTimeMillis() - 20000l)); worklog.setHoursWorked(BigDecimal.valueOf(3.4)); worklog.setComment("worklog"); mockTask.getWorkLogs().add(worklog); com.tasktop.c2c.server.tasks.domain.Task createdTask = taskService.createTask(mockTask); com.tasktop.c2c.server.tasks.domain.Task updatedTask = taskService.updateTask(createdTask); Assert.assertEquals(desc, updatedTask.getDescription()); } @Test public void testCommentDoesNotBecomeDescription_task2838() throws ValidationException, EntityNotFoundException, ConcurrentUpdateException, InterruptedException { com.tasktop.c2c.server.tasks.domain.Task mockTask = getMockTask(); String desc = "Description"; mockTask.setDescription(desc); com.tasktop.c2c.server.tasks.domain.Task createdTask = taskService.createTask(mockTask); com.tasktop.c2c.server.tasks.domain.Task updatedTask = taskService.updateTask(createdTask); Assert.assertEquals(desc, updatedTask.getDescription()); for (int i = 1; i < 10; i++) { Thread.sleep(1000); updatedTask.addComment("Comment" + i); updatedTask = taskService.updateTask(updatedTask); Assert.assertEquals("failed on comment " + i, desc, updatedTask.getDescription()); } } @Test public void testWikiRenderer() { String wikiText = ".pre hello"; String html = taskService.renderWikiMarkupAsHtml(wikiText); Assert.assertNotNull(html); } @Test public void testCreateTaskWithInvalidParentId_task4026() throws ValidationException, EntityNotFoundException { com.tasktop.c2c.server.tasks.domain.Task a = getMockTask("a"); com.tasktop.c2c.server.tasks.domain.Task invalid = new com.tasktop.c2c.server.tasks.domain.Task(); invalid.setId(666); a.setParentTask(invalid); try { taskService.createTask(a); Assert.fail("Expect ENF exception"); } catch (EntityNotFoundException e) { // expected } } @Test public void testCreateTaskWithInvalidSubtaskId_task4026() throws ValidationException, EntityNotFoundException { com.tasktop.c2c.server.tasks.domain.Task a = getMockTask("a"); com.tasktop.c2c.server.tasks.domain.Task invalid = new com.tasktop.c2c.server.tasks.domain.Task(); invalid.setId(666); a.setSubTasks(Arrays.asList(invalid)); try { taskService.createTask(a); Assert.fail("Expect ENF exception"); } catch (EntityNotFoundException e) { // expected } } @Test public void testRetrieveConfigurationProperty() throws EntityNotFoundException { final String TEST_CONFIGURATION_PROPERTY = "TEST_CONFIGURATION_PROPERTY"; ConfigurationProperty cp = new ConfigurationProperty(); cp.setName(TEST_CONFIGURATION_PROPERTY); cp.setValue("test value"); cp.setId(Long.valueOf(12345)); entityManager.persist(cp); entityManager.flush(); String property = taskService.retrieveConfigurationProperty(TEST_CONFIGURATION_PROPERTY); assertTrue(property.equals("test value")); } @Test public void testSetConfigurationProperty() throws ValidationException, EntityNotFoundException { final String TEST_CONFIGURATION_PROPERTY = "TEST_CONFIGURATION_PROPERTY"; taskService.setConfigurationProperty(TEST_CONFIGURATION_PROPERTY, "test value"); String property = taskService.retrieveConfigurationProperty(TEST_CONFIGURATION_PROPERTY); assertTrue(property.equals("test value")); } @Test public void testCommitsProperty() throws ValidationException, EntityNotFoundException, ConcurrentUpdateException { com.tasktop.c2c.server.tasks.domain.Task mock = getMockTask(); com.tasktop.c2c.server.tasks.domain.Task task = taskService.createTask(mock); Assert.assertEquals(0, task.getCommits().size()); task.getCommits().add("XXX"); task = taskService.updateTask(task); Assert.assertEquals(1, task.getCommits().size()); // Test for task 4520 task.setCommits(null); task = taskService.updateTask(task); Assert.assertEquals(1, task.getCommits().size()); } @Test // for task 4413: testing prior behaviours of setting logged in user // for Reporter, Comment Author, Work Logs public void testCreateTaskSetsPropertiesAsUser() throws Exception { // build our sample Task com.tasktop.c2c.server.tasks.domain.Task mock = getMockTask(); String commentText = "Hi, I'm so excited to add a comment!!!!"; mock.addComment(commentText); WorkLog origWorkLog = new WorkLog(); String workLogComment = "I did this!!!"; origWorkLog.setComment(workLogComment); origWorkLog.setHoursWorked(new BigDecimal(1.0)); List<WorkLog> origWorkLogs = new ArrayList<WorkLog>(); origWorkLogs.add(origWorkLog); mock.setWorkLogs(origWorkLogs); // save our Task com.tasktop.c2c.server.tasks.domain.Task task = taskService.createTask(mock); // assert that specific properties are set to logged in user ... // Reporter TaskUserProfile reporter = task.getReporter(); assertNotNull(reporter); assertEquals(currentUser.getId(), reporter.getId()); // Comments List<Comment> comments = task.getComments(); assertNotNull(comments); assertEquals(1, comments.size()); assertEquals(commentText, comments.get(0).getCommentText()); assertEquals(currentUser.getId(), comments.get(0).getAuthor().getId()); // Work Logs List<WorkLog> workLogs = task.getWorkLogs(); assertNotNull(workLogs); assertEquals(1, workLogs.size()); assertEquals(workLogComment, workLogs.get(0).getComment()); assertEquals(currentUser.getId(), workLogs.get(0).getProfile().getId()); // Save an Attachment TaskHandle taskHandle = new TaskHandle(); taskHandle.setId(task.getId()); taskHandle.setVersion(task.getVersion()); com.tasktop.c2c.server.tasks.domain.Attachment newAttachment = new com.tasktop.c2c.server.tasks.domain.Attachment(); newAttachment.setAttachmentData(new byte[10]); newAttachment.setDescription("Not much to describe."); newAttachment.setMimeType("text/plain"); newAttachment.setFilename("/dev/null"); Comment newComment = new Comment(); newComment.setCommentText("Yo"); taskService.saveAttachment(taskHandle, newAttachment, newComment); task = taskService.retrieveTask(task.getId()); // Verify the Attachment submitter has been set List<com.tasktop.c2c.server.tasks.domain.Attachment> attachments = task.getAttachments(); assertNotNull(attachments); assertEquals(1, attachments.size()); for (com.tasktop.c2c.server.tasks.domain.Attachment attachment : attachments) { assertEquals(currentUser.getId(), attachment.getSubmitter().getId()); } // Verify the Comment author has been set comments = task.getComments(); assertEquals(2, comments.size()); for (Comment comment : comments) { assertEquals(currentUser.getId(), comment.getAuthor().getId()); } } @Test // for task 4413 public void testCreateTaskAsAdminAllowsImpersonation() throws Exception { // log in again, with the Admin role TestSecurity.login(currentUser, Role.Admin); // create a Profile that we'll be impersonating Profile impersonatedGuy = MockProfileFactory.create(null); // create a Task and impersonate our guy com.tasktop.c2c.server.tasks.domain.Task mock = getMockTask(); TaskUserProfile tuImpersonatedGuy = ProfileConverter.copy(impersonatedGuy); // set Reporter mock.setReporter(tuImpersonatedGuy); mock.setAssignee(tuImpersonatedGuy); // add a Comment Comment origComment = new Comment(); origComment.setCommentText("Yo"); origComment.setAuthor(tuImpersonatedGuy); List<Comment> origComments = new ArrayList<Comment>(); origComments.add(origComment); mock.setComments(origComments); // add a Work Log WorkLog origWorkLog = new WorkLog(); origWorkLog.setComment("I said, 'Yo'!"); origWorkLog.setHoursWorked(new BigDecimal(1.0)); origWorkLog.setProfile(tuImpersonatedGuy); List<WorkLog> origWorkLogs = new ArrayList<WorkLog>(); origWorkLogs.add(origWorkLog); mock.setWorkLogs(origWorkLogs); // save the Task and ensure our impersonatedGuy remains set for specified properties // (i.e., is not overwritten as the logged in user due to default behaviours) com.tasktop.c2c.server.tasks.domain.Task task = taskService.createTask(mock); // Reporter TaskUserProfile reporter = task.getReporter(); assertNotNull(reporter); assertEquals(impersonatedGuy.getRealname(), reporter.getRealname()); // Assignee assertEquals(impersonatedGuy.getLoginName(), task.getAssignee().getLoginName()); // Comments List<Comment> comments = task.getComments(); assertNotNull(comments); assertEquals(1, comments.size()); assertEquals(origComment.getCommentText(), comments.get(0).getCommentText()); assertEquals(impersonatedGuy.getLoginName(), comments.get(0).getAuthor().getLoginName()); // Work Logs List<WorkLog> workLogs = task.getWorkLogs(); assertNotNull(workLogs); assertEquals(1, workLogs.size()); assertEquals(origWorkLog.getComment(), workLogs.get(0).getComment()); assertEquals(impersonatedGuy.getLoginName(), workLogs.get(0).getProfile().getLoginName()); // Save an Attachment TaskHandle taskHandle = new TaskHandle(); taskHandle.setId(task.getId()); taskHandle.setVersion(task.getVersion()); com.tasktop.c2c.server.tasks.domain.Attachment newAttachment = new com.tasktop.c2c.server.tasks.domain.Attachment(); newAttachment.setAttachmentData(new byte[10]); newAttachment.setDescription("Not much to describe."); newAttachment.setMimeType("text/plain"); newAttachment.setFilename("/dev/null"); newAttachment.setSubmitter(tuImpersonatedGuy); Comment newComment = new Comment(); newComment.setCommentText("Yo"); newComment.setAuthor(tuImpersonatedGuy); taskService.saveAttachment(taskHandle, newAttachment, newComment); task = taskService.retrieveTask(task.getId()); // Verify the Attachment submitter is the same as before List<com.tasktop.c2c.server.tasks.domain.Attachment> attachments = task.getAttachments(); assertNotNull(attachments); assertEquals(1, attachments.size()); for (com.tasktop.c2c.server.tasks.domain.Attachment attachment : attachments) { assertEquals(impersonatedGuy.getLoginName(), attachment.getSubmitter().getLoginName()); } // Verify the Comment author is the same as before comments = task.getComments(); assertEquals(2, comments.size()); for (Comment comment : comments) { assertEquals(impersonatedGuy.getLoginName(), comment.getAuthor().getLoginName()); } } @Test public void testCreateTaskAsAdminCreateAssignee() throws Exception { // log in again, with the Admin role TestSecurity.login(currentUser, Role.Admin); // create a Profile that we'll be impersonating Profile impersonatedGuy = MockProfileFactory.create(null); // create a Task and impersonate our guy com.tasktop.c2c.server.tasks.domain.Task mock = getMockTask(); TaskUserProfile tuImpersonatedGuy = ProfileConverter.copy(impersonatedGuy); mock.setAssignee(tuImpersonatedGuy); com.tasktop.c2c.server.tasks.domain.Task task = taskService.createTask(mock); // Assignee assertEquals(impersonatedGuy.getLoginName(), task.getAssignee().getLoginName()); } @Test(expected = InsufficientPermissionsException.class) public void testNonAdminUserCannotSetDifferentTaskReporter() throws Exception { // create a Task and set the Reporter to somebody else com.tasktop.c2c.server.tasks.domain.Task mock = getMockTask(); mock.setReporter(ProfileConverter.copy(getCreatedMockProfile())); // save the Task ... we should get an Exception here taskService.createTask(mock); } @Test(expected = InsufficientPermissionsException.class) public void testNonAdminUserCannotSetDifferentCommentAuthor() throws Exception { com.tasktop.c2c.server.tasks.domain.Task mock = getMockTask(); // add a Comment Comment origComment = new Comment(); origComment.setCommentText("Yo"); // set the Author to somebody else origComment.setAuthor(ProfileConverter.copy(getCreatedMockProfile())); List<Comment> origComments = new ArrayList<Comment>(); origComments.add(origComment); mock.setComments(origComments); // save the Task ... we should get an Exception here taskService.createTask(mock); } @Test(expected = InsufficientPermissionsException.class) public void testNonAdminUserCannotSetDifferentWorkLogProfile() throws Exception { com.tasktop.c2c.server.tasks.domain.Task mock = getMockTask(); // add a Work Log WorkLog origWorkLog = new WorkLog(); origWorkLog.setComment("I said, 'Yo'!"); origWorkLog.setHoursWorked(new BigDecimal(1.0)); // set the Profile to somebody else origWorkLog.setProfile(ProfileConverter.copy(getCreatedMockProfile())); List<WorkLog> origWorkLogs = new ArrayList<WorkLog>(); origWorkLogs.add(origWorkLog); mock.setWorkLogs(origWorkLogs); // save the Task ... we should get an Exception here taskService.createTask(mock); } @Test(expected = InsufficientPermissionsException.class) public void testNonAdminUserCannotSetDifferentAttachmentCommentAuthor() throws Exception { // create a Task com.tasktop.c2c.server.tasks.domain.Task mock = getMockTask(); com.tasktop.c2c.server.tasks.domain.Task task = taskService.createTask(mock); // get another profile TaskUserProfile anotherProfile = ProfileConverter.copy(getCreatedMockProfile()); // create an Attachment for the Task TaskHandle taskHandle = new TaskHandle(); taskHandle.setId(task.getId()); taskHandle.setVersion(task.getVersion()); com.tasktop.c2c.server.tasks.domain.Attachment newAttachment = new com.tasktop.c2c.server.tasks.domain.Attachment(); newAttachment.setAttachmentData(new byte[10]); newAttachment.setDescription("Not much to describe."); newAttachment.setMimeType("text/plain"); newAttachment.setFilename("/dev/null"); newAttachment.setSubmitter(anotherProfile); Comment newComment = new Comment(); newComment.setCommentText("Yo"); newComment.setAuthor(anotherProfile); // save the Attachment ... this should give an Exception taskService.saveAttachment(taskHandle, newAttachment, newComment); } }