francoisgib_webserver 1.0.3

HTTP Webserver
Documentation
#[cfg(test)]
mod tests {
    use tokio::io::BufReader;

    use crate::http::{
        errors::HttpError,
        headers::{ContentType, HttpHeader, HttpHeaderValue},
        methods::HttpMethod,
        requests::parser::{parse_headers, parse_http_version, parse_method, parse_uri},
    };

    #[test]
    fn test_parse_uri() {
        assert_eq!(Ok(("/uri", "")), parse_uri("/uri "))
    }

    #[test]
    fn test_parse_uri_without_space_at_the_end() {
        let res = parse_uri("/uri");
        assert!(matches!(res, Err(HttpError::BadRequest)));
    }

    #[test]
    fn test_parse_http_version() {
        let res = parse_http_version("HTTP/1\r\n");
        println!("{res:?}");
        assert!(matches!(res, Ok((1, 0))));
        let res = parse_http_version("HTTP/1.1\r\n");
        assert!(matches!(res, Ok((1, 1))));
    }

    #[test]
    fn test_parse_http_version_not_an_http_version() {
        let res = parse_http_version("NOT_HTTP_VERSION/1.1\r\n");
        assert!(matches!(res, Err(HttpError::BadRequest)));
    }

    #[test]
    fn test_parse_method() {
        assert_eq!(Ok((HttpMethod::GET, "")), parse_method("GET "));
        assert_eq!(Ok((HttpMethod::POST, "")), parse_method("POST "));
        assert_eq!(Ok((HttpMethod::DELETE, "")), parse_method("DELETE "));
        assert_eq!(Ok((HttpMethod::PUT, "")), parse_method("PUT "));
        assert_eq!(Ok((HttpMethod::PATCH, "")), parse_method("PATCH "));
    }

    #[test]
    fn test_parse_method_unknown_method() {
        let res = parse_method("UNKNOWN");
        assert!(matches!(res, Err(HttpError::BadRequest)));
    }

    #[test]
    fn test_parse_method_method_lowercase() {
        let res = parse_method("get");
        assert!(matches!(res, Err(HttpError::BadRequest)));

        let res = parse_method("post");
        assert!(matches!(res, Err(HttpError::BadRequest)));
    }

    #[tokio::test]
    async fn test_parse_single_valid_header() {
        let data = b"Content-Type: text/html\r\n\r\n";
        let mut reader = BufReader::new(&data[..]);

        let headers = parse_headers(&mut reader).await.unwrap();

        assert_eq!(headers.len(), 1);
        assert_eq!(headers[0].name, HttpHeader::ContentType);
        assert_eq!(
            headers[0].value,
            HttpHeaderValue::ContentType(ContentType::TextHtml)
        );
    }

    #[tokio::test]
    async fn test_parse_multiple_valid_headers() {
        let data = b"Content-Type: text/html\r\nContent-Length: 123\r\n\r\n";
        let mut reader = BufReader::new(&data[..]);

        let headers = parse_headers(&mut reader).await.unwrap();

        assert_eq!(headers.len(), 2);
        assert_eq!(headers[0].name, HttpHeader::ContentType);
        assert_eq!(headers[1].name, HttpHeader::ContentLength);
    }

    #[tokio::test]
    async fn test_parse_headers_with_unexpected_eof() {
        let data = b"Content-Type: text/html\r\nContent-Length: 123";
        let mut reader = BufReader::new(&data[..]);
        let res = parse_headers(&mut reader).await;

        assert!(res.is_err());
        assert_eq!(res.unwrap_err(), "Missing end line in header");

        let data = b"Content-Type: text/html\r\nContent-Length: 123\r\n";
        let mut reader = BufReader::new(&data[..]);
        let res = parse_headers(&mut reader).await;

        assert!(res.is_err());
        assert_eq!(res.unwrap_err(), "Unexpected EOF");
    }

    #[tokio::test]
    async fn test_parse_headers_with_invalid_header() {
        let data = b"Invalid-Header\r\n\r\n";
        let mut reader = BufReader::new(&data[..]);
        let headers = parse_headers(&mut reader).await.unwrap();
        assert!(headers.is_empty());
    }
}