use std::sync::Arc;
use business::application::greeting::get_greeting::GetGreetingUseCaseImpl;
use business::domain::greeting::repository::GreetingRepositoryTrait;
use infrastructure::greeting::repository::InMemoryGreetingRepository;
use poem::Endpoint;
use poem_openapi::OpenApiService;
use crate::api::greeting::routes::GreetingApi;
pub async fn build_app(config: puerto_web::Config) -> Result<impl Endpoint, String> {
let get_greeting = Arc::new(GetGreetingUseCaseImpl { repository: Arc::new(InMemoryGreetingRepository::new()) as Arc<dyn GreetingRepositoryTrait> });
let greeting_api = GreetingApi { get_greeting };
let ready = puerto_web::health::always_ready();
Ok(crate::app::configure(puerto_web::routes(
openapi_service(greeting_api),
&config,
ready,
)))
}
fn openapi_service<T: poem_openapi::OpenApi>(api: T) -> OpenApiService<T, ()> {
OpenApiService::new(api, env!("CARGO_PKG_NAME"), env!("CARGO_PKG_VERSION"))
}
#[cfg(test)]
mod tests {
use super::*;
use business::domain::greeting::use_cases::get_greeting::mocks::MockGetGreetingUseCase;
const OPENAPI_JSON: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/../docs/api/openapi.json");
#[test]
fn openapi_spec_matches_docs_api_openapi_json() {
let greeting_api = GreetingApi { get_greeting: Arc::new(MockGetGreetingUseCase::new()) };
let spec = openapi_service(greeting_api).spec();
let path = std::path::Path::new(OPENAPI_JSON);
if std::env::var_os("UPDATE_OPENAPI").is_some() || !path.exists() {
let dir = path.parent().expect("docs/api/openapi.json has a parent");
std::fs::create_dir_all(dir).expect("create docs/api");
std::fs::write(path, &spec).expect("write docs/api/openapi.json");
return;
}
let committed = std::fs::read_to_string(path).expect("read docs/api/openapi.json");
assert!(
committed == spec,
"docs/api/openapi.json is not the API this code serves: run `make web/sync`"
);
}
}