recipes/api/src/domain/ingredient/fetch_by_key.rs

98 lines
2.5 KiB
Rust

use super::types;
use crate::domain::misc_types;
use crate::repo::ingredient::IngredientRepo;
#[derive(Default, Debug)]
pub struct RequestOpts {
pub lang: Option<misc_types::Lang>,
}
pub enum ResponseError {
NotFound,
}
pub fn execute(
repo: &impl IngredientRepo,
key: String,
opts: RequestOpts,
) -> Result<types::Ingredient, ResponseError> {
match repo.get_ingredient_opt(key, opts.into()) {
Some(ing) => Ok(ing),
_ => Err(ResponseError::NotFound),
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{domain::misc_types::Lang, repo::ingredient::InMemoryIngredientRepo};
#[test]
fn should_return_ingredient() {
let repo = InMemoryIngredientRepo::new();
let res = execute(&repo, String::from("apple"), RequestOpts::default());
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,
String::from("apple"),
RequestOpts {
lang: Some(Lang::Eng),
},
);
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,
String::from("orange"),
RequestOpts {
lang: Some(Lang::Eng),
},
);
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, String::from("wildberries"), RequestOpts::default());
match res {
Err(ResponseError::NotFound) => {}
_ => unimplemented!(),
}
}
}