Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: HTML Validity Tests #2317

Merged
merged 9 commits into from Oct 31, 2019
118 changes: 118 additions & 0 deletions _test/tests/general/general_html.test.php
@@ -0,0 +1,118 @@
<?php

/**
* Check some page output for validity
*
* @group internet
*/
splitbrain marked this conversation as resolved.
Show resolved Hide resolved
class general_html_test extends DokuWikiTest
{
/** @var string[] we consider these hits shortcomings in the validator and not errors */
protected $allowedErrors = [
'The string “ugc” is not a registered keyword.',
];

/**
* List of requests to check for validity
*
* @return array
*/
public function requestProvider()
{
return [
['/doku.php', 'GET', []],
['/doku.php', 'GET', ['do' => 'recent']],
['/doku.php', 'GET', ['do' => 'index']],
['/doku.php', 'GET', ['do' => 'login']],
['/doku.php', 'GET', ['do' => 'search', 'q' => 'wiki']],
['/doku.php', 'GET', ['id' => 'wiki:syntax']],
['/doku.php', 'GET', ['id' => 'wiki:syntax', 'ns' => 'wiki', 'image' => 'wiki:dokuwiki-128.png', 'do' => 'media']],
['/lib/exe/detail.php', 'GET', ['id' => 'wiki:syntax', 'media' => 'wiki:dokuwiki-128.png']],
];
}

/**
* Sends the given HTML to the validator and returns the result
*
* @param string $html
* @return array
* @throws Exception when communication failed
*/
protected function validate($html)
{
$http = new \dokuwiki\HTTP\DokuHTTPClient();
$http->headers['Content-Type'] = 'text/html; charset=utf-8';
$result = $http->post('https://validator.w3.org/nu/?out=json&level=error', $html);

if ($result === false) {
throw new \Exception($http->error);
}

$result = json_decode($result, true);
if ($result === null) {
throw new \Exception('could not decode JSON');
}

return $result;
}

/**
* Reformat the errors for nicer display in output
*
* @param array $result
* @return string[]
*/
protected function listErrors($result)
{
$errors = [];
foreach ($result['messages'] as $msg) {
if ($this->isAllowedError($msg['message'])) continue;
$errors[] = "☛ " . $msg['message'] . "\n" . $msg['extract'] . "\n";
}
return $errors;
}

/**
* Is the given string an allowed error that should be skipped?
*
* @param string $string
* @return bool
*/
protected function isAllowedError($string)
{
$re = join('|', array_map('preg_quote_cb', $this->allowedErrors));
return (bool)preg_match("/$re/", $string);
}

/**
* @dataProvider requestProvider
* @param string $url
* @param string $method
* @param array $data
* @group internet
*/
public function test_Validity($url, $method, $data)
{
$request = new TestRequest();
if ($method == 'GET') {
$response = $request->get($data, $url);
} elseif ($method == 'POST') {
$response = $request->post($data, $url);
} else {
throw new \RuntimeException("unknown method given: $method");
}

$html = $response->getContent();
try {
$result = $this->validate($html);
} catch (\Exception $e) {
$this->markTestSkipped($e->getMessage());
return;
}

$errors = $this->listErrors($result);
$info = "Invalid HTML found:\n" . join("\n", $errors);

$this->assertEquals(0, count($errors), $info);
}
}
6 changes: 3 additions & 3 deletions inc/changelog.php
Expand Up @@ -228,9 +228,9 @@ function getRecents($first,$num,$ns='',$flags=0){

// read all recent changes. (kept short)
if ($flags & RECENTS_MEDIA_CHANGES) {
$lines = @file($conf['media_changelog']);
$lines = @file($conf['media_changelog']) ?: [];
} else {
$lines = @file($conf['changelog']);
$lines = @file($conf['changelog']) ?: [];
}
if (!is_array($lines)) {
$lines = array();
Expand All @@ -240,7 +240,7 @@ function getRecents($first,$num,$ns='',$flags=0){
$media_lines = array();

if ($flags & RECENTS_MEDIA_PAGES_MIXED) {
$media_lines = @file($conf['media_changelog']);
$media_lines = @file($conf['media_changelog']) ?: [];
if (!is_array($media_lines)) {
$media_lines = array();
}
Expand Down
4 changes: 2 additions & 2 deletions inc/html.php
Expand Up @@ -50,7 +50,7 @@ function html_login($svg = false){

print p_locale_xhtml('login');
print '<div class="centeralign">'.NL;
$form = new Doku_Form(array('id' => 'dw__login'));
$form = new Doku_Form(array('id' => 'dw__login', 'action'=>wl($ID)));
$form->startFieldset($lang['btn_login']);
$form->addHidden('id', $ID);
$form->addHidden('do', 'login');
Expand Down Expand Up @@ -707,7 +707,7 @@ function html_recent($first = 0, $show_changes = 'both') {
'</p></div>';
}

$form = new Doku_Form(array('id' => 'dw__recent', 'method' => 'GET', 'class' => 'changes'));
$form = new Doku_Form(array('id' => 'dw__recent', 'method' => 'GET', 'class' => 'changes', 'action'=>wl($ID)));
$form->addHidden('sectok', null);
$form->addHidden('do', 'recent');
$form->addHidden('id', $ID);
Expand Down