// Path: upload-parser-core/src/main/java/com/github/elopteryx/upload/PartStream.java
// public interface PartStream {
// 
//     /**
//      * Returns the content type of this part, as it was submitted by
//      * the client. 
//      *
//      * @return The content type of this part
//      */
//     String getContentType();
// 
//     /**
//      * Returns the name of this part, which equals the name of the form
//      * field the part was selected for.
//      *
//      * @return The name of this part as a String
//      */
//     String getName();
// 
//     /**
//      * Returns the known size of this part. This means that the
//      * returned value depends on how many bytes have been processed. When called
//      * during the start of the part processing the returned value will be equal
//      * to the specified buffer threshold or the actual part size if it's smaller
//      * than that. When called during the end the returned value is always the
//      * actual size, because by that time it has been fully processed.
//      *
//      * @return A long specifying the known size of this part, in bytes.
//      */
//     long getKnownSize();
// 
//     /**
//      * Returns the file name specified by the client or null if the
//      * part is a normal form field.
//      *
//      * @return The submitted file name
//      */
//     String getSubmittedFileName();
// 
//     /**
//      * Determines whether or not this PartStream instance represents
//      * a file item. If it's a normal form field then it will return false.
//      * Consequently, if this returns true then the {@link PartStream#getSubmittedFileName}
//      * will return with a non-null value and vice-versa.
//      *
//      * @return True if the instance represents an uploaded file; false if it represents a simple form field.
//      */
//     boolean isFile();
// 
//     /**
//      * Returns whether the part has been completely uploaded. The
//      * part begin callback is called only after the given size threshold
//      * is reached or if the part is completely uploaded. Therefore, the
//      * parts that are smaller than the threshold are passed to the part begin
//      * callback after their upload is finished and their actual size is known.
//      * This method can be used to determine that. In the part end callback
//      * this will always return true.
//      *
//      * @return True if the part is completely uploaded, false otherwise.
//      */
//     boolean isFinished();
// 
//     /**
//      * Returns the value of the specified mime header as a String. If
//      * the Part did not include a header of the specified name, this
//      * method returns null. If there are multiple headers with the same name,
//      * this method returns the first header in the part. The header name
//      * is case insensitive. You can use this method with any request header.
//      *
//      * @param name a String specifying the header name
//      * @return a String containing the value of the requested header, or null if the part does not have a header of that name
//      */
//     String getHeader(String name);
// 
//     /**
//      * Returns the values of the part header with the given name.
//      *
//      * @param name the header name whose values to return
//      * @return a (possibly empty) Collection of the values of the header with the given name
//      */
//     Collection<String> getHeaders(String name);
// 
//     /**
//      * Returns the header names of this part.
//      *
//      * @return a (possibly empty) Collection of the header names of this Part
//      */
//     Collection<String> getHeaderNames();
// 
// }


import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertThrows;
import com.github.elopteryx.upload.PartStream;
import org.junit.jupiter.api.Test;
package com.github.elopteryx.upload.internal;



class PartStreamImplTest {

    @Test
    void it_should_return_the_correct_data() {
        final var fileName = "r-" + System.currentTimeMillis();
        final var fieldName = "r-" + System.currentTimeMillis();
        final var contentType = "r-" + System.currentTimeMillis();
        final var headers = new Headers();
        headers.addHeader(Headers.CONTENT_TYPE, contentType);
        final PartStream partStream = new PartStreamImpl(fileName, fieldName, headers);
        assertEquals(fileName, partStream.getSubmittedFileName());
        assertEquals(fieldName, partStream.getName());
        assertEquals(contentType, partStream.getContentType());
        assertEquals(partStream.isFile(), partStream.getSubmittedFileName() != null);
        assertFalse(partStream.isFinished());
    }

