use std::error::Error;
use tracing::trace;
use crate::api::groups::{CreateGroup, DeleteGroup, Group, GroupWrapper, test::GROUP_LOCK};
use crate::api::projects::{
CreateProject, DeleteProject, GetProject, Project, ProjectWrapper, test::PROJECT_LOCK,
};
pub fn with_project<F>(name: &str, f: F) -> Result<(), Box<dyn Error>>
where
F: FnOnce(&crate::api::Redmine, u64, &str) -> Result<(), Box<dyn Error>>,
{
let _w_projects = PROJECT_LOCK.blocking_write();
dotenvy::dotenv()?;
let redmine = crate::api::Redmine::from_env(
reqwest::blocking::Client::builder()
.tls_backend_rustls()
.build()?,
)?;
let get_endpoint = GetProject::builder().project_id_or_name(name).build()?;
let get_result = redmine.json_response_body::<_, ProjectWrapper<Project>>(&get_endpoint);
trace!("Get result in {} test:\n{:?}", name, get_result);
if get_result.is_ok() {
let delete_endpoint = DeleteProject::builder().project_id_or_name(name).build()?;
redmine.ignore_response_body::<_>(&delete_endpoint)?;
}
let create_endpoint = CreateProject::builder()
.name(format!("Unittest redmine-api {name}"))
.identifier(name)
.enabled_module_names(vec![
"files".into(),
"issue_tracking".into(),
"news".into(),
"wiki".into(),
])
.build()?;
let ProjectWrapper { project } =
redmine.json_response_body::<_, ProjectWrapper<Project>>(&create_endpoint)?;
let current_user_endpoint = crate::api::my_account::GetMyAccount::builder().build()?;
let current_user_wrapper = redmine.json_response_body::<_, crate::api::users::UserWrapper<
crate::api::my_account::MyAccount,
>>(¤t_user_endpoint)?;
let current_user_id = current_user_wrapper.user.id;
let list_roles_endpoint = crate::api::roles::ListRoles::builder().build()?;
let roles_wrapper = redmine.json_response_body::<_, crate::api::roles::RolesWrapper<
crate::api::roles::RoleEssentials,
>>(&list_roles_endpoint)?;
let manager_role = roles_wrapper
.roles
.into_iter()
.find(|role| role.name.contains("Manager"))
.ok_or("No Manager role found")?;
let create_membership_endpoint =
crate::api::project_memberships::CreateProjectMembership::builder()
.project_id_or_name(project.id.to_string())
.user_ids(vec![current_user_id])
.role_ids(vec![manager_role.id])
.build()?;
redmine.ignore_response_body::<_>(&create_membership_endpoint)?;
let _fb = finally_block::finally(|| {
trace!(%name, "Deleting test project");
let delete_endpoint = DeleteProject::builder()
.project_id_or_name(name)
.build()
.unwrap_or_else(|_| panic!("Building delete endpoint for project {name} failed"));
redmine
.ignore_response_body::<_>(&delete_endpoint)
.unwrap_or_else(|_| panic!("Delete project {name} failed"));
});
trace!(%name, "Actual test body starts here");
f(&redmine, project.id, name)?;
trace!(%name, "Actual test body ends here");
Ok(())
}
pub fn with_group<F>(name: &str, f: F) -> Result<(), Box<dyn Error>>
where
F: FnOnce(&crate::api::Redmine, u64, &str) -> Result<(), Box<dyn Error>>,
{
let _w_groups = GROUP_LOCK.blocking_write();
dotenvy::dotenv()?;
let redmine = crate::api::Redmine::from_env(
reqwest::blocking::Client::builder()
.tls_backend_rustls()
.build()?,
)?;
let create_endpoint = CreateGroup::builder().name(name).build()?;
let GroupWrapper { group } =
redmine.json_response_body::<_, GroupWrapper<Group>>(&create_endpoint)?;
let id = group.id;
let _fb = finally_block::finally(|| {
trace!(%name, "Deleting test group");
let delete_endpoint = DeleteGroup::builder()
.id(id)
.build()
.unwrap_or_else(|_| panic!("Building delete endpoint for group {name} failed"));
redmine
.ignore_response_body::<_>(&delete_endpoint)
.unwrap_or_else(|_| panic!("Delete group {name} failed"));
});
trace!(%name, "Actual test body starts here");
f(&redmine, id, name)?;
trace!(%name, "Actual test body ends here");
Ok(())
}