Commit f037b52e1893522913e86018c987907ee325ced9

Authored by bernard
1 parent f15e87e9

Execute command on issue.

Refactored Filter.
  1 +package pl.com.it_crowd.youtrack.api;
  2 +
  3 +import pl.com.it_crowd.youtrack.api.defaults.Fields;
  4 +import pl.com.it_crowd.youtrack.api.defaults.StateValues;
  5 +
  6 +public class Command {
  7 +// ------------------------------ FIELDS ------------------------------
  8 +
  9 + protected StringBuilder command = new StringBuilder();
  10 +
  11 +// -------------------------- STATIC METHODS --------------------------
  12 +
  13 + public static Command assigneeCommand(String assignee)
  14 + {
  15 + return new Command().assignee(assignee);
  16 + }
  17 +
  18 + public static Command stateCommand(String state)
  19 + {
  20 + return new Command().state(state);
  21 + }
  22 +
  23 + public static Command stateCommand(StateValues state)
  24 + {
  25 + return new Command().state(state);
  26 + }
  27 +
  28 +// --------------------------- CONSTRUCTORS ---------------------------
  29 +
  30 + private Command()
  31 + {
  32 + }
  33 +
  34 +// ------------------------ CANONICAL METHODS ------------------------
  35 +
  36 + @Override
  37 + public String toString()
  38 + {
  39 + return command.toString().trim();
  40 + }
  41 +
  42 +// -------------------------- OTHER METHODS --------------------------
  43 +
  44 + public Command assignee(String assignee)
  45 + {
  46 + return command(Fields.assignee, assignee);
  47 + }
  48 +
  49 + public Command state(String state)
  50 + {
  51 + return command(Fields.state, state);
  52 + }
  53 +
  54 + public Command state(StateValues state)
  55 + {
  56 + if (state.getCommandValue() == null) {
  57 + throw new IllegalArgumentException("Cannot set readonly state: " + state);
  58 + }
  59 + return state(state.getCommandValue());
  60 + }
  61 +
  62 + private Command command(Fields command, String argument)
  63 + {
  64 + this.command.append(" ").append(command.getCommand()).append(" ").append(argument);
  65 + return this;
  66 + }
  67 +}
1 package pl.com.it_crowd.youtrack.api; 1 package pl.com.it_crowd.youtrack.api;
2 2
  3 +import pl.com.it_crowd.youtrack.api.defaults.DateValues;
  4 +import pl.com.it_crowd.youtrack.api.defaults.Fields;
  5 +import pl.com.it_crowd.youtrack.api.defaults.StateValues;
  6 +
