tests for restricted UI behavior
* add tests for privacy mode settings * test privacy mode settings for member role * test default language settings * test denied keys interface for each role * test adding new member interface depending on role * test member details depending on role * test invite button is disabled pending on user role
This commit is contained in:
parent
2c9fdcb98e
commit
cec5f93fb6
|
@ -8,6 +8,7 @@ import (
|
|||
"net/url"
|
||||
"testing"
|
||||
|
||||
"github.com/PuerkitoBio/goquery"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/ssb-ngi-pointer/go-ssb-room/roomdb"
|
||||
|
@ -32,6 +33,85 @@ func TestDeniedKeysEmpty(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
func TestDeniedKeysDisabledInterface(t *testing.T) {
|
||||
ts := newSession(t)
|
||||
a := assert.New(t)
|
||||
|
||||
listURL := ts.URLTo(router.AdminDeniedKeysOverview)
|
||||
|
||||
ts.User = roomdb.Member{
|
||||
ID: 1234,
|
||||
Role: roomdb.RoleAdmin,
|
||||
}
|
||||
|
||||
html, resp := ts.Client.GetHTML(listURL)
|
||||
a.Equal(http.StatusOK, resp.Code, "wrong HTTP status code")
|
||||
|
||||
formSelection := html.Find("form#add-entry")
|
||||
a.EqualValues(1, formSelection.Length())
|
||||
|
||||
method, ok := formSelection.Attr("method")
|
||||
a.True(ok, "form has method set")
|
||||
a.Equal("POST", method)
|
||||
|
||||
action, ok := formSelection.Attr("action")
|
||||
a.True(ok, "form has action set")
|
||||
|
||||
addURL := ts.URLTo(router.AdminDeniedKeysAdd)
|
||||
a.Equal(addURL.String(), action)
|
||||
|
||||
webassert.ElementsInForm(t, formSelection, []webassert.FormElement{
|
||||
{Name: "pub_key", Type: "text"},
|
||||
{Name: "comment", Type: "text"},
|
||||
})
|
||||
|
||||
newKey := "@x7iOLUcq3o+sjGeAnipvWeGzfuYgrXl8L4LYlxIhwDc=.ed25519"
|
||||
addVals := url.Values{
|
||||
"comment": []string{"some comment"},
|
||||
// just any key that looks valid
|
||||
"pub_key": []string{newKey},
|
||||
}
|
||||
rec := ts.Client.PostForm(addURL, addVals)
|
||||
a.Equal(http.StatusTemporaryRedirect, rec.Code)
|
||||
|
||||
a.Equal(1, ts.DeniedKeysDB.AddCallCount())
|
||||
_, addedKey, addedComment := ts.DeniedKeysDB.AddArgsForCall(0)
|
||||
a.Equal(newKey, addedKey.Ref())
|
||||
a.Equal("some comment", addedComment)
|
||||
|
||||
/* Verify that the inputs are visible/hidden depending on user roles */
|
||||
checkInputsAreDisabled := func(shouldBeDisabled bool) {
|
||||
html, resp = ts.Client.GetHTML(listURL)
|
||||
a.Equal(http.StatusOK, resp.Code, "wrong HTTP status code")
|
||||
inputContainer := html.Find("#denied-keys-input-container")
|
||||
a.Equal(1, inputContainer.Length())
|
||||
inputs := inputContainer.Find("input")
|
||||
// pubkey, comment, submit button
|
||||
a.Equal(3, inputs.Length())
|
||||
inputs.Each(func(i int, el *goquery.Selection) {
|
||||
_, disabled := el.Attr("disabled")
|
||||
a.Equal(shouldBeDisabled, disabled)
|
||||
})
|
||||
}
|
||||
|
||||
// verify that inputs are enabled for RoleAdmin
|
||||
checkInputsAreDisabled(false)
|
||||
|
||||
// verify that inputs are enabled for RoleModerator
|
||||
ts.User = roomdb.Member{
|
||||
ID: 9001,
|
||||
Role: roomdb.RoleModerator,
|
||||
}
|
||||
checkInputsAreDisabled(false)
|
||||
|
||||
// verify that inputs are disabled for RoleMember
|
||||
ts.User = roomdb.Member{
|
||||
ID: 7331,
|
||||
Role: roomdb.RoleMember,
|
||||
}
|
||||
checkInputsAreDisabled(true)
|
||||
}
|
||||
|
||||
func TestDeniedKeysAdd(t *testing.T) {
|
||||
ts := newSession(t)
|
||||
a := assert.New(t)
|
||||
|
|
|
@ -64,6 +64,50 @@ func TestInvitesOverview(t *testing.T) {
|
|||
a.True(yes, "a-tag has href attribute")
|
||||
wantURL := ts.URLTo(router.AdminInvitesRevokeConfirm, "id", 666)
|
||||
a.Equal(wantURL.String(), link)
|
||||
|
||||
testInviteButtonDisabled := func(shouldBeDisabled bool) {
|
||||
html, resp = ts.Client.GetHTML(invitesOverviewURL)
|
||||
a.Equal(http.StatusOK, resp.Code, "wrong HTTP status code")
|
||||
inviteButton := html.Find("#create-invite button")
|
||||
_, disabled := inviteButton.Attr("disabled")
|
||||
a.EqualValues(shouldBeDisabled, disabled, "invite button should be disabled")
|
||||
}
|
||||
|
||||
// member, mod, admin should all be able to invite in ModeCommunity
|
||||
ts.ConfigDB.GetPrivacyModeReturns(roomdb.ModeCommunity, nil)
|
||||
ts.User = roomdb.Member{
|
||||
ID: 1234,
|
||||
Role: roomdb.RoleAdmin,
|
||||
}
|
||||
testInviteButtonDisabled(false)
|
||||
ts.User = roomdb.Member{
|
||||
ID: 7331,
|
||||
Role: roomdb.RoleModerator,
|
||||
}
|
||||
testInviteButtonDisabled(false)
|
||||
ts.User = roomdb.Member{
|
||||
ID: 9001,
|
||||
Role: roomdb.RoleMember,
|
||||
}
|
||||
testInviteButtonDisabled(false)
|
||||
|
||||
// mod and admin should be able to invite, member should not
|
||||
ts.ConfigDB.GetPrivacyModeReturns(roomdb.ModeRestricted, nil)
|
||||
ts.User = roomdb.Member{
|
||||
ID: 1234,
|
||||
Role: roomdb.RoleAdmin,
|
||||
}
|
||||
testInviteButtonDisabled(false)
|
||||
ts.User = roomdb.Member{
|
||||
ID: 7331,
|
||||
Role: roomdb.RoleModerator,
|
||||
}
|
||||
testInviteButtonDisabled(false)
|
||||
ts.User = roomdb.Member{
|
||||
ID: 9001,
|
||||
Role: roomdb.RoleMember,
|
||||
}
|
||||
testInviteButtonDisabled(true)
|
||||
}
|
||||
|
||||
func TestInvitesCreateForm(t *testing.T) {
|
||||
|
|
|
@ -7,6 +7,7 @@ import (
|
|||
"net/url"
|
||||
"testing"
|
||||
|
||||
"github.com/PuerkitoBio/goquery"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/ssb-ngi-pointer/go-ssb-room/roomdb"
|
||||
|
@ -35,6 +36,11 @@ func TestMembersAdd(t *testing.T) {
|
|||
ts := newSession(t)
|
||||
a := assert.New(t)
|
||||
|
||||
ts.User = roomdb.Member{
|
||||
ID: 1234,
|
||||
Role: roomdb.RoleAdmin,
|
||||
}
|
||||
|
||||
listURL := ts.URLTo(router.AdminMembersOverview)
|
||||
|
||||
html, resp := ts.Client.GetHTML(listURL)
|
||||
|
@ -70,6 +76,43 @@ func TestMembersAdd(t *testing.T) {
|
|||
a.Equal(newKey, addedPubKey.Ref())
|
||||
a.Equal(roomdb.RoleMember, addedRole)
|
||||
|
||||
/* Verify that the inputs are visible/hidden depending on user roles */
|
||||
checkInputsAreDisabled := func(shouldBeDisabled bool) {
|
||||
html, resp = ts.Client.GetHTML(listURL)
|
||||
a.Equal(http.StatusOK, resp.Code, "wrong HTTP status code")
|
||||
inputContainer := html.Find("#add-member-input-container")
|
||||
a.Equal(1, inputContainer.Length())
|
||||
inputs := inputContainer.Find("input")
|
||||
// pubkey
|
||||
a.Equal(1, inputs.Length())
|
||||
inputs.Each(func(i int, el *goquery.Selection) {
|
||||
_, disabled := el.Attr("disabled")
|
||||
a.Equal(shouldBeDisabled, disabled)
|
||||
})
|
||||
button := inputContainer.Find("button")
|
||||
a.Equal(1, button.Length())
|
||||
button.Each(func(i int, el *goquery.Selection) {
|
||||
_, disabled := el.Attr("disabled")
|
||||
a.Equal(shouldBeDisabled, disabled)
|
||||
})
|
||||
}
|
||||
|
||||
// verify that inputs are enabled for RoleAdmin
|
||||
checkInputsAreDisabled(false)
|
||||
|
||||
// verify that inputs are enabled for RoleModerator
|
||||
ts.User = roomdb.Member{
|
||||
ID: 9001,
|
||||
Role: roomdb.RoleModerator,
|
||||
}
|
||||
checkInputsAreDisabled(false)
|
||||
|
||||
// verify that inputs are disabled for RoleMember
|
||||
ts.User = roomdb.Member{
|
||||
ID: 7331,
|
||||
Role: roomdb.RoleMember,
|
||||
}
|
||||
checkInputsAreDisabled(true)
|
||||
}
|
||||
|
||||
func TestMembersDontAddInvalid(t *testing.T) {
|
||||
|
@ -173,6 +216,11 @@ func TestMemberDetails(t *testing.T) {
|
|||
|
||||
memberURL := ts.URLTo(router.AdminMemberDetails, "id", "1")
|
||||
|
||||
ts.User = roomdb.Member{
|
||||
ID: 1234,
|
||||
Role: roomdb.RoleAdmin,
|
||||
}
|
||||
|
||||
html, resp := ts.Client.GetHTML(memberURL)
|
||||
a.Equal(http.StatusOK, resp.Code, "wrong HTTP status code")
|
||||
|
||||
|
@ -180,14 +228,6 @@ func TestMemberDetails(t *testing.T) {
|
|||
{"title", "AdminMemberDetailsTitle"},
|
||||
})
|
||||
|
||||
// check for SSB ID
|
||||
ssbID := html.Find("#ssb-id")
|
||||
a.Equal(feedRef.Ref(), ssbID.Text())
|
||||
|
||||
// check for change-role dropdown
|
||||
roleDropdown := html.Find("#change-role")
|
||||
a.EqualValues(roleDropdown.Length(), 1)
|
||||
|
||||
aliasList := html.Find("#alias-list").Find("a")
|
||||
|
||||
// check for link to resolve 1st Alias
|
||||
|
@ -220,6 +260,37 @@ func TestMemberDetails(t *testing.T) {
|
|||
a.True(yes, "a-tag has href attribute")
|
||||
wantLink = ts.URLTo(router.AdminMembersRemoveConfirm, "id", 1)
|
||||
a.Equal(wantLink.String(), removeLink)
|
||||
|
||||
testDisabledBehaviour := func(isElevated bool) {
|
||||
html, resp := ts.Client.GetHTML(memberURL)
|
||||
a.Equal(http.StatusOK, resp.Code, "wrong HTTP status code")
|
||||
// check for SSB ID
|
||||
ssbID := html.Find("#ssb-id")
|
||||
a.Equal(feedRef.Ref(), ssbID.Text())
|
||||
|
||||
// check for change-role dropdown
|
||||
roleDropdown := html.Find("#change-role")
|
||||
if isElevated {
|
||||
a.Equal(1, roleDropdown.Length())
|
||||
} else {
|
||||
a.Equal(0, roleDropdown.Length())
|
||||
}
|
||||
}
|
||||
testDisabledBehaviour(true)
|
||||
|
||||
/* Now: verify that moderators cannot make room settings changes */
|
||||
ts.User = roomdb.Member{
|
||||
ID: 7331,
|
||||
Role: roomdb.RoleModerator,
|
||||
}
|
||||
testDisabledBehaviour(true)
|
||||
|
||||
/* Finally: verify that members cannot make room settings changes */
|
||||
ts.User = roomdb.Member{
|
||||
ID: 9001,
|
||||
Role: roomdb.RoleMember,
|
||||
}
|
||||
testDisabledBehaviour(false)
|
||||
}
|
||||
|
||||
func TestMembersRemoveConfirmation(t *testing.T) {
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/ssb-ngi-pointer/go-ssb-room/roomdb"
|
||||
"github.com/ssb-ngi-pointer/go-ssb-room/web/router"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
@ -33,6 +34,10 @@ func TestLanguageSetDefaultLanguage(t *testing.T) {
|
|||
a := assert.New(t)
|
||||
|
||||
ts.ConfigDB.GetDefaultLanguageReturns("de", nil)
|
||||
ts.User = roomdb.Member{
|
||||
ID: 1234,
|
||||
Role: roomdb.RoleAdmin,
|
||||
}
|
||||
|
||||
u := ts.URLTo(router.AdminSettings)
|
||||
html, resp := ts.Client.GetHTML(u)
|
||||
|
|
|
@ -0,0 +1,100 @@
|
|||
package admin
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/PuerkitoBio/goquery"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/ssb-ngi-pointer/go-ssb-room/roomdb"
|
||||
"github.com/ssb-ngi-pointer/go-ssb-room/web/router"
|
||||
)
|
||||
|
||||
func TestSettingsOverview(t *testing.T) {
|
||||
ts := newSession(t)
|
||||
a := assert.New(t)
|
||||
|
||||
/* First: make sure everything renders correctly for admins */
|
||||
ts.User = roomdb.Member{
|
||||
ID: 1234,
|
||||
Role: roomdb.RoleAdmin,
|
||||
}
|
||||
|
||||
ts.ConfigDB.GetPrivacyModeReturns(roomdb.ModeCommunity, nil)
|
||||
ts.ConfigDB.GetDefaultLanguageReturns("en", nil)
|
||||
|
||||
settingsURL := ts.URLTo(router.AdminSettings)
|
||||
|
||||
html, resp := ts.Client.GetHTML(settingsURL)
|
||||
a.Equal(http.StatusOK, resp.Code, "wrong HTTP status code")
|
||||
|
||||
// the privacy mode form & its summary/details container should exist
|
||||
privacyFormContainer := html.Find("#change-privacy")
|
||||
a.Equal(1, privacyFormContainer.Length())
|
||||
a.Equal(1, privacyFormContainer.Find("summary").Length())
|
||||
// chosen privacy mode is ModeCommunity (english translation will only be the name of the label, due to testing suite is set up atm)
|
||||
a.Equal("ModeCommunity", strings.TrimSpace(privacyFormContainer.Find("summary").Text()))
|
||||
// details-dropdown should have two forms, one for each of the other two privacy modes
|
||||
// that can be selected (ModeOpen, ModeRestricted)
|
||||
a.Equal(2, privacyFormContainer.Find("form").Length())
|
||||
// and one span, showing the selected mode
|
||||
a.Equal(1, privacyFormContainer.Find("#selected-mode").Length())
|
||||
inputs := privacyFormContainer.Find("input")
|
||||
// verify none of the privacy mode container's inputs are disabled
|
||||
inputs.Each(func(i int, el *goquery.Selection) {
|
||||
_, exists := el.Attr("disabled")
|
||||
a.False(exists)
|
||||
})
|
||||
|
||||
// verify that the change language form exists & is enabled
|
||||
languageFormContainer := html.Find("#change-language-container")
|
||||
a.Equal(1, languageFormContainer.Length())
|
||||
a.Equal(1, languageFormContainer.Find("summary").Length())
|
||||
// (english translation will only be the name of the label, due to testing suite is set up atm)
|
||||
a.Equal("LanguageName", strings.TrimSpace(languageFormContainer.Find("summary").Text()))
|
||||
|
||||
testDisabledBehaviour := func() {
|
||||
settingsURL := ts.URLTo(router.AdminSettings)
|
||||
html, resp := ts.Client.GetHTML(settingsURL)
|
||||
a.Equal(http.StatusOK, resp.Code, "wrong HTTP status code")
|
||||
|
||||
// we do not have the summary/details hack if the forms are hidden
|
||||
privacyFormContainer := html.Find("#change-privacy")
|
||||
a.Equal(0, privacyFormContainer.Length())
|
||||
// the should still be the parent container, however
|
||||
privacyContainer := html.Find("#privacy-mode-container")
|
||||
a.Equal(1, privacyContainer.Length())
|
||||
// there should only be one input in the privacy mode container now
|
||||
inputs := privacyContainer.Find("input")
|
||||
a.Equal(1, inputs.Length())
|
||||
// the input should be disabled
|
||||
_, disabled := inputs.Attr("disabled")
|
||||
a.True(disabled)
|
||||
|
||||
// next, verify that the change language setting is disabled
|
||||
languageContainer := html.Find("#change-language-container")
|
||||
a.Equal(1, languageContainer.Length())
|
||||
// there should only be one input in the language mode container now
|
||||
inputs = languageContainer.Find("input")
|
||||
a.Equal(1, inputs.Length())
|
||||
// the input should be disabled
|
||||
_, disabled = inputs.Attr("disabled")
|
||||
a.True(disabled)
|
||||
}
|
||||
|
||||
/* Now: verify that moderators cannot make room settings changes */
|
||||
ts.User = roomdb.Member{
|
||||
ID: 7331,
|
||||
Role: roomdb.RoleModerator,
|
||||
}
|
||||
testDisabledBehaviour()
|
||||
|
||||
/* Finally: verify that members cannot make room settings changes */
|
||||
ts.User = roomdb.Member{
|
||||
ID: 9001,
|
||||
Role: roomdb.RoleMember,
|
||||
}
|
||||
testDisabledBehaviour()
|
||||
}
|
|
@ -133,9 +133,14 @@ func newSession(t *testing.T) *testSession {
|
|||
testFuncs["urlToNotice"] = func(name string) string { return "" }
|
||||
testFuncs["language_count"] = func() int { return 1 }
|
||||
testFuncs["list_languages"] = func(*url.URL, string) string { return "" }
|
||||
testFuncs["member_is_elevated"] = func() bool { return true }
|
||||
testFuncs["member_is_admin"] = func() bool { return true }
|
||||
testFuncs["member_can_invite"] = func() bool { return true }
|
||||
testFuncs["member_is_elevated"] = func() bool { return ts.User.Role == roomdb.RoleAdmin || ts.User.Role == roomdb.RoleModerator }
|
||||
testFuncs["member_is_admin"] = func() bool { return ts.User.Role == roomdb.RoleAdmin }
|
||||
testFuncs["member_can_invite"] = func() bool {
|
||||
pm, _ := ts.ConfigDB.GetPrivacyMode(ctx)
|
||||
memberElevated := ts.User.Role == roomdb.RoleAdmin || ts.User.Role == roomdb.RoleModerator
|
||||
memberCanInvite := ts.User.Role == roomdb.RoleMember && (pm == roomdb.ModeCommunity || pm == roomdb.ModeOpen)
|
||||
return memberElevated || memberCanInvite
|
||||
}
|
||||
testFuncs["list_languages"] = func(*url.URL, string) string { return "" }
|
||||
testFuncs["relative_time"] = func(when time.Time) string { return humanize.Time(when) }
|
||||
|
||||
|
|
|
@ -100,7 +100,7 @@ func ContextInjecter(mdb roomdb.MembersService, withPassword *auth.Handler, with
|
|||
//
|
||||
// {{ member_is_admin }} is a shortcut for {{ member_has_role "RoleAdmin" }}
|
||||
//
|
||||
// {{ member_is_admin }} is a shortcut for {{ or member_has_role "RoleAdmin" member_has_role "RoleModerator"}}
|
||||
// {{ member_is_elevated }} is a shortcut for {{ or member_has_role "RoleAdmin" member_has_role "RoleModerator"}}
|
||||
func TemplateHelpers() []render.Option {
|
||||
|
||||
return []render.Option{
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
method="POST"
|
||||
>
|
||||
{{ .csrfField }}
|
||||
<div class="flex flex-row items-center h-12">
|
||||
<div id="denied-keys-input-container" class="flex flex-row items-center h-12">
|
||||
<input
|
||||
{{ if member_is_elevated }} {{ else }} disabled {{ end }}
|
||||
type="text"
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
>
|
||||
{{ .csrfField }}
|
||||
<label class="block mt-6 mb-1 text-sm text-gray-500">{{ i18n "AdminAddNewMemberTitle" }}</label>
|
||||
<div class="flex flex-row items-center justify-start mb-6">
|
||||
<div id="add-member-input-container" class="flex flex-row items-center justify-start mb-6">
|
||||
<input
|
||||
{{ if member_is_elevated }} {{ else }} disabled {{ end }}
|
||||
type="text"
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
class="text-3xl tracking-tight font-black text-black mt-2 mb-0"
|
||||
>{{ i18n "Settings" }}</h1>
|
||||
|
||||
<div class="max-w-2xl">
|
||||
<div class="max-w-2xl" id="privacy-mode-container">
|
||||
<h2 class="text-xl tracking-tight font-bold text-black mt-2 mb-2">{{ i18n "PrivacyModesTitle" }}</h2>
|
||||
<p class="mb-4">
|
||||
{{ i18n "ExplanationPrivacyModes" }}
|
||||
|
@ -39,7 +39,7 @@
|
|||
<path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z" />
|
||||
</svg>
|
||||
</div>
|
||||
<span>{{ i18n .String }}</span>
|
||||
<span id="selected-mode">{{ i18n .String }}</span>
|
||||
</div>
|
||||
{{end}}
|
||||
{{end}}
|
||||
|
@ -59,7 +59,7 @@
|
|||
<div class="text-md col-span-2 italic">{{ i18n "ExplanationRestricted" }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="max-w-2xl">
|
||||
<div class="max-w-2xl" id="change-language-container">
|
||||
<h2 class="text-xl tracking-tight font-bold text-black mt-2 mb-2">{{ i18n "DefaultLanguageTitle" }}</h2>
|
||||
<p class="mb-4">
|
||||
{{ i18n "ExplanationDefaultLanguage" }}
|
||||
|
|
Loading…
Reference in New Issue