test(lidarr): extract and cover the album row style branches
Row styling is invisible to the snapshot harness, because render_to_string_with_app returns a plain String and discards colour and modifiers. The album row style branch was therefore entirely uncovered, and any arm could be swapped for another without a single test noticing. decorate_album_row_with_style now holds that branch, matching decorate_artist_row_with_style in the library view and decorate_book_row_with_style in the Readarr author details view. The extraction is behaviour preserving: the branch is token identical to the one it replaces, and no snapshot changed. Verified by mutation. Against the previous tree all eight mutations left the suite green: replacing each of the unmonitored, downloaded, unreleased, both missing and indeterminate arms, flipping the track file count comparison, and inverting the monitored check. Against the new tests every one of those eight fails.
This commit is contained in:
2 files changed
+156
-28
No files matched your search
@@ -288,33 +288,18 @@ fn draw_albums_table(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) {
|
||||
.map_or(0f64, |s| convert_to_gb(s.size_on_disk));
|
||||
let duration_mins = album.duration / 60000;
|
||||
|
||||
let row = Row::new(vec![
|
||||
Cell::from(monitored.to_owned()),
|
||||
Cell::from(album.title.to_string()),
|
||||
Cell::from(album_type),
|
||||
Cell::from(track_count),
|
||||
Cell::from(format!("{duration_mins} min")),
|
||||
Cell::from(release_date),
|
||||
Cell::from(format!("{size:.2} GB")),
|
||||
]);
|
||||
|
||||
if !album.monitored {
|
||||
row.unmonitored()
|
||||
} else if let Some(stats) = album.statistics.as_ref() {
|
||||
if stats.track_file_count == stats.total_track_count && stats.total_track_count > 0 {
|
||||
row.downloaded()
|
||||
} else if let Some(release_date) = album.release_date.as_ref() {
|
||||
if release_date > &Utc::now() {
|
||||
row.unreleased()
|
||||
} else {
|
||||
row.missing()
|
||||
}
|
||||
} else {
|
||||
row.missing()
|
||||
}
|
||||
} else {
|
||||
row.indeterminate()
|
||||
}
|
||||
decorate_album_row_with_style(
|
||||
album,
|
||||
Row::new(vec![
|
||||
Cell::from(monitored.to_owned()),
|
||||
Cell::from(album.title.to_string()),
|
||||
Cell::from(album_type),
|
||||
Cell::from(track_count),
|
||||
Cell::from(format!("{duration_mins} min")),
|
||||
Cell::from(release_date),
|
||||
Cell::from(format!("{size:.2} GB")),
|
||||
]),
|
||||
)
|
||||
};
|
||||
|
||||
let is_searching = active_lidarr_block == ActiveLidarrBlock::SearchAlbums;
|
||||
@@ -350,6 +335,26 @@ fn draw_albums_table(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) {
|
||||
}
|
||||
}
|
||||
|
||||
fn decorate_album_row_with_style<'a>(album: &Album, row: Row<'a>) -> Row<'a> {
|
||||
if !album.monitored {
|
||||
row.unmonitored()
|
||||
} else if let Some(stats) = album.statistics.as_ref() {
|
||||
if stats.track_file_count == stats.total_track_count && stats.total_track_count > 0 {
|
||||
row.downloaded()
|
||||
} else if let Some(release_date) = album.release_date.as_ref() {
|
||||
if release_date > &Utc::now() {
|
||||
row.unreleased()
|
||||
} else {
|
||||
row.missing()
|
||||
}
|
||||
} else {
|
||||
row.missing()
|
||||
}
|
||||
} else {
|
||||
row.indeterminate()
|
||||
}
|
||||
}
|
||||
|
||||
fn draw_artist_history_table(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) {
|
||||
if !app.is_loading {
|
||||
let current_selection = if app.data.lidarr_data.artist_history.is_empty() {
|
||||
|
||||
@@ -1,13 +1,20 @@
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use chrono::{Duration, Utc};
|
||||
use pretty_assertions::assert_eq;
|
||||
use ratatui::widgets::{Cell, Row};
|
||||
use strum::IntoEnumIterator;
|
||||
|
||||
use crate::models::lidarr_models::{Album, AlbumStatistics};
|
||||
use crate::models::servarr_data::lidarr::lidarr_data::{
|
||||
ALBUM_DETAILS_BLOCKS, ARTIST_DETAILS_BLOCKS, ARTIST_OVERVIEW_BLOCKS, ActiveLidarrBlock,
|
||||
DELETE_ALBUM_BLOCKS, TRACK_DETAILS_BLOCKS,
|
||||
};
|
||||
use crate::ui::DrawUi;
|
||||
use crate::ui::lidarr_ui::library::artist_details_ui::ArtistDetailsUi;
|
||||
use crate::ui::lidarr_ui::library::artist_details_ui::{
|
||||
ArtistDetailsUi, decorate_album_row_with_style,
|
||||
};
|
||||
use crate::ui::styles::ManagarrStyle;
|
||||
|
||||
#[test]
|
||||
fn test_artist_details_ui_accepts() {
|
||||
@@ -26,6 +33,122 @@ mod tests {
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_decorate_album_row_with_style_unmonitored() {
|
||||
let album = Album::default();
|
||||
let row = Row::new(vec![Cell::from("test".to_owned())]);
|
||||
|
||||
let style = decorate_album_row_with_style(&album, row.clone());
|
||||
|
||||
assert_eq!(style, row.unmonitored());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_decorate_album_row_with_style_downloaded_when_all_tracks_present() {
|
||||
let album = Album {
|
||||
monitored: true,
|
||||
statistics: Some(AlbumStatistics {
|
||||
track_file_count: 3,
|
||||
total_track_count: 3,
|
||||
..AlbumStatistics::default()
|
||||
}),
|
||||
..Album::default()
|
||||
};
|
||||
let row = Row::new(vec![Cell::from("test".to_owned())]);
|
||||
|
||||
let style = decorate_album_row_with_style(&album, row.clone());
|
||||
|
||||
assert_eq!(style, row.downloaded());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_decorate_album_row_with_style_unreleased_when_tracks_are_missing_and_release_date_is_future()
|
||||
{
|
||||
let album = Album {
|
||||
monitored: true,
|
||||
release_date: Some(Utc::now() + Duration::days(1)),
|
||||
statistics: Some(AlbumStatistics {
|
||||
track_file_count: 0,
|
||||
total_track_count: 3,
|
||||
..AlbumStatistics::default()
|
||||
}),
|
||||
..Album::default()
|
||||
};
|
||||
let row = Row::new(vec![Cell::from("test".to_owned())]);
|
||||
|
||||
let style = decorate_album_row_with_style(&album, row.clone());
|
||||
|
||||
assert_eq!(style, row.unreleased());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_decorate_album_row_with_style_missing_when_tracks_are_missing_and_release_date_has_passed()
|
||||
{
|
||||
let album = Album {
|
||||
monitored: true,
|
||||
release_date: Some(Utc::now() - Duration::days(1)),
|
||||
statistics: Some(AlbumStatistics {
|
||||
track_file_count: 1,
|
||||
total_track_count: 3,
|
||||
..AlbumStatistics::default()
|
||||
}),
|
||||
..Album::default()
|
||||
};
|
||||
let row = Row::new(vec![Cell::from("test".to_owned())]);
|
||||
|
||||
let style = decorate_album_row_with_style(&album, row.clone());
|
||||
|
||||
assert_eq!(style, row.missing());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_decorate_album_row_with_style_missing_when_tracks_are_missing_and_no_release_date() {
|
||||
let album = Album {
|
||||
monitored: true,
|
||||
release_date: None,
|
||||
statistics: Some(AlbumStatistics {
|
||||
track_file_count: 1,
|
||||
total_track_count: 3,
|
||||
..AlbumStatistics::default()
|
||||
}),
|
||||
..Album::default()
|
||||
};
|
||||
let row = Row::new(vec![Cell::from("test".to_owned())]);
|
||||
|
||||
let style = decorate_album_row_with_style(&album, row.clone());
|
||||
|
||||
assert_eq!(style, row.missing());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_decorate_album_row_with_style_missing_when_total_track_count_is_zero() {
|
||||
let album = Album {
|
||||
monitored: true,
|
||||
release_date: Some(Utc::now() - Duration::days(1)),
|
||||
statistics: Some(AlbumStatistics::default()),
|
||||
..Album::default()
|
||||
};
|
||||
let row = Row::new(vec![Cell::from("test".to_owned())]);
|
||||
|
||||
let style = decorate_album_row_with_style(&album, row.clone());
|
||||
|
||||
assert_eq!(style, row.missing());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_decorate_album_row_with_style_indeterminate_when_no_statistics() {
|
||||
let album = Album {
|
||||
monitored: true,
|
||||
statistics: None,
|
||||
..Album::default()
|
||||
};
|
||||
let row = Row::new(vec![Cell::from("test".to_owned())]);
|
||||
|
||||
let style = decorate_album_row_with_style(&album, row.clone());
|
||||
|
||||
assert_eq!(style, row.indeterminate());
|
||||
}
|
||||
|
||||
mod snapshot_tests {
|
||||
use pretty_assertions::assert_str_eq;
|
||||
use rstest::rstest;
|
||||
|
||||
Reference in new issue
Block a user