Stock Checker Test Timeout Issues - InfoSec & QA Projects

Hi everyone.

I am currently working on the Stock Price Checker project in the InfoSec & QA Projects section. I am running into a timeout issue with my final test which searches for two stocks and sends like: true in the query. Here’s the test:

test('2 stocks with like', function(done){
        chai.request(server)
          .get('/api/stock-prices')
          .query({stock: ['goog', 'msft'], like: true})
          .end(function(err,res){
            assert.equal(res.status, 200);
            done();
          })
      })

I can’t even get this test to pass, which only expects a successful response status. The resulting error message is:

  1) Functional Tests

       GET /api/stock-prices => stockData object

         2 stocks with like:

     Error: Timeout of 2000ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves. (/app/tests/2_functional-tests.js)


This is strange because the previous test which handles getting two stocks (without like: true) is passing and has similar structure.

My code is pretty sloppy (refactoring will come later I suppose) but here is the relevant portion that handles getting two stocks:

app.route('/api/stock-prices')
    .get(async function (req, res){
      var query = req.query;
      var likeBool = query.like || false
      var ip = req.connection.remoteAddress.slice(7);
        if (Array.isArray(query.stock)){
          try {
            var stockArr = await getStockData(query.stock);
          } catch (err){return err}
          Stock.find({stock: { $in: [stockArr[0].stock, stockArr[1].stock]}},function(err, stocks){
            if (stocks === undefined){
              var stock1 = new Stock({
                stock: stockArr[0].stock,
                price: stockArr[0].price,
                likes: likeBool ? 1 : 0,
                ip: [ip]
              })
              stock1.save(err=>{
                if (err) return err;
              })
              var stock2 = new Stock({
                stock: stockArr[1].stock,
                price: stockArr[1].price,
                likes: likeBool ? 1 : 0,
                ip: [ip]
              })
              stock2.save(err=>{
                if (err) return err;
              }) 
              return res.json({stockData: [
                {stock: stock1.stock, price: stock1.price, rel_likes: stock1.likes - stock2.likes},
                {stock: stock2.stock, price: stock2.price, rel_likes: stock2.likes - stock1.likes}
              ]})
            } else if(stocks.length === 1 && stocks[0].stock !== stockArr[0].stock){
              if (stocks[0].stock === stockArr[1].stock){
                stocks[0].price = stockArr[1].price;
                if (likeBool){
                  if (!stocks[0].ip.includes(ip)){
                    stocks[0].ip.push(ip)
                    stocks[0].likes += 1;
                  }
                }
                stocks[0].save(err=>{
                  if (err) return res.json({error: err})
                })
              }
              var newStock = new Stock({
                stock: stockArr[0].stock,
                price: stockArr[0].price,
                likes: likeBool ? 1 : 0,
                ip: [ip]
              })
              newStock.save(err=>{
                if (err) return err
              })
              return res.json({stockData: [
                  {stock: newStock.stock, price: newStock.price, rel_likes: newStock.likes - stocks[0].likes},
                  {stock: stocks[0].stock, price: stocks[0].price, rel_likes: stocks[0].likes - newStock.likes}
                ]})
            } else if (stocks.length === 1 && stocks[0].stock !== stockArr[1].stock){
              if (stocks[0].stock === stockArr[0].stock){
                stocks[0].price = stockArr[0].price;
                if (likeBool){
                  if (!stocks[0].ip.includes(ip)){
                    stocks[0].ip.push(ip)
                    stocks[0].likes += 1;
                  }
                }
                stocks[0].save(err=>{
                  if (err) return res.json({error: err})
                })
              }
              var newStock = new Stock({
                stock: stockArr[1].stock,
                price: stockArr[1].price,
                likes: likeBool ? 1 : 0,
                ip: [ip]
              })
              newStock.save(err=>{
                if (err) return err
              })
              return res.json({stockData: [
                  {stock: newStock.stock, price: newStock.price, rel_likes: newStock.likes - stocks[0].likes},
                  {stock: stocks[0].stock, price: stocks[0].price, rel_likes: stocks[0].likes - newStock.likes}
                ]})
            } else {
              stocks[0].price = stockArr[0].price
              stocks[1].price = stockArr[1].price
              if (likeBool){
                if (!stocks[0].ip.includes(ip)){
                  stocks[0].ip.push(ip)
                  stocks[0].likes += 1;
                }
                if (!stocks[1].ip.includes(ip)){
                  stocks[0].ip.push(ip)
                  stocks[1].likes += 1;
                }
              }
              stocks[0].save(err=>{
                if (err) return res.json({error: err})
              })
              stocks[1].save(err=>{
                if (err) return res.json({error: err})
              })
              return res.json({stockData: [
                {stock: stocks[0].stock, price: stocks[0].price, rel_likes: stocks[0].likes - stocks[1].likes},
                {stock: stocks[1].stock, price: stocks[1].price, rel_likes: stocks[1].likes - stocks[0].likes}
              ]})
            }
          })
        }
})

Any ideas? I’m kind of at a loss on why adding that parameter (that I think? I’m handling correctly) causes a timeout.

My glitch code: https://glitch.com/edit/#!/warpfox-stock-checker

1 Like

I hope you get to read this even after 1 year. So, hey @warpfox, I’m currently working on the same project and struggling with the same functional test. The difference is that even if I pass two stock arguments to query(), which would be translated into GET /api/stock-prices?stock=amzn&stock=goog, the query() method only considers the last one, stock=goog. So my test is failling because the Chai API appears to not be working properly. The method console.log(res.body) proves my point.

test('2 stocks', function(done) {
        chai.request(server)
        .get('/api/stock-prices')
        .query({stock: 'amzn', stock: 'goog'}) //api/stock-prices?stock=amzn&stock=fb
        .end(function(err, res){
            assert.equal(res.status, 200);
            console.log(res.body);           
          done();
        });
      });

So the question is, am I doing something wrong or is it that the Chai API is bugged?