#[cfg(test)]
use crate::{
res::HttpResponse,
res::{ResponseBody, ResponseBodyType},
};
mod cookies_test;
mod headers;
mod methods;
mod redirects_test;
mod status_code;
mod streaming_test;
#[cfg(test)]
mod test {
use crate::res::response_cookie::Cookie;
impl Cookie {
pub(crate) fn is_add_cookie(&self) -> bool {
matches!(self, Cookie::AddCookie(_))
}
pub(crate) fn is_remove_cookie(&self) -> bool {
matches!(self, Cookie::RemoveCookie(_))
}
pub fn value(&self) -> &str {
match self {
Cookie::AddCookie(add_cookie) => add_cookie.value,
Cookie::RemoveCookie(_) => "",
}
}
pub fn name(&self) -> &str {
match self {
Cookie::AddCookie(add_cookie) => add_cookie.name,
Cookie::RemoveCookie(name) => name,
}
}
}
}
#[cfg(test)]
impl HttpResponse {
pub(crate) fn get_status_code(&self) -> u16 {
self.status_code.as_u16()
}
pub(crate) fn get_content_type(&self) -> ResponseBodyType {
let content_type = &self.body.content_type();
return content_type.clone();
}
pub(crate) fn get_body(self) -> ResponseBody {
self.body
}
pub(crate) fn get_cookie(&self, key: &str) -> Option<&str> {
self.cookies
.iter()
.find(|cookie| cookie.is_add_cookie() && cookie.name() == key)
.map(|cookie| cookie.value())
}
}
#[cfg(test)]
mod tests {
use std::error::Error;
use crate::context::HttpRequest;
use crate::helpers::determine_content_type_request;
use crate::req::body::RequestBodyType;
use crate::req::body::TextData;
use crate::req::origin_url::Url;
use crate::req::request_error::HttpRequestError;
use crate::res::response_cookie::Cookie;
use crate::res::response_cookie::{AddCookie, CookieOptions};
use crate::res::response_headers::ResponseHeaders;
use crate::res::response_status::StatusCode;
use crate::res::HttpResponse;
use crate::res::HttpResponseError;
use futures::stream;
use serde_json::json;
#[test]
fn test_get_query() {
let mut req = HttpRequest::new();
req.set_query("q", "Ripress");
assert_eq!(req.query.get("q"), Some("Ripress"));
assert_eq!(req.query.get("nonexistent"), None);
}
#[test]
fn test_get_param() {
let mut req = HttpRequest::new();
req.set_param("q", "Ripress");
assert_eq!(req.params.get("q"), Some("Ripress"));
assert_eq!(req.params.get("nonexistent"), None);
}
#[test]
fn test_json_body() {
#[derive(Debug, PartialEq, serde::Serialize, serde::Deserialize)]
struct User {
id: u32,
name: String,
}
let mut req = HttpRequest::new();
req.set_json(User {
id: 1,
name: "John Doe".to_string(),
});
assert_eq!(
req.json::<User>().unwrap(),
User {
id: 1,
name: "John Doe".to_string()
}
);
req.set_json(User {
id: 1,
name: "John Doe".to_string(),
});
req.set_text(TextData::new("{invalid json}".to_string()));
assert!(req.json::<User>().is_err());
}
#[test]
fn test_binary_body() {
let mut req = HttpRequest::new();
req.set_binary(vec![1, 2, 3, 4, 5]);
assert_eq!(req.bytes().unwrap(), vec![1, 2, 3, 4, 5]);
}
#[test]
fn test_text_body() {
let mut req = HttpRequest::new();
req.set_text(TextData::new("Ripress".to_string()));
assert_eq!(req.text().unwrap().to_string(), "Ripress".to_string());
req.set_json(json!({"key": "value"}));
assert!(req.text().is_err());
}
#[test]
fn test_form_data() {
let mut req = HttpRequest::new();
req.set_form("key", "value");
assert_eq!(req.form_data().unwrap().get("key").unwrap(), "value");
assert_eq!(req.form_data().unwrap().get("nonexistent"), None);
req.set_json(json!({"key": "value"}));
assert!(req.form_data().is_err());
}
#[test]
fn text_cookie() {
let mut req = HttpRequest::new();
req.set_cookie("key", "value");
assert_eq!(req.get_cookie("key").unwrap(), "value");
assert_eq!(req.get_cookie("nonexistent"), None);
req.set_cookie("another_key", "another_value");
let cookie = req.get_cookie("another_key").unwrap();
assert_eq!(cookie, "another_value");
}
#[test]
fn test_get_path() {
let mut req = HttpRequest::new();
req.set_path("/user/1".to_string());
assert_eq!(req.path, "/user/1");
}
#[test]
fn test_origin_url() {
let mut req = HttpRequest::new();
req.set_origin_url(Url::new("value"));
assert_eq!(req.origin_url, Url::new("value"));
req.set_origin_url(Url::new("/user/1?q=hello"));
assert_eq!(req.origin_url, Url::new("/user/1?q=hello"));
}
#[test]
fn test_content_type() {
let content_type = determine_content_type_request("application/json");
assert_eq!(content_type, RequestBodyType::JSON);
let content_type = determine_content_type_request("");
assert_eq!(content_type, RequestBodyType::BINARY);
let content_type = determine_content_type_request("application/x-www-form-urlencoded");
assert_eq!(content_type, RequestBodyType::FORM);
let content_type = determine_content_type_request("application/octet-stream");
assert_eq!(content_type, RequestBodyType::BINARY);
let content_type = determine_content_type_request("image/png");
assert_eq!(content_type, RequestBodyType::BINARY);
let content_type = determine_content_type_request("application/xml");
assert_eq!(content_type, RequestBodyType::TEXT);
let content_type = determine_content_type_request(
"multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW",
);
assert_eq!(content_type, RequestBodyType::MultipartForm);
}
#[test]
fn test_error_enum() {
let err_1 = HttpRequestError::MissingParam("id".to_string());
let err_2 = HttpRequestError::MissingQuery("id".to_string());
let err_3 = HttpRequestError::MissingCookie("id".to_string());
let err_4 = HttpRequestError::MissingHeader("id".to_string());
let err_5 = HttpRequestError::InvalidJson("id".to_string());
assert_eq!(err_1.to_string(), "Param id doesn't exist");
assert_eq!(err_2.to_string(), "Query id doesn't exist");
assert_eq!(err_3.to_string(), "Cookie id doesn't exist");
assert_eq!(err_4.to_string(), "Header id doesn't exist");
assert_eq!(err_5.to_string(), "JSON is invalid: id");
}
#[test]
fn test_set_and_get_data() {
let mut req = HttpRequest::new();
req.set_data("id", "123");
assert_eq!(req.get_data("id"), Some(String::from("123")));
assert_eq!(req.get_data("nonexistent"), None);
}
#[test]
fn test_from_io_error() {
let io_err = std::io::Error::new(std::io::ErrorKind::NotFound, "file not found");
let resp_err: HttpResponseError = io_err.into();
match resp_err {
HttpResponseError::IoError(e) => {
assert_eq!(e.kind(), std::io::ErrorKind::NotFound);
assert_eq!(e.to_string(), "file not found");
}
_ => panic!("Expected ResponseError::IoError"),
}
}
#[test]
fn test_display_io_error() {
let io_err = std::io::Error::new(std::io::ErrorKind::PermissionDenied, "no permission");
let resp_err: HttpResponseError = io_err.into();
let output = format!("{}", resp_err);
assert_eq!(output, "IO error: no permission");
}
#[test]
fn test_display_other_error() {
let resp_err = HttpResponseError::_Other("something went wrong");
let output = format!("{}", resp_err);
assert_eq!(output, "Error: something went wrong");
}
#[test]
fn test_error_trait_description() {
let io_err = std::io::Error::new(std::io::ErrorKind::Other, "low-level failure");
let resp_err: HttpResponseError = io_err.into();
assert!(resp_err.source().is_none(), "Expected no source error");
}
fn sample_response() -> HttpResponse {
let mut headers = ResponseHeaders::new();
headers.insert("Content-Type", "application/json");
let cookies = AddCookie {
name: "session",
value: "abcd1234",
options: CookieOptions::default(),
};
HttpResponse {
status_code: StatusCode::Ok,
body: crate::res::ResponseBody::new_binary(bytes::Bytes::from_static(b"hello world")),
cookies: vec![Cookie::AddCookie(cookies)],
headers,
stream: Some(Box::pin(stream::empty::<
Result<bytes::Bytes, HttpResponseError>,
>())),
}
}
#[test]
fn test_clone_response() {
let resp = sample_response();
let cloned = resp.clone();
assert_eq!(resp.status_code, cloned.status_code);
assert_eq!(resp.body, cloned.body);
assert_eq!(resp.cookies, cloned.cookies);
assert_eq!(resp.headers, cloned.headers);
let orig_debug = format!("{:?}", resp);
let cloned_debug = format!("{:?}", cloned);
assert_eq!(orig_debug, cloned_debug);
}
#[test]
fn test_redirect_sets_status_and_location() {
let res = sample_response().redirect("/home");
assert_eq!(res.status_code, StatusCode::Redirect);
assert_eq!(res.headers.get("Location"), Some("/home"));
}
#[test]
fn test_permanent_redirect_sets_status_and_location() {
let res = sample_response().permanent_redirect("https://example.com");
assert_eq!(res.status_code, StatusCode::PermanentRedirect);
assert_eq!(res.headers.get("Location"), Some("https://example.com"));
}
}