Support to enable/disable the issue tracker integration per project

It can now be configured per project whether the issue tracker
integration is enabled or not. To enable the issue tracker integration
for a project the project must have the following entry in its
`project.config` file in the `refs/meta/config` branch:

  [plugin "<its-name>"]
    enabled = true

If `plugin.<its-name>.enabled` is not specified in the `project.config`
file the value is inherited from the parent project. If it is also not
set on any parent project the issue integration is disabled for this
project.

By setting `plugin.<its-name>.enabled` to true in the `project.config`
of the `All-Projects` project the issue tracker integration can be
enabled by default for all projects. During the initialization of the
plugin you are asked if the issue integration should be enabled by
default for all projects and if yes this setting in the
`project.config` of the `All-Projects` project is done automatically.

With this it is now possible to support integration with multiple
issue trackers on a server. E.g. a project can choose if it wants to
enable integration with Jira or with Bugzilla.

This uses new functionality in Gerrit and hence the Gerrit API
version needs to be changed to 2.9-SNAPSHOT.

Change-Id: I23edfb28006b8a34de985d13a2240dda022c4683
Signed-off-by: Edwin Kempin <edwin.kempin@sap.com>
diff --git a/its-base/src/main/java/com/googlesource/gerrit/plugins/hooks/ItsHookModule.java b/its-base/src/main/java/com/googlesource/gerrit/plugins/hooks/ItsHookModule.java
index 95c3e2c..53d1d17 100644
--- a/its-base/src/main/java/com/googlesource/gerrit/plugins/hooks/ItsHookModule.java
+++ b/its-base/src/main/java/com/googlesource/gerrit/plugins/hooks/ItsHookModule.java
@@ -19,6 +19,7 @@
 import com.google.gerrit.server.config.FactoryModule;
 import com.google.gerrit.server.git.validators.CommitValidationListener;
 
+import com.googlesource.gerrit.plugins.hooks.its.ItsConfig;
 import com.googlesource.gerrit.plugins.hooks.validation.ItsValidateComment;
 import com.googlesource.gerrit.plugins.hooks.workflow.ActionRequest;
 import com.googlesource.gerrit.plugins.hooks.workflow.Condition;
