// Copyright (C) 2021 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.backend.config;

import static com.google.common.collect.ImmutableSet.toImmutableSet;
import static com.google.common.truth.Truth.assertThat;
import static com.google.gerrit.plugins.codeowners.testing.CodeOwnerSetSubject.hasEmail;
import static com.google.gerrit.plugins.codeowners.testing.RequiredApprovalSubject.assertThat;
import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import static com.google.gerrit.truth.OptionalSubject.assertThat;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.gerrit.acceptance.TestAccount;
import com.google.gerrit.acceptance.config.GerritConfig;
import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.entities.Project;
import com.google.gerrit.entities.Project.NameKey;
import com.google.gerrit.entities.RefNames;
import com.google.gerrit.extensions.common.LabelDefinitionInput;
import com.google.gerrit.extensions.registration.DynamicMap;
import com.google.gerrit.extensions.registration.PrivateInternals_DynamicMapImpl;
import com.google.gerrit.extensions.registration.RegistrationHandle;
import com.google.gerrit.plugins.codeowners.acceptance.AbstractCodeOwnersTest;
import com.google.gerrit.plugins.codeowners.backend.CodeOwnerBackend;
import com.google.gerrit.plugins.codeowners.backend.CodeOwnerConfig;
import com.google.gerrit.plugins.codeowners.backend.CodeOwnerConfigUpdate;
import com.google.gerrit.plugins.codeowners.backend.FallbackCodeOwners;
import com.google.gerrit.plugins.codeowners.backend.PathExpressionMatcher;
import com.google.gerrit.plugins.codeowners.backend.findowners.FindOwnersBackend;
import com.google.gerrit.plugins.codeowners.common.CodeOwnerConfigValidationPolicy;
import com.google.gerrit.plugins.codeowners.common.MergeCommitStrategy;
import com.google.gerrit.server.IdentifiedUser;
import com.google.inject.Inject;
import com.google.inject.Key;
import com.google.inject.util.Providers;
import java.nio.file.Path;
import java.util.Optional;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.revwalk.RevWalk;
import org.junit.Before;
import org.junit.Test;

/** Tests for {@link CodeOwnersPluginConfigSnapshot}. */
public class CodeOwnersPluginConfigSnapshotTest extends AbstractCodeOwnersTest {
  @Inject private ProjectOperations projectOperations;

  private CodeOwnersPluginConfigSnapshot.Factory codeOwnersPluginConfigSnapshotFactory;
  private DynamicMap<CodeOwnerBackend> codeOwnerBackends;

  @Before
  public void setUpCodeOwnersPlugin() throws Exception {
    codeOwnersPluginConfigSnapshotFactory =
        plugin.getSysInjector().getInstance(CodeOwnersPluginConfigSnapshot.Factory.class);
    codeOwnerBackends =
        plugin.getSysInjector().getInstance(new Key<DynamicMap<CodeOwnerBackend>>() {});
  }

  @Test
  @GerritConfig(name = "plugin.code-owners.fileExtension", value = "foo")
  public void getFileExtensionIfNoneIsConfiguredOnProjectLevel() throws Exception {
    assertThat(cfgSnapshot().getFileExtension()).value().isEqualTo("foo");
  }

  @Test
  @GerritConfig(name = "plugin.code-owners.fileExtension", value = "foo")
  public void fileExtensionOnProjectLevelOverridesDefaultFileExtension() throws Exception {
    configureFileExtension(project, "bar");
    assertThat(cfgSnapshot().getFileExtension()).value().isEqualTo("bar");
  }

  @Test
  @GerritConfig(name = "plugin.code-owners.fileExtension", value = "foo")
  public void fileExtensionIsInheritedFromParentProject() throws Exception {
    configureFileExtension(allProjects, "bar");
    assertThat(cfgSnapshot().getFileExtension()).value().isEqualTo("bar");
  }

  @Test
  public void inheritedFileExtensionCanBeOverridden() throws Exception {
    configureFileExtension(allProjects, "foo");
    configureFileExtension(project, "bar");
    assertThat(cfgSnapshot().getFileExtension()).value().isEqualTo("bar");
  }

  @Test
  public void getMergeCommitStrategyIfNoneIsConfigured() throws Exception {
    assertThat(cfgSnapshot().getMergeCommitStrategy())
        .isEqualTo(MergeCommitStrategy.ALL_CHANGED_FILES);
  }

  @Test
  @GerritConfig(
      name = "plugin.code-owners.mergeCommitStrategy",
      value = "FILES_WITH_CONFLICT_RESOLUTION")
  public void getMergeCommitStrategyIfNoneIsConfiguredOnProjectLevel() throws Exception {
    assertThat(cfgSnapshot().getMergeCommitStrategy())
        .isEqualTo(MergeCommitStrategy.FILES_WITH_CONFLICT_RESOLUTION);
  }

  @Test
  @GerritConfig(
      name = "plugin.code-owners.mergeCommitStrategy",
      value = "FILES_WITH_CONFLICT_RESOLUTION")
  public void mergeCommitStrategyOnProjectLevelOverridesGlobalMergeCommitStrategy()
      throws Exception {
    configureMergeCommitStrategy(project, MergeCommitStrategy.ALL_CHANGED_FILES);
    assertThat(cfgSnapshot().getMergeCommitStrategy())
        .isEqualTo(MergeCommitStrategy.ALL_CHANGED_FILES);
  }

  @Test
  @GerritConfig(
      name = "plugin.code-owners.mergeCommitStrategy",
      value = "FILES_WITH_CONFLICT_RESOLUTION")
  public void mergeCommitStrategyIsInheritedFromParentProject() throws Exception {
    configureMergeCommitStrategy(allProjects, MergeCommitStrategy.ALL_CHANGED_FILES);
    assertThat(cfgSnapshot().getMergeCommitStrategy())
        .isEqualTo(MergeCommitStrategy.ALL_CHANGED_FILES);
  }

  @Test
  public void inheritedMergeCommitStrategyCanBeOverridden() throws Exception {
    configureMergeCommitStrategy(allProjects, MergeCommitStrategy.FILES_WITH_CONFLICT_RESOLUTION);
    configureMergeCommitStrategy(project, MergeCommitStrategy.ALL_CHANGED_FILES);
    assertThat(cfgSnapshot().getMergeCommitStrategy())
        .isEqualTo(MergeCommitStrategy.ALL_CHANGED_FILES);
  }

  @Test
  public void getFallbackCodeOwnersIfNoneIsConfigured() throws Exception {
    assertThat(cfgSnapshot().getFallbackCodeOwners()).isEqualTo(FallbackCodeOwners.NONE);
  }

  @Test
  @GerritConfig(name = "plugin.code-owners.fallbackCodeOwners", value = "ALL_USERS")
  public void getFallbackCodeOwnersIfNoneIsConfiguredOnProjectLevel() throws Exception {
    assertThat(cfgSnapshot().getFallbackCodeOwners()).isEqualTo(FallbackCodeOwners.ALL_USERS);
  }

  @Test
  @GerritConfig(name = "plugin.code-owners.fallbackCodeOwners", value = "ALL_USERS")
  public void fallbackCodeOnwersOnProjectLevelOverridesGlobalFallbackCodeOwners() throws Exception {
    configureFallbackCodeOwners(project, FallbackCodeOwners.NONE);
    assertThat(cfgSnapshot().getFallbackCodeOwners()).isEqualTo(FallbackCodeOwners.NONE);
  }

  @Test
  @GerritConfig(name = "plugin.code-owners.fallbackCodeOwners", value = "ALL_USERS")
  public void fallbackCodeOwnersIsInheritedFromParentProject() throws Exception {
    configureFallbackCodeOwners(allProjects, FallbackCodeOwners.NONE);
    assertThat(cfgSnapshot().getFallbackCodeOwners()).isEqualTo(FallbackCodeOwners.NONE);
  }

  @Test
  public void inheritedFallbackCodeOwnersCanBeOverridden() throws Exception {
    configureFallbackCodeOwners(allProjects, FallbackCodeOwners.ALL_USERS);
    configureFallbackCodeOwners(project, FallbackCodeOwners.NONE);
    assertThat(cfgSnapshot().getFallbackCodeOwners()).isEqualTo(FallbackCodeOwners.NONE);
  }

  @Test
  public void getGlobalCodeOwnersIfNoneIsConfigured() throws Exception {
    assertThat(cfgSnapshot().getGlobalCodeOwners()).isEmpty();
  }

  @Test
  @GerritConfig(
      name = "plugin.code-owners.globalCodeOwner",
      values = {"global-code-owner-1@example.com", "global-code-owner-2@example.com"})
  public void getGlobalCodeOwnerssIfNoneIsConfiguredOnProjectLevel() throws Exception {
    TestAccount globalCodeOwner1 =
        accountCreator.create(
            "globalCodeOwner1",
            "global-code-owner-1@example.com",
            "Global Code Owner 1",
            /* displayName= */ null);
    TestAccount globalCodeOwner2 =
        accountCreator.create(
            "globalCodeOwner2",
            "global-code-owner-2@example.com",
            "Global Code Owner 2",
            /* displayName= */ null);
    assertThat(cfgSnapshot().getGlobalCodeOwners())
        .comparingElementsUsing(hasEmail())
        .containsExactly(globalCodeOwner1.email(), globalCodeOwner2.email());
  }

  @Test
  @GerritConfig(
      name = "plugin.code-owners.globalCodeOwner",
      values = {"global-code-owner-1@example.com", "global-code-owner-2@example.com"})
  public void globalCodeOwnersOnProjectLevelExtendsGloballyConfiguredGlobalCodeOwners()
      throws Exception {
    TestAccount globalCodeOwner1 =
        accountCreator.create(
            "globalCodeOwner1",
            "global-code-owner-1@example.com",
            "Global Code Owner 1",
            /* displayName= */ null);
    TestAccount globalCodeOwner2 =
        accountCreator.create(
            "globalCodeOwner2",
            "global-code-owner-2@example.com",
            "Global Code Owner 2",
            /* displayName= */ null);
    TestAccount globalCodeOwner3 =
        accountCreator.create(
            "globalCodeOwner3",
            "global-code-owner-3@example.com",
            "Global Code Owner 3",
            /* displayName= */ null);
    TestAccount globalCodeOwner4 =
        accountCreator.create(
            "globalCodeOwner4",
            "global-code-owner-4@example.com",
            "Global Code Owner 4",
            /* displayName= */ null);
    configureGlobalCodeOwners(allProjects, globalCodeOwner3.email(), globalCodeOwner4.email());
    assertThat(cfgSnapshot().getGlobalCodeOwners())
        .comparingElementsUsing(hasEmail())
        .containsExactly(
            globalCodeOwner1.email(),
            globalCodeOwner2.email(),
            globalCodeOwner3.email(),
            globalCodeOwner4.email());
  }

