You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by jd...@apache.org on 2009/04/04 17:14:17 UTC

svn commit: r761957 - in /wicket/trunk/wicket/src: main/java/org/apache/wicket/util/upload/ test/java/org/apache/wicket/markup/html/form/upload/

Author: jdonnerstag
Date: Sat Apr  4 15:14:16 2009
New Revision: 761957

URL: http://svn.apache.org/viewvc?rev=761957&view=rev
Log:
added test cases for WICKET-2015
Issue: WICKET-2015

Added:
    wicket/trunk/wicket/src/test/java/org/apache/wicket/markup/html/form/upload/FileUploadError.html
    wicket/trunk/wicket/src/test/java/org/apache/wicket/markup/html/form/upload/FileUploadError.java
    wicket/trunk/wicket/src/test/java/org/apache/wicket/markup/html/form/upload/TestFileUploadError.java
    wicket/trunk/wicket/src/test/java/org/apache/wicket/markup/html/form/upload/testfile.txt
Modified:
    wicket/trunk/wicket/src/main/java/org/apache/wicket/util/upload/MultipartFormInputStream.java

Modified: wicket/trunk/wicket/src/main/java/org/apache/wicket/util/upload/MultipartFormInputStream.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/util/upload/MultipartFormInputStream.java?rev=761957&r1=761956&r2=761957&view=diff
==============================================================================
--- wicket/trunk/wicket/src/main/java/org/apache/wicket/util/upload/MultipartFormInputStream.java (original)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/util/upload/MultipartFormInputStream.java Sat Apr  4 15:14:16 2009
@@ -22,6 +22,9 @@
 import java.io.OutputStream;
 import java.io.UnsupportedEncodingException;
 
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
 /**
  * <p>
  * Low level API for processing file uploads.
@@ -75,8 +78,6 @@
  *      } catch(IOException) {
  *            // a read or write error occurred
  *      }
- * 
- * 
  * </pre>
  * 
  * @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a>
@@ -87,122 +88,106 @@
  */
 public class MultipartFormInputStream
 {
+	/** Log. */
+	private static final Logger log = LoggerFactory.getLogger(MultipartFormInputStream.class);
 
 	// ----------------------------------------------------- Manifest constants
 
-
 	/**
 	 * The Carriage Return ASCII character value.
 	 */
 	public static final byte CR = 0x0D;
 
-
 	/**
 	 * The Line Feed ASCII character value.
 	 */
 	public static final byte LF = 0x0A;
 
-
 	/**
 	 * The dash (-) ASCII character value.
 	 */
 	public static final byte DASH = 0x2D;
 
-
 	/**
 	 * The maximum length of <code>header-part</code> that will be processed (10 kilobytes = 10240
 	 * bytes.).
 	 */
 	public static final int HEADER_PART_SIZE_MAX = 10240;
 
-
 	/**
 	 * The default length of the buffer used for processing a request.
 	 */
 	protected static final int DEFAULT_BUFSIZE = 4096;
 
-
 	/**
 	 * A byte sequence that marks the end of <code>header-part</code> (<code>CRLFCRLF</code>).
 	 */
 	protected static final byte[] HEADER_SEPARATOR = { CR, LF, CR, LF };
 
-
 	/**
-	 * A byte sequence that that follows a delimiter that will be followed by an encapsulation (<code>CRLF</code>).
+	 * A byte sequence that that follows a delimiter that will be followed by an encapsulation (
+	 * <code>CRLF</code>).
 	 */
 	protected static final byte[] FIELD_SEPARATOR = { CR, LF };
 
-
 	/**
-	 * A byte sequence that that follows a delimiter of the last encapsulation in the stream (<code>--</code>).
+	 * A byte sequence that that follows a delimiter of the last encapsulation in the stream (
+	 * <code>--</code>).
 	 */
 	protected static final byte[] STREAM_TERMINATOR = { DASH, DASH };
 
-
 	// ----------------------------------------------------------- Data members
 
-
 	/**
 	 * The input stream from which data is read.
 	 */
 	private InputStream input;
 
-
 	/**
 	 * The length of the boundary token plus the leading <code>CRLF--</code>.
 	 */
 	private int boundaryLength;
 
-
 	/**
 	 * The amount of data, in bytes, that must be kept in the buffer in order to detect delimiters
 	 * reliably.
 	 */
 	private int keepRegion;
 
-
 	/**
 	 * The byte sequence that partitions the stream.
 	 */
 	private byte[] boundary;
 
-
 	/**
 	 * The length of the buffer used for processing the request.
 	 */
 	private int bufSize;
 
-
 	/**
 	 * The buffer used for processing the request.
 	 */
 	private byte[] buffer;
 
-
 	/**
 	 * The index of first valid character in the buffer. <br>
 	 * 0 <= head < bufSize
 	 */
 	private int head;
 
-
 	/**
 	 * The index of last valid character in the buffer + 1. <br>
 	 * 0 <= tail <= bufSize
 	 */
 	private int tail;
 
-
 	/**
 	 * The content encoding to use when reading headers.
 	 */
 	private String headerEncoding;
 
-
 	// ----------------------------------------------------------- Constructors
 
-
 	/**
 	 * Default constructor.
 	 * 
@@ -214,7 +199,6 @@
 	{
 	}
 
-
 	/**
 	 * <p>
 	 * Constructs a <code>MultipartStream</code> with a custom size buffer.
@@ -333,11 +317,11 @@
 
 
 	/**
-	 * Skips a <code>boundary</code> token, and checks whether more <code>encapsulations</code>
-	 * are contained in the stream.
+	 * Skips a <code>boundary</code> token, and checks whether more <code>encapsulations</code> are
+	 * contained in the stream.
 	 * 
-	 * @return <code>true</code> if there are more encapsulations in this stream;
-	 *         <code>false</code> otherwise.
+	 * @return <code>true</code> if there are more encapsulations in this stream; <code>false</code>
+	 *         otherwise.
 	 * 
 	 * @exception MalformedStreamException
 	 *                if the stream ends unexpectedly or fails to follow required syntax.
@@ -392,8 +376,8 @@
 	 * This method allows single pass processing of nested multipart streams.
 	 * 
 	 * <p>
-	 * The boundary token of the nested stream is <code>required</code> to be of the same length
-	 * as the boundary token in parent stream.
+	 * The boundary token of the nested stream is <code>required</code> to be of the same length as
+	 * the boundary token in parent stream.
 	 * 
 	 * <p>
 	 * Restoring the parent stream boundary token after processing of a nested stream is left to the
@@ -452,7 +436,7 @@
 			if (size > maxSize)
 			{
 				throw new MalformedStreamException("Stream exceeded maximum of " + maxSize +
-						" bytes");
+					" bytes");
 			}
 			if (b[0] == HEADER_SEPARATOR[i])
 			{
@@ -645,7 +629,6 @@
 		return total;
 	}
 
-
 	/**
 	 * Finds the beginning of the first <code>encapsulation</code>.
 	 * 
@@ -670,6 +653,8 @@
 		}
 		catch (MalformedStreamException e)
 		{
+			log.error("Error while reading servlet request multi-part data: " + e.getMessage() +
+				". " + toString());
 			return false;
 		}
 		finally
@@ -693,8 +678,8 @@
 	 * @param count
 	 *            How many bytes should be compared.
 	 * 
-	 * @return <code>true</code> if <code>count</code> first bytes in arrays <code>a</code>
-	 *         and <code>b</code> are equal.
+	 * @return <code>true</code> if <code>count</code> first bytes in arrays <code>a</code> and
+	 *         <code>b</code> are equal.
 	 */
 	public static boolean arrayequals(byte[] a, byte[] b, int count)
 	{
@@ -710,8 +695,8 @@
 
 
 	/**
-	 * Searches for a byte of specified value in the <code>buffer</code>, starting at the
-	 * specified <code>position</code>.
+	 * Searches for a byte of specified value in the <code>buffer</code>, starting at the specified
+	 * <code>position</code>.
 	 * 
 	 * @param value
 	 *            The value to find.
@@ -774,12 +759,25 @@
 	 * 
 	 * @return The string representation of this object.
 	 */
+	@Override
 	public String toString()
 	{
 		StringBuffer sbTemp = new StringBuffer();
 		sbTemp.append("boundary='");
-		sbTemp.append(String.valueOf(boundary));
-		sbTemp.append("'\nbufSize=");
+		for (byte b : boundary)
+		{
+			if (Character.isDefined(b))
+			{
+				sbTemp.append((char)b);
+			}
+			else
+			{
+				sbTemp.append("#");
+				sbTemp.append(b);
+				sbTemp.append(";");
+			}
+		}
+		sbTemp.append("'; bufSize=");
 		sbTemp.append(bufSize);
 		return sbTemp.toString();
 	}
@@ -848,15 +846,16 @@
 	// These are the methods that were used to debug this stuff.
 	/*
 	 * // Dump data. protected void dump() { System.out.println("01234567890"); byte[] temp = new
-	 * byte[buffer.length]; for(int i=0; i<buffer.length; i++) { if (buffer[i] == 0x0D || buffer[i] ==
-	 * 0x0A) { temp[i] = 0x21; } else { temp[i] = buffer[i]; } } System.out.println(new
+	 * byte[buffer.length]; for(int i=0; i<buffer.length; i++) { if (buffer[i] == 0x0D || buffer[i]
+	 * == 0x0A) { temp[i] = 0x21; } else { temp[i] = buffer[i]; } } System.out.println(new
 	 * String(temp)); int i; for (i=0; i<head; i++) System.out.print(" "); System.out.println("h");
-	 * for (i=0; i<tail; i++) System.out.print(" "); System.out.println("t"); System.out.flush(); } //
-	 * Main routine, for testing purposes only. // // @param args A String[] with the command line
-	 * arguments. // @exception Exception, a generic exception. public static void main( String[]
-	 * args ) throws Exception { File boundaryFile = new File("boundary.dat"); int boundarySize =
-	 * (int)boundaryFile.length(); byte[] boundary = new byte[boundarySize]; FileInputStream input =
-	 * new FileInputStream(boundaryFile); input.read(boundary,0,boundarySize);
+	 * for (i=0; i<tail; i++) System.out.print(" "); System.out.println("t"); System.out.flush(); }
+	 * // Main routine, for testing purposes only. // // @param args A String[] with the command
+	 * line arguments. // @exception Exception, a generic exception. public static void main(
+	 * String[] args ) throws Exception { File boundaryFile = new File("boundary.dat"); int
+	 * boundarySize = (int)boundaryFile.length(); byte[] boundary = new byte[boundarySize];
+	 * FileInputStream input = new FileInputStream(boundaryFile);
+	 * input.read(boundary,0,boundarySize);
 	 * 
 	 * input = new FileInputStream("multipart.dat"); MultipartStream chunks = new
 	 * MultipartStream(input, boundary);
@@ -866,6 +865,5 @@
 	 * System.out.println("wrote part"+i+".dat"); output = new
 	 * FileOutputStream("part"+(i++)+".dat"); chunks.readBodyData(output); nextChunk =
 	 * chunks.readBoundary(); } }
-	 * 
 	 */
 }

Added: wicket/trunk/wicket/src/test/java/org/apache/wicket/markup/html/form/upload/FileUploadError.html
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/test/java/org/apache/wicket/markup/html/form/upload/FileUploadError.html?rev=761957&view=auto
==============================================================================
--- wicket/trunk/wicket/src/test/java/org/apache/wicket/markup/html/form/upload/FileUploadError.html (added)
+++ wicket/trunk/wicket/src/test/java/org/apache/wicket/markup/html/form/upload/FileUploadError.html Sat Apr  4 15:14:16 2009
@@ -0,0 +1,44 @@
+<html>
+    <head>
+        <title>Wicket Quickstart: File upload Error page</title>
+    </head>
+    <body>
+    	<strong>Wicket Quickstart Archetype Homepage</strong>
+    	<br />
+    	<span wicket:id="message">message will be here</span>
+    	<br />
+        <br />
+    	<strong>FileUploadError Page for WicketTester</strong>
+        <br />
+        <br />
+        <form wicket:id="form">
+        	<table>
+        		<tr>
+        			<td>
+        				Mandatory TextField 
+        			</td>
+        			<td>
+        				<input type="text" wicket:id="textField" size="50" />
+        			</td>
+        		</tr>
+        		<tr>
+        			<td>
+        				FileUpload
+        			</td>
+        			<td>
+        				<input type="file" wicket:id="fileUpload" size="50" />
+        			</td>
+        		</tr>
+        		<tr>
+        			<td>
+        				<input type="submit" value="Submit" />
+        			</td>
+        			<td>
+        				<span wicket:id="feedback"></span>
+        			</td>
+				</tr>
+        	</table>
+    	</form>
+    </body>
+</html>
+

Added: wicket/trunk/wicket/src/test/java/org/apache/wicket/markup/html/form/upload/FileUploadError.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/test/java/org/apache/wicket/markup/html/form/upload/FileUploadError.java?rev=761957&view=auto
==============================================================================
--- wicket/trunk/wicket/src/test/java/org/apache/wicket/markup/html/form/upload/FileUploadError.java (added)
+++ wicket/trunk/wicket/src/test/java/org/apache/wicket/markup/html/form/upload/FileUploadError.java Sat Apr  4 15:14:16 2009
@@ -0,0 +1,82 @@
+/*
+ * 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.wicket.markup.html.form.upload;
+
+import org.apache.wicket.markup.html.WebPage;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.markup.html.form.Form;
+import org.apache.wicket.markup.html.form.TextField;
+import org.apache.wicket.markup.html.panel.FeedbackPanel;
+import org.apache.wicket.model.Model;
+import org.apache.wicket.validation.validator.StringValidator;
+
+/**
+ * Homepage
+ */
+public class FileUploadError extends WebPage
+{
+	private static final long serialVersionUID = 1L;
+	public static final String THIS_VALUE_SHOULD_THROW_EXCEPTION = "test ex";
+
+	/**
+	 */
+	public FileUploadError()
+	{
+		add(new Label("message",
+			"If you see this message wicket is properly configured and running."));
+
+		Form<?> form = new Form<Object>("form")
+		{
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void onSubmit()
+			{
+				super.onSubmit();
+				setResponsePage(FileUploadError.class);
+			}
+		};
+
+		add(form);
+
+		// inputField
+		TextField<String> inputField = new TextField<String>("textField", new Model<String>()
+		{
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void setObject(String value)
+			{
+				if (THIS_VALUE_SHOULD_THROW_EXCEPTION.equals(value))
+				{
+					throw new RuntimeException("Special value: " +
+						THIS_VALUE_SHOULD_THROW_EXCEPTION);
+				}
+				super.setObject(value);
+			}
+		});
+
+		inputField.add(StringValidator.lengthBetween(3, 10));
+		inputField.setRequired(true);
+		form.add(inputField);
+
+		// file upload
+		form.add(new FileUploadField("fileUpload", new Model<FileUpload>()));
+		// feedback
+		form.add(new FeedbackPanel("feedback"));
+	}
+}

Added: wicket/trunk/wicket/src/test/java/org/apache/wicket/markup/html/form/upload/TestFileUploadError.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/test/java/org/apache/wicket/markup/html/form/upload/TestFileUploadError.java?rev=761957&view=auto
==============================================================================
--- wicket/trunk/wicket/src/test/java/org/apache/wicket/markup/html/form/upload/TestFileUploadError.java (added)
+++ wicket/trunk/wicket/src/test/java/org/apache/wicket/markup/html/form/upload/TestFileUploadError.java Sat Apr  4 15:14:16 2009
@@ -0,0 +1,160 @@
+/*
+ * 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.wicket.markup.html.form.upload;
+
+import java.util.Locale;
+
+import junit.framework.TestCase;
+
+import org.apache.wicket.WicketRuntimeException;
+import org.apache.wicket.util.file.File;
+import org.apache.wicket.util.tester.FormTester;
+import org.apache.wicket.util.tester.WicketTester;
+
+/**
+ * see WICKET-2015
+ */
+public class TestFileUploadError extends TestCase
+{
+	private WicketTester tester;
+	private FormTester formTester;
+	private final String textFieldId = "textField";
+	private final String fileUploadId = "fileUpload";
+	private final String testUploadFilePath = "src/test/java/org/apache/wicket/markup/html/form/upload/testfile.txt";
+
+	@Override
+	public void setUp()
+	{
+		tester = new WicketTester();
+		// Start and render the test page
+		tester.startPage(FileUploadError.class);
+		tester.assertRenderedPage(FileUploadError.class);
+		// Set locale to fix error messages on this test.
+		tester.getWicketSession().setLocale(Locale.ENGLISH);
+		//
+		formTester = tester.newFormTester("form");
+	}
+
+	/**
+	 * FileUpload is empty on submit: Validation fails to see that TextField is also required.
+	 */
+	public void testSubmit_NoInput()
+	{
+		formTester.submit();
+		tester.assertErrorMessages(new String[] { "Field 'textField' is required.", });
+	}
+
+	/**
+	 * FileUpload is filled on submit: TexttField is required.
+	 */
+	public void testSubmit_NoInput_FileUploaded()
+	{
+		formTester.setFile(fileUploadId, new File(testUploadFilePath), "UTF-8");
+		formTester.submit();
+
+		tester.assertErrorMessages(new String[] { "Field 'textField' is required.", });
+	}
+
+	/**
+	 * FileUpload is empty on submit: Validation fails to report too short TextField input.
+	 */
+	public void testSubmit_NotValidTextFieldValue()
+	{
+		formTester.setValue(textFieldId, "te");
+		formTester.submit();
+
+		tester.assertErrorMessages(new String[] { "'te' is not between 3 and 10 characters long.", });
+	}
+
+	/**
+	 * FileUpload is empty on submit: Validation fails to report too short TextField input.
+	 */
+	public void testSubmit_NotValidTextFieldValue2()
+	{
+		formTester.setValue(textFieldId, "12345678901");
+		formTester.submit();
+
+		tester.assertErrorMessages(new String[] { "'12345678901' is not between 3 and 10 characters long.", });
+	}
+
+	/**
+	 * FileUpload is filled on submit: Validation reports too short TextField input.
+	 */
+	public void testSubmit_NotValidTextFieldValue_FileUploaded()
+	{
+		formTester.setValue(textFieldId, "te");
+		formTester.setFile(fileUploadId, new File(testUploadFilePath), "UTF-8");
+		formTester.submit();
+
+		tester.assertErrorMessages(new String[] { "'te' is not between 3 and 10 characters long.", });
+	}
+
+	/**
+	 * Throwing exception confirms that value is received.
+	 */
+	public void testSubmit_ValidTextField_NoFile()
+	{
+		formTester.setValue(textFieldId, FileUploadError.THIS_VALUE_SHOULD_THROW_EXCEPTION);
+		try
+		{
+			formTester.submit();
+			fail("Value not succesfully submitted.");
+		}
+		catch (WicketRuntimeException rex)
+		{
+			Throwable ex = rex.getCause().getCause();
+			assertEquals("Special value: " + FileUploadError.THIS_VALUE_SHOULD_THROW_EXCEPTION,
+				ex.getMessage());
+		}
+	}
+
+	/**
+	 */
+	public void testSubmit_ValidTextField_WithFile()
+	{
+		formTester.setValue(textFieldId, "test value");
+		formTester.setFile(fileUploadId, new File(testUploadFilePath), "UTF-8");
+
+		formTester.submit();
+		tester.assertNoErrorMessage();
+	}
+
+	/**
+	 */
+	public void testSubmit_RequiredFileUpload_Ok()
+	{
+		((FileUploadField)tester.getLastRenderedPage().get("form:" + fileUploadId)).setRequired(true);
+
+		formTester.setValue(textFieldId, "test value");
+		formTester.setFile(fileUploadId, new File(testUploadFilePath), "UTF-8");
+
+		formTester.submit();
+		tester.assertNoErrorMessage();
+	}
+
+	/**
+	 */
+	public void testSubmit_RequiredFileUpload_ShouldFailWithValidationError()
+	{
+		((FileUploadField)tester.getLastRenderedPage().get("form:" + fileUploadId)).setRequired(true);
+
+		formTester.setValue(textFieldId, "test value");
+
+		formTester.submit();
+		tester.assertErrorMessages(new String[] { "Field 'fileUpload' is required.", });
+	}
+}

Added: wicket/trunk/wicket/src/test/java/org/apache/wicket/markup/html/form/upload/testfile.txt
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/test/java/org/apache/wicket/markup/html/form/upload/testfile.txt?rev=761957&view=auto
==============================================================================
--- wicket/trunk/wicket/src/test/java/org/apache/wicket/markup/html/form/upload/testfile.txt (added)
+++ wicket/trunk/wicket/src/test/java/org/apache/wicket/markup/html/form/upload/testfile.txt Sat Apr  4 15:14:16 2009
@@ -0,0 +1 @@
+test file
\ No newline at end of file