nushell/crates/nu-command/tests/commands/network/http/get.rs

205 lines
4.7 KiB
Rust
Raw Normal View History

use mockito::Server;
use nu_test_support::{nu, pipeline};
#[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();
changes Reqwest to Ureq. (#8320) # Description _(Thank you for improving Nushell. Please, check our [contributing guide](../CONTRIBUTING.md) and talk to the core team before making major changes.)_ This pull request removes `Reqwest` and replaces it with `Ureq` to remove some of our dependencies, giving us faster compile times as well as smaller binaries. `Ureq` does not have an async runtime included so we do not need build heavy dependencies such as `Tokio`. From older tests I had the number of build units be reduced from `430 -> 392`. The default of `Ureq` uses `Rustls` but it has been configured to instead use `native_tls` which should work exactly the same as the `tls` works now. I removed `content-length` from the http commands as after refactoring i did not see a reason to have it available, correct me if this is something we should preserve. In the medium, to long term, we should maybe consider changing to `rustls` to have the same `tls` on all platforms. # User-Facing Changes _(List of all changes that impact the user experience here. This helps us keep track of breaking changes.)_ # 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.
2023-03-05 23:48:13 +01:00
let _mock = server.mock("GET", "/").with_status(400).create();
let actual = nu!(pipeline(
format!(
r#"
http get {url}
"#,
url = server.url()
)
.as_str()
));
assert!(actual.err.contains("Bad request (400)"))
}
#[test]
fn http_get_with_accept_errors() {
let mut server = Server::new();
let _mock = server
.mock("GET", "/")
.with_status(400)
.with_body("error body")
.create();
let actual = nu!(pipeline(
format!(
r#"
http get -e {url}
"#,
url = server.url()
)
.as_str()
));
assert!(actual.out.contains("error body"))
}
#[test]
fn http_get_with_accept_errors_and_full_raw_response() {
let mut server = Server::new();
let _mock = server
.mock("GET", "/")
.with_status(400)
.with_body("error body")
.create();
let actual = nu!(pipeline(
format!(
r#"
http get -e -f {url} | $"($in.status) => ($in.body)"
"#,
url = server.url()
)
.as_str()
));
assert!(actual.out.contains("400 => error body"))
}
#[test]
fn http_get_with_accept_errors_and_full_json_response() {
let mut server = Server::new();
let _mock = server
.mock("GET", "/")
.with_status(400)
.with_header("content-type", "application/json")
.with_body(
r#"
{"msg": "error body"}
"#,
)
.create();
let actual = nu!(pipeline(
format!(
r#"
http get -e -f {url} | $"($in.status) => ($in.body.msg)"
"#,
url = server.url()
)
.as_str()
));
assert!(actual.out.contains("400 => error body"))
}
#[test]
fn http_get_with_custom_headers_as_records() {
let mut server = Server::new();
let mock1 = server
.mock("GET", "/")
.match_header("content-type", "application/json")
.with_body(r#"{"hello": "world"}"#)
.create();
let mock2 = server
.mock("GET", "/")
.match_header("content-type", "text/plain")
.with_body("world")
.create();
let _json_response = nu!(format!(
"http get -H {{content-type: application/json}} {url}",
url = server.url()
));
let _text_response = nu!(format!(
"http get -H {{content-type: text/plain}} {url}",
url = server.url()
));
mock1.assert();
mock2.assert();
}
#[test]
fn http_get_full_response() {
let mut server = Server::new();
let _mock = server.mock("GET", "/").with_body("foo").create();
let actual = nu!(pipeline(
format!(
"http get --full {url} --headers [foo bar] | to json",
url = server.url()
)
.as_str()
));
let output: serde_json::Value = serde_json::from_str(&actual.out).unwrap();
assert_eq!(output["status"], 200);
assert_eq!(output["body"], "foo");
// There's only one request header, we can get it by index
assert_eq!(output["headers"]["request"][0]["name"], "foo");
assert_eq!(output["headers"]["request"][0]["value"], "bar");
// ... and multiple response headers, so have to search by name
let header = output["headers"]["response"]
.as_array()
.unwrap()
.iter()
.find(|e| e["name"] == "connection")
.unwrap();
assert_eq!(header["value"], "close");
}
// These tests require network access; they use badssl.com which is a Google-affiliated site for testing various SSL errors.
// Revisit this if these tests prove to be flaky or unstable.
#[test]
fn http_get_expired_cert_fails() {
let actual = nu!("http get https://expired.badssl.com/");
assert!(actual.err.contains("network_failure"));
}
#[test]
fn http_get_expired_cert_override() {
let actual = nu!("http get --insecure https://expired.badssl.com/");
assert!(actual.out.contains("<html>"));
}
#[test]
fn http_get_self_signed_fails() {
let actual = nu!("http get https://self-signed.badssl.com/");
assert!(actual.err.contains("network_failure"));
}
#[test]
fn http_get_self_signed_override() {
let actual = nu!("http get --insecure https://self-signed.badssl.com/");
assert!(actual.out.contains("<html>"));
}