use axum::http::{
HeaderMap, HeaderValue, Method,
header::{CONTENT_LENGTH, CONTENT_TYPE},
};
use bytes::Bytes;
use crate::http::request::HttpRequest;
#[derive(Debug, Clone, Copy, Default)]
pub struct RequestFactory;
impl RequestFactory {
#[must_use]
pub fn new() -> Self {
Self
}
#[must_use]
pub fn get(&self, path: &str) -> HttpRequest {
self.build_request(Method::GET, path, "")
}
#[must_use]
pub fn post(&self, path: &str, data: impl AsRef<str>) -> HttpRequest {
self.build_request(Method::POST, path, data.as_ref())
}
#[must_use]
pub fn put(&self, path: &str) -> HttpRequest {
self.build_request(Method::PUT, path, "")
}
#[must_use]
pub fn delete(&self, path: &str) -> HttpRequest {
self.build_request(Method::DELETE, path, "")
}
#[must_use]
fn build_request(&self, method: Method, path: &str, body: &str) -> HttpRequest {
let mut headers = HeaderMap::new();
if !body.is_empty() {
headers.insert(
CONTENT_TYPE,
HeaderValue::from_static("application/x-www-form-urlencoded"),
);
headers.insert(
CONTENT_LENGTH,
HeaderValue::from_str(&body.len().to_string())
.expect("request factory content length should be valid"),
);
}
HttpRequest::from_axum(
method,
path.parse()
.expect("request factory path should parse as URI"),
headers,
Bytes::copy_from_slice(body.as_bytes()),
)
}
}
#[cfg(test)]
mod tests {
use super::*;
use axum::http::Method;
#[test]
fn test_request_factory_get_builds_correct_method() {
let factory = RequestFactory::new();
let request = factory.get("/articles/");
assert_eq!(request.method, Method::GET);
assert_eq!(request.path, "/articles/");
assert_eq!(request.query_string, "");
assert!(request.body().is_empty());
}
#[test]
fn test_request_factory_post_sets_body() {
let factory = RequestFactory::new();
let request = factory.post("/submit/", "name=alice");
assert_eq!(request.method, Method::POST);
assert_eq!(request.body_str().expect("utf8 body"), "name=alice");
assert_eq!(
request.content_type.as_deref(),
Some("application/x-www-form-urlencoded")
);
assert_eq!(request.meta.get("CONTENT_LENGTH"), Some(&"10".to_string()));
}
#[test]
fn test_request_factory_with_query_string() {
let factory = RequestFactory::new();
let request = factory.get("/search/?page=2&tag=rust");
assert_eq!(request.path, "/search/");
assert_eq!(request.query_string, "page=2&tag=rust");
assert_eq!(request.get_full_path(), "/search/?page=2&tag=rust");
}
#[test]
fn request_factory_put_builds_empty_body_request() {
let factory = RequestFactory::new();
let request = factory.put("/items/42/");
assert_eq!(request.method, Method::PUT);
assert_eq!(request.path, "/items/42/");
assert!(request.body().is_empty());
}
#[test]
fn request_factory_delete_builds_empty_body_request() {
let factory = RequestFactory::new();
let request = factory.delete("/items/42/");
assert_eq!(request.method, Method::DELETE);
assert_eq!(request.path, "/items/42/");
assert!(request.body().is_empty());
}
}