diff --git a/CHANGELOG.md b/CHANGELOG.md index e4f704e..179df42 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ - Add bookmark folder to `SourceBookmark` and `TargetBookmark` - changed - Fix removing ignored urls + - Fix removed bookmarks in dry run - Update dependencies - removed diff --git a/src/bookmarks/bookmark_manager.rs b/src/bookmarks/bookmark_manager.rs index cc7e448..9dad121 100644 --- a/src/bookmarks/bookmark_manager.rs +++ b/src/bookmarks/bookmark_manager.rs @@ -142,11 +142,11 @@ impl BookmarkManager { }; if !added_bookmarks.is_empty() { - println!("Added {added_count} bookmarks"); + println!("Added {added_count} bookmarks{dry_run_str}"); } if !removed_bookmarks.is_empty() { - println!("Removed {removed_count} bookmarks"); + println!("Removed {removed_count} bookmarks{dry_run_str}"); } if added_bookmarks.is_empty() && removed_bookmarks.is_empty() { diff --git a/src/bookmarks/bookmark_service.rs b/src/bookmarks/bookmark_service.rs index 95d7d76..8f48d73 100644 --- a/src/bookmarks/bookmark_service.rs +++ b/src/bookmarks/bookmark_service.rs @@ -112,7 +112,8 @@ where | RunMode::FetchAll | RunMode::FetchUrls(_) | RunMode::FetchDiff(_) - | RunMode::Update => { + | RunMode::Update + | RunMode::DryRun => { self.execute_actions(bookmark_manager).await?; self.add_underlyings(bookmark_manager); @@ -186,9 +187,11 @@ where } for target_bookmark in bookmark_manager.target_bookmarks_mut().values_mut() { - match target_bookmark.status() { - Status::Removed => target_bookmark.set_action(Action::Remove), - Status::Added | Status::None => (), + if self.config.run_mode != RunMode::DryRun { + match target_bookmark.status() { + Status::Removed => target_bookmark.set_action(Action::Remove), + Status::Added | Status::None => (), + } } } @@ -200,7 +203,10 @@ where for bookmark in ignored_bookmarks { bookmark.set_status(Status::Removed); - bookmark.set_action(Action::Remove); + + if self.config.run_mode != RunMode::DryRun { + bookmark.set_action(Action::Remove); + } } } @@ -219,6 +225,10 @@ where .filter(|bookmark| bookmark.action() != &Action::None) .collect::>(); + if bookmarks.is_empty() { + return Ok(()); + } + { let mut report = self.report.lock(); report.set_total(bookmarks.len()); @@ -449,15 +459,17 @@ mod tests { cache } - fn create_mock_manager(urls: &[Url]) -> BookmarkManager { + fn create_mock_manager(urls: &[Url], status: &[Status]) -> BookmarkManager { let now = Utc::now(); let mut bookmark_manager = BookmarkManager::default(); + bookmark_manager.target_bookmarks_mut().insert( TargetBookmark::builder_with_id( "dd30381b-8e67-4e84-9379-0852f60a7cd7".to_owned(), urls[0].to_owned(), now, ) + .with_status(status[0].clone()) .with_action(Action::None) .build(), ); @@ -467,19 +479,119 @@ mod tests { urls[1].to_owned(), now, ) + .with_status(status[1].clone()) .with_action(Action::None) .build(), ); + if urls.len() == 3 { + bookmark_manager.target_bookmarks_mut().insert( + TargetBookmark::builder_with_id( + "a4d8f19b-92c1-4e68-a6e9-7d60b54024bc".to_owned(), + urls[2].to_owned(), + now, + ) + .with_status(status[2].clone()) + .with_action(Action::None) + .build(), + ); + } + bookmark_manager } + #[tokio::test] + async fn test_set_actions_import() { + let now = Utc::now(); + let url1 = Url::parse("https://url1.com").unwrap(); + let url2 = Url::parse("https://url2.com").unwrap(); + let url3 = Url::parse("https://url3.com").unwrap(); + let urls = vec![url1.clone(), url2.clone(), url3.clone()]; + let settings = Settings::default(); + let service_config = ServiceConfig::new( + RunMode::Import, + &settings.ignored_urls, + settings.max_concurrent_requests, + ) + .unwrap(); + let mut bookmark_manager = + create_mock_manager(&urls, &[Status::Added, Status::Removed, Status::None]); + let client = create_mock_client(&urls, "Test content"); + let cache = create_mock_cache(CacheMode::Html, None, &mut bookmark_manager).await; + let service = BookmarkService::new(service_config, client, cache); + + let res = service.set_actions(&mut bookmark_manager, now); + assert!(res.is_ok()); + + let bookmarks = bookmark_manager.target_bookmarks(); + assert_eq!(bookmarks.get(&url1).unwrap().action, Action::None); + assert_eq!(bookmarks.get(&url2).unwrap().action, Action::Remove); + assert_eq!(bookmarks.get(&url3).unwrap().action, Action::None); + } + + #[tokio::test] + async fn test_set_actions_fetch() { + let now = Utc::now(); + let url1 = Url::parse("https://url1.com").unwrap(); + let url2 = Url::parse("https://url2.com").unwrap(); + let url3 = Url::parse("https://url3.com").unwrap(); + let urls = vec![url1.clone(), url2.clone(), url3.clone()]; + let settings = Settings::default(); + let service_config = ServiceConfig::new( + RunMode::Fetch, + &settings.ignored_urls, + settings.max_concurrent_requests, + ) + .unwrap(); + let mut bookmark_manager = + create_mock_manager(&urls, &[Status::Added, Status::Removed, Status::None]); + let client = create_mock_client(&urls, "Test content"); + let cache = create_mock_cache(CacheMode::Html, None, &mut bookmark_manager).await; + let service = BookmarkService::new(service_config, client, cache); + + let res = service.set_actions(&mut bookmark_manager, now); + assert!(res.is_ok()); + + let bookmarks = bookmark_manager.target_bookmarks(); + assert_eq!(bookmarks.get(&url1).unwrap().action, Action::FetchAndAdd); + assert_eq!(bookmarks.get(&url2).unwrap().action, Action::Remove); + assert_eq!(bookmarks.get(&url3).unwrap().action, Action::FetchAndAdd); + } + + #[tokio::test] + async fn test_set_actions_dry_run() { + let now = Utc::now(); + let url1 = Url::parse("https://url1.com").unwrap(); + let url2 = Url::parse("https://url2.com").unwrap(); + let url3 = Url::parse("https://url3.com").unwrap(); + let urls = vec![url1.clone(), url2.clone(), url3.clone()]; + let settings = Settings::default(); + let service_config = ServiceConfig::new( + RunMode::DryRun, + &settings.ignored_urls, + settings.max_concurrent_requests, + ) + .unwrap(); + let mut bookmark_manager = + create_mock_manager(&urls, &[Status::Added, Status::Removed, Status::None]); + let client = create_mock_client(&urls, "Test content"); + let cache = create_mock_cache(CacheMode::Html, None, &mut bookmark_manager).await; + let service = BookmarkService::new(service_config, client, cache); + + let res = service.set_actions(&mut bookmark_manager, now); + assert!(res.is_ok()); + assert!(bookmark_manager + .target_bookmarks() + .values() + .any(|bookmark| bookmark.action == Action::DryRun)); + } + #[tokio::test] async fn test_process_fetch_ignored_urls() { + let now = Utc::now(); let url1 = Url::parse("https://url.com").unwrap(); let url2 = Url::parse("https://url.com/endpoint").unwrap(); let urls = vec![url1, url2]; - let now = Utc::now(); let settings = Settings::default(); let service_config = ServiceConfig::new( RunMode::Fetch, @@ -487,7 +599,7 @@ mod tests { settings.max_concurrent_requests, ) .unwrap(); - let mut bookmark_manager = create_mock_manager(&urls); + let mut bookmark_manager = create_mock_manager(&urls, &[Status::None, Status::None]); let client = create_mock_client(&urls, "Test content"); let cache = create_mock_cache(CacheMode::Html, None, &mut bookmark_manager).await; let service = BookmarkService::new(service_config, client, cache); @@ -510,7 +622,7 @@ mod tests { settings.max_concurrent_requests, ) .unwrap(); - let mut bookmark_manager = create_mock_manager(&urls); + let mut bookmark_manager = create_mock_manager(&urls, &[Status::None, Status::None]); let client = create_mock_client(&urls, "Test content"); let cache = create_mock_cache(CacheMode::Html, None, &mut bookmark_manager).await; let service = BookmarkService::new(service_config, client, cache); @@ -538,10 +650,10 @@ mod tests { #[tokio::test] async fn test_process_fetch_text() { + let now = Utc::now(); let url1 = Url::parse("https://url1.com").unwrap(); let url2 = Url::parse("https://url2.com").unwrap(); let urls = vec![url1, url2]; - let now = Utc::now(); let settings = Settings::default(); let service_config = ServiceConfig::new( RunMode::Fetch, @@ -549,7 +661,7 @@ mod tests { settings.max_concurrent_requests, ) .unwrap(); - let mut bookmark_manager = create_mock_manager(&urls); + let mut bookmark_manager = create_mock_manager(&urls, &[Status::None, Status::None]); let client = create_mock_client(&urls, "Test content"); let cache = create_mock_cache(CacheMode::Text, None, &mut bookmark_manager).await; let service = BookmarkService::new(service_config, client, cache); @@ -577,10 +689,10 @@ mod tests { #[tokio::test] async fn test_process_fetch_cached_html() { + let now = Utc::now(); let url1 = Url::parse("https://url1.com").unwrap(); let url2 = Url::parse("https://url2.com").unwrap(); let urls = vec![url1, url2]; - let now = Utc::now(); let settings = Settings::default(); let service_config = ServiceConfig::new( RunMode::Fetch, @@ -588,7 +700,7 @@ mod tests { settings.max_concurrent_requests, ) .unwrap(); - let mut bookmark_manager = create_mock_manager(&urls); + let mut bookmark_manager = create_mock_manager(&urls, &[Status::None, Status::None]); let client = create_mock_client(&urls, "Test content (fetched)"); let cache = create_mock_cache( CacheMode::Html, @@ -623,10 +735,10 @@ mod tests { #[tokio::test] async fn test_process_fetch_cached_text() { + let now = Utc::now(); let url1 = Url::parse("https://url1.com").unwrap(); let url2 = Url::parse("https://url2.com").unwrap(); let urls = vec![url1, url2]; - let now = Utc::now(); let settings = Settings::default(); let service_config = ServiceConfig::new( RunMode::Fetch, @@ -634,7 +746,7 @@ mod tests { settings.max_concurrent_requests, ) .unwrap(); - let mut bookmark_manager = create_mock_manager(&urls); + let mut bookmark_manager = create_mock_manager(&urls, &[Status::None, Status::None]); let client = create_mock_client(&urls, "Test content (fetched)"); let cache = create_mock_cache( CacheMode::Text, diff --git a/src/bookmarks/mod.rs b/src/bookmarks/mod.rs index 77182ad..6233ba2 100644 --- a/src/bookmarks/mod.rs +++ b/src/bookmarks/mod.rs @@ -315,7 +315,13 @@ impl From<&TargetBookmarks> for JsonBookmarks { fn from(target_bookmarks: &TargetBookmarks) -> Self { let mut bookmarks = target_bookmarks .values() - .filter(|bookmark| bookmark.action() != &Action::DryRun) + .filter(|bookmark| { + if bookmark.action() == &Action::DryRun { + bookmark.status() == &Status::None + } else { + true + } + }) .map(JsonBookmark::from) .collect::>(); bookmarks.sort_by(Self::compare);