Merge pull request #64 from ssb-ngi-pointer/44-notices
Add tests for notices view
This commit is contained in:
commit
04ba3b9477
|
@ -1,3 +1,6 @@
|
|||
# vim
|
||||
.*.sw[a-z]
|
||||
|
||||
# the binaries
|
||||
cmd/server/server
|
||||
cmd/insert-user/insert-user
|
||||
|
|
|
@ -19,6 +19,9 @@ import (
|
|||
|
||||
// AuthFallbackService might be helpful for scenarios where one lost access to his ssb device or key
|
||||
type AuthFallbackService interface {
|
||||
|
||||
// Check receives the username and password (in clear) and checks them accordingly.
|
||||
// If it's a valid combination it returns the user ID, or an error if they are not.
|
||||
auth.Auther
|
||||
|
||||
Create(ctx context.Context, user string, password []byte) (int64, error)
|
||||
|
@ -98,7 +101,7 @@ type InviteService interface {
|
|||
// PinnedNoticesService allows an admin to assign Notices to specific placeholder pages.
|
||||
// like updates, privacy policy, code of conduct
|
||||
type PinnedNoticesService interface {
|
||||
// List returns a list of all the pinned notices with their corrosponding notices and languges
|
||||
// List returns a list of all the pinned notices with their corresponding notices and languages
|
||||
List(context.Context) (PinnedNotices, error)
|
||||
|
||||
// Set assigns a fixed page name to an page ID and a language to allow for multiple translated versions of the same page.
|
||||
|
|
|
@ -24,6 +24,8 @@ type AuthFallback struct {
|
|||
db *sql.DB
|
||||
}
|
||||
|
||||
// Check receives the username and password (in clear) and checks them accordingly.
|
||||
// If it's a valid combination it returns the user ID, or an error if they are not.
|
||||
func (af AuthFallback) Check(name, password string) (interface{}, error) {
|
||||
ctx := context.Background()
|
||||
found, err := models.AuthFallbacks(qm.Where("name = ?", name)).One(ctx, af.db)
|
||||
|
|
|
@ -103,9 +103,9 @@ func TestPinnedNotices(t *testing.T) {
|
|||
}
|
||||
|
||||
for i, tcase := range cases {
|
||||
desc, has := allTheNotices[tcase.Name]
|
||||
notices, has := allTheNotices[tcase.Name]
|
||||
r.True(has, "case %d failed - notice %s not in map", i, tcase.Name)
|
||||
r.Len(desc, tcase.Count, "case %d failed - wrong number of notices for %s", i, tcase.Name)
|
||||
r.Len(notices, tcase.Count, "case %d failed - wrong number of notices for %s", i, tcase.Name)
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -130,7 +130,6 @@ func TestPinnedNotices(t *testing.T) {
|
|||
notice.Title = "política de privacidad"
|
||||
notice.Content = "solo una prueba"
|
||||
notice.Language = "es"
|
||||
|
||||
// save the new notice
|
||||
err = db.Notices.Save(ctx, ¬ice)
|
||||
r.NoError(err)
|
||||
|
|
|
@ -91,7 +91,7 @@ func TestAliasesRevokeConfirmation(t *testing.T) {
|
|||
|
||||
a.Equal(addURL.String(), action)
|
||||
|
||||
webassert.InputsInForm(t, form, []webassert.InputElement{
|
||||
webassert.ElementsInForm(t, form, []webassert.FormElement{
|
||||
{Name: "name", Type: "hidden", Value: testEntry.Name},
|
||||
})
|
||||
}
|
||||
|
|
|
@ -61,7 +61,7 @@ func TestAllowListAdd(t *testing.T) {
|
|||
|
||||
a.Equal(addURL.String(), action)
|
||||
|
||||
webassert.InputsInForm(t, formSelection, []webassert.InputElement{
|
||||
webassert.ElementsInForm(t, formSelection, []webassert.FormElement{
|
||||
{Name: "pub_key", Type: "text"},
|
||||
})
|
||||
|
||||
|
@ -181,7 +181,7 @@ func TestAllowListRemoveConfirmation(t *testing.T) {
|
|||
|
||||
a.Equal(addURL.String(), action)
|
||||
|
||||
webassert.InputsInForm(t, form, []webassert.InputElement{
|
||||
webassert.ElementsInForm(t, form, []webassert.FormElement{
|
||||
{Name: "id", Type: "hidden", Value: "666"},
|
||||
})
|
||||
}
|
||||
|
|
|
@ -78,7 +78,8 @@ func newSession(t *testing.T) *testSession {
|
|||
testFuncs["current_page_is"] = func(routeName string) bool {
|
||||
return true
|
||||
}
|
||||
testFuncs["is_logged_in"] = func() *roomdb.User { return nil }
|
||||
|
||||
testFuncs["is_logged_in"] = func() *roomdb.User { return ts.User }
|
||||
testFuncs["urlToNotice"] = func(name string) string { return "" }
|
||||
|
||||
r, err := render.New(web.Templates,
|
||||
|
|
|
@ -44,7 +44,7 @@ func TestInvitesCreateForm(t *testing.T) {
|
|||
|
||||
a.Equal(addURL.String(), action)
|
||||
|
||||
webassert.InputsInForm(t, formSelection, []webassert.InputElement{
|
||||
webassert.ElementsInForm(t, formSelection, []webassert.FormElement{
|
||||
{Name: "alias_suggestion", Type: "text"},
|
||||
})
|
||||
}
|
||||
|
|
|
@ -45,6 +45,12 @@ func (h noticeHandler) addTranslation(rw http.ResponseWriter, req *http.Request)
|
|||
return
|
||||
}
|
||||
|
||||
// reply with 405 error: Method not allowed
|
||||
if req.Method != "POST" {
|
||||
err := weberrors.ErrBadRequest{Where: "http method type", Details: fmt.Errorf("add translation only accepts POST requests, sorry!")}
|
||||
h.r.Error(rw, req, http.StatusMethodNotAllowed, err)
|
||||
}
|
||||
|
||||
pinnedName := roomdb.PinnedNoticeName(req.FormValue("name"))
|
||||
if !pinnedName.Valid() {
|
||||
err := weberrors.ErrBadRequest{Where: "name", Details: fmt.Errorf("invalid pinned notice name")}
|
||||
|
@ -54,6 +60,11 @@ func (h noticeHandler) addTranslation(rw http.ResponseWriter, req *http.Request)
|
|||
|
||||
var n roomdb.Notice
|
||||
n.Title = req.FormValue("title")
|
||||
if n.Title == "" {
|
||||
err = weberrors.ErrBadRequest{Where: "title", Details: fmt.Errorf("title can't be empty")}
|
||||
h.r.Error(rw, req, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
|
||||
// TODO: validate languages properly
|
||||
n.Language = req.FormValue("language")
|
||||
|
@ -64,6 +75,11 @@ func (h noticeHandler) addTranslation(rw http.ResponseWriter, req *http.Request)
|
|||
}
|
||||
|
||||
n.Content = req.FormValue("content")
|
||||
if n.Content == "" {
|
||||
err = weberrors.ErrBadRequest{Where: "content", Details: fmt.Errorf("content can't be empty")}
|
||||
h.r.Error(rw, req, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
// https://github.com/russross/blackfriday/issues/575
|
||||
n.Content = strings.Replace(n.Content, "\r\n", "\n", -1)
|
||||
|
||||
|
@ -137,6 +153,11 @@ func (h noticeHandler) save(rw http.ResponseWriter, req *http.Request) {
|
|||
}
|
||||
|
||||
n.Title = req.FormValue("title")
|
||||
if n.Title == "" {
|
||||
err = weberrors.ErrBadRequest{Where: "title", Details: fmt.Errorf("title can't be empty")}
|
||||
h.r.Error(rw, req, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
|
||||
// TODO: validate languages properly
|
||||
n.Language = req.FormValue("language")
|
||||
|
@ -147,6 +168,11 @@ func (h noticeHandler) save(rw http.ResponseWriter, req *http.Request) {
|
|||
}
|
||||
|
||||
n.Content = req.FormValue("content")
|
||||
if n.Content == "" {
|
||||
err = weberrors.ErrBadRequest{Where: "content", Details: fmt.Errorf("content can't be empty")}
|
||||
h.r.Error(rw, req, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
// https://github.com/russross/blackfriday/issues/575
|
||||
n.Content = strings.Replace(n.Content, "\r\n", "\n", -1)
|
||||
|
||||
|
|
|
@ -0,0 +1,153 @@
|
|||
package admin
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"testing"
|
||||
|
||||
"github.com/ssb-ngi-pointer/go-ssb-room/roomdb"
|
||||
"github.com/ssb-ngi-pointer/go-ssb-room/web"
|
||||
"github.com/ssb-ngi-pointer/go-ssb-room/web/router"
|
||||
"github.com/ssb-ngi-pointer/go-ssb-room/web/webassert"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
// Verifies that the notice.go save handler is like, actually, called.
|
||||
func TestNoticeSaveActuallyCalled(t *testing.T) {
|
||||
ts := newSession(t)
|
||||
a := assert.New(t)
|
||||
// instantiate the urlTo helper (constructs urls for us!)
|
||||
urlTo := web.NewURLTo(ts.Router)
|
||||
|
||||
id := []string{"1"}
|
||||
title := []string{"SSB Breaking News: This Test Is Great"}
|
||||
content := []string{"Absolutely Thrilling Content"}
|
||||
language := []string{"en-GB"}
|
||||
|
||||
// POST a correct request to the save handler, and verify that the save was handled using the mock database)
|
||||
u := urlTo(router.AdminNoticeSave)
|
||||
formValues := url.Values{"id": id, "title": title, "content": content, "language": language}
|
||||
resp := ts.Client.PostForm(u.String(), formValues)
|
||||
a.Equal(http.StatusSeeOther, resp.Code, "POST should work")
|
||||
a.Equal(1, ts.NoticeDB.SaveCallCount(), "noticedb should have saved after POST completed")
|
||||
}
|
||||
|
||||
// Verifies that the notices.go:save handler refuses requests missing required parameters
|
||||
func TestNoticeSaveRefusesIncomplete(t *testing.T) {
|
||||
ts := newSession(t)
|
||||
a := assert.New(t)
|
||||
// instantiate the urlTo helper (constructs urls for us!)
|
||||
urlTo := web.NewURLTo(ts.Router)
|
||||
|
||||
// notice values we are selectively omitting in the tests below
|
||||
id := []string{"1"}
|
||||
title := []string{"SSB Breaking News: This Test Is Great"}
|
||||
content := []string{"Absolutely Thrilling Content"}
|
||||
language := []string{"pt"}
|
||||
|
||||
/* save without id */
|
||||
u := urlTo(router.AdminNoticeSave)
|
||||
emptyParams := url.Values{}
|
||||
resp := ts.Client.PostForm(u.String(), emptyParams)
|
||||
a.Equal(http.StatusInternalServerError, resp.Code, "saving without id should not work")
|
||||
|
||||
/* save without title */
|
||||
formValues := url.Values{"id": id, "content": content, "language": language}
|
||||
resp = ts.Client.PostForm(u.String(), formValues)
|
||||
a.Equal(http.StatusInternalServerError, resp.Code, "saving without title should not work")
|
||||
|
||||
/* save without content */
|
||||
formValues = url.Values{"id": id, "title": title, "language": language}
|
||||
resp = ts.Client.PostForm(u.String(), formValues)
|
||||
a.Equal(http.StatusInternalServerError, resp.Code, "saving without content should not work")
|
||||
|
||||
/* save without language */
|
||||
formValues = url.Values{"id": id, "title": title, "content": content}
|
||||
resp = ts.Client.PostForm(u.String(), formValues)
|
||||
a.Equal(http.StatusInternalServerError, resp.Code, "saving without language should not work")
|
||||
|
||||
a.Equal(0, ts.NoticeDB.SaveCallCount(), "noticedb should never save incomplete requests")
|
||||
}
|
||||
|
||||
// Verifies that /translation/add only accepts POST requests
|
||||
func TestNoticeAddLanguageOnlyAllowsPost(t *testing.T) {
|
||||
ts := newSession(t)
|
||||
a := assert.New(t)
|
||||
// instantiate the urlTo helper (constructs urls for us!)
|
||||
urlTo := web.NewURLTo(ts.Router)
|
||||
|
||||
// verify that a GET request is no bueno
|
||||
u := urlTo(router.AdminNoticeAddTranslation, "name", roomdb.NoticeNews.String())
|
||||
_, resp := ts.Client.GetHTML(u.String())
|
||||
a.Equal(http.StatusMethodNotAllowed, resp.Code, "GET should not be allowed for this route")
|
||||
|
||||
// next up, we verify that a correct POST request actually works:
|
||||
id := []string{"1"}
|
||||
title := []string{"Bom Dia! SSB Breaking News: This Test Is Great"}
|
||||
content := []string{"conteúdo muito bom"}
|
||||
language := []string{"pt"}
|
||||
|
||||
formValues := url.Values{"name": []string{roomdb.NoticeNews.String()}, "id": id, "title": title, "content": content, "language": language}
|
||||
resp = ts.Client.PostForm(u.String(), formValues)
|
||||
a.Equal(http.StatusTemporaryRedirect, resp.Code)
|
||||
}
|
||||
|
||||
// Verifies that the "add a translation" page contains all the required form fields (id/title/content/language)
|
||||
func TestNoticeDraftLanguageIncludesAllFields(t *testing.T) {
|
||||
ts := newSession(t)
|
||||
a := assert.New(t)
|
||||
// instantiate the urlTo helper (constructs urls for us!)
|
||||
urlTo := web.NewURLTo(ts.Router)
|
||||
|
||||
// to test translations we first need to add a notice to the notice mockdb
|
||||
notice := roomdb.Notice{
|
||||
ID: 1,
|
||||
Title: "News",
|
||||
Content: "Breaking News: This Room Has News",
|
||||
Language: "en-GB",
|
||||
}
|
||||
// make sure we return a notice when accessing pinned notices (which are the only notices with translations at writing (2021-03-11)
|
||||
ts.PinnedDB.GetReturns(¬ice, nil)
|
||||
|
||||
u := urlTo(router.AdminNoticeDraftTranslation, "name", roomdb.NoticeNews.String())
|
||||
html, resp := ts.Client.GetHTML(u.String())
|
||||
form := html.Find("form")
|
||||
a.Equal(http.StatusOK, resp.Code, "Wrong HTTP status code")
|
||||
// FormElement defaults to input if tag omitted
|
||||
webassert.ElementsInForm(t, form, []webassert.FormElement{
|
||||
{Name: "title"},
|
||||
{Name: "language"},
|
||||
{Tag: "textarea", Name: "content"},
|
||||
})
|
||||
}
|
||||
|
||||
func TestNoticeEditFormIncludesAllFields(t *testing.T) {
|
||||
ts := newSession(t)
|
||||
a := assert.New(t)
|
||||
// instantiate the urlTo helper (constructs urls for us!)
|
||||
urlTo := web.NewURLTo(ts.Router)
|
||||
|
||||
// Create mock notice data to operate on
|
||||
notice := roomdb.Notice{
|
||||
ID: 1,
|
||||
Title: "News",
|
||||
Content: "Breaking News: This Room Has News",
|
||||
Language: "en-GB",
|
||||
}
|
||||
ts.NoticeDB.GetByIDReturns(notice, nil)
|
||||
|
||||
u := urlTo(router.AdminNoticeEdit, "id", 1)
|
||||
html, resp := ts.Client.GetHTML(u.String())
|
||||
form := html.Find("form")
|
||||
|
||||
a.Equal(http.StatusOK, resp.Code, "Wrong HTTP status code")
|
||||
// check for all the form elements & verify their initial contents are set correctly
|
||||
// FormElement defaults to input if tag omitted
|
||||
webassert.ElementsInForm(t, form, []webassert.FormElement{
|
||||
{Name: "title", Value: notice.Title},
|
||||
{Name: "language", Value: notice.Language},
|
||||
{Name: "id", Value: fmt.Sprintf("%d", notice.ID), Type: "hidden"},
|
||||
{Tag: "textarea", Name: "content"},
|
||||
})
|
||||
}
|
|
@ -96,7 +96,7 @@ func TestInviteShowAcceptForm(t *testing.T) {
|
|||
|
||||
webassert.CSRFTokenPresent(t, form)
|
||||
|
||||
webassert.InputsInForm(t, form, []webassert.InputElement{
|
||||
webassert.ElementsInForm(t, form, []webassert.FormElement{
|
||||
{Name: "token", Type: "hidden", Value: testToken},
|
||||
{Name: "alias", Type: "text", Value: fakeExistingInvite.AliasSuggestion},
|
||||
{Name: "new_member", Type: "text", Placeholder: wantNewMemberPlaceholder},
|
||||
|
@ -133,7 +133,7 @@ func TestInviteShowAcceptForm(t *testing.T) {
|
|||
r.Equal(1, form.Length())
|
||||
|
||||
webassert.CSRFTokenPresent(t, form)
|
||||
webassert.InputsInForm(t, form, []webassert.InputElement{
|
||||
webassert.ElementsInForm(t, form, []webassert.FormElement{
|
||||
{Name: "token", Type: "hidden", Value: testToken},
|
||||
{Name: "alias", Type: "text", Placeholder: "you@this.room"},
|
||||
{Name: "new_member", Type: "text", Placeholder: wantNewMemberPlaceholder},
|
||||
|
|
|
@ -0,0 +1,169 @@
|
|||
package handlers
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/http/cookiejar"
|
||||
"net/url"
|
||||
"testing"
|
||||
|
||||
"github.com/ssb-ngi-pointer/go-ssb-room/roomdb"
|
||||
"github.com/ssb-ngi-pointer/go-ssb-room/web"
|
||||
"github.com/ssb-ngi-pointer/go-ssb-room/web/router"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
// TestNoticeSmokeTest ensures the most basic notice serving is working
|
||||
func TestNoticeSmokeTest(t *testing.T) {
|
||||
ts := setup(t)
|
||||
a := assert.New(t)
|
||||
|
||||
noticeData := roomdb.Notice{
|
||||
ID: 1,
|
||||
Title: "Welcome!",
|
||||
}
|
||||
|
||||
ts.NoticeDB.GetByIDReturns(noticeData, nil)
|
||||
|
||||
html, res := ts.Client.GetHTML("/notice/show?id=1")
|
||||
a.Equal(http.StatusOK, res.Code, "wrong HTTP status code")
|
||||
a.Equal("Welcome!", html.Find("title").Text())
|
||||
}
|
||||
|
||||
func TestNoticeMarkdownServedCorrectly(t *testing.T) {
|
||||
ts := setup(t)
|
||||
a := assert.New(t)
|
||||
|
||||
markdown := `
|
||||
Hello world!
|
||||
|
||||
## The loveliest of rooms is here
|
||||
`
|
||||
noticeData := roomdb.Notice{
|
||||
ID: 1,
|
||||
Title: "Welcome!",
|
||||
Content: markdown,
|
||||
}
|
||||
|
||||
ts.NoticeDB.GetByIDReturns(noticeData, nil)
|
||||
|
||||
html, res := ts.Client.GetHTML("/notice/show?id=1")
|
||||
a.Equal(http.StatusOK, res.Code, "wrong HTTP status code")
|
||||
a.Equal("Welcome!", html.Find("title").Text())
|
||||
a.Equal("The loveliest of rooms is here", html.Find("h2").Text())
|
||||
}
|
||||
|
||||
// First we get the notices page (to see the buttons are NOT there)
|
||||
// then we log in as an admin and see that the edit links are there.
|
||||
func TestNoticesEditButtonVisible(t *testing.T) {
|
||||
ts := setup(t)
|
||||
a, r := assert.New(t), require.New(t)
|
||||
|
||||
urlTo := web.NewURLTo(ts.Router)
|
||||
|
||||
noticeData := roomdb.Notice{
|
||||
ID: 42,
|
||||
Title: "Welcome!",
|
||||
Content: `super simple conent`,
|
||||
}
|
||||
ts.NoticeDB.GetByIDReturns(noticeData, nil)
|
||||
|
||||
// first, we confirm that the button is missing when not logged in
|
||||
noticeURL := urlTo(router.CompleteNoticeShow, "id", 42)
|
||||
noticeURL.Host = "localhost"
|
||||
noticeURL.Scheme = "https"
|
||||
editButtonSelector := `#edit-notice`
|
||||
|
||||
doc, resp := ts.Client.GetHTML(noticeURL.String())
|
||||
a.Equal(http.StatusOK, resp.Code)
|
||||
|
||||
// empty selection <=> we have no link
|
||||
a.EqualValues(0, doc.Find(editButtonSelector).Length())
|
||||
|
||||
// start preparing the ~login dance~
|
||||
// TODO: make this code reusable and share it with the login => /dashboard http:200 test
|
||||
// cookiejar: a very cheap client session
|
||||
// TODO: refactor login dance for re-use in testing / across tests
|
||||
jar, err := cookiejar.New(nil)
|
||||
r.NoError(err)
|
||||
|
||||
// when dealing with cookies we also need to have an Host and URL-Scheme
|
||||
// for the jar to save and load them correctly
|
||||
formEndpoint := urlTo(router.AuthFallbackSignInForm)
|
||||
r.NotNil(formEndpoint)
|
||||
formEndpoint.Host = "localhost"
|
||||
formEndpoint.Scheme = "https"
|
||||
|
||||
doc, resp = ts.Client.GetHTML(formEndpoint.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(formEndpoint, 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},
|
||||
}
|
||||
|
||||
// have the database return okay for any user
|
||||
testUser := &roomdb.User{
|
||||
ID: 23,
|
||||
Name: "test admin",
|
||||
}
|
||||
ts.AuthFallbackDB.CheckReturns(testUser.ID, nil)
|
||||
ts.AuthFallbackDB.GetByIDReturns(testUser, nil)
|
||||
|
||||
postEndpoint, err := ts.Router.Get(router.AuthFallbackSignIn).URL()
|
||||
r.Nil(err)
|
||||
postEndpoint.Host = "localhost"
|
||||
postEndpoint.Scheme = "https"
|
||||
|
||||
// construct HTTP Header with Referer and Cookie
|
||||
var csrfCookieHeader = http.Header(map[string][]string{})
|
||||
csrfCookieHeader.Set("Referer", "https://localhost")
|
||||
cs := jar.Cookies(postEndpoint)
|
||||
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(postEndpoint.String(), loginVals)
|
||||
a.Equal(http.StatusSeeOther, resp.Code, "wrong HTTP status code for sign in")
|
||||
|
||||
sessionCookie := resp.Result().Cookies()
|
||||
jar.SetCookies(postEndpoint, sessionCookie)
|
||||
|
||||
var sessionHeader = http.Header(map[string][]string{})
|
||||
cs = jar.Cookies(noticeURL)
|
||||
// TODO: why doesnt this return the csrf cookie?!
|
||||
r.NotEqual(len(cs), 0, "expecting a cookie!")
|
||||
for _, c := range cs {
|
||||
theCookie := c.String()
|
||||
a.NotEqual("", theCookie, "should have a new cookie")
|
||||
sessionHeader.Add("Cookie", theCookie)
|
||||
}
|
||||
|
||||
// update headers
|
||||
ts.Client.ClearHeaders()
|
||||
ts.Client.SetHeaders(sessionHeader)
|
||||
|
||||
// now we are logged in, anchor tag should be there
|
||||
doc, resp = ts.Client.GetHTML(noticeURL.String())
|
||||
a.Equal(http.StatusOK, resp.Code)
|
||||
|
||||
a.EqualValues(1, doc.Find(editButtonSelector).Length())
|
||||
}
|
|
@ -11,6 +11,7 @@
|
|||
<div class="h-10"></div>
|
||||
{{if is_logged_in}}
|
||||
<a
|
||||
id="edit-notice"
|
||||
href="{{urlTo "admin:notice:edit" "id" .ID}}"
|
||||
class="self-start shadow rounded px-4 h-8 flex flex-row justify-center items-center text-gray-100 bg-pink-600 hover:bg-pink-700 focus:outline-none focus:ring-2 focus:ring-pink-600 focus:ring-opacity-50"
|
||||
>{{i18n "NoticeEditTitle"}}</a>
|
||||
|
|
|
@ -40,7 +40,9 @@ func NewURLTo(appRouter *mux.Router) func(string, ...interface{}) *url.URL {
|
|||
return func(routeName string, ps ...interface{}) *url.URL {
|
||||
route := appRouter.Get(routeName)
|
||||
if route == nil {
|
||||
level.Warn(l).Log("msg", "no such route", "route", routeName, "params", fmt.Sprintf("%v", ps))
|
||||
// TODO: https://github.com/ssb-ngi-pointer/go-ssb-room/issues/35 for a
|
||||
// for reference, see https://github.com/ssb-ngi-pointer/go-ssb-room/pull/64
|
||||
// level.Warn(l).Log("msg", "no such route", "route", routeName, "params", fmt.Sprintf("%v", ps))
|
||||
return &url.URL{}
|
||||
}
|
||||
|
||||
|
|
|
@ -31,36 +31,40 @@ func CSRFTokenPresent(t *testing.T, sel *goquery.Selection) {
|
|||
a.Equal("hidden", tipe, "wrong type on csrf field")
|
||||
}
|
||||
|
||||
type InputElement struct {
|
||||
Name, Value, Type, Placeholder string
|
||||
type FormElement struct {
|
||||
Tag, Name, Value, Type, Placeholder string
|
||||
}
|
||||
|
||||
// InputsInForm checks a list of defined elements. It tries to find them by input[name=$name]
|
||||
// and then proceeds with asserting their value, type or placeholder (if the fields in InputElement are not "")
|
||||
func InputsInForm(t *testing.T, form *goquery.Selection, elems []InputElement) {
|
||||
// ElementsInForm checks a list of defined elements. It tries to find them by input[name=$name]
|
||||
// and then proceeds with asserting their value, type or placeholder (if the fields in FormElement are not "")
|
||||
func ElementsInForm(t *testing.T, form *goquery.Selection, elems []FormElement) {
|
||||
a := assert.New(t)
|
||||
for _, e := range elems {
|
||||
// empty Tag defaults to <input>
|
||||
if e.Tag == "" {
|
||||
e.Tag = "input"
|
||||
}
|
||||
|
||||
inputSelector := form.Find(fmt.Sprintf("input[name=%s]", e.Name))
|
||||
ok := a.Equal(1, inputSelector.Length(), "expected to find input with name %s", e.Name)
|
||||
elementSelector := form.Find(fmt.Sprintf("%s[name=%s]", e.Tag, e.Name))
|
||||
ok := a.Equal(1, elementSelector.Length(), "expected to find element with name %s", e.Name)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
if e.Value != "" {
|
||||
value, has := inputSelector.Attr("value")
|
||||
value, has := elementSelector.Attr("value")
|
||||
a.True(has, "expected value attribute input[name=%s]", e.Name)
|
||||
a.Equal(e.Value, value, "wrong value attribute on input[name=%s]", e.Name)
|
||||
}
|
||||
|
||||
if e.Type != "" {
|
||||
tipe, has := inputSelector.Attr("type")
|
||||
tipe, has := elementSelector.Attr("type")
|
||||
a.True(has, "expected type attribute input[name=%s]", e.Name)
|
||||
a.Equal(e.Type, tipe, "wrong type attribute on input[name=%s]", e.Name)
|
||||
}
|
||||
|
||||
if e.Placeholder != "" {
|
||||
tipe, has := inputSelector.Attr("placeholder")
|
||||
tipe, has := elementSelector.Attr("placeholder")
|
||||
a.True(has, "expected placeholder attribute input[name=%s]", e.Name)
|
||||
a.Equal(e.Placeholder, tipe, "wrong placeholder attribute on input[name=%s]", e.Name)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue