HttpUnit Tutorial - create pool editor - step 2

Tutorial Task 1 Step 2: The pool editor form

# Examining a Form

In this step, you will learn how to:
• Extract a form from a web page, using its ID
• Examine form attributes
• Check text and radio button input fields
• Check form submit buttons

Now that we can invoke our servlet, the next step will be to produce the form in response to a GET command. This form will POST back to the same URL, allow for entry of 10 pairs of team names, allow for selection of a tie-breaker game, and allow the user to either save his entries or save them and open the betting pool. We can write a test for each of these required behaviors.

## Testing the Form action

Let us add the following test:

    public void testFormAction() throws Exception {
        ServletRunner sr = new ServletRunner( "web.xml" );
        ServletUnitClient client = sr.newClient();
        client.setAuthorization( "aUser", "pool-admin" );
        WebResponse response = client.getResponse( "http://localhost/PoolEditor" );

        WebForm form = response.getFormWithID( "pool" );               // (1) obtain the desired form
        assertNotNull( "No form found with ID 'pool'", form );
        assertEquals( "Form method", "POST", form.getMethod() );       // (2) verify that the form uses POST
        assertEquals( "Form action", "", form.getAction() );           // (3) verify that the default action is used
    }

The significant points in the code are:

1. Extracting the form from the page. In this case, we use the ID (which should be unique) attribute to find the form. We could also just ask for all the forms in the page and select the first one, but this skips the need to count the number of forms in the page. If the form is not present, we will just get a null value.
2. Checking that the form uses the POST method.
3. Checking that the form has no `action` attribute specified and will therefore default to the URL from which it was retrieved - in the case, the same servlet that produced it.

Again we run the test and fix the reported errors, one by one. The `printBody` method will now look like this:

    private void printBody( PrintWriter pw ) {
        pw.println( "<form id='pool' method='POST'>" );
        pw.println( "</form>" );
    }

and we now have two working tests.

## Testing the form contents

We can now test the input fields in the form:

    public void testFormContents() throws Exception {
        ServletRunner sr = new ServletRunner( "web.xml" );
        ServletUnitClient client = sr.newClient();
        client.setAuthorization( "aUser", "pool-admin" );
        WebResponse response = client.getResponse( "http://localhost/PoolEditor" );

        WebForm form = response.getFormWithID( "pool" );
        assertNotNull( "No form found with ID 'pool'", form );

        for (int i = 0; i < 10; i++) {
            assertTrue( "Missing home team " + i, form.isTextParameter( "home" + i ) ); // (1) text parameter
            assertTrue( "Missing away team " + i, form.isTextParameter( "away" + i ) ); // (1) text parameter
        }
        assertEquals( "Tie breaker values",
                      Arrays.asList( new String[] { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" } ),
                      Arrays.asList( form.getOptionValues( "tiebreaker" ) ) );          // (2) radio button
    }

The significant points in the code are:

1. We verify that a text parameter has been defined with the desired name for each of the 20 possible team values.
2. Here we verify that we have a set of radio buttons with a specific name and each of the desired values.

We satisfy this test by making the `printBody` method look like this:

    private void printBody( PrintWriter pw ) {
        pw.println( "<form id='pool' method='POST'>" );
        pw.println( "<table>" );
        pw.println( "<tr><th>Home Team</th><th>Away Team</th><th>Tiebreaker?</th></tr>" );
        for (int i = 0; i < 10; i++) {
            pw.println( "<tr><td><input name='home" + i + "'></td>" );
            pw.println( "<td><input name='away" + i + "'></td>" );
            pw.println( "<td><input type='radio' name='tiebreaker' value='" + i + "'/></td></tr>" );
        }
        pw.println( "</table>" );
        pw.println( "</form>" );
    }

## Testing the Submit Buttons

We confirm the presence of the desired submit buttons as follows:

    public void testSubmitButtons() throws Exception {
        ServletRunner sr = new ServletRunner( "web.xml" );
        ServletUnitClient client = sr.newClient();
        client.setAuthorization( "aUser", "pool-admin" );
        WebResponse response = client.getResponse( "http://localhost/PoolEditor" );

        WebForm form = response.getFormWithID( "pool" );
        assertNotNull( "No form found with ID 'pool'", form );

        assertEquals( "Number of submit buttons", 2, form.getSubmitButtons().length );    // (1) count the buttons
        assertNotNull( "Save button not found", form.getSubmitButton( "save", "Save" ) ); // (2) look up by name
        assertNotNull( "Open Pool button not found", form.getSubmitButton( "save", "Open Pool" ) );
    }

In this test, please note the following:

1. We ask for all the submit buttons associated with the form and just count them. This will ensure that we don't have more than we want, either.
2. We ask for each button that we do want by specifying its name and value - which will be used when we submit the form.

This test will pass once we modify the end of `printBody`, inserting lines to generate the submit buttons:

        }
        pw.println( "</table>" );
        pw.println( "<input type='submit' name='save' value='Save' />" );
        pw.println( "<input type='submit' name='save' value='Open Pool' />" );
        pw.println( "</form>" );
    }

We now have our form being generated, along with tests to confirm it. In the next step, we will test and code the response to a form submission.