1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package it;
17
18 import com.atlassian.jira.nimblefunctests.annotation.JiraBuildNumberDependent;
19 import com.atlassian.jira.nimblefunctests.annotation.RestoreOnce;
20 import com.atlassian.jira.rest.client.GetCreateIssueMetadataOptionsBuilder;
21 import com.atlassian.jira.rest.client.IntegrationTestUtil;
22 import com.atlassian.jira.rest.client.IssueRestClient;
23 import com.atlassian.jira.rest.client.NullProgressMonitor;
24 import com.atlassian.jira.rest.client.domain.Attachment;
25 import com.atlassian.jira.rest.client.domain.BasicUser;
26 import com.atlassian.jira.rest.client.domain.ChangelogGroup;
27 import com.atlassian.jira.rest.client.domain.ChangelogItem;
28 import com.atlassian.jira.rest.client.domain.CimIssueType;
29 import com.atlassian.jira.rest.client.domain.CimProject;
30 import com.atlassian.jira.rest.client.domain.Comment;
31 import com.atlassian.jira.rest.client.domain.Issue;
32 import com.atlassian.jira.rest.client.domain.TimeTracking;
33 import com.atlassian.jira.rest.client.domain.Transition;
34 import com.atlassian.jira.rest.client.domain.Visibility;
35 import com.atlassian.jira.rest.client.domain.Votes;
36 import com.atlassian.jira.rest.client.domain.Watchers;
37 import com.atlassian.jira.rest.client.domain.Worklog;
38 import com.atlassian.jira.rest.client.domain.input.FieldInput;
39 import com.atlassian.jira.rest.client.domain.input.TransitionInput;
40 import com.atlassian.jira.rest.client.internal.json.TestConstants;
41 import com.google.common.base.Predicate;
42 import com.google.common.collect.ImmutableList;
43 import com.google.common.collect.Iterables;
44 import org.joda.time.DateTime;
45 import org.joda.time.format.ISODateTimeFormat;
46 import org.junit.Test;
47
48 import javax.ws.rs.core.Response;
49 import javax.ws.rs.core.UriBuilder;
50 import java.net.URISyntaxException;
51 import java.util.Collections;
52 import java.util.EnumSet;
53 import java.util.Iterator;
54 import java.util.List;
55
56 import static com.atlassian.jira.rest.client.IntegrationTestUtil.USER1;
57 import static com.atlassian.jira.rest.client.IntegrationTestUtil.USER2;
58 import static com.atlassian.jira.rest.client.TestUtil.assertErrorCode;
59 import static com.atlassian.jira.rest.client.internal.ServerVersionConstants.BN_JIRA_5;
60 import static com.google.common.collect.Iterables.toArray;
61 import static org.hamcrest.collection.IsIterableContainingInAnyOrder.containsInAnyOrder;
62 import static org.junit.Assert.*;
63
64
65
66
67 @SuppressWarnings("ConstantConditions")
68 @RestoreOnce(TestConstants.DEFAULT_JIRA_DUMP_FILE)
69 public class JerseyIssueRestClientReadOnlyTest extends AbstractJerseyRestClientTest {
70
71
72 private final DateTime dateTime = ISODateTimeFormat.dateTimeParser().parseDateTime("2010-08-04T17:46:45.454");
73
74 @Test
75 public void testGetWatchers() throws Exception {
76 final Issue issue = client.getIssueClient().getIssue("TST-1", new NullProgressMonitor());
77 final Watchers watchers = client.getIssueClient().getWatchers(issue.getWatchers().getSelf(), new NullProgressMonitor());
78 assertEquals(1, watchers.getNumWatchers());
79 assertFalse(watchers.isWatching());
80 assertThat(watchers.getUsers(), containsInAnyOrder(USER1));
81 }
82
83 @Test
84 public void testGetWatcherForAnonymouslyAccessibleIssue() {
85 setAnonymousMode();
86 final Issue issue = client.getIssueClient().getIssue("ANNON-1", new NullProgressMonitor());
87 final Watchers watchers = client.getIssueClient().getWatchers(issue.getWatchers().getSelf(), pm);
88 assertEquals(1, watchers.getNumWatchers());
89 assertFalse(watchers.isWatching());
90 assertTrue("JRADEV-3594 bug!!!", Iterables.isEmpty(watchers.getUsers()));
91
92 assertEquals(new TimeTracking(2700, 2400, null), issue.getTimeTracking());
93 }
94
95 @Test
96 public void testGetIssueWithAnonymouslyCreatedAttachment() {
97 setAnonymousMode();
98 final Issue issue = client.getIssueClient().getIssue("ANONEDIT-1", new NullProgressMonitor());
99 final Iterator<Attachment> attachmentIterator = issue.getAttachments().iterator();
100 assertTrue(attachmentIterator.hasNext());
101 assertNull(attachmentIterator.next().getAuthor());
102 }
103
104 @Test
105 public void testGetIssueWithAnonymouslyCreatedWorklogEntry() {
106 setAnonymousMode();
107 final Issue issue = client.getIssueClient().getIssue("ANONEDIT-2", new NullProgressMonitor());
108 final Iterator<Worklog> worklogIterator = issue.getWorklogs().iterator();
109 assertTrue(worklogIterator.hasNext());
110 assertNull(worklogIterator.next().getAuthor());
111 }
112
113
114 private void assertEqualsNoUri(BasicUser expected, BasicUser actual) {
115 assertEquals(expected.getName(), actual.getName());
116 assertEquals(expected.getDisplayName(), actual.getDisplayName());
117 }
118
119
120 @Test
121 public void testGetIssue() throws Exception {
122 final Issue issue = client.getIssueClient().getIssue("TST-1", pm);
123 assertEquals("TST-1", issue.getKey());
124 assertTrue(issue.getSelf().toString().startsWith(jiraUri.toString()));
125 assertEqualsNoUri(IntegrationTestUtil.USER_ADMIN, issue.getReporter());
126 assertEqualsNoUri(IntegrationTestUtil.USER_ADMIN, issue.getAssignee());
127
128 assertThat(issue.getLabels(), containsInAnyOrder("a", "bcds"));
129
130 assertEquals(3, Iterables.size(issue.getComments()));
131 final Iterable<String> expectedExpandos = isJira5xOrNewer()
132 ? ImmutableList.of("renderedFields", "names", "schema", "transitions", "operations", "editmeta", "changelog") : ImmutableList.of("html");
133 assertThat(ImmutableList.copyOf(issue.getExpandos()), containsInAnyOrder(toArray(expectedExpandos, String.class)));
134 assertEquals(new TimeTracking(null, 0, 190), issue.getTimeTracking());
135 assertTrue(Iterables.size(issue.getFields()) > 0);
136
137 assertEquals(IntegrationTestUtil.START_PROGRESS_TRANSITION_ID, Iterables.size(issue.getAttachments()));
138 final Iterable<Attachment> items = issue.getAttachments();
139 assertNotNull(items);
140 Attachment attachment1 = new Attachment(IntegrationTestUtil.concat(
141 IntegrationTestUtil.TESTING_JIRA_5_OR_NEWER ? UriBuilder.fromUri(jiraUri).path("/rest/api/2/").build()
142 : jiraRestRootUri, "/attachment/10040"),
143 "dla Paw\u0142a.txt", IntegrationTestUtil.USER_ADMIN, dateTime, 643, "text/plain",
144 IntegrationTestUtil.concat(jiraUri, "/secure/attachment/10040/dla+Paw%C5%82a.txt"), null);
145
146 assertEquals(attachment1, items.iterator().next());
147
148
149 assertNull(issue.getChangelog());
150
151 final Issue issueWithChangelog = client.getIssueClient().getIssue("TST-2", EnumSet.of(IssueRestClient.Expandos.CHANGELOG), pm);
152 final Iterable<ChangelogGroup> changelog = issueWithChangelog.getChangelog();
153 if (isJira5xOrNewer()) {
154 assertNotNull(changelog);
155 final ChangelogGroup chg1 = Iterables.get(changelog, 18);
156 assertEquals("admin", chg1.getAuthor().getName());
157 assertEquals("Administrator", chg1.getAuthor().getDisplayName());
158 assertEquals(new DateTime(2010, 8, 17, 16, 40, 34, 924).toInstant(), chg1.getCreated().toInstant());
159
160 assertEquals(Collections
161 .singletonList(new ChangelogItem(ChangelogItem.FieldType.JIRA, "status", "1", "Open", "3", "In Progress")), chg1
162 .getItems());
163
164 final ChangelogGroup chg2 = Iterables.get(changelog, 20);
165 assertEquals("admin", chg2.getAuthor().getName());
166 assertEquals("Administrator", chg2.getAuthor().getDisplayName());
167 assertEquals(new DateTime(2010, 8, 24, 16, 10, 23, 468).toInstant(), chg2.getCreated().toInstant());
168
169 final List<ChangelogItem> expected = ImmutableList.of(
170 new ChangelogItem(ChangelogItem.FieldType.JIRA, "timeoriginalestimate", null, null, "0", "0"),
171 new ChangelogItem(ChangelogItem.FieldType.CUSTOM, "My Radio buttons", null, null, null, "Another"),
172 new ChangelogItem(ChangelogItem.FieldType.CUSTOM, "project3", null, null, "10000", "Test Project"),
173 new ChangelogItem(ChangelogItem.FieldType.CUSTOM, "My Number Field New", null, null, null, "1.45")
174 );
175 assertEquals(expected, chg2.getItems());
176 }
177 }
178
179 @Test
180 public void testGetIssueWithNonTrivialComments() {
181 final Issue issue = client.getIssueClient().getIssue("TST-2", pm);
182 final Iterable<Comment> comments = issue.getComments();
183 assertEquals(3, Iterables.size(comments));
184 final Comment c1 = Iterables.get(comments, 0);
185 assertEquals(Visibility.role("Administrators"), c1.getVisibility());
186
187 final Comment c3 = Iterables.get(comments, 2);
188 assertEquals(Visibility.group("jira-users"), c3.getVisibility());
189
190 }
191
192 @Test
193 public void testGetIssueWithNoViewWatchersPermission() {
194 setUser1();
195 assertTrue(client.getIssueClient().getIssue("TST-1", pm).getWatchers().isWatching());
196
197 setUser2();
198 final Issue issue = client.getIssueClient().getIssue("TST-1", pm);
199 assertFalse(issue.getWatchers().isWatching());
200 client.getIssueClient().watch(issue.getWatchers().getSelf(), pm);
201 final Issue watchedIssue = client.getIssueClient().getIssue("TST-1", pm);
202 assertTrue(watchedIssue.getWatchers().isWatching());
203 assertEquals(2, watchedIssue.getWatchers().getNumWatchers());
204
205
206
207 assertThat(client.getIssueClient().getWatchers(watchedIssue.getWatchers().getSelf(), pm).getUsers(), containsInAnyOrder(USER2));
208 }
209
210 @Test
211 public void testGetVoter() {
212 final Issue issue = client.getIssueClient().getIssue("TST-1", pm);
213 final Votes votes = client.getIssueClient().getVotes(issue.getVotes().getSelf(), pm);
214 assertFalse(votes.hasVoted());
215 assertThat(votes.getUsers(), containsInAnyOrder(USER1));
216 }
217
218 @Test
219 public void testGetVotersWithoutViewIssuePermission() {
220 final Issue issue = client.getIssueClient().getIssue("RST-1", pm);
221 setUser2();
222 final String optionalDot = isJira5xOrNewer() ? "." : "";
223 assertErrorCode(Response.Status.FORBIDDEN, "You do not have the permission to see the specified issue" + optionalDot, new Runnable() {
224 @Override
225 public void run() {
226 client.getIssueClient().getVotes(issue.getVotes().getSelf(), pm);
227 }
228 });
229 }
230
231 @Test
232 public void testGetVotersWithoutViewVotersPermission() {
233 setUser2();
234 assertNumVotesAndNoVotersDetails("TST-1", 1);
235 }
236
237 @Test
238 public void testGetVotersAnonymously() {
239 setAnonymousMode();
240 assertNumVotesAndNoVotersDetails("ANNON-1", 0);
241 }
242
243
244 private void assertNumVotesAndNoVotersDetails(final String issueKey, final int numVotes) {
245 final Issue issue = client.getIssueClient().getIssue(issueKey, pm);
246 assertEquals(numVotes, issue.getVotes().getVotes());
247 assertFalse(issue.getVotes().hasVoted());
248 final Votes votes = client.getIssueClient().getVotes(issue.getVotes().getSelf(), pm);
249 assertFalse(votes.hasVoted());
250 assertEquals(numVotes, votes.getVotes());
251 assertTrue(Iterables.isEmpty(votes.getUsers()));
252 }
253
254
255 @Test
256 public void testGetTransitions() throws Exception {
257 final Issue issue = client.getIssueClient().getIssue("TST-1", new NullProgressMonitor());
258 final Iterable<Transition> transitions = client.getIssueClient().getTransitions(issue, pm);
259 assertEquals(4, Iterables.size(transitions));
260 assertTrue(Iterables.contains(transitions, new Transition("Start Progress", IntegrationTestUtil.START_PROGRESS_TRANSITION_ID, Collections.<Transition.Field>emptyList())));
261 }
262
263 @Test
264 public void testTransition() throws Exception {
265 final Issue issue = client.getIssueClient().getIssue("TST-1", new NullProgressMonitor());
266 final Iterable<Transition> transitions = client.getIssueClient().getTransitions(issue, pm);
267 assertEquals(4, Iterables.size(transitions));
268 final Transition startProgressTransition = new Transition("Start Progress", IntegrationTestUtil.START_PROGRESS_TRANSITION_ID, Collections.<Transition.Field>emptyList());
269 assertTrue(Iterables.contains(transitions, startProgressTransition));
270
271 client.getIssueClient().transition(issue, new TransitionInput(IntegrationTestUtil.START_PROGRESS_TRANSITION_ID,
272 Collections.<FieldInput>emptyList(), Comment.valueOf("My test comment")), new NullProgressMonitor()) ;
273 final Issue transitionedIssue = client.getIssueClient().getIssue("TST-1", new NullProgressMonitor());
274 assertEquals("In Progress", transitionedIssue.getStatus().getName());
275 final Iterable<Transition> transitionsAfterTransition = client.getIssueClient().getTransitions(issue, pm);
276 assertFalse(Iterables.contains(transitionsAfterTransition, startProgressTransition));
277 final Transition stopProgressTransition = new Transition("Stop Progress", IntegrationTestUtil.STOP_PROGRESS_TRANSITION_ID, Collections.<Transition.Field>emptyList());
278 assertTrue(Iterables.contains(transitionsAfterTransition, stopProgressTransition));
279 }
280
281 @JiraBuildNumberDependent(BN_JIRA_5)
282 @Test
283 public void testGetCreateIssueMetadata() throws URISyntaxException {
284 final Iterable<CimProject> metadataProjects = client
285 .getIssueClient()
286 .getCreateIssueMetadata(new GetCreateIssueMetadataOptionsBuilder().withExpandedIssueTypesFields().build(), pm);
287
288 assertEquals(4, Iterables.size(metadataProjects));
289
290 final CimProject project = Iterables.find(metadataProjects, new Predicate<CimProject>() {
291 @Override
292 public boolean apply(CimProject input) {
293 return "ANONEDIT".equals(input.getKey());
294 }
295 });
296
297 assertEquals(project.getName(), "Anonymous Editable Project");
298
299 for (CimIssueType issueType : project.getIssueTypes()) {
300 assertFalse(String.format("Issue type ('%s') fields are not empty!", issueType.getName()), issueType.getFields().isEmpty());
301 }
302 }
303
304 @JiraBuildNumberDependent(BN_JIRA_5)
305 @Test
306 public void testGetCreateIssueMetadataWithFieldsNotExpanded() throws URISyntaxException {
307 final Iterable<CimProject> metadataProjects = client
308 .getIssueClient()
309 .getCreateIssueMetadata(null, pm);
310
311 assertEquals(4, Iterables.size(metadataProjects));
312
313 final CimProject project = Iterables.find(metadataProjects, new Predicate<CimProject>() {
314 @Override
315 public boolean apply(CimProject input) {
316 return "ANONEDIT".equals(input.getKey());
317 }
318 });
319
320 assertEquals(project.getName(), "Anonymous Editable Project");
321 assertEquals(5, Iterables.size(project.getIssueTypes()));
322
323 for (CimIssueType issueType : project.getIssueTypes()) {
324 assertTrue(issueType.getFields().isEmpty());
325 }
326 }
327
328 @JiraBuildNumberDependent(BN_JIRA_5)
329 @Test
330 public void testGetCreateIssueMetadataWithProjectKeyFilter() throws URISyntaxException {
331 final Iterable<CimProject> metadataProjects = client
332 .getIssueClient()
333 .getCreateIssueMetadata(
334 new GetCreateIssueMetadataOptionsBuilder().withProjectKeys("ANONEDIT", "TST").withExpandedIssueTypesFields().build(),
335 pm
336 );
337
338 assertEquals(2, Iterables.size(metadataProjects));
339
340 final CimProject project = Iterables.find(metadataProjects, new Predicate<CimProject>() {
341 @Override
342 public boolean apply(CimProject input) {
343 return "TST".equals(input.getKey());
344 }
345 });
346
347 assertEquals(project.getName(), "Test Project");
348 assertEquals(5, Iterables.size(project.getIssueTypes()));
349
350 for (CimIssueType issueType : project.getIssueTypes()) {
351 assertFalse(issueType.getFields().isEmpty());
352 }
353 }
354 }