Files
foxhunt/tests/regulatory_submission_tests.rs
jgrusewski 6093eac7bf 🔧 Tonic 0.14 Upgrade: Auto-generated and build system changes
Wave 64-65 cleanup: Proto regeneration and build system updates from Tonic 0.12→0.14 upgrade

Files updated:
- Cargo.lock: Dependency resolution for Tonic 0.14.2
- All build.rs: Updated for tonic-prost-build
- Proto files: Regenerated with tonic-prost 0.14
- Examples/tests: Updated for new gRPC API

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-03 07:34:26 +02:00

359 lines
12 KiB
Rust

//! Regulatory submission readiness tests
//! Validates automated generation and submission of regulatory reports
#![allow(unused_crate_dependencies)]
use chrono::{DateTime, Duration, Utc};
use std::collections::HashMap;
use tokio;
use trading_engine::compliance::*;
use common::{OrderId, OrderSide, OrderType, Price, Quantity};
#[tokio::test]
async fn test_mifid_ii_rts22_report_generation() {
// Test MiFID II RTS 22 transaction reporting
let config = ComplianceConfig::default();
let engine = ComplianceEngine::new(config);
let context = create_compliance_context_with_order();
let result = engine.assess_compliance(&context).await.unwrap();
// Verify MiFID II compliance assessment
assert!(matches!(
result.mifid2_status,
ComplianceStatus::Compliant | ComplianceStatus::Warning(_)
));
// Test RTS 22 report fields
assert!(result.assessment_timestamp <= Utc::now());
assert!(result.compliance_score >= 0.0 && result.compliance_score <= 100.0);
}
#[tokio::test]
async fn test_sox_section_404_certification() {
// Test SOX Section 404 management certification
let mut config = ComplianceConfig::default();
config.sox.management_certification_required = true;
config.sox.internal_controls_testing = true;
config.sox.section_404_enabled = true;
let engine = ComplianceEngine::new(config);
let context = create_compliance_context_with_order();
let result = engine.assess_compliance(&context).await.unwrap();
// Verify SOX compliance
assert!(matches!(result.sox_status, ComplianceStatus::Compliant));
// Check for SOX-specific findings
let sox_findings: Vec<_> = result
.findings
.iter()
.filter(|f| f.regulation.contains("SOX"))
.collect();
// Should have SOX compliance verification
assert!(
sox_findings.is_empty()
|| sox_findings.iter().all(|f| matches!(
f.severity,
ComplianceSeverity::Low | ComplianceSeverity::Info
))
);
}
#[tokio::test]
async fn test_iso27001_isms_certification() {
// Test ISO 27001 Information Security Management System
let mut config = ComplianceConfig::default();
config.data_protection.gdpr_enabled = true;
config.data_protection.consent_management_enabled = true;
let engine = ComplianceEngine::new(config);
let context = create_compliance_context_with_client();
let result = engine.assess_compliance(&context).await.unwrap();
// Verify data protection compliance
assert!(matches!(
result.data_protection_status,
ComplianceStatus::Compliant | ComplianceStatus::Warning(_)
));
// Check GDPR compliance findings
let gdpr_findings: Vec<_> = result
.findings
.iter()
.filter(|f| f.regulation.contains("GDPR"))
.collect();
// Should handle GDPR requirements
if !gdpr_findings.is_empty() {
assert!(gdpr_findings
.iter()
.any(|f| f.remediation.contains("retention") || f.remediation.contains("consent")));
}
}
#[tokio::test]
async fn test_automated_report_scheduling() {
// Test automated regulatory report generation and scheduling
let config = ComplianceConfig::default();
let engine = ComplianceEngine::new(config);
// Simulate daily reporting requirement
let mut reporting_intervals = HashMap::new();
reporting_intervals.insert("MiFID_II_DAILY".to_string(), Duration::days(1));
reporting_intervals.insert("SOX_QUARTERLY".to_string(), Duration::days(90));
reporting_intervals.insert("ISO27001_ANNUAL".to_string(), Duration::days(365));
// Test each reporting interval
for (report_type, _interval) in reporting_intervals {
let context = create_compliance_context_with_order();
let result = engine.assess_compliance(&context).await.unwrap();
// Verify report can be generated
assert!(!result.findings.is_empty() || result.compliance_score > 0.0);
// Check timestamp is recent
assert!(result.assessment_timestamp > Utc::now() - Duration::minutes(1));
println!(
"Generated {} report with score: {:.1}",
report_type, result.compliance_score
);
}
}
#[tokio::test]
async fn test_regulatory_data_export() {
// Test data export for regulatory submissions
let config = ComplianceConfig::default();
let engine = ComplianceEngine::new(config);
let context = create_compliance_context_with_order();
let result = engine.assess_compliance(&context).await.unwrap();
// Test serialization for regulatory export
let json_export = serde_json::to_string_pretty(&result).unwrap();
assert!(json_export.contains("compliance_score"));
assert!(json_export.contains("assessment_timestamp"));
// Verify all required regulatory fields are present
assert!(json_export.contains("mifid2_status"));
assert!(json_export.contains("sox_status"));
assert!(json_export.contains("data_protection_status"));
// Test CSV-compatible data structure
let findings_csv: Vec<String> = result
.findings
.iter()
.map(|f| {
format!(
"{},{},{},{}",
f.regulation,
format!("{:?}", f.severity),
f.description.replace(",", ";"),
format!("{:?}", f.status)
)
})
.collect();
assert!(!findings_csv.is_empty() || result.compliance_score == 100.0);
}
#[tokio::test]
async fn test_audit_trail_export() {
// Test audit trail export for regulatory examination
let config = ComplianceConfig::default();
let engine = ComplianceEngine::new(config);
// Generate multiple compliance events
for i in 0..10 {
let mut context = create_compliance_context_with_order();
// Modify order details for variety
if let Some(ref mut order) = context.order_info {
order.order_id = OrderId::new(); // Generate unique ID
order.quantity = Quantity::from_f64(100.0 * (i as f64 + 1.0)).unwrap();
}
let result = engine.assess_compliance(&context).await.unwrap();
// Verify each assessment generates findings
assert!(result.compliance_score >= 0.0);
}
// Test comprehensive audit trail export
let export_data = AuditTrailExport {
export_timestamp: Utc::now(),
total_assessments: 10,
date_range: DateRange {
start: Utc::now() - Duration::hours(1),
end: Utc::now(),
},
compliance_summary: ComplianceSummary {
average_score: 95.0,
total_violations: 0,
total_warnings: 2,
},
};
// Verify export structure
assert!(export_data.total_assessments == 10);
assert!(export_data.compliance_summary.average_score >= 0.0);
}
#[tokio::test]
async fn test_regulatory_deadline_tracking() {
// Test tracking of regulatory deadlines
let config = ComplianceConfig::default();
let engine = ComplianceEngine::new(config);
let context = create_compliance_context_with_order();
let result = engine.assess_compliance(&context).await.unwrap();
// Check for findings with deadlines
let findings_with_deadlines: Vec<_> = result
.findings
.iter()
.filter(|f| f.due_date.is_some())
.collect();
// Verify deadline tracking
for finding in findings_with_deadlines {
let due_date = finding.due_date.unwrap();
// Deadlines should be in the future
assert!(due_date > Utc::now());
// Deadlines should be reasonable (within regulatory timeframes)
let days_until_due = (due_date - Utc::now()).num_days();
assert!(days_until_due >= 0 && days_until_due <= 365);
// Critical findings should have shorter deadlines
if matches!(finding.severity, ComplianceSeverity::Critical) {
assert!(days_until_due <= 7); // Critical items due within 1 week
}
}
}
#[tokio::test]
async fn test_cross_regulation_compliance() {
// Test compliance across multiple regulations simultaneously
let mut config = ComplianceConfig::default();
config.mifid2.best_execution_enabled = true;
config.mifid2.transaction_reporting_endpoint = Some("https://test.regulator.eu".to_string());
config.sox.internal_controls_testing = true;
config.mar.real_time_surveillance = true;
config.data_protection.gdpr_enabled = true;
let engine = ComplianceEngine::new(config);
let context = create_compliance_context_with_order();
let result = engine.assess_compliance(&context).await.unwrap();
// Verify all regulations are assessed
assert!(!matches!(
result.mifid2_status,
ComplianceStatus::NotApplicable
));
assert!(!matches!(
result.sox_status,
ComplianceStatus::NotApplicable
));
assert!(!matches!(
result.mar_status,
ComplianceStatus::NotApplicable
));
assert!(!matches!(
result.data_protection_status,
ComplianceStatus::NotApplicable
));
// Overall compliance should be determined correctly
match result.status {
ComplianceStatus::Compliant => {
// All individual statuses should be compliant
assert!(matches!(result.mifid2_status, ComplianceStatus::Compliant));
assert!(matches!(result.sox_status, ComplianceStatus::Compliant));
},
ComplianceStatus::Warning(_) => {
// At least one should have warnings, but no violations
assert!(!matches!(
result.mifid2_status,
ComplianceStatus::Violation(_)
));
assert!(!matches!(result.sox_status, ComplianceStatus::Violation(_)));
},
ComplianceStatus::Violation(_) => {
// At least one should have violations
// This is acceptable in test scenarios
},
_ => {}, // Other statuses acceptable for test
}
}
// Helper functions and data structures
fn create_compliance_context_with_order() -> ComplianceContext {
ComplianceContext {
order_info: Some(OrderInfo {
order_id: OrderId::new(),
symbol: "AAPL".to_string(),
side: OrderSide::Buy,
quantity: Quantity::from_f64(1000.0).unwrap(),
price: Some(Price::from_f64(150.0).unwrap()),
order_type: OrderType::Limit,
client_id: "COMPLIANCE_CLIENT_001".to_string(),
timestamp: Utc::now(),
}),
client_info: Some(ClientInfo {
client_id: "COMPLIANCE_CLIENT_001".to_string(),
classification: ClientType::Professional,
risk_tolerance: RiskTolerance::Moderate,
jurisdiction: "EU".to_string(),
}),
market_context: Some(MarketContext {
conditions: MarketConditions::Normal,
session: TradingSession::Regular,
volatility: 0.15,
}),
timestamp: Utc::now(),
}
}
fn create_compliance_context_with_client() -> ComplianceContext {
ComplianceContext {
order_info: None,
client_info: Some(ClientInfo {
client_id: "DATA_PROTECTION_CLIENT".to_string(),
classification: ClientType::Retail,
risk_tolerance: RiskTolerance::Conservative,
jurisdiction: "EU".to_string(),
}),
market_context: None,
timestamp: Utc::now(),
}
}
#[derive(Debug, Clone)]
struct AuditTrailExport {
export_timestamp: DateTime<Utc>,
total_assessments: u32,
date_range: DateRange,
compliance_summary: ComplianceSummary,
}
#[derive(Debug, Clone)]
struct DateRange {
start: DateTime<Utc>,
end: DateTime<Utc>,
}
#[derive(Debug, Clone)]
struct ComplianceSummary {
average_score: f64,
total_violations: u32,
total_warnings: u32,
}