Add unit tests for HTTP commands. (#8267)

# Description

Following the comment from @fdncred:
https://github.com/nushell/nushell/pull/8144#issuecomment-1442514338. I
added some unit tests for HTTP commands. The tests are not exhaustive,
but at least, this is a first good step IMO.

# User-Facing Changes

None.

# Tests + Formatting

Don't forget to add tests that cover your changes.

Make sure you've run and fixed any issues with these commands:

- `cargo fmt --all -- --check` to check standard code formatting (`cargo
fmt --all` applies these changes)
- `cargo clippy --workspace -- -D warnings -D clippy::unwrap_used -A
clippy::needless_collect` to check that you're using the standard code
style
- `cargo test --workspace` to check that all tests pass

# After Submitting

If your PR had any user-facing changes, update [the
documentation](https://github.com/nushell/nushell.github.io) after the
PR is merged, if necessary. This will help us keep the docs up to date.
This commit is contained in:
Jérémy Audiger 2023-03-02 20:05:18 +01:00 committed by GitHub
parent 12483fac92
commit c1d76bfac7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 476 additions and 0 deletions

89
Cargo.lock generated
View file

@ -182,6 +182,16 @@ dependencies = [
"zstd", "zstd",
] ]
[[package]]
name = "assert-json-diff"
version = "2.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "47e4f2b81832e72834d7518d8487a0396a28cc408186a2e8854c0f98011faf12"
dependencies = [
"serde",
"serde_json",
]
[[package]] [[package]]
name = "assert_cmd" name = "assert_cmd"
version = "2.0.4" version = "2.0.4"
@ -618,6 +628,17 @@ dependencies = [
"encoding_rs", "encoding_rs",
] ]
[[package]]
name = "colored"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b3616f750b84d8f0de8a58bda93e08e2a81ad3f523089b05f1dffecab48c6cbd"
dependencies = [
"atty",
"lazy_static",
"winapi",
]
[[package]] [[package]]
name = "comfy-table" name = "comfy-table"
version = "6.1.4" version = "6.1.4"
@ -984,6 +1005,25 @@ dependencies = [
"parking_lot_core 0.9.3", "parking_lot_core 0.9.3",
] ]
[[package]]
name = "deadpool"
version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "421fe0f90f2ab22016f32a9881be5134fdd71c65298917084b0c7477cbc3856e"
dependencies = [
"async-trait",
"deadpool-runtime",
"num_cpus",
"retain_mut",
"tokio",
]
[[package]]
name = "deadpool-runtime"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eaa37046cc0f6c3cc6090fbdbf73ef0b8ef4cfcc37f6befc0020f63e8cf121e1"
[[package]] [[package]]
name = "derive_more" name = "derive_more"
version = "0.99.17" version = "0.99.17"
@ -2412,6 +2452,28 @@ dependencies = [
"windows-sys 0.36.1", "windows-sys 0.36.1",
] ]
[[package]]
name = "mockito"
version = "0.32.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09908a0c0e8c956c1360268b54c0f7eeefc7ef98020cfb81077fa71761a18d29"
dependencies = [
"assert-json-diff",
"async-trait",
"colored",
"deadpool",
"futures",
"hyper",
"lazy_static",
"log",
"rand 0.8.5",
"regex",
"serde_json",
"serde_urlencoded",
"similar",
"tokio",
]
[[package]] [[package]]
name = "multiversion" name = "multiversion"
version = "0.6.1" version = "0.6.1"
@ -2710,6 +2772,7 @@ dependencies = [
"md-5", "md-5",
"mime", "mime",
"mime_guess", "mime_guess",
"mockito",
"notify", "notify",
"nu-ansi-term", "nu-ansi-term",
"nu-cmd-lang", "nu-cmd-lang",
@ -4284,6 +4347,12 @@ dependencies = [
"winreg 0.10.1", "winreg 0.10.1",
] ]
[[package]]
name = "retain_mut"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4389f1d5789befaf6029ebd9f7dac4af7f7e3d61b69d4f30e2ac02b57e7712b0"
[[package]] [[package]]
name = "riscv" name = "riscv"
version = "0.7.0" version = "0.7.0"
@ -4798,6 +4867,12 @@ version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a" checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a"
[[package]]
name = "similar"
version = "2.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "420acb44afdae038210c99e69aae24109f32f15500aa708e81d46c9f29d55fcf"
[[package]] [[package]]
name = "simplelog" name = "simplelog"
version = "0.12.0" version = "0.12.0"
@ -5296,11 +5371,25 @@ dependencies = [
"memchr", "memchr",
"mio", "mio",
"num_cpus", "num_cpus",
"parking_lot 0.12.1",
"pin-project-lite", "pin-project-lite",
"signal-hook-registry",
"socket2", "socket2",
"tokio-macros",
"windows-sys 0.42.0", "windows-sys 0.42.0",
] ]
[[package]]
name = "tokio-macros"
version = "1.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d266c00fde287f55d3f1c3e96c500c362a2b8c695076ec180f27918820bc6df8"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]] [[package]]
name = "tokio-native-tls" name = "tokio-native-tls"
version = "0.3.0" version = "0.3.0"

