diff --git a/spring-restdocs-restassured/src/main/java/org/springframework/restdocs/restassured/RestAssuredRequestConverter.java b/spring-restdocs-restassured/src/main/java/org/springframework/restdocs/restassured/RestAssuredRequestConverter.java index d2e60f0c..1673366a 100644 --- a/spring-restdocs-restassured/src/main/java/org/springframework/restdocs/restassured/RestAssuredRequestConverter.java +++ b/spring-restdocs-restassured/src/main/java/org/springframework/restdocs/restassured/RestAssuredRequestConverter.java @@ -16,6 +16,9 @@ package org.springframework.restdocs.restassured; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; import java.net.URI; import java.util.ArrayList; import java.util.Collection; @@ -35,6 +38,8 @@ import org.springframework.restdocs.operation.OperationRequestPart; import org.springframework.restdocs.operation.OperationRequestPartFactory; import org.springframework.restdocs.operation.Parameters; import org.springframework.restdocs.operation.RequestConverter; +import org.springframework.util.FileCopyUtils; +import org.springframework.util.StreamUtils; /** * A converter for creating an {@link OperationRequest} from a REST Assured @@ -64,6 +69,12 @@ class RestAssuredRequestConverter else if (content instanceof byte[]) { return (byte[]) content; } + else if (content instanceof File) { + return copyToByteArray((File) content); + } + else if (content instanceof InputStream) { + return copyToByteArray((InputStream) content); + } else if (content == null) { return new byte[0]; } @@ -73,6 +84,33 @@ class RestAssuredRequestConverter } } + private byte[] copyToByteArray(File file) { + try { + return FileCopyUtils.copyToByteArray(file); + } + catch (IOException ex) { + throw new IllegalStateException("Failed to read content from file " + file, + ex); + } + } + + private byte[] copyToByteArray(InputStream inputStream) { + try { + inputStream.reset(); + } + catch (IOException ex) { + throw new IllegalStateException("Cannot read content from input stream " + + inputStream + " due to reset() failure"); + } + try { + return StreamUtils.copyToByteArray(inputStream); + } + catch (IOException ex) { + throw new IllegalStateException( + "Failed to read content from input stream " + inputStream, ex); + } + } + private HttpHeaders extractHeaders(FilterableRequestSpecification requestSpec) { HttpHeaders httpHeaders = new HttpHeaders(); for (Header header : requestSpec.getHeaders()) { diff --git a/spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured/RestAssuredRequestConverterTests.java b/spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured/RestAssuredRequestConverterTests.java index 3bf79098..9c4f7615 100644 --- a/spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured/RestAssuredRequestConverterTests.java +++ b/spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured/RestAssuredRequestConverterTests.java @@ -18,6 +18,8 @@ package org.springframework.restdocs.restassured; import java.io.ByteArrayInputStream; import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; import java.net.URI; import java.util.Arrays; import java.util.Collection; @@ -198,25 +200,105 @@ public class RestAssuredRequestConverterTests { } @Test - public void inputStreamBodyIsNotSupported() { + public void byteArrayInputStreamBody() { RequestSpecification requestSpec = RestAssured.given() .body(new ByteArrayInputStream(new byte[] { 1, 2, 3, 4 })) .port(this.port); requestSpec.post(); - this.thrown.expectMessage( - equalTo("Unsupported request content: java.io.ByteArrayInputStream")); + OperationRequest request = this.factory + .convert((FilterableRequestSpecification) requestSpec); + assertThat(request.getContent(), is(equalTo(new byte[] { 1, 2, 3, 4 }))); + } + + @Test + public void fileBody() { + RequestSpecification requestSpec = RestAssured.given() + .body(new File("src/test/resources/body.txt")).port(this.port); + requestSpec.post(); + OperationRequest request = this.factory + .convert((FilterableRequestSpecification) requestSpec); + assertThat(request.getContentAsString(), is(equalTo("file"))); + } + + @Test + public void fileInputStreamBody() throws FileNotFoundException { + FileInputStream inputStream = new FileInputStream("src/test/resources/body.txt"); + RequestSpecification requestSpec = RestAssured.given().body(inputStream) + .port(this.port); + requestSpec.post(); + this.thrown.expect(IllegalStateException.class); + this.thrown.expectMessage("Cannot read content from input stream " + inputStream + + " due to reset() failure"); this.factory.convert((FilterableRequestSpecification) requestSpec); } @Test - public void fileBodyIsNotSupported() { - RequestSpecification requestSpec = RestAssured.given() - .body(new File("src/test/resources/body.txt")).port(this.port); + public void multipartWithByteArrayInputStreamBody() { + RequestSpecification requestSpec = RestAssured.given().port(this.port) + .multiPart("foo", "foo.txt", new ByteArrayInputStream("foo".getBytes())); requestSpec.post(); - this.thrown.expectMessage(equalTo("Unsupported request content: java.io.File")); + OperationRequest request = this.factory + .convert((FilterableRequestSpecification) requestSpec); + assertThat(request.getParts().iterator().next().getContentAsString(), + is(equalTo("foo"))); + } + + @Test + public void multipartWithStringBody() { + RequestSpecification requestSpec = RestAssured.given().port(this.port) + .multiPart("control", "foo"); + requestSpec.post(); + OperationRequest request = this.factory + .convert((FilterableRequestSpecification) requestSpec); + assertThat(request.getParts().iterator().next().getContentAsString(), + is(equalTo("foo"))); + } + + @Test + public void multipartWithByteArrayBody() { + RequestSpecification requestSpec = RestAssured.given().port(this.port) + .multiPart("control", "file", "foo".getBytes()); + requestSpec.post(); + OperationRequest request = this.factory + .convert((FilterableRequestSpecification) requestSpec); + assertThat(request.getParts().iterator().next().getContentAsString(), + is(equalTo("foo"))); + } + + @Test + public void multipartWithFileBody() { + RequestSpecification requestSpec = RestAssured.given().port(this.port) + .multiPart(new File("src/test/resources/body.txt")); + requestSpec.post(); + OperationRequest request = this.factory + .convert((FilterableRequestSpecification) requestSpec); + assertThat(request.getParts().iterator().next().getContentAsString(), + is(equalTo("file"))); + } + + @Test + public void multipartWithFileInputStreamBody() throws FileNotFoundException { + FileInputStream inputStream = new FileInputStream("src/test/resources/body.txt"); + RequestSpecification requestSpec = RestAssured.given().port(this.port) + .multiPart("foo", "foo.txt", inputStream); + requestSpec.post(); + this.thrown.expect(IllegalStateException.class); + this.thrown.expectMessage("Cannot read content from input stream " + inputStream + + " due to reset() failure"); this.factory.convert((FilterableRequestSpecification) requestSpec); } + @Test + public void multipartWithObjectBody() { + RequestSpecification requestSpec = RestAssured.given().port(this.port) + .multiPart("control", new ObjectBody("bar")); + requestSpec.post(); + OperationRequest request = this.factory + .convert((FilterableRequestSpecification) requestSpec); + assertThat(request.getParts().iterator().next().getContentAsString(), + is(equalTo("{\"foo\":\"bar\"}"))); + } + /** * Minimal test web application. */