use bkmr::cli::args::{Cli, Commands};
use bkmr::domain::repositories::repository::BookmarkRepository;
use bkmr::domain::tag::Tag;
use bkmr::infrastructure::repositories::sqlite::repository::SqliteBookmarkRepository;
use bkmr::util::test_service_container::TestServiceContainer;
use bkmr::util::testing::{init_test_env, EnvGuard};
use std::collections::HashSet;
use std::io::Write;
use tempfile::NamedTempFile;
fn create_test_repository() -> SqliteBookmarkRepository {
let repository = bkmr::util::testing::setup_test_db();
repository
.empty_bookmark_table()
.expect("Could not empty bookmark table");
repository
}
#[test]
fn given_stdin_content_when_add_command_with_stdin_flag_then_stores_content_in_url_column() {
let _env = init_test_env();
let _guard = EnvGuard::new();
let repository = create_test_repository();
let test_container = TestServiceContainer::new();
let bookmark_service = test_container.bookmark_service;
let mut temp_file = NamedTempFile::new().unwrap();
let test_content = "echo 'Hello from stdin test!'";
temp_file.write_all(test_content.as_bytes()).unwrap();
temp_file.flush().unwrap();
let _cli = Cli {
name: None,
config: None,
debug: 0,
openai: false,
no_color: false,
generate_config: false,
command: Some(Commands::Add {
url: None,
tags: Some("test,stdin".to_string()),
title: Some("test_stdin_command".to_string()),
desc: None,
no_web: true,
edit: false,
bookmark_type: "shell".to_string(),
clone_id: None,
stdin: true,
open_with: None,
}),
};
let final_content = test_content.to_string();
let mut tag_set = HashSet::new();
tag_set.insert(Tag::new("test").unwrap());
tag_set.insert(Tag::new("stdin").unwrap());
tag_set.insert(Tag::new("_shell_").unwrap());
let bookmark = bookmark_service
.add_bookmark(
&final_content,
Some("test_stdin_command"),
None,
Some(&tag_set),
false,
)
.unwrap();
assert!(bookmark.id.is_some(), "Bookmark should have an ID");
assert_eq!(
bookmark.url, test_content,
"URL should contain the stdin content"
);
assert_eq!(bookmark.title, "test_stdin_command", "Title should match");
assert_eq!(bookmark.description, "", "Description should be empty");
assert!(
bookmark.tags.contains(&Tag::new("_shell_").unwrap()),
"Should have shell tag"
);
assert!(
bookmark.tags.contains(&Tag::new("test").unwrap()),
"Should have test tag"
);
assert!(
bookmark.tags.contains(&Tag::new("stdin").unwrap()),
"Should have stdin tag"
);
let stored_bookmark = repository.get_by_id(bookmark.id.unwrap()).unwrap().unwrap();
assert_eq!(
stored_bookmark.url, test_content,
"Stored URL should contain the stdin content"
);
}
#[test]
fn given_shell_bookmark_when_open_command_with_no_edit_flag_then_executes_without_interaction() {
let _env = init_test_env();
let _guard = EnvGuard::new();
let repository = create_test_repository();
let test_container = TestServiceContainer::new();
let bookmark_service = test_container.bookmark_service;
let action_service = test_container.action_service;
let mut tag_set = HashSet::new();
tag_set.insert(Tag::new("_shell_").unwrap());
tag_set.insert(Tag::new("test").unwrap());
let test_script = "echo 'Test script executed'";
let bookmark = bookmark_service
.add_bookmark(
test_script,
Some("test_no_edit"),
None,
Some(&tag_set),
false,
)
.unwrap();
let bookmark_id = bookmark.id.unwrap();
let _cli = Cli {
name: None,
config: None,
debug: 0,
openai: false,
no_color: false,
generate_config: false,
command: Some(Commands::Open {
ids: bookmark_id.to_string(),
no_edit: true,
file: false,
script_args: vec![],
stdout: false,
}),
};
let stored_bookmark = bookmark_service.get_bookmark(bookmark_id).unwrap().unwrap();
let result = action_service.execute_default_action_with_options(&stored_bookmark, true, &[]);
assert!(
result.is_ok(),
"Should execute successfully with no-edit flag"
);
let updated_bookmark = repository.get_by_id(bookmark_id).unwrap().unwrap();
assert_eq!(
updated_bookmark.access_count, 1,
"Access count should be incremented"
);
}
#[test]
fn given_non_shell_bookmark_when_open_command_with_no_edit_flag_then_executes_normally() {
let _env = init_test_env();
let _guard = EnvGuard::new();
let repository = create_test_repository();
let test_container = TestServiceContainer::new();
let bookmark_service = test_container.bookmark_service;
let action_service = test_container.action_service;
let tag_set = HashSet::new();
let test_url = "https://example.com";
let bookmark = bookmark_service
.add_bookmark(
test_url,
Some("test_url_no_edit"),
None,
Some(&tag_set),
false,
)
.unwrap();
let bookmark_id = bookmark.id.unwrap();
let stored_bookmark = bookmark_service.get_bookmark(bookmark_id).unwrap().unwrap();
let result = action_service.execute_default_action_with_options(&stored_bookmark, true, &[]);
assert!(
result.is_ok(),
"Should execute successfully even for non-shell bookmarks"
);
let updated_bookmark = repository.get_by_id(bookmark_id).unwrap().unwrap();
assert_eq!(
updated_bookmark.access_count, 1,
"Access count should be incremented"
);
}
#[test]
fn given_add_command_with_stdin_and_type_shell_when_executed_then_creates_shell_bookmark() {
let _env = init_test_env();
let _guard = EnvGuard::new();
let repository = create_test_repository();
let test_container = TestServiceContainer::new();
let bookmark_service = test_container.bookmark_service;
let test_script = "#!/bin/bash\necho 'Complex shell script'\nls -la";
let title = "complex_shell_script";
let mut tag_set = HashSet::new();
tag_set.insert(Tag::new("_shell_").unwrap());
tag_set.insert(Tag::new("automation").unwrap());
tag_set.insert(Tag::new("test").unwrap());
let bookmark = bookmark_service
.add_bookmark(test_script, Some(title), None, Some(&tag_set), false)
.unwrap();
assert!(bookmark.id.is_some(), "Bookmark should have an ID");
assert_eq!(
bookmark.url, test_script,
"URL should contain the script content"
);
assert_eq!(bookmark.title, title, "Title should match");
assert_eq!(
bookmark.description, "",
"Description should be empty for stdin input"
);
assert!(
bookmark.tags.contains(&Tag::new("_shell_").unwrap()),
"Should have shell tag"
);
let stored_bookmark = repository.get_by_id(bookmark.id.unwrap()).unwrap().unwrap();
assert_eq!(
stored_bookmark.url, test_script,
"Stored script should match input"
);
assert!(
stored_bookmark.tags.contains(&Tag::new("_shell_").unwrap()),
"Should be tagged as shell"
);
}
#[test]
fn given_stdin_with_multiline_content_when_add_command_then_preserves_formatting() {
let _env = init_test_env();
let _guard = EnvGuard::new();
let repository = create_test_repository();
let test_container = TestServiceContainer::new();
let bookmark_service = test_container.bookmark_service;
let multiline_content = "#!/bin/bash\n\n# This is a comment\necho 'Line 1'\necho 'Line 2'\n\n# Another comment\necho 'Line 3'";
let title = "multiline_script";
let mut tag_set = HashSet::new();
tag_set.insert(Tag::new("_shell_").unwrap());
tag_set.insert(Tag::new("multiline").unwrap());
let bookmark = bookmark_service
.add_bookmark(multiline_content, Some(title), None, Some(&tag_set), false)
.unwrap();
assert_eq!(
bookmark.url, multiline_content,
"Multiline content should be preserved exactly"
);
let stored_bookmark = repository.get_by_id(bookmark.id.unwrap()).unwrap().unwrap();
assert_eq!(
stored_bookmark.url, multiline_content,
"Stored multiline content should match"
);
assert!(
stored_bookmark.url.contains('\n'),
"Should preserve newlines"
);
assert!(
stored_bookmark.url.contains("# This is a comment"),
"Should preserve comments"
);
}