  @Test
  @GerritConfig(
      name = "plugin.code-owners.globalCodeOwner",
      values = {"global-code-owner-1@example.com", "global-code-owner-2@example.com"})
  public void
      globalCodeOwnersOnProjectLevelExtendsGloballyConfiguredGlobalCodeOwners_duplicatesAreFilteredOut()
          throws Exception {
    TestAccount globalCodeOwner1 =
        accountCreator.create(
            "globalCodeOwner1",
            "global-code-owner-1@example.com",
            "Global Code Owner 1",
            /* displayName= */ null);
    TestAccount globalCodeOwner2 =
        accountCreator.create(
            "globalCodeOwner2",
            "global-code-owner-2@example.com",
            "Global Code Owner 2",
            /* displayName= */ null);
    TestAccount globalCodeOwner3 =
        accountCreator.create(
            "globalCodeOwner3",
            "global-code-owner-3@example.com",
            "Global Code Owner 3",
            /* displayName= */ null);
    configureGlobalCodeOwners(allProjects, globalCodeOwner1.email(), globalCodeOwner3.email());
    assertThat(cfgSnapshot().getGlobalCodeOwners())
        .comparingElementsUsing(hasEmail())
        .containsExactly(
            globalCodeOwner1.email(), globalCodeOwner2.email(), globalCodeOwner3.email());
  }

  @Test
  @GerritConfig(
      name = "plugin.code-owners.globalCodeOwner",
      values = {"global-code-owner-1@example.com", "global-code-owner-2@example.com"})
  public void globalCodeOwnersAreInheritedFromParentProject() throws Exception {
    TestAccount globalCodeOwner1 =
        accountCreator.create(
            "globalCodeOwner1",
            "global-code-owner-1@example.com",
            "Global Code Owner 1",
            /* displayName= */ null);
    TestAccount globalCodeOwner2 =
        accountCreator.create(
            "globalCodeOwner2",
            "global-code-owner-2@example.com",
            "Global Code Owner 2",
            /* displayName= */ null);
    TestAccount globalCodeOwner3 =
        accountCreator.create(
            "globalCodeOwner3",
            "global-code-owner-3@example.com",
            "Global Code Owner 3",
            /* displayName= */ null);
    TestAccount globalCodeOwner4 =
        accountCreator.create(
            "globalCodeOwner4",
            "global-code-owner-4@example.com",
            "Global Code Owner 4",
            /* displayName= */ null);
    configureGlobalCodeOwners(allProjects, globalCodeOwner3.email(), globalCodeOwner4.email());
    assertThat(cfgSnapshot().getGlobalCodeOwners())
        .comparingElementsUsing(hasEmail())
        .containsExactly(
            globalCodeOwner1.email(),
            globalCodeOwner2.email(),
            globalCodeOwner3.email(),
            globalCodeOwner4.email());
  }

  @Test
  @GerritConfig(
      name = "plugin.code-owners.globalCodeOwner",
      values = {"global-code-owner-1@example.com", "global-code-owner-2@example.com"})
  public void globalCodeOwnersAreInheritedFromParentProject_duplicatesAreFilteredOut()
      throws Exception {
    TestAccount globalCodeOwner1 =
        accountCreator.create(
            "globalCodeOwner1",
            "global-code-owner-1@example.com",
            "Global Code Owner 1",
            /* displayName= */ null);
    TestAccount globalCodeOwner2 =
        accountCreator.create(
            "globalCodeOwner2",
            "global-code-owner-2@example.com",
            "Global Code Owner 2",
            /* displayName= */ null);
    TestAccount globalCodeOwner3 =
        accountCreator.create(
            "globalCodeOwner3",
            "global-code-owner-3@example.com",
            "Global Code Owner 3",
            /* displayName= */ null);
    configureGlobalCodeOwners(allProjects, globalCodeOwner1.email(), globalCodeOwner3.email());
    assertThat(cfgSnapshot().getGlobalCodeOwners())
        .comparingElementsUsing(hasEmail())
        .containsExactly(
            globalCodeOwner1.email(), globalCodeOwner2.email(), globalCodeOwner3.email());
  }

  @Test
  public void inheritedGlobalCodeOwnersCanBeExtended() throws Exception {
    TestAccount globalCodeOwner1 =
        accountCreator.create(
            "globalCodeOwner1",
            "global-code-owner-1@example.com",
            "Global Code Owner 1",
            /* displayName= */ null);
    TestAccount globalCodeOwner2 =
        accountCreator.create(
            "globalCodeOwner2",
            "global-code-owner-2@example.com",
            "Global Code Owner 2",
            /* displayName= */ null);
    TestAccount globalCodeOwner3 =
        accountCreator.create(
            "globalCodeOwner3",
            "global-code-owner-3@example.com",
            "Global Code Owner 3",
            /* displayName= */ null);
    TestAccount globalCodeOwner4 =
        accountCreator.create(
            "globalCodeOwner4",
            "global-code-owner-4@example.com",
            "Global Code Owner 4",
            /* displayName= */ null);
    configureGlobalCodeOwners(allProjects, globalCodeOwner1.email(), globalCodeOwner2.email());
    configureGlobalCodeOwners(project, globalCodeOwner3.email(), globalCodeOwner4.email());
    assertThat(cfgSnapshot().getGlobalCodeOwners())
        .comparingElementsUsing(hasEmail())
        .containsExactly(
            globalCodeOwner1.email(),
            globalCodeOwner2.email(),
            globalCodeOwner3.email(),
            globalCodeOwner4.email());
  }

  @Test
  public void inheritedGlobalCodeOwnersCanBeExtended_duplicatesAreFilteredOut() throws Exception {
    TestAccount globalCodeOwner1 =
        accountCreator.create(
            "globalCodeOwner1",
            "global-code-owner-1@example.com",
            "Global Code Owner 1",
            /* displayName= */ null);
    TestAccount globalCodeOwner2 =
        accountCreator.create(
            "globalCodeOwner2",
            "global-code-owner-2@example.com",
            "Global Code Owner 2",
            /* displayName= */ null);
    TestAccount globalCodeOwner3 =
        accountCreator.create(
            "globalCodeOwner3",
            "global-code-owner-3@example.com",
            "Global Code Owner 3",
            /* displayName= */ null);
    configureGlobalCodeOwners(allProjects, globalCodeOwner1.email(), globalCodeOwner2.email());
    configureGlobalCodeOwners(project, globalCodeOwner1.email(), globalCodeOwner3.email());
    assertThat(cfgSnapshot().getGlobalCodeOwners())
        .comparingElementsUsing(hasEmail())
        .containsExactly(
            globalCodeOwner1.email(), globalCodeOwner2.email(), globalCodeOwner3.email());
  }

  @Test
  public void inheritedGlobalCodeOwnersCannotBeRemoved() throws Exception {
    TestAccount globalCodeOwner1 =
        accountCreator.create(
            "globalCodeOwner1",
            "global-code-owner-1@example.com",
            "Global Code Owner 1",
            /* displayName= */ null);
    TestAccount globalCodeOwner2 =
        accountCreator.create(
            "globalCodeOwner2",
            "global-code-owner-2@example.com",
            "Global Code Owner 2",
            /* displayName= */ null);
    configureGlobalCodeOwners(allProjects, globalCodeOwner1.email(), globalCodeOwner2.email());
    configureGlobalCodeOwners(project, "");
    assertThat(cfgSnapshot().getGlobalCodeOwners())
        .comparingElementsUsing(hasEmail())
        .containsExactly(globalCodeOwner1.email(), globalCodeOwner2.email());
  }

  @Test
  public void getExemptedAccountsIfNoneIsConfigured() throws Exception {
    assertThat(cfgSnapshot().getExemptedAccounts()).isEmpty();
  }

  @Test
  @GerritConfig(
      name = "plugin.code-owners.exemptedUser",
      values = {"exempted-user-1@example.com", "exempted-user-2@example.com"})
  public void getExemptedAccountsIfNoneIsConfiguredOnProjectLevel() throws Exception {
    TestAccount exemptedUser1 =
        accountCreator.create(
            "exemptedUser1",
            "exempted-user-1@example.com",
            "Exempted User 1",
            /* displayName= */ null);
    TestAccount exemptedUser2 =
        accountCreator.create(
            "exemptedUser2",
            "exempted-user-2@example.com",
            "Exempted User 2",
            /* displayName= */ null);
    assertThat(cfgSnapshot().getExemptedAccounts())
        .containsExactly(exemptedUser1.id(), exemptedUser2.id());
  }

  @Test
  @GerritConfig(
      name = "plugin.code-owners.exemptedUser",
      values = {"exempted-user-1@example.com", "exempted-user-2@example.com"})
  public void exemptedAccountsOnProjectLevelExtendsGloballyConfiguredExemptedAcounts()
      throws Exception {
    TestAccount exemptedUser1 =
        accountCreator.create(
            "exemptedUser1",
            "exempted-user-1@example.com",
            "Exempted User 1",
            /* displayName= */ null);
    TestAccount exemptedUser2 =
        accountCreator.create(
            "exemptedUser2",
            "exempted-user-2@example.com",
            "Exempted User 2",
            /* displayName= */ null);
    TestAccount exemptedUser3 =
        accountCreator.create(
            "exemptedUser3",
            "exempted-user-3@example.com",
            "Exempted User 3",
            /* displayName= */ null);
    TestAccount exemptedUser4 =
        accountCreator.create(
            "exemptedUser4",
            "exempted-user-4@example.com",
            "Exempted User 4",
            /* displayName= */ null);
    configureExemptedUsers(allProjects, exemptedUser3.email(), exemptedUser4.email());
    assertThat(cfgSnapshot().getExemptedAccounts())
        .containsExactly(
            exemptedUser1.id(), exemptedUser2.id(), exemptedUser3.id(), exemptedUser4.id());
  }

  @Test
  @GerritConfig(
      name = "plugin.code-owners.exemptedUser",
      values = {"exempted-user-1@example.com", "exempted-user-2@example.com"})
  public void
      exemptedAccountsOnProjectLevelExtendsGloballyConfiguredExemptedAcounts_duplicatesAreFilteredOut()
          throws Exception {
    TestAccount exemptedUser1 =
        accountCreator.create(
            "exemptedUser1",
            "exempted-user-1@example.com",
            "Exempted User 1",
            /* displayName= */ null);
    TestAccount exemptedUser2 =
        accountCreator.create(
            "exemptedUser2",
            "exempted-user-2@example.com",
            "Exempted User 2",
            /* displayName= */ null);
    TestAccount exemptedUser3 =
        accountCreator.create(
            "exemptedUser3",
            "exempted-user-3@example.com",
            "Exempted User 3",
            /* displayName= */ null);
    configureExemptedUsers(allProjects, exemptedUser1.email(), exemptedUser3.email());
    assertThat(cfgSnapshot().getExemptedAccounts())
        .containsExactly(exemptedUser1.id(), exemptedUser2.id(), exemptedUser3.id());
  }

