How to assert 2 keys in many objects - karate

response =
[
{
id: "1",
modelId: "301",
modelName: "x",
trimId: "301",
trimName: "up!",
derivativeName: "xx",
fuelType: "PETROL",
tco: {
price: {
tco: null,
retail: 12,
offer: null,
subsidy: null,
residual: null
},
milesPerYear: 10000,
mpg: 51.5,
fuelCost: 1.1,
milesPerKW: 0,
monthsOfOwnership: 48,
energyCost: 12,
tax: 42,
comparable: false
}
},
{
id: "1239",
modelId: "301",
modelName: "up!",
trimId: "301",
trimName: "x",
derivativeName: "xx",
fuelType: "PETROL",
tco: {
price: {
tco: null,
retail: 1,
offer: null,
subsidy: null,
residual: null
},
milesPerYear: 10000,
mpg: 53.2,
fuelCost: 1.1,
milesPerKW: 0,
monthsOfOwnership: 48,
energyCost: 12,
tax: 4,
comparable: false
}
}
]
Been trying to work this out but can't figure out the best way to do it.
I'm trying to check when the key fuelType = PETROL then key fuelCost must equal 1.1
There are many objects within the response and I want to assert the 2 keys (fuelType and Fuelcost) in every object.
I tried the following:
Given path 'url'
When method GET
Then match each response[*] contains {[*].fuelType:PETROL , [*].tco.fuelCost:1.1}
Please help
thanks

Try this, adapt if needed:
* def isValid = function(x){ return if x.fuelType == 'PETROL' && x.fuelCost == 1.1 }
* match each response == '#? isValid(_)'

Related

Nest JS - Serialization not work with nested object

I want to append a new field called logo_img_url after data manipulation. It works with the object but the nested array object seems not to work. Any recommendations or solution
import { Expose } from 'class-transformer';
import {} from 'class-validator';
import { Entity, Column } from 'typeorm';
import { BaseEntity } from '#common/base/entity.base';
import { getAdminImageUrl } from '#common/util/vault-file.util';
#Entity()
export class Agency extends BaseEntity {
#Expose()
#Column({
type: 'varchar',
length: '255',
nullable: true,
})
public logo_key!: string;
#Expose({ name: 'logoImgUrl' })
logo_img_url = this.logoImgUrl;
#Expose()
get logoImgUrl(): any {
return "http://localhost:30001/". this.logo_key;
}
}
Actaul response:
{
"data": [
{
"logo_img_url": "",
"id": 22,
"logo_url": "9597e74d-aaea-4502-b5cd-b2867504fd80",
},
{
"logo_img_url": "",
"id": 21,
"logo_url": "0a655497-1318-4276-a21f-cfdc259241a2",
},
],
"meta": {
"status_code": 200,
"pagination": {
"totalPages": 1,
"currentPage": 1,
"nextPage": null,
"paginationToken": null,
"previousPage": null,
"totalItems": 9,
"itemsPerPage": 10
}
}
}
Expected result:
{
"data": [
{
"logo_img_url": "http://localhost:3000/9597e74d-aaea-4502-b5cd-b2867504fd80",
"id": 22,
"logo_url": "9597e74d-aaea-4502-b5cd-b2867504fd80",
},
{
"logo_img_url": "http://localhost:3000/0a655497-1318-4276-a21f-cfdc259241a2",
"id": 21,
"logo_url": "0a655497-1318-4276-a21f-cfdc259241a2",
},
],
"meta": {
"status_code": 200,
"pagination": {
"totalPages": 1,
"currentPage": 1,
"nextPage": null,
"paginationToken": null,
"previousPage": null,
"totalItems": 9,
"itemsPerPage": 10
}
}
}
You can use #AfterLoad decorator from typeorm. Its calls the decorated method once the entity is loaded and then one can perform the required manipulations.
logo_img_url:string
#AfterLoad()
async transform(){
this.logo_img_url=`http://localhost:30001/${this.logo_key}`
}

Apex Line Area chart is not getting displayed on the page in Vuejs

