81 lines
3.6 KiB
Python
81 lines
3.6 KiB
Python
"""Speicherkontingent je Workspace für Uploads."""
|
|
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
from fastapi.testclient import TestClient
|
|
from sqlalchemy import select
|
|
|
|
from app.identity.models import User
|
|
from app.main import create_app
|
|
from app.uploads.models import Upload
|
|
from app.workspaces.models import Workspace
|
|
from helpers import create_workspace
|
|
|
|
CSV = b"region,umsatz\nNord,100\nSued,250\n"
|
|
|
|
|
|
@pytest.fixture
|
|
def ws(browser, people, db):
|
|
with db.session() as session:
|
|
session.get(User, people["anna"]).is_admin = True
|
|
anna = browser("anna")
|
|
workspace_id = create_workspace(anna, people["team_demo"], "Speicher")
|
|
anna.post(f"/workspaces/{workspace_id}/members", {"username": "ben", "role": "member"})
|
|
return {"anna": anna, "ben": browser("ben"), "id": workspace_id, "team": people["team_demo"]}
|
|
|
|
|
|
def upload(b, workspace_id, name="umsatz.csv"):
|
|
return b.post(f"/workspaces/{workspace_id}/uploads", files={"file": (name, CSV)})
|
|
|
|
|
|
def test_belegung_wird_angezeigt_und_gezaehlt(ws, db):
|
|
assert upload(ws["ben"], ws["id"]).status_code == 303
|
|
with db.session() as session:
|
|
stored = session.scalar(select(Upload.stored_size))
|
|
assert stored > 0
|
|
page = ws["ben"].get(f"/workspaces/{ws['id']}/data").text
|
|
assert "von 500 MB belegt" in page and "<meter" in page
|
|
|
|
|
|
def test_kontingent_voll_lehnt_ab(ws, db, settings):
|
|
upload(ws["ben"], ws["id"])
|
|
with db.session() as session:
|
|
session.get(Workspace, ws["id"]).storage_limit_mb = 1
|
|
# Eine DuckDB-Datei ist mindestens ~0,5 MB: die zweite passt nicht mehr ins Kontingent von 1 MB
|
|
response = upload(ws["ben"], ws["id"], "zwei.csv")
|
|
assert response.status_code == 400 and "Speicherkontingent" in response.text
|
|
with db.session() as session:
|
|
assert session.scalar(select(Upload).where(Upload.filename == "zwei.csv")) is None
|
|
files = {u.id for u in session.scalars(select(Upload))}
|
|
assert {int(p.stem) for p in (Path(settings.upload_dir) / str(ws["id"])).glob("*.duckdb")} == files
|
|
assert "von 1 MB belegt" in ws["ben"].get(f"/workspaces/{ws['id']}/data").text
|
|
# Voll: schon vor dem Hochladen abgelehnt, mit Hinweis auf der Seite
|
|
with db.session() as session:
|
|
session.scalar(select(Upload)).stored_size = 2 * 1024 * 1024
|
|
assert "ausgeschöpft" in upload(ws["ben"], ws["id"], "drei.csv").text
|
|
assert "ausgeschöpft" in ws["ben"].get(f"/workspaces/{ws['id']}/data").text
|
|
|
|
|
|
def test_nur_plattform_admin_setzt_kontingent(ws, db, people):
|
|
url = f"/admin/teams/{ws['team']}/workspaces/{ws['id']}/storage"
|
|
assert ws["ben"].post(url, {"limit_mb": "5"}).status_code == 403
|
|
response = ws["anna"].post(url, {"limit_mb": "abc"})
|
|
assert response.status_code == 400 and "ganze Zahl" in response.text
|
|
assert "gespeichert" in ws["anna"].post(url, {"limit_mb": "2000"}).text
|
|
with db.session() as session:
|
|
assert session.get(Workspace, ws["id"]).storage_limit_mb == 2000
|
|
assert "von 2000 MB belegt" in ws["ben"].get(f"/workspaces/{ws['id']}/data").text
|
|
ws["anna"].post(url, {"limit_mb": ""})
|
|
with db.session() as session:
|
|
assert session.get(Workspace, ws["id"]).storage_limit_mb is None
|
|
|
|
|
|
def test_metrik_meldet_volle_workspaces(ws, db, settings):
|
|
upload(ws["ben"], ws["id"])
|
|
with db.session() as session:
|
|
session.get(Workspace, ws["id"]).storage_limit_mb = 1
|
|
session.scalar(select(Upload)).stored_size = 900 * 1024
|
|
client = TestClient(create_app(settings.model_copy(update={"metrics_token": "t-123456"}), listen=False))
|
|
text = client.get("/metrics", headers={"Authorization": "Bearer t-123456"}).text
|
|
assert "aiw_workspaces_storage_high 1.0" in text
|