How to upload created file - karate

I want to create a csv file and after it send it in the request. But, when I'm trying to do this, I'm getting an error:
class java.io.File cannot be cast to class java.lang.String (java.io.File and java.lang.String are in module java.base of loader 'bootstrap')
I'm creating file in the next way:
Via JS functions generating content of the file, and after it, I'm using karate.write:
* def csvFile = karate.write(csvContent,fileName)
But, when I'm trying to send this, it's an error appears:
And multipart file files = { read: '#(csvFile)', filename: 'bulkUpload.csv', contentType: 'multipart/form-data'}
When method POST
Then status 200
class java.io.File cannot be cast to class java.lang.String (java.io.File and java.lang.String are in module java.base of loader 'bootstrap')
What I'm doing wrong?
UPD: Also, I was trying to access created file directly, but it also doesn't work, even with absolute path

As mentioned in the docs, you get back a java.io.File instance: https://github.com/karatelabs/karate#karate-write
So do this:
* def csvFile = karate.write('foo', 'temp.txt')
* def csvPath = 'file:' + csvFile.getPath()
* multipart file files = { read: '#(csvPath)', filename: 'bulkUpload.csv', contentType: 'multipart/form-data' }
Note the use of .txt because of this: https://stackoverflow.com/a/55643097/143475
That said, I please read this before proceeding down this path: https://stackoverflow.com/a/54593057/143475

Related

Problems with a get request via RestClient in Groovy

I'm new to Groovy and a bit rusty on development.
I am trying to make a GET request to a woocommerce API. With Postman it works OK but not in Groovy it is not entirely clear to me what you need to cast from String to Map Entry.
I imagine it's something relatively simple but I can't find it.
Thanks a lot.
#Grab('com.github.groovy-wslite:groovy-wslite:1.1.2')
import groovy.json.JsonSlurper
import wslite.rest.*
def request
RESTClient client = new RESTClient("https://www.somewoomcersite.com")
def path = "/wp-json/wc/v3/customers"
request = client.get(path: path, headers: ["Authorization", "BLA BLA"])
Caught: java.lang.ClassCastException: java.lang.String cannot be cast to java.util.Map$Entry
java.lang.ClassCastException: java.lang.String cannot be cast to java.util.Map$Entry
at wslite.rest.RESTClient.createRequestParams(RESTClient.groovy:118)
at wslite.rest.RESTClient.this$2$createRequestParams(RESTClient.groovy)
at wslite.rest.RESTClient.executeMethod(RESTClient.groovy:93)
at wslite.rest.RESTClient.this$2$executeMethod(RESTClient.groovy)
at wslite.rest.RESTClient.get(RESTClient.groovy:49)
at wslite.rest.RESTClient.get(RESTClient.groovy)
at wslite.rest.RESTClient$get.call(Unknown Source)
at MAG.run(MAG.groovy:9)
An example json of the response would be this:
https://woocommerce.github.io/woocommerce-rest-api-docs/#list-all-customers

How to read a file for mulipart file upload from separate features in another location?- Karate DSL

