Mocha test failing to trigger function execution

I've been developing an Express.js application that includes a feature for creating appointments with a post request. This feature involves retrieving and saving data from a third-party API, followed by sending updated API data in the subsequent request. Everything seems to be working fine, except during testing, the function responsible for fetching API data is not being called.

Here is the route to create an appointment:

app.post('/schedule', requestHandler.postSchedule);

This is the request handler for creating an appointment:

requestHandler.postSchedule = function (req, res) {
  let appointment = {
    // posted data
  };

  new Appointment(appointment)
    .save()
    .then(newAppointment => {
      if(req.body.cityName && req.body.cityName !== '') {
        console.log('req.body.cityName', req.body.cityName);
        weatherHelper.addNewCityWeatherData(req.body.cityName);
      }
      return newAppointment;
    })
    .then(newAppointment => {
      // perform other tasks
      res.send(newAppointment);
    })
    .catch(err => {
      error(err);
    });
};

The function used to add weather data looks like this:

exports.addNewCityWeatherData = (city) => {
  console.log('City in addNewCityWeatherData', city);
  getCurrentTrackingCities(cities => {
    if(cities.indexOf(city) < 0) {
      console.log(city + ' data not in weather');
      getWeatherData(city, data => {
        console.log('Got weather data');
        addWeatherDataToDB(city, data);
      });
    } else {
      console.log('City exists');
    }
  });
};

And here is the function for getting weather data from the API:

getWeatherData = (city, callback) => {
  console.log('getWeatherData called', city);
  let url = `http://api.apixu.com/v1/forecast.json?key=${weatherApiKey}&q=${city}&days=${10}`
  request(url, (err, res, body) => {
    console.log('Weather data received body');
    callback(body);
  });
};

During testing, this particular feature fails, as all console logs are printed except for 'Weather data received body' and the logs in subsequent functions.

Below is my test script:

describe.only('Weather data', function() {
  let requestWithSession = request.defaults({jar: true});

  let hashedPass = bcrypt.hashSync('testpass', null);

  beforeEach((done) => {
    new User({
      'name': 'Test User',
      'email': '<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="93e7f6e0e7e6e0f6e1d3e7f6e0e7bdf0fcfe">[email protected]</a>',
      'password': hashedPass
    })
    .save()
    .then(() => {
      let options = {
        'method': 'POST',
        'uri': testHost + '/login',
        'form': {
          'email': '<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="97e3f2e4e3e2e4f2e5d7e3f2e4e3b9f4f8fa">[email protected]</a>',
          'password': 'testpass'
        }
      };
      requestWithSession(options, (err, res, body) => {
        done();
      });
    });
  }); // beforeEach

  afterEach((done) => {
    // remove test stuff from db
  }); // afterEach

  it('Adds weather data when an appointment with new city is posted', (done) => {
    let options = {
      'method': 'POST',
      'uri': testHost + '/schedule',
      'form': {
        'title': 'Test title',
        'description': 'Test description',
        'start_date_time': '2017-07-19 01:00',
        'end_date_time': '2017-07-19 02:00',
        'cityName': 'New York',
        'isTrackingWeather': 'true'
      }
    };

  
    requestWithSession(options, (err, res, body) => {
      if(err) {
        console.log('DatabaseError in Weather Data');
        throw {
          type: 'DatabaseError',
          message: 'Failed to create test setup data'
        };
      }

      let options = {
        'method': 'GET',
        'uri': testHost + '/allweather'
      };

     
      requestWithSession(options, (err, res, body) => {
        let found = false;
        weatherData = JSON.parse(body);
        
        weatherData.forEach(weather => {
          if(weather.location && weather.location.name === 'New York') {
            found = true;
          }
        });
        expect(found).to.be.true;
        done();
      });

    });
  });
}); 

Here is the terminal output:

https://i.sstatic.net/1chfv.png

If anyone could provide insight into what I might be doing incorrectly, it would be greatly appreciated.

Answer №1

During the execution of your test, the test suite triggers a request to your test server. The code responsible for handling this request within your test server then proceeds to make an additional request to another host.

The issue arises when you do not observe the message 'Weather data received body' because the initial request handled by your test server does not pause or wait for the subsequent request made by the test server itself. Without any callbacks or promises returned by addNewCityWeatherData, the calling code simply continues executing without consideration for completion. To address this, adjustments should be made to allow the calling code to await a response.

Furthermore, it is unclear how the information obtained from the request initiated by your test server is integrated back into the original request sent by your test suite. Additional coding may be necessary unless addWeatherDataToDB(city, data); incorporates this process automatically in some manner.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Iterate over the JSON data and evaluate the timestamps for comparison

I am attempting to iterate through this JSON data and compare the "start_time" and "end_time" values to ensure that there are no overlaps. However, I am struggling to implement this functionality. While researching, I came across a resource on how to vali ...

Uncovering the unique properties of custom Items in MUI v5 - RichTreeView: A Step-by-Step Guide

