Node.JS multiple new Class only last executed (http & socket.io-client) - node.js

First sorry for my bad english.
I tried connect to server using http token authentication with socket.io as exchange data. When socket.io got an error then request token by http and try to connect again.
I put the connection function in the class then call it from main program. My problem is when I create multiple client why only last work, here my code
call the class
const SocketHttpClient = require('./class/socket-http-client')
let ioClient_1 = new SocketHttpClient('localhost', 3001, 'admin', 'admin', '/login')
let ioClient_2 = new SocketHttpClient('localhost', 3002, 'admin', 'admin', '/login')
let ioClient_3 = new SocketHttpClient('localhost', 3003, 'admin', 'admin', '/login')
connection class
// =================================================================================================
// INCLUDE LIBRARY
// =================================================================================================
const ioClient = require('socket.io-client')
const http = require('http')
const cookie = require('cookie')
const log = require('./log-custom')
// =================================================================================================
// VARIABLE
// =================================================================================================
let data
let httpOption
ioOption = {
transportOptions: {
polling: {
extraHeaders: {
Cookie: 'hello=world'
}
}
}
}
module.exports = class Socket {
constructor(ioHostname, ioPort, httpUsername, httpPassword, loginPath) {
data = {
username: httpUsername,
password: httpPassword
}
data = JSON.stringify(data)
httpOption = {
hostname: ioHostname,
port: ioPort,
path: loginPath,
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Content-Length': data.length
}
}
log(`Connecting to "${httpOption.hostname}:${httpOption.port}"`)
this.io = ioClient(`http://${httpOption.hostname}:${httpOption.port}`, ioOption)
this.io.on('connect', () => {
log(`Connected to socket "${httpOption.hostname}:${httpOption.port}"`)
})
this.io.on('disconnect', () => {
log(`Disconnected to socket "${httpOption.hostname}:${httpOption.port}"`)
log('Reconnecting...')
})
this.io.on('error', () => {
console.log(`error: ${httpOption.hostname}:${httpOption.port}`)
// When error then try to reconnect...
setTimeout(() => {
this.io.disconnect()
this.io.close()
this.req = http.request(httpOption, res => {
this.c = cookie.parse(res.headers['set-cookie'][0])
ioOption.transportOptions.polling.extraHeaders.Cookie = `sid=${this.c.sid}`
this.io.io.opts.query = ioOption
})
this.req.write(data)
this.req.end()
this.req.on('error', err => {
})
// delay to reconnect
setTimeout(() => {
this.io.connect()
}, 1000)
}, 1000)
})
}
}
the result:
ioClient_1 => not working
ioClient_2 => not working
ioClient_3 => working fine as expected
Where I doing wrong here? Need advice from you guys. Thank you in advanced.

Related

Jest Mock Implementation is not working, instead original function is being called

