diff --git a/src/network/readarr_network/library/books/mod.rs b/src/network/readarr_network/library/books/mod.rs index 8db329fd..eaa28f47 100644 --- a/src/network/readarr_network/library/books/mod.rs +++ b/src/network/readarr_network/library/books/mod.rs @@ -275,10 +275,34 @@ impl Network<'_, '_> { }) .await?; + info!("Fetching book editions for book with ID: {book_id}"); + + let editions_event = ReadarrEvent::GetBookEditions(book_id); + let request_props = self + .request_props_from( + editions_event, + RequestMethod::Get, + None::<()>, + None, + Some(format!("bookId={book_id}")), + ) + .await; + + let mut editions_response = String::new(); + + self + .handle_request::<(), Value>(request_props, |editions_body, _| { + editions_response = editions_body.to_string() + }) + .await?; + info!("Constructing toggle book monitoring body"); - match serde_json::from_str::(&response) { - Ok(mut detailed_book_body) => { + match ( + serde_json::from_str::(&response), + serde_json::from_str::(&editions_response), + ) { + (Ok(mut detailed_book_body), Ok(editions)) => { let monitored = detailed_book_body .get("monitored") .unwrap() @@ -286,6 +310,10 @@ impl Network<'_, '_> { .unwrap(); *detailed_book_body.get_mut("monitored").unwrap() = json!(!monitored); + detailed_book_body + .as_object_mut() + .unwrap() + .insert("editions".to_owned(), editions); debug!("Toggle book monitoring body: {detailed_book_body:?}"); @@ -303,8 +331,8 @@ impl Network<'_, '_> { .handle_request::(request_props, |_, _| ()) .await } - Err(_) => { - warn!("Request for detailed book body was interrupted"); + _ => { + warn!("Request for detailed book body or book editions was interrupted"); Ok(()) } } diff --git a/src/network/readarr_network/library/books/readarr_books_network_tests.rs b/src/network/readarr_network/library/books/readarr_books_network_tests.rs index 85c84849..7be0fdaf 100644 --- a/src/network/readarr_network/library/books/readarr_books_network_tests.rs +++ b/src/network/readarr_network/library/books/readarr_books_network_tests.rs @@ -1020,15 +1020,53 @@ mod tests { #[case] initial_monitored: bool, #[case] expected_monitored: bool, ) { + let editions_json = json!([ + { + "id": 2, + "bookId": 1, + "foreignEditionId": "test-foreign-edition-id-2", + "monitored": false, + "isEbook": false, + "title": "Second Edition", + "language": "eng", + "overview": "the second edition", + "format": "Hardcover", + "publisher": "Second Publisher", + "pageCount": 128, + "releaseDate": "2023-02-01T00:00:00Z", + "isbn13": "9780000000002", + "asin": "B000000002", + "ratings": { "votes": 15, "value": 8.4, "popularity": 1.2 } + }, + serde_json::from_str::(EDITION_JSON).unwrap() + ]); let mut book_json: Value = serde_json::from_str(BOOK_JSON).unwrap(); *book_json.get_mut("monitored").unwrap() = json!(initial_monitored); let mut expected_body = book_json.clone(); *expected_body.get_mut("monitored").unwrap() = json!(expected_monitored); + expected_body + .as_object_mut() + .unwrap() + .insert("editions".to_owned(), editions_json.clone()); let (async_details_server, app, mut server) = MockServarrApi::get() .returns(book_json) .path("/1") .build_for(ReadarrEvent::GetBookDetails(1)) .await; + let async_editions_server = server + .mock( + "GET", + format!( + "/api/v1{}?bookId=1", + ReadarrEvent::GetBookEditions(1).resource() + ) + .as_str(), + ) + .with_status(200) + .match_header("X-Api-Key", "test1234") + .with_body(editions_json.to_string()) + .create_async() + .await; let async_toggle_server = server .mock( "PUT", @@ -1051,8 +1089,10 @@ mod tests { .await; async_details_server.assert_async().await; + async_editions_server.assert_async().await; async_toggle_server.assert_async().await; assert_ok!(result); + assert_none!(app.lock().await.data.readarr_data.book_details_modal); } #[tokio::test] @@ -1063,6 +1103,20 @@ mod tests { .path("/1") .build_for(ReadarrEvent::GetBookDetails(1)) .await; + let async_editions_server = server + .mock( + "GET", + format!( + "/api/v1{}?bookId=1", + ReadarrEvent::GetBookEditions(1).resource() + ) + .as_str(), + ) + .with_status(200) + .match_header("X-Api-Key", "test1234") + .expect(0) + .create_async() + .await; let async_toggle_server = server .mock( "PUT", @@ -1085,6 +1139,55 @@ mod tests { .await; async_details_server.assert_async().await; + async_editions_server.assert_async().await; + async_toggle_server.assert_async().await; + assert_err!(result); + } + + #[tokio::test] + async fn test_handle_toggle_book_monitoring_event_editions_failure() { + let (async_details_server, app, mut server) = MockServarrApi::get() + .returns(serde_json::from_str(BOOK_JSON).unwrap()) + .path("/1") + .build_for(ReadarrEvent::GetBookDetails(1)) + .await; + let async_editions_server = server + .mock( + "GET", + format!( + "/api/v1{}?bookId=1", + ReadarrEvent::GetBookEditions(1).resource() + ) + .as_str(), + ) + .with_status(404) + .match_header("X-Api-Key", "test1234") + .with_body(json!([serde_json::from_str::(EDITION_JSON).unwrap()]).to_string()) + .create_async() + .await; + let async_toggle_server = server + .mock( + "PUT", + format!( + "/api/v1{}/1", + ReadarrEvent::ToggleBookMonitoring(1).resource() + ) + .as_str(), + ) + .with_status(202) + .match_header("X-Api-Key", "test1234") + .expect(0) + .create_async() + .await; + app.lock().await.server_tabs.set_index(3); + let mut network = test_network(&app); + + let result = network + .handle_readarr_event(ReadarrEvent::ToggleBookMonitoring(1)) + .await; + + async_details_server.assert_async().await; + async_editions_server.assert_async().await; async_toggle_server.assert_async().await; assert_err!(result); }