Add tests to show that editing more than a single file in a change edit is possible

Interestingly, the code reads as if this would not work when using
POST, but only with PUT. The test shows that it does work (both
with the Java and HTTP REST API when using PUT).

Release-Notes: skip
Change-Id: I80e63454a0849098cf8a5ff12191a5b4c3ab3dac
diff --git a/javatests/com/google/gerrit/acceptance/edit/ChangeEditIT.java b/javatests/com/google/gerrit/acceptance/edit/ChangeEditIT.java
index 6cfb989..9f673c8 100644
--- a/javatests/com/google/gerrit/acceptance/edit/ChangeEditIT.java
+++ b/javatests/com/google/gerrit/acceptance/edit/ChangeEditIT.java
@@ -103,6 +103,7 @@
   private static final String FILE_NAME = "foo";
   private static final String FILE_NAME2 = "foo2";
   private static final String FILE_NAME3 = "foo3";
+  private static final String FILE_NAME4 = "foo4";
   private static final int FILE_MODE = 100644;
   private static final byte[] CONTENT_OLD = "bar".getBytes(UTF_8);
   private static final byte[] CONTENT_NEW = "baz".getBytes(UTF_8);
@@ -348,6 +349,16 @@
   }
 
   @Test
+  public void updateMultipleExistingFiles() throws Exception {
+    createEmptyEditFor(changeId);
+    gApi.changes().id(changeId).edit().modifyFile(FILE_NAME, RawInputUtil.create(CONTENT_NEW));
+    gApi.changes().id(changeId).edit().modifyFile(FILE_NAME2, RawInputUtil.create(CONTENT_NEW));
+    assertThat(getEdit(changeId)).isPresent();
+    ensureSameBytes(getFileContentOfEdit(changeId, FILE_NAME), CONTENT_NEW);
+    ensureSameBytes(getFileContentOfEdit(changeId, FILE_NAME2), CONTENT_NEW);
+  }
+
+  @Test
   public void updateExistingFileAfterUpdatingPreferredEmail() throws Exception {
     String emailOne = "email1@example.com";
     Account.Id testUser = accountOperations.newAccount().preferredEmail(emailOne).create();
@@ -1182,6 +1193,41 @@
   }
 
   @Test
+  public void addMultipleNewFiles() throws Exception {
+    createEmptyEditFor(changeId);
+    Optional<EditInfo> originalEdit =
+        gApi.changes()
+            .id(changeId)
+            .edit()
+            .detail()
+            .withOption(ChangeEditDetailOption.LIST_FILES)
+            .get();
+    assertThat(originalEdit)
+        .value()
+        .files()
+        .keys()
+        .containsExactly(COMMIT_MSG, FILE_NAME, FILE_NAME2);
+
+    gApi.changes().id(changeId).edit().modifyFile(FILE_NAME3, RawInputUtil.create(CONTENT_NEW));
+    ensureSameBytes(getFileContentOfEdit(changeId, FILE_NAME3), CONTENT_NEW);
+    gApi.changes().id(changeId).edit().modifyFile(FILE_NAME4, RawInputUtil.create(CONTENT_NEW));
+    ensureSameBytes(getFileContentOfEdit(changeId, FILE_NAME4), CONTENT_NEW);
+
+    Optional<EditInfo> adjustedEdit =
+        gApi.changes()
+            .id(changeId)
+            .edit()
+            .detail()
+            .withOption(ChangeEditDetailOption.LIST_FILES)
+            .get();
+    assertThat(adjustedEdit)
+        .value()
+        .files()
+        .keys()
+        .containsExactly(COMMIT_MSG, FILE_NAME, FILE_NAME2, FILE_NAME3, FILE_NAME4);
+  }
+
+  @Test
   public void addNewFileAndAmend() throws Exception {
     createEmptyEditFor(changeId);
     gApi.changes().id(changeId).edit().modifyFile(FILE_NAME3, RawInputUtil.create(CONTENT_NEW));
diff --git a/javatests/com/google/gerrit/acceptance/rest/change/ChangeEditIT.java b/javatests/com/google/gerrit/acceptance/rest/change/ChangeEditIT.java
new file mode 100644
index 0000000..c33de03
--- /dev/null
+++ b/javatests/com/google/gerrit/acceptance/rest/change/ChangeEditIT.java
@@ -0,0 +1,58 @@
+// Copyright (C) 2024 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.acceptance.rest.change;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import com.google.gerrit.acceptance.AbstractDaemonTest;
+import com.google.gerrit.acceptance.RestResponse;
+import com.google.gerrit.acceptance.testsuite.change.ChangeOperations;
+import com.google.gerrit.common.RawInputUtil;
+import com.google.gerrit.entities.Change;
+import com.google.inject.Inject;
+import org.junit.Test;
+
+public class ChangeEditIT extends AbstractDaemonTest {
+  private static final String FILE_NAME = "foo";
+  private static final String FILE_NAME2 = "foo2";
+
+  private static final String FILE_CONTENT = "content";
+  private static final String FILE_CONTENT2 = "content2";
+
+  @Inject private ChangeOperations changeOperations;
+
+  @Test
+  public void modifyMultipleFilesInOneChangeEdit() throws Exception {
+    Change.Id changeId = changeOperations.newChange().create();
+    RestResponse response =
+        adminRestSession.putRaw(
+            String.format("/changes/%s/edit/%s", changeId, FILE_NAME),
+            RawInputUtil.create(FILE_CONTENT));
+    assertThat(response.getStatusCode()).isEqualTo(204);
+    RestResponse response2 =
+        adminRestSession.putRaw(
+            String.format("/changes/%s/edit/%s", changeId, FILE_NAME2),
+            RawInputUtil.create(FILE_CONTENT2));
+    assertThat(response2.getStatusCode()).isEqualTo(204);
+    RestResponse publishResponse =
+        adminRestSession.post(String.format("/changes/%s/edit:publish", changeId));
+    assertThat(publishResponse.getStatusCode()).isEqualTo(204);
+    assertThat(gApi.changes().id(changeId.get()).current().files().keySet())
+        .containsExactly("/COMMIT_MSG", FILE_NAME, FILE_NAME2);
+    // Created an initial change, then applied a single edit with two files resulting in one more
+    // patchset.
+    assertThat(gApi.changes().id(changeId.get()).get().currentRevisionNumber).isEqualTo(2);
+  }
+}