use robson_core::connect_and_migrate;
use robson_core::formatter::markdown_to_mrkdwn;
use robson_core::processor::{Processor, SanitizedInput};
use tracing_test::traced_test;
#[traced_test]
#[test]
fn test_scheduler_log_format_is_capturable() {
tracing::info!(interval_secs = 999u64, "scheduler started");
tracing::info!("scheduler received shutdown signal — stopping");
assert!(logs_contain("scheduler started"));
assert!(logs_contain("scheduler received shutdown signal"));
}
#[traced_test]
#[test]
fn test_command_log_format_is_capturable() {
tracing::debug!("run-task PROJ-99: no state available — returning guidance");
assert!(logs_contain("run-task PROJ-99"));
assert!(logs_contain("no state available"));
}
#[test]
fn test_markdown_to_mrkdwn_bold() {
assert_eq!(markdown_to_mrkdwn("**hello**"), "*hello*");
assert_eq!(markdown_to_mrkdwn("**hello** world"), "*hello* world");
}
#[test]
fn test_markdown_to_mrkdwn_code_block() {
let input = "```rust\nlet x = 1;\n```";
let out = markdown_to_mrkdwn(input);
assert!(out.contains("```"));
assert!(out.contains("let x = 1;"));
}
#[test]
fn test_markdown_to_mrkdwn_italic() {
assert_eq!(markdown_to_mrkdwn("__italic__"), "_italic_");
assert_eq!(markdown_to_mrkdwn("_italic_"), "_italic_");
}
#[test]
fn test_markdown_to_mrkdwn_unicode_preserved() {
let input = "**こんにちは** مرحبا";
let out = markdown_to_mrkdwn(input);
assert!(out.contains("*こんにちは*"));
assert!(out.contains("مرحبا"));
}
#[test]
fn test_markdown_to_mrkdwn_heading() {
assert_eq!(markdown_to_mrkdwn("### Heading"), "*Heading*");
assert_eq!(markdown_to_mrkdwn("## Heading"), "*Heading*");
assert_eq!(markdown_to_mrkdwn("# Heading"), "*Heading*");
}
#[tokio::test]
async fn test_processor_dispatch_message() {
let db = connect_and_migrate(":memory:").await.unwrap();
let processor = Processor::new(db);
let input = SanitizedInput::Message {
text: "hello, how are you?".to_string(),
channel_id: "C123".to_string(),
user_id: "U456".to_string(),
thread_ts: Some("ts1".to_string()),
ts: "ts2".to_string(),
};
let output = processor.dispatch(input).await.unwrap();
assert!(!output.response_text.is_empty());
}
#[tokio::test]
async fn test_processor_dispatch_slash_text_as_message() {
let db = connect_and_migrate(":memory:").await.unwrap();
let processor = Processor::new(db);
let input = SanitizedInput::Message {
text: "/help".to_string(),
channel_id: "C123".to_string(),
user_id: "U456".to_string(),
thread_ts: None,
ts: "ts1".to_string(),
};
let output = processor.dispatch(input).await.unwrap();
assert!(!output.response_text.is_empty());
}
#[tokio::test]
async fn test_processor_build_context_returns_last_n() {
let db = connect_and_migrate(":memory:").await.unwrap();
use robson_core::entities::conversation::{self, ConversationRole};
for i in 0..5 {
conversation::Model::insert(
&db,
None,
"C123",
"ts_thread",
"U1",
ConversationRole::User,
&format!("message {}", i),
)
.await
.unwrap();
tokio::time::sleep(std::time::Duration::from_millis(5)).await;
}
let processor = Processor::new(db);
let ctx = processor
.build_context("C123", "ts_thread", 3)
.await
.unwrap();
assert_eq!(ctx.len(), 3);
assert!(ctx[2].content.contains("message 4"));
}