// 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.backend;

import static com.google.common.truth.Truth.assertThat;
import static com.google.gerrit.plugins.codeowners.testing.CodeOwnerSubject.assertThat;
import static com.google.gerrit.plugins.codeowners.testing.OptionalResultWithMessagesSubject.assertThat;
import static com.google.gerrit.testing.GerritJUnit.assertThrows;

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.account.AccountOperations;
import com.google.gerrit.acceptance.testsuite.request.RequestScopeOperations;
import com.google.gerrit.entities.Account;
import com.google.gerrit.plugins.codeowners.acceptance.AbstractCodeOwnersTest;
import com.google.gerrit.server.ServerInitiated;
import com.google.gerrit.server.account.AccountsUpdate;
import com.google.gerrit.server.account.externalids.ExternalId;
import com.google.gerrit.server.account.externalids.ExternalIdNotes;
import com.google.gerrit.server.git.meta.MetaDataUpdate;
import com.google.inject.Inject;
import com.google.inject.Key;
import com.google.inject.Provider;
import java.nio.file.Paths;
import java.util.Optional;
import java.util.Set;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Repository;
import org.junit.Before;
import org.junit.Test;

/** Tests for {@link CodeOwnerResolver}. */
public class CodeOwnerResolverTest extends AbstractCodeOwnersTest {
  private static final ObjectId TEST_REVISION =
      ObjectId.fromString("deadbeefdeadbeefdeadbeefdeadbeefdeadbeef");

  @Inject private RequestScopeOperations requestScopeOperations;
  @Inject @ServerInitiated private Provider<AccountsUpdate> accountsUpdate;
  @Inject private AccountOperations accountOperations;
  @Inject private ExternalIdNotes.Factory externalIdNotesFactory;

  private Provider<CodeOwnerResolver> codeOwnerResolver;

  @Before
  public void setUpCodeOwnersPlugin() throws Exception {
    codeOwnerResolver =
        plugin.getSysInjector().getInstance(new Key<Provider<CodeOwnerResolver>>() {});
  }

  @Test
  public void cannotResolveNullToCodeOwner() throws Exception {
    NullPointerException npe =
        assertThrows(
            NullPointerException.class,
            () ->
                codeOwnerResolver
                    .get()
                    .resolve(/* codeOwnerReference= */ (CodeOwnerReference) null));
    assertThat(npe).hasMessageThat().isEqualTo("codeOwnerReference");

    npe =
        assertThrows(
            NullPointerException.class,
            () ->
                codeOwnerResolver
                    .get()
                    .resolve(/* codeOwnerReferences= */ (Set<CodeOwnerReference>) null));
    assertThat(npe).hasMessageThat().isEqualTo("codeOwnerReferences");
  }

  @Test
  public void resolveCodeOwnerReferenceForNonExistingEmail() throws Exception {
    String nonExistingEmail = "non-existing@example.com";
    OptionalResultWithMessages<CodeOwner> result =
        codeOwnerResolver.get().resolveWithMessages(CodeOwnerReference.create(nonExistingEmail));
    assertThat(result).isEmpty();
    assertThat(result)
        .hasMessagesThat()
        .contains(
            String.format(
                "cannot resolve code owner email %s: no account with this email exists",
                nonExistingEmail));
  }

  @Test
  public void resolveCodeOwnerReferenceForEmail() throws Exception {
    OptionalResultWithMessages<CodeOwner> result =
        codeOwnerResolver.get().resolveWithMessages(CodeOwnerReference.create(admin.email()));
    assertThat(result.get()).hasAccountIdThat().isEqualTo(admin.id());
    assertThat(result)
        .hasMessagesThat()
        .contains(String.format("account %s is visible to user %s", admin.id(), admin.username()));
  }

  @Test
  public void cannotResolveCodeOwnerReferenceForStarAsEmail() throws Exception {
    OptionalResultWithMessages<CodeOwner> result =
        codeOwnerResolver
            .get()
            .resolveWithMessages(CodeOwnerReference.create(CodeOwnerResolver.ALL_USERS_WILDCARD));
    assertThat(result).isEmpty();
    assertThat(result)
        .hasMessagesThat()
        .contains(
            String.format(
                "cannot resolve code owner email %s: no account with this email exists",
                CodeOwnerResolver.ALL_USERS_WILDCARD));
  }

  @Test
  public void resolveCodeOwnerReferenceForAmbiguousEmailIfOtherAccountIsInactive()
      throws Exception {
    // Create an external ID for 'user' account that has the same email as the 'admin' account.
    accountsUpdate
        .get()
        .update(
            "Test update",
            user.id(),
            (a, u) ->
                u.addExternalId(
                    ExternalId.create(
                        "foo", "bar", user.id(), admin.email(), /* hashedPassword= */ null)));

    // Deactivate the 'user' account.
    accountOperations.account(user.id()).forUpdate().inactive().update();

    OptionalResultWithMessages<CodeOwner> result =
        codeOwnerResolver.get().resolveWithMessages(CodeOwnerReference.create(admin.email()));
    assertThat(result.get()).hasAccountIdThat().isEqualTo(admin.id());
  }

  @Test
  public void resolveCodeOwnerReferenceForAmbiguousEmail() throws Exception {
    // Create an external ID for 'user' account that has the same email as the 'admin' account.
    accountsUpdate
        .get()
        .update(
            "Test update",
            user.id(),
            (a, u) ->
                u.addExternalId(
                    ExternalId.create(
                        "foo", "bar", user.id(), admin.email(), /* hashedPassword= */ null)));

    OptionalResultWithMessages<CodeOwner> result =
        codeOwnerResolver.get().resolveWithMessages(CodeOwnerReference.create(admin.email()));
    assertThat(result).isEmpty();
    assertThat(result)
        .hasMessagesThat()
        .contains(
            String.format("cannot resolve code owner email %s: email is ambiguous", admin.email()));
  }

  @Test
  public void resolveCodeOwnerReferenceForOrphanedEmail() throws Exception {
    // Create an external ID with an email for a non-existing account.
    String email = "foo.bar@example.com";
    Account.Id accountId = Account.id(999999);
    try (Repository allUsersRepo = repoManager.openRepository(allUsers);
        MetaDataUpdate md = metaDataUpdateFactory.create(allUsers)) {
      ExternalIdNotes extIdNotes = externalIdNotesFactory.load(allUsersRepo);
      extIdNotes.upsert(ExternalId.createEmail(accountId, email));
      extIdNotes.commit(md);
    }

    OptionalResultWithMessages<CodeOwner> result =
        codeOwnerResolver.get().resolveWithMessages(CodeOwnerReference.create(email));
    assertThat(result).isEmpty();
    assertThat(result)
        .hasMessagesThat()
        .containsAnyOf(
            String.format(
                "cannot resolve account %s for email %s: account does not exists",
                accountId, email),
            String.format(
                "cannost resolve code owner email %s: no active account with this email found",
                email));
  }

  @Test
  public void resolveCodeOwnerReferenceForInactiveUser() throws Exception {
    accountOperations.account(user.id()).forUpdate().inactive().update();
    OptionalResultWithMessages<CodeOwner> result =
        codeOwnerResolver.get().resolveWithMessages(CodeOwnerReference.create(user.email()));
    assertThat(result).isEmpty();
    assertThat(result)
        .hasMessagesThat()
        .contains(
            String.format("ignoring inactive account %s for email %s", user.id(), user.email()));
  }

  @Test
  @GerritConfig(name = "accounts.visibility", value = "SAME_GROUP")
  public void resolveCodeOwnerReferenceForNonVisibleAccount() throws Exception {
    TestAccount user2 = accountCreator.user2();

    // Set user2 as current user.
    requestScopeOperations.setApiUser(user2.id());

    // user2 cannot see the admin account since they do not share any group and
    // "accounts.visibility" is set to "SAME_GROUP".
    OptionalResultWithMessages<CodeOwner> result =
        codeOwnerResolver.get().resolveWithMessages(CodeOwnerReference.create(admin.email()));
    assertThat(result).isEmpty();
    assertThat(result)
        .hasMessagesThat()
        .contains(
            String.format(
                "cannot resolve code owner email %s: account %s is not visible to user %s",
                admin.email(), admin.id(), user2.username()));
  }

