diff --git a/api/tests/manual/test_registration_api.py b/api/tests/manual/test_registration_api.py new file mode 100644 index 0000000000..ba8d6cc3e9 --- /dev/null +++ b/api/tests/manual/test_registration_api.py @@ -0,0 +1,255 @@ +#!/usr/bin/env python3 +""" +Manual test script for email registration API. +Run this script to test the new registration flow with the server running on port 5001. +""" + +import time +from typing import Any + +import requests + + +class RegistrationTester: + """Test class for registration API.""" + + def __init__(self, base_url: str = "http://localhost:5001"): + self.base_url = base_url + self.session = requests.Session() + + def test_send_verification_code(self, email: str) -> dict[str, Any]: + """Test sending verification code.""" + print(f"๐Ÿ”ต Testing verification code send for: {email}") + + response = self.session.post( + f"{self.base_url}/service/auth/email-code-login", + json={"email": email}, + headers={"Content-Type": "application/json"} + ) + + print(f" Status: {response.status_code}") + print(f" Response: {response.text}") + + return { + "status_code": response.status_code, + "response": ( + response.json() + if response.headers.get('content-type', '').startswith('application/json') + else response.text + ) + } + + def test_registration_with_code(self, email: str, code: str, token: str) -> dict[str, Any]: + """Test registration with verification code.""" + print(f"๐Ÿ”ต Testing registration for: {email} with code: {code}") + + response = self.session.post( + f"{self.base_url}/service/auth/email-code-login/validity", + json={"email": email, "code": code, "token": token}, + headers={"Content-Type": "application/json"} + ) + + print(f" Status: {response.status_code}") + print(f" Response: {response.text}") + + return { + "status_code": response.status_code, + "response": ( + response.json() + if response.headers.get('content-type', '').startswith('application/json') + else response.text + ) + } + + def test_verification_code_sending(self, email: str) -> dict[str, Any]: + """Test verification code sending (first step only).""" + print(f"\n๐Ÿš€ Testing verification code sending for: {email}") + print("=" * 50) + + # Step 1: Send verification code + send_result = self.test_send_verification_code(email) + + if send_result["status_code"] != 200: + print(f"โŒ Failed to send verification code for {email}") + return send_result + + print(f"โœ… Verification code sent successfully for {email}") + + # Extract token from send result + token = None + if isinstance(send_result["response"], dict) and "data" in send_result["response"]: + token = send_result["response"]["data"] + print(f"โ„น๏ธ Received token: {token}") + print(f"โ„น๏ธ A verification code has been sent to {email}") + print("โ„น๏ธ To complete registration, user would enter the code from their email") + else: + print("โŒ No token received from verification code send") + return {"status_code": 400, "response": "No token received"} + + return {"status_code": 200, "response": "Verification code sent successfully", "token": token} + + def test_registration_flow_interactive(self, email: str) -> dict[str, Any]: + """Test full registration flow with user input for verification code.""" + print(f"\n๐Ÿš€ Testing INTERACTIVE registration flow for: {email}") + print("=" * 50) + + # Step 1: Send verification code + send_result = self.test_send_verification_code(email) + + if send_result["status_code"] != 200: + print(f"โŒ Failed to send verification code for {email}") + return send_result + + print(f"โœ… Verification code sent successfully for {email}") + + # Extract token from send result + token = None + if isinstance(send_result["response"], dict) and "data" in send_result["response"]: + token = send_result["response"]["data"] + print(f"โ„น๏ธ Received token: {token}") + else: + print("โŒ No token received from verification code send") + return {"status_code": 400, "response": "No token received"} + + # Step 2: Get verification code from user + print(f"๐Ÿ“ง A verification code has been sent to {email}") + verification_code = input("๐Ÿ”ข Please enter the verification code from your email: ").strip() + + if not verification_code: + print("โŒ No verification code entered") + return {"status_code": 400, "response": "No verification code entered"} + + register_result = self.test_registration_with_code(email, verification_code, token) + + if register_result["status_code"] == 200: + print(f"โœ… Registration successful for {email}") + else: + print(f"โŒ Registration failed for {email}") + + return register_result + + def run_comprehensive_tests(self): + """Run comprehensive tests for different email scenarios.""" + print("๐Ÿงช Running Comprehensive Email Verification Code Tests") + print("=" * 60) + print("โ„น๏ธ This tests verification code sending (step 1 of registration)") + print("โ„น๏ธ For full registration testing, use interactive mode") + + test_cases = [ + { + "email": "student@university.edu", + "description": "University student (.edu domain)", + "expected_org": "Should be assigned to organization if domain match exists" + }, + { + "email": "user@gmail.com", + "description": "Personal Gmail account", + "expected_org": "Should register without organization assignment" + }, + { + "email": "employee@company.com", + "description": "Company email without pre-configured organization", + "expected_org": "Should register without organization assignment" + }, + { + "email": "admin@startup.io", + "description": "Startup email", + "expected_org": "Should register without organization assignment" + }, + { + "email": "test@protonmail.com", + "description": "ProtonMail account", + "expected_org": "Should register without organization assignment" + } + ] + + results = [] + + for i, test_case in enumerate(test_cases, 1): + print(f"\n๐Ÿ“‹ Test Case {i}: {test_case['description']}") + print(f" Email: {test_case['email']}") + print(f" Expected: {test_case['expected_org']}") + + result = self.test_verification_code_sending(test_case["email"]) + results.append({ + "test_case": test_case, + "result": result + }) + + # Small delay between tests + time.sleep(0.5) + + # Summary + print("\n๐Ÿ“Š Test Results Summary") + print("=" * 30) + + for i, test_result in enumerate(results, 1): + test_case = test_result["test_case"] + result = test_result["result"] + + status = "โœ… PASSED" if result["status_code"] == 200 else "โŒ FAILED" + print(f"{i}. {test_case['description']}: {status}") + + if result["status_code"] != 200: + print(f" Error: {result['response']}") + + # Overall summary + passed = sum(1 for r in results if r["result"]["status_code"] == 200) + total = len(results) + print(f"\n๐ŸŽฏ Overall: {passed}/{total} verification code tests passed") + + return results + + +def main(): + """Main function to run tests.""" + print("๐Ÿ” Email Registration API Test Suite") + print("=" * 40) + + tester = RegistrationTester() + + # Check if server is running + try: + response = requests.get("http://localhost:5001/health", timeout=5) + print("โœ… Server is running on port 5001") + except requests.exceptions.RequestException: + print("โŒ Server is not running on port 5001") + print(" Please start the server with: uv run flask run --host 0.0.0.0 --port=5001 --debug") + return + + # Run comprehensive tests + results = tester.run_comprehensive_tests() + + # Additional specific tests + print("\n๐Ÿ”ฌ Additional Tests") + print("=" * 20) + + # Test invalid email + print("\n๐Ÿ”ต Testing invalid email format") + invalid_result = tester.test_send_verification_code("invalid.email") + if invalid_result["status_code"] != 200: + print("โœ… Invalid email correctly rejected") + else: + print("โŒ Invalid email was accepted (should be rejected)") + + # Test registration with invalid code + print("\n๐Ÿ”ต Testing registration with invalid code") + # First get a valid token + send_result = tester.test_send_verification_code("test@example.com") + if send_result["status_code"] == 200 and isinstance(send_result["response"], dict): + token = send_result["response"]["data"] + invalid_code_result = tester.test_registration_with_code("test@example.com", "wrong_code", token) + if invalid_code_result["status_code"] != 200: + print("โœ… Invalid verification code correctly rejected") + else: + print("โŒ Invalid verification code was accepted (should be rejected)") + else: + print("โš ๏ธ Could not test invalid code - failed to get token") + + print("\n๐ŸŽ‰ All tests completed!") + print("\nโ„น๏ธ Note: This test uses mock verification codes.") + print(" In production, users would receive actual codes via email.") + + +if __name__ == "__main__": + main() \ No newline at end of file