Add REST endpoint to rename operation

Implement Rest API equivalent to the ssh rename command with usage of
projects API. New project name is getting passed in through json request
body.

With this change the plugin will be able to receive rename requests not
only through ssh but also through its new endpoint, making it more
testable with frameworks that utilise http, such as Gatling.

Change-Id: I0ce0ce68a4d5e65569e8b14a580f7890ef70075b
diff --git a/src/main/java/com/googlesource/gerrit/plugins/renameproject/Module.java b/src/main/java/com/googlesource/gerrit/plugins/renameproject/Module.java
index 6962811..568a7be 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/renameproject/Module.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/renameproject/Module.java
@@ -14,12 +14,14 @@
 
 package com.googlesource.gerrit.plugins.renameproject;
 
+import static com.google.gerrit.server.project.ProjectResource.PROJECT_KIND;
 import static com.googlesource.gerrit.plugins.renameproject.RenameOwnProjectCapability.RENAME_OWN_PROJECT;
 import static com.googlesource.gerrit.plugins.renameproject.RenameProjectCapability.RENAME_PROJECT;
 
 import com.google.gerrit.extensions.annotations.Exports;
 import com.google.gerrit.extensions.config.CapabilityDefinition;
 import com.google.gerrit.extensions.events.LifecycleListener;
+import com.google.gerrit.extensions.restapi.RestApiModule;
 import com.google.inject.AbstractModule;
 import com.google.inject.internal.UniqueAnnotations;
 import com.googlesource.gerrit.plugins.renameproject.cache.CacheRenameHandler;
@@ -45,5 +47,13 @@
     bind(RenamePreconditions.class);
     bind(IndexUpdateHandler.class);
     bind(RevertRenameProject.class);
+
+    install(
+        new RestApiModule() {
+          @Override
+          protected void configure() {
+            post(PROJECT_KIND, "rename").to(RenameProject.class);
+          }
+        });
   }
 }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/renameproject/RenameCommand.java b/src/main/java/com/googlesource/gerrit/plugins/renameproject/RenameCommand.java
index db1e862..4478ee6 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/renameproject/RenameCommand.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/renameproject/RenameCommand.java
@@ -14,6 +14,7 @@
 
 package com.googlesource.gerrit.plugins.renameproject;
 
+import static com.googlesource.gerrit.plugins.renameproject.RenameProject.CANCELLATION_MSG;
 import static com.googlesource.gerrit.plugins.renameproject.RenameProject.WARNING_LIMIT;
 
 import com.google.gerrit.extensions.restapi.RestApiException;
@@ -32,6 +33,7 @@
 import java.io.IOException;
 import java.io.InputStreamReader;
 import java.util.List;
+import java.util.Optional;
 import org.kohsuke.args4j.Argument;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -68,14 +70,13 @@
           new ProjectResource(
               projectCacheProvider.get().get(new Project.NameKey(projectControl)), self.get());
       try (CommandProgressMonitor monitor = new CommandProgressMonitor(stdout)) {
-        renameProject.assertCanRename(rsrc, input, monitor);
-        List<Change.Id> changeIds = renameProject.getChanges(rsrc, monitor);
+        renameProject.assertCanRename(rsrc, input, Optional.of(monitor));
+        List<Change.Id> changeIds = renameProject.getChanges(rsrc, Optional.of(monitor));
         if (continueRename(changeIds, monitor)) {
-          renameProject.doRename(changeIds, rsrc, input, monitor);
+          renameProject.doRename(changeIds, rsrc, input, Optional.of(monitor));
         } else {
-          String cancellationMsg = "Rename operation was cancelled by user.";
-          log.debug(cancellationMsg);
-          stdout.println(cancellationMsg);
+          log.debug(CANCELLATION_MSG);
+          stdout.println(CANCELLATION_MSG);
           stdout.flush();
         }
       }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/renameproject/RenameProject.java b/src/main/java/com/googlesource/gerrit/plugins/renameproject/RenameProject.java