I am stuck on a page where i am not able to display the charts on the page.
To make it simplify what I have done is, here is the code sandbox:
I see there an error in console about the data, I am not sure about it.
https://codesandbox.io/s/compassionate-snyder-bckoq
I want to display the chart like this (as an example), but I am not able to display on the code sandbox
Please help.
The format of series is not aligned with ApexCharts.
You need to transform the data to match with ApexChart format.
Please see the changes in the codesandbox.
https://codesandbox.io/s/small-dew-eztod?file=/src/components/HelloWorld.vue
options: {
// X axis labels
xaxis: {
type: 'date',
categories: ["2021-05-04", "2021-05-05", "2021-05-07"]
},
},
series: [
{
name: "total",
data: [2, 2, 1],
},
{
name: "pending",
data: [0, 1, 0],
},
{
name: "approved",
data: [2, 1, 1],
},
{
name: "rejected",
data: [0, 0, 0],
},
],
Transform data to fit ApexChart
const data = {
"2021-05-04": {
total: 2,
pending: 0,
approved: 2,
rejected: 0,
},
"2021-05-05": {
total: 2,
pending: 1,
approved: 1,
rejected: 0,
},
"2021-05-07": {
total: 1,
pending: 0,
approved: 1,
rejected: 0,
},
};
const xaxis = {
type: "date",
categories: Object.keys(data).map((key) => key), // ['2021-05-04', '2021-05-05', '2021-05-07']
};
let statusObj = [];
for (const dataValue of Object.values(data)) { // get the values from keys '2021-05-04', '2021-05-05' ...
// loop the values, e.g. 1st loop: { total: 2, pending: 0, approved: 2, rejected: 0, }
for (const [key, value] of Object.entries(dataValue)) {
// take 'total' as example, find if statusObj already has { name: 'total', data: [x] }, e.g. statusObj = { name: 'total', data: [1] }
const existingStatusIndex = Object.keys(statusObj).find(
(sKey) => statusObj[sKey].name === key
);
// if yes, return the index of it
if (existingStatusIndex) {
// add new data value to existing data object. e.g. { name: 'total', data: [1, 2] }
statusObj[existingStatusIndex].data.push(value);
continue;
}
// if no, create a new object and add it to statusObj
statusObj.push({
name: key,
data: [value],
});
}
}
Output:
xaxis {
type: 'date',
categories: [ '2021-05-04', '2021-05-05', '2021-05-07' ]
}
statusObj [
{ name: 'total', data: [ 2, 2, 1 ] },
{ name: 'pending', data: [ 0, 1, 0 ] },
{ name: 'approved', data: [ 2, 1, 1 ] },
{ name: 'rejected', data: [ 0, 0, 0 ] }
]

mongodb query need improvements

