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:
Edwin Kempin 2013-06-07 17:00:10 +02:00 committed by David Pursehouse
parent b5f15620b0
commit a7c0ba2b50
9 changed files with 335 additions and 614 deletions

View File

@ -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) {

View File

@ -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();
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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;
}
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}
}

View File

@ -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);

View File

@ -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);
}
};
}
}