Refactoring our step definitions

Red. Green. Refactor. Now that all tests pass, it's a good time to refactor our code.

Our application code, although slightly repetitive, is easy to follow and read; therefore, we don't need to refactor it for now. There are, however, some improvements we can make to our test code. For example, we are hardcoding the Create User payload into our tests; it'll be better if we abstract that into a function that generates the payload when called.

We are going to create a new spec/cucumber/steps/utils.js file to house our utility/support code. Add the following into the utils.js file:

function getValidPayload(type) {
const lowercaseType = type.toLowerCase();
switch (lowercaseType) {
case 'create user':
return {
email: 'e@ma.il',
password: 'password',
};
default:
return undefined;
}
}

function convertStringToArray(string) {
return string
.split(',')
.map(s => s.trim())
.filter(s => s !== '');
}

export {
getValidPayload,
convertStringToArray,
};

Import it and use it in our test code. For example, the When(/^attaches an? (.+) payload where the ([a-zA-Z0-9, ]+) fields? (?:is|are) exactly (.+)$/) step definition would become this:

import { getValidPayload, convertStringToArray } from './utils';
...
When(/^attaches an? (.+) payload where the ([a-zA-Z0-9, ]+) fields? (?:is|are) exactly (.+)$/, function (payloadType, fields, value) {
this.requestPayload = getValidPayload(payloadType);
const fieldsToModify = convertStringToArray(fields);
fieldsToModify.forEach((field) => {
this.requestPayload[field] = value;
});
this.request
.send(JSON.stringify(this.requestPayload))
.set('Content-Type', 'application/json');
});

Do this for all other step definitions that use an endpoint-specific payload. After this, run the tests again and make sure they all still pass (because refactoring shouldn't modify the functionality), and then commit the changes to Git:

$ git add -A && git commit -m "Refactor test code"