use crate::application::services::InterpolationService;
use crate::domain::{bookmark::Bookmark, error::DomainError, error::DomainResult};
use std::sync::Arc;
pub struct InterpolationHelper;
impl InterpolationHelper {
pub fn render_if_needed(
content: &str,
bookmark: &Bookmark,
service: &Arc<dyn InterpolationService>,
context_name: &str,
) -> DomainResult<String> {
if content.contains("{{") || content.contains("{%") {
service.render_bookmark_url(bookmark).map_err(|e| {
DomainError::Other(format!("Failed to render {}: {}", context_name, e))
})
} else {
Ok(content.to_string())
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::application::error::{ApplicationError, ApplicationResult};
use crate::application::services::InterpolationService;
use crate::domain::bookmark::Bookmark;
use std::sync::Arc;
#[derive(Debug)]
struct MockInterpolationService {
should_fail: bool,
}
impl InterpolationService for MockInterpolationService {
fn render_bookmark_url(&self, _bookmark: &Bookmark) -> ApplicationResult<String> {
if self.should_fail {
Err(ApplicationError::Other(
"Mock interpolation error".to_string(),
))
} else {
Ok("rendered content".to_string())
}
}
}
fn create_test_bookmark() -> Bookmark {
use chrono::Utc;
Bookmark::from_storage(
1,
"test content".to_string(),
"Test Bookmark".to_string(),
"Test description".to_string(),
"".to_string(), 0, Some(Utc::now()),
Utc::now(),
None, None, false, None, None, None, None, None, )
.unwrap()
}
#[test]
fn given_simple_content_when_render_if_needed_then_returns_unchanged() {
let bookmark = create_test_bookmark();
let service: Arc<dyn InterpolationService> =
Arc::new(MockInterpolationService { should_fail: false });
let content = "simple content without templates";
let result =
InterpolationHelper::render_if_needed(content, &bookmark, &service, "test").unwrap();
assert_eq!(result, "simple content without templates");
}
#[test]
fn given_template_content_when_render_if_needed_then_returns_interpolated() {
let bookmark = create_test_bookmark();
let service: Arc<dyn InterpolationService> =
Arc::new(MockInterpolationService { should_fail: false });
let content = "content with {{ template }}";
let result =
InterpolationHelper::render_if_needed(content, &bookmark, &service, "test").unwrap();
assert_eq!(result, "rendered content");
}
#[test]
fn given_template_content_when_render_fails_then_returns_original() {
let bookmark = create_test_bookmark();
let service: Arc<dyn InterpolationService> =
Arc::new(MockInterpolationService { should_fail: true });
let content = "content with {{ template }}";
let result =
InterpolationHelper::render_if_needed(content, &bookmark, &service, "shell script");
assert!(result.is_err());
assert!(result
.unwrap_err()
.to_string()
.contains("Failed to render shell script"));
}
#[test]
fn given_jinja_syntax_when_render_if_needed_then_handles_correctly() {
let bookmark = create_test_bookmark();
let service: Arc<dyn InterpolationService> =
Arc::new(MockInterpolationService { should_fail: false });
let content = "content with {% if condition %}";
let result =
InterpolationHelper::render_if_needed(content, &bookmark, &service, "test").unwrap();
assert_eq!(result, "rendered content");
}
}