    @Test
    void invalid_file_names_are_not_allowed() {
        final var fileName = "r-" + System.currentTimeMillis() + '\u0000';
// Path: upload-parser-core/src/main/java/com/github/elopteryx/upload/PartStream.java
// public interface PartStream {
// 
//     /**
//      * Returns the content type of this part, as it was submitted by
//      * the client. 
//      *
//      * @return The content type of this part
//      */
//     String getContentType();
// 
//     /**
//      * Returns the name of this part, which equals the name of the form
//      * field the part was selected for.
//      *
//      * @return The name of this part as a String
//      */
//     String getName();
// 
//     /**
//      * Returns the known size of this part. This means that the
//      * returned value depends on how many bytes have been processed. When called
//      * during the start of the part processing the returned value will be equal
//      * to the specified buffer threshold or the actual part size if it's smaller
//      * than that. When called during the end the returned value is always the
//      * actual size, because by that time it has been fully processed.
//      *
//      * @return A long specifying the known size of this part, in bytes.
//      */
//     long getKnownSize();
// 
//     /**
//      * Returns the file name specified by the client or null if the
//      * part is a normal form field.
//      *
//      * @return The submitted file name
//      */
//     String getSubmittedFileName();
// 
//     /**
//      * Determines whether or not this PartStream instance represents
//      * a file item. If it's a normal form field then it will return false.
//      * Consequently, if this returns true then the {@link PartStream#getSubmittedFileName}
//      * will return with a non-null value and vice-versa.
//      *
//      * @return True if the instance represents an uploaded file; false if it represents a simple form field.
//      */
//     boolean isFile();
// 
//     /**
//      * Returns whether the part has been completely uploaded. The
//      * part begin callback is called only after the given size threshold
//      * is reached or if the part is completely uploaded. Therefore, the
//      * parts that are smaller than the threshold are passed to the part begin
//      * callback after their upload is finished and their actual size is known.
//      * This method can be used to determine that. In the part end callback
//      * this will always return true.
//      *
//      * @return True if the part is completely uploaded, false otherwise.
//      */
//     boolean isFinished();
// 
//     /**
//      * Returns the value of the specified mime header as a String. If
//      * the Part did not include a header of the specified name, this
//      * method returns null. If there are multiple headers with the same name,
//      * this method returns the first header in the part. The header name
//      * is case insensitive. You can use this method with any request header.
//      *
//      * @param name a String specifying the header name
//      * @return a String containing the value of the requested header, or null if the part does not have a header of that name
//      */
//     String getHeader(String name);
// 
//     /**
//      * Returns the values of the part header with the given name.
//      *
//      * @param name the header name whose values to return
//      * @return a (possibly empty) Collection of the values of the header with the given name
//      */
//     Collection<String> getHeaders(String name);
// 
//     /**
//      * Returns the header names of this part.
//      *
//      * @return a (possibly empty) Collection of the header names of this Part
//      */
//     Collection<String> getHeaderNames();
// 
// }


// Path: upload-parser-tests/src/test/java/com/github/elopteryx/upload/internal/PartStreamImplTest.java
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertThrows;
import com.github.elopteryx.upload.PartStream;
import org.junit.jupiter.api.Test;

package com.github.elopteryx.upload.internal;



class PartStreamImplTest {

    @Test
    void it_should_return_the_correct_data() {
        final var fileName = "r-" + System.currentTimeMillis();
        final var fieldName = "r-" + System.currentTimeMillis();
        final var contentType = "r-" + System.currentTimeMillis();
        final var headers = new Headers();
        headers.addHeader(Headers.CONTENT_TYPE, contentType);
        final PartStream partStream = new PartStreamImpl(fileName, fieldName, headers);
        assertEquals(fileName, partStream.getSubmittedFileName());
        assertEquals(fieldName, partStream.getName());
        assertEquals(contentType, partStream.getContentType());
        assertEquals(partStream.isFile(), partStream.getSubmittedFileName() != null);
        assertFalse(partStream.isFinished());
    }

    @Test
    void invalid_file_names_are_not_allowed() {
        final var fileName = "r-" + System.currentTimeMillis() + '\u0000';
        final PartStream partStream = new PartStreamImpl(fileName, null, new Headers());