blob: 46e23452438789d080e069763ec8738aaf591080 [file] [log] [blame]
// Copyright (C) 2016 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.common.truth.Truth.assertThat;
import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import static java.util.stream.Collectors.toList;
import static org.eclipse.jgit.lib.Constants.R_TAGS;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.NoHttpd;
import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
import com.google.gerrit.acceptance.testsuite.request.RequestScopeOperations;
import com.google.gerrit.extensions.api.projects.DeleteTagsInput;
import com.google.gerrit.extensions.api.projects.ProjectApi;
import com.google.gerrit.extensions.api.projects.TagInfo;
import com.google.gerrit.extensions.api.projects.TagInput;
import com.google.gerrit.extensions.restapi.ResourceConflictException;
import com.google.inject.Inject;
import java.util.HashMap;
import java.util.List;
import org.eclipse.jgit.revwalk.RevCommit;
import org.junit.Before;
import org.junit.Test;
@NoHttpd
public class DeleteTagsIT extends AbstractDaemonTest {
private static final ImmutableList<String> TAGS =
ImmutableList.of("refs/tags/test-1", "refs/tags/test-2", "refs/tags/test-3", "test-4");
@Inject private ProjectOperations projectOperations;
@Inject private RequestScopeOperations requestScopeOperations;
@Before
public void setUp() throws Exception {
for (String name : TAGS) {
project().tag(name).create(new TagInput());
}
assertTags(TAGS);
}
@Test
public void deleteTags() throws Exception {
HashMap<String, RevCommit> initialRevisions = initialRevisions(TAGS);
DeleteTagsInput input = new DeleteTagsInput();
input.tags = TAGS;
project().deleteTags(input);
assertTagsDeleted();
assertRefUpdatedEvents(initialRevisions);
}
@Test
public void deleteTagsForbidden() throws Exception {
DeleteTagsInput input = new DeleteTagsInput();
input.tags = TAGS;
requestScopeOperations.setApiUser(user.id());
ResourceConflictException thrown =
assertThrows(ResourceConflictException.class, () -> project().deleteTags(input));
assertThat(thrown).hasMessageThat().isEqualTo(errorMessageForTags(TAGS));
requestScopeOperations.setApiUser(admin.id());
assertTags(TAGS);
}
@Test
public void deleteTagsNotFound() throws Exception {
DeleteTagsInput input = new DeleteTagsInput();
List<String> tags = Lists.newArrayList(TAGS);
tags.add("refs/tags/does-not-exist");
input.tags = tags;
ResourceConflictException thrown =
assertThrows(ResourceConflictException.class, () -> project().deleteTags(input));
assertThat(thrown)
.hasMessageThat()
.isEqualTo(errorMessageForTags(ImmutableList.of("refs/tags/does-not-exist")));
assertTagsDeleted();
}
@Test
public void deleteTagsNotFoundContinue() throws Exception {
// If it fails on the first tag in the input, it should still
// continue to process the remaining tags.
DeleteTagsInput input = new DeleteTagsInput();
List<String> tags = Lists.newArrayList("refs/tags/does-not-exist");
tags.addAll(TAGS);
input.tags = tags;
ResourceConflictException thrown =
assertThrows(ResourceConflictException.class, () -> project().deleteTags(input));
assertThat(thrown)
.hasMessageThat()
.isEqualTo(errorMessageForTags(ImmutableList.of("refs/tags/does-not-exist")));
assertTagsDeleted();
}
private String errorMessageForTags(List<String> tags) {
StringBuilder message = new StringBuilder();
for (String tag : tags) {
message
.append("Cannot delete ")
.append(prefixRef(tag))
.append(": it doesn't exist or you do not have permission ")
.append("to delete it\n");
}
return message.toString();
}
private HashMap<String, RevCommit> initialRevisions(List<String> tags) throws Exception {
HashMap<String, RevCommit> result = new HashMap<>();
for (String tag : tags) {
String ref = prefixRef(tag);
result.put(ref, projectOperations.project(project).getHead(ref));
}
return result;
}
private void assertRefUpdatedEvents(HashMap<String, RevCommit> revisions) throws Exception {
for (String tag : revisions.keySet()) {
RevCommit revision = revisions.get(prefixRef(tag));
eventRecorder.assertRefUpdatedEvents(
project.get(), prefixRef(tag), null, revision, revision, null);
}
}
private String prefixRef(String ref) {
return ref.startsWith(R_TAGS) ? ref : R_TAGS + ref;
}
private ProjectApi project() throws Exception {
return gApi.projects().name(project.get());
}
private void assertTags(List<String> expected) throws Exception {
List<TagInfo> actualTags = project().tags().get();
Iterable<String> actualNames = Iterables.transform(actualTags, b -> b.ref);
assertThat(actualNames)
.containsExactlyElementsIn(expected.stream().map(this::prefixRef).collect(toList()))
.inOrder();
}
private void assertTagsDeleted() throws Exception {
assertTags(ImmutableList.of());
}
}