Testing Keystone and Mongoose with Jest - node.js

I am implementing unit testing in a project with Keystone but it always throws an error at testing:
an all test suites.
/Project/node_modules/mongodb/lib/mongo_client.js:433
throw err
^
TypeError: require(...) is not a function
at /Project/node_modules/keystone/lib/core/start.js:64:44
at /Project/node_modules/async/dist/async.js:3880:24
at eachOfArrayLike (/Project/node_modules/async/dist/async.js:1069:9)
at eachOf (/Project/node_modules/async/dist/async.js:1117:5)
at _parallel (/Project/node_modules/async/dist/async.js:3879:5)
at Object.parallelLimit [as parallel] (/Project/node_modules/async/dist/async.js:3962:5)
at /Project/node_modules/keystone/lib/core/start.js:60:9
at connected (/Project/node_modules/keystone/lib/core/openDatabaseConnection.js:78:5)
at NativeConnection.<anonymous> (/Project/node_modules/keystone/lib/core/openDatabaseConnection.js:85:4)
at Object.onceWrapper (events.js:273:13)
at NativeConnection.emit (events.js:182:13)
at /Project/node_modules/mongoose/lib/connection.js:860:13
at connectCallback (/Project/node_modules/mongodb/lib/mongo_client.js:527:5)
at /Project/node_modules/mongodb/lib/mongo_client.js:430:11
at process._tickCallback (internal/process/next_tick.js:61:11)
npm ERR! Test failed. See above for more details.
I already tried using "import { init, start, mongoose } from 'keystone';" instead, and using jest async() and await. I run too "jest --clearCache". Jest version: "jest": "^24.3.1"
My .babelrc:
{
"presets": [
["#babel/preset-env",
{"targets": {
"node": "current"
}}
],
"#babel/preset-react"
]
}
test.js:
const Keystone = require('keystone');
beforeAll( done => {
Keystone.init({
'name': 'Keystone CMS',
'cookie secret': 'My_Biscuit',
});
Keystone.start();
done();
})
describe('Test Keystone CMS own features', () => {
test('Keystone connects to MongoDB', (done) => {
expect(Keystone.mongoose.connections._listening).toBeTruthy;
done();
});
});
I will then expand it to test mongoose

It seems, that it is not really possible at the moment:
https://github.com/keystonejs/keystone/issues/3564

Related

Issues while deploying a whatsapp bot on vercel

