feat: naive lidarr root folder tab implementation. Needs improved add logic

This commit is contained in:
2026-01-13 14:33:12 -07:00
parent c68cd75015
commit d2217509f2
32 changed files with 1718 additions and 24 deletions
@@ -87,11 +87,22 @@ mod tests {
assert_str_eq!(event.resource(), "/album");
}
#[rstest]
fn test_resource_root_folder(
#[values(
LidarrEvent::GetRootFolders,
LidarrEvent::DeleteRootFolder(0),
LidarrEvent::AddRootFolder(Default::default())
)]
event: LidarrEvent,
) {
assert_str_eq!(event.resource(), "/rootfolder");
}
#[rstest]
#[case(LidarrEvent::GetDiskSpace, "/diskspace")]
#[case(LidarrEvent::GetMetadataProfiles, "/metadataprofile")]
#[case(LidarrEvent::GetQualityProfiles, "/qualityprofile")]
#[case(LidarrEvent::GetRootFolders, "/rootfolder")]
#[case(LidarrEvent::GetStatus, "/system/status")]
#[case(LidarrEvent::GetTags, "/tag")]
#[case(LidarrEvent::HealthCheck, "/health")]
+14 -2
View File
@@ -5,7 +5,7 @@ use super::{NetworkEvent, NetworkResource};
use crate::models::lidarr_models::{
AddArtistBody, DeleteParams, EditArtistParams, LidarrSerdeable, MetadataProfile,
};
use crate::models::servarr_models::{QualityProfile, Tag};
use crate::models::servarr_models::{AddRootFolderBody, QualityProfile, Tag};
use crate::network::{Network, RequestMethod};
mod downloads;
@@ -25,10 +25,12 @@ pub mod lidarr_network_test_utils;
#[derive(Debug, Eq, PartialEq, Clone)]
pub enum LidarrEvent {
AddArtist(AddArtistBody),
AddRootFolder(AddRootFolderBody),
AddTag(String),
DeleteAlbum(DeleteParams),
DeleteArtist(DeleteParams),
DeleteDownload(i64),
DeleteRootFolder(i64),
DeleteTag(i64),
EditArtist(EditArtistParams),
GetAlbums(i64),
@@ -81,7 +83,9 @@ impl NetworkResource for LidarrEvent {
| LidarrEvent::UpdateDownloads => "/command",
LidarrEvent::GetMetadataProfiles => "/metadataprofile",
LidarrEvent::GetQualityProfiles => "/qualityprofile",
LidarrEvent::GetRootFolders => "/rootfolder",
LidarrEvent::GetRootFolders
| LidarrEvent::AddRootFolder(_)
| LidarrEvent::DeleteRootFolder(_) => "/rootfolder",
LidarrEvent::GetStatus => "/system/status",
LidarrEvent::HealthCheck => "/health",
LidarrEvent::SearchNewArtist(_) => "/artist/lookup",
@@ -102,6 +106,10 @@ impl Network<'_, '_> {
) -> Result<LidarrSerdeable> {
match lidarr_event {
LidarrEvent::AddTag(tag) => self.add_lidarr_tag(tag).await.map(LidarrSerdeable::from),
LidarrEvent::AddRootFolder(path) => self
.add_lidarr_root_folder(path)
.await
.map(LidarrSerdeable::from),
LidarrEvent::DeleteAlbum(params) => {
self.delete_album(params).await.map(LidarrSerdeable::from)
}
@@ -112,6 +120,10 @@ impl Network<'_, '_> {
.delete_lidarr_download(download_id)
.await
.map(LidarrSerdeable::from),
LidarrEvent::DeleteRootFolder(root_folder_id) => self
.delete_lidarr_root_folder(root_folder_id)
.await
.map(LidarrSerdeable::from),
LidarrEvent::DeleteTag(tag_id) => self
.delete_lidarr_tag(tag_id)
.await
@@ -1,19 +1,67 @@
#[cfg(test)]
mod tests {
use crate::models::lidarr_models::LidarrSerdeable;
use crate::models::servarr_models::RootFolder;
use crate::models::servarr_models::{AddRootFolderBody, RootFolder};
use crate::network::lidarr_network::LidarrEvent;
use crate::network::lidarr_network::lidarr_network_test_utils::test_utils::root_folder;
use crate::network::network_tests::test_utils::{MockServarrApi, test_network};
use pretty_assertions::assert_eq;
use serde_json::json;
#[tokio::test]
async fn test_handle_add_lidarr_root_folder_event() {
let expected_add_root_folder_body = AddRootFolderBody {
path: "/nfs/test".to_owned(),
};
let (mock, app, _server) = MockServarrApi::post()
.with_request_body(json!({
"path": "/nfs/test"
}))
.returns(json!({}))
.build_for(LidarrEvent::AddRootFolder(
expected_add_root_folder_body.clone(),
))
.await;
app.lock().await.server_tabs.set_index(2);
let mut network = test_network(&app);
assert!(
network
.handle_lidarr_event(LidarrEvent::AddRootFolder(expected_add_root_folder_body))
.await
.is_ok()
);
mock.assert_async().await;
assert!(app.lock().await.data.lidarr_data.edit_root_folder.is_none());
}
#[tokio::test]
async fn test_handle_delete_lidarr_root_folder_event() {
let (mock, app, _server) = MockServarrApi::delete()
.path("/1")
.build_for(LidarrEvent::DeleteRootFolder(1))
.await;
app.lock().await.server_tabs.set_index(2);
let mut network = test_network(&app);
assert!(
network
.handle_lidarr_event(LidarrEvent::DeleteRootFolder(1))
.await
.is_ok()
);
mock.assert_async().await;
}
#[tokio::test]
async fn test_handle_get_root_folders_event() {
let root_folders_json = json!([{
"id": 1,
"path": "/music",
"path": "/nfs",
"accessible": true,
"freeSpace": 50000000000i64
"freeSpace": 219902325555200i64
}]);
let response: Vec<RootFolder> = serde_json::from_value(root_folders_json.clone()).unwrap();
let (mock, app, _server) = MockServarrApi::get()
@@ -34,6 +82,9 @@ mod tests {
};
assert_eq!(root_folders, response);
assert!(!app.lock().await.data.lidarr_data.root_folders.is_empty());
assert_eq!(
app.lock().await.data.lidarr_data.root_folders.items,
vec![root_folder()]
);
}
}
+50 -4
View File
@@ -1,15 +1,61 @@
use anyhow::Result;
use log::info;
use crate::models::servarr_models::RootFolder;
use crate::models::servarr_models::{AddRootFolderBody, RootFolder};
use crate::network::lidarr_network::LidarrEvent;
use crate::network::{Network, RequestMethod};
use anyhow::Result;
use log::{debug, info};
use serde_json::Value;
#[cfg(test)]
#[path = "lidarr_root_folders_network_tests.rs"]
mod lidarr_root_folders_network_tests;
impl Network<'_, '_> {
pub(in crate::network::lidarr_network) async fn add_lidarr_root_folder(
&mut self,
add_root_folder_body: AddRootFolderBody,
) -> Result<Value> {
info!("Adding new root folder to Lidarr");
let event = LidarrEvent::AddRootFolder(AddRootFolderBody::default());
debug!("Add root folder body: {add_root_folder_body:?}");
let request_props = self
.request_props_from(
event,
RequestMethod::Post,
Some(add_root_folder_body),
None,
None,
)
.await;
self
.handle_request::<AddRootFolderBody, Value>(request_props, |_, _| ())
.await
}
pub(in crate::network::lidarr_network) async fn delete_lidarr_root_folder(
&mut self,
root_folder_id: i64,
) -> Result<()> {
let event = LidarrEvent::DeleteRootFolder(root_folder_id);
info!("Deleting Lidarr root folder for folder with id: {root_folder_id}");
let request_props = self
.request_props_from(
event,
RequestMethod::Delete,
None::<()>,
Some(format!("/{root_folder_id}")),
None,
)
.await;
self
.handle_request::<(), ()>(request_props, |_, _| ())
.await
}
pub(in crate::network::lidarr_network) async fn get_lidarr_root_folders(
&mut self,
) -> Result<Vec<RootFolder>> {