Check for 'http://' text in json object with Chai.js Should - node.js

I've got some nested objects inside each object and I want to check with chai that the images's hrefs start with 'http://'
{
"images": [
{
"header": {
"href": "http://somedomain.com/assets/header.jpg"
}
},
{
"logo": {
"href": "http://somedomain.com/assets/logo.jpg"
}
}
]
}
The problem is, I can't just key off of the image name property because it changes...so I can't do this:
images[0].[image name changes!! it's not a concrete property name].href.should.have.deep.property("href");
because imagename is like 'header', 'logo', and so on
so how would I be able to do this with chai and check the href for each image to make sure it's got the text 'http://'?

You could dynamically iterate through all objects in the images array as #gfpacheco suggested in his answer.
But I would research a way to create a deterministic test. This would simplify your assertions, but might require some creativity or refactoring to mock or render fixtures

I tried to write the entire Chai assertion function. It uses the Chai Things plugin to work with assertions over arrays:
var data = {...};
function startsWithHttp(string) {
return string.indexOf('http://') === 0;
}
data.images.should.all.satisfy(function(image) {
Object.keys(image).should.contain.an.item.that.satisfy(function(key) {
image[key].should.have.all.keys('href');
image[key].href.should.satisfy(startsWithHttp);
});
});
It assumes that all images should have at least one property that it's value must have an href property and it's value starts with http://.

As I said #dm03514, it's hard to find a deterministic method. I get the sub string of href and would verify if is equals (and iterate how #gfpacheco did do). I tried let the same environment for their:
var http = "http://";
if(header.href.substr(0,7) === http)
alert("Header ok");
else
alert("Header no ok")
https://jsfiddle.net/lbclucascosta/zhrfLa8m/2/
Obs: This is pure javascript, but you can get the substring in node too. nodejs: string manipulation

Related

How to add TypeScript Interface to shorthand variable?

How to set TypeScript interface to variable looking like this:
const { body, statusCode } = await got.post('smth', requestOpts)
How can I set the interface to ex. body. I would like to assign there an interface with potential requests from the server. An interface that I'm willing to implement looks like that:
interface ResponseBody {
data: [{ username: string }]
}
I tried different things to attach this interface to the upper variable body but I'm getting build errors. The only workaround that I have here is to do not use shorthand variable but that's not my goal - I wonder if there are solutions for such issue.
TypeScript Playground
You'd need to annotate the whole object, like this:
const { body, statusCode }: { body: ResponseBody, statusCode: number } =
await got.post<ResponseBody>('users', requestOpts)
While it would be nice if you could annotate the individual destructured variables inside the object, this is not currently possible. The syntax const { body: ResponseBody } = ... can't work because JavaScript interprets this as assigning to a new variable name (so there'd be a variable named ResponseBody holding the value that was in the body property). Perhaps something like const { body::ResponseBody, statusCode::number } would work instead, as requested in microsoft/TypeScript#29526. But for now this is not possible, and you have to annotate the whole object.
That's the answer to the question as asked.
Do note that for your particular example, though, the got.post() method has a call signature that's generic in the type you expect the body property to be. So you can write
const { body, statusCode } = await got.post<ResponseBody>('users', requestOpts);
to get a strongly typed body variable with a minimum of extra keystrokes.
Playground link to code

How to build a Graqhql mutation with existing variables

This might seem like an odd question, or something really straightforward, but honestly I am struggling to figure out how to do this. I am working in Node.js and I want to set data I have saved on a node object into my GraphQL mutation.
I'm working with a vendor's GraqhQL API, so this isn't something I have created myself, nor do I have a schema file for it. I'm building a mutation that will insert a record into their application, and I can write out everything manually and use a tool like Postman to manually create a new record...the structure of the mutation is not my problem.
What I'm struggling to figure out is how to build the mutation with variables from my node object without just catting a bunch of strings together.
For example, this is what I'm trying to avoid:
class MyClass {
constructor() {
this.username = "my_username"
this.title = "Some Title"
}
}
const obj = new MyClass()
let query = "mutation {
createEntry( input: {
author: { username: \"" + obj.username + "\" }
title: \"" + obj.title + "\"
})
}"
I've noticed that there are a number of different node packages out there for working with Graphql, but none of their documentation that I've seen really addresses the above situation. I've been completely unsuccessful in my Googling attempts, can someone please point me in the right direction? Is there a package out there that's useful for just building queries without requiring a schema or trying to send them at the same time?
GraphQL services typically implement this spec when using HTTP as a transport. That means you can construct a POST request with four parameters:
query - A Document containing GraphQL Operations and Fragments to execute.
operationName - (Optional): The name of the Operation in the Document to execute.
variables - (Optional): Values for any Variables defined by the Operation.
extensions - (Optional): This entry is reserved for implementors to extend the protocol however they see fit.
You can use a Node-friendly version of fetch like cross-fetch, axios, request or any other library of your choice to make the actual HTTP request.
If you have dynamic values you want to substitute inside the query, you should utilize variables to do so. Variables are defined as part of your operation definition at the top of the document:
const query = `
mutation ($input: SomeInputObjectType!) {
createEntry(input: $input) {
# whatever other fields assuming the createEntry
# returns an object and not a scalar
}
}
`
Note that the type you use will depend on the type specified by the input argument -- replace SomeInputObjectType with the appropriate type name. If the vendor did not provide adequate documentation for their service, you should at least have access to a GraphiQL or GraphQL Playground instance where you can look up the argument's type. Otherwise, you can use any generic GraphQL client like Altair and view the schema that way.
Once you've constructed your query, make the request like this:
const variables = {
input: {
title: obj.title,
...
}
}
const response = await fetch(YOUR_GRAPHQL_ENDPOINT, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ query, variables }),
})
const { data, errors } = await response.json()

