Jest timeout testing Koa route - automated-tests

I am starting with Jest for testing our API. However, the moment I add my second test, everything falls apart with a timeout exception.
Here's my code:
const server = require('../server')
const request = require('supertest')
const path = require("path")
const fs = require("fs")
const config = require('../knexfile.js')
const knex = require('knex')(config.development)
beforeAll(async () => {
let file = fs.readFileSync(path.join(__dirname, '..', 'galaxycard.sql'), 'utf8')
await knex.raw(file)
await knex.migrate.latest()
})
afterAll(async () => {
await knex.raw(`
DROP SCHEMA public CASCADE;
CREATE SCHEMA public;
GRANT ALL ON SCHEMA public TO public;
`)
server.close()
})
describe("test 1", () => {
it("should not be able to add a payment for user without credit", async () => {
let response = await request(server)
.post('/v1/hampers')
.set('Content-Type', 'application/json')
.send({
entity_type: 'utility',
latitude: 1,
longitude: 1,
comment: null,
user_id: new Date().getTime(),
amount: -200,
entity_id: 1,
processed: false
})
expect(response.status).toEqual(402)
})
})
describe("test 2", () => {
let userId
beforeEach(async () => {
userId = new Date().getTime()
let response = await request(server)
.post('/v1/hampers')
.set('Content-Type', 'application/json')
.send({
entity_type: 'credit',
latitude: 0,
longitude: 0,
user_id: userId,
amount: 5000,
entity_id: 1,
processed: true
})
expect(response.status).toEqual(200)
expect(JSON.parse(response.text)).toHaveProperty('uuid')
})
it("have hampers", async () => {
let response = await request(server)
.post('/v1/hampers')
.set('Content-Type', 'application/json')
.send({
entity_type: 'utility',
latitude: 1,
longitude: 1,
comment: null,
user_id: userId,
amount: -200,
entity_id: 1,
processed: false
})
expect(response.status).toEqual(200)
expect(JSON.parse(response.text)).toHaveProperty('uuid')
})
})
Jest keeps dying with:
Timeout - Async callback was not invoked within the 5000ms timeout
specified by jest.setTimeout.
Another weird issue is that Jest doesn't exit after the tests have run, even though I use server.close.

The second issue (seeming to hang after the test run) is probably caused by the lack of knex.destroy() in your afterAll. I can speak to the first problem after seeing your route definition.

Related

Firebase cloud function getting 404 timeout error

I'm trying to run a firebase cloud function. It reads 5k documents and it's taking more than one minute to run in insomnia. When it finally crashes showing a 404 timeout error, how can I fix it? I'm from Brazil and the function region is from the US by default, but I don't believe changing it will help.
I tried making the code cleaner, but didn't help.
This is one of the cloud functions:
exports.getTodosPedidos = functions.https.onRequest(
async (req: RequestType, res: ResponseType) => {
try {
const idProjeto = req.query.idProjeto;
if (!idProjeto) {
onFailureResponseStructure(res, "ID do Projeto não fornecido.", 404);
}
const projeto =
idProjeto &&
(await admin.firestore().collection("projetos").doc(idProjeto.toString()).get());
if (projeto != "" && !projeto?.createTime) {
onFailureResponseStructure(res, "O projeto fornecido não existe.", 405);
}
const snapshot = await admin.firestore().collection("pedidos").get();
const result = snapshot.docs.map(doc => ({ ...doc.data(), id: doc.id }));
let idsDosPedidos = result.map(elemento => elemento.id);
let somaDosArquivos = idsDosPedidos.map(async pedidoId => {
let bucketRef = await admin
.storage()
.bucket()
.getFiles({
prefix: `${idProjeto}/arquivos/${pedidoId}/`,
});
return bucketRef[0].map(elemento => parseInt(elemento.metadata.size));
});
const resultado = await Promise.all(somaDosArquivos);
onSuccessResponseStructure(res, { resultado, idsDosPedidos });
} catch (error: any) {
onFailureResponseStructure(res, error.message, 500);
}
}
);
const onSuccessResponseStructure = (res: ResponseType, data: any) => {
return res.status(200).json({
status: "OK",
data,
messages: [],
statusCode: "200",
});
};
const onFailureResponseStructure = (
res: ResponseType,
messages: string,
statusCode: number
) => {
return res.status(statusCode).json({ status: "ERRO", data: [], messages, statusCode });
};
I'm not entirely familiar with firebase. But other cloud services allow you to increase functions timeout lengths. It appears firebase does as well...https://firebase.google.com/docs/functions/manage-functions#set_timeout_and_memory_allocation
Though for long running tasks you may want to investigate other services.