for a given parameter, I am querying most recent record from collection like this:
query = {'id': parameter}
doc = collection.find_one(query, sort=[('updated_at',-1)])
How can I get most recent record for all 'id' present in collection in one query? For now, I am iterating over parameter and concatenating the output
INPUT: Collection has multiple record/documents like:
{
id: "ABC",
weight: 35,
updated_at: "2013-10-01T1:32:12.112Z"
},
{
id: "ABC",
weight: 45,
updated_at: "2017-10-01T1:32:12.112Z"
},
{
id: "BAD",
weight: 38,
updated_at: "2013-10-11T1:32:12.112Z"
}
Output:
{
{
id: "ABC",
weight: 45,
updated_at: "2017-10-01T1:32:12.112Z"
},
{
id: "BAD",
weight: 38,
updated_at: "2013-10-11T1:32:12.112Z"
}
}
Solution: If I construct pipeline as shown below. what would be the implication of weight using $first
[
{ "$sort": { "id": 1, "updated_at": -1 } },
{ "$group": {
"_id": "$id",
"updated_at": { "$first": "$updated_at" },
"weight": { "$first": "$weight" }
}
]
You should go for Aggregation if you want to do it in single query.
Try the following query:
db.collection.aggregate(
[
{
$group:
{
_id: "$id",
maxWeight: { $max: "$weight" }
recent: { $max: "$updated_at" }
}
}
]
)
Here you group by 'id' or 'parameter' field.

lo-dash : JSON parsing and returning required output

I am new to lodash and have below queries. i have attach a sample json of mine. I referred many other post but nothing worked for me
i want to find array with state as true and return below values
name only
name and partno
i also want to just return state and name
[{
'state': true,
'partno': 21,
'idno': 1,
'name': 'abc'
},
{
'state': true,
'partno': 22,
'idno': 2,
'name': 'xyz'
},
{
'state': false,
'partno': 23,
'idno': 3,
'name': 'mnd'
},
{
'state': true,
'partno': 26,
'idno': 4,
'name': 'koi'
},
{
'state': false,
'partno': 21,
'idno': 1,
'name': 'abc'
}
]
The below code does what you need
const data = getData();
console.log('I want to...\n\n');
console.log('1. find array with state as true and return name only')
const result1 = _(data)
.filter('state')
.map('name')
.value();
// logAsJson is a helper function below
logAsJson(result1);
console.log('2. find array with state as true and return name and partno');
const result2 = _(data)
.filter('state')
// pickProperties is a helper function below
.map(pickProperties(['name', 'partno']))
.value();
logAsJson(result2);
console.log('3. just return state and name');
const result3 = _.map(data, pickProperties(['state', 'name']));
logAsJson(result3);
//
// Helper functions
//
function logAsJson(anObject) {
console.log(JSON.stringify(anObject, null, 2));
}
function pickProperties(propsToPick) {
return function mapperFn(anObject) {
return _.pick(anObject, propsToPick);
};
}
function getData() {
return [
{
'state': true,
'partno': 21,
'idno': 1,
'name': 'abc'
},
{
'state': true,
'partno': 22,
'idno': 2,
'name': 'xyz'
},
{
'state': false,
'partno': 23,
'idno': 3,
'name': 'mnd'
},
{
'state': true,
'partno': 26,
'idno': 4,
'name': 'koi'
},
{
'state': false,
'partno': 21,
'idno': 1,
'name': 'abc'
}
];
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
Maybe I didn't get your question, but here is what you requested:
//Filters your array and creates a new object
yourArray.filter(x => x.state)
.map( x => ({'name':x.name, 'partno':x.partno}))
I didn't know lodash, but taking a look at the documentation, I came with this:
_map(_.filter(yourArray, 'state'), (x) => ({'name':x.name,'partno':x.partno})
Which is pretty much the same. Is there a reason why are you using lodash for this?

lodash casting, mapping and picking

I have an array of objects that I am simplifying as this:
var expenses = [
{
arm: "0",
cat_id: "1",
crop: {
crop: "corn",
id: 1
},
crop_id: "1",
dist: "164.97",
expense: "Fertilizer",
id: "1",
loan_id: "1"
},
{
arm: "20",
cat_id: "8",
crop: {
crop: "corn",
id: 1
},
crop_id: "1",
dist: "0",
expense: "Labor",
id: "8",
loan_id: "1"
}
];
I am trying to end up with this:
var expenses = [{
arm: 0,
cat_id: 1,
crop: "corn",
crop_id: 1,
dist: 164.97,
expense: "Fertilizer",
id: 1,
loan_id: 1
},{
arm: 20,
cat_id: 6,
crop: "corn",
crop_id: 1,
dist: 0,
expense: "Labor",
id: 1,
loan_id: 1
}];
I can get certain pieces in that direction but can't pull it all together without error. I can't find out how to cast the values to float or put crop INSIDE of stub because casted returns all nulls. I currently have this:
flattened = _.map(expenses, function(item){
var crop = item.crop.crop;
var stub = _.pick(item, [
'id',
'loan_id',
'cat_id',
'expense',
'crop_id',
'arm',
'dist'
]);
var casted = _.map(stub, function(i){
i.crop = crop;
return i;
});
return stub;
});
Any help is appreciated.
Problem 1: I can't find out how to cast the values to float
This should be easily fixed by using parseFloat.
e.g.
item.dist = parseFloat(item.dist);
Problem 2: put crop INSIDE of stub because casted returns all nulls
Since you're already using lodash, might as well get used to their chaining feature (lazy evaluation).
DEMO
var flattened = _.map(expenses, function(item) {
item.dist = parseFloat(item.dist);
return _(item)
.omit('crop')
.assign(_.omit(item.crop, 'id'))
.value();
});
The solution above maps the entire expenses array, converting item.dist to a floating point value and then flattening the values from the item.crop object towards the item object with the exception of the item.crop.id value.
Note: In regards to your solution above, using _.map in an object
results to an array.
My attempt for my own learning purposes based on #ryeballar code.
var flattened = _.map(expenses, function(item) {
return _(item)
.set('crop', item.crop.crop) // set item.crop
.set('dist', parseFloat(item.dist)) // set dist as (float)item.dist
.value();
});