go-ssb-room/web/handlers/http_test.go

250 lines
6.3 KiB
Go

// SPDX-License-Identifier: MIT
package handlers
import (
"bytes"
"net/http"
"net/http/cookiejar"
"net/url"
"testing"
"github.com/PuerkitoBio/goquery"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
refs "go.mindeco.de/ssb-refs"
"github.com/ssb-ngi-pointer/go-ssb-room/web/router"
)
func TestIndex(t *testing.T) {
ts := setup(t)
a := assert.New(t)
r := require.New(t)
url, err := ts.Router.Get(router.CompleteIndex).URL()
r.Nil(err)
html, resp := ts.Client.GetHTML(url.String())
a.Equal(http.StatusOK, resp.Code, "wrong HTTP status code")
assertLocalized(t, html, []localizedElement{
{"h1", "LandingWelcome"},
{"title", "LandingTitle"},
// {"#nav", "FooBar"},
})
val, has := html.Find("img").Attr("src")
a.True(has, "logo src attribute not found")
a.Equal("/assets/img/test-hermie.png", val)
}
func TestAbout(t *testing.T) {
ts := setup(t)
a := assert.New(t)
r := require.New(t)
url, err := ts.Router.Get(router.CompleteAbout).URL()
r.Nil(err)
html, resp := ts.Client.GetHTML(url.String())
a.Equal(http.StatusOK, resp.Code, "wrong HTTP status code")
found := html.Find("h1").Text()
a.Equal("The about page", found)
}
func TestNotFound(t *testing.T) {
ts := setup(t)
a := assert.New(t)
html, resp := ts.Client.GetHTML("/some/random/ASDKLANZXC")
a.Equal(http.StatusNotFound, resp.Code, "wrong HTTP status code")
found := html.Find("h1").Text()
a.Equal("Error #404 - Not Found", found)
}
func TestNewsRegisterd(t *testing.T) {
ts := setup(t)
a := assert.New(t)
html, resp := ts.Client.GetHTML("/news/")
a.Equal(http.StatusOK, resp.Code, "wrong HTTP status code")
assertLocalized(t, html, []localizedElement{
{"#welcome", "NewsWelcome"},
{"title", "NewsTitle"},
})
}
func TestRestricted(t *testing.T) {
ts := setup(t)
a := assert.New(t)
testURLs := []string{
// "/admin/",
"/admin/admin",
"/admin/admin/",
}
for _, turl := range testURLs {
html, resp := ts.Client.GetHTML(turl)
a.Equal(http.StatusUnauthorized, resp.Code, "wrong HTTP status code for %q", turl)
found := html.Find("h1").Text()
a.Equal("Error #401 - Unauthorized", found, "wrong error message code for %q", turl)
}
}
func TestLoginForm(t *testing.T) {
ts := setup(t)
a, r := assert.New(t), require.New(t)
url, err := ts.Router.Get(router.AuthFallbackSignInForm).URL()
r.Nil(err)
html, resp := ts.Client.GetHTML(url.String())
a.Equal(http.StatusOK, resp.Code, "wrong HTTP status code")
assertLocalized(t, html, []localizedElement{
{"#welcome", "AuthFallbackWelcome"},
{"title", "AuthFallbackTitle"},
})
}
func TestFallbackAuth(t *testing.T) {
ts := setup(t)
a, r := assert.New(t), require.New(t)
// very cheap client session
jar, err := cookiejar.New(nil)
r.NoError(err)
signInFormURL, err := ts.Router.Get(router.AuthFallbackSignInForm).URL()
r.Nil(err)
signInFormURL.Host = "localhost"
signInFormURL.Scheme = "https"
doc, resp := ts.Client.GetHTML(signInFormURL.String())
a.Equal(http.StatusOK, resp.Code)
csrfCookie := resp.Result().Cookies()
a.Len(csrfCookie, 1, "should have one cookie for CSRF protection validation")
t.Log(csrfCookie)
jar.SetCookies(signInFormURL, csrfCookie)
csrfTokenElem := doc.Find("input[type=hidden]")
a.Equal(1, csrfTokenElem.Length())
csrfName, has := csrfTokenElem.Attr("name")
a.True(has, "should have a name attribute")
csrfValue, has := csrfTokenElem.Attr("value")
a.True(has, "should have value attribute")
loginVals := url.Values{
"user": []string{"test"},
"pass": []string{"test"},
csrfName: []string{csrfValue},
}
ts.AuthFallbackDB.CheckReturns(int64(23), nil)
t.Log(loginVals)
signInURL, err := ts.Router.Get(router.AuthFallbackSignIn).URL()
r.Nil(err)
signInURL.Host = "localhost"
signInURL.Scheme = "https"
var csrfCookieHeader = http.Header(map[string][]string{})
csrfCookieHeader.Set("Referer", "https://localhost")
cs := jar.Cookies(signInURL)
r.Len(cs, 1, "expecting one cookie for csrf")
theCookie := cs[0].String()
a.NotEqual("", theCookie, "should have a new cookie")
csrfCookieHeader.Set("Cookie", theCookie)
ts.Client.SetHeaders(csrfCookieHeader)
resp = ts.Client.PostForm(signInURL.String(), loginVals)
a.Equal(http.StatusSeeOther, resp.Code, "wrong HTTP status code for sign in")
a.Equal(1, ts.AuthFallbackDB.CheckCallCount())
sessionCookie := resp.Result().Cookies()
jar.SetCookies(signInURL, sessionCookie)
dashboardURL, err := ts.Router.Get(router.AdminDashboard).URL()
r.Nil(err)
dashboardURL.Host = "localhost"
dashboardURL.Scheme = "https"
var sessionHeader = http.Header(map[string][]string{})
cs = jar.Cookies(dashboardURL)
// TODO: why doesnt this return the csrf cookie?!
// r.Len(cs, 2, "expecting one cookie!")
for _, c := range cs {
theCookie := c.String()
a.NotEqual("", theCookie, "should have a new cookie")
sessionHeader.Add("Cookie", theCookie)
}
durl := dashboardURL.String()
t.Log(durl)
// update headers
ts.Client.ClearHeaders()
ts.Client.SetHeaders(sessionHeader)
html, resp := ts.Client.GetHTML(durl)
if !a.Equal(http.StatusOK, resp.Code, "wrong HTTP status code for dashboard") {
t.Log(html.Find("body").Text())
}
assertLocalized(t, html, []localizedElement{
{"#welcome", "AdminDashboardWelcome"},
{"title", "AdminDashboardTitle"},
})
testRef := refs.FeedRef{Algo: "test", ID: bytes.Repeat([]byte{0}, 16)}
ts.RoomState.AddEndpoint(testRef, nil)
html, resp = ts.Client.GetHTML(durl)
if !a.Equal(http.StatusOK, resp.Code, "wrong HTTP status code") {
t.Log(html.Find("body").Text())
}
assertLocalized(t, html, []localizedElement{
{"#welcome", "AdminDashboardWelcome"},
{"title", "AdminDashboardTitle"},
{"#roomCount", "AdminRoomCountSingular"},
})
testRef2 := refs.FeedRef{Algo: "test", ID: bytes.Repeat([]byte{1}, 16)}
ts.RoomState.AddEndpoint(testRef2, nil)
html, resp = ts.Client.GetHTML(durl)
a.Equal(http.StatusOK, resp.Code, "wrong HTTP status code")
t.Log(html.Find("body").Text())
assertLocalized(t, html, []localizedElement{
{"#welcome", "AdminDashboardWelcome"},
{"title", "AdminDashboardTitle"},
{"#roomCount", "AdminRoomCountPlural"},
})
}
// utils
type localizedElement struct {
Selector, Label string
}
func assertLocalized(t *testing.T, html *goquery.Document, elems []localizedElement) {
a := assert.New(t)
for i, pair := range elems {
a.Equal(pair.Label, html.Find(pair.Selector).Text(), "localized pair %d failed", i+1)
}
}