Merge pull request #19552 from kamil-tekiela/Fix-default-values
[phpmyadmin.git] / tests / unit / HeaderTest.php
blob420c96a586de5e358c4d1e90cfbfc4163a171146
1 <?php
3 declare(strict_types=1);
5 namespace PhpMyAdmin\Tests;
7 use PhpMyAdmin\Bookmarks\BookmarkRepository;
8 use PhpMyAdmin\Config;
9 use PhpMyAdmin\ConfigStorage\Relation;
10 use PhpMyAdmin\Console;
11 use PhpMyAdmin\Current;
12 use PhpMyAdmin\Dbal\DatabaseInterface;
13 use PhpMyAdmin\Header;
14 use PhpMyAdmin\Message;
15 use PhpMyAdmin\Template;
16 use PHPUnit\Framework\Attributes\CoversClass;
17 use PHPUnit\Framework\Attributes\DataProvider;
18 use PHPUnit\Framework\Attributes\Medium;
19 use ReflectionProperty;
21 use function gmdate;
23 use const DATE_RFC1123;
25 #[CoversClass(Header::class)]
26 #[Medium]
27 class HeaderTest extends AbstractTestCase
29 /**
30 * Configures global environment.
32 protected function setUp(): void
34 parent::setUp();
36 $this->setLanguage();
38 DatabaseInterface::$instance = $this->createDatabaseInterface();
40 Current::$message = Message::success('phpmyadminmessage');
41 Current::$database = 'db';
42 Current::$table = '';
44 $this->setGlobalConfig();
46 $config = Config::getInstance();
47 $config->settings['Servers'] = [];
48 $config->selectedServer['DisableIS'] = false;
49 $config->selectedServer['verbose'] = 'verbose host';
50 $config->selectedServer['pmadb'] = '';
51 $config->selectedServer['user'] = '';
52 $config->selectedServer['auth_type'] = 'cookie';
55 private function getNewHeaderInstance(): Header
57 $dbi = DatabaseInterface::getInstance();
58 $relation = new Relation($dbi);
59 $template = new Template();
61 return new Header(
62 $template,
63 new Console($relation, $template, new BookmarkRepository($dbi, $relation)),
64 Config::getInstance(),
68 public function testEnable(): void
70 Current::$server = 0;
71 Current::$message = null;
72 $config = Config::getInstance();
73 $config->settings['CodemirrorEnable'] = false;
74 $config->set('SendErrorReports', 'never');
75 $config->settings['enable_drag_drop_import'] = false;
76 $config->set('DisableShortcutKeys', true);
77 $dbi = $this->createDatabaseInterface();
78 DatabaseInterface::$instance = $dbi;
79 $relation = new Relation($dbi);
80 $template = new Template($config);
81 $console = new Console($relation, $template, new BookmarkRepository($dbi, $relation));
82 $header = new Header($template, $console, $config);
84 $header->setBodyId('PMA_header_id');
85 $actual = $header->getDisplay();
86 $expected = [
87 'lang' => 'en',
88 'allow_third_party_framing' => false,
89 'base_dir' => '',
90 'theme_path' => '',
91 'server' => 0,
92 'title' => 'phpMyAdmin',
93 'scripts' => $header->getScripts()->getDisplay(),
94 'body_id' => 'PMA_header_id',
95 'navigation' => '',
96 'custom_header' => '',
97 'load_user_preferences' => '',
98 'show_hint' => true,
99 'is_warnings_enabled' => true,
100 'is_menu_enabled' => true,
101 'is_logged_in' => true,
102 'menu' => '',
103 'console' => $console->getDisplay(),
104 'messages' => '',
105 'theme_color_mode' => 'light',
106 'theme_color_modes' => ['light'],
107 'theme_id' => '',
108 'current_user' => ['pma_test', 'localhost'],
109 'is_mariadb' => false,
111 self::assertSame($expected, $actual);
115 * Test for Get JsParams
117 public function testGetJsParams(): void
119 $header = $this->getNewHeaderInstance();
120 self::assertArrayHasKey(
121 'common_query',
122 $header->getJsParams(),
126 public function testGetJsParamsCode(): void
128 $header = $this->getNewHeaderInstance();
129 self::assertStringContainsString(
130 'window.Navigation.update(window.CommonParams.setAll(',
131 $header->getJsParamsCode(),
136 * Test for Get Message
138 public function testGetMessage(): void
140 $header = $this->getNewHeaderInstance();
141 self::assertStringContainsString(
142 'phpmyadminmessage',
143 $header->getMessage(),
148 * Test for Disable Warnings
150 public function testDisableWarnings(): void
152 $reflection = new ReflectionProperty(Header::class, 'warningsEnabled');
154 $header = $this->getNewHeaderInstance();
155 $header->disableWarnings();
157 self::assertFalse($reflection->getValue($header));
160 #[DataProvider('providerForTestGetHttpHeaders')]
161 public function testGetHttpHeaders(
162 string|bool $frameOptions,
163 string $cspAllow,
164 string $privateKey,
165 string $publicKey,
166 string $captchaCsp,
167 string|null $expectedFrameOptions,
168 string $expectedCsp,
169 string $expectedXCsp,
170 string $expectedWebKitCsp,
171 ): void {
172 $header = $this->getNewHeaderInstance();
173 $date = gmdate(DATE_RFC1123);
175 $config = Config::getInstance();
176 $config->settings['AllowThirdPartyFraming'] = $frameOptions;
177 $config->settings['CSPAllow'] = $cspAllow;
178 $config->settings['CaptchaLoginPrivateKey'] = $privateKey;
179 $config->settings['CaptchaLoginPublicKey'] = $publicKey;
180 $config->settings['CaptchaCsp'] = $captchaCsp;
182 $expected = [
183 'X-Frame-Options' => $expectedFrameOptions,
184 'Referrer-Policy' => 'same-origin',
185 'Content-Security-Policy' => $expectedCsp,
186 'X-Content-Security-Policy' => $expectedXCsp,
187 'X-WebKit-CSP' => $expectedWebKitCsp,
188 'X-XSS-Protection' => '1; mode=block',
189 'X-Content-Type-Options' => 'nosniff',
190 'X-Permitted-Cross-Domain-Policies' => 'none',
191 'X-Robots-Tag' => 'noindex, nofollow',
192 'Permissions-Policy' => 'fullscreen=(self), oversized-images=(self), interest-cohort=()',
193 'Expires' => $date,
194 'Cache-Control' => 'no-store, no-cache, must-revalidate, pre-check=0, post-check=0, max-age=0',
195 'Pragma' => 'no-cache',
196 'Last-Modified' => $date,
197 'Content-Type' => 'text/html; charset=utf-8',
199 if ($expectedFrameOptions === null) {
200 unset($expected['X-Frame-Options']);
203 $headers = $this->callFunction($header, Header::class, 'getHttpHeaders', []);
204 self::assertSame($expected, $headers);
207 /** @return mixed[][] */
208 public static function providerForTestGetHttpHeaders(): array
210 return [
212 '1',
217 'DENY',
218 'default-src \'self\' ;script-src \'self\' \'unsafe-inline\' \'unsafe-eval\' ;'
219 . 'style-src \'self\' \'unsafe-inline\' ;img-src \'self\' data: tile.openstreetmap.org;'
220 . 'object-src \'none\';',
221 'default-src \'self\' ;options inline-script eval-script;referrer no-referrer;'
222 . 'img-src \'self\' data: tile.openstreetmap.org;object-src \'none\';',
223 'default-src \'self\' ;script-src \'self\' \'unsafe-inline\' \'unsafe-eval\';'
224 . 'referrer no-referrer;style-src \'self\' \'unsafe-inline\' ;'
225 . 'img-src \'self\' data: tile.openstreetmap.org;object-src \'none\';',
228 'SameOrigin',
229 'example.com example.net',
230 'PrivateKey',
231 'PublicKey',
232 'captcha.tld csp.tld',
233 'SAMEORIGIN',
234 'default-src \'self\' captcha.tld csp.tld example.com example.net;'
235 . 'script-src \'self\' \'unsafe-inline\' \'unsafe-eval\' '
236 . 'captcha.tld csp.tld example.com example.net;'
237 . 'style-src \'self\' \'unsafe-inline\' captcha.tld csp.tld example.com example.net;'
238 . 'img-src \'self\' data: example.com example.net tile.openstreetmap.org captcha.tld csp.tld ;'
239 . 'object-src \'none\';',
240 'default-src \'self\' captcha.tld csp.tld example.com example.net;'
241 . 'options inline-script eval-script;referrer no-referrer;img-src \'self\' data: example.com '
242 . 'example.net tile.openstreetmap.org captcha.tld csp.tld ;object-src \'none\';',
243 'default-src \'self\' captcha.tld csp.tld example.com example.net;script-src \'self\' '
244 . 'captcha.tld csp.tld example.com example.net \'unsafe-inline\' \'unsafe-eval\';'
245 . 'referrer no-referrer;style-src \'self\' \'unsafe-inline\' captcha.tld csp.tld ;'
246 . 'img-src \'self\' data: example.com example.net tile.openstreetmap.org captcha.tld csp.tld ;'
247 . 'object-src \'none\';',
250 true,
252 'PrivateKey',
253 'PublicKey',
254 'captcha.tld csp.tld',
255 null,
256 'default-src \'self\' captcha.tld csp.tld ;'
257 . 'script-src \'self\' \'unsafe-inline\' \'unsafe-eval\' captcha.tld csp.tld ;'
258 . 'style-src \'self\' \'unsafe-inline\' captcha.tld csp.tld ;'
259 . 'img-src \'self\' data: tile.openstreetmap.org captcha.tld csp.tld ;object-src \'none\';',
260 'default-src \'self\' captcha.tld csp.tld ;'
261 . 'options inline-script eval-script;referrer no-referrer;'
262 . 'img-src \'self\' data: tile.openstreetmap.org captcha.tld csp.tld ;object-src \'none\';',
263 'default-src \'self\' captcha.tld csp.tld ;'
264 . 'script-src \'self\' captcha.tld csp.tld \'unsafe-inline\' \'unsafe-eval\';'
265 . 'referrer no-referrer;style-src \'self\' \'unsafe-inline\' captcha.tld csp.tld ;'
266 . 'img-src \'self\' data: tile.openstreetmap.org captcha.tld csp.tld ;object-src \'none\';',
271 public function testAddedDefaultScripts(): void
273 $header = $this->getNewHeaderInstance();
274 $scripts = $header->getScripts();
275 $expected = [
276 ['name' => 'runtime.js', 'fire' => 0],
277 ['name' => 'vendor/jquery/jquery.min.js', 'fire' => 0],
278 ['name' => 'vendor/jquery/jquery-migrate.min.js', 'fire' => 0],
279 ['name' => 'vendor/sprintf.js', 'fire' => 0],
280 ['name' => 'vendor/jquery/jquery-ui.min.js', 'fire' => 0],
281 ['name' => 'vendor/bootstrap/bootstrap.bundle.min.js', 'fire' => 0],
282 ['name' => 'vendor/js.cookie.min.js', 'fire' => 0],
283 ['name' => 'vendor/jquery/jquery.validate.min.js', 'fire' => 0],
284 ['name' => 'vendor/jquery/jquery-ui-timepicker-addon.js', 'fire' => 0],
285 ['name' => 'index.php', 'fire' => 0],
286 ['name' => 'shared.js', 'fire' => 0],
287 ['name' => 'menu_resizer.js', 'fire' => 1],
288 ['name' => 'main.js', 'fire' => 1],
290 self::assertSame($expected, $scripts->getFiles());