3 import java.io.UnsupportedEncodingException; 7 import java.io.UnsupportedEncodingException;
4 import java.net.URLEncoder; 8 import java.net.URLEncoder;
5 import java.util.ArrayList; 9 import java.util.ArrayList;
6 import java.util.List; 10 import java.util.List;
7 11
8 -public final class FilterHelper { 12 +public final class Filter {
  13 +// ------------------------------ FIELDS ------------------------------
  14 +
  15 + private List<Condition> conditions = new ArrayList<Condition>();
  16 +
  17 + private long maxResults;
  18 +
9 // -------------------------- STATIC METHODS -------------------------- 19 // -------------------------- STATIC METHODS --------------------------
10 20
11 - public static Filter issueId(String issueId) 21 + public static Filter createdFilter(String date)
  22 + {
  23 + return new Filter().created(date);
  24 + }
  25 +
  26 + public static Filter createdFilter(DateValues date)
  27 + {
  28 + return new Filter().created(date);
  29 + }
  30 +
  31 + public static Filter descriptionFilter(String description)
  32 + {
  33 + return new Filter().description(description);
  34 + }
  35 +
  36 + public static Filter issueIdFilter(String issueId)
12 { 37 {
13 return new Filter().issueId(issueId); 38 return new Filter().issueId(issueId);
14 } 39 }
15 40
16 - public static Filter summary(String summary) 41 + public static Filter projectFilter(String project)
17 { 42 {
18 - return new Filter().summary(summary); 43 + return new Filter().project(project);
19 } 44 }
20 45
21 - public static Filter unresolved() 46 + public static Filter reporterFilter(String reporter)
22 { 47 {
23 - return new Filter().unresolved(); 48 + return new Filter().reporter(reporter);
24 } 49 }
25 50
26 -// --------------------------- CONSTRUCTORS --------------------------- 51 + public static Filter resolvedFilter(String date)
  52 + {
  53 + return new Filter().resolved(date);
  54 + }
27 55
28 - private FilterHelper() 56 + public static Filter resolvedFilter(DateValues date)
29 { 57 {
  58 + return new Filter().resolved(date);
  59 + }
30 60
  61 + public static Filter stateFilter(StateValues state)
  62 + {
  63 + return new Filter().state(state);
31 } 64 }
32 65
33 -// -------------------------- INNER CLASSES -------------------------- 66 + public static Filter stateFilter(String state)
  67 + {
  68 + return new Filter().state(state);
  69 + }
34 70
35 - public static class Filter {  
36 -// ------------------------------ FIELDS ------------------------------ 71 + public static Filter summaryFilter(String summary)
  72 + {
  73 + return new Filter().summary(summary);
  74 + }
  75 +
  76 + public static Filter unresolvedFilter()
  77 + {
  78 + return new Filter().unresolved();
  79 + }
  80 +
  81 + public static Filter updatedFilter(String date)
  82 + {
  83 + return new Filter().updated(date);
  84 + }
37 85
38 - private List<Condition> conditions = new ArrayList<Condition>(); 86 + public static Filter updatedFilter(DateValues date)
  87 + {
  88 + return new Filter().updated(date);
  89 + }
39 90
40 - private long maxResults; 91 + public static Filter updaterFilter(String updater)
  92 + {
  93 + return new Filter().updater(updater);
  94 + }
41 95
42 // --------------------------- CONSTRUCTORS --------------------------- 96 // --------------------------- CONSTRUCTORS ---------------------------
43 97
44 - private Filter()  
45 - { 98 + private Filter()
  99 + {
46 100
47 - } 101 + }
48 102
49 // ------------------------ CANONICAL METHODS ------------------------ 103 // ------------------------ CANONICAL METHODS ------------------------
50 104
51 - @Override  
52 - public String toString()  
53 - {  
54 - StringBuilder builder = new StringBuilder();  
55 - String space; 105 + @Override
  106 + public String toString()
  107 + {
  108 + StringBuilder builder = new StringBuilder();
  109 + String space;
  110 + try {
  111 + space = URLEncoder.encode(" ", "UTF-8");
  112 + } catch (UnsupportedEncodingException e) {
  113 + throw new RuntimeException(e);
  114 + }
  115 + for (Condition condition : conditions) {
  116 + builder.append(space);
  117 + if (condition.field != null) {
  118 + builder.append(condition.field.getCommand());
  119 + builder.append(":");
  120 + }
56 try { 121 try {
57 - space = URLEncoder.encode(" ", "UTF-8"); 122 + builder.append(URLEncoder.encode(condition.value, "UTF-8"));
58 } catch (UnsupportedEncodingException e) { 123 } catch (UnsupportedEncodingException e) {
59 throw new RuntimeException(e); 124 throw new RuntimeException(e);
60 } 125 }
61 - for (Condition condition : conditions) {  
62 - builder.append(space);  
63 - if (condition.key != null) {  
64 - builder.append(condition.key);  
65 - builder.append(":");  
66 - }  
67 - try {  
68 - builder.append(URLEncoder.encode(condition.value, "UTF-8"));  
69 - } catch (UnsupportedEncodingException e) {  
70 - throw new RuntimeException(e);  
71 - }  
72 - }  
73 - if (maxResults > 0) {  
74 - builder.append("&max=").append(maxResults);  
75 - }  
76 - return builder.toString().trim();  
77 } 126 }
  127 + if (maxResults > 0) {
  128 + builder.append("&max=").append(maxResults);
  129 + }
  130 + return builder.length() > space.length() ? builder.substring(space.length()) : builder.toString();
  131 + }
78 132
79 // -------------------------- OTHER METHODS -------------------------- 133 // -------------------------- OTHER METHODS --------------------------
80 134
81 - public Filter issueId(String issueId)  
82 - {  
83 - conditions.add(new Condition(Key.ISSUE_ID, issueId));  
84 - return this;  
85 - } 135 + public Filter created(DateValues date)
  136 + {
  137 + return created(date.getFilterValue());
  138 + }
86 139
87 - public Filter maxResults(long maxResults)  
88 - {  
89 - this.maxResults = maxResults;  
90 - return this;  
91 - } 140 + public Filter created(String date)
  141 + {
  142 + conditions.add(new Condition(Fields.created, date));
  143 + return this;
  144 + }
92 145
93 - public Filter summary(String summary)  
94 - {  
95 - conditions.add(new Condition(null, summary));  
96 - return this;  
97 - } 146 + public Filter description(String description)
  147 + {
  148 + conditions.add(new Condition(Fields.description, description));
  149 + return this;
  150 + }
98 151
99 - public Filter unresolved()  
100 - {  
101 - conditions.add(new Condition(Key.STATE, "Unresolved"));  
102 - return this;  
103 - } 152 + public Filter freeText(String text)
  153 + {
  154 + conditions.add(new Condition(null, text));
  155 + return this;
  156 + }
104 157
105 -// -------------------------- ENUMERATIONS -------------------------- 158 + public Filter issueId(String issueId)
  159 + {
  160 + conditions.add(new Condition(Fields.issueId, issueId));
  161 + return this;
  162 + }
106 163
107 - private enum Key {  
108 - ISSUE_ID("issue id"),  
109 - STATE("state"); 164 + public Filter maxResults(long maxResults)
  165 + {
  166 + this.maxResults = maxResults;
  167 + return this;
  168 + }
110 169
111 -// ------------------------------ FIELDS ------------------------------ 170 + public Filter project(String project)
  171 + {
  172 + conditions.add(new Condition(Fields.projectShortName, project));
  173 + return this;
  174 + }
112 175
113 - private String key; 176 + public Filter reporter(String reporter)
  177 + {
  178 + conditions.add(new Condition(Fields.reporterName, reporter));
  179 + return this;
  180 + }
114 181
115 -// --------------------------- CONSTRUCTORS --------------------------- 182 + public Filter resolved(DateValues date)
116 183
117 - Key(String key)  
118 - {  
119 - this.key = key;  
120 - } 184 + {
  185 + return resolved(date.getFilterValue());
  186 + }
121 187
122 -// ------------------------ CANONICAL METHODS ------------------------ 188 + public Filter resolved(String date)
  189 + {
  190 + conditions.add(new Condition(Fields.resolved, date));
  191 + return this;
  192 + }
123 193
124 - @Override  
125 - public String toString()  
126 - {  
127 - return key;  
128 - }  
129 - } 194 + public Filter state(StateValues state)
  195 + {
  196 + return state(state.getFilterValue());
  197 + }
  198 +
  199 + public Filter summary(String summary)
  200 + {
  201 + conditions.add(new Condition(Fields.summary, summary));
  202 + return this;
  203 + }
  204 +
  205 + public Filter unresolved()
  206 + {
  207 + conditions.add(new Condition(Fields.state, StateValues.Unresolved.getFilterValue()));
  208 + return this;
  209 + }
  210 +
  211 + public Filter updated(DateValues date)
  212 + {
  213 + return updated(date.getFilterValue());
  214 + }
  215 +
  216 + public Filter updated(String date)
  217 + {
  218 + conditions.add(new Condition(Fields.updated, date));
  219 + return this;
  220 + }
  221 +
  222 + public Filter updater(String updater)
  223 + {
  224 + conditions.add(new Condition(Fields.updaterName, updater));
  225 + return this;
  226 + }
  227 +
  228 + private Filter state(String state)
  229 + {
  230 + conditions.add(new Condition(Fields.state, state));
  231 + return this;
  232 + }
130 233
131 // -------------------------- INNER CLASSES -------------------------- 234 // -------------------------- INNER CLASSES --------------------------
132 235
133 - private class Condition { 236 + private class Condition {
134 // ------------------------------ FIELDS ------------------------------ 237 // ------------------------------ FIELDS ------------------------------
135 238
136 - private Key key; 239 + private Fields field;
137 240
138 - private String value; 241 + private String value;
139 242
140 // --------------------------- CONSTRUCTORS --------------------------- 243 // --------------------------- CONSTRUCTORS ---------------------------
141 244
142 - private Condition(Key key, String value)  
143 - {  
144 - this.key = key;  
145 - this.value = value;  
146 - } 245 + private Condition(Fields field, String value)
  246 + {
  247 + this.field = field;
  248 + this.value = value;
147 } 249 }
148 } 250 }
149 } 251 }
@@ -2,12 +2,14 @@ package pl.com.it_crowd.youtrack.api; @@ -2,12 +2,14 @@ package pl.com.it_crowd.youtrack.api;
2 2
3 import org.apache.commons.logging.Log; 3 import org.apache.commons.logging.Log;
4 import org.apache.commons.logging.LogFactory; 4 import org.apache.commons.logging.LogFactory;
  5 +import pl.com.it_crowd.youtrack.api.defaults.Fields;
