How to evaluate value of a variable in Json Key in Karate? [duplicate] - karate

This question already has an answer here:
Karate API function/keyword to substitute JSON placeholder key with argument passed
(1 answer)
Closed 1 year ago.
I have a request Json for one of my API calls, where the Key of Json Object itself is a variable which needs to be evaluated while hitting the API.
Normally when i have to use variable in Json, I simply use #(varName) and it works fine as long as I am having this as Json Value.
I want to do the same for Json Key.
Sample json snippet is:-
"Registrations": {
"#(varName)": {
"requestedAction": "REGISTER",
"productId": "#(varName)",
"registrationSourceType": "Selected",
"includedInAgenda": false
}`
In above example, Registration Json block has nested Json where my KeyName will be an uuid.

Just use JS:
* def myJson = { registrations: {} }
* def uuid = 'someString'
* myJson.registrations[uuid] = { foo: 'bar' }
* match myJson == { registrations: { someString: { foo: 'bar' } } }

Related

How to validate an object inside a JSON schema in Karate whether its empty or contains a series of key:value pairs?

I am trying to validate an API response using Karate for either of these two states.
Scenario 1 (when it returns a contractData object that contains a fee key):
{
"customer": {
"financialData": {
"totalAmount": 55736.51,
"CreateDate": "2022-04-01",
"RequestedBy": "user1#test.com"
},
"contractData": {
"Fee": 78.00
}
}
}
Scenario 2 (when it returns an empty contractData object):
{
"customer": {
"financialData": {
"totalAmount": 55736.51,
"CreateDate": "2022-04-01",
"RequestedBy": "user1#test.com"
},
"contractData": {}
}
}
How can I write my schema validation logic to validate both states?
The best thing I could have done is to write it like this:
* def schema = {"customer":{"financialData":{"totalAmount":"#number","CreateDate":"#?isValidDate(_)","RequestedBy":"#string"},"contractData":{"Fee": ##number}}}
* match response == schema
And it seems like it works for both above scenarios, but I am not sure whether this is the best approach or not. Problem with this approach is if I have more than one key:value pair inside "contractData" object and I want to be sure all those keys are present in there when it is not empty, I cannot check it via this approach because for each individual key:value pair, this approach assumes that they could either be present or not and will match the schema even if some of those keys will be present.
Wow, I have to admit I've never come across this case ever, and that's saying something. I finally was able to figure out a possible solution:
* def chunk = { foo: 'bar' }
* def valid = function(x){ return karate.match(x, {}).pass || karate.match(x, chunk).pass }
* def schema = { hey: '#? valid(_)' }
* def response1 = { hey: { foo: 'bar' } }
* def response2 = { hey: { } }
* match response1 == schema
* match response2 == schema

JSON Object validation with JSONSchema Validator

const Validator = require('jsonschema').Validator;
const validator = new Validator();
const obj =
[
{
"id":"1",
"firstname":"Jack"
}
];
const instance= {
properties: {
id: {
type: 'number'
},
firstname: {
type: 'string'
}
},
required: ['id', 'firstname'],
additionalProperties: false
};
const result = validator.validate(obj, instance);
console.log(result.errors);
I want to validate a JSON Object using jsonschema Validator. when json object is not as per schema, then also validate function is not returning any error. irrespective of obj being as per schema/instance or not, its error section always returning null.
You've defined obj as an array as opposed to an object. As a result, validation is passing because you've used JSON Schema keywords which only apply to objects. (Many JSON Schema keywords are only applicable to specific types.)
In your schema, add "type": "object", and you should see an error when the instance is not an object.
On a side note, an "instance" is the data you want to validate, and a "schema" is the JSON Schema you want to use for validation.

How to reference data variable from another data variable in Vue 2? [duplicate]

This question already has answers here:
How to put a value of data object in another data object vueJS
(2 answers)
Closed 4 years ago.
I have this in vue data:
data() {
return {
names: [],
length: names.length,
}
But this does not work as RefereneError ( names is undefined ) is thrown. I used this.names but makes no difference.
You need to do something like this to make it work:
#1st way
data() {
let defaultNames = [];
return {
names: defaultNames,
length: defaultNames.length
}
}
#2nd way — using computed data (the better way):
data() {
return {
names: [],
}
},
computed: {
length() {
return this.names.length;
}
}

finding an object by key using lodash

I have a json object like this
var variable = {
a : { },
b : { }
};
Using lodash how to get only [{ a: {} }] as result. Basically how to find an object inside list of objects using key.
Lodash has a _.get function.
documentation
The nice thing about _.get is that it'll protect you against TypeError exceptions.
In the example below, I am looking for the value of obj.a.b.c. The problem here is that there isn't a property c on obj.a.b object. This will throw a TypeError. With _.get, you can anticipate this and give it a default value if obj.a.b.c doesn't exist:
"use strict";
var _ = require('lodash');
var obj = {
a: {
b: 1
}
}
var value = _.get(obj, "a.b.c", "this is the default value");
console.log(value);
Output:
this is the default value

How to manage data template when serving an api using Node.js

I'm currently trying to create an api for my web app using Node.js. The api intended to return JSON data to the api user.
For example, i'm having following endpoint / object:
- Articles (collection of article)
- Article (single article, each article would be having tags)
- Tags
Each endpoint / object having they own json data format need to return, in example:
Articles: [{articleObject}, {articleObject}, {articleObject}]
Article
{
id: 12,
title: 'My awesome article *i said and i know it',
content: 'blah blah blah blah',
tags: [{tagObject}, {tagObject}, {tagObject}]
}
Each endpoint can call to other endpoint to get needed data, in example:
Article endpoint can calling the Tags endpoint to get the article tags collection, the Tags endpoint will be returning Array Object.
My questions:
How to manage the Object structures, so if a endpoint called from another endpoint it will return Array / Object, while it will be return JSON string when called from api user.
Should I create Object template for each endpoint. The process will be:
Endpoint will be calling Object Template;
The Object Template will fetching data from database;
Endpoint will return the Object Template when called from other endpoint;
Endpoint will call template engine to parse the Object Template to JSON string for api user. JSON string view will be provided for each endpoint.
What Template Engine can process below Object Template and treat them as variables, in PHP i'm using Twig that can receive PHP Object and treat them as variables. Here you can find how i do that using Twig
Object Template file content example:
var Tags = require('./tags');
module.exports = function(param){
/* do fetching data from database for specified parameters */
/* here */
var data = {};
return {
id: function() {
return data.id;
},
title: function() {
return data.title;
},
description: function() {
return data.description;
},
tags: function() {
return Tags(data.id);
}
}
}
Hope someone can show me the way for it.
I use express to do my apis...you can do something like this:
app.get('/api/article', authenticate, routes.api.article.get);
authenticate is just a middleware function that authenticates the user, typically this is grabbing the user from session and making sure they are logged in.
inside ./routes/api.js
var Article = require('../models/article.js');
exports.api = {}
exports.api.article = {}
exports.api.article.get = function(req, res){
//get article data here
Article.find({created_by: req.session.user._id}).populate('tags').populate('created_by').exec(function(err, list){
res.json(list);
});
};
This assume you're using mongoose and mongodb and have an Article schema similar to this, which includes a reference to a Tag schema:
var ArticleSchema = new Schema({
name : { type: String, required: true, trim: true }
, description: { type: String, trim: true }
, tags : [{ type: Schema.ObjectId, ref: 'Tag', index: true }]
, created_by : { type: Schema.ObjectId, ref: 'User', index: true }
, created_at : { type: Date }
, updated_at : { type: Date }
});