Package com.taskadapter.redmineapi

Source Code of com.taskadapter.redmineapi.IssueManagerTest

package com.taskadapter.redmineapi;

import com.taskadapter.redmineapi.bean.Changeset;
import com.taskadapter.redmineapi.bean.CustomFieldFactory;
import com.taskadapter.redmineapi.bean.Issue;
import com.taskadapter.redmineapi.bean.IssueCategory;
import com.taskadapter.redmineapi.bean.IssueCategoryFactory;
import com.taskadapter.redmineapi.bean.IssueFactory;
import com.taskadapter.redmineapi.bean.IssueRelation;
import com.taskadapter.redmineapi.bean.IssueStatus;
import com.taskadapter.redmineapi.bean.Journal;
import com.taskadapter.redmineapi.bean.JournalDetail;
import com.taskadapter.redmineapi.bean.Project;
import com.taskadapter.redmineapi.bean.SavedQuery;
import com.taskadapter.redmineapi.bean.TimeEntry;
import com.taskadapter.redmineapi.bean.TimeEntryFactory;
import com.taskadapter.redmineapi.bean.Tracker;
import com.taskadapter.redmineapi.bean.User;
import com.taskadapter.redmineapi.bean.Version;
import com.taskadapter.redmineapi.bean.VersionFactory;
import com.taskadapter.redmineapi.bean.Watcher;
import com.taskadapter.redmineapi.bean.WatcherFactory;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;

import static com.taskadapter.redmineapi.IssueHelper.createIssues;
import static org.fest.assertions.Assertions.assertThat;
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;

public class IssueManagerTest {

    private static final Logger logger = LoggerFactory.getLogger(IssueManagerTest.class);

    // 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 IssueManager issueManager;
    private static ProjectManager projectManager;
    private static String projectKey;
    private static RedmineManager mgr;
    private static UserManager userManager;

    @BeforeClass
    public static void oneTimeSetup() {
        mgr = IntegrationTestHelper.createRedmineManager();
        userManager = mgr.getUserManager();
        issueManager = mgr.getIssueManager();
        projectManager = mgr.getProjectManager();
        projectKey = IntegrationTestHelper.createProject(mgr);
    }

    @AfterClass
    public static void oneTimeTearDown() {
        IntegrationTestHelper.deleteProject(mgr, projectKey);
    }

    @Test
    public void issueCreated() {
        try {
            Issue issueToCreate = IssueFactory.createWithSubject("test zzx");

            Calendar startCal = Calendar.getInstance();
            // have to clear them because they are ignored by Redmine and
            // prevent from comparison later
            startCal.clear(Calendar.HOUR_OF_DAY);
            startCal.clear(Calendar.MINUTE);
            startCal.clear(Calendar.SECOND);
            startCal.clear(Calendar.MILLISECOND);

            startCal.add(Calendar.DATE, 5);
            issueToCreate.setStartDate(startCal.getTime());

            Calendar due = Calendar.getInstance();
            due.add(Calendar.MONTH, 1);
            issueToCreate.setDueDate(due.getTime());
            User assignee = IntegrationTestHelper.getOurUser();
            issueToCreate.setAssignee(assignee);

            String description = "This is the description for the new task."
                    + "\nIt has several lines." + "\nThis is the last line.";
            issueToCreate.setDescription(description);

            float estimatedHours = 44;
            issueToCreate.setEstimatedHours(estimatedHours);

            Issue newIssue = issueManager.createIssue(projectKey, issueToCreate);
            assertNotNull("Checking returned result", newIssue);
            assertNotNull("New issue must have some ID",
                    newIssue.getId());

            // check startDate
            Calendar returnedStartCal = Calendar.getInstance();
            returnedStartCal.setTime(newIssue.getStartDate());

            assertEquals(startCal.get(Calendar.YEAR),
                    returnedStartCal.get(Calendar.YEAR));
            assertEquals(startCal.get(Calendar.MONTH),
                    returnedStartCal.get(Calendar.MONTH));
            assertEquals(startCal.get(Calendar.DAY_OF_MONTH),
                    returnedStartCal.get(Calendar.DAY_OF_MONTH));

            // check dueDate
            Calendar returnedDueCal = Calendar.getInstance();
            returnedDueCal.setTime(newIssue.getDueDate());

            assertEquals(due.get(Calendar.YEAR),
                    returnedDueCal.get(Calendar.YEAR));
            assertEquals(due.get(Calendar.MONTH),
                    returnedDueCal.get(Calendar.MONTH));
            assertEquals(due.get(Calendar.DAY_OF_MONTH),
                    returnedDueCal.get(Calendar.DAY_OF_MONTH));

            // check ASSIGNEE
            User actualAssignee = newIssue.getAssignee();
            assertNotNull("Checking assignee not null", actualAssignee);
            assertEquals("Checking assignee id", assignee.getId(),
                    actualAssignee.getId());

            // check AUTHOR
            Integer EXPECTED_AUTHOR_ID = IntegrationTestHelper.getOurUser().getId();
            assertEquals(EXPECTED_AUTHOR_ID, newIssue.getAuthor()
                    .getId());

            // check ESTIMATED TIME
            assertEquals((Float) estimatedHours,
                    newIssue.getEstimatedHours());

            // check multi-line DESCRIPTION
            String regexpStripExtra = "\\r|\\n|\\s";
            description = description.replaceAll(regexpStripExtra, "");
            String actualDescription = newIssue.getDescription();
            actualDescription = actualDescription.replaceAll(regexpStripExtra,
                    "");
            assertEquals(description, actualDescription);

            // PRIORITY
            assertNotNull(newIssue.getPriorityId());
            assertTrue(newIssue.getPriorityId() > 0);
        } catch (Exception e) {
            e.printStackTrace();
            fail();
        }
    }

