//! Integration test for the complete service booking workflow //! Tests the end-to-end flow: Service Creation → Marketplace → Purchase → Customer Tracking use threefold_marketplace::models::user::{User, MockUserData, ServiceBooking, CustomerServiceData, SpendingRecord}; use threefold_marketplace::models::builders::{ServiceBookingBuilder, CustomerServiceDataBuilder, SpendingRecordBuilder}; use threefold_marketplace::services::order::OrderService; use threefold_marketplace::services::user_persistence::UserPersistence; use chrono::Utc; use std::collections::HashMap; #[cfg(test)] mod service_booking_tests { use super::*; #[test] fn test_service_booking_data_structures() { // Test ServiceBooking creation with builder pattern let booking = ServiceBookingBuilder::new() .id("test_booking_001") .service_id("service_001") .service_name("Cloud Migration Consulting") .provider_email("provider@example.com") .customer_email("customer@example.com") .budget(1000) .estimated_hours(20) .status("In Progress") .requested_date("2025-06-20") .priority("High") .description(Some("Test migration project".to_string())) .booking_date("2025-06-15") .build() .expect("Should create service booking"); assert_eq!(booking.id, "test_booking_001"); assert_eq!(booking.service_name, "Cloud Migration Consulting"); assert_eq!(booking.budget, 1000); assert_eq!(booking.status, "In Progress"); } #[test] fn test_customer_service_data_creation() { // Create test service bookings let booking1 = ServiceBookingBuilder::new() .id("booking_001") .service_id("service_001") .service_name("Cloud Migration") .provider_email("provider1@example.com") .customer_email("customer@example.com") .budget(800) .estimated_hours(16) .status("In Progress") .requested_date("2025-06-20") .priority("High") .booking_date("2025-06-15") .build() .expect("Should create booking 1"); let booking2 = ServiceBookingBuilder::new() .id("booking_002") .service_id("service_002") .service_name("DevOps Consultation") .provider_email("provider2@example.com") .customer_email("customer@example.com") .budget(600) .estimated_hours(12) .status("Pending") .requested_date("2025-06-25") .priority("Medium") .booking_date("2025-06-18") .build() .expect("Should create booking 2"); // Create spending history let spending1 = SpendingRecordBuilder::new() .date("2025-06-15") .amount(800) .service_name("Cloud Migration") .provider_name("Provider One") .build() .expect("Should create spending record 1"); let spending2 = SpendingRecordBuilder::new() .date("2025-05-20") .amount(400) .service_name("Security Audit") .provider_name("Security Expert") .build() .expect("Should create spending record 2"); // Create customer service data let customer_data = CustomerServiceDataBuilder::new() .active_bookings(2) .completed_bookings(3) .total_spent(2000) .monthly_spending(400) .average_rating_given(4.5) .service_bookings(vec![booking1, booking2]) .favorite_providers(vec!["provider1@example.com".to_string(), "provider2@example.com".to_string()]) .spending_history(vec![spending1, spending2]) .build() .expect("Should create customer service data"); assert_eq!(customer_data.active_bookings, 2); assert_eq!(customer_data.completed_bookings, 3); assert_eq!(customer_data.total_spent, 2000); assert_eq!(customer_data.service_bookings.len(), 2); assert_eq!(customer_data.favorite_providers.len(), 2); assert_eq!(customer_data.spending_history.len(), 2); } #[test] fn test_mock_user_data_with_customer_service_data() { // Test that user1 has customer service data let user1_data = MockUserData::user1(); assert!(user1_data.customer_service_data.is_some()); let customer_data = user1_data.customer_service_data.unwrap(); assert_eq!(customer_data.active_bookings, 2); assert_eq!(customer_data.completed_bookings, 5); assert!(customer_data.total_spent > 0); assert!(!customer_data.service_bookings.is_empty()); assert!(!customer_data.favorite_providers.is_empty()); assert!(!customer_data.spending_history.is_empty()); } #[test] fn test_non_customer_users_have_no_service_data() { // Test that users who aren't customers have None for customer_service_data let user2_data = MockUserData::user2(); // App provider let user3_data = MockUserData::user3(); // Power user let user4_data = MockUserData::user4(); // Regular user let user5_data = MockUserData::user5(); // Service provider let new_user_data = MockUserData::new_user(); assert!(user2_data.customer_service_data.is_none()); assert!(user3_data.customer_service_data.is_none()); assert!(user4_data.customer_service_data.is_none()); assert!(user5_data.customer_service_data.is_none()); assert!(new_user_data.customer_service_data.is_none()); } #[test] fn test_service_booking_workflow_integration() { // This test simulates the complete workflow: // 1. Customer (user1) has service bookings // 2. Service provider (user5) has service requests // 3. The booking IDs should match between customer and provider let customer_data = MockUserData::user1(); let provider_data = MockUserData::user5(); // Verify customer has service bookings assert!(customer_data.customer_service_data.is_some()); let customer_service_data = customer_data.customer_service_data.unwrap(); assert!(!customer_service_data.service_bookings.is_empty()); // Verify provider has service provider data assert!(provider_data.service_provider_data.is_some()); let provider_service_data = provider_data.service_provider_data.unwrap(); // In a real implementation, we would verify that booking IDs match // between customer bookings and provider requests println!("✅ Customer has {} active bookings", customer_service_data.active_bookings); println!("✅ Provider has {} active services", provider_service_data.active_services); // Verify the data structure integrity for booking in &customer_service_data.service_bookings { assert!(!booking.id.is_empty()); assert!(!booking.service_name.is_empty()); assert!(!booking.provider_email.is_empty()); assert!(!booking.customer_email.is_empty()); assert!(booking.budget > 0); assert!(booking.estimated_hours > 0); } } #[test] fn test_spending_calculation() { let user1_data = MockUserData::user1(); let customer_data = user1_data.customer_service_data.unwrap(); // Verify spending calculations make sense assert!(customer_data.total_spent >= customer_data.monthly_spending); assert!(customer_data.average_rating_given >= 0.0 && customer_data.average_rating_given <= 5.0); // Verify spending history totals let history_total: i32 = customer_data.spending_history.iter() .map(|record| record.amount) .sum(); // The history might not include all spending, but should be reasonable assert!(history_total > 0); println!("✅ Total spending from history: {} TFP", history_total); println!("✅ Total customer spending: {} TFP", customer_data.total_spent); } }