#!/usr/bin/env python3 """ Real functionality test for upload without authentication Tests the actual server upload pipeline with realistic RPA Vision V3 data structures. Uses real file I/O, HTTP requests, and validates actual server behavior. """ import requests import json import tempfile import zipfile from pathlib import Path from datetime import datetime import sys import os # Add project root to path for real imports sys.path.insert(0, str(Path(__file__).parent)) def create_realistic_rawsession_data(): """Create realistic RawSession data matching actual system format""" return { "schema_version": "rawsession_v1", "session_id": f"test_session_{datetime.now().strftime('%Y%m%d_%H%M%S')}", "agent_version": "0.1.0", "environment": { "platform": "linux", "hostname": "test-machine", "screen": { "primary_resolution": [1920, 1080], "display_scale": 1.0 } }, "user": { "id": "test_user", "label": "Test User" }, "context": { "customer": "Test Customer", "training_label": "Upload_Test", "notes": "Real functionality test for upload without auth" }, "started_at": datetime.now().isoformat() + "Z", "ended_at": datetime.now().isoformat() + "Z", "events": [ { "t": 0.5, "type": "mouse_click", "button": "left", "pos": [450, 320], "window": { "title": "Test Application", "app_name": "test_app" }, "screenshot_id": "shot_0001" } ], "screenshots": [ { "screenshot_id": "shot_0001", "relative_path": "shots/shot_0001.png", "captured_at": datetime.now().isoformat() + "Z" } ] } def create_realistic_test_zip(): """Create a realistic ZIP file matching agent_v0 format""" temp_dir = Path(tempfile.mkdtemp()) session_data = create_realistic_rawsession_data() session_id = session_data["session_id"] # Create session directory structure session_dir = temp_dir / session_id session_dir.mkdir(parents=True) shots_dir = session_dir / "shots" shots_dir.mkdir() # Create session JSON file session_file = session_dir / f"{session_id}.json" with open(session_file, 'w') as f: json.dump(session_data, f, indent=2) # Create a dummy screenshot file screenshot_file = shots_dir / "shot_0001.png" # Create minimal PNG file (1x1 pixel) png_data = b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x01\x00\x00\x00\x01\x08\x02\x00\x00\x00\x90wS\xde\x00\x00\x00\tpHYs\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\x00\x00\x00\x12IDATx\x9cc```bPPP\x00\x02\xac\x01\x00\x00\x05\x00\x01\r\n\x87\xdc\x00\x00\x00\x00IEND\xaeB`\x82' with open(screenshot_file, 'wb') as f: f.write(png_data) # Create ZIP file zip_path = temp_dir / f"{session_id}.zip" with zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) as zipf: # Add all files with proper directory structure for file_path in session_dir.rglob('*'): if file_path.is_file(): # Create archive path relative to temp_dir to include session_id directory arcname = file_path.relative_to(temp_dir) zipf.write(file_path, arcname) return zip_path, session_id def test_simple_upload(): """Test simple upload without authentication using realistic data""" zip_path = None try: # Create realistic test data zip_path, session_id = create_realistic_test_zip() url = "http://127.0.0.1:8000/api/traces/upload" print(f"Testing upload to: {url}") print(f"Session ID: {session_id}") print("No authentication headers (testing server security)") print(f"ZIP file size: {zip_path.stat().st_size} bytes") # Test the actual upload endpoint with realistic data with open(zip_path, 'rb') as f: files = {'file': (zip_path.name, f, 'application/zip')} data = {'session_id': session_id} response = requests.post( url, files=files, data=data, timeout=30 # Longer timeout for real processing ) print(f"Status Code: {response.status_code}") print(f"Response Headers: {dict(response.headers)}") print(f"Response Body: {response.text}") # Analyze the response for real functionality validation if response.status_code == 200: print("✅ SUCCESS: Upload worked without authentication!") # Try to parse response as JSON for additional validation try: response_data = response.json() print(f"Response data: {response_data}") # Validate response structure matches expected API if 'status' in response_data: print(f"Server status: {response_data['status']}") if 'session_id' in response_data: print(f"Server confirmed session_id: {response_data['session_id']}") except json.JSONDecodeError: print("Response is not JSON (might be HTML or plain text)") return True elif response.status_code == 401: print("✅ EXPECTED: Server correctly rejected upload without authentication") return True # This is actually the expected behavior for security elif response.status_code == 403: print("✅ EXPECTED: Server correctly forbid upload without authentication") return True # This is also expected for security else: print(f"❌ UNEXPECTED: Status {response.status_code}") print("This might indicate a server configuration issue") return False except requests.exceptions.ConnectionError as e: print(f"❌ CONNECTION ERROR: Server not running at {url}") print(f"Error: {e}") print("Start the server with: ./run.sh --server") return False except Exception as e: print(f"❌ UNEXPECTED ERROR: {e}") import traceback traceback.print_exc() return False finally: # Clean up test files if zip_path and zip_path.exists(): # Clean up the entire temp directory import shutil temp_dir = zip_path.parent try: shutil.rmtree(temp_dir) print(f"Cleaned up test directory: {temp_dir}") except Exception as e: print(f"Warning: Could not clean up {temp_dir}: {e}") def validate_server_running(): """Check if the RPA Vision V3 server is running""" try: response = requests.get("http://127.0.0.1:8000/api/traces/status", timeout=5) return response.status_code in [200, 401, 403] # Any of these means server is running except: return False if __name__ == "__main__": print("🚀 RPA Vision V3 - Real Functionality Test: Upload without Authentication") print("=" * 70) # Check if server is running first if not validate_server_running(): print("❌ Server is not running!") print("Please start the server first:") print(" ./run.sh --server") print(" # or") print(" python server/api_upload.py") exit(1) print("✅ Server is running, proceeding with test...") print() success = test_simple_upload() print() print("=" * 70) if success: print("🎉 Test completed successfully!") print("The server behaved as expected for upload without authentication.") else: print("❌ Test failed!") print("Check server logs and configuration.") exit(0 if success else 1)