Convert ListBranchesTest into an acceptance test
Add an acceptance test for the REST endpoint to list branches and remove the old RPC implementation classes for listing branches including the unit test. Change-Id: Id5d18163871b78cf2fd6680cae5f1b5a89c40105 Signed-off-by: Edwin Kempin <edwin.kempin@sap.com>
This commit is contained in:
parent
b5f15620b0
commit
a7c0ba2b50
@ -80,8 +80,18 @@ public class GitUtil {
|
||||
|
||||
public static void createProject(SshSession s, String name, Project.NameKey parent)
|
||||
throws JSchException, IOException {
|
||||
createProject(s, name, parent, true);
|
||||
}
|
||||
|
||||
public static void createProject(SshSession s, String name,
|
||||
Project.NameKey parent, boolean emptyCommit)
|
||||
throws JSchException, IOException {
|
||||
StringBuilder b = new StringBuilder();
|
||||
b.append("gerrit create-project --empty-commit --name \"");
|
||||
b.append("gerrit create-project");
|
||||
if (emptyCommit) {
|
||||
b.append(" --empty-commit");
|
||||
}
|
||||
b.append(" --name \"");
|
||||
b.append(name);
|
||||
b.append("\"");
|
||||
if (parent != null) {
|
||||
|
@ -0,0 +1,62 @@
|
||||
// Copyright (C) 2013 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.project;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class BranchAssert {
|
||||
|
||||
public static void assertBranches(List<BranchInfo> expectedBranches,
|
||||
List<BranchInfo> actualBranches) {
|
||||
List<BranchInfo> missingBranches = Lists.newArrayList(actualBranches);
|
||||
for (final BranchInfo b : expectedBranches) {
|
||||
BranchInfo info =
|
||||
Iterables.find(actualBranches, new Predicate<BranchInfo>() {
|
||||
@Override
|
||||
public boolean apply(BranchInfo info) {
|
||||
return info.ref.equals(b.ref);
|
||||
}
|
||||
}, null);
|
||||
assertNotNull("missing branch: " + b.ref, info);
|
||||
assertBranchInfo(b, info);
|
||||
missingBranches.remove(info);
|
||||
}
|
||||
assertTrue("unexpected branches: " + missingBranches,
|
||||
missingBranches.isEmpty());
|
||||
}
|
||||
|
||||
public static void assertBranchInfo(BranchInfo expected, BranchInfo actual) {
|
||||
assertEquals(expected.ref, actual.ref);
|
||||
if (expected.revision != null) {
|
||||
assertEquals(expected.revision, actual.revision);
|
||||
}
|
||||
assertEquals(expected.can_delete, toBoolean(actual.can_delete));
|
||||
}
|
||||
|
||||
private static boolean toBoolean(Boolean b) {
|
||||
if (b == null) {
|
||||
return false;
|
||||
}
|
||||
return b.booleanValue();
|
||||
}
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
// Copyright (C) 2013 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.project;
|
||||
|
||||
public class BranchInfo {
|
||||
public String ref;
|
||||
public String revision;
|
||||
public Boolean can_delete;
|
||||
|
||||
public BranchInfo() {
|
||||
}
|
||||
|
||||
public BranchInfo(String ref, String revision, boolean canDelete) {
|
||||
this.ref = ref;
|
||||
this.revision = revision;
|
||||
this.can_delete = canDelete;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return ref;
|
||||
}
|
||||
}
|
@ -0,0 +1,227 @@
|
||||
// Copyright (C) 2013 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.project;
|
||||
|
||||
import static com.google.gerrit.acceptance.git.GitUtil.cloneProject;
|
||||
import static com.google.gerrit.acceptance.git.GitUtil.createProject;
|
||||
import static com.google.gerrit.acceptance.git.GitUtil.initSsh;
|
||||
import static com.google.gerrit.acceptance.rest.project.BranchAssert.assertBranches;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.gerrit.acceptance.AbstractDaemonTest;
|
||||
import com.google.gerrit.acceptance.AccountCreator;
|
||||
import com.google.gerrit.acceptance.RestResponse;
|
||||
import com.google.gerrit.acceptance.RestSession;
|
||||
import com.google.gerrit.acceptance.SshSession;
|
||||
import com.google.gerrit.acceptance.TestAccount;
|
||||
import com.google.gerrit.acceptance.git.PushOneCommit;
|
||||
import com.google.gerrit.common.data.AccessSection;
|
||||
import com.google.gerrit.common.data.Permission;
|
||||
import com.google.gerrit.common.data.PermissionRule;
|
||||
import com.google.gerrit.reviewdb.client.AccountGroup;
|
||||
import com.google.gerrit.reviewdb.client.Project;
|
||||
import com.google.gerrit.reviewdb.server.ReviewDb;
|
||||
import com.google.gerrit.server.account.GroupCache;
|
||||
import com.google.gerrit.server.git.MetaDataUpdate;
|
||||
import com.google.gerrit.server.git.ProjectConfig;
|
||||
import com.google.gerrit.server.project.ProjectCache;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import com.google.gwtorm.server.OrmException;
|
||||
import com.google.gwtorm.server.SchemaFactory;
|
||||
import com.google.inject.Inject;
|
||||
|
||||
import com.jcraft.jsch.JSchException;
|
||||
|
||||
import org.apache.http.HttpStatus;
|
||||
import org.eclipse.jgit.api.Git;
|
||||
import org.eclipse.jgit.api.errors.GitAPIException;
|
||||
import org.eclipse.jgit.errors.ConfigInvalidException;
|
||||
import org.eclipse.jgit.errors.RepositoryNotFoundException;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class ListBranchesIT extends AbstractDaemonTest {
|
||||
|
||||
@Inject
|
||||
private AccountCreator accounts;
|
||||
|
||||
@Inject
|
||||
private MetaDataUpdate.Server metaDataUpdateFactory;
|
||||
|
||||
@Inject
|
||||
private ProjectCache projectCache;
|
||||
|
||||
@Inject
|
||||
private GroupCache groupCache;
|
||||
|
||||
@Inject
|
||||
private SchemaFactory<ReviewDb> reviewDbProvider;
|
||||
|
||||
private TestAccount admin;
|
||||
private RestSession session;
|
||||
private SshSession sshSession;
|
||||
private Project.NameKey project;
|
||||
private Git git;
|
||||
private ReviewDb db;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
admin = accounts.create("admin", "admin@example.com", "Administrator",
|
||||
"Administrators");
|
||||
session = new RestSession(admin);
|
||||
|
||||
project = new Project.NameKey("p");
|
||||
initSsh(admin);
|
||||
sshSession = new SshSession(admin);
|
||||
createProject(sshSession, project.get());
|
||||
git = cloneProject(sshSession.getUrl() + "/" + project.get());
|
||||
db = reviewDbProvider.open();
|
||||
}
|
||||
|
||||
@After
|
||||
public void cleanup() {
|
||||
db.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void listBranchesOfNonExistingProject_NotFound() throws IOException {
|
||||
assertEquals(HttpStatus.SC_NOT_FOUND,
|
||||
GET("/projects/non-existing/branches").getStatusCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void listBranchesOfNonVisibleProject_NotFound() throws IOException,
|
||||
OrmException, JSchException, ConfigInvalidException {
|
||||
blockRead(project, "refs/*");
|
||||
RestSession session =
|
||||
new RestSession(accounts.create("user", "user@example.com", "User"));
|
||||
assertEquals(HttpStatus.SC_NOT_FOUND,
|
||||
session.get("/projects/" + project.get() + "/branches").getStatusCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void listBranchesOfEmptyProject() throws IOException, JSchException {
|
||||
Project.NameKey emptyProject = new Project.NameKey("empty");
|
||||
createProject(sshSession, emptyProject.get(), null, false);
|
||||
RestResponse r = session.get("/projects/" + emptyProject.get() + "/branches");
|
||||
List<BranchInfo> result =
|
||||
(new Gson()).fromJson(r.getReader(),
|
||||
new TypeToken<List<BranchInfo>>() {}.getType());
|
||||
List<BranchInfo> expected = Lists.asList(
|
||||
new BranchInfo("refs/meta/config", null, false),
|
||||
new BranchInfo[] {
|
||||
new BranchInfo("HEAD", null, false)
|
||||
});
|
||||
assertBranches(expected, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void listBranches() throws IOException, GitAPIException {
|
||||
pushTo("refs/heads/master");
|
||||
String masterCommit = git.getRepository().getRef("master").getTarget().getObjectId().getName();
|
||||
pushTo("refs/heads/dev");
|
||||
String devCommit = git.getRepository().getRef("master").getTarget().getObjectId().getName();
|
||||
RestResponse r = session.get("/projects/" + project.get() + "/branches");
|
||||
List<BranchInfo> result =
|
||||
(new Gson()).fromJson(r.getReader(),
|
||||
new TypeToken<List<BranchInfo>>() {}.getType());
|
||||
List<BranchInfo> expected = Lists.asList(
|
||||
new BranchInfo("refs/meta/config", null, false),
|
||||
new BranchInfo[] {
|
||||
new BranchInfo("HEAD", "master", false),
|
||||
new BranchInfo("refs/heads/master", masterCommit, false),
|
||||
new BranchInfo("refs/heads/dev", devCommit, true)
|
||||
});
|
||||
assertBranches(expected, result);
|
||||
|
||||
// verify correct sorting
|
||||
assertEquals("HEAD", result.get(0).ref);
|
||||
assertEquals("refs/meta/config", result.get(1).ref);
|
||||
assertEquals("refs/heads/dev", result.get(2).ref);
|
||||
assertEquals("refs/heads/master", result.get(3).ref);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void listBranchesSomeHidden() throws IOException, GitAPIException,
|
||||
ConfigInvalidException, OrmException, JSchException {
|
||||
blockRead(project, "refs/heads/dev");
|
||||
RestSession session =
|
||||
new RestSession(accounts.create("user", "user@example.com", "User"));
|
||||
pushTo("refs/heads/master");
|
||||
String masterCommit = git.getRepository().getRef("master").getTarget().getObjectId().getName();
|
||||
pushTo("refs/heads/dev");
|
||||
RestResponse r = session.get("/projects/" + project.get() + "/branches");
|
||||
List<BranchInfo> result =
|
||||
(new Gson()).fromJson(r.getReader(),
|
||||
new TypeToken<List<BranchInfo>>() {}.getType());
|
||||
// refs/meta/config is hidden since user is no project owner
|
||||
List<BranchInfo> expected = Lists.asList(
|
||||
new BranchInfo("HEAD", "master", false),
|
||||
new BranchInfo[] {
|
||||
new BranchInfo("refs/heads/master", masterCommit, false),
|
||||
});
|
||||
assertBranches(expected, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void listBranchesHeadHidden() throws IOException, GitAPIException,
|
||||
ConfigInvalidException, OrmException, JSchException {
|
||||
blockRead(project, "refs/heads/master");
|
||||
RestSession session =
|
||||
new RestSession(accounts.create("user", "user@example.com", "User"));
|
||||
pushTo("refs/heads/master");
|
||||
pushTo("refs/heads/dev");
|
||||
String devCommit = git.getRepository().getRef("master").getTarget().getObjectId().getName();
|
||||
RestResponse r = session.get("/projects/" + project.get() + "/branches");
|
||||
List<BranchInfo> result =
|
||||
(new Gson()).fromJson(r.getReader(),
|
||||
new TypeToken<List<BranchInfo>>() {}.getType());
|
||||
// refs/meta/config is hidden since user is no project owner
|
||||
assertBranches(Collections.singletonList(new BranchInfo("refs/heads/dev",
|
||||
devCommit, false)), result);
|
||||
}
|
||||
|
||||
private RestResponse GET(String endpoint) throws IOException {
|
||||
return session.get(endpoint);
|
||||
}
|
||||
|
||||
private void blockRead(Project.NameKey project, String ref)
|
||||
throws RepositoryNotFoundException, IOException, ConfigInvalidException {
|
||||
MetaDataUpdate md = metaDataUpdateFactory.create(project);
|
||||
md.setMessage("Grant submit on " + ref);
|
||||
ProjectConfig config = ProjectConfig.read(md);
|
||||
AccessSection s = config.getAccessSection(ref, true);
|
||||
Permission p = s.getPermission(Permission.READ, true);
|
||||
AccountGroup adminGroup = groupCache.get(AccountGroup.REGISTERED_USERS);
|
||||
PermissionRule rule = new PermissionRule(config.resolve(adminGroup));
|
||||
rule.setBlock();
|
||||
p.add(rule);
|
||||
config.commit(md);
|
||||
projectCache.evict(config.getProject());
|
||||
}
|
||||
|
||||
private PushOneCommit.Result pushTo(String ref) throws GitAPIException,
|
||||
IOException {
|
||||
PushOneCommit push = new PushOneCommit(db, admin.getIdent());
|
||||
return push.to(git, ref);
|
||||
}
|
||||
}
|
@ -1,96 +0,0 @@
|
||||
// Copyright (C) 2012 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.common.data;
|
||||
|
||||
public class AddBranchResult {
|
||||
protected ListBranchesResult listBranchesResult;
|
||||
protected Error error;
|
||||
|
||||
protected AddBranchResult() {
|
||||
}
|
||||
|
||||
public AddBranchResult(final Error error) {
|
||||
this.error = error;
|
||||
}
|
||||
|
||||
public AddBranchResult(final ListBranchesResult listBranchesResult) {
|
||||
this.listBranchesResult = listBranchesResult;
|
||||
}
|
||||
|
||||
public ListBranchesResult getListBranchesResult() {
|
||||
return listBranchesResult;
|
||||
}
|
||||
|
||||
public boolean hasError() {
|
||||
return error != null;
|
||||
}
|
||||
|
||||
public Error getError() {
|
||||
return error;
|
||||
}
|
||||
|
||||
public static class Error {
|
||||
public static enum Type {
|
||||
/** The branch cannot be created because the given branch name is invalid. */
|
||||
INVALID_NAME,
|
||||
|
||||
/** The branch cannot be created because the given revision is invalid. */
|
||||
INVALID_REVISION,
|
||||
|
||||
/**
|
||||
* The branch cannot be created under the given refname prefix (e.g
|
||||
* branches cannot be created under magic refname prefixes).
|
||||
*/
|
||||
BRANCH_CREATION_NOT_ALLOWED_UNDER_REFNAME_PREFIX,
|
||||
|
||||
/** The branch that should be created exists already. */
|
||||
BRANCH_ALREADY_EXISTS,
|
||||
|
||||
/**
|
||||
* The branch cannot be created because it conflicts with an existing
|
||||
* branch (branches cannot be nested).
|
||||
*/
|
||||
BRANCH_CREATION_CONFLICT
|
||||
}
|
||||
|
||||
protected Type type;
|
||||
protected String refname;
|
||||
|
||||
protected Error() {
|
||||
}
|
||||
|
||||
public Error(final Type type) {
|
||||
this(type, null);
|
||||
}
|
||||
|
||||
public Error(final Type type, final String refname) {
|
||||
this.type = type;
|
||||
this.refname = refname;
|
||||
}
|
||||
|
||||
public Type getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public String getRefname() {
|
||||
return refname;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return type + " " + refname;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,51 +0,0 @@
|
||||
// Copyright (C) 2010 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.common.data;
|
||||
|
||||
import com.google.gerrit.reviewdb.client.Branch;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* It holds list of branches and boolean to indicate if it is allowed to add new
|
||||
* branches.
|
||||
*/
|
||||
public final class ListBranchesResult {
|
||||
protected boolean noRepository;
|
||||
protected boolean canAdd;
|
||||
protected List<Branch> branches;
|
||||
|
||||
protected ListBranchesResult() {
|
||||
}
|
||||
|
||||
public ListBranchesResult(List<Branch> branches, boolean canAdd,
|
||||
boolean noRepository) {
|
||||
this.branches = branches;
|
||||
this.canAdd = canAdd;
|
||||
this.noRepository = noRepository;
|
||||
}
|
||||
|
||||
public boolean getNoRepository() {
|
||||
return noRepository;
|
||||
}
|
||||
|
||||
public boolean getCanAdd() {
|
||||
return canAdd;
|
||||
}
|
||||
|
||||
public List<Branch> getBranches() {
|
||||
return branches;
|
||||
}
|
||||
}
|
@ -1,75 +0,0 @@
|
||||
// Copyright (C) 2009 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.httpd.rpc.project;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.gerrit.common.data.ListBranchesResult;
|
||||
import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
|
||||
import com.google.gerrit.httpd.rpc.Handler;
|
||||
import com.google.gerrit.reviewdb.client.Branch;
|
||||
import com.google.gerrit.reviewdb.client.Project;
|
||||
import com.google.gerrit.reviewdb.client.RevId;
|
||||
import com.google.gerrit.server.project.ListBranches.BranchInfo;
|
||||
import com.google.gerrit.server.project.NoSuchProjectException;
|
||||
import com.google.gerrit.server.project.ProjectControl;
|
||||
import com.google.gerrit.server.project.ProjectResource;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
import com.google.inject.assistedinject.Assisted;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
class ListBranches extends Handler<ListBranchesResult> {
|
||||
interface Factory {
|
||||
ListBranches create(@Assisted Project.NameKey name);
|
||||
}
|
||||
|
||||
private final ProjectControl.Factory projectControlFactory;
|
||||
private final Provider<com.google.gerrit.server.project.ListBranches> listBranchesProvider;
|
||||
|
||||
private final Project.NameKey projectName;
|
||||
|
||||
@Inject
|
||||
ListBranches(final ProjectControl.Factory projectControlFactory,
|
||||
final Provider<com.google.gerrit.server.project.ListBranches> listBranchesProvider,
|
||||
@Assisted final Project.NameKey name) {
|
||||
this.projectControlFactory = projectControlFactory;
|
||||
this.listBranchesProvider = listBranchesProvider;
|
||||
|
||||
this.projectName = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListBranchesResult call() throws NoSuchProjectException, IOException {
|
||||
ProjectControl pctl =
|
||||
projectControlFactory.validateFor(projectName, ProjectControl.OWNER
|
||||
| ProjectControl.VISIBLE);
|
||||
try {
|
||||
List<Branch> branches = Lists.newArrayList();
|
||||
List<BranchInfo> branchInfos = listBranchesProvider.get().apply(new ProjectResource(pctl));
|
||||
for (BranchInfo info : branchInfos) {
|
||||
Branch b = new Branch(new Branch.NameKey(projectName, info.ref));
|
||||
b.setRevision(new RevId(info.revision));
|
||||
b.setCanDelete(Objects.firstNonNull(info.canDelete, false));
|
||||
branches.add(b);
|
||||
}
|
||||
return new ListBranchesResult(branches, pctl.canAddRefs(), false);
|
||||
} catch (ResourceNotFoundException e) {
|
||||
throw new NoSuchProjectException(projectName);
|
||||
}
|
||||
}
|
||||
}
|
@ -31,7 +31,6 @@ public class ProjectModule extends RpcServletModule {
|
||||
factory(ChangeProjectAccess.Factory.class);
|
||||
factory(ReviewProjectAccess.Factory.class);
|
||||
factory(ChangeProjectSettings.Factory.class);
|
||||
factory(ListBranches.Factory.class);
|
||||
factory(VisibleProjectDetails.Factory.class);
|
||||
factory(ProjectAccessFactory.Factory.class);
|
||||
factory(ProjectDetailFactory.Factory.class);
|
||||
|
@ -1,390 +0,0 @@
|
||||
// Copyright (C) 2009 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.httpd.rpc.project;
|
||||
|
||||
import static org.easymock.EasyMock.createStrictMock;
|
||||
import static org.easymock.EasyMock.eq;
|
||||
import static org.easymock.EasyMock.expect;
|
||||
import static org.easymock.EasyMock.expectLastCall;
|
||||
import static org.easymock.EasyMock.replay;
|
||||
import static org.easymock.EasyMock.verify;
|
||||
import static org.eclipse.jgit.lib.Constants.HEAD;
|
||||
import static org.eclipse.jgit.lib.Constants.R_HEADS;
|
||||
import static org.eclipse.jgit.lib.Ref.Storage.LOOSE;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import com.google.gerrit.common.data.ListBranchesResult;
|
||||
import com.google.gerrit.reviewdb.client.Branch;
|
||||
import com.google.gerrit.reviewdb.client.Project;
|
||||
import com.google.gerrit.server.git.GitRepositoryManager;
|
||||
import com.google.gerrit.server.project.NoSuchProjectException;
|
||||
import com.google.gerrit.server.project.ProjectControl;
|
||||
import com.google.gerrit.server.project.RefControl;
|
||||
import com.google.gwtorm.client.KeyUtil;
|
||||
import com.google.gwtorm.server.StandardKeyEncoder;
|
||||
import com.google.inject.Provider;
|
||||
|
||||
import org.easymock.IExpectationSetters;
|
||||
import org.eclipse.jgit.junit.LocalDiskRepositoryTestCase;
|
||||
import org.eclipse.jgit.lib.ObjectId;
|
||||
import org.eclipse.jgit.lib.ObjectIdRef;
|
||||
import org.eclipse.jgit.lib.Ref;
|
||||
import org.eclipse.jgit.lib.RefUpdate;
|
||||
import org.eclipse.jgit.lib.Repository;
|
||||
import org.eclipse.jgit.lib.SymbolicRef;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class ListBranchesTest extends LocalDiskRepositoryTestCase {
|
||||
static {
|
||||
KeyUtil.setEncoderImpl(new StandardKeyEncoder());
|
||||
}
|
||||
|
||||
private ObjectId idA;
|
||||
private Project.NameKey name;
|
||||
private Repository realDb;
|
||||
private Repository mockDb;
|
||||
private ProjectControl.Factory pcf;
|
||||
private ProjectControl pc;
|
||||
private GitRepositoryManager grm;
|
||||
private List<RefControl> refMocks;
|
||||
|
||||
@Override
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
||||
idA = ObjectId.fromString("df84c2f4f7ce7e0b25cdeac84b8870bcff319885");
|
||||
name = new Project.NameKey("test");
|
||||
realDb = createBareRepository();
|
||||
|
||||
mockDb = createStrictMock(Repository.class);
|
||||
pc = createStrictMock(ProjectControl.class);
|
||||
expect(pc.getProject()).andReturn(new Project(name)).anyTimes();
|
||||
pcf = createStrictMock(ProjectControl.Factory.class);
|
||||
grm = createStrictMock(GitRepositoryManager.class);
|
||||
refMocks = new ArrayList<RefControl>();
|
||||
}
|
||||
|
||||
private IExpectationSetters<ProjectControl> validate()
|
||||
throws NoSuchProjectException {
|
||||
return expect(pcf.validateFor(eq(name), //
|
||||
eq(ProjectControl.OWNER | ProjectControl.VISIBLE)));
|
||||
}
|
||||
|
||||
private void doReplay() {
|
||||
replay(mockDb, pc, pcf, grm);
|
||||
replay(refMocks.toArray());
|
||||
}
|
||||
|
||||
private void doVerify() {
|
||||
verify(mockDb, pc, pcf, grm);
|
||||
verify(refMocks.toArray());
|
||||
}
|
||||
|
||||
private void set(String branch, ObjectId id) throws IOException {
|
||||
final RefUpdate u = realDb.updateRef(R_HEADS + branch);
|
||||
u.setForceUpdate(true);
|
||||
u.setNewObjectId(id);
|
||||
switch (u.update()) {
|
||||
case NEW:
|
||||
case FAST_FORWARD:
|
||||
case FORCED:
|
||||
break;
|
||||
default:
|
||||
fail("unexpected update failure " + branch + " " + u.getResult());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProjectNotVisible() throws Exception {
|
||||
final NoSuchProjectException err = new NoSuchProjectException(name);
|
||||
validate().andThrow(err);
|
||||
doReplay();
|
||||
try {
|
||||
new ListBranches(pcf, createListBranchesProvider(grm), name).call();
|
||||
fail("did not throw when expected not authorized");
|
||||
} catch (NoSuchProjectException e2) {
|
||||
assertSame(err, e2);
|
||||
}
|
||||
doVerify();
|
||||
}
|
||||
|
||||
|
||||
private ListBranchesResult permitted(boolean getHead)
|
||||
throws NoSuchProjectException, IOException {
|
||||
Map<String, Ref> refs = realDb.getAllRefs();
|
||||
|
||||
validate().andReturn(pc);
|
||||
|
||||
expect(grm.openRepository(eq(name))).andReturn(mockDb);
|
||||
expect(mockDb.getAllRefs()).andDelegateTo(realDb);
|
||||
if (getHead) {
|
||||
expect(mockDb.getRef(HEAD)).andDelegateTo(realDb);
|
||||
if (!refs.containsKey(HEAD) && realDb.getRef(HEAD) != null) {
|
||||
refs.put(HEAD, realDb.getRef(HEAD));
|
||||
}
|
||||
}
|
||||
|
||||
Set<String> targets = targets(refs);
|
||||
for (Ref ref : refs.values()) {
|
||||
assumeVisible(ref, true, targets);
|
||||
}
|
||||
|
||||
mockDb.close();
|
||||
|
||||
expect(pc.canAddRefs()).andReturn(true);
|
||||
|
||||
expectLastCall();
|
||||
|
||||
doReplay();
|
||||
final ListBranchesResult r =
|
||||
new ListBranches(pcf, createListBranchesProvider(grm), name).call();
|
||||
doVerify();
|
||||
assertNotNull(r);
|
||||
assertNotNull(r.getBranches());
|
||||
return r;
|
||||
}
|
||||
|
||||
private Set<String> targets(Map<String, Ref> refs) {
|
||||
Set<String> targets = new HashSet<String>();
|
||||
for (Ref ref : refs.values()) {
|
||||
if (ref.isSymbolic()) {
|
||||
targets.add(ref.getLeaf().getName());
|
||||
}
|
||||
}
|
||||
return targets;
|
||||
}
|
||||
|
||||
private void assumeVisible(Ref ref, boolean visible, Set<String> targets) {
|
||||
RefControl rc = createStrictMock(RefControl.class);
|
||||
refMocks.add(rc);
|
||||
expect(rc.isVisible()).andReturn(visible);
|
||||
if (visible && !ref.isSymbolic() && !targets.contains(ref.getName())) {
|
||||
expect(rc.canDelete()).andReturn(true);
|
||||
}
|
||||
|
||||
if (ref.isSymbolic()) {
|
||||
expect(pc.controlForRef(ref.getTarget().getName())).andReturn(rc);
|
||||
} else {
|
||||
expect(pc.controlForRef(ref.getName())).andReturn(rc);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEmptyProject() throws Exception {
|
||||
ListBranchesResult r = permitted(true);
|
||||
|
||||
assertEquals(1, r.getBranches().size());
|
||||
|
||||
Branch b = r.getBranches().get(0);
|
||||
assertNotNull(b);
|
||||
|
||||
assertNotNull(b.getNameKey());
|
||||
assertSame(name, b.getNameKey().getParentKey());
|
||||
assertEquals(HEAD, b.getNameKey().get());
|
||||
|
||||
assertEquals(HEAD, b.getName());
|
||||
assertEquals(HEAD, b.getShortName());
|
||||
|
||||
assertNotNull(b.getRevision());
|
||||
assertEquals("master", b.getRevision().get());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMasterBranch() throws Exception {
|
||||
set("master", idA);
|
||||
|
||||
ListBranchesResult r = permitted(false);
|
||||
assertEquals(2, r.getBranches().size());
|
||||
|
||||
Branch b = r.getBranches().get(0);
|
||||
assertNotNull(b);
|
||||
|
||||
assertNotNull(b.getNameKey());
|
||||
assertSame(name, b.getNameKey().getParentKey());
|
||||
assertEquals(HEAD, b.getNameKey().get());
|
||||
|
||||
assertEquals(HEAD, b.getName());
|
||||
assertEquals(HEAD, b.getShortName());
|
||||
|
||||
assertNotNull(b.getRevision());
|
||||
assertEquals("master", b.getRevision().get());
|
||||
|
||||
b = r.getBranches().get(1);
|
||||
assertNotNull(b);
|
||||
|
||||
assertNotNull(b.getNameKey());
|
||||
assertSame(name, b.getNameKey().getParentKey());
|
||||
assertEquals(R_HEADS + "master", b.getNameKey().get());
|
||||
|
||||
assertEquals(R_HEADS + "master", b.getName());
|
||||
assertEquals("master", b.getShortName());
|
||||
|
||||
assertNotNull(b.getRevision());
|
||||
assertEquals(idA.name(), b.getRevision().get());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBranchNotHead() throws Exception {
|
||||
set("foo", idA);
|
||||
|
||||
ListBranchesResult r = permitted(true);
|
||||
assertEquals(2, r.getBranches().size());
|
||||
|
||||
Branch b = r.getBranches().get(0);
|
||||
assertNotNull(b);
|
||||
|
||||
assertNotNull(b.getNameKey());
|
||||
assertSame(name, b.getNameKey().getParentKey());
|
||||
assertEquals(HEAD, b.getNameKey().get());
|
||||
|
||||
assertEquals(HEAD, b.getName());
|
||||
assertEquals(HEAD, b.getShortName());
|
||||
|
||||
assertNotNull(b.getRevision());
|
||||
assertEquals("master", b.getRevision().get());
|
||||
assertFalse(b.getCanDelete());
|
||||
|
||||
b = r.getBranches().get(1);
|
||||
assertNotNull(b);
|
||||
|
||||
assertNotNull(b.getNameKey());
|
||||
assertSame(name, b.getNameKey().getParentKey());
|
||||
assertEquals(R_HEADS + "foo", b.getNameKey().get());
|
||||
|
||||
assertEquals(R_HEADS + "foo", b.getName());
|
||||
assertEquals("foo", b.getShortName());
|
||||
|
||||
assertNotNull(b.getRevision());
|
||||
assertEquals(idA.name(), b.getRevision().get());
|
||||
assertTrue(b.getCanDelete());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSortByName() throws Exception {
|
||||
Map<String, Ref> u = new LinkedHashMap<String, Ref>();
|
||||
u.put("foo", new ObjectIdRef.Unpeeled(LOOSE, R_HEADS + "foo", idA));
|
||||
u.put("bar", new ObjectIdRef.Unpeeled(LOOSE, R_HEADS + "bar", idA));
|
||||
u.put(HEAD, new SymbolicRef(HEAD, new ObjectIdRef.Unpeeled(LOOSE, R_HEADS
|
||||
+ "master", null)));
|
||||
|
||||
validate().andReturn(pc);
|
||||
expect(grm.openRepository(eq(name))).andReturn(mockDb);
|
||||
expect(mockDb.getAllRefs()).andReturn(u);
|
||||
for (Ref ref : u.values()) {
|
||||
assumeVisible(ref, true, targets(u));
|
||||
}
|
||||
expect(pc.canAddRefs()).andReturn(true);
|
||||
mockDb.close();
|
||||
expectLastCall();
|
||||
|
||||
doReplay();
|
||||
final ListBranchesResult r =
|
||||
new ListBranches(pcf, createListBranchesProvider(grm), name).call();
|
||||
doVerify();
|
||||
assertNotNull(r);
|
||||
|
||||
assertEquals(3, r.getBranches().size());
|
||||
assertEquals(HEAD, r.getBranches().get(0).getShortName());
|
||||
assertEquals("bar", r.getBranches().get(1).getShortName());
|
||||
assertEquals("foo", r.getBranches().get(2).getShortName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHeadNotVisible() throws Exception {
|
||||
ObjectIdRef.Unpeeled bar =
|
||||
new ObjectIdRef.Unpeeled(LOOSE, R_HEADS + "bar", idA);
|
||||
Map<String, Ref> u = new LinkedHashMap<String, Ref>();
|
||||
u.put(bar.getName(), bar);
|
||||
u.put(HEAD, new SymbolicRef(HEAD, bar));
|
||||
|
||||
validate().andReturn(pc);
|
||||
expect(grm.openRepository(eq(name))).andReturn(mockDb);
|
||||
expect(mockDb.getAllRefs()).andReturn(u);
|
||||
assumeVisible(bar, false, targets(u));
|
||||
assumeVisible(bar, false, targets(u));
|
||||
expect(pc.canAddRefs()).andReturn(true);
|
||||
mockDb.close();
|
||||
expectLastCall();
|
||||
|
||||
doReplay();
|
||||
final ListBranchesResult r =
|
||||
new ListBranches(pcf, createListBranchesProvider(grm), name).call();
|
||||
doVerify();
|
||||
assertNotNull(r);
|
||||
assertTrue(r.getBranches().isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHeadVisibleButBranchHidden() throws Exception {
|
||||
ObjectIdRef.Unpeeled bar =
|
||||
new ObjectIdRef.Unpeeled(LOOSE, R_HEADS + "bar", idA);
|
||||
ObjectIdRef.Unpeeled foo =
|
||||
new ObjectIdRef.Unpeeled(LOOSE, R_HEADS + "foo", idA);
|
||||
|
||||
Map<String, Ref> u = new LinkedHashMap<String, Ref>();
|
||||
u.put(bar.getName(), bar);
|
||||
u.put(HEAD, new SymbolicRef(HEAD, bar));
|
||||
u.put(foo.getName(), foo);
|
||||
|
||||
validate().andReturn(pc);
|
||||
expect(grm.openRepository(eq(name))).andReturn(mockDb);
|
||||
expect(mockDb.getAllRefs()).andReturn(u);
|
||||
assumeVisible(bar, true, targets(u));
|
||||
assumeVisible(bar, true, targets(u));
|
||||
assumeVisible(foo, false, targets(u));
|
||||
expect(pc.canAddRefs()).andReturn(true);
|
||||
mockDb.close();
|
||||
expectLastCall();
|
||||
|
||||
doReplay();
|
||||
final ListBranchesResult r =
|
||||
new ListBranches(pcf, createListBranchesProvider(grm), name).call();
|
||||
doVerify();
|
||||
assertNotNull(r);
|
||||
|
||||
assertEquals(2, r.getBranches().size());
|
||||
|
||||
assertEquals(HEAD, r.getBranches().get(0).getShortName());
|
||||
assertFalse(r.getBranches().get(0).getCanDelete());
|
||||
|
||||
assertEquals("bar", r.getBranches().get(1).getShortName());
|
||||
assertFalse(r.getBranches().get(1).getCanDelete());
|
||||
}
|
||||
|
||||
private static Provider<com.google.gerrit.server.project.ListBranches> createListBranchesProvider(
|
||||
final GitRepositoryManager grm) {
|
||||
return new Provider<com.google.gerrit.server.project.ListBranches>() {
|
||||
@Override
|
||||
public com.google.gerrit.server.project.ListBranches get() {
|
||||
return new com.google.gerrit.server.project.ListBranches(grm);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user