""" e2e tests for the source drop box feature. The drop box is split into two distinct surfaces: - Admin surface (/dropbox/admin) — authenticated, token management - Source surface (/dropbox/upload/) — unauthenticated, CSRF-exempt Tests that exercise the source surface navigate in a fresh browser context (or just navigate directly to the upload URL) to confirm there is no session/authentication requirement on that path. """ from __future__ import annotations import re import time import pytest from playwright.sync_api import Page, expect from tests.e2e.helpers import create_test_image, create_test_txt # --------------------------------------------------------------------------- # Helpers # --------------------------------------------------------------------------- def _create_token(page: Page, live_server: str, label: str = "e2e source", hours: int = 24) -> str: """Create a drop box token via the admin UI and return the full upload URL.""" page.goto(f"{live_server}/dropbox/admin") page.wait_for_load_state("networkidle") label_input = page.locator("input[name='label']") if label_input.count(): label_input.fill(label) page.fill("input[name='hours']", str(hours)) page.fill("input[name='max_files']", "5") page.click("button[type='submit']") page.wait_for_load_state("networkidle") # Flash message contains the upload URL flash = page.locator("[class*='alert']").first.inner_text() match = re.search(r"http://\S+", flash) if not match: raise RuntimeError(f"No upload URL found in flash message: {flash!r}") return match.group(0) # --------------------------------------------------------------------------- # Admin panel tests # --------------------------------------------------------------------------- @pytest.mark.e2e def test_dropbox_admin_page(live_server: str, authenticated_page: Page) -> None: """The /dropbox/admin page loads and shows the token creation form.""" page = authenticated_page page.goto(f"{live_server}/dropbox/admin") page.wait_for_load_state("networkidle") expect(page.locator("input[name='label']")).to_be_visible() expect(page.locator("input[name='hours']")).to_be_visible() expect(page.locator("input[name='max_files']")).to_be_visible() expect(page.locator("button[type='submit']")).to_be_visible() @pytest.mark.e2e def test_create_upload_token(live_server: str, authenticated_page: Page) -> None: """Creating a token shows a success flash and the token appears in the active list.""" page = authenticated_page upload_url = _create_token(page, live_server, label="my-e2e-source") # The upload URL must contain the expected prefix assert "/dropbox/upload/" in upload_url, f"Unexpected upload URL: {upload_url}" # The token should now appear in the active token table # (token[:12] is shown in the table as per the template) token_slug = upload_url.split("/dropbox/upload/")[1].split("?")[0] table = page.locator("table") if table.count() > 0: expect(table).to_contain_text(token_slug[:12]) @pytest.mark.e2e def test_source_upload_page_accessible_without_auth( live_server: str, authenticated_page: Page, page: Page ) -> None: """The source upload page is accessible without any authentication. We get the URL via the admin (authenticated), then open it in a *separate* fresh page that has no session cookie. """ upload_url = _create_token(authenticated_page, live_server, label="anon-test") # Navigate to the upload URL in the unauthenticated page page.goto(upload_url) page.wait_for_load_state("networkidle") # Must not redirect to login assert "/login" not in page.url, ( f"Source upload page redirected to login: {page.url}" ) # Upload form must be present expect(page.locator("input[type='file'], input[name='files']")).to_be_visible() @pytest.mark.e2e def test_source_upload_file(live_server: str, authenticated_page: Page, page: Page) -> None: """A source can upload a file via the drop box and receives a receipt code.""" upload_url = _create_token(authenticated_page, live_server, label="upload-test") # Submit a file as the anonymous source (unauthenticated page) page.goto(upload_url) page.wait_for_load_state("networkidle") txt_bytes = create_test_txt() page.set_input_files( "input[type='file'], input[name='files']", files=[{"name": "tip.txt", "mimeType": "text/plain", "buffer": txt_bytes}], ) page.click("button[type='submit']") page.wait_for_load_state("networkidle") # The response page should show a receipt code body_text = page.locator("body").inner_text() assert any(word in body_text.lower() for word in ("receipt", "success", "received", "upload")), ( f"No success/receipt indication found after upload. Body: {body_text[:300]}" ) @pytest.mark.e2e def test_invalid_token_rejected(live_server: str, page: Page) -> None: """A request with an invalid/missing token returns 404, not a login redirect.""" page.goto(f"{live_server}/dropbox/upload/totally-invalid-token-xyz") page.wait_for_load_state("networkidle") # Should be a 404 / plain-text "expired or invalid" message, NOT a redirect to login assert "/login" not in page.url, ( f"Invalid token redirected to login instead of showing 404: {page.url}" ) body = page.locator("body").inner_text() assert any(word in body.lower() for word in ("expired", "invalid", "not found")), ( f"Expected 'expired or invalid' message, got: {body[:200]}" ) @pytest.mark.e2e def test_revoke_token(live_server: str, authenticated_page: Page, page: Page) -> None: """An admin can revoke a token; after revocation the upload URL returns 404.""" admin_page = authenticated_page upload_url = _create_token(admin_page, live_server, label="revoke-test") token = upload_url.split("/dropbox/upload/")[1].split("?")[0] # Verify the token works before revocation page.goto(upload_url) page.wait_for_load_state("networkidle") assert "/login" not in page.url # Revoke via admin UI admin_page.goto(f"{live_server}/dropbox/admin") admin_page.wait_for_load_state("networkidle") # Find the revoke button for this token and click it revoke_form = admin_page.locator(f"form input[name='token'][value='{token}']").locator("..") if revoke_form.count() == 0: # Try by partial token match in the table row revoke_form = admin_page.locator("form").filter( has=admin_page.locator(f"input[value='{token}']") ) if revoke_form.count() > 0: revoke_form.locator("button[type='submit']").click() admin_page.wait_for_load_state("networkidle") # Now the upload URL should return 404 page.goto(upload_url) page.wait_for_load_state("networkidle") body = page.locator("body").inner_text() assert any(word in body.lower() for word in ("expired", "invalid", "not found")), ( f"Expected 404 after revocation, got: {body[:200]}" )