feat: Full CLI and TUI support for adding an artist to Lidarr
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
use serde_json::Number;
|
||||
|
||||
use super::modals::EditArtistModal;
|
||||
use super::modals::{AddArtistModal, EditArtistModal};
|
||||
use crate::app::lidarr::lidarr_context_clues::ARTISTS_CONTEXT_CLUES;
|
||||
use crate::models::{
|
||||
BlockSelectionState, HorizontallyScrollableText, Route, TabRoute, TabState,
|
||||
@@ -31,6 +31,7 @@ use {
|
||||
mod lidarr_data_tests;
|
||||
|
||||
pub struct LidarrData<'a> {
|
||||
pub add_artist_modal: Option<AddArtistModal>,
|
||||
pub add_artist_search: Option<HorizontallyScrollableText>,
|
||||
pub add_import_list_exclusion: bool,
|
||||
pub add_searched_artists: Option<StatefulTable<AddArtistSearchResult>>,
|
||||
@@ -92,6 +93,7 @@ impl LidarrData<'_> {
|
||||
impl<'a> Default for LidarrData<'a> {
|
||||
fn default() -> LidarrData<'a> {
|
||||
LidarrData {
|
||||
add_artist_modal: None,
|
||||
add_artist_search: None,
|
||||
add_import_list_exclusion: false,
|
||||
add_searched_artists: None,
|
||||
@@ -122,6 +124,25 @@ impl<'a> Default for LidarrData<'a> {
|
||||
#[cfg(test)]
|
||||
impl LidarrData<'_> {
|
||||
pub fn test_default_fully_populated() -> Self {
|
||||
let mut add_artist_modal = AddArtistModal {
|
||||
tags: "usenet, testing".into(),
|
||||
..AddArtistModal::default()
|
||||
};
|
||||
add_artist_modal
|
||||
.monitor_list
|
||||
.set_items(Vec::from_iter(MonitorType::iter()));
|
||||
add_artist_modal
|
||||
.monitor_new_items_list
|
||||
.set_items(Vec::from_iter(NewItemMonitorType::iter()));
|
||||
add_artist_modal
|
||||
.metadata_profile_list
|
||||
.set_items(vec![metadata_profile().name]);
|
||||
add_artist_modal
|
||||
.quality_profile_list
|
||||
.set_items(vec![quality_profile().name]);
|
||||
add_artist_modal
|
||||
.root_folder_list
|
||||
.set_items(vec![root_folder()]);
|
||||
let mut edit_artist_modal = EditArtistModal {
|
||||
monitored: Some(true),
|
||||
path: "/nfs/music".into(),
|
||||
@@ -144,6 +165,7 @@ impl LidarrData<'_> {
|
||||
quality_profile_map: quality_profile_map(),
|
||||
metadata_profile_map: metadata_profile_map(),
|
||||
edit_artist_modal: Some(edit_artist_modal),
|
||||
add_artist_modal: Some(add_artist_modal),
|
||||
tags_map: tags_map(),
|
||||
..LidarrData::default()
|
||||
};
|
||||
@@ -172,9 +194,18 @@ pub enum ActiveLidarrBlock {
|
||||
#[default]
|
||||
Artists,
|
||||
ArtistsSortPrompt,
|
||||
AddArtistAlreadyInLibrary,
|
||||
AddArtistConfirmPrompt,
|
||||
AddArtistEmptySearchResults,
|
||||
AddArtistPrompt,
|
||||
AddArtistSearchInput,
|
||||
AddArtistSearchResults,
|
||||
AddArtistSelectMetadataProfile,
|
||||
AddArtistSelectMonitor,
|
||||
AddArtistSelectMonitorNewItems,
|
||||
AddArtistSelectQualityProfile,
|
||||
AddArtistSelectRootFolder,
|
||||
AddArtistTagsInput,
|
||||
DeleteArtistPrompt,
|
||||
DeleteArtistConfirmPrompt,
|
||||
DeleteArtistToggleDeleteFile,
|
||||
@@ -204,10 +235,29 @@ pub static LIBRARY_BLOCKS: [ActiveLidarrBlock; 7] = [
|
||||
ActiveLidarrBlock::UpdateAllArtistsPrompt,
|
||||
];
|
||||
|
||||
pub static ADD_ARTIST_BLOCKS: [ActiveLidarrBlock; 3] = [
|
||||
pub static ADD_ARTIST_BLOCKS: [ActiveLidarrBlock; 12] = [
|
||||
ActiveLidarrBlock::AddArtistAlreadyInLibrary,
|
||||
ActiveLidarrBlock::AddArtistConfirmPrompt,
|
||||
ActiveLidarrBlock::AddArtistEmptySearchResults,
|
||||
ActiveLidarrBlock::AddArtistPrompt,
|
||||
ActiveLidarrBlock::AddArtistSearchInput,
|
||||
ActiveLidarrBlock::AddArtistSearchResults,
|
||||
ActiveLidarrBlock::AddArtistSelectMetadataProfile,
|
||||
ActiveLidarrBlock::AddArtistSelectMonitor,
|
||||
ActiveLidarrBlock::AddArtistSelectMonitorNewItems,
|
||||
ActiveLidarrBlock::AddArtistSelectQualityProfile,
|
||||
ActiveLidarrBlock::AddArtistSelectRootFolder,
|
||||
ActiveLidarrBlock::AddArtistTagsInput,
|
||||
];
|
||||
|
||||
pub const ADD_ARTIST_SELECTION_BLOCKS: &[&[ActiveLidarrBlock]] = &[
|
||||
&[ActiveLidarrBlock::AddArtistSelectRootFolder],
|
||||
&[ActiveLidarrBlock::AddArtistSelectMonitor],
|
||||
&[ActiveLidarrBlock::AddArtistSelectMonitorNewItems],
|
||||
&[ActiveLidarrBlock::AddArtistSelectQualityProfile],
|
||||
&[ActiveLidarrBlock::AddArtistSelectMetadataProfile],
|
||||
&[ActiveLidarrBlock::AddArtistTagsInput],
|
||||
&[ActiveLidarrBlock::AddArtistConfirmPrompt],
|
||||
];
|
||||
|
||||
pub static DELETE_ARTIST_BLOCKS: [ActiveLidarrBlock; 4] = [
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
mod tests {
|
||||
use crate::app::lidarr::lidarr_context_clues::ARTISTS_CONTEXT_CLUES;
|
||||
use crate::models::servarr_data::lidarr::lidarr_data::{
|
||||
ADD_ARTIST_BLOCKS, DELETE_ARTIST_BLOCKS, DELETE_ARTIST_SELECTION_BLOCKS, EDIT_ARTIST_BLOCKS,
|
||||
EDIT_ARTIST_SELECTION_BLOCKS,
|
||||
ADD_ARTIST_BLOCKS, ADD_ARTIST_SELECTION_BLOCKS, DELETE_ARTIST_BLOCKS,
|
||||
DELETE_ARTIST_SELECTION_BLOCKS, EDIT_ARTIST_BLOCKS, EDIT_ARTIST_SELECTION_BLOCKS,
|
||||
};
|
||||
use crate::models::{
|
||||
BlockSelectionState, Route,
|
||||
@@ -155,10 +155,54 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_add_artist_blocks_contents() {
|
||||
assert_eq!(ADD_ARTIST_BLOCKS.len(), 3);
|
||||
assert_eq!(ADD_ARTIST_BLOCKS.len(), 12);
|
||||
assert!(ADD_ARTIST_BLOCKS.contains(&ActiveLidarrBlock::AddArtistAlreadyInLibrary));
|
||||
assert!(ADD_ARTIST_BLOCKS.contains(&ActiveLidarrBlock::AddArtistConfirmPrompt));
|
||||
assert!(ADD_ARTIST_BLOCKS.contains(&ActiveLidarrBlock::AddArtistEmptySearchResults));
|
||||
assert!(ADD_ARTIST_BLOCKS.contains(&ActiveLidarrBlock::AddArtistPrompt));
|
||||
assert!(ADD_ARTIST_BLOCKS.contains(&ActiveLidarrBlock::AddArtistSearchInput));
|
||||
assert!(ADD_ARTIST_BLOCKS.contains(&ActiveLidarrBlock::AddArtistSearchResults));
|
||||
assert!(ADD_ARTIST_BLOCKS.contains(&ActiveLidarrBlock::AddArtistSelectMetadataProfile));
|
||||
assert!(ADD_ARTIST_BLOCKS.contains(&ActiveLidarrBlock::AddArtistSelectMonitor));
|
||||
assert!(ADD_ARTIST_BLOCKS.contains(&ActiveLidarrBlock::AddArtistSelectMonitorNewItems));
|
||||
assert!(ADD_ARTIST_BLOCKS.contains(&ActiveLidarrBlock::AddArtistSelectQualityProfile));
|
||||
assert!(ADD_ARTIST_BLOCKS.contains(&ActiveLidarrBlock::AddArtistSelectRootFolder));
|
||||
assert!(ADD_ARTIST_BLOCKS.contains(&ActiveLidarrBlock::AddArtistTagsInput));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_add_artist_selection_blocks_ordering() {
|
||||
let mut add_artist_block_iter = ADD_ARTIST_SELECTION_BLOCKS.iter();
|
||||
|
||||
assert_eq!(
|
||||
add_artist_block_iter.next().unwrap(),
|
||||
&[ActiveLidarrBlock::AddArtistSelectRootFolder]
|
||||
);
|
||||
assert_eq!(
|
||||
add_artist_block_iter.next().unwrap(),
|
||||
&[ActiveLidarrBlock::AddArtistSelectMonitor]
|
||||
);
|
||||
assert_eq!(
|
||||
add_artist_block_iter.next().unwrap(),
|
||||
&[ActiveLidarrBlock::AddArtistSelectMonitorNewItems]
|
||||
);
|
||||
assert_eq!(
|
||||
add_artist_block_iter.next().unwrap(),
|
||||
&[ActiveLidarrBlock::AddArtistSelectQualityProfile]
|
||||
);
|
||||
assert_eq!(
|
||||
add_artist_block_iter.next().unwrap(),
|
||||
&[ActiveLidarrBlock::AddArtistSelectMetadataProfile]
|
||||
);
|
||||
assert_eq!(
|
||||
add_artist_block_iter.next().unwrap(),
|
||||
&[ActiveLidarrBlock::AddArtistTagsInput]
|
||||
);
|
||||
assert_eq!(
|
||||
add_artist_block_iter.next().unwrap(),
|
||||
&[ActiveLidarrBlock::AddArtistConfirmPrompt]
|
||||
);
|
||||
assert_none!(add_artist_block_iter.next());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -2,13 +2,50 @@ use strum::IntoEnumIterator;
|
||||
|
||||
use super::lidarr_data::LidarrData;
|
||||
use crate::models::{
|
||||
HorizontallyScrollableText, lidarr_models::NewItemMonitorType, stateful_list::StatefulList,
|
||||
HorizontallyScrollableText,
|
||||
lidarr_models::{MonitorType, NewItemMonitorType},
|
||||
servarr_models::RootFolder,
|
||||
stateful_list::StatefulList,
|
||||
};
|
||||
|
||||
#[cfg(test)]
|
||||
#[path = "modals_tests.rs"]
|
||||
mod modals_tests;
|
||||
|
||||
#[derive(Default)]
|
||||
#[cfg_attr(test, derive(Debug))]
|
||||
pub struct AddArtistModal {
|
||||
pub root_folder_list: StatefulList<RootFolder>,
|
||||
pub monitor_list: StatefulList<MonitorType>,
|
||||
pub monitor_new_items_list: StatefulList<NewItemMonitorType>,
|
||||
pub quality_profile_list: StatefulList<String>,
|
||||
pub metadata_profile_list: StatefulList<String>,
|
||||
pub tags: HorizontallyScrollableText,
|
||||
}
|
||||
|
||||
impl From<&LidarrData<'_>> for AddArtistModal {
|
||||
fn from(lidarr_data: &LidarrData<'_>) -> AddArtistModal {
|
||||
let mut add_artist_modal = AddArtistModal::default();
|
||||
add_artist_modal
|
||||
.monitor_list
|
||||
.set_items(Vec::from_iter(MonitorType::iter()));
|
||||
add_artist_modal
|
||||
.monitor_new_items_list
|
||||
.set_items(Vec::from_iter(NewItemMonitorType::iter()));
|
||||
add_artist_modal
|
||||
.quality_profile_list
|
||||
.set_items(lidarr_data.sorted_quality_profile_names());
|
||||
add_artist_modal
|
||||
.metadata_profile_list
|
||||
.set_items(lidarr_data.sorted_metadata_profile_names());
|
||||
add_artist_modal
|
||||
.root_folder_list
|
||||
.set_items(lidarr_data.root_folders.items.to_vec());
|
||||
|
||||
add_artist_modal
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
#[cfg_attr(test, derive(Debug))]
|
||||
pub struct EditArtistModal {
|
||||
|
||||
@@ -3,9 +3,66 @@ mod tests {
|
||||
use bimap::BiMap;
|
||||
use pretty_assertions::{assert_eq, assert_str_eq};
|
||||
|
||||
use crate::models::lidarr_models::{Artist, NewItemMonitorType};
|
||||
use crate::models::lidarr_models::{Artist, MonitorType, NewItemMonitorType};
|
||||
use crate::models::servarr_data::lidarr::lidarr_data::LidarrData;
|
||||
use crate::models::servarr_data::lidarr::modals::EditArtistModal;
|
||||
use crate::models::servarr_data::lidarr::modals::{AddArtistModal, EditArtistModal};
|
||||
use crate::models::servarr_models::RootFolder;
|
||||
|
||||
#[test]
|
||||
fn test_add_artist_modal_from_lidarr_data() {
|
||||
let mut lidarr_data = LidarrData {
|
||||
quality_profile_map: BiMap::from_iter([
|
||||
(2i64, "Lossless".to_owned()),
|
||||
(1i64, "Standard".to_owned()),
|
||||
]),
|
||||
metadata_profile_map: BiMap::from_iter([
|
||||
(2i64, "None".to_owned()),
|
||||
(1i64, "Standard".to_owned()),
|
||||
]),
|
||||
..LidarrData::default()
|
||||
};
|
||||
let root_folder_1 = RootFolder {
|
||||
id: 1,
|
||||
path: "/nfs".to_owned(),
|
||||
accessible: true,
|
||||
free_space: 219902325555200,
|
||||
unmapped_folders: None,
|
||||
};
|
||||
lidarr_data.root_folders.set_items(vec![
|
||||
root_folder_1.clone(),
|
||||
RootFolder {
|
||||
id: 2,
|
||||
path: "/nfs2".to_owned(),
|
||||
accessible: true,
|
||||
free_space: 21990232555520,
|
||||
unmapped_folders: None,
|
||||
},
|
||||
]);
|
||||
|
||||
let add_artist_modal = AddArtistModal::from(&lidarr_data);
|
||||
|
||||
assert_eq!(
|
||||
*add_artist_modal.monitor_list.current_selection(),
|
||||
MonitorType::default()
|
||||
);
|
||||
assert_eq!(
|
||||
*add_artist_modal.monitor_new_items_list.current_selection(),
|
||||
NewItemMonitorType::default()
|
||||
);
|
||||
assert_str_eq!(
|
||||
add_artist_modal.quality_profile_list.current_selection(),
|
||||
"Standard"
|
||||
);
|
||||
assert_str_eq!(
|
||||
add_artist_modal.metadata_profile_list.current_selection(),
|
||||
"Standard"
|
||||
);
|
||||
assert_eq!(
|
||||
add_artist_modal.root_folder_list.current_selection(),
|
||||
&root_folder_1
|
||||
);
|
||||
assert_is_empty!(add_artist_modal.tags.text);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_edit_artist_modal_from_lidarr_data() {
|
||||
|
||||
Reference in New Issue
Block a user