From 64712e23be004cb3fe6c81527ec2cfef0cd654a0 Mon Sep 17 00:00:00 2001 From: Mikhail Golubev Date: Wed, 20 Jan 2016 18:34:07 +0300 Subject: [PATCH] IDEA-101238 Add test case to check time tracking and that work item comment can contain spaces --- .../tasks/youtrack/YouTrackRepository.java | 6 ++ .../intellij/tasks/TaskManagerTestCase.java | 20 +++++ .../integration/JiraIntegrationTest.java | 17 ++-- .../integration/YouTrackIntegrationTest.java | 85 +++++++++++++++++++ 4 files changed, 116 insertions(+), 12 deletions(-) diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/youtrack/YouTrackRepository.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/youtrack/YouTrackRepository.java index 404e76ca7bba..32a25e982cd4 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/youtrack/YouTrackRepository.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/youtrack/YouTrackRepository.java @@ -385,4 +385,10 @@ public class YouTrackRepository extends BaseRepositoryImpl { protected int getFeatures() { return super.getFeatures() | TIME_MANAGEMENT | STATE_UPDATING; } + + @TestOnly + @Override + public HttpClient getHttpClient() { + return super.getHttpClient(); + } } diff --git a/plugins/tasks/tasks-tests/test/com/intellij/tasks/TaskManagerTestCase.java b/plugins/tasks/tasks-tests/test/com/intellij/tasks/TaskManagerTestCase.java index 895b92ae8b4e..f51fe1dbb568 100644 --- a/plugins/tasks/tasks-tests/test/com/intellij/tasks/TaskManagerTestCase.java +++ b/plugins/tasks/tasks-tests/test/com/intellij/tasks/TaskManagerTestCase.java @@ -15,16 +15,25 @@ */ package com.intellij.tasks; +import com.intellij.openapi.util.Couple; import com.intellij.tasks.impl.TaskManagerImpl; import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase; +import org.jetbrains.annotations.NotNull; +import java.text.SimpleDateFormat; import java.util.Collections; import java.util.List; +import java.util.TimeZone; /** * @author Dmitry Avdeev */ public abstract class TaskManagerTestCase extends LightCodeInsightFixtureTestCase { + protected static final SimpleDateFormat SHORT_TIMESTAMP_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm"); + static { + SHORT_TIMESTAMP_FORMAT.setTimeZone(TimeZone.getTimeZone("UTC")); + } + protected TaskManager myTaskManager; @Override @@ -52,4 +61,15 @@ public abstract class TaskManagerTestCase extends LightCodeInsightFixtureTestCas myTaskManager.removeTask(task); } } + + /** + * @return semi-random duration for a work item in the range [1m, 4h 0m] + */ + @NotNull + protected Couple generateWorkItemDuration() { + // semi-unique duration as timeSpend + // should be no longer than 8 hours in total, because it's considered as one full day + final int minutes = (int)(System.currentTimeMillis() % 240) + 1; + return Couple.of(minutes / 60, minutes % 60); + } } diff --git a/plugins/tasks/tasks-tests/test/com/intellij/tasks/integration/JiraIntegrationTest.java b/plugins/tasks/tasks-tests/test/com/intellij/tasks/integration/JiraIntegrationTest.java index c68149030908..0fea529cece0 100644 --- a/plugins/tasks/tasks-tests/test/com/intellij/tasks/integration/JiraIntegrationTest.java +++ b/plugins/tasks/tasks-tests/test/com/intellij/tasks/integration/JiraIntegrationTest.java @@ -18,6 +18,7 @@ package com.intellij.tasks.integration; import com.google.gson.Gson; import com.google.gson.JsonArray; import com.google.gson.JsonObject; +import com.intellij.openapi.util.Couple; import com.intellij.tasks.*; import com.intellij.tasks.config.TaskSettings; import com.intellij.tasks.impl.LocalTaskImpl; @@ -37,7 +38,6 @@ import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import java.net.URL; -import java.text.SimpleDateFormat; import java.util.*; import static com.intellij.tasks.jira.JiraRemoteApi.ApiType.REST_2_0; @@ -59,11 +59,6 @@ public class JiraIntegrationTest extends TaskManagerTestCase { */ @NonNls private static final String JIRA_5_TEST_SERVER_URL = "http://trackers-tests.labs.intellij.net:8015"; - private static final SimpleDateFormat SHORT_TIMESTAMP_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm"); - static { - SHORT_TIMESTAMP_FORMAT.setTimeZone(TimeZone.getTimeZone("UTC")); - } - private JiraRepository myRepository; public void testGerman() throws Exception { @@ -209,12 +204,10 @@ public class JiraIntegrationTest extends TaskManagerTestCase { // timestamp as comment final String comment = "Timestamp: " + TaskUtil.formatDate(new Date()); + final Couple duration = generateWorkItemDuration(); - // semi-unique duration as timeSpend - // should be no longer than 8 hours in total, because it's considered as one full day - final int minutes = (int)(System.currentTimeMillis() % 240) + 1; - final String duration = String.format("%dh %dm", minutes / 60, minutes % 60); - myRepository.updateTimeSpent(new LocalTaskImpl(task), duration, comment); + final int hours = duration.getFirst(), minutes = duration.getSecond(); + myRepository.updateTimeSpent(new LocalTaskImpl(task), String.format("%dh %dm", hours, minutes), comment); final GetMethod request = new GetMethod(myRepository.getRestUrl("issue", task.getId(), "worklog")); final String response = myRepository.executeMethod(request); @@ -224,7 +217,7 @@ public class JiraIntegrationTest extends TaskManagerTestCase { assertEquals(comment, last.get("comment").getAsString()); // don't depend on concrete response format: zero hours stripping, zero padding and so on - assertEquals(minutes * 60, last.get("timeSpentSeconds").getAsInt()); + assertEquals((hours * 60 + minutes) * 60, last.get("timeSpentSeconds").getAsInt()); } public void testParseVersionNumbers() throws Exception { diff --git a/plugins/tasks/tasks-tests/test/com/intellij/tasks/integration/YouTrackIntegrationTest.java b/plugins/tasks/tasks-tests/test/com/intellij/tasks/integration/YouTrackIntegrationTest.java index f4577b8b1327..0d8f0aca9e74 100644 --- a/plugins/tasks/tasks-tests/test/com/intellij/tasks/integration/YouTrackIntegrationTest.java +++ b/plugins/tasks/tasks-tests/test/com/intellij/tasks/integration/YouTrackIntegrationTest.java @@ -1,14 +1,29 @@ package com.intellij.tasks.integration; +import com.intellij.openapi.util.Couple; +import com.intellij.openapi.util.JDOMUtil; import com.intellij.tasks.CustomTaskState; import com.intellij.tasks.Task; import com.intellij.tasks.TaskManagerTestCase; +import com.intellij.tasks.impl.LocalTaskImpl; import com.intellij.tasks.youtrack.YouTrackRepository; import com.intellij.tasks.youtrack.YouTrackRepositoryType; import com.intellij.util.Function; +import com.intellij.util.PathUtil; import com.intellij.util.containers.ContainerUtil; +import org.apache.commons.httpclient.Header; +import org.apache.commons.httpclient.HttpClient; +import org.apache.commons.httpclient.HttpStatus; +import org.apache.commons.httpclient.NameValuePair; +import org.apache.commons.httpclient.methods.GetMethod; +import org.apache.commons.httpclient.methods.PostMethod; +import org.apache.commons.httpclient.methods.PutMethod; import org.jdom.Element; +import org.jdom.JDOMException; +import org.jetbrains.annotations.NotNull; +import java.io.IOException; +import java.util.Date; import java.util.List; import java.util.Set; @@ -48,6 +63,76 @@ public class YouTrackIntegrationTest extends TaskManagerTestCase { assertEquals("Submitted", element.getAttributeValue("state")); } + // IDEA-101238 + public void testTimeTracking() throws Exception { + final HttpClient client = myRepository.getHttpClient(); + authenticate(client); + final String issueId = createIssue(client); + final Task task = myRepository.findTask(issueId); + assertNotNull(task); + final Couple duration = generateWorkItemDuration(); + final String spentTime = formatDuration(duration.getFirst(), duration.getSecond()); + myRepository.updateTimeSpent(new LocalTaskImpl(task), spentTime, "Foo Bar"); + checkSpentTime(client, issueId, spentTime); + } + + @NotNull + private static String formatDuration(int hours, int minutes) { + final String spentTime; + if (hours == 0) { + spentTime = minutes + "m"; + } + else if (minutes == 0) { + spentTime = hours + "h"; + } + else { + spentTime = String.format("%dh%dm", hours, minutes); + } + return spentTime; + } + + private void authenticate(@NotNull HttpClient client) throws IOException { + PostMethod method = new PostMethod(myRepository.getUrl() + "/rest/user/login"); + method.addParameter("login", myRepository.getUsername()); + method.addParameter("password", myRepository.getPassword()); + final int statusCode = client.executeMethod(method); + assertEquals(HttpStatus.SC_OK, statusCode); + } + + @NotNull + private String createIssue(@NotNull HttpClient client) throws IOException { + // http PUT "http://trackers-tests.labs.intellij.net:8067/rest/issue" project==BTYT4TT "summary==First issue created via REST API" + final PutMethod method = new PutMethod(myRepository.getUrl() + "/rest/issue"); + method.setQueryString(new NameValuePair[] { + new NameValuePair("project", "BTYT4TT"), + new NameValuePair("summary", "Test issue for time tracking updates (" + SHORT_TIMESTAMP_FORMAT.format(new Date()) + ")") + }); + final int statusCode = client.executeMethod(method); + assertEquals(HttpStatus.SC_CREATED, statusCode); + final Header locationHeader = method.getResponseHeader("Location"); + assertNotNull(locationHeader); + // Otherwise there will be timeout on connection acquiring + method.releaseConnection(); + return PathUtil.getFileName(locationHeader.getValue()); + } + + private void checkSpentTime(@NotNull HttpClient client, @NotNull String issueId, @NotNull String expectedTime) throws IOException, JDOMException { + // Endpoint /rest/issue/BTYT4TT-8/timetracking/workitem/ doesn't work on this instance of YouTrack for some reason + final GetMethod method = new GetMethod(myRepository.getUrl() + "/rest/issue/" + issueId); + final int statusCode = client.executeMethod(method); + assertEquals(HttpStatus.SC_OK, statusCode); + final Element root = JDOMUtil.load(method.getResponseBodyAsStream()); + for (Element field : root.getChildren("field")) { + if ("Spent time".equals(field.getAttributeValue("name"))) { + final Element value = field.getChild("value"); + assertNotNull(value); + assertEquals(expectedTime, value.getText().trim()); + return; + } + } + fail("Field 'Spent time' not found in issue " + issueId); + } + @Override protected void setUp() throws Exception { super.setUp();