# retoor import time import requests from tests.conftest import BASE_URL, login_user from devplacepy.database import ( get_table, get_primary_admin_uid, invalidate_admins_cache, refresh_snapshot, ) from devplacepy.utils import clear_user_cache _counter = [0] def _make_admin(): _counter[0] += 1 name = f"ecm{int(time.time() * 1000)}{_counter[0]}" password = "secret123" requests.post( f"{BASE_URL}/auth/signup", data={ "username": name, "email": f"{name}@t.dev", "password": password, "confirm_password": password, }, allow_redirects=True, ) refresh_snapshot() row = get_table("users").find_one(username=name) get_table("users").update({"uid": row["uid"], "role": "Admin"}, ["uid"]) clear_user_cache(row["uid"]) invalidate_admins_cache() return { "email": f"{name}@t.dev", "password": password, "uid": row["uid"], "api_key": row["api_key"], } def _demote_existing_admins(): existing = [r["uid"] for r in get_table("users").find(role="Admin")] for uid in existing: get_table("users").update({"uid": uid, "role": "Member"}, ["uid"]) invalidate_admins_cache() return existing def _restore_admins(uids): for uid in uids: get_table("users").update({"uid": uid, "role": "Admin"}, ["uid"]) invalidate_admins_cache() def _create_project(api_key, title, is_private=False): data = { "title": title, "description": "e2e container manage isolation", "project_type": "software", "status": "In Development", } if is_private: data["is_private"] = "on" r = requests.post( f"{BASE_URL}/projects/create", headers={"Accept": "application/json", "X-API-KEY": api_key}, data=data, ) assert r.status_code == 200, r.text return r.json()["data"] def _insert_instance(project_uid, created_by): uid = f"ecm-{int(time.time() * 1000000)}" get_table("instances").insert( { "uid": uid, "slug": uid, "name": "e2e-manage-test", "project_uid": project_uid, "created_by": created_by, "owner_uid": "", "status": "stopped", "container_id": "", "workspace_dir": "", "restart_policy": "never", "deleted_at": None, "deleted_by": None, } ) refresh_snapshot() return uid def _cleanup(inst_uid): get_table("instances").delete(uid=inst_uid) refresh_snapshot() def test_admin_list_shows_view_only_for_non_owned_public_instance(page, app_server): owner = _make_admin() other = _make_admin() project = _create_project(owner["api_key"], "E2E Manage List Public", is_private=False) inst_uid = _insert_instance(project["uid"], owner["uid"]) try: login_user(page, other) page.goto(f"{BASE_URL}/admin/containers", wait_until="domcontentloaded") row = page.locator(f"tr.cm-row[data-uid='{inst_uid}']") row.wait_for(state="visible", timeout=15000) assert "view only" in row.inner_text().lower() assert row.locator("[data-cm-action='delete']").count() == 0 finally: _cleanup(inst_uid) def test_admin_list_shows_actions_for_owner(page, app_server): owner = _make_admin() project = _create_project(owner["api_key"], "E2E Manage List Owner", is_private=False) inst_uid = _insert_instance(project["uid"], owner["uid"]) try: login_user(page, owner) page.goto(f"{BASE_URL}/admin/containers", wait_until="domcontentloaded") row = page.locator(f"tr.cm-row[data-uid='{inst_uid}']") row.wait_for(state="visible", timeout=15000) assert row.locator("[data-cm-action='delete']").count() == 1 finally: _cleanup(inst_uid) def test_admin_list_excludes_others_private_project_instance(page, app_server): owner = _make_admin() other = _make_admin() project = _create_project(owner["api_key"], "E2E Manage List Private", is_private=True) inst_uid = _insert_instance(project["uid"], owner["uid"]) try: login_user(page, other) page.goto(f"{BASE_URL}/admin/containers", wait_until="domcontentloaded") assert page.locator(f"tr.cm-row[data-uid='{inst_uid}']").count() == 0 finally: _cleanup(inst_uid) def test_admin_detail_page_view_only_hides_manage_controls(page, app_server): owner = _make_admin() other = _make_admin() project = _create_project(owner["api_key"], "E2E Manage Detail Public", is_private=False) inst_uid = _insert_instance(project["uid"], owner["uid"]) try: login_user(page, other) page.goto(f"{BASE_URL}/admin/containers/{inst_uid}", wait_until="domcontentloaded") actions = page.locator("#ci-actions") actions.wait_for(state="visible") assert "view only" in actions.inner_text().lower() assert page.locator("#ci-term-toggle").count() == 0 assert page.locator("[data-modal='ci-schedule-modal']").count() == 0 assert page.locator("a:has-text('Edit configuration')").count() == 0 finally: _cleanup(inst_uid) def test_admin_detail_page_owner_sees_manage_controls(page, app_server): owner = _make_admin() project = _create_project(owner["api_key"], "E2E Manage Detail Owner", is_private=False) inst_uid = _insert_instance(project["uid"], owner["uid"]) try: login_user(page, owner) page.goto(f"{BASE_URL}/admin/containers/{inst_uid}", wait_until="domcontentloaded") page.locator("[data-modal='ci-schedule-modal']").wait_for(state="visible") assert page.locator("a:has-text('Edit configuration')").count() == 1 assert page.locator("#ci-term-toggle").count() == 1 finally: _cleanup(inst_uid) def test_admin_detail_page_404_for_non_viewer_on_private_project(page, app_server): owner = _make_admin() other = _make_admin() project = _create_project(owner["api_key"], "E2E Manage Detail Private", is_private=True) inst_uid = _insert_instance(project["uid"], owner["uid"]) try: login_user(page, other) page.goto(f"{BASE_URL}/admin/containers/{inst_uid}", wait_until="domcontentloaded") assert page.is_visible("text=Not Found") or page.is_visible("text=404") finally: _cleanup(inst_uid) def test_admin_edit_page_redirects_non_owner_to_detail(page, app_server): owner = _make_admin() other = _make_admin() project = _create_project(owner["api_key"], "E2E Manage Edit Redirect", is_private=False) inst_uid = _insert_instance(project["uid"], owner["uid"]) try: login_user(page, other) page.goto(f"{BASE_URL}/admin/containers/{inst_uid}/edit", wait_until="domcontentloaded") page.wait_for_url(f"**/admin/containers/{inst_uid}", wait_until="domcontentloaded") finally: _cleanup(inst_uid) def test_primary_admin_sees_and_manages_others_private_instance(page, app_server): restore = _demote_existing_admins() try: primary = _make_admin() owner = _make_admin() assert get_primary_admin_uid() == primary["uid"] project = _create_project( owner["api_key"], "E2E Manage Primary Private", is_private=True ) inst_uid = _insert_instance(project["uid"], owner["uid"]) try: login_user(page, primary) page.goto(f"{BASE_URL}/admin/containers", wait_until="domcontentloaded") row = page.locator(f"tr.cm-row[data-uid='{inst_uid}']") row.wait_for(state="visible", timeout=15000) assert row.locator("[data-cm-action='delete']").count() == 1 page.goto(f"{BASE_URL}/admin/containers/{inst_uid}", wait_until="domcontentloaded") page.locator("a:has-text('Edit configuration')").wait_for(state="visible") finally: _cleanup(inst_uid) finally: _restore_admins(restore)