Reader small image

You're reading from  Mastering React Test-Driven Development - Second Edition

Product typeBook
Published inSep 2022
Reading LevelIntermediate
PublisherPackt
ISBN-139781803247120
Edition2nd Edition
Languages
Tools
Right arrow
Author (1)
Daniel Irvine
Daniel Irvine
author image
Daniel Irvine

Daniel Irvine is a UK-based software consultant. He helps businesses simplify their existing codebases and assists dev teams in improving the quality of their software using eXtreme programming (XP) practices. He has been coaching developers for many years and co-founded the Queer Code London meetup.
Read more about Daniel Irvine

Right arrow

Form Validation

For many programmers, TDD makes sense when it involves toy programs that they learn in a training environment. But they find it hard to join the dots when they are faced with the complexity of real-world programs. The purpose of this part of this book is for you to apply the techniques you’ve learned to real-world applications.

This chapter takes a somewhat self-indulgent journey into form validation. Normally, with React, you’d reach for a ready-made form library that handles validation for you. But in this chapter, we’ll hand-craft our own validation logic, as an example of how real-world complexity can be conquered with TDD.

You will uncover an important architectural principle when dealing with frameworks such as React: take every opportunity to move logic out of framework-controlled components and into plain JavaScript objects.

In this chapter, we will cover the following topics:

  • Performing client-side validation
  • Handling...

Technical requirements

Performing client-side validation

In this section, we’ll update the CustomerForm and AppointmentForm components so that they alert the user to any issues with the text they’ve entered. For example, if they enter non-digit characters into the phone number field, the application will display an error.

We’ll listen for the DOM’s blur event on each field to take the current field value and run our validation rules on it.

Any validation errors will be stored as strings, such as First name is required, within a validationErrors state variable. Each field has a key in this object. An undefined value (or absence of a value) represents no validation error, and a string value represents an error. Here’s an example:

{
  firstName: "First name is required",
  lastName: undefined,
  phoneNumber: "Phone number must contain only numbers, spaces, and any of the following: + - ( ) ."
}

This error is rendered...

Handling server errors

The /customers endpoint may return a 422 Unprocessable Entity error if the customer data failed the validation process. This could happen if, for example, the phone number already exists within the system. If this happens, we want to withhold calling the onSave callback and instead display the errors to the user and give them the chance to correct them.

The body of the response will contain error data very similar to the data we’ve built for the validation framework. Here’s an example of the JSON that would be received:

{
  "errors": {
    "phoneNumber": "Phone number already exists in the system"
  }
}

We’ll update our code to display these errors in the same way our client errors appeared. Since we already handle errors for CustomerForm, we’ll need to adjust our tests in addition to the existing CustomerForm code.

Our code to date has made use of the...

Indicating form submission status

It’d be great if we could indicate to the user that their form data is being sent to our application servers. The GitHub repository for this book contains a spinner graphic and some CSS that we can use. All that our React component needs to do is display a span element with a class name of submittingIndicator.

Before we write out the tests, let’s look at how the production code will work. We will introduce a new submitting boolean state variable that is used to toggle between states. It will be toggled to true just before we perform the fetch request and toggled to false once the request completes. Here’s how we’ll modify handleSubmit:

...
if (!anyErrors(validationResult)) {
  setSubmitting(true);
  const result = await global.fetch(...);
  setSubmitting(false);
  ...
}
...

If submitting is set to true, then we will render the spinner graphic. Otherwise, we will render nothing...

Summary

This chapter has shown you how TDD can be applied beyond just toy examples. Although you may not ever want to implement form validation yourself, you can see how complex code can be test-driven using the same methods that you learned in the first part of this book.

First, you learned how to validate field values at an appropriate moment: when fields lose focus and when forms are submitted. You also saw how server-side errors can be integrated into that, and how to display an indicator to show the user that data is in the process of being saved.

This chapter also covered how to move logic from your React components into their own modules.

In the next chapter, we’ll add a new feature to our system: a snazzy search interface.

Exercises

The following are some exercises for you to complete:

  1. Add a feature that clears any validation errors when the user corrects them. Use the onChange handler for this rather than onBlur, since we want to let the user know as soon as they’ve corrected the error.
  2. Add a feature that disables the submit button once the form has been submitted.
  3. Write tests for each of the functions within the formValidation module.
  4. The handleSubmit function is long. Extract a doSave function that pulls out the main body of the if statement.

Further reading

To learn more about the topics that were covered in this chapter, take a look at the following resources:

  • A guide to regular expressions, explained by examples

https://reacttdd.com/testing-regular-expressions

  • More information on ARIA annotations such as aria-describedby

https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Annotations

lock icon
The rest of the chapter is locked
You have been reading a chapter from
Mastering React Test-Driven Development - Second Edition
Published in: Sep 2022Publisher: PacktISBN-13: 9781803247120
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
undefined
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at €14.99/month. Cancel anytime

Author (1)

author image
Daniel Irvine

Daniel Irvine is a UK-based software consultant. He helps businesses simplify their existing codebases and assists dev teams in improving the quality of their software using eXtreme programming (XP) practices. He has been coaching developers for many years and co-founded the Queer Code London meetup.
Read more about Daniel Irvine