0

I have a feature file with multiple scenarios (GET,POST etc.). There is one particular order where -

  1. Scenario 1 - POST Request is run with "multipart" data
  2. Scenario 2 - GET Request needs to be run.

First, when POST Request is run, following is the Request Information -

Request method: POST
Request URI:    <<Request URL>>
Proxy:          <none>
Request params: <none>
Query params:   <none>
Form params:    <none>
Path params:    <none>
Headers:        X-AUTH-TOKEN= <<AuthToken>>
            Accept=*/*
            Content-Type=multipart/form-data; boundary="sVIVdkx_Idma6CgU58sVMDuGK4e34kqBOPeoObL"
Cookies:        <none>
Multiparts:     ------------
            Content-Disposition: form-data; boundary="sVIVdkx_Idma6CgU58sVMDuGK4e34kqBOPeoObL"; name = files; filename = debug.log
            Content-Type: application/octet-stream

            <<log file location>>
            ------------
            Content-Disposition: form-data; boundary="sVIVdkx_Idma6CgU58sVMDuGK4e34kqBOPeoObL"; name = body; filename = Test_new.json
            Content-Type: application/json

            <<Static JSON Payload location>>
Body:           <none>

As seen above, this is a POST Request, where 'Content-Type' is 'multipart/form-data' and "Multiparts" param contains Static JSON Payload as well as File to be uploaded. This is done with following piece of code -

    RequestSpecification reqSpec_Int = getReqSpec.header("Content-Type", "multipart/form-data").
                            multiPart("files",uploadFiles).
                            multiPart("body", updateVinJsonFile, "application/json");

This works fine. But after this POST call, I need to run GET call (which is a different scenario), where "Content-Type" is "application/json" and there should be nothing in "Multiparts" param. But when I run this GET API call, "Multiparts" param still shows the previous POST Call's data. Please see below -

Request method: GET
Request URI:    <<GET URL>>
Proxy:          <none>
Request params: <none>
Query params:   <none>
Form params:    <none>
Path params:    <none>
Headers:        X-AUTH-TOKEN= <<authToken>>
            Accept=*/*
            Content-Type=application/json
Cookies:        <none>
Multiparts:     ------------
            Content-Disposition: application/json; name = files; filename = debug.log
            Content-Type: application/octet-stream

            <<log file location>>
            ------------
            Content-Disposition: application/json; name = body; filename = Test_new.json
            Content-Type: application/json

            <<Static JSON Payload location>>
Body: <none>

Due to this, I am getting following exception -

java.lang.IllegalArgumentException: Content-Type application/json is not valid when using multiparts, it must start with "multipart/" or contain "multipart+".

Is there any way to clear this "Multiparts" param after the POST call is done? So that this doesnt come in GET call.

Please Note - As mentioned above, this multipart setting is done using RequestSpecification. This reference is null at the start for every scenario.

Adding the Code below -

Below is the Feature File -

@EndToEndTest   
Scenario: Update API Call

Given "TEST" Authentication Token for "POST" "MULTIPART" Request
When User calls "<<UpdateAPICall>>" call with "POST" Http Request and Params
Then API call is successful

@EndToEndTest   
Scenario: Get API Call

Given "TEST" Authentication Token for "GET" "OCTET" Request
When User calls "<<GetAPICall>>" call with "GET" Http Request and Params
Then API call is successful

Below is the Step Definition Code -

RequestSpecification reqSpec;
Response response;
static List<String> instructionFileList = new ArrayList<String>();
static String authToken;
static int jobId;
static int vinId;
boolean apiCallSuccess;