index b55a264..c7937b6 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/renameproject/RenameProject.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/renameproject/RenameProject.java
@@ -25,7 +25,10 @@
 import com.google.gerrit.extensions.restapi.AuthException;
 import com.google.gerrit.extensions.restapi.BadRequestException;
 import com.google.gerrit.extensions.restapi.ResourceConflictException;
+import com.google.gerrit.extensions.restapi.Response;
+import com.google.gerrit.extensions.restapi.RestModifyView;
 import com.google.gerrit.reviewdb.client.Change;
+import com.google.gerrit.reviewdb.client.Change.Id;
 import com.google.gerrit.reviewdb.client.Project;
 import com.google.gerrit.server.CurrentUser;
 import com.google.gerrit.server.IdentifiedUser;
@@ -39,6 +42,7 @@
 import com.google.inject.Provider;
 import com.google.inject.Singleton;
 import com.google.inject.name.Named;
+import com.googlesource.gerrit.plugins.renameproject.RenameProject.Input;
 import com.googlesource.gerrit.plugins.renameproject.cache.CacheRenameHandler;
 import com.googlesource.gerrit.plugins.renameproject.conditions.RenamePreconditions;
 import com.googlesource.gerrit.plugins.renameproject.database.DatabaseRenameHandler;
@@ -48,18 +52,39 @@
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Optional;
 import org.eclipse.jgit.errors.ConfigInvalidException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 @Singleton
-public class RenameProject {
+public class RenameProject implements RestModifyView<ProjectResource, Input> {
+
+  @Override
+  public Object apply(ProjectResource resource, Input input)
+      throws IOException, AuthException, BadRequestException, ResourceConflictException,
+          InterruptedException, ConfigInvalidException, RenameRevertException {
+    assertCanRename(resource, input, Optional.empty());
+    List<Id> changeIds = getChanges(resource, Optional.empty());
+
+    if (changeIds == null || changeIds.size() <= WARNING_LIMIT || input.continueWithRename) {
+      doRename(changeIds, resource, input, Optional.empty());
+    } else {
+      log.debug(CANCELLATION_MSG);
+      return Response.none();
+    }
+    return Response.ok("");
+  }
 
   static class Input {
     String name;
+    boolean continueWithRename;
   }
 
   static final int WARNING_LIMIT = 5000;
+  static final String CANCELLATION_MSG =
+      "Rename cancelled due to number of changes exceeding warning limit and user's will to not continue";
+
   private static final Logger log = LoggerFactory.getLogger(RenameProject.class);
   private static final String CACHE_NAME = "changeid_project";
 
@@ -146,10 +171,11 @@
     return true;
   }
 
-  void assertCanRename(ProjectResource rsrc, Input input, ProgressMonitor pm)
+  void assertCanRename(ProjectResource rsrc, Input input, Optional<ProgressMonitor> pm)
       throws ResourceConflictException, BadRequestException, AuthException {
     try {
-      pm.beginTask("Checking preconditions");
+      pm.ifPresent(progressMonitor -> progressMonitor.beginTask("Checking preconditions"));
+
       assertNewNameNotNull(input);
       assertRenamePermission(rsrc);
       renamePreconditions.assertCanRename(rsrc, new Project.NameKey(input.name));
@@ -159,7 +185,8 @@
     }
   }
 
-  void doRename(List<Change.Id> changeIds, ProjectResource rsrc, Input input, ProgressMonitor pm)
+  void doRename(
+      List<Change.Id> changeIds, ProjectResource rsrc, Input input, Optional<ProgressMonitor> pm)
       throws InterruptedException, ConfigInvalidException, IOException, RenameRevertException {
     Project.NameKey oldProjectKey = rsrc.getNameKey();
     Project.NameKey newProjectKey = new Project.NameKey(input.name);
@@ -211,7 +238,7 @@
   }
 
   void fsRenameStep(
-      Project.NameKey oldProjectKey, Project.NameKey newProjectKey, ProgressMonitor pm)
+      Project.NameKey oldProjectKey, Project.NameKey newProjectKey, Optional<ProgressMonitor> pm)
       throws IOException {
     fsHandler.rename(oldProjectKey, newProjectKey, pm);
     logPerformedStep(Step.FILESYSTEM, newProjectKey, oldProjectKey);
@@ -227,7 +254,7 @@
       List<Change.Id> changeIds,
       Project.NameKey oldProjectKey,
       Project.NameKey newProjectKey,
-      ProgressMonitor pm)
+      Optional<ProgressMonitor> pm)
       throws IOException, ConfigInvalidException, RenameRevertException {
     List<Change.Id> updatedChangeIds = dbHandler.rename(changeIds, newProjectKey, pm);
     logPerformedStep(Step.DATABASE, newProjectKey, oldProjectKey);
@@ -238,7 +265,7 @@
       List<Change.Id> updatedChangeIds,
       Project.NameKey oldProjectKey,
       Project.NameKey newProjectKey,
-      ProgressMonitor pm)
+      Optional<ProgressMonitor> pm)
       throws InterruptedException {
     indexHandler.updateIndex(updatedChangeIds, newProjectKey, pm);
     logPerformedStep(Step.INDEX, newProjectKey, oldProjectKey);
@@ -274,8 +301,9 @@
     return stepsPerformed;
   }
 
