Mock Service Worker Error occurred while trying to proxy request - node.js

I am using MSW for my React app and am getting the following error when trying to run in mock mode;
Error occurred while trying to proxy request /api/myApi from localhost:3000 to { port: 8080 } (ECONNREFUSED) (https://nodejs.org/api/errors.html#errors_common_system_errors)
I am trying to use both for testing and as dev api server (mock data)
Not sure if there is additional config needed for proxying the request when running in mock mode.
Below is my command in package.json
"start:mock": "cross-env NODE_ENV=mock webpack serve --progress --config config/webpack.local.js",
Below is the code in src/index.js
import * as serviceWorker from './serviceWorker';
if (process.env.NODE_ENV === 'mock') {
const { worker } = require('./browser')
worker.start()
}
//src/browser.js
import { setupWorker } from 'msw'
import { handlers } from './testServer'
// This configures a Service Worker with the given request handlers.
export const worker = setupWorker(...handlers)
Below is src/testServer.js
import "whatwg-fetch";
import { rest } from "msw";
import { setupServer } from "msw/node";
import data from "./data";
const handlers = [
rest.get("http://localhost/api/myApi", (req, res, ctx) => {
return res(ctx.status(200), ctx.json(data));
})
];
// This configures a request mocking server with the given request handlers.
const server = setupServer(...handlers);
beforeAll(() => server.listen());
afterAll(() => server.close());
afterEach(() => server.resetHandlers());
export { server, rest, handlers};

Related

Inversify - Jest - call API endpoint to test auth guard

Iam using Inversify & inversify-express-utils for building an Express Server. I am new to testing(Jest).
I need to call API instead of calling the controller class so that I can test the AuthGuard and RolesGuard. I tried using supertest library. Iam facing some issues. Im pretty sure that I have a wrong test setup.
user.controller.spec.ts:
import 'reflect-metadata';
import { mock } from 'jest-mock-extended';
import request from 'supertest';
import { MailService } from '../../../shared/mail/mail. Service';
import { UserController } from '../controller/users.controller';
import { UserService } from '../service/users.service';
import { ValidationException } from '../../../core/exception';
import { createUserFixture, updateUserFixture, userFixture } from '../fixtures/userFixture';
import { bootstrap } from '../../../main';
const userServiceMock = mock<UserService>();
const mailServiceMock = mock<MailService>();
describe('Users Controller', () => {
let app: any;
let sut: UserController;
sut = new UserController(userServiceMock, mailServiceMock);
beforeEach(async () => {
app = await bootstrap();
});
test('should throw auth error', async () => {
const req = await request(app).get('/user');
console.log(req);
});
});
main.ts
import 'reflect-metadata';
import cors from 'cors';
import express, { NextFunction, Response, Request } from 'express';
import helmet from 'helmet';
import { InversifyExpressServer } from 'inversify-express-utils';
import { container } from './core/inversify/inversify.config';
import { Sql } from './database/sql';
import { GlobalErrorConfig } from './core/server';
export const bootstrap = () => new Promise((resolve) => {
/// /Connect to SQL Server
new Sql().connect();
/// Start Server
const server = new InversifyExpressServer(container);
server.setConfig((app) => {
app.use(express.json());
app.use(cors());
app.use(helmet());
});
/// Global Error Config
GlobalErrorConfig(server);
/// Build Server
const app = server.build();
app.listen(process.env.PORT || 5000, () => {
console.log(
`Server is running on http://localhost:${process.env.PORT || 5000}`,
);
resolve(app);
});
});
bootstrap();
While trying to start the test, I get these following error:
The error:
Jest trying to warn delayed logs.
Same controller name error(app working normally on npm start).
Jest warning a file import after Jest environment torn down.
I have no clue what went wrong. I would really appreciate if anyone points out the issue or suggesting me the proper Jest API testing setup. Thanks in advance.

Jest has detected the following 1 open handle potentially keeping Jest from exiting: ● TCPSERVERWRAP

I'm setting unit test for my nodejs app. To test the setup I have a very simple express route which looks as below
todo.ts
import { Router } from "express";
const router = Router();
router.get("/todo", async (req, res) => {
return res.status(200);
});
export default router;
Then I have created a folder _tests with a subfolder unit
todo.test.ts
/*
* #group unit
*/
import request, { SuperAgentTest } from "supertest";
import app from "../../../server";
let router: SuperAgentTest;
beforeAll(async () => {
router = request.agent(app);
});
afterAll(async () => {
await dbClose();
});
describe("ToDo API", () => {
// Test Case -> 200
it("Should return 200", async () => {
const result = await router.get("/todo");
expect(result.status).toEqual(200);
});
});
I have the script in my package.json to run the unit tests is
"test:unit": "jest --verbose --detectOpenHandles --group=unit",
Now when I'm running the test from cmd/bash npm run test:unit I keep getting the below error
Jest has detected the following 1 open handle potentially keeping Jest from exiting:
● TCPSERVERWRAP
What's is causing this & how to get rid of it?
Thanks!

Jest tests did not exit (one second) after the test run has completed using a simple Express application

I have a simple Express application that exposes a RESTful API. It uses Knex and Objection to access the database, and Jest / Supertest for testing the API.
I have a test that starts the server, fetches the available data from a given route and asserts the received values. Everything works fine, except that Jest never exits after executing this test.
This is my test:
import { app } from "../../src/application.js";
import { describe, expect, test } from "#jest/globals";
import request from "supertest";
describe("Customer Handler", () => {
test("should retrieve all existing customer(s)", async () => {
const expected = [
// ...real values here; omitted for brevity
];
const response = await request(app).get(`/api/customers`);
expect(response.statusCode).toStrictEqual(200);
expect(response.headers["content-type"]).toContain("application/json");
expect(response.body).toStrictEqual(expected);
});
});
The application.js file looks very much like a usual Express setup/configuration file:
import { CustomerHandler } from "./handler/customer.handler.js";
import connection from "../knexfile.js";
import express from "express";
import Knex from "knex";
import { Model } from "objection";
const app = express();
Model.knex(Knex(connection[process.env.NODE_ENV]));
// ...removed helmet and some other config for brevity
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use("/api/customers", CustomerHandler);
app.use((err, req, res, next) => {
res.status(err.status || 500);
res.json({
errors: {
error: err,
message: err.message,
},
});
next();
});
export { app };
I've tried --detectOpenHandles, but nothing else is printed in the console, so I can't see any hints about what the issue might be — which I suspect it's Knex / Objection because I'm using SQLite, so probably the connection to the database is not getting closed.
In the meantime I'm using --forceExit, but I would like to figure it out why is Jest not able to exit.
OK, looks like I was on the right track for this one.
Refactoring application.js to export the Knex object (after it's configured), and calling knex.destroy() after the test passes is the solution for this setup.
// application.js
...
const knex = Knex(connection[process.env.NODE_ENV]);
Model.knex(knex);
...
export { app, knex };
...then in the test(s), make sure you import knex and call destroy():
// customer.handler.test.js
import { app, knex } from "../../src/application.js";
import { afterAll, describe, expect, test } from "#jest/globals";
import request from "supertest";
describe("Customer Handler", () => {
afterAll(async () => {
await knex.destroy();
});
test("should retrieve all existing customer(s)", async () => {
const expected = [ /* ...real values here */ ];
...
expect(response.body).toStrictEqual(expected);
});
});

Network error: Failed to fetch on ionic react

it's the first time that i post on forums,
I really needs your help.
I'm stuck with a problem, I have an Ionic/React application, a Node.js application and a graphQL/Apollo API,
when i'm calling the graphql API from my browser it's all working fine but when i'm building the app with capacitor and running it on my Android device, I get "Network error: Failed to fetch".
Here is my client.ts code where i'm setting up my ApolloClient
import { ApolloClient } from 'apollo-client';
import { createHttpLink } from 'apollo-link-http';
import { setContext } from 'apollo-link-context';
import { InMemoryCache, NormalizedCacheObject } from 'apollo-cache-inmemory';
class RequestUtils {
clientApollo: any;
constructor() {
const httpLink = createHttpLink({
uri: 'http://192.168.1.86:4000/graphql'
});
const authLink = setContext((req, { headers }) => ({
headers: {
...headers
}
}));
this.clientApollo = new ApolloClient({
link: authLink.concat(httpLink),
cache: new InMemoryCache()
});
}
}
const requestUtils = new RequestUtils();
const client: ApolloClient<NormalizedCacheObject> = requestUtils.clientApollo;
export default client;
and here is my graphql.ts
import resolvers from "../resolvers/index";
import { ApolloServer, AuthenticationError } from "apollo-server-express";
import { getModels } from "../models/index";
import schemas from "../schemas/index";
import * as express from "express";
import * as cors from "cors";
import { connectToMongo } from "./config";
import { info, success, warning, error } from "./logger";
export class query {
public app: any;
constructor() {
const models = getModels();
this.app = express();
this.app.use(cors());
try {
info("Starting connection to graphql");
const server = new ApolloServer({
typeDefs: schemas,
resolvers,
context: async ({ req }) => {
if (req) {
return {
models: models
};
}
}
});
this.app = express();
server.applyMiddleware({ app: this.app, path: "/graphql" });
success(`Connected to graphql`);
} catch (error) {
warning(error);
}
this.app.listen(4000, () => {
connectToMongo();
});
}
}
I think that it's a problem with something like cors or ip adress but i don't find any solution to my problem.
I hope someone can help me !
EDIT:
I tried to run my node server on another computer and cal the graphql API from my main computer with my ionic react react webapp. The origin is in fact different but there is no error, all works perfectly. But with my builded app on my android device, always same error.
So, I think it's not cors, maybe it's something with Capacitor/cordova, or something like this.
At first, i thought android app wasn't allowed to connect to network, I checked and it's connected, but I'm not sure.
If someone could help me, it would be very sympathic , I'm really stuck with this, my app is useless if i can't connect to server en database XD
Had exactly the same problem.
It looks like the cause is that Android forbids HTTP requests by default.
The following fix worked for me:
To allow http requests, I added android:usesCleartextTraffic="true" to my app's AndroidManifest.xml
Solution post
I "solved" my problem by launching my app with " ionic capacitor run android -l --external "
I don't what will happens if the app is in production but at least I can progress in my dev.
I'll see later what happens ¯_(ツ)_/¯

typedi + fastify - initialize service asynchronously

I'm working on a nodejs fastify based app service and using typedi for dependency injection.
Some services I use need async initialization.
MyService.ts
export class MyService {
constructor() {
}
public async init() {
....
}
}
I am trying to initialize the service at application startup so that any service doing Container.get(MyService) gets this initialized instance of MyService
app.ts
export default async function(fastify: FastifyInstance, opts: Options, next: Function) {
// This loads everything under routes
fastify.register(autoload, {
dir: path.join(__dirname, "routes"),
options: opts,
includeTypeScript: true,
});
await Container.get(MyService);
next();
}
server.ts
import app from "./app";
const server = fastify({
logger: logger
});
server.register(oas, docs);
server.register(app);
server.ready(err => {
if (err) throw err;
server.oas();
});
server.listen(config.port, (err) => {
if (err) {
server.log.error(err);
process.exit(1);
}
server.log.info(`server listening on ${server.server.address()}`);
});
export default server;
My attempt to initialize MyService is failing.
MissingProvidedServiceTypeError [ServiceNotFoundError]: Cannot determine a class of the requesting service "undefined"
Any hints to what I'm doing wrong? I'm new to nodejs and would really appreciate sample code that is correct for this scenario.
Edit
I tried import
Container.import([CmkeService]);
MissingProvidedServiceTypeError [ServiceNotFoundError]: Cannot determine a class of the requesting service "undefined"

Resources