  @Test
  @GerritConfig(
      name = "plugin.code-owners.exemptedUser",
      values = {"exempted-user-1@example.com", "exempted-user-2@example.com"})
  public void exemptedAccountsAreInheritedFromParentProject() throws Exception {
    TestAccount exemptedUser1 =
        accountCreator.create(
            "exemptedUser1",
            "exempted-user-1@example.com",
            "Exempted User 1",
            /* displayName= */ null);
    TestAccount exemptedUser2 =
        accountCreator.create(
            "exemptedUser2",
            "exempted-user-2@example.com",
            "Exempted User 2",
            /* displayName= */ null);
    TestAccount exemptedUser3 =
        accountCreator.create(
            "exemptedUser3",
            "exempted-user-3@example.com",
            "Exempted User 3",
            /* displayName= */ null);
    TestAccount exemptedUser4 =
        accountCreator.create(
            "exemptedUser4",
            "exempted-user-4@example.com",
            "Exempted User 4",
            /* displayName= */ null);
    configureExemptedUsers(allProjects, exemptedUser3.email(), exemptedUser4.email());
    assertThat(cfgSnapshot().getExemptedAccounts())
        .containsExactly(
            exemptedUser1.id(), exemptedUser2.id(), exemptedUser3.id(), exemptedUser4.id());
  }

  @Test
  @GerritConfig(
      name = "plugin.code-owners.exemptedUser",
      values = {"exempted-user-1@example.com", "exempted-user-2@example.com"})
  public void exemptedAccountsAreInheritedFromParentProject_duplicatesAreFilteredOut()
      throws Exception {
    TestAccount exemptedUser1 =
        accountCreator.create(
            "exemptedUser1",
            "exempted-user-1@example.com",
            "Exempted User 1",
            /* displayName= */ null);
    TestAccount exemptedUser2 =
        accountCreator.create(
            "exemptedUser2",
            "exempted-user-2@example.com",
            "Exempted User 2",
            /* displayName= */ null);
    TestAccount exemptedUser3 =
        accountCreator.create(
            "exemptedUser3",
            "exempted-user-3@example.com",
            "Exempted User 3",
            /* displayName= */ null);
    configureExemptedUsers(allProjects, exemptedUser1.email(), exemptedUser3.email());
    assertThat(cfgSnapshot().getExemptedAccounts())
        .containsExactly(exemptedUser1.id(), exemptedUser2.id(), exemptedUser3.id());
  }

  @Test
  public void inheritedExemptedAccountsCanBeExtended() throws Exception {
    TestAccount exemptedUser1 =
        accountCreator.create(
            "exemptedUser1",
            "exempted-user-1@example.com",
            "Exempted User 1",
            /* displayName= */ null);
    TestAccount exemptedUser2 =
        accountCreator.create(
            "exemptedUser2",
            "exempted-user-2@example.com",
            "Exempted User 2",
            /* displayName= */ null);
    TestAccount exemptedUser3 =
        accountCreator.create(
            "exemptedUser3",
            "exempted-user-3@example.com",
            "Exempted User 3",
            /* displayName= */ null);
    TestAccount exemptedUser4 =
        accountCreator.create(
            "exemptedUser4",
            "exempted-user-4@example.com",
            "Exempted User 4",
            /* displayName= */ null);
    configureExemptedUsers(allProjects, exemptedUser1.email(), exemptedUser2.email());
    configureExemptedUsers(project, exemptedUser3.email(), exemptedUser4.email());
    assertThat(cfgSnapshot().getExemptedAccounts())
        .containsExactly(
            exemptedUser1.id(), exemptedUser2.id(), exemptedUser3.id(), exemptedUser4.id());
  }

  @Test
  public void inheritedExemptedAccountsCanBeExtended_duplicatesAreFilteredOut() throws Exception {
    TestAccount exemptedUser1 =
        accountCreator.create(
            "exemptedUser1",
            "exempted-user-1@example.com",
            "Exempted User 1",
            /* displayName= */ null);
    TestAccount exemptedUser2 =
        accountCreator.create(
            "exemptedUser2",
            "exempted-user-2@example.com",
            "Exempted User 2",
            /* displayName= */ null);
    TestAccount exemptedUser3 =
        accountCreator.create(
            "exemptedUser3",
            "exempted-user-3@example.com",
            "Exempted User 3",
            /* displayName= */ null);
    configureExemptedUsers(allProjects, exemptedUser1.email(), exemptedUser2.email());
    configureExemptedUsers(project, exemptedUser1.email(), exemptedUser3.email());
    assertThat(cfgSnapshot().getExemptedAccounts())
        .containsExactly(exemptedUser1.id(), exemptedUser2.id(), exemptedUser3.id());
  }

  @Test
  public void inheritedExemptedAccountsCannotBeRemoved() throws Exception {
    TestAccount exemptedUser1 =
        accountCreator.create(
            "exemptedUser1",
            "exempted-user-1@example.com",
            "Exempted User 1",
            /* displayName= */ null);
    TestAccount exemptedUser2 =
        accountCreator.create(
            "exemptedUser2",
            "exempted-user-2@example.com",
            "Exempted User 2",
            /* displayName= */ null);
    configureExemptedUsers(allProjects, exemptedUser1.email(), exemptedUser2.email());
    configureExemptedUsers(project, "");
    assertThat(cfgSnapshot().getExemptedAccounts())
        .containsExactly(exemptedUser1.id(), exemptedUser2.id());
  }

  @Test
  public void nonResolvableExemptedAccountsAreIgnored() throws Exception {
    TestAccount exemptedUser =
        accountCreator.create(
            "exemptedUser", "exempted-user@example.com", "Exempted User", /* displayName= */ null);
    configureExemptedUsers(project, exemptedUser.email(), "non-resolveable@example.com");
    assertThat(cfgSnapshot().getExemptedAccounts()).containsExactly(exemptedUser.id());
  }

  @Test
  public void exemptedAccountsByIdAreIgnored() throws Exception {
    TestAccount exemptedUser1 =
        accountCreator.create(
            "exemptedUser1",
            "exempted-user-1@example.com",
            "Exempted User 1",
            /* displayName= */ null);
    TestAccount exemptedUser2 =
        accountCreator.create(
            "exemptedUser2",
            "exempted-user-2@example.com",
            "Exempted User 2",
            /* displayName= */ null);
    configureExemptedUsers(
        project, exemptedUser1.email(), Integer.toString(exemptedUser2.id().get()));
    assertThat(cfgSnapshot().getExemptedAccounts()).containsExactly(exemptedUser1.id());
  }

  @Test
  public void getMaxPathsInChangeMessagesIfNoneIsConfigured() throws Exception {
    assertThat(cfgSnapshot().getMaxPathsInChangeMessages())
        .isEqualTo(GeneralConfig.DEFAULT_MAX_PATHS_IN_CHANGE_MESSAGES);
  }

  @Test
  @GerritConfig(name = "plugin.code-owners.maxPathsInChangeMessages", value = "50")
  public void getMaxPathsInChangeMessagesIfNoneIsConfiguredOnProjectLevel() throws Exception {
    assertThat(cfgSnapshot().getMaxPathsInChangeMessages()).isEqualTo(50);
  }

  @Test
  @GerritConfig(name = "plugin.code-owners.maxPathsInChangeMessages", value = "50")
  public void maxPathInChangeMessagesOnProjectLevelOverridesGlobalMaxPathInChangeMessages()
      throws Exception {
    configureMaxPathsInChangeMessages(project, 20);
    assertThat(cfgSnapshot().getMaxPathsInChangeMessages()).isEqualTo(20);
  }

  @Test
  @GerritConfig(name = "plugin.code-owners.maxPathsInChangeMessages", value = "50")
  public void maxPathInChangeMessagesIsInheritedFromParentProject() throws Exception {
    configureMaxPathsInChangeMessages(allProjects, 20);
    assertThat(cfgSnapshot().getMaxPathsInChangeMessages()).isEqualTo(20);
  }

  @Test
  public void inheritedMaxPathInChangeMessagesCanBeOverridden() throws Exception {
    configureMaxPathsInChangeMessages(allProjects, 50);
    configureMaxPathsInChangeMessages(project, 20);
    assertThat(cfgSnapshot().getMaxPathsInChangeMessages()).isEqualTo(20);
  }

  @Test
  public void cannotCheckForNullBranchIfCodeOwnersFunctionalityIsDisabled() throws Exception {
    NullPointerException npe =
        assertThrows(
            NullPointerException.class, () -> cfgSnapshot().isDisabled(/* branchName= */ null));
    assertThat(npe).hasMessageThat().isEqualTo("branchName");
  }

  @Test
  public void checkIfCodeOwnersFunctionalityIsDisabledForNonExistingBranch() throws Exception {
    assertThat(cfgSnapshot().isDisabled("non-existing")).isFalse();
  }

  @Test
  public void checkIfCodeOwnersFunctionalityIsDisabledForProjectWithEmptyConfig() throws Exception {
    assertThat(cfgSnapshot().isDisabled()).isFalse();
  }

  @Test
  public void checkIfCodeOwnersFunctionalityIsDisabledForBranchWithEmptyConfig() throws Exception {
    assertThat(cfgSnapshot().isDisabled("master")).isFalse();
  }

  @Test
  public void codeOwnersFunctionalityIsDisabledForProject() throws Exception {
    disableCodeOwnersForProject(project);
    assertThat(cfgSnapshot().isDisabled()).isTrue();
  }

  @Test
  public void codeOwnersFunctionalityIsDisabledForBranchIfItIsDisabledForProject()
      throws Exception {
    disableCodeOwnersForProject(project);
    assertThat(cfgSnapshot().isDisabled("master")).isTrue();
  }

  @Test
  public void codeOwnersFunctionalityIsDisabledForBranch_exactRef() throws Exception {
    configureDisabledBranch(project, "refs/heads/master");
    assertThat(cfgSnapshot().isDisabled("master")).isTrue();
    assertThat(cfgSnapshot().isDisabled("other")).isFalse();
  }

  @Test
  public void codeOwnersFunctionalityIsDisabledForBranch_refPattern() throws Exception {
    configureDisabledBranch(project, "refs/heads/*");
    assertThat(cfgSnapshot().isDisabled("master")).isTrue();
    assertThat(cfgSnapshot().isDisabled("other")).isTrue();
    assertThat(cfgSnapshot().isDisabled(RefNames.REFS_META)).isFalse();
  }

  @Test
  public void codeOwnersFunctionalityIsDisabledForBranch_regularExpression() throws Exception {
    configureDisabledBranch(project, "^refs/heads/.*");
    assertThat(cfgSnapshot().isDisabled("master")).isTrue();
    assertThat(cfgSnapshot().isDisabled("other")).isTrue();
    assertThat(cfgSnapshot().isDisabled(RefNames.REFS_META)).isFalse();
  }

  @Test
  public void codeOwnersFunctionalityIsDisabledForBranch_invalidRegularExpression()
      throws Exception {
    configureDisabledBranch(project, "^refs/heads/[");
    assertThat(cfgSnapshot().isDisabled("master")).isFalse();
  }

  @Test
  public void disabledIsInheritedFromParentProject() throws Exception {
    disableCodeOwnersForProject(allProjects);
    assertThat(cfgSnapshot().isDisabled()).isTrue();
  }

  @Test
  public void inheritedDisabledAlsoCountsForBranch() throws Exception {
    disableCodeOwnersForProject(allProjects);
    assertThat(cfgSnapshot().isDisabled("master")).isTrue();
  }