    @Test
    public void issueWithParentCreated() {
        try {
            Issue parentIssue = IssueFactory.createWithSubject("parent 1");
            Issue newParentIssue = issueManager.createIssue(projectKey, parentIssue);

            assertNotNull("Checking parent was created", newParentIssue);
            assertNotNull("Checking ID of parent issue is not null",
                    newParentIssue.getId());

            // Integer parentId = 46;
            Integer parentId = newParentIssue.getId();

            Issue childIssue = IssueFactory.createWithSubject("child 1");
            childIssue.setParentId(parentId);

            Issue newChildIssue = issueManager.createIssue(projectKey, childIssue);

            assertEquals("Checking parent ID of the child issue",
                    parentId, newChildIssue.getParentId());

        } catch (Exception e) {
            e.printStackTrace();
            fail();
        }
    }

    @Test
    public void testUpdateIssue() {
        try {
            String originalSubject = "Issue " + new Date();
            Issue issue = IssueFactory.createWithSubject(originalSubject);

            Issue newIssue = issueManager.createIssue(projectKey, issue);
            String changedSubject = "changed subject";
            newIssue.setSubject(changedSubject);

            issueManager.update(newIssue);

            Issue reloadedFromRedmineIssue = issueManager.getIssueById(newIssue.getId());

            assertEquals(
                    "Checking if 'update issue' operation changed the 'subject' field",
                    changedSubject, reloadedFromRedmineIssue.getSubject());
        } catch (Exception e) {
            e.printStackTrace();
            fail();
        }
    }

    /**
     * Tests the retrieval of an {@link Issue} by its ID.
     *
     * @throws com.taskadapter.redmineapi.RedmineException
     *                                        thrown in case something went wrong in Redmine
     * @throws RedmineAuthenticationException thrown in case something went wrong while trying to login
     * @throws com.taskadapter.redmineapi.NotFoundException
     *                                        thrown in case the objects requested for could not be found
     */
    @Test
    public void testGetIssueById() throws RedmineException {
        String originalSubject = "Issue " + new Date();
        Issue issue = IssueFactory.createWithSubject(originalSubject);

        Issue newIssue = issueManager.createIssue(projectKey, issue);

        Issue reloadedFromRedmineIssue = issueManager.getIssueById(newIssue.getId());

        assertEquals(
                "Checking if 'get issue by ID' operation returned issue with same 'subject' field",
                originalSubject, reloadedFromRedmineIssue.getSubject());
        Tracker tracker = reloadedFromRedmineIssue.getTracker();
        assertNotNull("Tracker of issue should not be null", tracker);
        assertNotNull("ID of tracker of issue should not be null",
                tracker.getId());
        assertNotNull("Name of tracker of issue should not be null",
                tracker.getName());
    }

    @Test
    public void testGetIssues() {
        try {
            // create at least 1 issue
            Issue issueToCreate = IssueFactory.createWithSubject("testGetIssues: " + new Date());
            Issue newIssue = issueManager.createIssue(projectKey, issueToCreate);

            List<Issue> issues = issueManager.getIssues(projectKey, null);
            assertTrue(issues.size() > 0);
            boolean found = false;
            for (Issue issue : issues) {
                if (issue.getId().equals(newIssue.getId())) {
                    found = true;
                    break;
                }
            }
            if (!found) {
                fail("getIssues() didn't return the issue we just created. The query "
                        + " must have returned all issues created during the last 2 days");
            }
        } catch (Exception e) {
            e.printStackTrace();
            fail(e.getMessage());
        }
    }

    @Test(expected = NotFoundException.class)
    public void testGetIssuesInvalidQueryId() throws RedmineException {
        Integer invalidQueryId = 9999999;
        issueManager.getIssues(projectKey, invalidQueryId);
    }

    @Test
    public void testCreateIssueNonUnicodeSymbols() {
        try {
            String nonLatinSymbols = "Example with accents A��o";
            Issue toCreate = IssueFactory.createWithSubject(nonLatinSymbols);
            Issue created = issueManager.createIssue(projectKey, toCreate);
            assertEquals(nonLatinSymbols, created.getSubject());
        } catch (Exception e) {
            fail(e.getMessage());
        }
    }

    @Test
    public void testCreateIssueSummaryOnly() {
        try {
            Issue issueToCreate = new Issue();
            issueToCreate.setSubject("This is the summary line 123");

            Issue newIssue = issueManager.createIssue(projectKey, issueToCreate);
            assertNotNull("Checking returned result", newIssue);
            assertNotNull("New issue must have some ID",
                    newIssue.getId());

            // check AUTHOR
            Integer EXPECTED_AUTHOR_ID = IntegrationTestHelper.getOurUser().getId();
            assertEquals(EXPECTED_AUTHOR_ID, newIssue.getAuthor()
                    .getId());

        } catch (Exception e) {
            e.printStackTrace();
            fail();
        }
    }

    @Test(expected = NotFoundException.class)
    public void testCreateIssueInvalidProjectKey() throws RedmineException {
        Issue issueToCreate = IssueFactory.createWithSubject("Summary line 100");
        issueManager.createIssue("someNotExistingProjectKey", issueToCreate);
    }

    @Test(expected = NotFoundException.class)
    public void testGetIssueNonExistingId() throws RedmineException {
        int someNonExistingID = 999999;
        issueManager.getIssueById(someNonExistingID);
    }

    @Test(expected = NotFoundException.class)
    public void testUpdateIssueNonExistingId() throws RedmineException {
        int nonExistingId = 999999;
        Issue issue = IssueFactory.create(nonExistingId);
        issueManager.update(issue);
    }

