umbau 1.0
This commit is contained in:
76
tests/test_teil_f_schritt3.py
Normal file
76
tests/test_teil_f_schritt3.py
Normal file
@ -0,0 +1,76 @@
|
||||
"""Tests fuer Teil F.3 (Stufe F3, Umsetzungsauftrag_Sonnet5.md): die
|
||||
dauerhafte Arbeitsflaeche /workspace.
|
||||
|
||||
Diese Stufe ist ueberwiegend Frontend (templates/workspace.html,
|
||||
static/js/workspace.js) -- die serverseitige Flaeche ist bewusst klein
|
||||
(rein statisches Markup wie /dashboard, Auth clientseitig ueber
|
||||
GET /auth/me, siehe app/main.py::workspace_page). Die CSP-Konformitaet
|
||||
(kein Inline-style/-script) wird zentral in tests/test_csp_compliance.py
|
||||
mitgeprueft (/workspace wurde dort in die Parametrisierung aufgenommen).
|
||||
Hier: die Route existiert, liefert die erwarteten Bausteine aus, und die
|
||||
Backend-Bausteine, auf denen workspace.js aufbaut (GET /catalog/hosts,
|
||||
GET /catalog/sessions), bleiben nutzbar."""
|
||||
from __future__ import annotations
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_workspace_page_renders_without_login(client):
|
||||
"""Wie /dashboard/-admin: die Seite selbst ist statisches Markup ohne
|
||||
Secrets -- die eigentliche Zugriffskontrolle laeuft clientseitig ueber
|
||||
GET /auth/me (401 -> Redirect zu /) UND serverseitig hart auf jedem
|
||||
/catalog/*-API-Aufruf, den workspace.js danach macht."""
|
||||
resp = await client.get("/workspace")
|
||||
assert resp.status_code == 200, resp.text
|
||||
html = resp.text
|
||||
assert 'id="workspace-tiles"' in html
|
||||
assert 'id="workspace-catalog-view"' in html
|
||||
assert 'id="workspace-sessions-area"' in html
|
||||
assert 'id="workspace-new-btn"' in html
|
||||
assert '/static/js/workspace.js' in html
|
||||
# F1-Bausteine werden mitgeladen (kein zweiter Sitzungs-Code, F.2).
|
||||
assert '/static/js/terminal.js' in html
|
||||
assert '/static/js/rdp.js' in html
|
||||
# F3 baut das Sitzungs-DOM erst zur Laufzeit -- kein #session-container
|
||||
# mit data-host-id wie bei /terminal/{id}, /rdp/{id} (die Seite haette
|
||||
# sonst automatisch eine Sitzung bootstrapped, siehe terminal.js/rdp.js
|
||||
# Bootstrap-Block).
|
||||
assert 'id="session-container"' not in html
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_workspace_backend_building_blocks_reachable_after_login(client):
|
||||
"""workspace.js ruft beim Laden GET /catalog/hosts und
|
||||
GET /catalog/sessions auf -- beide muessen fuer einen angemeldeten
|
||||
Benutzer erreichbar sein (volle Auth-Pruefung liegt bereits in
|
||||
test_teil_f_schritt2.py und den bestehenden Katalog-Tests; hier nur der
|
||||
Zusammenhang mit der neuen Seite)."""
|
||||
from app.db import get_db
|
||||
from app.security.passwords import hash_password
|
||||
import pyotp
|
||||
|
||||
conn = get_db()
|
||||
await conn.execute(
|
||||
"INSERT INTO users (username, password_hash, is_admin, must_change_password) "
|
||||
"VALUES ('f3_user', ?, 0, 0)",
|
||||
(hash_password("Correct-Horse-Battery-Staple-F3"),),
|
||||
)
|
||||
await conn.commit()
|
||||
|
||||
resp = await client.post("/auth/login", json={"username": "f3_user", "password": "Correct-Horse-Battery-Staple-F3"})
|
||||
pending = resp.json()["pending_token"]
|
||||
resp = await client.post("/auth/totp/enroll/start", json={"pending_token": pending})
|
||||
provisioning_uri = resp.json()["provisioning_uri"]
|
||||
secret = dict(part.split("=") for part in provisioning_uri.split("?", 1)[1].split("&"))["secret"]
|
||||
code = pyotp.TOTP(secret).now()
|
||||
resp = await client.post("/auth/totp/enroll/confirm", json={"pending_token": pending, "code": code})
|
||||
assert resp.status_code == 200, resp.text
|
||||
|
||||
resp = await client.get("/catalog/hosts")
|
||||
assert resp.status_code == 200, resp.text
|
||||
assert isinstance(resp.json(), list)
|
||||
|
||||
resp = await client.get("/catalog/sessions")
|
||||
assert resp.status_code == 200, resp.text
|
||||
assert resp.json() == [] # frisch angemeldeter Benutzer hat keine offenen Sitzungen
|
||||
Reference in New Issue
Block a user