Merge "transpose typo'd characters"
diff --git a/tests/base.py b/tests/base.py
index 8c96d18..535bb7f 100755
--- a/tests/base.py
+++ b/tests/base.py
@@ -892,6 +892,7 @@
         self.init_repo("org/conflict-project")
         self.init_repo("org/noop-project")
         self.init_repo("org/experimental-project")
+        self.init_repo("org/no-jobs-project")
 
         self.statsd = FakeStatsd()
         os.environ['STATSD_HOST'] = 'localhost'
diff --git a/tests/fixtures/layout.yaml b/tests/fixtures/layout.yaml
index cc4d34c..1d23443 100644
--- a/tests/fixtures/layout.yaml
+++ b/tests/fixtures/layout.yaml
@@ -246,3 +246,7 @@
   - name: org/experimental-project
     experimental:
       - experimental-project-test
+
+  - name: org/no-jobs-project
+    check:
+      - project-testfile
diff --git a/tests/test_scheduler.py b/tests/test_scheduler.py
index 3b59e3e..032a8f8 100755
--- a/tests/test_scheduler.py
+++ b/tests/test_scheduler.py
@@ -1878,6 +1878,23 @@
         self.assertEqual(A.data['status'], 'MERGED')
         self.assertEqual(A.reported, 2)
 
+    def test_no_job_project(self):
+        "Test that reports with no jobs don't get sent"
+        A = self.fake_gerrit.addFakeChange('org/no-jobs-project',
+                                           'master', 'A')
+        self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
+        self.waitUntilSettled()
+
+        # Change wasn't reported to
+        self.assertEqual(A.reported, False)
+
+        # Check queue is empty afterwards
+        check_pipeline = self.sched.layout.pipelines['check']
+        items = check_pipeline.getAllItems()
+        self.assertEqual(len(items), 0)
+
+        self.assertEqual(len(self.history), 0)
+
     def test_zuul_refs(self):
         "Test that zuul refs exist and have the right changes"
         self.worker.hold_jobs_in_build = True
diff --git a/zuul/model.py b/zuul/model.py
index 4d402ff..4b907c3 100644
--- a/zuul/model.py
+++ b/zuul/model.py
@@ -735,7 +735,13 @@
         ret['items_behind'] = [i.change._id() for i in self.items_behind]
         ret['failing_reasons'] = self.current_build_set.failing_reasons
         ret['zuul_ref'] = self.current_build_set.ref
-        ret['project'] = changeish.project.name
+        if changeish.project:
+            ret['project'] = changeish.project.name
+        else:
+            # For cross-project dependencies with the depends-on
+            # project not known to zuul, the project is None
+            # Set it to a static value
+            ret['project'] = "Unknown Project"
         ret['enqueue_time'] = int(self.enqueue_time * 1000)
         ret['jobs'] = []
         if hasattr(changeish, 'owner'):
diff --git a/zuul/scheduler.py b/zuul/scheduler.py
index 131ad62..39d19b8 100644
--- a/zuul/scheduler.py
+++ b/zuul/scheduler.py
@@ -1521,7 +1521,13 @@
     def _reportItem(self, item):
         self.log.debug("Reporting change %s" % item.change)
         ret = True  # Means error as returned by trigger.report
-        if self.pipeline.didAllJobsSucceed(item):
+        if not self.pipeline.getJobs(item):
+            # We don't send empty reports with +1,
+            # and the same for -1's (merge failures or transient errors)
+            # as they cannot be followed by +1's
+            self.log.debug("No jobs for change %s" % item.change)
+            actions = []
+        elif self.pipeline.didAllJobsSucceed(item):
             self.log.debug("success %s" % (self.pipeline.success_actions))
             actions = self.pipeline.success_actions
             item.setReportedResult('SUCCESS')