API Test Automation : How to upload file as the request for a POST Call - api

`I have a post api which require a file to be uploaded as the request as part of api test automation. we only have to get it uploaded. i have passed it as form param now .
Request method: POST Request URI: Valid url to be passed Proxy: <none> Request params: <none> Query params: <none> Form params: file=Valid file name Path params: <none> Headers: Accept=*/* Content-Type=application/vnd.openxmlformats-officedocument.spreadsheetml.sheet; charset=ISO-8859-1 Cookies: <none> Multiparts: <none> Body: <none> I am getting a null value as the response but am expecting a 200 ok with file upload successful message. Any help, appreciated. same is working fine in postman`

Related

Duplicate headers are added at runtime in Rest assured

I am trying to send a request with one header(authorization) but when i check the logs i am seeing same header is added twice to the request which is causing my tests to fail.
Below is the post method which i am using
public static Response doPost(String basePath, Object payload, String header) {
return reqSpec.given().header("X-HSBC-E2E-Trust-Token", header).config(RestAssuredConfig.config())
.body(payload.toString()).log().all()
.post(basePath).then().extract().response();
}
Log:
Request URI: https:Url
Proxy: <none>
Request params: <none>
Query params: <none>
Form params: <none>
Path params: <none>
Headers:E2E-Trust-Token=0JDX09VRIMl9TRVJWRVJfREVWIn0.eyJzaXQiOiJhZDp1c3I6ZW1wbG95ZWVJZCIsInN1YiI6IkdCLVNWQy1GV0tUQVBJRlAiLCJhbHQiOlt7InNpdCI6ImVtYWlsIiwic3ViIjoiR0ItU1ZDLUZXS1RBUElGUEBOb3RSZWNlaXZpbmdNYWlmhzYmMuY29tIn0seyJzaXQiOiJuYW1lIiwic3ViIjoiR0ItU1ZDLUZXS1RBUElGUCJ9LHsic2l0IjoibG9naW5JZCIsInN1YiI6IkdCLVNWQy1GV0tUQVBJRlAifV0sImdycCI6WyJDTj1JbmZvZGlyLUFQSUF1dG9GV0stUHJvZFN W5kYXJkLE9VPUlUSURBUEksT1U9QXBwbGljYXRpb25zLE9VPUdyb3VwcyxEQz1JbmZvRGlyLERDPVByb2QsREM9SFNCQyIsIkNOPUluZm9kaXItQVBJQXV0b0ZXSy1Qcm9kQWRtaW4sT1U9SVRJREFQSSxPVT1BcHBsaWNhdGlvbnM1U9R3JvdXBzLERDPUluZm9EaXIsREM9UHJvZCxEQz1IU0JDIl0sInNjb3BlIjoiSVRJREFQSSIsImp0aSI6IjBlMGQ0YzM5LThlMjQtNDI5MC1iZGExLTE0MzllOTRlMzcxYyIsImlzcyI6ImdibDIwMTA5MDk2LmhjLmNsb3VkLnVmhzYmMiLCJpYXQiOjE2NTc1MzE2NTEsImV4cCI6MTY1NzUzMjI1MSwiYXVkIjoiR0ItU1ZDLUFQSUZXREVWQEhCRVUiLCJ1c2VyX25hbWUiOiJHQi1TVkMtRldLVEFQSUZQIn0.HgxR7j7fbl5JRQxTFX0Z7OJLk_11Vc4fUFPEZ9E
Accept=*/*
E2E-Trust-Token=0JDX09BVVRIMl9TRVJWRVJfREVWIn0.eyJzaXQiOiJhZDp1c3I6ZW1wbG95ZWVJZCIsInN1YiI6IkdCLVNWQy1GV0tUQVBJRlAiLCJhbHQiOlt7InNpdCI6ImVtYWlsIiwic3ViIjoiR0ItU1ZDLUZXS1RBUElGUEBOb3RSZWNlaXZmdNYWlsLmhzYmMuY29tIn0seyJzaXQiOiJuYW1lIiwic3ViIjoiR0ItU1ZDLUZXS1RBUElGUCJ9LHsic2l0IjoibG9naW5JZCIsInN1YiI6IkdCLVNWQy1GV0tUQVBJRlAifV0sImdycCI6WyJDTj1JbmZvZGlyLUFQSUF1dG9GV0sHJvZFN0YW5kYXJkLE9VPUlUSURBUEksT1U9QXBwbGljYXRpb25zLE9VPUdyb3VwcyxEQz1JbmZvRGlyLERDPVByb2QsREM9SFNCQyIsIkNOPUluZm9kaXItQVBJQXV0b0ZXSy1Qcm9kQWRtaW4sT1U9SVRJREFQSSxPVT1BcHBsaWN
3VkLnVrLmhzYmMiLCJpYXQiOjE2NTc1MzE2NTEsImV4cCI6MTY1NzUzMjI1MSwiYXVkIjoiR0ItU1ZDLUFQSUZXREVWQEhCRVUiLCJ1c2VyX25hbWUiOiJHQi1TVkMtRldLVEFQSUZQIn0.HgxR7j7fbl5JRQxTFX0Z7OJLk_11Vc4FPEZ9Ec2xVXmUxeE6M3f8wBe4HOrQDJw_gWm_Kvf_hepsvAu0S0ACRQ3P_4i5yf2z0FXtBoUd3v9AvZcB299PZGJhNZ4HxUEP5SdzjQWOuZgdHAFg6GJdgsYBLTuCXQqy-kdqgPczgx7bgKTBfqrWH2I4qH1ZSE2OlksvGPj0Ia1Ts
Content-Type=application/json; charset=UTF-8
Cookies: <none>
Multiparts: <none>
Body:
{
"name": "TestRole11072733",
"requiresApproval": true,
"signatures": [
1091
]
}
10:27:36.574 [main] DEBUG org.apache.http.impl.conn.BasicClientConnectionManager - Get connection for route {s}->https:URL
10:27:36.574 [main] DEBUG org.apache.http.impl.conn.DefaultClientConnectionOperator - Connecting to Endpoint
10:27:37.001 [main] DEBUG org.apache.http.client.protocol.RequestAddCookies - CookieSpec selected: ignoreCookies
10:27:37.001 [main] DEBUG org.apache.http.client.protocol.RequestAuthCache - Auth cache not set in the context
10:27:37.001 [main] DEBUG org.apache.http.client.protocol.RequestProxyAuthentication - Proxy auth state: UNCHALLENGED
10:27:37.001 [main] DEBUG org.apache.http.impl.client.DefaultHttpClient - Attempt 1 to execute request
10:27:37.001 [main] DEBUG org.apache.http.impl.conn.DefaultClientConnection - Sending request: POST Endpoint

rest-assured kotlin extension sends an empty body

I'm using rest-assured 4.4.0 with Kotlin and this simple test fails:
Given {
body("hello")
}
When {
post("/endpoint/")
} Then {
statusCode(HttpStatus.SC_CREATED)
}
rest-assured is not sending the body with the request:
Request method: POST
Request URI: http://localhost:52298/endpoint/
Proxy: <none>
Request params: <none>
Query params: <none>
Form params: <none>
Path params: <none>
Headers: Accept=*/*
Content-Type=application/json
Cookies: <none>
Multiparts: <none>
Body: <none>
If I switch to the java-based API, the test passes:
given()
.body("hello")
.`when`()
.post("/endpoint")
.then()
.assertThat()
.statusCode(HttpStatus.SC_CREATED)
I couldn't find any open issue in rest-assured github repo related to this problem, I wonder if I'm doing something wrong.
Wrong formatting, the When block must be on the same line as the closing bracket of the Given block.
WRONG
Given {
body("{\"hello\":\"world\"}")
}
When {
...
RIGHT
Given {
body("{\"hello\":\"world\"}")
} When {
...

GCP API Gateway: Path parameters are being passed as query params

I'm trying to use GCP API Gateway to create a single endpoint for a couple of my backend services (A,B,C,D), each with their own path structure. I have the Gateway configured for one of the services as follows:
swagger: '2.0'
info:
title: <TITLE>
description: <DESC>
version: 1.0.0
schemes:
- https
produces:
- application/json
paths:
/service_a/match/{id_}:
get:
summary: <SUMMARY>
description: <DESC>
operationId: match_id_
parameters:
- required: true
type: string
name: id_
in: path
- required: true
type: boolean
default: false
name: bool_first
in: query
- required: false
type: boolean
default: false
name: bool_Second
in: query
x-google-backend:
address: <cloud_run_url>/match/{id_}
deadline: 60.0
responses:
'200':
description: Successful Response
'422':
description: Validation
This deploys just fine. But when I hit the endpoint gateway_url/service_a/match/123, it gets routed to cloud_run_url/match/%7Bid_%7D?id_=123 instead of cloud_run_url/match/123.
How can I fix this?
Editing my answer as I misunderstood the issue.
It seems like the { are getting leaked from your configuration as ASCII code, so when you call
x-google-backend:
address: <cloud_run_url>/match/{id_}
deadline: 60.0
it doesn't show the correct ID.
So this should be a leak issue from your yaml file and you can approach this the same way as in this thread about using path params

How to disable Ansible's password obfuscating feature

I have a simple Ansible playbook to
Fetch a database connection config from an RestAPI,
Extract the config object from the payload,
Using the config JSON (as request body) to create a PUT request to another RestAPI.
At the 3rd stage I found that the database username and password combination is wrong. Later, while I print the outputs, I have found that the password has been replaced with a string named "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER".
After some googling, I found that this is a security feature by Ansible. Unfortunately, I haven't found any configuration or something like this to disable this feature. Is it possible to disable this feature? Or any other workaround?
---
- name: my-playbook
gather_facts: no
hosts: all
vars_files:
- secret
tasks:
- name: Fetch the config payload from the API
uri:
url: "{{get_config}}"
method: GET
user: "{{username}}"
password: "{{password}}"
validate_certs: no
return_content: yes
status_code: 200
body_format: json
register: config
- name: Extract the config object
set_fact:
config_raw: "{{ config.json | json_query(jmesquery) }}"
vars:
jmesquery: '{{name}}.config'
- name: print the config
debug:
msg: "{{config_raw}}"
- name: Creating object using config
uri:
url: "{{create_ocject}}"
method: PUT
user: "{{username}}"
password: "{{password}}"
validate_certs: no
body: "{{config_raw}}"
body_format: json
return_content: yes
status_code: 200
headers:
Content-Type: "application/json"
register: test_res
- name: output value
debug:
msg: "{{test_res.json}}"

How should I handle an application/javascript response type in Swagger?

I have a swagger app that works when JSON is returned, but not with JSONP. Success and fail cases are described further down.
It is worth noting that the exact controller code shown below works fine under vanilla node/express - the problem seems to occure when the response goes through the swagger response validator.
The snippet of controller code that handles the response is as follows:
retVal.success = true;
retVal.data = jsondata;
res.set('Content-Type', 'application/javascript');
res.jsonp(200, retVal);
swagger.yaml:
swagger: "2.0"
info:
title: sometitle
version: v1
host: localhost:3000
basePath: /
schemes:
- http
consumes:
- application/json
- application/javascript
produces:
- application/json
- application/javascript
- text/javascript
paths:
/loadallrepos:
x-swagger-router-controller: loadallrepos
get:
summary: summary here...
description: |
description here...
operationId: loadallrepos
parameters:
- name: callback
in: query
description: Passed by .ajax call for cross-domain requests
required: false
type: string
responses:
200:
description: Success
schema:
$ref: "#/definitions/loadallreposResponse"
definitions:
loadallreposResponse:
type: object
required:
- success
- data
properties:
success:
type: boolean
data:
type: object
required:
- nextrefresh
properties:
nextrefresh:
type: integer
If I make a request without the callback parameter, it works:
request: localhost:3000/loadallrepos
response:
{
"success": true,
"data": {
"nextrefresh": 3439704
}
}
If I turn it into a jsonp request though, it fails:
request: localhost:3000/loadallrepos?callback=jQuery111106460774131119251_1439402109118&_1439402109119
response:
{
"message": "Response validation failed: value expected to be an array/object but is not",
"failedValidation": true,
"originalResponse": "typeof jQuery111106460774131119251_1439402109118 === 'function' && jQuery111106460774131119251_1439402109118({
"success": true,
"data": {
"nextrefresh": 3442750
}
});"
}
Again, this works under vanilla node/express. Any help is greatly appreciated!
JSONP APIs return a string of JavaScript. Your Swagger definition says your API returns an object defined at #/definitions/loadallreposResponse which is of type object. What happens is swagger-node/swagger-tools sees a type of object and attempts to use JSON.parse on the response body and fails. To support JSONP with Swagger, you need to make your response schema be of type string to avoid response validation failure.