1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package it;
18
19 import com.atlassian.jira.rest.client.IntegrationTestUtil;
20 import com.atlassian.jira.rest.client.IssueRestClient;
21 import com.atlassian.jira.rest.client.IterableMatcher;
22 import com.atlassian.jira.rest.client.NullProgressMonitor;
23 import com.atlassian.jira.rest.client.TestUtil;
24 import com.atlassian.jira.rest.client.annotation.Restore;
25 import com.atlassian.jira.rest.client.domain.Attachment;
26 import com.atlassian.jira.rest.client.domain.Comment;
27 import com.atlassian.jira.rest.client.domain.Issue;
28 import com.atlassian.jira.rest.client.domain.IssueLink;
29 import com.atlassian.jira.rest.client.domain.IssueLinkType;
30 import com.atlassian.jira.rest.client.domain.Transition;
31 import com.atlassian.jira.rest.client.domain.input.AttachmentInput;
32 import com.atlassian.jira.rest.client.domain.input.FieldInput;
33 import com.atlassian.jira.rest.client.domain.input.LinkIssuesInput;
34 import com.atlassian.jira.rest.client.domain.input.TransitionInput;
35 import com.atlassian.jira.rest.client.internal.ServerVersionConstants;
36 import com.atlassian.jira.rest.client.internal.json.TestConstants;
37 import com.google.common.base.Function;
38 import com.google.common.base.Predicate;
39 import com.google.common.collect.Iterables;
40 import org.apache.commons.io.IOUtils;
41 import org.hamcrest.Matchers;
42 import org.joda.time.DateTime;
43 import org.junit.Assert;
44 import org.junit.Test;
45
46 import javax.annotation.Nullable;
47 import javax.ws.rs.core.Response;
48 import java.io.ByteArrayInputStream;
49 import java.io.File;
50 import java.io.FileInputStream;
51 import java.io.FileWriter;
52 import java.io.IOException;
53 import java.text.NumberFormat;
54 import java.util.Arrays;
55 import java.util.Locale;
56 import java.util.regex.Matcher;
57 import java.util.regex.Pattern;
58
59 import static com.atlassian.jira.rest.client.IntegrationTestUtil.*;
60 import static com.atlassian.jira.rest.client.TestUtil.assertErrorCode;
61 import static com.atlassian.jira.rest.client.internal.json.TestConstants.USER1_USERNAME;
62 import static com.atlassian.jira.rest.client.internal.json.TestConstants.USER2_USERNAME;
63 import static com.atlassian.jira.rest.client.internal.json.TestConstants.ADMIN_USERNAME;
64 import static com.atlassian.jira.rest.client.internal.json.TestConstants.ADMIN_PASSWORD;
65 import static org.junit.Assert.*;
66
67
68 @Restore(TestConstants.DEFAULT_JIRA_DUMP_FILE)
69 public class JerseyIssueRestClientTest extends AbstractJerseyRestClientTest {
70
71 @Test
72 public void testTransitionWithNumericCustomFieldPolishLocale() throws Exception {
73 final double newValue = 123.45;
74 final FieldInput fieldInput;
75 if (IntegrationTestUtil.TESTING_JIRA_5_OR_NEWER) {
76 fieldInput = new FieldInput(NUMERIC_CUSTOMFIELD_ID, Double.valueOf(newValue));
77 } else {
78 fieldInput = new FieldInput(NUMERIC_CUSTOMFIELD_ID, NumberFormat.getNumberInstance(new Locale("pl")).format(newValue));
79 }
80 assertTransitionWithNumericCustomField(fieldInput, newValue);
81 }
82
83 @Test
84 public void testTransitionWithNumericCustomFieldEnglishLocale() throws Exception {
85 setUser1();
86 final double newValue = 123.45;
87 final FieldInput fieldInput = new FieldInput(NUMERIC_CUSTOMFIELD_ID,
88 NumberFormat.getNumberInstance(new Locale("pl")).format(newValue));
89
90 assertErrorCode(Response.Status.BAD_REQUEST, IntegrationTestUtil.TESTING_JIRA_5_OR_NEWER
91 ? "Operation value must be a number" : ("'" + fieldInput.getValue() + "' is an invalid number"), new Runnable() {
92 @Override
93 public void run() {
94 assertTransitionWithNumericCustomField(fieldInput, newValue);
95 }
96 });
97
98 final FieldInput fieldInput2 = new FieldInput(NUMERIC_CUSTOMFIELD_ID, newValue);
99 assertTransitionWithNumericCustomField(fieldInput2, newValue);
100
101 }
102
103
104 private void assertTransitionWithNumericCustomField(FieldInput fieldInput, Double expectedValue) {
105 final Issue issue = client.getIssueClient().getIssue("TST-1", new NullProgressMonitor());
106 assertNull(issue.getField(NUMERIC_CUSTOMFIELD_ID).getValue());
107 final Iterable<Transition> transitions = client.getIssueClient().getTransitions(issue, pm);
108
109 final Transition transitionFound = TestUtil.getTransitionByName(transitions, "Estimate");
110 assertNotNull(transitionFound);
111 assertTrue(Iterables.contains(transitionFound.getFields(),
112 new Transition.Field(NUMERIC_CUSTOMFIELD_ID, false, IntegrationTestUtil.TESTING_JIRA_5_OR_NEWER ? NUMERIC_CUSTOMFIELD_TYPE_V5 : NUMERIC_CUSTOMFIELD_TYPE)));
113 client.getIssueClient().transition(issue, new TransitionInput(transitionFound.getId(), Arrays.asList(fieldInput),
114 Comment.valueOf("My test comment")), new NullProgressMonitor());
115 final Issue changedIssue = client.getIssueClient().getIssue("TST-1", pm);
116 assertTrue(changedIssue.getField(NUMERIC_CUSTOMFIELD_ID).getValue().equals(expectedValue));
117 }
118
119 @Test
120 public void testTransitionWithNumericCustomFieldAndInteger() throws Exception {
121 final Issue issue = client.getIssueClient().getIssue("TST-1", pm);
122 assertNull(issue.getField(NUMERIC_CUSTOMFIELD_ID).getValue());
123 final Iterable<Transition> transitions = client.getIssueClient().getTransitions(issue, pm);
124 Transition transitionFound = TestUtil.getTransitionByName(transitions, "Estimate");
125
126 assertNotNull(transitionFound);
127 assertTrue(Iterables.contains(transitionFound.getFields(),
128 new Transition.Field(NUMERIC_CUSTOMFIELD_ID, false, IntegrationTestUtil.TESTING_JIRA_5_OR_NEWER ? NUMERIC_CUSTOMFIELD_TYPE_V5 : NUMERIC_CUSTOMFIELD_TYPE)));
129 final double newValue = 123;
130 final FieldInput fieldInput = new FieldInput(NUMERIC_CUSTOMFIELD_ID, newValue);
131 client.getIssueClient().transition(issue, new TransitionInput(transitionFound.getId(), Arrays.asList(fieldInput),
132 Comment.valueOf("My test comment")), pm);
133 final Issue changedIssue = client.getIssueClient().getIssue("TST-1", pm);
134 assertEquals(newValue, changedIssue.getField(NUMERIC_CUSTOMFIELD_ID).getValue());
135 }
136
137 @Test
138 public void testTransitionWithInvalidNumericField() throws Exception {
139 final Issue issue = client.getIssueClient().getIssue("TST-1", pm);
140 assertNull(issue.getField(NUMERIC_CUSTOMFIELD_ID).getValue());
141 final Iterable<Transition> transitions = client.getIssueClient().getTransitions(issue, pm);
142 final Transition transitionFound = TestUtil.getTransitionByName(transitions, "Estimate");
143
144 assertNotNull(transitionFound);
145 assertTrue(Iterables.contains(transitionFound.getFields(),
146 new Transition.Field(NUMERIC_CUSTOMFIELD_ID, false, TESTING_JIRA_5_OR_NEWER ? NUMERIC_CUSTOMFIELD_TYPE_V5 : NUMERIC_CUSTOMFIELD_TYPE)));
147 final FieldInput fieldInput = new FieldInput(NUMERIC_CUSTOMFIELD_ID, "]432jl");
148
149
150 assertErrorCode(Response.Status.BAD_REQUEST, TESTING_JIRA_5_OR_NEWER
151 ? "Operation value must be a number" : "']432jl' nie jest prawid\u0142ow\u0105 liczb\u0105", new Runnable() {
152 @Override
153 public void run() {
154 client.getIssueClient().transition(issue, new TransitionInput(transitionFound.getId(), Arrays.asList(fieldInput),
155 Comment.valueOf("My test comment")), pm);
156 }
157 });
158 }
159
160 @Test
161 public void testTransitionWithNoRoleOrGroup() {
162 Comment comment = Comment.valueOf("My text which I am just adding " + new DateTime());
163 testTransitionImpl(comment);
164 }
165
166 @Test
167 public void testTransitionWithRoleLevel() {
168 Comment comment = Comment.createWithRoleLevel("My text which I am just adding " + new DateTime(), "Users");
169 testTransitionImpl(comment);
170 }
171
172 @Test
173 public void testTransitionWithGroupLevel() {
174 Comment comment = Comment.createWithGroupLevel("My text which I am just adding " + new DateTime(), "jira-users");
175 testTransitionImpl(comment);
176 }
177
178 @Test
179 public void testTransitionWithInvalidRole() {
180 final Comment comment = Comment.createWithRoleLevel("My text which I am just adding " + new DateTime(), "some-fake-role");
181 if (IntegrationTestUtil.TESTING_JIRA_5_OR_NEWER) {
182 assertInvalidCommentInput(comment, "Invalid role level specified.");
183 } else {
184 assertInvalidCommentInput(comment, "Invalid role [some-fake-role]");
185 }
186 }
187
188 @Test
189 public void testTransitionWithInvalidGroup() {
190 final Comment comment = Comment.createWithGroupLevel("My text which I am just adding " + new DateTime(), "some-fake-group");
191 assertInvalidCommentInput(comment, "Group: some-fake-group does not exist.");
192 }
193
194 private void assertInvalidCommentInput(final Comment comment, String expectedErrorMsg) {
195 final Issue issue = client.getIssueClient().getIssue("TST-1", pm);
196 final Iterable<Transition> transitions = client.getIssueClient().getTransitions(issue, pm);
197 final Transition transitionFound = TestUtil.getTransitionByName(transitions, "Estimate");
198 final String errorMsg = doesJiraServeCorrectlyErrorMessagesForBadRequestWhileTransitioningIssue()
199 ? expectedErrorMsg : null;
200 assertErrorCode(Response.Status.BAD_REQUEST, errorMsg, new Runnable() {
201 @Override
202 public void run() {
203 client.getIssueClient().transition(issue, new TransitionInput(transitionFound.getId(), comment), pm);
204 }
205 });
206 }
207
208 private void testTransitionImpl(Comment comment) {
209 final Issue issue = client.getIssueClient().getIssue("TST-1", pm);
210 final Iterable<Transition> transitions = client.getIssueClient().getTransitions(issue, pm);
211 Transition transitionFound = TestUtil.getTransitionByName(transitions, "Estimate");
212 DateTime now = new DateTime();
213 client.getIssueClient().transition(issue, new TransitionInput(transitionFound.getId(), comment), pm);
214
215 final Issue changedIssue = client.getIssueClient().getIssue("TST-1", pm);
216 final Comment lastComment = Iterables.getLast(changedIssue.getComments());
217 assertEquals(comment.getBody(), lastComment.getBody());
218 assertEquals(USER_ADMIN, lastComment.getAuthor());
219 assertEquals(USER_ADMIN, lastComment.getUpdateAuthor());
220 assertEquals(lastComment.getCreationDate(), lastComment.getUpdateDate());
221 assertTrue(lastComment.getCreationDate().isAfter(now) || lastComment.getCreationDate().isEqual(now));
222 assertEquals(comment.getVisibility(), lastComment.getVisibility());
223 }
224
225 @Test
226 public void testVoteUnvote() {
227 final Issue issue1 = client.getIssueClient().getIssue("TST-1", pm);
228 assertFalse(issue1.getVotes().hasVoted());
229 assertEquals(1, issue1.getVotes().getVotes());
230 final String expectedMessage = isJira5xOrNewer()
231 ? "You cannot vote for an issue you have reported."
232 : "Nie mo\u017cesz g\u0142osowa\u0107 na zadanie kt\u00f3re utworzy\u0142e\u015b.";
233
234
235 assertErrorCode(Response.Status.NOT_FOUND, expectedMessage, new Runnable() {
236 @Override
237 public void run() {
238 client.getIssueClient().vote(issue1.getVotesUri(), pm);
239 }
240 });
241
242
243 final String issueKey = "TST-7";
244 Issue issue = client.getIssueClient().getIssue(issueKey, pm);
245 assertFalse(issue.getVotes().hasVoted());
246 assertEquals(0, issue.getVotes().getVotes());
247
248 client.getIssueClient().vote(issue.getVotesUri(), pm);
249 issue = client.getIssueClient().getIssue(issueKey, pm);
250 assertTrue(issue.getVotes().hasVoted());
251 assertEquals(1, issue.getVotes().getVotes());
252
253 client.getIssueClient().unvote(issue.getVotesUri(), pm);
254 issue = client.getIssueClient().getIssue(issueKey, pm);
255 assertFalse(issue.getVotes().hasVoted());
256 assertEquals(0, issue.getVotes().getVotes());
257
258 setUser2();
259 issue = client.getIssueClient().getIssue(issueKey, pm);
260 assertFalse(issue.getVotes().hasVoted());
261 assertEquals(0, issue.getVotes().getVotes());
262 final Issue finalIssue = issue;
263 assertErrorCode(Response.Status.NOT_FOUND, "Cannot remove a vote for an issue that the user has not already voted for.",
264 new Runnable() {
265 @Override
266 public void run() {
267 client.getIssueClient().unvote(finalIssue.getVotesUri(), pm);
268 }
269 });
270
271
272 issue = client.getIssueClient().getIssue(issueKey, pm);
273 assertFalse(issue.getVotes().hasVoted());
274 assertEquals(0, issue.getVotes().getVotes());
275 client.getIssueClient().vote(issue.getVotesUri(), pm);
276 issue = client.getIssueClient().getIssue(issueKey, pm);
277 assertTrue(issue.getVotes().hasVoted());
278 assertEquals(1, issue.getVotes().getVotes());
279
280 setClient(ADMIN_USERNAME, ADMIN_PASSWORD);
281 client.getIssueClient().vote(issue.getVotesUri(), pm);
282 issue = client.getIssueClient().getIssue(issueKey, pm);
283 assertTrue(issue.getVotes().hasVoted());
284 assertEquals(2, issue.getVotes().getVotes());
285 }
286
287 @Test
288 public void testWatchUnwatch() {
289 final IssueRestClient issueClient = client.getIssueClient();
290 final Issue issue1 = issueClient.getIssue("TST-1", pm);
291
292 Assert.assertThat(issueClient.getWatchers(issue1.getWatchers().getSelf(), pm).getUsers(),
293 Matchers.not(IterableMatcher.contains(USER_ADMIN)));
294
295 issueClient.watch(issue1.getWatchers().getSelf(), pm);
296 Assert.assertThat(issueClient.getWatchers(issue1.getWatchers().getSelf(), pm).getUsers(), IterableMatcher.contains(USER_ADMIN));
297
298 issueClient.unwatch(issue1.getWatchers().getSelf(), pm);
299 Assert.assertThat(issueClient.getWatchers(issue1.getWatchers().getSelf(), pm).getUsers(), Matchers.not(IterableMatcher.contains(USER_ADMIN)));
300
301 Assert.assertThat(issueClient.getWatchers(issue1.getWatchers().getSelf(), pm).getUsers(), IterableMatcher.contains(USER1));
302 issueClient.removeWatcher(issue1.getWatchers().getSelf(), USER1.getName(), pm);
303 Assert.assertThat(issueClient.getWatchers(issue1.getWatchers().getSelf(), pm).getUsers(), Matchers.not(IterableMatcher.contains(USER1)));
304 issueClient.addWatcher(issue1.getWatchers().getSelf(), USER1.getName(), pm);
305 Assert.assertThat(issueClient.getWatchers(issue1.getWatchers().getSelf(), pm).getUsers(), IterableMatcher.contains(USER1));
306 }
307
308 @Test
309 public void testRemoveWatcherUnauthorized() {
310 final IssueRestClient issueClient = client.getIssueClient();
311 final Issue issue1 = issueClient.getIssue("TST-1", pm);
312 issueClient.watch(issue1.getWatchers().getSelf(), pm);
313
314 setUser1();
315 final IssueRestClient issueClient2 = client.getIssueClient();
316 assertErrorCode(Response.Status.UNAUTHORIZED,
317 "User 'wseliga' is not allowed to remove watchers from issue 'TST-1'", new Runnable() {
318 @Override
319 public void run() {
320 issueClient2.removeWatcher(issue1.getWatchers().getSelf(), ADMIN_USERNAME, pm);
321 }
322 });
323 }
324
325
326 @Test
327 public void testWatchAlreadyWatched() {
328 setUser1();
329 final IssueRestClient issueClient = client.getIssueClient();
330 final Issue issue = issueClient.getIssue("TST-1", pm);
331 Assert.assertThat(client.getIssueClient().getWatchers(issue.getWatchers().getSelf(), pm).getUsers(), IterableMatcher.contains(USER1));
332
333 issueClient.watch(issue.getWatchers().getSelf(), pm);
334 Assert.assertThat(client.getIssueClient().getWatchers(issue.getWatchers().getSelf(), pm).getUsers(), IterableMatcher.contains(USER1));
335 }
336
337 @Test
338 public void testAddWatcherUnauthorized() {
339 final IssueRestClient issueClient = client.getIssueClient();
340 final Issue issue1 = issueClient.getIssue("TST-1", pm);
341 issueClient.addWatcher(issue1.getWatchers().getSelf(), USER1_USERNAME, pm);
342 assertThat(client.getIssueClient().getWatchers(issue1.getWatchers().getSelf(), pm).getUsers(), IterableMatcher.contains(USER1));
343
344 setUser1();
345 assertTrue(client.getIssueClient().getIssue("TST-1", pm).getWatchers().isWatching());
346 String expectedErrorMsg = isJraDev3516Fixed() ? ("User '" + USER1_USERNAME
347 + "' is not allowed to add watchers to issue 'TST-1'") : null;
348 assertErrorCode(Response.Status.UNAUTHORIZED, expectedErrorMsg, new Runnable() {
349 @Override
350 public void run() {
351 client.getIssueClient().addWatcher(issue1.getWatchers().getSelf(), ADMIN_USERNAME, pm);
352 }
353 });
354 }
355
356 private boolean isJraDev3516Fixed() {
357 return client.getMetadataClient().getServerInfo(pm).getBuildNumber() >= ServerVersionConstants.BN_JIRA_4_3;
358 }
359
360
361 public void xtestAddWatcherWhoDoesNotHaveViewIssuePermissions() {
362 final IssueRestClient issueClient = client.getIssueClient();
363 final Issue issue1 = issueClient.getIssue("RST-1", pm);
364 assertErrorCode(Response.Status.BAD_REQUEST, "The user \"" + USER2_USERNAME
365 + "\" does not have permission to view this issue. This user will not be added to the watch list.",
366 new Runnable() {
367 @Override
368 public void run() {
369 issueClient.addWatcher(issue1.getWatchers().getSelf(), USER2_USERNAME, pm);
370 }
371 });
372
373 }
374
375 @Test
376 public void testLinkIssuesWithRoleLevel() {
377 testLinkIssuesImpl(Comment.createWithRoleLevel("A comment about linking", "Administrators"));
378 }
379
380 @Test
381 public void testLinkIssuesWithGroupLevel() {
382 testLinkIssuesImpl(Comment.createWithGroupLevel("A comment about linking", "jira-administrators"));
383 }
384
385 @Test
386 public void testLinkIssuesWithSimpleComment() {
387 testLinkIssuesImpl(Comment.valueOf("A comment about linking"));
388 }
389
390 @Test
391 public void testLinkIssuesWithoutComment() {
392 testLinkIssuesImpl(null);
393 }
394
395 @Test
396 public void testLinkIssuesWithInvalidParams() {
397 if (!doesJiraSupportRestIssueLinking()) {
398 return;
399 }
400 assertErrorCode(Response.Status.NOT_FOUND,
401 IntegrationTestUtil.TESTING_JIRA_5_OR_NEWER ? "Issue Does Not Exist" : "The issue no longer exists.", new Runnable() {
402 @Override
403 public void run() {
404 client.getIssueClient().linkIssue(new LinkIssuesInput("TST-7", "FAKEKEY-1", "Duplicate", null), pm);
405 }
406 });
407
408 assertErrorCode(Response.Status.NOT_FOUND, "No issue link type with name 'NonExistingLinkType' found.", new Runnable() {
409 @Override
410 public void run() {
411 client.getIssueClient().linkIssue(new LinkIssuesInput("TST-7", "TST-6", "NonExistingLinkType", null), pm);
412 }
413 });
414
415 setUser1();
416 final String optionalDot = isJira5xOrNewer() ? "." : "";
417 assertErrorCode(Response.Status.NOT_FOUND, "You do not have the permission to see the specified issue" + optionalDot, new Runnable() {
418 @Override
419 public void run() {
420 client.getIssueClient().linkIssue(new LinkIssuesInput("TST-7", "RST-1", "Duplicate", null), pm);
421 }
422 });
423 assertErrorCode(Response.Status.BAD_REQUEST, "Failed to create comment for issue 'TST-6'\nYou are currently not a member of the project role: Administrators.", new Runnable() {
424 @Override
425 public void run() {
426 client.getIssueClient().linkIssue(new LinkIssuesInput("TST-7", "TST-6", "Duplicate",
427 Comment.createWithRoleLevel("my body", "Administrators")), pm);
428 }
429 });
430 assertErrorCode(Response.Status.BAD_REQUEST, "You are currently not a member of the group: jira-administrators.", new Runnable() {
431 @Override
432 public void run() {
433 client.getIssueClient().linkIssue(new LinkIssuesInput("TST-7", "TST-6", "Duplicate",
434 Comment.createWithGroupLevel("my body", "jira-administrators")), pm);
435 }
436 });
437 assertErrorCode(Response.Status.BAD_REQUEST, "Group: somefakegroup does not exist.", new Runnable() {
438 @Override
439 public void run() {
440 client.getIssueClient().linkIssue(new LinkIssuesInput("TST-7", "TST-6", "Duplicate",
441 Comment.createWithGroupLevel("my body", "somefakegroup")), pm);
442 }
443 });
444
445
446 setUser2();
447 assertErrorCode(Response.Status.UNAUTHORIZED, "No Link Issue Permission for issue 'TST-7'", new Runnable() {
448 @Override
449 public void run() {
450 client.getIssueClient().linkIssue(new LinkIssuesInput("TST-7", "TST-6", "Duplicate", null), pm);
451 }
452 });
453
454 }
455
456
457 private void testLinkIssuesImpl(@Nullable Comment commentInput) {
458 if (!doesJiraSupportRestIssueLinking()) {
459 return;
460 }
461
462 final IssueRestClient issueClient = client.getIssueClient();
463 final Issue originalIssue = issueClient.getIssue("TST-7", pm);
464 int origNumComments = Iterables.size(originalIssue.getComments());
465 assertFalse(originalIssue.getIssueLinks().iterator().hasNext());
466
467 issueClient.linkIssue(new LinkIssuesInput("TST-7", "TST-6", "Duplicate", commentInput), pm);
468
469 final Issue linkedIssue = issueClient.getIssue("TST-7", pm);
470 assertEquals(1, Iterables.size(linkedIssue.getIssueLinks()));
471 final IssueLink addedLink = linkedIssue.getIssueLinks().iterator().next();
472 assertEquals("Duplicate", addedLink.getIssueLinkType().getName());
473 assertEquals("TST-6", addedLink.getTargetIssueKey());
474 assertEquals(IssueLinkType.Direction.OUTBOUND, addedLink.getIssueLinkType().getDirection());
475
476 final int expectedNumComments = commentInput != null ? origNumComments + 1 : origNumComments;
477 assertEquals(expectedNumComments, Iterables.size(linkedIssue.getComments()));
478 if (commentInput != null) {
479 final Comment comment = linkedIssue.getComments().iterator().next();
480 assertEquals(commentInput.getBody(), comment.getBody());
481 assertEquals(USER_ADMIN, comment.getAuthor());
482 assertEquals(commentInput.getVisibility(), comment.getVisibility());
483 } else {
484 assertFalse(linkedIssue.getComments().iterator().hasNext());
485 }
486
487
488 final Issue targetIssue = issueClient.getIssue("TST-6", pm);
489 final IssueLink targetLink = targetIssue.getIssueLinks().iterator().next();
490 assertEquals(IssueLinkType.Direction.INBOUND, targetLink.getIssueLinkType().getDirection());
491 assertEquals("Duplicate", targetLink.getIssueLinkType().getName());
492 }
493
494 private boolean doesJiraSupportAddingAttachment() {
495 return client.getMetadataClient().getServerInfo(pm).getBuildNumber() >= ServerVersionConstants.BN_JIRA_4_3;
496 }
497
498 private boolean doesJiraServeCorrectlyErrorMessagesForBadRequestWhileTransitioningIssue() {
499 return client.getMetadataClient().getServerInfo(pm).getBuildNumber() >= ServerVersionConstants.BN_JIRA_4_3;
500 }
501
502 @Test
503 public void testAddAttachment() throws IOException {
504 if (!doesJiraSupportAddingAttachment()) {
505 return;
506 }
507 final IssueRestClient issueClient = client.getIssueClient();
508 final Issue issue = issueClient.getIssue("TST-3", pm);
509 assertFalse(issue.getAttachments().iterator().hasNext());
510
511 String str = "Wojtek";
512 final String filename1 = "my-test-file";
513 issueClient.addAttachment(pm, issue.getAttachmentsUri(), new ByteArrayInputStream(str.getBytes("UTF-8")), filename1);
514 final String filename2 = "my-picture.png";
515 issueClient.addAttachment(pm, issue.getAttachmentsUri(), JerseyIssueRestClientTest.class.getResourceAsStream("/attachment-test/transparent-png.png"), filename2);
516
517 final Issue issueWithAttachments = issueClient.getIssue("TST-3", pm);
518 final Iterable<Attachment> attachments = issueWithAttachments.getAttachments();
519 assertEquals(2, Iterables.size(attachments));
520 final Iterable<String> attachmentsNames = Iterables.transform(attachments, new Function<Attachment, String>() {
521 @Override
522 public String apply(@Nullable Attachment from) {
523 return from.getFilename();
524 }
525 });
526 assertThat(attachmentsNames, IterableMatcher.hasOnlyElements(filename1, filename2));
527 final Attachment pictureAttachment = Iterables.find(attachments, new Predicate<Attachment>() {
528 @Override
529 public boolean apply(@Nullable Attachment input) {
530 return filename2.equals(input.getFilename());
531 }
532 });
533
534
535
536 assertTrue(
537 IOUtils.contentEquals(JerseyIssueRestClientTest.class.getResourceAsStream("/attachment-test/transparent-png.png"),
538 issueClient.getAttachment(pm, pictureAttachment.getContentUri())));
539 }
540
541 @Test
542 public void testAddAttachments() throws IOException {
543 if (!doesJiraSupportAddingAttachment()) {
544 return;
545 }
546 final IssueRestClient issueClient = client.getIssueClient();
547 final Issue issue = issueClient.getIssue("TST-4", pm);
548 assertFalse(issue.getAttachments().iterator().hasNext());
549
550 final AttachmentInput[] attachmentInputs = new AttachmentInput[3];
551 for (int i = 1; i <= 3; i++) {
552 attachmentInputs[i - 1] = new AttachmentInput("my-test-file-" + i + ".txt", new ByteArrayInputStream(("content-of-the-file-" + i).getBytes("UTF-8")));
553 }
554 issueClient.addAttachments(pm, issue.getAttachmentsUri(), attachmentInputs);
555
556 final Issue issueWithAttachments = issueClient.getIssue("TST-4", pm);
557 final Iterable<Attachment> attachments = issueWithAttachments.getAttachments();
558 assertEquals(3, Iterables.size(attachments));
559 Pattern pattern = Pattern.compile("my-test-file-(\\d)\\.txt");
560 for (Attachment attachment : attachments) {
561 assertTrue(pattern.matcher(attachment.getFilename()).matches());
562 final Matcher matcher = pattern.matcher(attachment.getFilename());
563 matcher.find();
564 final String interfix = matcher.group(1);
565 assertTrue(IOUtils.contentEquals(new ByteArrayInputStream(("content-of-the-file-" + interfix).getBytes("UTF-8")),
566 issueClient.getAttachment(pm, attachment.getContentUri())));
567
568 }
569 }
570
571 @Test
572 public void testAddFileAttachments() throws IOException {
573 if (!doesJiraSupportAddingAttachment()) {
574 return;
575 }
576 final IssueRestClient issueClient = client.getIssueClient();
577 final Issue issue = issueClient.getIssue("TST-5", pm);
578 assertFalse(issue.getAttachments().iterator().hasNext());
579
580 final File tempFile = File.createTempFile("jim-integration-test", ".txt");
581 tempFile.deleteOnExit();
582 FileWriter writer = new FileWriter(tempFile);
583 writer.write("This is the content of my file which I am going to upload to JIRA for testing.");
584 writer.close();
585 issueClient.addAttachments(pm, issue.getAttachmentsUri(), tempFile);
586
587 final Issue issueWithAttachments = issueClient.getIssue("TST-5", pm);
588 final Iterable<Attachment> attachments = issueWithAttachments.getAttachments();
589 assertEquals(1, Iterables.size(attachments));
590 assertTrue(IOUtils.contentEquals(new FileInputStream(tempFile),
591 issueClient.getAttachment(pm, attachments.iterator().next().getContentUri())));
592 }
593
594
595 @Test
596 public void testFetchingUnassignedIssue() {
597 administration.generalConfiguration().setAllowUnassignedIssues(true);
598 assertEquals(USER_ADMIN, client.getIssueClient().getIssue("TST-5", pm).getAssignee());
599
600 navigation.userProfile().changeUserLanguage("angielski (UK)");
601 navigation.issue().unassignIssue("TST-5", "unassigning issue");
602
603
604
605
606 assertNull(client.getIssueClient().getIssue("TST-5", pm).getAssignee());
607 }
608
609 @Test
610 public void testFetchingIssueWithAnonymousComment() {
611 navigation.userProfile().changeUserLanguage("angielski (UK)");
612 administration.permissionSchemes().scheme("Anonymous Permission Scheme").grantPermissionToGroup(15, "");
613 assertEquals(USER_ADMIN, client.getIssueClient().getIssue("TST-5", pm).getAssignee());
614 navigation.logout();
615 navigation.issue().addComment("ANNON-1", "my nice comment");
616 final Issue issue = client.getIssueClient().getIssue("ANNON-1", pm);
617 assertEquals(1, Iterables.size(issue.getComments()));
618 final Comment comment = issue.getComments().iterator().next();
619 assertEquals("my nice comment", comment.getBody());
620 assertNull(comment.getAuthor());
621 assertNull(comment.getUpdateAuthor());
622
623 }
624
625 }