View file

@ -156,6 +156,7 @@ which-support = ["which"]
[dev-dependencies] [dev-dependencies]
nu-test-support = { path = "../nu-test-support", version = "0.76.1" } nu-test-support = { path = "../nu-test-support", version = "0.76.1" }
mockito = "0.32.3"
dirs-next = "2.0.0" dirs-next = "2.0.0"
hamcrest2 = "0.3.0" hamcrest2 = "0.3.0"

View file

@ -0,0 +1,44 @@
use mockito::Server;
use nu_test_support::{nu, pipeline};
use reqwest::StatusCode;
#[test]
fn http_delete_is_success() {
let mut server = Server::new();
let _mock = server.mock("DELETE", "/").create();
let actual = nu!(pipeline(
format!(
r#"
http delete {url}
"#,
url = server.url()
)
.as_str()
));
assert!(actual.out.is_empty())
}
#[test]
fn http_delete_failed_due_to_server_error() {
let mut server = Server::new();
let _mock = server
.mock("DELETE", "/")
.with_status(StatusCode::BAD_REQUEST.as_u16() as usize)
.create();
let actual = nu!(pipeline(
format!(
r#"
http delete {url}
"#,
url = server.url()
)
.as_str()
));
assert!(actual.err.contains("Bad request (400)"))
}

View file

@ -0,0 +1,44 @@
use mockito::Server;
use nu_test_support::{nu, pipeline};
use reqwest::StatusCode;
#[test]
fn http_get_is_success() {
let mut server = Server::new();
let _mock = server.mock("GET", "/").with_body("foo").create();
let actual = nu!(pipeline(
format!(
r#"
http get {url}
"#,
url = server.url()
)
.as_str()
));
assert_eq!(actual.out, "foo")
}
#[test]
fn http_get_failed_due_to_server_error() {
let mut server = Server::new();
let _mock = server
.mock("GET", "/")
.with_status(StatusCode::BAD_REQUEST.as_u16() as usize)
.create();
let actual = nu!(pipeline(
format!(
r#"
http get {url}
"#,
url = server.url()
)
.as_str()
));
assert!(actual.err.contains("Bad request (400)"))
}

View file

@ -0,0 +1,45 @@
use mockito::Server;
use nu_test_support::{nu, pipeline};
use reqwest::StatusCode;
#[test]
fn http_head_is_success() {
let mut server = Server::new();
let _mock = server.mock("HEAD", "/").with_header("foo", "bar").create();
let actual = nu!(pipeline(
format!(
r#"
http head {url}
"#,
url = server.url()
)
.as_str()
));
assert!(actual.out.contains("foo"));
assert!(actual.out.contains("bar"));
}
#[test]
fn http_head_failed_due_to_server_error() {
let mut server = Server::new();
let _mock = server
.mock("HEAD", "/")
.with_status(StatusCode::BAD_REQUEST.as_u16() as usize)
.create();
let actual = nu!(pipeline(
format!(
r#"
http head {url}
"#,
url = server.url()
)
.as_str()
));
assert!(actual.err.contains("Bad request (400)"))
}

View file

@ -0,0 +1,6 @@
mod delete;
mod get;
mod head;
mod patch;
mod post;
mod put;

View file

