From c1d84e43fe117f9e901e9a7ba0a91bc09458e54b Mon Sep 17 00:00:00 2001 From: Joan Maspons Date: Mon, 29 Apr 2024 17:47:27 +0200 Subject: [PATCH] Fix `build_mock_url()` for requests with multipart body with string values --- NEWS.md | 2 ++ R/build-mock-url.R | 6 ++++-- tests/testthat/test-capture-requests.R | 20 ++++++++++++++++++++ 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/NEWS.md b/NEWS.md index ae13e03..c78a0de 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,7 @@ # httptest2 1.1.0.9000 +* `build_mock_url()` now works with multipart body request containg strings (#40, @jmaspons) + # httptest2 1.1.0 * `request` is now removed when saving `httr2_response` objects. In earlier versions of `httr2`, requests were not included in responses, but in httr2 1.0.0, [they were added](https://github.com/r-lib/httr2/pull/359) in order to improve error messages. *If you recorded any responses with httr2 >= 1.0 and httptest2 prior to this version, you may have leaked auth secrets: this would happen if your requests included auth information (as in an `Authentication` header), and the response was saved in a .R file, not simplified to .json or other response-body-only formats. Please inspect your recorded responses and invalidate any tokens that were exposed.* diff --git a/R/build-mock-url.R b/R/build-mock-url.R index 74bd752..55b02a6 100644 --- a/R/build-mock-url.R +++ b/R/build-mock-url.R @@ -79,9 +79,11 @@ get_string_request_body <- function(req) { if (inherits(x, "form_file")) { # hash the file contents paste("File:", digest(x$path, serialize = FALSE, file = TRUE)) - } else { - # assume form_data + } else if (inherits(x, "form_data")){ rawToChar(x$value) + } else { + # assume string + x } }) b <- paste(c( diff --git a/tests/testthat/test-capture-requests.R b/tests/testthat/test-capture-requests.R index 94a38dd..2cfecb7 100644 --- a/tests/testthat/test-capture-requests.R +++ b/tests/testthat/test-capture-requests.R @@ -1,6 +1,8 @@ d <- tempfile() dl_file <- tempfile() webp_file <- tempfile() +file_path <- tempfile() +writeLines(letters[1:6], file_path) # The webfake URL will be something like 127.0.0.1:port, and port may vary # so the mock paths will be different every time it runs @@ -31,6 +33,14 @@ test_that("We can record a series of requests (a few ways)", { req_perform(path = webp_file) r8 <<- request(httpbin$url("/status/202")) %>% req_perform() r9 <<- request(httpbin$url("/status/200")) %>% req_perform() + r10 <<- request(httpbin$url("/post")) %>% + req_body_multipart( + file = curl::form_file(file_path), + string = "some text", + form_data = curl::form_data("form data") + ) %>% + req_method("POST") %>% + req_perform() stop_capturing() }) @@ -41,6 +51,7 @@ test_that("We can record a series of requests (a few ways)", { "httpbin.org/get.json", "httpbin.org/image/webp.R", # Not a simplifiable format, so .R "httpbin.org/image/webp.R-FILE", # The `write_disk` location + "httpbin.org/post-40b03d-POST.json", "httpbin.org/put-PUT.json", # Not a GET, but returns 200 "httpbin.org/response-headers-ac4928.json", "httpbin.org/status/200.txt", # empty 200 response "text/plain", so .txt @@ -94,6 +105,14 @@ test_that("We can then load the mocks it stores", { req_perform(path = mock_webp_file) m8 <- request(httpbin$url("/status/202")) %>% req_perform() m9 <- request(httpbin$url("/status/200")) %>% req_perform() + m10 <- request(httpbin$url("/post")) %>% + req_body_multipart( + file = curl::form_file(file_path), + string = "some text", + form_data = curl::form_data("form data") + ) %>% + req_method("POST") %>% + req_perform() }) }) expect_identical(resp_body_json(m1), resp_body_json(r1)) @@ -114,6 +133,7 @@ test_that("We can then load the mocks it stores", { expect_equal(resp_status(m9), 200) expect_equal(resp_content_type(m9), "text/plain") expect_false(resp_has_body(m9)) + expect_identical(resp_body_json(m10), resp_body_json(r10)) }) test_that("write_disk mocks can be reloaded even if the mock directory moves", {