automation.ninja.08
automation.ninja.08

Reputation: 95

Karate V 1.3.1 - json data in Multipart/form-data in Multipart field or Multipart file is not working as a expected

I am using Karate version 1.3.1 for our projects. Currently we have a use case to test an API which is taking a file and a metadata as part of the request.

we are using multipart file and field to write our feature file, but it seems when we check the POsT call on report we don’t see the metadata which is a Json going as part of the request.

As per the suggestion in link: https://github.com/karatelabs/karate/issues/1710

we tried the other approach to use multipart file and value as a parameter but it did not work for us.

Is there any other way to implement this on karate?

note: postman is working without any issues and we get a response too

please help if anyone has faced or resolved this.

Below is my feature file:

def temp = { 'upload': ['name':'test', 'org':123, 'branch': 'xyz', 'amount': 100], 'info': 8900, 'id': 123}

Given url "http://11.111.1.111:1111"

And path "/api/v1/upload

header Content-Type = 'multipart/form-data'

And multipart file file = {read: 'classpath:resources/file/file1.txt', filename: 'file1.txt'}

And multipart file metadata = {value: '#(temp)}

And method POST

print response

Note: I also tried * multipart field metadata = temp (but no luck here)

Response:

content-disposition: form-data; name= file; filename="file1.txt"
content-type: text/plain; charset= UTF-8
content-length: 5300
Completed: true
IsInMemory: true

content-disposition: form-data; name= metadata; filename=""
content-type: application/json; charset= UTF-8
content-length: 100
Completed: true
IsInMemory: true

The issue is when I run the feature file on Karate the api returns me 200 with a blank response. Response: { }

but when the same is executed from Postman it returns me response Response from postman: {id:123, status: ‘Done’}

also I tried the same request with Java okhttpClient request and it worked fine and gave me the expected response.

Is there anything which I am missing while running from Karate?

Implementation of Java Class for OkHttpClient (WORKING):

import okhttp3.*;

import java.io.File;
import java.io.IOException;
import java.util.Map;

public class OkHttpHelper {
    private OkHttpClient client;

    public OkHttpHelper() {
        client = new OkHttpClient();
    }

    public String executeMultipartRequest(String url, Map<String, String> fields, Map<String, String> files) throws IOException {
        MultipartBody.Builder requestBodyBuilder = new MultipartBody.Builder().setType(MultipartBody.FORM);

        // Add fields
        if (fields != null) {
            for (Map.Entry<String, String> field : fields.entrySet()) {
                requestBodyBuilder.addFormDataPart(field.getKey(), null, RequestBody.create(MediaType.parse("application/json"), field.getValue()));
            }
        }

        // Add files
        if (files != null) {
            for (Map.Entry<String, String> file : files.entrySet()) {
                File uploadFile = new File(file.getValue());
                requestBodyBuilder.addFormDataPart(file.getKey(), uploadFile.getName(),
                        RequestBody.create(MediaType.parse("text/plain"), uploadFile));
            }
        }

        RequestBody requestBody = requestBodyBuilder.build();

        // Print requestBody content
        System.out.println("Request Body: " + requestBodyToString(requestBody));

        Request request = new Request.Builder()
                .url(url)
                .post(requestBody)
                .build();

        try (Response response = client.newCall(request).execute()) {
            return response.body().string();
        }
    }

    private String requestBodyToString(RequestBody requestBody) throws IOException {
        Buffer buffer = new Buffer();
        requestBody.writeTo(buffer);
        return buffer.readUtf8();
    }
}

Feature file looks like below:

Feature: Multipart Request with OkHttp

Background:
* def OkHttpHelper = Java.type('com.example.OkHttpHelper')
* def okHttpHelper = new OkHttpHelper()

Scenario: Send Multipart Request
    * def url = 'https://example.com/upload'
    And def fields = { "metadata": '{"key1": "value1"}' }
    And def files = { "file": "path/to/file1.txt" }
    When def response = okHttpHelper.executeMultipartRequest(url, fields, files)
    Then print response

** CURL Command from POSTMAN**

curl -X POST \
  http://11.111.11.111:1111/api/v1/fileupload
  -H 'Accept: */*' \
  -H 'Accept-Encoding: gzip, deflate' \
  -H 'Cache-Control: no-cache' \
  -H 'Connection: keep-alive' \
  -H 'Content-Length: 5800' \
  -H 'Content-Type: multipart/form-data; boundary=---------23434234234343' \
  -H 'Host: 11.111.11.111:1111' \
  -H 'Postman-Token: XXXXXX-xxxx-xxxx-xxxx-Xxxxxxx,XXXXXXXX' \
  -H 'User-Agent: PostmanRuntime/X.XX.X' \
  -H 'cache-control: no-cache' \
  -H 'content-type: multipart/form-data; boundary=---------23434234234343' \
  -F file@/C:/Test/Sample/file1.txt \
  -F ‘metadata’= { "metadata": '{"key1": "value1"}' }

Upvotes: 1

Views: 838

Answers (1)

Peter Thomas
Peter Thomas

Reputation: 58088

As far as I can tell, this should work:

* url 'https://httpbin.org/anything'
* multipart file file = { read: 'myfile.txt' }
* multipart field metadata = { some: 'data' }
* method post

You can experiment by pointing your okhttp or postman test to https://httpbin.org/anything and see what are the differences. The response will tell you all the field values and file values sent in the request.

Upvotes: 0

Related Questions