    @Test
    public void testGetIssuesPaging() {
        try {
            // create 27 issues. default page size is 25.
            createIssues(issueManager, projectKey, 27);
            // mgr.setObjectsPerPage(5); <-- does not work now
            List<Issue> issues = issueManager.getIssues(projectKey, null);
            assertTrue(issues.size() > 26);

            Set<Issue> issueSet = new HashSet<Issue>(issues);
            assertEquals(issues.size(), issueSet.size());
        } catch (Exception e) {
            e.printStackTrace();
            fail(e.getMessage());
        }
    }

    @Test(expected = NotFoundException.class)
    public void testDeleteIssue() throws RedmineException {
        Issue issue = createIssues(issueManager, projectKey, 1).get(0);
        Issue retrievedIssue = issueManager.getIssueById(issue.getId());
        assertEquals(issue, retrievedIssue);

        issueManager.deleteIssue(issue.getId());
        issueManager.getIssueById(issue.getId());
    }

    @Test
    public void testUpdateIssueSpecialXMLtags() throws Exception {
        Issue issue = createIssues(issueManager, projectKey, 1).get(0);
        String newSubject = "\"text in quotes\" and <xml> tags";
        String newDescription = "<taghere>\"abc\"</here>";
        issue.setSubject(newSubject);
        issue.setDescription(newDescription);
        issueManager.update(issue);

        Issue updatedIssue = issueManager.getIssueById(issue.getId());
        assertEquals(newSubject, updatedIssue.getSubject());
        assertEquals(newDescription, updatedIssue.getDescription());
    }

    @Test
    public void testCreateRelation() {
        try {
            List<Issue> issues = createIssues(issueManager, projectKey, 2);
            Issue src = issues.get(0);
            Issue target = issues.get(1);

            String relationText = IssueRelation.TYPE.precedes.toString();
            IssueRelation r = issueManager.createRelation(src.getId(), target.getId(),
                    relationText);
            assertEquals(src.getId(), r.getIssueId());
            assertEquals(target.getId(), r.getIssueToId());
            assertEquals(relationText, r.getType());
        } catch (Exception e) {
            fail(e.toString());
        }
    }

    private IssueRelation createTwoRelatedIssues() throws RedmineException {
        List<Issue> issues = createIssues(issueManager, projectKey, 2);
        Issue src = issues.get(0);
        Issue target = issues.get(1);

        String relationText = IssueRelation.TYPE.precedes.toString();
        return issueManager.createRelation(src.getId(), target.getId(), relationText);
    }

    @Test
    public void issueRelationsAreCreatedAndLoadedOK() {
        try {
            IssueRelation relation = createTwoRelatedIssues();
            Issue issue = issueManager.getIssueById(relation.getIssueId(),
                    Include.relations);
            Issue issueTarget = issueManager.getIssueById(relation.getIssueToId(),
                    Include.relations);

            assertThat(issue.getRelations().size()).isEqualTo(1);
            assertThat(issueTarget.getRelations().size()).isEqualTo(1);

            IssueRelation relation1 = issue.getRelations().iterator().next();
            assertEquals(issue.getId(), relation1.getIssueId());
            assertEquals(issueTarget.getId(), relation1.getIssueToId());
            assertEquals("precedes", relation1.getType());
            assertEquals((Integer) 0, relation1.getDelay());

            IssueRelation reverseRelation = issueTarget.getRelations().iterator().next();
            // both forward and reverse relations are the same!
            assertEquals(relation1, reverseRelation);
        } catch (Exception e) {
            fail(e.toString());
        }
    }

    @Test
    public void testIssureRelationDelete() throws RedmineException {
        IssueRelation relation = createTwoRelatedIssues();

        issueManager.deleteRelation(relation.getId());
        Issue issue = issueManager
                .getIssueById(relation.getIssueId(), Include.relations);
        assertTrue(issue.getRelations().isEmpty());
    }

    @Test
    public void testIssueRelationsDelete() throws RedmineException {
        List<Issue> issues = createIssues(issueManager, projectKey, 3);
        Issue src = issues.get(0);
        Issue target = issues.get(1);
        String relationText = IssueRelation.TYPE.precedes.toString();

        issueManager.createRelation(src.getId(), target.getId(), relationText);

        target = issues.get(2);
        issueManager.createRelation(src.getId(), target.getId(), relationText);

        src = issueManager.getIssueById(src.getId(), Include.relations);
        issueManager.deleteIssueRelations(src);

        Issue issue = issueManager.getIssueById(src.getId(), Include.relations);
        assertTrue(issue.getRelations().isEmpty());
    }

    /**
     * Requires Redmine 2.3
     */
    @Test
    public void testAddIssueWatcher() throws RedmineException {
        final Issue issue = createIssues(issueManager, projectKey, 1).get(0);
        final Issue retrievedIssue = issueManager.getIssueById(issue.getId());
        assertEquals(issue, retrievedIssue);

        final User newUser = userManager.createUser(UserGenerator.generateRandomUser());
        try {
            Watcher watcher = WatcherFactory.create(newUser.getId());
            issueManager.addWatcherToIssue(watcher, issue);
        } finally {
            userManager.deleteUser(newUser.getId());
        }

        issueManager.getIssueById(issue.getId());
    }

    /**
     * Requires Redmine 2.3
     */
    @Test
    public void testDeleteIssueWatcher() throws RedmineException {
        final Issue issue = createIssues(issueManager, projectKey, 1).get(0);
        final Issue retrievedIssue = issueManager.getIssueById(issue.getId());
        assertEquals(issue, retrievedIssue);

        final User newUser = userManager.createUser(UserGenerator.generateRandomUser());
        try {
            Watcher watcher = WatcherFactory.create(newUser.getId());
            issueManager.addWatcherToIssue(watcher, issue);
            issueManager.deleteWatcherFromIssue(watcher, issue);
        } finally {
            userManager.deleteUser(newUser.getId());
        }

        issueManager.deleteIssue(issue.getId());
    }