I am trying to test an API by mocking the database function, but the imported function is being called instead of the mocked one.
Here are the code snippets
const supertest = require('supertest');
const axios = require('axios');
const querystring = require('querystring');
const { app } = require('../app');
const DEF = require('../Definition');
const tripDb = require('../database/trip');
const request = supertest.agent(app); // Agent can store cookies after login
const { logger } = require('../Log');
describe('trips route test', () => {
let token = '';
let companyId = '';
beforeAll(async (done) => {
// do something before anything else runs
logger('Jest starting!');
const body = {
username: process.env.EMAIL,
password: process.env.PASSWORD,
grant_type: 'password',
client_id: process.env.NODE_RESOURCE,
client_secret: process.env.NODE_SECRET,
};
const config = {
method: 'post',
url: `${process.env.AUTH_SERV_URL}/auth/realms/${process.env.REALM}/protocol/openid-connect/token`,
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
data: querystring.stringify(body),
};
const res = await axios(config);
token = res.data.access_token;
done();
});
const shutdown = async () => {
await new Promise((resolve) => {
DEF.COM.RCLIENT.quit(() => {
logger('redis quit');
resolve();
});
});
// redis.quit() creates a thread to close the connection.
// We wait until all threads have been run once to ensure the connection closes.
await new Promise(resolve => setImmediate(resolve));
};
afterAll(() => shutdown());
test('post correct data', async (done) => {
const createTripMock = jest.spyOn(tripDb, 'addTrip').mockImplementation(() => Promise.resolve({
pk: `${companyId}_trip`,
uid: '1667561135293773',
lsi1: 'Kotha Yatra',
lsi2: companyId,
name: 'Kotha Yatra',
companyId,
origin: {
address: 'Goa, India',
location: {
lat: 15.2993265,
lng: 74.12399599999999,
},
},
destination: {
address: 'Norway',
location: {
lat: 60.47202399999999,
lng: 8.468945999999999,
},
},
path: [
{
lat: 15.2993265,
lng: 74.12399599999999,
},
{
lat: 60.47202399999999,
lng: 8.468945999999999,
},
],
isDeleted: false,
currentVersion: 1,
geofences: [],
}));
const response = await request.post('/api/trips').set('Authorization', `Bearer ${token}`).send(tripPayload);
expect(createTripMock).toHaveBeenCalled();
expect(response.status).toEqual(200);
expect(response.body.status).toBe('success');
done();
});
});
The database function:
const addTrip = (trip) => {
// const uid = trip.uid ? trip.uid : (Date.now() * 1000) + Math.round(Math.random() * 1000);
const uid = (Date.now() * 1000) + Math.round(Math.random() * 1000);
const item = {
pk: `${trip.companyId}_trip`,
uid: `v${trip.version ? trip.version : 0}#${uid}`,
lsi1: trip.name,
lsi2: trip.companyId,
name: trip.name,
companyId: trip.companyId,
origin: trip.origin,
destination: trip.destination,
path: trip.path,
isDeleted: false,
};
if (!trip.version || trip.version === 0) {
item.currentVersion = 1;
} else {
item.version = trip.version;
}
if (trip.geofences) item.geofences = trip.geofences;
const params = {
TableName: TN,
Item: item,
ConditionExpression: 'attribute_not_exists(uid)',
};
// console.log('params ', params);
return new Promise((resolve, reject) => {
ddb.put(params, (err, result) => {
// console.log('err ', err);
if (err) {
if (err.code === 'ConditionalCheckFailedException') return reject(new Error('Trip id or name already exists'));
return reject(err);
}
if (!trip.version || trip.version === 0) {
const newItem = { ...item };
delete newItem.currentVersion;
newItem.version = 1;
newItem.uid = `v1#${item.uid.split('#')[1]}`;
const newParams = {
TableName: TN,
Item: newItem,
ConditionExpression: 'attribute_not_exists(uid)',
};
// console.log('new params ', newParams);
ddb.put(newParams, (v1Err, v1Result) => {
// console.log('v1 err ', v1Err);
if (v1Err) return reject(v1Err);
item.uid = item.uid.split('#')[1];
return resolve(item);
});
} else {
item.uid = item.uid.split('#')[1];
return resolve(item);
}
});
});
};
module.exports = {
addTrip,
};
I was mocking the above database function when I was making a request to add API, instead, the original function is being called and I was getting the result that I had written in the mock Implementation.
What should I do to just mock the result ,when the function is called and no implementation of the original function should happen.
Even this did not give an error
expect(createTripMock).toHaveBeenCalled();
Still the database function call is happening
I tried using mockReturnValue, mockReturnValueOnce, mockImplemenationOnce but not luck.
Can anyone help me with this?

Keep getting pending request when trying to call endpoint, what's wrong?

