blob: db9c1e7e86129992d190c07da2f4e85775fdff23 [file] [log] [blame]
// Copyright (C) 2018 The Android Open Source Project
//
// Licensed 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.google.gerrit.acceptance.rest.binding;
import static com.google.gerrit.acceptance.GitUtil.assertPushOk;
import static com.google.gerrit.acceptance.GitUtil.pushHead;
import static com.google.gerrit.acceptance.rest.util.RestCall.Method.GET;
import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allow;
import static com.google.gerrit.entities.RefNames.REFS_DASHBOARDS;
import static com.google.gerrit.server.restapi.project.DashboardsCollection.DEFAULT_DASHBOARD_NAME;
import static org.apache.http.HttpStatus.SC_METHOD_NOT_ALLOWED;
import static org.apache.http.HttpStatus.SC_NOT_FOUND;
import com.google.common.collect.ImmutableList;
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.GitUtil;
import com.google.gerrit.acceptance.rest.util.RestApiCallHelper;
import com.google.gerrit.acceptance.rest.util.RestCall;
import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
import com.google.gerrit.entities.LabelFunction;
import com.google.gerrit.entities.Permission;
import com.google.gerrit.entities.Project;
import com.google.gerrit.entities.SubmitRequirement;
import com.google.gerrit.entities.SubmitRequirementExpression;
import com.google.gerrit.extensions.api.changes.ReviewInput;
import com.google.gerrit.extensions.api.projects.BranchInput;
import com.google.gerrit.extensions.api.projects.TagInput;
import com.google.inject.Inject;
import org.eclipse.jgit.junit.TestRepository;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.transport.PushResult;
import org.junit.Test;
/**
* Tests for checking the bindings of the projects REST API.
*
* <p>These tests only verify that the project REST endpoints are correctly bound, they do no test
* the functionality of the project REST endpoints.
*/
public class ProjectsRestApiBindingsIT extends AbstractDaemonTest {
private static final ImmutableList<RestCall> PROJECT_ENDPOINTS =
ImmutableList.of(
RestCall.get("/projects/%s"),
RestCall.put("/projects/%s"),
RestCall.get("/projects/%s/access"),
RestCall.post("/projects/%s/access"),
RestCall.put("/projects/%s/access:review"),
RestCall.put("/projects/%s/ban"),
RestCall.get("/projects/%s/branches"),
RestCall.put("/projects/%s/branches/new-branch"),
RestCall.post("/projects/%s/branches:delete"),
RestCall.post("/projects/%s/check"),
RestCall.get("/projects/%s/check.access"),
RestCall.get("/projects/%s/children"),
// GET /projects/<project>/branches/<branch>/commits is not implemented
RestCall.builder(GET, "/projects/%s/commits").expectedResponseCode(SC_NOT_FOUND).build(),
RestCall.get("/projects/%s/commits:in"),
RestCall.get("/projects/%s/config"),
RestCall.put("/projects/%s/config"),
RestCall.post("/projects/%s/create.change"),
RestCall.get("/projects/%s/dashboards"),
RestCall.get("/projects/%s/description"),
RestCall.put("/projects/%s/description"),
RestCall.delete("/projects/%s/description"),
RestCall.post("/projects/%s/gc"),
RestCall.get("/projects/%s/HEAD"),
RestCall.put("/projects/%s/HEAD"),
RestCall.post("/projects/%s/index"),
RestCall.post("/projects/%s/index.changes"),
RestCall.get("/projects/%s/labels"),
RestCall.post("/projects/%s/labels/"),
RestCall.put("/projects/%s/labels/new-label"),
RestCall.get("/projects/%s/parent"),
RestCall.put("/projects/%s/parent"),
RestCall.get("/projects/%s/statistics.git"),
RestCall.get("/projects/%s/submit_requirements"),
RestCall.put("/projects/%s/submit_requirements/new-sr"),
RestCall.get("/projects/%s/tags"),
RestCall.put("/projects/%s/tags/new-tag"),
RestCall.post("/projects/%s/tags:delete"));
/**
* Child project REST endpoints to be tested, each URL contains placeholders for the parent
* project identifier and the child project identifier.
*/
private static final ImmutableList<RestCall> CHILD_PROJECT_ENDPOINTS =
ImmutableList.of(RestCall.get("/projects/%s/children/%s"));
/**
* Branch REST endpoints to be tested, each URL contains placeholders for the project identifier
* and the branch identifier.
*/
private static final ImmutableList<RestCall> BRANCH_ENDPOINTS =
ImmutableList.of(
RestCall.get("/projects/%s/branches/%s"),
RestCall.put("/projects/%s/branches/%s"),
// GET /projects/<project>/branches/<branch>/files is not implemented
RestCall.builder(GET, "/projects/%s/branches/%s/files")
.expectedResponseCode(SC_NOT_FOUND)
.build(),
RestCall.get("/projects/%s/branches/%s/mergeable"),
// The tests use DfsRepository which does not support getting the reflog.
RestCall.builder(GET, "/projects/%s/branches/%s/reflog")
.expectedResponseCode(SC_METHOD_NOT_ALLOWED)
.expectedMessage("reflog not supported on")
.build(),
RestCall.get("/projects/%s/branches/%s/suggest_reviewers"),
// Branch deletion must be tested last
RestCall.delete("/projects/%s/branches/%s"));
/**
* Branch file REST endpoints to be tested, each URL contains placeholders for the project
* identifier, the branch identifier and the file identifier.
*/
private static final ImmutableList<RestCall> BRANCH_FILE_ENDPOINTS =
ImmutableList.of(RestCall.get("/projects/%s/branches/%s/files/%s/content"));
/**
* Dashboard REST endpoints to be tested, each URL contains placeholders for the project
* identifier and the dashboard identifier.
*/
private static final ImmutableList<RestCall> DASHBOARD_ENDPOINTS =
ImmutableList.of(
RestCall.get("/projects/%s/dashboards/%s"),
RestCall.put("/projects/%s/dashboards/%s"),
// Dashboard deletion must be tested last
RestCall.delete("/projects/%s/dashboards/%s"));
/**
* Tag REST endpoints to be tested, each URL contains placeholders for the project identifier and
* the tag identifier.
*/
private static final ImmutableList<RestCall> TAG_ENDPOINTS =
ImmutableList.of(
RestCall.get("/projects/%s/tags/%s"),
RestCall.put("/projects/%s/tags/%s"),
RestCall.delete("/projects/%s/tags/%s"));
/**
* Commit REST endpoints to be tested, each URL contains placeholders for the project identifier
* and the commit identifier.
*/
private static final ImmutableList<RestCall> COMMIT_ENDPOINTS =
ImmutableList.of(
RestCall.get("/projects/%s/commits/%s"),
RestCall.post("/projects/%s/commits/%s/cherrypick"),
RestCall.get("/projects/%s/commits/%s/files"),
RestCall.get("/projects/%s/commits/%s/in"));
/**
* Commit file REST endpoints to be tested, each URL contains placeholders for the project
* identifier, the commit identifier and the file identifier.
*/
private static final ImmutableList<RestCall> COMMIT_FILE_ENDPOINTS =
ImmutableList.of(RestCall.get("/projects/%s/commits/%s/files/%s/content"));
/**
* Label REST endpoints to be tested, each URL contains placeholders for the project identifier
* and the label name.
*/
private static final ImmutableList<RestCall> LABEL_ENDPOINTS =
ImmutableList.of(
RestCall.get("/projects/%s/labels/%s"),
RestCall.put("/projects/%s/labels/%s"),
// Label deletion must be tested last
RestCall.delete("/projects/%s/labels/%s"));
/**
* Submit requirement REST endpoints to be tested, each URL contains placeholders for the project
* identifier and the submit requirement name.
*/
private static final ImmutableList<RestCall> SUBMIT_REQUIREMENT_ENDPOINTS =
ImmutableList.of(
RestCall.get("/projects/%s/submit_requirements/%s"),
RestCall.put("/projects/%s/submit_requirements/%s"),
// Submit requirement deletion must be tested last
RestCall.delete("/projects/%s/submit_requirements/%s"));
private static final String FILENAME = "test.txt";
@Inject private ProjectOperations projectOperations;
@Test
public void projectEndpoints() throws Exception {
RestApiCallHelper.execute(adminRestSession, PROJECT_ENDPOINTS, project.get());
}
@Test
public void childProjectEndpoints() throws Exception {
Project.NameKey childProject = projectOperations.newProject().parent(project).create();
RestApiCallHelper.execute(
adminRestSession, CHILD_PROJECT_ENDPOINTS, project.get(), childProject.get());
}
@Test
public void branchEndpoints() throws Exception {
RestApiCallHelper.execute(adminRestSession, BRANCH_ENDPOINTS, project.get(), "master");
}
@Test
public void branchFileEndpoints() throws Exception {
createAndSubmitChange(FILENAME);
RestApiCallHelper.execute(
adminRestSession, BRANCH_FILE_ENDPOINTS, project.get(), "master", FILENAME);
}
@Test
public void dashboardEndpoints() throws Exception {
createDefaultDashboard();
RestApiCallHelper.execute(
adminRestSession, DASHBOARD_ENDPOINTS, project.get(), DEFAULT_DASHBOARD_NAME);
}
@Test
public void tagEndpoints() throws Exception {
String tag = "test-tag";
gApi.projects().name(project.get()).tag(tag).create(new TagInput());
RestApiCallHelper.execute(adminRestSession, TAG_ENDPOINTS, project.get(), tag);
}
@Test
public void commitEndpoints() throws Exception {
String commit = createAndSubmitChange(FILENAME);
RestApiCallHelper.execute(adminRestSession, COMMIT_ENDPOINTS, project.get(), commit);
}
@Test
public void commitFileEndpoints() throws Exception {
String commit = createAndSubmitChange(FILENAME);
RestApiCallHelper.execute(
adminRestSession, COMMIT_FILE_ENDPOINTS, project.get(), commit, FILENAME);
}
@Test
public void labelEndpoints() throws Exception {
String label = "Foo-Review";
configLabel(label, LabelFunction.NO_OP);
RestApiCallHelper.execute(adminRestSession, LABEL_ENDPOINTS, project.get(), label);
}
@Test
public void submitRequirementsEndpoints() throws Exception {
// Create the SR, so that the GET endpoint succeeds
configSubmitRequirement(
project,
SubmitRequirement.builder()
.setName("code-review")
.setSubmittabilityExpression(SubmitRequirementExpression.maxCodeReview())
.setAllowOverrideInChildProjects(false)
.build());
RestApiCallHelper.execute(
adminRestSession, SUBMIT_REQUIREMENT_ENDPOINTS, project.get(), "code-review");
}
private String createAndSubmitChange(String filename) throws Exception {
RevCommit c =
testRepo
.commit()
.message("A change")
.parent(projectOperations.project(project).getHead("master"))
.add(filename, "content")
.insertChangeId()
.create();
String id = GitUtil.getChangeId(testRepo, c).get();
testRepo.reset(c);
String r = "refs/for/master";
PushResult pr = pushHead(testRepo, r, false);
assertPushOk(pr, r);
gApi.changes().id(id).current().review(ReviewInput.approve());
gApi.changes().id(id).current().submit();
return c.name();
}
private void createDefaultDashboard() throws Exception {
String dashboardRef = REFS_DASHBOARDS + "team";
projectOperations
.project(project)
.forUpdate()
.add(allow(Permission.CREATE).ref("refs/meta/*").group(adminGroupUuid()))
.update();
gApi.projects().name(project.get()).branch(dashboardRef).create(new BranchInput());
try (Repository r = repoManager.openRepository(project);
TestRepository<Repository> tr = new TestRepository<>(r)) {
TestRepository<Repository>.CommitBuilder cb = tr.branch(dashboardRef).commit();
StringBuilder content = new StringBuilder("[dashboard]\n");
content.append("title = ").append("Open Changes").append("\n");
content.append("[section \"").append("open").append("\"]\n");
content.append("query = ").append("is:open").append("\n");
cb.add("overview", content.toString());
cb.create();
}
try (ProjectConfigUpdate u = updateProject(project)) {
u.getConfig().updateProject(p -> p.setLocalDefaultDashboard(dashboardRef + ":overview"));
u.save();
}
}
}