Files
projectmycelium/tests/tests_archive/ux_suite/flows/authentication.rs
2025-09-01 21:37:01 -04:00

359 lines
14 KiB
Rust

//! Authentication Flow Tests
//!
//! Tests for user authentication functionality:
//! - User registration at /register
//! - Login and logout functionality
//! - Cart migration during login
//! - Session management
//! - GitEa OAuth integration (conditional)
use crate::utils::*;
use crate::environment::*;
use tokio_test;
/// Test user registration flow
#[tokio::test]
#[serial_test::serial]
async fn test_user_registration_flow() -> Result<(), Box<dyn std::error::Error>> {
let environment = TestFixtures::setup_test_environment().await?;
let mut helper = UXTestHelper::new(&environment);
log::info!("Testing user registration flow");
// Get test persona
let persona = helper.data_manager.get_persona(&UserRole::Consumer).unwrap();
// Navigate to registration page
helper.browser.navigate_to("/register").await?;
helper.assert_page_loaded("Register").await?;
// Verify registration form elements exist
assert!(helper.browser.element_exists("input[name='email'], input[type='email']").await);
assert!(helper.browser.element_exists("input[name='password'], input[type='password']").await);
assert!(helper.browser.element_exists("input[name='name'], input[name='full_name']").await);
helper.take_screenshot("registration_form").await?;
// Fill registration form
helper.browser.type_text("input[name='email'], input[type='email']", &persona.email).await?;
helper.browser.type_text("input[name='password'], input[type='password']", &persona.password).await?;
helper.browser.type_text("input[name='name'], input[name='full_name']", &persona.name).await?;
// Fill additional fields if they exist
if helper.browser.element_exists("input[name='confirm_password']").await {
helper.browser.type_text("input[name='confirm_password']", &persona.password).await?;
}
helper.take_screenshot("registration_form_filled").await?;
// Submit registration
helper.browser.click("button[type='submit'], .register-btn, .signup-btn").await?;
// Wait for success response or redirect
helper.browser.wait_for_element(".success, .dashboard, .registration-success, .alert-success").await?;
helper.take_screenshot("registration_success").await?;
// Verify user is now authenticated (should be on dashboard or logged in)
if helper.browser.get_current_url().await?.contains("dashboard") {
helper.assert_user_is_authenticated().await?;
}
log::info!("User registration flow test completed successfully");
Ok(())
}
/// Test user login flow
#[tokio::test]
#[serial_test::serial]
async fn test_user_login_flow() -> Result<(), Box<dyn std::error::Error>> {
let environment = TestFixtures::setup_test_environment().await?;
let mut helper = UXTestHelper::new(&environment);
log::info!("Testing user login flow");
// Get test persona (should already exist from registration or test data)
let persona = helper.data_manager.get_persona(&UserRole::Consumer).unwrap();
// Navigate to login page
helper.browser.navigate_to("/login").await?;
helper.assert_page_loaded("Login").await?;
// Verify login form elements exist
assert!(helper.browser.element_exists("input[name='email'], input[type='email']").await);
assert!(helper.browser.element_exists("input[name='password'], input[type='password']").await);
assert!(helper.browser.element_exists("button[type='submit'], .login-btn").await);
helper.take_screenshot("login_form").await?;
// Test login with valid credentials
helper.login_as(persona).await?;
// Verify successful login
helper.assert_user_is_authenticated().await?;
// Verify redirect to dashboard or appropriate page
let current_url = helper.browser.get_current_url().await?;
assert!(current_url.contains("dashboard") || current_url.contains("marketplace"));
helper.take_screenshot("login_success").await?;
log::info!("User login flow test completed successfully");
Ok(())
}
/// Test user logout flow
#[tokio::test]
#[serial_test::serial]
async fn test_user_logout_flow() -> Result<(), Box<dyn std::error::Error>> {
let environment = TestFixtures::setup_test_environment().await?;
let mut helper = UXTestHelper::new(&environment);
log::info!("Testing user logout flow");
// First login
let persona = helper.data_manager.get_persona(&UserRole::Consumer).unwrap();
helper.login_as(persona).await?;
helper.assert_user_is_authenticated().await?;
// Test logout
helper.logout().await?;
// Verify logout success
let current_url = helper.browser.get_current_url().await?;
assert!(!current_url.contains("dashboard"));
// Verify user menu/authentication indicators are gone
assert!(!helper.browser.element_exists(".user-menu, .logout-btn").await);
// Try to access protected page and verify redirect
helper.browser.navigate_to("/dashboard").await?;
// Should redirect to login or show unauthorized
let final_url = helper.browser.get_current_url().await?;
assert!(final_url.contains("login") || final_url.contains("unauthorized") || !final_url.contains("dashboard"));
helper.take_screenshot("logout_success").await?;
log::info!("User logout flow test completed successfully");
Ok(())
}
/// Test cart migration during login
#[tokio::test]
#[serial_test::serial]
async fn test_cart_migration_during_login() -> Result<(), Box<dyn std::error::Error>> {
let environment = TestFixtures::setup_test_environment().await?;
let mut helper = UXTestHelper::new(&environment);
log::info!("Testing cart migration during login");
// Step 1: Add items to cart as anonymous user
helper.browser.navigate_to("/marketplace").await?;
// Try to add item to anonymous cart
if helper.browser.element_exists(".add-to-cart, .product-card").await {
helper.browser.click(".add-to-cart, .product-card .btn").await?;
helper.browser.wait_for_element(".cart-updated, .notification").await.ok();
}
// Navigate to anonymous cart and verify items
helper.navigate_to_cart().await?;
let anonymous_cart_items = helper.browser.find_elements(".cart-item, .product-item").await.unwrap_or_default().len();
helper.take_screenshot("anonymous_cart_with_items").await?;
// Step 2: Login and verify cart migration
let persona = helper.data_manager.get_persona(&UserRole::Consumer).unwrap();
helper.login_as(persona).await?;
// Navigate to authenticated user cart
helper.navigate_to_cart().await?;
// Verify cart items were migrated
let authenticated_cart_items = helper.browser.find_elements(".cart-item, .product-item").await.unwrap_or_default().len();
// Cart should have same or more items (if user already had items)
assert!(authenticated_cart_items >= anonymous_cart_items,
"Cart migration failed: anonymous had {}, authenticated has {}",
anonymous_cart_items, authenticated_cart_items);
helper.take_screenshot("authenticated_cart_after_migration").await?;
log::info!("Cart migration during login test completed successfully");
Ok(())
}
/// Test session management and persistence
#[tokio::test]
#[serial_test::serial]
async fn test_session_management() -> Result<(), Box<dyn std::error::Error>> {
let environment = TestFixtures::setup_test_environment().await?;
let mut helper = UXTestHelper::new(&environment);
log::info!("Testing session management and persistence");
// Login
let persona = helper.data_manager.get_persona(&UserRole::Consumer).unwrap();
helper.login_as(persona).await?;
helper.assert_user_is_authenticated().await?;
// Navigate to different pages and verify session persists
let test_pages = vec![
"/dashboard",
"/dashboard/wallet",
"/marketplace",
"/dashboard/settings",
];
for page in test_pages {
helper.browser.navigate_to(page).await?;
// Verify still authenticated on each page
if page.contains("dashboard") {
// For dashboard pages, check for dashboard elements
helper.browser.wait_for_element(".dashboard, .user-content").await.ok();
}
// Check that we're not redirected to login
let current_url = helper.browser.get_current_url().await?;
assert!(!current_url.contains("login"), "Session expired on page {}", page);
helper.take_screenshot(&format!("session_check_{}", page.replace("/", "_"))).await?;
}
// Test API authentication status
let auth_status = helper.api_client.validate_auth_status().await?;
assert!(auth_status.authenticated, "API reports user not authenticated");
assert_eq!(auth_status.user_email, Some(persona.email.clone()));
log::info!("Session management test completed successfully");
Ok(())
}
/// Test login error handling
#[tokio::test]
#[serial_test::serial]
async fn test_login_error_handling() -> Result<(), Box<dyn std::error::Error>> {
let environment = TestFixtures::setup_test_environment().await?;
let mut helper = UXTestHelper::new(&environment);
log::info!("Testing login error handling");
// Navigate to login page
helper.browser.navigate_to("/login").await?;
// Test invalid credentials
helper.browser.type_text("input[name='email'], input[type='email']", "invalid@example.com").await?;
helper.browser.type_text("input[name='password'], input[type='password']", "wrongpassword").await?;
helper.take_screenshot("login_invalid_credentials").await?;
// Submit login
helper.browser.click("button[type='submit'], .login-btn").await?;
// Should show error message
helper.browser.wait_for_element(".error, .alert-danger, .login-error").await?;
// Verify error message is displayed
assert!(helper.browser.element_exists(".error, .alert-danger, .login-error").await);
// Verify user is not authenticated
assert!(!helper.browser.element_exists(".user-menu, .dashboard-link").await);
helper.take_screenshot("login_error_displayed").await?;
// Test empty form submission
helper.browser.navigate_to("/login").await?;
helper.browser.click("button[type='submit'], .login-btn").await?;
// Should show validation errors
helper.browser.wait_for_element(".validation-error, .required-field").await.ok();
helper.take_screenshot("login_validation_errors").await?;
log::info!("Login error handling test completed successfully");
Ok(())
}
/// Test GitEa OAuth integration (conditional on environment)
#[tokio::test]
#[serial_test::serial]
async fn test_gitea_oauth_integration() -> Result<(), Box<dyn std::error::Error>> {
let environment = TestFixtures::setup_test_environment().await?;
let mut helper = UXTestHelper::new(&environment).await?;
log::info!("Testing GitEa OAuth integration");
// Check if GitEa OAuth is enabled
if std::env::var("GITEA_CLIENT_ID").is_ok() {
// Navigate to login page
helper.browser.navigate_to("/login").await?;
// Look for GitEa OAuth button
if helper.browser.element_exists(".oauth-gitea, .gitea-login, a[href*='auth/gitea']").await {
helper.take_screenshot("login_with_gitea_option").await?;
// Click GitEa OAuth (don't complete the flow in tests)
// Just verify the redirect starts
helper.browser.click(".oauth-gitea, .gitea-login, a[href*='auth/gitea']").await?;
// Should redirect to GitEa or show OAuth flow
let current_url = helper.browser.get_current_url().await?;
assert!(current_url.contains("gitea") || current_url.contains("oauth") || current_url.contains("auth"));
helper.take_screenshot("gitea_oauth_redirect").await?;
log::info!("GitEa OAuth integration verified");
} else {
log::info!("GitEa OAuth button not found - may not be enabled");
}
} else {
log::info!("GitEa OAuth not configured - skipping integration test");
}
Ok(())
}
/// Test registration validation
#[tokio::test]
#[serial_test::serial]
async fn test_registration_validation() -> Result<(), Box<dyn std::error::Error>> {
let environment = TestFixtures::setup_test_environment().await?;
let mut helper = UXTestHelper::new(&environment).await?;
log::info!("Testing registration validation");
// Navigate to registration page
helper.browser.navigate_to("/register").await?;
// Test empty form submission
helper.browser.click("button[type='submit'], .register-btn").await?;
// Should show validation errors
helper.browser.wait_for_element(".validation-error, .required-field, .error").await.ok();
helper.take_screenshot("registration_validation_errors").await?;
// Test invalid email format
helper.browser.type_text("input[name='email'], input[type='email']", "invalid-email").await?;
helper.browser.type_text("input[name='password'], input[type='password']", "short").await?;
helper.browser.click("button[type='submit'], .register-btn").await?;
// Should show format validation errors
helper.browser.wait_for_element(".validation-error, .email-error").await.ok();
helper.take_screenshot("registration_format_errors").await?;
// Test duplicate email (if validation exists)
let existing_persona = helper.data_manager.get_persona(&UserRole::Consumer).unwrap();
helper.browser.navigate_to("/register").await?;
helper.browser.type_text("input[name='email'], input[type='email']", &existing_persona.email).await?;
helper.browser.type_text("input[name='password'], input[type='password']", "validpassword123").await?;
helper.browser.type_text("input[name='name'], input[name='full_name']", "Test User").await?;
helper.browser.click("button[type='submit'], .register-btn").await?;
// May show duplicate email error
helper.browser.wait_for_element(".error, .duplicate-email").await.ok();
helper.take_screenshot("registration_duplicate_email").await?;
log::info!("Registration validation test completed successfully");
Ok(())
}