To be brief with the requirement:
My folder structure looks as below:
Requirement & Challenge: When I try to read the FixedTestFile.dat
from different features, the read method appends the path wrong followed by the path of feature file and hence fails.
Tried with the following ways to read the file but failed with error.
And multipart file myFile = { read: 'src/test/java/e2e/common/data/FixedTestFile.dat', filename: #(randomFileName), contentType: 'text/plain' }
Logs:
Requirement: I have to read file "FixedTestFile.dat" from different features located in folders individual and testScenarios while using in Mutlipart file myFile.
Note : I tried with using classpath: and file: But no luck
And multipart file myFile = { read: 'classpath:e2e/common/data/FixedTestFile.dat', filename: #(randomFileName), contentType: 'text/plain' }
Tried using a variable for filename with path and tried using this as a parameter in read. Did not work.
* string myDataFileWithPath = "\'"+"../common/data/"+fileName+".dat"+"\'"
And multipart file myFile = { read: myDataFileWithPath, filename: #(randomFileName), contentType: 'text/plain' }
So the question is: "How to read a file from two features in another location?" Precisely for a multipart file upload.
Am I missing something or it is a bug while reading files?

"Lighthouse failed while trying to load a type: <XXX> Make sure the type is present in your schema definition."

I'm performing dusk test with lighthouse inside it like:
class ExampleTest extends DuskTestCase
{
use DatabaseMigrations;
public function testExample()
{
//this is a mutation for adding more stuff
$this->graphQL('mutation ...')
$this->browse(function (Browser $browser) use ($url) {
$browser->visit($url)
//asserts...
});
}
}
And on my mutations, the error message is:
"""Lighthouse failed while trying to load a type: typeFromMySchemaExample \n
\n
Make sure the type is present in your schema definition.\n
"""
I've already seen that schema is valid by:
php artisan lighthouse:validate-schema
And check the schema by it self to see if that type is present with:
php artisan lighthouse:print-schema
And cleared all configs/cache from laravel and lighthouse as in solution#1 with no success.
In my composer, I have:
laravel/dusk in v6.12.0
nuwave/lighthouse in v5.2.0
phpunit/phpunit in v9.5.2
ps:I commented that type in the graphql and the error keeps going by my import order in the schema.graphql.

Correct media type for swagger spec for downloading zip file

I am creating an api which allows downloading a zip file, so for this I am looking for correct media type for sending this zip file as response in swagger "2.0" specification.
My current api spec looks like this
/config:
get:
produces:
- application/zip
responses:
200: # OK
description: All config files
schema:
type: string
format: binary
I have compiled this spec with "go-swagger" and implemented the backend for this, but when try to call this API I get this error
http: panic serving 127.0.0.1:20366: applicationZip producer has not yet been implemented
In the documentation of swagger I don't see this media type
Official swagger media types
So then what should be the correct media type if we want to provide an API to download a zip file.
Thanks in advance
You need to implement this.
The error occurs because of the following generated code:
func NewSampleAPI(spec *loads.Document) *SampleAPI {
return &SampleAPI{
...
ApplicationZipProducer: runtime.ProducerFunc(func(w io.Writer, data interface{}) error {
return errors.NotImplemented("applicationZip producer has not yet been implemented")
}),
So after calling NewSampleAPI, you should set ApplicationZipProducer:
api := operations.NewSampleAPI(swaggerSpec)
api.ApplicationZipProducer = func(w io.Writer, data interface{}) error {
...
}
You should use "application/octet-stream" for implementing api that downloads file as an attachment , and since its Producer is already implemented by default so you won't face this issue.
As mentioned in other answer, using "application/octet-stream" partially solves the issue, but the browser does not know the file format. I think that his can be improved adding the correct headers to the response, that will tell the browser that the file has a zip extension. At least, I can download a file as ZIP and Firefox recognizes it.
#Operation(summary = "Downloads a ZIP file)
#GetMapping(value = "/zip", produces="application/octet-stream")
public byte[] start(HttpServletResponse response) {
final ContentDisposition contentDisposition = ContentDisposition.builder("attachment")
.filename("MyFile.zip").build();
response.setHeader(HttpHeaders.CONTENT_DISPOSITION, contentDisposition.toString());
return getZipDataAsByteArray();
}

How do I upload multiple files with multipart in Karate

I would like to upload multiple image files in one request using multipart. I have reviewed the Karate examples on this, but the multiple file upload does not meet my need (/multiple endpoint here - https://github.com/intuit/karate/blob/master/karate-demo/src/main/java/com/intuit/karate/demo/controller/UploadController.java). My service method (Spring REST) signature expects an array of MultipartFile[] so that I can accept any number of files. Here is my scenario:
Scenario: Upload multiple files
* def json = {}
* set json.files[0] = { read: 'file1.jpg', filename: 'file1.jpg', contentType: 'image/jpeg' }
* set json.files[1] = { read: 'file2.jpg', filename: 'file2.jpg', contentType: 'image/jpeg' }
Given path '/rest'
And multipart files json
When method post
Then status 200
And here is the Spring web service method (just trying to receive the files right now, so the method doesn't do much):
#PostMapping("/rest")
public String handleFileUpload(#RequestParam("file") MultipartFile[] file) {
System.out.println("Len: " + file.length);
for(MultipartFile currentFile : file) {
System.out.println("In here: " + currentFile.getOriginalFilename());
}
return file[0].getOriginalFilename();
}
When I run this I receive a Karate error: 'multipart file value should be json'
If I change the scenario to do this:
Scenario: Upload multiple files
* def json = {}
* set json.files = { read: 'file1.jpg', filename: 'file1.jpg', contentType: 'image/jpeg' }, { read: 'file2.jpg', filename: 'file2.jpg', contentType: 'image/jpeg' }
Given path '/rest'
And multipart files json
When method post
Then status 200
Then the test executes ok, but only one file ends up in the MultipartFile array 'files' (service method argument).
What is the proper way to upload multiple files to the web service method above using Karate?
Edit: Adding client code (below) and updated Spring method above.
Here is a simple HTML form that will submit multiple files to the Spring method above:
<form method="POST" enctype="multipart/form-data" action="/rest">
<table>
<tr><td>File to upload:</td><td><input type="file" name="file" /></td></tr>
<tr><td>File to upload:</td><td><input type="file" name="file" /></td></tr>
<tr><td></td><td><input type="submit" value="Upload" /></td></tr>
</table>
</form>
When submitted I get 2 files in the service method.
Seems that it does work, you just need to send the same parameter twice in the feature file
And multipart file files = { read: 'mergeTest.pdf', filename: 'upload-name.pdf', contentType: 'application/pdf' }
And multipart file files = { read: 'mergeTest.pdf', filename: 'upload-name.pdf', contentType: 'application/pdf' }
And multipart field filesMetadata = .........................................
my service:
public ResponseEntity<StreamingResponseBody> mergePdfs(#RequestPart #Validated
List<FileMetaData> filesMetadata, #RequestPart #Validated List<MultipartFile> files)
Wow, never seen this before and it is likely that Karate does not support it. I'm also wondering if this is legal as per the HTTP spec - as far as I know - each file has to have unique field-name. Do you have the corresponding client-side code for the Apache HTTP Client, that would help.
EDIT: also see answer by Esteban Lopez below: https://stackoverflow.com/a/59833358/143475
Your best bet may be to submit a feature request and also contribute code to expedite. Note that this is the first time in 2 years that anyone has reported this as a problem.