  @Test
  public void inheritedDisabledValueIsIgnoredIfInvalid() throws Exception {
    configureDisabled(project, "invalid");
    assertThat(cfgSnapshot().isDisabled()).isFalse();
  }

  @Test
  public void inheritedDisabledValueIsIgnoredForBranchIfInvalid() throws Exception {
    configureDisabled(project, "invalid");
    assertThat(cfgSnapshot().isDisabled("master")).isFalse();
  }

  @Test
  public void disabledForOtherProjectHasNoEffect() throws Exception {
    Project.NameKey otherProject = projectOperations.newProject().create();
    disableCodeOwnersForProject(otherProject);
    assertThat(cfgSnapshot().isDisabled()).isFalse();
  }

  @Test
  public void disabledBranchForOtherProjectHasNoEffect() throws Exception {
    Project.NameKey otherProject = projectOperations.newProject().create();
    configureDisabledBranch(otherProject, "refs/heads/master");
    assertThat(cfgSnapshot().isDisabled("master")).isFalse();
  }

  @Test
  public void disabledBranchIsInheritedFromParentProject() throws Exception {
    configureDisabledBranch(allProjects, "refs/heads/master");
    assertThat(cfgSnapshot().isDisabled("master")).isTrue();
  }

  @Test
  public void inheritedDisabledCanBeOverridden() throws Exception {
    disableCodeOwnersForProject(allProjects);
    enableCodeOwnersForProject(project);
    assertThat(cfgSnapshot().isDisabled("master")).isFalse();
  }

  @Test
  public void inheritedDisabledBranchCanBeExtended() throws Exception {
    configureDisabledBranch(allProjects, "refs/heads/master");
    configureDisabledBranch(project, "refs/heads/test");
    assertThat(cfgSnapshot().isDisabled("master")).isTrue();
    assertThat(cfgSnapshot().isDisabled("test")).isTrue();
  }

  @Test
  public void inheritedDisabledBranchCannotBeRemoved() throws Exception {
    configureDisabledBranch(allProjects, "refs/heads/master");

    // trying to override the inherited config with an empty value to enable code owners for all
    // branches doesn't work because the empty string is added to the inherited value list so that
    // disabledBranch is ["refs/heads/master", ""] now
    configureDisabledBranch(project, "");

    assertThat(cfgSnapshot().isDisabled("master")).isTrue();
  }

  @Test
  public void getBackendForNonExistingBranch() throws Exception {
    assertThat(cfgSnapshot().getBackend("non-existing")).isInstanceOf(FindOwnersBackend.class);
  }

  @Test
  public void getDefaultBackendWhenNoBackendIsConfigured() throws Exception {
    assertThat(cfgSnapshot().getBackend("master")).isInstanceOf(FindOwnersBackend.class);
  }

  @Test
  @GerritConfig(name = "plugin.code-owners.backend", value = TestCodeOwnerBackend.ID)
  public void getConfiguredDefaultBackend() throws Exception {
    try (AutoCloseable registration = registerTestBackend()) {
      assertThat(cfgSnapshot().getBackend("master")).isInstanceOf(TestCodeOwnerBackend.class);
    }
  }

  @Test
  @GerritConfig(name = "plugin.code-owners.backend", value = "non-existing-backend")
  public void cannotGetBackendIfNonExistingBackendIsConfigured() throws Exception {
    InvalidPluginConfigurationException exception =
        assertThrows(
            InvalidPluginConfigurationException.class, () -> cfgSnapshot().getBackend("master"));
    assertThat(exception)
        .hasMessageThat()
        .isEqualTo(
            "Invalid configuration of the code-owners plugin. Code owner backend"
                + " 'non-existing-backend' that is configured in gerrit.config (parameter"
                + " plugin.code-owners.backend) not found.");
  }

  @Test
  public void getBackendConfiguredOnProjectLevel() throws Exception {
    configureBackend(project, TestCodeOwnerBackend.ID);
    try (AutoCloseable registration = registerTestBackend()) {
      assertThat(cfgSnapshot().getBackend("master")).isInstanceOf(TestCodeOwnerBackend.class);
    }
  }

  @Test
  @GerritConfig(name = "plugin.code-owners.backend", value = FindOwnersBackend.ID)
  public void backendConfiguredOnProjectLevelOverridesDefaultBackend() throws Exception {
    configureBackend(project, TestCodeOwnerBackend.ID);
    try (AutoCloseable registration = registerTestBackend()) {
      assertThat(cfgSnapshot().getBackend("master")).isInstanceOf(TestCodeOwnerBackend.class);
    }
  }

  @Test
  public void backendIsInheritedFromParentProject() throws Exception {
    configureBackend(allProjects, TestCodeOwnerBackend.ID);
    try (AutoCloseable registration = registerTestBackend()) {
      assertThat(cfgSnapshot().getBackend("master")).isInstanceOf(TestCodeOwnerBackend.class);
    }
  }

  @Test
  @GerritConfig(name = "plugin.code-owners.backend", value = FindOwnersBackend.ID)
  public void inheritedBackendOverridesDefaultBackend() throws Exception {
    configureBackend(allProjects, TestCodeOwnerBackend.ID);
    try (AutoCloseable registration = registerTestBackend()) {
      assertThat(cfgSnapshot().getBackend("master")).isInstanceOf(TestCodeOwnerBackend.class);
    }
  }

  @Test
  public void projectLevelBackendOverridesInheritedBackend() throws Exception {
    configureBackend(allProjects, TestCodeOwnerBackend.ID);
    configureBackend(project, FindOwnersBackend.ID);
    try (AutoCloseable registration = registerTestBackend()) {
      assertThat(cfgSnapshot().getBackend("master")).isInstanceOf(FindOwnersBackend.class);
    }
  }

  @Test
  public void cannotGetBackendIfNonExistingBackendIsConfiguredOnProjectLevel() throws Exception {
    configureBackend(project, "non-existing-backend");
    InvalidPluginConfigurationException exception =
        assertThrows(
            InvalidPluginConfigurationException.class, () -> cfgSnapshot().getBackend("master"));
    assertThat(exception)
        .hasMessageThat()
        .isEqualTo(
            String.format(
                "Invalid configuration of the code-owners plugin. Code owner backend"
                    + " 'non-existing-backend' that is configured for project %s in"
                    + " code-owners.config (parameter codeOwners.backend) not found.",
                project));
  }

  @Test
  public void projectLevelBackendForOtherProjectHasNoEffect() throws Exception {
    Project.NameKey otherProject = projectOperations.newProject().create();
    configureBackend(otherProject, TestCodeOwnerBackend.ID);
    try (AutoCloseable registration = registerTestBackend()) {
      assertThat(cfgSnapshot().getBackend("master")).isInstanceOf(FindOwnersBackend.class);
    }
  }

  @Test
  public void getBackendConfiguredOnBranchLevel() throws Exception {
    configureBackend(project, "refs/heads/master", TestCodeOwnerBackend.ID);
    try (AutoCloseable registration = registerTestBackend()) {
      assertThat(cfgSnapshot().getBackend("master")).isInstanceOf(TestCodeOwnerBackend.class);
    }
  }

  @Test
  public void getBackendConfiguredOnBranchLevelShortName() throws Exception {
    configureBackend(project, "master", TestCodeOwnerBackend.ID);
    try (AutoCloseable registration = registerTestBackend()) {
      assertThat(cfgSnapshot().getBackend("master")).isInstanceOf(TestCodeOwnerBackend.class);
    }
  }

  @Test
  public void branchLevelBackendOnFullNameTakesPrecedenceOverBranchLevelBackendOnShortName()
      throws Exception {
    configureBackend(project, "master", TestCodeOwnerBackend.ID);
    configureBackend(project, "refs/heads/master", FindOwnersBackend.ID);
    try (AutoCloseable registration = registerTestBackend()) {
      assertThat(cfgSnapshot().getBackend("master")).isInstanceOf(FindOwnersBackend.class);
    }
  }

  @Test
  public void branchLevelBackendOverridesProjectLevelBackend() throws Exception {
    configureBackend(project, TestCodeOwnerBackend.ID);
    configureBackend(project, "master", FindOwnersBackend.ID);
    try (AutoCloseable registration = registerTestBackend()) {
      assertThat(cfgSnapshot().getBackend("master")).isInstanceOf(FindOwnersBackend.class);
    }
  }

  @Test
  public void cannotGetBackendIfNonExistingBackendIsConfiguredOnBranchLevel() throws Exception {
    configureBackend(project, "master", "non-existing-backend");
    InvalidPluginConfigurationException exception =
        assertThrows(
            InvalidPluginConfigurationException.class, () -> cfgSnapshot().getBackend("master"));
    assertThat(exception)
        .hasMessageThat()
        .isEqualTo(
            String.format(
                "Invalid configuration of the code-owners plugin. Code owner backend"
                    + " 'non-existing-backend' that is configured for project %s in"
                    + " code-owners.config (parameter codeOwners.master.backend) not found.",
                project));
  }

  @Test
  public void branchLevelBackendForOtherBranchHasNoEffect() throws Exception {
    configureBackend(project, "foo", TestCodeOwnerBackend.ID);
    try (AutoCloseable registration = registerTestBackend()) {
      assertThat(cfgSnapshot().getBackend("master")).isInstanceOf(FindOwnersBackend.class);
    }
  }

  @Test
  public void getDefaultRequiredApprovalWhenNoRequiredApprovalIsConfigured() throws Exception {
    RequiredApproval requiredApproval = cfgSnapshot().getRequiredApproval();
    assertThat(requiredApproval).hasLabelNameThat().isEqualTo(RequiredApprovalConfig.DEFAULT_LABEL);
    assertThat(requiredApproval).hasValueThat().isEqualTo(RequiredApprovalConfig.DEFAULT_VALUE);
  }

  @Test
  @GerritConfig(name = "plugin.code-owners.requiredApproval", value = "Code-Review+2")
  public void getGloballyConfiguredRequiredApproval() throws Exception {
    RequiredApproval requiredApproval = cfgSnapshot().getRequiredApproval();
    assertThat(requiredApproval).hasLabelNameThat().isEqualTo("Code-Review");
    assertThat(requiredApproval).hasValueThat().isEqualTo(2);
  }

  @Test
  @GerritConfig(name = "plugin.code-owners.requiredApproval", value = "Foo-Bar+1")
  public void cannotGetRequiredApprovalIfNonExistingLabelIsConfiguredAsRequiredApproval()
      throws Exception {
    InvalidPluginConfigurationException exception =
        assertThrows(
            InvalidPluginConfigurationException.class, () -> cfgSnapshot().getRequiredApproval());
    assertThat(exception)
        .hasMessageThat()
        .isEqualTo(
            String.format(
                "Invalid configuration of the code-owners plugin. Required approval 'Foo-Bar+1'"
                    + " that is configured in gerrit.config (parameter"
                    + " plugin.code-owners.requiredApproval) is invalid: Label Foo-Bar doesn't exist"
                    + " for project %s.",
                project.get()));
  }

