use chrono::Utc; use sea_orm::ActiveValue::Set; use shanty_db::entities::wanted_item::{ItemType, WantedStatus}; use shanty_db::{Database, queries}; use shanty_watch::{add_album, add_artist, add_track, library_summary, list_items, remove_item}; async fn test_db() -> Database { Database::new("sqlite::memory:") .await .expect("failed to create test database") } /// Insert a fake track into the DB to simulate an indexed library. async fn insert_track(db: &Database, artist: &str, title: &str, album: &str) { let now = Utc::now().naive_utc(); let artist_rec = queries::artists::upsert(db.conn(), artist, None) .await .unwrap(); let album_rec = queries::albums::upsert(db.conn(), album, artist, None, Some(artist_rec.id)) .await .unwrap(); let active = shanty_db::entities::track::ActiveModel { file_path: Set(format!("/music/{artist}/{album}/{title}.mp3")), title: Set(Some(title.to_string())), artist: Set(Some(artist.to_string())), album: Set(Some(album.to_string())), album_artist: Set(Some(artist.to_string())), file_size: Set(1_000_000), artist_id: Set(Some(artist_rec.id)), album_id: Set(Some(album_rec.id)), added_at: Set(now), updated_at: Set(now), ..Default::default() }; queries::tracks::upsert(db.conn(), active).await.unwrap(); } #[tokio::test] async fn test_add_artist_wanted() { let db = test_db().await; let entry = add_artist(db.conn(), "Radiohead", None).await.unwrap(); assert_eq!(entry.item_type, ItemType::Artist); assert_eq!(entry.name, "Radiohead"); assert_eq!(entry.status, WantedStatus::Wanted); } #[tokio::test] async fn test_add_artist_auto_owned() { let db = test_db().await; // Index some tracks first insert_track(&db, "Pink Floyd", "Time", "DSOTM").await; // Add artist to watchlist — should auto-detect as owned let entry = add_artist(db.conn(), "Pink Floyd", None).await.unwrap(); assert_eq!(entry.status, WantedStatus::Owned); } #[tokio::test] async fn test_add_album_wanted() { let db = test_db().await; let entry = add_album(db.conn(), "Radiohead", "OK Computer", None) .await .unwrap(); assert_eq!(entry.item_type, ItemType::Album); assert_eq!(entry.name, "OK Computer"); assert_eq!(entry.status, WantedStatus::Wanted); } #[tokio::test] async fn test_add_album_auto_owned() { let db = test_db().await; insert_track(&db, "Pink Floyd", "Time", "DSOTM").await; let entry = add_album(db.conn(), "Pink Floyd", "DSOTM", None) .await .unwrap(); assert_eq!(entry.status, WantedStatus::Owned); } #[tokio::test] async fn test_add_track_wanted() { let db = test_db().await; let entry = add_track(db.conn(), "Radiohead", "Creep", None) .await .unwrap(); assert_eq!(entry.item_type, ItemType::Track); assert_eq!(entry.name, "Creep"); assert_eq!(entry.status, WantedStatus::Wanted); } #[tokio::test] async fn test_add_track_auto_owned() { let db = test_db().await; insert_track(&db, "Pink Floyd", "Time", "DSOTM").await; let entry = add_track(db.conn(), "Pink Floyd", "Time", None) .await .unwrap(); assert_eq!(entry.status, WantedStatus::Owned); } #[tokio::test] async fn test_list_items_with_filters() { let db = test_db().await; add_artist(db.conn(), "Radiohead", None).await.unwrap(); add_artist(db.conn(), "Tool", None).await.unwrap(); // List all let all = list_items(db.conn(), None, None).await.unwrap(); assert_eq!(all.len(), 2); // List by status let wanted = list_items(db.conn(), Some(WantedStatus::Wanted), None) .await .unwrap(); assert_eq!(wanted.len(), 2); let owned = list_items(db.conn(), Some(WantedStatus::Owned), None) .await .unwrap(); assert!(owned.is_empty()); // List by artist let radiohead = list_items(db.conn(), None, Some("Radiohead")) .await .unwrap(); assert_eq!(radiohead.len(), 1); assert_eq!(radiohead[0].name, "Radiohead"); } #[tokio::test] async fn test_remove_item() { let db = test_db().await; let entry = add_artist(db.conn(), "Radiohead", None).await.unwrap(); let all = list_items(db.conn(), None, None).await.unwrap(); assert_eq!(all.len(), 1); remove_item(db.conn(), entry.id).await.unwrap(); let all = list_items(db.conn(), None, None).await.unwrap(); assert!(all.is_empty()); } #[tokio::test] async fn test_library_summary() { let db = test_db().await; insert_track(&db, "Pink Floyd", "Time", "DSOTM").await; add_artist(db.conn(), "Radiohead", None).await.unwrap(); // wanted add_artist(db.conn(), "Pink Floyd", None).await.unwrap(); // owned add_album(db.conn(), "Tool", "Lateralus", None).await.unwrap(); // wanted add_track(db.conn(), "Pink Floyd", "Time", None).await.unwrap(); // owned let summary = library_summary(db.conn()).await.unwrap(); assert_eq!(summary.total_artists, 2); assert_eq!(summary.total_albums, 1); assert_eq!(summary.total_tracks, 1); assert_eq!(summary.wanted, 2); assert_eq!(summary.owned, 2); }