From d93dcf9a1d612b5724e052760c1d140ec31f7435 Mon Sep 17 00:00:00 2001
From: WidgetsBurritos <davidstinemetze@gmail.com>
Date: Wed, 15 Feb 2017 15:14:44 -0600
Subject: [PATCH] Issue #2852651: Styleguide Compliance

---
 panels_pane_report.admin.inc            |  14 +++
 panels_pane_report.install              |  30 +++++
 panels_pane_report.views.inc            |  64 ++++++++--
 src/panels_pane_report.class.inc        |  71 +++++++++++
 src/views.handlers.inc                  |  39 ++++++
 tests/PanelsPaneReportUnitTestCase.test | 202 ++++++++++++++++++++++++++++++++
 tests/PanelsPaneReportWebTestCase.test  |  53 ++++++++-
 7 files changed, 464 insertions(+), 9 deletions(-)

diff --git a/panels_pane_report.admin.inc b/panels_pane_report.admin.inc
index a4099bd..0de1fd8 100644
--- a/panels_pane_report.admin.inc
+++ b/panels_pane_report.admin.inc
@@ -25,5 +25,19 @@ function panels_pane_report_admin() {
     '#required' => TRUE,
   );
 
+  $form['panels_pane_report_styleguide_allowed'] = array(
+    '#type' => 'textarea',
+    '#title' => t('Styleguide Combination: Allowed'),
+    '#default_value' => variable_get('panels_pane_report_styleguide_allowed', '[]'),
+    '#description' => t('Which combinations you specifically specify as being permitted in your styleguide. JSON format'),
+  );
+
+  $form['panels_pane_report_styleguide_disallowed'] = array(
+    '#type' => 'textarea',
+    '#title' => t('Styleguide Combination: Disallowed'),
+    '#default_value' => variable_get('panels_pane_report_styleguide_disallowed', '[]'),
+    '#description' => t('Which combinations you specifically specify as being forbidden in your styleguide. JSON format'),
+  );
+
   return system_settings_form($form);
 }
diff --git a/panels_pane_report.install b/panels_pane_report.install
index 63e2fb9..97c1163 100644
--- a/panels_pane_report.install
+++ b/panels_pane_report.install
@@ -103,6 +103,18 @@ function panels_pane_report_schema() {
         'not null' => TRUE,
         'default' => '',
       ),
+      'styleguide_status' => array(
+        'description' => 'Status of the styleguide checks.',
+        'type' => 'int',
+        'not null' => FALSE,
+        'unsigned' => TRUE,
+        'default' => NULL,
+      ),
+      'styleguide_details' => array(
+        'description' => 'Styleguide details',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
     ),
     'primary key' => array(
       'entity_type',
@@ -148,3 +160,21 @@ function panels_pane_report_update_7002() {
     'default' => '',
   ));
 }
+
+/**
+ * Adds styleguide to the report.
+ */
+function panels_pane_report_update_7003() {
+  db_add_field('panels_pane_report', 'styleguide_status', array(
+    'description' => 'Status of the styleguide checks.',
+    'type' => 'int',
+    'not null' => FALSE,
+    'unsigned' => TRUE,
+    'default' => NULL,
+  ));
+  db_add_field('panels_pane_report', 'styleguide_details', array(
+    'description' => 'Styleguide details',
+    'type' => 'text',
+    'not null' => FALSE,
+  ));
+}
diff --git a/panels_pane_report.views.inc b/panels_pane_report.views.inc
index 355ac0a..d53e8e2 100644
--- a/panels_pane_report.views.inc
+++ b/panels_pane_report.views.inc
@@ -144,6 +144,24 @@ function panels_pane_report_views_data() {
     'filter' => array('handler' => 'panels_pane_report_display_layout'),
   );
 