I have created a whatsapp bot which uses openai, whatsapp-web.js and nodejs.
While deploying it on vercel, I am facing following issues:
Error: Failed to launch the browser process!
[0212/144729.058867:ERROR:zygote_host_impl_linux.cc(90)] Running as root without --no-sandbox is not supported.
These are the output that I am getting on deployment:
Running build in Washington, D.C., USA (East) – iad1
Cloning github.com/hritik2002/GitaGpt-Bot (Branch: main, Commit: 17356f1)
Previous build cache not available
Cloning completed: 401.653ms
Running "vercel build"
Vercel CLI 28.15.3
Running "install" command: `npm install`...
npm WARN deprecated puppeteer#13.7.0: < 18.1.0 is no longer supported
added 121 packages, and audited 122 packages in 6s
10 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
/vercel/path0/node_modules/puppeteer/lib/cjs/puppeteer/node/BrowserRunner.js:241
reject(new Error([
^
Error: Failed to launch the browser process!
[0212/144729.058867:ERROR:zygote_host_impl_linux.cc(90)] Running as root without --no-sandbox is not supported. See https://crbug.com/638180.
TROUBLESHOOTING: https://github.com/puppeteer/puppeteer/blob/main/docs/troubleshooting.md
at onClose (/vercel/path0/node_modules/puppeteer/lib/cjs/puppeteer/node/BrowserRunner.js:241:20)
at Interface.<anonymous> (/vercel/path0/node_modules/puppeteer/lib/cjs/puppeteer/node/BrowserRunner.js:231:68)
at Interface.emit (node:events:525:35)
at Interface.close (node:internal/readline/interface:536:10)
at Socket.onend (node:internal/readline/interface:262:10)
at Socket.emit (node:events:525:35)
at endReadableNT (node:internal/streams/readable:1359:12)
at process.processTicksAndRejections (node:internal/process/task_queues:82:21)
Node.js v18.12.1
Error: Command "node app.js" exited with 1
My package.json file:
{
"dependencies": {
"axios": "^0.26.1",
"qrcode-terminal": "^0.12.0",
"whatsapp-web.js": "^1.18.0"
}
}
My app.js code:
const qrcode = require("qrcode-terminal");
const { Client, LocalAuth, MessageMedia } = require("whatsapp-web.js");
const axios = require("axios");
async function QueryMessage(message) {
// performs certain task:
}
const client = new Client({
authStrategy: new LocalAuth(),
});
client.initialize();
client.on("qr", (qr) => {
qrcode.generate(qr, { small: true });
});
client.on("authenticated", () => {
console.log("AUTHENTICATED");
});
client.on("ready", () => {
console.log("Client is ready!");
});
const sendMessage = async (chat, message) => {
await chat.sendMessage(await QueryMessage(message));
};
//Replying Messages with image from url
client.on("message", async (message) => {
const chat = await message.getChat();
if (!chat.isGroup) {
sendMessage(chat, message.body);
}
});

MongoMemoryServer: Instance closed unexpectedly in supertest for express app

I am trying to use Mongo Memory Server in supertest to test my API, but I get the following error:
Starting the MongoMemoryServer Instance failed, enable debug log for more information. Error:
UnexpectedCloseError: Instance closed unexpectedly with code "1" and signal "null"
at MongoInstance.closeHandler (/home/jonathanpotter/code/express-apps/rest-api-tutorial/node_modules/mongodb-memory-server-core/src/util/MongoInstance.ts:543:52)
at ChildProcess.emit (node:events:513:28)
at ChildProcess.emit (node:domain:489:12)
at maybeClose (node:internal/child_process:1091:16)
at Socket.<anonymous> (node:internal/child_process:449:11)
at Socket.emit (node:events:513:28)
at Socket.emit (node:domain:489:12)
at Pipe.<anonymous> (node:net:313:12)
My test is as follows:
import supertest from "supertest";
import createServer from "../utils/server";
import { MongoMemoryServer } from "mongodb-memory-server";
import mongoose from "mongoose";
const app = createServer();
describe("product", () => {
beforeAll(async () => {
const mongoServer = await MongoMemoryServer.create();
await mongoose.connect(mongoServer.getUri());
});
afterAll(async () => {
await mongoose.disconnect();
await mongoose.connection.close();
});
describe("get product", () => {
describe("given the product does not exist", () => {
it("should return a 404", async () => {
const productId = "product123";
await supertest(app).get(`/api/products/${productId}`);
});
});
});
});
My testing dependencies are:
"jest": "^29.3.1",
"mongodb-memory-server": "^8.10.2",
"supertest": "^6.3.3",
"ts-jest": "^29.0.3",
"ts-node-dev": "^2.0.0",
...and I my operating system is Pop!_OS 22.04 LTS.
edit: This all works fine on my Mac, but not on my Linux machine. Does anyone know of a fix for Linux (Pop!OS)?

Jest throws error from jsdom when testing Vue comoponent: Error: Error: connect ECONNREFUSED 127.0.0.1:80

I am new to Vue and Jest, and what I want to do is to test the following XXX.vue component. And the error "Error: Error: connect ECONNREFUSED 127.0.0.1:80" that I mentioned was throw from the part 'renders correctly with different data' (I have narrowed it down by commenting out other tests in the file, so I am sure the error was thrown from the part.
Another questions is that, by running the test multiple times, it may output 3 results:
throw error: Error: Error: connect ECONNREFUSED 127.0.0.1:80 from jsdom
console.error node_modules/jest-environment-jsdom-fifteen/node_modules/jsdom/lib/jsdom/virtual-console.js:29
Error: Error: connect ECONNREFUSED 127.0.0.1:80
at Object.dispatchError (/Users/jingjiejiang/Documents/My_Project/Tech_Test_Assemble/rakuten_test/rtx-cdt-test-v2/client/node_modules/jest-environment-jsdom-fifteen/node_modules/jsdom/lib/jsdom/living/xhr-utils.js:54:19)
at Request.<anonymous> (/Users/jingjiejiang/Documents/My_Project/Tech_Test_Assemble/rakuten_test/rtx-cdt-test-v2/client/node_modules/jest-environment-jsdom-fifteen/node_modules/jsdom/lib/jsdom/living/xmlhttprequest.js:675:20)
at Request.emit (node:events:525:35)
at Request.onRequestError (/Users/jingjiejiang/Documents/My_Project/Tech_Test_Assemble/rakuten_test/rtx-cdt-test-v2/client/node_modules/request/request.js:877:8)
at ClientRequest.emit (node:events:513:28)
at Socket.socketErrorListener (node:_http_client:481:9)
at Socket.emit (node:events:513:28)
at emitErrorNT (node:internal/streams/destroy:151:8)
at emitErrorCloseNT (node:internal/streams/destroy:116:3)
at processTicksAndRejections (node:internal/process/task_queues:82:21) undefined
throw "Network error: renders correctly with different data"
● Mounted About › renders correctly with different data
Network Error
at createError (node_modules/axios/lib/core/createError.js:16:15)
at XMLHttpRequest.handleError (node_modules/axios/lib/adapters/xhr.js:117:14)
at Request.onRequestError (node_modules/request/request.js:877:8)
pass the test.
Question:
How to troubleshoot the issue? Thank you so much in advance.
Vue component: XXX.vue:
<template>
<div class="about">
<el-table :data="displayHotels" stripe style="width: 100%">
<el-table-column
prop="property.name"
label="Name"
width="300">
</el-table-column>
<el-table-column
prop="property.location.country"
label="Location"
width="180">
</el-table-column>
<el-table-column prop="property.reviews.summary.score" label="Score">
</el-table-column>
</el-table>
<el-pagination
:page-size="pageSize"
:pager-count="pagerCount"
#current-change="handleCurrentChange"
layout="prev, pager, next"
:total="displayHotelsNum">
</el-pagination>
</div>
</template>
<script>
// import { ref, computed } from 'vue';
import axios from 'axios';
export default {
data() {
return {
hotels: [],
page: 1,
pageSize: 5,
};
},
computed: {
...
},
mounted() {
axios.get('/api/fromSource')
.then((res) => {
this.hotels = res?.data?.outlets?.availability?.results;
});
},
methods: {
handleCurrentChange(pageNum) {
this.page = pageNum;
},
// Filter the data where the record does not have country and/or score
filteredHotels() {
...
},
},
};
</script>
Jest settings
module.exports = {
preset: '#vue/cli-plugin-unit-jest',
transform: {
'^.+\\.vue$': 'vue-jest',
},
};
Jest test file
import { mount } from '#vue/test-utils';
import { readFile } from 'fs/promises';
import rootPath from 'app-root-path';
import path from 'path';
import About from '../../src/views/About.vue';
/**
*
* The unit tests for About.vue.
*
*/
describe('About', () => {
it('has data', () => {
expect(typeof About.data).toBe('function');
});
});
describe('Mounted About', () => {
const wrapper = mount(About);
// afterEach(() => {
// wrapper.unmount();
// });
test('does a wrapper exist', () => {
...
});
// Check if the html page are correctly renderred
it('renders the correct table', () => {
...
});
it('renders correctly with different data', async () => {
const res = await readFile('./tests/utils/sample_data.json', 'utf8');
const hotelData = JSON.parse(res);
wrapper.setData({
hotels: [hotelData],
page: 1,
pageSize: 5,
});
// expect(1).toEqual(1);
);
}, 10000);
});

Next JS - How to fix Error: connect ECONNREFUSED 127.0.0.1:3003 at TCPConnectWrap.afterConnect [as oncomplete]

I am new to Next JS.
I can't build my application locally. When I enter the npm run build command I get the following errors :
...
_currentUrl: 'http://localhost:3003/data/menus.json',
[Symbol(kCapture)]: false
},
response: undefined,
isAxiosError: true,
toJSON: [Function: toJSON]
}
Error: connect ECONNREFUSED 127.0.0.1:3003
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1148:16) {
errno: -4078,
code: 'ECONNREFUSED',
syscall: 'connect',
address: '127.0.0.1',
port: 3003,
config: {
url: 'http://localhost:3003/data/menus.json',
method: 'get',
headers: {
Accept: 'application/json, text/plain, */*',
'User-Agent': 'axios/0.21.4'
},
transformRequest: [ [Function: transformRequest] ],
transformResponse: [ [Function: transformResponse] ],
timeout: 0,
adapter: [Function: httpAdapter],
...
Et à la fin du log
...
info - Generating static pages (771/771)
> Build error occurred
Error: Export encountered errors on following paths:
/ar
/ar/classic
/ar/minimal
/ar/standard
/ar/vintage
/de
/de/classic
/de/minimal
/de/standard
/de/vintage
/en
/en/classic
/en/minimal
/en/standard
/en/vintage
/es
/es/classic
/es/minimal
/es/standard
/es/vintage
/fr
/fr/classic
/fr/minimal
/fr/standard
/fr/vintage
/he
/he/classic
/he/minimal
/he/standard
/he/vintage
/zh
/zh/classic
/zh/minimal
/zh/standard
/zh/vintage
at C:\Users\PC\OneDrive\Documents\lab\samara\laravel\node_modules\next\dist\export\index.js:487:19
at runMicrotasks (<anonymous>)
at processTicksAndRejections (internal/process/task_queues.js:95:5)
at async Span.traceAsyncFn (C:\Users\PC\OneDrive\Documents\lab\samara\laravel\node_modules\next\dist\telemetry\trace\trace.js:60:20)
at async C:\Users\PC\OneDrive\Documents\lab\samara\laravel\node_modules\next\dist\build\index.js:833:17
at async Span.traceAsyncFn (C:\Users\PC\OneDrive\Documents\lab\samara\laravel\node_modules\next\dist\telemetry\trace\trace.js:60:20)
at async C:\Users\PC\OneDrive\Documents\lab\samara\laravel\node_modules\next\dist\build\index.js:707:13
at async Span.traceAsyncFn (C:\Users\PC\OneDrive\Documents\lab\samara\laravel\node_modules\next\dist\telemetry\trace\trace.js:60:20)
at async Object.build [as default] (C:\Users\PC\OneDrive\Documents\lab\samara\laravel\node_modules\next\dist\build\index.js:77:25)
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
error Command failed.
Exit code: 1
Command: C:\Program Files\nodejs\node.exe
Arguments: C:\Users\PC\.node\corepack\yarn\1.22.15\lib\cli.js build
Directory: C:\Users\PC\OneDrive\Documents\lab\samara\laravel\shop
Output:
info Visit https://yarnpkg.com/en/docs/cli/workspace for documentation about this command.
error Command failed with exit code 1.
The npm run dev command works without any problem. So locally the application has no problem. But when I go to production, I want to build I get these errors above.
Here is my server.js file:
// server.js
const { createServer } = require('http');
const { parse } = require('url');
const next = require('next');
const dev = process.env.NODE_ENV !== 'production';
const hostname = 'localhost';
const port = 3003;
// when using middleware `hostname` and `port` must be provided below
const app = next({ dev, hostname, port });
const handle = app.getRequestHandler();
app.prepare().then(() => {
createServer(async (req, res) => {
try {
// Be sure to pass `true` as the second argument to `url.parse`.
// This tells it to parse the query portion of the URL.
const parsedUrl = parse(req.url, true);
const { pathname, query } = parsedUrl;
if (pathname === '/a') {
await app.render(req, res, '/a', query);
} else if (pathname === '/b') {
await app.render(req, res, '/b', query);
} else {
await handle(req, res, parsedUrl);
}
} catch (err) {
console.error('Error occurred handling', req.url, err);
res.statusCode = 500;
res.end('internal server error');
}
}).listen(port, (err) => {
if (err) throw err;
console.log(`> Ready on http://${hostname}:${port}`);
});
});
And my package.json file
{
"name": "#samara/shop",
"version": "1.1.0",
"private": true,
"scripts": {
"dev": "next dev -p 3003",
"build": "next build",
"start": "NODE_ENV=production node server.js"
If you need another file to check let me know.
I don't know if it's the best way but in my case I run npm run dev then run npm run build and the error stops happening
then stop the dev and run npm run start
you can also add a try catch in the api call http://localhost:3003/data/menus.json
if you are calling in a getStaticProps function, you can in the catch set the revalidity to 1 second if you need to revalidate
This one is a duplicate of a:
ECONNREFUSED during 'next build'. Works fine with 'next dev'
The issue is explained quite well in this thread.
Essentially as the comment states:
You should not fetch an API route from getStaticProps...
Please check also Ciro Santilli answer, he gives more details to the issue

Supertest: You are trying to `import` a file after the Jest environment has been torn down

I'm using supertest to test api route in a node/typescript application. The server crashes with this error:
ReferenceError: You are trying to import a file after the Jest environment has been torn down.
Here is the test:
import request from "supertest";
import { server } from "../index";
describe("GET /user/:id", () => {
it("return user information", (done) => {
request(server)
.get("/user/123")
.set("Cookie", ["_id=567;locale=en"])
.expect(200, done);
});
});
The jest config (which has a linter error: 'module' is not defined.)
module.exports = {
roots: ["<rootDir>/src"],
testMatch: [
"**/__tests__/**/*.+(ts|tsx|js)",
"**/?(*.)+(spec|test).+(ts|tsx|js)",
],
transform: {
"^.+\\.(ts|tsx)$": "ts-jest",
},
testEnvironment: "node",
};
How to fix this?

Resources