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

129 lines
5.1 KiB
Rust

use actix_web::{test, App, http::StatusCode, web};
use rust_decimal::Decimal;
use serde_json::json;
use tera::Tera;
use threefold_marketplace::routes::configure_routes;
use threefold_marketplace::services::user_persistence::UserPersistence;
use threefold_marketplace::utils;
use threefold_marketplace::models::user::Service;
fn sanitize(email: &str) -> String {
email.replace("@", "_at_").replace(".", "_")
}
/// Helper to read a Set-Cookie header by name
fn extract_cookie_value(resp: &actix_web::dev::ServiceResponse, name: &str) -> Option<String> {
for header in resp.headers().get_all(actix_web::http::header::SET_COOKIE) {
if let Ok(s) = header.to_str() {
if s.starts_with(&format!("{}=", name)) {
// Take only the name=value part
if let Some((prefix, _rest)) = s.split_once(';') {
return Some(prefix.to_string());
}
}
}
}
None
}
#[actix_rt::test]
async fn test_instant_purchase_persists_service_booking() {
// Ensure clean user_data directory entries for test users
let _ = std::fs::create_dir_all("user_data");
let customer_email = "instant_customer@example.com";
let provider_email = "provider_instant@example.com";
let product_id = "svc-test-123";
let customer_path = format!("user_data/{}.json", sanitize(customer_email));
let provider_path = format!("user_data/{}.json", sanitize(provider_email));
let _ = std::fs::remove_file(&customer_path);
let _ = std::fs::remove_file(&provider_path);
// Initialize Tera templates similar to main.rs
let mut tera = Tera::new("src/views/**/*.html").expect("failed to load templates");
utils::register_tera_functions(&mut tera);
// Start test app with configured routes (includes session middleware)
let app = test::init_service(
App::new()
.app_data(web::Data::new(tera))
.configure(configure_routes)
).await;
// 1) Register a new customer to obtain a valid session cookie
let form = [
("name", "Instant Customer"),
("email", customer_email),
("password", "secret123"),
("password_confirmation", "secret123"),
];
let req = test::TestRequest::post()
.uri("/register")
.set_form(&form)
.to_request();
let resp = test::call_service(&app, req).await;
assert!(resp.status().is_redirection());
// Extract session cookie set by session middleware
let session_cookie = extract_cookie_value(&resp, "threefold_marketplace_session")
.expect("session cookie should be set after registration");
// 2) Seed provider user_data with a service matching product_id
let mut provider_data = UserPersistence::create_default_user_data(provider_email);
provider_data.services.push(Service {
id: product_id.to_string(),
name: "Instant Test Service".to_string(),
category: "service".to_string(),
description: "test service".to_string(),
price_per_hour_usd: 100,
status: "active".to_string(),
clients: 0,
rating: 0.0,
total_hours: 0,
});
UserPersistence::save_user_data(&provider_data).expect("save provider data");
// 3) Increase customer's wallet balance so purchase can succeed
let mut customer_data = UserPersistence::create_default_user_data(customer_email);
customer_data.name = Some("Instant Customer".to_string());
customer_data.wallet_balance_usd = Decimal::from(500);
UserPersistence::save_user_data(&customer_data).expect("save customer data");
// 4) Perform instant purchase
let body = json!({
"product_id": product_id,
"product_name": "Instant Test Service",
"product_category": "service",
"quantity": 1u32,
"unit_price_usd": Decimal::from(100),
"provider_id": provider_email,
"provider_name": "Instant Provider",
"specifications": json!({"note":"test"}),
});
let req = test::TestRequest::post()
.uri("/api/wallet/instant-purchase")
.insert_header((actix_web::http::header::CONTENT_TYPE, "application/json"))
.insert_header((actix_web::http::header::COOKIE, session_cookie.clone()))
.set_payload(body.to_string())
.to_request();
let resp = test::call_service(&app, req).await;
assert_eq!(resp.status(), StatusCode::OK);
let resp_body: serde_json::Value = test::read_body_json(resp).await;
assert!(resp_body.get("success").and_then(|v| v.as_bool()).unwrap_or(false));
// 5) Verify that a booking got persisted to the customer's file
let persisted = UserPersistence::load_user_data(customer_email).expect("customer data should exist");
assert!(persisted.service_bookings.len() >= 1, "expected at least one service booking to be persisted");
assert!(persisted.service_bookings.iter().any(|b| b.service_name == "Instant Test Service"));
// Also verify provider got a service request
let provider_persisted = UserPersistence::load_user_data(provider_email).expect("provider data should exist");
assert!(provider_persisted.service_requests.len() >= 1, "expected at least one service request for provider");
}