Repository: authorjapps/zerocode (java)

Issue:
Cannot send multipart/form-data without a file
`multipart/form-data` is used to send **key-value** pairs in the body of the request. The key should be string and ***value can be either string or it can be a file***. It is not mandatory to provide the file to send a `multipart/form-data` request. 

In the current implementation, if `multipart/form-data` does not contain any file then `null pointer exception` is thrown. There should be a `null check and empty check` for smooth functioning of the BasicHttpClient. 

There is a work around to overcome this issue untill next release by overriding the below method in your `HttpClient`

```java
        @Override
	public RequestBuilder createFileUploadRequestBuilder(String httpUrl, String methodName, String reqBodyAsString) throws IOException {
        Map<String, Object> fileFieldNameValueMap = FileUploadUtils.getFileFieldNameValue(reqBodyAsString);

        List<String> fileFieldsList = (List<String>) fileFieldNameValueMap.get(FILES_FIELD);

        MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create();

        // Hot fix for the issue
        if(fileFieldsList != null && !fileFieldsList.isEmpty()) {
        FileUploadUtils.buildAllFilesToUpload(fileFieldsList, multipartEntityBuilder);
        }
        FileUploadUtils.buildOtherRequestParams(fileFieldNameValueMap, multipartEntityBuilder);

        FileUploadUtils.buildMultiPartBoundary(fileFieldNameValueMap, multipartEntityBuilder);

        return FileUploadUtils.createUploadRequestBuilder(httpUrl, methodName, multipartEntityBuilder);
    }
```

Pull request:
ISS-168 # multipart/form-data support without file
Fixes #168 , also added adequate tests to verify the fix. I am open for suggestions.

Patch:
diff --git a/src/main/java/org/jsmart/zerocode/core/httpclient/BasicHttpClient.java b/src/main/java/org/jsmart/zerocode/core/httpclient/BasicHttpClient.java
index ef1696f1..18438ce2 100644
--- a/src/main/java/org/jsmart/zerocode/core/httpclient/BasicHttpClient.java
+++ b/src/main/java/org/jsmart/zerocode/core/httpclient/BasicHttpClient.java
@@ -344,7 +344,14 @@ public class BasicHttpClient {
 
         MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create();
 
-        buildAllFilesToUpload(fileFieldsList, multipartEntityBuilder);
+        /*
+	 * Allow fileFieldsList to be null.
+	 * fileFieldsList can be null if multipart/form-data is sent without any files
+	 * Refer Issue #168 - Raised and fixed by santhoshTpixler
+	 */
+        if(fileFieldsList != null) {
+        	buildAllFilesToUpload(fileFieldsList, multipartEntityBuilder);
+	}
 
         buildOtherRequestParams(fileFieldNameValueMap, multipartEntityBuilder);
 
diff --git a/src/main/java/org/jsmart/zerocode/core/httpclient/utils/FileUploadUtils.java b/src/main/java/org/jsmart/zerocode/core/httpclient/utils/FileUploadUtils.java
index 8bc439e5..78d431fa 100644
--- a/src/main/java/org/jsmart/zerocode/core/httpclient/utils/FileUploadUtils.java
+++ b/src/main/java/org/jsmart/zerocode/core/httpclient/utils/FileUploadUtils.java
@@ -54,7 +54,6 @@ public class FileUploadUtils {
 
     public static void buildOtherRequestParams(Map<String, Object> fileFieldNameValueMap, MultipartEntityBuilder multipartEntityBuilder) {
         for (Map.Entry<String, Object> entry : fileFieldNameValueMap.entrySet()) {
-            System.out.println(entry.getKey() + "/" + entry.getValue());
             if (entry.getKey().equals(FILES_FIELD) || entry.getKey().equals(BOUNDARY_FIELD)) {
                 continue;
             }


Test patch:
diff --git a/src/test/java/org/jsmart/zerocode/core/httpclient/BasicHttpClientTest.java b/src/test/java/org/jsmart/zerocode/core/httpclient/BasicHttpClientTest.java
index 5eca1bbc..4f1663c2 100644
--- a/src/test/java/org/jsmart/zerocode/core/httpclient/BasicHttpClientTest.java
+++ b/src/test/java/org/jsmart/zerocode/core/httpclient/BasicHttpClientTest.java
@@ -101,6 +101,11 @@ public class BasicHttpClientTest {
         effectiveUrl = basicHttpClient.handleUrlAndQueryParams("http://test-url", null);
         assertThat(effectiveUrl, is("http://test-url"));
     }
+    
+    @Test
+    public void test_multipart_without_file() throws IOException {
+    	basicHttpClient.createFileUploadRequestBuilder("http://test-url", "POST", "{\"modelStorage\":\"DB\",\"sketchingAlgorithm\":\"UPDATE\"}");
+    }
 
     @Test
     public void willMockUTF16Response() throws Exception {