use std::sync::Arc;
use async_trait::async_trait;
{% for imp in extra_imports %}{{ imp }}
{% endfor %}
use crate::domain::{{ snake }}::{
errors::{{ pascal }}Error,
model::{{ model_import }},
repository::{{ pascal }}RepositoryTrait,
use_cases::create_{{ snake }}::{Create{{ pascal }}Params, Create{{ pascal }}UseCaseTrait},
};
pub struct Create{{ pascal }}UseCaseImpl {
pub repository: Arc<dyn {{ pascal }}RepositoryTrait>,
}
#[async_trait]
impl Create{{ pascal }}UseCaseTrait for Create{{ pascal }}UseCaseImpl {
async fn execute(&self, params: Create{{ pascal }}Params) -> Result<{{ pascal }}, {{ pascal }}Error> {
tracing::info!("create_{{ snake }}: start");
{% if vo_constructions %}{{ vo_constructions }}{% endif %} let entity = {{ pascal }}::new({{ pascal }}Props {
{{ props_fields }}
}).inspect_err(|e| tracing::warn!(error = %e, "create_{{ snake }}: rejected"))?;
self.repository.save(&entity).await.inspect_err(|e| tracing::error!(error = %e, "create_{{ snake }}: repository failed"))?;
tracing::info!(id = %entity.id, "create_{{ snake }}: done");
Ok(entity)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::domain::{{ snake }}::repository::mocks::Mock{{ pascal }}Repository;
{{ test_imports }}
#[tokio::test]
async fn {{ valid_test_name }}() {
// Arrange
let mut mock_repo = Mock{{ pascal }}Repository::new();
mock_repo.expect_save().returning(|_| Ok(()));
let use_case = Create{{ pascal }}UseCaseImpl {
repository: Arc::new(mock_repo),
};
// Act
let result = use_case
.execute(Create{{ pascal }}Params {
{{ valid_params }}
})
.await;
// Assert
assert!(result.is_ok());{{ valid_assertion }}
}
{% for tc in validation_test_cases %}
#[tokio::test]
async fn {{ tc.test_name }}() {
// Arrange
let mock_repo = Mock{{ pascal }}Repository::new();
let use_case = Create{{ pascal }}UseCaseImpl {
repository: Arc::new(mock_repo),
};
// Act
let result = use_case
.execute(Create{{ pascal }}Params {
{{ tc.empty_params }}
})
.await;
// Assert
assert!(result.is_err());
assert_eq!(
result.unwrap_err().to_string(),
"{{ tc.error_str }}"
);
}
{% endfor %}}