  @Test
  @GerritConfig(name = "plugin.code-owners.requiredApproval", value = "Code-Review+3")
  public void cannotGetRequiredApprovalIfNonExistingLabelValueIsConfiguredAsRequiredApproval()
      throws Exception {
    InvalidPluginConfigurationException exception =
        assertThrows(
            InvalidPluginConfigurationException.class, () -> cfgSnapshot().getRequiredApproval());
    assertThat(exception)
        .hasMessageThat()
        .isEqualTo(
            String.format(
                "Invalid configuration of the code-owners plugin. Required approval"
                    + " 'Code-Review+3' that is configured in gerrit.config (parameter"
                    + " plugin.code-owners.requiredApproval) is invalid: Label Code-Review on"
                    + " project %s doesn't allow value 3.",
                project.get()));
  }

  @Test
  @GerritConfig(name = "plugin.code-owners.requiredApproval", value = "INVALID")
  public void cannotGetRequiredApprovalIfInvalidRequiredApprovalIsConfigured() throws Exception {
    InvalidPluginConfigurationException exception =
        assertThrows(
            InvalidPluginConfigurationException.class, () -> cfgSnapshot().getRequiredApproval());
    assertThat(exception)
        .hasMessageThat()
        .isEqualTo(
            "Invalid configuration of the code-owners plugin. Required approval 'INVALID' that is"
                + " configured in gerrit.config (parameter plugin.code-owners.requiredApproval) is"
                + " invalid: Invalid format, expected '<label-name>+<label-value>'.");
  }

  @Test
  public void getRequiredApprovalConfiguredOnProjectLevel() throws Exception {
    configureRequiredApproval(project, "Code-Review+2");
    RequiredApproval requiredApproval = cfgSnapshot().getRequiredApproval();
    assertThat(requiredApproval).hasLabelNameThat().isEqualTo("Code-Review");
    assertThat(requiredApproval).hasValueThat().isEqualTo(2);
  }

  @Test
  public void getRequiredApprovalMultipleConfiguredOnProjectLevel() throws Exception {
    setCodeOwnersConfig(
        project,
        /* subsection= */ null,
        RequiredApprovalConfig.KEY_REQUIRED_APPROVAL,
        ImmutableList.of("Code-Review+2", "Code-Review+1"));

    // If multiple values are set for a key, the last value wins.
    RequiredApproval requiredApproval = cfgSnapshot().getRequiredApproval();
    assertThat(requiredApproval).hasLabelNameThat().isEqualTo("Code-Review");
    assertThat(requiredApproval).hasValueThat().isEqualTo(1);
  }

  @Test
  @GerritConfig(name = "plugin.code-owners.requiredApproval", value = "Code-Review+1")
  public void requiredApprovalConfiguredOnProjectLevelOverridesGloballyConfiguredRequiredApproval()
      throws Exception {
    configureRequiredApproval(project, "Code-Review+2");
    RequiredApproval requiredApproval = cfgSnapshot().getRequiredApproval();
    assertThat(requiredApproval).hasLabelNameThat().isEqualTo("Code-Review");
    assertThat(requiredApproval).hasValueThat().isEqualTo(2);
  }

  @Test
  public void requiredApprovalIsInheritedFromParentProject() throws Exception {
    configureRequiredApproval(allProjects, "Code-Review+2");
    RequiredApproval requiredApproval = cfgSnapshot().getRequiredApproval();
    assertThat(requiredApproval).hasLabelNameThat().isEqualTo("Code-Review");
    assertThat(requiredApproval).hasValueThat().isEqualTo(2);
  }

  @Test
  @GerritConfig(name = "plugin.code-owners.requiredApproval", value = "Code-Review+1")
  public void inheritedRequiredApprovalOverridesGloballyConfiguredRequiredApproval()
      throws Exception {
    configureRequiredApproval(allProjects, "Code-Review+2");
    RequiredApproval requiredApproval = cfgSnapshot().getRequiredApproval();
    assertThat(requiredApproval).hasLabelNameThat().isEqualTo("Code-Review");
    assertThat(requiredApproval).hasValueThat().isEqualTo(2);
  }

  @Test
  public void projectLevelRequiredApprovalOverridesInheritedRequiredApproval() throws Exception {
    configureRequiredApproval(allProjects, "Code-Review+1");
    configureRequiredApproval(project, "Code-Review+2");
    RequiredApproval requiredApproval = cfgSnapshot().getRequiredApproval();
    assertThat(requiredApproval).hasLabelNameThat().isEqualTo("Code-Review");
    assertThat(requiredApproval).hasValueThat().isEqualTo(2);
  }

  @Test
  public void
      cannotGetRequiredApprovalIfNonExistingLabelIsConfiguredAsRequiredApprovalOnProjectLevel()
          throws Exception {
    configureRequiredApproval(project, "Foo-Bar+1");
    InvalidPluginConfigurationException exception =
        assertThrows(
            InvalidPluginConfigurationException.class, () -> cfgSnapshot().getRequiredApproval());
    assertThat(exception)
        .hasMessageThat()
        .isEqualTo(
            String.format(
                "Invalid configuration of the code-owners plugin. Required approval 'Foo-Bar+1'"
                    + " that is configured in code-owners.config (parameter"
                    + " codeOwners.requiredApproval) is invalid: Label Foo-Bar doesn't exist for"
                    + " project %s.",
                project.get()));
  }

  @Test
  public void
      cannotGetRequiredApprovalIfNonExistingLabelValueIsConfiguredAsRequiredApprovalOnProjectLevel()
          throws Exception {
    configureRequiredApproval(project, "Code-Review+3");
    InvalidPluginConfigurationException exception =
        assertThrows(
            InvalidPluginConfigurationException.class, () -> cfgSnapshot().getRequiredApproval());
    assertThat(exception)
        .hasMessageThat()
        .isEqualTo(
            String.format(
                "Invalid configuration of the code-owners plugin. Required approval"
                    + " 'Code-Review+3' that is configured in code-owners.config (parameter"
                    + " codeOwners.requiredApproval) is invalid: Label Code-Review on project %s"
                    + " doesn't allow value 3.",
                project.get()));
  }

  @Test
  public void cannotGetRequiredApprovalIfInvalidRequiredApprovalIsConfiguredOnProjectLevel()
      throws Exception {
    configureRequiredApproval(project, "INVALID");
    InvalidPluginConfigurationException exception =
        assertThrows(
            InvalidPluginConfigurationException.class, () -> cfgSnapshot().getRequiredApproval());
    assertThat(exception)
        .hasMessageThat()
        .isEqualTo(
            "Invalid configuration of the code-owners plugin. Required approval 'INVALID' that is"
                + " configured in code-owners.config (parameter codeOwners.requiredApproval) is"
                + " invalid: Invalid format, expected '<label-name>+<label-value>'.");
  }

  @Test
  public void projectLevelRequiredApprovalForOtherProjectHasNoEffect() throws Exception {
    Project.NameKey otherProject = projectOperations.newProject().create();
    configureRequiredApproval(otherProject, "Code-Review+2");
    RequiredApproval requiredApproval = cfgSnapshot().getRequiredApproval();
    assertThat(requiredApproval).hasLabelNameThat().isEqualTo("Code-Review");
    assertThat(requiredApproval).hasValueThat().isEqualTo(1);
  }

  @Test
  public void getOverrideApprovalWhenNoRequiredApprovalIsConfigured() throws Exception {
    assertThat(cfgSnapshot().getOverrideApprovals()).isEmpty();
  }

  @Test
  @GerritConfig(name = "plugin.code-owners.overrideApproval", value = "Owners-Override+1")
  public void getConfiguredOverrideApproval() throws Exception {
    createOwnersOverrideLabel();
    ImmutableSet<RequiredApproval> requiredApprovals = cfgSnapshot().getOverrideApprovals();
    assertThat(requiredApprovals).hasSize(1);
    assertThat(requiredApprovals).element(0).hasLabelNameThat().isEqualTo("Owners-Override");
    assertThat(requiredApprovals).element(0).hasValueThat().isEqualTo(1);
  }

  @Test
  @GerritConfig(name = "plugin.code-owners.overrideApproval", value = "Foo-Bar+1")
  public void getOverrideApprovalIfNonExistingLabelIsConfiguredAsOverrideApproval()
      throws Exception {
    assertThat(cfgSnapshot().getOverrideApprovals()).isEmpty();
  }

  @Test
  @GerritConfig(name = "plugin.code-owners.overrideApproval", value = "Code-Review+3")
  public void getOverrideApprovalIfNonExistingLabelValueIsConfiguredAsOverrideApproval()
      throws Exception {
    assertThat(cfgSnapshot().getOverrideApprovals()).isEmpty();
  }

  @Test
  @GerritConfig(name = "plugin.code-owners.overrideApproval", value = "INVALID")
  public void getOverrideApprovalIfInvalidOverrideApprovalIsConfigured() throws Exception {
    assertThat(cfgSnapshot().getOverrideApprovals()).isEmpty();
  }

  @Test
  public void getOverrideApprovalConfiguredOnProjectLevel() throws Exception {
    createOwnersOverrideLabel();
    configureOverrideApproval(project, "Owners-Override+1");
    ImmutableSet<RequiredApproval> requiredApprovals = cfgSnapshot().getOverrideApprovals();
    assertThat(requiredApprovals).hasSize(1);
    assertThat(requiredApprovals).element(0).hasLabelNameThat().isEqualTo("Owners-Override");
    assertThat(requiredApprovals).element(0).hasValueThat().isEqualTo(1);
  }

  @Test
  public void getOverrideApprovalMultipleConfiguredOnProjectLevel() throws Exception {
    createOwnersOverrideLabel();
    createOwnersOverrideLabel("Other-Override");

    setCodeOwnersConfig(
        project,
        /* subsection= */ null,
        OverrideApprovalConfig.KEY_OVERRIDE_APPROVAL,
        ImmutableList.of("Owners-Override+1", "Other-Override+1"));

    ImmutableSet<RequiredApproval> requiredApprovals = cfgSnapshot().getOverrideApprovals();
    assertThat(
            requiredApprovals.stream()
                .map(requiredApproval -> requiredApproval.toString())
                .collect(toImmutableSet()))
        .containsExactly("Owners-Override+1", "Other-Override+1");
  }

  @Test
  @GerritConfig(name = "plugin.code-owners.overrideApproval", value = "Owners-Override+1")
  public void overrideApprovalConfiguredOnProjectLevelExtendsGloballyConfiguredOverrideApproval()
      throws Exception {
    createOwnersOverrideLabel();
    createOwnersOverrideLabel("Other-Override");

    configureOverrideApproval(project, "Other-Override+1");
    ImmutableSet<RequiredApproval> requiredApprovals = cfgSnapshot().getOverrideApprovals();
    assertThat(requiredApprovals).hasSize(2);
    assertThat(requiredApprovals).element(0).hasLabelNameThat().isEqualTo("Owners-Override");
    assertThat(requiredApprovals).element(0).hasValueThat().isEqualTo(1);
    assertThat(requiredApprovals).element(1).hasLabelNameThat().isEqualTo("Other-Override");
    assertThat(requiredApprovals).element(1).hasValueThat().isEqualTo(1);
  }