How to get entity from the argument and create if condition in Dialogflow Inline editor for fulfilment

I am completely new to Dialogflow and nodejs. I need to get the entity value from the argument to the function (agent) and apply if the condition on that. How can I achieve this?
I am trying below but every time I get else condition become true.
I have created an entity named about_member.
function about_member_handeller(agent)
{
if(agent.about_member=="Tarun")
{
agent.add('Yes Tarun');
}
else
{
agent.add("No tarun");
}
}
Please help.
In such cases, you may use console.log to help unleash your black box, like below:
function about_member_handeller(agent) {
console.log(JSON.stringify(agent, null, 2));
if(agent.about_member=="Tarun") {
agent.add('Yes Tarun');
}
else {
agent.add("No tarun");
}
}
JSON.stringfy() will serialize your json object into string and console.log will print the same on the stdOut. So once you run your code this will print the object structure for agent and after which you will know on how to access about_member. Because in the above code it's obvious that you are expecting about_member to be a string, but this code will let you know on the actual data in it and how to compare it.
To get the parameter you can use the following;
const valueOfParam = agent.parameters["parameterName"];

Error: Argument "data" is not a valid Document. Input is not a plain JavaScript object

I am getting the error
Error: Argument "data" is not a valid Document. Input is not a plain
JavaScript object.
when updating a document, using firebase admin SDK. Here the Typescript code.
var myDoc = new MyDoc();
myDoc.Public.Name = "Jonh Doe" //setup up content
admin.firestore()
.collection('MyDocs')
.doc("Id1")
.set(myDoc);
I did something similar:
var myDoc = <MyDoc> {
Public: {
Name: "Jonh Doe"
}
}
It is semantically the same, I just think it is a bit cleaner.
In case some else bump into the same issue, the solution is to simple use Json to instantiate the object, like this:
var myDoc = {
Public: {
Name: "Jonh Doe"
}
} as MyDoc; //keep type to still get typescript compiler validations
I had same problem, in my case I'd forgot to add Content-Type:application/json to my header when sending request, and then the object was treated as string and I got that error.
You can recreate js object via; {...__data}
return refDB.set({...__data}).then((newData) => {
})

Botframework (Node) - dialogData stripping out regex

Does the BotBuilder Node SDK actively strip out anything that is stored the dialogData object?
For example, I have created a simple loop and I am storing a regex in session.dialogData.questions. When I console log this after storing it, I can see that my regex is stored as expected:
{
validation: /^[0-9]{19}$/,
}
However, when I try and log the same session.dialogData.questions object in the next step of my waterfall, then the regex seems to have been converted into an empty object:
{
validation: {}
}
I presume this a deliberate attempt to prevent XSS and other types of exploitation?
The code for this example can be found below:
const builder = require('botbuilder')
const lib = new builder.Library('FormBuilder')
lib.dialog('/', [
(session, args) => {
session.dialogData.questions = {
validation: /^[0-9]{19}$/
}
console.log(session.dialogData.questions)
builder.Prompts.confirm(session, 'Would you like to proceed?')
},
(session, results) => {
console.log(session.dialogData.questions)
}
])
module.exports.createLibrary = () => {
return lib.clone()
}
Regarding your initial question, no the SDK doesn't actively strip anything out of the dialogData object. Anything that is, except for regexp...
I'm not sure why this is, but for the time being I recommend storing your pattern as a string, '^[0-9]{19}$', and then constructing a new regexp via new RegExp(session.dialogData.questions.validation) when needed.
I tried storing a method to construct a new RegExp using this.questions.validation, but likewise this was also stripped out.
Edit:
Per Ezequiel's comment, this isn't a Bot Framework issue in the end. It is not possible to store non-serializable data inside JSON.

Resources