//! Shared helpers for integration tests. #![allow(dead_code)] use bb_core::orchestrator::{Orchestrator, OrchestratorConfig}; use bb_db::{BusserId, CreateFeedItem, CreateFeed, Database}; use chrono::{Duration, Utc}; use std::env::temp_dir; /// Build an `OrchestratorConfig` that uses in-memory SQLite and an empty /// temp directory for plugins. pub fn test_config(suffix: &str) -> OrchestratorConfig { let dir = temp_dir().join(format!("bb_cmd_test_{}", suffix)); let _ = std::fs::create_dir_all(&dir); OrchestratorConfig { database_url: "sqlite::memory:".to_string(), plugins_dir: dir.to_string_lossy().to_string(), fetch_interval_secs: 300, } } /// Create an Orchestrator with in-memory DB and run migrations. pub async fn setup(suffix: &str) -> Orchestrator { let config = test_config(suffix); let orchestrator = Orchestrator::new(config).await.unwrap(); orchestrator.migrate().await.unwrap(); orchestrator } /// Create a standalone in-memory Database and run migrations. pub async fn test_db() -> Database { let db = Database::connect("sqlite::memory:").await.unwrap(); db.migrate().await.unwrap(); db } /// Insert an RSS feed with the given name and URL config. pub async fn create_rss_feed(db: &Database, name: &str, feed_url: &str) -> bb_db::DbFeed { db.feeds() .create(CreateFeed { busser_id: BusserId::new("rss"), name: name.to_string(), config: serde_json::json!({ "feed_url": feed_url }), }) .await .unwrap() } /// Insert a non-RSS feed (e.g. "hn"). pub async fn create_other_feed(db: &Database, busser_id: &str, name: &str) -> bb_db::DbFeed { db.feeds() .create(CreateFeed { busser_id: BusserId::new(busser_id), name: name.to_string(), config: serde_json::json!({}), }) .await .unwrap() } /// Insert a feed item attached to a feed. pub async fn insert_item( db: &Database, feed: &bb_db::DbFeed, external_id: &str, title: &str, hours_ago: i64, ) -> bb_db::DbFeedItem { db.items() .upsert(CreateFeedItem { external_id: external_id.to_string(), feed_id: feed.id, busser_id: feed.busser_id.clone(), bite_author: "author".to_string(), bite_text: format!("Item {external_id}"), bite_secondary: None, bite_indicator: None, title: Some(title.to_string()), body: Some(format!("Body of {title}")), url: Some(format!("https://example.com/{external_id}")), media: vec![], published_at: Utc::now() - Duration::hours(hours_ago), source_name: "test".to_string(), score: None, tags: vec![], actions: vec![], }) .await .unwrap() }