From f95633b51759060f433a5e7664b84a8642f58e4b Mon Sep 17 00:00:00 2001 From: Pierre-Louis JAEGER Date: Wed, 7 Dec 2016 18:09:20 +0100 Subject: [PATCH 01/11] Tag version to avoid collisions with original module --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 76bbdf66..d409b6a7 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ group = com.cdancy -version = 0.0.10 +version = 0.0.10-pjr artifactoryURL = http://127.0.0.1:8080/artifactory artifactoryUser = admin From 926286707c3853e64858f03e6fc65836c1c92356 Mon Sep 17 00:00:00 2001 From: Pierre-Louis JAEGER Date: Wed, 7 Dec 2016 18:10:06 +0100 Subject: [PATCH 02/11] Update auto-value version to support generics --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 0a67a795..5db65967 100644 --- a/build.gradle +++ b/build.gradle @@ -31,7 +31,7 @@ dependencies { compile ('org.apache.jclouds:jclouds-core:1.9.2') compile ('org.apache.jclouds.driver:jclouds-okhttp:1.9.2') compile ('com.google.auto.service:auto-service:1.0-rc2') - compile ('com.google.auto.value:auto-value:1.1') + compile ('com.google.auto.value:auto-value:1.2') testCompile ('org.apache.jclouds:jclouds-core:1.9.2:tests') testCompile ('org.testng:testng:6.8.21') From ed082328bc80bba13e29f23284bdab14656d9937 Mon Sep 17 00:00:00 2001 From: Pierre-Louis JAEGER Date: Wed, 7 Dec 2016 18:13:33 +0100 Subject: [PATCH 03/11] Add paging API to retrieve project and repository lists --- .../bitbucket/rest/domain/common/Page.java | 39 +++++++++++++++++++ .../bitbucket/rest/domain/common/Utils.java | 28 +++++++++++++ .../rest/domain/project/ProjectPage.java | 39 +++++++++++++++++++ .../domain/repository/RepositoryPage.java | 39 +++++++++++++++++++ .../bitbucket/rest/features/ProjectApi.java | 35 +++++++++++------ .../rest/features/RepositoryApi.java | 33 ++++++++++------ 6 files changed, 190 insertions(+), 23 deletions(-) create mode 100644 src/main/java/com/cdancy/bitbucket/rest/domain/common/Page.java create mode 100644 src/main/java/com/cdancy/bitbucket/rest/domain/common/Utils.java create mode 100644 src/main/java/com/cdancy/bitbucket/rest/domain/project/ProjectPage.java create mode 100644 src/main/java/com/cdancy/bitbucket/rest/domain/repository/RepositoryPage.java diff --git a/src/main/java/com/cdancy/bitbucket/rest/domain/common/Page.java b/src/main/java/com/cdancy/bitbucket/rest/domain/common/Page.java new file mode 100644 index 00000000..5296c315 --- /dev/null +++ b/src/main/java/com/cdancy/bitbucket/rest/domain/common/Page.java @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.cdancy.bitbucket.rest.domain.common; + +import java.util.List; + +import com.cdancy.bitbucket.rest.error.Error; + +public interface Page { + + public abstract int start(); + + public abstract int limit(); + + public abstract int size(); + + public abstract int nextPageStart(); + + public abstract boolean isLastPage(); + + public abstract List values(); + + public abstract List errors(); +} diff --git a/src/main/java/com/cdancy/bitbucket/rest/domain/common/Utils.java b/src/main/java/com/cdancy/bitbucket/rest/domain/common/Utils.java new file mode 100644 index 00000000..5709a95a --- /dev/null +++ b/src/main/java/com/cdancy/bitbucket/rest/domain/common/Utils.java @@ -0,0 +1,28 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.cdancy.bitbucket.rest.domain.common; + +import java.util.List; + +import com.google.common.collect.ImmutableList; + +public class Utils { + public static List nullToEmpty(Iterable input) { + return input == null ? ImmutableList. of() : ImmutableList.copyOf(input); + } +} diff --git a/src/main/java/com/cdancy/bitbucket/rest/domain/project/ProjectPage.java b/src/main/java/com/cdancy/bitbucket/rest/domain/project/ProjectPage.java new file mode 100644 index 00000000..b8077bf7 --- /dev/null +++ b/src/main/java/com/cdancy/bitbucket/rest/domain/project/ProjectPage.java @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.cdancy.bitbucket.rest.domain.project; + +import java.util.List; + +import org.jclouds.javax.annotation.Nullable; +import org.jclouds.json.SerializedNames; + +import com.cdancy.bitbucket.rest.domain.common.Page; +import com.cdancy.bitbucket.rest.domain.common.Utils; +import com.cdancy.bitbucket.rest.error.Error; +import com.google.auto.value.AutoValue; + +@AutoValue +public abstract class ProjectPage implements Page { + + @SerializedNames({ "start", "limit", "size", "nextPageStart", "isLastPage", "values", "errors" }) + public static ProjectPage create(int start, int limit, int size, int nextPageStart, boolean isLastPage, + @Nullable List values, @Nullable List errors) { + return new AutoValue_ProjectPage(start, limit, size, nextPageStart, isLastPage, + Utils.nullToEmpty(values), Utils.nullToEmpty(errors)); + } +} diff --git a/src/main/java/com/cdancy/bitbucket/rest/domain/repository/RepositoryPage.java b/src/main/java/com/cdancy/bitbucket/rest/domain/repository/RepositoryPage.java new file mode 100644 index 00000000..c6b0b25a --- /dev/null +++ b/src/main/java/com/cdancy/bitbucket/rest/domain/repository/RepositoryPage.java @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.cdancy.bitbucket.rest.domain.repository; + +import java.util.List; + +import org.jclouds.javax.annotation.Nullable; +import org.jclouds.json.SerializedNames; + +import com.cdancy.bitbucket.rest.domain.common.Page; +import com.cdancy.bitbucket.rest.domain.common.Utils; +import com.cdancy.bitbucket.rest.error.Error; +import com.google.auto.value.AutoValue; + +@AutoValue +public abstract class RepositoryPage implements Page { + + @SerializedNames({ "start", "limit", "size", "nextPageStart", "isLastPage", "values", "errors" }) + public static RepositoryPage create(int start, int limit, int size, int nextPageStart, boolean isLastPage, + @Nullable List values, @Nullable List errors) { + return new AutoValue_RepositoryPage(start, limit, size, nextPageStart, isLastPage, + Utils.nullToEmpty(values), Utils.nullToEmpty(errors)); + } +} diff --git a/src/main/java/com/cdancy/bitbucket/rest/features/ProjectApi.java b/src/main/java/com/cdancy/bitbucket/rest/features/ProjectApi.java index 70b231ad..f26f53ea 100644 --- a/src/main/java/com/cdancy/bitbucket/rest/features/ProjectApi.java +++ b/src/main/java/com/cdancy/bitbucket/rest/features/ProjectApi.java @@ -17,18 +17,7 @@ package com.cdancy.bitbucket.rest.features; -import com.cdancy.bitbucket.rest.domain.project.Project; -import com.cdancy.bitbucket.rest.domain.pullrequest.PullRequest; -import com.cdancy.bitbucket.rest.fallbacks.BitbucketFallbacks; -import com.cdancy.bitbucket.rest.filters.BitbucketAuthentication; -import com.cdancy.bitbucket.rest.options.CreateProject; -import org.jclouds.rest.annotations.BinderParam; -import org.jclouds.rest.annotations.Fallback; -import org.jclouds.rest.annotations.RequestFilters; -import org.jclouds.rest.binders.BindToJsonPayload; - import javax.inject.Named; - import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; import javax.ws.rs.GET; @@ -36,9 +25,21 @@ import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; - +import javax.ws.rs.QueryParam; import javax.ws.rs.core.MediaType; +import org.jclouds.javax.annotation.Nullable; +import org.jclouds.rest.annotations.BinderParam; +import org.jclouds.rest.annotations.Fallback; +import org.jclouds.rest.annotations.RequestFilters; +import org.jclouds.rest.binders.BindToJsonPayload; + +import com.cdancy.bitbucket.rest.domain.project.Project; +import com.cdancy.bitbucket.rest.domain.project.ProjectPage; +import com.cdancy.bitbucket.rest.fallbacks.BitbucketFallbacks; +import com.cdancy.bitbucket.rest.filters.BitbucketAuthentication; +import com.cdancy.bitbucket.rest.options.CreateProject; + @Produces(MediaType.APPLICATION_JSON) @RequestFilters(BitbucketAuthentication.class) @Path("/rest/api/{jclouds.api-version}/projects") @@ -63,4 +64,14 @@ public interface ProjectApi { @Fallback(BitbucketFallbacks.FalseOnError.class) @DELETE boolean delete(@PathParam("project") String project); + + @GET + @Named("project:list") + @Consumes(MediaType.APPLICATION_JSON) + @Fallback(BitbucketFallbacks.ProjectOnError.class) + ProjectPage list( + @Nullable @QueryParam("start") Integer start, + @Nullable @QueryParam("limit") Integer limit, + @Nullable @QueryParam("name") String name, + @Nullable @QueryParam("permission") String permission); } diff --git a/src/main/java/com/cdancy/bitbucket/rest/features/RepositoryApi.java b/src/main/java/com/cdancy/bitbucket/rest/features/RepositoryApi.java index 908d0fb8..2d076cf0 100644 --- a/src/main/java/com/cdancy/bitbucket/rest/features/RepositoryApi.java +++ b/src/main/java/com/cdancy/bitbucket/rest/features/RepositoryApi.java @@ -17,17 +17,7 @@ package com.cdancy.bitbucket.rest.features; -import com.cdancy.bitbucket.rest.domain.repository.Repository; -import com.cdancy.bitbucket.rest.fallbacks.BitbucketFallbacks; -import com.cdancy.bitbucket.rest.filters.BitbucketAuthentication; -import com.cdancy.bitbucket.rest.options.CreateRepository; -import org.jclouds.rest.annotations.BinderParam; -import org.jclouds.rest.annotations.Fallback; -import org.jclouds.rest.annotations.RequestFilters; -import org.jclouds.rest.binders.BindToJsonPayload; - import javax.inject.Named; - import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; import javax.ws.rs.GET; @@ -35,9 +25,21 @@ import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; - +import javax.ws.rs.QueryParam; import javax.ws.rs.core.MediaType; +import org.jclouds.javax.annotation.Nullable; +import org.jclouds.rest.annotations.BinderParam; +import org.jclouds.rest.annotations.Fallback; +import org.jclouds.rest.annotations.RequestFilters; +import org.jclouds.rest.binders.BindToJsonPayload; + +import com.cdancy.bitbucket.rest.domain.project.ProjectPage; +import com.cdancy.bitbucket.rest.domain.repository.Repository; +import com.cdancy.bitbucket.rest.fallbacks.BitbucketFallbacks; +import com.cdancy.bitbucket.rest.filters.BitbucketAuthentication; +import com.cdancy.bitbucket.rest.options.CreateRepository; + @Produces(MediaType.APPLICATION_JSON) @RequestFilters(BitbucketAuthentication.class) @Path("/rest/api/{jclouds.api-version}/projects") @@ -66,4 +68,13 @@ Repository get(@PathParam("project") String project, @DELETE boolean delete(@PathParam("project") String project, @PathParam("repo") String repo); + + @GET + @Named("repository:list") + @Consumes(MediaType.APPLICATION_JSON) + @Path("/{project}/repos") + @Fallback(BitbucketFallbacks.RepositoryOnError.class) + ProjectPage list(@PathParam("project") String project, + @Nullable @QueryParam("start") Integer start, + @Nullable @QueryParam("limit") Integer limit); } From 734285998f472819f21c530005b838fe40ddb403 Mon Sep 17 00:00:00 2001 From: Pierre-Louis JAEGER Date: Wed, 7 Dec 2016 18:38:56 +0100 Subject: [PATCH 04/11] Factorize ErrorWrapper interface common to all domain objects --- .../rest/domain/common/ErrorsWrapper.java | 27 +++++++++++++++++++ .../bitbucket/rest/domain/common/Page.java | 4 --- .../rest/domain/project/ProjectPage.java | 3 ++- .../domain/repository/RepositoryPage.java | 3 ++- 4 files changed, 31 insertions(+), 6 deletions(-) create mode 100644 src/main/java/com/cdancy/bitbucket/rest/domain/common/ErrorsWrapper.java diff --git a/src/main/java/com/cdancy/bitbucket/rest/domain/common/ErrorsWrapper.java b/src/main/java/com/cdancy/bitbucket/rest/domain/common/ErrorsWrapper.java new file mode 100644 index 00000000..752e976a --- /dev/null +++ b/src/main/java/com/cdancy/bitbucket/rest/domain/common/ErrorsWrapper.java @@ -0,0 +1,27 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.cdancy.bitbucket.rest.domain.common; + +import java.util.List; + +import com.cdancy.bitbucket.rest.error.Error; + +public interface ErrorsWrapper { + + public abstract List errors(); +} diff --git a/src/main/java/com/cdancy/bitbucket/rest/domain/common/Page.java b/src/main/java/com/cdancy/bitbucket/rest/domain/common/Page.java index 5296c315..0d0b6654 100644 --- a/src/main/java/com/cdancy/bitbucket/rest/domain/common/Page.java +++ b/src/main/java/com/cdancy/bitbucket/rest/domain/common/Page.java @@ -19,8 +19,6 @@ import java.util.List; -import com.cdancy.bitbucket.rest.error.Error; - public interface Page { public abstract int start(); @@ -34,6 +32,4 @@ public interface Page { public abstract boolean isLastPage(); public abstract List values(); - - public abstract List errors(); } diff --git a/src/main/java/com/cdancy/bitbucket/rest/domain/project/ProjectPage.java b/src/main/java/com/cdancy/bitbucket/rest/domain/project/ProjectPage.java index b8077bf7..9cd483a3 100644 --- a/src/main/java/com/cdancy/bitbucket/rest/domain/project/ProjectPage.java +++ b/src/main/java/com/cdancy/bitbucket/rest/domain/project/ProjectPage.java @@ -22,13 +22,14 @@ import org.jclouds.javax.annotation.Nullable; import org.jclouds.json.SerializedNames; +import com.cdancy.bitbucket.rest.domain.common.ErrorsWrapper; import com.cdancy.bitbucket.rest.domain.common.Page; import com.cdancy.bitbucket.rest.domain.common.Utils; import com.cdancy.bitbucket.rest.error.Error; import com.google.auto.value.AutoValue; @AutoValue -public abstract class ProjectPage implements Page { +public abstract class ProjectPage implements Page, ErrorsWrapper { @SerializedNames({ "start", "limit", "size", "nextPageStart", "isLastPage", "values", "errors" }) public static ProjectPage create(int start, int limit, int size, int nextPageStart, boolean isLastPage, diff --git a/src/main/java/com/cdancy/bitbucket/rest/domain/repository/RepositoryPage.java b/src/main/java/com/cdancy/bitbucket/rest/domain/repository/RepositoryPage.java index c6b0b25a..ad7e686f 100644 --- a/src/main/java/com/cdancy/bitbucket/rest/domain/repository/RepositoryPage.java +++ b/src/main/java/com/cdancy/bitbucket/rest/domain/repository/RepositoryPage.java @@ -22,13 +22,14 @@ import org.jclouds.javax.annotation.Nullable; import org.jclouds.json.SerializedNames; +import com.cdancy.bitbucket.rest.domain.common.ErrorsWrapper; import com.cdancy.bitbucket.rest.domain.common.Page; import com.cdancy.bitbucket.rest.domain.common.Utils; import com.cdancy.bitbucket.rest.error.Error; import com.google.auto.value.AutoValue; @AutoValue -public abstract class RepositoryPage implements Page { +public abstract class RepositoryPage implements Page, ErrorsWrapper { @SerializedNames({ "start", "limit", "size", "nextPageStart", "isLastPage", "values", "errors" }) public static RepositoryPage create(int start, int limit, int size, int nextPageStart, boolean isLastPage, From cc229882104d1715911e9b93eb201d66e8ca4998 Mon Sep 17 00:00:00 2001 From: Pierre-Louis JAEGER Date: Wed, 7 Dec 2016 22:22:51 +0100 Subject: [PATCH 05/11] Integrate Pull requests issues --- .../com/cdancy/bitbucket/rest/features/ProjectApi.java | 3 +-- .../com/cdancy/bitbucket/rest/features/RepositoryApi.java | 8 ++++---- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/cdancy/bitbucket/rest/features/ProjectApi.java b/src/main/java/com/cdancy/bitbucket/rest/features/ProjectApi.java index f26f53ea..51f570bb 100644 --- a/src/main/java/com/cdancy/bitbucket/rest/features/ProjectApi.java +++ b/src/main/java/com/cdancy/bitbucket/rest/features/ProjectApi.java @@ -69,8 +69,7 @@ public interface ProjectApi { @Named("project:list") @Consumes(MediaType.APPLICATION_JSON) @Fallback(BitbucketFallbacks.ProjectOnError.class) - ProjectPage list( - @Nullable @QueryParam("start") Integer start, + ProjectPage list(@Nullable @QueryParam("start") Integer start, @Nullable @QueryParam("limit") Integer limit, @Nullable @QueryParam("name") String name, @Nullable @QueryParam("permission") String permission); diff --git a/src/main/java/com/cdancy/bitbucket/rest/features/RepositoryApi.java b/src/main/java/com/cdancy/bitbucket/rest/features/RepositoryApi.java index 2d076cf0..2a4bb85e 100644 --- a/src/main/java/com/cdancy/bitbucket/rest/features/RepositoryApi.java +++ b/src/main/java/com/cdancy/bitbucket/rest/features/RepositoryApi.java @@ -34,8 +34,8 @@ import org.jclouds.rest.annotations.RequestFilters; import org.jclouds.rest.binders.BindToJsonPayload; -import com.cdancy.bitbucket.rest.domain.project.ProjectPage; import com.cdancy.bitbucket.rest.domain.repository.Repository; +import com.cdancy.bitbucket.rest.domain.repository.RepositoryPage; import com.cdancy.bitbucket.rest.fallbacks.BitbucketFallbacks; import com.cdancy.bitbucket.rest.filters.BitbucketAuthentication; import com.cdancy.bitbucket.rest.options.CreateRepository; @@ -74,7 +74,7 @@ boolean delete(@PathParam("project") String project, @Consumes(MediaType.APPLICATION_JSON) @Path("/{project}/repos") @Fallback(BitbucketFallbacks.RepositoryOnError.class) - ProjectPage list(@PathParam("project") String project, - @Nullable @QueryParam("start") Integer start, - @Nullable @QueryParam("limit") Integer limit); + RepositoryPage list(@PathParam("project") String project, + @Nullable @QueryParam("start") Integer start, + @Nullable @QueryParam("limit") Integer limit); } From f19a4bb6b64bc219219dcca2fac69897a4e3f6ca Mon Sep 17 00:00:00 2001 From: Pierre-Louis JAEGER Date: Wed, 7 Dec 2016 22:40:52 +0100 Subject: [PATCH 06/11] Changed version to 0.0.10-SNAPSHOT --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index d409b6a7..a58be94f 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ group = com.cdancy -version = 0.0.10-pjr +version = 0.0.10-SNAPSHOT artifactoryURL = http://127.0.0.1:8080/artifactory artifactoryUser = admin From d8332d64f28da193b45f23afe1799442e6971af0 Mon Sep 17 00:00:00 2001 From: Pierre-Louis JAEGER Date: Wed, 7 Dec 2016 22:53:01 +0100 Subject: [PATCH 07/11] Changed version to 0.0.11-SNAPSHOT --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index a58be94f..682bd01d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ group = com.cdancy -version = 0.0.10-SNAPSHOT +version = 0.0.11-SNAPSHOT artifactoryURL = http://127.0.0.1:8080/artifactory artifactoryUser = admin From 89635bd9609670002ace797c3afa6042c59b74d4 Mon Sep 17 00:00:00 2001 From: Pierre-Louis JAEGER Date: Thu, 8 Dec 2016 00:38:08 +0100 Subject: [PATCH 08/11] Addding queryParam argument to assertSent to test URL query parameters Test is more relevant than including parameters in expected path as param order is not significative. Also discard silently empty params. --- .../rest/features/CommentsApiMockTest.java | 17 +++++--- .../rest/features/PullRequestApiMockTest.java | 31 ++++++++++----- .../rest/internal/BaseBitbucketMockTest.java | 39 ++++++++++++++++++- 3 files changed, 70 insertions(+), 17 deletions(-) diff --git a/src/test/java/com/cdancy/bitbucket/rest/features/CommentsApiMockTest.java b/src/test/java/com/cdancy/bitbucket/rest/features/CommentsApiMockTest.java index 30afc949..00443cbe 100644 --- a/src/test/java/com/cdancy/bitbucket/rest/features/CommentsApiMockTest.java +++ b/src/test/java/com/cdancy/bitbucket/rest/features/CommentsApiMockTest.java @@ -17,6 +17,13 @@ package com.cdancy.bitbucket.rest.features; +import static org.testng.Assert.assertNotNull; +import static org.testng.Assert.assertTrue; + +import java.util.Map; + +import org.testng.annotations.Test; + import com.cdancy.bitbucket.rest.BitbucketApi; import com.cdancy.bitbucket.rest.BitbucketApiMetadata; import com.cdancy.bitbucket.rest.domain.comment.Anchor; @@ -24,13 +31,9 @@ import com.cdancy.bitbucket.rest.domain.comment.Parent; import com.cdancy.bitbucket.rest.internal.BaseBitbucketMockTest; import com.cdancy.bitbucket.rest.options.CreateComment; +import com.google.common.collect.ImmutableMap; import com.squareup.okhttp.mockwebserver.MockResponse; import com.squareup.okhttp.mockwebserver.MockWebServer; -import org.testng.annotations.Test; - -import static org.testng.Assert.assertFalse; -import static org.testng.Assert.assertNotNull; -import static org.testng.Assert.assertTrue; /** * Mock tests for the {@link CommentsApi} class. @@ -113,8 +116,10 @@ public void testDeleteComment() throws Exception { boolean pr = api.delete("PRJ", "my-repo", 101, 1, 1); assertNotNull(pr); assertTrue(pr); + + Map queryParams = ImmutableMap.of("version", 1); assertSent(server, "DELETE", "/rest/api/" + BitbucketApiMetadata.API_VERSION - + "/projects/PRJ/repos/my-repo/pull-requests/101/comments/1?version=1"); + + "/projects/PRJ/repos/my-repo/pull-requests/101/comments/1", queryParams); } finally { baseApi.close(); server.shutdown(); diff --git a/src/test/java/com/cdancy/bitbucket/rest/features/PullRequestApiMockTest.java b/src/test/java/com/cdancy/bitbucket/rest/features/PullRequestApiMockTest.java index 040e2919..2c367584 100644 --- a/src/test/java/com/cdancy/bitbucket/rest/features/PullRequestApiMockTest.java +++ b/src/test/java/com/cdancy/bitbucket/rest/features/PullRequestApiMockTest.java @@ -21,21 +21,22 @@ import static org.testng.Assert.assertNotNull; import static org.testng.Assert.assertTrue; -import com.cdancy.bitbucket.rest.domain.pullrequest.PagedChangeResponse; -import com.cdancy.bitbucket.rest.domain.pullrequest.PagedCommitResponse; +import java.util.Map; + import org.testng.annotations.Test; import com.cdancy.bitbucket.rest.BitbucketApi; import com.cdancy.bitbucket.rest.BitbucketApiMetadata; import com.cdancy.bitbucket.rest.domain.pullrequest.MergeStatus; import com.cdancy.bitbucket.rest.domain.pullrequest.MinimalRepository; +import com.cdancy.bitbucket.rest.domain.pullrequest.PagedChangeResponse; +import com.cdancy.bitbucket.rest.domain.pullrequest.PagedCommitResponse; import com.cdancy.bitbucket.rest.domain.pullrequest.ProjectKey; import com.cdancy.bitbucket.rest.domain.pullrequest.PullRequest; import com.cdancy.bitbucket.rest.domain.pullrequest.Reference; - -import com.cdancy.bitbucket.rest.options.CreatePullRequest; - import com.cdancy.bitbucket.rest.internal.BaseBitbucketMockTest; +import com.cdancy.bitbucket.rest.options.CreatePullRequest; +import com.google.common.collect.ImmutableMap; import com.squareup.okhttp.mockwebserver.MockResponse; import com.squareup.okhttp.mockwebserver.MockWebServer; @@ -112,8 +113,10 @@ public void testDeclinePullRequest() throws Exception { assertTrue(pr.id() == 101); assertTrue(pr.state().equalsIgnoreCase("DECLINED")); assertFalse(pr.open()); + + Map queryParams = ImmutableMap.of("version", 1); assertSent(server, "POST", "/rest/api/" + BitbucketApiMetadata.API_VERSION - + "/projects/PRJ/repos/my-repo/pull-requests/101/decline?version=1"); + + "/projects/PRJ/repos/my-repo/pull-requests/101/decline", queryParams); } finally { baseApi.close(); server.shutdown(); @@ -135,8 +138,10 @@ public void testReopenPullRequest() throws Exception { assertTrue(pr.id() == 101); assertTrue(pr.state().equalsIgnoreCase("OPEN")); assertTrue(pr.open()); + + Map queryParams = ImmutableMap.of("version", 1); assertSent(server, "POST", "/rest/api/" + BitbucketApiMetadata.API_VERSION - + "/projects/PRJ/repos/my-repo/pull-requests/101/reopen?version=1"); + + "/projects/PRJ/repos/my-repo/pull-requests/101/reopen", queryParams); } finally { baseApi.close(); @@ -199,8 +204,10 @@ public void testMergePullRequest() throws Exception { assertTrue(pr.id() == 101); assertTrue(pr.state().equalsIgnoreCase("MERGED")); assertFalse(pr.open()); + + Map queryParams = ImmutableMap.of("version", 1); assertSent(server, "POST", "/rest/api/" + BitbucketApiMetadata.API_VERSION - + "/projects/PRJ/repos/my-repo/pull-requests/101/merge?version=1"); + + "/projects/PRJ/repos/my-repo/pull-requests/101/merge", queryParams); } finally { baseApi.close(); server.shutdown(); @@ -240,8 +247,10 @@ public void testGetPullRequestChanges() throws Exception { assertTrue(pr.errors().size() == 0); assertTrue(pr.values().size() == 1); assertNotNull(pr); + + Map queryParams = ImmutableMap.of("withComments", true, "limit", 12); assertSent(server, "GET", "/rest/api/" + BitbucketApiMetadata.API_VERSION - + "/projects/PRJ/repos/my-repo/pull-requests/101/changes?withComments=true&limit=12"); + + "/projects/PRJ/repos/my-repo/pull-requests/101/changes", queryParams); } finally { baseApi.close(); server.shutdown(); @@ -262,8 +271,10 @@ public void testGetPullRequestCommits() throws Exception { assertTrue(pr.errors().size() == 0); assertTrue(pr.values().size() == 1); assertTrue(pr.totalCount() == 1); + + Map queryParams = ImmutableMap.of("withCounts", true, "limit", 1); assertSent(server, "GET", "/rest/api/" + BitbucketApiMetadata.API_VERSION - + "/projects/PRJ/repos/my-repo/pull-requests/101/commits?withCounts=true&limit=1"); + + "/projects/PRJ/repos/my-repo/pull-requests/101/commits", queryParams); } finally { baseApi.close(); server.shutdown(); diff --git a/src/test/java/com/cdancy/bitbucket/rest/internal/BaseBitbucketMockTest.java b/src/test/java/com/cdancy/bitbucket/rest/internal/BaseBitbucketMockTest.java index 05545204..0238d683 100644 --- a/src/test/java/com/cdancy/bitbucket/rest/internal/BaseBitbucketMockTest.java +++ b/src/test/java/com/cdancy/bitbucket/rest/internal/BaseBitbucketMockTest.java @@ -24,6 +24,7 @@ import java.io.IOException; import java.net.URL; +import java.util.Map; import java.util.Properties; import javax.ws.rs.core.HttpHeaders; @@ -34,7 +35,10 @@ import com.cdancy.bitbucket.rest.BitbucketApi; import com.google.common.base.Charsets; +import com.google.common.base.Functions; import com.google.common.base.Throwables; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Maps; import com.google.gson.JsonParser; import com.squareup.okhttp.mockwebserver.MockWebServer; import com.squareup.okhttp.mockwebserver.RecordedRequest; @@ -88,11 +92,44 @@ public String payloadFromResource(String resource) { } } + private static Map extractParams(String path) { + + int qmIndex = path.indexOf('?'); + if (qmIndex <= 0) { + return ImmutableMap.of(); + } + + ImmutableMap.Builder b = ImmutableMap.builder(); + + String[] params = path.substring(qmIndex + 1).split("&"); + for (int i = 0; i < params.length; i++) { + String[] keyValue = params[i].split("=", 2); + if (keyValue.length > 1) { + b.put(keyValue[0], keyValue[1]); + } + } + + return b.build(); + } + protected RecordedRequest assertSent(MockWebServer server, String method, String path) throws InterruptedException { + return assertSent(server, method, path, ImmutableMap. of()); + } + + protected RecordedRequest assertSent(MockWebServer server, String method, String expectedPath, Map queryParams) + throws InterruptedException { + RecordedRequest request = server.takeRequest(); assertThat(request.getMethod()).isEqualTo(method); - assertThat(request.getPath()).isEqualTo(path); assertThat(request.getHeader(HttpHeaders.ACCEPT)).isEqualTo(MediaType.APPLICATION_JSON); + + String path = request.getPath(); + String rawPath = path.contains("?") ? path.substring(0, path.indexOf('?')) : path; + assertThat(rawPath).isEqualTo(expectedPath); + + Map normalizedParams = Maps.transformValues(queryParams, Functions.toStringFunction()); + assertThat(normalizedParams).isEqualTo(extractParams(path)); + return request; } From 8e94f5ff91eb8d07a0d413b22aa39c906ab2150a Mon Sep 17 00:00:00 2001 From: Pierre-Louis JAEGER Date: Wed, 7 Dec 2016 23:47:32 +0100 Subject: [PATCH 09/11] Add mock tests for paging API --- .../rest/features/ProjectApiMockTest.java | 76 +++++++++- .../rest/features/RepositoryApiMockTest.java | 67 +++++++++ src/test/resources/project-page-full.json | 53 +++++++ .../resources/project-page-truncated.json | 39 +++++ src/test/resources/repository-page-full.json | 134 ++++++++++++++++++ .../resources/repository-page-truncated.json | 93 ++++++++++++ 6 files changed, 457 insertions(+), 5 deletions(-) create mode 100644 src/test/resources/project-page-full.json create mode 100644 src/test/resources/project-page-truncated.json create mode 100644 src/test/resources/repository-page-full.json create mode 100644 src/test/resources/repository-page-truncated.json diff --git a/src/test/java/com/cdancy/bitbucket/rest/features/ProjectApiMockTest.java b/src/test/java/com/cdancy/bitbucket/rest/features/ProjectApiMockTest.java index 0b5ce105..2d64d6ad 100644 --- a/src/test/java/com/cdancy/bitbucket/rest/features/ProjectApiMockTest.java +++ b/src/test/java/com/cdancy/bitbucket/rest/features/ProjectApiMockTest.java @@ -17,18 +17,24 @@ package com.cdancy.bitbucket.rest.features; +import static org.assertj.core.api.Assertions.assertThat; +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertNotNull; +import static org.testng.Assert.assertTrue; + +import java.util.Map; + +import org.testng.annotations.Test; + import com.cdancy.bitbucket.rest.BitbucketApi; import com.cdancy.bitbucket.rest.BitbucketApiMetadata; import com.cdancy.bitbucket.rest.domain.project.Project; +import com.cdancy.bitbucket.rest.domain.project.ProjectPage; import com.cdancy.bitbucket.rest.internal.BaseBitbucketMockTest; import com.cdancy.bitbucket.rest.options.CreateProject; +import com.google.common.collect.ImmutableMap; import com.squareup.okhttp.mockwebserver.MockResponse; import com.squareup.okhttp.mockwebserver.MockWebServer; -import org.testng.annotations.Test; - -import static org.testng.Assert.assertNotNull; -import static org.testng.Assert.assertFalse; -import static org.testng.Assert.assertTrue; /** * Mock tests for the {@link ProjectApi} class. @@ -147,4 +153,64 @@ public void testDeleteProjectNonExistent() throws Exception { server.shutdown(); } } + + public void testGetProjectList() throws Exception { + MockWebServer server = mockEtcdJavaWebServer(); + + server.enqueue(new MockResponse().setBody(payloadFromResource("/project-page-full.json")).setResponseCode(200)); + try (BitbucketApi baseApi = api(server.getUrl("/"))) { + ProjectApi api = baseApi.projectApi(); + + ProjectPage projectPage = api.list(null, null, null, null); + + assertSent(server, "GET", "/rest/api/" + BitbucketApiMetadata.API_VERSION + "/projects"); + + assertNotNull(projectPage); + assertThat(projectPage.errors()).isEmpty(); + + int size = projectPage.size(); + int limit = projectPage.limit(); + + assertThat(size).isLessThanOrEqualTo(limit); + assertThat(projectPage.start()).isEqualTo(0); + assertThat(projectPage.isLastPage()).isTrue(); + + assertThat(projectPage.values()).hasSize(size); + assertThat(projectPage.values()).hasOnlyElementsOfType(Project.class); + } finally { + server.shutdown(); + } + } + + public void testGetProjectListWithLimit() throws Exception { + MockWebServer server = mockEtcdJavaWebServer(); + + server.enqueue(new MockResponse().setBody(payloadFromResource("/project-page-truncated.json")).setResponseCode(200)); + try (BitbucketApi baseApi = api(server.getUrl("/"))) { + ProjectApi api = baseApi.projectApi(); + + int start = 0; + int limit = 2; + ProjectPage projectPage = api.list(start, limit, null, null); + + Map queryParams = ImmutableMap.of("start", start, "limit", limit); + assertSent(server, "GET", "/rest/api/" + BitbucketApiMetadata.API_VERSION + "/projects", queryParams); + + assertNotNull(projectPage); + assertThat(projectPage.errors()).isEmpty(); + + int size = projectPage.size(); + + assertThat(size).isEqualTo(limit); + assertThat(projectPage.start()).isEqualTo(start); + assertThat(projectPage.limit()).isEqualTo(limit); + assertThat(projectPage.isLastPage()).isFalse(); + assertThat(projectPage.nextPageStart()).isEqualTo(size); + + assertThat(projectPage.values()).hasSize(size); + assertThat(projectPage.values()).hasOnlyElementsOfType(Project.class); + } finally { + server.shutdown(); + } + } } diff --git a/src/test/java/com/cdancy/bitbucket/rest/features/RepositoryApiMockTest.java b/src/test/java/com/cdancy/bitbucket/rest/features/RepositoryApiMockTest.java index 87070b75..2accfc0d 100644 --- a/src/test/java/com/cdancy/bitbucket/rest/features/RepositoryApiMockTest.java +++ b/src/test/java/com/cdancy/bitbucket/rest/features/RepositoryApiMockTest.java @@ -17,16 +17,21 @@ package com.cdancy.bitbucket.rest.features; +import static org.assertj.core.api.Assertions.assertThat; import static org.testng.Assert.assertNotNull; import static org.testng.Assert.assertTrue; +import java.util.Map; + import org.testng.annotations.Test; import com.cdancy.bitbucket.rest.BitbucketApi; import com.cdancy.bitbucket.rest.BitbucketApiMetadata; import com.cdancy.bitbucket.rest.domain.repository.Repository; +import com.cdancy.bitbucket.rest.domain.repository.RepositoryPage; import com.cdancy.bitbucket.rest.internal.BaseBitbucketMockTest; import com.cdancy.bitbucket.rest.options.CreateRepository; +import com.google.common.collect.ImmutableMap; import com.squareup.okhttp.mockwebserver.MockResponse; import com.squareup.okhttp.mockwebserver.MockWebServer; @@ -151,4 +156,66 @@ public void testDeleteRepositoryNonExistent() throws Exception { server.shutdown(); } } + + public void testGetRepositoryList() throws Exception { + MockWebServer server = mockEtcdJavaWebServer(); + + server.enqueue(new MockResponse().setBody(payloadFromResource("/repository-page-full.json")).setResponseCode(200)); + try (BitbucketApi baseApi = api(server.getUrl("/"))) { + RepositoryApi api = baseApi.repositoryApi(); + + String projectKey = "PRJ1"; + RepositoryPage repositoryPage = api.list(projectKey, null, null); + + assertSent(server, "GET", "/rest/api/" + BitbucketApiMetadata.API_VERSION + "/projects/" + projectKey + "/repos"); + + assertNotNull(repositoryPage); + assertThat(repositoryPage.errors()).isEmpty(); + + int size = repositoryPage.size(); + int limit = repositoryPage.limit(); + + assertThat(size).isLessThanOrEqualTo(limit); + assertThat(repositoryPage.start()).isEqualTo(0); + assertThat(repositoryPage.isLastPage()).isTrue(); + + assertThat(repositoryPage.values()).hasSize(size); + assertThat(repositoryPage.values()).hasOnlyElementsOfType(Repository.class); + } finally { + server.shutdown(); + } + } + + public void testGetRepositoryListWithLimit() throws Exception { + MockWebServer server = mockEtcdJavaWebServer(); + + server.enqueue(new MockResponse().setBody(payloadFromResource("/repository-page-truncated.json")).setResponseCode(200)); + try (BitbucketApi baseApi = api(server.getUrl("/"))) { + RepositoryApi api = baseApi.repositoryApi(); + + String projectKey = "PRJ1"; + int start = 0; + int limit = 2; + RepositoryPage repositoryPage = api.list(projectKey, start, limit); + + Map queryParams = ImmutableMap.of("start", start, "limit", limit); + assertSent(server, "GET", "/rest/api/" + BitbucketApiMetadata.API_VERSION + "/projects/" + projectKey + "/repos", queryParams); + + assertNotNull(repositoryPage); + assertThat(repositoryPage.errors()).isEmpty(); + + int size = repositoryPage.size(); + + assertThat(size).isEqualTo(limit); + assertThat(repositoryPage.start()).isEqualTo(start); + assertThat(repositoryPage.limit()).isEqualTo(limit); + assertThat(repositoryPage.isLastPage()).isFalse(); + assertThat(repositoryPage.nextPageStart()).isEqualTo(size); + + assertThat(repositoryPage.values()).hasSize(size); + assertThat(repositoryPage.values()).hasOnlyElementsOfType(Repository.class); + } finally { + server.shutdown(); + } + } } diff --git a/src/test/resources/project-page-full.json b/src/test/resources/project-page-full.json new file mode 100644 index 00000000..90cbb057 --- /dev/null +++ b/src/test/resources/project-page-full.json @@ -0,0 +1,53 @@ +{ + "size": 3, + "limit": 25, + "start": 0, + "isLastPage": true, + "values": [ + { + "key": "PRJ1", + "id": 1, + "name": "Project 1", + "description": "Mock project #1", + "public": false, + "type": "NORMAL", + "links": { + "self": [ + { + "href": "http://127.0.0.1:7990/projects/PRJ1" + } + ] + } + }, + { + "key": "PRJ2", + "id": 2, + "name": "Project 2", + "description": "Mock project #2", + "public": false, + "type": "NORMAL", + "links": { + "self": [ + { + "href": "http://127.0.0.1:7990/projects/PRJ2" + } + ] + } + }, + { + "key": "PRJ3", + "id": 3, + "name": "Project 3", + "description": "Mock project #3", + "public": false, + "type": "NORMAL", + "links": { + "self": [ + { + "href": "http://127.0.0.1:7990/projects/PRJ3" + } + ] + } + } + ] +} \ No newline at end of file diff --git a/src/test/resources/project-page-truncated.json b/src/test/resources/project-page-truncated.json new file mode 100644 index 00000000..61eede2e --- /dev/null +++ b/src/test/resources/project-page-truncated.json @@ -0,0 +1,39 @@ +{ + "size": 2, + "limit": 2, + "start": 0, + "isLastPage": false, + "nextPageStart": 2, + "values": [ + { + "key": "PRJ1", + "id": 1, + "name": "Project 1", + "description": "Mock project #1", + "public": false, + "type": "NORMAL", + "links": { + "self": [ + { + "href": "http://127.0.0.1:7990/projects/PRJ1" + } + ] + } + }, + { + "key": "PRJ2", + "id": 2, + "name": "Project 2", + "description": "Mock project #2", + "public": false, + "type": "NORMAL", + "links": { + "self": [ + { + "href": "http://127.0.0.1:7990/projects/PRJ2" + } + ] + } + } + ] +} \ No newline at end of file diff --git a/src/test/resources/repository-page-full.json b/src/test/resources/repository-page-full.json new file mode 100644 index 00000000..4a9b64a9 --- /dev/null +++ b/src/test/resources/repository-page-full.json @@ -0,0 +1,134 @@ +{ + "size": 3, + "limit": 25, + "start": 0, + "isLastPage": true, + "values": [ + { + "slug": "repo-1", + "id": 101, + "name": "repo-1", + "scmId": "git", + "state": "AVAILABLE", + "statusMessage": "Available", + "forkable": true, + "project": { + "key": "PRJ1", + "id": 1, + "name": "Project 1", + "description": "Mock project #1", + "public": false, + "type": "NORMAL", + "links": { + "self": [ + { + "href": "http://127.0.0.1:7990/projects/PRJ1" + } + ] + } + }, + "public": false, + "links": { + "clone": [ + { + "href": "https://127.0.0.1/scm/PRJ1/repo-1.git", + "name": "http" + }, + { + "href": "ssh://git@127.0.0.1/PRJ1/repo-1.git", + "name": "ssh" + } + ], + "self": [ + { + "href": "http://127.0.0.1:7990/projects/PRJ1/repos/repo-1/browse" + } + ] + } + }, + { + "slug": "repo-2", + "id": 102, + "name": "repo-2", + "scmId": "git", + "state": "AVAILABLE", + "statusMessage": "Available", + "forkable": true, + "project": { + "key": "PRJ1", + "id": 1, + "name": "Project 1", + "description": "Mock project #1", + "public": false, + "type": "NORMAL", + "links": { + "self": [ + { + "href": "http://127.0.0.1:7990/projects/PRJ1" + } + ] + } + }, + "public": false, + "links": { + "clone": [ + { + "href": "https://127.0.0.1/scm/PRJ1/repo-2.git", + "name": "http" + }, + { + "href": "ssh://git@127.0.0.1/PRJ1/repo-2.git", + "name": "ssh" + } + ], + "self": [ + { + "href": "http://127.0.0.1:7990/projects/PRJ1/repos/repo-2/browse" + } + ] + } + }, + { + "slug": "repo-3", + "id": 103, + "name": "repo-3", + "scmId": "git", + "state": "AVAILABLE", + "statusMessage": "Available", + "forkable": true, + "project": { + "key": "PRJ1", + "id": 1, + "name": "Project 1", + "description": "Mock project #1", + "public": false, + "type": "NORMAL", + "links": { + "self": [ + { + "href": "http://127.0.0.1:7990/projects/PRJ1" + } + ] + } + }, + "public": false, + "links": { + "clone": [ + { + "href": "https://127.0.0.1/scm/PRJ1/repo-3.git", + "name": "http" + }, + { + "href": "ssh://git@127.0.0.1/PRJ1/repo-3.git", + "name": "ssh" + } + ], + "self": [ + { + "href": "http://127.0.0.1:7990/projects/PRJ1/repos/repo-3/browse" + } + ] + } + } + ] +} \ No newline at end of file diff --git a/src/test/resources/repository-page-truncated.json b/src/test/resources/repository-page-truncated.json new file mode 100644 index 00000000..ac9941a1 --- /dev/null +++ b/src/test/resources/repository-page-truncated.json @@ -0,0 +1,93 @@ +{ + "size": 2, + "limit": 2, + "start": 0, + "isLastPage": false, + "nextPageStart": 2, + "values": [ + { + "slug": "repo-1", + "id": 101, + "name": "repo-1", + "scmId": "git", + "state": "AVAILABLE", + "statusMessage": "Available", + "forkable": true, + "project": { + "key": "PRJ1", + "id": 1, + "name": "Project 1", + "description": "Mock project #1", + "public": false, + "type": "NORMAL", + "links": { + "self": [ + { + "href": "http://127.0.0.1:7990/projects/PRJ1" + } + ] + } + }, + "public": false, + "links": { + "clone": [ + { + "href": "https://127.0.0.1/scm/PRJ1/repo-1.git", + "name": "http" + }, + { + "href": "ssh://git@127.0.0.1/PRJ1/repo-1.git", + "name": "ssh" + } + ], + "self": [ + { + "href": "http://127.0.0.1:7990/projects/PRJ1/repos/repo-1/browse" + } + ] + } + }, + { + "slug": "repo-2", + "id": 102, + "name": "repo-2", + "scmId": "git", + "state": "AVAILABLE", + "statusMessage": "Available", + "forkable": true, + "project": { + "key": "PRJ1", + "id": 1, + "name": "Project 1", + "description": "Mock project #1", + "public": false, + "type": "NORMAL", + "links": { + "self": [ + { + "href": "http://127.0.0.1:7990/projects/PRJ1" + } + ] + } + }, + "public": false, + "links": { + "clone": [ + { + "href": "https://127.0.0.1/scm/PRJ1/repo-2.git", + "name": "http" + }, + { + "href": "ssh://git@127.0.0.1/PRJ1/repo-2.git", + "name": "ssh" + } + ], + "self": [ + { + "href": "http://127.0.0.1:7990/projects/PRJ1/repos/repo-2/browse" + } + ] + } + } + ] +} \ No newline at end of file From 650dff6fa45e2b680a68be19b960b4de7933bf63 Mon Sep 17 00:00:00 2001 From: Pierre-Louis JAEGER Date: Thu, 8 Dec 2016 00:52:49 +0100 Subject: [PATCH 10/11] Add live tests for paging API --- .../rest/features/ProjectApiLiveTest.java | 36 +++++++++++++++--- .../rest/features/RepositoryApiLiveTest.java | 38 ++++++++++++++++--- 2 files changed, 63 insertions(+), 11 deletions(-) diff --git a/src/test/java/com/cdancy/bitbucket/rest/features/ProjectApiLiveTest.java b/src/test/java/com/cdancy/bitbucket/rest/features/ProjectApiLiveTest.java index aa049aaf..043fe582 100644 --- a/src/test/java/com/cdancy/bitbucket/rest/features/ProjectApiLiveTest.java +++ b/src/test/java/com/cdancy/bitbucket/rest/features/ProjectApiLiveTest.java @@ -17,20 +17,33 @@ package com.cdancy.bitbucket.rest.features; +import static org.assertj.core.api.Assertions.assertThat; +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertNotNull; +import static org.testng.Assert.assertTrue; + +import java.util.List; + +import org.assertj.core.api.Condition; +import org.testng.annotations.Test; + import com.cdancy.bitbucket.rest.BaseBitbucketApiLiveTest; import com.cdancy.bitbucket.rest.domain.project.Project; +import com.cdancy.bitbucket.rest.domain.project.ProjectPage; import com.cdancy.bitbucket.rest.options.CreateProject; -import org.testng.annotations.Test; - -import static org.testng.Assert.assertNotNull; -import static org.testng.Assert.assertFalse; -import static org.testng.Assert.assertTrue; @Test(groups = "live", testName = "ProjectApiLiveTest", singleThreaded = true) public class ProjectApiLiveTest extends BaseBitbucketApiLiveTest { String projectKey = randomStringLettersOnly(); + Condition withProjectKey = new Condition() { + @Override + public boolean matches(Project value) { + return value.key().equals(projectKey); + } + }; + @Test public void testCreateProject() { CreateProject createProject = CreateProject.create(projectKey, null, null, null); @@ -56,6 +69,19 @@ public void testDeleteProject() { assertTrue(success); } + @Test(dependsOnMethods = "testGetProject") + public void testListProjects() { + ProjectPage projectPage = api().list(0, 100, null, null); + + assertNotNull(projectPage); + assertThat(projectPage.errors()).isEmpty(); + assertThat(projectPage.size()).isGreaterThan(0); + + List projects = projectPage.values(); + assertThat(projects).isNotEmpty(); + assertThat(projects).areExactly(1, withProjectKey); + } + @Test public void testDeleteProjectNonExistent() { boolean success = api().delete(randomStringLettersOnly()); diff --git a/src/test/java/com/cdancy/bitbucket/rest/features/RepositoryApiLiveTest.java b/src/test/java/com/cdancy/bitbucket/rest/features/RepositoryApiLiveTest.java index cc4a8882..a6246a68 100644 --- a/src/test/java/com/cdancy/bitbucket/rest/features/RepositoryApiLiveTest.java +++ b/src/test/java/com/cdancy/bitbucket/rest/features/RepositoryApiLiveTest.java @@ -17,17 +17,23 @@ package com.cdancy.bitbucket.rest.features; +import static org.assertj.core.api.Assertions.assertThat; +import static org.testng.Assert.assertNotNull; +import static org.testng.Assert.assertTrue; + +import java.util.List; + +import org.assertj.core.api.Condition; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + import com.cdancy.bitbucket.rest.BaseBitbucketApiLiveTest; import com.cdancy.bitbucket.rest.domain.project.Project; import com.cdancy.bitbucket.rest.domain.repository.Repository; +import com.cdancy.bitbucket.rest.domain.repository.RepositoryPage; import com.cdancy.bitbucket.rest.options.CreateProject; import com.cdancy.bitbucket.rest.options.CreateRepository; -import org.testng.annotations.AfterClass; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.Test; - -import static org.testng.Assert.assertNotNull; -import static org.testng.Assert.assertTrue; @Test(groups = "live", testName = "RepositoryApiLiveTest", singleThreaded = true) public class RepositoryApiLiveTest extends BaseBitbucketApiLiveTest { @@ -35,6 +41,13 @@ public class RepositoryApiLiveTest extends BaseBitbucketApiLiveTest { String projectKey = randomStringLettersOnly(); String repoKey = randomStringLettersOnly(); + Condition withRepositorySlug = new Condition() { + @Override + public boolean matches(Repository value) { + return value.slug().equals(repoKey); + } + }; + @BeforeClass public void init() { CreateProject createProject = CreateProject.create(projectKey, null, null, null); @@ -67,6 +80,19 @@ public void testDeleteRepository() { assertTrue(success); } + @Test(dependsOnMethods = "testGetRepository") + public void testListProjects() { + RepositoryPage repositoryPage = api().list(projectKey, 0, 100); + + assertNotNull(repositoryPage); + assertThat(repositoryPage.errors()).isEmpty(); + assertThat(repositoryPage.size()).isGreaterThan(0); + + List repositories = repositoryPage.values(); + assertThat(repositories).isNotEmpty(); + assertThat(repositories).areExactly(1, withRepositorySlug); + } + @Test public void testDeleteRepositoryNonExistent() { boolean success = api().delete(projectKey, randomStringLettersOnly()); From 3b547807e93d3d79282f43027f72a2bad8eb2fdf Mon Sep 17 00:00:00 2001 From: Pierre-Louis JAEGER Date: Thu, 8 Dec 2016 00:56:05 +0100 Subject: [PATCH 11/11] Fix Checkstyle issue --- .../rest/internal/BaseBitbucketMockTest.java | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/test/java/com/cdancy/bitbucket/rest/internal/BaseBitbucketMockTest.java b/src/test/java/com/cdancy/bitbucket/rest/internal/BaseBitbucketMockTest.java index 0238d683..4b591e30 100644 --- a/src/test/java/com/cdancy/bitbucket/rest/internal/BaseBitbucketMockTest.java +++ b/src/test/java/com/cdancy/bitbucket/rest/internal/BaseBitbucketMockTest.java @@ -70,7 +70,8 @@ protected Properties setupProperties() { * Create a MockWebServer. * * @return instance of MockWebServer - * @throws IOException if unable to start/play server + * @throws IOException + * if unable to start/play server */ public static MockWebServer mockEtcdJavaWebServer() throws IOException { MockWebServer server = new MockWebServer(); @@ -81,7 +82,8 @@ public static MockWebServer mockEtcdJavaWebServer() throws IOException { /** * Get the String representation of some resource to be used as payload. * - * @param resource String representation of a given resource + * @param resource + * String representation of a given resource * @return payload in String form */ public String payloadFromResource(String resource) { @@ -99,17 +101,17 @@ private static Map extractParams(String path) { return ImmutableMap.of(); } - ImmutableMap.Builder b = ImmutableMap.builder(); + ImmutableMap.Builder builder = ImmutableMap.builder(); String[] params = path.substring(qmIndex + 1).split("&"); for (int i = 0; i < params.length; i++) { String[] keyValue = params[i].split("=", 2); if (keyValue.length > 1) { - b.put(keyValue[0], keyValue[1]); + builder.put(keyValue[0], keyValue[1]); } } - return b.build(); + return builder.build(); } protected RecordedRequest assertSent(MockWebServer server, String method, String path) throws InterruptedException {