Repository: ioos/compliance-checker
Pull request #789 (2020-04-02 18:56:59)

Fix flag messages HTML output
Fixes an issue referenced in https://github.com/ioos/compliance-checker/issues/780 where unescaped HTML would be printed in the HTML format.

Also changes flag_masks error message to be slightly more readable.


Patch:
diff --git a/compliance_checker/base.py b/compliance_checker/base.py
index 5f06f29..0928fb8 100644
--- a/compliance_checker/base.py
+++ b/compliance_checker/base.py
@@ -77,10 +77,11 @@ class ValidationObject(object):
             type_result = self.validate_type(input_name, input_value)
             if not type_result[0]:
                 return type_result
+        validator_stat = True
         for processed_value in self.split_func(input_value):
             validator_result = self.validator_func(processed_value)
             if not validator_result:
-                return False, [self.validator_fail_msg.format(input_name)]
+                return False, self.validator_fail_msg.format(input_name)
         # if all pass, then we're good.
         return True, None
 
@@ -464,9 +465,7 @@ def attr_check(kvp, ds, priority, ret_val, gname=None, var_name=None):
         else:
             check_val = attr_result[1]
             res_tup = other.validate(name, check_val)
-
-        msgs = [] if res_tup[1] is None else res_tup[1]
-
+            msgs = [] if res_tup[1] is None else [res_tup[1]]
         ret_val.append(
             Result(
                 priority,
diff --git a/compliance_checker/cf/cf.py b/compliance_checker/cf/cf.py
index 1c3d206..a013185 100644
--- a/compliance_checker/cf/cf.py
+++ b/compliance_checker/cf/cf.py
@@ -2006,7 +2006,7 @@ class CF1_6Check(CFNCCheck):
         valid_masks = TestCtx(BaseCheck.HIGH, self.section_titles['3.5'])
 
         valid_masks.assert_true(isinstance(flag_masks, np.ndarray),
-                                "{}'s flag_masks must be an array of values not {}".format(name, type(flag_masks)))
+                                "{}'s flag_masks must be an array of values not {}".format(name, type(flag_masks).__name__))
 
         if not isinstance(flag_masks, np.ndarray):
             return valid_masks.to_result()
diff --git a/compliance_checker/data/templates/ccheck.html.j2 b/compliance_checker/data/templates/ccheck.html.j2
index b398821..02d7c8a 100644
--- a/compliance_checker/data/templates/ccheck.html.j2
+++ b/compliance_checker/data/templates/ccheck.html.j2
@@ -45,18 +45,18 @@ li{
   <div class="col-md-12">
     <div class="page-header">
       <h2 align="center">IOOS Compliance Checker Report</h2>
-      <p align="center">For dataset {{source_name}}</p>
+      <p align="center">For dataset {{source_name|e}}</p>
     </div>
   </div>
   <div class="col-md-12">
     <h3 align="center">
       {% if cc_url %}
-        <a href={{cc_url}} target="_blank">{{testname}}</a>
+        <a href={{cc_url|e}} target="_blank">{{testname|e}}</a>
       {% else %}
-        {{testname}}
+        {{testname|e}}
       {% endif %}
     </h3>
-    <!--<a href={{cc_url}}>Reference Page</a>-->
+    <!--<a href={{cc_url|e}}>Reference Page</a>-->
   </div>
 
   <!-- -------------- -->
@@ -71,7 +71,7 @@ li{
       <!-- High Priority -->
 
       <div class="table-collapse">
-        <a data-target="high-priority-table" href="#"> {{scoreheader.get(3)}} <i class="glyphicon glyphicon-collapse-up"></i></a>
+        <a data-target="high-priority-table" href="#"> {{scoreheader.get(3)|e}} <i class="glyphicon glyphicon-collapse-up"></i></a>
       </div>
       {% if high_count -%}
       <div class="failures">
@@ -93,13 +93,13 @@ li{
 
                   <tr>
                     {% if result["msgs"]|length > 0 -%}
-                      <td>{{result['name']}}</td>
+                      <td>{{result['name']|e}}</td>
                       <td>
                           {% for msg in result['msgs'] -%}
 
                           <!-- bulleted list inside the table row -->
                         <ul>
-                          <li>{{msg}}</li>
+                          <li>{{msg|e}}</li>
                         </ul>
 
                         {% endfor -%}
@@ -136,7 +136,7 @@ li{
     <div class="col-md-12">
       {% if medium_count -%}
       <div class="table-collapse">
-        <a data-target="medium-priority-table" href="#"> {{scoreheader.get(2)}} <i class="glyphicon glyphicon-collapse-up"></i></a>
+        <a data-target="medium-priority-table" href="#"> {{scoreheader.get(2)|e}} <i class="glyphicon glyphicon-collapse-up"></i></a>
       </div>
       <div class="failures">
         | <span class="label label-danger label-as-badge">{{ medium_count }}</span>
@@ -156,13 +156,13 @@ li{
 
                   <tr>
                     {% if result["msgs"]|length -%}
-                      <td>{{result['name']}}</td>
+                      <td>{{result['name']|e}}</td>
                       <td>
                           {% for msg in result['msgs'] -%}
 
                           <!-- bulleted list inside the table row -->
                         <ul>
-                          <li>{{msg}}</li>
+                          <li>{{msg|e}}</li>
                         </ul>
 
                         {% endfor -%}
@@ -185,7 +185,7 @@ li{
     <div class="col-md-12">
       {% if low_count -%}
       <div class="table-collapse">
-        <a data-target="low-priority-table" href="#"> {{scoreheader.get(1)}} <i class="glyphicon glyphicon-collapse-up"></i></a>
+        <a data-target="low-priority-table" href="#"> {{scoreheader.get(1)|e}} <i class="glyphicon glyphicon-collapse-up"></i></a>
       </div>
       <div class="failures">
         | <span class="label label-danger label-as-badge">{{ low_count }}</span>
@@ -205,13 +205,13 @@ li{
 
                   <tr>
                     {% if result["msgs"]|length -%}
-                      <td>{{result['name']}}</td>
+                      <td>{{result['name']|e}}</td>
                       <td>
                           {% for msg in result['msgs'] -%}
 
                           <!-- bulleted list inside the table row -->
                         <ul>
-                          <li>{{msg}}</li>
+                          <li>{{msg|e}}</li>
                         </ul>
 
                         {% endfor -%}
diff --git a/compliance_checker/ioos.py b/compliance_checker/ioos.py
index 3a615ca..15bd396 100644
--- a/compliance_checker/ioos.py
+++ b/compliance_checker/ioos.py
@@ -420,7 +420,7 @@ class IOOS1_2Check(IOOSNCCheck):
             ("standard_name_url", BaseCheck.MEDIUM),
             #( "platform", BaseCheck.HIGH) # checked under check_single_platform()
             #( "wmo_platform_code", BaseCheck.HIGH) # only "if applicable", see check_wmo_platform_code()
-            #( "ancillary_variables", BaseCheck.HIGH) # only "if applicable", see _check_var_gts_ingest()
+            #( "ancillary_variables", BaseCheck.HIGH) # only "if applicable", see _check_var_gts_ingest() 
         ]))
 
         # geospatial vars must have the following attrs:
@@ -569,7 +569,7 @@ class IOOS1_2Check(IOOSNCCheck):
             not isinstance(igst, str) and igst is not None):
             r = False
 
-        return Result(BaseCheck.MEDIUM, r, "ioos_ingest", None if r else [m])
+        return Result(BaseCheck.MEDIUM, r, "ioos_ingest", [m])
 
     def check_contributor_role_and_vocabulary(self, ds):
         """
@@ -600,26 +600,26 @@ class IOOS1_2Check(IOOSNCCheck):
 
         if role:
             if role in [ # each in both vocabularies
-                "author",
-                "coAuthor",
-                "collaborator",
-                "contributor",
-                "custodian",
-                "distributor",
-                "editor",
-                "funder",
-                "mediator",
-                "originator",
-                "owner",
-                "pointOfContact",
+                "author",               
+                "coAuthor",             
+                "collaborator",         
+                "contributor",          
+                "custodian",            
+                "distributor",          
+                "editor",               
+                "funder",               
+                "mediator",             
+                "originator",           
+                "owner",                
+                "pointOfContact",       
                 "principalInvestigator",
-                "processor",
-                "publisher",
-                "resourceProvider",
-                "rightsHolder",
-                "sponsor",
-                "stakeholder",
-                "user"
+                "processor",            
+                "publisher",            
+                "resourceProvider",     
+                "rightsHolder",         
+                "sponsor",              
+                "stakeholder",          
+                "user"                  
             ]:
                 role_val = True
 
@@ -631,8 +631,8 @@ class IOOS1_2Check(IOOSNCCheck):
                 vocb_val = True
 
         return [
-            Result(BaseCheck.MEDIUM, role_val, "contributor_role", None if role_val else [role_msg]),
-            Result(BaseCheck.MEDIUM, vocb_val, "contributor_role_vocabulary", None if vocb_val else [vocb_msg]),
+            Result(BaseCheck.MEDIUM, role_val, "contributor_role", [role_msg]),
+            Result(BaseCheck.MEDIUM, vocb_val, "contributor_role_vocabulary", [vocb_msg]),
         ]
 
     def check_geophysical_vars_have_attrs(self, ds):
@@ -781,12 +781,12 @@ class IOOS1_2Check(IOOSNCCheck):
             if re.match(r'^\S+$', p):
                 r = True
 
-        return Result(BaseCheck.HIGH, r, "platform", None if r else [m.format(p)])
+        return Result(BaseCheck.HIGH, r, "platform", [m.format(p)])
 
     def check_single_platform(self, ds):
         """
         Verify that a dataset only has a single platform attribute. If one exists,
-        examine the featureType of the dataset. If the featureType is
+        examine the featureType of the dataset. If the featureType is 
         [point, timeSeries, profile, trajectory] and cf_role in [timeseries_id,
         profile_id, trajectory_id] dimensionality of the variable containing
         cf_role must be 1 as "we only want a single glider/auv/ship"; if
@@ -815,22 +815,23 @@ class IOOS1_2Check(IOOSNCCheck):
         if num_platforms > 1 and glb_platform:
             msg = "A dataset may only have one platform; {} found".format(len(platform_set))
             val = False
-            results.append(Result(BaseCheck.HIGH, val, "platform", None if val else [msg]))
+            results.append(Result(BaseCheck.HIGH, val, "platform", [msg]))
+
 
         elif ((not glb_platform) and num_platforms > 0):
             msg = "If platform variables exist, a global attribute \"platform\" must also exist"
             val = False
-            results.append(Result(BaseCheck.HIGH, val, "platform", None if val else [msg]))
+            results.append(Result(BaseCheck.HIGH, val, "platform", [msg]))
 
         elif num_platforms == 0 and glb_platform:
             msg = "A dataset with a global \"platform\" attribute must platform have variables"
             val = False
-            results.append(Result(BaseCheck.HIGH, val, "platform", None if val else [msg]))
+            results.append(Result(BaseCheck.HIGH, val, "platform", [msg]))
 
         elif num_platforms == 0 and (not glb_platform):
             msg = "Gridded model datasets are not required to declare a platform"
             val = True
-            results.append(Result(BaseCheck.HIGH, val, "platform", None if val else [msg]))
+            results.append(Result(BaseCheck.HIGH, val, "platform", [msg]))
 
         else: # num_platforms==1 and glb_platform, test the dimensionality
 
@@ -867,7 +868,7 @@ class IOOS1_2Check(IOOSNCCheck):
                            BaseCheck.HIGH,
                            _val,
                            "platform variables",
-                           None if _val else [msg.format(cf_role_var=var.name, cf_role=cf_role, dim=shp)]
+                           [msg.format(cf_role_var=var.name, cf_role=cf_role, dim=shp)]
                        )
                     )
 
@@ -890,8 +891,8 @@ class IOOS1_2Check(IOOSNCCheck):
         m = "platform_vocabulary must be a valid URL"
         pvocab = getattr(ds, "platform_vocabulary", "")
         val = bool(validators.url(pvocab))
-        return Result(BaseCheck.MEDIUM, val, "platform_vocabulary", None if val else [m])
-
+        return Result(BaseCheck.MEDIUM, val, "platform_vocabulary", [m])
+            
     def _check_gts_ingest_val(self, val):
         """
         Check that `val` is a str and is equal to "true" or "false"
@@ -922,15 +923,13 @@ class IOOS1_2Check(IOOSNCCheck):
         Result
         """
 
-        gts_ingest_value = getattr(ds, "gts_ingest", None)
+        r = True # default
+        gts = getattr(ds, "gts_ingest", None)
 
-        is_valid_string = True
-        if isinstance(gts_ingest_value, str):
-            is_valid_string = self._check_gts_ingest_val(gts_ingest_value)
+        if gts:
+            r = self._check_gts_ingest_val(gts)
 
-        fail_message = ["gts_ingest must be a string \"true\" or \"false\""]
-        return Result(BaseCheck.HIGH, is_valid_string, "gts_ingest",
-                      None if is_valid_string else fail_message)
+        return Result(BaseCheck.HIGH, r, "gts_ingest", ["gts_ingest must be a string \"true\" or \"false\""])
 
     def _var_qualifies_for_gts_ingest(self, ds, var):
         """
@@ -1014,42 +1013,34 @@ class IOOS1_2Check(IOOSNCCheck):
 
         # check variables
         all_passed_ingest_reqs = True # default
-        var_failed_ingest_msg = None
-        var_passed_ingest_msg = None
 
         if do_gts: # execute if dataset flagged for ingest
 
             var_passed_ingest_reqs = set()
+            var_passed_ingest_msg  = "The following variables qualifed for GTS Ingest:"
+            var_failed_ingest_msg  = "The following variables did not qualify for GTS Ingest:"
+
             for v in ds.get_variables_by_attributes(gts_ingest=lambda x: x=="true"):
                 var_passed_ingest_reqs.add((v.name, self._var_qualifies_for_gts_ingest(ds, v)))
 
-            all_passed_ingest_reqs = all(map(lambda x: x[1], var_passed_ingest_reqs))
-            if not all_passed_ingest_reqs:
-                _var_failed = map(lambda y: y[0], filter(lambda x: not x[1], var_passed_ingest_reqs))
-                _var_passed = map(lambda y: y[0], filter(lambda x: x[1], var_passed_ingest_reqs))
-
-                var_failed_ingest_msg = (
-                                            "The following variables did not "
-                                            "qualify for GTS Ingest: {}".format(
-                                                ", ".join(_var_failed),
-                                            )
-                                        )
-
-                var_passed_ingest_msg = (
-                                            "The following variables qualified "
-                                            "for GTS Ingest: {}\n".format(
-                                                  ", ".join(_var_passed)
-                                            )
-                                        )
+            for var_name, pass_result in var_passed_ingest_reqs:
+                if pass_result:
+                    var_passed_ingest_msg += "\n - {}".format(var_name)
+                else:
+                    var_failed_ingest_msg += "\n - {}".format(var_name)
+                    all_passed_ingest_reqs = False
+    
+            # join messages together
+            var_passed_ingest_msg += "\n{}".format(var_failed_ingest_msg)
 
+        else:
+            var_passed_ingest_msg = "Dataset not flagged for GTS Ingest; skipping variable checks"
 
         return Result(
             BaseCheck.HIGH,
             all_passed_ingest_reqs,
             "gts_ingest requirements",
-            None if all_passed_ingest_reqs else [
-                var_passed_ingest_msg, var_failed_ingest_msg
-            ]
+            [var_passed_ingest_msg]
         )
 
     def check_instrument_variables(self, ds):
@@ -1157,7 +1148,7 @@ class IOOS1_2Check(IOOSNCCheck):
                 msg = "\"references\" attribute for variable \"{}\" must be a valid URL".format(v.name)
                 val = bool(validators.url(attval))
 
-            results.append(Result(BaseCheck.MEDIUM, val, "qartod_variable:references", None if val else [msg]))
+            results.append(Result(BaseCheck.MEDIUM, val, "qartod_variable:references", [msg]))
 
         return results
 
@@ -1196,7 +1187,7 @@ class IOOS1_2Check(IOOSNCCheck):
            ):
                valid = False
 
-        return Result(BaseCheck.HIGH, valid, ctxt, None if valid else [msg])
+        return Result(BaseCheck.HIGH, valid, ctxt, [msg])
 
 class IOOSBaseSOSCheck(BaseCheck):
     _cc_spec = 'ioos_sos'


Test patch:
diff --git a/compliance_checker/tests/test_base.py b/compliance_checker/tests/test_base.py
index 23e6bbd..ae5c596 100644
--- a/compliance_checker/tests/test_base.py
+++ b/compliance_checker/tests/test_base.py
@@ -120,7 +120,7 @@ class TestBase(TestCase):
         bad_result = validator.validate(test_attr_name, 'foo@@bar.com')
         self.assertFalse(bad_result[0])
         self.assertEqual(bad_result[1],
-                         ["test must be a valid email address"])
+                         "test must be a valid email address")
 
     def test_url_validation(self):
         """
@@ -132,7 +132,7 @@ class TestBase(TestCase):
         validator = base.UrlValidator()
         bad_result = validator.validate(test_attr_name, test_url)
         self.assertFalse(bad_result[0])
-        self.assertEqual(bad_result[1], ["test must be a valid URL"])
+        self.assertEqual(bad_result[1], "test must be a valid URL")
         # valid URL
         test_url = "https://ioos.us"
         self.assertTrue(validator.validate(test_attr_name, test_url)[0])
@@ -146,7 +146,7 @@ class TestBase(TestCase):
         url_multi_string += ",noaa.ioos.webmaster@noaa.gov"
         bad_result = validator.validate(test_attr_name, url_multi_string)
         self.assertFalse(bad_result[0])
-        self.assertEqual(bad_result[1], ["test must be a valid URL"])
+        self.assertEqual(bad_result[1], "test must be a valid URL")
 
 
 class TestGenericFile(TestCase):
diff --git a/compliance_checker/tests/test_ioos_profile.py b/compliance_checker/tests/test_ioos_profile.py
index ed3bac4..0eaf053 100644
--- a/compliance_checker/tests/test_ioos_profile.py
+++ b/compliance_checker/tests/test_ioos_profile.py
@@ -318,7 +318,7 @@ class TestIOOS1_2(BaseTestCase):
         self.assertLess(scored, out_of)
 
         # set the necessary attributes
-        ds = MockTimeSeries(default_fill_value=9999999999.) # time, lat, lon, depth
+        ds = MockTimeSeries(default_fill_value=9999999999.) # time, lat, lon, depth 
         temp = ds.createVariable("temp", np.float64, fill_value=9999999999.) # _FillValue
         temp.setncattr("missing_value", 9999999999.)
         temp.setncattr("standard_name", "sea_surface_temperature")
@@ -333,7 +333,7 @@ class TestIOOS1_2(BaseTestCase):
     def test_check_geospatial_vars_have_attrs(self):
 
         # create geophysical variable
-        ds = MockTimeSeries() # time, lat, lon, depth
+        ds = MockTimeSeries() # time, lat, lon, depth 
         temp = ds.createVariable("temp", np.float64, dimensions=("time",))
 
         # should fail here
@@ -342,7 +342,7 @@ class TestIOOS1_2(BaseTestCase):
         self.assertLess(scored, out_of)
 
         # should pass - default_fill_value sets _FillValue attr
-        ds = MockTimeSeries(default_fill_value=9999999999.) # time, lat, lon, depth
+        ds = MockTimeSeries(default_fill_value=9999999999.) # time, lat, lon, depth 
 
         ds.variables["time"].setncattr("standard_name", "time")
         ds.variables["time"].setncattr("standard_name_url", "http://cfconventions.org/Data/cf-standard-names/64/build/cf-standard-name-table.html")
@@ -354,7 +354,7 @@ class TestIOOS1_2(BaseTestCase):
         self.assertEqual(scored, out_of)
 
     def test_check_contributor_role_and_vocabulary(self):
-        ds = MockTimeSeries() # time, lat, lon, depth
+        ds = MockTimeSeries() # time, lat, lon, depth 
 
         # no contributor_role or vocab, fail both
         results = self.ioos.check_contributor_role_and_vocabulary(ds)
@@ -370,7 +370,6 @@ class TestIOOS1_2(BaseTestCase):
         ds.setncattr("contributor_role", "contributor")
         results = self.ioos.check_contributor_role_and_vocabulary(ds)
         self.assertTrue(results[0].value)
-        self.assertEqual(results[0].msgs, [])
         self.assertFalse(results[1].value)
 
         # bad role, good vocab
@@ -379,24 +378,19 @@ class TestIOOS1_2(BaseTestCase):
         results = self.ioos.check_contributor_role_and_vocabulary(ds)
         self.assertFalse(results[0].value)
         self.assertTrue(results[1].value)
-        self.assertEqual(results[1].msgs, [])
         
         # good role, good vocab
         ds.setncattr("contributor_role", "contributor")
         ds.setncattr("contributor_role_vocabulary", "http://vocab.nerc.ac.uk/collection/G04/current/")
         results = self.ioos.check_contributor_role_and_vocabulary(ds)
         self.assertTrue(results[0].value)
-        self.assertEqual(results[0].msgs, [])
         self.assertTrue(results[1].value)
-        self.assertEqual(results[1].msgs, [])
 
         ds.setncattr("contributor_role", "resourceProvider")
         ds.setncattr("contributor_role_vocabulary", "https://www.ngdc.noaa.gov/wiki/index.php?title=ISO_19115_and_19115-2_CodeList_Dictionaries#CI_RoleCode")
         results = self.ioos.check_contributor_role_and_vocabulary(ds)
         self.assertTrue(results[0].value)
-        self.assertEqual(results[0].msgs, [])
         self.assertTrue(results[1].value)
-        self.assertEqual(results[1].msgs, [])
 
     def test_check_creator_and_publisher_type(self):
         """
@@ -432,13 +426,11 @@ class TestIOOS1_2(BaseTestCase):
         # no gts_ingest_requirements, should pass
         result = self.ioos.check_gts_ingest_global(ds)
         self.assertTrue(result.value)
-        self.assertEqual(result.msgs, [])
 
         # passing value
         ds.setncattr("gts_ingest", "true")
         result = self.ioos.check_gts_ingest_global(ds)
         self.assertTrue(result.value)
-        self.assertEqual(result.msgs, [])
 
         ds.setncattr("gts_ingest", "false")
         result = self.ioos.check_gts_ingest_global(ds)
@@ -533,7 +525,6 @@ class TestIOOS1_2(BaseTestCase):
         # no wmo_platform_code, pass
         result = self.ioos.check_wmo_platform_code(ds)
         self.assertTrue(result.value)
-        self.assertEqual(result.msgs, [])
 
         # valid code
         ds.setncattr("wmo_platform_code", "12345")
@@ -610,15 +601,15 @@ class TestIOOS1_2(BaseTestCase):
                                         "webmaster.ioos.us@noaa.gov")
         self.assertFalse(bad_result[0])
         self.assertEqual(bad_result[1],
-                         ["naming_authority should either be a URL or a "
-                          "reversed DNS name (e.g \"edu.ucar.unidata\")"])
+                         "naming_authority should either be a URL or a "
+                         "reversed DNS name (e.g \"edu.ucar.unidata\")")
 
     def test_platform_id_validation(self):
         attn = "platform_id"
         attv = "alphaNum3R1C"
         v = IOOS1_2_PlatformIDValidator()
         self.assertTrue(v.validate(attn, attv)[0])
-
+        
         attv = "alpha"
         v = IOOS1_2_PlatformIDValidator()
         self.assertTrue(v.validate(attn, attv)[0])
@@ -661,7 +652,7 @@ class TestIOOS1_2(BaseTestCase):
         self.assertEqual(score, out_of)
 
     def test_check_platform_global(self):
-        ds = MockTimeSeries() # time, lat, lon, depth
+        ds = MockTimeSeries() # time, lat, lon, depth 
 
         # no global attr, fail
         self.assertFalse(self.ioos.check_platform_global(ds).value)
@@ -676,18 +667,15 @@ class TestIOOS1_2(BaseTestCase):
 
         # good value
         ds.setncattr("platform", "single_string")
-        res = self.ioos.check_platform_global(ds)
-        self.assertTrue(res.value)
-        self.assertEqual(res.msgs, [])
+        self.assertTrue(self.ioos.check_platform_global(ds).value)
 
     def test_check_single_platform(self):
 
-        ds = MockTimeSeries() # time, lat, lon, depth
+        ds = MockTimeSeries() # time, lat, lon, depth 
 
         # no global attr but also no platform variables, should pass
         results = self.ioos.check_single_platform(ds)
         self.assertTrue(results[0].value)
-        self.assertEqual(results[0].msgs, [])
 
         # give platform global, no variables, fail
         ds.setncattr("platform", "buoy")
@@ -704,7 +692,6 @@ class TestIOOS1_2(BaseTestCase):
         cf_role_var.setncattr("cf_role", "timeseries_id")
         results = self.ioos.check_single_platform(ds)
         self.assertTrue(all(r.value for r in results))
-        self.assertTrue(all(r.msgs==[] for r in results))
 
         # global attr, multiple platform variables, correct cf_role & featureType, fail
         plat2 = ds.createVariable("platform_var_2", np.byte)
@@ -718,7 +705,7 @@ class TestIOOS1_2(BaseTestCase):
         self.assertFalse(results[0].value)
 
         # global attr, one platform var, correct featureType, incorrect cf_role var dimension
-        ds = MockTimeSeries() # time, lat, lon, depth
+        ds = MockTimeSeries() # time, lat, lon, depth 
         ds.setncattr("featureType", "trajectoryprofile")
         ds.createDimension("trajectory", 2) # should only be 1
         temp = ds.createVariable("temp", "d", ("time"))
@@ -730,11 +717,9 @@ class TestIOOS1_2(BaseTestCase):
         self.assertFalse(results[0].value)
 
     def test_check_platform_vocabulary(self):
-        ds = MockTimeSeries() # time, lat, lon, depth
+        ds = MockTimeSeries() # time, lat, lon, depth 
         ds.setncattr("platform_vocabulary", "http://google.com")
-        result = self.ioos.check_platform_vocabulary(ds)
-        self.assertTrue(result.value)
-        self.assertEqual(result.msgs, [])
+        self.assertTrue(self.ioos.check_platform_vocabulary(ds).value)
 
         ds.setncattr("platform_vocabulary", "bad")
         self.assertFalse(self.ioos.check_platform_vocabulary(ds).value)
@@ -796,7 +781,6 @@ class TestIOOS1_2(BaseTestCase):
         qr.setncattr("references", "http://services.cormp.org/quality.php")
         results = self.ioos.check_qartod_variables_references(ds)
         self.assertTrue(all(r.value for r in results))
-        self.assertEqual(results[0].msgs, []) # only one Result to test
 
         # QARTOD variable with bad references (fail)
         qr.setncattr("references", r"p9q384ht09q38@@####???????////??//\/\/\/\//\/\74ht")
@@ -807,9 +791,7 @@ class TestIOOS1_2(BaseTestCase):
         ds = MockTimeSeries()
 
         # no value, pass
-        res = self.ioos.check_ioos_ingest(ds)
-        self.assertTrue(res.value)
-        self.assertEqual(res.msgs, [])
+        self.assertTrue(self.ioos.check_ioos_ingest(ds).value)
 
         # value false
         ds.setncattr("ioos_ingest", "false")