package com.taskadapter.redmineapi;
import com.taskadapter.redmineapi.bean.Issue;
import com.taskadapter.redmineapi.bean.IssueFactory;
import com.taskadapter.redmineapi.bean.Project;
import com.taskadapter.redmineapi.bean.ProjectFactory;
import com.taskadapter.redmineapi.bean.TimeEntry;
import com.taskadapter.redmineapi.bean.TimeEntryFactory;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static com.taskadapter.redmineapi.IssueHelper.createIssue;
import static com.taskadapter.redmineapi.IssueHelper.createIssues;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
public class TimeEntryManagerIT {
// TODO We don't know activities' IDs!
// see feature request http://www.redmine.org/issues/7506
private static final Integer ACTIVITY_ID = 8;
private static ProjectManager projectManager;
private static TimeEntryManager timeEntryManager;
private static IssueManager issueManager;
private static String projectKey;
private static Integer projectId;
@BeforeClass
public static void oneTimeSetUp() {
RedmineManager mgr = IntegrationTestHelper.createRedmineManager();
timeEntryManager = mgr.getTimeEntryManager();
projectManager = mgr.getProjectManager();
issueManager = mgr.getIssueManager();
Project junitTestProject = ProjectFactory.create("test project", "test" + Calendar.getInstance().getTimeInMillis());
try {
Project createdProject = projectManager.createProject(junitTestProject);
projectKey = createdProject.getIdentifier();
projectId = createdProject.getId();
} catch (Exception e) {
Assert.fail("can't create a test project. " + e.getMessage());
}
}
@AfterClass
public static void oneTimeTearDown() {
try {
if (projectManager != null && projectKey != null) {
projectManager.deleteProject(projectKey);
}
} catch (Exception e) {
Assert.fail("can't delete the test project '" + projectKey
+ ". reason: " + e.getMessage());
}
}
@Test
public void testTimeEntryDefaults() throws RedmineException {
final TimeEntry template = TimeEntryFactory.create();
final Issue tmp = IssueFactory.create(projectId, "aaabbbccc");
final Issue tmpIssue = issueManager.createIssue(tmp);
try {
template.setHours(123.f);
template.setActivityId(ACTIVITY_ID);
template.setIssueId(tmpIssue.getId());
final TimeEntry result = timeEntryManager.createTimeEntry(template);
try {
Assert.assertNotNull(result.getId());
Assert.assertNotNull(result.getIssueId());
Assert.assertNotNull(result.getProjectId());
Assert.assertNotNull(result.getProjectName());
Assert.assertNotNull(result.getUserName());
Assert.assertNotNull(result.getUserId());
Assert.assertNotNull(result.getActivityName());
Assert.assertNotNull(result.getActivityId());
Assert.assertEquals(Float.valueOf(123.0f), result.getHours());
Assert.assertEquals("", result.getComment());
Assert.assertNotNull(result.getSpentOn());
Assert.assertNotNull(result.getCreatedOn());
Assert.assertNotNull(result.getUpdatedOn());
} finally {
timeEntryManager.deleteTimeEntry(result.getId());
}
} finally {
issueManager.deleteIssue(tmpIssue.getId());
}
}
/**
* Test for issue 64 (time entry format)
*/
@Test
public void testTimeEntryComments() throws RedmineException {
Issue issue = createIssues(issueManager, projectId, 1).get(0);
Integer issueId = issue.getId();
TimeEntry entry = TimeEntryFactory.create();
Float hours = 11f;
entry.setHours(hours);
entry.setIssueId(issueId);
final String comment = "This is a comment although it may not look like it";
entry.setComment(comment);
// TODO We don't know activities IDs!
// see feature request http://www.redmine.org/issues/7506
entry.setActivityId(ACTIVITY_ID);
TimeEntry createdEntry = timeEntryManager.createTimeEntry(entry);
assertNotNull(createdEntry);
assertEquals(comment, createdEntry.getComment());
createdEntry.setComment("New comment");
timeEntryManager.update(createdEntry);
final TimeEntry updatedEntry = timeEntryManager.getTimeEntry(createdEntry.getId());
assertEquals("New comment", updatedEntry.getComment());
}
@Test
public void testTimeEntryActivities() throws RedmineException {
assertTrue(timeEntryManager.getTimeEntryActivities().size() > 0);
}
@Test
public void testGetTimeEntries() throws RedmineException {
List<TimeEntry> list = timeEntryManager.getTimeEntries();
assertNotNull(list);
}
@Test
public void testCreateGetTimeEntry() throws RedmineException {
Issue issue = createIssues(issueManager, projectId, 1).get(0);
Integer issueId = issue.getId();
TimeEntry entry = TimeEntryFactory.create();
Float hours = 11f;
entry.setHours(hours);
entry.setIssueId(issueId);
// TODO We don't know activities IDs!
// see feature request http://www.redmine.org/issues/7506
entry.setActivityId(ACTIVITY_ID);
TimeEntry createdEntry = timeEntryManager.createTimeEntry(entry);
assertNotNull(createdEntry);
assertEquals(hours, createdEntry.getHours());
Float newHours = 22f;
createdEntry.setHours(newHours);
timeEntryManager.update(createdEntry);
TimeEntry updatedEntry = timeEntryManager.getTimeEntry(createdEntry.getId());
assertEquals(newHours, updatedEntry.getHours());
}
@Test(expected = NotFoundException.class)
public void testCreateDeleteTimeEntry() throws RedmineException {
Issue issue = createIssues(issueManager, projectId, 1).get(0);
Integer issueId = issue.getId();
TimeEntry entry = TimeEntryFactory.create();
Float hours = 4f;
entry.setHours(hours);
entry.setIssueId(issueId);
entry.setActivityId(ACTIVITY_ID);
TimeEntry createdEntry = timeEntryManager.createTimeEntry(entry);
assertNotNull(createdEntry);
timeEntryManager.deleteTimeEntry(createdEntry.getId());
timeEntryManager.getTimeEntry(createdEntry.getId());
}
@Test
public void testGetTimeEntriesForIssue() throws RedmineException {
Issue issue = createIssues(issueManager, projectId, 1).get(0);
Integer issueId = issue.getId();
Float hours1 = 2f;
Float hours2 = 7f;
Float totalHoursExpected = hours1 + hours2;
TimeEntry createdEntry1 = createTimeEntry(issueId, hours1);
TimeEntry createdEntry2 = createTimeEntry(issueId, hours2);
assertNotNull(createdEntry1);
assertNotNull(createdEntry2);
List<TimeEntry> entries = timeEntryManager.getTimeEntriesForIssue(issueId);
assertEquals(2, entries.size());
Float totalTime = 0f;
for (TimeEntry timeEntry : entries) {
totalTime += timeEntry.getHours();
}
assertEquals(totalHoursExpected, totalTime);
}
private TimeEntry createTimeEntry(Integer issueId, float hours) throws RedmineException {
return createTimeEntry(issueId, hours, ACTIVITY_ID);
}
private TimeEntry createTimeEntry(Integer issueId, float hours, int activityId)
throws RedmineException {
TimeEntry entry = TimeEntryFactory.create();
entry.setHours(hours);
entry.setIssueId(issueId);
entry.setActivityId(activityId);
return timeEntryManager.createTimeEntry(entry);
}
@Test(expected = IllegalArgumentException.class)
public void invalidTimeEntryFailsWithIAEOnCreate() throws RedmineException {
timeEntryManager.createTimeEntry(createIncompleteTimeEntry());
}
@Test(expected = IllegalArgumentException.class)
public void invalidTimeEntryFailsWithIAEOnUpdate() throws RedmineException {
timeEntryManager.update(createIncompleteTimeEntry());
}
private TimeEntry createIncompleteTimeEntry() {
TimeEntry timeEntry = TimeEntryFactory.create();
timeEntry.setActivityId(ACTIVITY_ID);
timeEntry.setSpentOn(new Date());
timeEntry.setHours(1.5f);
return timeEntry;
}
@Test
public void testViolateTimeEntryConstraint_ProjectOrIssueID() throws RedmineException {
TimeEntry timeEntry = createIncompleteTimeEntry();
timeEntry.setProjectId(projectId);
timeEntryManager.createTimeEntry(timeEntry);
// no exceptions - good.
}
/**
* This integration test requires activities with ids 8 and 9 to be present on
* the redmine server. we cannot detect Ids of existing activities -
* see Redmine feature request http://www.redmine.org/issues/7506
*/
@Test
public void timeEntriesAreFoundByFreeFormSearch() throws RedmineException {
// create some random issues in the project
Issue createdIssue = createIssue(issueManager, projectId);
// TODO We don't know activities' IDs
// see feature request http://www.redmine.org/issues/7506
Integer createdIssueId = createdIssue.getId();
createTimeEntry(createdIssueId, 2, 8);
createTimeEntry(createdIssueId, 6, 8);
createTimeEntry(createdIssueId, 10, 8);
createTimeEntry(createdIssueId, 30, 9);
try {
Map<String, String> paramsForActivity8 = new HashMap<>();
paramsForActivity8.put("issue_id", Integer.toString(createdIssueId));
paramsForActivity8.put("activity_id", ACTIVITY_ID + "");
List<TimeEntry> timeEntriesForActivity8 = timeEntryManager.getTimeEntries(paramsForActivity8).getResults();
assertThat(timeEntriesForActivity8.size()).isEqualTo(3);
Map<String, String> paramsForActivity9 = new HashMap<>();
paramsForActivity9.put("issue_id", Integer.toString(createdIssueId));
paramsForActivity9.put("activity_id", "9");
List<TimeEntry> timeEntriesForActivity9 = timeEntryManager.getTimeEntries(paramsForActivity9).getResults();
assertThat(timeEntriesForActivity9.size()).isEqualTo(1);
} finally {
issueManager.deleteIssue(createdIssueId);
}
}
}