Checking for required fields

In our requirements, we specified that in order to create a user account, the client must provide at least the email and password fields. So, let's write a test for this.

In our spec/cucumber/features/users/create/main.feature file, add the following scenario outline:

Scenario Outline: Bad Request Payload

When the client creates a POST request to /users
And attaches a Create User payload which is missing the <missingFields> field
And sends the request
Then our API should respond with a 400 HTTP status code
And the payload of the response should be a JSON object
And contains a message property which says "Payload must contain at least the email and password fields"

Examples:

| missingFields |
| email |
| password |

Apart from the second step, And attaches a Create User payload which is missing the <missingFields> field, every other step has already been implemented. The missing step should attach a dummy user payload, but then remove the specified property. Try implementing the logic of this step definition yourself, and compare it with the following solution:

When(/^attaches an? (.+) payload which is missing the ([a-zA-Z0-9, ]+) fields?$/, function (payloadType, missingFields) {
const payload = {
email: 'e@ma.il',
password: 'password',
};
const fieldsToDelete = missingFields.split(',').map(s => s.trim()).filter(s => s !== '');
fieldsToDelete.forEach(field => delete payload[field]);
this.request
.send(JSON.stringify(payload))
.set('Content-Type', 'application/json');
});

In the step definition, we first extract the variables and convert the missingFields string into an array. We then loop through this array and delete each property from the payload object. Lastly, we feed this incomplete payload into the request as the payload.

If we run the test now, it will fail. This is because we have not implemented the validation logic inside our Create User handler. Once again, have a go at implementing it, and check back here for our solution:

// Inside the app.post('/users') callback
app.post('/users', (req, res, next) => {
if (
!Object.prototype.hasOwnProperty.call(req.body, 'email')
|| !Object.prototype.hasOwnProperty.call(req.body, 'password')
) {
res.status(400);
res.set('Content-Type', 'application/json');
res.json({ message: 'Payload must contain at least the email and password fields' });
}
next();
});

Now, all our tests will pass again:

$ yarn run test:e2e
.............................................................

10 scenarios (10 passed)
61 steps (61 passed)

Don't forget to commit these changes into Git:

$ git add -A && git commit -m "Check Create User endpoint for missing fields"