This is an automated email from the ASF dual-hosted git repository. reta pushed a commit to branch 3.6.x-fixes in repository https://gitbox.apache.org/repos/asf/cxf.git
commit 269c9ffb1b936ae8ef1435c9dcb280bf29b849d5 Author: Andriy Redko <[email protected]> AuthorDate: Mon Dec 23 10:41:55 2024 -0500 Add more @Multipart tests (#2152) (cherry picked from commit 477ee89c020bb21c6d2528646bc34230cb6cb719) (cherry picked from commit 7c1a0f3da3f3111cd8be8bd663f18ba900cd2319) # Conflicts: # systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSMultipartTest.java --- .../cxf/systest/jaxrs/JAXRSMultipartTest.java | 44 ++++++ .../apache/cxf/systest/jaxrs/MultipartStore.java | 18 +++ .../validation/JAXRSMultipartValidationTest.java | 169 +++++++++++++++++++++ .../MultipartBookStoreWithValidation.java | 54 +++++++ 4 files changed, 285 insertions(+) diff --git a/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSMultipartTest.java b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSMultipartTest.java index dcd0856952..b3b3a6f451 100644 --- a/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSMultipartTest.java +++ b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSMultipartTest.java @@ -38,6 +38,7 @@ import java.util.Map; import javax.activation.DataHandler; import javax.imageio.ImageIO; import javax.mail.util.ByteArrayDataSource; +import javax.ws.rs.client.Client; import javax.ws.rs.client.ClientBuilder; import javax.ws.rs.client.Entity; import javax.ws.rs.client.WebTarget; @@ -418,6 +419,49 @@ public class JAXRSMultipartTest extends AbstractBusClientServerTestBase { doAddBook(address, "attachmentData", 200); } + @Test + public void testAddBookWithDetailsAsMultipart() throws Exception { + String address = "http://localhost:" + PORT + "/bookstore/books/details"; + + final Client client = ClientBuilder.newClient(); + try (InputStream is = getClass() + .getResourceAsStream("/org/apache/cxf/systest/jaxrs/resources/attachmentData")) { + final MultipartBody builder = new MultipartBody(Arrays.asList( + new AttachmentBuilder() + .mediaType("application/xml") + .id("book") + .object(new Book()) + .build(), + new AttachmentBuilder() + .id("upfile1Detail") + .object(is) + .contentDisposition(new ContentDisposition("form-data; name=\"field1\";")) + .build(), + new AttachmentBuilder() + .id("upfile2Detail") + .dataHandler(new DataHandler( + new InputStreamDataSource(new ByteArrayInputStream(new byte[0]), "text/xml"))) + .contentDisposition(new ContentDisposition("form-data; name=\"field2\";")) + .build(), + new AttachmentBuilder() + .id("upfile3Detail") + .dataHandler(new DataHandler(new InputStreamDataSource( + new ByteArrayInputStream(new byte[0]), "text/xml"))) + .contentDisposition(new ContentDisposition("form-data; name=\"field3\";")) + .build())); + + final Response response = client + .target(address) + .request("text/xml") + .post(Entity.entity(builder, "multipart/form-data")); + + final Book book = response.readEntity(Book.class); + assertThat("Unexpected status code for response:" + response, + response.getStatus(), equalTo(200)); + assertThat(book.getName(), equalTo("upfile1Detail,upfile2Detail,upfile3Detail")); + } + } + @Test public void testAddBookAsJAXBBody() throws Exception { String address = "http://localhost:" + PORT + "/bookstore/books/jaxb-body"; diff --git a/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/MultipartStore.java b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/MultipartStore.java index b9c244b43a..03c03019ae 100644 --- a/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/MultipartStore.java +++ b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/MultipartStore.java @@ -405,6 +405,24 @@ public class MultipartStore { return Response.ok(b1).build(); } + @POST + @Path("/books/details") + @Consumes("multipart/form-data") + @Produces("text/xml") + public Response addBookWithDetails(@Multipart(value = "book", type = "application/xml") Book book, + @Multipart("upfile1Detail") Attachment a1, + @Multipart("upfile2Detail") Attachment a2, + @Multipart("upfile3Detail") Attachment a3) + throws Exception { + + if (a1.equals(a2) || a1.equals(a3) || a2.equals(a3)) { + throw new WebApplicationException(); + } + + book.setName(a1.getContentId() + "," + a2.getContentId() + "," + a3.getContentId()); + return Response.ok(book).build(); + } + @POST @Path("/books/jaxb-body") @Consumes("multipart/related;type=\"text/xml\"") diff --git a/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/validation/JAXRSMultipartValidationTest.java b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/validation/JAXRSMultipartValidationTest.java new file mode 100644 index 0000000000..7e73395d05 --- /dev/null +++ b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/validation/JAXRSMultipartValidationTest.java @@ -0,0 +1,169 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.cxf.systest.jaxrs.validation; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.util.Arrays; +import java.util.List; + +import javax.activation.DataHandler; +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.Entity; +import javax.ws.rs.core.Response; + +import org.apache.cxf.Bus; +import org.apache.cxf.jaxrs.JAXRSServerFactoryBean; +import org.apache.cxf.jaxrs.ext.multipart.AttachmentBuilder; +import org.apache.cxf.jaxrs.ext.multipart.ContentDisposition; +import org.apache.cxf.jaxrs.ext.multipart.InputStreamDataSource; +import org.apache.cxf.jaxrs.ext.multipart.MultipartBody; +import org.apache.cxf.jaxrs.lifecycle.SingletonResourceProvider; +import org.apache.cxf.jaxrs.model.AbstractResourceInfo; +import org.apache.cxf.jaxrs.validation.ValidationExceptionMapper; +import org.apache.cxf.testutil.common.AbstractServerTestServerBase; +import org.apache.cxf.validation.BeanValidationFeature; + +import org.junit.BeforeClass; +import org.junit.Test; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.Assert.assertTrue; + +public class JAXRSMultipartValidationTest extends AbstractJAXRSValidationTest { + public static final String PORT = allocatePort(JAXRSMultipartValidationTest.class); + + public static class Server extends AbstractServerTestServerBase { + @Override + protected org.apache.cxf.endpoint.Server createServer(Bus bus) throws Exception { + final JAXRSServerFactoryBean sf = new JAXRSServerFactoryBean(); + sf.setResourceClasses(MultipartBookStoreWithValidation.class); + sf.setFeatures(List.of(new BeanValidationFeature())); + sf.setProvider(new ValidationExceptionMapper()); + sf.setResourceProvider(new SingletonResourceProvider(new MultipartBookStoreWithValidation())); + sf.setAddress("http://localhost:" + PORT + "/"); + return sf.create(); + } + + public static void main(String[] args) throws Exception { + new Server().start(); + } + } + + @BeforeClass + public static void startServers() throws Exception { + AbstractResourceInfo.clearAllMaps(); + //keep out of process due to stack traces testing failures + assertTrue("server did not launch correctly", launchServer(Server.class, true)); + } + + @Test + public void testAddBookWithDetailsAsMultipartBadRequest() throws Exception { + String address = "http://localhost:" + PORT + "/bookstore/books/details"; + + final Client client = ClientBuilder.newClient(); + try (InputStream is = getClass() + .getResourceAsStream("/org/apache/cxf/systest/jaxrs/resources/attachmentData")) { + final MultipartBody builder = new MultipartBody(Arrays.asList( + new AttachmentBuilder() + .mediaType("application/xml") + .id("book") + .object(new BookWithValidation()) + .build(), + new AttachmentBuilder() + .id("upfile1Detail") + .object(is) + .contentDisposition(new ContentDisposition("form-data; name=\"field1\";")) + .build(), + new AttachmentBuilder() + .id("upfile2Detail") + .dataHandler(new DataHandler( + new InputStreamDataSource(new ByteArrayInputStream(new byte[0]), "text/xml"))) + .contentDisposition(new ContentDisposition("form-data; name=\"field2\";")) + .build(), + new AttachmentBuilder() + .id("upfile3Detail") + .dataHandler(new DataHandler(new InputStreamDataSource( + new ByteArrayInputStream(new byte[0]), "text/xml"))) + .contentDisposition(new ContentDisposition("form-data; name=\"field3\";")) + .build())); + + final Response response = client + .target(address) + .request("text/xml") + .post(Entity.entity(builder, "multipart/form-data")); + + // Book's name is 'null', validation should fail with 400 + assertThat("Unexpected status code for response:" + response, + response.getStatus(), equalTo(400)); + } + } + + @Test + public void testAddBookWithDetailsAsMultipart() throws Exception { + String address = "http://localhost:" + PORT + "/bookstore/books/details"; + + final Client client = ClientBuilder.newClient(); + try (InputStream is = getClass() + .getResourceAsStream("/org/apache/cxf/systest/jaxrs/resources/attachmentData")) { + final MultipartBody builder = new MultipartBody(Arrays.asList( + new AttachmentBuilder() + .mediaType("application/xml") + .id("book") + .object(new BookWithValidation("Book", "book1")) + .build(), + new AttachmentBuilder() + .id("upfile1Detail") + .object(is) + .contentDisposition(new ContentDisposition("form-data; name=\"field1\";")) + .build(), + new AttachmentBuilder() + .id("upfile2Detail") + .dataHandler(new DataHandler( + new InputStreamDataSource(new ByteArrayInputStream(new byte[0]), "text/xml"))) + .contentDisposition(new ContentDisposition("form-data; name=\"field2\";")) + .build(), + new AttachmentBuilder() + .id("upfile3Detail") + .dataHandler(new DataHandler(new InputStreamDataSource( + new ByteArrayInputStream(new byte[0]), "text/xml"))) + .contentDisposition(new ContentDisposition("form-data; name=\"field3\";")) + .build())); + + final Response response = client + .target(address) + .request("text/xml") + .post(Entity.entity(builder, "multipart/form-data")); + + final BookWithValidation book = response.readEntity(BookWithValidation.class); + assertThat("Unexpected status code for response:" + response, + response.getStatus(), equalTo(200)); + assertThat(book.getName(), equalTo("upfile1Detail,upfile2Detail,upfile3Detail")); + } + } + + @Override + protected String getPort() { + return PORT; + } +} + diff --git a/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/validation/MultipartBookStoreWithValidation.java b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/validation/MultipartBookStoreWithValidation.java new file mode 100644 index 0000000000..9dfd355afc --- /dev/null +++ b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/validation/MultipartBookStoreWithValidation.java @@ -0,0 +1,54 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.cxf.systest.jaxrs.validation; + +import javax.validation.Valid; +import javax.ws.rs.Consumes; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.apache.cxf.jaxrs.ext.multipart.Attachment; +import org.apache.cxf.jaxrs.ext.multipart.Multipart; + +@Path("/bookstore") +public class MultipartBookStoreWithValidation { + @POST + @Path("/books/details") + @Consumes("multipart/form-data") + @Produces("text/xml") + public Response addBookWithDetails( + @Valid @Multipart(value = "book", type = "application/xml") BookWithValidation book, + @Multipart("upfile1Detail") Attachment a1, + @Multipart("upfile2Detail") Attachment a2, + @Multipart("upfile3Detail") Attachment a3) + throws Exception { + + if (a1.equals(a2) || a1.equals(a3) || a2.equals(a3)) { + throw new WebApplicationException(); + } + + book.setName(a1.getContentId() + "," + a2.getContentId() + "," + a3.getContentId()); + return Response.ok(book, MediaType.APPLICATION_XML_TYPE).build(); + } +}