I have made an endpoint to get token for paytm payment integration. In backend when i'm calling api i'm getting reqdata json but in frontend when i'm logging await transactionAPI, i'm getting only pending promise. i've tried using then in backend in PaytmChecksum.generateSignature method & in frontend in fetch but nothing is working. Keep getting the same result. Pls help.
Frontend code:
const makePayment = async () => {
const data = {
oid: String(new Date().valueOf()),
amount: '1.00',
email: 'abc#gmail.com',
};
let transactionAPI = fetch('http://localhost:3000/api/pretransact', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data),
});
console.log(await transactionAPI);
}
Backend code:
const https = require('https');
const PaytmChecksum = require('./PaytmChecksum');
export default async function handler(req, res) {
if (req.method == 'POST') {
const { oid, amount, email } = req.body;
let mid = process.env.PAYTM_MID;
let paytmParams = {};
paytmParams.body = {
requestType: 'Payment',
mid,
websiteName: process.env.WEBSITE,
orderId: oid,
callbackUrl: 'http://localhost:3000/api/callback',
txnAmount: {
value: amount,
currency: 'INR',
},
userInfo: {
custId: email,
},
};
const checksum = await PaytmChecksum.generateSignature(
JSON.stringify(paytmParams.body),
process.env.MERCHANT_KEY
);
paytmParams.head = {
signature: checksum,
};
var post_data = JSON.stringify(paytmParams);
const requestAsync = () => {
return new Promise((resolve, reject) => {
var options = {
hostname: 'securegw-stage.paytm.in',
// hostname: 'securegw.paytm.in',
port: 443,
path: `/theia/api/v1/initiateTransaction?mid=${mid}&orderId=${oid}`,
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Content-Length': post_data.length,
},
};
var response = '';
var post_req = https.request(options, function (post_res) {
post_res.on('data', function (chunk) {
response += chunk;
});
post_res.on('end', function () {
resolve(response);
});
});
post_req.write(post_data);
post_req.end();
});
};
const reqdata = await requestAsync();
res.send(200).json(reqdata);
}
}

FaunaDB returns empty array (FaunaDB + Netlify + VueJS)

My code is based on the repository - https://github.com/ttntm/recept0r-ts
Code from "\functions\read-all.js":
const faunadb = require('faunadb');
const fnHeaders = require('./_shared/headers.js');
exports.handler = (event, context) => {
const client = new faunadb.Client({
secret: process.env.FAUNA_SECRET,
domain: 'db.fauna.com',
scheme: 'https',
port: '443'
});
const q = faunadb.query;
const headers = { ...fnHeaders };
const origin = event.headers.Origin || event.headers.origin;
headers['Access-Control-Allow-Origin'] = origin ? origin : '*';
return client.query(q.Paginate(q.Match(q.Index('all_users'), false), { size: 500 }))
.then((response) => {
const listRefs = response.data;
const getListDataQuery = listRefs.map(ref => q.Get(ref)); // create new query out of list refs, then query the refs
return client.query(getListDataQuery).then((records) => {
return { statusCode: 200, headers: headers, body: JSON.stringify(records) }
})
})
.catch((error) => {
return { statusCode: 400, headers: headers, body: JSON.stringify(error) }
});
}
Code from "\src\store\modules\data.js":
async readAll({ commit, dispatch, rootGetters })
{
const fn = rootGetters['app/functions'];
const request = await fetch(fn.readAll, { method: 'GET' });
const response = await request.json();
if (response.length > 0) {
commit('SET_ALL_RECIPES', response);
commit('SET_LAST_UPDATED', new Date); }
else {
dispatch('app/sendToastMessage', { text: 'Error loading recipes. Please try again later.', type: 'error' }, { root: true });
return 'error';
}
}
Everything seems to be set. For example, this code works:
client.query(q.CreateCollection({ name: 'someCollection' }))
But can't read any data.
If launch application by "netlify dev" (localhost) - "read-all" returns empty array ("[]").
If launch application by "network" - "read-all" returns default "index.html".
I have no idea what's wrong. Maybe someone give advice...
I found a similar question - Local Netlify function server gives strange response instead of FaunaDB data
Some answer:
"In my experience, one of the most common reasons for this error is a routing problem, which is triggering a 404 response route serving HTML instead of your expected function handler."
This code works:
return client.query(q.Paginate(q.Documents(q.Collection('customers')), { size: 500 }))
.then((response) => {
const listRefs = response.data;
const getListDataQuery = listRefs.map(ref => q.Get(ref)); // create new query out of list refs, then query the refs
return client.query(getListDataQuery).then((records) => {
return { statusCode: 200, headers: headers, body: JSON.stringify(records) }
});
})
.catch((error) => {
return { statusCode: 400, headers: headers, body: JSON.stringify(error) }
});

