xref: /webtrees/tests/views/AbstractViewTest.php (revision 0d047a8c74753c7558a60f4789c838996d6fae8b)
1<?php
2
3/**
4 * webtrees: online genealogy
5 * Copyright (C) 2021 webtrees development team
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <https://www.gnu.org/licenses/>.
16 */
17
18declare(strict_types=1);
19
20namespace Fisharebest\Webtrees;
21
22use DOMDocument;
23use Exception;
24
25use function str_starts_with;
26use function trim;
27
28use const LIBXML_PEDANTIC;
29
30/**
31 * Common functions for testing views
32 */
33abstract class AbstractViewTest extends TestCase
34{
35    protected const EVIL_VALUE = '<script>evil()</script>';
36
37    /**
38     * Check the view runs without error and generates valid HTML
39     *
40     * @param string $view
41     * @param array<array<string,array<string,mixed>>  $data
42     */
43    protected function doTestView(string $view, array $data): void
44    {
45        foreach ($this->cartesian($data) as $datum) {
46            $html = view($view, $datum);
47
48            $this->validateHTML($html);
49        }
50    }
51
52    /**
53     * @param array<string,array<string,mixed>> $input
54     *
55     * @return array<array<string,array<string,mixed>>
56     */
57    private function cartesian(array $input): array
58    {
59        $result = [[]];
60
61        foreach ($input as $key => $values) {
62            $append = [];
63
64            foreach ($result as $product) {
65                foreach ($values as $item) {
66                    $product[$key] = $item;
67                    $append[]      = $product;
68                }
69            }
70
71            $result = $append;
72        }
73
74        return $result;
75    }
76
77    /**
78     * @param string $html
79     */
80    private function validateHTML(string $html): void
81    {
82        if (str_starts_with($html, '<!DOCTYPE html>')) {
83            $xml = $html;
84        } else {
85            $xml = '<!DOCTYPE html><html lang="en"><body>' . $html . '</body></html>';
86        }
87
88        $doc = new DOMDocument();
89        $doc->validateOnParse = true;
90
91        try {
92            self::assertTrue($doc->loadXML($xml, LIBXML_PEDANTIC), $html);
93        } catch (Exception $ex) {
94            echo $html, PHP_EOL;
95            self::assertTrue(false);
96        }
97    }
98}
99