[ Index ]

PHP Cross Reference of DokuWiki

title

Body

[close]

/_test/tests/general/ -> general_html.test.php (source)

   1  <?php
   2  
   3  /**
   4   * Check some page output for validity
   5   *
   6   * @group internet
   7   */
   8  class general_html_test extends DokuWikiTest
   9  {
  10      /** @var string[] we consider these hits shortcomings in the validator and not errors */
  11      protected $allowedErrors = [
  12          'The string “ugc” is not a registered keyword.',
  13      ];
  14  
  15      /**
  16       * List of requests to check for validity
  17       *
  18       * @return array
  19       */
  20      public function requestProvider()
  21      {
  22          return [
  23              ['/doku.php', 'GET', []],
  24              ['/doku.php', 'GET', ['do' => 'recent']],
  25              ['/doku.php', 'GET', ['do' => 'index']],
  26              ['/doku.php', 'GET', ['do' => 'login']],
  27              ['/doku.php', 'GET', ['do' => 'search', 'q' => 'wiki']],
  28              ['/doku.php', 'GET', ['id' => 'wiki:syntax']],
  29              ['/doku.php', 'GET', ['id' => 'wiki:syntax', 'ns' => 'wiki', 'image' => 'wiki:dokuwiki-128.png', 'do' => 'media']],
  30              ['/lib/exe/detail.php', 'GET', ['id' => 'wiki:syntax', 'media' => 'wiki:dokuwiki-128.png']],
  31          ];
  32      }
  33  
  34      /**
  35       * Sends the given HTML to the validator and returns the result
  36       *
  37       * @param string $html
  38       * @return array
  39       * @throws Exception when communication failed
  40       */
  41      protected function validate($html)
  42      {
  43          $http = new \dokuwiki\HTTP\DokuHTTPClient();
  44          $http->headers['Content-Type'] = 'text/html; charset=utf-8';
  45          $result = $http->post('https://validator.w3.org/nu/?out=json&level=error', $html);
  46  
  47          if ($result === false) {
  48              throw new \Exception($http->error);
  49          }
  50  
  51          $result = json_decode($result, true);
  52          if ($result === null) {
  53              throw new \Exception('could not decode JSON');
  54          }
  55  
  56          return $result;
  57      }
  58  
  59      /**
  60       * Reformat the errors for nicer display in output
  61       *
  62       * @param array $result
  63       * @return string[]
  64       */
  65      protected function listErrors($result)
  66      {
  67          $errors = [];
  68          foreach ($result['messages'] as $msg) {
  69              if ($this->isAllowedError($msg['message'])) continue;
  70              $errors[] = "☛ " . $msg['message'] . "\n" . $msg['extract'] . "\n";
  71          }
  72          return $errors;
  73      }
  74  
  75      /**
  76       * Is the given string an allowed error that should be skipped?
  77       *
  78       * @param string $string
  79       * @return bool
  80       */
  81      protected function isAllowedError($string)
  82      {
  83          $re = join('|', array_map('preg_quote_cb', $this->allowedErrors));
  84          return (bool)preg_match("/$re/", $string);
  85      }
  86  
  87      /**
  88       * @dataProvider requestProvider
  89       * @param string $url
  90       * @param string $method
  91       * @param array $data
  92       * @group internet
  93       */
  94      public function test_Validity($url, $method, $data)
  95      {
  96          $request = new TestRequest();
  97          if ($method == 'GET') {
  98              $response = $request->get($data, $url);
  99          } elseif ($method == 'POST') {
 100              $response = $request->post($data, $url);
 101          } else {
 102              throw new \RuntimeException("unknown method given: $method");
 103          }
 104  
 105          $html = $response->getContent();
 106          try {
 107              $result = $this->validate($html);
 108          } catch (\Exception $e) {
 109              $this->markTestSkipped($e->getMessage());
 110              return;
 111          }
 112  
 113          $errors = $this->listErrors($result);
 114          $info = "Invalid HTML found:\n" . join("\n", $errors);
 115  
 116          $this->assertEquals(0, count($errors), $info);
 117      }
 118  }