Testing Login and Logout Functionalities

Based on the requirements for this functionality, this code should allow the use of a valid username/password combination and disallow the use of an invalid username/password combination.

To test the isUserValid function in models.user.go, let's update the models.user_test.go with the following test:

// models.user_test.go

func TestUserValidity(t *testing.T) {
    if !isUserValid("user1", "pass1") {
        t.Fail()
    }

    if isUserValid("user2", "pass1") {
        t.Fail()
    }

    if isUserValid("user1", "") {
        t.Fail()
    }

    if isUserValid("", "pass1") {
        t.Fail()
    }

    if isUserValid("User1", "pass1") {
        t.Fail()
    }
}

This test uses several username/password combinations to test that the isUserValid function returns the expected result. Note that this uses the hard-coded list of users that we created earlier in models.user.go.

The tests for the new handlers will be similar in structure to the ones added in the previous section. The new handlers added in handlers.user.go will need the following tests:

1. TestShowLoginPageUnauthenticated

This test will check that the login page is shown to unauthenticated users as expected.

// handlers.user_test.go

func TestShowLoginPageUnauthenticated(t *testing.T){
    r := getRouter(true)

    r.GET("/u/login", showLoginPage)

    req, _ := http.NewRequest("GET", "/u/login", nil)

    testHTTPResponse(t, r, req, func(w *httptest.ResponseRecorder) bool {
        statusOK := w.Code == http.StatusOK

        p, err := ioutil.ReadAll(w.Body)
        pageOK := err == nil && strings.Index(string(p), "<title>Login</title>") > 0

        return statusOK && pageOK
    })
}

2. TestLoginUnauthenticated

This test will check that a POST request to login with the correct credentials returns a success message.

//handlers.user_test.go

func TestLoginUnauthenticated(t *testing.T) {
    saveLists()
    w := httptest.NewRecorder()
    r := getRouter(true)

    r.POST("/u/login", performLogin)

    loginPayload := getLoginPOSTPayload()
    req, _ := http.NewRequest("POST", "/u/login", strings.NewReader(loginPayload))
    req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
    req.Header.Add("Content-Length", strconv.Itoa(len(loginPayload)))

    r.ServeHTTP(w, req)

    if w.Code != http.StatusOK {
        t.Fail()
    }

    p, err := ioutil.ReadAll(w.Body)
    if err != nil || strings.Index(string(p), "<title>Successful Login</title>") < 0 {
        t.Fail()
    }
    restoreLists()
}

3. TestLoginUnauthenticatedIncorrectCredentials

This test will check that a POST request to login with incorrect credentials returns an error.

//handlers.user_test.go

func TestLoginUnauthenticatedIncorrectCredentials(t *testing.T) {
    saveLists()
    w := httptest.NewRecorder()
    r := getRouter(true)

    r.POST("/u/login", performLogin)

    loginPayload := getRegistrationPOSTPayload()
    req, _ := http.NewRequest("POST", "/u/login", strings.NewReader(loginPayload))
    req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
    req.Header.Add("Content-Length", strconv.Itoa(len(loginPayload)))

    r.ServeHTTP(w, req)

    if w.Code != http.StatusBadRequest {
        t.Fail()
    }
    restoreLists()
}

With these tests written, let's run them to see what happens. In your project directory, execute the following command:

go test -v

This should give the following output:

=== RUN   TestShowIndexPageUnauthenticated
[GIN] 2016/09/04 - 08:33:22 | 200 |     277.294µs |  |   GET     /
--- PASS: TestShowIndexPageUnauthenticated (0.00s)
=== RUN   TestArticleUnauthenticated
[GIN] 2016/09/04 - 08:33:22 | 200 |     131.567µs |  |   GET     /article/view/1
--- PASS: TestArticleUnauthenticated (0.00s)
=== RUN   TestArticleListJSON
[GIN] 2016/09/04 - 08:33:22 | 200 |      67.678µs |  |   GET     /
--- PASS: TestArticleListJSON (0.00s)
=== RUN   TestArticleXML
[GIN] 2016/09/04 - 08:33:22 | 200 |      26.344µs |  |   GET     /article/view/1
--- PASS: TestArticleXML (0.00s)
=== RUN   TestShowRegistrationPageUnauthenticated
[GIN] 2016/09/04 - 08:33:22 | 200 |     130.407µs |  |   GET     /u/register
--- PASS: TestShowRegistrationPageUnauthenticated (0.00s)
=== RUN   TestRegisterUnauthenticated
[GIN] 2016/09/04 - 08:33:22 | 200 |     176.598µs |  |   POST    /u/register
--- PASS: TestRegisterUnauthenticated (0.00s)
=== RUN   TestRegisterUnauthenticatedUnavailableUsername
[GIN] 2016/09/04 - 08:33:22 | 400 |     181.588µs |  |   POST    /u/register
--- PASS: TestRegisterUnauthenticatedUnavailableUsername (0.00s)
=== RUN   TestShowLoginPageUnauthenticated
[GIN] 2016/09/04 - 08:33:22 | 200 |         327ns |  |   GET     /u/login
--- FAIL: TestShowLoginPageUnauthenticated (0.00s)
=== RUN   TestLoginUnauthenticated
[GIN] 2016/09/04 - 08:33:22 | 200 |         316ns |  |   POST    /u/login
--- FAIL: TestLoginUnauthenticated (0.00s)
=== RUN   TestLoginUnauthenticatedIncorrectCredentials
[GIN] 2016/09/04 - 08:33:22 | 200 |         258ns |  |   POST    /u/login
--- FAIL: TestLoginUnauthenticatedIncorrectCredentials (0.00s)
=== RUN   TestGetAllArticles
--- PASS: TestGetAllArticles (0.00s)
=== RUN   TestGetArticleByID
--- PASS: TestGetArticleByID (0.00s)
=== RUN   TestValidUserRegistration
--- PASS: TestValidUserRegistration (0.00s)
=== RUN   TestInvalidUserRegistration
--- PASS: TestInvalidUserRegistration (0.00s)
=== RUN   TestUsernameAvailability
--- PASS: TestUsernameAvailability (0.00s)
=== RUN   TestUserValidity
--- FAIL: TestUserValidity (0.00s)
FAIL
exit status 1
FAIL    github.com/demo-apps/go-gin-app 0.009s

As expected, the tests fail. Let's now start implementing the functionality for login and logout.

results matching ""

    No results matching ""