1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package com.atlassian.jira.rest.client.internal.json;
18
19 import com.atlassian.jira.rest.client.BasicComponentNameExtractionFunction;
20 import com.atlassian.jira.rest.client.IterableMatcher;
21 import com.atlassian.jira.rest.client.domain.Attachment;
22 import com.atlassian.jira.rest.client.domain.BasicIssueType;
23 import com.atlassian.jira.rest.client.domain.BasicPriority;
24 import com.atlassian.jira.rest.client.domain.BasicProject;
25 import com.atlassian.jira.rest.client.domain.BasicUser;
26 import com.atlassian.jira.rest.client.domain.BasicWatchers;
27 import com.atlassian.jira.rest.client.domain.ChangelogGroup;
28 import com.atlassian.jira.rest.client.domain.ChangelogItem;
29 import com.atlassian.jira.rest.client.domain.Comment;
30 import com.atlassian.jira.rest.client.domain.Field;
31 import com.atlassian.jira.rest.client.domain.Issue;
32 import com.atlassian.jira.rest.client.domain.IssueLink;
33 import com.atlassian.jira.rest.client.domain.IssueLinkType;
34 import com.atlassian.jira.rest.client.domain.Subtask;
35 import com.atlassian.jira.rest.client.domain.TimeTracking;
36 import com.atlassian.jira.rest.client.domain.Visibility;
37 import com.atlassian.jira.rest.client.domain.Worklog;
38 import com.google.common.collect.ImmutableList;
39 import com.google.common.collect.Iterables;
40 import org.codehaus.jettison.json.JSONException;
41 import org.codehaus.jettison.json.JSONObject;
42 import org.joda.time.format.ISODateTimeFormat;
43 import org.junit.Assert;
44 import org.junit.Test;
45
46 import java.util.Iterator;
47
48 import static com.atlassian.jira.rest.client.TestUtil.toDateTime;
49 import static com.atlassian.jira.rest.client.TestUtil.toUri;
50 import static org.junit.Assert.*;
51
52 public class IssueJsonParserTest {
53 @Test
54 public void testParseIssue() throws Exception {
55 final Issue issue = parseIssue("/json/issue/valid-all-expanded.json");
56 assertExpectedIssue(issue);
57 }
58
59 @Test
60 public void testParseIssueJira4x2() throws Exception {
61 final Issue issue = parseIssue("/json/issue/valid-all-expanded-jira-4-2.json");
62 assertExpectedIssue(issue);
63 }
64
65 private void assertExpectedIssue(Issue issue) {
66 assertEquals("Testing issue", issue.getSummary());
67 assertEquals("TST-2", issue.getKey());
68 assertEquals(new BasicIssueType(toUri("http://localhost:8090/jira/rest/api/latest/issueType/1"), "Bug", false),
69 issue.getIssueType());
70 assertEquals(new BasicProject(toUri("http://localhost:8090/jira/rest/api/latest/project/TST"), "TST", null), issue.getProject());
71 assertEquals("Major", issue.getPriority().getName());
72 assertNull(issue.getResolution());
73 assertEquals(toDateTime("2010-07-26T13:29:18.262+0200"), issue.getCreationDate());
74 assertEquals(toDateTime("2010-08-27T15:00:02.107+0200"), issue.getUpdateDate());
75
76 assertEquals(TestConstants.USER_ADMIN, issue.getReporter());
77 assertEquals(TestConstants.USER1, issue.getAssignee());
78
79
80 Assert.assertThat(issue.getIssueLinks(), IterableMatcher.hasOnlyElements(
81 new IssueLink("TST-1", toUri("http://localhost:8090/jira/rest/api/latest/issue/TST-1"),
82 new IssueLinkType("Duplicate", "duplicates", IssueLinkType.Direction.OUTBOUND)),
83 new IssueLink("TST-1", toUri("http://localhost:8090/jira/rest/api/latest/issue/TST-1"),
84 new IssueLinkType("Duplicate", "is duplicated by", IssueLinkType.Direction.INBOUND))
85 ));
86
87
88
89 final BasicWatchers watchers = issue.getWatchers();
90 assertFalse(watchers.isWatching());
91 assertEquals(toUri("http://localhost:8090/jira/rest/api/latest/issue/TST-2/watchers"), watchers.getSelf());
92 assertEquals(1, watchers.getNumWatchers());
93 assertEquals(new TimeTracking(0, 0, 145), issue.getTimeTracking());
94
95
96 final Iterable<Attachment> attachments = issue.getAttachments();
97 assertEquals(3, Iterables.size(attachments));
98 final Attachment attachment = attachments.iterator().next();
99 assertEquals("jira_logo.gif", attachment.getFilename());
100 assertEquals(TestConstants.USER_ADMIN, attachment.getAuthor());
101 assertEquals(2517, attachment.getSize());
102 assertEquals(toUri("http://localhost:8090/jira/secure/thumbnail/10036/10036_jira_logo.gif"), attachment.getThumbnailUri());
103 final Iterator<Attachment> attachmentIt = attachments.iterator();
104 attachmentIt.next();
105 attachmentIt.next();
106 final Attachment lastAttachment = attachmentIt.next();
107 assertEquals("transparent-png.png", lastAttachment.getFilename());
108
109
110 final Iterable<Worklog> worklogs = issue.getWorklogs();
111 assertEquals(5, Iterables.size(worklogs));
112 final Worklog worklog = Iterables.get(worklogs, 2);
113 assertEquals(new Worklog(toUri("http://localhost:8090/jira/rest/api/latest/worklog/10012"),
114 toUri("http://localhost:8090/jira/rest/api/latest/issue/TST-2"), TestConstants.USER1,
115 TestConstants.USER1, "a worklog viewable just by jira-users",
116 toDateTime("2010-08-17T16:53:15.848+0200"), toDateTime("2010-08-17T16:53:15.848+0200"),
117 toDateTime("2010-08-11T16:52:00.000+0200"), 3, Visibility.group("jira-users")), worklog);
118
119 final Worklog worklog3 = Iterables.get(worklogs, 3);
120 assertEquals("", worklog3.getComment());
121
122
123 assertEquals(3, Iterables.size(issue.getComments()));
124 final Comment comment = issue.getComments().iterator().next();
125 assertEquals(Visibility.Type.ROLE, comment.getVisibility().getType());
126 assertEquals(TestConstants.USER_ADMIN, comment.getAuthor());
127 assertEquals(TestConstants.USER_ADMIN, comment.getUpdateAuthor());
128 }
129
130 private Issue parseIssue(final String resourcePath) throws JSONException {
131 final JSONObject issueJson = ResourceUtil.getJsonObjectFromResource(resourcePath);
132 final IssueJsonParser parser = new IssueJsonParser();
133 return parser.parse(issueJson);
134 }
135
136 @Test
137 public void testParseIssueWithResolution() throws JSONException {
138 final Issue issue = parseIssue("/json/issue/valid-all-expanded-with-resolution.json");
139 assertEquals("Incomplete", issue.getResolution().getName());
140
141 }
142
143 @Test
144 public void testParseIssueWhenWatchersAndVotersAreSwitchedOff() throws JSONException {
145 final Issue issue = parseIssue("/json/issue/valid-no-votes-no-watchers.json");
146 assertNull(issue.getWatchers());
147 assertNull(issue.getVotes());
148 }
149
150 @Test
151 public void testParseUnassignedIssue() throws JSONException {
152 final Issue issue = parseIssue("/json/issue/valid-unassigned.json");
153 assertNull(issue.getAssignee());
154 }
155
156 @Test
157 public void testParseNoTimeTrackingInfo() throws JSONException {
158 final Issue issue = parseIssue("/json/issue/valid-unassigned.json");
159 assertNull(issue.getTimeTracking());
160 }
161
162 @Test
163 public void testParseUnassignedIssueJira4x3() throws JSONException {
164 final Issue issue = parseIssue("/json/issue/valid-unassigned-jira-4.3.json");
165 assertNull(issue.getAssignee());
166 }
167
168 @Test
169 public void testParseIssueWithAnonymousComment() throws JSONException {
170 final Issue issue = parseIssue("/json/issue/valid-anonymous-comment-jira-4.3.json");
171 assertEquals(1, Iterables.size(issue.getComments()));
172 final Comment comment = issue.getComments().iterator().next();
173 assertEquals("A comment from anonymous user", comment.getBody());
174 assertNull(comment.getAuthor());
175
176 }
177
178 @Test
179 public void testParseIssueWithVisibilityJira4x3() throws JSONException {
180 final Issue issue = parseIssue("/json/issue/valid-visibility-jira-4.3.json");
181 assertEquals(Visibility.role("Administrators"), issue.getComments().iterator().next().getVisibility());
182 assertEquals(Visibility.role("Developers"), Iterables.get(issue.getWorklogs(), 1).getVisibility());
183 assertEquals(Visibility.group("jira-users"), Iterables.get(issue.getWorklogs(), 2).getVisibility());
184 }
185
186 @Test
187 public void testParseIssueWithUserPickerCustomFieldFilledOut() throws JSONException {
188 final Issue issue = parseIssue("/json/issue/valid-user-picker-custom-field-filled-out.json");
189 final Field extraUserField = issue.getFieldByName("Extra User");
190 assertNotNull(extraUserField);
191 assertEquals(BasicUser.class, extraUserField.getValue().getClass());
192 assertEquals(TestConstants.USER1, extraUserField.getValue());
193 }
194
195 @Test
196 public void testParseIssueWithUserPickerCustomFieldEmpty() throws JSONException {
197 final Issue issue = parseIssue("/json/issue/valid-user-picker-custom-field-empty.json");
198 final Field extraUserField = issue.getFieldByName("Extra User");
199 assertNotNull(extraUserField);
200 assertNull(extraUserField.getValue());
201 }
202
203 @Test
204 public void testParseIssueJira5x0Representation() throws JSONException {
205 final Issue issue = parseIssue("/json/issue/valid-5.0.json");
206 assertEquals(3, Iterables.size(issue.getComments()));
207 final BasicPriority priority = issue.getPriority();
208 assertNotNull(priority);
209 assertEquals("Major", priority.getName());
210 assertEquals("my description", issue.getDescription());
211 assertEquals("TST", issue.getProject().getKey());
212 assertEquals(4, Iterables.size(issue.getAttachments()));
213 assertEquals(1, Iterables.size(issue.getIssueLinks()));
214 assertEquals(1.457, issue.getField("customfield_10000").getValue());
215 assertThat(Iterables.transform(issue.getComponents(), new BasicComponentNameExtractionFunction()), IterableMatcher.hasOnlyElements("Component A", "Component B"));
216 assertEquals(2, Iterables.size(issue.getWorklogs()));
217 assertEquals(1, issue.getWatchers().getNumWatchers());
218 assertFalse(issue.getWatchers().isWatching());
219 assertEquals(new TimeTracking(2700, 2220, 180), issue.getTimeTracking());
220
221 assertEquals(Visibility.role("Developers"), issue.getWorklogs().iterator().next().getVisibility());
222 assertEquals(Visibility.group("jira-users"), Iterables.get(issue.getWorklogs(), 1).getVisibility());
223
224 }
225
226 @Test
227 public void testParseIssueJira50Representation() throws JSONException {
228 final Issue issue = parseIssue("/json/issue/valid-5.0-1.json");
229 }
230
231 @Test
232 public void testParseIssueWithProjectNamePresentInRepresentation() throws JSONException {
233 final Issue issue = parseIssue("/json/issue/issue-with-project-name-present.json");
234 assertEquals("My Test Project", issue.getProject().getName());
235 }
236
237 @Test
238 public void testParseIssueJiraRepresentationJrjc49() throws JSONException {
239 final Issue issue = parseIssue("/json/issue/jrjc49.json");
240 final Iterable<Worklog> worklogs = issue.getWorklogs();
241 assertEquals(1, Iterables.size(worklogs));
242 final Worklog worklog = Iterables.get(worklogs, 0);
243 assertNull(worklog.getComment());
244 assertEquals(180, worklog.getMinutesSpent());
245 assertEquals("Sample, User", worklog.getAuthor().getDisplayName());
246
247 }
248
249 @Test
250 public void testParseIssueJira5x0RepresentationNullCustomField() throws JSONException {
251 final Issue issue = parseIssue("/json/issue/valid-5.0-null-custom-field.json");
252 assertEquals(null, issue.getField("customfield_10000").getValue());
253 assertNull(issue.getIssueLinks());
254 }
255
256 @Test
257 public void issueWithSubtasks() throws JSONException {
258 final Issue issue = parseIssue("/json/issue/subtasks-5.json");
259 Iterable<Subtask> subtasks = issue.getSubtasks();
260 assertEquals(1, Iterables.size(subtasks));
261 Subtask subtask = Iterables.get(subtasks, 0, null);
262 assertNotNull(subtask);
263 assertEquals("SAM-2", subtask.getIssueKey());
264 assertEquals("Open", subtask.getStatus().getName());
265 assertEquals("Subtask", subtask.getIssueType().getName());
266 }
267
268 @Test
269 public void issueWithChangelog() throws JSONException {
270 final Issue issue = parseIssue("/json/issue/valid-5.0-with-changelog.json");
271 assertEquals("HST-1", issue.getKey());
272
273 final Iterable<ChangelogGroup> changelog = issue.getChangelog();
274 assertNotNull(changelog);
275
276 assertEquals(3, Iterables.size(changelog));
277 final Iterator<ChangelogGroup> iterator = changelog.iterator();
278
279 final BasicUser user1 = new BasicUser(toUri("http://localhost:2990/jira/rest/api/2/user?username=user1"), "user1", "User One");
280 final BasicUser user2 = new BasicUser(toUri("http://localhost:2990/jira/rest/api/2/user?username=user2"), "user2", "User Two");
281
282 verifyChangelog(iterator.next(),
283 "2012-04-12T14:28:28.255+0200",
284 user1,
285 ImmutableList.of(
286 new ChangelogItem(ChangelogItem.FieldType.JIRA, "duedate", null, null, "2012-04-12", "2012-04-12 00:00:00.0"),
287 new ChangelogItem(ChangelogItem.FieldType.CUSTOM, "Radio Field", null, null, "10000", "One")
288 ));
289
290 verifyChangelog(iterator.next(),
291 "2012-04-12T14:28:44.079+0200",
292 user1,
293 ImmutableList.of(
294 new ChangelogItem(ChangelogItem.FieldType.JIRA, "assignee", "user1", "User One", "user2", "User Two")
295 ));
296
297 verifyChangelog(iterator.next(),
298 "2012-04-12T14:30:09.690+0200",
299 user2,
300 ImmutableList.of(
301 new ChangelogItem(ChangelogItem.FieldType.JIRA, "summary", null, "Simple history test", null, "Simple history test - modified"),
302 new ChangelogItem(ChangelogItem.FieldType.JIRA, "issuetype", "1", "Bug", "2", "New Feature"),
303 new ChangelogItem(ChangelogItem.FieldType.JIRA, "priority", "3", "Major", "4", "Minor"),
304 new ChangelogItem(ChangelogItem.FieldType.JIRA, "description", null, "Initial Description", null, "Modified Description"),
305 new ChangelogItem(ChangelogItem.FieldType.CUSTOM, "Date Field", "2012-04-11T14:26+0200", "11/Apr/12 2:26 PM", "2012-04-12T14:26+0200", "12/Apr/12 2:26 PM"),
306 new ChangelogItem(ChangelogItem.FieldType.JIRA, "duedate", "2012-04-12", "2012-04-12 00:00:00.0", "2012-04-13", "2012-04-13 00:00:00.0"),
307 new ChangelogItem(ChangelogItem.FieldType.CUSTOM, "Radio Field", "10000", "One", "10001", "Two"),
308 new ChangelogItem(ChangelogItem.FieldType.CUSTOM, "Text Field", null, "Initial text field value", null, "Modified text field value")
309 ));
310 }
311
312 private static void verifyChangelog(ChangelogGroup changelogGroup, String createdDate, BasicUser author, Iterable<ChangelogItem> expectedItems) {
313 assertEquals(ISODateTimeFormat.dateTime().parseDateTime(createdDate), changelogGroup.getCreated());
314 assertEquals(author, changelogGroup.getAuthor());
315 assertEquals(expectedItems, changelogGroup.getItems());
316 }
317
318 @Test
319 public void testParseIssueWithLabelsForJira5x0() throws JSONException {
320 final Issue issue = parseIssue("/json/issue/valid-5.0-with-labels.json");
321 assertThat(issue.getLabels(), IterableMatcher.hasOnlyElements("a", "bcds"));
322 }
323
324 @Test
325 public void testParseIssueWithLabels() throws JSONException {
326 final Issue issue = parseIssue("/json/issue/valid-5.0-with-labels.json");
327 assertThat(issue.getLabels(), IterableMatcher.hasOnlyElements("a", "bcds"));
328 }
329
330 @Test
331 public void testParseIssueWithoutLabelsForJira5x0() throws JSONException {
332 final Issue issue = parseIssue("/json/issue/valid-5.0-without-labels.json");
333 assertThat(issue.getLabels(), IterableMatcher.<String>isEmpty());
334 }
335
336 @Test
337 public void testParseIssueWithoutLabels() throws JSONException {
338 final Issue issue = parseIssue("/json/issue/valid-without-labels.json");
339 assertThat(issue.getLabels(), IterableMatcher.<String>isEmpty());
340 }
341
342 }