test: Wrote snapshot tests for all Sonarr UI

This commit is contained in:
2025-12-16 14:12:10 -07:00
parent e0fcbc71e1
commit 0532d59746
257 changed files with 8089 additions and 1029 deletions
@@ -58,7 +58,12 @@ mod tests {
CollectionsUi::draw(f, app, f.area());
});
insta::assert_snapshot!(output);
insta::assert_snapshot!(
format!(
"is_loading_{is_loading}_empty_movies_{empty_movies}_empty_profile_{empty_profile_map}"
),
output
);
}
#[rstest]
@@ -81,7 +86,7 @@ mod tests {
CollectionsUi::draw(f, app, f.area());
});
insta::assert_snapshot!(active_radarr_block.to_string(), output);
insta::assert_snapshot!(format!("collections_tab_{active_radarr_block}"), output);
}
#[test]
@@ -141,7 +146,7 @@ mod tests {
insta::assert_snapshot!(
format!(
"{}_{}",
"edit_collection_modal_{}_{}",
active_radarr_block.to_string(),
context_block.to_string()
),
+2 -2
View File
@@ -82,7 +82,7 @@ mod tests {
LibraryUi::draw(f, app, f.area());
});
insta::assert_snapshot!(active_radarr_block.to_string(), output);
insta::assert_snapshot!(format!("library_tab_{active_radarr_block}"), output);
}
#[rstest]
@@ -109,7 +109,7 @@ mod tests {
LibraryUi::draw(f, app, f.area());
});
insta::assert_snapshot!(active_radarr_block.to_string(), output);
insta::assert_snapshot!(format!("add_movie_ui_{active_radarr_block}"), output);
}
#[test]
@@ -0,0 +1,54 @@
---
source: src/ui/radarr_ui/system/system_ui_tests.rs
expression: output
---
╭ Tasks ────────────────────────────────────────────────────────────────────────╮╭ Queued Events ───────────────────────────────────────────────────────────────╮
│Name Interval Last Execution Last Duration Next Execution ││Trigger Status Name Queued Started Duration │
│Backup 1 hour now 00:00:17 59 minutes ││manual completed Refresh Monitored D 4 minutes ago 4 minutes a 00:03:03 │
│ ││ │
│ ││ │
│ ││ │
│ ╭ Log Details ───────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │
│ │2025-12-15 16:14:45 UTC|INFO|DownloadDecisionMaker|Processing 545 releases │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
╰───────────────────│ │────────────────────╯
╭ Logs ───────────│ │────────────────────╮
│2025-12-15 16:14:45│ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │
│ │
│ │
│ │
│ │
│ │
╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
@@ -0,0 +1,54 @@
---
source: src/ui/radarr_ui/system/system_ui_tests.rs
expression: output
---
╭ Tasks ────────────────────────────────────────────────────────────────────────╮╭ Queued Events ───────────────────────────────────────────────────────────────╮
│Name Interval Last Execution Last Duration Next Execution ││Trigger Status Name Queued Started Duration │
│Backup 1 hour now 00:00:17 59 minutes ││manual completed Refresh Monitored D 4 minutes ago 4 minutes a 00:03:03 │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ╭ Queued Events ────────────────────────────────────────────────────────────────────────────────╮ │
│ │Trigger Status Name Queued Started Duration │ │
│ │manual completed Refresh Monitored Downlo 4 minutes ago 4 minutes ago 00:03:03 │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
╰────────────────────────────────│ │────────────────────────────────╯
╭ Logs ────────────────────────│ │────────────────────────────────╮
│2025-12-15 16:14:45 UTC|INFO|Dow│ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ ╰─────────────────────────────────────────────────────────────────────────────────────────────────╯ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
@@ -0,0 +1,54 @@
---
source: src/ui/radarr_ui/system/system_ui_tests.rs
expression: output
---
╭ Tasks ────────────────────────────────────────────────────────────────────────╮╭ Queued Events ───────────────────────────────────────────────────────────────╮
│Name Interval Last Execution Last Duration Next Execution ││Trigger Status Name Queued Started Duration │
│Backup 1 hour now 00:00:17 59 minutes ││manual completed Refresh Monitored D 4 minutes ago 4 minutes a 00:03:03 │
│ ││ │
│ ││ │
│ ││ │
│ ╭ Tasks ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │
│ │ Name Interval Last Execution Last Duration Next Execution │ │
│ │=> Backup 1 hour now 00:00:17 59 minutes │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ ╭────────────────────── Start Task ───────────────────────╮ │ │
│ │ │ Do you want to manually start this task: Backup? │ │ │
│ │ │ │ │ │
│ │ │ │ │ │
│ │ │ │ │ │
│ │ │ │ │ │
│ │ │ │ │ │
│ │ │ │ │ │
╰───────────────────│ │ │ │────────────────────╯
╭ Logs ───────────│ │ │ │────────────────────╮
│2025-12-15 16:14:45│ │ │ │ │
│ │ │ │ │ │
│ │ │ │ │ │
│ │ │ │ │ │
│ │ │╭────────────────────────────╮╭───────────────────────────╮│ │ │
│ │ ││ Yes ││ No ││ │ │
│ │ │╰────────────────────────────╯╰───────────────────────────╯│ │ │
│ │ ╰───────────────────────────────────────────────────────────╯ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │
│ │
│ │
│ │
│ │
│ │
╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
@@ -0,0 +1,54 @@
---
source: src/ui/radarr_ui/system/system_ui_tests.rs
expression: output
---
╭ Tasks ────────────────────────────────────────────────────────────────────────╮╭ Queued Events ───────────────────────────────────────────────────────────────╮
│Name Interval Last Execution Last Duration Next Execution ││Trigger Status Name Queued Started Duration │
│Backup 1 hour now 00:00:17 59 minutes ││manual completed Refresh Monitored D 4 minutes ago 4 minutes a 00:03:03 │
│ ││ │
│ ││ │
│ ││ │
│ ╭ Tasks ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │
│ │ Name Interval Last Execution Last Duration Next Execution │ │
│ │=> Backup 1 hour now 00:00:17 59 minutes │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
╰───────────────────│ │────────────────────╯
╭ Logs ───────────│ │────────────────────╮
│2025-12-15 16:14:45│ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │
│ │
│ │
│ │
│ │
│ │
╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
@@ -0,0 +1,54 @@
---
source: src/ui/radarr_ui/system/system_ui_tests.rs
expression: output
---
╭ Tasks ────────────────────────────────────────────────────────────────────────╮╭ Queued Events ───────────────────────────────────────────────────────────────╮
│Name Interval Last Execution Last Duration Next Execution ││Trigger Status Name Queued Started Duration │
│Backup 1 hour now 00:00:17 59 minutes ││manual completed Refresh Monitored D 4 minutes ago 4 minutes a 00:03:03 │
│ ││ │
│ ││ │
│ ││ │
│ ╭ Updates ───────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │
│ │The latest version of Radarr is already installed │ │
│ │ │ │
│ │4.3.2.1 - 2023-04-15 02:02:53 UTC (Currently Installed) │ │
│ │--------------------------------------------------------------------------------------------------------------------------│ │
│ │New: │ │
│ │ * Cool new thing │ │
│ │Fixed: │ │
│ │ * Some bugs killed │ │
│ │ │ │
│ │ │ │
│ │3.2.1.0 - 2023-04-15 02:02:53 UTC (Previously Installed) │ │
│ │--------------------------------------------------------------------------------------------------------------------------│ │
│ │New: │ │
│ │ * Cool new thing (old) │ │
│ │ * Other cool new thing (old) │ │
│ │ │ │
│ │ │ │
╰───────────────────│2.1.0 - 2023-04-15 02:02:53 UTC │────────────────────╯
╭ Logs ───────────│--------------------------------------------------------------------------------------------------------------------------│────────────────────╮
│2025-12-15 16:14:45│Fixed: │ │
│ │ * Killed bug 1 │ │
│ │ * Fixed bug 2 │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │
│ │
│ │
│ │
│ │
│ │
╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
@@ -27,7 +27,7 @@ mod tests {
use rstest::rstest;
#[rstest]
fn test_system_details_ui_renders_tasks(
fn test_system_details_ui_renders_popups(
#[values(
ActiveRadarrBlock::SystemLogs,
ActiveRadarrBlock::SystemQueuedEvents,
@@ -29,6 +29,7 @@ mod tests {
use super::*;
use crate::models::stateful_list::StatefulList;
use crate::models::stateful_table::StatefulTable;
use rstest::rstest;
#[test]
fn test_radarr_ui_renders_system_tab_loading() {
@@ -98,5 +99,29 @@ mod tests {
insta::assert_snapshot!(output);
}
#[rstest]
fn test_system_details_ui_renders_popups_over_system_tab(
#[values(
ActiveRadarrBlock::SystemLogs,
ActiveRadarrBlock::SystemQueuedEvents,
ActiveRadarrBlock::SystemTasks,
ActiveRadarrBlock::SystemTaskStartConfirmPrompt,
ActiveRadarrBlock::SystemUpdates
)]
active_radarr_block: ActiveRadarrBlock,
) {
let mut app = App::test_default_fully_populated();
app.push_navigation_stack(active_radarr_block.into());
let output = render_to_string_with_app(TerminalSize::Large, &mut app, |f, app| {
SystemUi::draw(f, app, f.area());
});
insta::assert_snapshot!(
format!("system_details_over_system_tab_{active_radarr_block}"),
output
);
}
}
}
@@ -4,8 +4,6 @@ mod tests {
use crate::app::App;
use crate::models::servarr_data::sonarr::sonarr_data::{ActiveSonarrBlock, BLOCKLIST_BLOCKS};
use crate::models::sonarr_models::BlocklistItem;
use crate::models::stateful_table::StatefulTable;
use crate::ui::DrawUi;
use crate::ui::sonarr_ui::blocklist::BlocklistUi;
use crate::ui::ui_test_utils::test_utils::render_to_string_with_app;
@@ -23,11 +21,12 @@ mod tests {
mod snapshot_tests {
use crate::ui::ui_test_utils::test_utils::TerminalSize;
use rstest::rstest;
use super::*;
#[test]
fn test_blocklist_ui_renders_loading_state() {
fn test_blocklist_ui_renders_loading() {
let mut app = App::test_default();
app.is_loading = true;
app.push_navigation_stack(ActiveSonarrBlock::Blocklist.into());
@@ -40,10 +39,9 @@ mod tests {
}
#[test]
fn test_blocklist_ui_renders_empty_blocklist() {
fn test_blocklist_ui_renders_empty() {
let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::Blocklist.into());
app.data.sonarr_data.blocklist = StatefulTable::default();
let output = render_to_string_with_app(TerminalSize::Large, &mut app, |f, app| {
BlocklistUi::draw(f, app, f.area());
@@ -52,29 +50,25 @@ mod tests {
insta::assert_snapshot!(output);
}
#[test]
fn test_blocklist_ui_renders_with_blocklist_items() {
let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::Blocklist.into());
app.data.sonarr_data.blocklist = StatefulTable::default();
app.data.sonarr_data.blocklist.set_items(vec![
BlocklistItem {
id: 1,
source_title: "Test.Series.S01E01.1080p".to_owned(),
..BlocklistItem::default()
},
BlocklistItem {
id: 2,
source_title: "Another.Series.S02E05.720p".to_owned(),
..BlocklistItem::default()
},
]);
#[rstest]
fn test_blocklist_ui_renders(
#[values(
ActiveSonarrBlock::Blocklist,
ActiveSonarrBlock::BlocklistItemDetails,
ActiveSonarrBlock::DeleteBlocklistItemPrompt,
ActiveSonarrBlock::BlocklistClearAllItemsPrompt,
ActiveSonarrBlock::BlocklistSortPrompt
)]
active_sonarr_block: ActiveSonarrBlock,
) {
let mut app = App::test_default_fully_populated();
app.push_navigation_stack(active_sonarr_block.into());
let output = render_to_string_with_app(TerminalSize::Large, &mut app, |f, app| {
BlocklistUi::draw(f, app, f.area());
});
insta::assert_snapshot!(output);
insta::assert_snapshot!(format!("blocklist_tab_{active_sonarr_block}"), output);
}
}
}
@@ -3,6 +3,5 @@ source: src/ui/sonarr_ui/blocklist/blocklist_ui_tests.rs
expression: output
---
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Series Title Source Title Language Quality Date
=> Test.Series.S01E01.1080p 1970-01-01 00:00:00 UTC
Another.Series.S02E05.720p 1970-01-01 00:00:00 UTC
Series Title Source Title Language Quality Date
=> Test Series Test Source Title English Bluray-1080p 2024-02-10 07:28:45 UTC
@@ -0,0 +1,34 @@
---
source: src/ui/sonarr_ui/blocklist/blocklist_ui_tests.rs
expression: output
---
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Series Title ▼ Source Title Language Quality Date
=> Test Series Test Source Title English Bluray-1080p 2024-02-10 07:28:45 UTC
╭────── Clear Blocklist ──────╮
│ Do you want to clear your │
│ blocklist? │
│ │
│ │
│ │
│╭──────────────╮╭─────────────╮│
││ Yes ││ No ││
│╰──────────────╯╰─────────────╯│
╰───────────────────────────────╯
@@ -0,0 +1,34 @@
---
source: src/ui/sonarr_ui/blocklist/blocklist_ui_tests.rs
expression: output
---
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Series Title ▼ Source Title Language Quality Date
=> Test Series Test Source Title English Bluray-1080p 2024-02-10 07:28:45 UTC
╭─────────────────────────────────── Details ───────────────────────────────────╮
│Name: Test Source Title │
│Protocol: usenet │
│Indexer: NZBgeek (Prowlarr) │
│Message: test message │
│ │
│ │
│ │
│ │
╰─────────────────────────────────────────────────────────────────────────────────╯
@@ -0,0 +1,42 @@
---
source: src/ui/sonarr_ui/blocklist/blocklist_ui_tests.rs
expression: output
---
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Series Title Source Title Language Quality Date
=> Test Series Test Source Title English Bluray-1080p 2024-02-10 07:28:45 UTC
╭───────────────────────────────╮
│Something │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
╰───────────────────────────────╯
@@ -0,0 +1,38 @@
---
source: src/ui/sonarr_ui/blocklist/blocklist_ui_tests.rs
expression: output
---
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Series Title ▼ Source Title Language Quality Date
=> Test Series Test Source Title English Bluray-1080p 2024-02-10 07:28:45 UTC
╭────────────── Remove Item from Blocklist ───────────────╮
│ Do you want to remove this item from your blocklist: │
│ Test Source Title? │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│╭────────────────────────────╮╭───────────────────────────╮│
││ Yes ││ No ││
│╰────────────────────────────╯╰───────────────────────────╯│
╰───────────────────────────────────────────────────────────╯
@@ -4,8 +4,6 @@ mod tests {
use crate::app::App;
use crate::models::servarr_data::sonarr::sonarr_data::{ActiveSonarrBlock, DOWNLOADS_BLOCKS};
use crate::models::sonarr_models::DownloadRecord;
use crate::models::stateful_table::StatefulTable;
use crate::ui::DrawUi;
use crate::ui::sonarr_ui::downloads::DownloadsUi;
use crate::ui::ui_test_utils::test_utils::render_to_string_with_app;
@@ -23,11 +21,12 @@ mod tests {
mod snapshot_tests {
use crate::ui::ui_test_utils::test_utils::TerminalSize;
use rstest::rstest;
use super::*;
#[test]
fn test_downloads_ui_renders_loading_state() {
fn test_downloads_ui_renders_loading() {
let mut app = App::test_default();
app.is_loading = true;
app.push_navigation_stack(ActiveSonarrBlock::Downloads.into());
@@ -43,7 +42,6 @@ mod tests {
fn test_downloads_ui_renders_empty_downloads() {
let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::Downloads.into());
app.data.sonarr_data.downloads = StatefulTable::default();
let output = render_to_string_with_app(TerminalSize::Large, &mut app, |f, app| {
DownloadsUi::draw(f, app, f.area());
@@ -52,35 +50,23 @@ mod tests {
insta::assert_snapshot!(output);
}
#[test]
fn test_downloads_ui_renders_with_downloads() {
let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::Downloads.into());
app.data.sonarr_data.downloads = StatefulTable::default();
app.data.sonarr_data.downloads.set_items(vec![
DownloadRecord {
id: 1,
title: "Test Series Download".to_owned(),
status: Default::default(),
size: 1024.0 * 1024.0 * 1024.0,
sizeleft: 512.0 * 1024.0 * 1024.0,
..DownloadRecord::default()
},
DownloadRecord {
id: 2,
title: "Another Series Download".to_owned(),
status: Default::default(),
size: 2048.0 * 1024.0 * 1024.0,
sizeleft: 0.0,
..DownloadRecord::default()
},
]);
#[rstest]
fn test_downloads_ui_renders(
#[values(
ActiveSonarrBlock::Downloads,
ActiveSonarrBlock::DeleteDownloadPrompt,
ActiveSonarrBlock::UpdateDownloadsPrompt
)]
active_sonarr_block: ActiveSonarrBlock,
) {
let mut app = App::test_default_fully_populated();
app.push_navigation_stack(active_sonarr_block.into());
let output = render_to_string_with_app(TerminalSize::Large, &mut app, |f, app| {
DownloadsUi::draw(f, app, f.area());
});
insta::assert_snapshot!(output);
insta::assert_snapshot!(format!("downloads_ui_{active_sonarr_block}"), output);
}
}
}
@@ -0,0 +1,38 @@
---
source: src/ui/sonarr_ui/downloads/downloads_ui_tests.rs
expression: output
---
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Title Percent Complete Size Output Path Indexer Download Client
=> Test Download Title 50% 3.30 GB /nfs/tv/Test show/season 1/ kickass torrents transmission
╭──────────────────── Cancel Download ────────────────────╮
│ Do you really want to delete this download: │
│ Test Download Title? │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│╭────────────────────────────╮╭───────────────────────────╮│
││ Yes ││ No ││
│╰────────────────────────────╯╰───────────────────────────╯│
╰───────────────────────────────────────────────────────────╯
@@ -4,5 +4,4 @@ expression: output
---
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Title Percent Complete Size Output Path Indexer Download Client
=> Test Series Download 50% 1.00 GB
Another Series Download 100% 2.00 GB
=> Test Download Title 50% 3.30 GB /nfs/tv/Test show/season 1/ kickass torrents transmission
@@ -0,0 +1,38 @@
---
source: src/ui/sonarr_ui/downloads/downloads_ui_tests.rs
expression: output
---
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Title Percent Complete Size Output Path Indexer Download Client
=> Test Download Title 50% 3.30 GB /nfs/tv/Test show/season 1/ kickass torrents transmission
╭─────────────────── Update Downloads ────────────────────╮
│ Do you want to update your downloads? │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│╭────────────────────────────╮╭───────────────────────────╮│
││ Yes ││ No ││
│╰────────────────────────────╯╰───────────────────────────╯│
╰───────────────────────────────────────────────────────────╯
+25 -26
View File
@@ -4,8 +4,6 @@ mod tests {
use crate::app::App;
use crate::models::servarr_data::sonarr::sonarr_data::{ActiveSonarrBlock, HISTORY_BLOCKS};
use crate::models::sonarr_models::SonarrHistoryItem;
use crate::models::stateful_table::StatefulTable;
use crate::ui::DrawUi;
use crate::ui::sonarr_ui::history::HistoryUi;
use crate::ui::ui_test_utils::test_utils::render_to_string_with_app;
@@ -23,11 +21,12 @@ mod tests {
mod snapshot_tests {
use crate::ui::ui_test_utils::test_utils::TerminalSize;
use rstest::rstest;
use super::*;
#[test]
fn test_history_ui_renders_loading_state() {
fn test_history_ui_renders_loading() {
let mut app = App::test_default();
app.is_loading = true;
app.push_navigation_stack(ActiveSonarrBlock::History.into());
@@ -39,42 +38,42 @@ mod tests {
insta::assert_snapshot!(output);
}
#[test]
fn test_history_ui_renders_empty_history() {
#[rstest]
fn test_history_ui_renders_empty(
#[values(ActiveSonarrBlock::History, ActiveSonarrBlock::HistoryItemDetails)]
active_sonarr_block: ActiveSonarrBlock,
) {
let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::History.into());
app.data.sonarr_data.history = StatefulTable::default();
app.push_navigation_stack(active_sonarr_block.into());
let output = render_to_string_with_app(TerminalSize::Large, &mut app, |f, app| {
HistoryUi::draw(f, app, f.area());
});
insta::assert_snapshot!(output);
insta::assert_snapshot!(format!("loading_history_tab_{active_sonarr_block}"), output);
}
#[test]
fn test_history_ui_renders_with_history_items() {
let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::History.into());
app.data.sonarr_data.history = StatefulTable::default();
app.data.sonarr_data.history.set_items(vec![
SonarrHistoryItem {
id: 1,
source_title: "Test.Series.S01E01".to_owned().into(),
..SonarrHistoryItem::default()
},
SonarrHistoryItem {
id: 2,
source_title: "Another.Series.S02E05".to_owned().into(),
..SonarrHistoryItem::default()
},
]);
#[rstest]
fn test_history_ui_renders(
#[values(
ActiveSonarrBlock::History,
ActiveSonarrBlock::HistoryItemDetails,
ActiveSonarrBlock::HistorySortPrompt,
ActiveSonarrBlock::FilterHistory,
ActiveSonarrBlock::FilterHistoryError,
ActiveSonarrBlock::SearchHistory,
ActiveSonarrBlock::SearchHistoryError
)]
active_sonarr_block: ActiveSonarrBlock,
) {
let mut app = App::test_default_fully_populated();
app.push_navigation_stack(active_sonarr_block.into());
let output = render_to_string_with_app(TerminalSize::Large, &mut app, |f, app| {
HistoryUi::draw(f, app, f.area());
});
insta::assert_snapshot!(output);
insta::assert_snapshot!(format!("history_tab_{active_sonarr_block}"), output);
}
}
}
@@ -0,0 +1,28 @@
---
source: src/ui/sonarr_ui/history/history_ui_tests.rs
expression: output
---
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Source Title ▼ Event Type Language Quality Date
=> Test source grabbed English Bluray-1080p 2024-02-10 07:28:45 UTC
╭───────────────── Filter ──────────────────╮
│test filter │
╰─────────────────────────────────────────────╯
@@ -0,0 +1,31 @@
---
source: src/ui/sonarr_ui/history/history_ui_tests.rs
expression: output
---
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Source Title ▼ Event Type Language Quality Date
=> Test source grabbed English Bluray-1080p 2024-02-10 07:28:45 UTC
╭─────────────── Error ───────────────╮
│The given filter produced empty results│
│ │
╰───────────────────────────────────────╯
@@ -3,6 +3,5 @@ source: src/ui/sonarr_ui/history/history_ui_tests.rs
expression: output
---
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Source Title Event Type Language Quality Date
=> Test.Series.S01E01 unknown 1970-01-01 00:00:00 UTC
Another.Series.S02E05 unknown 1970-01-01 00:00:00 UTC
Source Title Event Type Language Quality Date
=> Test source grabbed English Bluray-1080p 2024-02-10 07:28:45 UTC
@@ -0,0 +1,34 @@
---
source: src/ui/sonarr_ui/history/history_ui_tests.rs
expression: output
---
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Source Title ▼ Event Type Language Quality Date
=> Test source grabbed English Bluray-1080p 2024-02-10 07:28:45 UTC
╭─────────────────────────────────── Details ───────────────────────────────────╮
│Source Title: Test source │
│Indexer: │
│Release Group: │
│Series Match Type: │
│NZB Info URL: │
│Download Client Name: │
│Age: 0 days │
│Published Date: 1970-01-01 00:00:00 UTC │
╰─────────────────────────────────────────────────────────────────────────────────╯
@@ -0,0 +1,42 @@
---
source: src/ui/sonarr_ui/history/history_ui_tests.rs
expression: output
---
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Source Title Event Type Language Quality Date
=> Test source grabbed English Bluray-1080p 2024-02-10 07:28:45 UTC
╭───────────────────────────────╮
│Something │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
╰───────────────────────────────╯
@@ -0,0 +1,28 @@
---
source: src/ui/sonarr_ui/history/history_ui_tests.rs
expression: output
---
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Source Title ▼ Event Type Language Quality Date
=> Test source grabbed English Bluray-1080p 2024-02-10 07:28:45 UTC
╭───────────────── Search ──────────────────╮
│test search │
╰─────────────────────────────────────────────╯
@@ -0,0 +1,31 @@
---
source: src/ui/sonarr_ui/history/history_ui_tests.rs
expression: output
---
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Source Title ▼ Event Type Language Quality Date
=> Test source grabbed English Bluray-1080p 2024-02-10 07:28:45 UTC
╭─────────────── Error ───────────────╮
│ No items found matching search │
│ │
╰───────────────────────────────────────╯
@@ -0,0 +1,34 @@
---
source: src/ui/sonarr_ui/history/history_ui_tests.rs
expression: output
---
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
╭─────────────────────────────────── Details ───────────────────────────────────╮
│Source Title: │
│ │
│No additional data available │
│ │
│ │
│ │
│ │
│ │
╰─────────────────────────────────────────────────────────────────────────────────╯
@@ -4,16 +4,13 @@ mod tests {
use crate::app::App;
use crate::models::BlockSelectionState;
use crate::models::servarr_data::modals::EditIndexerModal;
use crate::models::servarr_data::sonarr::sonarr_data::{
ActiveSonarrBlock, EDIT_INDEXER_BLOCKS, EDIT_INDEXER_TORRENT_SELECTION_BLOCKS,
};
use crate::models::servarr_models::{Indexer, IndexerField};
use crate::models::stateful_table::StatefulTable;
use crate::models::servarr_models::Indexer;
use crate::ui::DrawUi;
use crate::ui::sonarr_ui::indexers::edit_indexer_ui::EditIndexerUi;
use crate::ui::ui_test_utils::test_utils::render_to_string_with_app;
use serde_json::json;
#[test]
fn test_edit_indexer_ui_accepts() {
@@ -27,39 +24,52 @@ mod tests {
}
mod snapshot_tests {
use crate::models::servarr_data::sonarr::sonarr_data::EDIT_INDEXER_NZB_SELECTION_BLOCKS;
use crate::network::sonarr_network::sonarr_network_test_utils::test_utils::indexer;
use crate::ui::ui_test_utils::test_utils::TerminalSize;
use super::*;
#[test]
fn test_edit_indexer_ui_renders_edit_indexer_modal() {
let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::EditIndexerNameInput.into());
app.data.sonarr_data.indexers = StatefulTable::default();
app.data.sonarr_data.indexers.set_items(vec![Indexer {
id: 1,
name: Some("Test Indexer".to_owned()),
enable_rss: true,
priority: 25,
fields: Some(vec![
IndexerField {
name: Some("baseUrl".to_owned()),
value: Some(json!("https://test.indexer.com")),
},
IndexerField {
name: Some("apiKey".to_owned()),
value: Some(json!("test-api-key")),
},
IndexerField {
name: Some("seedCriteria.seedRatio".to_owned()),
value: Some(json!(1.0)),
},
]),
..Indexer::default()
}]);
fn test_edit_indexer_ui_renders_loading() {
let mut app = App::test_default_fully_populated();
app.is_loading = true;
app.data.sonarr_data.edit_indexer_modal = None;
app.push_navigation_stack(ActiveSonarrBlock::EditIndexerPrompt.into());
app.data.sonarr_data.selected_block =
BlockSelectionState::new(EDIT_INDEXER_TORRENT_SELECTION_BLOCKS);
app.data.sonarr_data.edit_indexer_modal = Some(EditIndexerModal::from(&app.data.sonarr_data));
let output = render_to_string_with_app(TerminalSize::Large, &mut app, |f, app| {
EditIndexerUi::draw(f, app, f.area());
});
insta::assert_snapshot!(output);
}
#[test]
fn test_edit_indexer_ui_renders_edit_torrent_indexer() {
let mut app = App::test_default_fully_populated();
app.push_navigation_stack(ActiveSonarrBlock::EditIndexerPrompt.into());
app.data.sonarr_data.selected_block =
BlockSelectionState::new(EDIT_INDEXER_TORRENT_SELECTION_BLOCKS);
let output = render_to_string_with_app(TerminalSize::Large, &mut app, |f, app| {
EditIndexerUi::draw(f, app, f.area());
});
insta::assert_snapshot!(output);
}
#[test]
fn test_edit_indexer_ui_renders_edit_usenet_indexer() {
let mut app = App::test_default_fully_populated();
app.push_navigation_stack(ActiveSonarrBlock::EditIndexerPrompt.into());
app.data.sonarr_data.indexers.set_items(vec![Indexer {
protocol: "usenet".into(),
..indexer()
}]);
app.data.sonarr_data.selected_block =
BlockSelectionState::new(EDIT_INDEXER_NZB_SELECTION_BLOCKS);
let output = render_to_string_with_app(TerminalSize::Large, &mut app, |f, app| {
EditIndexerUi::draw(f, app, f.area());
@@ -7,7 +7,6 @@ mod tests {
use crate::models::servarr_data::sonarr::sonarr_data::{
ActiveSonarrBlock, INDEXER_SETTINGS_BLOCKS, INDEXER_SETTINGS_SELECTION_BLOCKS,
};
use crate::models::sonarr_models::IndexerSettings;
use crate::ui::DrawUi;
use crate::ui::sonarr_ui::indexers::indexer_settings_ui::IndexerSettingsUi;
use crate::ui::ui_test_utils::test_utils::render_to_string_with_app;
@@ -30,11 +29,10 @@ mod tests {
#[test]
fn test_indexer_settings_ui_renders_indexer_settings() {
let mut app = App::test_default();
let mut app = App::test_default_fully_populated();
app.push_navigation_stack(ActiveSonarrBlock::IndexerSettingsMinimumAgeInput.into());
app.data.sonarr_data.selected_block =
BlockSelectionState::new(INDEXER_SETTINGS_SELECTION_BLOCKS);
app.data.sonarr_data.indexer_settings = Some(IndexerSettings::default());
let output = render_to_string_with_app(TerminalSize::Large, &mut app, |f, app| {
IndexerSettingsUi::draw(f, app, f.area());
+88 -25
View File
@@ -7,7 +7,6 @@ mod tests {
ActiveSonarrBlock, EDIT_INDEXER_BLOCKS, INDEXER_SETTINGS_BLOCKS, INDEXERS_BLOCKS,
};
use crate::models::servarr_models::Indexer;
use crate::models::stateful_table::StatefulTable;
use crate::ui::DrawUi;
use crate::ui::sonarr_ui::indexers::IndexersUi;
use crate::ui::ui_test_utils::test_utils::render_to_string_with_app;
@@ -30,13 +29,19 @@ mod tests {
}
mod snapshot_tests {
use crate::models::BlockSelectionState;
use crate::models::servarr_data::sonarr::sonarr_data::{
EDIT_INDEXER_NZB_SELECTION_BLOCKS, EDIT_INDEXER_TORRENT_SELECTION_BLOCKS,
};
use crate::network::sonarr_network::sonarr_network_test_utils::test_utils::indexer;
use crate::ui::ui_test_utils::test_utils::TerminalSize;
use rstest::rstest;
use super::*;
#[test]
fn test_indexers_ui_renders_loading_state() {
let mut app = App::test_default();
fn test_indexers_ui_renders_loading() {
let mut app = App::test_default_fully_populated();
app.is_loading = true;
app.push_navigation_stack(ActiveSonarrBlock::Indexers.into());
@@ -47,11 +52,67 @@ mod tests {
insta::assert_snapshot!(output);
}
#[test]
fn test_indexers_ui_renders_loading_test_results() {
let mut app = App::test_default_fully_populated();
app.is_loading = true;
app.push_navigation_stack(ActiveSonarrBlock::TestIndexer.into());
let output = render_to_string_with_app(TerminalSize::Large, &mut app, |f, app| {
IndexersUi::draw(f, app, f.area());
});
insta::assert_snapshot!(output);
}
#[test]
fn test_indexers_ui_renders_loading_test_results_when_indexer_test_errors_is_none() {
let mut app = App::test_default_fully_populated();
app.push_navigation_stack(ActiveSonarrBlock::TestIndexer.into());
app.data.sonarr_data.indexer_test_errors = None;
let output = render_to_string_with_app(TerminalSize::Large, &mut app, |f, app| {
IndexersUi::draw(f, app, f.area());
});
insta::assert_snapshot!(output);
}
#[test]
fn test_indexers_ui_renders_empty_indexers() {
let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::Indexers.into());
app.data.sonarr_data.indexers = StatefulTable::default();
let output = render_to_string_with_app(TerminalSize::Large, &mut app, |f, app| {
IndexersUi::draw(f, app, f.area());
});
insta::assert_snapshot!(output);
}
#[rstest]
fn test_indexers_ui_renders(
#[values(
ActiveSonarrBlock::DeleteIndexerPrompt,
ActiveSonarrBlock::Indexers,
ActiveSonarrBlock::TestIndexer
)]
active_sonarr_block: ActiveSonarrBlock,
) {
let mut app = App::test_default_fully_populated();
app.push_navigation_stack(active_sonarr_block.into());
let output = render_to_string_with_app(TerminalSize::Large, &mut app, |f, app| {
IndexersUi::draw(f, app, f.area());
});
insta::assert_snapshot!(format!("indexers_ui_{active_sonarr_block}"), output);
}
#[test]
fn test_indexers_ui_renders_test_all_over_indexers() {
let mut app = App::test_default_fully_populated();
app.push_navigation_stack(ActiveSonarrBlock::TestAllIndexers.into());
let output = render_to_string_with_app(TerminalSize::Large, &mut app, |f, app| {
IndexersUi::draw(f, app, f.area());
@@ -61,27 +122,29 @@ mod tests {
}
#[test]
fn test_indexers_ui_renders_with_indexers() {
let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::Indexers.into());
app.data.sonarr_data.indexers = StatefulTable::default();
app.data.sonarr_data.indexers.set_items(vec![
Indexer {
id: 1,
name: Some("Test Indexer 1".to_owned()),
enable_rss: true,
enable_automatic_search: true,
enable_interactive_search: true,
priority: 25,
..Indexer::default()
},
Indexer {
id: 2,
name: Some("Test Indexer 2".to_owned()),
enable_rss: false,
..Indexer::default()
},
]);
fn test_indexers_ui_renders_edit_usenet_indexer_over_indexers() {
let mut app = App::test_default_fully_populated();
app.push_navigation_stack(ActiveSonarrBlock::EditIndexerPrompt.into());
app.data.sonarr_data.selected_block =
BlockSelectionState::new(EDIT_INDEXER_NZB_SELECTION_BLOCKS);
app.data.sonarr_data.indexers.set_items(vec![Indexer {
protocol: "usenet".into(),
..indexer()
}]);
let output = render_to_string_with_app(TerminalSize::Large, &mut app, |f, app| {
IndexersUi::draw(f, app, f.area());
});
insta::assert_snapshot!(output);
}
#[test]
fn test_indexers_ui_renders_edit_torrent_indexer_over_indexers() {
let mut app = App::test_default_fully_populated();
app.push_navigation_stack(ActiveSonarrBlock::EditIndexerPrompt.into());
app.data.sonarr_data.selected_block =
BlockSelectionState::new(EDIT_INDEXER_TORRENT_SELECTION_BLOCKS);
let output = render_to_string_with_app(TerminalSize::Large, &mut app, |f, app| {
IndexersUi::draw(f, app, f.area());
@@ -0,0 +1,42 @@
---
source: src/ui/sonarr_ui/indexers/edit_indexer_ui_tests.rs
expression: output
---
╭──────────────────────────────────────────────── Edit Indexer ─────────────────────────────────────────────────╮
│ │
│ ╭─────────────────────────╮ ╭─────────────────────────╮ │
│ Name: │DrunkenSlug │ URL: │http://127.0.0.1:9696/1/ │ │
│ ╰─────────────────────────╯ ╰─────────────────────────╯ │
│ ╭───╮ ╭─────────────────────────╮ │
│ Enable RSS: │ ✔ │ API Key: │someApiKey │ │
│ ╰───╯ ╰─────────────────────────╯ │
│ ╭───╮ ╭─────────────────────────╮ │
│ Enable Automatic Search: │ ✔ │ Seed Ratio: │ratio │ │
│ ╰───╯ ╰─────────────────────────╯ │
│ ╭───╮ ╭─────────────────────────╮ │
│ Enable Interactive Search: │ ✔ │ Tags: │25 │ │
│ ╰───╯ ╰─────────────────────────╯ │
│ ╭─────────────────────────╮ │
│ Indexer Priority ▴▾: │1 │ │
│ ╰─────────────────────────╯ │
│ │
│ │
│ │
│ │
│ ╭───────────────────────────╮╭──────────────────────────╮ │
│ │ Save ││ Cancel │ │
│ ╰───────────────────────────╯╰──────────────────────────╯ │
╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
@@ -18,16 +18,16 @@ expression: output
╭──────────────────────────────────────────────── Edit Indexer ─────────────────────────────────────────────────╮
│ │
│ ╭─────────────────────────╮ ╭─────────────────────────╮ │
│ Name: │Test Indexer │ URL: │https://test.indexer.com │ │
│ Name: │DrunkenSlug │ URL: │http://127.0.0.1:9696/1/ │ │
│ ╰─────────────────────────╯ ╰─────────────────────────╯ │
│ ╭───╮ ╭─────────────────────────╮ │
│ Enable RSS: │ ✔ │ API Key: │test-api-key │ │
│ Enable RSS: │ ✔ │ API Key: │someApiKey │ │
│ ╰───╯ ╰─────────────────────────╯ │
│ ╭───╮ ╭─────────────────────────╮ │
│ Enable Automatic Search: │ │ Tags: │ │ │
│ Enable Automatic Search: │ │ Tags: │25 │ │
│ ╰───╯ ╰─────────────────────────╯ │
│ ╭───╮ ╭─────────────────────────╮ │
│ Enable Interactive Search: │ │ Indexer Priority ▴▾: │25 │ │
│ Enable Interactive Search: │ │ Indexer Priority ▴▾: │1 │ │
│ ╰───╯ ╰─────────────────────────╯ │
│ │
│ │
@@ -0,0 +1,42 @@
---
source: src/ui/sonarr_ui/indexers/edit_indexer_ui_tests.rs
expression: output
---
╭──────────────────────────────────────────────── Edit Indexer ─────────────────────────────────────────────────╮
│ │
│ │
│ Loading ... │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
@@ -21,16 +21,16 @@ expression: output
│ │
│ │
│ ╭────────────────────────────────╮ │
│ Minimum Age (minutes) ▴▾: │0 │ │
│ Minimum Age (minutes) ▴▾: │1 │ │
│ ╰────────────────────────────────╯ │
│ ╭────────────────────────────────╮ │
│ Retention (days) ▴▾: │0 │ │
│ Retention (days) ▴▾: │1 │ │
│ ╰────────────────────────────────╯ │
│ ╭────────────────────────────────╮ │
│ Maximum Size (MB) ▴▾: │0 │ │
│ Maximum Size (MB) ▴▾: │12345 │ │
│ ╰────────────────────────────────╯ │
│ ╭────────────────────────────────╮ │
│ RSS Sync Interval (minutes) ▴▾: │0 │ │
│ RSS Sync Interval (minutes) ▴▾: │60 │ │
│ ╰────────────────────────────────╯ │
│ │
│ │
@@ -0,0 +1,38 @@
---
source: src/ui/sonarr_ui/indexers/indexers_ui_tests.rs
expression: output
---
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Indexer RSS Automatic Search Interactive Search Priority Tags
=> Test Indexer Enabled Enabled Enabled 25 alex
╭──────────────────── Delete Indexer ─────────────────────╮
│ Do you really want to delete this indexer: │
│ Test Indexer? │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│╭────────────────────────────╮╭───────────────────────────╮│
││ Yes ││ No ││
│╰────────────────────────────╯╰───────────────────────────╯│
╰───────────────────────────────────────────────────────────╯
@@ -4,5 +4,4 @@ expression: output
---
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Indexer RSS Automatic Search Interactive Search Priority Tags
=> Test Indexer 1 Enabled Enabled Enabled 25
Test Indexer 2 Disabled Disabled Disabled 0
=> Test Indexer Enabled Enabled Enabled 25 alex
@@ -0,0 +1,35 @@
---
source: src/ui/sonarr_ui/indexers/indexers_ui_tests.rs
expression: output
---
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Indexer RSS Automatic Search Interactive Search Priority Tags
=> Test Indexer Enabled Enabled Enabled 25 alex
╭─────────────── Error ───────────────╮
│ error │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
╰───────────────────────────────────────╯
@@ -0,0 +1,42 @@
---
source: src/ui/sonarr_ui/indexers/indexers_ui_tests.rs
expression: output
---
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Indexer RSS Automatic Search Interactive Search Priority Tags
=> Test Indexer Enabled Enabled Enabled 25 alex
╭──────────────────────────────────────────────── Edit Indexer ─────────────────────────────────────────────────╮
│ │
│ ╭─────────────────────────╮ ╭─────────────────────────╮ │
│ Name: │DrunkenSlug │ URL: │http://127.0.0.1:9696/1/ │ │
│ ╰─────────────────────────╯ ╰─────────────────────────╯ │
│ ╭───╮ ╭─────────────────────────╮ │
│ Enable RSS: │ ✔ │ API Key: │someApiKey │ │
│ ╰───╯ ╰─────────────────────────╯ │
│ ╭───╮ ╭─────────────────────────╮ │
│ Enable Automatic Search: │ ✔ │ Seed Ratio: │ratio │ │
│ ╰───╯ ╰─────────────────────────╯ │
│ ╭───╮ ╭─────────────────────────╮ │
│ Enable Interactive Search: │ ✔ │ Tags: │25 │ │
│ ╰───╯ ╰─────────────────────────╯ │
│ ╭─────────────────────────╮ │
│ Indexer Priority ▴▾: │1 │ │
│ ╰─────────────────────────╯ │
│ │
│ │
│ │
│ │
│ ╭───────────────────────────╮╭──────────────────────────╮ │
│ │ Save ││ Cancel │ │
│ ╰───────────────────────────╯╰──────────────────────────╯ │
╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
@@ -0,0 +1,42 @@
---
source: src/ui/sonarr_ui/indexers/indexers_ui_tests.rs
expression: output
---
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Indexer RSS Automatic Search Interactive Search Priority Tags
=> Test Indexer Enabled Enabled Enabled 25 alex
╭──────────────────────────────────────────────── Edit Indexer ─────────────────────────────────────────────────╮
│ │
│ ╭─────────────────────────╮ ╭─────────────────────────╮ │
│ Name: │DrunkenSlug │ URL: │http://127.0.0.1:9696/1/ │ │
│ ╰─────────────────────────╯ ╰─────────────────────────╯ │
│ ╭───╮ ╭─────────────────────────╮ │
│ Enable RSS: │ ✔ │ API Key: │someApiKey │ │
│ ╰───╯ ╰─────────────────────────╯ │
│ ╭───╮ ╭─────────────────────────╮ │
│ Enable Automatic Search: │ ✔ │ Tags: │25 │ │
│ ╰───╯ ╰─────────────────────────╯ │
│ ╭───╮ ╭─────────────────────────╮ │
│ Enable Interactive Search: │ ✔ │ Indexer Priority ▴▾: │1 │ │
│ ╰───╯ ╰─────────────────────────╯ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ ╭───────────────────────────╮╭──────────────────────────╮ │
│ │ Save ││ Cancel │ │
│ ╰───────────────────────────╯╰──────────────────────────╯ │
╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
@@ -0,0 +1,35 @@
---
source: src/ui/sonarr_ui/indexers/indexers_ui_tests.rs
expression: output
---
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Loading ...
╭ Testing Indexer ────────────────────╮
│ │
│ │
│ Loading ... │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
╰───────────────────────────────────────╯
@@ -0,0 +1,35 @@
---
source: src/ui/sonarr_ui/indexers/indexers_ui_tests.rs
expression: output
---
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Indexer RSS Automatic Search Interactive Search Priority Tags
=> Test Indexer Enabled Enabled Enabled 25 alex
╭ Testing Indexer ────────────────────╮
│ │
│ │
│ Loading ... │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
╰───────────────────────────────────────╯
@@ -0,0 +1,48 @@
---
source: src/ui/sonarr_ui/indexers/indexers_ui_tests.rs
expression: output
---
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Indexer RSS Automatic Search Interactive Search Priority Tags
=> Test Indexer Enabled Enabled Enabled 25 alex
╭ Test All Indexers ─────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ Indexer Pass/Fail Failure Messages │
│=> DrunkenSlug ❌ Some failure │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
@@ -0,0 +1,48 @@
---
source: src/ui/sonarr_ui/indexers/test_all_indexers_ui_tests.rs
expression: output
---
╭ Test All Indexers ─────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ Indexer Pass/Fail Failure Messages │
│=> DrunkenSlug ❌ Some failure │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
@@ -25,8 +25,8 @@ mod tests {
use super::*;
#[test]
fn test_test_all_indexers_ui_renders_loading_state() {
let mut app = App::test_default();
fn test_test_all_indexers_ui_renders_loading() {
let mut app = App::test_default_fully_populated();
app.is_loading = true;
app.push_navigation_stack(ActiveSonarrBlock::TestAllIndexers.into());
@@ -36,5 +36,17 @@ mod tests {
insta::assert_snapshot!(output);
}
#[test]
fn test_test_all_indexers_ui_renders() {
let mut app = App::test_default_fully_populated();
app.push_navigation_stack(ActiveSonarrBlock::TestAllIndexers.into());
let output = render_to_string_with_app(TerminalSize::Large, &mut app, |f, app| {
TestAllIndexersUi::draw(f, app, f.area());
});
insta::assert_snapshot!(output);
}
}
}
@@ -21,15 +21,18 @@ mod tests {
}
mod snapshot_tests {
use crate::models::BlockSelectionState;
use crate::models::servarr_data::sonarr::sonarr_data::ADD_SERIES_SELECTION_BLOCKS;
use crate::ui::ui_test_utils::test_utils::TerminalSize;
use rstest::rstest;
use super::*;
#[test]
fn test_add_series_ui_renders_loading_state() {
let mut app = App::test_default();
fn test_add_series_ui_renders_loading_search() {
let mut app = App::test_default_fully_populated();
app.is_loading = true;
app.push_navigation_stack(ActiveSonarrBlock::AddSeriesSearchInput.into());
app.push_navigation_stack(ActiveSonarrBlock::AddSeriesSearchResults.into());
app.data.sonarr_data.add_series_search = Some(HorizontallyScrollableText::default());
let output = render_to_string_with_app(TerminalSize::Large, &mut app, |f, app| {
@@ -39,17 +42,30 @@ mod tests {
insta::assert_snapshot!(output);
}
#[test]
fn test_add_series_ui_renders_search_input() {
let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::AddSeriesSearchInput.into());
app.data.sonarr_data.add_series_search = Some(HorizontallyScrollableText::default());
#[rstest]
fn test_add_series_ui_renders(
#[values(
ActiveSonarrBlock::AddSeriesAlreadyInLibrary,
ActiveSonarrBlock::AddSeriesEmptySearchResults,
ActiveSonarrBlock::AddSeriesPrompt,
ActiveSonarrBlock::AddSeriesSearchResults,
ActiveSonarrBlock::AddSeriesSelectLanguageProfile,
ActiveSonarrBlock::AddSeriesSelectMonitor,
ActiveSonarrBlock::AddSeriesSelectQualityProfile,
ActiveSonarrBlock::AddSeriesSelectRootFolder,
ActiveSonarrBlock::AddSeriesSelectSeriesType
)]
active_sonarr_block: ActiveSonarrBlock,
) {
let mut app = App::test_default_fully_populated();
app.push_navigation_stack(active_sonarr_block.into());
app.data.sonarr_data.selected_block = BlockSelectionState::new(ADD_SERIES_SELECTION_BLOCKS);
let output = render_to_string_with_app(TerminalSize::Large, &mut app, |f, app| {
AddSeriesUi::draw(f, app, f.area());
});
insta::assert_snapshot!(output);
insta::assert_snapshot!(format!("add_series_ui_{active_sonarr_block}"), output);
}
}
}
@@ -7,8 +7,6 @@ mod tests {
use crate::models::servarr_data::sonarr::sonarr_data::{
ActiveSonarrBlock, DELETE_SERIES_BLOCKS, DELETE_SERIES_SELECTION_BLOCKS,
};
use crate::models::sonarr_models::Series;
use crate::models::stateful_table::StatefulTable;
use crate::ui::DrawUi;
use crate::ui::sonarr_ui::library::delete_series_ui::DeleteSeriesUi;
use crate::ui::ui_test_utils::test_utils::render_to_string_with_app;
@@ -30,15 +28,9 @@ mod tests {
use super::*;
#[test]
fn test_delete_series_ui_renders_delete_series_toggle() {
let mut app = App::test_default();
fn test_delete_series_ui_renders_delete_series() {
let mut app = App::test_default_fully_populated();
app.push_navigation_stack(ActiveSonarrBlock::DeleteSeriesPrompt.into());
app.data.sonarr_data.series = StatefulTable::default();
app.data.sonarr_data.series.set_items(vec![Series {
id: 1,
title: "Test Series".into(),
..Series::default()
}]);
app.data.sonarr_data.selected_block =
BlockSelectionState::new(DELETE_SERIES_SELECTION_BLOCKS);
@@ -1,16 +1,12 @@
#[cfg(test)]
mod tests {
use bimap::BiMap;
use strum::IntoEnumIterator;
use crate::app::App;
use crate::models::BlockSelectionState;
use crate::models::servarr_data::sonarr::modals::EditSeriesModal;
use crate::models::servarr_data::sonarr::sonarr_data::{
ActiveSonarrBlock, EDIT_SERIES_BLOCKS, EDIT_SERIES_SELECTION_BLOCKS,
};
use crate::models::sonarr_models::Series;
use crate::models::stateful_table::StatefulTable;
use crate::ui::DrawUi;
use crate::ui::sonarr_ui::library::edit_series_ui::EditSeriesUi;
use crate::ui::ui_test_utils::test_utils::render_to_string_with_app;
@@ -28,33 +24,56 @@ mod tests {
mod snapshot_tests {
use crate::ui::ui_test_utils::test_utils::TerminalSize;
use rstest::rstest;
use super::*;
#[test]
fn test_edit_series_ui_renders_edit_series_modal() {
let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::EditSeriesPathInput.into());
app.data.sonarr_data.quality_profile_map = BiMap::from_iter(vec![(1, "HD-1080p".to_owned())]);
app.data.sonarr_data.language_profiles_map =
BiMap::from_iter(vec![(1, "English".to_owned())]);
app.data.sonarr_data.series = StatefulTable::default();
app.data.sonarr_data.series.set_items(vec![Series {
id: 1,
title: "Test Series".into(),
path: "/tv/test".to_owned(),
quality_profile_id: 1,
language_profile_id: 1,
..Series::default()
}]);
#[rstest]
#[case(ActiveSonarrBlock::EditSeriesPrompt, None)]
#[case(ActiveSonarrBlock::EditSeriesConfirmPrompt, None)]
#[case(ActiveSonarrBlock::EditSeriesSelectSeriesType, None)]
#[case(ActiveSonarrBlock::EditSeriesSelectQualityProfile, None)]
#[case(ActiveSonarrBlock::EditSeriesSelectLanguageProfile, None)]
#[case(
ActiveSonarrBlock::EditSeriesPrompt,
Some(ActiveSonarrBlock::SeriesDetails)
)]
#[case(
ActiveSonarrBlock::EditSeriesConfirmPrompt,
Some(ActiveSonarrBlock::SeriesDetails)
)]
#[case(
ActiveSonarrBlock::EditSeriesSelectSeriesType,
Some(ActiveSonarrBlock::SeriesDetails)
)]
#[case(
ActiveSonarrBlock::EditSeriesSelectQualityProfile,
Some(ActiveSonarrBlock::SeriesDetails)
)]
#[case(
ActiveSonarrBlock::EditSeriesSelectLanguageProfile,
Some(ActiveSonarrBlock::SeriesDetails)
)]
fn test_edit_series_ui_renders(
#[case] active_sonarr_block: ActiveSonarrBlock,
#[case] context: Option<ActiveSonarrBlock>,
) {
let mut app = App::test_default_fully_populated();
app.push_navigation_stack((active_sonarr_block, context).into());
app.data.sonarr_data.selected_block = BlockSelectionState::new(EDIT_SERIES_SELECTION_BLOCKS);
app.data.sonarr_data.edit_series_modal = Some(EditSeriesModal::from(&app.data.sonarr_data));
let output = render_to_string_with_app(TerminalSize::Large, &mut app, |f, app| {
EditSeriesUi::draw(f, app, f.area());
});
insta::assert_snapshot!(output);
if let Some(context) = context {
insta::assert_snapshot!(
format!("edit_series_{active_sonarr_block}_{context}"),
output
);
} else {
insta::assert_snapshot!(format!("edit_series_{active_sonarr_block}"), output);
}
}
}
}
+49 -49
View File
@@ -194,60 +194,60 @@ fn draw_episode_details(f: &mut Frame<'_>, app: &App<'_>, area: Rect) {
fn draw_file_info(f: &mut Frame<'_>, app: &App<'_>, area: Rect) {
match app.data.sonarr_data.season_details_modal.as_ref() {
Some(season_details_modal) => match season_details_modal.episode_details_modal.as_ref() {
Some(episode_details_modal)
if !episode_details_modal.file_details.is_empty() && !app.is_loading =>
{
let file_info = episode_details_modal.file_details.to_owned();
let audio_details = episode_details_modal.audio_details.to_owned();
let video_details = episode_details_modal.video_details.to_owned();
let [
file_details_title_area,
file_details_area,
audio_details_title_area,
audio_details_area,
video_details_title_area,
video_details_area,
] = Layout::vertical([
Constraint::Length(2),
Constraint::Length(5),
Constraint::Length(1),
Constraint::Length(6),
Constraint::Length(1),
Constraint::Length(7),
])
.areas(area);
Some(season_details_modal) if !app.is_loading => {
match season_details_modal.episode_details_modal.as_ref() {
Some(episode_details_modal) if !episode_details_modal.file_details.is_empty() => {
let file_info = episode_details_modal.file_details.to_owned();
let audio_details = episode_details_modal.audio_details.to_owned();
let video_details = episode_details_modal.video_details.to_owned();
let [
file_details_title_area,
file_details_area,
audio_details_title_area,
audio_details_area,
video_details_title_area,
video_details_area,
] = Layout::vertical([
Constraint::Length(2),
Constraint::Length(5),
Constraint::Length(1),
Constraint::Length(6),
Constraint::Length(1),
Constraint::Length(7),
])
.areas(area);
let file_details_title_paragraph =
Paragraph::new("File Details".bold()).block(layout_block_top_border());
let audio_details_title_paragraph =
Paragraph::new("Audio Details".bold()).block(borderless_block());
let video_details_title_paragraph =
Paragraph::new("Video Details".bold()).block(borderless_block());
let file_details_title_paragraph =
Paragraph::new("File Details".bold()).block(layout_block_top_border());
let audio_details_title_paragraph =
Paragraph::new("Audio Details".bold()).block(borderless_block());
let video_details_title_paragraph =
Paragraph::new("Video Details".bold()).block(borderless_block());
let file_details = Text::from(file_info);
let audio_details = Text::from(audio_details);
let video_details = Text::from(video_details);
let file_details = Text::from(file_info);
let audio_details = Text::from(audio_details);
let video_details = Text::from(video_details);
let file_details_paragraph = Paragraph::new(file_details)
.block(layout_block_bottom_border())
.wrap(Wrap { trim: false });
let audio_details_paragraph = Paragraph::new(audio_details)
.block(layout_block_bottom_border())
.wrap(Wrap { trim: false });
let video_details_paragraph = Paragraph::new(video_details)
.block(borderless_block())
.wrap(Wrap { trim: false });
let file_details_paragraph = Paragraph::new(file_details)
.block(layout_block_bottom_border())
.wrap(Wrap { trim: false });
let audio_details_paragraph = Paragraph::new(audio_details)
.block(layout_block_bottom_border())
.wrap(Wrap { trim: false });
let video_details_paragraph = Paragraph::new(video_details)
.block(borderless_block())
.wrap(Wrap { trim: false });
f.render_widget(file_details_title_paragraph, file_details_title_area);
f.render_widget(file_details_paragraph, file_details_area);
f.render_widget(audio_details_title_paragraph, audio_details_title_area);
f.render_widget(audio_details_paragraph, audio_details_area);
f.render_widget(video_details_title_paragraph, video_details_title_area);
f.render_widget(video_details_paragraph, video_details_area);
f.render_widget(file_details_title_paragraph, file_details_title_area);
f.render_widget(file_details_paragraph, file_details_area);
f.render_widget(audio_details_title_paragraph, audio_details_title_area);
f.render_widget(audio_details_paragraph, audio_details_area);
f.render_widget(video_details_title_paragraph, video_details_title_area);
f.render_widget(video_details_paragraph, video_details_area);
}
_ => f.render_widget(layout_block_top_border(), area),
}
_ => f.render_widget(layout_block_top_border(), area),
},
}
_ => f.render_widget(
LoadingBlock::new(app.is_loading, layout_block_top_border()),
area,
@@ -3,12 +3,9 @@ mod tests {
use strum::IntoEnumIterator;
use crate::app::App;
use crate::models::servarr_data::sonarr::modals::{EpisodeDetailsModal, SeasonDetailsModal};
use crate::models::servarr_data::sonarr::sonarr_data::{
ActiveSonarrBlock, EPISODE_DETAILS_BLOCKS,
};
use crate::models::sonarr_models::{Episode, Season, Series};
use crate::models::stateful_table::StatefulTable;
use crate::ui::DrawUi;
use crate::ui::sonarr_ui::library::episode_details_ui::EpisodeDetailsUi;
use crate::ui::ui_test_utils::test_utils::render_to_string_with_app;
@@ -26,110 +23,121 @@ mod tests {
mod snapshot_tests {
use crate::ui::ui_test_utils::test_utils::TerminalSize;
use rstest::rstest;
use super::*;
#[test]
fn test_episode_details_ui_renders_loading_state() {
let mut app = App::test_default();
#[rstest]
#[case(ActiveSonarrBlock::EpisodeDetails, 0)]
#[case(ActiveSonarrBlock::EpisodeHistory, 1)]
#[case(ActiveSonarrBlock::EpisodeHistoryDetails, 1)]
#[case(ActiveSonarrBlock::EpisodeFile, 2)]
#[case(ActiveSonarrBlock::ManualEpisodeSearch, 3)]
#[case(ActiveSonarrBlock::ManualEpisodeSearchConfirmPrompt, 3)]
#[case(ActiveSonarrBlock::ManualEpisodeSearchSortPrompt, 3)]
#[case(ActiveSonarrBlock::AutomaticallySearchEpisodePrompt, 0)]
#[case(ActiveSonarrBlock::AutomaticallySearchEpisodePrompt, 1)]
#[case(ActiveSonarrBlock::AutomaticallySearchEpisodePrompt, 2)]
#[case(ActiveSonarrBlock::AutomaticallySearchEpisodePrompt, 3)]
fn test_episode_details_ui_renders(
#[case] active_sonarr_block: ActiveSonarrBlock,
#[case] index: usize,
) {
let mut app = App::test_default_fully_populated();
app.push_navigation_stack(active_sonarr_block.into());
app
.data
.sonarr_data
.season_details_modal
.as_mut()
.unwrap()
.episode_details_modal
.as_mut()
.unwrap()
.episode_details_tabs
.set_index(index);
let output = render_to_string_with_app(TerminalSize::Large, &mut app, |f, app| {
EpisodeDetailsUi::draw(f, app, f.area());
});
insta::assert_snapshot!(
format!("episode_details_{active_sonarr_block}_{index}"),
output
);
}
#[rstest]
#[case(ActiveSonarrBlock::EpisodeDetails, 0)]
#[case(ActiveSonarrBlock::EpisodeHistory, 1)]
#[case(ActiveSonarrBlock::EpisodeFile, 2)]
#[case(ActiveSonarrBlock::ManualEpisodeSearch, 3)]
fn test_episode_details_ui_renders_loading(
#[case] active_sonarr_block: ActiveSonarrBlock,
#[case] index: usize,
) {
let mut app = App::test_default_fully_populated();
app.is_loading = true;
app.push_navigation_stack(ActiveSonarrBlock::EpisodeDetails.into());
app.data.sonarr_data.series = StatefulTable::default();
app.data.sonarr_data.series.set_items(vec![Series {
seasons: Some(vec![Season {
season_number: 1,
..Season::default()
}]),
..Series::default()
}]);
app.push_navigation_stack(active_sonarr_block.into());
app
.data
.sonarr_data
.season_details_modal
.as_mut()
.unwrap()
.episode_details_modal
.as_mut()
.unwrap()
.episode_details_tabs
.set_index(index);
let output = render_to_string_with_app(TerminalSize::Large, &mut app, |f, app| {
EpisodeDetailsUi::draw(f, app, f.area());
});
insta::assert_snapshot!(output);
insta::assert_snapshot!(
format!("loading_episode_details_{active_sonarr_block}_{index}"),
output
);
}
#[test]
fn test_episode_details_ui_renders_episode_details_tab() {
let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::EpisodeDetails.into());
app.data.sonarr_data.series = StatefulTable::default();
app.data.sonarr_data.series.set_items(vec![Series {
seasons: Some(vec![Season {
season_number: 1,
..Season::default()
}]),
..Series::default()
}]);
let mut season_details_modal = SeasonDetailsModal::default();
season_details_modal
.episodes
.set_items(vec![Episode::default()]);
season_details_modal.episode_details_modal = Some(EpisodeDetailsModal::default());
app.data.sonarr_data.season_details_modal = Some(season_details_modal);
#[rstest]
#[case(ActiveSonarrBlock::EpisodeDetails, 0)]
#[case(ActiveSonarrBlock::EpisodeHistory, 1)]
#[case(ActiveSonarrBlock::EpisodeHistoryDetails, 1)]
#[case(ActiveSonarrBlock::EpisodeFile, 2)]
#[case(ActiveSonarrBlock::ManualEpisodeSearch, 3)]
fn test_episode_details_ui_renders_empty(
#[case] active_sonarr_block: ActiveSonarrBlock,
#[case] index: usize,
) {
let mut app = App::test_default_fully_populated();
app.push_navigation_stack(active_sonarr_block.into());
{
let episode_details_modal = app
.data
.sonarr_data
.season_details_modal
.as_mut()
.unwrap()
.episode_details_modal
.as_mut()
.unwrap();
episode_details_modal.episode_details_tabs.set_index(index);
episode_details_modal.episode_details = Default::default();
episode_details_modal.episode_history = Default::default();
episode_details_modal.file_details = Default::default();
episode_details_modal.episode_releases = Default::default();
}
let output = render_to_string_with_app(TerminalSize::Large, &mut app, |f, app| {
EpisodeDetailsUi::draw(f, app, f.area());
});
insta::assert_snapshot!(output);
}
#[test]
fn test_episode_details_ui_renders_episode_history_tab() {
let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::EpisodeDetails.into());
app.data.sonarr_data.series = StatefulTable::default();
app.data.sonarr_data.series.set_items(vec![Series {
seasons: Some(vec![Season {
season_number: 1,
..Season::default()
}]),
..Series::default()
}]);
let mut season_details_modal = SeasonDetailsModal::default();
season_details_modal
.episodes
.set_items(vec![Episode::default()]);
let mut episode_details_modal = EpisodeDetailsModal::default();
episode_details_modal.episode_details_tabs.set_index(1);
season_details_modal.episode_details_modal = Some(episode_details_modal);
app.data.sonarr_data.season_details_modal = Some(season_details_modal);
let output = render_to_string_with_app(TerminalSize::Large, &mut app, |f, app| {
EpisodeDetailsUi::draw(f, app, f.area());
});
insta::assert_snapshot!(output);
}
#[test]
fn test_episode_details_ui_renders_manual_search_tab() {
let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::EpisodeDetails.into());
app.data.sonarr_data.series = StatefulTable::default();
app.data.sonarr_data.series.set_items(vec![Series {
seasons: Some(vec![Season {
season_number: 1,
..Season::default()
}]),
..Series::default()
}]);
let mut season_details_modal = SeasonDetailsModal::default();
season_details_modal
.episodes
.set_items(vec![Episode::default()]);
let mut episode_details_modal = EpisodeDetailsModal::default();
episode_details_modal.episode_details_tabs.set_index(3);
season_details_modal.episode_details_modal = Some(episode_details_modal);
app.data.sonarr_data.season_details_modal = Some(season_details_modal);
let output = render_to_string_with_app(TerminalSize::Large, &mut app, |f, app| {
EpisodeDetailsUi::draw(f, app, f.area());
});
insta::assert_snapshot!(output);
insta::assert_snapshot!(
format!("empty_episode_details_{active_sonarr_block}_{index}"),
output
);
}
}
}
+90 -62
View File
@@ -247,18 +247,44 @@ mod tests {
}
mod snapshot_tests {
use crate::app::App;
use crate::models::servarr_data::sonarr::sonarr_data::ActiveSonarrBlock;
use crate::models::BlockSelectionState;
use crate::models::servarr_data::sonarr::sonarr_data::{
ADD_SERIES_SELECTION_BLOCKS, ActiveSonarrBlock, DELETE_SERIES_SELECTION_BLOCKS,
EDIT_SERIES_SELECTION_BLOCKS,
};
use rstest::rstest;
use crate::models::stateful_table::StatefulTable;
use crate::ui::DrawUi;
use crate::ui::sonarr_ui::library::LibraryUi;
use crate::ui::ui_test_utils::test_utils::{TerminalSize, render_to_string_with_app};
#[rstest]
fn test_library_ui_renders(
#[values(
ActiveSonarrBlock::Series,
ActiveSonarrBlock::SeriesSortPrompt,
ActiveSonarrBlock::SearchSeries,
ActiveSonarrBlock::SearchSeriesError,
ActiveSonarrBlock::FilterSeries,
ActiveSonarrBlock::FilterSeriesError,
ActiveSonarrBlock::UpdateAllSeriesPrompt
)]
active_sonarr_block: ActiveSonarrBlock,
) {
let mut app = App::test_default_fully_populated();
app.push_navigation_stack(active_sonarr_block.into());
let output = render_to_string_with_app(TerminalSize::Large, &mut app, |f, app| {
LibraryUi::draw(f, app, f.area());
});
insta::assert_snapshot!(format!("sonarr_library_{active_sonarr_block}"), output);
}
#[test]
fn test_library_ui_renders_loading_state() {
let mut app = App::test_default();
fn test_library_ui_renders_loading() {
let mut app = App::test_default_fully_populated();
app.is_loading = true;
app.push_navigation_stack(ActiveSonarrBlock::Series.into());
@@ -270,10 +296,9 @@ mod tests {
}
#[test]
fn test_library_ui_renders_empty_series() {
fn test_library_ui_renders_empty() {
let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::Series.into());
app.data.sonarr_data.series = StatefulTable::default();
let output = render_to_string_with_app(TerminalSize::Large, &mut app, |f, app| {
LibraryUi::draw(f, app, f.area());
@@ -283,56 +308,9 @@ mod tests {
}
#[test]
fn test_library_ui_renders_with_series() {
use crate::models::sonarr_models::{Series, SeriesStatus, SeriesType};
use crate::models::stateful_table::StatefulTable;
use bimap::BiMap;
let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::Series.into());
// Set up quality profile and language profile maps
let mut quality_profile_map = BiMap::new();
quality_profile_map.insert(1, "HD-1080p".to_owned());
quality_profile_map.insert(2, "Any".to_owned());
app.data.sonarr_data.quality_profile_map = quality_profile_map;
let mut language_profiles_map = BiMap::new();
language_profiles_map.insert(1, "English".to_owned());
language_profiles_map.insert(2, "Any".to_owned());
app.data.sonarr_data.language_profiles_map = language_profiles_map;
// Create series with data
let mut series_table = StatefulTable::default();
series_table.set_items(vec![
Series {
id: 1,
title: "Breaking Bad".into(),
year: 2008,
network: Some("AMC".to_owned()),
status: SeriesStatus::Ended,
monitored: true,
series_type: SeriesType::Standard,
quality_profile_id: 1,
language_profile_id: 1,
seasons: Some(vec![]),
..Series::default()
},
Series {
id: 2,
title: "The Wire".into(),
year: 2002,
network: Some("HBO".to_owned()),
status: SeriesStatus::Continuing,
monitored: true,
series_type: SeriesType::Standard,
quality_profile_id: 2,
language_profile_id: 1,
seasons: Some(vec![]),
..Series::default()
},
]);
app.data.sonarr_data.series = series_table;
fn test_library_ui_renders_series_details_over_series() {
let mut app = App::test_default_fully_populated();
app.push_navigation_stack(ActiveSonarrBlock::SeriesDetails.into());
let output = render_to_string_with_app(TerminalSize::Large, &mut app, |f, app| {
LibraryUi::draw(f, app, f.area());
@@ -342,11 +320,61 @@ mod tests {
}
#[test]
fn test_library_ui_renders_update_all_series_prompt() {
let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::Series.into());
app.push_navigation_stack(ActiveSonarrBlock::UpdateAllSeriesPrompt.into());
app.data.sonarr_data.series = StatefulTable::default();
fn test_library_ui_renders_season_details_over_series() {
let mut app = App::test_default_fully_populated();
app.push_navigation_stack(ActiveSonarrBlock::SeasonDetails.into());
let output = render_to_string_with_app(TerminalSize::Large, &mut app, |f, app| {
LibraryUi::draw(f, app, f.area());
});
insta::assert_snapshot!(output);
}
#[test]
fn test_library_ui_renders_episode_details_over_series() {
let mut app = App::test_default_fully_populated();
app.push_navigation_stack(ActiveSonarrBlock::EpisodeDetails.into());
let output = render_to_string_with_app(TerminalSize::Large, &mut app, |f, app| {
LibraryUi::draw(f, app, f.area());
});
insta::assert_snapshot!(output);
}
#[test]
fn test_library_ui_renders_delete_episode_over_series() {
let mut app = App::test_default_fully_populated();
app.push_navigation_stack(ActiveSonarrBlock::DeleteSeriesPrompt.into());
app.data.sonarr_data.selected_block =
BlockSelectionState::new(DELETE_SERIES_SELECTION_BLOCKS);
let output = render_to_string_with_app(TerminalSize::Large, &mut app, |f, app| {
LibraryUi::draw(f, app, f.area());
});
insta::assert_snapshot!(output);
}
#[test]
fn test_library_ui_renders_edit_series_over_series() {
let mut app = App::test_default_fully_populated();
app.push_navigation_stack(ActiveSonarrBlock::EditSeriesPrompt.into());
app.data.sonarr_data.selected_block = BlockSelectionState::new(EDIT_SERIES_SELECTION_BLOCKS);
let output = render_to_string_with_app(TerminalSize::Large, &mut app, |f, app| {
LibraryUi::draw(f, app, f.area());
});
insta::assert_snapshot!(output);
}
#[test]
fn test_library_ui_renders_add_series_over_series() {
let mut app = App::test_default_fully_populated();
app.push_navigation_stack(ActiveSonarrBlock::AddSeriesPrompt.into());
app.data.sonarr_data.selected_block = BlockSelectionState::new(ADD_SERIES_SELECTION_BLOCKS);
let output = render_to_string_with_app(TerminalSize::Large, &mut app, |f, app| {
LibraryUi::draw(f, app, f.area());
@@ -1,14 +1,11 @@
#[cfg(test)]
mod tests {
use bimap::BiMap;
use strum::IntoEnumIterator;
use crate::app::App;
use crate::models::servarr_data::sonarr::modals::SeasonDetailsModal;
use crate::models::servarr_data::sonarr::sonarr_data::{
ActiveSonarrBlock, EPISODE_DETAILS_BLOCKS, SEASON_DETAILS_BLOCKS,
};
use crate::models::sonarr_models::{Season, Series};
use crate::models::stateful_table::StatefulTable;
use crate::ui::DrawUi;
use crate::ui::sonarr_ui::library::season_details_ui::SeasonDetailsUi;
@@ -30,114 +27,116 @@ mod tests {
mod snapshot_tests {
use crate::ui::ui_test_utils::test_utils::TerminalSize;
use rstest::rstest;
use super::*;
#[test]
fn test_season_details_ui_renders_loading_state() {
let mut app = App::test_default();
#[rstest]
#[case(ActiveSonarrBlock::SeasonDetails, 0)]
#[case(ActiveSonarrBlock::SeasonHistory, 1)]
#[case(ActiveSonarrBlock::SearchEpisodes, 0)]
#[case(ActiveSonarrBlock::SearchEpisodesError, 0)]
#[case(ActiveSonarrBlock::AutomaticallySearchSeasonPrompt, 0)]
#[case(ActiveSonarrBlock::AutomaticallySearchSeasonPrompt, 1)]
#[case(ActiveSonarrBlock::AutomaticallySearchSeasonPrompt, 2)]
#[case(ActiveSonarrBlock::SearchSeasonHistory, 1)]
#[case(ActiveSonarrBlock::SearchSeasonHistoryError, 1)]
#[case(ActiveSonarrBlock::FilterSeasonHistory, 1)]
#[case(ActiveSonarrBlock::FilterSeasonHistoryError, 1)]
#[case(ActiveSonarrBlock::SeasonHistorySortPrompt, 1)]
#[case(ActiveSonarrBlock::SeasonHistoryDetails, 1)]
#[case(ActiveSonarrBlock::ManualSeasonSearch, 2)]
#[case(ActiveSonarrBlock::ManualSeasonSearchConfirmPrompt, 2)]
#[case(ActiveSonarrBlock::ManualSeasonSearchSortPrompt, 2)]
#[case(ActiveSonarrBlock::DeleteEpisodeFilePrompt, 0)]
fn test_season_details_ui_renders(
#[case] active_sonarr_block: ActiveSonarrBlock,
#[case] index: usize,
) {
let mut app = App::test_default_fully_populated();
app.push_navigation_stack(active_sonarr_block.into());
app
.data
.sonarr_data
.season_details_modal
.as_mut()
.unwrap()
.season_details_tabs
.set_index(index);
let output = render_to_string_with_app(TerminalSize::Large, &mut app, |f, app| {
SeasonDetailsUi::draw(f, app, f.area());
});
insta::assert_snapshot!(
format!("season_details_renders_{active_sonarr_block}_{index}"),
output
);
}
#[rstest]
#[case(ActiveSonarrBlock::SeasonDetails, 0)]
#[case(ActiveSonarrBlock::SeasonHistory, 1)]
#[case(ActiveSonarrBlock::SeasonHistoryDetails, 1)]
#[case(ActiveSonarrBlock::ManualSeasonSearch, 2)]
fn test_season_details_ui_renders_loading(
#[case] active_sonarr_block: ActiveSonarrBlock,
#[case] index: usize,
) {
let mut app = App::test_default_fully_populated();
app.is_loading = true;
app.push_navigation_stack(ActiveSonarrBlock::SeasonDetails.into());
app.data.sonarr_data.series = StatefulTable::default();
app.data.sonarr_data.series.set_items(vec![Series {
seasons: Some(vec![Season::default()]),
..Series::default()
}]);
app.push_navigation_stack(active_sonarr_block.into());
{
let season_details_modal = app.data.sonarr_data.season_details_modal.as_mut().unwrap();
season_details_modal.season_releases = StatefulTable::default();
season_details_modal.season_history = StatefulTable::default();
season_details_modal.episodes = StatefulTable::default();
season_details_modal.season_details_tabs.set_index(index);
}
let output = render_to_string_with_app(TerminalSize::Large, &mut app, |f, app| {
SeasonDetailsUi::draw(f, app, f.area());
});
insta::assert_snapshot!(output);
insta::assert_snapshot!(
format!("loading_season_details_{active_sonarr_block}_{index}"),
output
);
}
#[test]
fn test_season_details_ui_renders_episodes_tab() {
let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::SeasonDetails.into());
app.data.sonarr_data.series = StatefulTable::default();
app.data.sonarr_data.series.set_items(vec![Series {
seasons: Some(vec![Season::default()]),
..Series::default()
}]);
#[rstest]
#[case(ActiveSonarrBlock::SeasonDetails, 0)]
#[case(ActiveSonarrBlock::SeasonHistory, 1)]
#[case(ActiveSonarrBlock::SeasonHistoryDetails, 1)]
#[case(ActiveSonarrBlock::ManualSeasonSearch, 2)]
fn test_season_details_ui_renders_empty(
#[case] active_sonarr_block: ActiveSonarrBlock,
#[case] index: usize,
) {
let mut app = App::test_default_fully_populated();
app.push_navigation_stack(active_sonarr_block.into());
{
let season_details_modal = app.data.sonarr_data.season_details_modal.as_mut().unwrap();
season_details_modal.season_releases = StatefulTable::default();
season_details_modal.season_history = StatefulTable::default();
season_details_modal.episodes = StatefulTable::default();
season_details_modal.season_details_tabs.set_index(index);
}
let output = render_to_string_with_app(TerminalSize::Large, &mut app, |f, app| {
SeasonDetailsUi::draw(f, app, f.area());
});
insta::assert_snapshot!(output);
insta::assert_snapshot!(
format!("empty_season_details_{active_sonarr_block}_{index}"),
output
);
}
#[test]
fn test_season_details_ui_renders_manual_search_tab() {
use crate::models::sonarr_models::{Episode, EpisodeFile, SonarrRelease};
let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::SeasonDetails.into());
app.data.sonarr_data.quality_profile_map = BiMap::from_iter(vec![(0, "Any".to_owned())]);
app.data.sonarr_data.language_profiles_map =
BiMap::from_iter(vec![(0, "English".to_owned())]);
app.data.sonarr_data.series = StatefulTable::default();
app.data.sonarr_data.series.set_items(vec![Series {
seasons: Some(vec![Season::default()]),
..Series::default()
}]);
app
.data
.sonarr_data
.seasons
.set_items(vec![Season::default()]);
let mut season_details_modal = SeasonDetailsModal::default();
season_details_modal.season_details_tabs.set_index(2);
season_details_modal
.episodes
.set_items(vec![Episode::default()]);
season_details_modal
.episode_files
.set_items(vec![EpisodeFile::default()]);
season_details_modal
.season_releases
.set_items(vec![SonarrRelease::default()]);
app.data.sonarr_data.season_details_modal = Some(season_details_modal);
let output = render_to_string_with_app(TerminalSize::Large, &mut app, |f, app| {
SeasonDetailsUi::draw(f, app, f.area());
});
insta::assert_snapshot!(output);
}
#[test]
fn test_season_details_ui_renders_season_history_tab() {
use crate::models::sonarr_models::{Episode, EpisodeFile, SonarrHistoryItem};
let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::SeasonDetails.into());
app.data.sonarr_data.quality_profile_map = BiMap::from_iter(vec![(0, "Any".to_owned())]);
app.data.sonarr_data.language_profiles_map =
BiMap::from_iter(vec![(0, "English".to_owned())]);
app.data.sonarr_data.series = StatefulTable::default();
app.data.sonarr_data.series.set_items(vec![Series {
seasons: Some(vec![Season::default()]),
..Series::default()
}]);
app
.data
.sonarr_data
.seasons
.set_items(vec![Season::default()]);
let mut season_details_modal = SeasonDetailsModal::default();
season_details_modal.season_details_tabs.set_index(1);
season_details_modal
.episodes
.set_items(vec![Episode::default()]);
season_details_modal
.episode_files
.set_items(vec![EpisodeFile::default()]);
season_details_modal
.season_history
.set_items(vec![SonarrHistoryItem::default()]);
app.data.sonarr_data.season_details_modal = Some(season_details_modal);
fn test_season_details_ui_renders_episode_details_over_season_details() {
let mut app = App::test_default_fully_populated();
app.push_navigation_stack(ActiveSonarrBlock::EpisodeDetails.into());
let output = render_to_string_with_app(TerminalSize::Large, &mut app, |f, app| {
SeasonDetailsUi::draw(f, app, f.area());
@@ -252,7 +252,7 @@ fn draw_seasons_table(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) {
let row = Row::new(vec![
Cell::from(season_monitored.to_owned()),
Cell::from(title.clone().unwrap()),
Cell::from(title.clone().unwrap_or_default()),
Cell::from(format!("{episode_file_count}/{episode_count}")),
Cell::from(format!("{size:.2} GB")),
]);
@@ -1,14 +1,11 @@
#[cfg(test)]
mod tests {
use bimap::BiMap;
use strum::IntoEnumIterator;
use crate::app::App;
use crate::models::servarr_data::sonarr::sonarr_data::{
ActiveSonarrBlock, EPISODE_DETAILS_BLOCKS, SEASON_DETAILS_BLOCKS, SERIES_DETAILS_BLOCKS,
};
use crate::models::sonarr_models::{Season, Series};
use crate::models::stateful_table::StatefulTable;
use crate::ui::DrawUi;
use crate::ui::sonarr_ui::library::series_details_ui::SeriesDetailsUi;
use crate::ui::ui_test_utils::test_utils::render_to_string_with_app;
@@ -29,27 +26,107 @@ mod tests {
}
mod snapshot_tests {
use crate::models::stateful_table::StatefulTable;
use crate::ui::ui_test_utils::test_utils::TerminalSize;
use rstest::rstest;
use super::*;
#[test]
fn test_series_details_ui_renders_series_details() {
let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::SeriesDetails.into());
app.data.sonarr_data.quality_profile_map = BiMap::from_iter(vec![(1, "HD-1080p".to_owned())]);
app.data.sonarr_data.language_profiles_map =
BiMap::from_iter(vec![(1, "English".to_owned())]);
app.data.sonarr_data.series = StatefulTable::default();
app.data.sonarr_data.series.set_items(vec![Series {
id: 1,
title: "Test Series".into(),
seasons: Some(vec![Season::default()]),
quality_profile_id: 1,
language_profile_id: 1,
..Series::default()
}]);
#[rstest]
#[case(ActiveSonarrBlock::SeriesDetails, 0)]
#[case(ActiveSonarrBlock::SeriesHistory, 1)]
#[case(ActiveSonarrBlock::SearchSeason, 0)]
#[case(ActiveSonarrBlock::SearchSeasonError, 0)]
#[case(ActiveSonarrBlock::UpdateAndScanSeriesPrompt, 0)]
#[case(ActiveSonarrBlock::UpdateAndScanSeriesPrompt, 1)]
#[case(ActiveSonarrBlock::AutomaticallySearchSeriesPrompt, 0)]
#[case(ActiveSonarrBlock::AutomaticallySearchSeriesPrompt, 1)]
#[case(ActiveSonarrBlock::SearchSeriesHistory, 1)]
#[case(ActiveSonarrBlock::SearchSeriesHistoryError, 1)]
#[case(ActiveSonarrBlock::FilterSeriesHistory, 1)]
#[case(ActiveSonarrBlock::FilterSeriesHistoryError, 1)]
#[case(ActiveSonarrBlock::SeriesHistorySortPrompt, 1)]
#[case(ActiveSonarrBlock::SeriesHistoryDetails, 1)]
fn test_series_details_ui_renders_series_details(
#[case] active_sonarr_block: ActiveSonarrBlock,
#[case] index: usize,
) {
let mut app = App::test_default_fully_populated();
app.push_navigation_stack(active_sonarr_block.into());
app.data.sonarr_data.series_info_tabs.set_index(index);
let output = render_to_string_with_app(TerminalSize::Large, &mut app, |f, app| {
SeriesDetailsUi::draw(f, app, f.area());
});
insta::assert_snapshot!(
format!("series_details_ui_{active_sonarr_block}_{index}"),
output
);
}
#[rstest]
#[case(ActiveSonarrBlock::SeriesDetails, 0)]
#[case(ActiveSonarrBlock::SeriesHistory, 1)]
fn test_series_details_ui_renders_series_details_loading(
#[case] active_sonarr_block: ActiveSonarrBlock,
#[case] index: usize,
) {
let mut app = App::test_default_fully_populated();
app.push_navigation_stack(active_sonarr_block.into());
app.data.sonarr_data.series_info_tabs.set_index(index);
app.is_loading = true;
let output = render_to_string_with_app(TerminalSize::Large, &mut app, |f, app| {
SeriesDetailsUi::draw(f, app, f.area());
});
insta::assert_snapshot!(
format!("loading_series_details_{active_sonarr_block}"),
output
);
}
#[rstest]
#[case(ActiveSonarrBlock::SeriesDetails, 0)]
#[case(ActiveSonarrBlock::SeriesHistory, 1)]
#[case(ActiveSonarrBlock::SeriesHistoryDetails, 1)]
fn test_series_details_ui_renders_series_details_empty(
#[case] active_sonarr_block: ActiveSonarrBlock,
#[case] index: usize,
) {
let mut app = App::test_default_fully_populated();
app.data.sonarr_data.seasons = StatefulTable::default();
app.data.sonarr_data.series_history = Some(StatefulTable::default());
app.data.sonarr_data.series_info_tabs.set_index(index);
app.push_navigation_stack(active_sonarr_block.into());
let output = render_to_string_with_app(TerminalSize::Large, &mut app, |f, app| {
SeriesDetailsUi::draw(f, app, f.area());
});
insta::assert_snapshot!(
format!("empty_series_details_{active_sonarr_block}"),
output
);
}
#[test]
fn test_series_details_ui_renders_season_details_over_series_details() {
let mut app = App::test_default_fully_populated();
app.push_navigation_stack(ActiveSonarrBlock::SeasonDetails.into());
let output = render_to_string_with_app(TerminalSize::Large, &mut app, |f, app| {
SeriesDetailsUi::draw(f, app, f.area());
});
insta::assert_snapshot!(output);
}
#[test]
fn test_series_details_ui_renders_episode_details_over_series_details() {
let mut app = App::test_default_fully_populated();
app.push_navigation_stack(ActiveSonarrBlock::EpisodeDetails.into());
let output = render_to_string_with_app(TerminalSize::Large, &mut app, |f, app| {
SeriesDetailsUi::draw(f, app, f.area());
@@ -0,0 +1,47 @@
---
source: src/ui/sonarr_ui/library/add_series_ui_tests.rs
expression: output
---
╭───────────────────────────────────────────────────── Add Series ─────────────────────────────────────────────────────╮
│something │
╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ ✔ Title Year Network Seasons Rating Genres │
│=> Test 2023 Prime Video 8.4 3 cool, family, fun │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ ╭─────────────── Error ───────────────╮ │
│ │This series is already in your library │ │
│ │ │ │
│ ╰───────────────────────────────────────╯ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
@@ -0,0 +1,47 @@
---
source: src/ui/sonarr_ui/library/add_series_ui_tests.rs
expression: output
---
╭───────────────────────────────────────────────────── Add Series ─────────────────────────────────────────────────────╮
│something │
╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ ╭─────────────── Error ───────────────╮ │
│ │ No series found matching your query! │ │
│ │ │ │
│ ╰───────────────────────────────────────╯ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
@@ -0,0 +1,48 @@
---
source: src/ui/sonarr_ui/library/add_series_ui_tests.rs
expression: output
---
╭────────────────────────────────────────── Add Series - Test ──────────────────────────────────────────╮
╭──────│ New series blah blah blah │───────╮
│someth│ │ │
╰──────│ │───────╯
╭──────│ │───────╮
│ ✔ │ │ │
│=> │ │ │
│ │ ╭─────────────────────────────────────────────────╮ │ │
│ │ Root Folder: │/nfs ▼ │ │ │
│ │ ╰─────────────────────────────────────────────────╯ │ │
│ │ ╭─────────────────────────────────────────────────╮ │ │
│ │ Monitor: │All Episodes ▼ │ │ │
│ │ ╰─────────────────────────────────────────────────╯ │ │
│ │ ╭─────────────────────────────────────────────────╮ │ │
│ │ Quality Profile: │Bluray-1080p ▼ │ │ │
│ │ ╰─────────────────────────────────────────────────╯ │ │
│ │ ╭─────────────────────────────────────────────────╮ │ │
│ │ Language Profile: │English ▼ │ │ │
│ │ ╰─────────────────────────────────────────────────╯ │ │
│ │ ╭─────────────────────────────────────────────────╮ │ │
│ │ Series Type: │Standard ▼ │ │ │
│ │ ╰─────────────────────────────────────────────────╯ │ │
│ │ ╭───╮ │ │
│ │ Season Folder: │ ✔ │ │ │
│ │ ╰───╯ │ │
│ │ ╭─────────────────────────────────────────────────╮ │ │
│ │ Tags: │alex │ │ │
│ │ ╰─────────────────────────────────────────────────╯ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │╭───────────────────────────────────────────────────╮╭──────────────────────────────────────────────────╮│ │
│ ││ Add ││ Cancel ││ │
╰──────│╰───────────────────────────────────────────────────╯╰──────────────────────────────────────────────────╯│───────╯
╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯
@@ -10,11 +10,11 @@ expression: output
╭───────────────────────────────────────────────────── Add Series ─────────────────────────────────────────────────────╮
something
╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
✔ Title Year Network Seasons Rating Genres
=> Test 2023 Prime Video 8.4 3 cool, family, fun
│ │
│ │
│ │
@@ -0,0 +1,48 @@
---
source: src/ui/sonarr_ui/library/add_series_ui_tests.rs
expression: output
---
╭────────────────────────────────────────── Add Series - Test ──────────────────────────────────────────╮
╭──────│ New series blah blah blah │───────╮
│someth│ │ │
╰──────│ │───────╯
╭──────│ │───────╮
│ ✔ │ │ │
│=> │ │ │
│ │ ╭─────────────────────────────────────────────────╮ │ │
│ │ Root Folder: │/nfs ▼ │ │ │
│ │ ╰─────────────────────────────────────────────────╯ │ │
│ │ ╭─────────────────────────────────────────────────╮ │ │
│ │ Monitor: │All Episodes ▼ │ │ │
│ │ ╭───────────────────────────────╮──────────────────────────────╯ │ │
│ │ │English │──────────────────────────────╮ │ │
│ │ Qual│ │ ▼ │ │ │
│ │ │ │──────────────────────────────╯ │ │
│ │ │ │──────────────────────────────╮ │ │
│ │ Langu│ │ ▼ │ │ │
│ │ │ │──────────────────────────────╯ │ │
│ │ │ │──────────────────────────────╮ │ │
│ │ │ │ ▼ │ │ │
│ │ │ │──────────────────────────────╯ │ │
│ │ │ │ │ │
│ │ Se│ │ │ │
│ │ │ │ │ │
│ │ │ │──────────────────────────────╮ │ │
│ │ ╰───────────────────────────────╯ │ │ │
│ │ ╰─────────────────────────────────────────────────╯ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │╭───────────────────────────────────────────────────╮╭──────────────────────────────────────────────────╮│ │
│ ││ Add ││ Cancel ││ │
╰──────│╰───────────────────────────────────────────────────╯╰──────────────────────────────────────────────────╯│───────╯
╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯

Some files were not shown because too many files have changed in this diff Show More