feat: Initial Lidarr support for searching for new artists
This commit is contained in:
@@ -198,6 +198,19 @@ pub struct SystemStatus {
|
||||
pub start_time: DateTime<Utc>,
|
||||
}
|
||||
|
||||
#[derive(Derivative, Serialize, Deserialize, Debug, Default, Clone, PartialEq, Eq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct AddArtistSearchResult {
|
||||
pub foreign_artist_id: String,
|
||||
pub artist_name: HorizontallyScrollableText,
|
||||
pub status: ArtistStatus,
|
||||
pub overview: Option<String>,
|
||||
pub artist_type: Option<String>,
|
||||
pub disambiguation: Option<String>,
|
||||
pub genres: Vec<String>,
|
||||
pub ratings: Option<Ratings>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Default, Clone, Eq, PartialEq)]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
pub struct DeleteArtistParams {
|
||||
@@ -229,6 +242,7 @@ impl From<LidarrSerdeable> for Serdeable {
|
||||
|
||||
serde_enum_from!(
|
||||
LidarrSerdeable {
|
||||
AddArtistSearchResults(Vec<AddArtistSearchResult>),
|
||||
Artist(Artist),
|
||||
Artists(Vec<Artist>),
|
||||
DiskSpaces(Vec<DiskSpace>),
|
||||
|
||||
@@ -5,8 +5,8 @@ mod tests {
|
||||
use serde_json::json;
|
||||
|
||||
use crate::models::lidarr_models::{
|
||||
DownloadRecord, DownloadStatus, DownloadsResponse, Member, MetadataProfile, NewItemMonitorType,
|
||||
SystemStatus,
|
||||
AddArtistSearchResult, DownloadRecord, DownloadStatus, DownloadsResponse, Member,
|
||||
MetadataProfile, NewItemMonitorType, SystemStatus,
|
||||
};
|
||||
use crate::models::servarr_models::{
|
||||
DiskSpace, HostConfig, QualityProfile, RootFolder, SecurityConfig, Tag,
|
||||
@@ -424,4 +424,72 @@ mod tests {
|
||||
);
|
||||
assert_str_eq!(DownloadStatus::Fallback.to_display_str(), "Fallback");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_add_artist_search_result_deserialization() {
|
||||
let search_result_json = json!({
|
||||
"foreignArtistId": "test-foreign-id",
|
||||
"artistName": "Test Artist",
|
||||
"status": "continuing",
|
||||
"overview": "Test overview",
|
||||
"artistType": "Group",
|
||||
"disambiguation": "UK Band",
|
||||
"genres": ["Rock", "Alternative"],
|
||||
"ratings": {
|
||||
"votes": 100,
|
||||
"value": 4.5
|
||||
}
|
||||
});
|
||||
|
||||
let search_result: AddArtistSearchResult = serde_json::from_value(search_result_json).unwrap();
|
||||
|
||||
assert_str_eq!(search_result.foreign_artist_id, "test-foreign-id");
|
||||
assert_str_eq!(search_result.artist_name.text, "Test Artist");
|
||||
assert_eq!(search_result.status, ArtistStatus::Continuing);
|
||||
assert_some_eq_x!(&search_result.overview, "Test overview");
|
||||
assert_some_eq_x!(&search_result.artist_type, "Group");
|
||||
assert_some_eq_x!(&search_result.disambiguation, "UK Band");
|
||||
assert_eq!(search_result.genres, vec!["Rock", "Alternative"]);
|
||||
assert_some!(&search_result.ratings);
|
||||
|
||||
let ratings = search_result.ratings.unwrap();
|
||||
assert_eq!(ratings.votes, 100);
|
||||
assert_eq!(ratings.value, 4.5);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_add_artist_search_result_with_optional_fields_none() {
|
||||
let search_result_json = json!({
|
||||
"foreignArtistId": "test-foreign-id",
|
||||
"artistName": "Test Artist",
|
||||
"status": "ended",
|
||||
"genres": []
|
||||
});
|
||||
|
||||
let search_result: AddArtistSearchResult = serde_json::from_value(search_result_json).unwrap();
|
||||
|
||||
assert_str_eq!(search_result.foreign_artist_id, "test-foreign-id");
|
||||
assert_str_eq!(search_result.artist_name.text, "Test Artist");
|
||||
assert_eq!(search_result.status, ArtistStatus::Ended);
|
||||
assert_none!(&search_result.overview);
|
||||
assert_none!(&search_result.artist_type);
|
||||
assert_none!(&search_result.disambiguation);
|
||||
assert!(search_result.genres.is_empty());
|
||||
assert_none!(&search_result.ratings);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_lidarr_serdeable_from_add_artist_search_results() {
|
||||
let search_results = vec![AddArtistSearchResult {
|
||||
foreign_artist_id: "test-id".to_owned(),
|
||||
..AddArtistSearchResult::default()
|
||||
}];
|
||||
|
||||
let lidarr_serdeable: LidarrSerdeable = search_results.clone().into();
|
||||
|
||||
assert_eq!(
|
||||
lidarr_serdeable,
|
||||
LidarrSerdeable::AddArtistSearchResults(search_results)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,8 +3,8 @@ use serde_json::Number;
|
||||
use super::modals::EditArtistModal;
|
||||
use crate::app::lidarr::lidarr_context_clues::ARTISTS_CONTEXT_CLUES;
|
||||
use crate::models::{
|
||||
BlockSelectionState, Route, TabRoute, TabState,
|
||||
lidarr_models::{Artist, DownloadRecord},
|
||||
BlockSelectionState, HorizontallyScrollableText, Route, TabRoute, TabState,
|
||||
lidarr_models::{AddArtistSearchResult, Artist, DownloadRecord},
|
||||
servarr_models::{DiskSpace, RootFolder},
|
||||
stateful_table::StatefulTable,
|
||||
};
|
||||
@@ -18,7 +18,8 @@ use {
|
||||
crate::models::stateful_table::SortOption,
|
||||
crate::network::lidarr_network::lidarr_network_test_utils::test_utils::quality_profile_map,
|
||||
crate::network::lidarr_network::lidarr_network_test_utils::test_utils::{
|
||||
download_record, metadata_profile, metadata_profile_map, quality_profile, root_folder, tags_map,
|
||||
add_artist_search_result, download_record, metadata_profile, metadata_profile_map,
|
||||
quality_profile, root_folder, tags_map,
|
||||
},
|
||||
crate::network::servarr_test_utils::diskspace,
|
||||
strum::{Display, EnumString, IntoEnumIterator},
|
||||
@@ -29,7 +30,9 @@ use {
|
||||
mod lidarr_data_tests;
|
||||
|
||||
pub struct LidarrData<'a> {
|
||||
pub add_artist_search: Option<HorizontallyScrollableText>,
|
||||
pub add_import_list_exclusion: bool,
|
||||
pub add_searched_artists: Option<StatefulTable<AddArtistSearchResult>>,
|
||||
pub artists: StatefulTable<Artist>,
|
||||
pub delete_artist_files: bool,
|
||||
pub disk_space_vec: Vec<DiskSpace>,
|
||||
@@ -82,7 +85,9 @@ impl LidarrData<'_> {
|
||||
impl<'a> Default for LidarrData<'a> {
|
||||
fn default() -> LidarrData<'a> {
|
||||
LidarrData {
|
||||
add_artist_search: None,
|
||||
add_import_list_exclusion: false,
|
||||
add_searched_artists: None,
|
||||
artists: StatefulTable::default(),
|
||||
delete_artist_files: false,
|
||||
disk_space_vec: Vec::new(),
|
||||
@@ -145,6 +150,10 @@ impl LidarrData<'_> {
|
||||
lidarr_data.downloads.set_items(vec![download_record()]);
|
||||
lidarr_data.root_folders.set_items(vec![root_folder()]);
|
||||
lidarr_data.version = "1.0.0".to_owned();
|
||||
lidarr_data.add_artist_search = Some("Test Artist".into());
|
||||
let mut add_searched_artists = StatefulTable::default();
|
||||
add_searched_artists.set_items(vec![add_artist_search_result()]);
|
||||
lidarr_data.add_searched_artists = Some(add_searched_artists);
|
||||
|
||||
lidarr_data
|
||||
}
|
||||
@@ -156,6 +165,9 @@ pub enum ActiveLidarrBlock {
|
||||
#[default]
|
||||
Artists,
|
||||
ArtistsSortPrompt,
|
||||
AddArtistEmptySearchResults,
|
||||
AddArtistSearchInput,
|
||||
AddArtistSearchResults,
|
||||
DeleteArtistPrompt,
|
||||
DeleteArtistConfirmPrompt,
|
||||
DeleteArtistToggleDeleteFile,
|
||||
@@ -185,6 +197,12 @@ pub static LIBRARY_BLOCKS: [ActiveLidarrBlock; 7] = [
|
||||
ActiveLidarrBlock::UpdateAllArtistsPrompt,
|
||||
];
|
||||
|
||||
pub static ADD_ARTIST_BLOCKS: [ActiveLidarrBlock; 3] = [
|
||||
ActiveLidarrBlock::AddArtistEmptySearchResults,
|
||||
ActiveLidarrBlock::AddArtistSearchInput,
|
||||
ActiveLidarrBlock::AddArtistSearchResults,
|
||||
];
|
||||
|
||||
pub static DELETE_ARTIST_BLOCKS: [ActiveLidarrBlock; 4] = [
|
||||
ActiveLidarrBlock::DeleteArtistPrompt,
|
||||
ActiveLidarrBlock::DeleteArtistConfirmPrompt,
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
mod tests {
|
||||
use crate::app::lidarr::lidarr_context_clues::ARTISTS_CONTEXT_CLUES;
|
||||
use crate::models::servarr_data::lidarr::lidarr_data::{
|
||||
DELETE_ARTIST_BLOCKS, DELETE_ARTIST_SELECTION_BLOCKS, EDIT_ARTIST_BLOCKS,
|
||||
ADD_ARTIST_BLOCKS, DELETE_ARTIST_BLOCKS, DELETE_ARTIST_SELECTION_BLOCKS, EDIT_ARTIST_BLOCKS,
|
||||
EDIT_ARTIST_SELECTION_BLOCKS,
|
||||
};
|
||||
use crate::models::{
|
||||
@@ -109,7 +109,9 @@ mod tests {
|
||||
fn test_lidarr_data_default() {
|
||||
let lidarr_data = LidarrData::default();
|
||||
|
||||
assert_none!(lidarr_data.add_artist_search);
|
||||
assert!(!lidarr_data.add_import_list_exclusion);
|
||||
assert_none!(lidarr_data.add_searched_artists);
|
||||
assert_is_empty!(lidarr_data.artists);
|
||||
assert!(!lidarr_data.delete_artist_files);
|
||||
assert_is_empty!(lidarr_data.disk_space_vec);
|
||||
@@ -151,6 +153,14 @@ mod tests {
|
||||
assert!(LIBRARY_BLOCKS.contains(&ActiveLidarrBlock::UpdateAllArtistsPrompt));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_add_artist_blocks_contents() {
|
||||
assert_eq!(ADD_ARTIST_BLOCKS.len(), 3);
|
||||
assert!(ADD_ARTIST_BLOCKS.contains(&ActiveLidarrBlock::AddArtistEmptySearchResults));
|
||||
assert!(ADD_ARTIST_BLOCKS.contains(&ActiveLidarrBlock::AddArtistSearchInput));
|
||||
assert!(ADD_ARTIST_BLOCKS.contains(&ActiveLidarrBlock::AddArtistSearchResults));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_delete_artist_blocks_contents() {
|
||||
assert_eq!(DELETE_ARTIST_BLOCKS.len(), 4);
|
||||
|
||||
Reference in New Issue
Block a user