This is an automated email from the ASF dual-hosted git repository.
lukaszlenart pushed a commit to branch
feature/WW-5585-dynamic-file-upload-params
in repository https://gitbox.apache.org/repos/asf/struts.git
The following commit(s) were added to
refs/heads/feature/WW-5585-dynamic-file-upload-params by this push:
new ce667c9d3 test(fileupload): add integration tests for dynamic file
upload
ce667c9d3 is described below
commit ce667c9d36d0535985b326b495305831680ebece
Author: Lukasz Lenart <[email protected]>
AuthorDate: Mon Nov 17 15:41:17 2025 +0100
test(fileupload): add integration tests for dynamic file upload
- Add DynamicFileUploadTest with 7 comprehensive test cases
- Test valid document and image uploads
- Test file type validation (documents reject images, images reject
documents)
- Test size limit validation (5MB for documents, 2MB for images)
- Test switching between upload modes
- Add helper methods for creating test files of various sizes
- Follow existing FileUploadTest patterns using HtmlUnit
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <[email protected]>
---
.../webapp/WEB-INF/fileupload/dynamic-upload.jsp | 17 +-
.../struts2/showcase/DynamicFileUploadTest.java | 265 +++++++++++++++++++++
2 files changed, 269 insertions(+), 13 deletions(-)
diff --git
a/apps/showcase/src/main/webapp/WEB-INF/fileupload/dynamic-upload.jsp
b/apps/showcase/src/main/webapp/WEB-INF/fileupload/dynamic-upload.jsp
index 13d1b49fe..b1f2b50b5 100644
--- a/apps/showcase/src/main/webapp/WEB-INF/fileupload/dynamic-upload.jsp
+++ b/apps/showcase/src/main/webapp/WEB-INF/fileupload/dynamic-upload.jsp
@@ -67,22 +67,13 @@
<div class="row">
<div class="col-md-12">
<s:form action="doDynamicUpload" method="POST"
enctype="multipart/form-data" cssClass="form-vertical">
- <div class="form-group">
- <label class="col-sm-2 control-label">Upload Type:</label>
- <div class="col-sm-10">
- <s:radio name="uploadType"
- list="#{'document':'Documents (PDF, Word) -
up to 5MB', 'image':'Images (JPEG, PNG) - up to 2MB'}"/>
- </div>
- </div>
+ <s:radio name="uploadType" label="Upload type"
+ list="#{'document':'Documents (PDF, Word) - up to
5MB', 'image':'Images (JPEG, PNG) - up to 2MB'}"/>
<s:file name="upload" label="Select File"
cssClass="form-control"/>
- <div class="form-group">
- <div class="col-sm-offset-2 col-sm-10">
- <s:submit value="Upload File" cssClass="btn
btn-primary"/>
- <s:submit value="Refresh Rules" action="dynamicUpload"
cssClass="btn btn-default"/>
- </div>
- </div>
+ <s:submit value="Upload File" cssClass="btn btn-primary"/>
+ <s:submit value="Refresh Rules" action="dynamicUpload"
cssClass="btn btn-default"/>
</s:form>
</div>
</div>
diff --git
a/apps/showcase/src/test/java/it/org/apache/struts2/showcase/DynamicFileUploadTest.java
b/apps/showcase/src/test/java/it/org/apache/struts2/showcase/DynamicFileUploadTest.java
new file mode 100644
index 000000000..2917dddc5
--- /dev/null
+++
b/apps/showcase/src/test/java/it/org/apache/struts2/showcase/DynamicFileUploadTest.java
@@ -0,0 +1,265 @@
+/*
+ * 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 it.org.apache.struts2.showcase;
+
+import org.htmlunit.WebClient;
+import org.htmlunit.html.HtmlFileInput;
+import org.htmlunit.html.HtmlForm;
+import org.htmlunit.html.HtmlPage;
+import org.htmlunit.html.HtmlRadioButtonInput;
+import org.htmlunit.html.HtmlSubmitInput;
+import org.junit.Test;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.FileWriter;
+import java.security.SecureRandom;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * Integration tests for dynamic file upload validation feature.
+ * Tests the WithLazyParams functionality that allows runtime configuration
+ * of file upload validation rules based on action state.
+ */
+public class DynamicFileUploadTest {
+
+ @Test
+ public void testDynamicUploadValidDocument() throws Exception {
+ try (final WebClient webClient = new WebClient()) {
+ final HtmlPage page =
webClient.getPage(ParameterUtils.getBaseUrl() +
"/fileupload/dynamicUpload.action");
+ final HtmlForm form = page.getForms().get(0);
+
+ // Select document upload type
+ HtmlRadioButtonInput documentRadio =
form.getInputByValue("document");
+ documentRadio.setChecked(true);
+
+ // Create a small PDF-like file
+ File pdfFile = createTestFile("test.pdf", "txt", 1024);
+ pdfFile.deleteOnExit();
+
+ HtmlFileInput uploadInput = form.getInputByName("upload");
+ uploadInput.setFiles(pdfFile);
+
+ final HtmlSubmitInput button = (HtmlSubmitInput)
form.getInputByValue("Upload File");
+ final HtmlPage resultPage = button.click();
+
+ String content = resultPage.getVisibleText();
+ assertThat(content).contains(
+ "File Upload Successful",
+ "Upload Type: Document",
+ "File Name: test.pdf"
+ );
+ }
+ }
+
+ @Test
+ public void testDynamicUploadValidImage() throws Exception {
+ try (final WebClient webClient = new WebClient()) {
+ final HtmlPage page =
webClient.getPage(ParameterUtils.getBaseUrl() +
"/fileupload/dynamicUpload.action");
+ final HtmlForm form = page.getForms().get(0);
+
+ // Select image upload type
+ HtmlRadioButtonInput imageRadio = form.getInputByValue("image");
+ imageRadio.setChecked(true);
+
+ // Create a small image-like file
+ File imageFile = createTestFile("test.png", "png", 1024);
+ imageFile.deleteOnExit();
+
+ HtmlFileInput uploadInput = form.getInputByName("upload");
+ uploadInput.setFiles(imageFile);
+
+ final HtmlSubmitInput button = (HtmlSubmitInput)
form.getInputByValue("Upload File");
+ final HtmlPage resultPage = button.click();
+
+ String content = resultPage.getVisibleText();
+ assertThat(content).contains(
+ "File Upload Successful",
+ "Upload Type: Image",
+ "File Name: test.png"
+ );
+ }
+ }
+
+ @Test
+ public void testDynamicUploadDocumentRejectsImage() throws Exception {
+ try (final WebClient webClient = new WebClient()) {
+ final HtmlPage page =
webClient.getPage(ParameterUtils.getBaseUrl() +
"/fileupload/dynamicUpload.action");
+ final HtmlForm form = page.getForms().get(0);
+
+ // Select document upload type
+ HtmlRadioButtonInput documentRadio =
form.getInputByValue("document");
+ documentRadio.setChecked(true);
+
+ // Try to upload an image file
+ File imageFile = createTestFile("test.jpg", "jpg", 512);
+ imageFile.deleteOnExit();
+
+ HtmlFileInput uploadInput = form.getInputByName("upload");
+ uploadInput.setFiles(imageFile);
+
+ final HtmlSubmitInput button = (HtmlSubmitInput)
form.getInputByValue("Upload File");
+ final HtmlPage resultPage = button.click();
+
+ String content = resultPage.getVisibleText();
+ assertThat(content).containsIgnoringCase("error");
+ }
+ }
+
+ @Test
+ public void testDynamicUploadImageRejectsDocument() throws Exception {
+ try (final WebClient webClient = new WebClient()) {
+ final HtmlPage page =
webClient.getPage(ParameterUtils.getBaseUrl() +
"/fileupload/dynamicUpload.action");
+ final HtmlForm form = page.getForms().get(0);
+
+ // Select image upload type
+ HtmlRadioButtonInput imageRadio = form.getInputByValue("image");
+ imageRadio.setChecked(true);
+
+ // Try to upload a PDF file
+ File pdfFile = createTestFile("test.pdf", "pdf", 512);
+ pdfFile.deleteOnExit();
+
+ HtmlFileInput uploadInput = form.getInputByName("upload");
+ uploadInput.setFiles(pdfFile);
+
+ final HtmlSubmitInput button = (HtmlSubmitInput)
form.getInputByValue("Upload File");
+ final HtmlPage resultPage = button.click();
+
+ String content = resultPage.getVisibleText();
+ assertThat(content).containsIgnoringCase("error");
+ }
+ }
+
+ @Test
+ public void testDynamicUploadDocumentExceedsMaxSize() throws Exception {
+ try (final WebClient webClient = new WebClient()) {
+ final HtmlPage page =
webClient.getPage(ParameterUtils.getBaseUrl() +
"/fileupload/dynamicUpload.action");
+ final HtmlForm form = page.getForms().get(0);
+
+ // Select document upload type (max 5MB)
+ HtmlRadioButtonInput documentRadio =
form.getInputByValue("document");
+ documentRadio.setChecked(true);
+
+ // Create a file larger than 5MB
+ File largeFile = createLargeTestFile("large.pdf", "pdf", 5 * 1024
* 1024 + 1024);
+ largeFile.deleteOnExit();
+
+ HtmlFileInput uploadInput = form.getInputByName("upload");
+ uploadInput.setFiles(largeFile);
+
+ final HtmlSubmitInput button = (HtmlSubmitInput)
form.getInputByValue("Upload File");
+ final HtmlPage resultPage = button.click();
+
+ String content = resultPage.getVisibleText();
+ assertThat(content).containsAnyOf("size", "Size", "limit",
"exceed");
+ }
+ }
+
+ @Test
+ public void testDynamicUploadImageExceedsMaxSize() throws Exception {
+ try (final WebClient webClient = new WebClient()) {
+ final HtmlPage page =
webClient.getPage(ParameterUtils.getBaseUrl() +
"/fileupload/dynamicUpload.action");
+ final HtmlForm form = page.getForms().get(0);
+
+ // Select image upload type (max 2MB)
+ HtmlRadioButtonInput imageRadio = form.getInputByValue("image");
+ imageRadio.setChecked(true);
+
+ // Create a file larger than 2MB
+ File largeFile = createLargeTestFile("large.png", "png", 2 * 1024
* 1024 + 1024);
+ largeFile.deleteOnExit();
+
+ HtmlFileInput uploadInput = form.getInputByName("upload");
+ uploadInput.setFiles(largeFile);
+
+ final HtmlSubmitInput button = (HtmlSubmitInput)
form.getInputByValue("Upload File");
+ final HtmlPage resultPage = button.click();
+
+ String content = resultPage.getVisibleText();
+ assertThat(content).containsAnyOf("size", "Size", "limit",
"exceed");
+ }
+ }
+
+ @Test
+ public void testDynamicUploadSwitchBetweenModes() throws Exception {
+ try (final WebClient webClient = new WebClient()) {
+ final HtmlPage page =
webClient.getPage(ParameterUtils.getBaseUrl() +
"/fileupload/dynamicUpload.action");
+
+ // Verify initial state shows document mode by default
+ String initialContent = page.getVisibleText();
+ assertThat(initialContent).contains("Document Upload");
+
+ final HtmlForm form = page.getForms().get(0);
+
+ // Switch to image mode and refresh rules
+ HtmlRadioButtonInput imageRadio = form.getInputByValue("image");
+ imageRadio.setChecked(true);
+
+ final HtmlSubmitInput refreshButton = (HtmlSubmitInput)
form.getInputByValue("Refresh Rules");
+ final HtmlPage refreshedPage = refreshButton.click();
+
+ // Verify rules changed to image mode
+ String refreshedContent = refreshedPage.getVisibleText();
+ assertThat(refreshedContent).contains(
+ "Image Upload",
+ "image/jpeg",
+ "2 MB"
+ );
+ }
+ }
+
+ /**
+ * Creates a small test file with specified name and extension.
+ */
+ private File createTestFile(String fileName, String extension, int
sizeInBytes) throws Exception {
+ File tempFile = File.createTempFile("test_" + fileName, "." +
extension);
+ try (FileWriter writer = new FileWriter(tempFile)) {
+ // Write some content to make it non-empty
+ for (int i = 0; i < sizeInBytes; i++) {
+ writer.write('A');
+ }
+ writer.flush();
+ }
+ return tempFile;
+ }
+
+ /**
+ * Creates a large test file for size limit testing.
+ */
+ private File createLargeTestFile(String fileName, String extension, int
sizeInBytes) throws Exception {
+ File tempFile = File.createTempFile("large_test_" + fileName, "." +
extension);
+ SecureRandom rng = new SecureRandom();
+
+ try (FileOutputStream fos = new FileOutputStream(tempFile)) {
+ byte[] buffer = new byte[8192];
+ int remaining = sizeInBytes;
+
+ while (remaining > 0) {
+ int toWrite = Math.min(buffer.length, remaining);
+ rng.nextBytes(buffer);
+ fos.write(buffer, 0, toWrite);
+ remaining -= toWrite;
+ }
+ fos.flush();
+ }
+ return tempFile;
+ }
+}