use chrono::{Duration, Utc};
use qrusty::message::{Message, Priority, PriorityKind, PriorityOrdering, QueueConfig, QueueStats};
#[test]
fn test_message_creation() {
let now = Utc::now();
let message = Message {
id: "test-id-123".to_string(),
queue: "test_queue".to_string(),
priority: Priority::Numeric(100),
payload: r#"{"key": "value"}"#.to_string(),
created_at: now,
locked_until: None,
locked_by: None,
retry_count: 0,
max_retries: 3,
payload_ref: None,
payload_hash: None,
};
assert_eq!(message.id, "test-id-123");
assert_eq!(message.queue, "test_queue");
assert_eq!(message.priority, Priority::Numeric(100));
assert_eq!(message.payload, r#"{"key": "value"}"#);
assert_eq!(message.created_at, now);
assert!(message.locked_until.is_none());
assert!(message.locked_by.is_none());
assert_eq!(message.retry_count, 0);
assert_eq!(message.max_retries, 3);
}
#[test]
fn test_message_serialization() {
let now = Utc::now();
let message = Message {
id: "test-id-123".to_string(),
queue: "test_queue".to_string(),
priority: Priority::Numeric(100),
payload: r#"{"key": "value"}"#.to_string(),
created_at: now,
locked_until: Some(now + Duration::seconds(30)),
locked_by: Some("consumer-1".to_string()),
retry_count: 1,
max_retries: 3,
payload_ref: None,
payload_hash: None,
};
let json = serde_json::to_string(&message).unwrap();
assert!(json.contains("test-id-123"));
assert!(json.contains("test_queue"));
assert!(json.contains("consumer-1"));
let deserialized: Message = serde_json::from_str(&json).unwrap();
assert_eq!(deserialized.id, message.id);
assert_eq!(deserialized.queue, message.queue);
assert_eq!(deserialized.priority, message.priority);
assert_eq!(deserialized.payload, message.payload);
assert_eq!(deserialized.retry_count, message.retry_count);
assert_eq!(deserialized.max_retries, message.max_retries);
assert_eq!(deserialized.locked_by, message.locked_by);
}
#[test]
fn test_message_clone() {
let now = Utc::now();
let original = Message {
id: "test-id-123".to_string(),
queue: "test_queue".to_string(),
priority: Priority::Numeric(100),
payload: r#"{"key": "value"}"#.to_string(),
created_at: now,
locked_until: Some(now + Duration::seconds(30)),
locked_by: Some("consumer-1".to_string()),
retry_count: 1,
max_retries: 3,
payload_ref: None,
payload_hash: None,
};
let cloned = original.clone();
assert_eq!(cloned.id, original.id);
assert_eq!(cloned.queue, original.queue);
assert_eq!(cloned.priority, original.priority);
assert_eq!(cloned.payload, original.payload);
assert_eq!(cloned.created_at, original.created_at);
assert_eq!(cloned.locked_until, original.locked_until);
assert_eq!(cloned.locked_by, original.locked_by);
assert_eq!(cloned.retry_count, original.retry_count);
assert_eq!(cloned.max_retries, original.max_retries);
}
#[test]
fn test_message_debug() {
let message = Message {
id: "test-id-123".to_string(),
queue: "test_queue".to_string(),
priority: Priority::Numeric(100),
payload: r#"{"key": "value"}"#.to_string(),
created_at: Utc::now(),
locked_until: None,
locked_by: None,
retry_count: 0,
max_retries: 3,
payload_ref: None,
payload_hash: None,
};
let debug_str = format!("{:?}", message);
assert!(debug_str.contains("Message"));
assert!(debug_str.contains("test-id-123"));
assert!(debug_str.contains("test_queue"));
assert!(debug_str.contains("100"));
}
#[test]
fn test_queue_stats_creation() {
let stats = QueueStats {
name: "orders".to_string(),
available: 150,
locked: 25,
total: 175,
config: QueueConfig::default(),
};
assert_eq!(stats.name, "orders");
assert_eq!(stats.available, 150);
assert_eq!(stats.locked, 25);
assert_eq!(stats.total, 175);
}
#[test]
fn test_queue_stats_serialization() {
let stats = QueueStats {
name: "orders".to_string(),
available: 150,
locked: 25,
total: 175,
config: QueueConfig::default(),
};
let json = serde_json::to_string(&stats).unwrap();
assert!(json.contains("orders"));
assert!(json.contains("150"));
assert!(json.contains("25"));
assert!(json.contains("175"));
let deserialized: QueueStats = serde_json::from_str(&json).unwrap();
assert_eq!(deserialized.name, stats.name);
assert_eq!(deserialized.available, stats.available);
assert_eq!(deserialized.locked, stats.locked);
assert_eq!(deserialized.total, stats.total);
}
#[test]
fn test_queue_stats_clone() {
let original = QueueStats {
name: "orders".to_string(),
available: 150,
locked: 25,
total: 175,
config: QueueConfig::default(),
};
let cloned = original.clone();
assert_eq!(cloned.name, original.name);
assert_eq!(cloned.available, original.available);
assert_eq!(cloned.locked, original.locked);
assert_eq!(cloned.total, original.total);
}
#[test]
fn test_queue_stats_debug() {
let stats = QueueStats {
name: "orders".to_string(),
available: 150,
locked: 25,
total: 175,
config: QueueConfig::default(),
};
let debug_str = format!("{:?}", stats);
assert!(debug_str.contains("QueueStats"));
assert!(debug_str.contains("orders"));
assert!(debug_str.contains("150"));
assert!(debug_str.contains("25"));
assert!(debug_str.contains("175"));
}
#[test]
fn test_message_with_complex_payload() {
let complex_payload = r#"{
"order_id": 12345,
"customer": {
"name": "John Doe",
"email": "john@example.com"
},
"items": [
{"sku": "ABC123", "quantity": 2},
{"sku": "XYZ789", "quantity": 1}
],
"total": 99.99,
"metadata": {
"source": "web",
"campaign": "summer2025"
}
}"#;
let message = Message {
id: uuid::Uuid::new_v4().to_string(),
queue: "orders".to_string(),
priority: Priority::Numeric(100),
payload: complex_payload.to_string(),
created_at: Utc::now(),
locked_until: None,
locked_by: None,
retry_count: 0,
max_retries: 3,
payload_ref: None,
payload_hash: None,
};
let parsed: serde_json::Value = serde_json::from_str(&message.payload).unwrap();
assert_eq!(parsed["order_id"], 12345);
assert_eq!(parsed["customer"]["name"], "John Doe");
assert_eq!(parsed["items"][0]["sku"], "ABC123");
assert_eq!(parsed["total"], 99.99);
let serialized = serde_json::to_string(&message).unwrap();
let deserialized: Message = serde_json::from_str(&serialized).unwrap();
assert_eq!(deserialized.payload, message.payload);
}
#[test]
fn test_message_priority_extremes() {
let min_priority_msg = Message {
id: "min-test".to_string(),
queue: "test".to_string(),
priority: Priority::Numeric(0),
payload: "min priority".to_string(),
created_at: Utc::now(),
locked_until: None,
locked_by: None,
retry_count: 0,
max_retries: 3,
payload_ref: None,
payload_hash: None,
};
let max_priority_msg = Message {
id: "max-test".to_string(),
queue: "test".to_string(),
priority: Priority::Numeric(u64::MAX),
payload: "max priority".to_string(),
created_at: Utc::now(),
locked_until: None,
locked_by: None,
retry_count: 0,
max_retries: 3,
payload_ref: None,
payload_hash: None,
};
assert_eq!(min_priority_msg.priority, Priority::Numeric(0));
assert_eq!(
max_priority_msg.priority,
Priority::Numeric(18_446_744_073_709_551_615)
);
let min_json = serde_json::to_string(&min_priority_msg).unwrap();
let max_json = serde_json::to_string(&max_priority_msg).unwrap();
let min_deserialized: Message = serde_json::from_str(&min_json).unwrap();
let max_deserialized: Message = serde_json::from_str(&max_json).unwrap();
assert_eq!(min_deserialized.priority, Priority::Numeric(0));
assert_eq!(max_deserialized.priority, Priority::Numeric(u64::MAX));
}
#[test]
fn test_message_retry_count_extremes() {
let high_retry_msg = Message {
id: "retry-test".to_string(),
queue: "test".to_string(),
priority: Priority::Numeric(100),
payload: "retry test".to_string(),
created_at: Utc::now(),
locked_until: None,
locked_by: None,
retry_count: u32::MAX,
max_retries: u32::MAX,
payload_ref: None,
payload_hash: None,
};
assert_eq!(high_retry_msg.retry_count, u32::MAX);
assert_eq!(high_retry_msg.max_retries, u32::MAX);
let json = serde_json::to_string(&high_retry_msg).unwrap();
let deserialized: Message = serde_json::from_str(&json).unwrap();
assert_eq!(deserialized.retry_count, u32::MAX);
assert_eq!(deserialized.max_retries, u32::MAX);
}
#[test]
fn test_priority_ordering_enum() {
let max_first = PriorityOrdering::MaxFirst;
let min_first = PriorityOrdering::MinFirst;
assert_ne!(max_first, min_first);
let max_json = serde_json::to_string(&max_first).unwrap();
let min_json = serde_json::to_string(&min_first).unwrap();
assert_eq!(max_json, "\"MaxFirst\"");
assert_eq!(min_json, "\"MinFirst\"");
let max_deserialized: PriorityOrdering = serde_json::from_str(&max_json).unwrap();
let min_deserialized: PriorityOrdering = serde_json::from_str(&min_json).unwrap();
assert_eq!(max_deserialized, PriorityOrdering::MaxFirst);
assert_eq!(min_deserialized, PriorityOrdering::MinFirst);
}
#[test]
fn test_priority_ordering_default() {
let default_ordering = PriorityOrdering::default();
assert_eq!(default_ordering, PriorityOrdering::MaxFirst);
}
#[test]
fn test_priority_ordering_debug_clone() {
let ordering = PriorityOrdering::MinFirst;
let cloned = ordering;
assert_eq!(ordering, cloned);
let debug_str = format!("{:?}", ordering);
assert!(debug_str.contains("MinFirst"));
}
#[test]
fn test_queue_config_creation() {
let max_config = QueueConfig {
ordering: PriorityOrdering::MaxFirst,
..Default::default()
};
let min_config = QueueConfig {
ordering: PriorityOrdering::MinFirst,
..Default::default()
};
assert_eq!(max_config.ordering, PriorityOrdering::MaxFirst);
assert_eq!(min_config.ordering, PriorityOrdering::MinFirst);
}
#[test]
fn test_queue_config_default() {
let default_config = QueueConfig::default();
assert_eq!(default_config.ordering, PriorityOrdering::MaxFirst);
}
#[test]
fn test_queue_config_serialization() {
let config = QueueConfig {
ordering: PriorityOrdering::MinFirst,
..Default::default()
};
let json = serde_json::to_string(&config).unwrap();
assert!(json.contains("MinFirst"));
let deserialized: QueueConfig = serde_json::from_str(&json).unwrap();
assert_eq!(deserialized.ordering, PriorityOrdering::MinFirst);
}
#[test]
fn test_queue_config_clone_debug() {
let original = QueueConfig {
ordering: PriorityOrdering::MaxFirst,
..Default::default()
};
let cloned = original.clone();
assert_eq!(cloned.ordering, original.ordering);
let debug_str = format!("{:?}", original);
assert!(debug_str.contains("QueueConfig"));
assert!(debug_str.contains("MaxFirst"));
}
#[test]
fn test_queue_config_with_different_orderings() {
let configs = vec![
QueueConfig {
ordering: PriorityOrdering::MaxFirst,
..Default::default()
},
QueueConfig {
ordering: PriorityOrdering::MinFirst,
..Default::default()
},
];
assert_ne!(configs[0].ordering, configs[1].ordering);
for config in configs {
let json = serde_json::to_string(&config).unwrap();
let deserialized: QueueConfig = serde_json::from_str(&json).unwrap();
assert_eq!(config.ordering, deserialized.ordering);
}
}
#[test]
fn test_priority_display() {
assert_eq!(format!("{}", Priority::Numeric(42)), "42");
assert_eq!(format!("{}", Priority::Text("high".to_string())), "high");
}
#[test]
fn test_priority_kind() {
assert_eq!(Priority::Numeric(0).kind(), PriorityKind::Numeric);
assert_eq!(Priority::Text("a".to_string()).kind(), PriorityKind::Text);
}
#[test]
fn test_priority_kind_default() {
assert_eq!(PriorityKind::default(), PriorityKind::Numeric);
}
#[test]
fn test_priority_default() {
assert_eq!(Priority::default(), Priority::Numeric(0));
}
#[test]
fn test_payload_ref_and_hash_serde_roundtrip() {
use qrusty::message::PayloadRef;
let msg = Message {
id: "serde-test".to_string(),
queue: "q".to_string(),
priority: Priority::Numeric(1),
payload: String::new(),
created_at: Utc::now(),
locked_until: None,
locked_by: None,
retry_count: 0,
max_retries: 3,
payload_ref: Some(PayloadRef {
file_id: 1,
offset: 100,
length: 50,
}),
payload_hash: Some([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]),
};
let json = serde_json::to_string(&msg).unwrap();
assert!(json.contains("payload_ref"));
assert!(json.contains("payload_hash"));
let deserialized: Message = serde_json::from_str(&json).unwrap();
assert_eq!(deserialized.payload_ref, msg.payload_ref);
assert_eq!(deserialized.payload_hash, msg.payload_hash);
}
#[test]
fn test_payload_ref_and_hash_omitted_when_none() {
let msg = Message {
id: "no-ref".to_string(),
queue: "q".to_string(),
priority: Priority::Numeric(1),
payload: "inline".to_string(),
created_at: Utc::now(),
locked_until: None,
locked_by: None,
retry_count: 0,
max_retries: 3,
payload_ref: None,
payload_hash: None,
};
let json = serde_json::to_string(&msg).unwrap();
assert!(!json.contains("payload_ref"));
assert!(!json.contains("payload_hash"));
let deserialized: Message = serde_json::from_str(&json).unwrap();
assert!(deserialized.payload_ref.is_none());
assert!(deserialized.payload_hash.is_none());
}