  @Test
  @GerritConfig(name = "plugin.code-owners.overrideApproval", value = "Owners-Override+1")
  public void
      overrideApprovalConfiguredOnProjectLevelExtendsGloballyConfiguredOverrideApproval_duplicatesAreFilteredOut()
          throws Exception {
    createOwnersOverrideLabel();

    configureOverrideApproval(project, "Owners-Override+1");
    ImmutableSet<RequiredApproval> requiredApprovals = cfgSnapshot().getOverrideApprovals();
    assertThat(requiredApprovals).hasSize(1);
    assertThat(requiredApprovals).element(0).hasLabelNameThat().isEqualTo("Owners-Override");
    assertThat(requiredApprovals).element(0).hasValueThat().isEqualTo(1);
  }

  @Test
  public void overrideApprovalIsInheritedFromParentProject() throws Exception {
    createOwnersOverrideLabel();

    configureOverrideApproval(allProjects, "Owners-Override+1");
    ImmutableSet<RequiredApproval> requiredApprovals = cfgSnapshot().getOverrideApprovals();
    assertThat(requiredApprovals).hasSize(1);
    assertThat(requiredApprovals).element(0).hasLabelNameThat().isEqualTo("Owners-Override");
    assertThat(requiredApprovals).element(0).hasValueThat().isEqualTo(1);
  }

  @Test
  @GerritConfig(name = "plugin.code-owners.overrideApproval", value = "Owners-Override+1")
  public void inheritedOverrideApprovalExtendsGloballyConfiguredOverrideApproval()
      throws Exception {
    createOwnersOverrideLabel();
    createOwnersOverrideLabel("Other-Override");

    configureOverrideApproval(allProjects, "Other-Override+1");
    ImmutableSet<RequiredApproval> requiredApprovals = cfgSnapshot().getOverrideApprovals();
    assertThat(requiredApprovals).hasSize(2);
    assertThat(requiredApprovals).element(0).hasLabelNameThat().isEqualTo("Owners-Override");
    assertThat(requiredApprovals).element(0).hasValueThat().isEqualTo(1);
    assertThat(requiredApprovals).element(1).hasLabelNameThat().isEqualTo("Other-Override");
    assertThat(requiredApprovals).element(1).hasValueThat().isEqualTo(1);
  }

  @Test
  @GerritConfig(name = "plugin.code-owners.overrideApproval", value = "Owners-Override+1")
  public void
      inheritedOverrideApprovalExtendsGloballyConfiguredOverrideApproval_duplicatesAreFilteredOut()
          throws Exception {
    createOwnersOverrideLabel();

    configureOverrideApproval(allProjects, "Owners-Override+1");
    ImmutableSet<RequiredApproval> requiredApprovals = cfgSnapshot().getOverrideApprovals();
    assertThat(requiredApprovals).hasSize(1);
    assertThat(requiredApprovals).element(0).hasLabelNameThat().isEqualTo("Owners-Override");
    assertThat(requiredApprovals).element(0).hasValueThat().isEqualTo(1);
  }

  @Test
  public void projectLevelOverrideApprovalExtendsInheritedOverrideApproval() throws Exception {
    createOwnersOverrideLabel();
    createOwnersOverrideLabel("Other-Override");

    configureOverrideApproval(allProjects, "Owners-Override+1");
    configureOverrideApproval(project, "Other-Override+1");
    ImmutableSet<RequiredApproval> requiredApprovals = cfgSnapshot().getOverrideApprovals();
    assertThat(requiredApprovals).hasSize(2);
    assertThat(requiredApprovals).element(0).hasLabelNameThat().isEqualTo("Owners-Override");
    assertThat(requiredApprovals).element(0).hasValueThat().isEqualTo(1);
    assertThat(requiredApprovals).element(1).hasLabelNameThat().isEqualTo("Other-Override");
    assertThat(requiredApprovals).element(1).hasValueThat().isEqualTo(1);
  }

  @Test
  public void
      projectLevelOverrideApprovalExtendsInheritedOverrideApproval_duplicatesAreFilteredOut()
          throws Exception {
    createOwnersOverrideLabel();

    configureOverrideApproval(allProjects, "Owners-Override+1");
    configureOverrideApproval(project, "Owners-Override+1");
    ImmutableSet<RequiredApproval> requiredApprovals = cfgSnapshot().getOverrideApprovals();
    assertThat(requiredApprovals).hasSize(1);
    assertThat(requiredApprovals).element(0).hasLabelNameThat().isEqualTo("Owners-Override");
    assertThat(requiredApprovals).element(0).hasValueThat().isEqualTo(1);
  }

  @Test
  public void projectLevelOverrideApprovalExtendsInheritedOverrideApprovalWithDifferentLabelValue()
      throws Exception {
    LabelDefinitionInput input = new LabelDefinitionInput();
    input.values = ImmutableMap.of("+2", "Super-Override", "+1", "Override", " 0", "No Override");
    gApi.projects().name(project.get()).label("Owners-Override").create(input).get();

    configureOverrideApproval(allProjects, "Owners-Override+1");
    configureOverrideApproval(project, "Owners-Override+2");

    // if the same label is configured multiple times as override approval, only the definition with
    // the lowest value is returned (since all higher values are implicitly considered as overrides
    // as well)
    ImmutableSet<RequiredApproval> requiredApprovals = cfgSnapshot().getOverrideApprovals();
    assertThat(requiredApprovals).hasSize(1);
    assertThat(requiredApprovals).element(0).hasLabelNameThat().isEqualTo("Owners-Override");
    assertThat(requiredApprovals).element(0).hasValueThat().isEqualTo(1);
  }

  @Test
  public void getOverrideApprovalIfNonExistingLabelIsConfiguredAsOverrideApprovalOnProjectLevel()
      throws Exception {
    configureOverrideApproval(project, "Foo-Bar+1");
    assertThat(cfgSnapshot().getOverrideApprovals()).isEmpty();
  }

  @Test
  public void
      getOverrideApprovalIfNonExistingLabelValueIsConfiguredAsOverrideApprovalOnProjectLevel()
          throws Exception {
    createOwnersOverrideLabel();
    configureOverrideApproval(project, "Owners-Override+2");
    assertThat(cfgSnapshot().getOverrideApprovals()).isEmpty();
  }

  @Test
  public void getOverrideApprovalIfInvalidOverrideApprovalIsConfiguredOnProjectLevel()
      throws Exception {
    configureOverrideApproval(project, "INVALID");
    assertThat(cfgSnapshot().getOverrideApprovals()).isEmpty();
  }

  @Test
  public void projectLevelOverrideApprovalForOtherProjectHasNoEffect() throws Exception {
    createOwnersOverrideLabel();
    Project.NameKey otherProject = projectOperations.newProject().create();
    configureOverrideApproval(otherProject, "Owners-Override+1");
    assertThat(cfgSnapshot().getOverrideApprovals()).isEmpty();
  }

  @Test
  public void getOverrideApprovalDuplicatesAreFilteredOut() throws Exception {
    setCodeOwnersConfig(
        project,
        /* subsection= */ null,
        OverrideApprovalConfig.KEY_OVERRIDE_APPROVAL,
        ImmutableList.of("Code-Review+2", "Code-Review+1", "Code-Review+2"));

    // If multiple values are set for a key, the last value wins.
    ImmutableSet<RequiredApproval> requiredApprovals = cfgSnapshot().getOverrideApprovals();
    assertThat(requiredApprovals).hasSize(1);
    assertThat(requiredApprovals).element(0).hasLabelNameThat().isEqualTo("Code-Review");
    assertThat(requiredApprovals).element(0).hasValueThat().isEqualTo(1);
  }

  @Test
  @GerritConfig(name = "plugin.code-owners.enableImplicitApprovals", value = "true")
  public void implicitApprovalsAreDisabledIfRequiredLabelIgnoresSelfApprovals() throws Exception {
    assertThat(cfgSnapshot().areImplicitApprovalsEnabled()).isTrue();

    LabelDefinitionInput input = new LabelDefinitionInput();
    input.ignoreSelfApproval = true;
    gApi.projects().name(allProjects.get()).label("Code-Review").update(input);
    assertThat(cfgSnapshot().areImplicitApprovalsEnabled()).isFalse();
  }

  @Test
  public void cannotGetCodeOwnerConfigValidationPolicyForCommitReceivedForNullBranch()
      throws Exception {
    NullPointerException npe =
        assertThrows(
            NullPointerException.class,
            () ->
                cfgSnapshot()
                    .getCodeOwnerConfigValidationPolicyForCommitReceived(/* branchName= */ null));
    assertThat(npe).hasMessageThat().isEqualTo("branchName");
  }

  @Test
  public void getCodeOwnerConfigValidationPolicyForCommitReceived_notConfigured() throws Exception {
    assertThat(cfgSnapshot().getCodeOwnerConfigValidationPolicyForCommitReceived("master"))
        .isEqualTo(CodeOwnerConfigValidationPolicy.TRUE);
    assertThat(cfgSnapshot().getCodeOwnerConfigValidationPolicyForCommitReceived("non-existing"))
        .isEqualTo(CodeOwnerConfigValidationPolicy.TRUE);
  }

  @Test
  public void getCodeOwnerConfigValidationPolicyForCommitReceived_configuredOnProjectLevel()
      throws Exception {
    configureEnableValidationOnCommitReceived(project, CodeOwnerConfigValidationPolicy.FALSE);
    assertThat(cfgSnapshot().getCodeOwnerConfigValidationPolicyForCommitReceived("master"))
        .isEqualTo(CodeOwnerConfigValidationPolicy.FALSE);
    assertThat(cfgSnapshot().getCodeOwnerConfigValidationPolicyForCommitReceived("non-existing"))
        .isEqualTo(CodeOwnerConfigValidationPolicy.FALSE);
  }

  @Test
  public void getCodeOwnerConfigValidationPolicyForCommitReceived_configuredOnBranchLevel()
      throws Exception {
    configureEnableValidationOnCommitReceivedForBranch(
        project, "refs/heads/master", CodeOwnerConfigValidationPolicy.FALSE);
    assertThat(cfgSnapshot().getCodeOwnerConfigValidationPolicyForCommitReceived("master"))
        .isEqualTo(CodeOwnerConfigValidationPolicy.FALSE);
    assertThat(
            cfgSnapshot().getCodeOwnerConfigValidationPolicyForCommitReceived("refs/heads/master"))
        .isEqualTo(CodeOwnerConfigValidationPolicy.FALSE);
    assertThat(cfgSnapshot().getCodeOwnerConfigValidationPolicyForCommitReceived("foo"))
        .isEqualTo(CodeOwnerConfigValidationPolicy.TRUE);
  }

