Repository: Nitrate/Nitrate

Issue:
Error when generate report from "By Case-Run Tester" type of Testing Report
This is reported

```
TypeError at /report/testing/

'<' not supported between instances of 'NoneType' and 'int'
```

Happened when running with PostgreSQL.


Discussion:

Resolving patch:
diff --git a/src/tcms/report/data.py b/src/tcms/report/data.py
--- a/src/tcms/report/data.py
+++ b/src/tcms/report/data.py
@@ -7,6 +7,7 @@
 from operator import attrgetter
 from operator import itemgetter
 
+
 from django.contrib.auth.models import User
 from django.db.models import Count
 
@@ -16,6 +17,7 @@
 from tcms.core.db import workaround_single_value_for_in_clause
 from tcms.management.models import Priority
 from tcms.management.models import TestBuild
+from tcms.management.models import TestTag
 from tcms.report import sqls
 from tcms.testcases.models import TestCase
 from tcms.testplans.models import TestPlan
@@ -465,9 +467,7 @@ def _get_report_data_without_builds_selected(self, form):
         tested_by_usernames = self.get_usernames(status_matrix.keys())
 
         def walk_status_matrix_rows():
-            tested_by_ids = sorted(status_matrix.iteritems(),
-                                   key=itemgetter(0))
-            for tested_by_id, status_subtotal in tested_by_ids:
+            for tested_by_id, status_subtotal in status_matrix.iteritems():
                 tested_by_username = tested_by_usernames.get(tested_by_id,
                                                              'None')
                 tested_by = None
@@ -714,13 +714,13 @@ def passed_failed_case_runs_subtotal(self, form):
 
     def get_tags_names(self, tag_ids):
         """Get tags names from status matrix"""
-        from tcms.management.models import TestTag
+        names = {
+            pk: name
+            for pk, name in TestTag.objects.filter(pk__in=tag_ids)
+                                           .values_list('pk', 'name')
+                                           .order_by('pk', 'name')
+        }
 
-        names = dict(
-            TestTag.objects.filter(pk__in=tag_ids)
-                           .values_list('pk', 'name')
-                           .iterator()
-        )
         # The existence of None tells us the fact that there are plans without
         # any tag. So, name it untagged.
         if None in tag_ids:
@@ -745,9 +745,7 @@ def _get_report_data(self, form, builds, builds_selected):
 
         def walk_status_matrix():
             status_matrix.leaf_values_count(value_in_row=True)
-            ordered_builds = sorted(status_matrix.iteritems(),
-                                    key=itemgetter(0))
-            for tag_id, builds in ordered_builds:
+            for tag_id, builds in status_matrix.iteritems():
                 # Data on top of each status matrix under each tag
                 yield tags_names.get(tag_id, 'untagged'), \
                     plans_subtotal.get(tag_id, 0), \
@@ -762,8 +760,7 @@ def walk_status_matrix():
             'reports': walk_status_matrix(),
 
             # This is only used for displaying tags in report
-            'tags_names': (
-                tags_names[key] for key in sorted(tags_names.keys())),
+            'tags_names': list(tags_names.values())
         }
 
     def walk_status_matrix_rows(self, root_matrix):
diff --git a/src/tcms/report/sqls.py b/src/tcms/report/sqls.py
--- a/src/tcms/report/sqls.py
+++ b/src/tcms/report/sqls.py
@@ -153,7 +153,9 @@
 inner join test_case_runs on (test_runs.run_id = test_case_runs.run_id)
 inner join test_case_run_status on (test_case_run_status.case_run_status_id = test_case_runs.case_run_status_id)
 where {0}
-group by test_case_runs.tested_by_id, test_case_run_status.name'''
+group by test_case_runs.tested_by_id, test_case_run_status.name
+order by test_case_runs.tested_by_id, test_case_run_status.name
+'''
 
 by_case_run_tester_runs_subtotal = '''
 select tested_by_id, count(*) as total_count
@@ -232,7 +234,10 @@
 left join test_plan_tags on (test_plans.plan_id = test_plan_tags.plan_id)
 where {0}
 group by test_plan_tags.tag_id, test_builds.build_id, test_plans.plan_id,
-    test_runs.run_id, test_case_run_status.name'''
+         test_runs.run_id, test_case_run_status.name
+order by test_plan_tags.tag_id, test_builds.build_id, test_plans.plan_id,
+         test_runs.run_id, test_case_run_status.name
+'''
 
 ### Report data of By Plan Build ###
 


Test patch: