129 lines
5.1 KiB
Rust
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");
|
|
}
|