Updated JSON file is not reading during runtime - karate

Team,
I have service to register a user with certain data along with unique mail id and phone no in JSON file format as a body (for ex: registerbody.json).
Before Post call I am generating unique mail id , phone no and updating the same json file (registerbody.json) fields which is in the same folder where feature file locates. I see the file is updated with the required data during runtime.
I used read () method and performed POST request
Surprisingly read method is not taking updated JSON file instead it is reading old data in the registerbody.json file.
Do you have any idea on this, why it is picking up old data even though file is updated with the latest information?
Please assist me with this.

Karate uses the Java classpath, which is typically target/test-classes. So if you edit a file in src/test/java Karate won't see it unless it is copied. This copying is automatically done when you build / compile your code.
My suggestion is use target/ as a temp folder and then you can read using the file: prefix:
* def payload = read('file:some.json')
Before Post call I am generating unique mail id , phone no and updating the same json file (registerbody.json)
You are making a big mistake here, Karate specializes in updating JSON based on variables. I suggest you take 5 minutes and read this part of the docs VERY carefully: https://github.com/intuit/karate#reading-files
Especially the part about embedded expressions: https://github.com/intuit/karate#embedded-expressions

Related

JSZip reports missing bytes when reading back previously uploaded zip file

I am working on a webapp where the user provides an image file-text sequence. I am compressing the sequence into a single ZIP file uisng JSZip.
On the server I simply use PHP move_uploaded_file to the desired location after having checked the file upload error status.
A test ZIP file created in this way can be found here. I have downloaded the file, expanded it in Windows Explorer and verified that its contents (two images and some HTML markup in this instance) are all present and correct.
So far so good. The trouble begins when I try to fetch that same ZIP file and expand it using JSZip.loadAsync which consistently reports Corrupted zip: missing 210 bytes. My PHP code for squirting back the ZIP file is actually pretty simple. Shorn of the various security checks I have in place the essential bits of that code are listed below
if (file_exists($file))
{
ob_clean();
readfile($file);
http_response_code(200);
die();
} else http_response_code(399);
where the 399 code is interpreted in my webapp as a need to create a new resource locally instead of trying to read existing resource data. The trouble happens when I use the result text (on an HTTP response of 200) and feed it to JSZip.loadAsync.
What am I doing wrong here? I assume there is something too naive about the way I am using readfile at the PHP end but I am unable to figure out what that might be.
What we set out to do
Attempt to grab a server-side ZIP file from JavaScript
If it does not exist send back a reply (I simply set a custom HTTP response code of 399 and interpret it) telling the client to go prepare its own new local copy of that resource
If it does exist send back that ZIP file
Good so far. However, reading the existent ZIP file into PHP and sending it back does not make sense + is fraught with problems. My approach now is to send back an http_response_code of 302 which the client interprets as being an instruction to "go get that ZIP for yourself directly".
At this point to get the ZIP "directly" simply follow the instructions in this tutorial on MDN.

Is there a place where a set of code is run every time I visit a route and the output of the code is available to the module at the route?

I have a web application that hosts several tools. E.g. docx-to-pdf, pdf-to-docx, etc... each is a vue module file within the application.
When the user goes to the docx-to-pdf tool, uploads the file using a dropzone, the server's file manager will generate a uuid (I call it a module session id) and use this as the directory name to place the uploaded file and return the uuid to the browser. Then when the user clicks on 'convert', the uuid is sent with the 'convert' command and the server will perform the conversion and allows the user to download the converted file.
This works fine until I have a tool called combine-pdf and have 2 dropzones on the page. When I'm uploading file1 in dropzone1 and file2 in dropzone2 at the same time, each goes into its own directory because the server's file manager thinks they're the first file to be uploaded. Unless I complete file1's upload first before I start file2, otherwise when I try click on 'combine', the server will only have one of the two uuids and will try to combine but only find one file there.
The most logical solution I can think of would be to generate the uuid in Vue, and when I upload files to the server, it'll validate that it's a proper uuid and use this throughout the session in this module. I can put this is Vue's created hook. This is fine but I find that as me or my teammates add modules, we keep repeating this same code in every module which seems repetitive.
Is there a place where I can generate this uuid and eventually pass it to the module's data so it's write once but every module gets a new uuid?
I thought of having a parent module for all these tool modules and in this parent module I would perform this uuid generation in its created hook but this is only loaded once and not every time I visit a module.
You could move the the fileUpload function to the dropzone parent so that each dropzone component emits the file to the parent. The parent can then upload both files as an array to the server, and return an array of uuids to the client.