-  List<Change.Id> getChanges(ProjectResource rsrc, ProgressMonitor pm) throws IOException {
-    pm.beginTask("Retrieving the list of changes from DB");
+  List<Change.Id> getChanges(ProjectResource rsrc, Optional<ProgressMonitor> opm)
+      throws IOException {
+    opm.ifPresent(pm -> pm.beginTask("Retrieving the list of changes from DB"));
     Project.NameKey oldProjectKey = rsrc.getNameKey();
     return dbHandler.getChangeIds(oldProjectKey);
   }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/renameproject/RevertRenameProject.java b/src/main/java/com/googlesource/gerrit/plugins/renameproject/RevertRenameProject.java
index 37f261f..0671c71 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/renameproject/RevertRenameProject.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/renameproject/RevertRenameProject.java
@@ -27,6 +27,7 @@
 import java.io.IOException;
 import java.util.Collections;
 import java.util.List;
+import java.util.Optional;
 import org.eclipse.jgit.errors.ConfigInvalidException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -56,13 +57,13 @@
       List<Id> changeIds,
       Project.NameKey oldProjectKey,
       Project.NameKey newProjectKey,
-      ProgressMonitor pm)
+      Optional<ProgressMonitor> opm)
       throws IOException, RenameRevertException, ConfigInvalidException {
-    pm.beginTask("Reverting the rename procedure.");
+    opm.ifPresent(pm -> pm.beginTask("Reverting the rename procedure."));
     List<Change.Id> updatedChangeIds = Collections.emptyList();
     if (stepsPerformed.contains(Step.FILESYSTEM)) {
       try {
-        fsHandler.rename(newProjectKey, oldProjectKey, pm);
+        fsHandler.rename(newProjectKey, oldProjectKey, opm);
         log.debug("Reverted the git repo name to {} successfully.", oldProjectKey.get());
       } catch (IOException e) {
         log.error(
@@ -76,7 +77,7 @@
     }
     if (stepsPerformed.contains(Step.DATABASE)) {
       try {
-        updatedChangeIds = dbHandler.rename(changeIds, newProjectKey, pm);
+        updatedChangeIds = dbHandler.rename(changeIds, newProjectKey, opm);
         log.debug(
             "Reverted the changes in DB successfully from project {} to project {}.",
             newProjectKey.get(),
@@ -91,7 +92,7 @@
     }
     if (stepsPerformed.contains(Step.INDEX)) {
       try {
-        indexHandler.updateIndex(updatedChangeIds, oldProjectKey, pm);
+        indexHandler.updateIndex(updatedChangeIds, oldProjectKey, opm);
         log.debug(
             "Reverted the secondary index successfully from project {} to project {}.",
             newProjectKey.get(),
diff --git a/src/main/java/com/googlesource/gerrit/plugins/renameproject/database/DatabaseRenameHandler.java b/src/main/java/com/googlesource/gerrit/plugins/renameproject/database/DatabaseRenameHandler.java
index 97cd59f..2ed4ad5 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/renameproject/database/DatabaseRenameHandler.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/renameproject/database/DatabaseRenameHandler.java
@@ -39,6 +39,7 @@
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Optional;
 import java.util.Set;
 import java.util.stream.Stream;
 import org.eclipse.jgit.errors.ConfigInvalidException;
@@ -89,9 +90,9 @@
   }
 
   public List<Change.Id> rename(
-      List<Change.Id> changes, Project.NameKey newProjectKey, ProgressMonitor pm)
+      List<Change.Id> changes, Project.NameKey newProjectKey, Optional<ProgressMonitor> opm)
       throws RenameRevertException, IOException, ConfigInvalidException {
-    pm.beginTask("Updating changes in the database");
+    opm.ifPresent(pm -> pm.beginTask("Updating changes in the database"));
     log.debug("Updating the changes in noteDb related to project {}", oldProjectKey.get());
     try {
       updateWatchEntries(newProjectKey);
diff --git a/src/main/java/com/googlesource/gerrit/plugins/renameproject/database/IndexUpdateHandler.java b/src/main/java/com/googlesource/gerrit/plugins/renameproject/database/IndexUpdateHandler.java
index daef534..f75b784 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/renameproject/database/IndexUpdateHandler.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/renameproject/database/IndexUpdateHandler.java
@@ -24,6 +24,7 @@
 import com.googlesource.gerrit.plugins.renameproject.monitor.ProgressMonitor;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Optional;
 import java.util.concurrent.Callable;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.ExecutorService;
@@ -46,17 +47,17 @@
   }
 
   public void updateIndex(
-      List<Change.Id> changeIds, Project.NameKey newProjectKey, ProgressMonitor pm)
+      List<Change.Id> changeIds, Project.NameKey newProjectKey, Optional<ProgressMonitor> opm)
       throws InterruptedException {
     log.debug("Starting to index {} change(s).", changeIds.size());
     ExecutorService executor =
         Executors.newFixedThreadPool(
             config.getIndexThreads(),
             new ThreadFactoryBuilder().setNameFormat("Rename-Index-%d").build());
-    pm.beginTask("Indexing changes", changeIds.size());
+    opm.ifPresent(pm -> pm.beginTask("Indexing changes", changeIds.size()));
     List<Callable<Boolean>> callableTasks = new ArrayList<>(changeIds.size());
     for (Change.Id id : changeIds) {
-      callableTasks.add(new IndexTask(id, newProjectKey, pm));
+      callableTasks.add(new IndexTask(id, newProjectKey, opm));
     }
     List<Future<Boolean>> tasksCompleted = executor.invokeAll(callableTasks);
     executor.shutdown();
@@ -83,9 +84,10 @@
 
     private Change.Id changeId;
     private Project.NameKey newProjectKey;
-    private ProgressMonitor monitor;
+    private Optional<ProgressMonitor> monitor;
 
-    IndexTask(Change.Id changeId, Project.NameKey newProjectKey, ProgressMonitor monitor) {
+    IndexTask(
+        Change.Id changeId, Project.NameKey newProjectKey, Optional<ProgressMonitor> monitor) {
       this.changeId = changeId;
       this.newProjectKey = newProjectKey;
       this.monitor = monitor;
@@ -94,7 +96,7 @@
     @Override
     public Boolean call() throws Exception {
       indexer.index(newProjectKey, changeId);
-      monitor.update(1);
+      monitor.ifPresent(monitor -> monitor.update(1));
       return Boolean.TRUE;
     }
   }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/renameproject/fs/FilesystemRenameHandler.java b/src/main/java/com/googlesource/gerrit/plugins/renameproject/fs/FilesystemRenameHandler.java
index 29a76d8..1572d53 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/renameproject/fs/FilesystemRenameHandler.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/renameproject/fs/FilesystemRenameHandler.java
@@ -26,6 +26,7 @@
 import java.nio.file.Path;
 import java.nio.file.StandardCopyOption;
 import java.util.Comparator;
+import java.util.Optional;
 import java.util.stream.Stream;
 import org.eclipse.jgit.errors.RepositoryNotFoundException;
 import org.eclipse.jgit.lib.Repository;
@@ -45,12 +46,12 @@
   }
 
   public void rename(
-      Project.NameKey oldProjectKey, Project.NameKey newProjectKey, ProgressMonitor pm)
+      Project.NameKey oldProjectKey, Project.NameKey newProjectKey, Optional<ProgressMonitor> opm)
       throws IOException, RepositoryNotFoundException {
     Repository repository = repoManager.openRepository(oldProjectKey);
     File repoFile = repository.getDirectory();
     RepositoryCache.close(repository);
-    pm.beginTask("Renaming git repository");
+    opm.ifPresent(pm -> pm.beginTask("Renaming git repository"));
     renameGitRepository(repoFile, newProjectKey, oldProjectKey);
   }
 
diff --git a/src/main/resources/Documentation/rest-api-rename.md b/src/main/resources/Documentation/rest-api-rename.md
new file mode 100644
index 0000000..70ecf15
--- /dev/null
+++ b/src/main/resources/Documentation/rest-api-rename.md
@@ -0,0 +1,55 @@
+@PLUGIN@ - /@PLUGIN@/ REST API
+===================================
+
+This page describes the REST endpoint that is added by the @PLUGIN@
+plugin.
+
+Please also take note of the general information on the
+[REST API](../../../Documentation/rest-api.html).
+
+This API implements a REST equivalent of the Ssh rename-project command.
+For more information, refer to:
+* [Ssh rename-project command](cmd-rename.md)
+------------------------------------------
+
+REQUEST
+-------
+```
+POST /projects/project-1/@PLUGIN@~rename HTTP/1.1
+  {
+    "name" : "project-2",
+  }
+```
+to rename project-1 to project-2.
+
+By default, if project-1 has more than 5000 changes, the rename procedure will be cancelled as it
+can take longer time and can degrade in performance in that time frame.
+
+To rename a project with more than 5000 changes, the following request is needed:
+```
+POST /projects/project-1/@PLUGIN@~rename HTTP/1.1
+  {
+    "name" : "project-2",
+    "continueWithRename" : "true"
+  }
+```
+
+RESPONSE
+--------
+If rename succeeded:
+
+```
+HTTP/1.1 200 OK
+```
+
+If rename was cancelled due to user's intent to not proceed when the number of changes exceeds the
+warning limit of 5000 changes:
+
+```
+HTTP/1.1 204 No Content
+```
+
+ACCESS
+------
+Same as ssh version of the command, caller must be a member of a group that is granted the
+'Rename Project' (provided by this plugin) or 'Administrate Server' capabilities.
diff --git a/src/test/java/com/googlesource/gerrit/plugins/renameproject/RenameIT.java b/src/test/java/com/googlesource/gerrit/plugins/renameproject/RenameIT.java
index 1c26f50..7df0e60 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/renameproject/RenameIT.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/renameproject/RenameIT.java
@@ -19,15 +19,18 @@
 import com.google.common.cache.Cache;
 import com.google.gerrit.acceptance.LightweightPluginDaemonTest;
 import com.google.gerrit.acceptance.PushOneCommit.Result;
+import com.google.gerrit.acceptance.RestResponse;
 import com.google.gerrit.acceptance.TestPlugin;
 import com.google.gerrit.acceptance.UseLocalDisk;
 import com.google.gerrit.acceptance.UseSsh;
+import com.google.gerrit.acceptance.testsuite.request.RequestScopeOperations;
 import com.google.gerrit.extensions.client.ProjectWatchInfo;
 import com.google.gerrit.reviewdb.client.Change.Id;
 import com.google.gerrit.reviewdb.client.Project;
 import com.google.gerrit.reviewdb.client.Project.NameKey;
 import com.google.gerrit.server.project.ProjectState;
 import com.google.inject.Inject;
+import com.googlesource.gerrit.plugins.renameproject.RenameProject.Input;
 import java.util.List;
 import javax.inject.Named;
 import org.eclipse.jgit.junit.TestRepository;
@@ -44,6 +47,8 @@
   private static final String NEW_PROJECT_NAME = "newProject";
   private static final String CACHE_NAME = "changeid_project";
 
+  @Inject private RequestScopeOperations requestScopeOperations;
+
   @Inject
   @Named(CACHE_NAME)
   private Cache<Id, String> changeIdProjectCache;
@@ -146,4 +151,39 @@
 
     assertThat(changeIdProjectCache.getIfPresent(changeID)).isNull();
   }
+
+  @Test
+  @UseLocalDisk
+  public void testRenameViaHttpSuccessful() throws Exception {
+    createChange();
+    RestResponse r = renameProjectTo(NEW_PROJECT_NAME);
+    r.assertOK();
+
+    ProjectState projectState = projectCache.get(Project.nameKey(NEW_PROJECT_NAME));
+    assertThat(projectState).isNotNull();
+    assertThat(queryProvider.get().byProject(project)).isEmpty();
+    assertThat(queryProvider.get().byProject(Project.nameKey(NEW_PROJECT_NAME))).isNotEmpty();
+  }
+
+  @Test
+  @UseLocalDisk
+  public void testRenameViaHttpWithEmptyNewName() throws Exception {
+    createChange();
+    String newProjectName = "";
+    RestResponse r = renameProjectTo(newProjectName);
+    r.assertBadRequest();
+
+    ProjectState projectState = projectCache.get(Project.nameKey(newProjectName));
+    assertThat(projectState).isNull();
+  }
+
+  private RestResponse renameProjectTo(String newName) throws Exception {
+    requestScopeOperations.setApiUser(user.id());
+    sender.clear();
+    String endPoint = "/projects/" + project.get() + "/" + PLUGIN_NAME + "~rename";
+    Input i = new Input();
+    i.name = newName;
+    i.continueWithRename = true;
+    return adminRestSession.post(endPoint, i);
+  }
 }
diff --git a/src/test/java/com/googlesource/gerrit/plugins/renameproject/RevertRenameProjectTest.java b/src/test/java/com/googlesource/gerrit/plugins/renameproject/RevertRenameProjectTest.java
index d060414..f77d80e 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/renameproject/RevertRenameProjectTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/renameproject/RevertRenameProjectTest.java
@@ -30,6 +30,7 @@
 import com.googlesource.gerrit.plugins.renameproject.RenameProject.Step;
 import com.googlesource.gerrit.plugins.renameproject.monitor.ProgressMonitor;
 import java.util.List;
+import java.util.Optional;
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.Mockito;
@@ -45,7 +46,7 @@
   private RevertRenameProject revertRenameProject;
   private Project.NameKey oldProjectKey;
   private Project.NameKey newProjectKey;
-  private ProgressMonitor pm;
+  private Optional<ProgressMonitor> pm;
   private ProjectResource oldRsrc;
 
   @Before
@@ -56,7 +57,7 @@
     oldProjectKey = project;
     newProjectKey = new Project.NameKey(NEW_PROJECT_NAME);
 
-    pm = Mockito.mock(ProgressMonitor.class);
+    pm = Optional.of(Mockito.mock(ProgressMonitor.class));
 
     oldRsrc = Mockito.mock(ProjectResource.class);
     when(oldRsrc.getNameKey()).thenReturn(oldProjectKey);