couchdb_orm/client/couchdb/actions/db/create/
mod.rs1use crate::regexes::COUCHDB_DB_RULE;
18use awc::Client;
19
20pub mod errors;
21
22use errors::DBCreationError;
23
24pub async fn create_db(
25 client: &Client,
26 db_name: &str,
27 host: &str,
28) -> Result<bool, Box<dyn std::error::Error>> {
29 if !COUCHDB_DB_RULE.is_match(db_name) {
30 return Err(Box::new(DBCreationError::new(&format!(
31 "{} string doesn't respect the regex rule {}",
32 db_name,
33 COUCHDB_DB_RULE.as_str()
34 ))));
35 }
36 let uri: String = format!("{}/{}", host, db_name,);
37 match client.put(&uri).send().await {
38 Ok(mut response) => {
39 if response.status().as_u16() >= 400 {
41 let bytes: Vec<u8> = response.body().await?.iter().cloned().collect();
42 let error: serde_json::Value =
43 serde_json::from_str(std::str::from_utf8(bytes.as_slice()).unwrap()).unwrap();
44 Err(Box::new(DBCreationError::new(&format!(
45 "Error with the request to {}: error: \n{}",
46 &uri, error
47 ))))
48 } else {
49 Ok(true)
50 }
51 }
52 Err(error) => Err(Box::new(DBCreationError::new(&format!(
53 "Error with the request to {}: error: \n{}",
54 host, error
55 )))),
56 }
57}
58
59#[cfg(test)]
60mod tests {
61 extern crate actix_web;
62 extern crate wiremock;
63
64 use super::*;
65 use actix_web::test;
66 use dotenv::dotenv;
67 use serde_json::Value;
68 use std::error::Error;
69
70 use wiremock::matchers::{method, path};
71 use wiremock::{Mock, MockServer, ResponseTemplate};
72
73 #[actix_rt::test]
74 async fn create_db_regex_error_test() {
75 let client: Client = Client::default();
76 let box_result: Box<dyn Error> = create_db(&client, "Test", "").await.unwrap_err();
77 let result: &DBCreationError = box_result.downcast_ref().unwrap();
78 assert_eq!(
79 format!("{}", result),
80 format!(
81 "DBCreationError: {} string doesn't respect the regex rule {}",
82 "Test",
83 COUCHDB_DB_RULE.as_str()
84 )
85 );
86
87 let box_result: Box<dyn Error> = create_db(&client, "testT", "").await.unwrap_err();
88 let result: &DBCreationError = box_result.downcast_ref().unwrap();
89 assert_eq!(
90 format!("{}", result),
91 format!(
92 "DBCreationError: {} string doesn't respect the regex rule {}",
93 "testT",
94 COUCHDB_DB_RULE.as_str()
95 )
96 )
97 }
98
99 #[actix_rt::test]
100 async fn create_db_http_error_test() {
101 let mock_server = MockServer::start().await;
102 let data = r#"
104 {
105 "error": "test error"
106 }"#;
107
108 let response_template: ResponseTemplate =
109 ResponseTemplate::new(400).set_body_raw(data.as_bytes(), "application/json");
110 Mock::given(method("PUT"))
111 .and(path("/test"))
112 .respond_with(response_template)
113 .mount(&mock_server)
114 .await;
115
116 let error: serde_json::Value = serde_json::from_str(data).unwrap();
117
118 let client: Client = Client::default();
119 let host: String = mock_server.uri();
120
121 let box_result: Box<dyn Error> = create_db(&client, "test", &host).await.unwrap_err();
122 let result: &DBCreationError = box_result.downcast_ref().unwrap();
123 assert_eq!(
124 format!("{}", result),
125 format!(
126 "DBCreationError: Error with the request to {}: error: \n{}",
127 format!("{}/{}", host, "test"),
128 error
129 )
130 )
131 }
132
133 #[actix_rt::test]
134 async fn create_db_test() {
135 let mock_server = MockServer::start().await;
136 Mock::given(method("PUT"))
137 .and(path("/test"))
138 .respond_with(ResponseTemplate::new(200))
139 .mount(&mock_server)
140 .await;
141
142 let client: Client = Client::default();
143 let host: String = mock_server.uri();
144 println!("test host: {}", host);
145 assert_eq!(create_db(&client, "test", &host).await.unwrap(), true);
146 }
147}