ChatAccess admits only chat-group members to context bm/1 and manages nothing; the chat context oversees nothing and its loader knows only id 1; /chat and /chat/members need a caller and a database. The migration count rises to 15 for the chat group seed.
108 lines
3.6 KiB
Go
108 lines
3.6 KiB
Go
package classes_test
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"testing"
|
|
|
|
"git.golem15.com/jakub/sm-bm-plugin/classes"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
// members is an injected group check: user 7 is in studenci, user 9 is in
|
|
// moderatorzy only, user 13 makes the check fail.
|
|
func members(_ context.Context, _ *gorm.DB, userID uint, group string) (bool, error) {
|
|
switch {
|
|
case userID == 13:
|
|
return false, errors.New("database down")
|
|
case group == "studenci":
|
|
return userID == 7, nil
|
|
case group == "moderatorzy":
|
|
return userID == 9 || userID == 7, nil
|
|
}
|
|
return false, nil
|
|
}
|
|
|
|
func TestChatAccess(t *testing.T) {
|
|
db := func() *gorm.DB { return &gorm.DB{} }
|
|
access := classes.NewChatAccess(db, "studenci", members)
|
|
ctx := t.Context()
|
|
for _, c := range []struct {
|
|
name string
|
|
userID uint
|
|
contextType string
|
|
contextID uint
|
|
want bool
|
|
}{
|
|
{"member of bm/1", 7, "bm", 1, true},
|
|
{"other context type", 7, "channel", 1, false},
|
|
{"other context id", 7, "bm", 2, false},
|
|
{"non-member", 8, "bm", 1, false},
|
|
{"moderator only", 9, "bm", 1, false},
|
|
{"check fails", 13, "bm", 1, false},
|
|
{"no user", 0, "bm", 1, false},
|
|
} {
|
|
if got := access.CanAccessContext(ctx, c.userID, c.contextType, c.contextID); got != c.want {
|
|
t.Errorf("%s: CanAccessContext = %v, want %v", c.name, got, c.want)
|
|
}
|
|
if access.CanManageContext(ctx, c.userID, c.contextType, c.contextID) {
|
|
t.Errorf("%s: CanManageContext = true; nobody creates channels", c.name)
|
|
}
|
|
}
|
|
noDB := classes.NewChatAccess(func() *gorm.DB { return nil }, "studenci", members)
|
|
if noDB.CanAccessContext(ctx, 7, "bm", 1) {
|
|
t.Error("CanAccessContext without a database = true, want false")
|
|
}
|
|
nilFunc := classes.NewChatAccess(nil, "studenci", members)
|
|
if nilFunc.CanAccessContext(ctx, 7, "bm", 1) {
|
|
t.Error("CanAccessContext without a database func = true, want false")
|
|
}
|
|
noGroup := classes.NewChatAccess(db, "", members)
|
|
if noGroup.CanAccessContext(ctx, 7, "bm", 1) {
|
|
t.Error("CanAccessContext without a chat group = true, want false")
|
|
}
|
|
}
|
|
|
|
func TestChatContext(t *testing.T) {
|
|
ctx := t.Context()
|
|
c := classes.NewChatContext(&gorm.DB{}, "studenci", "moderatorzy").WithMembership(members)
|
|
if c.ID() != classes.ChatContextID || c.ID() != 1 || c.Type() != "bm" {
|
|
t.Errorf("context = %s/%d, want bm/1", c.Type(), c.ID())
|
|
}
|
|
if !c.ChatEnabled() || c.GroupName() != "ogólny" {
|
|
t.Errorf("ChatEnabled %v GroupName %q", c.ChatEnabled(), c.GroupName())
|
|
}
|
|
if c.BroadcastChannel() != "chat:context:1" {
|
|
t.Errorf("BroadcastChannel = %q, want chat:context:1", c.BroadcastChannel())
|
|
}
|
|
for _, id := range []uint{7, 9, 8} {
|
|
if ok, err := c.CanOverseeChats(ctx, id); ok || err != nil {
|
|
t.Errorf("CanOverseeChats(%d) = %v, %v; nobody oversees", id, ok, err)
|
|
}
|
|
}
|
|
if ok, err := c.HasMember(ctx, 7); !ok || err != nil {
|
|
t.Errorf("HasMember(7) = %v, %v, want true", ok, err)
|
|
}
|
|
if ok, err := c.HasMember(ctx, 9); ok || err != nil {
|
|
t.Errorf("HasMember(9) = %v, %v, want false (moderator group only)", ok, err)
|
|
}
|
|
if ok, _ := c.HasMember(ctx, 0); ok {
|
|
t.Error("HasMember(0) = true")
|
|
}
|
|
if _, err := c.HasMember(ctx, 13); err == nil {
|
|
t.Error("HasMember with a failing check returned no error")
|
|
}
|
|
if !c.CanActFor(ctx, 7, 7) || c.CanActFor(ctx, 7, 8) {
|
|
t.Error("CanActFor is not self-only")
|
|
}
|
|
|
|
load := classes.ChatContextLoader(func() string { return "studenci" }, func() string { return "moderatorzy" })
|
|
if got, err := load(ctx, &gorm.DB{}, 2); got != nil || err != nil {
|
|
t.Errorf("loader(2) = %v, %v, want nil, nil", got, err)
|
|
}
|
|
got, err := load(ctx, &gorm.DB{}, 1)
|
|
if err != nil || got == nil || got.ID() != 1 || got.Type() != "bm" {
|
|
t.Errorf("loader(1) = %v, %v, want the bm/1 context", got, err)
|
|
}
|
|
}
|