From 6e2064de9516a06d8d252ffe61d570e5915123d3 Mon Sep 17 00:00:00 2001 From: Florin Lipan Date: Sat, 11 Mar 2023 15:53:33 +0100 Subject: [PATCH] Drop legacy interface --- src/legacy.rs | 95 --- src/lib.rs | 2 - tests/legacy.rs | 1616 ----------------------------------------------- 3 files changed, 1713 deletions(-) delete mode 100644 src/legacy.rs delete mode 100644 tests/legacy.rs diff --git a/src/legacy.rs b/src/legacy.rs deleted file mode 100644 index 3887a78..0000000 --- a/src/legacy.rs +++ /dev/null @@ -1,95 +0,0 @@ -use crate::{Matcher, Mock, Server}; -use lazy_static::lazy_static; -use std::cell::RefCell; -use std::sync::LockResult; -use std::sync::{Mutex, MutexGuard}; -lazy_static! { - // Legacy mode. - // A global lock that ensure all Mockito tests are run on a single thread. - static ref TEST_MUTEX: Mutex<()> = Mutex::new(()); - - // Legacy mode. - static ref DEFAULT_SERVER: Mutex = Mutex::new(Server::new_with_port(0)); -} -thread_local!( - // Legacy mode. - // A thread-local reference to the global lock. This is acquired within `mock()`. - pub(crate) static LOCAL_TEST_MUTEX: RefCell>> = - RefCell::new(TEST_MUTEX.lock()); -); - -/// -/// **DEPRECATED:** This method is part of the legacy interface an will be removed -/// in future versions. You should replace it with `Server::mock`: -/// -/// ``` -/// let mut s = mockito::Server::new(); -/// let _m1 = s.mock("GET", "/"); -/// ``` -/// -/// Initializes a mock with the given HTTP `method` and `path`. -/// -/// The mock is registered to the server only after the `create()` method has been called. -/// -#[deprecated(since = "0.32.0", note = "Use `Server::mock` instead")] -pub fn mock>(method: &str, path: P) -> Mock { - // Legacy mode. - // Ensures Mockito tests are run sequentially. - LOCAL_TEST_MUTEX.with(|_| {}); - - let mut server = DEFAULT_SERVER.lock().unwrap(); - - server.mock(method, path) -} - -/// -/// **DEPRECATED:** This method is part of the legacy interface an will be removed -/// in future versions. You should replace it with `Server::host_with_port`: -/// -/// ``` -/// let mut s = mockito::Server::new(); -/// let server_address = s.host_with_port(); -/// ``` -/// -/// The host and port of the local server. -/// Can be used with `std::net::TcpStream`. -/// -#[deprecated(since = "0.32.0", note = "Use `Server::host_with_port` instead")] -pub fn server_address() -> String { - let server = DEFAULT_SERVER.lock().unwrap(); - server.host_with_port() -} - -/// -/// **DEPRECATED:** This method is part of the legacy interface an will be removed -/// in future versions. You should replace it with `Server::url`: -/// -/// ``` -/// let mut s = mockito::Server::new(); -/// let server_url = s.url(); -/// ``` -/// -/// The local `http://...` URL of the server. -/// -#[deprecated(since = "0.32.0", note = "Use `Server::url` instead")] -pub fn server_url() -> String { - let server = DEFAULT_SERVER.lock().unwrap(); - server.url() -} - -/// -/// **DEPRECATED:** This method is part of the legacy interface an will be removed -/// in future versions. You should replace it with `Server::reset`: -/// -/// ``` -/// let mut s = mockito::Server::new(); -/// s.reset(); -/// ``` -/// -/// Removes all the mocks stored on the server. -/// -#[deprecated(since = "0.32.0", note = "Use `Server::reset` instead")] -pub fn reset() { - let mut server = DEFAULT_SERVER.lock().unwrap(); - server.reset(); -} diff --git a/src/lib.rs b/src/lib.rs index f9aaa4e..91822d9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -647,7 +647,6 @@ //! pub use error::{Error, ErrorKind}; #[allow(deprecated)] -pub use legacy::{mock, reset, server_address, server_url}; pub use matcher::Matcher; pub use mock::Mock; pub use request::Request; @@ -656,7 +655,6 @@ pub use server_pool::ServerGuard; mod diff; mod error; -mod legacy; mod matcher; mod mock; mod request; diff --git a/tests/legacy.rs b/tests/legacy.rs deleted file mode 100644 index 40e0cdd..0000000 --- a/tests/legacy.rs +++ /dev/null @@ -1,1616 +0,0 @@ -#[macro_use] -extern crate serde_json; - -#[allow(deprecated)] -use mockito::{mock, server_address, Matcher}; -use rand::distributions::Alphanumeric; -use rand::Rng; -use std::fs; -use std::io::{BufRead, BufReader, Read, Write}; -use std::mem; -use std::net::TcpStream; -use std::path::Path; -use std::str::FromStr; -use std::thread; - -type Binary = Vec; - -#[allow(deprecated)] -fn request_stream>( - version: &str, - route: &str, - headers: &str, - body: StrOrBytes, -) -> TcpStream { - let mut stream = TcpStream::connect(server_address()).unwrap(); - let mut message: Binary = Vec::new(); - for b in [route, " HTTP/", version, "\r\n", headers, "\r\n"] - .join("") - .as_bytes() - { - message.push(*b); - } - for b in body.as_ref().iter() { - message.push(*b); - } - - stream.write_all(&message).unwrap(); - - stream -} - -fn parse_stream(stream: TcpStream, skip_body: bool) -> (String, Vec, Binary) { - let mut reader = BufReader::new(stream); - - let mut status_line = String::new(); - reader.read_line(&mut status_line).unwrap(); - - let mut headers = vec![]; - let mut content_length: Option = None; - let mut is_chunked = false; - loop { - let mut header_line = String::new(); - reader.read_line(&mut header_line).unwrap(); - - if header_line == "\r\n" { - break; - } - - if header_line.starts_with("transfer-encoding:") && header_line.contains("chunked") { - is_chunked = true; - } - - if header_line.starts_with("content-length:") { - let mut parts = header_line.split(':'); - content_length = Some(u64::from_str(parts.nth(1).unwrap().trim()).unwrap()); - } - - headers.push(header_line.trim_end().to_string()); - } - - let mut body: Binary = Vec::new(); - if !skip_body { - if let Some(content_length) = content_length { - reader.take(content_length).read_to_end(&mut body).unwrap(); - } else if is_chunked { - let mut chunk_size_buf = String::new(); - loop { - chunk_size_buf.clear(); - reader.read_line(&mut chunk_size_buf).unwrap(); - - let chunk_size = u64::from_str_radix( - chunk_size_buf.trim_matches(|c| c == '\r' || c == '\n'), - 16, - ) - .expect("chunk size"); - if chunk_size == 0 { - break; - } - - (&mut reader) - .take(chunk_size) - .read_to_end(&mut body) - .unwrap(); - - chunk_size_buf.clear(); - reader.read_line(&mut chunk_size_buf).unwrap(); - } - } - } - - (status_line, headers, body) -} - -fn binary_request>( - route: &str, - headers: &str, - body: StrOrBytes, -) -> (String, Vec, Binary) { - parse_stream( - request_stream("1.1", route, headers, body), - route.starts_with("HEAD"), - ) -} - -fn request(route: &str, headers: &str) -> (String, Vec, String) { - let (status, headers, body) = binary_request(route, headers, ""); - let parsed_body: String = std::str::from_utf8(body.as_slice()).unwrap().to_string(); - (status, headers, parsed_body) -} - -fn request_with_body(route: &str, headers: &str, body: &str) -> (String, Vec, String) { - let headers = format!("{}content-length: {}\r\n", headers, body.len()); - let (status, headers, body) = binary_request(route, &headers, body); - let parsed_body: String = std::str::from_utf8(body.as_slice()).unwrap().to_string(); - (status, headers, parsed_body) -} - -#[allow(deprecated)] -#[test] -#[allow(deprecated)] -fn test_legacy_create_starts_the_server() { - let _m = mock("GET", "/").with_body("hello").create(); - - let stream = TcpStream::connect(server_address()); - assert!(stream.is_ok()); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_simple_route_mock() { - let _m = mock("GET", "/hello").with_body("world").create(); - - let (status_line, _, body) = request("GET /hello", ""); - assert_eq!("HTTP/1.1 200 OK\r\n", status_line); - assert_eq!("world", body); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_two_route_mocks() { - let _m1 = mock("GET", "/a").with_body("aaa").create(); - let _m2 = mock("GET", "/b").with_body("bbb").create(); - - let (_, _, body_a) = request("GET /a", ""); - - assert_eq!("aaa", body_a); - let (_, _, body_b) = request("GET /b", ""); - assert_eq!("bbb", body_b); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_no_match_returns_501() { - let _m = mock("GET", "/").with_body("matched").create(); - - let (status_line, headers, _) = request("GET /nope", ""); - assert_eq!("HTTP/1.1 501 Not Implemented\r\n", status_line); - assert_eq!("content-length: 0", headers[0]); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_match_header() { - let _m1 = mock("GET", "/") - .match_header("content-type", "application/json") - .with_body("{}") - .create(); - - let _m2 = mock("GET", "/") - .match_header("content-type", "text/plain") - .with_body("hello") - .create(); - - let (_, _, body_json) = request("GET /", "content-type: application/json\r\n"); - assert_eq!("{}", body_json); - - let (_, _, body_text) = request("GET /", "content-type: text/plain\r\n"); - assert_eq!("hello", body_text); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_match_header_is_case_insensitive_on_the_field_name() { - let _m = mock("GET", "/") - .match_header("content-type", "text/plain") - .create(); - - let (uppercase_status_line, _, _) = request("GET /", "Content-Type: text/plain\r\n"); - assert_eq!("HTTP/1.1 200 OK\r\n", uppercase_status_line); - - let (lowercase_status_line, _, _) = request("GET /", "content-type: text/plain\r\n"); - assert_eq!("HTTP/1.1 200 OK\r\n", lowercase_status_line); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_match_multiple_headers() { - let _m = mock("GET", "/") - .match_header("Content-Type", "text/plain") - .match_header("Authorization", "secret") - .with_body("matched") - .create(); - - let (_, _, body_matching) = request( - "GET /", - "content-type: text/plain\r\nauthorization: secret\r\n", - ); - assert_eq!("matched", body_matching); - - let (status_not_matching, _, _) = request( - "GET /", - "content-type: text/plain\r\nauthorization: meh\r\n", - ); - assert_eq!("HTTP/1.1 501 Not Implemented\r\n", status_not_matching); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_match_header_any_matching() { - let _m = mock("GET", "/") - .match_header("Content-Type", Matcher::Any) - .with_body("matched") - .create(); - - let (_, _, body) = request("GET /", "content-type: something\r\n"); - assert_eq!("matched", body); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_match_header_any_not_matching() { - let _m = mock("GET", "/") - .match_header("Content-Type", Matcher::Any) - .with_body("matched") - .create(); - - let (status, _, _) = request("GET /", ""); - assert_eq!("HTTP/1.1 501 Not Implemented\r\n", status); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_match_header_missing_matching() { - let _m = mock("GET", "/") - .match_header("Authorization", Matcher::Missing) - .create(); - - let (status, _, _) = request("GET /", ""); - assert_eq!("HTTP/1.1 200 OK\r\n", status); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_match_header_missing_not_matching() { - let _m = mock("GET", "/") - .match_header("Authorization", Matcher::Missing) - .create(); - - let (status, _, _) = request("GET /", "Authorization: something\r\n"); - assert_eq!("HTTP/1.1 501 Not Implemented\r\n", status); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_match_header_missing_not_matching_even_when_empty() { - let _m = mock("GET", "/") - .match_header("Authorization", Matcher::Missing) - .create(); - - let (status, _, _) = request("GET /", "Authorization:\r\n"); - assert_eq!("HTTP/1.1 501 Not Implemented\r\n", status); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_match_multiple_header_conditions_matching() { - let _m = mock("GET", "/") - .match_header("Hello", "World") - .match_header("Content-Type", Matcher::Any) - .match_header("Authorization", Matcher::Missing) - .create(); - - let (status, _, _) = request("GET /", "Hello: World\r\nContent-Type: something\r\n"); - assert_eq!("HTTP/1.1 200 OK\r\n", status); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_match_multiple_header_conditions_not_matching() { - let _m = mock("GET", "/") - .match_header("hello", "world") - .match_header("Content-Type", Matcher::Any) - .match_header("Authorization", Matcher::Missing) - .create(); - - let (status, _, _) = request("GET /", "Hello: World\r\n"); - assert_eq!("HTTP/1.1 501 Not Implemented\r\n", status); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_match_any_body_by_default() { - let _m = mock("POST", "/").create(); - - let (status, _, _) = request_with_body("POST /", "", "hello"); - assert_eq!("HTTP/1.1 200 OK\r\n", status); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_match_body() { - let _m = mock("POST", "/").match_body("hello").create(); - - let (status, _, _) = request_with_body("POST /", "", "hello"); - assert_eq!("HTTP/1.1 200 OK\r\n", status); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_match_body_not_matching() { - let _m = mock("POST", "/").match_body("hello").create(); - - let (status, _, _) = request_with_body("POST /", "", "bye"); - assert_eq!("HTTP/1.1 501 Not Implemented\r\n", status); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_match_binary_body() { - let _m = mock("POST", "/") - .match_body(Path::new("./tests/files/test_payload.bin")) - .create(); - - let mut file_content: Binary = Vec::new(); - fs::File::open("./tests/files/test_payload.bin") - .unwrap() - .read_to_end(&mut file_content) - .unwrap(); - let content_length_header = format!("Content-Length: {}\r\n", file_content.len()); - let (status, _, _) = binary_request("POST /", &content_length_header, file_content); - assert_eq!("HTTP/1.1 200 OK\r\n", status); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_does_not_match_binary_body() { - let _m = mock("POST", "/") - .match_body(Path::new("./tests/files/test_payload.bin")) - .create(); - - let file_content: Binary = (0..1024).map(|_| rand::random::()).collect(); - let content_length_header = format!("Content-Length: {}\r\n", file_content.len()); - let (status, _, _) = binary_request("POST /", &content_length_header, file_content); - assert_eq!("HTTP/1.1 501 Not Implemented\r\n", status); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_match_body_with_regex() { - let _m = mock("POST", "/") - .match_body(Matcher::Regex("hello".to_string())) - .create(); - - let (status, _, _) = request_with_body("POST /", "", "test hello test"); - assert_eq!("HTTP/1.1 200 OK\r\n", status); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_match_body_with_regex_not_matching() { - let _m = mock("POST", "/") - .match_body(Matcher::Regex("hello".to_string())) - .create(); - - let (status, _, _) = request_with_body("POST /", "", "bye"); - assert_eq!("HTTP/1.1 501 Not Implemented\r\n", status); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_match_body_with_json() { - let _m = mock("POST", "/") - .match_body(Matcher::Json(json!({"hello":"world", "foo": "bar"}))) - .create(); - - let (status, _, _) = request_with_body("POST /", "", r#"{"hello":"world", "foo": "bar"}"#); - assert_eq!("HTTP/1.1 200 OK\r\n", status); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_match_body_with_more_headers_with_json() { - let _m = mock("POST", "/") - .match_body(Matcher::Json(json!({"hello":"world", "foo": "bar"}))) - .create(); - - let headers = (0..15) - .map(|n| { - format!( - "x-header-{}: foo-bar-value-zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz\r\n", - n - ) - }) - .collect::>() - .concat(); - - let (status, _, _) = - request_with_body("POST /", &headers, r#"{"hello":"world", "foo": "bar"}"#); - assert_eq!("HTTP/1.1 200 OK\r\n", status); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_match_body_with_json_order() { - let _m = mock("POST", "/") - .match_body(Matcher::Json(json!({"foo": "bar", "hello": "world"}))) - .create(); - - let (status, _, _) = request_with_body("POST /", "", r#"{"hello":"world", "foo": "bar"}"#); - assert_eq!("HTTP/1.1 200 OK\r\n", status); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_match_body_with_json_string() { - let _m = mock("POST", "/") - .match_body(Matcher::JsonString( - "{\"hello\":\"world\", \"foo\": \"bar\"}".to_string(), - )) - .create(); - - let (status, _, _) = request_with_body("POST /", "", r#"{"hello":"world", "foo": "bar"}"#); - assert_eq!("HTTP/1.1 200 OK\r\n", status); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_match_body_with_json_string_order() { - let _m = mock("POST", "/") - .match_body(Matcher::JsonString( - "{\"foo\": \"bar\", \"hello\": \"world\"}".to_string(), - )) - .create(); - - let (status, _, _) = request_with_body("POST /", "", r#"{"hello":"world", "foo": "bar"}"#); - assert_eq!("HTTP/1.1 200 OK\r\n", status); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_match_body_with_partial_json() { - let _m = mock("POST", "/") - .match_body(Matcher::PartialJson(json!({"hello":"world"}))) - .create(); - - let (status, _, _) = request_with_body("POST /", "", r#"{"hello":"world", "foo": "bar"}"#); - assert_eq!("HTTP/1.1 200 OK\r\n", status); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_match_body_with_partial_json_and_extra_fields() { - let _m = mock("POST", "/") - .match_body(Matcher::PartialJson(json!({"hello":"world", "foo": "bar"}))) - .create(); - - let (status, _, _) = request_with_body("POST /", "", r#"{"hello":"world"}"#); - assert_eq!("HTTP/1.1 501 Not Implemented\r\n", status); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_match_body_with_partial_json_string() { - let _m = mock("POST", "/") - .match_body(Matcher::PartialJsonString( - "{\"hello\": \"world\"}".to_string(), - )) - .create(); - - let (status, _, _) = request_with_body("POST /", "", r#"{"hello":"world", "foo": "bar"}"#); - assert_eq!("HTTP/1.1 200 OK\r\n", status); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_match_body_with_partial_json_string_and_extra_fields() { - let _m = mock("POST", "/") - .match_body(Matcher::PartialJsonString( - "{\"foo\": \"bar\", \"hello\": \"world\"}".to_string(), - )) - .create(); - - let (status, _, _) = request_with_body("POST /", "", r#"{"hello":"world"}"#); - assert_eq!("HTTP/1.1 501 Not Implemented\r\n", status); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_mock_with_status() { - let _m = mock("GET", "/").with_status(204).with_body("").create(); - - let (status_line, _, _) = request("GET /", ""); - assert_eq!("HTTP/1.1 204 No Content\r\n", status_line); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_mock_with_custom_status() { - let _m = mock("GET", "/").with_status(499).with_body("").create(); - - let (status_line, _, _) = request("GET /", ""); - assert_eq!("HTTP/1.1 499 \r\n", status_line); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_mock_with_body() { - let _m = mock("GET", "/").with_body("hello").create(); - - let (_, _, body) = request("GET /", ""); - assert_eq!("hello", body); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_mock_with_fn_body() { - let _m = mock("GET", "/") - .with_body_from_fn(|w| { - w.write_all(b"hel")?; - w.write_all(b"lo") - }) - .create(); - - let (_, _, body) = request("GET /", ""); - assert_eq!("hello", body); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_mock_with_header() { - let _m = mock("GET", "/") - .with_header("content-type", "application/json") - .with_body("{}") - .create(); - - let (_, headers, _) = request("GET /", ""); - assert!(headers.contains(&"content-type: application/json".to_string())); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_mock_with_multiple_headers() { - let _m = mock("GET", "/") - .with_header("content-type", "application/json") - .with_header("x-api-key", "1234") - .with_body("{}") - .create(); - - let (_, headers, _) = request("GET /", ""); - assert!(headers.contains(&"content-type: application/json".to_string())); - assert!(headers.contains(&"x-api-key: 1234".to_string())); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_mock_preserves_header_order() { - let mut expected_headers = Vec::new(); - let mut mock = mock("GET", "/"); - - // Add a large number of headers so getting the same order accidentally is unlikely. - for i in 0..100 { - let field = format!("x-custom-header-{}", i); - let value = "test"; - mock = mock.with_header(&field, value); - expected_headers.push(format!("{}: {}", field, value)); - } - - let _m = mock.create(); - - let (_, headers, _) = request("GET /", ""); - let custom_headers: Vec<_> = headers - .into_iter() - .filter(|header| header.starts_with("x-custom-header")) - .collect(); - - assert_eq!(custom_headers, expected_headers); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_going_out_of_context_removes_mock() { - { - let _m = mock("GET", "/reset").create(); - - let (working_status_line, _, _) = request("GET /reset", ""); - assert_eq!("HTTP/1.1 200 OK\r\n", working_status_line); - } - - let (reset_status_line, _, _) = request("GET /reset", ""); - assert_eq!("HTTP/1.1 501 Not Implemented\r\n", reset_status_line); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_going_out_of_context_doesnt_remove_other_mocks() { - let _m1 = mock("GET", "/long").create(); - - { - let _m2 = mock("GET", "/short").create(); - - let (short_status_line, _, _) = request("GET /short", ""); - assert_eq!("HTTP/1.1 200 OK\r\n", short_status_line); - } - - let (long_status_line, _, _) = request("GET /long", ""); - assert_eq!("HTTP/1.1 200 OK\r\n", long_status_line); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_explicitly_calling_drop_removes_the_mock() { - let mock = mock("GET", "/").create(); - - let (status_line, _, _) = request("GET /", ""); - assert_eq!("HTTP/1.1 200 OK\r\n", status_line); - - mem::drop(mock); - - let (dropped_status_line, _, _) = request("GET /", ""); - assert_eq!("HTTP/1.1 501 Not Implemented\r\n", dropped_status_line); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_regex_match_path() { - let _m1 = mock("GET", Matcher::Regex(r"^/a/\d{1}$".to_string())) - .with_body("aaa") - .create(); - let _m2 = mock("GET", Matcher::Regex(r"^/b/\d{1}$".to_string())) - .with_body("bbb") - .create(); - - let (_, _, body_a) = request("GET /a/1", ""); - assert_eq!("aaa", body_a); - - let (_, _, body_b) = request("GET /b/2", ""); - assert_eq!("bbb", body_b); - - let (status_line, _, _) = request("GET /a/11", ""); - assert_eq!("HTTP/1.1 501 Not Implemented\r\n", status_line); - - let (status_line, _, _) = request("GET /c/2", ""); - assert_eq!("HTTP/1.1 501 Not Implemented\r\n", status_line); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_regex_match_header() { - let _m = mock("GET", "/") - .match_header( - "Authorization", - Matcher::Regex(r"^Bearer token\.\w+$".to_string()), - ) - .with_body("{}") - .create(); - - let (_, _, body_json) = request("GET /", "Authorization: Bearer token.payload\r\n"); - assert_eq!("{}", body_json); - - let (status_line, _, _) = request("GET /", "authorization: Beare none\r\n"); - assert_eq!("HTTP/1.1 501 Not Implemented\r\n", status_line); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_any_of_match_header() { - let _m = mock("GET", "/") - .match_header( - "Via", - Matcher::AnyOf(vec![ - Matcher::Exact("one".into()), - Matcher::Exact("two".into()), - ]), - ) - .with_body("{}") - .create(); - - let (_, _, body_json) = request("GET /", "Via: one\r\n"); - assert_eq!("{}", body_json); - - let (_, _, body_json) = request("GET /", "Via: two\r\n"); - assert_eq!("{}", body_json); - - let (_, _, body_json) = request("GET /", "Via: one\r\nVia: two\r\n"); - assert_eq!("{}", body_json); - - let (status_line, _, _) = request("GET /", "Via: one\r\nVia: two\r\nVia: wrong\r\n"); - assert!(status_line.starts_with("HTTP/1.1 501 ")); - - let (status_line, _, _) = request("GET /", "Via: wrong\r\n"); - assert!(status_line.starts_with("HTTP/1.1 501 ")); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_any_of_match_body() { - let _m = mock("GET", "/") - .match_body(Matcher::AnyOf(vec![ - Matcher::Regex("one".to_string()), - Matcher::Regex("two".to_string()), - ])) - .create(); - - let (status_line, _, _) = request_with_body("GET /", "", "one"); - assert!(status_line.starts_with("HTTP/1.1 200 ")); - - let (status_line, _, _) = request_with_body("GET /", "", "two"); - assert!(status_line.starts_with("HTTP/1.1 200 ")); - - let (status_line, _, _) = request_with_body("GET /", "", "one two"); - assert!(status_line.starts_with("HTTP/1.1 200 ")); - - let (status_line, _, _) = request_with_body("GET /", "", "three"); - assert!(status_line.starts_with("HTTP/1.1 501 ")); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_any_of_missing_match_header() { - let _m = mock("GET", "/") - .match_header( - "Via", - Matcher::AnyOf(vec![Matcher::Exact("one".into()), Matcher::Missing]), - ) - .with_body("{}") - .create(); - - let (_, _, body_json) = request("GET /", "Via: one\r\n"); - assert_eq!("{}", body_json); - - let (_, _, body_json) = request("GET /", "Via: one\r\nVia: one\r\nVia: one\r\n"); - assert_eq!("{}", body_json); - - let (_, _, body_json) = request("GET /", "NotVia: one\r\n"); - assert_eq!("{}", body_json); - - let (status_line, _, _) = request("GET /", "Via: wrong\r\n"); - assert!(status_line.starts_with("HTTP/1.1 501 ")); - - let (status_line, _, _) = request("GET /", "Via: wrong\r\nVia: one\r\n"); - assert!(status_line.starts_with("HTTP/1.1 501 ")); - - let (status_line, _, _) = request("GET /", "Via: one\r\nVia: wrong\r\n"); - assert!(status_line.starts_with("HTTP/1.1 501 ")); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_all_of_match_header() { - let _m = mock("GET", "/") - .match_header( - "Via", - Matcher::AllOf(vec![ - Matcher::Regex("one".into()), - Matcher::Regex("two".into()), - ]), - ) - .with_body("{}") - .create(); - - let (status_line, _, _) = request("GET /", "Via: one\r\n"); - assert!(status_line.starts_with("HTTP/1.1 501 ")); - - let (status_line, _, _) = request("GET /", "Via: two\r\n"); - assert!(status_line.starts_with("HTTP/1.1 501 ")); - - let (status_line, _, _) = request("GET /", "Via: one two\r\nVia: one two three\r\n"); - assert!(status_line.starts_with("HTTP/1.1 200 ")); - - let (status_line, _, _) = request("GET /", "Via: one\r\nVia: two\r\nVia: wrong\r\n"); - assert!(status_line.starts_with("HTTP/1.1 501 ")); - - let (status_line, _, _) = request("GET /", "Via: wrong\r\n"); - assert!(status_line.starts_with("HTTP/1.1 501 ")); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_all_of_match_body() { - let _m = mock("GET", "/") - .match_body(Matcher::AllOf(vec![ - Matcher::Regex("one".to_string()), - Matcher::Regex("two".to_string()), - ])) - .create(); - - let (status_line, _, _) = request_with_body("GET /", "", "one"); - assert!(status_line.starts_with("HTTP/1.1 501 ")); - - let (status_line, _, _) = request_with_body("GET /", "", "two"); - assert!(status_line.starts_with("HTTP/1.1 501 ")); - - let (status_line, _, _) = request_with_body("GET /", "", "one two"); - assert!(status_line.starts_with("HTTP/1.1 200 ")); - - let (status_line, _, _) = request_with_body("GET /", "", "three"); - assert!(status_line.starts_with("HTTP/1.1 501 ")); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_all_of_missing_match_header() { - let _m = mock("GET", "/") - .match_header("Via", Matcher::AllOf(vec![Matcher::Missing])) - .with_body("{}") - .create(); - - let (status_line, _, _) = request("GET /", "Via: one\r\n"); - assert!(status_line.starts_with("HTTP/1.1 501 ")); - - let (status_line, _, _) = request("GET /", "Via: one\r\nVia: one\r\nVia: one\r\n"); - assert!(status_line.starts_with("HTTP/1.1 501 ")); - - let (status_line, _, _) = request("GET /", "NotVia: one\r\n"); - assert!(status_line.starts_with("HTTP/1.1 200 ")); - - let (status_line, _, _) = request("GET /", "Via: wrong\r\n"); - assert!(status_line.starts_with("HTTP/1.1 501 ")); - - let (status_line, _, _) = request("GET /", "Via: wrong\r\nVia: one\r\n"); - assert!(status_line.starts_with("HTTP/1.1 501 ")); - - let (status_line, _, _) = request("GET /", "Via: one\r\nVia: wrong\r\n"); - assert!(status_line.starts_with("HTTP/1.1 501 ")); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_large_utf8_body() { - let mock_body: String = rand::thread_rng() - .sample_iter(&Alphanumeric) - .map(char::from) - .take(3 * 1024) // Must be larger than the request read buffer - .map(char::from) - .collect(); - - let _m = mock("GET", "/").with_body(&mock_body).create(); - - let (_, _, body) = request("GET /", ""); - assert_eq!(mock_body, body); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_body_from_file() { - let _m = mock("GET", "/") - .with_body_from_file("tests/files/simple.http") - .create(); - let (status_line, _, body) = request("GET /", ""); - assert_eq!("HTTP/1.1 200 OK\r\n", status_line); - assert_eq!("test body\n", body); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_display_mock_matching_exact_path() { - let mock = mock("GET", "/hello"); - - assert_eq!("\r\nGET /hello\r\n", format!("{}", mock)); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_display_mock_matching_regex_path() { - let mock = mock("GET", Matcher::Regex(r"^/hello/\d+$".to_string())); - - assert_eq!("\r\nGET ^/hello/\\d+$ (regex)\r\n", format!("{}", mock)); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_display_mock_matching_any_path() { - let mock = mock("GET", Matcher::Any); - - assert_eq!("\r\nGET (any)\r\n", format!("{}", mock)); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_display_mock_matching_exact_query() { - let mock = mock("GET", "/test?hello=world"); - - assert_eq!("\r\nGET /test?hello=world\r\n", format!("{}", mock)); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_display_mock_matching_regex_query() { - let mock = mock("GET", "/test").match_query(Matcher::Regex("hello=world".to_string())); - - assert_eq!("\r\nGET /test?hello=world (regex)\r\n", format!("{}", mock)); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_display_mock_matching_any_query() { - let mock = mock("GET", "/test").match_query(Matcher::Any); - - assert_eq!("\r\nGET /test?(any)\r\n", format!("{}", mock)); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_display_mock_matching_exact_header() { - let mock = mock("GET", "/") - .match_header("content-type", "text") - .create(); - - assert_eq!("\r\nGET /\r\ncontent-type: text\r\n", format!("{}", mock)); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_display_mock_matching_multiple_headers() { - let mock = mock("GET", "/") - .match_header("content-type", "text") - .match_header("content-length", Matcher::Regex(r"\d+".to_string())) - .match_header("authorization", Matcher::Any) - .match_header("x-request-id", Matcher::Missing) - .create(); - - assert_eq!("\r\nGET /\r\ncontent-type: text\r\ncontent-length: \\d+ (regex)\r\nauthorization: (any)\r\nx-request-id: (missing)\r\n", format!("{}", mock)); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_display_mock_matching_exact_body() { - let mock = mock("POST", "/").match_body("hello").create(); - - assert_eq!("\r\nPOST /\r\nhello\r\n", format!("{}", mock)); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_display_mock_matching_regex_body() { - let mock = mock("POST", "/") - .match_body(Matcher::Regex("hello".to_string())) - .create(); - - assert_eq!("\r\nPOST /\r\nhello\r\n", format!("{}", mock)); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_display_mock_matching_any_body() { - let mock = mock("POST", "/").match_body(Matcher::Any).create(); - - assert_eq!("\r\nPOST /\r\n", format!("{}", mock)); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_display_mock_matching_headers_and_body() { - let mock = mock("POST", "/") - .match_header("content-type", "text") - .match_body("hello") - .create(); - - assert_eq!( - "\r\nPOST /\r\ncontent-type: text\r\nhello\r\n", - format!("{}", mock) - ); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_display_mock_matching_all_of_queries() { - let mock = mock("POST", "/") - .match_query(Matcher::AllOf(vec![ - Matcher::Exact("query1".to_string()), - Matcher::UrlEncoded("key".to_string(), "val".to_string()), - ])) - .create(); - - assert_eq!( - "\r\nPOST /?(query1, key=val (urlencoded)) (all of)\r\n", - format!("{}", mock) - ); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_display_mock_matching_any_of_headers() { - let mock = mock("POST", "/") - .match_header( - "content-type", - Matcher::AnyOf(vec![ - Matcher::Exact("type1".to_string()), - Matcher::Regex("type2".to_string()), - ]), - ) - .create(); - - assert_eq!( - "\r\nPOST /\r\ncontent-type: (type1, type2 (regex)) (any of)\r\n", - format!("{}", mock) - ); -} -#[test] -#[allow(deprecated)] -fn test_legacy_assert_defaults_to_one_hit() { - let mock = mock("GET", "/hello").create(); - - request("GET /hello", ""); - - mock.assert(); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_expect() { - let mock = mock("GET", "/hello").expect(3).create(); - - request("GET /hello", ""); - request("GET /hello", ""); - request("GET /hello", ""); - - mock.assert(); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_expect_at_least_and_at_most() { - let mock = mock("GET", "/hello") - .expect_at_least(3) - .expect_at_most(6) - .create(); - - request("GET /hello", ""); - request("GET /hello", ""); - request("GET /hello", ""); - request("GET /hello", ""); - request("GET /hello", ""); - - mock.assert(); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_expect_at_least() { - let mock = mock("GET", "/hello").expect_at_least(3).create(); - - request("GET /hello", ""); - request("GET /hello", ""); - request("GET /hello", ""); - - mock.assert(); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_expect_at_least_more() { - let mock = mock("GET", "/hello").expect_at_least(3).create(); - - request("GET /hello", ""); - request("GET /hello", ""); - request("GET /hello", ""); - request("GET /hello", ""); - - mock.assert(); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_expect_at_most_with_needed_requests() { - let mock = mock("GET", "/hello").expect_at_most(3).create(); - - request("GET /hello", ""); - request("GET /hello", ""); - request("GET /hello", ""); - - mock.assert(); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_expect_at_most_with_few_requests() { - let mock = mock("GET", "/hello").expect_at_most(3).create(); - - request("GET /hello", ""); - request("GET /hello", ""); - - mock.assert(); -} - -#[test] -#[allow(deprecated)] -#[should_panic( - expected = "\n> Expected at least 3 request(s) to:\n\r\nGET /hello\r\n\n...but received 2\n" -)] -fn test_legacy_assert_panics_expect_at_least_with_too_few_requests() { - let mock = mock("GET", "/hello").expect_at_least(3).create(); - - request("GET /hello", ""); - request("GET /hello", ""); - - mock.assert(); -} - -#[test] -#[allow(deprecated)] -#[should_panic( - expected = "\n> Expected at most 3 request(s) to:\n\r\nGET /hello\r\n\n...but received 4\n" -)] -fn test_legacy_assert_panics_expect_at_most_with_too_many_requests() { - let mock = mock("GET", "/hello").expect_at_most(3).create(); - - request("GET /hello", ""); - request("GET /hello", ""); - request("GET /hello", ""); - request("GET /hello", ""); - - mock.assert(); -} - -#[test] -#[allow(deprecated)] -#[should_panic( - expected = "\n> Expected between 3 and 5 request(s) to:\n\r\nGET /hello\r\n\n...but received 2\n" -)] -fn test_legacy_assert_panics_expect_at_least_and_at_most_with_too_few_requests() { - let mock = mock("GET", "/hello") - .expect_at_least(3) - .expect_at_most(5) - .create(); - - request("GET /hello", ""); - request("GET /hello", ""); - - mock.assert(); -} - -#[test] -#[allow(deprecated)] -#[should_panic( - expected = "\n> Expected between 3 and 5 request(s) to:\n\r\nGET /hello\r\n\n...but received 6\n" -)] -fn test_legacy_assert_panics_expect_at_least_and_at_most_with_too_many_requests() { - let mock = mock("GET", "/hello") - .expect_at_least(3) - .expect_at_most(5) - .create(); - - request("GET /hello", ""); - request("GET /hello", ""); - request("GET /hello", ""); - request("GET /hello", ""); - request("GET /hello", ""); - request("GET /hello", ""); - - mock.assert(); -} - -#[test] -#[allow(deprecated)] -#[should_panic(expected = "\n> Expected 1 request(s) to:\n\r\nGET /hello\r\n\n...but received 0\n")] -fn test_legacy_assert_panics_if_no_request_was_performed() { - let mock = mock("GET", "/hello").create(); - - mock.assert(); -} - -#[test] -#[allow(deprecated)] -#[should_panic(expected = "\n> Expected 3 request(s) to:\n\r\nGET /hello\r\n\n...but received 2\n")] -fn test_legacy_assert_panics_with_too_few_requests() { - let mock = mock("GET", "/hello").expect(3).create(); - - request("GET /hello", ""); - request("GET /hello", ""); - - mock.assert(); -} - -#[test] -#[allow(deprecated)] -#[should_panic(expected = "\n> Expected 3 request(s) to:\n\r\nGET /hello\r\n\n...but received 4\n")] -fn test_legacy_assert_panics_with_too_many_requests() { - let mock = mock("GET", "/hello").expect(3).create(); - - request("GET /hello", ""); - request("GET /hello", ""); - request("GET /hello", ""); - request("GET /hello", ""); - - mock.assert(); -} - -#[test] -#[allow(deprecated)] -#[should_panic( - expected = "\n> Expected 1 request(s) to:\n\r\nGET /hello\r\n\n...but received 0\n\n> The last unmatched request was:\n\r\nGET /bye\r\n\n> Difference:\n\n\u{1b}[31mGET /hello\n\u{1b}[0m\u{1b}[32mGET\u{1b}[0m\u{1b}[32m \u{1b}[0m\u{1b}[42;37m/bye\u{1b}[0m\u{1b}[32m\n\u{1b}[0m\n\n" -)] -#[cfg(feature = "color")] -fn test_legacy_assert_with_last_unmatched_request() { - let mock = mock("GET", "/hello").create(); - - request("GET /bye", ""); - - mock.assert(); -} - -// Same test but without colors (for Appveyor) -#[test] -#[allow(deprecated)] -#[should_panic( - expected = "\n> Expected 1 request(s) to:\n\r\nGET /hello\r\n\n...but received 0\n\n> The last unmatched request was:\n\r\nGET /bye\r\n\n> Difference:\n\nGET /hello\nGET /bye\n\n\n" -)] -#[cfg(not(feature = "color"))] -fn test_legacy_assert_with_last_unmatched_request() { - let mock = mock("GET", "/hello").create(); - - request("GET /bye", ""); - - mock.assert(); -} - -#[test] -#[allow(deprecated)] -#[should_panic( - expected = "\n> Expected 1 request(s) to:\n\r\nGET /hello\r\n\n...but received 0\n\n> The last unmatched request was:\n\r\nGET /bye\r\nauthorization: 1234\r\naccept: text\r\n\n> Difference:\n\n\u{1b}[31mGET /hello\n\u{1b}[0m\u{1b}[32mGET\u{1b}[0m\u{1b}[32m \u{1b}[0m\u{1b}[42;37m/bye\u{1b}[0m\u{1b}[32m\n\u{1b}[0m\u{1b}[92mauthorization: 1234\n\u{1b}[0m\u{1b}[92maccept: text\n\u{1b}[0m\n\n" -)] -#[cfg(feature = "color")] -fn test_legacy_assert_with_last_unmatched_request_and_headers() { - let mock = mock("GET", "/hello").create(); - - request("GET /bye", "authorization: 1234\r\naccept: text\r\n"); - - mock.assert(); -} - -// Same test but without colors (for Appveyor) -#[test] -#[allow(deprecated)] -#[should_panic( - expected = "\n> Expected 1 request(s) to:\n\r\nGET /hello\r\n\n...but received 0\n\n> The last unmatched request was:\n\r\nGET /bye\r\nauthorization: 1234\r\naccept: text\r\n\n> Difference:\n\nGET /hello\nGET /bye\nauthorization: 1234\naccept: text\n\n\n" -)] -#[cfg(not(feature = "color"))] -fn test_legacy_assert_with_last_unmatched_request_and_headers() { - let mock = mock("GET", "/hello").create(); - - request("GET /bye", "authorization: 1234\r\naccept: text\r\n"); - - mock.assert(); -} - -#[test] -#[allow(deprecated)] -#[should_panic( - expected = "\n> Expected 1 request(s) to:\n\r\nGET /hello\r\n\n...but received 0\n\n> The last unmatched request was:\n\r\nPOST /bye\r\ncontent-length: 5\r\nhello\r\n\n" -)] -fn test_legacy_assert_with_last_unmatched_request_and_body() { - let mock = mock("GET", "/hello").create(); - - request_with_body("POST /bye", "", "hello"); - - mock.assert(); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_request_from_thread() { - let mock = mock("GET", "/").create(); - - let process = thread::spawn(move || { - request("GET /", ""); - }); - - process.join().unwrap(); - - mock.assert(); -} - -#[test] -#[allow(deprecated)] -#[ignore] -// Can't work unless there's a way to apply LOCAL_TEST_MUTEX only to test threads and -// not to any of their sub-threads. -fn test_legacy_mock_from_inside_thread_does_not_lock_forever() { - let _mock_outside_thread = mock("GET", "/").with_body("outside").create(); - - let process = thread::spawn(move || { - let _mock_inside_thread = mock("GET", "/").with_body("inside").create(); - }); - - process.join().unwrap(); - - let (_, _, body) = request("GET /", ""); - - assert_eq!("outside", body); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_head_request_with_overridden_content_length() { - let _mock = mock("HEAD", "/") - .with_header("content-length", "100") - .create(); - - let (_, headers, _) = request("HEAD /", ""); - - assert_eq!( - vec!["connection: close", "content-length: 100"], - headers[0..=1] - ); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_propagate_protocol_to_response() { - let _mock = mock("GET", "/").create(); - - let stream = request_stream("1.0", "GET /", "", ""); - - let (status_line, _, _) = parse_stream(stream, true); - assert_eq!("HTTP/1.0 200 OK\r\n", status_line); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_large_body_without_content_length() { - let body = "123".repeat(2048); - - let _mock = mock("POST", "/").match_body(body.as_str()).create(); - - let headers = format!("content-length: {}\r\n", body.len()); - let stream = request_stream("1.0", "POST /", &headers, &body); - - let (status_line, _, _) = parse_stream(stream, false); - assert_eq!("HTTP/1.0 200 OK\r\n", status_line); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_transfer_encoding_chunked() { - let _mock = mock("POST", "/") - .match_body("Hello, chunked world!") - .create(); - - let body = "3\r\nHel\r\n5\r\nlo, c\r\nD\r\nhunked world!\r\n0\r\n\r\n"; - - let (status, _, _) = parse_stream( - request_stream("1.1", "POST /", "Transfer-Encoding: chunked\r\n", body), - false, - ); - - assert_eq!("HTTP/1.1 200 OK\r\n", status); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_match_exact_query() { - let _m = mock("GET", "/hello") - .match_query(Matcher::Exact("number=one".to_string())) - .create(); - - let (status_line, _, _) = request("GET /hello?number=one", ""); - assert_eq!("HTTP/1.1 200 OK\r\n", status_line); - - let (status_line, _, _) = request("GET /hello?number=two", ""); - assert_eq!("HTTP/1.1 501 Not Implemented\r\n", status_line); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_match_exact_query_via_path() { - let _m = mock("GET", "/hello?number=one").create(); - - let (status_line, _, _) = request("GET /hello?number=one", ""); - assert_eq!("HTTP/1.1 200 OK\r\n", status_line); - - let (status_line, _, _) = request("GET /hello?number=two", ""); - assert_eq!("HTTP/1.1 501 Not Implemented\r\n", status_line); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_match_partial_query_by_regex() { - let _m = mock("GET", "/hello") - .match_query(Matcher::Regex("number=one".to_string())) - .create(); - - let (status_line, _, _) = request("GET /hello?something=else&number=one", ""); - assert_eq!("HTTP/1.1 200 OK\r\n", status_line); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_match_partial_query_by_urlencoded() { - let _m = mock("GET", "/hello") - .match_query(Matcher::UrlEncoded("num ber".into(), "o ne".into())) - .create(); - - let (status_line, _, _) = request("GET /hello?something=else&num%20ber=o%20ne", ""); - assert_eq!("HTTP/1.1 200 OK\r\n", status_line); - - let (status_line, _, _) = request("GET /hello?something=else&number=one", ""); - assert_eq!("HTTP/1.1 501 Not Implemented\r\n", status_line); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_match_partial_query_by_regex_all_of() { - let _m = mock("GET", "/hello") - .match_query(Matcher::AllOf(vec![ - Matcher::Regex("number=one".to_string()), - Matcher::Regex("hello=world".to_string()), - ])) - .create(); - - let (status_line, _, _) = request("GET /hello?hello=world&something=else&number=one", ""); - assert_eq!("HTTP/1.1 200 OK\r\n", status_line); - - let (status_line, _, _) = request("GET /hello?hello=world&something=else", ""); - assert_eq!("HTTP/1.1 501 Not Implemented\r\n", status_line); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_match_partial_query_by_urlencoded_all_of() { - let _m = mock("GET", "/hello") - .match_query(Matcher::AllOf(vec![ - Matcher::UrlEncoded("num ber".into(), "o ne".into()), - Matcher::UrlEncoded("hello".into(), "world".into()), - ])) - .create(); - - let (status_line, _, _) = request("GET /hello?hello=world&something=else&num%20ber=o%20ne", ""); - assert_eq!("HTTP/1.1 200 OK\r\n", status_line); - - let (status_line, _, _) = request("GET /hello?hello=world&something=else", ""); - assert_eq!("HTTP/1.1 501 Not Implemented\r\n", status_line); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_match_query_with_non_percent_url_escaping() { - let _m = mock("GET", "/hello") - .match_query(Matcher::AllOf(vec![ - Matcher::UrlEncoded("num ber".into(), "o ne".into()), - Matcher::UrlEncoded("hello".into(), "world".into()), - ])) - .create(); - - let (status_line, _, _) = request("GET /hello?hello=world&something=else&num+ber=o+ne", ""); - assert_eq!("HTTP/1.1 200 OK\r\n", status_line); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_match_missing_query() { - let _m = mock("GET", "/hello").match_query(Matcher::Missing).create(); - - let (status_line, _, _) = request("GET /hello?", ""); - assert_eq!("HTTP/1.1 200 OK\r\n", status_line); - - let (status_line, _, _) = request("GET /hello?number=one", ""); - assert_eq!("HTTP/1.1 501 Not Implemented\r\n", status_line); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_anyof_exact_path_and_query_matcher() { - let mock = mock( - "GET", - Matcher::AnyOf(vec![Matcher::Exact("/hello?world".to_string())]), - ) - .create(); - - let (status_line, _, _) = request("GET /hello?world", ""); - assert_eq!("HTTP/1.1 200 OK\r\n", status_line); - - mock.assert(); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_default_headers() { - let _m = mock("GET", "/").create(); - - let (_, headers, _) = request("GET /", ""); - assert_eq!( - vec!["connection: close", "content-length: 0"], - headers[0..=1] - ); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_missing_create_bad() { - testing_logger::setup(); - - let m = mock("GET", "/"); - drop(m); - - // Expecting one warning - testing_logger::validate(|captured_logs| { - let warnings = captured_logs - .iter() - .filter(|c| c.level == log::Level::Warn) - .collect::>(); - - assert_eq!(warnings.len(), 1); - assert_eq!( - warnings[0].body, - "Missing .create() call on mock \r\nGET /\r\n" - ); - assert_eq!(warnings[0].level, log::Level::Warn); - }); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_missing_create_good() { - testing_logger::setup(); - - let m = mock("GET", "/").create(); - drop(m); - - // No warnings should occur - testing_logger::validate(|captured_logs| { - assert_eq!( - captured_logs - .iter() - .filter(|c| c.level == log::Level::Warn) - .count(), - 0 - ); - }); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_same_endpoint_different_responses() { - let mock_200 = mock("GET", "/hello").with_status(200).create(); - let mock_404 = mock("GET", "/hello").with_status(404).create(); - let mock_500 = mock("GET", "/hello").with_status(500).create(); - - let response_200 = request("GET /hello", ""); - let response_404 = request("GET /hello", ""); - let response_500 = request("GET /hello", ""); - - mock_200.assert(); - mock_404.assert(); - mock_500.assert(); - - assert_eq!(response_200.0, "HTTP/1.1 200 OK\r\n"); - assert_eq!(response_404.0, "HTTP/1.1 404 Not Found\r\n"); - assert_eq!(response_500.0, "HTTP/1.1 500 Internal Server Error\r\n"); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_same_endpoint_different_responses_last_one_forever() { - let _mock_200 = mock("GET", "/hello").with_status(200).create(); - let _mock_404 = mock("GET", "/hello").with_status(404).create(); - let _mock_500 = mock("GET", "/hello") - .expect_at_least(1) - .with_status(500) - .create(); - - let response_200 = request("GET /hello", ""); - let response_404 = request("GET /hello", ""); - let response_500_1 = request("GET /hello", ""); - let response_500_2 = request("GET /hello", ""); - let response_500_3 = request("GET /hello", ""); - - assert_eq!(response_200.0, "HTTP/1.1 200 OK\r\n"); - assert_eq!(response_404.0, "HTTP/1.1 404 Not Found\r\n"); - assert_eq!(response_500_1.0, "HTTP/1.1 500 Internal Server Error\r\n"); - assert_eq!(response_500_2.0, "HTTP/1.1 500 Internal Server Error\r\n"); - assert_eq!(response_500_3.0, "HTTP/1.1 500 Internal Server Error\r\n"); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_matched_bool() { - let m = mock("GET", "/").create(); - - let (_, _, _) = request_with_body("GET /", "", ""); - m.assert(); - assert!(m.matched(), "matched method returns correctly"); - - let (_, _, _) = request_with_body("GET /", "", ""); - assert!(!m.matched(), "matched method returns correctly"); -} - -#[test] -#[allow(deprecated)] -fn test_legacy_invalid_header_field_name() { - let _m = mock("GET", "/").create(); - - let (uppercase_status_line, _, body) = request("GET /", "Bad Header: something\r\n"); - assert_eq!("HTTP/1.1 400 Bad Request\r\n", uppercase_status_line); - assert_eq!(body, ""); -}