Sample Database Connection to SQLite Database in Cypress - database

I ran into an issue when connecting to a SQLite Database before. Now that I figured it out, I'd like to share the solution with everyone. Thanks.
In plugins/index.js
const sqlite3 = require('sqlite3').verbose();
module.exports = (on, _config) => {
on('task', {
queryDb: queryTestDb,
//wait: timeout,
});
};
Also in plugins/index.js
const path='C:/Users/Mamga/TestDB/chinook.db'
function queryTestDb(sql) {
let db = new sqlite3.Database(path);
return new Promise((resolve, reject) => {
db.all(sql, [], (err, rows) => {
if(err)
reject(err);
else {
db.close();
console.log(rows)
return resolve(rows);
}//End else
});//End db.run
});
}
Actual Test in TaskCommandDBConnectionTest.js ///
/// <reference types="Cypress" />
describe('Task Command', () => {
it('Should send execute something on node', () => {
const query='select * from Persons';
cy.task('queryDb', query).then((rows) => {
//expect(rows).to.have.lengthOf(4);
for(var i=0; i<rows.length; i++)
{
cy.log(rows[i].FirstName + " "+ rows[i].LastName + " " + rows[i].Age)
}
});
})
})

Might be related to a bugfix in cypress 5.3.0:
"Fixed an issue where a cy.task with no arguments passed would receive null as the first argument instead of undefined"
https://docs.cypress.io/guides/references/changelog.html#5-3-0

Related

Exceeded timeout of 5000 ms for a test when the target method has 2 api calls

I am facing an issue for Exceeded timeout of 5000 ms for a particular test. below is the method that I am testing:
createTask(
newTask: TaskModel,
status: string
): Observable<Model> {
let status: String;
if ('Publish' === publishStatus) {
status = 'Published';
} else {
status = 'Draft';
}
return this.http
.post<void>(
`${this.envTasksApi}/tasks`,
{
...newTask,
currentStatus: status,
},
{
headers: this.headers,
}
)
.pipe(
tap(() => {
this.store.add(task);
}),
switchMap(() => {
return this.publishTaskAction(newTask, publishStatus);
})
);
}
below is my test class code:
it('should be created', (done) => {
jest.spyOn(store, 'addTask');
taskApiService.createTask(taskToStore[0], 'Publish').subscribe((taskHistoryModel) => {
expect(store.addTask).lastCalledWith(taskToStore[0]);
done();
});
const req = httpTestingController.expectOne(api + '/tasks');
expect(req.request.method).toEqual('POST');
expect(req.request.body).toEqual({
...taskToStore[0],
currentStatus: 'Published',
});
req.flush(taskToStore[0]);
});
If I remove the switchMap part from the method to be tested, then the tests are running fine. Please suggest any way to fix this. Thanks!!
Edit1: As suggested by Esaith, I updated the code below:
it('should save task in store when new one is created', (done) => {
jest.spyOn(store, 'addTask');
taskApiService.createTask(taskToStore[0], 'Publish').subscribe(() => {
taskApiService.publishActionTask(taskToStore[0], 'Publish').subscribe(() => {
expect(store.addTask).lastCalledWith(taskToStore[0]);
});
const req = httpTestingController.expectOne(api + '/tasks');
expect(req.request.method).toEqual('POST');
expect(req.request.body).toEqual({
...taskToStore[0],
currentStatus: 'Published',
});
req.flush(taskToStore[0]);
done();
});
});
Still facing the same issue.
Edit2: I wrote a separate test for publishActionTask and there as well timeout is happening. Below is the code:
it('should publish the task', (done) => {
jest.spyOn(store, 'addTask');
jest.setTimeout(30000);
taskApiService.publishActionTask(taskToStore[0], 'PublishTask').subscribe(() => {
const req = httpTestingController.expectOne(api + '/tasks/actions');
expect(req.request.method).toEqual('POST');
req.flush(taskToStore[0]);
done();
});
});
Although this code is working well when tested through web. Any more suggestions please.
Well the error message mislead me, when writing the test case, expects should be done in order of the calls done from main code. So this is what worked for me:
it('should save task in store when new one is created', (done) => {
jest.spyOn(store, 'addSomething1');
taskApiService.createTask(taskToStore[0], 'action1').subscribe(() => {
expect(store.addTask).lastCalledWith(taskToStore[0]);
done();
});
const req = httpTestingController.expectOne('mock-task-path' + '/tasks');
expect(req.request.method).toEqual('POST');
req.flush(null);
const publishReq = httpTestingController.expectOne(
'mock-task-path' + '/tasks/actions'
);
expect(publishReq.request.method).toEqual('POST');
publishReq.flush(null);
const getHistoryReq = httpTestingController.expectOne(
'mock-task-path' + '/tasks/Finance/test1/history'
);
expect(getHistoryReq.request.method).toEqual('GET');
getHistoryReq.flush({
taskId: '1',
taskStatuses: [
{
id: null,
date: null,
status: 'Action1',
changes: '',
},
],
});
});

