feat: brand-new interface

This was initally generated by ai, but later has been heavily edited.
The reason why it has been implemented is that there are plans to
implement more features to ui, but it becomes hard to add new features
to plain js, so I decided to rewrite it in typescript.

Yet because it is still ai slop, it is still possible to enable old
interface via configuration, even though new interface is turned on by
default to get feedback
This commit is contained in:
2026-02-25 22:49:38 +02:00
parent db46147f0d
commit dd31f37c2a
158 changed files with 5979 additions and 304 deletions

View File

@@ -16,6 +16,13 @@ def test_auth_control(auth: Auth) -> None:
assert "button" in auth.auth_control # I think it should be a button
def test_is_external(auth: Auth) -> None:
"""
must not be external provider
"""
assert not auth.is_external
def test_load_dummy(configuration: Configuration, database: SQLite) -> None:
"""
must load dummy validator if authorization is not enabled

View File

@@ -15,6 +15,13 @@ def test_auth_control(oauth: OAuth) -> None:
assert "<a" in oauth.auth_control # I think it should be a link
def test_is_external(oauth: OAuth) -> None:
"""
must be external provider
"""
assert oauth.is_external
def test_get_provider() -> None:
"""
must return valid provider type

View File

@@ -583,6 +583,7 @@ def test_walk(resource_path_root: Path) -> None:
resource_path_root / "web" / "templates" / "utils" / "style.jinja2",
resource_path_root / "web" / "templates" / "api.jinja2",
resource_path_root / "web" / "templates" / "build-status.jinja2",
resource_path_root / "web" / "templates" / "build-status-legacy.jinja2",
resource_path_root / "web" / "templates" / "email-index.jinja2",
resource_path_root / "web" / "templates" / "error.jinja2",
resource_path_root / "web" / "templates" / "repo-index.jinja2",
@@ -590,5 +591,5 @@ def test_walk(resource_path_root: Path) -> None:
resource_path_root / "web" / "templates" / "shell",
resource_path_root / "web" / "templates" / "telegram-index.jinja2",
])
local_files = list(sorted(walk(resource_path_root)))
local_files = list(path for path in sorted(walk(resource_path_root)) if path.name not in ("index.js", "index.css"))
assert local_files == expected

View File

@@ -0,0 +1 @@
# schema testing goes in view class tests

View File

@@ -0,0 +1 @@
# schema testing goes in view class tests

View File

@@ -0,0 +1 @@
# schema testing goes in view class tests

View File

@@ -0,0 +1,27 @@
import pytest
from aiohttp.web import Application
from ahriman import __version__
from ahriman.models.repository_id import RepositoryId
from ahriman.web.server_info import server_info
from ahriman.web.views.index import IndexView
async def test_server_info(application: Application, repository_id: RepositoryId) -> None:
"""
must generate server info
"""
request = pytest.helpers.request(application, "", "GET")
view = IndexView(request)
result = await server_info(view)
assert result["repositories"] == [{"id": repository_id.id, **repository_id.view()}]
assert not result["auth"]["enabled"]
assert not result["auth"]["external"]
assert result["auth"]["username"] is None
assert result["auth"]["control"]
assert result["version"] == __version__
assert result["autorefresh_intervals"] == []
assert result["docs_enabled"]
assert result["index_url"] is None

View File

@@ -35,6 +35,6 @@ async def test_get(client: TestClient, repository_id: RepositoryId) -> None:
json = await response.json()
assert not response_schema.validate(json)
assert json["repositories"] == [repository_id.view()]
assert json["repositories"] == [{"id": repository_id.id, **repository_id.view()}]
assert not json["auth"]
assert json["version"] == __version__

View File

@@ -0,0 +1,43 @@
import pytest
from aiohttp.test_utils import TestClient
from ahriman import __version__
from ahriman.models.repository_id import RepositoryId
from ahriman.models.user_access import UserAccess
from ahriman.web.views.v2.status.info import InfoView
async def test_get_permission() -> None:
"""
must return correct permission for the request
"""
for method in ("GET",):
request = pytest.helpers.request("", "", method)
assert await InfoView.get_permission(request) == UserAccess.Unauthorized
def test_routes() -> None:
"""
must return correct routes
"""
assert InfoView.ROUTES == ["/api/v2/info"]
async def test_get(client: TestClient, repository_id: RepositoryId) -> None:
"""
must return service information
"""
response_schema = pytest.helpers.schema_response(InfoView.get)
response = await client.get("/api/v2/info")
assert response.ok
json = await response.json()
assert not response_schema.validate(json)
assert json["repositories"] == [{"id": repository_id.id, **repository_id.view()}]
assert not json["auth"]["enabled"]
assert json["auth"]["control"]
assert json["version"] == __version__
assert json["autorefresh_intervals"] == []
assert json["docs_enabled"]