67 lines
2.8 KiB
Python
67 lines
2.8 KiB
Python
import os
|
||
import unittest
|
||
from pathlib import Path
|
||
|
||
from httpx import ASGITransport, AsyncClient
|
||
|
||
MASTER_KEY = "master-secret-for-ui-tests"
|
||
os.environ["IGNIS_API_KEY"] = MASTER_KEY
|
||
|
||
import main # noqa: E402
|
||
|
||
|
||
class UiSecurityTests(unittest.IsolatedAsyncioTestCase):
|
||
async def asyncSetUp(self):
|
||
self.client = AsyncClient(
|
||
transport=ASGITransport(app=main.app),
|
||
base_url="http://testserver",
|
||
)
|
||
|
||
async def asyncTearDown(self):
|
||
await self.client.aclose()
|
||
|
||
async def test_root_sets_security_headers(self):
|
||
response = await self.client.get("/")
|
||
|
||
self.assertEqual(response.status_code, 200)
|
||
self.assertEqual(response.headers["cache-control"], "no-store")
|
||
self.assertEqual(response.headers["pragma"], "no-cache")
|
||
self.assertEqual(response.headers["referrer-policy"], "no-referrer")
|
||
self.assertEqual(response.headers["x-content-type-options"], "nosniff")
|
||
self.assertEqual(response.headers["x-frame-options"], "DENY")
|
||
self.assertIn("default-src 'self'", response.headers["content-security-policy"])
|
||
self.assertIn(
|
||
"script-src 'self' 'unsafe-eval'",
|
||
response.headers["content-security-policy"],
|
||
)
|
||
self.assertIn(
|
||
"style-src 'self' 'unsafe-inline'",
|
||
response.headers["content-security-policy"],
|
||
)
|
||
|
||
async def test_static_ui_uses_only_local_assets_and_session_storage(self):
|
||
index_html = Path("static/index.html").read_text(encoding="utf-8")
|
||
app_js = Path("static/app.js").read_text(encoding="utf-8")
|
||
|
||
self.assertIn("/static/vendor/tailwindcdn.js", index_html)
|
||
self.assertIn("/static/ui.css", index_html)
|
||
self.assertIn("/static/vendor/vue.global.prod.js", index_html)
|
||
self.assertIn("/static/app.js", index_html)
|
||
self.assertNotIn("https://unpkg.com", index_html)
|
||
self.assertNotIn("https://cdn.tailwindcss.com", index_html)
|
||
self.assertNotIn("https://fonts.googleapis.com", index_html)
|
||
self.assertNotIn("localStorage", index_html)
|
||
self.assertNotIn("localStorage", app_js)
|
||
self.assertIn("sessionStorage", app_js)
|
||
self.assertIn("/system/info", app_js)
|
||
self.assertIn("serverInfo", app_js)
|
||
self.assertIn("Комнаты, сцены и свет", index_html)
|
||
self.assertIn("Устройства и группы", index_html)
|
||
self.assertIn("Собрать комнату из найденных ламп", index_html)
|
||
self.assertIn("Повторяющееся расписание", index_html)
|
||
self.assertIn("Гостевые и админ-ключи", index_html)
|
||
self.assertIn("О сервере", index_html)
|
||
self.assertIn("Запущен", index_html)
|
||
self.assertNotIn("ОБЗОР", index_html)
|
||
self.assertNotIn("tab === 'overview'", app_js)
|