Making only admins execute commands

The problem is that I couldn't figure out a way to make this command only accessible by admins. I've tried using if statements, however, I failed. message. I am not sure if member. roles. cache. has( ' 732524984777572363 ' ) would allow members with the role ID 732524984777572363 to execute it since there's already an if statement.
const Discord = require('discord.js');
const fs = require('fs');
const cooldown = new Set();
module.exports.run = async (client, msg, args, config) => {
if(cooldown.has(msg.author.id)) {
msg.reply(`You need to wait ${config.COOLDOWN} minutes to use this command again!`)
.then((m) => {
msg.delete();
setTimeout(() => {
m.delete();
}, 5000);
});
} else {
fs.readFile('./accounts/crunchy.txt', 'utf8', function(err, data) {
if (err) throw err;
data = data + '';
var lines = data.split('\n');
let account = lines[Math.floor(Math.random() * 1)];
fs.writeFile('./accounts/crunchy.txt', lines.slice(1).join('\n'), function(err) {
if(err) throw err;
});
let embed = new Discord.RichEmbed()
.addField('Rate Us Here | قيمنا هنا ', `<#915***********80>`)
.addField('CrunchyRoll Account',`\n**${account}**`)
.setThumbnail('**************************')
.setColor("#363940")
.setFooter('Bot made by ******')
.setTimestamp();
msg.author.send(embed);
msg.reply('I\'ve sent you the account! Please check your DM!')
.then(m => {
setTimeout(() => {
m.delete();
}, 900000);
});
cooldown.add(msg.author.id);
setTimeout(() => {
cooldown.delete(msg.author.id);
}, config.COOLDOWN * 60 * 1000);
});
}
};
module.exports.help = {
name: `CrunchyRoll`,
description: `Sends you a CrunchyRoll account!`
};```
Simply adding a role check and a server check will prevent any issues!
The first line would be:
if(!msg.guild) return;
This line makes sure the user is running the command in a server(guild), this prevents a member role from being undefined or null.
The second line would be:
if(!msg.author.roles.cache.has('ROLE_ID_HERE')) return;
This prevents a user from running a command if they do not have a specific role.
The final code would be:
if(!msg.guild) return;
if(!msg.author.roles.cache.has('ROLE_ID_HERE')) return;
You will need to add this to the top of your code in order for it to work as you'd like.
const Discord = require('discord.js');
const fs = require('fs');
const cooldown = new Set();
module.exports.run = async (client, msg, args, config) => {
if(!msg.guild) return;
if(!msg.member.roles.cache.has('ROLE_ID_HERE')) return;
if(cooldown.has(msg.author.id)) {
msg.reply(`You need to wait ${config.COOLDOWN} minutes to use this command again!`)
.then((m) => {
msg.delete();
setTimeout(() => {
m.delete();
}, 5000);
});
} else {
fs.readFile('./accounts/crunchy.txt', 'utf8', function(err, data) {
if (err) throw err;
data = data + '';
var lines = data.split('\n');
let account = lines[Math.floor(Math.random() * 1)];
fs.writeFile('./accounts/crunchy.txt', lines.slice(1).join('\n'), function(err) {
if(err) throw err;
});
let embed = new Discord.RichEmbed()
.addField('Rate Us Here | قيمنا هنا ', `<#915***********80>`)
.addField('CrunchyRoll Account',`\n**${account}**`)
.setThumbnail('**************************')
.setColor("#363940")
.setFooter('Bot made by ******')
.setTimestamp();
msg.author.send(embed);
msg.reply('I\'ve sent you the account! Please check your DM!')
.then(m => {
setTimeout(() => {
m.delete();
}, 900000);
});
cooldown.add(msg.author.id);
setTimeout(() => {
cooldown.delete(msg.author.id);
}, config.COOLDOWN * 60 * 1000);
});
}
};
module.exports.help = {
name: `CrunchyRoll`,
description: `Sends you a CrunchyRoll account!`
};

