Support to control notifications when creating changes through REST
Change-Id: I0792c38f429459ce2e2f74fef2dc0b962188f451 Signed-off-by: Edwin Kempin <ekempin@google.com>
This commit is contained in:
		@@ -5232,6 +5232,14 @@ change operation.
 | 
				
			|||||||
Allow creating a new branch when set to `true`.
 | 
					Allow creating a new branch when set to `true`.
 | 
				
			||||||
|`merge`              |optional|
 | 
					|`merge`              |optional|
 | 
				
			||||||
The detail of a merge commit as a link:#merge-input[MergeInput] entity.
 | 
					The detail of a merge commit as a link:#merge-input[MergeInput] entity.
 | 
				
			||||||
 | 
					|`notify`             |optional|
 | 
				
			||||||
 | 
					Notify handling that defines to whom email notifications should be sent
 | 
				
			||||||
 | 
					after the change is created. +
 | 
				
			||||||
 | 
					Allowed values are `NONE`, `OWNER`, `OWNER_REVIEWERS` and `ALL`. +
 | 
				
			||||||
 | 
					If not set, the default is `ALL`.
 | 
				
			||||||
 | 
					|`notify_details`     |optional|
 | 
				
			||||||
 | 
					Additional information about whom to notify about the change creation
 | 
				
			||||||
 | 
					as a map of recipient type to link:#notify-info[NotifyInfo] entity.
 | 
				
			||||||
|==================================
 | 
					|==================================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[change-message-info]]
 | 
					[[change-message-info]]
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -49,6 +49,7 @@ import com.google.gerrit.extensions.api.projects.BranchInput;
 | 
				
			|||||||
import com.google.gerrit.extensions.api.projects.ProjectInput;
 | 
					import com.google.gerrit.extensions.api.projects.ProjectInput;
 | 
				
			||||||
import com.google.gerrit.extensions.client.InheritableBoolean;
 | 
					import com.google.gerrit.extensions.client.InheritableBoolean;
 | 
				
			||||||
import com.google.gerrit.extensions.client.ListChangesOption;
 | 
					import com.google.gerrit.extensions.client.ListChangesOption;
 | 
				
			||||||
 | 
					import com.google.gerrit.extensions.client.ProjectWatchInfo;
 | 
				
			||||||
import com.google.gerrit.extensions.client.SubmitType;
 | 
					import com.google.gerrit.extensions.client.SubmitType;
 | 
				
			||||||
import com.google.gerrit.extensions.common.ActionInfo;
 | 
					import com.google.gerrit.extensions.common.ActionInfo;
 | 
				
			||||||
import com.google.gerrit.extensions.common.ChangeInfo;
 | 
					import com.google.gerrit.extensions.common.ChangeInfo;
 | 
				
			||||||
