From c8f98ecd8d36b6d270852f0fd5b6b491108c696c Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Wed, 25 Jan 2017 15:23:18 -0500 Subject: [PATCH] Add MockPart to spring-test Issue: SPR-14252 --- .../springframework/mock/web/MockPart.java | 133 ++++++++++++++++++ .../mock/web/test/MockPart.java | 83 +++++------ 2 files changed, 165 insertions(+), 51 deletions(-) create mode 100644 spring-test/src/main/java/org/springframework/mock/web/MockPart.java diff --git a/spring-test/src/main/java/org/springframework/mock/web/MockPart.java b/spring-test/src/main/java/org/springframework/mock/web/MockPart.java new file mode 100644 index 0000000000..cf7d898457 --- /dev/null +++ b/spring-test/src/main/java/org/springframework/mock/web/MockPart.java @@ -0,0 +1,133 @@ +/* + * Copyright 2002-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.mock.web; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Collection; +import javax.servlet.http.Part; + +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.util.Assert; +import org.springframework.util.FileCopyUtils; + + +/** + * Mock implementation of {@code javax.servlet.http.Part}. + * + * @author Rossen Stoyanchev + * @since 5.0 + */ +public class MockPart implements Part { + + private final String name; + + private final String filename; + + private final byte[] content; + + private final HttpHeaders headers = new HttpHeaders(); + + + /** + * Constructor for a part with byte[] content only. + */ + public MockPart(String name, byte[] content) { + this(name, null, content); + } + + /** + * Constructor for a part with a filename. + */ + public MockPart(String name, String filename, InputStream content) throws IOException { + this(name, filename, FileCopyUtils.copyToByteArray(content)); + } + + /** + * Constructor for a part with byte[] content only. + * @see #getHeaders() + */ + private MockPart(String name, String filename, byte[] content) { + Assert.hasLength(name, "Name must not be null"); + this.name = name; + this.filename = filename; + this.content = (content != null ? content : new byte[0]); + this.headers.setContentDispositionFormData(name, filename); + } + + + @Override + public String getName() { + return this.name; + } + + @Override + public String getSubmittedFileName() { + return this.filename; + } + + @Override + public String getContentType() { + MediaType contentType = this.headers.getContentType(); + return (contentType != null ? contentType.toString() : null); + } + + @Override + public long getSize() { + return this.content.length; + } + + @Override + public InputStream getInputStream() throws IOException { + return new ByteArrayInputStream(this.content); + } + + @Override + public String getHeader(String name) { + return this.headers.getFirst(name); + } + + @Override + public Collection getHeaders(String name) { + return this.headers.get(name); + } + + @Override + public Collection getHeaderNames() { + return this.headers.keySet(); + } + + /** + * Return the {@link HttpHeaders} backing header related accessor methods. + */ + public HttpHeaders getHeaders() { + return this.headers; + } + + @Override + public void write(String fileName) throws IOException { + throw new UnsupportedOperationException(); + } + + @Override + public void delete() throws IOException { + throw new UnsupportedOperationException(); + } + +} diff --git a/spring-web/src/test/java/org/springframework/mock/web/test/MockPart.java b/spring-web/src/test/java/org/springframework/mock/web/test/MockPart.java index 1f742eed9e..77384e9be5 100644 --- a/spring-web/src/test/java/org/springframework/mock/web/test/MockPart.java +++ b/spring-web/src/test/java/org/springframework/mock/web/test/MockPart.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,72 +20,55 @@ import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.util.Collection; -import java.util.Collections; import javax.servlet.http.Part; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; import org.springframework.util.Assert; import org.springframework.util.FileCopyUtils; + /** - * Mock implementation of the {@link Part} interface. + * Mock implementation of {@code javax.servlet.http.Part}. * * @author Rossen Stoyanchev * @since 3.1 - * @see MockHttpServletRequest */ public class MockPart implements Part { - private static final String CONTENT_TYPE = "Content-Type"; - private final String name; - private String contentType; + private final String filename; private final byte[] content; + private final HttpHeaders headers = new HttpHeaders(); + + /** - * Create a new MockPart with the given content. - * @param name the name of the part - * @param content the content for the part + * Constructor for a part with byte[] content only. */ public MockPart(String name, byte[] content) { - this(name, "", content); + this(name, null, content); } /** - * Create a new MockPart with the given content. - * @param name the name of the part - * @param contentStream the content of the part as stream - * @throws IOException if reading from the stream failed + * Constructor for a part with a filename. */ - public MockPart(String name, InputStream contentStream) throws IOException { - this(name, "", FileCopyUtils.copyToByteArray(contentStream)); + public MockPart(String name, String filename, InputStream content) throws IOException { + this(name, filename, FileCopyUtils.copyToByteArray(content)); } /** - * Create a new MockPart with the given content. - * @param name the name of the file - * @param contentType the content type (if known) - * @param content the content of the file + * Constructor for a part with byte[] content only. + * @see #getHeaders() */ - public MockPart(String name, String contentType, byte[] content) { + private MockPart(String name, String filename, byte[] content) { Assert.hasLength(name, "Name must not be null"); this.name = name; - this.contentType = contentType; + this.filename = filename; this.content = (content != null ? content : new byte[0]); - } - - /** - * Create a new MockPart with the given content. - * @param name the name of the file - * @param contentType the content type (if known) - * @param contentStream the content of the part as stream - * @throws IOException if reading from the stream failed - */ - public MockPart(String name, String contentType, InputStream contentStream) - throws IOException { - - this(name, contentType, FileCopyUtils.copyToByteArray(contentStream)); + this.headers.setContentDispositionFormData(name, filename); } @@ -96,12 +79,13 @@ public class MockPart implements Part { @Override public String getSubmittedFileName() { - return this.name; + return this.filename; } @Override public String getContentType() { - return this.contentType; + MediaType contentType = this.headers.getContentType(); + return (contentType != null ? contentType.toString() : null); } @Override @@ -116,27 +100,24 @@ public class MockPart implements Part { @Override public String getHeader(String name) { - if (CONTENT_TYPE.equalsIgnoreCase(name)) { - return this.contentType; - } - else { - return null; - } + return this.headers.getFirst(name); } @Override public Collection getHeaders(String name) { - if (CONTENT_TYPE.equalsIgnoreCase(name)) { - return Collections.singleton(this.contentType); - } - else { - return null; - } + return this.headers.get(name); } @Override public Collection getHeaderNames() { - return Collections.singleton(CONTENT_TYPE); + return this.headers.keySet(); + } + + /** + * Return the {@link HttpHeaders} backing header related accessor methods. + */ + public HttpHeaders getHeaders() { + return this.headers; } @Override