@@ -38,6 +39,7 @@
 
   @Override
   protected void configure() {
+    bind(ItsConfig.class);
     DynamicSet.bind(binder(), ChangeListener.class).to(
         GerritHookFilterAddRelatedLinkToChangeId.class);
     DynamicSet.bind(binder(), ChangeListener.class).to(
diff --git a/its-base/src/main/java/com/googlesource/gerrit/plugins/hooks/its/InitIts.java b/its-base/src/main/java/com/googlesource/gerrit/plugins/hooks/its/InitIts.java
index c7d9251..6e1f24a 100644
--- a/its-base/src/main/java/com/googlesource/gerrit/plugins/hooks/its/InitIts.java
+++ b/its-base/src/main/java/com/googlesource/gerrit/plugins/hooks/its/InitIts.java
@@ -14,10 +14,16 @@
 
 package com.googlesource.gerrit.plugins.hooks.its;
 
+import com.google.gerrit.pgm.init.AllProjectsConfig;
 import com.google.gerrit.pgm.init.InitStep;
 import com.google.gerrit.pgm.init.Section;
 import com.google.gerrit.pgm.util.ConsoleUI;
 
+import org.eclipse.jgit.errors.ConfigInvalidException;
+import org.eclipse.jgit.lib.Config;
+
+import java.io.IOException;
+
 public class InitIts implements InitStep {
 
   public static String COMMENT_LINK_SECTION = "commentLink";
@@ -26,11 +32,40 @@
     TRUE, FALSE;
   }
 
-  @Override
-  public void run() throws Exception {
+  private final String pluginName;
+  private final String itsDisplayName;
+  protected final ConsoleUI ui;
+  private final AllProjectsConfig allProjectsConfig;
+
+  public InitIts(String pluginName, String itsDisplayName, ConsoleUI ui,
+      AllProjectsConfig allProjectsConfig) {
+    this.pluginName = pluginName;
+    this.itsDisplayName = itsDisplayName;
+    this.ui = ui;
+    this.allProjectsConfig = allProjectsConfig;
   }
 
-  public boolean isConnectivityRequested(ConsoleUI ui, String url) {
+  @Override
+  public void run() {
+  }
+
+  @Override
+  public void postRun() throws IOException, ConfigInvalidException {
+    Config cfg = allProjectsConfig.load();
+    ui.message("\n");
+    ui.header(itsDisplayName + " Integration");
+    boolean enabled =
+        ui.yesno(cfg.getBoolean("plugin", pluginName, "enabled", false),
+            "By default enabled for all projects");
+    if (enabled) {
+      cfg.setBoolean("plugin", pluginName, "enabled", enabled);
+    } else {
+      cfg.unset("plugin", pluginName, "enabled");
+    }
+    allProjectsConfig.save(pluginName, "Initialize " + itsDisplayName + " Integration");
+  }
+
+  public boolean isConnectivityRequested(String url) {
     return ui.yesno(false, "Test connectivity to %s", url);
   }
 
@@ -38,8 +73,4 @@
     return TrueFalseEnum.TRUE == section.select("Verify SSL Certificates",
         "sslVerify", TrueFalseEnum.TRUE);
   }
-
-  @Override
-  public void postRun() throws Exception {
-  }
 }
diff --git a/its-base/src/main/java/com/googlesource/gerrit/plugins/hooks/its/ItsConfig.java b/its-base/src/main/java/com/googlesource/gerrit/plugins/hooks/its/ItsConfig.java
new file mode 100644
index 0000000..2aea591
--- /dev/null
+++ b/its-base/src/main/java/com/googlesource/gerrit/plugins/hooks/its/ItsConfig.java
@@ -0,0 +1,74 @@
+// Copyright (C) 2013 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.googlesource.gerrit.plugins.hooks.its;
+
+import com.google.gerrit.extensions.annotations.PluginName;
+import com.google.gerrit.reviewdb.client.Project;
+import com.google.gerrit.server.config.PluginConfigFactory;
+import com.google.gerrit.server.events.ChangeAbandonedEvent;
+import com.google.gerrit.server.events.ChangeEvent;
+import com.google.gerrit.server.events.ChangeMergedEvent;
+import com.google.gerrit.server.events.ChangeRestoredEvent;
+import com.google.gerrit.server.events.CommentAddedEvent;
+import com.google.gerrit.server.events.PatchSetCreatedEvent;
+import com.google.gerrit.server.events.RefUpdatedEvent;
+import com.google.gerrit.server.project.NoSuchProjectException;
+import com.google.inject.Inject;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ItsConfig {
+  private static final Logger log = LoggerFactory.getLogger(ItsConfig.class);
+
+  private final String pluginName;
+  private final PluginConfigFactory pluginCfgFactory;
+
+  @Inject
+  public ItsConfig(@PluginName String pluginName, PluginConfigFactory pluginCfgFactory) {
+    this.pluginName = pluginName;
+    this.pluginCfgFactory = pluginCfgFactory;
+  }
+
+  public boolean isEnabled(ChangeEvent event) {
+    if (event instanceof PatchSetCreatedEvent) {
+      return isEnabled(((PatchSetCreatedEvent) event).change.project);
+    } else if (event instanceof CommentAddedEvent) {
+      return isEnabled(((CommentAddedEvent) event).change.project);
+    } else if (event instanceof ChangeMergedEvent) {
+      return isEnabled(((ChangeMergedEvent) event).change.project);
+    } else if (event instanceof ChangeAbandonedEvent) {
+      return isEnabled(((ChangeAbandonedEvent) event).change.project);
+    } else if (event instanceof ChangeRestoredEvent) {
+      return isEnabled(((ChangeRestoredEvent) event).change.project);
+    } else if (event instanceof RefUpdatedEvent) {
+      return isEnabled(((RefUpdatedEvent) event).refUpdate.project);
+    } else {
+      log.debug("Event " + event + " not recognised and ignored");
+      return false;
+    }
+  }
+
+  public boolean isEnabled(String project) {
+    try {
+      return pluginCfgFactory.getFromProjectConfigWithInheritance(
+          new Project.NameKey(project), pluginName).getBoolean("enabled", false);
+    } catch (NoSuchProjectException e) {
+      log.error("Failed to check if " + pluginName + " is enabled for project "
+          + project, e);
+      return false;
+    }
+  }
+}
diff --git a/its-base/src/main/java/com/googlesource/gerrit/plugins/hooks/validation/ItsValidateComment.java b/its-base/src/main/java/com/googlesource/gerrit/plugins/hooks/validation/ItsValidateComment.java
index ddc108d..bf00f13 100644
--- a/its-base/src/main/java/com/googlesource/gerrit/plugins/hooks/validation/ItsValidateComment.java
+++ b/its-base/src/main/java/com/googlesource/gerrit/plugins/hooks/validation/ItsValidateComment.java
@@ -33,6 +33,7 @@
 import com.google.gerrit.server.git.validators.CommitValidationMessage;
 import com.google.inject.Inject;
 
+import com.googlesource.gerrit.plugins.hooks.its.ItsConfig;
 import com.googlesource.gerrit.plugins.hooks.its.ItsFacade;
 import com.googlesource.gerrit.plugins.hooks.util.IssueExtractor;
 
@@ -52,6 +53,9 @@
   private String pluginName;
 
   @Inject
+  private ItsConfig itsConfig;
+
+  @Inject
   private IssueExtractor issueExtractor;
 
   private List<CommitValidationMessage> validCommit(ReceiveCommand cmd, RevCommit commit) throws CommitValidationException {
@@ -150,6 +154,10 @@
   @Override
   public List<CommitValidationMessage> onCommitReceived(
       CommitReceivedEvent receiveEvent) throws CommitValidationException {
-    return validCommit(receiveEvent.command, receiveEvent.commit);
+    if (itsConfig.isEnabled(receiveEvent.project.getName())) {
+      return validCommit(receiveEvent.command, receiveEvent.commit);
+    } else {
+      return Collections.emptyList();
+    }
   }
 }
diff --git a/its-base/src/main/java/com/googlesource/gerrit/plugins/hooks/workflow/ActionController.java b/its-base/src/main/java/com/googlesource/gerrit/plugins/hooks/workflow/ActionController.java
index 16657fb..9b5f4c6 100644
--- a/its-base/src/main/java/com/googlesource/gerrit/plugins/hooks/workflow/ActionController.java
+++ b/its-base/src/main/java/com/googlesource/gerrit/plugins/hooks/workflow/ActionController.java
@@ -20,6 +20,8 @@
 import com.google.gerrit.common.ChangeListener;
 import com.google.gerrit.server.events.ChangeEvent;
 import com.google.inject.Inject;
+
+import com.googlesource.gerrit.plugins.hooks.its.ItsConfig;
 import com.googlesource.gerrit.plugins.hooks.util.PropertyExtractor;
 
 /**
@@ -32,17 +34,23 @@
   private final PropertyExtractor propertyExtractor;
   private final RuleBase ruleBase;
   private final ActionExecutor actionExecutor;
+  private final ItsConfig itsConfig;
 
   @Inject
   public ActionController(PropertyExtractor propertyExtractor,
-      RuleBase ruleBase, ActionExecutor actionExecutor) {
+      RuleBase ruleBase, ActionExecutor actionExecutor, ItsConfig itsConfig) {
     this.propertyExtractor = propertyExtractor;
     this.ruleBase = ruleBase;
     this.actionExecutor = actionExecutor;
+    this.itsConfig = itsConfig;
   }
 
   @Override
   public void onChangeEvent(ChangeEvent event) {
+    if (!itsConfig.isEnabled(event)) {
+      return;
+    }
+
     Set<Set<Property>> propertiesCollections =
         propertyExtractor.extractFrom(event);
     for (Set<Property> properties : propertiesCollections) {
diff --git a/its-base/src/main/java/com/googlesource/gerrit/plugins/hooks/workflow/GerritHookFilter.java b/its-base/src/main/java/com/googlesource/gerrit/plugins/hooks/workflow/GerritHookFilter.java
index 4a5670d..6ab647c 100644
--- a/its-base/src/main/java/com/googlesource/gerrit/plugins/hooks/workflow/GerritHookFilter.java
+++ b/its-base/src/main/java/com/googlesource/gerrit/plugins/hooks/workflow/GerritHookFilter.java
@@ -29,6 +29,8 @@
 import com.google.gerrit.server.events.RefUpdatedEvent;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
+
+import com.googlesource.gerrit.plugins.hooks.its.ItsConfig;
 import com.googlesource.gerrit.plugins.hooks.util.CommitMessageFetcher;
 
 public class GerritHookFilter implements ChangeListener {
@@ -37,6 +39,9 @@
   @Inject
   private CommitMessageFetcher commitMessageFetcher;
 
+  @Inject
+  private ItsConfig itsConfig;
+
   public String getComment(String projectName, String commitId)
       throws IOException {
     return commitMessageFetcher.fetch(projectName, commitId);
@@ -65,6 +70,10 @@
 
   @Override
   public void onChangeEvent(ChangeEvent event) {
+    if (!itsConfig.isEnabled(event)) {
+      return;
+    }
+
     try {
       if (event instanceof PatchSetCreatedEvent) {
         doFilter((PatchSetCreatedEvent) event);
diff --git a/its-base/src/main/resources/Documentation/config.md b/its-base/src/main/resources/Documentation/config.md
index 3cab393..fd238b1 100644
--- a/its-base/src/main/resources/Documentation/config.md
+++ b/its-base/src/main/resources/Documentation/config.md
@@ -24,6 +24,32 @@
 configured through a xref:config-rule-base[rule base] in
 `etc/its/action.config`.
 
+It can be configured per project whether the issue tracker
+integration is enabled or not. To enable the issue tracker integration
+for a project the project must have the following entry in its
+`project.config` file in the `refs/meta/config` branch:
+
+```
+  [plugin "<its-name>"]
+    enabled = true
+```
+
+If `plugin.<its-name>.enabled` is not specified in the `project.config`
+file the value is inherited from the parent project. If it is also not
+set on any parent project the issue integration is disabled for this
+project.
+
+By setting `plugin.<its-name>.enabled` to true in the `project.config`
+of the `All-Projects` project the issue tracker integration can be
+enabled by default for all projects. During the initialization of the
+plugin you are asked if the issue integration should be enabled by
+default for all projects and if yes this setting in the
+`project.config` of the `All-Projects` project is done automatically.
+
+With this it is possible to support integration with multiple
+issue tracker systems on a server. E.g. a project can choose if it
+wants to enable integration with Jira or with Bugzilla.
+
 
 
 [[config-rule-base]]
diff --git a/its-base/src/test/java/com/googlesource/gerrit/plugins/hooks/validation/ItsValidateCommentTest.java b/its-base/src/test/java/com/googlesource/gerrit/plugins/hooks/validation/ItsValidateCommentTest.java
index 78eec51..d0119a9 100644
--- a/its-base/src/test/java/com/googlesource/gerrit/plugins/hooks/validation/ItsValidateCommentTest.java
+++ b/its-base/src/test/java/com/googlesource/gerrit/plugins/hooks/validation/ItsValidateCommentTest.java
@@ -29,6 +29,7 @@
 import org.powermock.modules.junit4.PowerMockRunner;
 
 import com.google.gerrit.extensions.annotations.PluginName;
+import com.google.gerrit.reviewdb.client.Project;
 import com.google.gerrit.server.config.FactoryModule;
 import com.google.gerrit.server.config.GerritServerConfig;
 import com.google.gerrit.server.events.CommitReceivedEvent;
@@ -37,11 +38,10 @@
 import com.google.inject.Guice;
 import com.google.inject.Injector;
 
+import com.googlesource.gerrit.plugins.hooks.its.ItsConfig;
 import com.googlesource.gerrit.plugins.hooks.its.ItsFacade;
 import com.googlesource.gerrit.plugins.hooks.testutil.LoggingMockingTestCase;
 import com.googlesource.gerrit.plugins.hooks.util.IssueExtractor;
-import com.googlesource.gerrit.plugins.hooks.validation.ItsAssociationPolicy;
-import com.googlesource.gerrit.plugins.hooks.validation.ItsValidateComment;
 
 @RunWith(PowerMockRunner.class)
 @PrepareForTest({RevCommit.class})
@@ -50,13 +50,14 @@
   private Config serverConfig;
   private IssueExtractor issueExtractor;
   private ItsFacade itsFacade;
+  private Project project = new Project(new Project.NameKey("myProject"));
 
   public void testOptional() throws CommitValidationException {
     List<CommitValidationMessage> ret;
     ItsValidateComment ivc = injector.getInstance(ItsValidateComment.class);
     ReceiveCommand command = createMock(ReceiveCommand.class);
     RevCommit commit = createMock(RevCommit.class);
-    CommitReceivedEvent event = new CommitReceivedEvent(command, null, null,
+    CommitReceivedEvent event = new CommitReceivedEvent(command, project, null,
         commit, null);
     expect(serverConfig.getEnum("commentLink", "ItsTestName", "association",
         ItsAssociationPolicy.OPTIONAL)).andReturn(
@@ -73,7 +74,7 @@
     ItsValidateComment ivc = injector.getInstance(ItsValidateComment.class);
     ReceiveCommand command = createMock(ReceiveCommand.class);
     RevCommit commit = createMock(RevCommit.class);
-    CommitReceivedEvent event = new CommitReceivedEvent(command, null, null,
+    CommitReceivedEvent event = new CommitReceivedEvent(command, project, null,
         commit, null);
     expect(serverConfig.getEnum("commentLink", "ItsTestName", "association",
         ItsAssociationPolicy.OPTIONAL)).andReturn(
@@ -101,7 +102,7 @@
     ItsValidateComment ivc = injector.getInstance(ItsValidateComment.class);
     ReceiveCommand command = createMock(ReceiveCommand.class);
     RevCommit commit = createMock(RevCommit.class);
-    CommitReceivedEvent event = new CommitReceivedEvent(command, null, null,
+    CommitReceivedEvent event = new CommitReceivedEvent(command, project, null,
         commit, null);
     expect(serverConfig.getEnum("commentLink", "ItsTestName", "association",
         ItsAssociationPolicy.OPTIONAL)).andReturn(
@@ -131,7 +132,7 @@
     ItsValidateComment ivc = injector.getInstance(ItsValidateComment.class);
     ReceiveCommand command = createMock(ReceiveCommand.class);
     RevCommit commit = createMock(RevCommit.class);
-    CommitReceivedEvent event = new CommitReceivedEvent(command, null, null,
+    CommitReceivedEvent event = new CommitReceivedEvent(command, project, null,
         commit, null);
     expect(serverConfig.getEnum("commentLink", "ItsTestName", "association",
         ItsAssociationPolicy.OPTIONAL)).andReturn(
@@ -157,7 +158,7 @@
     ItsValidateComment ivc = injector.getInstance(ItsValidateComment.class);
     ReceiveCommand command = createMock(ReceiveCommand.class);
     RevCommit commit = createMock(RevCommit.class);
-    CommitReceivedEvent event = new CommitReceivedEvent(command, null, null,
+    CommitReceivedEvent event = new CommitReceivedEvent(command, project, null,
         commit, null);
     expect(serverConfig.getEnum("commentLink", "ItsTestName", "association",
         ItsAssociationPolicy.OPTIONAL)).andReturn(
@@ -183,7 +184,7 @@
     ItsValidateComment ivc = injector.getInstance(ItsValidateComment.class);
     ReceiveCommand command = createMock(ReceiveCommand.class);
     RevCommit commit = createMock(RevCommit.class);
-    CommitReceivedEvent event = new CommitReceivedEvent(command, null, null,
+    CommitReceivedEvent event = new CommitReceivedEvent(command, project, null,
         commit, null);
     expect(serverConfig.getEnum("commentLink", "ItsTestName", "association",
         ItsAssociationPolicy.OPTIONAL)).andReturn(
@@ -213,7 +214,7 @@
     ItsValidateComment ivc = injector.getInstance(ItsValidateComment.class);
     ReceiveCommand command = createMock(ReceiveCommand.class);
     RevCommit commit = createMock(RevCommit.class);
-    CommitReceivedEvent event = new CommitReceivedEvent(command, null, null,
+    CommitReceivedEvent event = new CommitReceivedEvent(command, project, null,
         commit, null);
     expect(serverConfig.getEnum("commentLink", "ItsTestName", "association",
         ItsAssociationPolicy.OPTIONAL)).andReturn(
@@ -243,7 +244,7 @@
     ItsValidateComment ivc = injector.getInstance(ItsValidateComment.class);
     ReceiveCommand command = createMock(ReceiveCommand.class);
     RevCommit commit = createMock(RevCommit.class);
-    CommitReceivedEvent event = new CommitReceivedEvent(command, null, null,
+    CommitReceivedEvent event = new CommitReceivedEvent(command, project, null,
         commit, null);
     expect(serverConfig.getEnum("commentLink", "ItsTestName", "association",
         ItsAssociationPolicy.OPTIONAL)).andReturn(
@@ -271,7 +272,7 @@
     ItsValidateComment ivc = injector.getInstance(ItsValidateComment.class);
     ReceiveCommand command = createMock(ReceiveCommand.class);
     RevCommit commit = createMock(RevCommit.class);
-    CommitReceivedEvent event = new CommitReceivedEvent(command, null, null,
+    CommitReceivedEvent event = new CommitReceivedEvent(command, project, null,
         commit, null);
     expect(serverConfig.getEnum("commentLink", "ItsTestName", "association",
         ItsAssociationPolicy.OPTIONAL)).andReturn(
@@ -299,7 +300,7 @@
     ItsValidateComment ivc = injector.getInstance(ItsValidateComment.class);
     ReceiveCommand command = createMock(ReceiveCommand.class);
     RevCommit commit = createMock(RevCommit.class);
-    CommitReceivedEvent event = new CommitReceivedEvent(command, null, null,
+    CommitReceivedEvent event = new CommitReceivedEvent(command, project, null,
         commit, null);
     expect(serverConfig.getEnum("commentLink", "ItsTestName", "association",
         ItsAssociationPolicy.OPTIONAL)).andReturn(
@@ -333,7 +334,7 @@
     ItsValidateComment ivc = injector.getInstance(ItsValidateComment.class);
     ReceiveCommand command = createMock(ReceiveCommand.class);
     RevCommit commit = createMock(RevCommit.class);
-    CommitReceivedEvent event = new CommitReceivedEvent(command, null, null,
+    CommitReceivedEvent event = new CommitReceivedEvent(command, project, null,
         commit, null);
     expect(serverConfig.getEnum("commentLink", "ItsTestName", "association",
         ItsAssociationPolicy.OPTIONAL)).andReturn(
@@ -365,7 +366,7 @@
     ItsValidateComment ivc = injector.getInstance(ItsValidateComment.class);
     ReceiveCommand command = createMock(ReceiveCommand.class);
     RevCommit commit = createMock(RevCommit.class);
-    CommitReceivedEvent event = new CommitReceivedEvent(command, null, null,
+    CommitReceivedEvent event = new CommitReceivedEvent(command, project, null,
         commit, null);
     expect(serverConfig.getEnum("commentLink", "ItsTestName", "association",
         ItsAssociationPolicy.OPTIONAL)).andReturn(
@@ -399,7 +400,7 @@
     ItsValidateComment ivc = injector.getInstance(ItsValidateComment.class);
     ReceiveCommand command = createMock(ReceiveCommand.class);
     RevCommit commit = createMock(RevCommit.class);
-    CommitReceivedEvent event = new CommitReceivedEvent(command, null, null,
+    CommitReceivedEvent event = new CommitReceivedEvent(command, project, null,
         commit, null);
     expect(serverConfig.getEnum("commentLink", "ItsTestName", "association",
         ItsAssociationPolicy.OPTIONAL)).andReturn(
@@ -431,7 +432,7 @@
     ItsValidateComment ivc = injector.getInstance(ItsValidateComment.class);
     ReceiveCommand command = createMock(ReceiveCommand.class);
     RevCommit commit = createMock(RevCommit.class);
-    CommitReceivedEvent event = new CommitReceivedEvent(command, null, null,
+    CommitReceivedEvent event = new CommitReceivedEvent(command, project, null,
         commit, null);
     expect(serverConfig.getEnum("commentLink", "ItsTestName", "association",
         ItsAssociationPolicy.OPTIONAL)).andReturn(
@@ -510,6 +511,13 @@
 
       itsFacade = createMock(ItsFacade.class);
       bind(ItsFacade.class).toInstance(itsFacade);
+
+      bind(ItsConfig.class).toInstance(new ItsConfig(null, null) {
+        @Override
+        public boolean isEnabled(String project) {
+          return true;
+        }
+      });
     }
   }
 }
diff --git a/its-base/src/test/java/com/googlesource/gerrit/plugins/hooks/workflow/ActionControllerTest.java b/its-base/src/test/java/com/googlesource/gerrit/plugins/hooks/workflow/ActionControllerTest.java
index d6c9c2d..428375d 100644
--- a/its-base/src/test/java/com/googlesource/gerrit/plugins/hooks/workflow/ActionControllerTest.java
+++ b/its-base/src/test/java/com/googlesource/gerrit/plugins/hooks/workflow/ActionControllerTest.java
@@ -25,6 +25,8 @@
 import com.google.gerrit.server.events.ChangeEvent;
 import com.google.inject.Guice;
 import com.google.inject.Injector;
+
+import com.googlesource.gerrit.plugins.hooks.its.ItsConfig;
 import com.googlesource.gerrit.plugins.hooks.testutil.LoggingMockingTestCase;
 import com.googlesource.gerrit.plugins.hooks.util.PropertyExtractor;
 
@@ -195,6 +197,13 @@
 
       actionExecutor = createMock(ActionExecutor.class);
       bind(ActionExecutor.class).toInstance(actionExecutor);
+
+      bind(ItsConfig.class).toInstance(new ItsConfig(null, null) {
+        @Override
+        public boolean isEnabled(ChangeEvent event) {
+          return true;
+        }
+      });
     }
   }
 }
\ No newline at end of file