@Given("{string} Authentication Token for {string} {string} Request")
public void authentication_token_for_request(String environment, String method, String contentType) throws Exception {
    System.out.println("Authentication Token - "+authToken);
    RequestSpecification reqSpec_Int = null;
    
    File updateVinJsonFile = new File(getPropertyValue("updateJobVINJSON"));
    File uploadFiles = new File(getPropertyValue("fileUpload"));
    
    if(environment.equalsIgnoreCase("TEST")) {
        if(method.equalsIgnoreCase("GET")) {
            switch(contentType) {
                case "FORMURL":
                    reqSpec_Int = getReqSpec_Test().header("Content-Type", "application/x-www-form-urlencoded");
                    break;
                case "OCTET":
                    reqSpec_Int = getReqSpec_Test().header("Content-Type", "application/octet-stream");
                    break;
            }
        }
        else if (method.equalsIgnoreCase("POST")) {
            switch (contentType) {
                case "JSON":
                    reqSpec_Int = getReqSpec_Test().header("Content-Type", "application/json");
                    break;
                case "MULTIPART":
                    reqSpec_Int = getReqSpec_Test().header("Content-Type", "multipart/form-data").
                            multiPart("files",uploadFiles).
                            multiPart("body", updateVinJsonFile, "application/json");
                    break;
            }
        }           
    }
            
    reqSpec = given()
            .spec(reqSpec_Int).log().all()
            .header("X-AUTH-TOKEN",authToken);
}

@When("User calls {string} call with {string} Http Request and Params")
public void user_call_with_http_request_and_params(String resource, String method) {
    
    SoftAssert softAssert = new SoftAssert();       
    String finalResourceName = null;
    APIResources resourceAPI = APIResources.valueOf(resource);
    System.out.println("Resource Name - "+resourceAPI.getResource());
    
    try {
        if(resource.equalsIgnoreCase("<<UpdateAPI>>")) {
            for(int vinId:vinList) {
                finalResourceName = resourceAPI.getResource()+vinId;
                System.out.println("Final Resource Name - "+finalResourceName);
                response = reqSpec.when().post(finalResourceName);
                if(response.getStatusCode() == 200) {
                    System.out.println("API Call successful with Status Code - "+response.getStatusCode());
                    apiCallSuccess = true;
                }
                else {
                    System.out.println("API Call is not successful with Response - "+response.asString());
                    apiCallSuccess = false;
                }
            }
        }
        else if(resource.equalsIgnoreCase("<<GetAPI>>")) {
            for(String instruction:instructionFileList) {
                finalResourceName = resourceAPI.getResource()+jobId+"/instructionfile/"+instruction+".pdf";
                System.out.println("Final Resource Name - "+finalResourceName);
                Thread.sleep(4000);
                response = reqSpec.when().log().all().get(finalResourceName);
                if(response.getStatusCode() == 200) {
                    System.out.println("API Call successful with Status Code - "+response.getStatusCode());
                    apiCallSuccess = true;
                }
                else if(response.getStatusCode() == 500) {
                    JsonPath jj = CommonMethods.rawToJson(response.asString());
                    if(jj.get("error").toString().equalsIgnoreCase("Internal Server Error") && jj.get("exception").toString().equalsIgnoreCase("java.lang.NullPointerException")) {
                        System.out.println("API Call successful with Status Code - "+response.getStatusCode());
                        apiCallSuccess = true;
                    }
                    else {
                        System.out.println("API Call is not successful with Response - "+response.asString());
                        apiCallSuccess = false;
                    }
                }
            }
        }
   }

As mentioned earlier, RequestSpecification reference 'reqSpec' is null at the start of every scenario. I am getting the mentioned exception when execution reaches below line for "GetAPICall"-

response = reqSpec.when().log().all().get(finalResourceName);

Also Point To Note - If I run the GET call before POST Call, it runs fine.

user1865709
  • 55
  • 1
  • 10

1 Answers1

0

As far as I understand, problem is RequestSpecification reqSpec, it still contains config of the first run. My suggesstion is makeing it null after calling the api.

Code would be:

@When("User calls {string} call with {string} Http Request and Params")
public void user_call_with_http_request_and_params(String resource, String method) {
    
    ...other code
    reqSpec = null; //At the end of method
}

or

@When("User calls {string} call with {string} Http Request and Params")
public void user_call_with_http_request_and_params(String resource, String method) {
    
    ...
    
    try {...}
    finally {
        reqSpec = null;
    }
}
lucas-nguyen-17
  • 5,516
  • 2
  • 9
  • 20