  @Test
  public void getCodeOwnerConfigValidationPolicyForCommitReceived_branchLevelConfigTakesPrecedence()
      throws Exception {
    updateCodeOwnersConfig(
        project,
        codeOwnersConfig -> {
          codeOwnersConfig.setEnum(
              CodeOwnersPluginConfiguration.SECTION_CODE_OWNERS,
              /* subsection= */ null,
              GeneralConfig.KEY_ENABLE_VALIDATION_ON_COMMIT_RECEIVED,
              CodeOwnerConfigValidationPolicy.DRY_RUN);
          codeOwnersConfig.setEnum(
              GeneralConfig.SECTION_VALIDATION,
              "refs/heads/master",
              GeneralConfig.KEY_ENABLE_VALIDATION_ON_COMMIT_RECEIVED,
              CodeOwnerConfigValidationPolicy.FALSE);
        });
    assertThat(cfgSnapshot().getCodeOwnerConfigValidationPolicyForCommitReceived("master"))
        .isEqualTo(CodeOwnerConfigValidationPolicy.FALSE);
    assertThat(
            cfgSnapshot().getCodeOwnerConfigValidationPolicyForCommitReceived("refs/heads/master"))
        .isEqualTo(CodeOwnerConfigValidationPolicy.FALSE);
    assertThat(cfgSnapshot().getCodeOwnerConfigValidationPolicyForCommitReceived("foo"))
        .isEqualTo(CodeOwnerConfigValidationPolicy.DRY_RUN);
  }

  @Test
  public void
      getCodeOwnerConfigValidationPolicyForCommitReceived_inheritedBranchLevelConfigTakesPrecedence()
          throws Exception {
    configureEnableValidationOnCommitReceivedForBranch(
        allProjects, "refs/heads/master", CodeOwnerConfigValidationPolicy.FALSE);
    configureEnableValidationOnCommitReceived(project, CodeOwnerConfigValidationPolicy.DRY_RUN);
    assertThat(cfgSnapshot().getCodeOwnerConfigValidationPolicyForCommitReceived("master"))
        .isEqualTo(CodeOwnerConfigValidationPolicy.FALSE);
    assertThat(
            cfgSnapshot().getCodeOwnerConfigValidationPolicyForCommitReceived("refs/heads/master"))
        .isEqualTo(CodeOwnerConfigValidationPolicy.FALSE);
    assertThat(cfgSnapshot().getCodeOwnerConfigValidationPolicyForCommitReceived("foo"))
        .isEqualTo(CodeOwnerConfigValidationPolicy.DRY_RUN);
  }

  @Test
  public void
      getCodeOwnerConfigValidationPolicyForCommitReceived_inheritedBranchLevelCanBeOverridden()
          throws Exception {
    configureEnableValidationOnCommitReceivedForBranch(
        allProjects, "refs/heads/master", CodeOwnerConfigValidationPolicy.FALSE);
    configureEnableValidationOnCommitReceivedForBranch(
        project, "refs/heads/master", CodeOwnerConfigValidationPolicy.DRY_RUN);
    assertThat(cfgSnapshot().getCodeOwnerConfigValidationPolicyForCommitReceived("master"))
        .isEqualTo(CodeOwnerConfigValidationPolicy.DRY_RUN);
  }

  @Test
  public void cannotGetCodeOwnerConfigValidationPolicyForSubmitForNullBranch() throws Exception {
    NullPointerException npe =
        assertThrows(
            NullPointerException.class,
            () ->
                cfgSnapshot().getCodeOwnerConfigValidationPolicyForSubmit(/* branchName= */ null));
    assertThat(npe).hasMessageThat().isEqualTo("branchName");
  }

  @Test
  public void getCodeOwnerConfigValidationPolicyForSubmitd_notConfigured() throws Exception {
    assertThat(cfgSnapshot().getCodeOwnerConfigValidationPolicyForSubmit("master"))
        .isEqualTo(CodeOwnerConfigValidationPolicy.FALSE);
    assertThat(cfgSnapshot().getCodeOwnerConfigValidationPolicyForSubmit("non-existing"))
        .isEqualTo(CodeOwnerConfigValidationPolicy.FALSE);
  }

  @Test
  public void getCodeOwnerConfigValidationPolicyForSubmit_configuredOnProjectLevel()
      throws Exception {
    configureEnableValidationOnSubmit(project, CodeOwnerConfigValidationPolicy.TRUE);
    assertThat(cfgSnapshot().getCodeOwnerConfigValidationPolicyForSubmit("master"))
        .isEqualTo(CodeOwnerConfigValidationPolicy.TRUE);
    assertThat(cfgSnapshot().getCodeOwnerConfigValidationPolicyForSubmit("non-existing"))
        .isEqualTo(CodeOwnerConfigValidationPolicy.TRUE);
  }

  @Test
  public void getCodeOwnerConfigValidationPolicyForSubmit_configuredOnBranchLevel()
      throws Exception {
    configureEnableValidationOnSubmitForBranch(
        project, "refs/heads/master", CodeOwnerConfigValidationPolicy.TRUE);
    assertThat(cfgSnapshot().getCodeOwnerConfigValidationPolicyForSubmit("master"))
        .isEqualTo(CodeOwnerConfigValidationPolicy.TRUE);
    assertThat(cfgSnapshot().getCodeOwnerConfigValidationPolicyForSubmit("refs/heads/master"))
        .isEqualTo(CodeOwnerConfigValidationPolicy.TRUE);
    assertThat(cfgSnapshot().getCodeOwnerConfigValidationPolicyForSubmit("foo"))
        .isEqualTo(CodeOwnerConfigValidationPolicy.FALSE);
  }

  @Test
  public void getCodeOwnerConfigValidationPolicyForSubmit_branchLevelConfigTakesPrecedence()
      throws Exception {
    updateCodeOwnersConfig(
        project,
        codeOwnersConfig -> {
          codeOwnersConfig.setEnum(
              CodeOwnersPluginConfiguration.SECTION_CODE_OWNERS,
              /* subsection= */ null,
              GeneralConfig.KEY_ENABLE_VALIDATION_ON_SUBMIT,
              CodeOwnerConfigValidationPolicy.DRY_RUN);
          codeOwnersConfig.setEnum(
              GeneralConfig.SECTION_VALIDATION,
              "refs/heads/master",
              GeneralConfig.KEY_ENABLE_VALIDATION_ON_SUBMIT,
              CodeOwnerConfigValidationPolicy.TRUE);
        });
    assertThat(cfgSnapshot().getCodeOwnerConfigValidationPolicyForSubmit("master"))
        .isEqualTo(CodeOwnerConfigValidationPolicy.TRUE);
    assertThat(cfgSnapshot().getCodeOwnerConfigValidationPolicyForSubmit("refs/heads/master"))
        .isEqualTo(CodeOwnerConfigValidationPolicy.TRUE);
    assertThat(cfgSnapshot().getCodeOwnerConfigValidationPolicyForSubmit("foo"))
        .isEqualTo(CodeOwnerConfigValidationPolicy.DRY_RUN);
  }

  @Test
  public void
      getCodeOwnerConfigValidationPolicyForSubmit_inheritedBranchLevelConfigTakesPrecedence()
          throws Exception {
    configureEnableValidationOnSubmitForBranch(
        allProjects, "refs/heads/master", CodeOwnerConfigValidationPolicy.TRUE);
    configureEnableValidationOnSubmit(project, CodeOwnerConfigValidationPolicy.DRY_RUN);
    assertThat(cfgSnapshot().getCodeOwnerConfigValidationPolicyForSubmit("master"))
        .isEqualTo(CodeOwnerConfigValidationPolicy.TRUE);
    assertThat(cfgSnapshot().getCodeOwnerConfigValidationPolicyForSubmit("refs/heads/master"))
        .isEqualTo(CodeOwnerConfigValidationPolicy.TRUE);
    assertThat(cfgSnapshot().getCodeOwnerConfigValidationPolicyForSubmit("foo"))
        .isEqualTo(CodeOwnerConfigValidationPolicy.DRY_RUN);
  }

  @Test
  public void getCodeOwnerConfigValidationPolicyForSubmit_inheritedBranchLevelCanBeOverridden()
      throws Exception {
    configureEnableValidationOnSubmitForBranch(
        allProjects, "refs/heads/master", CodeOwnerConfigValidationPolicy.TRUE);
    configureEnableValidationOnSubmitForBranch(
        project, "refs/heads/master", CodeOwnerConfigValidationPolicy.DRY_RUN);
    assertThat(cfgSnapshot().getCodeOwnerConfigValidationPolicyForSubmit("master"))
        .isEqualTo(CodeOwnerConfigValidationPolicy.DRY_RUN);
  }

  @Test
  public void cannotGetRejectNonResolvableCodeOwnersForNullBranch() throws Exception {
    NullPointerException npe =
        assertThrows(
            NullPointerException.class,
            () -> cfgSnapshot().rejectNonResolvableCodeOwners(/* branchName= */ null));
    assertThat(npe).hasMessageThat().isEqualTo("branchName");
  }

  @Test
  public void getRejectNonResolvableCodeOwners_notConfigured() throws Exception {
    assertThat(cfgSnapshot().rejectNonResolvableCodeOwners("master")).isTrue();
    assertThat(cfgSnapshot().rejectNonResolvableCodeOwners("non-existing")).isTrue();
  }

  @Test
  public void getRejectNonResolvableCodeOwners_configuredOnProjectLevel() throws Exception {
    configureRejectNonResolvableCodeOwners(project, false);
    assertThat(cfgSnapshot().rejectNonResolvableCodeOwners("master")).isFalse();
    assertThat(cfgSnapshot().rejectNonResolvableCodeOwners("non-existing")).isFalse();
  }

  @Test
  public void getRejectNonResolvableCodeOwners_configuredOnBranchLevel() throws Exception {
    configureRejectNonResolvableCodeOwnersForBranch(project, "refs/heads/master", false);
    assertThat(cfgSnapshot().rejectNonResolvableCodeOwners("master")).isFalse();
    assertThat(cfgSnapshot().rejectNonResolvableCodeOwners("refs/heads/master")).isFalse();
    assertThat(cfgSnapshot().rejectNonResolvableCodeOwners("foo")).isTrue();
  }

  @Test
  public void getRejectNonResolvableCodeOwners_branchLevelConfigTakesPrecedence() throws Exception {
    updateCodeOwnersConfig(
        project,
        codeOwnersConfig -> {
          codeOwnersConfig.setBoolean(
              CodeOwnersPluginConfiguration.SECTION_CODE_OWNERS,
              /* subsection= */ null,
              GeneralConfig.KEY_REJECT_NON_RESOLVABLE_CODE_OWNERS,
              /* value= */ false);
          codeOwnersConfig.setBoolean(
              GeneralConfig.SECTION_VALIDATION,
              "refs/heads/master",
              GeneralConfig.KEY_REJECT_NON_RESOLVABLE_CODE_OWNERS,
              /* value= */ true);
        });
    assertThat(cfgSnapshot().rejectNonResolvableCodeOwners("master")).isTrue();
    assertThat(cfgSnapshot().rejectNonResolvableCodeOwners("refs/heads/master")).isTrue();
    assertThat(cfgSnapshot().rejectNonResolvableCodeOwners("foo")).isFalse();
  }