Telegram sendInvoice method is failing

Hello stack overflow so when I am testing a stripe transaction with testing credit cards. I get a "bot precheckout timeout" error and cannot succeed with the tested transaction. After the stripe payment I would like to see a success method. Here is my source code.
require("dotenv").config();
const express = require("express");
const axios = require("axios");
const bodyParser = require("body-parser");
const invoiceDescription = require('./constants');
const { TOKEN, SERVER_URL, BOTTOKEN } = process.env;
const TELEGRAM_API = `https://api.telegram.org/bot${TOKEN}`;
const URI = `/webhook/${TOKEN}`;
const WEBHOOK_URL = SERVER_URL + URI;
const app = express();
app.use(bodyParser.json());
const init = async () => {
const res = await axios.get(`${TELEGRAM_API}/setWebhook?url=${WEBHOOK_URL}`);
console.log(res.data);
};
app.post(URI, async (req, res) => {
console.log(req.body)
let text = "", chatId = "", userObjectForTable = {};
if(req.body.message?.chat?.id && req.body.message?.text){
chatId = req.body.message.chat.id;
text = req.body.message.text;
await axios.post(`${TELEGRAM_API}/sendMessage`, {
chat_id: chatId,
text: text,
});
}
if (text === "/pay") {
const message = await axios.post(`${TELEGRAM_API}/sendInvoice`, {
chat_id: chatId,
title: `FinnessinPips`,
description: invoiceDescription,
payload: "Invoice for payment",
provider_token: BOTTOKEN,
currency: "USD",
prices: [{ label: "tax", amount: 4000 }],
});
userObjectForTable = {
date: new Date(message.data.result.date),
username: message.data.result.from.username
}
}
if(req.body.pre_checkout_query?.id){
//save to sqlite
console.log("saving to sqlite", req.body)
await axios.post(`${TELEGRAM_API}/sendMessage`, {
chat_id: req.body.pre_checkout_query?.from.id,
text: "Successfully Payed private url is",
});
}
return res.send();
});
app.listen(process.env.PORT || 5050, async () => {
console.log("🚀 app running on port", process.env.PORT || 5050);
await init();
});
Take a look at "7. Pre-Checkout" section in the Payment API here: https://core.telegram.org/bots/payments#7-pre-checkout
More specifically :
Your bot must reply using answerPrecheckoutQuery within 10 seconds after receiving this update or the transaction is canceled.

next-redux-wrapper Wrapper.getStaticProps not working with

This is my backend controller, I am getting the rooms data
const allRooms = catchAsyncErrors(async (req, res) => {
const resPerPage = 4;
const roomsCount = await Room.countDocuments();
const apiFeatures = new APIFeatures(Room.find(), req.query)
.search()
.filter()
let rooms = await apiFeatures.query;
let filteredRoomsCount = rooms.length;
apiFeatures.pagination(resPerPage)
rooms = await apiFeatures.query;
res.status(200).json({
success: true,
roomsCount,
resPerPage,
filteredRoomsCount,
rooms
})
})
This is my redux actions I am sending the payload and data
export const getRooms = (req, currentPage = 1, location = '', guests, category) => async (dispatch) => {
try {
const { origin } = absoluteUrl(req);
let link = `${origin}/api/rooms?page=${currentPage}&location=${location}`
if (guests) link = link.concat(`&guestCapacity=${guests}`)
if (category) link = link.concat(`&category=${category}`)
const { data } = await axios.get(link)
dispatch({
type: ALL_ROOMS_SUCCESS,
payload: data
})
} catch (error) {
dispatch({
type: ALL_ROOMS_FAIL,
payload: error.response.data.message
})
}
}
This is my reducer function, dispatching the room data
export const allRoomsReducer = (state = { rooms: [] }, action) => {
switch (action.type) {
case ALL_ROOMS_SUCCESS:
return {
rooms: action.payload.rooms
}
case ALL_ROOMS_FAIL:
return {
error: action.payload
}
case CLEAR_ERRORS:
return {
...state,
error: null
}
default:
return state
}
}
Here I want to get the data using wrapper.getStaticProps but I am getting an error, but when i am using wrapper.getServerSideProps I get the data.
export const getStaticProps = wrapper.getStaticProps(store=> async ({ req, query, }) => {
await store.dispatch(getRooms(req, query.page, query.location, query.guests, query.category))
})
It seems that in ({ req, query, }) => , query is undefined.
Going by the documentation of next, the context object for getStaticProps has no property query. It is only available in getServerSideProps.
See also this info:
Only runs at build time
Because getStaticProps runs at build time, it does not receive data that’s only available during request time, such as query parameters or HTTP headers as it generates static HTML.

