Mocha and Chai: JSON contains/includes certain text - mocha.js

Using Mocha and Chai, I am trying to check whether JSON array contains a specific text. I tried multiple things suggested on this site but none worked.
await validatePropertyIncludes(JSON.parse(response.body), 'scriptPrivacy');
async validatePropertyIncludes(item, propertyValue) {
expect(item).to.contain(propertyValue);
}
Error that I getting:
AssertionError: expected [ Array(9) ] to include 'scriptPrivacy'
My response from API:
[
{
"scriptPrivacy": {
"settings": "settings=\"foobar\";",
"id": "foobar-notice-script",
"src": "https://foobar.com/foobar-privacy-notice-scripts.js",
}

You can check if the field is undefined.
If field exists in the JSON object, then won't be undefined, otherwise yes.
Using filter() expresion you can get how many documents don't get undefined.
var filter = object.filter(item => item.scriptPrivacy != undefined).length
If attribute exists into JSON file, then, variable filter should be > 0.
var filter = object.filter(item => item.scriptPrivacy != undefined).length
//Comparsion you want: equal(1) , above(0) ...
expect(filter).to.equal(1)
Edit:
To use this method from a method where you pass attribute name by parameter you can use item[propertyName] because properties into objects in node can be accessed as an array.
So the code could be:
//Call function
validatePropertyIncludes(object, 'scriptPrivacy')
function validatePropertyIncludes(object, propertyValue){
var filter = object.filter(item => item[propertyValue] != undefined).length
//Comparsion you want: equal(1) , above(0) ...
expect(filter).to.equal(1)
}

Related

How do you get the property value from a FHIR property using FhirClient

I am using the following code to call the NHS Retrieve Reference Data method
var result = await fhirClient.ReadAsync<CodeSystem>(url);
which returns the following Json (this is a snippet of the full json)
concept": [
{
"code": "BOOKED_CLINICAL_NEED",
"display": "Booked more urgently due to clinical need",
"property": [
{
"code": "effectiveFrom",
"valueDateTime": "2019-07-23T17:09:56.000Z"
},
{
"code": "commentIsMandatory",
"valueBoolean": true
},
{
"code": "canCancelAppointment",
"valueBoolean": false
}
]
}
I have used the GetExtensionValue method for other calls when the data is within an extension but I can't find a similar method for properties.
Is there a simple method or do I need to just cast into the required type manually?
Thanks in advance
There is no convenience method for this. However, the properties per concept are a list, so you could for example iterate over the concepts and select the properties with boolean values using regular list methods:
foreach (var c in myCodeSystem.Concept)
{
var booleanProperties = c.Property.Where(p => (p.Value.TypeName == "boolean"));
// do something with these properties
}
or find all concepts that have a boolean property:
var conceptsWithDateTimeProperties = myCodeSystem.Concept.Where(c => c.Property.Exists(p => (p.Value.TypeName == "dateTime")));
Of course you can make your selections as specific as you need.

How to add a json in a nested array of a mongodb document using Spring?

Document stored in mongodb:
{
"CNF_SERVICE_ID":"1",
"SERVICE_CATEGORY":"COMMON_SERVICE",
"SERVICES":[{
"SERVICE_NAME":"Authentication Service",
"VERSIONS":[{
"VERSION_NAME":"AuthenticationServiceV6_3",
"VERSION_NUMBER":"2",
"VERSION_NOTES":"test",
"RELEASE_DATE":"21-02-2020",
"OBSOLETE_DATE":"21-02-2020",
"STATUS":"Y",
"GROUPS":[{
"GROUP_NAME":"TEST GROUP",
"CREATED_DATE":"",
"NODE_NAMES":[
""
],
"CUSTOMERS":[{
"CUSTOMER_CONFIG_ID":"4",
"ACTIVATION_DATE":"21-02-2020",
"DEACTIVATION_DATE":"21-02-2020",
"STATUS":"Y"
}]
}]
}]
}
]
}
Now, I need to add another customer json to the array "CUSTOMERS" inside "GROUPS" in the same document above. The customer json would be like this:
{
"CUSTOMER_CONFIG_ID":"10",
"ACTIVATION_DATE":"16-03-2020",
"DEACTIVATION_DATE":"16-03-2021",
"STATUS":"Y"
}
I tried this:
Update update = new Update().push("SERVICES.$.VERSIONS.GROUPS.CUSTOMERS",customerdto);
mongoOperations.update(query, update, Myclass.class, "mycollection");
But, I am getting the exception: org.springframework.data.mongodb.UncategorizedMongoDbException: Command failed with error 28 (PathNotViable): 'Cannot create field 'GROUPS' in element
[ EDIT ADD ]
I was able to update it using the filtered positional operator. Below is the query I used:
update(
{ "SERVICE_CATEGORY":"COMMON_SERVICE", "SERVICES.SERVICE_NAME":"Authentication Service", "SERVICES.VERSIONS.VERSION_NAME":"AuthenticationServiceV6_3"},
{ $push:{"SERVICES.$[].VERSIONS.$[].GROUPS.$[].CUSTOMERS": { "CUSTOMER_CONFIG_ID":"6", "ACTIVATION_DATE":"31-03-2020", "STATUS":"Y" } } }
);
Actually, this query updated all the fields irrespective of the filter conditions. So. I tried this but I am facing syntax exception. Please help.
update(
{"SERVICE_CATEGORY":"COMMON_SERVICE"},
{"SERVICES.SERVICE_NAME":"Authentication Service"},
{"SERVICES.VERSIONS.VERSION_NAME":"AuthenticationServiceV6_3"}
{
$push:{"SERVICES.$[service].VERSIONS.$[version].GROUPS.$[group].CUSTOMERS":{
"CUSTOMER_CONFIG_ID":"6",
"ACTIVATION_DATE":"31-03-2020",
"STATUS":"Y"
}
}
},
{
multi: true,
arrayFilters: [ { $and:[{ "version.VERSION_NAME": "AuthenticationServiceV6_3"},{"service.SERVICE_NAME":"Authentication Service"},{"group.GROUP_NAME":"TEST GROUP"}]} ]
}
);
Update: April 1,2020
The code I tried:
validationquery.addCriteria(Criteria.where("SERVICE_CATEGORY").is(servicedto.getService_category()).and("SERVICES.SERVICE_NAME").is(servicedetail.getService_name()).and("SERVICES.VERSIONS.VERSION_NAME").is(version.getVersion_name()));
Update update=new Update().push("SERVICES.$[s].VERSIONS.$[v].GROUPS.$[].CUSTOMERS", customer).filterArray(Criteria.where("SERVICE_CATEGORY").is(servicedto.getService_category()).and("s.SERVICE_NAME").is(servicedetail.getService_name()).and("v.VERSION_NAME").is(version.getVersion_name()));
mongoOperations.updateMulti(validationquery, update, ServiceRegistrationDTO.class, collection, key,env);
The below exception is thrown:
ERROR com.sample.amt.mongoTemplate.MongoOperations - Exception in count(query, collectionName,key,env) :: org.springframework.dao.DataIntegrityViolationException: Error parsing array filter :: caused by :: Expected a single top-level field name, found 'SERVICE_CATEGORY' and 's'; nested exception is com.mongodb.MongoWriteException: Error parsing array filter :: caused by :: Expected a single top-level field name, found 'SERVICE_CATEGORY' and 's'
This update query adds the JSON to the nested array, "SERVICES.VERSIONS.GROUPS.CUSTOMERS", based upon the specified filter conditions. Note that your filter conditions direct the update operation to the specific array (of the nested arrays).
// JSON document to be added to the CUSTOMERS array
new_cust = {
"CUSTOMER_CONFIG_ID": "6",
"ACTIVATION_DATE": "31-03-2020",
"STATUS": "Y"
}
db.collection.update(
{
"SERVICE_CATEGORY": "COMMON_SERVICE",
"SERVICES.SERVICE_NAME": "Authentication Service",
"SERVICES.VERSIONS.VERSION_NAME": "AuthenticationServiceV6_3"
},
{
$push: { "SERVICES.$[s].VERSIONS.$[v].GROUPS.$[g].CUSTOMERS": new_cust }
},
{
multi: true,
arrayFilters: [
{ "s.SERVICE_NAME": "Authentication Service" },
{ "v.VERSION_NAME": "AuthenticationServiceV6_3" },
{ "g.GROUP_NAME": "TEST GROUP" }
]
}
);
Few things to note when updating documents with nested arrays of more than one level nesting.
Use the all positional operator $[] and the filtered positional
operator $[<identifier>], and not the $ positional operator.
With filtered positional operator specify the array filter conditions
using the arrayFilters parameter. Note that this will direct your update to target the specific nested array.
For the filtered positional operator $[<identifier>], the
identifier must begin with a lowercase letter and contain only
alphanumeric characters.
References:
Array Update
Operators
db.collection.update() with arrayFilters
Thanks to #prasad_ for providing the query. I was able to eventually convert the query successfully to code with Spring data MongoTemplate's updateMulti method. I have posted the code below:
Query validationquery = new Query();
validationquery.addCriteria(Criteria.where("SERVICE_CATEGORY").is(servicedto.getService_category()).and("SERVICES.SERVICE_NAME").is(servicedetail.getService_name()).and("SERVICES.VERSIONS.VERSION_NAME").is(version.getVersion_name()));
Update update=new Update().push("SERVICES.$[s].VERSIONS.$[v].GROUPS.$[].CUSTOMERS", customer).filterArray(Criteria.where("s.SERVICE_NAME").is(servicedetail.getService_name())).filterArray(Criteria.where("v.VERSION_NAME").is(version.getVersion_name()));
mongoOperations.updateMulti(validationquery, update, ServiceRegistrationDTO.class, collection, key,env);
mongoTemplateobj.updateMulti(validationquery, update, ServiceRegistrationDTO.class, collection, key,env);

How do I add an OR condition in a graphql where statement?

I cannot get a WHERE statement working with an 'OR' condition in Strapi via graphql playground.
I would like to return all results where either the 'title' OR 'content' fields contain the search_text.
I have tried the following:
articles(where: {
or: [
{"title_contains" : "search_text"},
{"content_contains" : "search_text"}
]
}) {
title
content
}
but an error is returned.
ERROR: "Your filters contain a field 'or' that doesnt appear on your model definition nor it's relations.
Some statements that work (but not what I am after):
where: { "title_contains" : "sometext" }
working, but behaves as an 'AND'
where: {
"title_contains" : "search_text",
"content_contains" : "search_text"
}
As of July it's possible to do it like this
(where: { _or: [{ someField: "1" }, { someField2: "2" }] })
The workaround here is to create a custom Query and make a custom database query that matches your need.
Here is how to create a custom GraphQL query:
https://strapi.io/documentation/3.0.0-beta.x/guides/graphql.html#example-2
To access the data model, you will have to use strapi.models.article (For an Article model) and inside this variable, you will access to native Mongoose or Bookshelf function. So you will be able to query with an OR

apollo watch method with variables

I am trying to use apollo client watch method in angular to query spring boot server. I am not able to pass arguments with this method.
Since "aid" is mandatory, when it is trying to make a call I getting error like
ERROR Error: GraphQL error: Variable 'aid' has coerced Null value for NonNull type 'String!'
Below is my code in typescript.
export class AgreementGQL extends Query {
document = gql`query agreement($aid: String!) {
agreement(id: $aid) {
id
name
}
}
Below is calling code to the agreement. Where agreement is injected in constructor.
this.agreement.watch({
aid: "1234567"
}).valueChanges.subscribe(result => {
console.log("*********** result : " + JSON.stringify(result.data));
});
I tried using "variables" as well, but no luck.
this.agreement.watch({ variables:{
aid: "1234567"
}}).valueChanges.subscribe(result => {
console.log("*********** result : " + JSON.stringify(result.data));
});
You just need to set the value as a key/value pair like:
const myVal = '123';
Then pass that as an object into the watch method...
const agreement = this.agreementQuery
.watch({ myVal })
.valueChanges.pipe(pluck('data'));
Then Subscribe to get the data out:
agreement.subscribe(data => console.log(data));
This approach worked for me.

How can I set polymer property attribute value and passing attribute value into another polymer component property?

I have below piece of code which I am using to call http request using iron ajax with polymer so passing the value of body and last-response using polymer properties.as we can see here we have requestBody polymer property in this we are returning no of values in requestBody all values are hardcoded like start and end and name under tag.
<px-vis-timeseries
width="1000"
height="250"
margin='{"top":30,"bottom":60,"left":65,"right":65}'
register-config='{"type":"vertical","width":200}'
selection-type="xy"
chart-data="{{ltuchartData}}"
series-config="[[LTUseriesConfig]]"
chart-extents='{"x":["dynamic",1619712],"y":[0,100]}'
event-data='[{"id":"333","time":15697128,"label":"test"}]'
x-axis-config='{"title":"Time"}'
y-axis-config='{"axis1":
{"title":"Remaining","titleTruncation":false,"unit":"%"}}'>
</px-vis-timeseries>
<iron-ajax
id="Request"
method="POST"
content-type="application/json"
auto
url="/api/series/v1/points"
last-response="{{Data123}}"
body="{{requestBody}}">
</iron-ajax>
Polymer({
is: 'test-view',
behaviors: [GlobalsBehaviour],
properties: {
uri: {
type: String,
observer: '_uriChanged'
},
requestBody:{
type: Object,
value: function() {
return {
"start": 11111,
"end": 123333,
"tags": [
{
"name" : "/asset/India/rotor",
}
]
};
}
},
Data123:{
type: Object,
observer: '_formateData'
},
observers: [
'_uriChanged(globals.uri)'
],
_uriChanged: function(uri) {
this.set('requestBody.tags.0.name', uri);
this.$.Request.generateRequest();
}
Now Below are the queries with respect to above code .
I want to set end attribute value (which is defined in requestBody property value )dynamically based on the uri for that I tried like : this.set('requestBody.end', "1113444"); in _uriChanged, But it didn't work.
I want to pass this end attribute value dynamically in above px-vis-timeseries polymer component's property that is:
chart-extents='{"x":["dynamic",1619712],"y":[0,100]}'
event-data='[{"id":"333","time":15697128,"label":"test"}]'
in above properties I want to pass end attribute value like :
in chart-extents at the place of "1619712" I want to pass "end" + 2*50000
in event-data at the place of "15697128" I want to pass "end" + 50000
for that also i tried like this chart-extents = '{"x":["dynamic" , {{requestBody.end}}] , ,"y":[0,100]}'
now I have set end attribute value in requestBody computed function that is (_getRequestBody) based on my requirement .Now my problem is I want to get this end attribute value in my another computed functio(n of _chartExtents that is (_getChartExtents) I want pass this end attirbute value (which we will get from request body ) to xDynamic (which is the attribute of chartExtents)
As I wanted to pass uri value in name attribute which is defined in requestBody property for that I am setting like
this.set('requestBody.tags.0.name', uri); in _urichanged callback which is working fine now my problem is while defining or declaring polymer property named as requestBody i dont want to pass any hardcoded value in name attribute for that i tried "name": "" and "name" : this.uri,and "name" : uri ,but not able to get value.
Note: uri is coming from another polymer component and in some case its coming from global set variable.
How can I declare name attribute value without passing any hardcoded value?
I want to set end attribute value (which is defined in requestBody property value )dynamically ...
Not a satisfactory answer, but it should work as Polymer does dirty checking. Polymer have sometimes trouble updating properties, but not in this case, so try to override dirty checking by nullifying the element first.
_uriChanged: function(uri) {
if (this.requestBody.start) {
var clonedObj = JSON.parse(JSON.stringify(this.requestBody);
clonedObj.tags.0.name = uri;
this.set('requestBody', {});
this.set('requestBody', clonedObj);
this.$.Request.generateRequest();
}
Again, this shouldn't be needed. I would most of all make requestBody a computed value instead of setting specific values,
properties: {
requestBody:{
type: Object,
computed: '_getRequestBody(uri)'
},
// Other properties, like uri
}
// Other javascript methods
_getRequestBody: function(uri) {
var defaultURI = 123333; // I would make this a property or add a default value to 'uri'
uri = (uri) ? uri : defaultURI;
return {
"start": 11111,
"end": uri, // Here's the change
"tags": [
{
"name" : "/asset/India/rotor",
}
]
};
},
Note that computed will run no matter if the properties (uri, in this case) are defined or not. Sometimes, the order of the properties are important when using event handlers (observers) so place those last in properties.
i want to pass this end attribute value dynamically...
chart-extents='{"x":["dynamic",1619712],"y":[0,100]}'
You shouldn't pass variables like that but instead use something like chart-extents='[[myObject]]'; However, for this specific solution one of the keys depends on another variable (the object requestBody in this case).
chart-extents="[[_getChartExtents(requestBody.end)]]"
---
// Other javascript methods
_getChartExtents: function(xDynamics) {
return {"x":["dynamic",xDynamics],"y":[0,100]};
},
The _ before the method name is just a programming habit of mine, so I can see that the methods and properties aren't used by other elements.
as i wanted to pass uri value in name attribute which is defined in requestBody property for that i am setting like this.set('requestBody.tags.0.name', uri);
Just extend answer 1.
_getRequestBody: function(uri) {
var defaultURI = 123333; // I would make this a property or add a default value to 'uri'
uri = (uri) ? uri : defaultURI;
return {
"start": 11111,
"end": uri,
"tags": [
{
"name" : uri, // Here's the change
}
]
};
},

Resources