  @Test
  public void resolveCodeOwnerReferenceForSecondaryEmail() throws Exception {
    TestAccount user2 = accountCreator.user2();

    // add secondary email to user account
    String secondaryEmail = "user@foo.bar";
    accountOperations.account(user.id()).forUpdate().addSecondaryEmail(secondaryEmail).update();

    // admin has the "Modify Account" global capability and hence can see the secondary email of the
    // user account.
    OptionalResultWithMessages<CodeOwner> result =
        codeOwnerResolver.get().resolveWithMessages(CodeOwnerReference.create(secondaryEmail));
    assertThat(result.get()).hasAccountIdThat().isEqualTo(user.id());
    assertThat(result)
        .hasMessagesThat()
        .contains(
            String.format(
                "resolved code owner email %s: account %s is referenced by secondary email and the calling user %s can see secondary emails",
                secondaryEmail, user.id(), admin.username()));

    // admin has the "Modify Account" global capability and hence can see the secondary email of the
    // user account if another user is the calling user
    requestScopeOperations.setApiUser(user2.id());
    result =
        codeOwnerResolver
            .get()
            .forUser(identifiedUserFactory.create(admin.id()))
            .resolveWithMessages(CodeOwnerReference.create(secondaryEmail));
    assertThat(result.get()).hasAccountIdThat().isEqualTo(user.id());
    assertThat(result)
        .hasMessagesThat()
        .contains(
            String.format(
                "resolved code owner email %s: account %s is referenced by secondary email and user %s can see secondary emails",
                secondaryEmail, user.id(), admin.username()));

    // user can see its own secondary email.
    requestScopeOperations.setApiUser(user.id());
    result = codeOwnerResolver.get().resolveWithMessages(CodeOwnerReference.create(secondaryEmail));
    assertThat(result.get()).hasAccountIdThat().isEqualTo(user.id());
    assertThat(result)
        .hasMessagesThat()
        .contains(
            String.format(
                "email %s is visible to the calling user %s: email is a secondary email that is owned by this user",
                secondaryEmail, user.username()));

    // user can see its own secondary email if another user is the calling user.
    requestScopeOperations.setApiUser(user2.id());
    result =
        codeOwnerResolver
            .get()
            .forUser(identifiedUserFactory.create(user.id()))
            .resolveWithMessages(CodeOwnerReference.create(secondaryEmail));
    assertThat(result.get()).hasAccountIdThat().isEqualTo(user.id());
    assertThat(result)
        .hasMessagesThat()
        .contains(
            String.format(
                "email %s is visible to user %s: email is a secondary email that is owned by this user",
                secondaryEmail, user.username()));
  }

  @Test
  public void resolveCodeOwnerReferenceForNonVisibleSecondaryEmail() throws Exception {
    // add secondary email to admin account
    String secondaryEmail = "admin@foo.bar";
    accountOperations.account(admin.id()).forUpdate().addSecondaryEmail(secondaryEmail).update();

    // user doesn't have the "Modify Account" global capability and hence cannot see the secondary
    // email of the admin account.
    requestScopeOperations.setApiUser(user.id());
    OptionalResultWithMessages<CodeOwner> result =
        codeOwnerResolver.get().resolveWithMessages(CodeOwnerReference.create(secondaryEmail));
    assertThat(result).isEmpty();
    assertThat(result)
        .hasMessagesThat()
        .contains(
            String.format(
                "cannot resolve code owner email %s: account %s is referenced by secondary email but the calling user %s cannot see secondary emails",
                secondaryEmail, admin.id(), user.username()));

    // user doesn't have the "Modify Account" global capability and hence cannot see the secondary
    // email of the admin account if another user is the calling user
    requestScopeOperations.setApiUser(admin.id());
    result =
        codeOwnerResolver
            .get()
            .forUser(identifiedUserFactory.create(user.id()))
            .resolveWithMessages(CodeOwnerReference.create(secondaryEmail));
    assertThat(result).isEmpty();
    assertThat(result)
        .hasMessagesThat()
        .contains(
            String.format(
                "cannot resolve code owner email %s: account %s is referenced by secondary email but user %s cannot see secondary emails",
                secondaryEmail, admin.id(), user.username()));
  }

