153 lines
4.9 KiB
Python
153 lines
4.9 KiB
Python
|
|
# retoor <retoor@molodetz.nl>
|
||
|
|
|
||
|
|
import time
|
||
|
|
from datetime import datetime, timezone
|
||
|
|
|
||
|
|
import pytest
|
||
|
|
import requests
|
||
|
|
|
||
|
|
from devplacepy.database import get_table, refresh_snapshot
|
||
|
|
from tests.conftest import BASE_URL
|
||
|
|
|
||
|
|
JSON = {"Accept": "application/json"}
|
||
|
|
_counter = [0]
|
||
|
|
|
||
|
|
|
||
|
|
def _unique(prefix="wsi"):
|
||
|
|
_counter[0] += 1
|
||
|
|
return f"{prefix}{int(time.time() * 1000)}{_counter[0]}"
|
||
|
|
|
||
|
|
|
||
|
|
def _member():
|
||
|
|
name = _unique()
|
||
|
|
session = requests.Session()
|
||
|
|
session.post(
|
||
|
|
f"{BASE_URL}/auth/signup",
|
||
|
|
data={
|
||
|
|
"username": name,
|
||
|
|
"email": f"{name}@t.dev",
|
||
|
|
"password": "secret123",
|
||
|
|
"confirm_password": "secret123",
|
||
|
|
"birth_date": "1990-01-01",
|
||
|
|
"accept_terms": "1",
|
||
|
|
},
|
||
|
|
allow_redirects=True,
|
||
|
|
)
|
||
|
|
refresh_snapshot()
|
||
|
|
return session, name, get_table("users").find_one(username=name)
|
||
|
|
|
||
|
|
|
||
|
|
def _project(session, title, private=False):
|
||
|
|
data = {
|
||
|
|
"title": title,
|
||
|
|
"description": f"Description of {title}.",
|
||
|
|
"project_type": "software",
|
||
|
|
"status": "In Development",
|
||
|
|
}
|
||
|
|
if private:
|
||
|
|
data["is_private"] = "on"
|
||
|
|
response = session.post(f"{BASE_URL}/projects/create", data=data, headers=JSON)
|
||
|
|
assert response.status_code == 200, response.text
|
||
|
|
refresh_snapshot()
|
||
|
|
return get_table("projects").find_one(slug=response.json()["data"]["slug"])
|
||
|
|
|
||
|
|
|
||
|
|
def _publish(project, owner_uid):
|
||
|
|
uid = _unique("wsuid")
|
||
|
|
slug = _unique("wsslug")
|
||
|
|
get_table("instances").insert(
|
||
|
|
{
|
||
|
|
"deleted_at": None,
|
||
|
|
"deleted_by": None,
|
||
|
|
"uid": uid,
|
||
|
|
"project_uid": project["uid"],
|
||
|
|
"owner_uid": owner_uid,
|
||
|
|
"name": f"workspace {slug}",
|
||
|
|
"slug": slug,
|
||
|
|
"ingress_slug": slug,
|
||
|
|
"status": "running",
|
||
|
|
"desired_state": "running",
|
||
|
|
"created_at": datetime.now(timezone.utc).isoformat(),
|
||
|
|
}
|
||
|
|
)
|
||
|
|
refresh_snapshot()
|
||
|
|
return uid, slug
|
||
|
|
|
||
|
|
|
||
|
|
@pytest.fixture(scope="module")
|
||
|
|
def published(app_server):
|
||
|
|
session, name, user = _member()
|
||
|
|
public = _project(session, f"Public {name}")
|
||
|
|
private = _project(session, f"Private {name}", private=True)
|
||
|
|
public_uid, public_slug = _publish(public, user["uid"])
|
||
|
|
private_uid, private_slug = _publish(private, user["uid"])
|
||
|
|
yield {
|
||
|
|
"session": session,
|
||
|
|
"user": user,
|
||
|
|
"public": {"project": public, "uid": public_uid, "slug": public_slug},
|
||
|
|
"private": {"project": private, "uid": private_uid, "slug": private_slug},
|
||
|
|
}
|
||
|
|
instances = get_table("instances")
|
||
|
|
instances.delete(uid=public_uid)
|
||
|
|
instances.delete(uid=private_uid)
|
||
|
|
|
||
|
|
|
||
|
|
def _entries(session=None, key=None):
|
||
|
|
headers = dict(JSON)
|
||
|
|
if key:
|
||
|
|
headers["X-API-KEY"] = key
|
||
|
|
caller = session or requests
|
||
|
|
response = caller.get(f"{BASE_URL}/workspaces/index", headers=headers)
|
||
|
|
assert response.status_code == 200, response.text
|
||
|
|
return {entry["slug"]: entry for entry in response.json()["workspaces"]}
|
||
|
|
|
||
|
|
|
||
|
|
def test_the_index_is_public_and_lists_every_published_workspace(published):
|
||
|
|
entries = _entries()
|
||
|
|
assert published["public"]["slug"] in entries
|
||
|
|
assert published["private"]["slug"] in entries
|
||
|
|
|
||
|
|
|
||
|
|
def test_each_row_exposes_its_uid_and_owner_uid_field(published):
|
||
|
|
entries = _entries()
|
||
|
|
row = entries[published["public"]["slug"]]
|
||
|
|
assert row["uid"] == published["public"]["uid"]
|
||
|
|
assert "owner_uid" in row
|
||
|
|
|
||
|
|
|
||
|
|
def test_a_private_projects_description_and_url_are_withheld_from_a_guest(published):
|
||
|
|
entries = _entries()
|
||
|
|
public_row = entries[published["public"]["slug"]]
|
||
|
|
private_row = entries[published["private"]["slug"]]
|
||
|
|
assert public_row["description"] == published["public"]["project"]["description"]
|
||
|
|
assert public_row["project_url"] == f"/projects/{published['public']['project']['slug']}"
|
||
|
|
assert private_row["description"] == ""
|
||
|
|
assert private_row["project_url"] == ""
|
||
|
|
|
||
|
|
|
||
|
|
def test_the_owner_still_sees_their_private_projects_fields(published):
|
||
|
|
entries = _entries(key=published["user"]["api_key"])
|
||
|
|
private_row = entries[published["private"]["slug"]]
|
||
|
|
assert private_row["description"] == published["private"]["project"]["description"]
|
||
|
|
assert (
|
||
|
|
private_row["project_url"]
|
||
|
|
== f"/projects/{published['private']['project']['slug']}"
|
||
|
|
)
|
||
|
|
|
||
|
|
|
||
|
|
def test_a_stranger_is_treated_like_a_guest(published):
|
||
|
|
stranger, _, user = _member()
|
||
|
|
entries = _entries(session=stranger, key=user["api_key"])
|
||
|
|
assert entries[published["private"]["slug"]]["description"] == ""
|
||
|
|
assert entries[published["private"]["slug"]]["project_url"] == ""
|
||
|
|
|
||
|
|
|
||
|
|
def test_the_table_carries_a_report_control_column(published):
|
||
|
|
reporter, _, _ = _member()
|
||
|
|
html = reporter.get(f"{BASE_URL}/workspaces/index").text
|
||
|
|
assert '<th scope="col">Report</th>' in html
|
||
|
|
assert 'data-report-type="workspace"' in html
|
||
|
|
assert f'data-report-uid="{published["public"]["uid"]}"' in html
|
||
|
|
assert "css/admin.css" in html
|
||
|
|
assert 'class="admin-table"' in html
|