@@ -1237,4 +1238,17 @@ public abstract class AbstractDaemonTest {
 | 
				
			|||||||
    assertThat(m.headers().get("To").isEmpty()).isTrue();
 | 
					    assertThat(m.headers().get("To").isEmpty()).isTrue();
 | 
				
			||||||
    assertThat(m.headers().get("CC").isEmpty()).isTrue();
 | 
					    assertThat(m.headers().get("CC").isEmpty()).isTrue();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  protected void watch(String project, String filter)
 | 
				
			||||||
 | 
					      throws RestApiException {
 | 
				
			||||||
 | 
					    List<ProjectWatchInfo> projectsToWatch = new ArrayList<>();
 | 
				
			||||||
 | 
					    ProjectWatchInfo pwi = new ProjectWatchInfo();
 | 
				
			||||||
 | 
					    pwi.project = project;
 | 
				
			||||||
 | 
					    pwi.filter = filter;
 | 
				
			||||||
 | 
					    pwi.notifyAbandonedChanges = true;
 | 
				
			||||||
 | 
					    pwi.notifyNewChanges = true;
 | 
				
			||||||
 | 
					    pwi.notifyAllComments = true;
 | 
				
			||||||
 | 
					    projectsToWatch.add(pwi);
 | 
				
			||||||
 | 
					    gApi.accounts().self().setWatchedProjects(projectsToWatch);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -28,6 +28,7 @@ import com.google.gerrit.acceptance.PushOneCommit.Result;
 | 
				
			|||||||
import com.google.gerrit.acceptance.RestResponse;
 | 
					import com.google.gerrit.acceptance.RestResponse;
 | 
				
			||||||
import com.google.gerrit.extensions.api.changes.ChangeApi;
 | 
					import com.google.gerrit.extensions.api.changes.ChangeApi;
 | 
				
			||||||
import com.google.gerrit.extensions.api.changes.CherryPickInput;
 | 
					import com.google.gerrit.extensions.api.changes.CherryPickInput;
 | 
				
			||||||
 | 
					import com.google.gerrit.extensions.api.changes.NotifyHandling;
 | 
				
			||||||
import com.google.gerrit.extensions.api.changes.ReviewInput;
 | 
					import com.google.gerrit.extensions.api.changes.ReviewInput;
 | 
				
			||||||
import com.google.gerrit.extensions.client.ChangeStatus;
 | 
					import com.google.gerrit.extensions.client.ChangeStatus;
 | 
				
			||||||
import com.google.gerrit.extensions.client.GeneralPreferencesInfo;
 | 
					import com.google.gerrit.extensions.client.GeneralPreferencesInfo;
 | 
				
			||||||
@@ -43,6 +44,7 @@ import com.google.gerrit.server.config.AnonymousCowardNameProvider;
 | 
				
			|||||||
import com.google.gerrit.server.git.ChangeAlreadyMergedException;
 | 
					import com.google.gerrit.server.git.ChangeAlreadyMergedException;
 | 
				
			||||||
import com.google.gerrit.testutil.ConfigSuite;
 | 
					import com.google.gerrit.testutil.ConfigSuite;
 | 
				
			||||||
import com.google.gerrit.testutil.TestTimeUtil;
 | 
					import com.google.gerrit.testutil.TestTimeUtil;
 | 
				
			||||||
 | 
					import com.google.gerrit.testutil.FakeEmailSender.Message;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import org.eclipse.jgit.lib.Config;
 | 
					import org.eclipse.jgit.lib.Config;
 | 
				
			||||||
import org.eclipse.jgit.lib.ObjectId;
 | 
					import org.eclipse.jgit.lib.ObjectId;
 | 
				
			||||||
@@ -55,6 +57,8 @@ import org.junit.AfterClass;
 | 
				
			|||||||
import org.junit.BeforeClass;
 | 
					import org.junit.BeforeClass;
 | 
				
			||||||
import org.junit.Test;
 | 
					import org.junit.Test;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.util.List;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public class CreateChangeIT extends AbstractDaemonTest {
 | 
					public class CreateChangeIT extends AbstractDaemonTest {
 | 
				
			||||||
  @ConfigSuite.Config
 | 
					  @ConfigSuite.Config
 | 
				
			||||||
  public static Config allowDraftsDisabled() {
 | 
					  public static Config allowDraftsDisabled() {
 | 
				
			||||||
@@ -100,6 +104,30 @@ public class CreateChangeIT extends AbstractDaemonTest {
 | 
				
			|||||||
    assertCreateSucceeds(newChangeInput(ChangeStatus.NEW));
 | 
					    assertCreateSucceeds(newChangeInput(ChangeStatus.NEW));
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @Test
 | 
				
			||||||
 | 
					  public void notificationsOnChangeCreation() throws Exception {
 | 
				
			||||||
 | 
					    setApiUser(user);
 | 
				
			||||||
 | 
					    watch(project.get(), null);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // check that watcher is notified
 | 
				
			||||||
 | 
					    setApiUser(admin);
 | 
				
			||||||
 | 
					    assertCreateSucceeds(newChangeInput(ChangeStatus.NEW));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    List<Message> messages = sender.getMessages();
 | 
				
			||||||
 | 
					    assertThat(messages).hasSize(1);
 | 
				
			||||||
 | 
					    Message m = messages.get(0);
 | 
				
			||||||
 | 
					    assertThat(m.rcpt()).containsExactly(user.emailAddress);
 | 
				
			||||||
 | 
					    assertThat(m.body())
 | 
				
			||||||
 | 
					        .contains(admin.fullName + " has uploaded this change for review.");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // check that watcher is not notified if notify=NONE
 | 
				
			||||||
 | 
					    sender.clear();
 | 
				
			||||||
 | 
					    ChangeInput input = newChangeInput(ChangeStatus.NEW);
 | 
				
			||||||
 | 
					    input.notify = NotifyHandling.NONE;
 | 
				
			||||||
 | 
					    assertCreateSucceeds(input);
 | 
				
			||||||
 | 
					    assertThat(sender.getMessages()).isEmpty();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @Test
 | 
					  @Test
 | 
				
			||||||
  public void createNewChangeSignedOffByFooter() throws Exception {
 | 
					  public void createNewChangeSignedOffByFooter() throws Exception {
 | 
				
			||||||
    assume().that(isAllowDrafts()).isTrue();
 | 
					    assume().that(isAllowDrafts()).isTrue();
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -21,8 +21,6 @@ import com.google.gerrit.acceptance.NoHttpd;
 | 
				
			|||||||
import com.google.gerrit.acceptance.PushOneCommit;
 | 
					import com.google.gerrit.acceptance.PushOneCommit;
 | 
				
			||||||
import com.google.gerrit.acceptance.Sandboxed;
 | 
					import com.google.gerrit.acceptance.Sandboxed;
 | 
				
			||||||
import com.google.gerrit.acceptance.TestAccount;
 | 
					import com.google.gerrit.acceptance.TestAccount;
 | 
				
			||||||
import com.google.gerrit.extensions.client.ProjectWatchInfo;
 | 
					 | 
				
			||||||
import com.google.gerrit.extensions.restapi.RestApiException;
 | 
					 | 
				
			||||||
import com.google.gerrit.reviewdb.client.Project;
 | 
					import com.google.gerrit.reviewdb.client.Project;
 | 
				
			||||||
import com.google.gerrit.server.account.WatchConfig.NotifyType;
 | 
					import com.google.gerrit.server.account.WatchConfig.NotifyType;
 | 
				
			||||||
import com.google.gerrit.server.git.NotifyConfig;
 | 
					import com.google.gerrit.server.git.NotifyConfig;
 | 
				
			||||||
@@ -34,7 +32,6 @@ import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
 | 
				
			|||||||
import org.eclipse.jgit.junit.TestRepository;
 | 
					import org.eclipse.jgit.junit.TestRepository;
 | 
				
			||||||
import org.junit.Test;
 | 
					import org.junit.Test;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.util.ArrayList;
 | 
					 | 
				
			||||||
import java.util.EnumSet;
 | 
					import java.util.EnumSet;
 | 
				
			||||||
import java.util.List;
 | 
					import java.util.List;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -312,17 +309,4 @@ public class ProjectWatchIT extends AbstractDaemonTest {
 | 
				
			|||||||
    // assert email notification
 | 
					    // assert email notification
 | 
				
			||||||
    assertThat(sender.getMessages()).hasSize(0);
 | 
					    assertThat(sender.getMessages()).hasSize(0);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					 | 
				
			||||||
  private void watch(String project, String filter)
 | 
					 | 
				
			||||||
      throws RestApiException {
 | 
					 | 
				
			||||||
    List<ProjectWatchInfo> projectsToWatch = new ArrayList<>();
 | 
					 | 
				
			||||||
    ProjectWatchInfo pwi = new ProjectWatchInfo();
 | 
					 | 
				
			||||||
    pwi.project = project;
 | 
					 | 
				
			||||||
    pwi.filter = filter;
 | 
					 | 
				
			||||||
    pwi.notifyAbandonedChanges = true;
 | 
					 | 
				
			||||||
    pwi.notifyNewChanges = true;
 | 
					 | 
				
			||||||
    pwi.notifyAllComments = true;
 | 
					 | 
				
			||||||
    projectsToWatch.add(pwi);
 | 
					 | 
				
			||||||
    gApi.accounts().self().setWatchedProjects(projectsToWatch);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,8 +14,13 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
package com.google.gerrit.extensions.common;
 | 
					package com.google.gerrit.extensions.common;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import com.google.gerrit.extensions.api.changes.NotifyHandling;
 | 
				
			||||||
 | 
					import com.google.gerrit.extensions.api.changes.NotifyInfo;
 | 
				
			||||||
 | 
					import com.google.gerrit.extensions.api.changes.RecipientType;
 | 
				
			||||||
import com.google.gerrit.extensions.client.ChangeStatus;
 | 
					import com.google.gerrit.extensions.client.ChangeStatus;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.util.Map;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public class ChangeInput {
 | 
					public class ChangeInput {
 | 
				
			||||||
  public String project;
 | 
					  public String project;
 | 
				
			||||||
  public String branch;
 | 
					  public String branch;
 | 
				
			||||||
@@ -26,4 +31,8 @@ public class ChangeInput {
 | 
				
			|||||||
  public String baseChange;
 | 
					  public String baseChange;
 | 
				
			||||||
  public Boolean newBranch;
 | 
					  public Boolean newBranch;
 | 
				
			||||||
  public MergeInput merge;
 | 
					  public MergeInput merge;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /** Who to send email notifications to after change is created. */
 | 
				
			||||||
 | 
					  public NotifyHandling notify = NotifyHandling.ALL;
 | 
				
			||||||
 | 
					  public Map<RecipientType, NotifyInfo> notifyDetails;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -106,6 +106,7 @@ public class CreateChange implements
 | 
				
			|||||||
  private final boolean allowDrafts;
 | 
					  private final boolean allowDrafts;
 | 
				
			||||||
  private final MergeUtil.Factory mergeUtilFactory;
 | 
					  private final MergeUtil.Factory mergeUtilFactory;
 | 
				
			||||||
  private final SubmitType submitType;
 | 
					  private final SubmitType submitType;
 | 
				
			||||||
 | 
					  private final NotifyUtil notifyUtil;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @Inject
 | 
					  @Inject
 | 
				
			||||||
  CreateChange(@AnonymousCowardName String anonymousCowardName,
 | 
					  CreateChange(@AnonymousCowardName String anonymousCowardName,
 | 
				
			||||||
@@ -122,7 +123,8 @@ public class CreateChange implements
 | 
				
			|||||||
      BatchUpdate.Factory updateFactory,
 | 
					      BatchUpdate.Factory updateFactory,
 | 
				
			||||||
      PatchSetUtil psUtil,
 | 
					      PatchSetUtil psUtil,
 | 
				
			||||||
      @GerritServerConfig Config config,
 | 
					      @GerritServerConfig Config config,
 | 
				
			||||||
      MergeUtil.Factory mergeUtilFactory) {
 | 
					      MergeUtil.Factory mergeUtilFactory,
 | 
				
			||||||
 | 
					      NotifyUtil notifyUtil) {
 | 
				
			||||||
    this.anonymousCowardName = anonymousCowardName;
 | 
					    this.anonymousCowardName = anonymousCowardName;
 | 
				
			||||||
    this.db = db;
 | 
					    this.db = db;
 | 
				
			||||||
    this.gitManager = gitManager;
 | 
					    this.gitManager = gitManager;
 | 
				
			||||||
@@ -140,6 +142,7 @@ public class CreateChange implements
 | 
				
			|||||||
    this.submitType = config
 | 
					    this.submitType = config
 | 
				
			||||||
        .getEnum("project", null, "submitType", SubmitType.MERGE_IF_NECESSARY);
 | 
					        .getEnum("project", null, "submitType", SubmitType.MERGE_IF_NECESSARY);
 | 
				
			||||||
    this.mergeUtilFactory = mergeUtilFactory;
 | 
					    this.mergeUtilFactory = mergeUtilFactory;
 | 
				
			||||||
 | 
					    this.notifyUtil = notifyUtil;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @Override
 | 
					  @Override
 | 
				
			||||||
@@ -269,6 +272,8 @@ public class CreateChange implements
 | 
				
			|||||||
      ins.setTopic(topic);
 | 
					      ins.setTopic(topic);
 | 
				
			||||||
      ins.setDraft(input.status == ChangeStatus.DRAFT);
 | 
					      ins.setDraft(input.status == ChangeStatus.DRAFT);
 | 
				
			||||||
      ins.setGroups(groups);
 | 
					      ins.setGroups(groups);
 | 
				
			||||||
 | 
					      ins.setNotify(input.notify);
 | 
				
			||||||
 | 
					      ins.setAccountsToNotify(notifyUtil.resolveAccounts(input.notifyDetails));
 | 
				
			||||||
      try (BatchUpdate bu = updateFactory.create(
 | 
					      try (BatchUpdate bu = updateFactory.create(
 | 
				
			||||||
          db.get(), project, me, now)) {
 | 
					          db.get(), project, me, now)) {
 | 
				
			||||||
        bu.setRepository(git, rw, oi);
 | 
					        bu.setRepository(git, rw, oi);
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user