use crate::agents::gpt4_agent::ProposedEdit;
use std::collections::BTreeSet;
pub mod validation;
pub mod staged_application;
pub mod edit_history_time_travel;
pub mod conditional_logic;
pub mod file_protection;
#[derive(Debug, Clone)]
pub struct ModifiableEdit {
pub base_edit: ProposedEdit,
pub modifications: Vec<EditModification>,
pub approval_state: ApprovalState,
pub processing_metadata: ProcessingMetadata,
}
#[derive(Debug, Clone)]
pub enum EditModification {
CodeChange {
line: usize,
old: String,
new: String,
},
ScopeExpansion {
additional_lines: (usize, usize),
},
ScopeReduction {
removed_lines: BTreeSet<usize>,
},
ConfidenceAdjustment {
new_confidence: f64,
},
}
#[derive(Debug, Clone, PartialEq)]
pub enum ApprovalState {
Pending,
Approved,
ApprovedWithModifications,
Conditional { conditions: Vec<String> },
Queued { priority: u8 },
Rejected,
GranularPending {
required_level: ApprovalLevel,
current_approvals: Vec<ApprovalRecord>,
},
PartiallyApproved {
required_level: ApprovalLevel,
current_level: ApprovalLevel,
approvals: Vec<ApprovalRecord>,
pending_escalation: bool,
},
EscalationRequired {
current_level: ApprovalLevel,
required_level: ApprovalLevel,
reason: String,
approvals: Vec<ApprovalRecord>,
},
}
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub enum ApprovalLevel {
Auto, Low, Medium, High, Critical, }
#[derive(Debug, Clone, PartialEq)]
pub struct ApprovalRecord {
pub approver_id: String,
pub approver_role: ApprovalRole,
pub level: ApprovalLevel,
pub timestamp: std::time::SystemTime,
pub comments: Option<String>,
pub delegation_chain: Vec<String>, }
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum ApprovalRole {
Junior,
Senior,
Lead,
Architect,
Security,
System, }
#[derive(Debug, Clone)]
pub struct ApprovalPolicy {
pub risk_thresholds: RiskThresholds,
pub file_patterns: Vec<FileApprovalRule>,
pub change_type_rules: Vec<ChangeTypeRule>,
pub delegation_rules: DelegationRules,
}
#[derive(Debug, Clone)]
pub struct RiskThresholds {
pub lines_changed_high_risk: usize,
pub complexity_score_critical: f64,
pub confidence_threshold_escalation: f64,
pub security_sensitive_patterns: Vec<String>,
}
#[derive(Debug, Clone)]
pub struct FileApprovalRule {
pub pattern: String,
pub required_level: ApprovalLevel,
pub reason: String,
}
#[derive(Debug, Clone)]
pub struct ChangeTypeRule {
pub change_type: String,
pub required_level: ApprovalLevel,
pub conditions: Vec<String>,
}
#[derive(Debug, Clone)]
pub struct DelegationRules {
pub max_delegation_depth: usize,
pub allowed_delegations: std::collections::HashMap<ApprovalRole, Vec<ApprovalRole>>,
pub time_based_escalation: Option<std::time::Duration>,
}
#[derive(Debug, Clone)]
pub struct ProcessingMetadata {
pub processing_time_ms: u64,
pub memory_usage_bytes: usize,
pub validation_results: Vec<ValidationResult>,
}
#[derive(Debug, Clone)]
pub struct ValidationResult {
pub validator_name: String,
pub passed: bool,
pub message: String,
pub severity: ValidationSeverity,
}
#[derive(Debug, Clone, PartialEq)]
pub enum ValidationSeverity {
Info,
Warning,
Error,
Critical,
}
impl Default for ApprovalPolicy {
fn default() -> Self {
let mut allowed_delegations = std::collections::HashMap::new();
allowed_delegations.insert(ApprovalRole::Architect, vec![ApprovalRole::Lead]);
allowed_delegations.insert(ApprovalRole::Lead, vec![ApprovalRole::Senior]);
allowed_delegations.insert(ApprovalRole::Senior, vec![ApprovalRole::Junior]);
Self {
risk_thresholds: RiskThresholds {
lines_changed_high_risk: 50,
complexity_score_critical: 0.8,
confidence_threshold_escalation: 0.6,
security_sensitive_patterns: vec![
"password".to_string(),
"secret".to_string(),
"token".to_string(),
"auth".to_string(),
"crypto".to_string(),
],
},
file_patterns: vec![
FileApprovalRule {
pattern: "src/security/*".to_string(),
required_level: ApprovalLevel::Critical,
reason: "Security-critical code".to_string(),
},
FileApprovalRule {
pattern: "*/mod.rs".to_string(),
required_level: ApprovalLevel::High,
reason: "Module structure changes".to_string(),
},
FileApprovalRule {
pattern: "Cargo.toml".to_string(),
required_level: ApprovalLevel::High,
reason: "Dependency changes".to_string(),
},
],
change_type_rules: vec![
ChangeTypeRule {
change_type: "refactoring".to_string(),
required_level: ApprovalLevel::Medium,
conditions: vec!["Large scope changes".to_string()],
},
ChangeTypeRule {
change_type: "bug_fix".to_string(),
required_level: ApprovalLevel::Low,
conditions: vec!["Small isolated fixes".to_string()],
},
],
delegation_rules: DelegationRules {
max_delegation_depth: 2,
allowed_delegations,
time_based_escalation: Some(std::time::Duration::from_secs(24 * 60 * 60)), },
}
}
}
#[derive(Debug, Clone)]
pub struct GranularApprovalSystem {
pub policy: ApprovalPolicy,
pub approval_history: Vec<ApprovalRecord>,
pub escalation_queue: Vec<EscalationRequest>,
}
#[derive(Debug, Clone)]
pub struct EscalationRequest {
pub edit_id: String,
pub current_level: ApprovalLevel,
pub required_level: ApprovalLevel,
pub reason: String,
pub timestamp: std::time::SystemTime,
pub requesting_approver: String,
}
impl GranularApprovalSystem {
pub fn new() -> Self {
Self {
policy: ApprovalPolicy::default(),
approval_history: Vec::new(),
escalation_queue: Vec::new(),
}
}
pub fn determine_required_level(&self, edit: &ModifiableEdit) -> ApprovalLevel {
let mut required_level = ApprovalLevel::Auto;
if edit.get_effective_confidence() < self.policy.risk_thresholds.confidence_threshold_escalation {
required_level = std::cmp::max(required_level, ApprovalLevel::Medium);
}
for rule in &self.policy.file_patterns {
if self.matches_pattern(&edit.base_edit.file, &rule.pattern) {
required_level = std::cmp::max(required_level, rule.required_level.clone());
}
}
let lines_changed = edit.base_edit.new_code.lines().count();
if lines_changed > self.policy.risk_thresholds.lines_changed_high_risk {
required_level = std::cmp::max(required_level, ApprovalLevel::High);
}
for pattern in &self.policy.risk_thresholds.security_sensitive_patterns {
if edit.base_edit.new_code.to_lowercase().contains(pattern) {
required_level = std::cmp::max(required_level, ApprovalLevel::Critical);
break;
}
}
required_level
}
pub fn add_approval(&mut self, approval: ApprovalRecord) -> Result<ApprovalLevel, String> {
if approval.delegation_chain.len() > self.policy.delegation_rules.max_delegation_depth {
return Err("Delegation chain too deep".to_string());
}
self.approval_history.push(approval.clone());
self.calculate_current_approval_level()
}
pub fn calculate_current_approval_level(&self) -> Result<ApprovalLevel, String> {
if self.approval_history.is_empty() {
return Ok(ApprovalLevel::Auto);
}
let mut highest_level = ApprovalLevel::Auto;
let mut senior_count = 0;
let mut has_lead = false;
let mut has_architect = false;
let mut has_security = false;
for approval in &self.approval_history {
match approval.approver_role {
ApprovalRole::Junior => {
}
ApprovalRole::Senior => {
senior_count += 1;
highest_level = std::cmp::max(highest_level, ApprovalLevel::Low);
}
ApprovalRole::Lead => {
has_lead = true;
highest_level = std::cmp::max(highest_level, ApprovalLevel::High);
}
ApprovalRole::Architect => {
has_architect = true;
highest_level = std::cmp::max(highest_level, ApprovalLevel::High);
}
ApprovalRole::Security => {
has_security = true;
}
ApprovalRole::System => {
}
}
}
if has_architect && has_security {
highest_level = std::cmp::max(highest_level, ApprovalLevel::Critical);
} else if has_lead || has_architect {
highest_level = std::cmp::max(highest_level, ApprovalLevel::High);
} else if senior_count >= 2 {
highest_level = std::cmp::max(highest_level, ApprovalLevel::Medium);
} else if senior_count >= 1 {
highest_level = std::cmp::max(highest_level, ApprovalLevel::Low);
}
Ok(highest_level)
}
pub fn is_approval_sufficient(&self, required_level: &ApprovalLevel) -> Result<bool, String> {
let current_level = self.calculate_current_approval_level()?;
Ok(current_level >= *required_level)
}
pub fn request_escalation(&mut self, request: EscalationRequest) {
self.escalation_queue.push(request);
}
pub fn get_approval_status(&self, required_level: &ApprovalLevel) -> ApprovalStatus {
let current_level = self.calculate_current_approval_level().unwrap_or(ApprovalLevel::Auto);
let is_sufficient = current_level >= *required_level;
ApprovalStatus {
required_level: required_level.clone(),
current_level: current_level.clone(),
is_sufficient,
approval_count: self.approval_history.len(),
escalation_pending: !self.escalation_queue.is_empty(),
next_required_role: self.determine_next_required_role(required_level, ¤t_level),
}
}
fn matches_pattern(&self, file_path: &str, pattern: &str) -> bool {
if pattern.contains('*') {
let prefix = pattern.split('*').next().unwrap_or("");
let suffix = pattern.split('*').last().unwrap_or("");
file_path.starts_with(prefix) && file_path.ends_with(suffix)
} else {
file_path == pattern
}
}
fn determine_next_required_role(&self, required_level: &ApprovalLevel, current_level: &ApprovalLevel) -> Option<ApprovalRole> {
if current_level >= required_level {
return None;
}
match required_level {
ApprovalLevel::Auto => None,
ApprovalLevel::Low => Some(ApprovalRole::Senior),
ApprovalLevel::Medium => {
let senior_count = self.approval_history.iter()
.filter(|a| a.approver_role == ApprovalRole::Senior)
.count();
if senior_count < 2 {
Some(ApprovalRole::Senior)
} else {
Some(ApprovalRole::Lead)
}
},
ApprovalLevel::High => Some(ApprovalRole::Lead),
ApprovalLevel::Critical => {
let has_architect = self.approval_history.iter()
.any(|a| a.approver_role == ApprovalRole::Architect);
let has_security = self.approval_history.iter()
.any(|a| a.approver_role == ApprovalRole::Security);
if !has_architect {
Some(ApprovalRole::Architect)
} else if !has_security {
Some(ApprovalRole::Security)
} else {
None
}
}
}
}
}
#[derive(Debug, Clone)]
pub struct ApprovalStatus {
pub required_level: ApprovalLevel,
pub current_level: ApprovalLevel,
pub is_sufficient: bool,
pub approval_count: usize,
pub escalation_pending: bool,
pub next_required_role: Option<ApprovalRole>,
}
impl Default for ProcessingMetadata {
fn default() -> Self {
Self {
processing_time_ms: 0,
memory_usage_bytes: 0,
validation_results: Vec::new(),
}
}
}
impl ModifiableEdit {
pub fn from_proposed_edit(edit: ProposedEdit) -> Self {
Self {
base_edit: edit,
modifications: Vec::with_capacity(4), approval_state: ApprovalState::Pending,
processing_metadata: ProcessingMetadata::default(),
}
}
pub fn from_proposed_edit_with_approval_level(edit: ProposedEdit, required_level: ApprovalLevel) -> Self {
Self {
base_edit: edit,
modifications: Vec::with_capacity(4),
approval_state: ApprovalState::GranularPending {
required_level,
current_approvals: Vec::new(),
},
processing_metadata: ProcessingMetadata::default(),
}
}
pub fn add_approval_record(&mut self, approval: ApprovalRecord) -> Result<(), String> {
match &mut self.approval_state {
ApprovalState::GranularPending { current_approvals, .. } => {
current_approvals.push(approval);
Ok(())
}
ApprovalState::PartiallyApproved { approvals, .. } => {
approvals.push(approval);
Ok(())
}
ApprovalState::EscalationRequired { approvals, .. } => {
approvals.push(approval);
Ok(())
}
_ => Err("Edit is not in a granular approval state".to_string())
}
}
pub fn evaluate_granular_approval(&mut self) -> Result<(), String> {
let mut approval_system = GranularApprovalSystem::new();
let approvals = match &self.approval_state {
ApprovalState::GranularPending { current_approvals, required_level } => {
(current_approvals.clone(), required_level.clone())
}
ApprovalState::PartiallyApproved { approvals, required_level, .. } => {
(approvals.clone(), required_level.clone())
}
ApprovalState::EscalationRequired { approvals, required_level, .. } => {
(approvals.clone(), required_level.clone())
}
_ => return Err("Edit is not in a granular approval state".to_string())
};
for approval in &approvals.0 {
approval_system.add_approval(approval.clone())?;
}
if approval_system.is_approval_sufficient(&approvals.1)? {
self.approval_state = ApprovalState::Approved;
} else {
let status = approval_system.get_approval_status(&approvals.1);
if status.current_level < status.required_level {
self.approval_state = ApprovalState::PartiallyApproved {
required_level: status.required_level,
current_level: status.current_level,
approvals: approvals.0,
pending_escalation: status.escalation_pending,
};
}
}
Ok(())
}
pub fn compute_final_code(&self) -> String {
let mut result = self.base_edit.new_code.clone();
for modification in &self.modifications {
match modification {
EditModification::CodeChange { line: _, old, new } => {
result = result.replace(old, new);
}
EditModification::ScopeExpansion { additional_lines } => {
result.push_str(&format!(
"\n// Expanded scope: lines {}-{}",
additional_lines.0, additional_lines.1
));
}
EditModification::ScopeReduction { removed_lines: _ } => {
result.push_str("\n// Scope reduced");
}
EditModification::ConfidenceAdjustment { new_confidence: _ } => {
}
}
}
result
}
pub fn add_modification(&mut self, modification: EditModification) {
self.modifications.push(modification);
}
pub fn set_approval_state(&mut self, state: ApprovalState) {
self.approval_state = state;
}
pub fn get_effective_confidence(&self) -> f64 {
let mut confidence = self.base_edit.confidence;
for modification in &self.modifications {
if let EditModification::ConfidenceAdjustment { new_confidence } = modification {
confidence = *new_confidence;
}
}
confidence
}
pub fn is_approved(&self) -> bool {
matches!(
self.approval_state,
ApprovalState::Approved | ApprovalState::ApprovedWithModifications
)
}
pub fn is_ready_for_application(&self) -> bool {
self.is_approved()
&& self
.processing_metadata
.validation_results
.iter()
.all(|v| v.severity != ValidationSeverity::Critical)
}
}
#[derive(Debug, Clone)]
pub struct EditModificationInterface {
pub modifiable_edit: ModifiableEdit,
pub modification_history: Vec<ModificationSnapshot>,
pub current_snapshot: usize,
pub interface_state: InterfaceState,
pub view_mode: ViewMode,
pub syntax_highlighting: bool,
}
#[derive(Debug, Clone)]
pub struct ModificationSnapshot {
pub modifications: Vec<EditModification>,
pub code_content: String,
pub timestamp: std::time::SystemTime,
pub description: String,
}
#[derive(Debug, Clone, PartialEq)]
pub enum InterfaceState {
Editing,
Comparing,
Previewing,
Validating,
Saving,
}
#[derive(Debug, Clone, PartialEq)]
pub enum ViewMode {
Single, SideBySide, Unified, FullScreen, }
impl EditModificationInterface {
pub fn new(modifiable_edit: ModifiableEdit) -> Self {
let initial_snapshot = ModificationSnapshot {
modifications: modifiable_edit.modifications.clone(),
code_content: modifiable_edit.compute_final_code(),
timestamp: std::time::SystemTime::now(),
description: "Initial state".to_string(),
};
Self {
modifiable_edit,
modification_history: vec![initial_snapshot],
current_snapshot: 0,
interface_state: InterfaceState::Editing,
view_mode: ViewMode::Single,
syntax_highlighting: true,
}
}
pub fn add_modification(&mut self, modification: EditModification, description: String) {
self.modifiable_edit.add_modification(modification);
let snapshot = ModificationSnapshot {
modifications: self.modifiable_edit.modifications.clone(),
code_content: self.modifiable_edit.compute_final_code(),
timestamp: std::time::SystemTime::now(),
description,
};
if self.current_snapshot < self.modification_history.len() - 1 {
self.modification_history.truncate(self.current_snapshot + 1);
}
self.modification_history.push(snapshot);
self.current_snapshot = self.modification_history.len() - 1;
}
pub fn undo(&mut self) -> bool {
if self.current_snapshot > 0 {
self.current_snapshot -= 1;
self.restore_snapshot();
true
} else {
false
}
}
pub fn redo(&mut self) -> bool {
if self.current_snapshot < self.modification_history.len() - 1 {
self.current_snapshot += 1;
self.restore_snapshot();
true
} else {
false
}
}
fn restore_snapshot(&mut self) {
if let Some(snapshot) = self.modification_history.get(self.current_snapshot) {
self.modifiable_edit.modifications = snapshot.modifications.clone();
}
}
pub fn modification_count(&self) -> usize {
self.modifiable_edit.modifications.len()
}
pub fn can_undo(&self) -> bool {
self.current_snapshot > 0
}
pub fn can_redo(&self) -> bool {
self.current_snapshot < self.modification_history.len() - 1
}
pub fn set_view_mode(&mut self, mode: ViewMode) {
self.view_mode = mode;
}
pub fn set_state(&mut self, state: InterfaceState) {
self.interface_state = state;
}
pub fn toggle_syntax_highlighting(&mut self) {
self.syntax_highlighting = !self.syntax_highlighting;
}
pub fn current_snapshot_description(&self) -> Option<&str> {
self.modification_history
.get(self.current_snapshot)
.map(|s| s.description.as_str())
}
pub fn get_history_summary(&self) -> Vec<String> {
self.modification_history
.iter()
.enumerate()
.map(|(i, snapshot)| {
let marker = if i == self.current_snapshot { ">" } else { " " };
format!("{} {}: {}", marker, i, snapshot.description)
})
.collect()
}
pub fn get_diff_summary(&self) -> DiffSummary {
let original = &self.modifiable_edit.base_edit.new_code;
let current = &self.modifiable_edit.compute_final_code();
let original_lines: Vec<&str> = original.lines().collect();
let current_lines: Vec<&str> = current.lines().collect();
DiffSummary {
lines_added: current_lines.len().saturating_sub(original_lines.len()),
lines_removed: original_lines.len().saturating_sub(current_lines.len()),
lines_modified: self.calculate_modified_lines(&original_lines, ¤t_lines),
total_changes: self.modification_count(),
}
}
fn calculate_modified_lines(&self, original: &[&str], current: &[&str]) -> usize {
let min_len = original.len().min(current.len());
let mut modified = 0;
for i in 0..min_len {
if original[i] != current[i] {
modified += 1;
}
}
modified
}
}
#[derive(Debug, Clone)]
pub struct DiffSummary {
pub lines_added: usize,
pub lines_removed: usize,
pub lines_modified: usize,
pub total_changes: usize,
}
pub use conditional_logic::{
ConditionalLogicSystem, Condition, ConditionType, ClassificationCriteria,
TestConfiguration, ConditionalChain, ChainLink, ChainFailureStrategy,
ConditionalApplicationResult, ChainExecutionResult, ExecutionContext
};
#[cfg(test)]
mod tests {
use super::*;
fn create_test_edit() -> ProposedEdit {
ProposedEdit {
file: "test.rs".to_string(),
line_range: (10, 15),
new_code: "fn test() {\n println!(\"Hello\");\n}".to_string(),
reason: "Test function".to_string(),
confidence: 0.9,
}
}
#[test]
fn test_modifiable_edit_creation() {
let edit = create_test_edit();
let modifiable = ModifiableEdit::from_proposed_edit(edit);
assert_eq!(modifiable.approval_state, ApprovalState::Pending);
assert_eq!(modifiable.modifications.len(), 0);
assert_eq!(modifiable.get_effective_confidence(), 0.9);
}
#[test]
fn test_code_modification() {
let edit = create_test_edit();
let mut modifiable = ModifiableEdit::from_proposed_edit(edit);
modifiable.add_modification(EditModification::CodeChange {
line: 1,
old: "Hello".to_string(),
new: "World".to_string(),
});
let final_code = modifiable.compute_final_code();
assert!(final_code.contains("World"));
assert!(!final_code.contains("Hello"));
}
#[test]
fn test_confidence_adjustment() {
let edit = create_test_edit();
let mut modifiable = ModifiableEdit::from_proposed_edit(edit);
modifiable.add_modification(EditModification::ConfidenceAdjustment {
new_confidence: 0.8,
});
assert_eq!(modifiable.get_effective_confidence(), 0.8);
}
#[test]
fn test_approval_states() {
let edit = create_test_edit();
let mut modifiable = ModifiableEdit::from_proposed_edit(edit);
assert!(!modifiable.is_approved());
modifiable.set_approval_state(ApprovalState::Approved);
assert!(modifiable.is_approved());
assert!(modifiable.is_ready_for_application());
modifiable.set_approval_state(ApprovalState::Rejected);
assert!(!modifiable.is_approved());
}
#[test]
fn test_edit_modification_interface_creation() {
let edit = create_test_edit();
let modifiable = ModifiableEdit::from_proposed_edit(edit);
let interface = EditModificationInterface::new(modifiable);
assert_eq!(interface.current_snapshot, 0);
assert_eq!(interface.modification_history.len(), 1);
assert_eq!(interface.interface_state, InterfaceState::Editing);
assert_eq!(interface.view_mode, ViewMode::Single);
assert!(interface.syntax_highlighting);
assert_eq!(interface.modification_count(), 0);
}
#[test]
fn test_modification_tracking_with_snapshots() {
let edit = create_test_edit();
let modifiable = ModifiableEdit::from_proposed_edit(edit);
let mut interface = EditModificationInterface::new(modifiable);
interface.add_modification(
EditModification::CodeChange {
line: 1,
old: "Hello".to_string(),
new: "World".to_string(),
},
"Changed greeting".to_string(),
);
assert_eq!(interface.modification_count(), 1);
assert_eq!(interface.modification_history.len(), 2);
assert_eq!(interface.current_snapshot, 1);
interface.add_modification(
EditModification::ConfidenceAdjustment { new_confidence: 0.8 },
"Adjusted confidence".to_string(),
);
assert_eq!(interface.modification_count(), 2);
assert_eq!(interface.modification_history.len(), 3);
assert_eq!(interface.current_snapshot, 2);
}
#[test]
fn test_undo_redo_functionality() {
let edit = create_test_edit();
let modifiable = ModifiableEdit::from_proposed_edit(edit);
let mut interface = EditModificationInterface::new(modifiable);
interface.add_modification(
EditModification::CodeChange {
line: 1,
old: "Hello".to_string(),
new: "World".to_string(),
},
"First change".to_string(),
);
interface.add_modification(
EditModification::ConfidenceAdjustment { new_confidence: 0.8 },
"Second change".to_string(),
);
assert_eq!(interface.modification_count(), 2);
assert!(interface.can_undo());
assert!(!interface.can_redo());
assert!(interface.undo());
assert_eq!(interface.modification_count(), 1);
assert_eq!(interface.current_snapshot, 1);
assert!(interface.can_undo());
assert!(interface.can_redo());
assert!(interface.undo());
assert_eq!(interface.modification_count(), 0);
assert_eq!(interface.current_snapshot, 0);
assert!(!interface.can_undo());
assert!(interface.can_redo());
assert!(interface.redo());
assert_eq!(interface.modification_count(), 1);
assert_eq!(interface.current_snapshot, 1);
assert!(interface.can_undo());
assert!(interface.can_redo());
assert!(interface.redo());
assert_eq!(interface.modification_count(), 2);
assert_eq!(interface.current_snapshot, 2);
assert!(interface.can_undo());
assert!(!interface.can_redo());
}
#[test]
fn test_branching_history_after_undo() {
let edit = create_test_edit();
let modifiable = ModifiableEdit::from_proposed_edit(edit);
let mut interface = EditModificationInterface::new(modifiable);
interface.add_modification(
EditModification::CodeChange {
line: 1,
old: "Hello".to_string(),
new: "World".to_string(),
},
"First change".to_string(),
);
interface.add_modification(
EditModification::ConfidenceAdjustment { new_confidence: 0.8 },
"Second change".to_string(),
);
assert_eq!(interface.modification_history.len(), 3);
interface.undo();
assert_eq!(interface.current_snapshot, 1);
interface.add_modification(
EditModification::ScopeExpansion {
additional_lines: (5, 10),
},
"Branched change".to_string(),
);
assert_eq!(interface.modification_history.len(), 3); assert_eq!(interface.current_snapshot, 2);
assert!(!interface.can_redo()); }
#[test]
fn test_view_mode_and_interface_state() {
let edit = create_test_edit();
let modifiable = ModifiableEdit::from_proposed_edit(edit);
let mut interface = EditModificationInterface::new(modifiable);
assert_eq!(interface.view_mode, ViewMode::Single);
interface.set_view_mode(ViewMode::SideBySide);
assert_eq!(interface.view_mode, ViewMode::SideBySide);
interface.set_view_mode(ViewMode::Unified);
assert_eq!(interface.view_mode, ViewMode::Unified);
assert_eq!(interface.interface_state, InterfaceState::Editing);
interface.set_state(InterfaceState::Comparing);
assert_eq!(interface.interface_state, InterfaceState::Comparing);
interface.set_state(InterfaceState::Previewing);
assert_eq!(interface.interface_state, InterfaceState::Previewing);
}
#[test]
fn test_syntax_highlighting_toggle() {
let edit = create_test_edit();
let modifiable = ModifiableEdit::from_proposed_edit(edit);
let mut interface = EditModificationInterface::new(modifiable);
assert!(interface.syntax_highlighting);
interface.toggle_syntax_highlighting();
assert!(!interface.syntax_highlighting);
interface.toggle_syntax_highlighting();
assert!(interface.syntax_highlighting);
}
#[test]
fn test_history_summary() {
let edit = create_test_edit();
let modifiable = ModifiableEdit::from_proposed_edit(edit);
let mut interface = EditModificationInterface::new(modifiable);
let summary = interface.get_history_summary();
assert_eq!(summary.len(), 1);
assert!(summary[0].contains("> 0: Initial state"));
interface.add_modification(
EditModification::CodeChange {
line: 1,
old: "Hello".to_string(),
new: "World".to_string(),
},
"Changed greeting".to_string(),
);
let summary = interface.get_history_summary();
assert_eq!(summary.len(), 2);
assert!(summary[0].contains(" 0: Initial state"));
assert!(summary[1].contains("> 1: Changed greeting"));
}
#[test]
fn test_diff_summary_calculation() {
let edit = create_test_edit();
let modifiable = ModifiableEdit::from_proposed_edit(edit);
let mut interface = EditModificationInterface::new(modifiable);
let diff = interface.get_diff_summary();
assert_eq!(diff.total_changes, 0);
interface.add_modification(
EditModification::CodeChange {
line: 1,
old: "println!(\"Hello\")".to_string(),
new: "println!(\"Hello, World!\")".to_string(),
},
"Enhanced greeting".to_string(),
);
let diff = interface.get_diff_summary();
assert_eq!(diff.total_changes, 1);
}
#[test]
fn test_current_snapshot_description() {
let edit = create_test_edit();
let modifiable = ModifiableEdit::from_proposed_edit(edit);
let mut interface = EditModificationInterface::new(modifiable);
assert_eq!(interface.current_snapshot_description(), Some("Initial state"));
interface.add_modification(
EditModification::CodeChange {
line: 1,
old: "Hello".to_string(),
new: "World".to_string(),
},
"Custom description".to_string(),
);
assert_eq!(interface.current_snapshot_description(), Some("Custom description"));
interface.undo();
assert_eq!(interface.current_snapshot_description(), Some("Initial state"));
}
#[test]
fn test_approval_level_ordering() {
use std::cmp::Ordering;
assert_eq!(ApprovalLevel::Auto.cmp(&ApprovalLevel::Low), Ordering::Less);
assert_eq!(ApprovalLevel::Low.cmp(&ApprovalLevel::Medium), Ordering::Less);
assert_eq!(ApprovalLevel::Medium.cmp(&ApprovalLevel::High), Ordering::Less);
assert_eq!(ApprovalLevel::High.cmp(&ApprovalLevel::Critical), Ordering::Less);
assert_eq!(ApprovalLevel::Critical.cmp(&ApprovalLevel::Critical), Ordering::Equal);
}
#[test]
fn test_granular_approval_system_creation() {
let system = GranularApprovalSystem::new();
assert_eq!(system.approval_history.len(), 0);
assert_eq!(system.escalation_queue.len(), 0);
assert!(system.policy.risk_thresholds.lines_changed_high_risk > 0);
}
#[test]
fn test_approval_level_determination() {
let system = GranularApprovalSystem::new();
let mut edit = create_test_edit();
edit.confidence = 0.5; let modifiable = ModifiableEdit::from_proposed_edit(edit);
let level = system.determine_required_level(&modifiable);
assert!(level >= ApprovalLevel::Medium); }
#[test]
fn test_security_pattern_detection() {
let system = GranularApprovalSystem::new();
let mut edit = create_test_edit();
edit.new_code = "const password = 'secret123';".to_string();
let modifiable = ModifiableEdit::from_proposed_edit(edit);
let level = system.determine_required_level(&modifiable);
assert_eq!(level, ApprovalLevel::Critical); }
#[test]
fn test_file_pattern_matching() {
let system = GranularApprovalSystem::new();
let mut edit = create_test_edit();
edit.file = "src/security/crypto.rs".to_string();
let modifiable = ModifiableEdit::from_proposed_edit(edit);
let level = system.determine_required_level(&modifiable);
assert_eq!(level, ApprovalLevel::Critical); }
#[test]
fn test_large_change_detection() {
let system = GranularApprovalSystem::new();
let mut edit = create_test_edit();
edit.new_code = (0..60).map(|i| format!("line {}", i)).collect::<Vec<_>>().join("\n");
let modifiable = ModifiableEdit::from_proposed_edit(edit);
let level = system.determine_required_level(&modifiable);
assert!(level >= ApprovalLevel::High); }
#[test]
fn test_approval_record_creation() {
use std::time::SystemTime;
let approval = ApprovalRecord {
approver_id: "test_user".to_string(),
approver_role: ApprovalRole::Senior,
level: ApprovalLevel::Low,
timestamp: SystemTime::now(),
comments: Some("Looks good".to_string()),
delegation_chain: Vec::new(),
};
assert_eq!(approval.approver_id, "test_user");
assert_eq!(approval.approver_role, ApprovalRole::Senior);
assert!(approval.comments.is_some());
}
#[test]
fn test_approval_level_calculation() {
let mut system = GranularApprovalSystem::new();
let senior_approval = ApprovalRecord {
approver_id: "senior1".to_string(),
approver_role: ApprovalRole::Senior,
level: ApprovalLevel::Low,
timestamp: std::time::SystemTime::now(),
comments: None,
delegation_chain: Vec::new(),
};
system.add_approval(senior_approval).unwrap();
let level = system.calculate_current_approval_level().unwrap();
assert_eq!(level, ApprovalLevel::Low);
let senior_approval2 = ApprovalRecord {
approver_id: "senior2".to_string(),
approver_role: ApprovalRole::Senior,
level: ApprovalLevel::Medium,
timestamp: std::time::SystemTime::now(),
comments: None,
delegation_chain: Vec::new(),
};
system.add_approval(senior_approval2).unwrap();
let level = system.calculate_current_approval_level().unwrap();
assert_eq!(level, ApprovalLevel::Medium); }
#[test]
fn test_lead_approval() {
let mut system = GranularApprovalSystem::new();
let lead_approval = ApprovalRecord {
approver_id: "lead1".to_string(),
approver_role: ApprovalRole::Lead,
level: ApprovalLevel::High,
timestamp: std::time::SystemTime::now(),
comments: None,
delegation_chain: Vec::new(),
};
system.add_approval(lead_approval).unwrap();
let level = system.calculate_current_approval_level().unwrap();
assert_eq!(level, ApprovalLevel::High);
}
#[test]
fn test_critical_approval_requirements() {
let mut system = GranularApprovalSystem::new();
let architect_approval = ApprovalRecord {
approver_id: "architect1".to_string(),
approver_role: ApprovalRole::Architect,
level: ApprovalLevel::Critical,
timestamp: std::time::SystemTime::now(),
comments: None,
delegation_chain: Vec::new(),
};
system.add_approval(architect_approval).unwrap();
let level = system.calculate_current_approval_level().unwrap();
assert_eq!(level, ApprovalLevel::High);
let security_approval = ApprovalRecord {
approver_id: "security1".to_string(),
approver_role: ApprovalRole::Security,
level: ApprovalLevel::Critical,
timestamp: std::time::SystemTime::now(),
comments: None,
delegation_chain: Vec::new(),
};
system.add_approval(security_approval).unwrap();
let level = system.calculate_current_approval_level().unwrap();
assert_eq!(level, ApprovalLevel::Critical); }
#[test]
fn test_approval_sufficiency_check() {
let mut system = GranularApprovalSystem::new();
assert!(!system.is_approval_sufficient(&ApprovalLevel::Medium).unwrap());
let senior_approval1 = ApprovalRecord {
approver_id: "senior1".to_string(),
approver_role: ApprovalRole::Senior,
level: ApprovalLevel::Medium,
timestamp: std::time::SystemTime::now(),
comments: None,
delegation_chain: Vec::new(),
};
let senior_approval2 = ApprovalRecord {
approver_id: "senior2".to_string(),
approver_role: ApprovalRole::Senior,
level: ApprovalLevel::Medium,
timestamp: std::time::SystemTime::now(),
comments: None,
delegation_chain: Vec::new(),
};
system.add_approval(senior_approval1).unwrap();
system.add_approval(senior_approval2).unwrap();
assert!(system.is_approval_sufficient(&ApprovalLevel::Medium).unwrap());
}
#[test]
fn test_approval_status_summary() {
let system = GranularApprovalSystem::new();
let required_level = ApprovalLevel::High;
let status = system.get_approval_status(&required_level);
assert_eq!(status.required_level, ApprovalLevel::High);
assert_eq!(status.current_level, ApprovalLevel::Auto);
assert!(!status.is_sufficient);
assert_eq!(status.approval_count, 0);
assert_eq!(status.next_required_role, Some(ApprovalRole::Lead));
}
#[test]
fn test_delegation_chain_validation() {
let mut system = GranularApprovalSystem::new();
let valid_approval = ApprovalRecord {
approver_id: "delegated_user".to_string(),
approver_role: ApprovalRole::Senior,
level: ApprovalLevel::Low,
timestamp: std::time::SystemTime::now(),
comments: None,
delegation_chain: vec!["lead1".to_string()], };
assert!(system.add_approval(valid_approval).is_ok());
let invalid_approval = ApprovalRecord {
approver_id: "delegated_user2".to_string(),
approver_role: ApprovalRole::Junior,
level: ApprovalLevel::Low,
timestamp: std::time::SystemTime::now(),
comments: None,
delegation_chain: vec!["lead1".to_string(), "senior1".to_string(), "junior1".to_string()], };
assert!(system.add_approval(invalid_approval).is_err());
}
#[test]
fn test_escalation_request() {
let mut system = GranularApprovalSystem::new();
let escalation = EscalationRequest {
edit_id: "edit_123".to_string(),
current_level: ApprovalLevel::Medium,
required_level: ApprovalLevel::High,
reason: "Complex security implications".to_string(),
timestamp: std::time::SystemTime::now(),
requesting_approver: "senior1".to_string(),
};
system.request_escalation(escalation);
assert_eq!(system.escalation_queue.len(), 1);
}
#[test]
fn test_modifiable_edit_granular_approval_integration() {
let edit = create_test_edit();
let mut modifiable = ModifiableEdit::from_proposed_edit_with_approval_level(
edit,
ApprovalLevel::Medium
);
match &modifiable.approval_state {
ApprovalState::GranularPending { required_level, current_approvals } => {
assert_eq!(*required_level, ApprovalLevel::Medium);
assert_eq!(current_approvals.len(), 0);
}
_ => panic!("Expected GranularPending state"),
}
let approval = ApprovalRecord {
approver_id: "senior1".to_string(),
approver_role: ApprovalRole::Senior,
level: ApprovalLevel::Medium,
timestamp: std::time::SystemTime::now(),
comments: Some("Approved".to_string()),
delegation_chain: Vec::new(),
};
modifiable.add_approval_record(approval).unwrap();
match &modifiable.approval_state {
ApprovalState::GranularPending { current_approvals, .. } => {
assert_eq!(current_approvals.len(), 1);
}
_ => panic!("Expected approval to be added"),
}
}
#[test]
fn test_approval_evaluation_workflow() {
let edit = create_test_edit();
let mut modifiable = ModifiableEdit::from_proposed_edit_with_approval_level(
edit,
ApprovalLevel::Low
);
let approval = ApprovalRecord {
approver_id: "senior1".to_string(),
approver_role: ApprovalRole::Senior,
level: ApprovalLevel::Low,
timestamp: std::time::SystemTime::now(),
comments: None,
delegation_chain: Vec::new(),
};
modifiable.add_approval_record(approval).unwrap();
modifiable.evaluate_granular_approval().unwrap();
assert_eq!(modifiable.approval_state, ApprovalState::Approved);
}
#[test]
fn test_pattern_matching() {
let system = GranularApprovalSystem::new();
assert!(system.matches_pattern("Cargo.toml", "Cargo.toml"));
assert!(system.matches_pattern("src/security/auth.rs", "src/security/*"));
assert!(system.matches_pattern("tests/mod.rs", "*/mod.rs"));
assert!(!system.matches_pattern("src/main.rs", "*/mod.rs"));
}
}
pub use file_protection::{
FileProtectionSystem, FileProtectionRule, FunctionConstraint, ProtectionConfig,
ProtectionLevel, EditType, ProtectionResult
};