blob: c2d2900590247b0ec75d28e246b86912039d5ad4 [file] [log] [blame]
// Copyright (C) 2020 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.plugins.codeowners.acceptance.api;
import static com.google.common.truth.Truth.assertThat;
import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import com.google.common.collect.ImmutableList;
import com.google.gerrit.acceptance.config.GerritConfig;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.entities.Project;
import com.google.gerrit.extensions.api.projects.ConfigInput;
import com.google.gerrit.extensions.client.ProjectState;
import com.google.gerrit.extensions.restapi.ResourceConflictException;
import com.google.gerrit.plugins.codeowners.acceptance.AbstractCodeOwnersIT;
import com.google.gerrit.plugins.codeowners.api.CodeOwnerBranchConfigInfo;
import com.google.gerrit.plugins.codeowners.backend.CodeOwnerBackend;
import com.google.gerrit.plugins.codeowners.backend.CodeOwnerBackendId;
import com.google.gerrit.plugins.codeowners.backend.FallbackCodeOwners;
import com.google.gerrit.plugins.codeowners.backend.config.BackendConfig;
import com.google.gerrit.plugins.codeowners.backend.config.GeneralConfig;
import com.google.gerrit.plugins.codeowners.backend.config.OverrideApprovalConfig;
import com.google.gerrit.plugins.codeowners.backend.config.RequiredApprovalConfig;
import com.google.gerrit.plugins.codeowners.backend.config.StatusConfig;
import com.google.gerrit.plugins.codeowners.common.MergeCommitStrategy;
import org.junit.Before;
import org.junit.Test;
/**
* Acceptance test for the {@link
* com.google.gerrit.plugins.codeowners.restapi.GetCodeOwnerBranchConfig} REST endpoint.
*
* <p>Further tests for the {@link
* com.google.gerrit.plugins.codeowners.restapi.GetCodeOwnerBranchConfig} REST endpoint that require
* using the REST API are implemented in {@link
* com.google.gerrit.plugins.codeowners.acceptance.restapi.GetCodeOwnerBranchConfigRestIT}.
*/
public class GetCodeOwnerBranchConfigIT extends AbstractCodeOwnersIT {
@Before
public void setup() throws Exception {
backendConfig = plugin.getSysInjector().getInstance(BackendConfig.class);
}
@Test
public void cannotGetConfigForHiddenProject() throws Exception {
ConfigInput configInput = new ConfigInput();
configInput.state = ProjectState.HIDDEN;
gApi.projects().name(project.get()).config(configInput);
ResourceConflictException exception =
assertThrows(
ResourceConflictException.class,
() -> projectCodeOwnersApiFactory.project(project).branch("master").getConfig());
assertThat(exception).hasMessageThat().isEqualTo("project state HIDDEN does not permit read");
}
@Test
public void getDefaultConfig() throws Exception {
codeOwnerConfigOperations
.newCodeOwnerConfig()
.project(project)
.branch("master")
.folderPath("/")
.addCodeOwnerEmail(admin.email())
.create();
CodeOwnerBranchConfigInfo codeOwnerBranchConfigInfo =
projectCodeOwnersApiFactory.project(project).branch("master").getConfig();
assertThat(codeOwnerBranchConfigInfo.general.fileExtension).isNull();
assertThat(codeOwnerBranchConfigInfo.general.mergeCommitStrategy)
.isEqualTo(MergeCommitStrategy.ALL_CHANGED_FILES);
assertThat(codeOwnerBranchConfigInfo.general.fallbackCodeOwners)
.isEqualTo(FallbackCodeOwners.NONE);
assertThat(codeOwnerBranchConfigInfo.general.implicitApprovals).isNull();
assertThat(codeOwnerBranchConfigInfo.general.overrideInfoUrl).isNull();
assertThat(codeOwnerBranchConfigInfo.disabled).isNull();
assertThat(codeOwnerBranchConfigInfo.backendId)
.isEqualTo(CodeOwnerBackendId.getBackendId(backendConfig.getDefaultBackend().getClass()));
assertThat(codeOwnerBranchConfigInfo.requiredApproval.label)
.isEqualTo(RequiredApprovalConfig.DEFAULT_LABEL);
assertThat(codeOwnerBranchConfigInfo.requiredApproval.value)
.isEqualTo(RequiredApprovalConfig.DEFAULT_VALUE);
assertThat(codeOwnerBranchConfigInfo.overrideApproval).isNull();
}
@Test
public void getConfigWithConfiguredFileExtension() throws Exception {
configureFileExtension(project, "foo");
CodeOwnerBranchConfigInfo codeOwnerBranchConfigInfo =
projectCodeOwnersApiFactory.project(project).branch("master").getConfig();
assertThat(codeOwnerBranchConfigInfo.general.fileExtension).isEqualTo("foo");
}
@Test
public void getConfigWithConfiguredOverrideInfoUrl() throws Exception {
configureOverrideInfoUrl(project, "http://foo.example.com");
CodeOwnerBranchConfigInfo codeOwnerBranchConfigInfo =
projectCodeOwnersApiFactory.project(project).branch("master").getConfig();
assertThat(codeOwnerBranchConfigInfo.general.overrideInfoUrl)
.isEqualTo("http://foo.example.com");
}
@Test
public void getConfigWithConfiguredMergeCommitStrategy() throws Exception {
configureMergeCommitStrategy(project, MergeCommitStrategy.FILES_WITH_CONFLICT_RESOLUTION);
CodeOwnerBranchConfigInfo codeOwnerBranchConfigInfo =
projectCodeOwnersApiFactory.project(project).branch("master").getConfig();
assertThat(codeOwnerBranchConfigInfo.general.mergeCommitStrategy)
.isEqualTo(MergeCommitStrategy.FILES_WITH_CONFLICT_RESOLUTION);
}
@Test
public void getConfigWithConfiguredFallbackCodeOwners() throws Exception {
configureFallbackCodeOwners(project, FallbackCodeOwners.ALL_USERS);
CodeOwnerBranchConfigInfo codeOwnerBranchConfigInfo =
projectCodeOwnersApiFactory.project(project).branch("master").getConfig();
assertThat(codeOwnerBranchConfigInfo.general.fallbackCodeOwners)
.isEqualTo(FallbackCodeOwners.ALL_USERS);
}
@Test
public void getConfigForBranchOfDisabledProject() throws Exception {
disableCodeOwnersForProject(project);
CodeOwnerBranchConfigInfo codeOwnerBranchConfigInfo =
projectCodeOwnersApiFactory.project(project).branch("master").getConfig();
assertThat(codeOwnerBranchConfigInfo.disabled).isTrue();
assertThat(codeOwnerBranchConfigInfo.general).isNull();
assertThat(codeOwnerBranchConfigInfo.backendId).isNull();
assertThat(codeOwnerBranchConfigInfo.requiredApproval).isNull();
assertThat(codeOwnerBranchConfigInfo.overrideApproval).isNull();
}
@Test
@GerritConfig(name = "plugin.code-owners.disabled", value = "true")
@GerritConfig(name = "plugin.code-owners.requiredApproval", value = "INVALID")
public void getConfigForBranchOfDisabledProject_invalidPluginConfig() throws Exception {
CodeOwnerBranchConfigInfo codeOwnerBranchConfigInfo =
projectCodeOwnersApiFactory.project(project).branch("master").getConfig();
assertThat(codeOwnerBranchConfigInfo.disabled).isTrue();
assertThat(codeOwnerBranchConfigInfo.general).isNull();
assertThat(codeOwnerBranchConfigInfo.backendId).isNull();
assertThat(codeOwnerBranchConfigInfo.requiredApproval).isNull();
assertThat(codeOwnerBranchConfigInfo.overrideApproval).isNull();
}
@Test
public void getConfigForDisabledBranch() throws Exception {
configureDisabledBranch(project, "refs/heads/master");
CodeOwnerBranchConfigInfo codeOwnerBranchConfigInfo =
projectCodeOwnersApiFactory.project(project).branch("master").getConfig();
assertThat(codeOwnerBranchConfigInfo.disabled).isTrue();
assertThat(codeOwnerBranchConfigInfo.general).isNull();
assertThat(codeOwnerBranchConfigInfo.backendId).isNull();
assertThat(codeOwnerBranchConfigInfo.requiredApproval).isNull();
assertThat(codeOwnerBranchConfigInfo.overrideApproval).isNull();
}
@Test
@GerritConfig(name = "plugin.code-owners.disabledBranch", value = "refs/heads/master")
@GerritConfig(name = "plugin.code-owners.requiredApproval", value = "INVALID")
public void getConfigForDisabledBranch_invalidPluginConfig() throws Exception {
CodeOwnerBranchConfigInfo codeOwnerBranchConfigInfo =
projectCodeOwnersApiFactory.project(project).branch("master").getConfig();
assertThat(codeOwnerBranchConfigInfo.disabled).isTrue();
assertThat(codeOwnerBranchConfigInfo.general).isNull();
assertThat(codeOwnerBranchConfigInfo.backendId).isNull();
assertThat(codeOwnerBranchConfigInfo.requiredApproval).isNull();
assertThat(codeOwnerBranchConfigInfo.overrideApproval).isNull();
}
@Test
public void getConfigWithConfiguredBackend() throws Exception {
String otherBackendId = getOtherCodeOwnerBackend(backendConfig.getDefaultBackend());
configureBackend(project, otherBackendId);
CodeOwnerBranchConfigInfo codeOwnerBranchConfigInfo =
projectCodeOwnersApiFactory.project(project).branch("master").getConfig();
assertThat(codeOwnerBranchConfigInfo.backendId).isEqualTo(otherBackendId);
}
@Test
public void getConfigWithConfiguredBackendForBranch() throws Exception {
String otherBackendId = getOtherCodeOwnerBackend(backendConfig.getDefaultBackend());
configureBackend(project, "refs/heads/master", otherBackendId);
CodeOwnerBranchConfigInfo codeOwnerBranchConfigInfo =
projectCodeOwnersApiFactory.project(project).branch("master").getConfig();
assertThat(codeOwnerBranchConfigInfo.backendId).isEqualTo(otherBackendId);
}
@Test
public void getConfigWithConfiguredRequiredApproval() throws Exception {
configureRequiredApproval(project, "Code-Review+2");
CodeOwnerBranchConfigInfo codeOwnerBranchConfigInfo =
projectCodeOwnersApiFactory.project(project).branch("master").getConfig();
assertThat(codeOwnerBranchConfigInfo.requiredApproval.label).isEqualTo("Code-Review");
assertThat(codeOwnerBranchConfigInfo.requiredApproval.value).isEqualTo(2);
}
@Test
public void getConfigWithConfiguredOverrideApproval() throws Exception {
configureOverrideApproval(project, "Code-Review+2");
CodeOwnerBranchConfigInfo codeOwnerBranchConfigInfo =
projectCodeOwnersApiFactory.project(project).branch("master").getConfig();
assertThat(codeOwnerBranchConfigInfo.overrideApproval).hasSize(1);
assertThat(codeOwnerBranchConfigInfo.overrideApproval.get(0).label).isEqualTo("Code-Review");
assertThat(codeOwnerBranchConfigInfo.overrideApproval.get(0).value).isEqualTo(2);
}
@Test
public void getConfigWithMultipleConfiguredOverrideApproval() throws Exception {
createOwnersOverrideLabel();
setCodeOwnersConfig(
project,
/* subsection= */ null,
OverrideApprovalConfig.KEY_OVERRIDE_APPROVAL,
ImmutableList.of("Owners-Override+1", "Code-Review+2"));
CodeOwnerBranchConfigInfo codeOwnerBranchConfigInfo =
projectCodeOwnersApiFactory.project(project).branch("master").getConfig();
assertThat(codeOwnerBranchConfigInfo.overrideApproval).hasSize(2);
assertThat(codeOwnerBranchConfigInfo.overrideApproval.get(0).label).isEqualTo("Code-Review");
assertThat(codeOwnerBranchConfigInfo.overrideApproval.get(0).value).isEqualTo(2);
assertThat(codeOwnerBranchConfigInfo.overrideApproval.get(1).label)
.isEqualTo("Owners-Override");
assertThat(codeOwnerBranchConfigInfo.overrideApproval.get(1).value).isEqualTo(1);
}
@Test
public void getConfigWithEnabledImplicitApprovals() throws Exception {
configureImplicitApprovals(project);
CodeOwnerBranchConfigInfo codeOwnerBranchConfigInfo =
projectCodeOwnersApiFactory.project(project).branch("master").getConfig();
assertThat(codeOwnerBranchConfigInfo.general.implicitApprovals).isTrue();
}
private void configureFileExtension(Project.NameKey project, String fileExtension)
throws Exception {
setCodeOwnersConfig(
project, /* subsection= */ null, GeneralConfig.KEY_FILE_EXTENSION, fileExtension);
}
private void configureOverrideInfoUrl(Project.NameKey project, String overrideInfoUrl)
throws Exception {
setCodeOwnersConfig(
project, /* subsection= */ null, GeneralConfig.KEY_OVERRIDE_INFO_URL, overrideInfoUrl);
}
private void configureMergeCommitStrategy(
Project.NameKey project, MergeCommitStrategy mergeCommitStrategy) throws Exception {
setCodeOwnersConfig(
project,
/* subsection= */ null,
GeneralConfig.KEY_MERGE_COMMIT_STRATEGY,
mergeCommitStrategy.name());
}
private void configureFallbackCodeOwners(
Project.NameKey project, FallbackCodeOwners fallbackCodeOwners) throws Exception {
setCodeOwnersConfig(
project,
/* subsection= */ null,
GeneralConfig.KEY_FALLBACK_CODE_OWNERS,
fallbackCodeOwners.name());
}
private void configureDisabledBranch(Project.NameKey project, String disabledBranch)
throws Exception {
setCodeOwnersConfig(
project, /* subsection= */ null, StatusConfig.KEY_DISABLED_BRANCH, disabledBranch);
}
private void configureBackend(Project.NameKey project, String backendName) throws Exception {
configureBackend(project, /* branch= */ null, backendName);
}
private void configureBackend(
Project.NameKey project, @Nullable String branch, String backendName) throws Exception {
setCodeOwnersConfig(project, branch, BackendConfig.KEY_BACKEND, backendName);
}
private void configureRequiredApproval(Project.NameKey project, String requiredApproval)
throws Exception {
setCodeOwnersConfig(
project,
/* subsection= */ null,
RequiredApprovalConfig.KEY_REQUIRED_APPROVAL,
requiredApproval);
}
private void configureOverrideApproval(Project.NameKey project, String overrideApproval)
throws Exception {
setCodeOwnersConfig(
project,
/* subsection= */ null,
OverrideApprovalConfig.KEY_OVERRIDE_APPROVAL,
overrideApproval);
}
private void configureImplicitApprovals(Project.NameKey project) throws Exception {
setCodeOwnersConfig(
project, /* subsection= */ null, GeneralConfig.KEY_ENABLE_IMPLICIT_APPROVALS, "true");
}
/** Returns the ID of a code owner backend that is not the given backend. */
private String getOtherCodeOwnerBackend(CodeOwnerBackend codeOwnerBackend) {
for (CodeOwnerBackendId codeOwnerBackendId : CodeOwnerBackendId.values()) {
if (!codeOwnerBackendId.getCodeOwnerBackendClass().equals(codeOwnerBackend.getClass())) {
return codeOwnerBackendId.getBackendId();
}
}
throw new IllegalStateException(
String.format("couldn't find other backend than %s", codeOwnerBackend.getClass()));
}
}