Function execution took 60002 ms, finished with status: 'timeout' for callable function

I am experiencing an issue with Firebase callable functions and Auth triggers. You can see the callable function below. When it works it usually takes less than 1 second to finish but it started give frequent timeout errors since yesterday. Same thing for the Auth trigger, I was simply returning a Promise that writes user email to the Firestore in that case.
exports.respondToInvite = functions.https.onCall(async (data, context) => {
if (!context.auth) {
throw new functions.https.HttpsError('failed-precondition', 'The function must be called ' +
'while authenticated.');
}
const uid = context.auth.token.uid;
const inviteId = data.inviteId;
const groupId = data.groupId;
const accepted: boolean = data.accepted;
try {
const batch = admin.firestore().batch();
const inviteRef = admin.firestore().collection("invites").doc(inviteId);
batch.update(inviteRef, {
userId: uid,
status: accepted ? "accepted" : "rejected",
})
if (accepted) {
const groupUsersRef = admin.firestore().collection("groups").doc(groupId).collection("users").doc(context.auth.uid);
batch.set(groupUsersRef, {
createdAt: admin.firestore.Timestamp.now()
})
const userRef = admin.firestore().collection("users").doc(uid);
batch.set(userRef, {
"groupId": groupId
});
}
await batch.commit();
return "invitation accepted";
} catch (error) {
console.error(error);
throw new functions.https.HttpsError('failed-precondition', 'invite response failed',error);
}
});
Edit:
Here is the Auth trigger function
exports.newUser = functions.auth.user().onCreate((user) => {
const userRef = admin.firestore().collection("users").doc(user.uid);
return userRef.create({
"email": user.email,
});
});

Batch Geocode using Axios

Testing the HERE Batch GeoCode life-cycle through node application. We have similar working with Azure Mappings but they are crazy expensive.
Seems as if the initial post request is succeeding. But is stuck on "submitted" status during status check. And failing during result check with 404. Using axius to make the queries - with the documented examples.
const getStatus = async requestId => {
const url = statusURL(requestId);
const res = await axios.get(url);
const response = res.data.Response;
return response;
};
const getResult = async requestId => {
const url = resultURL(requestId);
const config = { headers: { 'Content-type': 'text/plain' } };
const res = await axios.get(url, config);
const response = res.data.Response;
return response;
};
const requestGeo = async input => {
const url = requestURL;
const res = await axios.post(url, input, {
headers: { 'Content-type': 'text/plain' },
});
const requestId = res.data.Response.MetaInfo.RequestId;
return requestId;
};
getStatus(requestId)
.then(res => {
console.log(res);
})
.catch(e => {
console.log(e);
});
const input = `recId|street|city|postalCode|country
1|425 Randolph St|Chicago||USA
2|31 St James Ave|Boston|02116|USA
3|Invalidenstrasse 117|Berlin|10115|DEU`;
requestGeo(input)
.then(console.log)
.catch(e => {
console.log(e);
});
If you don't specify the "&action=run" parameter in your initial request, then the job is being checked, stored and set as "submitted". This does not mean that it will be executed.
Alternatively you can send an "action=start"-request to start the job.
Having applied one of these two options, the job will be scheduled for execution and flagged as "accepted".

Resources