Let's Go Guided exercises › Test the snippetCreate handler
Previous · Contents · Next
Chapter 16.3.

Test the snippetCreate handler

Your goal in this exercise is to create an end-to-end test for the GET /snippet/create route. Specifically, you want to test that:

Step 1

Create a new test function named TestSnippetCreate in your cmd/web/handlers_test.go file. In this test, use the pattern and helpers from the end-to-end testing chapter to initialize a new test application containing the application routes and mocked dependencies.

Show suggested code

Step 2

Create a sub-test with the name "Unauthenticated". In this sub-test, make a GET /snippet/create request against the test server as an unauthenticated user. Verify that the response has the status code 303 and a Location: /user/login header. Again, reuse the helpers that we made in the end-to-end testing chapter.

Show suggested code

Step 3

Create another sub-test with the name "Authenticated"”. In this sub-test, mimic the workflow of logging in as a user to authenticate, before making the GET /snippet/create request. Specifically:

Show suggested code

Suggested code

Suggested code for step 1

File: cmd/web/handlers_test.go
...

func TestSnippetCreate(t *testing.T) {
    app := newTestApplication(t)
    ts := newTestServer(t, app.routes())
    defer ts.Close()
}

Suggested code for step 2

File: cmd/web/handlers_test.go
...

func TestSnippetCreate(t *testing.T) {
    app := newTestApplication(t)
    ts := newTestServer(t, app.routes())
    defer ts.Close()

    t.Run("Unauthenticated", func(t *testing.T) {
        ts.resetClientCookieJar(t)

        res := ts.get(t, "/snippet/create")
        assert.Equal(t, res.status,  http.StatusSeeOther)
        assert.Equal(t, res.headers.Get("Location"), "/user/login")
    })
}
$  go test -v -run=TestSnippetCreate ./cmd/web/
=== RUN   TestSnippetCreate
=== RUN   TestSnippetCreate/Unauthenticated
--- PASS: TestSnippetCreate (0.01s)
    --- PASS: TestSnippetCreate/Unauthenticated (0.00s)
PASS
ok      snippetbox.alexedwards.net/cmd/web      0.010s

Suggested code for step 3

File: cmd/web/handlers_test.go
...

func TestSnippetCreate(t *testing.T) {
    app := newTestApplication(t)
    ts := newTestServer(t, app.routes())
    defer ts.Close()

    t.Run("Unauthenticated", func(t *testing.T) {
        ts.resetClientCookieJar(t)

        res := ts.get(t, "/snippet/create")
        assert.Equal(t, res.status, http.StatusSeeOther)
        assert.Equal(t, res.headers.Get("Location"), "/user/login")
    })

    t.Run("Authenticated", func(t *testing.T) {
        ts.resetClientCookieJar(t)

        // Make a GET /user/login request.
        res := ts.get(t, "/user/login")

        // Make a POST /user/login request using the credentials from our mock 
		// user model and the CSRF token extracted from the previous response.
        form := url.Values{}
        form.Add("email", "alice@example.com")
        form.Add("password", "pa$$word")
        form.Add("csrf_token", extractCSRFToken(t, res.body))

        ts.postForm(t, "/user/login", form)

        // Then check that the authenticated user is shown the create snippet
        // form.
        res = ts.get(t, "/snippet/create")
        assert.Equal(t, res.status, http.StatusOK)
        assert.StringContains(t, res.body, "<form action='/snippet/create' method='POST'>")
    })
}
$ go test -v -run=TestSnippetCreate ./cmd/web/
=== RUN   TestSnippetCreate
=== RUN   TestSnippetCreate/Unauthenticated
=== RUN   TestSnippetCreate/Authenticated
--- PASS: TestSnippetCreate (0.01s)
    --- PASS: TestSnippetCreate/Unauthenticated (0.00s)
    --- PASS: TestSnippetCreate/Authenticated (0.00s)
PASS
ok      snippetbox.alexedwards.net/cmd/web      0.012s