@ -0,0 +1,82 @@
use mockito::Server;
use nu_test_support::{nu, pipeline};
use reqwest::StatusCode;
#[test]
fn http_patch_is_success() {
let mut server = Server::new();
let _mock = server.mock("PATCH", "/").match_body("foo").create();
let actual = nu!(pipeline(
format!(
r#"
http patch {url} "foo"
"#,
url = server.url()
)
.as_str()
));
assert!(actual.out.is_empty())
}
#[test]
fn http_patch_failed_due_to_server_error() {
let mut server = Server::new();
let _mock = server
.mock("PATCH", "/")
.with_status(StatusCode::BAD_REQUEST.as_u16() as usize)
.create();
let actual = nu!(pipeline(
format!(
r#"
http patch {url} "body"
"#,
url = server.url()
)
.as_str()
));
assert!(actual.err.contains("Bad request (400)"))
}
#[test]
fn http_patch_failed_due_to_missing_body() {
let mut server = Server::new();
let _mock = server.mock("PATCH", "/").create();
let actual = nu!(pipeline(
format!(
r#"
http patch {url}
"#,
url = server.url()
)
.as_str()
));
assert!(actual.err.contains("Usage: http patch"))
}
#[test]
fn http_patch_failed_due_to_unexpected_body() {
let mut server = Server::new();
let _mock = server.mock("PATCH", "/").match_body("foo").create();
let actual = nu!(pipeline(
format!(
r#"
http patch {url} "bar"
"#,
url = server.url()
)
.as_str()
));
assert!(actual.err.contains("Cannot make request"))
}

View file

@ -0,0 +1,82 @@
use mockito::Server;
use nu_test_support::{nu, pipeline};
use reqwest::StatusCode;
#[test]
fn http_post_is_success() {
let mut server = Server::new();
let _mock = server.mock("POST", "/").match_body("foo").create();
let actual = nu!(pipeline(
format!(
r#"
http post {url} "foo"
"#,
url = server.url()
)
.as_str()
));
assert!(actual.out.is_empty())
}
#[test]
fn http_post_failed_due_to_server_error() {
let mut server = Server::new();
let _mock = server
.mock("POST", "/")
.with_status(StatusCode::BAD_REQUEST.as_u16() as usize)
.create();
let actual = nu!(pipeline(
format!(
r#"
http post {url} "body"
"#,
url = server.url()
)
.as_str()
));
assert!(actual.err.contains("Bad request (400)"))
}
#[test]
fn http_post_failed_due_to_missing_body() {
let mut server = Server::new();
let _mock = server.mock("POST", "/").create();
let actual = nu!(pipeline(
format!(
r#"
http post {url}
"#,
url = server.url()
)
.as_str()
));
assert!(actual.err.contains("Usage: http post"))
}
#[test]
fn http_post_failed_due_to_unexpected_body() {
let mut server = Server::new();
let _mock = server.mock("POST", "/").match_body("foo").create();
let actual = nu!(pipeline(
format!(
r#"
http post {url} "bar"
"#,
url = server.url()
)
.as_str()
));
assert!(actual.err.contains("Cannot make request"))
}

View file

@ -0,0 +1,82 @@
use mockito::Server;
use nu_test_support::{nu, pipeline};
use reqwest::StatusCode;
#[test]
fn http_put_is_success() {
let mut server = Server::new();
let _mock = server.mock("PUT", "/").match_body("foo").create();
let actual = nu!(pipeline(
format!(
r#"
http put {url} "foo"
"#,
url = server.url()
)
.as_str()
));
assert!(actual.out.is_empty())
}
#[test]
fn http_put_failed_due_to_server_error() {
let mut server = Server::new();
let _mock = server
.mock("PUT", "/")
.with_status(StatusCode::BAD_REQUEST.as_u16() as usize)
.create();
let actual = nu!(pipeline(
format!(
r#"
http put {url} "body"
"#,
url = server.url()
)
.as_str()
));
assert!(actual.err.contains("Bad request (400)"))
}
#[test]
fn http_put_failed_due_to_missing_body() {
let mut server = Server::new();
let _mock = server.mock("PUT", "/").create();
let actual = nu!(pipeline(
format!(
r#"
http put {url}
"#,
url = server.url()
)
.as_str()
));
assert!(actual.err.contains("Usage: http put"))
}
#[test]
fn http_put_failed_due_to_unexpected_body() {
let mut server = Server::new();
let _mock = server.mock("PUT", "/").match_body("foo").create();
let actual = nu!(pipeline(
format!(
r#"
http put {url} "bar"
"#,
url = server.url()
)
.as_str()
));
assert!(actual.err.contains("Cannot make request"))
}

View file

@ -1 +1,2 @@
mod http;
mod port; mod port;