    /**
     * Requires Redmine 2.3
     */
    @Test
    public void testGetIssueWatcher() throws RedmineException {
        final Issue issue = createIssues(issueManager, projectKey, 1).get(0);
        final Issue retrievedIssue = issueManager.getIssueById(issue.getId());
        assertEquals(issue, retrievedIssue);

        final User newUser = userManager.createUser(UserGenerator.generateRandomUser());
        try {
            Watcher watcher = WatcherFactory.create(newUser.getId());
            issueManager.addWatcherToIssue(watcher, issue);
            final Issue includeWatcherIssue = issueManager.getIssueById(issue.getId(),
                    Include.watchers);
            if (!includeWatcherIssue.getWatchers().isEmpty()) {
                Watcher watcher1 = includeWatcherIssue.getWatchers().iterator().next();
                assertThat(watcher1.getId()).isEqualTo(newUser.getId());
            }
        } finally {
            userManager.deleteUser(newUser.getId());
        }

        issueManager.getIssueById(issue.getId());
    }

    @Test
    public void testAddIssueWithWatchers() throws RedmineException {
        final Issue issue = IssueHelper.generateRandomIssue();

        final User newUserWatcher = userManager.createUser(UserGenerator.generateRandomUser());

        try {
            List<Watcher> watchers = new ArrayList<Watcher>();
            Watcher watcher = WatcherFactory.create(newUserWatcher.getId());
            watchers.add(watcher);

            issue.addWatchers(watchers);

            final Issue retrievedIssue = issueManager.createIssue(projectKey, issue);
            final Issue retrievedIssueWithWatchers =  issueManager.getIssueById(retrievedIssue.getId(), Include.watchers);

            assertNotNull(retrievedIssueWithWatchers);
            assertNotNull(retrievedIssueWithWatchers.getWatchers());
            assertEquals(watchers.size(), retrievedIssueWithWatchers.getWatchers().size());
            assertEquals(watcher.getId(), retrievedIssueWithWatchers.getWatchers().iterator().next().getId());
        } finally {
            userManager.deleteUser(newUserWatcher.getId());
        }
    }

    @Test
    public void testGetIssuesBySummary() {
        String summary = "issue with subject ABC";
        try {
            Issue issue = IssueFactory.createWithSubject(summary);
            User assignee = IntegrationTestHelper.getOurUser();
            issue.setAssignee(assignee);

            Issue newIssue = issueManager.createIssue(projectKey, issue);
            assertNotNull("Checking returned result", newIssue);
            assertNotNull("New issue must have some ID",
                    newIssue.getId());

            // try to find the issue
            List<Issue> foundIssues = issueManager.getIssuesBySummary(projectKey,
                    summary);

            assertNotNull("Checking if search results is not NULL",
                    foundIssues);
            assertTrue("Search results must be not empty",
                    !(foundIssues.isEmpty()));

            Issue loadedIssue1 = RedmineTestUtils.findIssueInList(foundIssues,
                    newIssue.getId());
            assertNotNull(loadedIssue1);
            assertEquals(summary, loadedIssue1.getSubject());
        } catch (Exception e) {
            e.printStackTrace();
            fail();
        }
    }

    @Test
    public void findByNonExistingSummaryReturnsEmptyList() {
        String summary = "some summary here for issue which does not exist";
        try {
            // try to find the issue
            List<Issue> foundIssues = issueManager.getIssuesBySummary(projectKey,
                    summary);
            assertNotNull("Search result must be not null", foundIssues);
            assertTrue("Search result list must be empty",
                    foundIssues.isEmpty());
        } catch (Exception e) {
            e.printStackTrace();
            fail();
        }
    }

    @Test(expected = RedmineAuthenticationException.class)
    public void noAPIKeyOnCreateIssueThrowsAE() throws Exception {
        TestConfig testConfig = new TestConfig();
        RedmineManager redmineMgrEmpty = RedmineManagerFactory.createUnauthenticated(testConfig.getURI());
        Issue issue = IssueFactory.createWithSubject("test zzx");
        redmineMgrEmpty.getIssueManager().createIssue(projectKey, issue);
    }

    @Test(expected = RedmineAuthenticationException.class)
    public void wrongAPIKeyOnCreateIssueThrowsAE() throws Exception {
        TestConfig testConfig = new TestConfig();
        RedmineManager redmineMgrInvalidKey = RedmineManagerFactory.createWithApiKey(
                testConfig.getURI(), "wrong_key");
        Issue issue = IssueFactory.createWithSubject("test zzx");
        redmineMgrInvalidKey.getIssueManager().createIssue(projectKey, issue);
    }

    @Test
    public void testIssueDoneRatio() {
        try {
            Issue issue = new Issue();
            String subject = "Issue " + new Date();
            issue.setSubject(subject);

            Issue createdIssue = issueManager.createIssue(projectKey, issue);
            assertEquals("Initial 'done ratio' must be 0", (Integer) 0,
                    createdIssue.getDoneRatio());
            Integer doneRatio = 50;
            createdIssue.setDoneRatio(doneRatio);
            issueManager.update(createdIssue);

            Integer issueId = createdIssue.getId();
            Issue reloadedFromRedmineIssue = issueManager.getIssueById(issueId);
            assertEquals(
                    "Checking if 'update issue' operation changed 'done ratio' field",
                    doneRatio, reloadedFromRedmineIssue.getDoneRatio());

            Integer invalidDoneRatio = 130;
            reloadedFromRedmineIssue.setDoneRatio(invalidDoneRatio);
            try {
                issueManager.update(reloadedFromRedmineIssue);
            } catch (RedmineProcessingException e) {
                assertEquals("Must be 1 error", 1, e.getErrors().size());
                assertEquals("Checking error text",
                        "% Done is not included in the list", e.getErrors()
                                .get(0));
            }

            Issue reloadedFromRedmineIssueUnchanged = issueManager.getIssueById(issueId);
            assertEquals(
                    "'done ratio' must have remained unchanged after invalid value",
                    doneRatio, reloadedFromRedmineIssueUnchanged.getDoneRatio());
        } catch (Exception e) {
            fail(e.toString());
        }
    }

