blob: adc0a8e4ea6d9674995ed0d4aeee8199ac2f955b [file] [log] [blame]
// Copyright (C) 2024 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.acceptance.testsuite.project.TestProjectUpdate.allow;
import static com.google.gerrit.server.group.SystemGroupBackend.REGISTERED_USERS;
import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
import com.google.gerrit.acceptance.testsuite.request.RequestScopeOperations;
import com.google.gerrit.entities.Permission;
import com.google.gerrit.entities.RefNames;
import com.google.gerrit.extensions.common.BatchSubmitRequirementInput;
import com.google.gerrit.extensions.common.SubmitRequirementInfo;
import com.google.gerrit.extensions.common.SubmitRequirementInput;
import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.extensions.restapi.BadRequestException;
import com.google.gerrit.extensions.restapi.ResourceConflictException;
import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
import com.google.gerrit.extensions.restapi.UnprocessableEntityException;
import com.google.gerrit.server.restapi.project.PostLabels;
import com.google.inject.Inject;
import org.eclipse.jgit.revwalk.RevCommit;
import org.junit.Test;
/** Tests for the {@link PostLabels} REST endpoint. */
public class PostSubmitRequirementsIT extends AbstractDaemonTest {
@Inject private RequestScopeOperations requestScopeOperations;
@Inject private ProjectOperations projectOperations;
@Test
public void anonymous() throws Exception {
requestScopeOperations.setApiUserAnonymous();
AuthException thrown =
assertThrows(
AuthException.class,
() ->
gApi.projects()
.name(allProjects.get())
.submitRequirements(new BatchSubmitRequirementInput()));
assertThat(thrown).hasMessageThat().contains("Authentication required");
}
@Test
public void notAllowed() throws Exception {
projectOperations
.project(allProjects)
.forUpdate()
.add(allow(Permission.READ).ref(RefNames.REFS_CONFIG).group(REGISTERED_USERS))
.update();
requestScopeOperations.setApiUser(user.id());
AuthException thrown =
assertThrows(
AuthException.class,
() ->
gApi.projects()
.name(allProjects.get())
.submitRequirements(new BatchSubmitRequirementInput()));
assertThat(thrown).hasMessageThat().contains("write refs/meta/config not permitted");
}
@Test
public void deleteNonExistingSR() throws Exception {
BatchSubmitRequirementInput input = new BatchSubmitRequirementInput();
input.delete = ImmutableList.of("Foo");
UnprocessableEntityException thrown =
assertThrows(
UnprocessableEntityException.class,
() -> gApi.projects().name(allProjects.get()).submitRequirements(input));
assertThat(thrown).hasMessageThat().contains("Submit requirement Foo not found");
}
@Test
public void deleteSR() throws Exception {
configSubmitRequirement(project, "Foo");
configSubmitRequirement(project, "Bar");
assertThat(gApi.projects().name(project.get()).submitRequirements().get()).isNotEmpty();
BatchSubmitRequirementInput input = new BatchSubmitRequirementInput();
input.delete = ImmutableList.of("Foo", "Bar");
gApi.projects().name(project.get()).submitRequirements(input);
assertThat(gApi.projects().name(project.get()).submitRequirements().get()).isEmpty();
}
@Test
public void deleteSR_namesAreTrimmed() throws Exception {
configSubmitRequirement(project, "Foo");
configSubmitRequirement(project, "Bar");
assertThat(gApi.projects().name(project.get()).submitRequirements().get()).isNotEmpty();
BatchSubmitRequirementInput input = new BatchSubmitRequirementInput();
input.delete = ImmutableList.of(" Foo ", " Bar ");
gApi.projects().name(project.get()).submitRequirements(input);
assertThat(gApi.projects().name(project.get()).submitRequirements().get()).isEmpty();
}
@Test
public void cannotDeleteTheSameSRTwice() throws Exception {
configSubmitRequirement(allProjects, "Foo");
BatchSubmitRequirementInput input = new BatchSubmitRequirementInput();
input.delete = ImmutableList.of("Foo", "Foo");
UnprocessableEntityException thrown =
assertThrows(
UnprocessableEntityException.class,
() -> gApi.projects().name(allProjects.get()).submitRequirements(input));
assertThat(thrown).hasMessageThat().contains("Submit requirement Foo not found");
}
@Test
public void cannotCreateSRWithNameThatIsAlreadyInUse() throws Exception {
configSubmitRequirement(allProjects, "Foo");
SubmitRequirementInput srInput = new SubmitRequirementInput();
srInput.name = "Foo";
srInput.allowOverrideInChildProjects = false;
srInput.submittabilityExpression = "label:code-review=+2";
BatchSubmitRequirementInput input = new BatchSubmitRequirementInput();
input.create = ImmutableList.of(srInput);
ResourceConflictException thrown =
assertThrows(
ResourceConflictException.class,
() -> gApi.projects().name(allProjects.get()).submitRequirements(input));
assertThat(thrown)
.hasMessageThat()
.contains("submit requirement \"Foo\" conflicts with existing submit requirement \"Foo\"");
}
@Test
public void cannotCreateTwoSRWithTheSameName() throws Exception {
SubmitRequirementInput srInput = new SubmitRequirementInput();
srInput.name = "Foo";
srInput.allowOverrideInChildProjects = false;
srInput.submittabilityExpression = "label:code-review=+2";
BatchSubmitRequirementInput input = new BatchSubmitRequirementInput();
input.create = ImmutableList.of(srInput, srInput);
ResourceConflictException thrown =
assertThrows(
ResourceConflictException.class,
() -> gApi.projects().name(project.get()).submitRequirements(input));
assertThat(thrown)
.hasMessageThat()
.contains("submit requirement \"Foo\" conflicts with existing submit requirement \"Foo\"");
}
@Test
public void cannotCreateTwoSrWithConflictingNames() throws Exception {
SubmitRequirementInput sr1Input = new SubmitRequirementInput();
sr1Input.name = "Foo";
sr1Input.allowOverrideInChildProjects = false;
sr1Input.submittabilityExpression = "label:code-review=+2";
SubmitRequirementInput sr2Input = new SubmitRequirementInput();
sr2Input.name = "foo";
sr2Input.allowOverrideInChildProjects = false;
sr2Input.submittabilityExpression = "label:code-review=+2";
BatchSubmitRequirementInput input = new BatchSubmitRequirementInput();
input.create = ImmutableList.of(sr1Input, sr2Input);
ResourceConflictException thrown =
assertThrows(
ResourceConflictException.class,
() -> gApi.projects().name(project.get()).submitRequirements(input));
assertThat(thrown)
.hasMessageThat()
.contains("submit requirement \"foo\" conflicts with existing submit requirement \"Foo\"");
}
@Test
public void createSubmitRequirements() throws Exception {
SubmitRequirementInput fooInput = new SubmitRequirementInput();
fooInput.name = "Foo";
fooInput.allowOverrideInChildProjects = false;
fooInput.submittabilityExpression = "label:code-review=+2";
SubmitRequirementInput barInput = new SubmitRequirementInput();
barInput.name = "Bar";
barInput.allowOverrideInChildProjects = false;
barInput.submittabilityExpression = "label:code-review=+1";
BatchSubmitRequirementInput input = new BatchSubmitRequirementInput();
input.create = ImmutableList.of(fooInput, barInput);
gApi.projects().name(allProjects.get()).submitRequirements(input);
assertThat(gApi.projects().name(allProjects.get()).submitRequirement("Foo").get()).isNotNull();
assertThat(gApi.projects().name(allProjects.get()).submitRequirement("Bar").get()).isNotNull();
}
@Test
public void cannotCreateSRWithIncorrectName() throws Exception {
SubmitRequirementInput fooInput = new SubmitRequirementInput();
fooInput.name = "Foo ";
fooInput.allowOverrideInChildProjects = false;
fooInput.submittabilityExpression = "label:code-review=+2";
BatchSubmitRequirementInput input = new BatchSubmitRequirementInput();
input.create = ImmutableList.of(fooInput, fooInput);
BadRequestException thrown =
assertThrows(
BadRequestException.class,
() -> gApi.projects().name(allProjects.get()).submitRequirements(input));
assertThat(thrown)
.hasMessageThat()
.contains("Name can only consist of alphanumeric characters");
}
@Test
public void cannotCreateSRWithoutName() throws Exception {
BatchSubmitRequirementInput input = new BatchSubmitRequirementInput();
input.create = ImmutableList.of(new SubmitRequirementInput());
BadRequestException thrown =
assertThrows(
BadRequestException.class,
() -> gApi.projects().name(allProjects.get()).submitRequirements(input));
assertThat(thrown).hasMessageThat().contains("Empty submit requirement name");
}
@Test
public void updateNonExistingSR() throws Exception {
SubmitRequirementInput fooInput = new SubmitRequirementInput();
fooInput.name = "Foo2";
fooInput.allowOverrideInChildProjects = false;
fooInput.submittabilityExpression = "label:code-review=+2";
BatchSubmitRequirementInput input = new BatchSubmitRequirementInput();
input.update = ImmutableMap.of("Foo", fooInput);
UnprocessableEntityException thrown =
assertThrows(
UnprocessableEntityException.class,
() -> gApi.projects().name(allProjects.get()).submitRequirements(input));
assertThat(thrown).hasMessageThat().contains("Submit requirement Foo not found");
}
@Test
public void updateSR() throws Exception {
configSubmitRequirement(project, "Foo");
configSubmitRequirement(project, "Bar");
SubmitRequirementInput fooUpdate = new SubmitRequirementInput();
fooUpdate.name = "Foo";
fooUpdate.description = "new description";
fooUpdate.submittabilityExpression = "-has:submodule-update";
SubmitRequirementInput barUpdate = new SubmitRequirementInput();
barUpdate.name = "Baz";
barUpdate.submittabilityExpression = "label:code-review=+1";
BatchSubmitRequirementInput input = new BatchSubmitRequirementInput();
input.update = ImmutableMap.of("Foo", fooUpdate, "Bar", barUpdate);
gApi.projects().name(project.get()).submitRequirements(input);
assertThat(gApi.projects().name(project.get()).submitRequirement("Foo").get().description)
.isEqualTo(fooUpdate.description);
assertThat(
gApi.projects()
.name(project.get())
.submitRequirement("Foo")
.get()
.submittabilityExpression)
.isEqualTo(fooUpdate.submittabilityExpression);
assertThat(gApi.projects().name(project.get()).submitRequirement("Baz").get()).isNotNull();
assertThat(
gApi.projects()
.name(project.get())
.submitRequirement("Baz")
.get()
.submittabilityExpression)
.isEqualTo(barUpdate.submittabilityExpression);
assertThrows(
ResourceNotFoundException.class,
() -> gApi.projects().name(project.get()).submitRequirement("Bar").get());
}
@Test
public void deleteAndRecreateSR() throws Exception {
configSubmitRequirement(project, "Foo");
SubmitRequirementInput fooUpdate = new SubmitRequirementInput();
fooUpdate.name = "Foo";
fooUpdate.description = "new description";
fooUpdate.submittabilityExpression = "-has:submodule-update";
BatchSubmitRequirementInput input = new BatchSubmitRequirementInput();
input.delete = ImmutableList.of("Foo");
input.create = ImmutableList.of(fooUpdate);
gApi.projects().name(project.get()).submitRequirements(input);
SubmitRequirementInfo fooSR =
gApi.projects().name(project.get()).submitRequirement("Foo").get();
assertThat(fooSR.description).isEqualTo(fooUpdate.description);
assertThat(fooSR.submittabilityExpression).isEqualTo(fooUpdate.submittabilityExpression);
}
@Test
public void cannotDeleteAndUpdateSR() throws Exception {
configSubmitRequirement(project, "Foo");
SubmitRequirementInput fooUpdate = new SubmitRequirementInput();
fooUpdate.name = "Foo";
fooUpdate.description = "new description";
fooUpdate.submittabilityExpression = "-has:submodule-update";
BatchSubmitRequirementInput input = new BatchSubmitRequirementInput();
input.delete = ImmutableList.of("Foo");
input.update = ImmutableMap.of("Foo", fooUpdate);
UnprocessableEntityException thrown =
assertThrows(
UnprocessableEntityException.class,
() -> gApi.projects().name(project.get()).submitRequirements(input));
assertThat(thrown).hasMessageThat().contains("Submit requirement Foo not found");
}
@Test
public void noOpUpdate() throws Exception {
RevCommit refsMetaConfigHead =
projectOperations.project(allProjects).getHead(RefNames.REFS_CONFIG);
gApi.projects().name(allProjects.get()).submitRequirements(new BatchSubmitRequirementInput());
assertThat(projectOperations.project(allProjects).getHead(RefNames.REFS_CONFIG))
.isEqualTo(refsMetaConfigHead);
}
@Test
public void defaultCommitMessage() throws Exception {
configSubmitRequirement(allProjects, "Foo");
BatchSubmitRequirementInput input = new BatchSubmitRequirementInput();
input.delete = ImmutableList.of("Foo");
gApi.projects().name(allProjects.get()).submitRequirements(input);
assertThat(
projectOperations.project(allProjects).getHead(RefNames.REFS_CONFIG).getShortMessage())
.isEqualTo("Update Submit Requirements");
}
@Test
public void withCommitMessage() throws Exception {
configSubmitRequirement(allProjects, "Foo");
BatchSubmitRequirementInput input = new BatchSubmitRequirementInput();
input.commitMessage = "Batch Update SubmitRequirements";
input.delete = ImmutableList.of("Foo");
gApi.projects().name(allProjects.get()).submitRequirements(input);
assertThat(
projectOperations.project(allProjects).getHead(RefNames.REFS_CONFIG).getShortMessage())
.isEqualTo(input.commitMessage);
}
@Test
public void commitMessageIsTrimmed() throws Exception {
configSubmitRequirement(allProjects, "Foo");
BatchSubmitRequirementInput input = new BatchSubmitRequirementInput();
input.commitMessage = "Batch Update SubmitRequirements ";
input.delete = ImmutableList.of("Foo");
gApi.projects().name(allProjects.get()).submitRequirements(input);
assertThat(
projectOperations.project(allProjects).getHead(RefNames.REFS_CONFIG).getShortMessage())
.isEqualTo("Batch Update SubmitRequirements");
}
}