5 import pl.com.it_crowd.youtrack.api.rest.Comment; 6 import pl.com.it_crowd.youtrack.api.rest.Comment;
6 import pl.com.it_crowd.youtrack.api.rest.Field; 7 import pl.com.it_crowd.youtrack.api.rest.Field;
7 import pl.com.it_crowd.youtrack.api.rest.Issue; 8 import pl.com.it_crowd.youtrack.api.rest.Issue;
8 9
9 import java.io.Serializable; 10 import java.io.Serializable;
10 import java.util.ArrayList; 11 import java.util.ArrayList;
  12 +import java.util.Collections;
11 import java.util.HashMap; 13 import java.util.HashMap;
12 import java.util.List; 14 import java.util.List;
13 import java.util.Map; 15 import java.util.Map;
@@ -33,7 +35,7 @@ public class IssueWrapper implements Serializable { @@ -33,7 +35,7 @@ public class IssueWrapper implements Serializable {
33 for (Object o : issue.getFieldOrComment()) { 35 for (Object o : issue.getFieldOrComment()) {
34 if (o instanceof Field) { 36 if (o instanceof Field) {
35 Field field = (Field) o; 37 Field field = (Field) o;
36 - fieldMap.put(field.getName(), field); 38 + fieldMap.put(field.getName().toLowerCase(), field);
37 } else if (o instanceof Comment) { 39 } else if (o instanceof Comment) {
38 comments.add((Comment) o); 40 comments.add((Comment) o);
39 } else { 41 } else {
@@ -44,6 +46,11 @@ public class IssueWrapper implements Serializable { @@ -44,6 +46,11 @@ public class IssueWrapper implements Serializable {
44 46
45 // -------------------------- OTHER METHODS -------------------------- 47 // -------------------------- OTHER METHODS --------------------------
46 48
  49 + public List<Comment> getComments()
  50 + {
  51 + return Collections.unmodifiableList(comments);
  52 + }
  53 +
47 public Field getField(String field) 54 public Field getField(String field)
48 { 55 {
49 return fieldMap.get(field); 56 return fieldMap.get(field);
@@ -51,7 +58,7 @@ public class IssueWrapper implements Serializable { @@ -51,7 +58,7 @@ public class IssueWrapper implements Serializable {
51 58
52 public String getFieldValue(String fieldName) 59 public String getFieldValue(String fieldName)
53 { 60 {
54 - Field field = getField(fieldName); 61 + Field field = getField(fieldName.toLowerCase());
55 if (field == null) { 62 if (field == null) {
56 return null; 63 return null;
57 } 64 }
@@ -59,27 +66,13 @@ public class IssueWrapper implements Serializable { @@ -59,27 +66,13 @@ public class IssueWrapper implements Serializable {
59 return values.isEmpty() ? null : values.get(0).getContent(); 66 return values.isEmpty() ? null : values.get(0).getContent();
60 } 67 }
61 68
62 - public String getFieldValue(Fields fieldName) 69 + public String getFieldValue(Fields field)
63 { 70 {
64 - return getFieldValue(fieldName.name()); 71 + return getFieldValue(field.name());
65 } 72 }
66 73
67 public String getId() 74 public String getId()
68 { 75 {
69 return issue.getId(); 76 return issue.getId();
70 } 77 }
71 -  
72 -// -------------------------- ENUMERATIONS --------------------------  
73 -  
74 - public enum Fields {  
75 - created,  
76 - description,  
77 - numberInProject,  
78 - projectShortName,  
79 - reporterName,  
80 - resolved,  
81 - summary,  
82 - updated,  
83 - updaterName  
84 - }  
85 } 78 }
@@ -97,6 +97,11 @@ public class YoutrackAPI { @@ -97,6 +97,11 @@ public class YoutrackAPI {
97 return new DefaultHttpClient(cm); 97 return new DefaultHttpClient(cm);
98 } 98 }
99 99
  100 + private static boolean isBlank(String string)
  101 + {
  102 + return string != null && string.trim().length() > 0;
  103 + }
  104 +
100 // --------------------------- CONSTRUCTORS --------------------------- 105 // --------------------------- CONSTRUCTORS ---------------------------
101 106
102 public YoutrackAPI(String serviceLocation) 107 public YoutrackAPI(String serviceLocation)
@@ -125,6 +130,37 @@ public class YoutrackAPI { @@ -125,6 +130,37 @@ public class YoutrackAPI {
125 130
126 // -------------------------- OTHER METHODS -------------------------- 131 // -------------------------- OTHER METHODS --------------------------
127 132
  133 + public void command(String issueId, String command) throws IOException
  134 + {
  135 + command(issueId, command, null, null, null, null);
  136 + }
  137 +
  138 + public void command(String issueId, Command command) throws IOException
  139 + {
  140 + command(issueId, command.toString());
  141 + }
  142 +
  143 + public void command(String issueId, String command, String comment, String group, Boolean disableNotifications, String runAs) throws IOException
  144 + {
  145 + final HttpPost request = new HttpPost(serviceLocation + "/rest/issue/" + issueId + "/execute");
  146 + final List<BasicNameValuePair> parameters = new ArrayList<BasicNameValuePair>();
  147 + parameters.add(new BasicNameValuePair("command", command));
  148 + if (isBlank(comment)) {
  149 + parameters.add(new BasicNameValuePair("comment", comment));
  150 + }
  151 + if (isBlank(group)) {
  152 + parameters.add(new BasicNameValuePair("group", group));
  153 + }
  154 + if (disableNotifications != null) {
  155 + parameters.add(new BasicNameValuePair("disableNotifications", disableNotifications.toString()));
  156 + }
  157 + if (isBlank(runAs)) {
  158 + parameters.add(new BasicNameValuePair("runAs", runAs));
  159 + }
  160 + request.setEntity(new UrlEncodedFormEntity(parameters));
  161 + execute(request);
  162 + }
  163 +
128 /** 164 /**
129 * Creates new issue on Youtrack. 165 * Creates new issue on Youtrack.
130 * 166 *
@@ -176,15 +212,9 @@ public class YoutrackAPI { @@ -176,15 +212,9 @@ public class YoutrackAPI {
176 final String responseString; 212 final String responseString;
177 try { 213 try {
178 responseString = execute(new HttpGet(uri)); 214 responseString = execute(new HttpGet(uri));
179 - } catch (HttpResponseException e) { 215 + } catch (YoutrackErrorException e) {
180 if (e.getStatusCode() == HttpStatus.SC_NOT_FOUND) { 216 if (e.getStatusCode() == HttpStatus.SC_NOT_FOUND) {
181 - try {  
182 - final String error = ErrorUnmarshaller.unmarshal(e.getMessage());  
183 - throw new NoResultFoundException(error);  
184 - } catch (JAXBException e1) {  
185 - // TODO we should log on debug level the JAXBException  
186 - throw e;  
187 - } 217 + throw new NoResultFoundException(e.getMessage(), e);
188 } else { 218 } else {
189 throw e; 219 throw e;
190 } 220 }
@@ -210,21 +240,7 @@ public class YoutrackAPI { @@ -210,21 +240,7 @@ public class YoutrackAPI {
210 { 240 {
211 final HttpPost request = new HttpPost(serviceLocation + "/rest/user/login"); 241 final HttpPost request = new HttpPost(serviceLocation + "/rest/user/login");
212 request.setEntity(new UrlEncodedFormEntity(Arrays.asList(new BasicNameValuePair("login", username), new BasicNameValuePair("password", password)))); 242 request.setEntity(new UrlEncodedFormEntity(Arrays.asList(new BasicNameValuePair("login", username), new BasicNameValuePair("password", password))));
213 - try {  
214 - execute(request);  
215 - } catch (HttpResponseException e) {  
216 - if (e.getStatusCode() == HttpStatus.SC_FORBIDDEN) {  
217 - try {  
218 - final String error = ErrorUnmarshaller.unmarshal(e.getMessage());  
219 - throw new YoutrackErrorException(error, e.getStatusCode());  
220 - } catch (JAXBException e1) {  
221 - // TODO we should log on debug level the JAXBException  
222 - throw e;  
223 - }  
224 - } else {  
225 - throw e;  
226 - }  
227 - } 243 + execute(request);
228 } 244 }
229 245
230 public List<IssueWrapper> searchIssuesByProject(String project, Object filter) throws JAXBException, IOException 246 public List<IssueWrapper> searchIssuesByProject(String project, Object filter) throws JAXBException, IOException
@@ -291,7 +307,13 @@ public class YoutrackAPI { @@ -291,7 +307,13 @@ public class YoutrackAPI {
291 final HttpEntity entity = response.getEntity(); 307 final HttpEntity entity = response.getEntity();
292 String responseText = entity == null ? null : EntityUtils.toString(entity); 308 String responseText = entity == null ? null : EntityUtils.toString(entity);
293 if (statusLine.getStatusCode() >= 300) { 309 if (statusLine.getStatusCode() >= 300) {
294 - throw new HttpResponseException(statusLine.getStatusCode(), responseText); 310 + try {
  311 + final String error = ErrorUnmarshaller.unmarshal(responseText);
  312 + throw new YoutrackErrorException(error, statusLine.getStatusCode());
  313 + } catch (JAXBException e) {
  314 + // TODO we should log on debug level the JAXBException
  315 + throw new HttpResponseException(statusLine.getStatusCode(), responseText);
  316 + }
295 } 317 }
296 if (entity == null) { 318 if (entity == null) {
297 throw new ClientProtocolException("Response contains no content"); 319 throw new ClientProtocolException("Response contains no content");
  1 +package pl.com.it_crowd.youtrack.api.defaults;
  2 +
  3 +public enum DateValues {
  4 + Today, Yesterday, Saturday, Friday, Thursday, Wednesday, Tuesday, Monday, Sunday, ThisWeek("{This week}"), LastWeek("{Last week}"), TwoWeeksAgo(
  5 + "{Two weeks ago}"), ThreeWeeksAgo("{Three weeks ago}"), ThisMonth("{This month}"), LastMonth("{Last month}");
  6 +
  7 +// ------------------------------ FIELDS ------------------------------
  8 +
  9 + private String filterValue;
  10 +
  11 +// --------------------------- CONSTRUCTORS ---------------------------
  12 +
  13 + private DateValues()
  14 + {
  15 + filterValue = name();
  16 + }
  17 +
  18 + private DateValues(String filterValue)
  19 + {
  20 + this.filterValue = filterValue;
  21 + }
  22 +
  23 +// --------------------- GETTER / SETTER METHODS ---------------------
  24 +
  25 + public String getFilterValue()
  26 + {
  27 + return filterValue;
  28 + }
  29 +}
  1 +package pl.com.it_crowd.youtrack.api.defaults;
  2 +
  3 +public enum Fields {
  4 + assignee,
  5 + issueId("issue id"),
  6 + state,
  7 + created("created"),
  8 + description,
  9 + numberInProject(null),
  10 + projectShortName("project"),
  11 + reporterName("reporter"),
  12 + resolved("resolved date"),
  13 + summary,
  14 + updated,
  15 + updaterName("updated by");
  16 +
  17 +// ------------------------------ FIELDS ------------------------------
  18 +
  19 + private String command;
  20 +
  21 +// --------------------------- CONSTRUCTORS ---------------------------
  22 +
  23 + private Fields()
  24 + {
  25 + command = name();
  26 + }
  27 +
  28 + private Fields(String command)
  29 + {
  30 + this.command = command;
  31 + }
  32 +
  33 +// --------------------- GETTER / SETTER METHODS ---------------------
  34 +
  35 + public String getCommand()
  36 + {
  37 + if (command == null) {
  38 + throw new UnsupportedOperationException("There is no command for field: " + name());
  39 + }
  40 + return command;
  41 + }
  42 +}
  1 +package pl.com.it_crowd.youtrack.api.defaults;
  2 +
  3 +public enum StateValues {
  4 + Submitted, Open, InProgress("{In Progress}", "In Progress"), ToBeDiscussed("{To be discussed}", "To be discussed"), Reopened, CantReproduce(
  5 + "{Can't Reproduce}", "Can't Reproduce"), Duplicate, Fixed, WontFix("{Won't fix}", "Won't fix"),
  6 + Incomplete, Obsolete, Verified, New, Resolved("Resolved", null), Unresolved("Unresolved", null);
  7 +
  8 +// ------------------------------ FIELDS ------------------------------
  9 +
  10 + private String commandValue;
  11 +
  12 + private String filterValue;
  13 +
  14 +// --------------------------- CONSTRUCTORS ---------------------------
  15 +
  16 + private StateValues()
  17 + {
  18 + filterValue = name();
  19 + commandValue = name();
  20 + }
  21 +
  22 + private StateValues(String filterValue, String commandValue)
  23 + {
  24 + this.filterValue = filterValue;
  25 + this.commandValue = commandValue;
  26 + }
  27 +
  28 +// --------------------- GETTER / SETTER METHODS ---------------------
  29 +
  30 + public String getCommandValue()
  31 + {
  32 + return commandValue;
  33 + }
  34 +
  35 + public String getFilterValue()
  36 + {
  37 + return filterValue;
  38 + }
  39 +}
@@ -3,12 +3,8 @@ package pl.com.it_crowd.youtrack.api.exceptions; @@ -3,12 +3,8 @@ package pl.com.it_crowd.youtrack.api.exceptions;
3 public class NoResultFoundException extends RuntimeException { 3 public class NoResultFoundException extends RuntimeException {
4 // --------------------------- CONSTRUCTORS --------------------------- 4 // --------------------------- CONSTRUCTORS ---------------------------
5 5
6 - public NoResultFoundException() 6 + public NoResultFoundException(String message, Throwable cause)
7 { 7 {
8 - }  
9 -  
10 - public NoResultFoundException(String message)  
11 - {  
12 - super(message); 8 + super(message, cause);
13 } 9 }
14 } 10 }
  1 +package pl.com.it_crowd.youtrack.api.rest;
  2 +
  3 +import junit.framework.Assert;
  4 +import org.junit.Test;
  5 +import pl.com.it_crowd.youtrack.api.Command;
  6 +import pl.com.it_crowd.youtrack.api.defaults.StateValues;
  7 +
  8 +public class CommandTest {
  9 +// -------------------------- OTHER METHODS --------------------------
  10 +
  11 + @Test
  12 + public void assignee()
  13 + {
  14 + Assert.assertEquals("state Fixed assignee Tomek", Command.stateCommand("Fixed").assignee("Tomek").toString());
  15 + }
  16 +
  17 + @Test
  18 + public void assigneeChaining()
  19 + {
  20 + Assert.assertEquals("assignee Jacek assignee Tomek assignee Bernard",
  21 + Command.assigneeCommand("Jacek").assignee("Tomek").assignee("Bernard").toString());
  22 + }
  23 +
  24 + @Test
  25 + public void assigneeCommand()
  26 + {
  27 + Assert.assertEquals("assignee Jacek", Command.assigneeCommand("Jacek").toString());
  28 + }
  29 +
  30 + @Test
  31 + public void state()
  32 + {
  33 + Assert.assertEquals("assignee Tomek state Open", Command.assigneeCommand("Tomek").state("Open").toString());
  34 + Assert.assertEquals("assignee Tomek state To be discussed", Command.assigneeCommand("Tomek").state(StateValues.ToBeDiscussed).toString());
  35 + }
  36 +
  37 + @Test
  38 + public void stateChaining()
  39 + {
  40 + Assert.assertEquals("state Fixed state Open state Obsolete", Command.stateCommand("Fixed").state("Open").state("Obsolete").toString());
  41 + Assert.assertEquals("state Fixed state Open state Obsolete", Command.stateCommand("Fixed").state(StateValues.Open).state("Obsolete").toString());
  42 + }
  43 +
  44 + @Test
  45 + public void stateCommand()
  46 + {
  47 + Assert.assertEquals("state Fixed", Command.stateCommand("Fixed").toString());
  48 + Assert.assertEquals("state In Progress", Command.stateCommand(StateValues.InProgress).toString());
  49 + }
  50 +}
  1 +package pl.com.it_crowd.youtrack.api.rest;
  2 +
  3 +import junit.framework.Assert;
  4 +import org.junit.Test;
  5 +import pl.com.it_crowd.youtrack.api.Filter;
  6 +import pl.com.it_crowd.youtrack.api.defaults.DateValues;
  7 +import pl.com.it_crowd.youtrack.api.defaults.StateValues;
  8 +
  9 +import java.io.UnsupportedEncodingException;
  10 +import java.net.URLEncoder;
  11 +
  12 +public class FilterTest {
  13 +// -------------------------- STATIC METHODS --------------------------
  14 +
  15 + private static String encodeURL(String s)
  16 + {
  17 + try {
  18 + return URLEncoder.encode(s, "UTF-8");
  19 + } catch (UnsupportedEncodingException e) {
  20 + throw new RuntimeException(e);
  21 + }
  22 + }
  23 +
  24 +// -------------------------- OTHER METHODS --------------------------
  25 +
  26 + @Test
  27 + public void chaining()
  28 + {
  29 + final String reporterBernard = "reporter:bernard";
  30 + final String updaterJacek = "updated by:Jacek";
  31 + final String projectTST_QA = "project:TST_QA";
  32 + final String resolvedSunday = "resolved date:Sunday";
  33 + final String updatedThreeWeeksAgo = "updated:" + encodeURL("{Three weeks ago}");
  34 + final String createdLastMonth = "created:" + encodeURL("{Last month}");
  35 + final String stateDuplicate = "state:" + encodeURL("Duplicate");
  36 + final String space = encodeURL(" ");
  37 + Assert.assertEquals(stateDuplicate + space + createdLastMonth, Filter.stateFilter(StateValues.Duplicate).created(DateValues.LastMonth).toString());
  38 + Assert.assertEquals(createdLastMonth + space + stateDuplicate, Filter.createdFilter(DateValues.LastMonth).state(StateValues.Duplicate).toString());
  39 + Assert.assertEquals(createdLastMonth + space + stateDuplicate + space + "description:pikachu",
  40 + Filter.createdFilter(DateValues.LastMonth).state(StateValues.Duplicate).description("pikachu").toString());
  41 + Assert.assertEquals(reporterBernard + space + projectTST_QA, Filter.reporterFilter("bernard").project("TST_QA").toString());
  42 + Assert.assertEquals(projectTST_QA + space + reporterBernard, Filter.projectFilter("TST_QA").reporter("bernard").toString());
  43 + Assert.assertEquals(resolvedSunday + space + updatedThreeWeeksAgo, Filter.resolvedFilter("Sunday").updated(DateValues.ThreeWeeksAgo).toString());
  44 + Assert.assertEquals(updatedThreeWeeksAgo + space + resolvedSunday, Filter.updatedFilter(DateValues.ThreeWeeksAgo).resolved("Sunday").toString());
  45 + Assert.assertEquals(updatedThreeWeeksAgo + space + updaterJacek, Filter.updatedFilter("{Three weeks ago}").updater("Jacek").toString());
  46 + Assert.assertEquals(updaterJacek + space + updatedThreeWeeksAgo, Filter.updaterFilter("Jacek").updated("{Three weeks ago}").toString());
  47 + }
  48 +
  49 + @Test
  50 + public void createdFilter()
  51 + {
  52 + Assert.assertEquals("created:" + encodeURL("2012-01-01"), Filter.createdFilter("2012-01-01").toString());
  53 + Assert.assertEquals("created:" + encodeURL("{Last month}"), Filter.createdFilter(DateValues.LastMonth).toString());
  54 + Assert.assertEquals("created:" + encodeURL("{This month}"), Filter.createdFilter(DateValues.ThisMonth).toString());
  55 + Assert.assertEquals("created:" + encodeURL("{Two weeks ago}"), Filter.createdFilter(DateValues.TwoWeeksAgo).toString());
  56 + Assert.assertEquals("created:" + encodeURL("{Three weeks ago}"), Filter.createdFilter(DateValues.ThreeWeeksAgo).toString());
  57 + Assert.assertEquals("created:" + encodeURL("{Last week}"), Filter.createdFilter(DateValues.LastWeek).toString());
  58 + Assert.assertEquals("created:" + encodeURL("{This week}"), Filter.createdFilter(DateValues.ThisWeek).toString());
  59 + Assert.assertEquals("created:" + encodeURL("Saturday"), Filter.createdFilter(DateValues.Saturday).toString());
  60 + Assert.assertEquals("created:" + encodeURL("Friday"), Filter.createdFilter(DateValues.Friday).toString());
  61 + Assert.assertEquals("created:" + encodeURL("Thursday"), Filter.createdFilter(DateValues.Thursday).toString());
  62 + Assert.assertEquals("created:" + encodeURL("Wednesday"), Filter.createdFilter(DateValues.Wednesday).toString());
  63 + Assert.assertEquals("created:" + encodeURL("Tuesday"), Filter.createdFilter(DateValues.Tuesday).toString());
  64 + Assert.assertEquals("created:" + encodeURL("Monday"), Filter.createdFilter(DateValues.Monday).toString());
  65 + Assert.assertEquals("created:" + encodeURL("Sunday"), Filter.createdFilter(DateValues.Sunday).toString());
  66 + }
  67 +
  68 + @Test
  69 + public void descriptionFilter()
  70 + {
  71 + Assert.assertEquals("description:" + encodeURL("Wacek Ramtamtamski's"), Filter.descriptionFilter("Wacek Ramtamtamski's").toString());
  72 + }
  73 +
  74 + @Test
  75 + public void projectFilter()
  76 + {
  77 + Assert.assertEquals("project:TST", Filter.projectFilter("TST").toString());
  78 + }
  79 +
  80 + @Test
  81 + public void reporterFilter()
  82 + {
  83 + Assert.assertEquals("reporter:bernard", Filter.reporterFilter("bernard").toString());
  84 + }
  85 +
  86 + @Test
  87 + public void resolvedFilter()
  88 + {
  89 + Assert.assertEquals("resolved date:" + encodeURL("2012-01-01"), Filter.resolvedFilter("2012-01-01").toString());
  90 + Assert.assertEquals("resolved date:" + encodeURL("{Last month}"), Filter.resolvedFilter(DateValues.LastMonth).toString());
  91 + Assert.assertEquals("resolved date:" + encodeURL("{This month}"), Filter.resolvedFilter(DateValues.ThisMonth).toString());
  92 + Assert.assertEquals("resolved date:" + encodeURL("{Two weeks ago}"), Filter.resolvedFilter(DateValues.TwoWeeksAgo).toString());
  93 + Assert.assertEquals("resolved date:" + encodeURL("{Three weeks ago}"), Filter.resolvedFilter(DateValues.ThreeWeeksAgo).toString());
  94 + Assert.assertEquals("resolved date:" + encodeURL("{Last week}"), Filter.resolvedFilter(DateValues.LastWeek).toString());
  95 + Assert.assertEquals("resolved date:" + encodeURL("{This week}"), Filter.resolvedFilter(DateValues.ThisWeek).toString());
  96 + Assert.assertEquals("resolved date:" + encodeURL("Saturday"), Filter.resolvedFilter(DateValues.Saturday).toString());
  97 + Assert.assertEquals("resolved date:" + encodeURL("Friday"), Filter.resolvedFilter(DateValues.Friday).toString());
  98 + Assert.assertEquals("resolved date:" + encodeURL("Thursday"), Filter.resolvedFilter(DateValues.Thursday).toString());
  99 + Assert.assertEquals("resolved date:" + encodeURL("Wednesday"), Filter.resolvedFilter(DateValues.Wednesday).toString());
  100 + Assert.assertEquals("resolved date:" + encodeURL("Tuesday"), Filter.resolvedFilter(DateValues.Tuesday).toString());
  101 + Assert.assertEquals("resolved date:" + encodeURL("Monday"), Filter.resolvedFilter(DateValues.Monday).toString());
  102 + Assert.assertEquals("resolved date:" + encodeURL("Sunday"), Filter.resolvedFilter(DateValues.Sunday).toString());
  103 + }
  104 +
  105 + @Test
  106 + public void stateFilter()
  107 + {
  108 + Assert.assertEquals("state:" + encodeURL("{Can't Reproduce}"), Filter.stateFilter(StateValues.CantReproduce).toString());
  109 + Assert.assertEquals("state:" + encodeURL("Verified"), Filter.stateFilter(StateValues.Verified).toString());
  110 + Assert.assertEquals("state:" + encodeURL("Submitted"), Filter.stateFilter(StateValues.Submitted).toString());
  111 + Assert.assertEquals("state:" + encodeURL("Reopened"), Filter.stateFilter(StateValues.Reopened).toString());
  112 + Assert.assertEquals("state:" + encodeURL("{To be discussed}"), Filter.stateFilter(StateValues.ToBeDiscussed).toString());
  113 + Assert.assertEquals("state:" + encodeURL("Duplicate"), Filter.stateFilter(StateValues.Duplicate).toString());
  114 + Assert.assertEquals("state:" + encodeURL("Resolved"), Filter.stateFilter(StateValues.Resolved).toString());
  115 + Assert.assertEquals("state:" + encodeURL("Fixed"), Filter.stateFilter(StateValues.Fixed).toString());
  116 + Assert.assertEquals("state:" + encodeURL("Incomplete"), Filter.stateFilter(StateValues.Incomplete).toString());
  117 + Assert.assertEquals("state:" + encodeURL("{In Progress}"), Filter.stateFilter(StateValues.InProgress).toString());
  118 + Assert.assertEquals("state:" + encodeURL("New"), Filter.stateFilter(StateValues.New).toString());
  119 + Assert.assertEquals("state:" + encodeURL("Obsolete"), Filter.stateFilter(StateValues.Obsolete).toString());
  120 + Assert.assertEquals("state:" + encodeURL("Open"), Filter.stateFilter(StateValues.Open).toString());
  121 + Assert.assertEquals("state:" + encodeURL("{Won't fix}"), Filter.stateFilter(StateValues.WontFix).toString());
  122 + }
  123 +
  124 + @Test
  125 + public void updatedFilter()
  126 + {
  127 + Assert.assertEquals("updated:" + encodeURL("Today"), Filter.updatedFilter(DateValues.Today).toString());
  128 + Assert.assertEquals("updated:" + encodeURL("Yesterday"), Filter.updatedFilter(DateValues.Yesterday).toString());
  129 + Assert.assertEquals("updated:" + encodeURL("2012-01-01"), Filter.updatedFilter("2012-01-01").toString());
  130 + Assert.assertEquals("updated:" + encodeURL("{Last month}"), Filter.updatedFilter(DateValues.LastMonth).toString());
  131 + Assert.assertEquals("updated:" + encodeURL("{This month}"), Filter.updatedFilter(DateValues.ThisMonth).toString());
  132 + Assert.assertEquals("updated:" + encodeURL("{Two weeks ago}"), Filter.updatedFilter(DateValues.TwoWeeksAgo).toString());
  133 + Assert.assertEquals("updated:" + encodeURL("{Three weeks ago}"), Filter.updatedFilter(DateValues.ThreeWeeksAgo).toString());
  134 + Assert.assertEquals("updated:" + encodeURL("{Last week}"), Filter.updatedFilter(DateValues.LastWeek).toString());
  135 + Assert.assertEquals("updated:" + encodeURL("{This week}"), Filter.updatedFilter(DateValues.ThisWeek).toString());
  136 + Assert.assertEquals("updated:" + encodeURL("Saturday"), Filter.updatedFilter(DateValues.Saturday).toString());
  137 + Assert.assertEquals("updated:" + encodeURL("Friday"), Filter.updatedFilter(DateValues.Friday).toString());
  138 + Assert.assertEquals("updated:" + encodeURL("Thursday"), Filter.updatedFilter(DateValues.Thursday).toString());
  139 + Assert.assertEquals("updated:" + encodeURL("Wednesday"), Filter.updatedFilter(DateValues.Wednesday).toString());
  140 + Assert.assertEquals("updated:" + encodeURL("Tuesday"), Filter.updatedFilter(DateValues.Tuesday).toString());
  141 + Assert.assertEquals("updated:" + encodeURL("Monday"), Filter.updatedFilter(DateValues.Monday).toString());
  142 + Assert.assertEquals("updated:" + encodeURL("Sunday"), Filter.updatedFilter(DateValues.Sunday).toString());
  143 + }
  144 +
  145 + @Test
  146 +
  147 + public void updaterFilter()
  148 + {
  149 + Assert.assertEquals("updated by:bernard", Filter.updaterFilter("bernard").toString());
  150 + }
  151 +}
@@ -4,8 +4,11 @@ import junit.framework.Assert; @@ -4,8 +4,11 @@ import junit.framework.Assert;
4 import org.apache.http.HttpStatus; 4 import org.apache.http.HttpStatus;
5 import org.apache.http.auth.AuthenticationException; 5 import org.apache.http.auth.AuthenticationException;
6 import org.junit.Test; 6 import org.junit.Test;
  7 +import pl.com.it_crowd.youtrack.api.Command;
7 import pl.com.it_crowd.youtrack.api.IssueWrapper; 8 import pl.com.it_crowd.youtrack.api.IssueWrapper;
8 import pl.com.it_crowd.youtrack.api.YoutrackAPI; 9 import pl.com.it_crowd.youtrack.api.YoutrackAPI;
  10 +import pl.com.it_crowd.youtrack.api.defaults.Fields;
  11 +import pl.com.it_crowd.youtrack.api.defaults.StateValues;
9 import pl.com.it_crowd.youtrack.api.exceptions.NoResultFoundException; 12 import pl.com.it_crowd.youtrack.api.exceptions.NoResultFoundException;
10 import pl.com.it_crowd.youtrack.api.exceptions.YoutrackErrorException; 13 import pl.com.it_crowd.youtrack.api.exceptions.YoutrackErrorException;
11 14
@@ -16,11 +19,72 @@ import java.util.List; @@ -16,11 +19,72 @@ import java.util.List;
16 /** 19 /**
17 * This test requires Youtrack instance with "Test(TST)" project to be running and expects following JVM params: 20 * This test requires Youtrack instance with "Test(TST)" project to be running and expects following JVM params:
18 * youtrackLocation, youtrackUsername and youtrackPassword. 21 * youtrackLocation, youtrackUsername and youtrackPassword.
  22 + * There should be no assigner "wacek" for project TST.
  23 + * There should be following assigners for TST project: bernard,root.
  24 + * Ticket TST-2 should be deleted.
19 */ 25 */
20 public class YoutrackAPITest { 26 public class YoutrackAPITest {
21 // -------------------------- OTHER METHODS -------------------------- 27 // -------------------------- OTHER METHODS --------------------------
22 28
23 @Test 29 @Test
  30 + public void commandAllStatesTest() throws IOException, JAXBException
  31 + {
  32 + final YoutrackAPI api = new YoutrackAPI(getServiceLocation(), getUsername(), getPassword());
  33 + final String issueId = "TST-1";
  34 + IssueWrapper issue;
  35 + final StateValues[] stateValueses = StateValues.values();
  36 + for (StateValues state : stateValueses) {
  37 + if (state.getCommandValue() != null && !StateValues.Duplicate.equals(state)) {
  38 + api.command(issueId, Command.stateCommand(state));
  39 + issue = api.getIssue(issueId);
  40 + Assert.assertNotNull(issue);
  41 + Assert.assertEquals(state.getCommandValue(), issue.getFieldValue(Fields.state));
  42 + }
  43 + }
  44 + }
  45 +
  46 + @Test
  47 + public void commandTest() throws IOException, JAXBException
  48 + {
  49 + final YoutrackAPI api = new YoutrackAPI(getServiceLocation(), getUsername(), getPassword());
  50 + final String issueId = "TST-1";
  51 + IssueWrapper issue;
  52 + try {
  53 + api.command(issueId, Command.assigneeCommand("wacek").toString());
  54 + Assert.fail("Command should fail");
  55 + } catch (YoutrackErrorException e) {
  56 +// There is no such assignee
  57 + Assert.assertEquals(HttpStatus.SC_BAD_REQUEST, e.getStatusCode());
  58 + }
  59 + api.command(issueId, Command.assigneeCommand("bernard").assignee("root"));
  60 + issue = api.getIssue(issueId);
  61 + Assert.assertNotNull(issue);
  62 + Assert.assertEquals("root", issue.getFieldValue(Fields.assignee));
  63 +
  64 + api.command(issueId, Command.assigneeCommand("bernard"));
  65 + issue = api.getIssue(issueId);
  66 + Assert.assertNotNull(issue);
  67 + Assert.assertEquals("bernard", issue.getFieldValue(Fields.assignee));
  68 +
  69 + api.command(issueId, Command.stateCommand(StateValues.InProgress));
  70 + issue = api.getIssue(issueId);
  71 + Assert.assertNotNull(issue);
  72 + Assert.assertEquals("In Progress", issue.getFieldValue(Fields.state));
  73 +
  74 + api.command(issueId, Command.stateCommand(StateValues.InProgress).assignee("root"));
  75 + issue = api.getIssue(issueId);
  76 + Assert.assertNotNull(issue);
  77 + Assert.assertEquals("In Progress", issue.getFieldValue(Fields.state));
  78 + Assert.assertEquals("root", issue.getFieldValue(Fields.assignee));
  79 +
  80 + api.command(issueId, Command.assigneeCommand("bernard").state(StateValues.New));
  81 + issue = api.getIssue(issueId);
  82 + Assert.assertNotNull(issue);
  83 + Assert.assertEquals("New", issue.getFieldValue(Fields.state));
  84 + Assert.assertEquals("bernard", issue.getFieldValue(Fields.assignee));
  85 + }
  86 +
  87 + @Test
24 public void createIssueTest() throws IOException, AuthenticationException, JAXBException 88 public void createIssueTest() throws IOException, AuthenticationException, JAXBException
25 { 89 {
26 YoutrackAPI api = new YoutrackAPI(getServiceLocation(), getUsername(), getPassword()); 90 YoutrackAPI api = new YoutrackAPI(getServiceLocation(), getUsername(), getPassword());
@@ -35,6 +99,7 @@ public class YoutrackAPITest { @@ -35,6 +99,7 @@ public class YoutrackAPITest {
35 YoutrackAPI api = new YoutrackAPI(getServiceLocation(), getUsername(), getPassword()); 99 YoutrackAPI api = new YoutrackAPI(getServiceLocation(), getUsername(), getPassword());
36 final IssueWrapper issue = api.getIssue("TST-1"); 100 final IssueWrapper issue = api.getIssue("TST-1");
37 Assert.assertNotNull(issue); 101 Assert.assertNotNull(issue);
  102 + Assert.assertEquals("1", issue.getFieldValue(Fields.numberInProject));
38 103
39 try { 104 try {
40 api.getIssue("TST-2"); 105 api.getIssue("TST-2");
@@ -81,7 +146,7 @@ public class YoutrackAPITest { @@ -81,7 +146,7 @@ public class YoutrackAPITest {
81 List<IssueWrapper> issues = api.searchIssuesByProject("TST", null); 146 List<IssueWrapper> issues = api.searchIssuesByProject("TST", null);
82 Assert.assertTrue(!issues.isEmpty()); 147 Assert.assertTrue(!issues.isEmpty());
83 for (IssueWrapper issue : issues) { 148 for (IssueWrapper issue : issues) {
84 - String summary = issue.getFieldValue(IssueWrapper.Fields.summary); 149 + String summary = issue.getFieldValue(Fields.summary);
85 Assert.assertNotNull(summary); 150 Assert.assertNotNull(summary);
86 Assert.assertTrue(!"".equals(summary.trim())); 151 Assert.assertTrue(!"".equals(summary.trim()));
87 } 152 }
Please register or login to post a comment