    @Test
    public void testIssueNullDescriptionDoesNotEraseIt() {
        try {
            Issue issue = new Issue();
            String subject = "Issue " + new Date();
            String descr = "Some description";
            issue.setSubject(subject);
            issue.setDescription(descr);

            Issue createdIssue = issueManager.createIssue(projectKey, issue);
            assertEquals("Checking description", descr,
                    createdIssue.getDescription());

            createdIssue.setDescription(null);
            issueManager.update(createdIssue);

            Integer issueId = createdIssue.getId();
            Issue reloadedFromRedmineIssue = issueManager.getIssueById(issueId);
            assertEquals("Description must not be erased", descr,
                    reloadedFromRedmineIssue.getDescription());

            reloadedFromRedmineIssue.setDescription("");
            issueManager.update(reloadedFromRedmineIssue);

            Issue reloadedFromRedmineIssueUnchanged = issueManager.getIssueById(issueId);
            assertEquals("Description must be erased", "",
                    reloadedFromRedmineIssueUnchanged.getDescription());
        } catch (Exception e) {
            fail();
        }
    }

    @Test
    public void testIssueJournals() {
        try {
            // create at least 1 issue
            Issue issueToCreate = new Issue();
            issueToCreate.setSubject("testGetIssues: " + new Date());
            Issue newIssue = issueManager.createIssue(projectKey, issueToCreate);

            Issue loadedIssueWithJournals = issueManager.getIssueById(newIssue.getId(),
                    Include.journals);
            assertTrue(loadedIssueWithJournals.getJournals().isEmpty());

            String commentDescribingTheUpdate = "some comment describing the issue update";
            loadedIssueWithJournals.setSubject("new subject");
            loadedIssueWithJournals.setNotes(commentDescribingTheUpdate);
            issueManager.update(loadedIssueWithJournals);

            Issue loadedIssueWithJournals2 = issueManager.getIssueById(newIssue.getId(),
                    Include.journals);
            assertEquals(1, loadedIssueWithJournals2.getJournals()
                    .size());

            Journal journalItem = loadedIssueWithJournals2.getJournals().iterator().next();
            assertEquals(commentDescribingTheUpdate, journalItem.getNotes());
            User ourUser = IntegrationTestHelper.getOurUser();
            // can't compare User objects because either of them is not
            // completely filled
            assertEquals(ourUser.getId(), journalItem.getUser().getId());
            assertEquals(ourUser.getFirstName(), journalItem.getUser()
                    .getFirstName());
            assertEquals(ourUser.getLastName(), journalItem.getUser()
                    .getLastName());
            assertEquals(1, journalItem.getDetails().size());
            final JournalDetail journalDetail = journalItem.getDetails().get(0);
            assertEquals("new subject", journalDetail.getNewValue());
            assertEquals("subject", journalDetail.getName());
            assertEquals("attr", journalDetail.getProperty());

            Issue loadedIssueWithoutJournals = issueManager.getIssueById(newIssue.getId());
            assertTrue(loadedIssueWithoutJournals.getJournals().isEmpty());

        } catch (Exception e) {
            e.printStackTrace();
            fail(e.getMessage());
        }
    }
    @Test
    public void emptyDescriptionReturnedAsEmptyString() throws RedmineException {
        Issue issue = IssueFactory.createWithSubject("Issue " + new Date());
        Issue createdIssue = issueManager.createIssue(projectKey, issue);
        assertEquals("Description must be an empty string, not NULL", "",
                createdIssue.getDescription());
    }

    @Test
    public void updateIssueDescription() throws RedmineException {
        Issue issue = new Issue();
        issue.setSubject("test123");
        final Issue iss1 = issueManager.createIssue(projectKey, issue);
        final Issue iss2 = IssueFactory.create(iss1.getId());
        iss2.setDescription("This is a test");
        issueManager.update(iss2);
        final Issue iss3 = issueManager.getIssueById(iss2.getId());
        assertEquals("test123", iss3.getSubject());
        assertEquals("This is a test", iss3.getDescription());
    }

    @Test
    public void updateIssueTitle() throws RedmineException {
        Issue issue = new Issue();
        issue.setSubject("test123");
        issue.setDescription("Original description");
        final Issue iss1 = issueManager.createIssue(projectKey, issue);
        final Issue iss2 = IssueFactory.create(iss1.getId());
        iss2.setSubject("New subject");
        issueManager.update(iss2);
        final Issue iss3 = issueManager.getIssueById(iss2.getId());
        assertEquals("New subject", iss3.getSubject());
        assertEquals("Original description", iss3.getDescription());
    }

