feat: serve landing page via Jinja2 with module grid
This commit is contained in:
parent
90d7910500
commit
9e60fbb7cf
68
app/main.py
68
app/main.py
@ -1,4 +1,7 @@
|
||||
from fastapi import FastAPI, WebSocket
|
||||
from fastapi import FastAPI, Request, WebSocket
|
||||
from fastapi.responses import HTMLResponse
|
||||
from fastapi.staticfiles import StaticFiles
|
||||
from fastapi.templating import Jinja2Templates
|
||||
|
||||
from app.core.config import get_settings
|
||||
|
||||
@ -9,10 +12,67 @@ app = FastAPI(
|
||||
root_path=settings.APP_PREFIX,
|
||||
)
|
||||
|
||||
app.mount("/static", StaticFiles(directory="app/static"), name="static")
|
||||
templates = Jinja2Templates(directory="app/templates")
|
||||
|
||||
@app.get("/")
|
||||
async def root():
|
||||
return {"status": "ok", "env": settings.APP_ENV}
|
||||
MODULES = [
|
||||
{
|
||||
"icon": "📡",
|
||||
"name": "RSS-Feed Server",
|
||||
"description": "Aggregiert und verteilt Neuigkeiten der Fakultät als standardkonformen RSS 2.0 Feed.",
|
||||
"status": "active",
|
||||
},
|
||||
{
|
||||
"icon": "📅",
|
||||
"name": "Kalender",
|
||||
"description": "Veranstaltungen, Prüfungstermine und Fristen im iCal-Format.",
|
||||
"status": "planned",
|
||||
},
|
||||
{
|
||||
"icon": "🔔",
|
||||
"name": "Benachrichtigungen",
|
||||
"description": "Push-Nachrichten und WebSocket-basierte Echtzeit-Alerts für Studierende.",
|
||||
"status": "planned",
|
||||
},
|
||||
{
|
||||
"icon": "📊",
|
||||
"name": "Auslastung",
|
||||
"description": "Raum- und Ressourcenauslastung der Fakultät in Echtzeit.",
|
||||
"status": "planned",
|
||||
},
|
||||
{
|
||||
"icon": "📚",
|
||||
"name": "Lehrveranstaltungen",
|
||||
"description": "Stundenplan-API und Kursinformationen aus dem Campus-System.",
|
||||
"status": "planned",
|
||||
},
|
||||
]
|
||||
|
||||
NAV_ITEMS = [
|
||||
{"label": "Übersicht", "url": "/", "active": True},
|
||||
{"label": "RSS-Feeds", "url": "/rss", "active": False},
|
||||
{"label": "Kalender", "url": "/kalender", "active": False},
|
||||
{"label": "Docs", "url": "/docs", "active": False},
|
||||
]
|
||||
|
||||
|
||||
def _db_mode() -> str:
|
||||
url = settings.DATABASE_URL
|
||||
return "SQLite (dev)" if url.startswith("sqlite") else "MariaDB (prod)"
|
||||
|
||||
|
||||
@app.get("/", response_class=HTMLResponse)
|
||||
async def root(request: Request):
|
||||
return templates.TemplateResponse(
|
||||
request,
|
||||
"index.html",
|
||||
{
|
||||
"nav_items": NAV_ITEMS,
|
||||
"modules": MODULES,
|
||||
"db_mode": _db_mode(),
|
||||
"app_version": "0.1.0",
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
@app.websocket("/ws/hello/{name}")
|
||||
|
||||
0
tests/__init__.py
Normal file
0
tests/__init__.py
Normal file
31
tests/test_landing.py
Normal file
31
tests/test_landing.py
Normal file
@ -0,0 +1,31 @@
|
||||
from fastapi.testclient import TestClient
|
||||
from app.main import app
|
||||
|
||||
client = TestClient(app)
|
||||
|
||||
|
||||
def test_landing_returns_html():
|
||||
response = client.get("/")
|
||||
assert response.status_code == 200
|
||||
assert "text/html" in response.headers["content-type"]
|
||||
|
||||
|
||||
def test_landing_contains_title():
|
||||
response = client.get("/")
|
||||
assert "University Process Hub" in response.text
|
||||
|
||||
|
||||
def test_landing_contains_rss_module():
|
||||
response = client.get("/")
|
||||
assert "RSS-Feed Server" in response.text
|
||||
|
||||
|
||||
def test_landing_navbar_links_present():
|
||||
response = client.get("/")
|
||||
assert "Übersicht" in response.text
|
||||
assert "RSS-Feeds" in response.text
|
||||
|
||||
|
||||
def test_landing_info_strip_shows_db_mode():
|
||||
response = client.get("/")
|
||||
assert "SQLite" in response.text or "MariaDB" in response.text
|
||||
Loading…
x
Reference in New Issue
Block a user