nushell/crates/nu-command/tests/commands/network/http/post.rs
Jack Wright 0d060aeae8
Use pipeline data for http post|put|patch|delete commands. (#13254)
# Description
Provides the ability to use http commands as part of a pipeline.
Additionally, this pull requests extends the pipeline metadata to add a
content_type field. The content_type metadata field allows commands such
as `to json` to set the metadata in the pipeline allowing the http
commands to use it when making requests.

This pull request also introduces the ability to directly stream http
requests from streaming pipelines.

One other small change is that Content-Type will always be set if it is
passed in to the http commands, either indirectly or throw the content
type flag. Previously it was not preserved with requests that were not
of type json or form data.

# User-Facing Changes
* `http post`, `http put`, `http patch`, `http delete` can be used as
part of a pipeline
* `to text`, `to json`, `from json` all set the content_type metadata
field and the http commands will utilize them when making requests.
2024-07-01 12:34:19 -07:00

200 lines
4.2 KiB
Rust

use mockito::Server;
use nu_test_support::{nu, pipeline};
#[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_is_success_pipeline() {
let mut server = Server::new();
let _mock = server.mock("POST", "/").match_body("foo").create();
let actual = nu!(pipeline(
format!(
r#"
"foo" | http post {url}
"#,
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(400).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("Data must be provided either through pipeline or positional argument"))
}
#[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"))
}
#[test]
fn http_post_json_is_success() {
let mut server = Server::new();
let mock = server
.mock("POST", "/")
.match_body(r#"{"foo":"bar"}"#)
.create();
let actual = nu!(format!(
r#"http post -t 'application/json' {url} {{foo: 'bar'}}"#,
url = server.url()
));
mock.assert();
assert!(actual.out.is_empty())
}
#[test]
fn http_post_json_list_is_success() {
let mut server = Server::new();
let mock = server
.mock("POST", "/")
.match_body(r#"[{"foo":"bar"}]"#)
.create();
let actual = nu!(format!(
r#"http post -t 'application/json' {url} [{{foo: "bar"}}]"#,
url = server.url()
));
mock.assert();
assert!(actual.out.is_empty())
}
#[test]
fn http_post_follows_redirect() {
let mut server = Server::new();
let _mock = server.mock("GET", "/bar").with_body("bar").create();
let _mock = server
.mock("POST", "/foo")
.with_status(301)
.with_header("Location", "/bar")
.create();
let actual = nu!(pipeline(
format!("http post {url}/foo postbody", url = server.url()).as_str()
));
assert_eq!(&actual.out, "bar");
}
#[test]
fn http_post_redirect_mode_manual() {
let mut server = Server::new();
let _mock = server
.mock("POST", "/foo")
.with_status(301)
.with_body("foo")
.with_header("Location", "/bar")
.create();
let actual = nu!(pipeline(
format!(
"http post --redirect-mode manual {url}/foo postbody",
url = server.url()
)
.as_str()
));
assert_eq!(&actual.out, "foo");
}
#[test]
fn http_post_redirect_mode_error() {
let mut server = Server::new();
let _mock = server
.mock("POST", "/foo")
.with_status(301)
.with_body("foo")
.with_header("Location", "/bar")
.create();
let actual = nu!(pipeline(
format!(
"http post --redirect-mode error {url}/foo postbody",
url = server.url()
)
.as_str()
));
assert!(&actual.err.contains("nu::shell::network_failure"));
assert!(&actual.err.contains(
"Redirect encountered when redirect handling mode was 'error' (301 Moved Permanently)"
));
}