Add method to test API to retrieve raw file content of code owner config

Signed-off-by: Edwin Kempin <ekempin@google.com>
Change-Id: Id885bde0f9f74ac2dd7b7b5ea672e232aee83ba9
diff --git a/java/com/google/gerrit/plugins/codeowners/acceptance/testsuite/CodeOwnerConfigOperations.java b/java/com/google/gerrit/plugins/codeowners/acceptance/testsuite/CodeOwnerConfigOperations.java
index 4d7f536..d98c735 100644
--- a/java/com/google/gerrit/plugins/codeowners/acceptance/testsuite/CodeOwnerConfigOperations.java
+++ b/java/com/google/gerrit/plugins/codeowners/acceptance/testsuite/CodeOwnerConfigOperations.java
@@ -110,6 +110,16 @@
     String getFilePath();
 
     /**
+     * Retrieves the raw file content of the code owner config.
+     *
+     * <p><strong>Note:</strong> This call will fail with an {@link IllegalStateException} if the
+     * requested code owner config doesn't exist.
+     *
+     * @return the raw file content of the code owner config
+     */
+    String getContent() throws Exception;
+
+    /**
      * Starts the fluent chain to update a code owner config. The returned builder can be used to
      * specify how the attributes of the code owner config should be modified. To update the code
      * owner config for real, {@link TestCodeOwnerConfigUpdate.Builder#update()} must be called.
diff --git a/java/com/google/gerrit/plugins/codeowners/acceptance/testsuite/CodeOwnerConfigOperationsImpl.java b/java/com/google/gerrit/plugins/codeowners/acceptance/testsuite/CodeOwnerConfigOperationsImpl.java
index 1e98136..8462d52 100644
--- a/java/com/google/gerrit/plugins/codeowners/acceptance/testsuite/CodeOwnerConfigOperationsImpl.java
+++ b/java/com/google/gerrit/plugins/codeowners/acceptance/testsuite/CodeOwnerConfigOperationsImpl.java
@@ -25,11 +25,20 @@
 import com.google.gerrit.plugins.codeowners.backend.CodeOwnersUpdate;
 import com.google.gerrit.plugins.codeowners.config.BackendConfig;
 import com.google.gerrit.server.ServerInitiated;
+import com.google.gerrit.server.git.GitRepositoryManager;
 import com.google.gerrit.server.project.ProjectCache;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
 import java.nio.file.Path;
 import java.util.Optional;
+import org.eclipse.jgit.errors.RepositoryNotFoundException;
+import org.eclipse.jgit.junit.TestRepository;
+import org.eclipse.jgit.lib.Ref;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.revwalk.RevObject;
+import org.eclipse.jgit.treewalk.TreeWalk;
+import org.eclipse.jgit.util.RawParseUtils;
 
 /**
  * The implementation of {@link CodeOwnerConfigOperations}.
@@ -38,6 +47,7 @@
  * the separation between interface and implementation to enhance clarity.
  */
 public class CodeOwnerConfigOperationsImpl implements CodeOwnerConfigOperations {
+  private final GitRepositoryManager repoManager;
   private final CodeOwners codeOwners;
   private final Provider<CodeOwnersUpdate> codeOwnersUpdate;
   private final ProjectCache projectCache;
@@ -45,10 +55,12 @@
 
   @Inject
   CodeOwnerConfigOperationsImpl(
+      GitRepositoryManager repoManager,
       CodeOwners codeOwners,
       @ServerInitiated Provider<CodeOwnersUpdate> codeOwnersUpdate,
       ProjectCache projectCache,
       BackendConfig backendConfig) {
+    this.repoManager = repoManager;
     this.codeOwners = codeOwners;
     this.codeOwnersUpdate = codeOwnersUpdate;
     this.projectCache = projectCache;
@@ -145,6 +157,33 @@
     }
 
     @Override
+    public String getContent() throws Exception {
+      try (TestRepository<Repository> testRepo =
+          new TestRepository<>(repoManager.openRepository(codeOwnerConfigKey.project()))) {
+        Ref ref = testRepo.getRepository().exactRef(codeOwnerConfigKey.ref());
+        if (ref == null) {
+          throw new IllegalStateException(
+              String.format("code owner config %s does not exist", codeOwnerConfigKey));
+        }
+        RevCommit commit = testRepo.getRevWalk().parseCommit(ref.getObjectId());
+        try (TreeWalk tw =
+            TreeWalk.forPath(
+                testRepo.getRevWalk().getObjectReader(), getJGitFilePath(), commit.getTree())) {
+          if (tw == null) {
+            throw new IllegalStateException(
+                String.format("code owner config %s does not exist", codeOwnerConfigKey));
+          }
+        }
+        RevObject blob = testRepo.get(commit.getTree(), getJGitFilePath());
+        byte[] data = testRepo.getRepository().open(blob).getCachedBytes(Integer.MAX_VALUE);
+        return RawParseUtils.decode(data);
+      } catch (RepositoryNotFoundException e) {
+        throw new IllegalStateException(
+            String.format("code owner config %s does not exist", codeOwnerConfigKey));
+      }
+    }
+
+    @Override
     public TestCodeOwnerConfigUpdate.Builder forUpdate() {
       return TestCodeOwnerConfigUpdate.builder(this::updateCodeOwnerConfig);
     }
diff --git a/javatests/com/google/gerrit/plugins/codeowners/acceptance/testsuite/CodeOwnerConfigOperationsImplTest.java b/javatests/com/google/gerrit/plugins/codeowners/acceptance/testsuite/CodeOwnerConfigOperationsImplTest.java
index 542fc3d..c0e9040 100644
--- a/javatests/com/google/gerrit/plugins/codeowners/acceptance/testsuite/CodeOwnerConfigOperationsImplTest.java
+++ b/javatests/com/google/gerrit/plugins/codeowners/acceptance/testsuite/CodeOwnerConfigOperationsImplTest.java
@@ -639,6 +639,58 @@
         .isEqualTo("/foo/OWNERS");
   }
 
+  @Test
+  public void getContent() throws Exception {
+    CodeOwnerConfig.Key codeOwnerConfigKey =
+        codeOwnerConfigOperations
+            .newCodeOwnerConfig()
+            .project(project)
+            .branch("master")
+            .folderPath("/foo/")
+            .addCodeOwnerEmail(admin.email())
+            .create();
+    assertThat(codeOwnerConfigOperations.codeOwnerConfig(codeOwnerConfigKey).getContent())
+        .isEqualTo(admin.email() + "\n");
+  }
+
+  @Test
+  public void getContent_nonExistingCodeOwnerConfig() throws Exception {
+    CodeOwnerConfig.Key codeOwnerConfigKey = CodeOwnerConfig.Key.create(project, "master", "/foo/");
+    IllegalStateException exception =
+        assertThrows(
+            IllegalStateException.class,
+            () -> codeOwnerConfigOperations.codeOwnerConfig(codeOwnerConfigKey).getContent());
+    assertThat(exception)
+        .hasMessageThat()
+        .isEqualTo(String.format("code owner config %s does not exist", codeOwnerConfigKey));
+  }
+
+  @Test
+  public void getContent_nonExistingBranch() throws Exception {
+    CodeOwnerConfig.Key codeOwnerConfigKey =
+        CodeOwnerConfig.Key.create(project, "non-existing", "/foo/");
+    IllegalStateException exception =
+        assertThrows(
+            IllegalStateException.class,
+            () -> codeOwnerConfigOperations.codeOwnerConfig(codeOwnerConfigKey).getContent());
+    assertThat(exception)
+        .hasMessageThat()
+        .isEqualTo(String.format("code owner config %s does not exist", codeOwnerConfigKey));
+  }
+
+  @Test
+  public void getContent_nonExistingProject() throws Exception {
+    CodeOwnerConfig.Key codeOwnerConfigKey =
+        CodeOwnerConfig.Key.create(Project.nameKey("non-existing"), "master", "/foo/");
+    IllegalStateException exception =
+        assertThrows(
+            IllegalStateException.class,
+            () -> codeOwnerConfigOperations.codeOwnerConfig(codeOwnerConfigKey).getContent());
+    assertThat(exception)
+        .hasMessageThat()
+        .isEqualTo(String.format("code owner config %s does not exist", codeOwnerConfigKey));
+  }
+
   private CodeOwnerConfig getCodeOwnerConfigFromServer(CodeOwnerConfig.Key codeOwnerConfigKey) {
     return codeOwners
         .getFromCurrentRevision(codeOwnerConfigKey)