111 lines
2.9 KiB
Rust
111 lines
2.9 KiB
Rust
use crate::app_core::{
|
|
components::ingredient::Ingredient,
|
|
port::repo::{FindOneError, IngredientRepoPort},
|
|
shared::lib::UseCase,
|
|
};
|
|
|
|
#[derive(Default, Debug)]
|
|
pub struct Request {
|
|
pub key: String,
|
|
}
|
|
|
|
type Response = Ingredient;
|
|
|
|
#[derive(Debug, thiserror::Error)]
|
|
pub enum Error {
|
|
#[error("Ingredient not found")]
|
|
NotFound,
|
|
|
|
#[error("Unknown error")]
|
|
Unknown,
|
|
}
|
|
|
|
pub trait FetchOneIngredientUseCase: UseCase<Request, Response, Error> {}
|
|
|
|
#[derive(Provider)]
|
|
#[shaku(interface = FetchOneIngredientUseCase)]
|
|
pub struct FetchOneIngredient {
|
|
#[shaku(provide)]
|
|
ingredient_repo: Box<dyn IngredientRepoPort>,
|
|
}
|
|
|
|
#[async_trait]
|
|
impl UseCase<Request, Response, Error> for FetchOneIngredient {
|
|
async fn execute(&self, req: Request) -> Result<Response, Error> {
|
|
self.ingredient_repo
|
|
.find_one(&req.key)
|
|
.await
|
|
.map_err(|e| match e {
|
|
FindOneError::Unknown => Error::Unknown,
|
|
FindOneError::NotFound => Error::NotFound,
|
|
})
|
|
}
|
|
}
|
|
|
|
impl FetchOneIngredientUseCase for FetchOneIngredient {}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
use crate::{
|
|
domain::{Context, Lang},
|
|
repo::ingredient::InMemoryIngredientRepo,
|
|
};
|
|
|
|
#[test]
|
|
fn should_return_ingredient() {
|
|
let repo = InMemoryIngredientRepo::new();
|
|
let res = execute(&repo, &Context::default(), String::from("apple"));
|
|
|
|
match res {
|
|
Ok(apple) => {
|
|
assert_eq!(apple.key, String::from("apple"));
|
|
assert_eq!(apple.lang, Lang::Rus);
|
|
assert_eq!(apple.name, String::from("Яблоко"));
|
|
}
|
|
_ => unimplemented!(),
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn should_return_ingredient_with_choosed_lang() {
|
|
let repo = InMemoryIngredientRepo::new();
|
|
let res = execute(&repo, &Context::eng(), String::from("apple"));
|
|
|
|
match res {
|
|
Ok(apple) => {
|
|
assert_eq!(apple.key, String::from("apple"));
|
|
assert_eq!(apple.lang, Lang::Eng);
|
|
assert_eq!(apple.name, String::from("Apple"));
|
|
}
|
|
_ => unimplemented!(),
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn should_return_ingredient_with_fallback_lang() {
|
|
let repo = InMemoryIngredientRepo::new();
|
|
let res = execute(&repo, &Context::eng(), String::from("orange"));
|
|
|
|
match res {
|
|
Ok(orange) => {
|
|
assert_eq!(orange.key, String::from("orange"));
|
|
assert_eq!(orange.lang, Lang::Rus);
|
|
assert_eq!(orange.name, String::from("Апельсин"));
|
|
}
|
|
_ => unimplemented!(),
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn should_throw_not_found_error() {
|
|
let repo = InMemoryIngredientRepo::new();
|
|
let res = execute(&repo, &Context::default(), String::from("wildberries"));
|
|
|
|
match res {
|
|
Err(ResponseError::NotFound) => {}
|
|
_ => unimplemented!(),
|
|
}
|
|
}
|
|
}
|