MegaRoks
MegaRoks

Reputation: 948

Tests with the multer library are not performed

I am testing adding products, I want to add 10 products, but the problem is that I cannot transfer the image to the https://www.npmjs.com/package/multer library.

My code is:

import { expect } from 'chai';
import chai from 'chai';
import chaiHttp from 'chai-http';
import server from '../src/index';
import db from '../src/db/database';

chai.use(chaiHttp);

import constants from './tool/constants';
import utils from './tool/utils';

let addProductCount = 10;

describe('Test products', () => {
    describe('POST /api/products/add', () => {
        it(`should create ${addProductCount} products with 0...1000 price`, (done) => {
            let operationCount = addProductCount;
            for (let i = 0; i < addProductCount; i++) {
                let product = utils.getFakeProduct(2, 1000);
                chai.request(server)
                    .post('api/products/add')
                    .set('token', constants.merchantToken)
                    .send(product)
                    .end((err, res) => {
                        operationCount--;
                        expect(res).have.status(200);
                        expect(res.body).have.property('message');
                        expect(res.body.message).to.be.equal('Product added');
                        if (operationCount == 0) {
                            done();
                        }
                    });
            }
        });
    });
});

...
function getFakeProduct(lowerPrice, upperPrice) {
    let currentDate = faker.date.recent();
    let original_price = getRandomInt(lowerPrice, upperPrice);
    return {
        product_name: faker.commerce.productName(),
        product_description: `${faker.commerce.productAdjective()} ${faker.commerce.productAdjective()}`,
        original_price,
        sale_price: original_price - getRandomInt(lowerPrice, original_price - 1),
        starting_date: currentDate,
        end_date: moment(currentDate).add(1, 'days'),
        product_photos: faker.image.image(),
        quantity_available: faker.random.number(50),
        categories: 'HOME APPLIANCES',
    };
}
...
//handles url http://localhost:8081/api/products/add/
router.post('/add', upload, validatorAdd, async (req, res) => {
        ...
        if (!req.files.product_photos) {
            return res.status(422).json({
                name: 'MulterError',
                message: 'Missing required image file',
                field: 'product_photos'
            });
        }
        let photos = addProductPhotos(req.files.product_photos);
        let user_id = 0;
        let product = new Product(
            user_id,
            req.body.product_name,
            req.body.product_description,
            req.body.original_price,
            req.body.sale_price,
            discount,
            moment().format(),
            req.body.starting_date,
            req.body.end_date,
            photos,
            req.body.quantity_available,
            req.body.categories,
            merchant_id,
        );
        await db.query(product.getAddProduct());
        return res.status(200).json({
            message: 'Product added'
        });
});

...
'use strict';

import multer, { memoryStorage } from 'multer';
import path from 'path';

let storage = memoryStorage()
let upload = multer({
    storage: storage,
    limits: {
        fileSize: 1000000
    },
    fileFilter: (req, file, cb) => {
        console.log(file)
        let ext = path.extname(file.originalname).toLowerCase();
        if (ext !== '.png' && ext !== '.jpg' && ext !== '.jpeg') {
            return cb(null, false);
        }
        cb(null, true);
    }
}).fields([{
        name: 'user_avatar',
        maxCount: 1
    },
    {
        name: 'product_photos',
        maxCount: 3
    },
    {
        name: 'store_photos',
        maxCount: 3
    }
]);

export default upload;
...

I get an error Uncaught TypeError: Cannot use 'in' operator to search for 'status' in undefined.

How to test the multer library? How to transfer the photo to the library so that the test runs? Why the test fails I ponma, problems with the image

Upvotes: 0

Views: 423

Answers (1)

aitchkhan
aitchkhan

Reputation: 1952

The problem is you are using faker.image.image() which returns an image link, which is not desired.

You need to add the attach() function to your chai.request() function for the files to be available for multer. If there are multiple files, then you need to add multiple attach() calls. Also, remove the parameter of files from getFakeProduct() to avoid any undesired errors.

const fs = require('fs');
chai
  .request(server)
  .post('api/products/add')
  .set('token', constants.merchantToken)
  .field('product_name', faker.commerce.productName())
  // .filed() ... etc
  .field('user[email]', '[email protected]')
  .field('friends[]', ['loki', 'jane'])
  .attach('product_photos', fs.readFileSync('/path/to/test.png'), 'test.png')
  .end((err, res) => {
    operationCount--;
    expect(res).have.status(200);
    expect(res.body).have.property('message');
    expect(res.body.message).to.be.equal('Product added');
    if (operationCount == 0) {
      done();
    }
  });

EDIT:

Since chai uses superagent under the hood. It is mentioned in their docs that you can not use attach() and send() together. You instead need to use field().

Example from the superagent documentation

 request
   .post('/upload')
   .field('user[name]', 'Tobi')
   .field('user[email]', '[email protected]')
   .field('friends[]', ['loki', 'jane'])
   .attach('image', 'path/to/tobi.png')
   .then(callback);

Upvotes: 1

Related Questions