Convert most of CreateProjectIT to extension API
Left a few tests of the HTTP-specific codepath.
Fix an omission in ProjectApiImpl where the @RequiresCapability
annotation was not being checked on CreateProject.
Change-Id: I657a508f71c00d1101a20d9ff1163c2e04b10bd3
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/project/CreateProjectIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/project/CreateProjectIT.java
index 78132a9..6f35733 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/project/CreateProjectIT.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/project/CreateProjectIT.java
@@ -17,6 +17,7 @@
import static com.google.common.truth.Truth.assertThat;
import static com.google.gerrit.acceptance.rest.project.ProjectAssert.assertProjectInfo;
import static com.google.gerrit.acceptance.rest.project.ProjectAssert.assertProjectOwners;
+import static org.junit.Assert.fail;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
@@ -26,6 +27,10 @@
import com.google.gerrit.extensions.client.InheritableBoolean;
import com.google.gerrit.extensions.client.SubmitType;
import com.google.gerrit.extensions.common.ProjectInfo;
+import com.google.gerrit.extensions.restapi.AuthException;
+import com.google.gerrit.extensions.restapi.ResourceConflictException;
+import com.google.gerrit.extensions.restapi.RestApiException;
+import com.google.gerrit.extensions.restapi.UnprocessableEntityException;
import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.client.RefNames;
@@ -47,29 +52,7 @@
public class CreateProjectIT extends AbstractDaemonTest {
@Test
- public void testCreateProjectApi() throws Exception {
- final String newProjectName = "newProject";
- ProjectInfo p = gApi.projects().create(newProjectName).get();
- assertThat(p.name).isEqualTo(newProjectName);
- ProjectState projectState = projectCache.get(new Project.NameKey(newProjectName));
- assertThat(projectState).isNotNull();
- assertProjectInfo(projectState.getProject(), p);
- assertHead(newProjectName, "refs/heads/master");
- }
-
- @Test
- public void testCreateProjectApiWithGitSuffix() throws Exception {
- final String newProjectName = "newProject";
- ProjectInfo p = gApi.projects().create(newProjectName + ".git").get();
- assertThat(p.name).isEqualTo(newProjectName);
- ProjectState projectState = projectCache.get(new Project.NameKey(newProjectName));
- assertThat(projectState).isNotNull();
- assertProjectInfo(projectState.getProject(), p);
- assertHead(newProjectName, "refs/heads/master");
- }
-
- @Test
- public void testCreateProject() throws Exception {
+ public void testCreateProjectHttp() throws Exception {
final String newProjectName = "newProject";
RestResponse r = adminSession.put("/projects/" + newProjectName);
assertThat(r.getStatusCode()).isEqualTo(HttpStatus.SC_CREATED);
@@ -82,11 +65,17 @@
}
@Test
- public void testCreateProjectWithGitSuffix() throws Exception {
+ public void testCreateProjectHttpWithNameMismatch_BadRequest() throws Exception {
+ ProjectInput in = new ProjectInput();
+ in.name = "otherName";
+ RestResponse r = adminSession.put("/projects/someName", in);
+ assertThat(r.getStatusCode()).isEqualTo(HttpStatus.SC_BAD_REQUEST);
+ }
+
+ @Test
+ public void testCreateProject() throws Exception {
final String newProjectName = "newProject";
- RestResponse r = adminSession.put("/projects/" + newProjectName + ".git");
- assertThat(r.getStatusCode()).isEqualTo(HttpStatus.SC_CREATED);
- ProjectInfo p = newGson().fromJson(r.getReader(), ProjectInfo.class);
+ ProjectInfo p = gApi.projects().create(newProjectName).get();
assertThat(p.name).isEqualTo(newProjectName);
ProjectState projectState = projectCache.get(new Project.NameKey(newProjectName));
assertThat(projectState).isNotNull();
@@ -95,25 +84,28 @@
}
@Test
- public void testCreateProjectWithNameMismatch_BadRequest() throws Exception {
- ProjectInput in = new ProjectInput();
- in.name = "otherName";
- RestResponse r = adminSession.put("/projects/someName", in);
- assertThat(r.getStatusCode()).isEqualTo(HttpStatus.SC_BAD_REQUEST);
+ public void testCreateProjectWithGitSuffix() throws Exception {
+ final String newProjectName = "newProject";
+ ProjectInfo p = gApi.projects().create(newProjectName + ".git").get();
+ assertThat(p.name).isEqualTo(newProjectName);
+ ProjectState projectState = projectCache.get(new Project.NameKey(newProjectName));
+ assertThat(projectState).isNotNull();
+ assertProjectInfo(projectState.getProject(), p);
+ assertHead(newProjectName, "refs/heads/master");
}
@Test
public void testCreateProjectWithProperties() throws Exception {
final String newProjectName = "newProject";
ProjectInput in = new ProjectInput();
+ in.name = newProjectName;
in.description = "Test description";
in.submitType = SubmitType.CHERRY_PICK;
in.useContributorAgreements = InheritableBoolean.TRUE;
in.useSignedOffBy = InheritableBoolean.TRUE;
in.useContentMerge = InheritableBoolean.TRUE;
in.requireChangeId = InheritableBoolean.TRUE;
- RestResponse r = adminSession.put("/projects/" + newProjectName, in);
- ProjectInfo p = newGson().fromJson(r.getReader(), ProjectInfo.class);
+ ProjectInfo p = gApi.projects().create(in).get();
assertThat(p.name).isEqualTo(newProjectName);
Project project = projectCache.get(new Project.NameKey(newProjectName)).getProject();
assertProjectInfo(project, p);
@@ -128,12 +120,15 @@
@Test
public void testCreateChildProject() throws Exception {
final String parentName = "parent";
- RestResponse r = adminSession.put("/projects/" + parentName);
- r.consume();
- final String childName = "child";
ProjectInput in = new ProjectInput();
+ in.name = parentName;
+ gApi.projects().create(in);
+
+ final String childName = "child";
+ in = new ProjectInput();
+ in.name = childName;
in.parent = parentName;
- r = adminSession.put("/projects/" + childName, in);
+ gApi.projects().create(in);
Project project = projectCache.get(new Project.NameKey(childName)).getProject();
assertThat(project.getParentName()).isEqualTo(in.parent);
}
@@ -142,21 +137,22 @@
public void testCreateChildProjectUnderNonExistingParent_UnprocessableEntity()
throws Exception {
ProjectInput in = new ProjectInput();
+ in.name = "newProjectName";
in.parent = "non-existing-project";
- RestResponse r = adminSession.put("/projects/child", in);
- assertThat(r.getStatusCode()).isEqualTo(HttpStatus.SC_UNPROCESSABLE_ENTITY);
+ assertCreateFails(in, UnprocessableEntityException.class);
}
@Test
public void testCreateProjectWithOwner() throws Exception {
final String newProjectName = "newProject";
ProjectInput in = new ProjectInput();
+ in.name = newProjectName;
in.owners = Lists.newArrayListWithCapacity(3);
in.owners.add("Anonymous Users"); // by name
in.owners.add(SystemGroupBackend.REGISTERED_USERS.get()); // by UUID
in.owners.add(Integer.toString(groupCache.get(
new AccountGroup.NameKey("Administrators")).getId().get())); // by ID
- adminSession.put("/projects/" + newProjectName, in);
+ gApi.projects().create(in);
ProjectState projectState = projectCache.get(new Project.NameKey(newProjectName));
Set<AccountGroup.UUID> expectedOwnerIds = Sets.newHashSetWithExpectedSize(3);
expectedOwnerIds.add(SystemGroupBackend.ANONYMOUS_USERS);
@@ -169,17 +165,18 @@
public void testCreateProjectWithNonExistingOwner_UnprocessableEntity()
throws Exception {
ProjectInput in = new ProjectInput();
+ in.name = "newProjectName";
in.owners = Collections.singletonList("non-existing-group");
- RestResponse r = adminSession.put("/projects/newProject", in);
- assertThat(r.getStatusCode()).isEqualTo(HttpStatus.SC_UNPROCESSABLE_ENTITY);
+ assertCreateFails(in, UnprocessableEntityException.class);
}
@Test
public void testCreatePermissionOnlyProject() throws Exception {
final String newProjectName = "newProject";
ProjectInput in = new ProjectInput();
+ in.name = newProjectName;
in.permissionsOnly = true;
- adminSession.put("/projects/" + newProjectName, in);
+ gApi.projects().create(in);
assertHead(newProjectName, RefNames.REFS_CONFIG);
}
@@ -187,8 +184,9 @@
public void testCreateProjectWithEmptyCommit() throws Exception {
final String newProjectName = "newProject";
ProjectInput in = new ProjectInput();
+ in.name = newProjectName;
in.createEmptyCommit = true;
- adminSession.put("/projects/" + newProjectName, in);
+ gApi.projects().create(in);
assertEmptyCommit(newProjectName, "refs/heads/master");
}
@@ -196,12 +194,13 @@
public void testCreateProjectWithBranches() throws Exception {
final String newProjectName = "newProject";
ProjectInput in = new ProjectInput();
+ in.name = newProjectName;
in.createEmptyCommit = true;
in.branches = Lists.newArrayListWithCapacity(3);
in.branches.add("refs/heads/test");
in.branches.add("refs/heads/master");
in.branches.add("release"); // without 'refs/heads' prefix
- adminSession.put("/projects/" + newProjectName, in);
+ gApi.projects().create(in);
assertHead(newProjectName, "refs/heads/test");
assertEmptyCommit(newProjectName, "refs/heads/test", "refs/heads/master",
"refs/heads/release");
@@ -209,15 +208,18 @@
@Test
public void testCreateProjectWithoutCapability_Forbidden() throws Exception {
- RestResponse r = userSession.put("/projects/newProject");
- assertThat(r.getStatusCode()).isEqualTo(HttpStatus.SC_FORBIDDEN);
+ setApiUser(user);
+ ProjectInput in = new ProjectInput();
+ in.name = "newProject";
+ assertCreateFails(in, AuthException.class);
}
@Test
public void testCreateProjectWhenProjectAlreadyExists_Conflict()
throws Exception {
- RestResponse r = adminSession.put("/projects/All-Projects");
- assertThat(r.getStatusCode()).isEqualTo(HttpStatus.SC_CONFLICT);
+ ProjectInput in = new ProjectInput();
+ in.name = allProjects.get();
+ assertCreateFails(in, ResourceConflictException.class);
}
private AccountGroup.UUID groupUuid(String groupName) {
@@ -251,4 +253,14 @@
}
}
}
+
+ private void assertCreateFails(ProjectInput in,
+ Class<? extends RestApiException> errType) throws Exception {
+ try {
+ gApi.projects().create(in);
+ fail("Expected " + errType.getSimpleName());
+ } catch (RestApiException expected) {
+ assertThat(expected).isInstanceOf(errType);
+ }
+ }
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/api/projects/ProjectApiImpl.java b/gerrit-server/src/main/java/com/google/gerrit/server/api/projects/ProjectApiImpl.java
index f80762d..219931e 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/api/projects/ProjectApiImpl.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/api/projects/ProjectApiImpl.java
@@ -14,6 +14,8 @@
package com.google.gerrit.server.api.projects;
+import static com.google.gerrit.server.account.CapabilityUtils.checkRequiresCapability;
+
import com.google.gerrit.common.errors.ProjectCreationFailedException;
import com.google.gerrit.extensions.api.projects.BranchApi;
import com.google.gerrit.extensions.api.projects.ChildProjectApi;
@@ -27,7 +29,7 @@
import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.gerrit.extensions.restapi.TopLevelResource;
-import com.google.gerrit.extensions.restapi.UnprocessableEntityException;
+import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.project.ChildProjectsCollection;
import com.google.gerrit.server.project.CreateProject;
import com.google.gerrit.server.project.GetDescription;
@@ -49,6 +51,7 @@
ProjectApiImpl create(String name);
}
+ private final Provider<CurrentUser> user;
private final Provider<CreateProject.Factory> createProjectFactory;
private final ProjectApiImpl.Factory projectApi;
private final ProjectsCollection projects;
@@ -62,7 +65,8 @@
private final BranchApiImpl.Factory branchApi;
@AssistedInject
- ProjectApiImpl(Provider<CreateProject.Factory> createProjectFactory,
+ ProjectApiImpl(Provider<CurrentUser> user,
+ Provider<CreateProject.Factory> createProjectFactory,
ProjectApiImpl.Factory projectApi,
ProjectsCollection projects,
GetDescription getDescription,
@@ -72,13 +76,14 @@
ProjectJson projectJson,
BranchApiImpl.Factory branchApiFactory,
@Assisted ProjectResource project) {
- this(createProjectFactory, projectApi, projects, getDescription,
+ this(user, createProjectFactory, projectApi, projects, getDescription,
putDescription, childApi, children, projectJson, branchApiFactory,
project, null);
}
@AssistedInject
- ProjectApiImpl(Provider<CreateProject.Factory> createProjectFactory,
+ ProjectApiImpl(Provider<CurrentUser> user,
+ Provider<CreateProject.Factory> createProjectFactory,
ProjectApiImpl.Factory projectApi,
ProjectsCollection projects,
GetDescription getDescription,
@@ -88,12 +93,13 @@
ProjectJson projectJson,
BranchApiImpl.Factory branchApiFactory,
@Assisted String name) {
- this(createProjectFactory, projectApi, projects, getDescription,
+ this(user, createProjectFactory, projectApi, projects, getDescription,
putDescription, childApi, children, projectJson, branchApiFactory, null,
name);
}
- private ProjectApiImpl(Provider<CreateProject.Factory> createProjectFactory,
+ private ProjectApiImpl(Provider<CurrentUser> user,
+ Provider<CreateProject.Factory> createProjectFactory,
ProjectApiImpl.Factory projectApi,
ProjectsCollection projects,
GetDescription getDescription,
@@ -104,6 +110,7 @@
BranchApiImpl.Factory branchApiFactory,
ProjectResource project,
String name) {
+ this.user = user;
this.createProjectFactory = createProjectFactory;
this.projectApi = projectApi;
this.projects = projects;
@@ -131,12 +138,11 @@
if (in.name != null && !name.equals(in.name)) {
throw new BadRequestException("name must match input.name");
}
+ checkRequiresCapability(user, null, CreateProject.class);
createProjectFactory.get().create(name)
.apply(TopLevelResource.INSTANCE, in);
return projectApi.create(projects.parse(name));
- } catch (BadRequestException | UnprocessableEntityException
- | ResourceNotFoundException | ProjectCreationFailedException
- | IOException e) {
+ } catch (ProjectCreationFailedException | IOException e) {
throw new RestApiException("Cannot create project: " + e.getMessage(), e);
}
}