use crate::regexes::COUCHDB_DB_RULE;
use awc::Client;
pub mod errors;
use errors::DBCreationError;
pub async fn create_db(
client: &Client,
db_name: &str,
host: &str,
) -> Result<bool, Box<dyn std::error::Error>> {
if !COUCHDB_DB_RULE.is_match(db_name) {
return Err(Box::new(DBCreationError::new(&format!(
"{} string doesn't respect the regex rule {}",
db_name,
COUCHDB_DB_RULE.as_str()
))));
}
let uri: String = format!("{}/{}", host, db_name,);
match client.put(&uri).send().await {
Ok(mut response) => {
if response.status().as_u16() >= 400 {
let bytes: Vec<u8> = response.body().await?.iter().cloned().collect();
let error: serde_json::Value =
serde_json::from_str(std::str::from_utf8(bytes.as_slice()).unwrap()).unwrap();
Err(Box::new(DBCreationError::new(&format!(
"Error with the request to {}: error: \n{}",
&uri, error
))))
} else {
Ok(true)
}
}
Err(error) => Err(Box::new(DBCreationError::new(&format!(
"Error with the request to {}: error: \n{}",
host, error
)))),
}
}
#[cfg(test)]
mod tests {
extern crate actix_web;
extern crate wiremock;
use super::*;
use actix_web::test;
use dotenv::dotenv;
use serde_json::Value;
use std::error::Error;
use wiremock::matchers::{method, path};
use wiremock::{Mock, MockServer, ResponseTemplate};
#[actix_rt::test]
async fn create_db_regex_error_test() {
let client: Client = Client::default();
let box_result: Box<dyn Error> = create_db(&client, "Test", "").await.unwrap_err();
let result: &DBCreationError = box_result.downcast_ref().unwrap();
assert_eq!(
format!("{}", result),
format!(
"DBCreationError: {} string doesn't respect the regex rule {}",
"Test",
COUCHDB_DB_RULE.as_str()
)
);
let box_result: Box<dyn Error> = create_db(&client, "testT", "").await.unwrap_err();
let result: &DBCreationError = box_result.downcast_ref().unwrap();
assert_eq!(
format!("{}", result),
format!(
"DBCreationError: {} string doesn't respect the regex rule {}",
"testT",
COUCHDB_DB_RULE.as_str()
)
)
}
#[actix_rt::test]
async fn create_db_http_error_test() {
let mock_server = MockServer::start().await;
let data = r#"
{
"error": "test error"
}"#;
let response_template: ResponseTemplate =
ResponseTemplate::new(400).set_body_raw(data.as_bytes(), "application/json");
Mock::given(method("PUT"))
.and(path("/test"))
.respond_with(response_template)
.mount(&mock_server)
.await;
let error: serde_json::Value = serde_json::from_str(data).unwrap();
let client: Client = Client::default();
let host: String = mock_server.uri();
let box_result: Box<dyn Error> = create_db(&client, "test", &host).await.unwrap_err();
let result: &DBCreationError = box_result.downcast_ref().unwrap();
assert_eq!(
format!("{}", result),
format!(
"DBCreationError: Error with the request to {}: error: \n{}",
format!("{}/{}", host, "test"),
error
)
)
}
#[actix_rt::test]
async fn create_db_test() {
let mock_server = MockServer::start().await;
Mock::given(method("PUT"))
.and(path("/test"))
.respond_with(ResponseTemplate::new(200))
.mount(&mock_server)
.await;
let client: Client = Client::default();
let host: String = mock_server.uri();
println!("test host: {}", host);
assert_eq!(create_db(&client, "test", &host).await.unwrap(), true);
}
}