how to reduce bundle.js file size with vfs_fonts.js?

I'm developing pdf down load function with react/typescript.
(using pdfmake)
My bundle.js file size is too large.(8MB over)
So, I want to reduce this.
The main cause is the bundle.js contains vfs_fonts.js.
this file size is over 17MB.
I've tried fetching font file dynamically instead of bundling the file, referring to this page.
https://github.com/bpampuch/pdfmake/issues/1374
But it didn't work.
this is a part of my code
import * as pdfMake from 'pdfmake/build/pdfmake';
function fetchFont (fontURL: string) {
return new Promise((resolve, reject) => {
const request = new XMLHttpRequest();
request.open('GET', fontURL, true);
request.responseType = 'arraybuffer';
request.onload = function (e: any) {
resolve(request.response);
};
request.onerror = reject;
request.send();
});
}
interface Dictionary {
[index: string]: string;
}
class PdfFontLoader {
fontDefs: Dictionary[];
vfs: {};
loaded: boolean;
constructor () {
this.fontDefs = [];
this.vfs = {};
}
addFont (fontDef: Dictionary) {
this.fontDefs.push(fontDef);
}
load() {
return new Promise((resolve, reject) => {
if (this.loaded) {
resolve();
} else {
const fetches = this.fontDefs.map(fontDef => {
return fetchFont(fontDef.URL).then((data) => {
console.log('fetched ' + JSON.stringify(data));
this.vfs[fontDef.name] = data;
}).catch(e => {
console.log('error ' + e);
});
});
Promise.all(fetches).then(() => {
this.loaded = true;
resolve();
}).catch(reject);
}
});
}
}
const pdf = pdfMake;
pdf.vfs = fontLoader.vfs;
fontLoader.addFont({URL: 'GenShinGothic-Normal.ttf', name: 'GenShinGothic-Normal.ttf'});
fontLoader.addFont({URL: 'GenShinGothic-Bold.ttf', name: 'GenShinGothic-Bold.ttf'});
fontLoader.load().then(res => {
console.log('load finished');
pdf.fonts = {
GenShinGothic: {
normal: 'GenShinGothic-Normal.ttf',
bold: 'GenShinGothic-Bold.ttf'
}
};
console.log("vfs is " + JSON.stringify(pdf.vfs));
console.log
load finished
fetched {}
vfs is {"GenShinGothic-Normal.ttf":{},"GenShinGothic-Bold.ttf":{}}
if pdf generating...
Error: unknown font format
Can you help me?
====additional info=====
the font file(ttf) are deployed in same directory with bundle.js...

JSSIP and React audio issue

So I am using jssip 3.2.10 to make calls on a React project.
The server is setup on Asterisk and CentOS.
I can make calls where the call receiver hears me well, but I can't hear their audio, nor the waiting (traditional) beep noises it should make until the call is picked up.
It does work with some sipml5/asterisk udp online tests so I feel it's on my clients side issue. I tested it on Chrome and Firefox (both latest, with the same results).
My setup
I have a helper to connect called sip.js:
const JsSIP = require('jssip')
const GLOBAL = require('../globals')
function register(user, pass, cb) {
console.log('Registering to SIP')
JsSIP.debug.disable('JsSIP:*')
const address = GLOBAL.jssip_server + ':' + GLOBAL.jssip_port
let socket = new JsSIP.WebSocketInterface('ws://' + address + '/ws')
const configuration = {
sockets: [socket],
uri: 'sip:' + user + '#' + GLOBAL.jssip_server,
authorization_user: user,
password: pass,
connection_recovery_min_interval: 3,
register: true
}
let ua = new JsSIP.UA(configuration)
ua.start()
cb(ua)
}
export {
register
}
Then on my main component I do the following:
componentDidMount() {
if(GLOBAL.jssip) {
this.props.dispatch(connecting(true))
register('***', '***', (ua) => {
this.setState({ua: ua}, () => {
this.state.ua.on("registered", () => {
this.props.dispatch(connecting(false))
this.setState({critical: false})
})
this.state.ua.on("registrationFailed", () => {
this.props.dispatch(connecting(false))
this.setState({critical: true})
})
})
})
}
}
And when I try to make a call I do the following:
doCall(number) {
this.props.dispatch(placeCall(call))
if(GLOBAL.jssip) {
let eventHandlers = {
'connecting': (e) => {
console.log('call is in progress')
this.setState({sipStatus: "connecting"})
},
'progress': (e) => {
console.log('call is in progress')
this.setState({sipStatus: "progress"})
},
'failed': (e) => {
console.log('call failed with cause: ', e)
this.setState({sipStatus: "failed"})
},
'ended': (e) => {
console.log('call ended with cause: ', e)
this.setState({sipStatus: "ended"})
},
'confirmed': (e) => {
this.setState({sipStatus: "confirmed"})
}
}
let options = {
eventHandlers: eventHandlers,
mediaConstraints: { 'audio': true, 'video': false }
}
let session = this.state.ua.call('sip:'+number+'#'+GLOBAL.jssip_server, options)
}
}
Anyone has a clue on how to fix this?
Thanks to the answer here:
How to handle audio stream in JsSIP?
I found the solution, I needed to add to the file rendering the call:
<audio ref={(audio) => {this.audioElement = audio}} id="audio-element"></audio>
And changed doCall last bit to this:
this.setState({session: this.state.ua.call('sip:'+number+'#'+GLOBAL.jssip_server, options)}, () =>{
this.state.session.connection.addEventListener('addstream', (event: any) => {
this.audioElement.srcObject = event.stream
this.audioElement.play()
})
})

Returning NodeJS console value into client side (AngularJS)

I''m totally new to AngularJS and NodeJs. I'm having a promise and it works well. There's console.log here ,this works well in server console.I need to print this console.log into client side (It's in Angular JS).
This is my server side code.
function checkNamesAvailable(
name /* : string | void */,
) /* :Promise<Object[]> */ {
const connection = createConnection()
return new Promise((resolve, reject) => {
const sql =
`SELECT names
FROM Names
WHERE JSON_EXTRACT(names, '$.name') = ? `
const values = [name]
const query = connection.query(sql, values, (error, results, fields) => {
connection.end()
if (error) {
return reject(error)
console.log(error)
}
resolve(results)
})
})
.then((results) => {
if(results.length > 0){
console.log("name is already exist")
}else{
saveNewName(names)
}
})
}
I'm calling above function in index.js as follows
addresses.post = function (
request /* : Object */,
response /* : Object */
) /* : Promise<Object> */ {
return authentication.authenticate((request.headers || {}).authorization)
.then((authorised) => {
if (!authorised) {
return Promise.reject(boom.forbidden('You do not have access to add new names'))
}
libAddr.checkNamesAvailable(request.body.data.attributes.names)
.then(() => {
return response.setStatusCode(200).setPayload({
})
})
.catch(err => {
return response.setStatusCode(400).setPayload({
message: err
})
})
Could someone help me regarding this?
You need to send your error message to client.
As like:
res.status(500).send({ error: 'Something failed!' });
And inside your AngularJS controller, you need to catch this error. For example:
$http.get('/url')
.then(function(result){
console.log('good!');
})
.error(function(error){
$scope.myErrorMessage = error.error;
});
And now you can show it on the page
<div ng-if="myErrorMessage">{{ myErrorMessage }}</div>
Please check the below code snippet:
addresses.post = function (
request /* : Object */ ,
response /* : Object */
) /* : Promise<Object> */ {
return authentication.authenticate((request.headers || {}).authorization)
.then((authorised) => {
if (!authorised) {
return Promise.reject(boom.forbidden('You do not have access to add new names'))
}
libAddr.checkNamesAvailable(request.body.data.attributes.names)
.then((results) => {
return response.setStatusCode(200).setPayload({
data: results
});
})
.catch(err => {
return response.setStatusCode(400).setPayload({
message: err
});
})

Resources