test(files): add server-detail e2e fixture

Adds server_with_files fixture: seeds alice + a Blueprint + a Server
row pinned to port 27015, then pre-creates
LEFT4ME_ROOT/runtime/<server_id>/merged/ with a single seed file.
The /servers/<id> page lists files from that merged directory (the
kernel-overlayfs view of a running server), which never exists on
dev/test boxes — without the pre-mkdir + seed, the page renders
the empty-state branch instead of file rows.

Server.port is a global UNIQUE constraint on the model, but every
e2e test gets its own SQLite DB, so a fixed L4D2-default port is
fine.

Sets the stage for the Tier 3 hover-download test.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
mwiegand 2026-05-17 19:20:20 +02:00
parent e89dd25cdd
commit b43bb9e0fa
No known key found for this signature in database

View file

@ -14,7 +14,7 @@ from werkzeug.serving import make_server
from l4d2web.app import create_app from l4d2web.app import create_app
from l4d2web.auth import hash_password from l4d2web.auth import hash_password
from l4d2web.db import init_db, session_scope from l4d2web.db import init_db, session_scope
from l4d2web.models import Blueprint, Overlay, User from l4d2web.models import Blueprint, Overlay, Server, User
def _free_port() -> int: def _free_port() -> int:
@ -164,3 +164,65 @@ def files_overlay_server(tmp_path, monkeypatch):
} }
finally: finally:
shutdown() shutdown()
@pytest.fixture(scope="function")
def server_with_files(tmp_path, monkeypatch):
"""live_server + a Server owned by alice with a populated runtime
merged directory. Used by the server-detail e2e tests that exercise
file rows + download.
The /servers/<id> page lists files from
LEFT4ME_ROOT/runtime/<server_id>/merged/ (the kernel-overlayfs view
of a running server). On a dev/test box no overlayfs is mounted, so
the fixture pre-creates that directory and seeds one plain file
enough for the file-tree partial to render rows.
Yields {base_url, user_id, blueprint_id, server_id, merged_root}.
"""
monkeypatch.setenv("LEFT4ME_ROOT", str(tmp_path))
app = _boot_app(tmp_path, monkeypatch)
with session_scope() as session:
user = User(
username="alice",
password_digest=hash_password("secret"),
admin=False,
)
session.add(user)
session.flush()
bp = Blueprint(
user_id=user.id, name="bp", arguments="[]", config="[]"
)
session.add(bp)
session.flush()
# Server.port has a global UNIQUE constraint, but this is a
# fresh per-test SQLite DB so any value works — 27015 is the
# L4D2 default, semantically obvious.
server = Server(
user_id=user.id,
blueprint_id=bp.id,
name="srv",
port=27015,
)
session.add(server)
session.flush()
user_id = user.id
blueprint_id = bp.id
server_id = server.id
merged_root = tmp_path / "runtime" / str(server_id) / "merged"
merged_root.mkdir(parents=True)
(merged_root / "server.cfg").write_text('hostname "from-merged-runtime"\n')
base_url, shutdown = _serve(app)
try:
yield {
"base_url": base_url,
"user_id": user_id,
"blueprint_id": blueprint_id,
"server_id": server_id,
"merged_root": merged_root,
}
finally:
shutdown()