Home > Blockchain >  Test a POST Http request from a local node server in REACT
Test a POST Http request from a local node server in REACT

Time:02-13

I need to make unit tests for some post requests but i dont understand how.I tried with mswjs but the test passes because i'm missing something and i dont know what.I tried to test the requests in an usual way but i wasnt able to put my conditions there and it was sending only 200 status code..
To start with,this is my folder structure:

 main folder  
  nodeServer  
   public  
   routes  
  public  
  src  
   tests  

This is my try for testing the post request to /subscribe endpoint,where i should send an email as a payload and get the response that the payload was received succesefully.
subscribeFetch.test.js:

import {setupServer} from 'msw/node'
import {rest} from 'msw'

const handlers = [
    rest.post("/api/subscribe",(req,res,context)=>{

                if (!req.body || !req.body.email) {
                  return res(context.status(400).json({ error: "Wrong payload" }));
                }
            
                if (req.body.email === '[email protected]') {
                  return res(context.status(422).json({ error: "Email is already in use" }));
                }
        
                return res(
                    context.status(200),
                    context.json({email:'[email protected]'})
                )

    })
]

const server = setupServer(...handlers)

beforeAll(()=>server.listen())
afterAll(()=>server.close())
afterEach(()=>server.resetHandlers())

test('should send post request to the server',async()=>{
    server.use(
        rest.post('/api/subscribe',(req,res,ctx)=>{
            return res(
                expect (ctx.status()).toBe(200)
            )
        }
        )
    )
})

//export {handlers,rest}  

This is the subscribe post request function that i need to test:

import { validateEmail } from './email-validator.js'

export const sendSubscribe = (emailInput) => {
  const isValidEmail = validateEmail(emailInput)
  if (isValidEmail === true) {
    sendData(emailInput)
  }
}

export const sendHttpRequest = (method, url, data) => {
  return fetch(url, {
    method: method,
    body: JSON.stringify(data),
    headers: data
      ? {
        'Content-Type': 'application/json'
      }
      : {}
  }).then(response => {
    if (response.status >= 400) {
      return response.json().then(errResData => {
        const error = new Error('Something went wrong!')
        error.data = errResData
        throw error
      })
    }
    return response.json()
  })
}

const sendData = (emailInput) => {
  sendHttpRequest('POST', '/api/subscribe', {
    email: emailInput
  }).then(responseData => {
    return responseData
  }).catch(err => {
    console.log(err, err.data)
    window.alert(err.data.error)
  })
}

Files from the server:
app.js:

const express = require('express');
const path = require('path');
const cookieParser = require('cookie-parser');
const logger = require('morgan');

const indexRouter = require('./routes/index');
const communityRouter = require('./routes/community');
const analyticsRouter = require('./routes/analytics');

const app = express();
global.appRoot = path.resolve(__dirname);

app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

app.use('/', indexRouter);
app.use('/community', communityRouter);
app.use('/analytics', analyticsRouter);

module.exports = app;

index.js from routes folder in the server folder:

const express = require('express');
const router = express.Router();
const FileStorage = require('../services/FileStorage');

/* POST /subscribe */
router.post('/subscribe', async function (req, res) {
  try {
    if (!req.body || !req.body.email) {
      return res.status(400).json({ error: "Wrong payload" });
    }

    if (req.body.email === '[email protected]') {
      return res.status(422).json({ error: "Email is already in use" });
    }

    const data = {email: req.body.email};
    await FileStorage.writeFile('user.json', data);
    await res.json({success: true})
  } catch (e) {
    console.log(e);
    res.status(500).send('Internal error');
  }
});

/* GET /unsubscribe */
router.post('/unsubscribe', async function (req, res) {
  try {
    await FileStorage.deleteFile('user.json');
    await FileStorage.writeFile('user-analytics.json', []);
    await FileStorage.writeFile('performance-analytics.json', []);
    await res.json({success: true})
  } catch (e) {
    console.log(e);
    res.status(500).send('Internal error');
  }
});

module.exports = router;  

Please guys,help me write unit test for subscribe endpoint to match the conditions from index.js file from routes folder in the server folder,thank you in advance!

CodePudding user response:

So,i got the expected result without any library,but i dont know if its a good aproach,but at least it works :
const app = require('../../../personal-website-server/app') const request = require('supertest')

describe('POST /subscribe', () => {
    it('should give 400 status code when email is empty', async () => {
        const email = { email: '' }
        const response = await request(app).post('/subscribe').send(email)
        if (!request.body || !request.body.email) {
            expect(response.status).toBe(400)
        }
    })
    it('should give 422 status code when email is forbidden', async () => {
        const email = { email: '[email protected]' }
        const response = await request(app).post('/subscribe').send(email)
        if (request.body === '[email protected]') {
            expect(response.status).toBe(422)
        }
    })
    it('should give 200 status code when email is valid', async () => {
        const email = { email: '[email protected]' }
        const response = await request(app).post('/subscribe').send(email)
        expect(response.error).toBe(false)
        expect(response.status).toBe(200)
        expect(response.body.body).not.toBeNull()
    })
})
  • Related