    /**
     * Test for issue 64 (time entry format)
     */
    @Test
    public void testTimeEntryComments() throws RedmineException {
        Issue issue = createIssues(issueManager, projectKey, 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 = issueManager.createTimeEntry(entry);

        assertNotNull(createdEntry);
        assertEquals(comment, createdEntry.getComment());

        createdEntry.setComment("New comment");
        issueManager.update(createdEntry);
        final TimeEntry updatedEntry = issueManager.getTimeEntry(createdEntry.getId());
        assertEquals("New comment", updatedEntry.getComment());
    }

    @Test
    public void testIssuePriorities() throws RedmineException {
        assertTrue(issueManager.getIssuePriorities().size() > 0);
    }

    @Test
    public void testTimeEntryActivities() throws RedmineException {
        assertTrue(issueManager.getTimeEntryActivities().size() > 0);
    }
    @Test
    public void testGetTimeEntries() throws RedmineException {
        List<TimeEntry> list = issueManager.getTimeEntries();
        assertNotNull(list);
    }

    @Test
    public void testCreateGetTimeEntry() throws RedmineException {
        Issue issue = createIssues(issueManager, projectKey, 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 = issueManager.createTimeEntry(entry);

        assertNotNull(createdEntry);
        logger.debug("Created time entry " + createdEntry);
        assertEquals(hours, createdEntry.getHours());

        Float newHours = 22f;
        createdEntry.setHours(newHours);

        issueManager.update(createdEntry);

        TimeEntry updatedEntry = issueManager.getTimeEntry(createdEntry.getId());
        assertEquals(newHours, updatedEntry.getHours());
    }

    @Test(expected = NotFoundException.class)
    public void testCreateDeleteTimeEntry() throws RedmineException {
        Issue issue = createIssues(issueManager, projectKey, 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 = issueManager.createTimeEntry(entry);
        assertNotNull(createdEntry);

        issueManager.deleteTimeEntry(createdEntry.getId());
        issueManager.getTimeEntry(createdEntry.getId());
    }

    @Test
    public void testGetTimeEntriesForIssue() throws RedmineException {
        Issue issue = createIssues(issueManager, projectKey, 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 = issueManager.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 {
        TimeEntry entry = TimeEntryFactory.create();
        entry.setHours(hours);
        entry.setIssueId(issueId);
        entry.setActivityId(ACTIVITY_ID);
        return issueManager.createTimeEntry(entry);
    }

    /**
     * this test is ignored because: 1) we can't create Versions. see
     * http://www.redmine.org/issues/9088 2) we don't currently set versions
     * when creating issues.
     * <p/>
     * 3) setting "fixed_version_id" does not work on creating issue.
     */
    @Ignore
    @Test
    public void issueFixVersionIsSet() throws Exception {

        String existingProjectKey = "test";
        Issue toCreate = IssueHelper.generateRandomIssue();
        Version v = VersionFactory.create(1);
        String versionName = "1.0";
        v.setName("1.0");
        v.setProject(mgr.getProjectManager().getProjectByKey(projectKey));
        v = mgr.getProjectManager().createVersion(v);
        toCreate.setTargetVersion(v);
        Issue createdIssue = issueManager.createIssue(existingProjectKey, toCreate);

        assertNotNull(createdIssue.getTargetVersion());
        assertEquals(createdIssue.getTargetVersion().getName(),
                versionName);
    }

    /**
     * Not supported by Redmine REST API.
     */
    @Ignore
    @Test
    public void testSpentTimeFieldLoaded() {
        try {
            Issue issue = new Issue();
            String subject = "Issue " + new Date();
            issue.setSubject(subject);
            float spentHours = 2;
            issue.setSpentHours(spentHours);

            Issue createdIssue = issueManager.createIssue(projectKey, issue);
            Issue newIssue = issueManager.getIssueById(createdIssue.getId());
            assertEquals((Float) spentHours, newIssue.getSpentHours());
        } catch (Exception e) {
            fail();
        }
    }

    @Test(expected = IllegalArgumentException.class)
    public void invalidTimeEntryFailsWithIAEOnCreate() throws RedmineException {
        issueManager.createTimeEntry(createIncompleteTimeEntry());
    }

    @Test(expected = IllegalArgumentException.class)
    public void invalidTimeEntryFailsWithIAEOnUpdate() throws RedmineException {
        issueManager.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_issue66()
            throws RedmineException {
        TimeEntry timeEntry = createIncompleteTimeEntry();
        // Now can try to verify with project ID (only test with issue ID seems
        // to be already covered)
        int projectId = mgr.getProjectManager().getProjects().get(0).getId();
        timeEntry.setProjectId(projectId);
        try {
            TimeEntry created = issueManager.createTimeEntry(timeEntry);
            logger.debug("Created time entry " + created);
        } catch (Exception e) {
            e.printStackTrace();
            fail("Unexpected " + e.getClass().getSimpleName() + ": "
                    + e.getMessage());
        }
    }

    @Test
    public void testUpdateIssueDoesNotChangeEstimatedTime() {
        try {
            Issue issue = new Issue();
            String originalSubject = "Issue " + new Date();
            issue.setSubject(originalSubject);

            Issue newIssue = issueManager.createIssue(projectKey, issue);
            assertEquals("Estimated hours must be NULL", null,
                    newIssue.getEstimatedHours());

            issueManager.update(newIssue);

            Issue reloadedFromRedmineIssue = issueManager.getIssueById(newIssue.getId());
            assertEquals("Estimated hours must be NULL", null,
                    reloadedFromRedmineIssue.getEstimatedHours());
        } catch (Exception e) {
            fail();
        }
    }

    /**
     * tests the retrieval of statuses.
     *
     * @throws RedmineProcessingException     thrown in case something went wrong in Redmine
     * @throws java.io.IOException                    thrown in case something went wrong while performing I/O
     *                                        operations
     * @throws RedmineAuthenticationException thrown in case something went wrong while trying to login
     * @throws NotFoundException              thrown in case the objects requested for could not be found
     */
    @Test
    public void testGetStatuses() throws RedmineException {
        // TODO we should create some statuses first, but the Redmine Java API
        // does not support this presently
        List<IssueStatus> statuses = issueManager.getStatuses();
        assertFalse("Expected list of statuses not to be empty",
                statuses.isEmpty());
        for (IssueStatus issueStatus : statuses) {
            // asserts on status
            assertNotNull("ID of status must not be null", issueStatus.getId());
            assertNotNull("Name of status must not be null",
                    issueStatus.getName());
        }
    }

    /**
     * tests the creation and deletion of a {@link com.taskadapter.redmineapi.bean.IssueCategory}.
     *
     * @throws RedmineException               thrown in case something went wrong in Redmine
     * @throws java.io.IOException                    thrown in case something went wrong while performing I/O
     *                                        operations
     * @throws RedmineAuthenticationException thrown in case something went wrong while trying to login
     * @throws NotFoundException              thrown in case the objects requested for could not be found
     */
    @Test
    public void testCreateAndDeleteIssueCategory() throws RedmineException {
        Project project = projectManager.getProjectByKey(projectKey);
        IssueCategory category = IssueCategoryFactory.create(project, "Category" + new Date().getTime());
        category.setAssignee(IntegrationTestHelper.getOurUser());
        IssueCategory newIssueCategory = issueManager.createCategory(category);
        assertNotNull("Expected new category not to be null", newIssueCategory);
        assertNotNull("Expected project of new category not to be null", newIssueCategory.getProject());
        assertNotNull("Expected assignee of new category not to be null",
                newIssueCategory.getAssignee());
        // now delete category
        issueManager.deleteCategory(newIssueCategory);
        // assert that the category is gone
        List<IssueCategory> categories = issueManager.getCategories(project.getId());
        assertTrue(
                "List of categories of test project must be empty now but is "
                        + categories, categories.isEmpty());
    }

    /**
     * tests the retrieval of {@link IssueCategory}s.
     *
     * @throws RedmineException               thrown in case something went wrong in Redmine
     * @throws java.io.IOException                    thrown in case something went wrong while performing I/O
     *                                        operations
     * @throws RedmineAuthenticationException thrown in case something went wrong while trying to login
     * @throws NotFoundException              thrown in case the objects requested for could not be found
     */
    @Test
    public void testGetIssueCategories() throws RedmineException {
        Project project = projectManager.getProjectByKey(projectKey);
        // create some categories
        IssueCategory testIssueCategory1 = IssueCategoryFactory.create(project,
                "Category" + new Date().getTime());
        testIssueCategory1.setAssignee(IntegrationTestHelper.getOurUser());
        IssueCategory newIssueCategory1 = issueManager.createCategory(testIssueCategory1);
        IssueCategory testIssueCategory2 = IssueCategoryFactory.create(project,
                "Category" + new Date().getTime());
        testIssueCategory2.setAssignee(IntegrationTestHelper.getOurUser());
        IssueCategory newIssueCategory2 = issueManager.createCategory(testIssueCategory2);
        try {
            List<IssueCategory> categories = issueManager.getCategories(project.getId());
            assertEquals("Wrong number of categories for project "
                            + project.getName() + " delivered by Redmine Java API", 2,
                    categories.size());
            for (IssueCategory category : categories) {
                // assert category
                assertNotNull("ID of category must not be null",
                        category.getId());
                assertNotNull("Name of category must not be null",
                        category.getName());
                assertNotNull("Project of category must not be null",
                        category.getProject());
                assertNotNull("Assignee of category must not be null",
                        category.getAssignee());
            }
        } finally {
            // scrub test categories
            if (newIssueCategory1 != null) {
                issueManager.deleteCategory(newIssueCategory1);
            }
            if (newIssueCategory2 != null) {
                issueManager.deleteCategory(newIssueCategory2);
            }
        }
    }

    /**
     * tests the creation of an invalid {@link IssueCategory}.
     *
     * @throws RedmineException               thrown in case something went wrong in Redmine
     * @throws java.io.IOException                    thrown in case something went wrong while performing I/O
     *                                        operations
     * @throws RedmineAuthenticationException thrown in case something went wrong while trying to login
     * @throws NotFoundException              thrown in case the objects requested for could not be found
     */
    @Test(expected = IllegalArgumentException.class)
    public void testCreateInvalidIssueCategory() throws RedmineException {
        IssueCategory category = IssueCategoryFactory.create(null, "InvalidCategory"
                + new Date().getTime());
        issueManager.createCategory(category);
    }

    /**
     * tests the deletion of an invalid {@link IssueCategory}. Expects a
     * {@link NotFoundException} to be thrown.
     *
     * @throws RedmineException               thrown in case something went wrong in Redmine
     * @throws java.io.IOException                    thrown in case something went wrong while performing I/O
     *                                        operations
     * @throws RedmineAuthenticationException thrown in case something went wrong while trying to login
     * @throws NotFoundException              thrown in case the objects requested for could not be found
     */
    @Test(expected = NotFoundException.class)
    public void testDeleteInvalidIssueCategory() throws RedmineException {
        // create new test category
        IssueCategory category = IssueCategoryFactory.create(-1);
        category.setName("InvalidCategory" + new Date().getTime());
        // now try deleting the category
        issueManager.deleteCategory(category);
    }

    /**
     * Tests the creation and retrieval of an
     * {@link com.taskadapter.redmineapi.bean.Issue} with a
     * {@link IssueCategory}.
     *
     * @throws RedmineException               thrown in case something went wrong in Redmine
     * @throws java.io.IOException                    thrown in case something went wrong while performing I/O
     *                                        operations
     * @throws RedmineAuthenticationException thrown in case something went wrong while trying to login
     * @throws NotFoundException              thrown in case the objects requested for could not be found
     */
    @Test
    public void testCreateAndGetIssueWithCategory() throws RedmineException {
        IssueCategory newIssueCategory = null;
        Issue newIssue = null;
        try {
            Project project = projectManager.getProjectByKey(projectKey);
            // create an issue category
            IssueCategory category = IssueCategoryFactory.create(project, "Category_"
                    + new Date().getTime());
            category.setAssignee(IntegrationTestHelper.getOurUser());
            newIssueCategory = issueManager.createCategory(category);
            // create an issue
            Issue issueToCreate = IssueFactory.createWithSubject("getIssueWithCategory_" + UUID.randomUUID());
            issueToCreate.setCategory(newIssueCategory);
            newIssue = issueManager.createIssue(projectKey, issueToCreate);
            // retrieve issue
            Issue retrievedIssue = issueManager.getIssueById(newIssue.getId());
            // assert retrieved category of issue
            IssueCategory retrievedCategory = retrievedIssue.getCategory();
            assertNotNull("Category retrieved for issue " + newIssue.getId()
                    + " should not be null", retrievedCategory);
            assertEquals("ID of category retrieved for issue "
                            + newIssue.getId() + " is wrong", newIssueCategory.getId(),
                    retrievedCategory.getId());
            assertEquals("Name of category retrieved for issue "
                            + newIssue.getId() + " is wrong",
                    newIssueCategory.getName(), retrievedCategory.getName());
        } finally {
            if (newIssue != null) {
                issueManager.deleteIssue(newIssue.getId());
            }
            if (newIssueCategory != null) {
                issueManager.deleteCategory(newIssueCategory);
            }
        }
    }

    @Test
    public void nullStartDateIsPreserved() {
        try {
            Issue issue = IssueFactory.createWithSubject("test start date");
            issue.setStartDate(null);

            Issue newIssue = issueManager.createIssue(projectKey, issue);

            Issue loadedIssue = issueManager.getIssueById(newIssue.getId());
            assertNull(loadedIssue.getStartDate());
        } catch (Exception e) {
            e.printStackTrace();
            fail();
        }
    }

    /**
     * The custom fields used here MUST ALREADY EXIST on the server and be
     * associated with the required task type (bug/feature/task/..).
     * <p/>
     * See feature request http://www.redmine.org/issues/9664
     */
    @Test
    public void testCustomFields() throws Exception {
        Issue issue = createIssues(issueManager, projectKey, 1).get(0);
        // default empty values
        assertThat(issue.getCustomFields().size()).isEqualTo(2);

        // TODO update this!
        int id1 = 1; // TODO this is pretty much a hack, we don't generally know
        // these ids!
        String custom1FieldName = "my_custom_1";
        String custom1Value = "some value 123";

        int id2 = 2;
        String custom2FieldName = "custom_boolean_1";
        String custom2Value = "true";

        issue.clearCustomFields();

        issue.addCustomField(CustomFieldFactory.create(id1, custom1FieldName, custom1Value));
        issue.addCustomField(CustomFieldFactory.create(id2, custom2FieldName, custom2Value));
        issueManager.update(issue);

        Issue updatedIssue = issueManager.getIssueById(issue.getId());
        assertThat(updatedIssue.getCustomFields().size()).isEqualTo(2);
        assertEquals(custom1Value,
                updatedIssue.getCustomField(custom1FieldName));
        assertEquals(custom2Value,
                updatedIssue.getCustomField(custom2FieldName));
    }

    @Ignore
    @Test
    public void testChangesets() throws RedmineException {
        final Issue issue = issueManager.getIssueById(89, Include.changesets);
        assertThat(issue.getChangesets().size()).isEqualTo(2);
        final Changeset firstChange = issue.getChangesets().iterator().next();
        assertNotNull(firstChange.getComments());
    }

    /**
     * Tests the retrieval of {@link Tracker}s.
     *
     * @throws RedmineException               thrown in case something went wrong in Redmine
     * @throws RedmineAuthenticationException thrown in case something went wrong while trying to login
     * @throws NotFoundException              thrown in case the objects requested for could not be found
     */
    @Test
    public void testGetTrackers() throws RedmineException {
        List<Tracker> trackers = issueManager.getTrackers();
        assertNotNull("List of trackers returned should not be null", trackers);
        assertFalse("List of trackers returned should not be empty",
                trackers.isEmpty());
        for (Tracker tracker : trackers) {
            assertNotNull("Tracker returned should not be null", tracker);
            assertNotNull("ID of tracker returned should not be null",
                    tracker.getId());
            assertNotNull("Name of tracker returned should not be null",
                    tracker.getName());
        }
    }

    @Test
    public void getSavedQueriesDoesNotFailForTempProject()
            throws RedmineException {
        issueManager.getSavedQueries(projectKey);
    }

    @Test
    public void getSavedQueriesDoesNotFailForNULLProject()
            throws RedmineException {
        issueManager.getSavedQueries(null);
    }

    @Ignore("This test requires a specific project configuration")
    @Test
    public void testSavedQueries() throws RedmineException {
        final Collection<SavedQuery> queries = issueManager.getSavedQueries("test");
        assertTrue(queries.size() > 0);
    }

    @Test
    public void statusIsUpdated() throws RedmineException {
        Issue issue = createIssues(issueManager, projectKey, 1).get(0);
        Issue retrievedIssue = issueManager.getIssueById(issue.getId());
        Integer initialStatusId = retrievedIssue.getStatusId();

        List<IssueStatus> statuses = issueManager.getStatuses();
        // get some status ID that is not equal to the initial one
        Integer newStatusId = null;
        for (IssueStatus status : statuses) {
            if (!status.getId().equals(initialStatusId)) {
                newStatusId = status.getId();
                break;
            }
        }
        if (newStatusId == null) {
            throw new RuntimeException("can't run this test: no Issue Statuses are available except for the initial one");
        }
        retrievedIssue.setStatusId(newStatusId);
        issueManager.update(retrievedIssue);

        Issue issueWithUpdatedStatus = issueManager.getIssueById(retrievedIssue.getId());
        assertThat(issueWithUpdatedStatus.getStatusId()).isEqualTo(newStatusId);
    }
}
TOP

Related Classes of com.taskadapter.redmineapi.IssueManagerTest

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