  @Test
  public void resolvePathCodeOwnersForEmptyCodeOwnerConfig() throws Exception {
    CodeOwnerConfig codeOwnerConfig =
        CodeOwnerConfig.builder(CodeOwnerConfig.Key.create(project, "master", "/"), TEST_REVISION)
            .build();
    CodeOwnerResolverResult result =
        codeOwnerResolver.get().resolvePathCodeOwners(codeOwnerConfig, Paths.get("/README.md"));
    assertThat(result.codeOwners()).isEmpty();
    assertThat(result.ownedByAllUsers()).isFalse();
    assertThat(result.hasUnresolvedCodeOwners()).isFalse();
  }

  @Test
  public void resolvePathCodeOwners() throws Exception {
    CodeOwnerConfig codeOwnerConfig =
        CodeOwnerConfig.builder(CodeOwnerConfig.Key.create(project, "master", "/"), TEST_REVISION)
            .addCodeOwnerSet(CodeOwnerSet.createWithoutPathExpressions(admin.email(), user.email()))
            .build();

    CodeOwnerResolverResult result =
        codeOwnerResolver.get().resolvePathCodeOwners(codeOwnerConfig, Paths.get("/README.md"));
    assertThat(result.codeOwnersAccountIds()).containsExactly(admin.id(), user.id());
    assertThat(result.ownedByAllUsers()).isFalse();
    assertThat(result.hasUnresolvedCodeOwners()).isFalse();
  }

  @Test
  public void resolvePathCodeOwnersWhenStarIsUsedAsEmail() throws Exception {
    CodeOwnerConfig codeOwnerConfig =
        CodeOwnerConfig.builder(CodeOwnerConfig.Key.create(project, "master", "/"), TEST_REVISION)
            .addCodeOwnerSet(
                CodeOwnerSet.createWithoutPathExpressions(CodeOwnerResolver.ALL_USERS_WILDCARD))
            .build();

    CodeOwnerResolverResult result =
        codeOwnerResolver.get().resolvePathCodeOwners(codeOwnerConfig, Paths.get("/README.md"));
    assertThat(result.codeOwnersAccountIds()).isEmpty();
    assertThat(result.ownedByAllUsers()).isTrue();
    assertThat(result.hasUnresolvedCodeOwners()).isFalse();
  }

  @Test
  public void resolvePathCodeOwnersNonResolvableCodeOwnersAreFilteredOut() throws Exception {
    CodeOwnerConfig codeOwnerConfig =
        CodeOwnerConfig.builder(CodeOwnerConfig.Key.create(project, "master", "/"), TEST_REVISION)
            .addCodeOwnerSet(
                CodeOwnerSet.createWithoutPathExpressions(
                    admin.email(), "non-existing@example.com"))
            .build();
    CodeOwnerResolverResult result =
        codeOwnerResolver.get().resolvePathCodeOwners(codeOwnerConfig, Paths.get("/README.md"));
    assertThat(result.codeOwnersAccountIds()).containsExactly(admin.id());
    assertThat(result.ownedByAllUsers()).isFalse();
    assertThat(result.hasUnresolvedCodeOwners()).isTrue();
  }

  @Test
  public void resolvePathCodeOwnersNonResolvableCodeOwnersAreFilteredOutIfOwnedByAllUsers()
      throws Exception {
    CodeOwnerConfig codeOwnerConfig =
        CodeOwnerConfig.builder(CodeOwnerConfig.Key.create(project, "master", "/"), TEST_REVISION)
            .addCodeOwnerSet(
                CodeOwnerSet.createWithoutPathExpressions(
                    "*", admin.email(), "non-existing@example.com"))
            .build();
    CodeOwnerResolverResult result =
        codeOwnerResolver.get().resolvePathCodeOwners(codeOwnerConfig, Paths.get("/README.md"));
    assertThat(result.codeOwnersAccountIds()).containsExactly(admin.id());
    assertThat(result.ownedByAllUsers()).isTrue();
    assertThat(result.hasUnresolvedCodeOwners()).isTrue();
  }

  @Test
  public void cannotResolvePathCodeOwnersOfNullCodeOwnerConfig() throws Exception {
    NullPointerException npe =
        assertThrows(
            NullPointerException.class,
            () ->
                codeOwnerResolver
                    .get()
                    .resolvePathCodeOwners(/* codeOwnerConfig= */ null, Paths.get("/README.md")));
    assertThat(npe).hasMessageThat().isEqualTo("codeOwnerConfig");
  }