Next Js build give error 500 internal server error in some routes

I'm trying to make the page in question getServerSideProps because the content is list of products through API so getStaticProps isnt going to help with this page.
but unfortunately all the pages work perfectly on localhost but when i deploy on vercel the page in question is giving me 500 internal server error.
any help?
build log:
error:
folder structure:
export async function getStaticProps(context) {
const { host } = context.params;
const headersTn = {
domain: "tn",
};
const headersDz = {
domain: "dz",
};
const headersCi = {
domain: "ci",
};
const resTn = await fetch(`${process.env.urlApi}v1/getProductsByCountry/`, {
headers: headersTn,
}).then((res) => res.json());
const resDz = await fetch(`${process.env.urlApi}v1/getProductsByCountry/`, {
headers: headersDz,
}).then((res) => res.json());
const resCi = await fetch(`${process.env.urlApi}v1/getProductsByCountry/`, {
headers: headersCi,
}).then((res) => res.json());
const langParam = await fetch(`${process.env.urlApi}v1/getLanguage/`).then(
(res) => res.json()
);
return {
props: {
host,
tn: resTn,
dz: resDz,
ci: resCi,
dataLang: langParam,
},
};
}
export async function getStaticPaths(context) {
const paths = context.locales.map((locale) => {
return { params: { host: `${process.env.staticHost}` }, locale };
});
return {
paths,
fallback: "blocking",
};
}

Google Cloud Tasks - Network Error on create multiples tasks

In this code below I have a client which creates multiples tasks inside a map loop. However, this process doesn't complete and returns the follow network error:
Error: request to https://cloudtasks.googleapis.com/$rpc/google.cloud.tasks.v2.CloudTasks/CreateTask failed, reason: Client network socket disconnected before secure TLS connection was established
How can I fix this?
const { CloudTasksClient } = require('#google-cloud/tasks');
exports.sendTask = (req, res) => {
const data = req.body.data;
const client = new CloudTasksClient({ fallback: true });
const parent = client.queuePath(process.env.PROJECT, process.env.LOCATION, process.env.QUEUE);
const url = process.env.URL;
let counter = 0;
data.map(payload => {
counter += 1;
console.log('preparando task ', counter);
const task = {
httpRequest: {
httpMethod: 'POST',
url,
oidcToken: {
serviceAccountEmail: process.env.SERVICE_ACCOUNT,
},
headers: {
'Content-Type': 'application/json',
},
body: Buffer.from(payload).toString('base64')
}
};
client.createTask({parent, task});
console.log('Task gerada.');
});
res.status(200).send();
}
Exception from task creation
According to documentation - client.createTask is async function, means, your code should wait for it's result somehow. Having a loop here, I guess, you want call all of them asynchronously, not one by one, and wait for result of all of them. I suggest you to use Promise.all
const { CloudTasksClient } = require('#google-cloud/tasks');
exports.sendTask = async (req, res) => {
const data = req.body.data;
const client = new CloudTasksClient({ fallback: true });
const parent = client.queuePath(process.env.PROJECT, process.env.LOCATION, process.env.QUEUE);
const url = process.env.URL;
let counter = 0;
await Promise.all(data.map(payload => {
counter += 1;
console.log('preparando task ', counter);
const task = {
httpRequest: {
httpMethod: 'POST',
url,
oidcToken: {
serviceAccountEmail: process.env.SERVICE_ACCOUNT,
},
headers: {
'Content-Type': 'application/json',
},
body: Buffer.from(payload).toString('base64')
}
};
console.log('Task gerada.');
return client.createTask({parent, task});
}));
console.log('All task were generated.');
res.status(200).send();
}

Resources