+  // The styleguide status field.
+  $data['panels_pane_report']['styleguide_status'] = array(
+    'title' => t('Styleguide Status'),
+    'help' => t('Status of the styleguide validation.'),
+    'field' => array('handler' => 'panels_pane_report_styleguide_status_field'),
+    'sort' => array('handler' => 'views_handler_sort'),
+    'filter' => array('handler' => 'views_handler_filter_boolean_operator'),
+  );
+
+  // The styleguide details field.
+  $data['panels_pane_report']['styleguide_details'] = array(
+    'title' => t('Styleguide Details'),
+    'help' => t('Details about the styleguide validation.'),
+    'field' => array('handler' => 'views_handler_field'),
+    'sort' => array('handler' => 'views_handler_sort'),
+    'filter' => array('handler' => 'views_handler_filter_string'),
+  );
+
   return $data;
 }
 
@@ -256,8 +274,7 @@ function _panels_pane_report_view_panels_pane_report() {
   $handler->display->display_options['fields']['pattern_storage_id']['field'] = 'pattern_storage_id';
   $handler->display->display_options['fields']['pattern_storage_id']['label'] = 'Pattern';
   $handler->display->display_options['fields']['pattern_storage_id']['alter']['alter_text'] = TRUE;
-  $handler->display->display_options['fields']['pattern_storage_id']['alter']['text'] = '<span class="pattern-status">[pattern_status]</span> [pattern_storage_id]<br>
-  [pattern_title]';
+  $handler->display->display_options['fields']['pattern_storage_id']['alter']['text'] = '<span class="pattern-status">[pattern_status]</span> [pattern_storage_id]<br>[pattern_title]';
   /* Field: Panels Pane Report: Panel Page Title */
   $handler->display->display_options['fields']['page_title']['id'] = 'page_title';
   $handler->display->display_options['fields']['page_title']['table'] = 'panels_pane_report';
@@ -280,8 +297,7 @@ function _panels_pane_report_view_panels_pane_report() {
   $handler->display->display_options['fields']['page_storage_id']['field'] = 'page_storage_id';
   $handler->display->display_options['fields']['page_storage_id']['label'] = 'Page';
   $handler->display->display_options['fields']['page_storage_id']['alter']['alter_text'] = TRUE;
-  $handler->display->display_options['fields']['page_storage_id']['alter']['text'] = '<span class="page-status">[page_status]</span> [page_storage_id]<br>
-  [page_title]';
+  $handler->display->display_options['fields']['page_storage_id']['alter']['text'] = '<span class="page-status">[page_status]</span> [page_storage_id]<br>[page_title]';
   /* Field: Panels Pane Report: Display Layout */
   $handler->display->display_options['fields']['display_layout']['id'] = 'display_layout';
   $handler->display->display_options['fields']['display_layout']['table'] = 'panels_pane_report';
@@ -301,6 +317,23 @@ function _panels_pane_report_view_panels_pane_report() {
   $handler->display->display_options['fields']['display_storage_type']['label'] = 'Container';
   $handler->display->display_options['fields']['display_storage_type']['alter']['alter_text'] = TRUE;
   $handler->display->display_options['fields']['display_storage_type']['alter']['text'] = '[display_storage_type] [[display_storage_id]]<br>Layout: [display_layout]';
+  /* Field: Panels Pane Report: Styleguide*/
+  $handler->display->display_options['fields']['styleguide_details']['id'] = 'styleguide_details';
+  $handler->display->display_options['fields']['styleguide_details']['table'] = 'panels_pane_report';
+  $handler->display->display_options['fields']['styleguide_details']['field'] = 'styleguide_details';
+  $handler->display->display_options['fields']['styleguide_details']['label'] = '';
+  $handler->display->display_options['fields']['styleguide_details']['exclude'] = TRUE;
+  $handler->display->display_options['fields']['styleguide_details']['element_label_colon'] = FALSE;
+  $handler->display->display_options['fields']['styleguide_details']['hide_alter_empty'] = FALSE;
+  /* Field: Panels Pane Report: Styleguide Status */
+  $handler->display->display_options['fields']['styleguide_status']['id'] = 'styleguide_status';
+  $handler->display->display_options['fields']['styleguide_status']['table'] = 'panels_pane_report';
+  $handler->display->display_options['fields']['styleguide_status']['field'] = 'styleguide_status';
+  $handler->display->display_options['fields']['styleguide_status']['label'] = 'Styleguide';
+  $handler->display->display_options['fields']['styleguide_status']['element_label_colon'] = FALSE;
+  $handler->display->display_options['fields']['styleguide_status']['element_default_classes'] = FALSE;
+  $handler->display->display_options['fields']['styleguide_status']['type'] = 'unicode-yes-no';
+  $handler->display->display_options['fields']['styleguide_status']['not'] = 0;
   /* Sort criterion: Panels Pane Report: Entity Type */
   $handler->display->display_options['sorts']['entity_type']['id'] = 'entity_type';
   $handler->display->display_options['sorts']['entity_type']['table'] = 'panels_pane_report';
@@ -540,6 +573,22 @@ function _panels_pane_report_view_panels_pane_report() {
     3 => 0,
   );
 
+  /* Filter criterion: Panels Pane Report: Styleguide Status */
+  $handler->display->display_options['filters']['styleguide_status']['id'] = 'styleguide_status';
+  $handler->display->display_options['filters']['styleguide_status']['table'] = 'panels_pane_report';
+  $handler->display->display_options['filters']['styleguide_status']['field'] = 'styleguide_status';
+  $handler->display->display_options['filters']['styleguide_status']['value'] = 'All';
+  $handler->display->display_options['filters']['styleguide_status']['exposed'] = TRUE;
+  $handler->display->display_options['filters']['styleguide_status']['expose']['operator_id'] = '';
+  $handler->display->display_options['filters']['styleguide_status']['expose']['label'] = 'Styleguide';
+  $handler->display->display_options['filters']['styleguide_status']['expose']['operator'] = 'styleguide_status_op';
+  $handler->display->display_options['filters']['styleguide_status']['expose']['identifier'] = 'styleguide_status';
+  $handler->display->display_options['filters']['styleguide_status']['expose']['remember_roles'] = array(
+    2 => '2',
+    1 => 0,
+    3 => 0,
+  );
+
   /* Display: Page */
   $handler = $view->new_display('page', 'Page', 'page');
   $handler->display->display_options['path'] = 'admin/reports/panels-pane-report';
@@ -550,6 +599,7 @@ function _panels_pane_report_view_panels_pane_report() {
   $handler->display->display_options['menu']['name'] = 'management';
   $handler->display->display_options['menu']['context'] = 0;
   $handler->display->display_options['menu']['context_only_inline'] = 0;
+
   $translatables['panels_pane_report'] = array(
     t('Master'),
     t('Panels Pane Report'),
@@ -573,11 +623,9 @@ function _panels_pane_report_view_panels_pane_report() {
     t('Entity'),
     t('[entity_type][bundle] [build_mode] [style_mode]'),
     t('Pattern'),
-    t('<span class="pattern-status">[pattern_status]</span> [pattern_storage_id]<br>
-  [pattern_title]'),
+    t('<span class="pattern-status">[pattern_status]</span> [pattern_storage_id]<br>[pattern_title]'),
     t('Page'),
-    t('<span class="page-status">[page_status]</span> [page_storage_id]<br>
-  [page_title]'),
+    t('<span class="page-status">[page_status]</span> [page_storage_id]<br>[page_title]'),
     t('Display Storage ID'),
     t('Container'),
     t('[display_storage_type] [[display_storage_id]]'),
diff --git a/src/panels_pane_report.class.inc b/src/panels_pane_report.class.inc
index 495db44..f4d4358 100644
--- a/src/panels_pane_report.class.inc
+++ b/src/panels_pane_report.class.inc
@@ -273,6 +273,10 @@ class PanelsPaneReport {
             'display_layout' => isset($instance_info['panel']->layout) ? $instance_info['panel']->layout : '',
           );
 
+          $results = self::validateStyleguideRow($item_array);
+          $item_array['styleguide_status'] = $results['status'];
+          $item_array['styleguide_details'] = serialize($results['details']);
+
           self::reportItem($item_array);
         }
       }
@@ -286,4 +290,71 @@ class PanelsPaneReport {
     variable_set(self::LAST_RUN_VARIABLE, REQUEST_TIME);
   }
 
+  /**
+   * Retrieves the styleguide.
+   */
+  public static function retrieveStyleguide() {
+    $styleguide = &drupal_static(__FUNCTION__);
+    if (!isset($styleguide)) {
+      $allowed_text = variable_get('panels_pane_report_styleguide_allowed', '[]');
+      $allowed_array = json_decode($allowed_text, TRUE);
+      if (!is_array($allowed_array)) {
+        $allowed_array = array();
+      }
+
+      $disallowed_text = variable_get('panels_pane_report_styleguide_disallowed', '[]');
+      $disallowed_array = json_decode($disallowed_text, TRUE);
+      if (!is_array($disallowed_array)) {
+        $disallowed_array = array();
+      }
+
+      $styleguide = array(
+        'allowed' => $allowed_array,
+        'disallowed' => $disallowed_array,
+      );
+    }
+
+    return $styleguide;
+  }
+
+  /**
+   * Validates a row against a set of rules.
+   */
+  public static function validateStyleguideRules($row, $rules) {
+    foreach ($rules as $key => $value) {
+      if (!isset($row[$key]) || $row[$key] != $value) {
+        return FALSE;
+      }
+    }
+    return TRUE;
+  }
+
+  /**
+   * Validates a row against all styleguide rules.
+   * @todo Optimize performance.
+   */
+  public static function validateStyleguideRow($row, $styleguide = NULL) {
+    if (!isset($styleguide)) {
+      $styleguide = self::retrieveStyleguide();
+    }
+
+    $results = array('status' => NULL, 'details' => array());
+    foreach ($styleguide['disallowed'] as $disallowed_rules) {
+      if (self::validateStyleguideRules($row, $disallowed_rules)) {
+        $results['status'] = 0;
+        $results['details'][] = $disallowed_rules;
+      }
+    }
+
+    foreach ($styleguide['allowed'] as $allowed_rules) {
+      if (self::validateStyleguideRules($row, $allowed_rules)) {
+        $results['status'] = isset($results['status']) ? 1 & $results['status'] : 1;
+        $results['details'][] = $allowed_rules;
+      }
+    }
+
+
+    return $results;
+  }
+
 }
diff --git a/src/views.handlers.inc b/src/views.handlers.inc
index 5c876f9..294105b 100644
--- a/src/views.handlers.inc
+++ b/src/views.handlers.inc
@@ -223,3 +223,42 @@ class panels_pane_report_page_storage_id_field extends views_handler_field {
   }
 
 }
+
+/**
+ * Render options for styleguide status field.
+ */
+class panels_pane_report_styleguide_status_field extends views_handler_field_boolean {
+
+  /**
+   * Override render().
+   *
+   * @param $values
+   *
+   * @return null|string|void
+   */
+  function render($values) {
+    if ($values->panels_pane_report_styleguide_status === NULL || !isset($values->panels_pane_report_styleguide_details)) {
+      return '<div class="ppr-styleguide-neutral"></div>';
+    }
+
+    $styleguide_class = ($values->panels_pane_report_styleguide_status) ? 'ppr-styleguide-pass' : 'ppr-styleguide-fail';
+    $details = unserialize($values->panels_pane_report_styleguide_details);
+    $html = '<div class="' . $styleguide_class . '">';
+    $html .= t('Styleguide: !status', array('!status' => parent::render($values)));
+
+    if (!empty($details)) {
+      $html .= '<ol>';
+      foreach ($details as $detail) {
+        $html .= '<li>';
+        foreach ($detail as $key => $value) {
+          $html .= "{$key}: $value<br>";
+        }
+        $html .= '</li>';
+      }
+      $html .= '</ol>';
+    }
+    $html .= '</div>';
+    return $html;
+  }
+
+}
diff --git a/tests/PanelsPaneReportUnitTestCase.test b/tests/PanelsPaneReportUnitTestCase.test
index e8b92ad..3e406ec 100644
--- a/tests/PanelsPaneReportUnitTestCase.test
+++ b/tests/PanelsPaneReportUnitTestCase.test
@@ -125,4 +125,206 @@ class PanelsPaneReportUnitTestCase extends DrupalUnitTestCase {
     $this->assertEqual($expected, PanelsPaneReport::retrievePageStorageIdsForInstance($instance_info, $pane_mapping));
   }
 
+  /**
+   * Test PanelsPaneReport::validateStyleguideRules() output.
+   */
+  public function testRulesMatchRow() {
+    $row = array(
+      'entity_type' => 'node',
+      'pattern_storage_id' => 'k9',
+      'page_storage_id' => 'yard1',
+      'display_storage_type' => 'doghouse',
+      'display_storage_id' => 'woofhouse9',
+      'display_layout' => 'single',
+      'build_mode' => 'default',
+      'style_mode' => 'rounded_corners',
+      'bundle' => 'page',
+    );
+    $rules = array('bundle' => 'page', 'style_mode' => 'rounded_corners');
+    $this->assertTrue(PanelsPaneReport::validateStyleguideRules($row, $rules));
+  }
+
+  /**
+   * Test PanelsPaneReport::validateStyleguideRules() output.
+   */
+  public function testRulesDoNotMatchRow() {
+    $row = array(
+      'entity_type' => 'node',
+      'pattern_storage_id' => 'k9',
+      'page_storage_id' => 'yard1',
+      'display_storage_type' => 'doghouse',
+      'display_storage_id' => 'woofhouse9',
+      'display_layout' => 'single',
+      'build_mode' => 'default',
+      'style_mode' => 'rounded_corners',
+      'bundle' => 'page',
+    );
+    $rules = array('bundle' => 'article', 'style_mode' => 'rounded_corners');
+    $this->assertFalse(PanelsPaneReport::validateStyleguideRules($row, $rules));
+  }
+
+  /**
+   * Test PanelsPaneReport::validateStyleguideRules() output.
+   */
+  public function testEmptyRowDoesNotMatch() {
+    $row = array();
+    $rules = array('bundle' => 'page', 'style_mode' => 'rounded_corners');
+    $this->assertFalse(PanelsPaneReport::validateStyleguideRules($row, $rules));
+  }
+
+  /**
+   * Test PanelsPaneReport::validateStyleguideRules() output.
+   */
+  public function testEmptyRuleDoesMatch() {
+    $row = array(
+      'entity_type' => 'node',
+      'pattern_storage_id' => 'k9',
+      'page_storage_id' => 'yard1',
+      'display_storage_type' => 'doghouse',
+      'display_storage_id' => 'woofhouse9',
+      'display_layout' => 'single',
+      'build_mode' => 'default',
+      'style_mode' => 'rounded_corners',
+      'bundle' => 'page',
+    );
+    $rules = array();
+    $this->assertTrue(PanelsPaneReport::validateStyleguideRules($row, $rules));
+  }
+
+  /**
+   * Test PanelsPaneReport::validateStyleguideRow() output.
+   */
+  public function testRowMeetsStyleguidePattern() {
+    $row = array(
+      'entity_type' => 'node',
+      'pattern_storage_id' => 'k9',
+      'page_storage_id' => 'yard1',
+      'display_storage_type' => 'doghouse',
+      'display_storage_id' => 'woofhouse9',
+      'display_layout' => 'single',
+      'build_mode' => 'default',
+      'style_mode' => 'rounded_corners',
+      'bundle' => 'page',
+    );
+
+    $allowed_text = '[{"bundle":"page","style_mode":"boxed_corners"},{"entity_type":"node","build_mode":"default"}]';
+
+    $styleguide = array(
+      'allowed' => json_decode($allowed_text, TRUE),
+      'disallowed' => array(),
+    );
+
+    $expected = array(
+      'status' => 1,
+      'details' => array(
+        array(
+          'entity_type' => 'node',
+          'build_mode' => 'default',
+        ),
+      ),
+    );
+    $this->assertEqual($expected, PanelsPaneReport::validateStyleguideRow($row, $styleguide));
+  }
+
+  /**
+   * Test PanelsPaneReport::validateStyleguideRow() output.
+   */
+  public function testRowMeetsMultipleStyleguidePatterns() {
+    $row = array(
+      'entity_type' => 'node',
+      'pattern_storage_id' => 'k9',
+      'page_storage_id' => 'yard1',
+      'display_storage_type' => 'doghouse',
+      'display_storage_id' => 'woofhouse9',
+      'display_layout' => 'single',
+      'build_mode' => 'default',
+      'style_mode' => 'rounded_corners',
+      'bundle' => 'page',
+    );
+
+    $allowed_text = '[{"bundle":"page","style_mode":"rounded_corners"},{"entity_type":"node","build_mode":"default"}]';
+
+    $styleguide = array(
+      'allowed' => json_decode($allowed_text, TRUE),
+      'disallowed' => array(),
+    );
+
+    $expected = array(
+      'status' => 1,
+      'details' => array(
+        array(
+          'bundle' => 'page',
+          'style_mode' => 'rounded_corners',
+        ),
+        array(
+          'entity_type' => 'node',
+          'build_mode' => 'default',
+        ),
+      ),
+    );
+    $this->assertEqual($expected, PanelsPaneReport::validateStyleguideRow($row, $styleguide));
+  }
+
+  /**
+   * Test PanelsPaneReport::validateStyleguideRow() output.
+   */
+  public function testRowFailsStyleguidePattern() {
+    $row = array(
+      'entity_type' => 'node',
+      'pattern_storage_id' => 'k9',
+      'page_storage_id' => 'yard1',
+      'display_storage_type' => 'doghouse',
+      'display_storage_id' => 'woofhouse9',
+      'display_layout' => 'single',
+      'build_mode' => 'search_index',
+      'style_mode' => 'rounded_corners',
+      'bundle' => 'page',
+    );
+
+    $disallowed_text = '[{"entity_type":"node","build_mode":"search_index"},{"bundle":"page","style":""}]';
+
+    $styleguide = array(
+      'allowed' => array(),
+      'disallowed' => json_decode($disallowed_text, TRUE),
+    );
+
+    $expected = array(
+      'status' => FALSE,
+      'details' => array(
+        array(
+          'entity_type' => 'node',
+          'build_mode' => 'search_index',
+        ),
+      ),
+    );
+    $this->assertEqual($expected, PanelsPaneReport::validateStyleguideRow($row, $styleguide));
+  }
+
+  /**
+   * Test PanelsPaneReport::validateStyleguideRow() output.
+   */
+  public function testRowIsStyleguideNeutral() {
+    $row = array(
+      'entity_type' => 'node',
+      'pattern_storage_id' => 'k9',
+      'page_storage_id' => 'yard1',
+      'display_storage_type' => 'doghouse',
+      'display_storage_id' => 'woofhouse9',
+      'display_layout' => 'single',
+      'build_mode' => 'search_index',
+      'style_mode' => 'rounded_corners',
+      'bundle' => 'page',
+    );
+
+    $allowed_text = '[{"bundle":"page","style_mode":"boxed_corners"},{"entity_type":"node","build_mode":"default"}]';
+    $disallowed_text = '[{"entity_type":"node","build_mode":"standard"},{"bundle":"page","style_mode":""}]';
+
+    $styleguide = array(
+      'allowed' => json_decode($allowed_text, TRUE),
+      'disallowed' => json_decode($disallowed_text, TRUE),
+    );
+
+    $expected = array('status' => NULL, 'details' => array());
+    $this->assertEqual($expected, PanelsPaneReport::validateStyleguideRow($row, $styleguide));
+  }
 }
diff --git a/tests/PanelsPaneReportWebTestCase.test b/tests/PanelsPaneReportWebTestCase.test
index 2f5f906..06cf2de 100644
--- a/tests/PanelsPaneReportWebTestCase.test
+++ b/tests/PanelsPaneReportWebTestCase.test
@@ -155,6 +155,11 @@ class PanelsPaneReportWebTestCase extends DrupalWebTestCase {
 
     // Container Layout.
     $this->assertRaw('<option value="single">single</option>');
+
+    // Status dropdowns.
+    $this->assertRaw('name="styleguide_status"');
+    $this->assertRaw('name="pattern_status"');
+    $this->assertRaw('name="page_status"');
   }
 
   /**
@@ -554,7 +559,53 @@ class PanelsPaneReportWebTestCase extends DrupalWebTestCase {
    $this->assertRaw('<a href="' . url('node/' . $node2->nid) . '" target="_blank">node/' . $node2->nid . '</a>');
    $this->assertRaw('<a href="' . url('custom-page') . '" target="_blank">custom-page</a>');
    $this->assertText('page_manager [' . $handler->name . ']');
- }
+  }
+
+  /**
+   * Tests styleguide data.
+   */
+  public function testStyleguideRequirements() {
+    $admin_user = $this->drupalCreateUser(array(
+      'access panels pane report',
+      'generate panels pane report',
+    ));
 
+    // Set our allowed and disallowed styleguide criteria.
+    $allowed_text = '[{"bundle":"widget","build_mode":"fancy"},{"bundle":"burrito","build_mode":"standard"}]';
+    $disallowed_text = '[{"bundle":"widget","build_mode":"standard"},{"bundle":"burrito","build_mode":"fancy"}]';
+    variable_set('panels_pane_report_styleguide_allowed', $allowed_text);
+    variable_set('panels_pane_report_styleguide_disallowed', $disallowed_text);
+
+    $panel_node = $this->drupalCreateNode(array('type' => 'panels_node', 'uid' => $admin_user->uid));
+
+    $nodes = array(
+      $this->drupalCreateNode(array('type' => 'burrito', 'uid' => $admin_user->uid)),
+      $this->drupalCreateNode(array('type' => 'burrito', 'uid' => $admin_user->uid)),
+      $this->drupalCreateNode(array('type' => 'burrito', 'uid' => $admin_user->uid)),
+      $this->drupalCreateNode(array('type' => 'widget', 'uid' => $admin_user->uid)),
+      $this->drupalCreateNode(array('type' => 'widget', 'uid' => $admin_user->uid)),
+      $this->drupalCreateNode(array('type' => 'widget', 'uid' => $admin_user->uid)),
+    );
 
+    // Create display.
+    $display = self::createNewPanelsDisplay('panels_node', $panel_node->nid);
+
+    // Create the panes and add them to the display.
+    $build_modes = array('fancy', 'standard', 'premium');
+    for ($i=0; $i<count($nodes); $i++) {
+      $config_array = array('nid' => $nodes[$i]->nid, 'build_mode' => $build_modes[$i % 3]);
+      $pane = self::createNewPanelsPane($config_array, 'node', 'node');
+      self::addPaneToDisplay($display, $pane);
+    }
+
+    // Attempt to login and regenerate the report.
+    $this->drupalLogin($admin_user);
+    $submit_options = array('query' => array('op' => 'Regenerate Report'));
+    $this->drupalGet('admin/reports/panels-pane-report', $submit_options);
+    $this->assertPattern('|<div class="ppr-styleguide-pass">[^$]*bundle: burrito[^$]*build_mode: standard|');
+    $this->assertPattern('|<div class="ppr-styleguide-pass">[^$]*bundle: widget[^$]*build_mode: fancy|');
+    $this->assertPattern('|<div class="ppr-styleguide-fail">[^$]*bundle: burrito[^$]*build_mode: fancy|');
+    $this->assertPattern('|<div class="ppr-styleguide-fail">[^$]*bundle: widget[^$]*build_mode: standard|');
+    $this->assertRaw('<div class="ppr-styleguide-neutral"></div>');
+  }
 }
-- 
2.10.1 (Apple Git-78)