  @Test
  public void cannotResolvePathCodeOwnersForNullPath() throws Exception {
    CodeOwnerConfig codeOwnerConfig =
        CodeOwnerConfig.builder(CodeOwnerConfig.Key.create(project, "master", "/"), TEST_REVISION)
            .addCodeOwnerSet(CodeOwnerSet.createWithoutPathExpressions(admin.email()))
            .build();
    NullPointerException npe =
        assertThrows(
            NullPointerException.class,
            () ->
                codeOwnerResolver
                    .get()
                    .resolvePathCodeOwners(codeOwnerConfig, /* absolutePath= */ null));
    assertThat(npe).hasMessageThat().isEqualTo("absolutePath");
  }

  @Test
  public void cannotResolvePathCodeOwnersOfNullPathCodeOwners() throws Exception {
    NullPointerException npe =
        assertThrows(
            NullPointerException.class,
            () -> codeOwnerResolver.get().resolvePathCodeOwners(/* pathCodeOwners= */ null));
    assertThat(npe).hasMessageThat().isEqualTo("pathCodeOwners");
  }

  @Test
  public void cannotResolvePathCodeOwnersForRelativePath() throws Exception {
    String relativePath = "foo/bar.md";
    CodeOwnerConfig codeOwnerConfig =
        CodeOwnerConfig.builder(CodeOwnerConfig.Key.create(project, "master", "/"), TEST_REVISION)
            .addCodeOwnerSet(CodeOwnerSet.createWithoutPathExpressions(admin.email()))
            .build();
    IllegalStateException npe =
        assertThrows(
            IllegalStateException.class,
            () ->
                codeOwnerResolver
                    .get()
                    .resolvePathCodeOwners(codeOwnerConfig, Paths.get(relativePath)));
    assertThat(npe)
        .hasMessageThat()
        .isEqualTo(String.format("path %s must be absolute", relativePath));
  }

  @Test
  @GerritConfig(name = "accounts.visibility", value = "SAME_GROUP")
  public void nonVisibleCodeOwnerCanBeResolvedIfVisibilityIsNotEnforced() throws Exception {
    TestAccount user2 = accountCreator.user2();

    // Set user2 as current user.
    requestScopeOperations.setApiUser(user2.id());

    CodeOwnerReference adminCodeOwnerReference = CodeOwnerReference.create(admin.email());

    // user2 cannot see the admin account since they do not share any group and
    // "accounts.visibility" is set to "SAME_GROUP".
    assertThat(codeOwnerResolver.get().resolve(adminCodeOwnerReference)).isEmpty();

    // if visibility is not enforced the code owner reference can be resolved regardless
    Optional<CodeOwner> codeOwner =
        codeOwnerResolver.get().enforceVisibility(false).resolve(adminCodeOwnerReference);
    assertThat(codeOwner).value().hasAccountIdThat().isEqualTo(admin.id());
  }

  @Test
  @GerritConfig(name = "accounts.visibility", value = "SAME_GROUP")
  public void codeOwnerVisibilityIsCheckedForGivenAccount() throws Exception {
    // Create a new user that is not a member of any group. This means 'user' and 'admin' are not
    // visible to this user since they do not share any group.
    TestAccount user2 = accountCreator.user2();

    // admin is the current user and can see the account
    assertThat(codeOwnerResolver.get().resolve(CodeOwnerReference.create(user.email())))
        .isPresent();
    assertThat(
            codeOwnerResolver
                .get()
                .forUser(identifiedUserFactory.create(admin.id()))
                .resolve(CodeOwnerReference.create(user.email())))
        .isPresent();

    // user2 cannot see the account
    assertThat(
            codeOwnerResolver
                .get()
                .forUser(identifiedUserFactory.create(user2.id()))
                .resolve(CodeOwnerReference.create(user.email())))
        .isEmpty();
  }

  @Test
  @GerritConfig(name = "plugin.code-owners.allowedEmailDomain", value = "example.net")
  public void resolveCodeOwnerReferenceForEmailWithNonAllowedEmailDomain() throws Exception {
    assertThat(codeOwnerResolver.get().resolve(CodeOwnerReference.create("foo@example.com")))
        .isEmpty();
  }

  @Test
  public void isEmailDomainAllowedRequiresEmailToBeNonNull() throws Exception {
    NullPointerException npe =
        assertThrows(
            NullPointerException.class,
            () -> codeOwnerResolver.get().isEmailDomainAllowed(/* email= */ null));
    assertThat(npe).hasMessageThat().isEqualTo("email");
  }

  @Test
  @GerritConfig(
      name = "plugin.code-owners.allowedEmailDomain",
      values = {"example.com", "example.net"})
  public void configuredEmailDomainsAreAllowed() throws Exception {
    assertIsEmailDomainAllowed(
        "foo@example.com", true, "domain example.com of email foo@example.com is allowed");
    assertIsEmailDomainAllowed(
        "foo@example.net", true, "domain example.net of email foo@example.net is allowed");
    assertIsEmailDomainAllowed(
        "foo@example.org@example.com",
        true,
        "domain example.com of email foo@example.org@example.com is allowed");
    assertIsEmailDomainAllowed(
        "foo@example.org", false, "domain example.org of email foo@example.org is not allowed");
    assertIsEmailDomainAllowed("foo", false, "email foo has no domain");
    assertIsEmailDomainAllowed(
        "foo@example.com@example.org",
        false,
        "domain example.org of email foo@example.com@example.org is not allowed");
    assertIsEmailDomainAllowed(
        CodeOwnerResolver.ALL_USERS_WILDCARD, true, "all users wildcard is allowed");
  }

  @Test
  public void allEmailDomainsAreAllowed() throws Exception {
    String expectedMessage = "all domains are allowed";
    assertIsEmailDomainAllowed("foo@example.com", true, expectedMessage);
    assertIsEmailDomainAllowed("foo@example.net", true, expectedMessage);
    assertIsEmailDomainAllowed("foo@example.org@example.com", true, expectedMessage);
    assertIsEmailDomainAllowed("foo@example.org", true, expectedMessage);
    assertIsEmailDomainAllowed("foo", true, expectedMessage);
    assertIsEmailDomainAllowed("foo@example.com@example.org", true, expectedMessage);
    assertIsEmailDomainAllowed(CodeOwnerResolver.ALL_USERS_WILDCARD, true, expectedMessage);
  }

  private void assertIsEmailDomainAllowed(
      String email, boolean expectedResult, String expectedMessage) {
    OptionalResultWithMessages<Boolean> isEmailDomainAllowedResult =
        codeOwnerResolver.get().isEmailDomainAllowed(email);
    assertThat(isEmailDomainAllowedResult.get()).isEqualTo(expectedResult);
    assertThat(isEmailDomainAllowedResult.messages()).containsExactly(expectedMessage);
  }

  @Test
  public void resolveCodeOwnerReferences() throws Exception {
    CodeOwnerResolverResult result =
        codeOwnerResolver
            .get()
            .resolve(
                ImmutableSet.of(
                    CodeOwnerReference.create(admin.email()),
                    CodeOwnerReference.create(user.email())));
    assertThat(result.codeOwnersAccountIds()).containsExactly(admin.id(), user.id());
    assertThat(result.ownedByAllUsers()).isFalse();
    assertThat(result.hasUnresolvedCodeOwners()).isFalse();
  }

  @Test
  public void resolveCodeOwnerReferencesNonResolveableCodeOwnersAreFilteredOut() throws Exception {
    CodeOwnerResolverResult result =
        codeOwnerResolver
            .get()
            .resolve(
                ImmutableSet.of(
                    CodeOwnerReference.create(admin.email()),
                    CodeOwnerReference.create("non-existing@example.com")));
    assertThat(result.codeOwnersAccountIds()).containsExactly(admin.id());
    assertThat(result.ownedByAllUsers()).isFalse();
    assertThat(result.hasUnresolvedCodeOwners()).isTrue();
  }

  @Test
  public void isResolvable() throws Exception {
    assertThat(codeOwnerResolver.get().isResolvable(CodeOwnerReference.create(admin.email())))
        .isTrue();
  }

  @Test
  public void isNotResolvable() throws Exception {
    assertThat(
            codeOwnerResolver.get().isResolvable(CodeOwnerReference.create("unknown@example.com")))
        .isFalse();
  }
}
