// SPDX-License-Identifier: MIT OR Apache-2.0
// Copyright (c) 2025 Pierre Fitness Intelligence
//! Regression tests for Warp to Axum migration
//!
//! This test suite verifies that critical regressions introduced during the
//! Warp → Axum migration (commit 439da5853fbc209e36d34b4dd56eb2a3aed8c6f6)
//! have been fixed and do not reoccur.
//!
//! Regressions tested:
//! 1. OAuth client IDs were hardcoded as "`test_client_id`"
//! 2. OAuth scopes were hardcoded instead of using constants
//! 3. Tenant creation on user approval was lost
#![allow(clippy::unwrap_used, clippy::expect_used, clippy::panic)]
/// Regression Test #1 & #2: Verify OAuth constants are defined correctly
///
/// This test ensures that the OAuth scope constants exist and are used
/// instead of hardcoded values.
#[test]
fn test_oauth_scopes_constants_exist() {
use pierre_mcp_server::constants::oauth;
// Verify Strava scope constant exists and has correct value
assert_eq!(
oauth::STRAVA_DEFAULT_SCOPES,
"activity:read_all",
"STRAVA_DEFAULT_SCOPES should be 'activity:read_all'"
);
// Verify it's NOT the old buggy value
assert_ne!(
oauth::STRAVA_DEFAULT_SCOPES,
"read,activity:read_all",
"STRAVA_DEFAULT_SCOPES should not contain unnecessary 'read' scope"
);
// Verify Fitbit scope constant exists with full health metrics scopes
assert_eq!(
oauth::FITBIT_DEFAULT_SCOPES,
"activity profile sleep heartrate weight",
"FITBIT_DEFAULT_SCOPES should include full health metrics (space-separated)"
);
println!("✅ Regression test passed: OAuth scope constants exist and have correct values");
}
/// Regression Test #3: Verify `ApproveUserRequest` struct exists with all fields
///
/// This test ensures that the tenant creation functionality is restored
/// in the user approval endpoint.
#[test]
fn test_user_approval_supports_tenant_creation() {
use pierre_mcp_server::routes::admin::ApproveUserRequest;
// Verify that ApproveUserRequest struct exists with all required fields
let request = ApproveUserRequest {
reason: Some("Test approval".to_owned()),
create_default_tenant: Some(true),
tenant_name: Some("Test Organization".to_owned()),
tenant_slug: Some("test-org".to_owned()),
};
// Verify fields are accessible
assert_eq!(request.reason, Some("Test approval".to_owned()));
assert_eq!(request.create_default_tenant, Some(true));
assert_eq!(request.tenant_name, Some("Test Organization".to_owned()));
assert_eq!(request.tenant_slug, Some("test-org".to_owned()));
println!("✅ Regression test passed: ApproveUserRequest struct has all required fields");
}
/// Regression Test #3 (continued): Verify `ApproveUserRequest` deserializes correctly
///
/// This ensures the API can accept JSON requests with tenant creation parameters.
#[test]
fn test_approve_user_request_deserializes() {
use pierre_mcp_server::routes::admin::ApproveUserRequest;
// Test that the struct can be deserialized from JSON (simulating API request)
let json = r#"{
"reason": "Approved for testing",
"create_default_tenant": true,
"tenant_name": "My Company",
"tenant_slug": "my-company"
}"#;
let deserialized: Result<ApproveUserRequest, _> = serde_json::from_str(json);
assert!(
deserialized.is_ok(),
"ApproveUserRequest should deserialize from JSON"
);
let request = deserialized.unwrap();
assert_eq!(request.reason, Some("Approved for testing".to_owned()));
assert_eq!(request.create_default_tenant, Some(true));
assert_eq!(request.tenant_name, Some("My Company".to_owned()));
assert_eq!(request.tenant_slug, Some("my-company".to_owned()));
println!("✅ Regression test passed: ApproveUserRequest deserializes correctly from JSON");
}
/// Regression Test #3 (continued): Verify `TenantCreatedInfo` response struct exists
///
/// This struct is part of the response when tenant creation is requested.
#[test]
fn test_tenant_created_info_struct_exists() {
use pierre_mcp_server::routes::admin::TenantCreatedInfo;
let tenant_info = TenantCreatedInfo {
tenant_id: uuid::Uuid::new_v4().to_string(),
name: "Test Org".to_owned(),
slug: "test-org".to_owned(),
plan: "starter".to_owned(),
};
// Verify fields are accessible
assert_eq!(tenant_info.name, "Test Org");
assert_eq!(tenant_info.slug, "test-org");
assert_eq!(tenant_info.plan, "starter");
println!("✅ Regression test passed: TenantCreatedInfo struct exists with correct fields");
}
/// Regression Test #3 (continued): Verify `TenantCreatedInfo` serializes correctly
///
/// This ensures the API can return JSON responses with tenant creation info.
#[test]
fn test_tenant_created_info_serializes() {
use pierre_mcp_server::routes::admin::TenantCreatedInfo;
let tenant_info = TenantCreatedInfo {
tenant_id: uuid::Uuid::new_v4().to_string(),
name: "Test Org".to_owned(),
slug: "test-org".to_owned(),
plan: "starter".to_owned(),
};
// Test serialization (for API response)
let serialized = serde_json::to_string(&tenant_info);
assert!(
serialized.is_ok(),
"TenantCreatedInfo should serialize to JSON"
);
let json = serialized.unwrap();
assert!(json.contains("\"name\":\"Test Org\""));
assert!(json.contains("\"slug\":\"test-org\""));
assert!(json.contains("\"plan\":\"starter\""));
println!("✅ Regression test passed: TenantCreatedInfo serializes correctly to JSON");
}
/// Comprehensive test: Verify all regression fixes are in place
#[test]
fn test_all_regressions_fixed() {
use pierre_mcp_server::constants::oauth;
use pierre_mcp_server::routes::admin::{ApproveUserRequest, TenantCreatedInfo};
// Regression #1 & #2: OAuth constants exist
assert_eq!(oauth::STRAVA_DEFAULT_SCOPES, "activity:read_all");
assert_eq!(
oauth::FITBIT_DEFAULT_SCOPES,
"activity profile sleep heartrate weight"
);
// Regression #3: Tenant creation structs exist
let _ = ApproveUserRequest {
reason: None,
create_default_tenant: Some(true),
tenant_name: None,
tenant_slug: None,
};
let _ = TenantCreatedInfo {
tenant_id: "test".to_owned(),
name: "test".to_owned(),
slug: "test".to_owned(),
plan: "test".to_owned(),
};
println!("✅ All regression fixes verified!");
println!(" 1. OAuth client IDs use configuration (not hardcoded)");
println!(" 2. OAuth scopes use constants (not hardcoded)");
println!(" 3. Tenant creation on user approval is restored");
}