Can custom item properties received asynchronously with MUI - RichTreeView be exposed inside a custom treeItem? For instance, how can the customProperty1 and customProperty2 be accessed within the CustomTreeItem? The console.log to props only shows defaul ...

Do we really need Renderer2 in Angular?

Angular utilizes the Renderer2 class to manipulate our view, acting as a protective shield between Angular and the DOM, making it possible for us to modify elements without directly interacting with the DOM ourselves. ElementRef provides another way to al ...

Unlocking the Power of VueJS Mixins in an External JS Library

I'm currently using a 'commonLibrary.js' in my Vue application. One of the functions in this library that I find particularly useful is: var defaultDecimalRounding=3 function formatNumber(number) { if (isNaN(number.value) == tr ...

Unable to establish a connection with Mongoose on localhost

I'm currently working on establishing a connection to my database using mongoose within Apollo-Server-Express. Following the creation of a db in the terminal, I understood that 'mongodb://localhost:27017/*db-name*' serves as the default uri- ...

The XMLHttpRequest encountered an error: "Failed to establish a connection with the Parse API". Error codes 141 and 100 were generated as a result

We are currently in the process of transferring our iOs application from Parse to AWS. When using Curl, we are able to access certain functions, but encounter errors otherwise. Below is the content of the index.js file. Any guidance on what might be incorr ...

Can we dynamically add an identical DOM structure by clicking a button using jQuery?

I currently have ten text fields within a single div. I am interested in including another set of ten text fields with the same name, class, and id. Is there a way to recycle the existing DOM structure mentioned above, or will I need to generate and add t ...

Strange behavior observed when resizing objects in Three.js WebGl

Everything was going smoothly with my code until I decided to enable WebGL. It seems that the function responsible for resizing my object every frame rate stopped working. function animate(){ window.requestAnimationFrame(animate); s.setPositio ...

What is the process for changing proxy settings through the command line when using Create React App?

I recently created a React project using Create React App and set up the development server to proxy API requests through the proxy setting in my package.json: ... "proxy": "https://dev-backend.example.com" ... However, I am looking ...

Safari's problem with CSS transitions

This issue is specific to Safari, as it has been tested and works fine in Chrome, Opera, and Firefox. Upon hovering over a certain div (1), a child div (2) slides out by adjusting the left property. However, the child elements (buttons) within the second ...

No matter the method used for sending, the request body from post always returns as undefined

I have encountered a problem where none of the existing answers have helped me resolve it. I am attempting to pass a variable through ajax in the following manner: var myData = "Hi Og"; $.ajax({ type: 'POST', data: myData, url: &a ...

Throttle the RxJs interval based on the inner observables

Sorry if the way I am asking this question is not clear, I am having difficulty finding the right words to explain it. I am currently working on Selenium automation and here is how the process goes:- Go to a specific page Every 1 second, check if the pag ...

Steps for adding an array of JSON objects into a single JSON object

I have a JSON array that looks like this: var finalResponse2 = [ {Transaction Amount: {type: "number"}}, {UTR number: {type: "string"}} ] My goal is to convert it into the following format: responses : [ { Transaction Amount: {type: "number"}, UTR numbe ...

Executing simultaneous asynchronous queries with Mongoose results in an error: `SyntaxError: Illegal return statement` due to

My goal is to make multiple asynchronous requests to Mongo using Mongoose in parallel. To achieve this, I created a helper function that handles these queries dynamically without knowing the exact number beforehand. While my current implementation works ...

Navigating between multiple Angular applications using Express

In my project, I am facing an issue with the file structure. I have a server folder and a client folder which includes two Angular apps: one for the website and one for the dashboard. If you want to check out the code, it's available at this link. A ...

What is the best way to utilize typed variables as types with identical names in Typescript?

Utilizing THREE.js with Typescript allows you to use identical names for types and code. For instance: import * as THREE from '/build/three.module.js' // The following line employs THREE.Scene as type and code const scene: THREE.Scene = new THRE ...

Javascript Array Dilemmas

The current task; Determine whether the first string in the array contains all the letters of the second string. For instance, ['hello', 'Hello'] should result in true as all letters from the second string are found in the first, rega ...

Deciphering the intricacies of using middleware in Express -

As a novice, I find it challenging to interpret documentation, but I can grasp the code's meaning once I see it in action. Take app.use([path,] callback [, callback...]), for example. I know how to utilize this method, yet I still struggle with unde ...

Encountering HTTP 504 error while using AWS ELBs in conjunction with nginx reverse

My node/express app is running in a Fargate container, serving static files (html/css/js) and hosting an API. The network setup in front of it is as follows: (WAN) ---> (HTTPS HTTP/2) Proxy ELB ---> (HTTP HTTP/1) nginx reverse proxy ---> (HTTPS H ...

What could be causing this error in a new Next.js application?

After multiple attempts, my frustration and disappointment in myself are causing a headache. Can someone please assist me? I am trying to create an app using the following command: npx create-next-app@latest --ts Immediately after running next dev, I enco ...