Xquery extracting property values from .properties file

I am currently trying to extract property values from my properties file, but am running into some problems. I can't test this in ML query console, because the properties file doesn't exist there. I am currently trying to grab the values of the file like this
let $port := #{#properties["ml.properties-name"]}
I've also looked at
xdmp:document-get-properties(
$uri as xs:string,
$property as xs:QName
however that is limited to .xml files I believe. Does anyone have a way/work-around of accessing these values? I can't seem to find one I've looked at some documentation on Marklogic's website, but can't seem to get anything to work. The way I was accessing before was in ruby, through monkey-patching allowing me to access those private fields.The problem with that is the ruby script I call is only called once, while my .xqy file is ran every minute that sends args to another function. I need to access those args from the properties file, right now I just have them hard-coded in. Any thoughts?
Thanks
You cannot access deployment properties like that, but you can pass them along with deployment. If you create a new REST app with latest Roxy, you should get a copy of this config.xqy added to src/config/:
https://github.com/marklogic-community/roxy/blob/master/deploy/sample/custom-config.xqy
That file is treated specially when deployed to the modules database. Properties references are replaced inside there. In your case, add another variable, and give it a string value following the #ml.xyz pattern:
declare variable $c:port := "#ml.property-name";
You can then import the config lib, and use it in your code.
These so-called Deployer Substitutions are described in more detail on the Roxy wiki:
https://github.com/marklogic-community/roxy/wiki/Deployer-Substitutions

Jbehave as Data Driven Testing Framework

I have some scenarios written in Jbehave and I would like to run it for 1000+ data. The Problem is that I cannot list all data items in 'Examples' because, firstly, it is not maintainable and secondly, I get this data file everyday from an external service.
Is there a way to write a scenario that can take data from the file?
Parameters can be loaded from an external file,
Details with an example are here: http://jbehave.org/reference/stable/parametrised-scenarios.html
Loading parameters from an external resource
The parameters table can also be loaded from an external resource, be
it a classpath resource or a URL.
Given a stock of <symbol> and a <threshold>
When the stock is traded at <price>
Then the alert status should be <status>
Examples:
org/jbehave/examples/trader/stories/trades.table
We need to enable the parser to find the resource with the appropriate
resource loader configured via the ExamplesTableFactory:
new MostUsefulConfiguration()
.useStoryParser(new RegexStoryParser(
new ExamplesTableFactory(new LoadFromClasspath(this.getClass())))
)
I too have same requirement and I think below will be the possible solution.
Implement a method to read the excel sheet and prepare the testData.table before scenario start executes, use #BeforeScenario jbehave annotation in steps java file.
refer this link to implement loading data from external resource http://jbehave.org/reference/stable/parametrised-scenarios.html
#BeforeScenario
public void prepareTestData(String excelSheetPath) {
// java code to read given excelSheetPath and prepare a *.table
}

How to set http headers in dotCMS

I'm trying to create a XML data feed with dotCMS. I can easily output the correct XML document structure in a .dot "page", but the http headers sent to the client are still saying that my page contains "text/html". How can I change them to "text/xml" or "application/xml"?
Apparently there's no way to do it using the administration console. The only way I found is to add this line of (velocity) code
$response.setHeader("Content-Type", "application/xml")
to the top of the page template.
Your solution is the easiest. However there are other options that are a bit more work, but that would prevent you from having to use velocity to do the XML generation, which is more robust most of the time.
DotCMS uses xstream to generate XML files (and vise versa). You could write a generic plugin to use this as well.
An JSONContentServlet exists in dotCMS that takes a query and generates json or xml (depending on your parameters). It is not mapped on a servlet by default, but that is easy to add.