use askama::Template;
use web_route::ParameterizedRoute;
use web_route::WebRoute;
use crate::project::domain::ProjectDescription;
use crate::project::domain::ProjectName;
use crate::render::domain::error::RenderDomainError;
#[derive(Debug, Template)]
#[template(path = "project_dashboard/index.html")]
pub struct ProjectDashboard {
pub projects: Vec<Project>,
}
impl ProjectDashboard {
pub fn from_domain_projects<P>(
projects: P,
default_render_route: &ParameterizedRoute,
) -> Result<Self, RenderDomainError>
where
P: IntoIterator<Item = crate::project::domain::Project>,
{
let projects = projects
.into_iter()
.map(|p| Project::from_domain_project(p, default_render_route))
.collect::<Result<Vec<_>, _>>()?;
Ok(Self { projects })
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct Project {
pub name: ProjectName,
pub description: Option<ProjectDescription>,
pub render_route: WebRoute,
}
impl Project {
pub fn from_domain_project(
project: crate::project::domain::Project,
default_render_route: &ParameterizedRoute,
) -> Result<Self, RenderDomainError> {
let render_route = default_render_route
.to_web_route(&serde_json::json!({"project_id": project.id}))
.map_err(|_e| RenderDomainError::InvalidRoutePopulation {
route: default_render_route.clone(),
})?;
Ok(Self {
name: project.name,
description: project.description,
render_route,
})
}
}
#[cfg(test)]
mod project_tests {
use fake::Fake;
use fake::Faker;
use super::*;
mod from_domain_project {
use super::*;
#[test]
fn should_create_a_valid_render_route() {
let domain_project = Faker.fake::<crate::project::domain::Project>();
let default_render_route =
ParameterizedRoute::new(Faker.fake::<WebRoute>()).join("/{project_id}");
let project =
Project::from_domain_project(domain_project.clone(), &default_render_route)
.unwrap();
assert!(
project
.render_route
.as_ref()
.contains(domain_project.id.as_str())
);
}
}
}