add invalid subtask in case of invalid task factory config

Before the change, missing preload-task in task factory makes the parent
task invalid, which is not consistent with how invalid config is handled
in case of subtasks, subtask files and subtask externals. Handle
invalid task factory config by adding invalid subtask to make the logic
consistent with the rest.

Change-Id: I88288e6709c2667c689a2bd0b9c1531e18ff68a5
diff --git a/src/main/java/com/googlesource/gerrit/plugins/task/TaskTree.java b/src/main/java/com/googlesource/gerrit/plugins/task/TaskTree.java
index 4d46c7c..2f0210f 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/task/TaskTree.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/task/TaskTree.java
@@ -431,7 +431,11 @@
           if (StringUtils.isEmptyOrNull(name)) {
             addInvalidNode();
           } else {
-            addPreloaded(preloader.preload(task.config.new Task(tasksFactory, name)));
+            try {
+              addPreloaded(preloader.preload(task.config.new Task(tasksFactory, name)));
+            } catch (ConfigInvalidException e) {
+              addInvalidNode();
+            }
           }
         }
       }
@@ -450,7 +454,7 @@
           }
         } catch (StorageException e) {
           log.atSevere().withCause(e).log("ERROR: running changes query: " + namesFactory.changes);
-        } catch (QueryParseException e) {
+        } catch (QueryParseException | ConfigInvalidException e) {
         }
         addInvalidNode();
       }
diff --git a/src/main/resources/Documentation/test/preview.md b/src/main/resources/Documentation/test/preview.md
index 2a436ae..502ade2 100644
--- a/src/main/resources/Documentation/test/preview.md
+++ b/src/main/resources/Documentation/test/preview.md
@@ -152,6 +152,30 @@
       {
          "applicable" : true,
          "hasPass" : false,
+         "name" : "task (tasks-factory static INVALID)",
+         "status" : "WAITING",
+         "subTasks" : [
+            {
+               "name" : "UNKNOWN",
+               "status" : "INVALID"
+            }
+         ]
+      },
+      {
+         "applicable" : true,
+         "hasPass" : false,
+         "name" : "task (tasks-factory change INVALID)",
+         "status" : "WAITING",
+         "subTasks" : [
+            {
+               "name" : "UNKNOWN",
+               "status" : "INVALID"
+            }
+         ]
+      },
+      {
+         "applicable" : true,
+         "hasPass" : false,
          "name" : "task (names-factory type missing)",
          "status" : "WAITING",
          "subTasks" : [
@@ -484,6 +508,30 @@
       {
          "applicable" : true,
          "hasPass" : false,
+         "name" : "task (tasks-factory static INVALID)",
+         "status" : "WAITING",
+         "subTasks" : [
+            {
+               "name" : "UNKNOWN",
+               "status" : "INVALID"
+            }
+         ]
+      },
+      {
+         "applicable" : true,
+         "hasPass" : false,
+         "name" : "task (tasks-factory change INVALID)",
+         "status" : "WAITING",
+         "subTasks" : [
+            {
+               "name" : "UNKNOWN",
+               "status" : "INVALID"
+            }
+         ]
+      },
+      {
+         "applicable" : true,
+         "hasPass" : false,
          "name" : "task (names-factory type missing)",
          "status" : "WAITING",
          "subTasks" : [
diff --git a/src/main/resources/Documentation/test/task_states.md b/src/main/resources/Documentation/test/task_states.md
index f5d4cd8..c5881c6 100644
--- a/src/main/resources/Documentation/test/task_states.md
+++ b/src/main/resources/Documentation/test/task_states.md
@@ -2316,6 +2316,30 @@
       {
          "applicable" : true,
          "hasPass" : false,
+         "name" : "task (tasks-factory static INVALID)",
+         "status" : "WAITING",
+         "subTasks" : [
+            {
+               "name" : "UNKNOWN",
+               "status" : "INVALID"
+            }
+         ]
+      },
+      {
+         "applicable" : true,
+         "hasPass" : false,
+         "name" : "task (tasks-factory change INVALID)",
+         "status" : "WAITING",
+         "subTasks" : [
+            {
+               "name" : "UNKNOWN",
+               "status" : "INVALID"
+            }
+         ]
+      },
+      {
+         "applicable" : true,
+         "hasPass" : false,
          "name" : "task (names-factory type missing)",
          "status" : "WAITING",
          "subTasks" : [
@@ -2583,6 +2607,30 @@
       {
          "applicable" : true,
          "hasPass" : false,
+         "name" : "task (tasks-factory static INVALID)",
+         "status" : "WAITING",
+         "subTasks" : [
+            {
+               "name" : "UNKNOWN",
+               "status" : "INVALID"
+            }
+         ]
+      },
+      {
+         "applicable" : true,
+         "hasPass" : false,
+         "name" : "task (tasks-factory change INVALID)",
+         "status" : "WAITING",
+         "subTasks" : [
+            {
+               "name" : "UNKNOWN",
+               "status" : "INVALID"
+            }
+         ]
+      },
+      {
+         "applicable" : true,
+         "hasPass" : false,
          "name" : "task (names-factory type missing)",
          "status" : "WAITING",
          "subTasks" : [
@@ -2745,6 +2793,12 @@
 [task "task (tasks-factory missing)"]
   subtasks-factory = missing
 
+[task "task (tasks-factory static INVALID)"]
+  subtasks-factory = tasks-factory (preload-task missing)
+
+[task "task (tasks-factory change INVALID)"]
+  subtasks-factory = tasks-factory change (preload-task missing)
+
 [task "task (names-factory type missing)"]
   subtasks-factory = tasks-factory (names-factory type missing)
 
@@ -2770,6 +2824,16 @@
   names-factory = names-factory (type missing)
   fail = True
 
+[tasks-factory "tasks-factory (preload-task missing)"]
+  names-factory = names-factory static
+  fail = True
+  preload-task = missing
+
+[tasks-factory "tasks-factory change (preload-task missing)"]
+  names-factory = names-factory change list
+  fail = True
+  preload-task = missing
+
 [tasks-factory "tasks-factory (names-factory type INVALID)"]
   names-factory = name-factory (type INVALID)
 
@@ -2793,6 +2857,14 @@
   names-factory = names-factory change list (changes invalid)
   fail = True
 
+[names-factory "names-factory static"]
+  name = task A
+  type = static
+
+[names-factory "names-factory change list"]
+  changes = change:_change1_number OR change:_change2_number
+  type = change
+
 [names-factory "names-factory (type missing)"]
   name = no type test