earliest_timestamp is below latest_timestamp in postman test - get

im trying to create test script for condition earlier_timestamp is below that latest_timestamp
var moment = require('moment');
pm.test("Condition - Earliest Timestamp is < 1 day", function() {
var latest_Timestamp = pm.response.json();
var earliest_Timestamp = pm.response.json();
pm.expect(pm.earliest_timestamp.get(earliest_timestamp)).to.be.below(pm.latest_timestamp.get(latest_timestamp));
});
Im getting response
TypeError: Cannot read property 'get' of undefined

Assuming the following response body:
{
"latest_timestamp":"2022-03-18 13:01:14.619542+00:00",
"earliest_timestamp":"2022-03-17 13:01:14.619542+00:00"
}
this will work:
var jsonData = pm.response.json();
var latest = Date.parse(jsonData.latest_timestamp);
var earliest = Date.parse(jsonData.earliest_timestamp);
pm.test("Condition - Earliest Timestamp is < 1 day", function() {
pm.expect(latest).to.be.above(earliest);
});
Depending on your actual response body, you would need to adapt lines 3 & 4 a little bit.

Related

Firebase Database Get All Value In Order Cloud Functions

I develop for Firebase Cloud Functions. I have a Firebase Realtime Database like this:
----- myData
-------eqewrwrepere (this one is a device token)
---------Lta+sde-fer (this one is a firebase id)
firstvalue : "a"
secondvalue : "b"
----------Qrgd+ad-qdda (this one is second firebase id)
firstvalue : "c"
secondvalue : "d"
-------eqwerSAsdqe (this one is another device token)
---------Lta+sde-fer (this one is a firebase id)
firstvalue : "x"
secondvalue : "y"
----------Qrgd+ad-qdda (this one is second firebase id)
firstvalue : "z"
secondvalue : "t"
I fetch these data by this code. With this code i fetch all data and put them an array. And when fetching done, i loop this array for finding items. I am an iOS developer, so i am a newbie for NodeJS. Here is what i want to do:
Get firstvalue for each database data.
Make a api request with firstvalue of each database data.
Api returns an image.
Write image temp directory.
Process this image for visionApi.
Extract text.
Update database.
Send notification for deviceToken
Now i am able to retrieve database items in my array. When i make a request in for loop, request called async. So for loop continues, but request response or writing file and vision processing executed only once.
In for loop, get databasearray[0], make request, write file, process it with vision api, update database and go for next databasearray[1] item.
I read about Promises on different pages. But i did not understand.
Thank you.
'use strict';
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
var request = require('request');
var fs = require('fs');
//var fs = require("fs");
// Get a reference to the Cloud Vision API component
const Vision = require('#google-cloud/vision');
const vision = new Vision.ImageAnnotatorClient();
// Imports the Google Cloud client library
//const {Storage} = require('#google-cloud/storage');
var fs = require("fs");
var os = require("os");
var databaseArray = [];
exports.hourly_job = functions.pubsub
.topic('hourly-job')
.onPublish((event) => {
console.log("Hourly Job");
var db = admin.database();
var ref = db.ref("myData")
ref.once("value").then(function(allData) {
allData.forEach(function(deviceToken) {
deviceToken.forEach(function(firebaseIDs) {
var deviceTokenVar = deviceToken.key;
var firebaseIDVar = firebaseIDs.key;
var firstvalue = firebaseIDs.child("firstvalue").val();
var secondvalue = firebaseIDs.child("secondvalue").val();
var items = [deviceTokenVar, firebaseIDVar, firstvalue, secondvalue];
databaseArray.push([...items]);
});
});
return databaseArray;
}).then(function(databasem) {
var i;
for (i = 0; i < databaseArray.length; i++) {
var databaseArrayDeviceToken = databaseArray[i][0];
console.log("DeviceToken: " + databaseArrayDeviceToken);
var databaseArrayFirebaseID = databaseArray[i][1];
console.log("FirebaseID: " + databaseArrayFirebaseID);
var databaseArrayfirstvalue = databaseArray[i][2];
console.log("firstval: " + databaseArrayfirstvalue);
var databaseArraysecondval = databaseArray[i][3];
console.log("Second: " + databaseArraysecondval);
var url = "http://api.blabla" + databaseArrayfirstvalue;
/////////////here make a request, pause loop, process returned image, but how //////////////////////
request.get({
url: url,
encoding: 'binary'
}, function(error, httpResponse, body) {
if (!error && httpResponse.statusCode == 200) {
fs.writeFileSync('/tmp/processed.jpg', body, 'binary')
console.log("file written");
})
}
});
return true;
});
I found solution with Mocas helps. Here is the solution. I use async/await functions in code. Now for loop waits for the function response. But now I have different problems. I think main async function hangs because of awaits. And then next hourly trigger, it runs again. So console log shows 15-16-17 or more ‘i’ values in for loop. I have 4 element in database array but console log shows more than this every hour. And it increases every time. So I guess that I should cancel this await functions after a timeout. But I don’t know how. Here is code:
use strict';
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
var request = require('request-promise').defaults({ encoding: null });
var fs = require('fs');
// Get a reference to the Cloud Vision API component
const Vision = require('#google-cloud/vision');
const vision = new Vision.ImageAnnotatorClient();
var os = require("os");
var databaseArray = [];
var uniqueFilename = require('unique-filename')
exports.hourly_job = functions.pubsub
.topic('hourly-job')
.onPublish((event) => {
console.log("Hourly Job");
var db = admin.database();
var ref = db.ref("myData")
ref.once("value").then(function(allData) {
allData.forEach(function(deviceToken) {
deviceToken.forEach(function(firebaseIDs) {
var deviceTokenVar = deviceToken.key;
var firebaseIDVar = firebaseIDs.key;
var firstvalue = firebaseIDs.child("firstvalue").val();
var secondvalue = firebaseIDs.child("secondvalue").val();
var items = [deviceTokenVar, firebaseIDVar, firstvalue, secondvalue];
databaseArray.push([...items]);
//console.log(databaseArray);
//return true;
});
//return true;
});
return databaseArray;
}).then(function (databasem) {
main().catch(console.error);
});
return true;
});
const main = async () => {
var i;
for (i = 0; i < databaseArray.length; i++) {
console.log("Database Arrays " + i + ". elements: ");
var databaseArrayDeviceToken = databaseArray[i][0];
console.log("DeviceToken: " + databaseArrayDeviceToken);
var databaseArrayFirebaseID = databaseArray[i][1];
console.log("FirebaseID: " + databaseArrayFirebaseID);
var databaseArrayfirst = databaseArray[i][2];
console.log("first: " + databaseArrayfirst);
var databaseArraysecond = databaseArray[i][3];
console.log("second: " + databaseArraysecond);
if (databaseArrayfirst != "") {
var apiUrl = "http://api.blabla;
try {
const apiBody = await request.get(apiUrl);
///////////////////////////vison start//////////////////////
const visionResponseBody = await vision.documentTextDetection(apiBody)
var visionResponse = visionResponseBody[0].textAnnotations[0].description;
console.log("Vision response text " + visionResponse );
...some logic here about response...
/////////////////////////////////////////////////
var getdatabasevar = await admin.database().ref("myData/" + databaseArrayDeviceToken + "/" + databaseArrayFirebaseID);
await getdatabasevar.update({
"firstvalue": visionResponse
});
/////////////////////////////////////////////////
var getanotgerdatabasevar = await admin.database().ref("myData/" + databaseArrayDeviceToken + "/" + databaseArrayFirebaseID + "/" + "secondvalue");
await getanotgerdatabasevar.once("value")
.then(function(var) {
..some logic..
//send notification
});
} catch (error) {
console.error(error);
}
///////////////////////////vison end//////////////////////
}
};
return true;
};

Create API in node js to get data with multiple queries with my sql

I am new to node js. I am trying to develop API for getting items list by its category list. For that i have create a function to fetch all available active featured tags from table ( featured_tags ). After that featured tag list fetch i want to get items list from ( items ) table which belongs to that particular tag. Can anyone help me how to so that in node js. I am using mysql database.
i have done below things to fetch categories from table.
route.js file
this.app.get('/list_menu',async(request,response) =>{
var itemlist = '';
const featuretags = helper.getFeatureTag().then(function(featuredtags){
//console.log('test');
itemlist = helper.getitems(featuredtags);
});
response.status(200).json({
status:200,
message: "success",
data:itemlist
});
});
function to get active featured tags in helper.js file
async getFeatureTag(){
return this.db.query("select * from featured_tags where status = 1 order by id desc ");
//const featuredtags = await this.db.query("select * from featured_tags where status = 1 order by id desc ");
}
Function which get items list of featured tags in helper.js file
async getitems(featuredtags){
var itemdata = [];
var featured_tagdataset = [];
if(featuredtags.length > 0){
for (var i = 0; i < featuredtags.length; i++) {
var row = featuredtags[i];
var featurtag = {};
featurtag.id = row.id;
featurtag.featured_tag = row.featured_tag;
var itemresult = await this.db.query("SELECT * FROM `items` WHERE status = 1 and FIND_IN_SET('"+ row.id +"' ,featured_tags) > 0");
if(itemresult.length > 0){
for(var l=0; l < itemresult.length; l++){
var itemrow = itemresult[l];
var item = {};
item.id = itemrow.id;
item.category_id = row.id;
item.name = itemrow.item_name;
itemdata.push(JSON.stringify(item));
}
}
featurtag.tag_items = itemdata;
featured_tagdataset.push(featurtag);
}
//console.log(featured_tagdataset);
return featured_tagdataset;
}else{
return null;
}
}
when i console featuredtag_dataset array in itemlist() in helper.js file it show me perfect response which i have to pass in API response. But in route.js it shows me blank in data parameter.
Can anyone help me for how to develop this type of APIs in node js.
This is because helper.getitems(featuredtags) method is called successfully but send response doesn't wait until method returns a response as node js is asynchronous .
you need to write the code in such a way that it should work in series. I have created sample example you can try this.
this.app.get('/list_menu',async(request,response) =>{
helper.getFeatureTag().then(function(featuredtags){
helper.getitems(featuredtags).then(function(itemlist){
response.status(200).json({
status:200,
message: "success",
data:itemlist
});
})
}
});
You forget to use await in your roter.js on calling asynchronous function, just update your router to this
this.app.get('/list_menu',async(request,response) =>{
const featuredtags = await helper.getFeatureTag(),
itemlist = await helper.getitems(featuredtags);
response.status(200).json({
status:200,
message: "success",
data:itemlist
});
});
you can either nested callback function or async await function or chained promises using then.

How to read and get events from zoho calendar using CalDav in node.js

I want to communicate from backend with the calendar using caldav of zoho mail using nodejs. Could anyone suggest me how to implement it?
I am using plugin node-caldav-mod
I tried this piece of code which doesn't seem to be working.
var caldav = require("node-caldav-mod");
var moment = require('moment-timezone');
var express = require('express');
var app = express();
var xmljs = require("libxmljs");
var https = require("https");
var CalendarId = "2123123123";
var url = "https://calendar.zoho.com/caldav/{CalendarId}/events";
var username = "username"
var password = "password"
var timeFormat = "YYYYMMDDTHHmms";
var getTodayEvent = function (callback){
var startDate = moment().set({'hour': 0,'minute': 0,'second': 0}).format(timeFormat) + "Z";
var endDate = moment().set({'hour': 23,'minute': 59,'second': 59}).format(timeFormat) + "Z";
var output = {};
output.startDate = startDate;
output.endDate = endDate;
caldav.getEvents(url, username, password, startDate, endDate, function(response){
console.log(response);
callback(response);
});
}
var findPropertyNameByRegex = function(o, r) {
var key;
for (key in o) {
if (key.match(r)) {
return key;
}
}
return undefined;
};
function compare(a,b) {
var startDate_a = findPropertyNameByRegex(a, "DTSTART");
var startDate_b = findPropertyNameByRegex(b, "DTSTART");
if (a[startDate_a] < b[startDate_b])
return -1;
else if (a[startDate_a] > b[startDate_b])
return 1;
else
return 0;
}
app.get('/today',function(req, res){
getTodayEvent(function(events){
events.sort(compare);
res.send("Communication set up properly!")
})
});
This is the error which I am getting
Parsing.....
undefined
Error parsing response
TypeError: Cannot read property 'D:multistatus' of undefined
Could somebody tell me what's wrong with this code?
Could somebody tell me what's wrong with this code?
Yes. Your error seems to come from
this line
in the module you seem to use:
var data = result['D:multistatus']['D:response'];
Which is utter non-sense. D: is just a namespace prefix and can be anything the server chooses.
A CalDAV client needs to properly parse and process XML namespaces.
Solution: Use a proper module, or just write it on your own.

Writing test cases using Mocha and Chai for function with Error

I have a following simple function:
var moment = require('moment-timezone');
exports.splitIntoDays = function(from,to) {
var timeIntervals = [];
var interval = {};
var start = moment(from);
var end = moment(to);
if(start.isAfter(end)) {
throw new Error('From date ('+from+') is after To date ('+to+').Enter a valid date range.');
}
var initial = start;
console.log("Before loop"+initial.format("YYYY/MM/DD-HH:mm:ss")+" "+initial.diff(end,'hours'));
while(end.diff(initial,'hours') > 24) {
timeIntervals.push({"from" : initial.format("YYYY/MM/DD-HH:mm:ss"), "to" : initial.add(24,'hours').format("YYYY/MM/DD-HH:mm:ss")});
initial = initial.add(1,'hours');
}
timeIntervals.push({"from" : initial.format("YYYY/MM/DD-HH:mm:ss"), "to" : end.format("YYYY/MM/DD-HH:mm:ss")});
console.info(JSON.stringify(timeIntervals));
return timeIntervals;
}
So, if I call it, splitIntoDays('2014/09/13-10:00:00','2014/09/12-09:00:00'), I get the following response:
Error: From date (2014/09/13-10:00:00) is after To date (2014/09/12-09:00:00).Enter a valid date range.
I wrote the following test using Mocha and Chai:
var expect = require("chai").expect;
var utils = require("../Utils.js");
describe("Utils", function(){
describe("#splitIntoDays()", function(){
it("equal", function () {
var results = utils.splitIntoDays('2014/09/13-10:00:00','2014/09/12-09:00:00');
expect(utils.splitIntoDays('2014/09/13-10:00:00','2014/09/12-09:00:00')).to.throw(new Error('From date (2014/09/13-10:00:00) is after To date (2014/09/12-09:00:00).Enter a valid date range.'));
});
});
});
But, this one fails. Can you please help me in pointing out a mistake?
I tried tried the following as well:
describe("Utils", function(){
describe("#splitIntoDays()", function(){
var error = new Error('From date (2014/09/13-10:00:00) is after To date (2014/09/12-09:00:00).Enter a valid date range.');
it("equal", function () {
expect(function(){
utils.splitIntoDays('2014/09/13-10:00:00','2014/09/12-09:00:00');
}).to.throw(error);
});
});
});
And I am getting the following:
AssertionError: expected [Function] to throw 'Error: From date (2014/09/13-10:00:00) is after To date (2014/09/12-09:00:00).Enter a valid date range.' but 'Error: From date (2014/09/13-10:00:00) is after To date (2014/09/12-09:00:00).Enter a valid date range.' was thrown
You can find an answer here: Mocha / Chai expect.to.throw not catching thrown errors.
Basically, you have to pass a function to expect(). Now you are passing it the result.
EDIT: Pasting the example from my comment which worked.
var expect = require('chai').expect;
describe('test', function(){
var utils = {
splitIntoDays : function(from, to){
throw new Error('Invalid date range.');
}
}
it('throws errors', function(){
expect(utils.splitIntoDays.bind(utils, '2014/09/13-10:00:00', '2014/09/12-09:00:00')).to.throw(Error, 'Invalid date range.');
});
});

MongoDB Time conversion

I have a MongoDB collection that I am querying based on a time frame and address number. If the query is successful, then the server will return a CSV file with a number of attributes stored in each query entry. This part is working fine.
The problem is that one of the attributes in my CSV file is the timestamp. I'd like it to return the local date time (ie. "Time":"2014-02-09T06:00:02.000Z")... however the CSV file is returning the date object in milliseconds (ie. "Time":1392040717774). Is there an easy way to transform the query entry before it's written to the CSV file to a local date string? Here's my code snippet:
var JSONStream = require('JSONStream');
var httpserver = http.createServer(function(req, res) {
var pathname = url.parse(req.url).pathname;
if (pathname=="/DownloadUCData") {
var requestData = '';
req.on('data', function (data) {
requestData += data;
});
req.on('end', function () {
var json = JSON.parse(requestData);
var st = new Date(json.startDate);
var et = new Date(json.endDate);
st.setHours(st.getHours()-4); //compensate for GMT offset
et.setHours(et.getHours()-4);
st=st.getTime();
et=et.getTime();
var proj=JSON.parse('{"state":1, "temperature":1, "mode":1, "speed":1, "time":1}');
var cursor = userControlCollection.find({"addr": json.addr.toString(), "time": {$gte:st, $lte:et}}, proj);
var dbstream = cursor.stream();
var tempname = json.type+".csv";
var wstream = fs.createWriteStream(tempname);
wstream.on('error', function(e){console.error(e);});
dbstream.on("end", function() {
wstream.end();
console.log("write end");
res.writeHead(200, {"Content-Type": "application/json"});
res.write(JSON.stringify({fname:tempname}));
res.end();
return;
});
var jsonToStrings = JSONStream.stringify(false);
dbstream.pipe(jsonToStrings).pipe(wstream);
});
}
So, I figured out one way to solve this problem (although there may be others). Basically, I had to add a transformation into the piping system to convert the .getTime() data into a new Date() object. Here's the code snippet which seemed to resolve the issue:
var Transform = require('stream').Transform;
var parser = new Transform({objectMode: true});
parser._transform = function(data, encoding, done) {
if(data.time) data.time = new Date(data.time);
this.push(data);
done();
};
var jsonToStrings = JSONStream.stringify(false);
dbstream.pipe(parser).pipe(jsonToStrings).pipe(wstream);

Resources