View Javadoc

1   /*
2    * Copyright (C) 2011 Atlassian
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package it;
18  
19  import com.atlassian.jira.nimblefunctests.annotation.JiraBuildNumberDependent;
20  import com.atlassian.jira.nimblefunctests.annotation.LongCondition;
21  import com.atlassian.jira.rest.client.IntegrationTestUtil;
22  import com.atlassian.jira.rest.client.TestUtil;
23  import com.atlassian.jira.rest.client.api.domain.EntityHelper;
24  import com.atlassian.jira.rest.client.api.domain.Issue;
25  import com.atlassian.jira.rest.client.api.domain.Version;
26  import com.atlassian.jira.rest.client.api.domain.VersionRelatedIssuesCount;
27  import com.atlassian.jira.rest.client.api.domain.input.VersionInput;
28  import com.atlassian.jira.rest.client.api.domain.input.VersionInputBuilder;
29  import com.atlassian.jira.rest.client.api.domain.input.VersionPosition;
30  import com.atlassian.jira.rest.client.internal.json.TestConstants;
31  import com.google.common.base.Function;
32  import com.google.common.collect.Iterables;
33  import com.google.common.collect.Lists;
34  import org.hamcrest.collection.IsEmptyIterable;
35  import org.junit.Before;
36  import org.junit.Test;
37  
38  import javax.annotation.Nullable;
39  import javax.ws.rs.core.Response;
40  import java.net.URI;
41  
42  import static com.atlassian.jira.rest.client.TestUtil.getLastPathSegment;
43  import static com.atlassian.jira.rest.client.internal.ServerVersionConstants.BN_JIRA_6;
44  import static com.google.common.collect.Iterables.toArray;
45  import static org.hamcrest.collection.IsIterableContainingInAnyOrder.containsInAnyOrder;
46  import static org.junit.Assert.assertEquals;
47  import static org.junit.Assert.assertNotNull;
48  import static org.junit.Assert.assertThat;
49  
50  public class AsynchronousVersionRestClientTest extends AbstractAsynchronousRestClientTest {
51  
52      @Before
53      public void setup() {
54          IntegrationTestUtil.restoreAppropriateJiraData(TestConstants.DEFAULT_JIRA_DUMP_FILE, administration);
55      }
56  
57      @Test
58      public void testCreateAndUpdateVersion() throws Exception {
59          if (!isJira4x4OrNewer()) {
60              return;
61          }
62  
63          assertThat(Iterables.transform(client.getProjectClient().getProject("TST").claim().getVersions(),
64                  new VersionToNameMapper()), containsInAnyOrder("1.1", "1"));
65  
66          final VersionInput versionInput = VersionInput.create("TST", "My newly created version", "A description\nwith\new line", null, false, false);
67          final Version version = client.getVersionRestClient().createVersion(versionInput).claim();
68          assertVersionInputAndVersionEquals(versionInput, version);
69          assertNotNull(version.getId());
70          assertThat(Iterables.transform(client.getProjectClient().getProject("TST").claim()
71                          .getVersions(), new VersionToNameMapper()),
72                  containsInAnyOrder("1.1", "1", versionInput.getName()));
73  
74          TestUtil.assertErrorCode(Response.Status.BAD_REQUEST, "A version with this name already exists in this project.", new Runnable() {
75              @Override
76              public void run() {
77                  client.getVersionRestClient().createVersion(versionInput).claim();
78              }
79          });
80  
81  
82          final VersionInput versionInput2 = VersionInput.create("TST", "My newly created version2", "A description\nwith\new line", null, false, false);
83          setAnonymousMode();
84          TestUtil.assertErrorCode(IntegrationTestUtil.TESTING_JIRA_5_OR_NEWER ? Response.Status.NOT_FOUND
85                  : Response.Status.UNAUTHORIZED, new Runnable() {
86              @Override
87              public void run() {
88                  client.getVersionRestClient().createVersion(versionInput2).claim();
89              }
90          });
91  
92          setUser2();
93          TestUtil.assertErrorCode(Response.Status.NOT_FOUND, "Project with key 'TST' either does not exist or you do not have permission to create versions in it.", new Runnable() {
94              @Override
95              public void run() {
96                  client.getVersionRestClient().createVersion(versionInput2).claim();
97              }
98          });
99  
100         // now version updates
101         setAdmin();
102         final VersionInput newVersionInput = new VersionInputBuilder(versionInput.getProjectKey(), version)
103                 .setDescription("my updated description").setReleased(true).setName("my updated name").build();
104         client.getVersionRestClient().updateVersion(version.getSelf(), newVersionInput).claim();
105         final Version modifiedVersion = client.getVersionRestClient().updateVersion(version.getSelf(), newVersionInput).claim();
106         assertVersionInputAndVersionEquals(newVersionInput, modifiedVersion);
107 
108         final VersionInput duplicateVersionInput = new VersionInputBuilder("TST", modifiedVersion).setName("1.1").build();
109         TestUtil.assertErrorCode(Response.Status.BAD_REQUEST, "A version with this name already exists in this project.", new Runnable() {
110             @Override
111             public void run() {
112                 client.getVersionRestClient().updateVersion(modifiedVersion.getSelf(), duplicateVersionInput).claim();
113             }
114         });
115 
116         setAnonymousMode();
117         TestUtil.assertErrorCode(IntegrationTestUtil.TESTING_JIRA_5_OR_NEWER ? Response.Status.NOT_FOUND
118                 : Response.Status.UNAUTHORIZED, new Runnable() {
119             @Override
120             public void run() {
121                 client.getVersionRestClient().updateVersion(modifiedVersion.getSelf(), newVersionInput).claim();
122             }
123         });
124 
125         setAdmin();
126         final Version restrictedVersion = client.getVersionRestClient().createVersion(new VersionInputBuilder("RST")
127                 .setName("My version").build()).claim();
128         final VersionInput restrictedVersionInput = new VersionInputBuilder("RST", restrictedVersion)
129                 .setDescription("another description").build();
130         setUser2();
131         TestUtil.assertErrorCode(Response.Status.NOT_FOUND, "You must have browse project rights in order to view versions.", new Runnable() {
132             @Override
133             public void run() {
134                 client.getVersionRestClient().updateVersion(restrictedVersion.getSelf(), restrictedVersionInput).claim();
135             }
136         });
137     }
138 
139     private void assertVersionInputAndVersionEquals(VersionInput versionInput, Version version) {
140         assertEquals(version.getName(), versionInput.getName());
141         assertEquals(version.getDescription(), versionInput.getDescription());
142         assertEquals(version.getReleaseDate(), versionInput.getReleaseDate());
143         assertEquals(version.isArchived(), versionInput.isArchived());
144         assertEquals(version.isReleased(), versionInput.isReleased());
145     }
146 
147 
148     private static class VersionToNameMapper implements Function<Version, String> {
149         @Override
150         public String apply(Version from) {
151             return from.getName();
152         }
153     }
154 
155     @Test
156     public void testGetAndRemoveVersion() {
157         if (!isJira4x4OrNewer()) {
158             return;
159         }
160         final Iterable<Version> versionsInTheBeggining = client.getProjectClient().getProject("TST").claim().getVersions();
161         final VersionInput versionInput = VersionInput
162                 .create("TST", "My newly created version", "A description\nwith\new line", null, false, false);
163         final Version version = client.getVersionRestClient().createVersion(versionInput).claim();
164         assertEquals(version, client.getVersionRestClient().getVersion(version.getSelf()).claim());
165 
166         setAnonymousMode();
167         // weird - inconsistent with PUT/POST
168         TestUtil.assertErrorCode(Response.Status.NOT_FOUND, "You must have browse project rights in order to view versions.", new Runnable() {
169             @Override
170             public void run() {
171                 client.getVersionRestClient().getVersion(version.getSelf()).claim();
172             }
173         });
174 
175         setAdmin();
176         TestUtil.assertErrorCodeWithRegexp(Response.Status.NOT_FOUND, "Could not find version for id .*", new Runnable() {
177             @Override
178             public void run() {
179                 client.getVersionRestClient().getVersion(TestUtil.toUri(version.getSelf().toString() + "9")).claim();
180             }
181         });
182 
183         setUser1();
184         assertEquals(version, client.getVersionRestClient().getVersion(version.getSelf()).claim());
185 
186         TestUtil.assertErrorCode(Response.Status.UNAUTHORIZED, "The user wseliga does not have permission to complete this operation.", new Runnable() {
187             @Override
188             public void run() {
189                 client.getVersionRestClient().removeVersion(version.getSelf(), null, null).claim();
190             }
191         });
192 
193         setAdmin();
194         client.getVersionRestClient().removeVersion(version.getSelf(), null, null).claim();
195         TestUtil.assertErrorCodeWithRegexp(Response.Status.NOT_FOUND, "Could not find version for id .*", new Runnable() {
196             @Override
197             public void run() {
198                 client.getVersionRestClient().getVersion(version.getSelf()).claim();
199             }
200         });
201 
202         assertThat(client.getProjectClient().getProject("TST").claim()
203                 .getVersions(), containsInAnyOrder(toArray(versionsInTheBeggining, Version.class)));
204         for (Version ver : versionsInTheBeggining) {
205             client.getVersionRestClient().removeVersion(ver.getSelf(), null, null).claim();
206         }
207         assertThat(client.getProjectClient().getProject("TST").claim().getVersions(), IsEmptyIterable.<Version>emptyIterable());
208     }
209 
210     @JiraBuildNumberDependent(value = BN_JIRA_6, condition = LongCondition.LESS_THAN)
211     @Test
212     public void testDeleteAndMoveVersionBefore6_0() {
213         if (!isJira4x4OrNewer()) {
214             return;
215         }
216         final Issue issue = client.getIssueClient().getIssue("TST-2").claim();
217         assertThat(Iterables.transform(issue.getFixVersions(), new VersionToNameMapper()), containsInAnyOrder("1.1"));
218         assertThat(Iterables.transform(issue.getAffectedVersions(), new VersionToNameMapper()), containsInAnyOrder("1", "1.1"));
219 
220         final Version version1 = EntityHelper.findEntityByName(client.getProjectClient().getProject("TST").claim()
221                 .getVersions(), "1");
222 
223         final Version version = Iterables.getOnlyElement(issue.getFixVersions());
224         final URI fakeVersionUri = TestUtil.toUri("http://localhost/version/3432");
225         final URI fakeVersionUri2 = TestUtil.toUri("http://localhost/version/34323");
226         // @todo expected error code should be rather NOT FOUND in all cases below - see JRA-25045
227         assertInvalidMoveToVersion(version.getSelf(), fakeVersionUri, null, "The fix version with id " +
228                 getLastPathSegment(fakeVersionUri) + " does not exist.", Response.Status.BAD_REQUEST);
229         // @todo fix when bug JRA-25044 is fixed
230         assertInvalidMoveToVersion(version.getSelf(), TestUtil.toUri("http://localhost/version/fdsa34323"), null,
231                 "Could not find version for id '-1'", Response.Status.NOT_FOUND);
232         assertInvalidMoveToVersion(version.getSelf(), null, fakeVersionUri2, "The affects version with id " +
233                 getLastPathSegment(fakeVersionUri2) + " does not exist.", Response.Status.BAD_REQUEST);
234         assertInvalidMoveToVersion(version.getSelf(), fakeVersionUri, fakeVersionUri2, "The affects version with id " +
235                 getLastPathSegment(fakeVersionUri2) + " does not exist.", Response.Status.BAD_REQUEST);
236 
237         assertEquals(1, client.getVersionRestClient().getNumUnresolvedIssues(version.getSelf()).claim().intValue());
238         assertEquals(new VersionRelatedIssuesCount(version.getSelf(), 1, 1), client.getVersionRestClient()
239                 .getVersionRelatedIssuesCount(version.getSelf()).claim());
240         assertEquals(new VersionRelatedIssuesCount(version.getSelf(), 1, 1), client.getVersionRestClient()
241                 .getVersionRelatedIssuesCount(version.getSelf()).claim());
242 
243         // now removing the first version
244         client.getVersionRestClient().removeVersion(version.getSelf(), version1.getSelf(), version1.getSelf()).claim();
245         final Issue issueAfterVerRemoval = client.getIssueClient().getIssue("TST-2").claim();
246         assertThat(Iterables.transform(issueAfterVerRemoval
247                 .getFixVersions(), new VersionToNameMapper()), containsInAnyOrder("1"));
248         assertThat(Iterables.transform(issueAfterVerRemoval
249                 .getAffectedVersions(), new VersionToNameMapper()), containsInAnyOrder("1"));
250         assertThat(Iterables.transform(client.getProjectClient().getProject("TST").claim()
251                         .getVersions(), new VersionToNameMapper()),
252                 containsInAnyOrder("1"));
253 
254         TestUtil.assertErrorCode(Response.Status.BAD_REQUEST, "You cannot move the issues to the version being deleted.", new Runnable() {
255             @Override
256             public void run() {
257                 client.getVersionRestClient().removeVersion(version1.getSelf(), version1.getSelf(), version1.getSelf()).claim();
258             }
259         });
260 
261         // now removing the other version
262         client.getVersionRestClient().removeVersion(version1.getSelf(), null, null).claim();
263         final Issue issueAfter2VerRemoval = client.getIssueClient().getIssue("TST-2").claim();
264         assertThat(Iterables.transform(issueAfter2VerRemoval.getFixVersions(), new VersionToNameMapper()), IsEmptyIterable
265                 .<String>emptyIterable());
266         assertThat(Iterables.transform(issueAfter2VerRemoval.getAffectedVersions(), new VersionToNameMapper()), IsEmptyIterable
267                 .<String>emptyIterable());
268     }
269 
270     @JiraBuildNumberDependent(BN_JIRA_6)
271     @Test
272     public void testDeleteAndMoveVersion() {
273         final Issue issue = client.getIssueClient().getIssue("TST-2").claim();
274         assertThat(Iterables.transform(issue.getFixVersions(), new VersionToNameMapper()), containsInAnyOrder("1.1"));
275         assertThat(Iterables.transform(issue.getAffectedVersions(), new VersionToNameMapper()), containsInAnyOrder("1", "1.1"));
276 
277         final Version version1 = EntityHelper.findEntityByName(client.getProjectClient().getProject("TST").claim()
278                 .getVersions(), "1");
279 
280         final Version version = Iterables.getOnlyElement(issue.getFixVersions());
281         final URI fakeVersionUri = TestUtil.toUri("http://localhost/version/3432");
282         final URI fakeVersionUri2 = TestUtil.toUri("http://localhost/version/34323");
283         // @todo expected error code should be rather NOT FOUND in all cases below - see JRA-25045
284         assertInvalidMoveToVersion(version.getSelf(), fakeVersionUri, null, "The fix version with id " +
285                 getLastPathSegment(fakeVersionUri) + " does not exist.", Response.Status.BAD_REQUEST);
286         // @todo fix when bug JRA-25044 is fixed
287         assertInvalidMoveToVersion(version.getSelf(), TestUtil.toUri("http://localhost/version/fdsa34323"), null,
288                 "Could not find version for id 'fdsa34323'", Response.Status.NOT_FOUND);
289         assertInvalidMoveToVersion(version.getSelf(), null, fakeVersionUri2, "The affects version with id " +
290                 getLastPathSegment(fakeVersionUri2) + " does not exist.", Response.Status.BAD_REQUEST);
291         assertInvalidMoveToVersion(version.getSelf(), fakeVersionUri, fakeVersionUri2, "The affects version with id " +
292                 getLastPathSegment(fakeVersionUri2) + " does not exist.", Response.Status.BAD_REQUEST);
293 
294         assertEquals(1, client.getVersionRestClient().getNumUnresolvedIssues(version.getSelf()).claim().intValue());
295         assertEquals(new VersionRelatedIssuesCount(version.getSelf(), 1, 1), client.getVersionRestClient()
296                 .getVersionRelatedIssuesCount(version.getSelf()).claim());
297         assertEquals(new VersionRelatedIssuesCount(version.getSelf(), 1, 1), client.getVersionRestClient()
298                 .getVersionRelatedIssuesCount(version.getSelf()).claim());
299 
300         // now removing the first version
301         client.getVersionRestClient().removeVersion(version.getSelf(), version1.getSelf(), version1.getSelf()).claim();
302         final Issue issueAfterVerRemoval = client.getIssueClient().getIssue("TST-2").claim();
303         assertThat(Iterables.transform(issueAfterVerRemoval
304                 .getFixVersions(), new VersionToNameMapper()), containsInAnyOrder("1"));
305         assertThat(Iterables.transform(issueAfterVerRemoval
306                 .getAffectedVersions(), new VersionToNameMapper()), containsInAnyOrder("1"));
307         assertThat(Iterables.transform(client.getProjectClient().getProject("TST").claim()
308                         .getVersions(), new VersionToNameMapper()),
309                 containsInAnyOrder("1"));
310 
311         TestUtil.assertErrorCode(Response.Status.BAD_REQUEST, "You cannot move the issues to the version being deleted.", new Runnable() {
312             @Override
313             public void run() {
314                 client.getVersionRestClient().removeVersion(version1.getSelf(), version1.getSelf(), version1.getSelf()).claim();
315             }
316         });
317 
318         // now removing the other version
319         client.getVersionRestClient().removeVersion(version1.getSelf(), null, null).claim();
320         final Issue issueAfter2VerRemoval = client.getIssueClient().getIssue("TST-2").claim();
321         assertThat(Iterables.transform(issueAfter2VerRemoval.getFixVersions(), new VersionToNameMapper()), IsEmptyIterable
322                 .<String>emptyIterable());
323         assertThat(Iterables.transform(issueAfter2VerRemoval.getAffectedVersions(), new VersionToNameMapper()), IsEmptyIterable
324                 .<String>emptyIterable());
325     }
326 
327     private void assertInvalidMoveToVersion(final URI versionUri, @Nullable final URI moveFixIssuesToVersionUri,
328                                             @Nullable final URI moveAffectedIssuesToVersionUri, final String expectedErrorMsg, final Response.Status status) {
329         TestUtil.assertErrorCode(status, expectedErrorMsg, new Runnable() {
330             @Override
331             public void run() {
332                 client.getVersionRestClient().removeVersion(versionUri, moveFixIssuesToVersionUri, moveAffectedIssuesToVersionUri)
333                         .claim();
334             }
335         });
336     }
337 
338     @Test
339     public void testMoveVersion() {
340         if (!isJira4x4OrNewer()) {
341             return;
342         }
343         final Version v3 = client.getVersionRestClient().createVersion(VersionInput
344                 .create("TST", "my added version", "a description", null, false, false)).claim();
345         assertProjectHasOrderedVersions("TST", "1", "1.1", v3.getName());
346         client.getVersionRestClient().moveVersion(v3.getSelf(), VersionPosition.FIRST).claim();
347         assertProjectHasOrderedVersions("TST", v3.getName(), "1", "1.1");
348         client.getVersionRestClient().moveVersion(v3.getSelf(), VersionPosition.LAST).claim();
349         assertProjectHasOrderedVersions("TST", "1", "1.1", v3.getName());
350         client.getVersionRestClient().moveVersion(v3.getSelf(), VersionPosition.EARLIER).claim();
351         assertProjectHasOrderedVersions("TST", "1", v3.getName(), "1.1");
352         client.getVersionRestClient().moveVersion(v3.getSelf(), VersionPosition.EARLIER).claim();
353         assertProjectHasOrderedVersions("TST", v3.getName(), "1", "1.1");
354         client.getVersionRestClient().moveVersion(v3.getSelf(), VersionPosition.LATER).claim();
355         assertProjectHasOrderedVersions("TST", "1", v3.getName(), "1.1");
356         client.getVersionRestClient().moveVersion(v3.getSelf(), VersionPosition.LATER).claim();
357         assertProjectHasOrderedVersions("TST", "1", "1.1", v3.getName());
358         // later for the last version means nothing - but also no error
359         client.getVersionRestClient().moveVersion(v3.getSelf(), VersionPosition.LATER).claim();
360         assertProjectHasOrderedVersions("TST", "1", "1.1", v3.getName());
361 
362         setUser1();
363         TestUtil.assertErrorCode(Response.Status.UNAUTHORIZED, "You must have global or project administrator rights in order to modify versions.", new Runnable() {
364             @Override
365             public void run() {
366                 client.getVersionRestClient().moveVersion(v3.getSelf(), VersionPosition.FIRST).claim();
367             }
368         });
369 
370     }
371 
372     @Test
373     public void testMoveVersionAfter() {
374         if (!isJira4x4OrNewer()) {
375             return;
376         }
377         final Version v3 = client.getVersionRestClient().createVersion(VersionInput
378                 .create("TST", "my added version", "a description", null, false, false)).claim();
379         final Version v4 = client.getVersionRestClient().createVersion(VersionInput
380                 .create("TST", "my added version2", "a description2", null, true, false)).claim();
381         final Version v1 = Iterables.get(client.getProjectClient().getProject("TST").claim().getVersions(), 0);
382         final String v1n = v1.getName();
383         final String v3n = v3.getName();
384         final String v4n = v4.getName();
385         assertProjectHasOrderedVersions("TST", v1n, "1.1", v3n, v4n);
386         client.getVersionRestClient().moveVersionAfter(v3.getSelf(), v4.getSelf()).claim();
387         assertProjectHasOrderedVersions("TST", v1n, "1.1", v4n, v3n);
388         client.getVersionRestClient().moveVersionAfter(v3.getSelf(), v1.getSelf()).claim();
389         assertProjectHasOrderedVersions("TST", v1n, v3n, "1.1", v4n);
390         client.getVersionRestClient().moveVersionAfter(v1.getSelf(), v4.getSelf()).claim();
391         assertProjectHasOrderedVersions("TST", v3n, "1.1", v4n, v1n);
392 
393         setUser1();
394         TestUtil.assertErrorCode(Response.Status.UNAUTHORIZED, "You must have global or project administrator rights in order to modify versions.", new Runnable() {
395             @Override
396             public void run() {
397                 client.getVersionRestClient().moveVersionAfter(v3.getSelf(), v4.getSelf()).claim();
398             }
399         });
400 
401         setAnonymousMode();
402         TestUtil.assertErrorCode(Response.Status.UNAUTHORIZED, new Runnable() {
403             @Override
404             public void run() {
405                 client.getVersionRestClient().moveVersionAfter(v3.getSelf(), v4.getSelf()).claim();
406             }
407         });
408     }
409 
410 
411     private void assertProjectHasOrderedVersions(String projectKey, String... expectedVersions) {
412         assertEquals(Lists.newArrayList(expectedVersions), Lists.newArrayList(Iterables.transform(client.getProjectClient()
413                 .getProject(projectKey).claim().getVersions(), new VersionToNameMapper())));
414     }
415 }