  @Test
  public void getRejectNonResolvableCodeOwners_inheritedBranchLevelConfigTakesPrecedence()
      throws Exception {
    configureRejectNonResolvableCodeOwnersForBranch(allProjects, "refs/heads/master", true);
    configureRejectNonResolvableCodeOwners(project, false);
    assertThat(cfgSnapshot().rejectNonResolvableCodeOwners("master")).isTrue();
    assertThat(cfgSnapshot().rejectNonResolvableCodeOwners("refs/heads/master")).isTrue();
    assertThat(cfgSnapshot().rejectNonResolvableCodeOwners("foo")).isFalse();
  }

  @Test
  public void getRejectNonResolvableCodeOwners_inheritedBranchLevelCanBeOverridden()
      throws Exception {
    configureRejectNonResolvableCodeOwnersForBranch(allProjects, "refs/heads/master", true);
    configureRejectNonResolvableCodeOwnersForBranch(project, "refs/heads/master", false);
    assertThat(cfgSnapshot().rejectNonResolvableCodeOwners("master")).isFalse();
  }

  @Test
  public void cannotGetRejectNonResolvableImportsForNullBranch() throws Exception {
    NullPointerException npe =
        assertThrows(
            NullPointerException.class,
            () -> cfgSnapshot().rejectNonResolvableImports(/* branchName= */ null));
    assertThat(npe).hasMessageThat().isEqualTo("branchName");
  }

  @Test
  public void getRejectNonResolvableImports_notConfigured() throws Exception {
    assertThat(cfgSnapshot().rejectNonResolvableImports("master")).isTrue();
    assertThat(cfgSnapshot().rejectNonResolvableImports("non-existing")).isTrue();
  }

  @Test
  public void getRejectNonResolvableImports_configuredOnProjectLevel() throws Exception {
    configureRejectNonResolvableImports(project, false);
    assertThat(cfgSnapshot().rejectNonResolvableImports("master")).isFalse();
    assertThat(cfgSnapshot().rejectNonResolvableImports("non-existing")).isFalse();
  }

  @Test
  public void getRejectNonResolvableImports_configuredOnBranchLevel() throws Exception {
    configureRejectNonResolvableImportsForBranch(project, "refs/heads/master", false);
    assertThat(cfgSnapshot().rejectNonResolvableImports("master")).isFalse();
    assertThat(cfgSnapshot().rejectNonResolvableImports("refs/heads/master")).isFalse();
    assertThat(cfgSnapshot().rejectNonResolvableImports("foo")).isTrue();
  }

  @Test
  public void getRejectNonResolvableImports_branchLevelConfigTakesPrecedence() throws Exception {
    updateCodeOwnersConfig(
        project,
        codeOwnersConfig -> {
          codeOwnersConfig.setBoolean(
              CodeOwnersPluginConfiguration.SECTION_CODE_OWNERS,
              /* subsection= */ null,
              GeneralConfig.KEY_REJECT_NON_RESOLVABLE_IMPORTS,
              /* value= */ false);
          codeOwnersConfig.setBoolean(
              GeneralConfig.SECTION_VALIDATION,
              "refs/heads/master",
              GeneralConfig.KEY_REJECT_NON_RESOLVABLE_IMPORTS,
              /* value= */ true);
        });
    assertThat(cfgSnapshot().rejectNonResolvableImports("master")).isTrue();
    assertThat(cfgSnapshot().rejectNonResolvableImports("refs/heads/master")).isTrue();
    assertThat(cfgSnapshot().rejectNonResolvableImports("foo")).isFalse();
  }

  @Test
  public void getRejectNonResolvableImports_inheritedBranchLevelConfigTakesPrecedence()
      throws Exception {
    configureRejectNonResolvableImportsForBranch(allProjects, "refs/heads/master", true);
    configureRejectNonResolvableImports(project, false);
    assertThat(cfgSnapshot().rejectNonResolvableImports("master")).isTrue();
    assertThat(cfgSnapshot().rejectNonResolvableImports("refs/heads/master")).isTrue();
    assertThat(cfgSnapshot().rejectNonResolvableImports("foo")).isFalse();
  }

  @Test
  public void getRejectNonResolvableImports_inheritedBranchLevelCanBeOverridden() throws Exception {
    configureRejectNonResolvableImportsForBranch(allProjects, "refs/heads/master", true);
    configureRejectNonResolvableImportsForBranch(project, "refs/heads/master", false);
    assertThat(cfgSnapshot().rejectNonResolvableImports("master")).isFalse();
  }

  private CodeOwnersPluginConfigSnapshot cfgSnapshot() {
    return codeOwnersPluginConfigSnapshotFactory.create(project);
  }

  private void configureFileExtension(Project.NameKey project, String fileExtension)
      throws Exception {
    setCodeOwnersConfig(
        project, /* subsection= */ null, GeneralConfig.KEY_FILE_EXTENSION, fileExtension);
  }

  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 configureGlobalCodeOwners(Project.NameKey project, String... globalCodeOwners)
      throws Exception {
    setCodeOwnersConfig(
        project,
        /* subsection= */ null,
        GeneralConfig.KEY_GLOBAL_CODE_OWNER,
        ImmutableList.copyOf(globalCodeOwners));
  }

  private void configureExemptedUsers(Project.NameKey project, String... exemptedUsers)
      throws Exception {
    setCodeOwnersConfig(
        project,
        /* subsection= */ null,
        GeneralConfig.KEY_EXEMPTED_USER,
        ImmutableList.copyOf(exemptedUsers));
  }

  private void configureMaxPathsInChangeMessages(
      Project.NameKey project, int maxPathsInChangeMessages) throws Exception {
    setCodeOwnersConfig(
        project,
        /* subsection= */ null,
        GeneralConfig.KEY_MAX_PATHS_IN_CHANGE_MESSAGES,
        Integer.toString(maxPathsInChangeMessages));
  }

  private void configureDisabled(Project.NameKey project, String disabled) throws Exception {
    setCodeOwnersConfig(project, /* subsection= */ null, StatusConfig.KEY_DISABLED, disabled);
  }

  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 requiredApproval)
      throws Exception {
    setCodeOwnersConfig(
        project,
        /* subsection= */ null,
        OverrideApprovalConfig.KEY_OVERRIDE_APPROVAL,
        requiredApproval);
  }

  private void configureEnableValidationOnCommitReceived(
      Project.NameKey project, CodeOwnerConfigValidationPolicy codeOwnerConfigValidationPolicy)
      throws Exception {
    setCodeOwnersConfig(
        project,
        /* subsection= */ null,
        GeneralConfig.KEY_ENABLE_VALIDATION_ON_COMMIT_RECEIVED,
        codeOwnerConfigValidationPolicy.name());
  }

  private void configureEnableValidationOnCommitReceivedForBranch(
      Project.NameKey project,
      String branchSubsection,
      CodeOwnerConfigValidationPolicy codeOwnerConfigValidationPolicy)
      throws Exception {
    updateCodeOwnersConfig(
        project,
        codeOwnersConfig ->
            codeOwnersConfig.setString(
                GeneralConfig.SECTION_VALIDATION,
                branchSubsection,
                GeneralConfig.KEY_ENABLE_VALIDATION_ON_COMMIT_RECEIVED,
                codeOwnerConfigValidationPolicy.name()));
  }

  private void configureEnableValidationOnSubmit(
      Project.NameKey project, CodeOwnerConfigValidationPolicy codeOwnerConfigValidationPolicy)
      throws Exception {
    setCodeOwnersConfig(
        project,
        /* subsection= */ null,
        GeneralConfig.KEY_ENABLE_VALIDATION_ON_SUBMIT,
        codeOwnerConfigValidationPolicy.name());
  }

  private void configureEnableValidationOnSubmitForBranch(
      Project.NameKey project,
      String branchSubsection,
      CodeOwnerConfigValidationPolicy codeOwnerConfigValidationPolicy)
      throws Exception {
    updateCodeOwnersConfig(
        project,
        codeOwnersConfig ->
            codeOwnersConfig.setString(
                GeneralConfig.SECTION_VALIDATION,
                branchSubsection,
                GeneralConfig.KEY_ENABLE_VALIDATION_ON_SUBMIT,
                codeOwnerConfigValidationPolicy.name()));
  }

  private void configureRejectNonResolvableCodeOwners(Project.NameKey project, boolean value)
      throws Exception {
    setCodeOwnersConfig(
        project,
        /* subsection= */ null,
        GeneralConfig.KEY_REJECT_NON_RESOLVABLE_CODE_OWNERS,
        Boolean.toString(value));
  }

  private void configureRejectNonResolvableCodeOwnersForBranch(
      Project.NameKey project, String branchSubsection, boolean value) throws Exception {
    updateCodeOwnersConfig(
        project,
        codeOwnersConfig ->
            codeOwnersConfig.setString(
                GeneralConfig.SECTION_VALIDATION,
                branchSubsection,
                GeneralConfig.KEY_REJECT_NON_RESOLVABLE_CODE_OWNERS,
                Boolean.toString(value)));
  }

  private void configureRejectNonResolvableImports(Project.NameKey project, boolean value)
      throws Exception {
    setCodeOwnersConfig(
        project,
        /* subsection= */ null,
        GeneralConfig.KEY_REJECT_NON_RESOLVABLE_IMPORTS,
        Boolean.toString(value));
  }

  private void configureRejectNonResolvableImportsForBranch(
      Project.NameKey project, String branchSubsection, boolean value) throws Exception {
    updateCodeOwnersConfig(
        project,
        codeOwnersConfig ->
            codeOwnersConfig.setString(
                GeneralConfig.SECTION_VALIDATION,
                branchSubsection,
                GeneralConfig.KEY_REJECT_NON_RESOLVABLE_IMPORTS,
                Boolean.toString(value)));
  }

  private AutoCloseable registerTestBackend() {
    RegistrationHandle registrationHandle =
        ((PrivateInternals_DynamicMapImpl<CodeOwnerBackend>) codeOwnerBackends)
            .put("gerrit", TestCodeOwnerBackend.ID, Providers.of(new TestCodeOwnerBackend()));
    return registrationHandle::remove;
  }

  private static class TestCodeOwnerBackend implements CodeOwnerBackend {
    static final String ID = "test-backend";

    @Override
    public Optional<CodeOwnerConfig> getCodeOwnerConfig(
        CodeOwnerConfig.Key codeOwnerConfigKey,
        @Nullable RevWalk revWalk,
        @Nullable ObjectId revision) {
      throw new UnsupportedOperationException("not implemented");
    }

    @Override
    public Optional<CodeOwnerConfig> upsertCodeOwnerConfig(
        CodeOwnerConfig.Key codeOwnerConfigKey,
        CodeOwnerConfigUpdate codeOwnerConfigUpdate,
        @Nullable IdentifiedUser currentUser) {
      throw new UnsupportedOperationException("not implemented");
    }

    @Override
    public boolean isCodeOwnerConfigFile(NameKey project, String fileName) {
      throw new UnsupportedOperationException("not implemented");
    }

    @Override
    public Path getFilePath(CodeOwnerConfig.Key codeOwnerConfigKey) {
      throw new UnsupportedOperationException("not implemented");
    }

    @Override
    public Optional<PathExpressionMatcher> getPathExpressionMatcher() {
      return Optional.empty();
    }
  }
}
